← all components

Primitives & controls

The token system and the small parts everything else is assembled from. Two things are worth knowing before you read the rest: Scry ships no icon library and no webfont — the icons are 20 hand-drawn 24×24 SVGs and the type is the system stack — and every token is theme-scoped and runtime-writable, which is why the accent picker recolours the whole application on the next paint.

00

Design tokens

One :root block, one [data-theme='light'] override, and a settings store that writes accent and font-scale over the top at runtime. The light theme is hand-tuned rather than inverted — "paper with water in it" — which is why its stage hues are entirely different values, not the dark ones darkened.

🎨
Surface & ink
Five surface steps from --bg-deep up to --panel-3, two line weights, and a five-step ink ramp. The --faint value was darkened at 6.69.36 because micro-labels measured 2.71:1 on paper against a 3:1 requirement; they now measure 3.85:1.
ui/src/styles/tokens.css
Dark · surfaces
--bg-deep --bg --panel --panel-2 --panel-3 --line
Dark · ink ramp
--ink--ink-dim--muted--muted-2--faint
Light · surfaces (hand-tuned, not inverted)
--bg-deep --bg --panel --panel-2 --panel-3
🌈
Stage hues
Six hues seeded from the original layered-systems map — capture, process, storage, representation, retrieval, use — reused throughout as semantic colour: --store doubles as "active", --cap as "warn" and as the lens amber, --ret as the cyan on system entities and citation links.
ui/src/styles/tokens.css · stage / type hues
Dark
--cap · warn --proc --store · ok --rep --ret --use --danger
Light · same family, re-derived for paper
--cap --proc --store --rep --ret --use
🅰️
Type scale
Eight sizes, every one written as calc(px * var(--font-scale)) — a conversion done deliberately at 1.2.8 so that a base-size control could exist at all. Three stacks: a text face, a display face, and a mono. No font files ship; the app resolves the system stack, and so does this page.
ui/src/styles/tokens.css · --t-xs … --t-3xl
Scale at 1.00×
Scry the Well --t-3xl · 42
Coverage and depth --t-2xl · 30
The ledger rooms --t-xl · 22
Depth is age --t-lg · 17
Brightness is recency --t-md · 14.5
Size is salience --t-base · 13
chunks in mimir.chunk --t-sm · 11.5
Eyebrow · --t-xs · 10.5
📏
Spacing & radii
A nine-step 4px spacing scale and a five-step radius scale (6 / 10 / 16 / 22 / pill). Both are used consistently across the app — there is no component in Scry hardcoding its own radius, which is unusual enough to be worth stating.
ui/src/styles/tokens.css · --s1…--s9 · --r-sm…--r-pill
Spacing · 4 8 12 16 24 32 48 64 96
s1 s2 s3 s4 s5 s6 s7 s8 s9
Radii · 6 10 16 22 pill
r-sm r-md r-lg r-xl r-pill
✒️
Icon set
Twenty icons, all hand-drawn on a 24×24 grid at 1.4 stroke, round caps and joins, with selective opacity on secondary strokes to give depth without a second colour. There is no icon library dependency. The Well, Constellation, Capture, Digest and Stats glyphs are drawn to carry the metaphor — a well mouth with ripples, a settling atom, things rising back up.
ui/src/components/Icons.tsx
All twenty
Well Constellation Capture Digest Stats Registry Sources Settings Search ArrowRight Link Chevron Close Check Sink Rise Plus Mic Paperclip Text
01

Chips, pills & badges

Four badge families, each with a distinct job so the eye can tell them apart without reading: chips are facets you can toggle, pills are trajectory status, the lens is a governance receipt, and the classification badge is an access-control fact.

🔘
Chip
The workhorse. A pill with an optional 6px colour dot and an optional trailing count. The on state takes accent ink, an accent border, an accent-soft fill and an outward glow. Used for facets, filters, suggestions, statuses and lens toggles — one component doing six jobs, which is why its dot slot exists.
ui/src/styles/global.css · .chip
Plain
internal
With dot & count
Selected
Dashed · an action, not a filter
Trajectory pill
Uppercase, letter-spaced, with a dot in currentColor and a border of the same — so one colour declaration paints the whole badge. The values are Sprawler's trajectory vocabulary: a fact does not merely have a state, it has a direction.
ui/src/styles/global.css · .pill
All statuses
activestalledreversedsupersededopenanswered
⌨️
Key badge
Mono, hairline-bordered, used inline in prose and inside buttons. Scry is keyboard-first, so hotkeys are shown wherever the action is rather than hidden in a help modal — the rail tooltips, the capture button, the Settings table and the command palette rows all carry them.
ui/src/styles/components/controls.css · .kbd
Inline and in a button
/cescCtrl / ⌘ + Pshift + enter
02

Controls

Everything in Settings is applied as a CSS custom property and persisted to localStorage with merge-on-load, so adding a new setting never wipes a stored profile. Changes land on the next paint — there is no save button anywhere in Scry.

🔲
Buttons
Two weights and no more: a ghost outline for secondary actions and a filled accent for the one primary action a surface has. Plus cap-lane, the quieter variant used inside the capture overlay's footer where three lanes need equal weight.
ui/src/styles/components/controls.css
Ghost · primary · lane · disabled
Segmented control
Two options, one selected. Used for exactly one thing — the theme — because a third option would make it a select. The label copy underneath is the product's own framing: "Dark is the well at depth; light is the same water by day."
ui/src/views/Settings.tsx · .seg
Dark selected
Light selected
Switch
A proper role="switch" with aria-checked, not a styled checkbox. Drives reduced motion, which is honoured in three separate places: the CSS token layer, the ambient field, and the graph engine's drift — the last of which skips under reduced motion rather than merely shortening.
ui/src/views/Settings.tsx · .switch
Off
On
🎚️
Range slider
Used for base font size (0.85× to 1.35×) and for all six graph force parameters. The current value always sits beside the track in mono, formatted per-control — 62px, 1.00×, or the literal string all labels when the text-fade threshold hits zero.
ui/src/views/Settings.tsx · GraphControls.tsx · Slider
Settings style
1.15×
Graph-controls style
🌟
Accent picker
Seven named presets — Wellwater, Deep current, Bioluminescence, Nightshade, Ember, Coral, Lamplight — plus a native colour input for anything else. The picked value is darkened for light mode by a derivation step, because an accent tuned to glow on black is illegible on paper.
ui/src/settings/types.ts · ACCENT_PRESETS
Seven presets + custom
Settings row
Label plus an italic one-line rationale on the left, control on the right. The rationale is never a restatement of the label — it says what the setting is for, which is the same discipline the purpose copy on this site follows.
ui/src/views/Settings.tsx · .set-row
Two rows
Accent colourDrives every glow, focus ring and lit edge.
Reduced motionStills the drift, the descent rings and the ambient field.
🗝️
Hotkeys table
Thirteen bindings with their scope. rebinding is phase 2 — the note above the table says so in the product's own words: "Rebinding is not wired yet — the table below is the current, fixed map." A fixed map stated honestly beats a settings screen that implies configurability it does not have.
ui/src/views/Settings.tsx · HOTKEYS
Global bindings
KeyActionScope
/Focus the command bar (Ask the Well)global
cCapture a thoughtglobal
Ctrl / ⌘ + PCommand paletteglobal
escClose the topmost layer — palette, capture, dossierglobal
gGo to Constellationglobal
shift + enterNew line inside a capturecapture
ℹ️
About block
Four facts, and the last two are the reason this block exists: the data source is stated as MockProvider — seeded corpus, and the serving core as not built — provider seam ready. An app that tells you it is not wired to anything yet is doing something most demos do not.
ui/src/views/Settings.tsx · .about
Current
version
6.69.36 · pondo semver
data source
MockProvider — seeded corpus
views
8
serving core
not built — provider seam ready