Canvas Design System
Main Site Tokens

Feature Card

Icon, title, and one line of description — the unit a benefits grid is built from.

When to Use

Use when: You're presenting three to six parallel capabilities or benefits in a grid, each summarised in a sentence. The fixed icon-title-description shape is what makes the set scannable.
Don't use when: The items are content records rather than features — use Listing Card. For an arbitrary container use Card, and for numbered sequences use How Steps.

Variants

Default

Curated Library

Browse our collection of workshops, exercises, and icebreakers.

AI Facilitation Coach

Get real-time guidance powered by AI during your sessions.

Workshop Planner

Drag and drop to build your perfect agenda.

<?= ws_feature_card('Curated Library', 'Browse our collection…', [
    'icon' => 'menu_book',
]) ?>

Compact

Smaller icon and tighter padding, for grids inside app screens rather than full-width marketing sections.

Quick Setup

Get started in under 5 minutes.

Team Ready

Built for groups of any size.

<?= ws_feature_card('Quick Setup', 'Get started fast.', [
    'icon'    => 'bolt',
    'variant' => 'compact',
]) ?>

Coming soon

Dims the card to mark a feature as not yet available. Don't pass href alongside it — a dimmed card that still navigates is worse than no card.

Custom Builder

Create your own workshops from scratch.

Analytics

Track session outcomes and engagement.

Templates

Start from proven templates.

<?= ws_feature_card('Custom Builder', 'Create your own workshops.', [
    'icon'    => 'construction',
    'variant' => 'coming-soon',
]) ?>

As links

With href the card renders as an <a>, making the whole surface focusable and clickable — the accessible way to make a feature card actionable.

<?= ws_feature_card('Workshops', 'Full-day and half-day formats.', [
    'icon' => 'groups',
    'href' => '/library/workshops/',
]) ?>

States

StateBehavior
DefaultSurface fill, bordered, with a tinted icon holder.
HoverOnly meaningful on the link form: border and shadow step up over --transition-base.
FocusNative focus ring, present only when href makes the card an anchor. A non-link card has no focus state.
Coming soonAdds .ws-feature-card--coming-soon, which dims the card. Purely visual — it doesn't disable anything.
Icon vs SVGicon renders a Material Symbol; svg injects raw markup instead. Passing both is redundant — pick one.

Real-World Usage

The homepage capability grid: three live features as links into the apps, one marked coming-soon and deliberately not linked.

<?php foreach ($features as $f): ?>
    <?= ws_feature_card($f['title'], $f['description'], [
        'icon'    => $f['icon'],
        'href'    => $f['live'] ? $f['url'] : null,
        'variant' => $f['live'] ? 'default' : 'coming-soon',
    ]) ?>
<?php endforeach; ?>

Options

OptionTypeDefaultPurpose
$titlestringrequiredPositional. The capability, in one or two words.
$descriptionstringrequiredPositional. One sentence. Keep lengths even across a grid so the cards align.
iconstringnullMaterial icon name
svgstringnullRaw SVG markup, as an alternative to icon
variantstring'default'default | compact | coming-soon
hrefstringnullRenders the card as an <a>
idstringnullElement ID
classstring''Additional CSS classes
attrsarray[]Extra HTML attributes as key/value pairs

Accessibility

ConcernBehavior
SemanticsA <div> normally, an <a> with href. Use href rather than a JS click handler — it's the difference between a keyboard-reachable card and an invisible one.
Title elementThe title is styled text, not a heading element. That keeps the page outline clean but means a screen-reader user can't jump between cards by heading — introduce the grid with a Section Header so the set is findable.
Link textAs a link, the accessible name is the title plus description — usually good. Avoid titles like "Learn more" that say nothing out of context.
Coming soonKnown gap: the state is conveyed by dimming alone. Nothing in the markup says "coming soon", so it's invisible to screen readers and easily missed at low contrast. Put the words in the description — "Coming soon — track engagement…".
IconsDecorative. The title always carries the meaning, so an icon-only card would have nothing to announce.
ContrastTitle uses --text-dark and description --text-muted. The coming-soon variant reduces contrast further — don't stack extra opacity on top.

Tokens

TokenUsed for
--bg-surfaceCard background
--gray-200 / --gray-300Border, resting and hover
--mainsite-primary / --mainsite-very-lightIcon colour and its tinted holder
--text-darkTitle
--text-mutedDescription
--text-inverseIcon on a solid fill
--radius-xlCard corners
--shadow-lgHover elevation on the link form
--text-h2 / --text-h3 / --text-ui / --text-body / --text-small / --text-metaType scale across variants
--font-heading / --font-body / --font-semiboldFraunces title, Inter description
--transition-baseHover transition

CSS Classes

ClassPurpose
.ws-feature-cardBase card, <div> or <a>
.ws-feature-card--compactReduced padding and icon size
.ws-feature-card--coming-soonDimmed unavailable state
.ws-feature-card__iconTinted icon holder
.ws-feature-card__titleTitle text
.ws-feature-card__descDescription text

Files

FilePurpose
includes/components/helpers.phpws_feature_card() helper function
includes/components/feature-card.phpTemplate — tag selection and icon/SVG branch
includes/components/components.cssStyles (.ws-feature-card rules)