Design system

One human, many themes.

The vocabulary behind the landing page. Every colour, size, radius, shadow and duration below is read live from shared/tokens.css, so this page cannot drift from the site.

Four ideas

Night and paper

The person’s world is dark and lit by persona colour. The business world is daylight paper. Same token names, two sets of values: components never know which theme they are in.

The card and the door

A persona is a card you hold close to your chest (.pcard), fanned like a hand. A door (.arch) is where a business stands, and the page opens like one. Never a dome on a persona: it reads as a gravestone.

Three disclosure glyphs

○ none, ◐ coarse, ● precise. The same marks drive the dial, the fact field, the legend and the console tags, so a share level always looks the same.

Open, focus, fan

Three signature moves: a thing opens, a value resolves from blur to sharp, a retinue re-orders. Everything else is quiet. Reduced motion keeps every state, drops the travel.

Colour

Semantic tokens, resolved per theme. The ratio on each chip is WCAG contrast of that token as text against the theme’s --bg (AA needs 4.5 for body text, 3 for large text and graphics).

Night default

Paper [data-theme="paper"]

Persona colours

Each business console owns one colour (shared/usecases.js). On night it is lifted to a luminous tone (--p-lit, same hue and chroma, lightness .78); on paper it is used as is. Set --p on any element, or on :root to retarget the whole page’s light.

Disclosure semantics

PreciseCoarseNonePersonaNeutral

Type

Instrument Serif for voice (display and headings, italic for the one idea in a line), Inter for reading, the system monospace for receipts, labels and anything a machine said. Fluid sizes use clamp(); there are no breakpoint-only type sizes.

--fs-display

Door

--fs-h1

One human. Many personas.

--fs-h2

Share the answer, not the data.

--fs-h3

You wear a persona

--fs-lede

Businesses ask your personas, you decide what each one shares, and every answer comes with a receipt.

--fs-base

Body copy sits at 16px on a 1.6 line height, in Inter, with text-wrap: pretty so paragraphs end well.

--fs-micro / mono

How it works

Receipt rcp_4e1c written to both ledgers.

Space, shape and depth

Space

4px base, half-step scale.

Radius

Soft, never sharp; pill for anything you press.

Depth

Highlight edge plus a long, cool shadow.

The persona card

.pcard is a rounded card (--r-2xl, width --card-w) lit by --p. Add .edge for the lit rim. Several cards fan from a pivot below, like a hand; the front one is live. Never put a dome on a persona: a dome on a slab reads as a gravestone.

.pcard.edge
--p: any
.pcard

The door

.arch sets the top corners to half the width (--arch-w). It is for openings only: the way into the business side and the doorways of the finale. Doors nest (echo rings) and open (@keyframes rt-open).

.arch.edge
.arch

Motion

Durations and easings are tokens; reduced motion collapses them to 1ms, so a state change is still a state change. Press replay.

Open

A door opens. --ease-open, --dur-stage.

Focus

A value resolves from blur to sharp. .focus-in for entrances; .focus-swap when a value changes in place, so the old one is never removed first. --ease-settle, --blur-focus.

$200–250k

Fan

The hand re-orders on a spring. --ease-spring.

TokenValueUse

Components

Shown in both themes. State lives in ARIA (aria-selected, aria-checked, aria-pressed, aria-expanded), so a component’s look and its accessibility cannot disagree. Tab through them.

Using it

Add a page

<link rel="stylesheet" href="shared/tokens.css">
<link rel="stylesheet" href="shared/components.css">
<link rel="stylesheet" href="my-page.css">   /* @layer page { … } */

Tokens first, then components, then the page’s own layer. Reference tokens, never hex.

Switch to paper

<section data-theme="paper">
  …every component re-themes
</section>

Use paper for anything a business operates; night for anything a person owns.

Colour by persona

<a class="chip" style="--p:#b4531f">
  Tenant
</a>
/* :root { --p: … } retargets the light */

One variable drives dot, rim, glow and tint, in either theme.

Rules we hold ourselves to

  • Contrast. Body text 4.5:1 or better in both themes. --dim is decoration only; small text uses --soft or stronger.
  • Focus. Every control shows a 2px ring (--focus) on keyboard focus; never remove it.
  • Targets. Primary controls are 44px; dense controls (the dial) are 30px and spaced.
  • Motion. Nothing auto-plays for more than one lap, auto-play is pausable, and prefers-reduced-motion removes travel, blur and tilt.
  • Words. One word for what a person wears: “persona”. The product name comes from shared/brand.js, never from the markup.
  • Honesty. Anything simulated says so, once, quietly: an “illustrative demo” note, not a warning.

The person’s console and the business consoles still carry their own stylesheets. tokens.css ships compatibility aliases (--panel, --line2, --mint …) so they can adopt it later without touching a rule.