Files
Keysat 833d0235f9 Reconcile DESIGN.md debt note: admin SPA can't @import (rust-embed)
The palette-consolidation task was dropped during the 2026-06-18 adjudication
because the rust-embedded admin SPA can't @import at runtime, so consolidation
there is a verbatim re-copy that removes no duplication. Update the §9 debt note
accordingly and drop the now-stale ROADMAP pointer.
2026-06-18 08:31:18 -05:00

8.3 KiB
Raw Permalink Blame History

project, tagline, source, tokens, canonical_css, last_distilled
project tagline source tokens canonical_css last_distilled
keysat Software licensing for Bitcoin creators design/_imports/2026-06-16-claude-design-system/ (Claude Design output, May 2025) design/tokens.tokens.json design/brand/palette.css 2026-06-16

Keysat — design contract

The durable, vendor-neutral brand brief. Any agent building or changing a user-facing surface (the marketing landing, the docs site, the creator admin SPA) reads this and design/tokens.tokens.json first and conforms to them. Token values live in the tokens file; this document is the intent and the rules. Distilled from a prior Claude Design system (now in design/_imports/).

1. Visual theme

Navy ink on cream paper, with a gold accent that whispers. The reference objects are a certificate of authenticity, a vault deed, a hand-numbered print — classical trust signaling crossed with modern indie-software practicality. Restrained, archival, precise; modern in interaction, classical in composition. The identity is anchored by the logo: a deep-navy key crossing a Bitcoin "B" bow, on cream paper with a gold inner border. The brand reads as printed, not liquid — solid surfaces over glass and gradients.

2. Color palette

Values in tokens.tokens.json. Roles:

  • Navy is the primary brand color. navy-800 (#1E3A5F) is the wordmark color and dominant ink — primary buttons, headings, key chrome. Full scale navy-950 → navy-50.
  • Cream is the page background. cream-100 (#F5F1E8) default; cream-50 (#FBF9F2) for elevated paper. Pure white (#FFFFFF) is reserved for forms, tables, and code blocks where contrast matters.
  • Gold (gold-500, #BFA068) is the accent, used sparingly — eyebrow labels, dividers, the inner stroke of premium cards, a verified-badge highlight. Never a primary button color.
  • Ink scale (ink-900 → ink-300) handles body text, secondary copy, disabled states.
  • Semantic: success #2D7A5F, warning #B8861F, danger #B23A3A, info = navy-700, each with a tinted -bg.
  • Borders are alpha navy, not solid lines: border-1 12%, border-2 20%, border-3 35%.

3. Typography

  • Display — Manrope (font-display): geometric sans, mirrors the wordmark. h1h4, large numerals, the wordmark. Weights 400700 (500 for h1/h2, 600 for h3/h4). Note: the original design-system README named "Archivo" as a placeholder substitution, but the shipped CSS and every live surface use Manrope — Manrope is canonical. If a licensed display face is ever supplied, swap font.display in the tokens and remove the Google Fonts import.
  • Body — Inter (font-body): humanist sans for prose, UI labels, form fields. Stylistic sets ss01 + cv11.
  • Mono — JetBrains Mono (font-mono): license keys, code samples, API responses, tx IDs.
  • Type scale is the fs-* tokens (display-xl clamp 5688px down to meta 12px). Headings track tight (-0.02em); eyebrows track wide (0.18em), uppercase.
  • Casing: sentence case for buttons/menus/headings ("Create a license"); ALL CAPS + wide tracking only for eyebrow labels above sections, sparingly. Proper nouns capitalized (Keysat, Start9, StartOS, BTCPay, Bitcoin, Lightning, Ed25519).
  • Identifiers: license keys monospace, hyphen-grouped (KS-9F2A-7C41-XK22-6D8E); keys/ hashes ellipsized middle (mz7q8…h3k2p); amounts default to sats under 0.01 BTC.

4. Component styling

  • Buttons — radius r-md (8px). Primary: navy-800 bg, cream-50 text; hover navy-900, press navy-950 + 1px translate-down (no scale). Secondary: cream-50 bg, alpha-navy border; hover cream-200. Ghost: transparent; hover rgba(14,31,51,0.05). Gold is a text/border treatment only, never a primary button fill. Danger: red text + faint red border.
  • Cards — radius r-lg (12px), on cream with a hairline border-1 and shadow-sm. Premium/featured cards get a 1px gold inner stroke (gold-500) + shadow-md.
  • Badges — pill (r-pill), tinted semantic bg + matching text; gold/neutral = transparent with a gold border.
  • Forms — white bg, alpha-navy border, radius ~7px; focus = navy border + ring-focus halo. Monospace variant for keys.
  • Code blocksnavy-950 bg, cream-50 text, r-lg, JetBrains Mono; gold/cream syntax.
  • Icons — Lucide, stroke 1.75px, 16/20/24px. No emoji in product UI. No PNG icons (the logo mark is SVG; only the source thumbnail is PNG). The logo mark is never recolored — navy, or cream on dark surfaces.

5. Layout

  • 4px base grid, spacing tokens sp-1 (4px) → sp-12 (128px). Use the scale; don't mint magic numbers.
  • Marketing pages breathe — sections often sp-11 (96px) apart. Dashboard density is moderate: table rows ~52px, card padding sp-6 (24px).
  • Max content width on marketing ~1200px; reading width for prose/docs ~680px.
  • Backgrounds are cream with a subtle grain (the paper-texture utility — two radial-dot grids at ~2.5% opacity), never flat color. Section bands alternate cream → cream-200 → cream-50 → navy-950 (dark CTAs/footers).

6. Depth / elevation

A paper-shadow system, not a glassy one. shadow-xs/sm for resting cards; shadow-md for elevated/premium cards; shadow-lg for popovers/menus; shadow-xl for modals/command palettes. shadow-inset gives buttons subtle paper relief. Elevation comes from shadow, not heavy borders. Transparency/blur is rare — acceptable only for the sticky marketing header (blur(12px) over rgba(245,241,232,0.85)) and the modal scrim (rgba(14,31,51,0.55)).

7. Do's and don'ts

Do

  • Lead copy with what the creator owns — the signing key, the customer list, the payment rails. Sovereignty-first is the brand's center of gravity.
  • Keep gold rare and accenting; keep motion quiet (200ms standard, 120ms hover).
  • Use solid surfaces, restrained radii, hairline alpha borders, the paper grain.
  • Link a one-sentence definition the first time a term appears (Ed25519, BTCPay webhook, .s9pk).

Don't

  • No hype words: revolutionary, seamless, unlock, supercharge, leverage, ecosystem, journey, paradigm, game-changing.
  • No emoji in product UI; no PNG icons; no Bitcoin orange in the UI (navy/cream stands alone); no blue/purple gradients, no glassmorphism.
  • Gold is never a primary button fill. Radii never exceed ~18px (r-xl) for surfaces — no 24px+ rounding (reads as a consumer fintech app, which Keysat is not).
  • No spring physics, no scale-up on hover (cards move at most 1px; buttons darken, not grow).
  • Never remove focus rings.

8. Responsive behavior

Breakpoints in use: 980px (grids collapse), 720px (sidebar → slide-in drawer), 640px (phone: tighter chrome, single column). Container padding steps 32px desktop → 20px tablet → 14px phone. Marketing is full-width hero + stacked sections; docs is a 3-column (sidebar | prose | TOC) collapsing to single column at 980px; admin is a 240px sticky sidebar

  • main, sidebar drawering at 720px.

9. Agent prompt guide

When building or changing a Keysat UI:

  • Pull every color, size, space, radius, and shadow from design/tokens.tokens.json (or a CSS custom property derived from it — see design/brand/palette.css). Do not hardcode hex or px values that bypass the scale.
  • Match the existing surface you're editing (landing / docs / admin) — they share the token set; keep them consistent rather than introducing a new look.
  • Default to navy primary buttons, cream pages, gold-as-accent-only, paper shadows, Lucide icons, sentence-case labels, no emoji.
  • If a needed value genuinely isn't in the tokens, add it to the tokens file (and ideally palette.css) rather than inlining a one-off — keep the contract the single source of truth.
  • Known debt: the three surfaces inline their own copy of the variables. For landing and docs (static files) prefer importing design/brand/palette.css when you touch them. The admin SPA is rust-embedded and cannot @import at runtime, so its copy stays inline by necessity — keep it a verbatim copy of palette.css, don't let it drift. (A blanket "consolidate all three onto palette.css" task was adjudicated and dropped 2026-06-18 for exactly this reason — it can't remove the admin duplication it targets.)