Appearance — the wardrobe
/appearance lets any visitor — signed in or not — choose how this platform looks (theme) and how its chrome speaks (tone). This page names exactly what that system stores, who may wear what, and the approximations it admits to.
Where this lives in code. Theme registry atapps/storefront/src/lib/wardrobe/themes.ts; CSS bundles atapps/storefront/src/app/themes.css; the only cookie writer atapps/storefront/src/app/api/appearance/route.ts. Spec:docs/superpowers/specs/2026-06-10-the-wardrobe-design.md.
1. What is stored, and where
- Two cookies:
theme(one ofgallery · terminal · midnight · high-contrast) andtone(standard · plain). Both last one year, both are device-local — they do not follow you across browsers or devices. Account-level persistence is planned, not shipped; until it ships, this page will keep saying so. - Follow system stores nothing (since 2026-07-06): with no theme cookie the page carries
data-theme="system"and your device’s colour-scheme preference picks Gallery (light) or Midnight (dark) in CSS, at render — the preference itself never reaches our servers. Choosing “Follow system” deletes the cookie; it does not write one. - Nothing else. No analytics event fires on a theme change; the choice is not used for pricing, ranking, or any decision beyond rendering.
2. Themes, and who may wear them
- Free for everyone: all four — Gallery (the light face), Terminal (the original dark look, kept whole), Midnight (the quiet gallery, lights off), High contrast. Midnight launched as a member perk on 2026-06-10 and was un-gated on 2026-07-06: dark mode is table stakes, not a perk. The entitlement mechanism remains in the code for a future skin that may genuinely be one; today nothing uses it.
- If a skin is ever locked again, the check runs server-side when the cookie is set; a locked request changes nothing and shows no error — the lock is explained only on the settings page, next to the path to membership.
- Never paywalled: high contrast, text-only layout, reduced motion, tone. Anything a visitor might need rather than want is free, by rule. If we ever break this rule, this sentence must be edited first — treat its presence as the guarantee.
3. The staged rollout, honestly
Themes re-bind the platform’s semanticdesign tokens. Pages migrate to those tokens surface by surface; a page that has not migrated yet keeps the original dark look regardless of your theme. As of this page’s last edit, the migrated set is: the market suite (/market, /market/[sku], /market/pulse, /market/lots), the card market mirror (/cards/[sku]/market), and the appearance settings page itself. The site-wide default flips to Gallery when the home page completes its sweep.
4. What tone does — and refuses to do
Tone swaps chrome strings: titles, empty-state copy, button labels. It never rewrites facts, figures, methodology text, or anything doctrine-bearing. The dictionary lives at apps/storefront/src/lib/wardrobe/voice.ts; every string ships in every register, so the registers cannot drift apart silently.
5. What this system does NOT do
- No per-user CSS injection; themes are a fixed, audited set.
- No tracking of which theme you wear.
- No flash-of-wrong-theme: the cookie is read server-side at render, and system-follow resolves in CSS at first paint — no script swaps the theme after the fact.
- No override of text-mode: the text-only layout wins over any theme, by construction.