main character

design tokens · 3 ramps · 19 color roles · 2 families · 8 type steps · 8 space steps · 5 radii · 2 motion
source: static/css/tokens.css

Tokens

Every token the app is built from, rendered live. Colour comes in three tiers: ramps hold the only hex values, roles say what a colour is for and point at ramp steps, and a few component tokens point at roles. Dark is the default palette; light points the same roles at other steps, not a separate design. Two font families, one motion idiom. Nothing here is proposed: it is what tokens.css already says.

Color

Nineteen roles, named --{bg, text, fill, border, focus}-{role}. CSS uses only these, never a ramp step. Each points at a step of the ramps: dark applies when nothing else is set; light applies when the OS prefers it or data-theme="light" is pinned on <html>. Contrast is against the page (text and rules) or under --text-on-accent (fills); AA for text is 4.5:1. In Figma they are the Semantic collection, each an alias to its step.

role · job
dark (default)
light
you · september 1, 2026

Wrote until the lamp was the only light left on.

companion

That is the second night this week you stayed with it.

31 entries · 49 entitiessavedcould not reach the model
you · september 1, 2026

Wrote until the lamp was the only light left on.

companion

That is the second night this week you stayed with it.

31 entries · 49 entitiessavedcould not reach the model

Component tokens, only where a component needs a value its role doesn't give: --toggle-on is --fill-accent in both themes (light used to take the olive muted accent), and --card-thumb-hover is --bg-muted mixed 10% toward --fill-accent in dark, --bg-page in light. --modal-scrim, behind an open modal, is --bg-page at 75%, so it dims toward the page colour in either theme. Shadows are four whole box-shadows, the same in both themes: --shadow-sm (tooltip, settings popover), --shadow-md (cost panel), --shadow-lg (popover menu), --shadow-xl (the nav sheet).

platform, not ours Chrome's own colours, which the select and checkbox pages draw because the page can't style them. Sampled on Windows; tokens in design.css only, so the drawings and Figma's Platform collection follow the theme.
Ramps

Three hues, built in OKLCH so the steps look evenly spaced: umber for every background, text and rule, amber for the lamp, rust for danger. These are the only hex values in the palette. Each dark value is a step exactly as it was before the ramps (2026-10), so dark looks the same; the steps between them are interpolated. Light takes the light end of the same ramps. Its neutrals sit on steps or within a just-noticeable difference of one (text and hairlines moved by less than that), and its accents were re-picked from amber, which retired the olive #827020: --text-accent is amber-700 (6.0:1, was #9c6021 at 4.8:1) and --text-accent-muted amber-600, the same step in both themes (4.7:1 in light, was 4.6:1). amber-600 is duller than its neighbours because dark's muted accent, #8a6a44, is anchored there. A new hue gets its own hue-named ramp beside these. In Figma they are the Primitives collection, hidden from the pickers.

Typography

Two families, no third. Serif is writing, yours and the companion's. Condensed sans is the machinery around it: buttons, labels, nav, meta.

--font-body
'Old Standard TT', Georgia, 'Times New Roman', serif · self-hosted · 400, 400 italic, 700

After work, Jordan met Mika for a run at Greenwood Park.

main character — the wordmark is this face, italic, in accent

Bold is reserved for entry titles and category names.

Journal entries, companion replies, help prose, AI-written summaries: anything meant to read as writing, even when a machine wrote it.
--font-ui
'CMU Sans Demi Condensed', system-ui, sans-serif · self-hosted · 400–600

write · ask · search · entities · categories

save entry   send   reflect   detect patterns

july 30, 2026 · updating memory

Every button, label, nav item, status line, chip and meta line. The tell for "this is interface, not journal content."
step · covers
--font-ui
--font-body
body prose17px / 1.65 · literal, not on the scale

Here's what I notice you didn't: on 8/3, the recovery cost you a sick day. This time you went to work, sat through the meetings, and still made it to Groundwork after. You're not doing the same loop, you're doing a tighter one.

Set on body directly. Entries and companion replies keep this size; do not swap it for --font-base.
Spacing

Eight steps, chosen by frequency: every step is a value the app already used, nothing was rounded. The long tail of one-off nudges stays literal. Column horizontal padding on every screen is clamp(1rem, 3vw, 1.5rem).

Radius

Three tiers: small controls, default components, pill and circle. Rendered at real component height (2.2rem); at that size 8–10px reads rounder than the number suggests. That is correct, not drift.

left literal on purpose 4px · settings selects and inputs, help code 12px · every content card: pattern, dream, triage, compact composer, search box
Motion

One idiom: a slow breathing fade, standing in for "something is happening, wait." No spinners, no skeletons. New async states reuse this.

lamp-pulse1.6s ease-in-out infinite · opacity .25 ↔ 1
companion
···
.msg.thinking::after: the pending reply, before the companion answers.
updating memory
·saved the entry
·tagged entities
…refreshing weekly arc
·detecting patterns
·writing summary
Pending steps sit at .5 opacity; running and done are full, differing only by mark.
One hover fade: --dur-hover .25s ease, on the item card's visual (background to --card-thumb-hover) and title (color to --text-accent). The only other transition is a one-off transform .15s ease on the help caret.