Canvas Design System
Main Site Tokens

Planner Inspector Rail

The Planner's right column when nothing is selected: energy, coach suggestions, and who else is in the room.

When to Use

Use when: You need the Planner's right column in its default, whole-agenda state — three fixed sections, each optional. It's the counterpart to Planner Activity Inspector, which takes over when an item is selected.
Don't use when: An activity is selected — swap to the activity inspector. And don't reach for it if you need sections beyond these three; the anatomy is deliberately fixed.

Variants

Canonical — all three sections

Note the energy section's title and meta sit outside the card: the rail auto-sets showHeader => false on the wrapped Energy Arc Card and defaults its score badge to the note variant, so the badge sits beside the score without dominating.

<?= ws_planner_inspector_rail([
    'energy' => [
        'title' => 'Energy arc',
        'meta'  => '8 of 4h used · 0m over',
        'card'  => [ /* forwarded to ws_energy_arc_card */ ],
    ],
    'coach' => [
        'title' => 'Coach suggests',
        'meta'  => '3 notes',
        'items' => [
            ['icon' => 'schedule', 'pre' => 'TIMING',
             'line' => 'Five Whys runs long — budget <em>45 min</em>, not 40.',
             'meta' => 'Based on 142 prior runs', 'action' => 'apply'],
        ],
    ],
    'facilitators' => [
        'title'    => 'Facilitators',
        'avatars'  => [['initials' => 'PS', 'bg' => '…']],
        'presence' => ['name' => 'Priya Sundararajan', 'status' => 'editing · 2 others viewing'],
    ],
]) ?>

Energy only

Omit a section and it disappears. Use this when the rail only needs to surface the arc — a solo facilitator with no coach notes.

<?= ws_planner_inspector_rail(['energy' => ['title' => 'Energy arc', 'card' => $arc]]) ?>

States

StateBehavior
Section presentRendered with a divider above it. The last section takes --section--last and drops its trailing rule.
Section omittedPassing null or leaving the key out removes it entirely — no heading, no divider.
Suggestion emphasisInline <em> inside a coach line renders in the phase colour. It's the one place markup is honoured, so escape any user data before it goes in.
Suggestion iconsDefaulted from pre when no icon is given: TIMINGschedule, ENERGYmonitoring, CLOSEchat_bubble.
PresenceStatic text as passed. The rail doesn't poll or subscribe — supply fresh values from your own presence layer.
Phase themingAccents read --wpir-phase. Override it on the container through attrs to retheme the rail for another app.
warning When overriding --wpir-phase, pass a token reference — style="--wpir-phase: var(--phase-facilitate);" — not a literal hex. Earlier guidance here suggested #7C4DFF, which is the retired pre-unification purple; every phase token now resolves to Learn Red.

Real-World Usage

The Planner's right column, swapping between this rail and the activity inspector on selection. Energy comes from the scorer; suggestions from the Coach; presence from the live layer.

<?php if ($selectedItem): ?>
    <?= ws_planner_activity_inspector($selectedItem) ?>
<?php else: ?>
    <?= ws_planner_inspector_rail([
        'energy' => [
            'title' => 'Energy arc',
            'meta'  => formatDuration($used) . ' of ' . formatDuration($total) . ' used',
            'card'  => $energyScorer->cardOptions($planId),
        ],
        'coach' => $suggestions ? [
            'title' => 'Coach suggests',
            'meta'  => count($suggestions) . ' notes',
            'items' => array_map(fn($s) => [
                'pre'    => strtoupper($s['category']),
                'line'   => $s['html'],          // pre-escaped, may contain <em>
                'meta'   => $s['evidence'],
                'action' => $s['action_label'],
            ], $suggestions),
        ] : null,
        'facilitators' => $collaborators ? [
            'title'    => 'Facilitators',
            'meta'     => count($collaborators) . ' collaborating',
            'avatars'  => array_map(fn($c) => ['initials' => $c['initials'], 'bg' => $c['color']],
                                    $collaborators),
            'presence' => ['name' => $activeEditor['name'], 'status' => $activeEditor['status']],
        ] : null,
    ]) ?>
<?php endif; ?>

Options

OptionTypePurpose
energyarray|null['title', 'meta', 'card']. card is forwarded to ws_energy_arc_card(); the rail sets showHeader => false and defaults the score badge to note.
coacharray|null['title', 'meta', 'items'], each item ['icon?', 'pre', 'line', 'meta', 'action', 'href?']. line honours inline <em>.
facilitatorsarray|null['title', 'meta', 'avatars', 'presence']. avatars is [['initials', 'bg']] where bg takes any CSS background including gradients; presence is ['name', 'status'].
idstringElement ID
classstringAdditional CSS classes
attrsarrayExtra HTML attributes — where the --wpir-phase override goes
info The avatar stack uses an initials pattern rather than Avatar. That's intentional for density at this size — don't substitute <img> avatars here.

Accessibility

ConcernBehavior
Decorative iconsSuggestion icons and dividers carry aria-hidden="true", so they aren't read as stray text.
Section headingsRendered as text rather than heading elements, so the rail doesn't pollute the page outline. The trade-off is that screen-reader users can't jump between sections by heading — acceptable in a fixed three-section rail.
Suggestion actionsAction labels are short verbs ("apply", "preview", "add 3m"). Out of context those are ambiguous — give each an aria-label naming what it applies to.
EmphasisInline <em> is semantic emphasis, announced as such. Good — the phase colour reinforces rather than replaces it.
PresenceChanges to who's editing aren't announced; the text is rendered once. If presence matters live, add a polite live region.
Avatar initialsInitials alone are near-meaningless to a screen reader. The presence line names the active editor, which covers the common case — but the other avatars are unnamed. Add a title or visually-hidden name per avatar if the roster matters.
Energy chartOwned by Energy Arc Card — see that page for its text-alternative behaviour.

Tokens

The rail resolves the shared scales into a local --wpir-* set, so its internal rules reference one variable per role and the whole rail can be rethemed from the container.

TokenUsed for
--wpir-phaseAccent for the score, chart line, suggestion icons, and inline <em>. The override point.
--wpir-surface / --wpir-paper-edgeRail surface and its section dividers
--wpir-ink / -soft / -quiet / -whisperThe four text weights, from title down to meta
--wpir-display / --wpir-monoResolved display and mono faces
--color-surface / --gray-200Source surfaces and borders
--color-ink / -secondary / -muted / -faintSource ink scale
--font-display / --font-sans / --font-monoSource faces — Fraunces titles, Inter body, mono eyebrows
--planner-exercise-colorActivity accent where a suggestion references one
--text-nano / --text-caption / --text-meta / --text-h4Type scale across the rail
--text-inverseInitials on the avatar gradients

CSS Classes

ClassPurpose
.ws-planner-inspector-railRail container — where --wpir-* is defined and can be overridden
.ws-planner-inspector-rail__sectionA section block
.ws-planner-inspector-rail__section--lastFinal section; drops the trailing divider
.ws-planner-inspector-rail__titleSection title and its meta
.ws-planner-inspector-rail__energyEnergy slot wrapping the arc card
.ws-planner-inspector-rail__suggestionsCoach suggestion list
.ws-planner-inspector-rail__suggOne suggestion
.ws-planner-inspector-rail__sugg-icon / -pre / -line / -metaSuggestion internals
.ws-planner-inspector-rail__avatarsFacilitator initials stack
.ws-planner-inspector-rail__presence / -metaActive-editor line

Files

FilePurpose
includes/components/helpers.phpws_planner_inspector_rail() helper function
includes/components/planner-inspector-rail.phpTemplate — the three sections and the energy-card forwarding
includes/components/energy-arc-card.phpRenders the energy slot
includes/components/components.cssStyles and the --wpir-* definitions
css/planner/components/_sidebar.cssPlanner-side rail styling