Canvas Design System
Main Site Tokens

Planner Activity Inspector

The Planner's right column when an activity is selected: everything known about that one item, and what you can do to it.

When to Use

Use when: The user has selected a card on the timeline. It's the sibling of Planner Inspector Rail — same visual shell, different sections — and you swap between them on selection state.
Don't use when: Nothing is selected — show the inspector rail instead. Never render both at once; the right column is one or the other.

Variants

Canonical — fully annotated activity

Seven sections: identity, overview, energy impact, logistics, notes, when it runs, and actions. The left border carries the type accent so the rail ties visually to the selected card.

info Supplying instructions turns the overview into a two-tab panel — Overview and Instructions. Without them, the overview renders as a plain block.

Type accents

One type drives the whole card: left border, energy bars, net badge tint, logistics bullets, note rule, and button hover. Never hardcode these downstream.

Minimal — identity and actions

Every section is optional. This is what a custom activity or an un-annotated library item looks like.

States

StateBehavior
Section omittedPassing null or leaving a key out removes that section entirely, dividers included. The last rendered section takes --section--last.
Overview without instructionsRenders as a plain block, no tabs.
Overview with instructionsBecomes a tab panel. activeTab chooses which is active on first paint; the tabs carry data-tab and data-tab-group for your switching code.
Instructions as array vs stringAn array renders a numbered list with mono step counters. A string is rendered as raw HTML — you own the markup, and the escaping.
Empty bodyWith no optional sections at all the body takes --body--empty, tightening the layout rather than leaving a gap.
Closableclosable defaults to true, rendering the × in the eyebrow row with data-action="close". Your code handles the click and swaps back to the inspector rail.
Action fallbackAn action without an explicit action key derives one from its label — "Remove from agenda" becomes remove-from-agenda. Set it explicitly if your handler expects a specific value.

Real-World Usage

The selection swap in the Planner's right column, with the energy figures coming from the scorer and notes from the facilitator's own record.

<?php if ($selected): ?>
    <?= ws_planner_activity_inspector([
        'type'         => $selected['item_type'],
        'duration'     => $selected['duration'] . ' min',
        'groupSize'    => $selected['group_size'],
        'title'        => $selected['title'],
        'tags'         => $selected['tags'],
        'overview'     => $selected['overview'],
        'instructions' => $selected['instructions'],       // array ⇒ numbered list
        'energy'       => $energyScorer->itemImpact($selected['id']),
        'logistics'    => [$selected['duration'] . ' min', $selected['group_size'],
                           $selected['posture'], $selected['materials']],
        'notes'        => $notes ? [
            'body' => $notes['content'], 'author' => $notes['author'],
            'date' => $notes['date'],    'canAdd' => true,
        ] : null,
        'context'      => ['time'        => $startTime . ' → ' . $endTime,
                           'description' => 'right after ' . $previous['title']],
        'actions'      => [
            ['label' => 'Swap',      'icon' => 'swap_horiz',   'action' => 'swap'],
            ['label' => 'Duplicate', 'icon' => 'content_copy', 'action' => 'duplicate'],
            ['label' => 'Adjust',    'icon' => 'schedule',     'action' => 'adjust'],
        ],
        'destructive'  => ['label' => 'Remove from agenda', 'icon' => 'close', 'action' => 'remove'],
    ]) ?>
<?php else: ?>
    <?= ws_planner_inspector_rail($railOptions) ?>
<?php endif; ?>

Options

OptionTypePurpose
titlestringRequired. The activity name, in the display face.
typestringexercise (default) | icebreaker | break | custom. Drives every accent in the panel.
duration / groupSizestringComposed into the eyebrow: EXERCISE · 60 MIN · 6–12 PPL. Omit either to drop it.
tagsarrayShort strings joined with · below the title
closableboolShow the × control. Default true.
overviewstringOne or two sentences. Deeper description belongs on the library detail page.
instructionsarray|string|nullArray of steps, or an HTML string. Presence switches the overview to tabs.
activeTabstringoverview (default) | instructions
energyarray|null['net', 'dimensions' => [['label', 'delta', 'fill' => 0..100]]]. The net badge is the headline; dimensions are supporting detail.
logisticsarrayStrings in a two-column mono grid with accent-tinted bullets
notesarray|null['body', 'author', 'date', 'canAdd']. Renders as a blockquote with an accent rule; canAdd surfaces the add affordance.
contextarray|null['time', 'description'] — when the item runs, as a dashed mono pill
actionsarray[['label', 'icon?', 'action?', 'href?']]. Three at most at this width — mono labels wrap badly in narrow columns.
destructivearray|nullOne destructive action, full width below the primary row. Keep removal out of actions — the separate slot exists so it reads as different.
id / class / attrsstring / string / arrayStandard passthrough

Accessibility

ConcernBehavior
TabsThe overview/instructions panel emits the full pattern: role="tablist", role="tab" with aria-selected and aria-controls, and role="tabpanel" on each panel — better wired than the standalone Tabs component, which never emits panels.
Tab keyboardSame gap as Tabs: the roles promise arrow-key navigation between tabs, but only Tab and Enter/Space work. Two tabs makes it less painful, but the promise is still unmet.
Close controlLabelled aria-label="Close inspector" — it names the region, not just the glyph.
Decorative iconsBullets, dividers, and step counters carry aria-hidden="true".
Energy barsThe delta is text next to each label, so the number is announced; the bar is reinforcement. Good.
Focus on selectionYours to handle. Swapping the rail replaces the DOM, so focus drops to <body>. Move focus to the inspector's title when it opens, and back to the timeline card when it closes.
Destructive actionMarked by a red-tinted border and the word "Remove". Colour is reinforcement, not the signal — keep the verb in the label.
Instructions as HTMLA string is rendered raw. Escape anything user-supplied before passing it.

Tokens

Like its sibling rail, the inspector resolves the shared scales into a locally-scoped set on the root, then references those internally — which is why one type can retint the entire panel.

Token groupUsed for
Type accent (--planner-*)Left border stripe, energy bar fills, net badge tint, logistics bullets, note rule, and button hover
Surface and edgePanel background and section dividers — the planner "paper" surface
Ink scaleTitle, overview, labels, and meta text across four weights
Display and mono facesFraunces title; mono for eyebrows, tags, logistics, and step counters
Error colourThe destructive action's border and hover

See the .ws-planner-activity-inspector rules in components.css for exact declarations, and Token Reference for values.

CSS Classes

ClassPurpose
.ws-planner-activity-inspectorRoot panel
.ws-planner-activity-inspector--exercise / --icebreaker / --break / --customType accents
__eyebrow / __eyebrow-rowType, duration, group size, and the close control
__close× control, data-action="close"
__title / __tagsActivity identity
__tabs / __tab / __panelOverview / Instructions tab set
__steps / __stepNumbered instruction list
__instructions-htmlWrapper when instructions are passed as a string
__netNet energy badge
__dims / __dim / __dim-label / __dim-bar / __dim-fill / __dim-valPer-dimension energy rows
__logistics / __log-itemTwo-column logistics grid
__note / __note-attr / __addFacilitator note, its attribution, and the add affordance
__whenWhen-it-runs pill
__actions / __btn / __btn-iconPrimary action row
__destructive / __btn--dangerDestructive action
__section / __section--last / __body / __body--empty / __labelSection scaffolding

Files

FilePurpose
includes/components/helpers.phpws_planner_activity_inspector() helper function
includes/components/planner-activity-inspector.phpTemplate — sections, tab wiring, and accent resolution
includes/components/components.cssStyles (.ws-planner-activity-inspector rules)
css/planner/components/_sidebar.cssPlanner-side rail styling