diff --git a/AGENTS.md b/AGENTS.md
index 3a9d95a..20f3b74 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -25,6 +25,7 @@ its guide** — see the index below.
- Before building, bumping the version, or editing the StartOS wrapper, read `docs/guides/startos-packaging.md`.
- Before editing the admin SPA (`web/index.html`), read `docs/guides/admin-ui.md`.
- Before editing public site/docs copy, read `docs/guides/website-copy.md`.
+- **Before building or changing any user-facing UI (landing, docs, admin SPA), read `design/DESIGN.md` and `design/tokens.tokens.json` and conform to them** — the brand contract; pull colors/type/space/radii/shadows from the tokens, never hardcode off-scale values.
- Before adding/altering tests or relying on lint/CI, read `docs/guides/testing.md`.
## Build / test / run (quick ref)
@@ -50,7 +51,7 @@ licensing-service-startos/ daemon + StartOS wrapper (s9pk package source)
keysat-xyz-landing/ keysat-docs/ keysat-registry-landing/ public sites → guides/website-copy.md
licensing-client-{rust,ts,python,go}/ the four SDK source repos
activate-license-template/ Tauri desktop template for license activation
-keysat-design-system/ design tokens / brand assets
+design/ design contract (DESIGN.md + tokens.tokens.json) + brand/ assets; original Claude Design system archived in design/_imports/
plans/ design specs (multi-provider-payment-model.md, keysat-smtp-emails.md)
tests/crosscheck/ cross-language LIC1 verifier → guides/crypto-wire-format.md
```
diff --git a/ROADMAP.md b/ROADMAP.md
index 9b622a4..d12e6ff 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -24,3 +24,36 @@ Longer-term backlog. Near-term state lives in `AGENTS.md` → Current state.
- Re-test `KEYSAT_INTEGRATION.md` against a fresh downstream app to confirm a clean one-shot SDK integration.
- End-to-end Zaprite sandbox pass on the multi-merchant-profile webhook routing before relying on it in production.
+
+## Design (contract conformance)
+
+The brand contract now lives in `design/DESIGN.md` + `design/tokens.tokens.json` (distilled
+2026-06-16 from the prior Claude Design system, now archived in `design/_imports/`). A
+`design-checker` audit (2026-06-16) found high fidelity overall, with these items where the
+**code contradicts the contract's stated rules** or bypasses the token scale:
+
+**Blockers (code violates a named "never" rule):**
+- Gold used as an actionable *fill* (contract: gold is accent/border only, never a fill).
+ (a) admin SPA `.featured-pill-toggle.on` → `web/index.html:418`; (b) admin sidebar
+ upgrade CTA `#tier-banner-cta` → `web/index.html:537-542`. Fix to navy-fill or
+ gold-border/text.
+- Primary buy CTA uses pill radius `999px` (contract: buttons are `r-md` 8px; pill is
+ badges-only) — `keysat-xyz-landing/index.html:384-385`. Set to 8px.
+
+**Structural (headline):**
+- All four surfaces inline their own copy of the CSS variables instead of importing the
+ canonical `design/brand/palette.css` (landing :33-56, registry :11-22, docs.css :7-21,
+ admin :9-25). Copies are currently exact but one edit from drift. Consolidate onto
+ `palette.css`.
+
+**Token gaps / drift (decide: tokenize the as-built value, or snap to an existing token):**
+- `14px` card radius used throughout the marketing landing — not a token (between `r-lg` 12
+ and `r-xl` 18). Snap to a token or add one.
+- Wordmark letter-spacing is `0.30em` (landing) vs `0.28em` (docs/admin) and has no token —
+ pick one value, add a `letterSpacing.wordmark` token.
+- Semantic badge *text* colors (`#205c47`/`#7a5814`/`#8a2828`) are darker one-offs with no
+ token — add `semantic.*-text` tokens or reference existing ones.
+- Syntax-highlight colors hardcoded as hex (`#d4b985`=gold-400, `#a6b7cf`=navy-300) — switch
+ to `var()`. One admin hex `#f6f1e7` isn't a token (closest cream-50/100) — reconcile.
+- Sticky-header backdrop on docs/admin (`blur(10px)`/`blur(8px)`) diverges from the contract's
+ `blur(12px)` — align if a single header treatment is wanted.
diff --git a/design/DESIGN.md b/design/DESIGN.md
new file mode 100644
index 0000000..2daf32d
--- /dev/null
+++ b/design/DESIGN.md
@@ -0,0 +1,142 @@
+---
+project: keysat
+tagline: Software licensing for Bitcoin creators
+source: design/_imports/2026-06-16-claude-design-system/ (Claude Design output, May 2025)
+tokens: design/tokens.tokens.json
+canonical_css: design/brand/palette.css
+last_distilled: 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. h1–h4, large
+ numerals, the wordmark. Weights 400–700 (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 56–88px 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 blocks** — `navy-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 (see ROADMAP): the three surfaces currently inline their own copy of the
+ variables. Prefer importing `design/brand/palette.css`; when you touch a surface, move it
+ toward that shared source rather than perpetuating a private copy.
diff --git a/keysat-design-system/README.md b/design/_imports/2026-06-16-claude-design-system/README.md
similarity index 100%
rename from keysat-design-system/README.md
rename to design/_imports/2026-06-16-claude-design-system/README.md
diff --git a/keysat-design-system/SKILL.md b/design/_imports/2026-06-16-claude-design-system/SKILL.md
similarity index 100%
rename from keysat-design-system/SKILL.md
rename to design/_imports/2026-06-16-claude-design-system/SKILL.md
diff --git a/keysat-design-system/assets/bitcoin-mark.svg b/design/_imports/2026-06-16-claude-design-system/assets/bitcoin-mark.svg
similarity index 100%
rename from keysat-design-system/assets/bitcoin-mark.svg
rename to design/_imports/2026-06-16-claude-design-system/assets/bitcoin-mark.svg
diff --git a/keysat-design-system/assets/favicon.svg b/design/_imports/2026-06-16-claude-design-system/assets/favicon.svg
similarity index 100%
rename from keysat-design-system/assets/favicon.svg
rename to design/_imports/2026-06-16-claude-design-system/assets/favicon.svg
diff --git a/keysat-design-system/assets/keysat-lockup.svg b/design/_imports/2026-06-16-claude-design-system/assets/keysat-lockup.svg
similarity index 100%
rename from keysat-design-system/assets/keysat-lockup.svg
rename to design/_imports/2026-06-16-claude-design-system/assets/keysat-lockup.svg
diff --git a/keysat-design-system/assets/keysat-mark-mono.svg b/design/_imports/2026-06-16-claude-design-system/assets/keysat-mark-mono.svg
similarity index 100%
rename from keysat-design-system/assets/keysat-mark-mono.svg
rename to design/_imports/2026-06-16-claude-design-system/assets/keysat-mark-mono.svg
diff --git a/keysat-design-system/assets/keysat-mark-reverse.svg b/design/_imports/2026-06-16-claude-design-system/assets/keysat-mark-reverse.svg
similarity index 100%
rename from keysat-design-system/assets/keysat-mark-reverse.svg
rename to design/_imports/2026-06-16-claude-design-system/assets/keysat-mark-reverse.svg
diff --git a/keysat-design-system/assets/keysat-mark.svg b/design/_imports/2026-06-16-claude-design-system/assets/keysat-mark.svg
similarity index 100%
rename from keysat-design-system/assets/keysat-mark.svg
rename to design/_imports/2026-06-16-claude-design-system/assets/keysat-mark.svg
diff --git a/keysat-design-system/colors_and_type.css b/design/_imports/2026-06-16-claude-design-system/colors_and_type.css
similarity index 100%
rename from keysat-design-system/colors_and_type.css
rename to design/_imports/2026-06-16-claude-design-system/colors_and_type.css
diff --git a/keysat-design-system/explorations/design-canvas.jsx b/design/_imports/2026-06-16-claude-design-system/explorations/design-canvas.jsx
similarity index 100%
rename from keysat-design-system/explorations/design-canvas.jsx
rename to design/_imports/2026-06-16-claude-design-system/explorations/design-canvas.jsx
diff --git a/keysat-design-system/explorations/logo-directions-v2.html b/design/_imports/2026-06-16-claude-design-system/explorations/logo-directions-v2.html
similarity index 100%
rename from keysat-design-system/explorations/logo-directions-v2.html
rename to design/_imports/2026-06-16-claude-design-system/explorations/logo-directions-v2.html
diff --git a/keysat-design-system/explorations/logo-directions.html b/design/_imports/2026-06-16-claude-design-system/explorations/logo-directions.html
similarity index 100%
rename from keysat-design-system/explorations/logo-directions.html
rename to design/_imports/2026-06-16-claude-design-system/explorations/logo-directions.html
diff --git a/keysat-design-system/explorations/type-directions.html b/design/_imports/2026-06-16-claude-design-system/explorations/type-directions.html
similarity index 100%
rename from keysat-design-system/explorations/type-directions.html
rename to design/_imports/2026-06-16-claude-design-system/explorations/type-directions.html
diff --git a/keysat-design-system/preview/badges.html b/design/_imports/2026-06-16-claude-design-system/preview/badges.html
similarity index 100%
rename from keysat-design-system/preview/badges.html
rename to design/_imports/2026-06-16-claude-design-system/preview/badges.html
diff --git a/keysat-design-system/preview/brand-logo.html b/design/_imports/2026-06-16-claude-design-system/preview/brand-logo.html
similarity index 100%
rename from keysat-design-system/preview/brand-logo.html
rename to design/_imports/2026-06-16-claude-design-system/preview/brand-logo.html
diff --git a/keysat-design-system/preview/buttons.html b/design/_imports/2026-06-16-claude-design-system/preview/buttons.html
similarity index 100%
rename from keysat-design-system/preview/buttons.html
rename to design/_imports/2026-06-16-claude-design-system/preview/buttons.html
diff --git a/keysat-design-system/preview/cards.html b/design/_imports/2026-06-16-claude-design-system/preview/cards.html
similarity index 100%
rename from keysat-design-system/preview/cards.html
rename to design/_imports/2026-06-16-claude-design-system/preview/cards.html
diff --git a/keysat-design-system/preview/colors-cream-gold.html b/design/_imports/2026-06-16-claude-design-system/preview/colors-cream-gold.html
similarity index 100%
rename from keysat-design-system/preview/colors-cream-gold.html
rename to design/_imports/2026-06-16-claude-design-system/preview/colors-cream-gold.html
diff --git a/keysat-design-system/preview/colors-navy.html b/design/_imports/2026-06-16-claude-design-system/preview/colors-navy.html
similarity index 100%
rename from keysat-design-system/preview/colors-navy.html
rename to design/_imports/2026-06-16-claude-design-system/preview/colors-navy.html
diff --git a/keysat-design-system/preview/colors-semantic.html b/design/_imports/2026-06-16-claude-design-system/preview/colors-semantic.html
similarity index 100%
rename from keysat-design-system/preview/colors-semantic.html
rename to design/_imports/2026-06-16-claude-design-system/preview/colors-semantic.html
diff --git a/keysat-design-system/preview/forms.html b/design/_imports/2026-06-16-claude-design-system/preview/forms.html
similarity index 100%
rename from keysat-design-system/preview/forms.html
rename to design/_imports/2026-06-16-claude-design-system/preview/forms.html
diff --git a/keysat-design-system/preview/license-keys.html b/design/_imports/2026-06-16-claude-design-system/preview/license-keys.html
similarity index 100%
rename from keysat-design-system/preview/license-keys.html
rename to design/_imports/2026-06-16-claude-design-system/preview/license-keys.html
diff --git a/keysat-design-system/preview/radii.html b/design/_imports/2026-06-16-claude-design-system/preview/radii.html
similarity index 100%
rename from keysat-design-system/preview/radii.html
rename to design/_imports/2026-06-16-claude-design-system/preview/radii.html
diff --git a/keysat-design-system/preview/shadows.html b/design/_imports/2026-06-16-claude-design-system/preview/shadows.html
similarity index 100%
rename from keysat-design-system/preview/shadows.html
rename to design/_imports/2026-06-16-claude-design-system/preview/shadows.html
diff --git a/keysat-design-system/preview/spacing-scale.html b/design/_imports/2026-06-16-claude-design-system/preview/spacing-scale.html
similarity index 100%
rename from keysat-design-system/preview/spacing-scale.html
rename to design/_imports/2026-06-16-claude-design-system/preview/spacing-scale.html
diff --git a/keysat-design-system/preview/type-body-mono.html b/design/_imports/2026-06-16-claude-design-system/preview/type-body-mono.html
similarity index 100%
rename from keysat-design-system/preview/type-body-mono.html
rename to design/_imports/2026-06-16-claude-design-system/preview/type-body-mono.html
diff --git a/keysat-design-system/preview/type-display.html b/design/_imports/2026-06-16-claude-design-system/preview/type-display.html
similarity index 100%
rename from keysat-design-system/preview/type-display.html
rename to design/_imports/2026-06-16-claude-design-system/preview/type-display.html
diff --git a/keysat-design-system/ui_kits/dashboard/README.md b/design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/README.md
similarity index 100%
rename from keysat-design-system/ui_kits/dashboard/README.md
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/README.md
diff --git a/keysat-design-system/ui_kits/dashboard/dash.css b/design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/dash.css
similarity index 100%
rename from keysat-design-system/ui_kits/dashboard/dash.css
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/dash.css
diff --git a/keysat-design-system/ui_kits/dashboard/index.html b/design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/index.html
similarity index 100%
rename from keysat-design-system/ui_kits/dashboard/index.html
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/index.html
diff --git a/keysat-design-system/ui_kits/dashboard/license-detail.html b/design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/license-detail.html
similarity index 100%
rename from keysat-design-system/ui_kits/dashboard/license-detail.html
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/license-detail.html
diff --git a/keysat-design-system/ui_kits/dashboard/licenses.html b/design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/licenses.html
similarity index 100%
rename from keysat-design-system/ui_kits/dashboard/licenses.html
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/licenses.html
diff --git a/keysat-design-system/ui_kits/dashboard/new-product.html b/design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/new-product.html
similarity index 100%
rename from keysat-design-system/ui_kits/dashboard/new-product.html
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/new-product.html
diff --git a/keysat-design-system/ui_kits/dashboard/signin.html b/design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/signin.html
similarity index 100%
rename from keysat-design-system/ui_kits/dashboard/signin.html
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/dashboard/signin.html
diff --git a/keysat-design-system/ui_kits/docs/README.md b/design/_imports/2026-06-16-claude-design-system/ui_kits/docs/README.md
similarity index 100%
rename from keysat-design-system/ui_kits/docs/README.md
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/docs/README.md
diff --git a/keysat-design-system/ui_kits/docs/index.html b/design/_imports/2026-06-16-claude-design-system/ui_kits/docs/index.html
similarity index 100%
rename from keysat-design-system/ui_kits/docs/index.html
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/docs/index.html
diff --git a/keysat-design-system/ui_kits/marketing/README.md b/design/_imports/2026-06-16-claude-design-system/ui_kits/marketing/README.md
similarity index 100%
rename from keysat-design-system/ui_kits/marketing/README.md
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/marketing/README.md
diff --git a/keysat-design-system/ui_kits/marketing/index.html b/design/_imports/2026-06-16-claude-design-system/ui_kits/marketing/index.html
similarity index 100%
rename from keysat-design-system/ui_kits/marketing/index.html
rename to design/_imports/2026-06-16-claude-design-system/ui_kits/marketing/index.html
diff --git a/keysat-design-system/uploads/index.html b/design/_imports/2026-06-16-claude-design-system/uploads/index.html
similarity index 100%
rename from keysat-design-system/uploads/index.html
rename to design/_imports/2026-06-16-claude-design-system/uploads/index.html
diff --git a/keysat-design-system/uploads/keysat-thumbnail.png b/design/_imports/2026-06-16-claude-design-system/uploads/keysat-thumbnail.png
similarity index 100%
rename from keysat-design-system/uploads/keysat-thumbnail.png
rename to design/_imports/2026-06-16-claude-design-system/uploads/keysat-thumbnail.png
diff --git a/design/brand/bitcoin-mark.svg b/design/brand/bitcoin-mark.svg
new file mode 100644
index 0000000..cd43f29
--- /dev/null
+++ b/design/brand/bitcoin-mark.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/design/brand/favicon.svg b/design/brand/favicon.svg
new file mode 100644
index 0000000..31f1365
--- /dev/null
+++ b/design/brand/favicon.svg
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/design/brand/keysat-lockup.svg b/design/brand/keysat-lockup.svg
new file mode 100644
index 0000000..41d46c7
--- /dev/null
+++ b/design/brand/keysat-lockup.svg
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/design/brand/keysat-mark-mono.svg b/design/brand/keysat-mark-mono.svg
new file mode 100644
index 0000000..472cb08
--- /dev/null
+++ b/design/brand/keysat-mark-mono.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/design/brand/keysat-mark-reverse.svg b/design/brand/keysat-mark-reverse.svg
new file mode 100644
index 0000000..0880e15
--- /dev/null
+++ b/design/brand/keysat-mark-reverse.svg
@@ -0,0 +1,12 @@
+
\ No newline at end of file
diff --git a/design/brand/keysat-mark.svg b/design/brand/keysat-mark.svg
new file mode 100644
index 0000000..826dea1
--- /dev/null
+++ b/design/brand/keysat-mark.svg
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/design/brand/palette.css b/design/brand/palette.css
new file mode 100644
index 0000000..25f197b
--- /dev/null
+++ b/design/brand/palette.css
@@ -0,0 +1,285 @@
+/* ============================================================
+ Keysat — palette.css (CANONICAL design tokens as CSS custom properties)
+ "Software Licensing for Bitcoin Creators"
+ Navy + cream, paper texture, classical type.
+
+ Single canonical stylesheet, derived from design/tokens.tokens.json.
+ Surfaces (landing, docs, admin SPA) should @import or inline THIS file
+ rather than keep private copies — see the "shared token source" item in
+ ROADMAP.md. Keep this and the tokens JSON in sync; never fork a one-off copy.
+ ============================================================ */
+
+@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
+
+:root {
+ /* ---------- Brand Colors ---------- */
+ /* Primary navy — pulled from the wordmark */
+ --navy-950: #0E1F33;
+ --navy-900: #142A47;
+ --navy-800: #1E3A5F; /* core brand navy */
+ --navy-700: #2A4A75;
+ --navy-600: #3A5C8A;
+ --navy-500: #5074A1;
+ --navy-400: #7892B8;
+ --navy-300: #A6B7CF;
+ --navy-200: #CBD5E2;
+ --navy-100: #E4EAF1;
+ --navy-50: #F2F5F9;
+
+ /* Cream / paper — the background tone of the logo card */
+ --cream-50: #FBF9F2;
+ --cream-100: #F5F1E8; /* core cream */
+ --cream-200: #EDE7D7;
+ --cream-300: #E1D8C0;
+ --cream-400: #C9BC9A;
+
+ /* Gold / tan — the inner key border */
+ --gold-700: #8A6F3D;
+ --gold-600: #A88652;
+ --gold-500: #BFA068; /* core gold accent */
+ --gold-400: #D4B985;
+ --gold-300: #E5CFA5;
+ --gold-200: #F0E2C5;
+
+ /* Ink — dark text */
+ --ink-900: #0E1F33;
+ --ink-700: #2C3E54;
+ --ink-500: #5A6B7F;
+ --ink-400: #7E8C9D;
+ --ink-300: #A4AEBB;
+
+ /* Semantic */
+ --success: #2D7A5F;
+ --success-bg: #E3F0EA;
+ --warning: #B8861F;
+ --warning-bg: #F7EFD7;
+ --danger: #B23A3A;
+ --danger-bg: #F4E0E0;
+ --info: var(--navy-700);
+ --info-bg: var(--navy-100);
+
+ /* ---------- Semantic surface tokens ---------- */
+ --bg-page: var(--cream-100); /* default page bg */
+ --bg-paper: var(--cream-50); /* lighter paper */
+ --bg-elev: #FFFFFF; /* elevated surface (cards on cream) */
+ --bg-inverse: var(--navy-900); /* dark surface */
+ --bg-tint: var(--cream-200); /* tinted band/section */
+
+ --fg-1: var(--ink-900); /* primary text */
+ --fg-2: var(--ink-700); /* secondary text */
+ --fg-3: var(--ink-500); /* tertiary / meta */
+ --fg-4: var(--ink-400); /* disabled / hint */
+ --fg-on-navy: var(--cream-50);
+ --fg-on-gold: var(--navy-900);
+
+ --border-1: rgba(14, 31, 51, 0.12); /* hairline on cream */
+ --border-2: rgba(14, 31, 51, 0.20); /* card border */
+ --border-3: rgba(14, 31, 51, 0.35); /* focus / strong */
+ --border-on-navy: rgba(245, 241, 232, 0.18);
+
+ --accent: var(--navy-800);
+ --accent-hover: var(--navy-900);
+ --accent-press: var(--navy-950);
+ --accent-soft: var(--navy-100);
+
+ --gold: var(--gold-500);
+ --gold-hover: var(--gold-600);
+
+ /* ---------- Type families ---------- */
+ --font-display: 'Manrope', 'Helvetica Neue', Arial, sans-serif;
+ --font-body: 'Inter', 'Helvetica Neue', Arial, sans-serif;
+ --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
+
+ /* ---------- Type scale ---------- */
+ --fs-display-xl: clamp(56px, 6vw, 88px);
+ --fs-display: clamp(40px, 4.5vw, 64px);
+ --fs-h1: 44px;
+ --fs-h2: 32px;
+ --fs-h3: 24px;
+ --fs-h4: 20px;
+ --fs-h5: 17px;
+ --fs-body-lg: 18px;
+ --fs-body: 15px;
+ --fs-body-sm: 13.5px;
+ --fs-meta: 12px;
+ --fs-mono: 13px;
+
+ /* ---------- Line heights ---------- */
+ --lh-display: 1.02;
+ --lh-heading: 1.15;
+ --lh-body: 1.55;
+ --lh-tight: 1.25;
+
+ /* ---------- Letter spacing ---------- */
+ --tracking-tight: -0.02em;
+ --tracking-normal: 0;
+ --tracking-wide: 0.04em;
+ --tracking-eyebrow: 0.18em;
+
+ /* ---------- Spacing (4px base) ---------- */
+ --sp-1: 4px;
+ --sp-2: 8px;
+ --sp-3: 12px;
+ --sp-4: 16px;
+ --sp-5: 20px;
+ --sp-6: 24px;
+ --sp-7: 32px;
+ --sp-8: 40px;
+ --sp-9: 56px;
+ --sp-10: 72px;
+ --sp-11: 96px;
+ --sp-12: 128px;
+
+ /* ---------- Radii ---------- */
+ --r-xs: 3px;
+ --r-sm: 5px;
+ --r-md: 8px;
+ --r-lg: 12px;
+ --r-xl: 18px;
+ --r-2xl: 24px;
+ --r-pill: 999px;
+
+ /* ---------- Shadows ---------- */
+ /* Quiet, layered shadows — paper, not glassy */
+ --shadow-xs: 0 1px 1px rgba(14,31,51,0.04);
+ --shadow-sm: 0 1px 2px rgba(14,31,51,0.06), 0 1px 1px rgba(14,31,51,0.03);
+ --shadow-md: 0 2px 4px rgba(14,31,51,0.06), 0 4px 12px rgba(14,31,51,0.06);
+ --shadow-lg: 0 4px 8px rgba(14,31,51,0.07), 0 12px 32px rgba(14,31,51,0.10);
+ --shadow-xl: 0 8px 16px rgba(14,31,51,0.10), 0 24px 64px rgba(14,31,51,0.14);
+ --shadow-inset: inset 0 1px 0 rgba(255,255,255,0.6), inset 0 -1px 0 rgba(14,31,51,0.05);
+ --ring-focus: 0 0 0 3px rgba(30,58,95,0.25);
+
+ /* ---------- Motion ---------- */
+ --ease-standard: cubic-bezier(0.2, 0.7, 0.2, 1);
+ --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
+ --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
+ --dur-fast: 120ms;
+ --dur-base: 200ms;
+ --dur-slow: 360ms;
+}
+
+/* ============================================================
+ Paper texture — subtle grain on cream surfaces
+ ============================================================ */
+.paper-texture {
+ background-color: var(--bg-page);
+ background-image:
+ radial-gradient(rgba(14,31,51,0.025) 1px, transparent 1px),
+ radial-gradient(rgba(138,111,61,0.022) 1px, transparent 1px);
+ background-size: 3px 3px, 7px 7px;
+ background-position: 0 0, 1px 1px;
+}
+.paper-texture-strong {
+ background-color: var(--bg-page);
+ background-image:
+ radial-gradient(rgba(14,31,51,0.04) 1px, transparent 1.4px),
+ radial-gradient(rgba(138,111,61,0.035) 1px, transparent 1.2px);
+ background-size: 3px 3px, 7px 7px;
+}
+
+/* ============================================================
+ Element defaults — drop these into a body class .keysat
+ ============================================================ */
+.keysat {
+ font-family: var(--font-body);
+ font-size: var(--fs-body);
+ line-height: var(--lh-body);
+ color: var(--fg-1);
+ background: var(--bg-page);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-feature-settings: 'ss01', 'cv11';
+}
+
+.keysat h1, .keysat .h1 {
+ font-family: var(--font-display);
+ font-size: var(--fs-h1);
+ font-weight: 500;
+ line-height: var(--lh-heading);
+ letter-spacing: var(--tracking-tight);
+ color: var(--fg-1);
+ margin: 0;
+}
+.keysat h2, .keysat .h2 {
+ font-family: var(--font-display);
+ font-size: var(--fs-h2);
+ font-weight: 500;
+ line-height: var(--lh-heading);
+ letter-spacing: var(--tracking-tight);
+ color: var(--fg-1);
+ margin: 0;
+}
+.keysat h3, .keysat .h3 {
+ font-family: var(--font-display);
+ font-size: var(--fs-h3);
+ font-weight: 600;
+ line-height: var(--lh-tight);
+ letter-spacing: var(--tracking-tight);
+ margin: 0;
+}
+.keysat h4, .keysat .h4 {
+ font-family: var(--font-display);
+ font-size: var(--fs-h4);
+ font-weight: 600;
+ line-height: var(--lh-tight);
+ margin: 0;
+}
+.keysat h5, .keysat .h5 {
+ font-family: var(--font-body);
+ font-size: var(--fs-h5);
+ font-weight: 600;
+ line-height: var(--lh-tight);
+ margin: 0;
+}
+.keysat .display-xl {
+ font-family: var(--font-display);
+ font-size: var(--fs-display-xl);
+ font-weight: 500;
+ line-height: var(--lh-display);
+ letter-spacing: -0.022em;
+}
+.keysat .display {
+ font-family: var(--font-display);
+ font-size: var(--fs-display);
+ font-weight: 500;
+ line-height: var(--lh-display);
+ letter-spacing: -0.022em;
+}
+.keysat .wordmark {
+ font-family: var(--font-display);
+ font-weight: 500;
+ letter-spacing: 0.32em;
+ text-transform: uppercase;
+ color: var(--navy-800);
+}
+.keysat .eyebrow {
+ font-family: var(--font-body);
+ font-size: 11.5px;
+ font-weight: 600;
+ letter-spacing: var(--tracking-eyebrow);
+ text-transform: uppercase;
+ color: var(--gold-700);
+}
+.keysat p { margin: 0 0 1em 0; color: var(--fg-2); }
+.keysat .lead {
+ font-size: var(--fs-body-lg);
+ line-height: 1.5;
+ color: var(--fg-2);
+}
+.keysat .meta {
+ font-size: var(--fs-meta);
+ color: var(--fg-3);
+ letter-spacing: 0.02em;
+}
+.keysat code, .keysat .mono {
+ font-family: var(--font-mono);
+ font-size: var(--fs-mono);
+ font-feature-settings: 'ss02';
+}
+.keysat a {
+ color: var(--accent);
+ text-decoration: underline;
+ text-decoration-thickness: 1px;
+ text-underline-offset: 2px;
+}
+.keysat a:hover { color: var(--accent-hover); }
diff --git a/design/tokens.tokens.json b/design/tokens.tokens.json
new file mode 100644
index 0000000..903d9ab
--- /dev/null
+++ b/design/tokens.tokens.json
@@ -0,0 +1,171 @@
+{
+ "$description": "Keysat design tokens — W3C DTCG-shaped, distilled from design/_imports/2026-06-16-claude-design-system/colors_and_type.css (as-built values). Group-level $type is set where it maps cleanly to a DTCG primitive; a few groups (fontSize, letterSpacing, shadow) carry as-built CSS expressions (clamp(), em, multi-layer shadows) as strings and are intentionally left untyped pending a Style Dictionary build. See design/DESIGN.md for intent and rules.",
+
+ "color": {
+ "$type": "color",
+ "navy": {
+ "950": { "$value": "#0E1F33" },
+ "900": { "$value": "#142A47" },
+ "800": { "$value": "#1E3A5F", "$description": "core brand navy — wordmark, primary buttons, dominant ink" },
+ "700": { "$value": "#2A4A75" },
+ "600": { "$value": "#3A5C8A" },
+ "500": { "$value": "#5074A1" },
+ "400": { "$value": "#7892B8" },
+ "300": { "$value": "#A6B7CF" },
+ "200": { "$value": "#CBD5E2" },
+ "100": { "$value": "#E4EAF1" },
+ "50": { "$value": "#F2F5F9" }
+ },
+ "cream": {
+ "50": { "$value": "#FBF9F2", "$description": "elevated paper / card surface" },
+ "100": { "$value": "#F5F1E8", "$description": "core cream — default page background" },
+ "200": { "$value": "#EDE7D7" },
+ "300": { "$value": "#E1D8C0" },
+ "400": { "$value": "#C9BC9A" }
+ },
+ "gold": {
+ "700": { "$value": "#8A6F3D", "$description": "eyebrow labels / dark gold accent" },
+ "600": { "$value": "#A88652" },
+ "500": { "$value": "#BFA068", "$description": "core gold accent — sparing use only, never a primary button fill" },
+ "400": { "$value": "#D4B985" },
+ "300": { "$value": "#E5CFA5" },
+ "200": { "$value": "#F0E2C5" }
+ },
+ "ink": {
+ "900": { "$value": "#0E1F33", "$description": "primary text" },
+ "700": { "$value": "#2C3E54", "$description": "secondary text" },
+ "500": { "$value": "#5A6B7F", "$description": "tertiary / meta" },
+ "400": { "$value": "#7E8C9D", "$description": "disabled / hint" },
+ "300": { "$value": "#A4AEBB" }
+ },
+ "semantic": {
+ "success": { "$value": "#2D7A5F" },
+ "success-bg": { "$value": "#E3F0EA" },
+ "warning": { "$value": "#B8861F" },
+ "warning-bg": { "$value": "#F7EFD7" },
+ "danger": { "$value": "#B23A3A" },
+ "danger-bg": { "$value": "#F4E0E0" },
+ "info": { "$value": "{color.navy.700}" },
+ "info-bg": { "$value": "{color.navy.100}" }
+ },
+ "surface": {
+ "page": { "$value": "{color.cream.100}", "$description": "default page bg (apply with paper-texture grain)" },
+ "paper": { "$value": "{color.cream.50}" },
+ "elevated":{ "$value": "#FFFFFF", "$description": "forms, tables, code blocks — reserved white" },
+ "inverse": { "$value": "{color.navy.900}" },
+ "tint": { "$value": "{color.cream.200}" }
+ },
+ "fg": {
+ "primary": { "$value": "{color.ink.900}" },
+ "secondary": { "$value": "{color.ink.700}" },
+ "tertiary": { "$value": "{color.ink.500}" },
+ "hint": { "$value": "{color.ink.400}" },
+ "on-navy": { "$value": "{color.cream.50}" },
+ "on-gold": { "$value": "{color.navy.900}" }
+ },
+ "accent": {
+ "default": { "$value": "{color.navy.800}" },
+ "hover": { "$value": "{color.navy.900}" },
+ "press": { "$value": "{color.navy.950}" },
+ "soft": { "$value": "{color.navy.100}" },
+ "gold": { "$value": "{color.gold.500}" }
+ },
+ "border": {
+ "1": { "$value": "rgba(14, 31, 51, 0.12)", "$description": "hairline on cream" },
+ "2": { "$value": "rgba(14, 31, 51, 0.20)", "$description": "card border" },
+ "3": { "$value": "rgba(14, 31, 51, 0.35)", "$description": "focus / strong" },
+ "on-navy": { "$value": "rgba(245, 241, 232, 0.18)" }
+ }
+ },
+
+ "font": {
+ "$type": "fontFamily",
+ "display": { "$value": ["Manrope", "Helvetica Neue", "Arial", "sans-serif"], "$description": "canonical display face (README's 'Archivo' was a stale placeholder)" },
+ "body": { "$value": ["Inter", "Helvetica Neue", "Arial", "sans-serif"] },
+ "mono": { "$value": ["JetBrains Mono", "ui-monospace", "SF Mono", "Menlo", "monospace"] }
+ },
+
+ "fontSize": {
+ "$description": "as-built type scale; display sizes use CSS clamp() and are kept as strings",
+ "display-xl": { "$value": "clamp(56px, 6vw, 88px)" },
+ "display": { "$value": "clamp(40px, 4.5vw, 64px)" },
+ "h1": { "$value": "44px" },
+ "h2": { "$value": "32px" },
+ "h3": { "$value": "24px" },
+ "h4": { "$value": "20px" },
+ "h5": { "$value": "17px" },
+ "body-lg": { "$value": "18px" },
+ "body": { "$value": "15px" },
+ "body-sm": { "$value": "13.5px" },
+ "meta": { "$value": "12px" },
+ "mono": { "$value": "13px" }
+ },
+
+ "lineHeight": {
+ "$type": "number",
+ "display": { "$value": 1.02 },
+ "heading": { "$value": 1.15 },
+ "body": { "$value": 1.55 },
+ "tight": { "$value": 1.25 }
+ },
+
+ "letterSpacing": {
+ "$description": "em values kept as strings",
+ "tight": { "$value": "-0.02em" },
+ "normal": { "$value": "0" },
+ "wide": { "$value": "0.04em" },
+ "eyebrow": { "$value": "0.18em" }
+ },
+
+ "space": {
+ "$type": "dimension",
+ "1": { "$value": "4px" },
+ "2": { "$value": "8px" },
+ "3": { "$value": "12px" },
+ "4": { "$value": "16px" },
+ "5": { "$value": "20px" },
+ "6": { "$value": "24px" },
+ "7": { "$value": "32px" },
+ "8": { "$value": "40px" },
+ "9": { "$value": "56px" },
+ "10": { "$value": "72px" },
+ "11": { "$value": "96px" },
+ "12": { "$value": "128px" }
+ },
+
+ "radius": {
+ "$type": "dimension",
+ "xs": { "$value": "3px" },
+ "sm": { "$value": "5px" },
+ "md": { "$value": "8px", "$description": "buttons" },
+ "lg": { "$value": "12px", "$description": "cards" },
+ "xl": { "$value": "18px", "$description": "max surface rounding — never exceed" },
+ "2xl": { "$value": "24px", "$description": "reserved; avoid in product UI" },
+ "pill": { "$value": "999px", "$description": "tags/badges only" }
+ },
+
+ "shadow": {
+ "$description": "paper-shadow system — multi-layer CSS strings, not glassy",
+ "xs": { "$value": "0 1px 1px rgba(14,31,51,0.04)" },
+ "sm": { "$value": "0 1px 2px rgba(14,31,51,0.06), 0 1px 1px rgba(14,31,51,0.03)" },
+ "md": { "$value": "0 2px 4px rgba(14,31,51,0.06), 0 4px 12px rgba(14,31,51,0.06)" },
+ "lg": { "$value": "0 4px 8px rgba(14,31,51,0.07), 0 12px 32px rgba(14,31,51,0.10)" },
+ "xl": { "$value": "0 8px 16px rgba(14,31,51,0.10), 0 24px 64px rgba(14,31,51,0.14)" },
+ "inset": { "$value": "inset 0 1px 0 rgba(255,255,255,0.6), inset 0 -1px 0 rgba(14,31,51,0.05)" },
+ "ring-focus": { "$value": "0 0 0 3px rgba(30,58,95,0.25)" }
+ },
+
+ "duration": {
+ "$type": "duration",
+ "fast": { "$value": "120ms", "$description": "hover transitions" },
+ "base": { "$value": "200ms", "$description": "default" },
+ "slow": { "$value": "360ms" }
+ },
+
+ "easing": {
+ "$type": "cubicBezier",
+ "standard": { "$value": [0.2, 0.7, 0.2, 1] },
+ "out": { "$value": [0.16, 1, 0.3, 1] },
+ "in": { "$value": [0.7, 0, 0.84, 0] }
+ }
+}