Canvas Design System
Main Site Tokens

Level Up Grid

Cross-promotes the rest of the Workshopr ecosystem, grouped by facilitation phase.

When to Use

Use when: A public landing page or long-form article ends and the reader might want the rest of the platform. Once per page, in the footer region, with current_app set so the page doesn't advertise itself.
Don't use when: The user is inside an authenticated product — they're already engaged, and a promo grid is a distraction. Never on a detail page competing with its own CTA, and never twice on one page.

Variants

Grouped by phase

group_by_phase splits the grid into four sub-sections, each with an italic phase title and a short intro in the Workshopr voice. Use it where you have room to explain the journey rather than just list tools.

More from Workshopr

Level Up Your Facilitation

Learn.

Before you run the room, you read it. Steal from facilitators who've made every mistake, study the moves that worked, and stockpile exercises you can pull when the agenda goes sideways. Your reading list now is your toolkit later.

Plan.

A workshop is a sequence of decisions you make before anyone walks in: who's there, what changes by the end, where the energy spikes and dips. Block out the time, name the moves, leave room for the room. Plan tight enough to start, loose enough to follow what actually happens.

Facilitate.

The plan meets the room and the room wins. Your job is to read what's actually happening, not what you scripted, and steer with small, specific moves. Hold the timer. Surface the unsaid. Cut what's not landing.

Reflect.

The hour after the workshop is when the value either compounds or evaporates. Capture what surfaced, send the artifacts before momentum dies, and write down the one thing you'd do differently. Run enough sessions and the patterns become a craft.

<?= ws_level_up_grid([
    'current_app'    => 'academy',
    'group_by_phase' => true,
]) ?>

States

StateBehavior
DefaultEvery card is a link to its app, with icon, title, and one-line description.
HoverCard lifts and its phase accent strengthens.
FocusNative focus ring — each card is a real anchor.
Excluded appcurrent_app removes that card entirely; the grid reflows to 11.
GroupedFour sub-sections, each with a phase heading, intro prose, and a 3- or 4-up grid. A phase whose only app was excluded still renders its heading.

Real-World Usage

The standard landing-page footer: the grid, then the CTA. ws_footer() already composes both, so on pages using it you don't call this component directly.

<!-- On a standalone landing page -->
<?= ws_level_up_grid(['current_app' => 'dna']) ?>
<?= ws_cta_section('Discover your Facilitator DNA', [
    'primaryBtn' => ['text' => 'Take the quiz', 'href' => '/dna/'],
]) ?>

<!-- On a page using the global footer, both are already included -->
<?= ws_footer() ?>

Options

OptionTypeDefaultPurpose
current_appstringnullApp key to exclude — library, planner, intervention, and so on
eyebrowstring'More from Workshopr'Small label above the title
titlestring'Level Up Your Facilitation'Section heading
group_by_phaseboolfalseSplit into four phase sub-sections with intro prose. Not in the helper's docblock, but supported.
phase_copyarraybuilt-inOverride the per-phase intro prose. Merged recursively, so you can replace one phase and keep the rest. Also undocumented in the helper.
appsarraybuilt-in catalogueReplace the app list entirely. Rarely needed — the built-in catalogue is the source of truth.
idstringnullSection element ID
classstring''Additional CSS classes

Accessibility

ConcernBehavior
SemanticsEach card is a real <a>, so the whole card is focusable and announced as a link. No custom click handling is involved.
KeyboardStandard link tabbing. With 12 cards this is a long run of tab stops at the end of the page — a reason to set current_app and to keep the grid to one instance.
Link textThe accessible name is the card's title plus description, so each is distinct in a screen reader's link list.
Phase colourDecorative only. The phase is also named in the grouped variant's heading, so colour never carries it alone — which matters more than ever now that all four render the same red.
Heading levelsThe section title and phase headings are real headings, so the block is navigable. Check the levels suit where you place it.
RepetitionScreen-reader users hit this grid on every landing page. Keeping it in a consistent position, always last, makes it easy to skip.

Tokens

Each card reads its phase token. Since Red Unification all four resolve to the same red — the phase names remain as semantic grouping, not as distinct colours.

PhaseTokenCurrent valueApps
learn--phase-learn#E54D4Dlibrary, academy, podcasts
plan--phase-plan#E54D4Dplanner, hybrid
facilitate--phase-facilitate#E54D4Dfacilitator, sidekick, intervention, tips
reflect--phase-reflect#E54D4Ddna, coach, roi
warning Corrected July 2026. This table previously listed #0284C7 (plan), #7C4DFF (facilitate), and #10B981 (reflect) — the pre-unification colours. Those were retired; every phase token now resolves to Learn Red. Don't reintroduce them as literals or as var() fallbacks. See Colors.

CSS Classes

ClassPurpose
.ws-level-upSection wrapper
.ws-level-up__containerMax-width wrapper
.ws-level-up__headerEyebrow and title block
.ws-level-up__eyebrowSmall label above the title
.ws-level-up__gridCard grid
.ws-level-up__grid--3Three-up grid, used in the grouped variant
.ws-level-up__phasePhase sub-section (grouped variant)
.ws-level-up__phase--learn / --plan / --facilitate / --reflectPhase accents
.ws-level-up__cardAn app card — an <a>
.ws-level-up__card--learn / --plan / --facilitate / --reflectPer-card phase accent
.ws-level-up__card-icon / -title / -desc / -linkCard internals

Files

FilePurpose
includes/components/helpers.phpws_level_up_grid() helper function
includes/components/level-up-grid.phpTemplate — the app catalogue, phase copy, and grid markup
includes/components/components.cssStyles (.ws-level-up rules)
includes/components/footer.phpComposes this grid into the global footer

The app catalogue lives in the template. When an app is added or renamed, update it there — and keep it consistent with PRODUCT.md §5 and the app switcher.