Style apply guide

When to use each token, mode, and size.

The Tokens page lists what every token is. The Guides page covers tier rules + composition. This page closes the third loop — when to reach for which mode, which status colour, which font-size step, and which spacing band. Every rule is one line; every rule has a do / not-that pair. Read once, then ship.

Modes — pick one per surface

Every gyrum surface declares <html data-mode="…">. The mode rebinds --accent, --accent-soft, --surface, --text-muted, --border, and --radius to that mode's palette. Components downstream consume the generic names — switching the mode re-skins the whole page without touching the component CSS. Five modes; one rule each.

home

Calm slate, near-white surfaces. Use for identity / landing / docs / canon itself — anything where the chrome should recede so the content reads cleanly. Default mode.

accent
accent-soft
surface
text-muted

ship

Greenish product accent, moderate density. Use for success surfaces — release dashboards, deploy timelines, "X shipped" cards — where green is the dominant tonal cue.

accent
accent-soft
surface
text-muted

operate

Blue + amber, high contrast for alerts. Use for live dashboards, fleet boards, incident surfaces — anywhere a human is watching state change and needs unmistakable tonal contrast between healthy / warning / failing.

accent
accent-soft
surface
text-muted

infra

Technical blue-grey, calmer sibling of operate. Use for technical detail surfaces — runner config, secret rotation, terraform plan output — where the operator is reading specifics, not scanning for change.

accent
accent-soft
surface
text-muted

experiment

Warm neutral with amber accent, emphasis on charts. Use for evaluation runs, A/B reports, experiment notebooks — surfaces where data visualisation dominates and the chrome should warm-tone the page to read as analytical.

accent
accent-soft
surface
text-muted

Cross-link: ADR-058 (5-mode palette) · the Tokens page renders the mode chips that re-skin the whole page live.

Status — pick one per state

Status colours are mode-invariant — the same --ok green reads correctly on every mode's surface. Reach for status tokens when conveying a binary or trinary condition (healthy / failing, ran / never-ran, currently-running). Reach for the mode's --accent for emphasis without a condition attached.

healthy

--ok — green. Use for surfaces that have completed successfully or are currently passing their health check. Pair with --ok-soft as a callout background.

All 23 services responding · last incident 19 days ago.
drift

--warn — amber. Use for something that is not failing yet but needs operator attention soon — drift, behind, degraded. Pair with --warn-soft as a callout background.

3 PRs behind main · review window closes in 2 days.
failing

--bad — red. Use for outright failure — broken build, crashed runner, expired secret. Pair with --bad-soft as a callout background. White (--text-on-bad) is the only legal foreground on solid bad fills.

distill-staging deploy failed · last green 4h ago.
never run

--never — desaturated slate. Use for surfaces with no observation yet — never deployed, never tested, archived. The absence colour, not a failure colour. Pair with --never-soft as a callout.

buzzy · archived 2026-01-12 · no recent activity.
running

--running — bright blue. Use for transient in-flight state — deploy in progress, agent working, build running. Distinct from --ok because the work isn't finished yet; distinct from --warn because nothing is wrong.

ai-frontend · deploy in flight · started 38s ago.

Don't blur --accent and --ok. Accent is identity (this page is the dashboard); ok is condition (this service is healthy). On ship-mode dashboards the accent happens to be green — that does not make accent a status. Use --ok for status; let accent stay identity.

Typography — pick one per role

Six steps. Every step has a designated role; designs that ask for an off-step size (15px, 1.2rem) need either a different step or an ADR adding a new step. Don't compute new ones.

Page hero
--font-size-h1 · 1.5rem · use for: the single page title in <GyHero>'s <h1>.
Section title
--font-size-h2 · 1.25rem · use for: every <h2> section heading on the page (.canon-tier-h).
Card title
--font-size-lg · 1.125rem · use for: emphasis inside a card or other in-flow sub-heading that isn't an <h2>.
Body copy — the default paragraph reading size. Most prose on every page is this step.
--font-size-base · 1rem · use for: paragraphs, list items, default text. The "no styling needed" step.
Secondary body — meta lines, supporting detail, card subtitles.
--font-size-sm · 0.8125rem · use for: card body, meta lines, table cells, hint text under a form field.
Caption · timestamp · token name
--font-size-xs · 0.7rem · use for: timestamps, footer build stamps, token-name labels, sitemap path captions — anything supportive that should recede.

Spacing — pick one per rhythm

Six steps. The ramp is geometric, not linear — don't compute a between-step value. Reach for the named step that fits the rhythm of the surrounding context.

--space-1 4px use for: tight inline gap — dot-to-label, icon-to-text inside a chip.
--space-2 8px use for: chip-internal padding, sibling gap inside a row, badge-to-label spacing.
--space-3 12px use for: list-row to list-row, default inline form-field gap, between siblings in a card.
--space-4 16px use for: card-internal padding, form-row gap, grid-cell gap on dense grids.
--space-5 24px use for: section-to-section gap, default .canon-main gutter, footer padding.
--space-6 32px use for: top-level page padding, the gap between the major sections of a page (.canon-main).

Do this / not that

One pair per concern. Read across — the left column is the canonical move; the right column is the failure mode that appears in the wild when an author skips the rule.

Mode — pick the surface's job, not the brand

Do

A live fleet dashboard ships <html data-mode="operate">. The blue accent + amber warning are part of the operate palette and read across every status row.

Not that

"Our brand is green so the dashboard is data-mode="ship"." Ship is for release surfaces; on a live-state board the green accent collides with --ok and the operator can't read the difference between healthy and emphasis.

Status — bind to condition, not to layout

Do

The "service healthy" badge is background: var(--ok-soft); color: var(--ok). The colour describes the condition; switching to ship mode does not change it.

Not that

The healthy badge is background: var(--accent-soft); color: var(--accent) because "it looked right in home mode". On a operate-mode page the badge turns blue and stops reading as success.

Status — never ≠ failing

Do

An archived project shows <span class="status-never">archived</span>. The desaturated grey reads as "no observation", not as "this is broken".

Not that

An archived project shows status-bad because "we haven't seen it in a while". Red triggers operator attention for an outage that isn't happening; the right token is --never.

Typography — one step per role

Do

Page hero <h1> uses var(--font-size-h1); section <h2> uses var(--font-size-h2); card sub-heading uses var(--font-size-lg).

Not that

font-size: 1.35rem "because the design spec said so". The canon ramp covers it; computing a between-step size silently breaks the vertical-rhythm contract every other canon page already holds.

Spacing — named step, not arithmetic

Do

Section-to-section gap uses gap: var(--space-5); card-internal padding uses padding: var(--space-4).

Not that

margin-top: 18px because it "looked right". 18px isn't in the ramp; the next canon-styled component dropped in below will mis-align with everything around it. Pick --space-3 (12px) or --space-4 (16px) and live with one of them.