{
  "$schema": "https://dr.eamer.dev/design/themes/tokens.json",
  "$version": "2.0.0",
  "$updated": "2026-09-09",
  "$description": "Machine-readable design tokens for the visual systems actually running across dr.eamer.dev, lukesteuber.com, datapoems.io, world-languages.com, diachronica.com, geepers.ai, ideatiles.app and mandaza.app. Every value here was read from the live surface on the date in $updated, not from a source repo. Use these when building a new page so it lands inside a system that already exists.",

  "$changelog": {
    "2.0.0": "Restructured from seven flat themes into six families, each carrying named variants. Folded bioluminescent, ethereal, earthy and glassmorphic into the Instrument family (they were four accent variations of one dark dashboard theme). Added the live systems v1 never documented: chalk, numerals, paper, catalog, trophy-wall, product and canvas. Added $contracts, which is the part that actually matters: a family is a token contract, and a variant is a palette poured into it.",
    "1.0.0": "Seven flat themes, all examples under /datavis/. Superseded."
  },

  "$contracts": {
    "$note": "A family is a set of token NAMES plus structural rules. A variant is one set of VALUES for those names. This is not a theory imposed after the fact: /clocks/ and /clocks/numerals/ already ship the same token names with different values, and /clocks/ and datapoems.io already ship byte-identical values. Build a new page by picking a contract, then picking a variant.",

    "surface": {
      "used-by": ["instrument"],
      "required": ["--bg", "--fg", "--fg-muted", "--line", "--line-strong", "--scrim"],
      "optional": ["--bg-elevated", "--fg-dim", "--cyan", "--amber", "--scrim-mid", "--tile-bg", "--board-bg", "--h2"],
      "structure": {
        "--radius-tile": "corner on a content tile",
        "--radius-btn": "corner on a control",
        "--border-w": "hairline width, 1px throughout",
        "--gap-featured": "gutter in the featured grid",
        "--tile-lift": "translateY on hover, negative"
      },
      "note": "--cyan and --amber are role names, not color claims. --cyan is the primary accent (links, titles, active state); --amber is the secondary accent (outbound markers, art bands). In the chalk variant --cyan is a pale sage and --amber is a soft straw; the names survive from the numerals variant where they are literally cyan and amber."
    },

    "document": {
      "used-by": ["paper"],
      "required": ["--bg", "--ink", "--ink-muted", "--rule", "--accent"],
      "optional": ["--bg-band", "--surface", "--ink-bright", "--border", "--btn-bg", "--btn-border"],
      "note": "Ink on a sheet, not foreground on a background. Load the theme file before the page stylesheet: theme owns color, page owns layout. This split is live at world-languages.com/shared/theme.css + page.css."
    },

    "grid": {
      "used-by": ["swiss"],
      "required": ["--bg", "--text", "--line"],
      "optional": ["--muted", "--link", "--focus"],
      "structure": {
        "border-radius": "0 in the classic and trophy-wall variants",
        "gap": "0 in trophy-wall; the hairline between cells is the only separator",
        "max-colors-per-composition": 3,
        "text-alignment": "left"
      }
    },

    "product": {
      "used-by": ["product"],
      "required": ["--background", "--foreground", "--card", "--popover", "--primary", "--secondary", "--muted", "--accent", "--destructive", "--border", "--input", "--ring", "--radius"],
      "optional": ["--chart-1", "--chart-2", "--chart-3", "--chart-4", "--chart-5", "--sidebar", "--sidebar-primary", "--sidebar-accent", "--sidebar-border", "--sidebar-ring"],
      "note": "The shadcn/ui contract on Tailwind 4, values in oklch. Do not hand-author these: they come with the component library. Listed here so a new app picks the same contract instead of a ninth bespoke one, and so the brand hue is a deliberate choice rather than a default."
    }
  },

  "instrument": {
    "meta": {
      "name": "Instrument",
      "mood": "Dark ground, hairline rules, one bright accent and one warm secondary. Reads as a lit panel in a dark room.",
      "contract": "surface",
      "dominant": true,
      "merged-from": ["bioluminescent", "ethereal", "earthy", "glassmorphic"],
      "merge-rationale": "All four were a near-black blue-shifted ground, an Inter/JetBrains Mono pair, 8px spacing and 8px radius, separated only by accent hue. They are variants, not systems."
    },
    "typography": {
      "font-display": "\"Atkinson Hyperlegible\", \"Source Sans 3\", ui-sans-serif, system-ui, sans-serif",
      "font-ui": "\"Source Sans 3\", \"Atkinson Hyperlegible\", ui-sans-serif, system-ui, sans-serif",
      "font-data": "\"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace",
      "display-weight": 700,
      "display-tracking": "-0.02em",
      "h2-tracking": "0.22em",
      "note": "Atkinson Hyperlegible is the house display face on the live tile indexes and it is a legibility face by design. The older datavis variants used Inter and Space Grotesk; prefer Atkinson on anything new."
    },
    "spacing": { "unit": "8px", "scale": [8, 16, 24, 32, 40, 48, 64] },
    "structure": {
      "--radius-tile": "0.45rem",
      "--radius-btn": "0.35rem",
      "--border-w": "1px",
      "--gap-featured": "0.7rem",
      "--gap-featured-md": "0.95rem",
      "--gap-board": "12px",
      "--tile-lift": "-3px",
      "grid": "grid-template-columns: repeat(var(--feature-cols), 1fr) with --feature-cols stepping 3 to 4 to 5 (or 6) across breakpoints; grid-auto-rows computed from 100cqw so tiles stay square in a container query"
    },
    "variants": {
      "chalk": {
        "name": "Chalk",
        "status": "live, dominant",
        "mood": "Soft chalkboard. Desaturated sage and straw on slate, diffuse lift rather than glow.",
        "source": ["https://dr.eamer.dev/clocks/", "https://datapoems.io/"],
        "verified": "2026-09-09",
        "colors": {
          "--bg": "#1a1e22",
          "--bg-elevated": "#242a30",
          "--fg": "#e8ece8",
          "--fg-muted": "rgba(232, 236, 232, 0.55)",
          "--fg-dim": "rgba(232, 236, 232, 0.4)",
          "--cyan": "#d4e0d0",
          "--amber": "#f0e6a8",
          "--line": "rgba(212, 224, 208, 0.14)",
          "--line-strong": "rgba(212, 224, 208, 0.4)",
          "--scrim": "rgba(26, 30, 34, 0.9)",
          "--scrim-mid": "rgba(26, 30, 34, 0.55)",
          "--glow-a": "rgba(220, 230, 220, 0.06)",
          "--glow-b": "rgba(180, 190, 160, 0.04)",
          "--vignette": "rgba(0, 0, 0, 0.4)",
          "--tile-bg": "#22282e",
          "--board-bg": "#1e2428",
          "--h2": "rgba(212, 224, 208, 0.55)",
          "--exp-h2": "rgba(240, 230, 168, 0.6)",
          "--skip-fg": "#1a1e22"
        },
        "effects": {
          "--tile-shadow": "0 2px 4px rgba(0, 0, 0, 0.3), 0 8px 22px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.06)",
          "--tile-shadow-hover": "0 6px 14px rgba(0, 0, 0, 0.35), 0 18px 40px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(212, 224, 208, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.1)",
          "body-wash": "radial-gradient(ellipse 90% 55% at 50% -18%, var(--glow-a), transparent 55%), radial-gradient(ellipse 50% 40% at 100% 80%, var(--glow-b), transparent 50%), radial-gradient(ellipse 40% 35% at 0% 60%, var(--glow-a), transparent 45%), linear-gradient(180deg, var(--bg-elevated) 0%, var(--bg) 28%, var(--bg) 100%)",
          "vignette": "radial-gradient(ellipse 70% 60% at 50% 50%, transparent 40%, var(--vignette) 100%) at opacity 0.85 on body::before"
        },
        "note": "/clocks/ and datapoems.io carry this token set identically. The only difference across the two pages is --feature-cols at the widest breakpoint: 5 on clocks, 6 on datapoems. Selector is `:root, html[data-theme=\"chalk\"]` so the theme can be named explicitly without changing the default."
      },
      "numerals": {
        "name": "Numerals",
        "status": "live",
        "mood": "Night instrument. True cyan and amber on deep navy, the readout look.",
        "source": ["https://dr.eamer.dev/clocks/numerals/"],
        "verified": "2026-09-09",
        "colors": {
          "--bg": "#040912",
          "--cyan": "#5cd9ff",
          "--amber": "#f5b441",
          "--line": "rgba(159, 178, 201, 0.18)",
          "--line-strong": "rgba(159, 178, 201, 0.42)",
          "--scrim": "rgba(4, 9, 18, 0.82)"
        },
        "typography": {
          "font-ui": "\"Atkinson Hyperlegible\", ui-sans-serif, system-ui, -apple-system, sans-serif",
          "font-data": "\"JetBrains Mono\", monospace"
        },
        "structure": {
          "border-radius": "10px on cards, 999px on pills",
          "gap": "0.6rem in the tile grid, 9px in the dense grid",
          "grid": "repeat(3|4|5|6, 1fr) across breakpoints",
          "aspect-ratio": "3/2 and 3/4 depending on band"
        },
        "note": "Proof that the surface contract generalizes: same token names as chalk, different palette, no structural rewrite."
      },
      "deep-sea": {
        "name": "Deep Sea",
        "status": "datavis legacy",
        "mood": "Saturated cyan and magenta glow on near-black.",
        "colors": {
          "--bg": "#0a0a0a",
          "--bg-void": "#030508",
          "--tile-bg": "#1a1a1a",
          "--bg-elevated": "#2a2a2a",
          "--line": "#3a3a3a",
          "--fg": "#e0e0e0",
          "--fg-muted": "#888888",
          "--fg-dim": "#666666",
          "--cyan": "#00ffff",
          "--amber": "#ff00ff"
        },
        "effects": {
          "glow-sm": "0 0 8px rgba(0, 255, 255, 0.3)",
          "glow-md": "0 0 16px rgba(0, 255, 255, 0.4)",
          "glow-lg": "0 0 24px rgba(0, 255, 255, 0.5)"
        },
        "examples": ["/datavis/attractive/", "/datavis/poems/flow/", "/datavis/poems/silence/"]
      },
      "aurora": {
        "name": "Aurora",
        "status": "datavis legacy",
        "mood": "Green, ice and magenta over a radial night sky.",
        "colors": {
          "--bg": "#080a0d",
          "--fg": "#e8eaed",
          "--fg-muted": "#6b7280",
          "--cyan": "#00f5ff",
          "--amber": "#00ff6a",
          "--accent-3": "#ff38c7"
        },
        "effects": { "bg-gradient": "radial-gradient(ellipse at top, #0a1a20 0%, #080a0d 50%)" },
        "typography": {
          "font-display": "'Space Grotesk', sans-serif",
          "font-data": "'DM Mono', monospace"
        },
        "examples": ["/datavis/poems/aurora/", "/datavis/dev/quirky/aurora-northern-veils.html"]
      },
      "cosmic": {
        "name": "Cosmic",
        "status": "datavis legacy",
        "mood": "Warm gold and amber for astronomical and geological subjects.",
        "colors": {
          "--bg": "#0a0e27",
          "--cyan": "#ffd700",
          "--amber": "#ffaa00",
          "--accent-3": "#ff6b35"
        },
        "effects": { "bg-gradient": "radial-gradient(ellipse at center, #0a0e27 0%, #050508 100%)" },
        "examples": ["/datavis/dev/cosmic-clock/", "/datavis/dev/quirky/falling-stars-global.html"]
      },
      "mission-control": {
        "name": "Mission Control",
        "status": "datavis legacy",
        "mood": "Status readout. Muted traffic-light semantics over the deep-sea ground.",
        "colors": {
          "status-ok": "#22aa55",
          "status-warn": "#ccaa44",
          "status-alert": "#cc4444"
        },
        "typography": { "font-ui": "'Open Sans', sans-serif" },
        "note": "A semantic overlay on deep-sea rather than a full palette. Use it when a page reports state."
      },
      "topographic": {
        "name": "Topographic",
        "status": "datavis legacy",
        "mood": "Teal and copper on slate, organic contour shapes.",
        "was": "ethereal",
        "colors": {
          "--bg": "#0f172a",
          "--tile-bg": "#1a2332",
          "--bg-elevated": "#1e293b",
          "--fg": "#e2e8f0",
          "--fg-muted": "#94a3b8",
          "--cyan": "#14b8a6",
          "--cyan-light": "#5eead4",
          "--amber": "#d97706",
          "--amber-light": "#fbbf24",
          "--line": "rgba(20, 184, 166, 0.15)",
          "elevation-low": "#064e3b",
          "elevation-mid": "#14b8a6",
          "elevation-high": "#fbbf24",
          "water": "#0ea5e9"
        },
        "examples": ["/datavis/dev/pnw-isolates/", "/datavis/dev/quirky/lighthouses-beacon-spiral.html"]
      },
      "documentary": {
        "name": "Documentary",
        "status": "datavis legacy",
        "mood": "Desert orange and yellow on deep navy, journalistic.",
        "was": "earthy",
        "colors": {
          "--bg": "#0a0f1a",
          "--tile-bg": "#1a2332",
          "--fg": "#ffffff",
          "--fg-muted": "#94a3b8",
          "--cyan": "#ff6b35",
          "--amber": "#ffaa00",
          "healthy-green": "#2dd4bf",
          "poverty-red": "#ef4444",
          "vehicle-purple": "#a78bfa"
        },
        "effects": { "gradient-warm": "linear-gradient(135deg, #ff6b35, #ffaa00)" },
        "structure": { "--radius-tile": "20px", "--radius-tile-lg": "24px" },
        "examples": ["/datavis/dev/food_deserts/", "/datavis/dev/healthcare_deserts/"]
      },
      "glass": {
        "name": "Glass",
        "status": "datavis legacy",
        "mood": "Frosted blur panels over a dark ground, cyan accent.",
        "was": "glassmorphic",
        "colors": {
          "--bg": "#0a0e1a",
          "--tile-bg": "rgba(10, 14, 26, 0.75)",
          "--fg": "#ffffff",
          "--fg-muted": "#94a3b8",
          "--cyan": "#06b6d4",
          "--line": "rgba(6, 182, 212, 0.2)",
          "glass-light": "rgba(255, 255, 255, 0.7)",
          "glass-border-light": "rgba(255, 255, 255, 0.3)",
          "glass-shadow": "rgba(31, 38, 135, 0.15)"
        },
        "effects": {
          "blur-sm": "backdrop-filter: blur(4px)",
          "blur-md": "backdrop-filter: blur(8px)",
          "blur-lg": "backdrop-filter: blur(12px)"
        },
        "structure": { "--radius-tile": "12px", "--radius-modal": "16px" },
        "examples": ["/datavis/expat-guide/", "/datavis/dev/inequality-atlas/"]
      },
      "neon-lab": {
        "name": "Neon Lab",
        "status": "datavis legacy",
        "mood": "Deep-sea with the glow turned up and doubled.",
        "colors": { "--bg": "#0a0014" },
        "effects": { "glow-multiplier": 2.0, "double-glow": true }
      }
    }
  },

  "paper": {
    "meta": {
      "name": "Paper",
      "mood": "Warm sheet, dark ink, one accent. Everything on it is an inscription, a manuscript or a printed page.",
      "contract": "document",
      "rationale": "Quoted from the live theme.css: these charts were dark, and dark was the wrong call. A black sheet with neon letters reads as a copy of the chart that suggested the form, however different the content. Paper is more honest to the material. Warm rather than white, because a cool white sheet reads as an interface and a warm one reads as a document."
    },
    "typography": {
      "font-body": "system-ui, -apple-system, sans-serif",
      "font-display-serif": "'Cormorant Garamond', Georgia, serif",
      "font-serif-alt": "\"Iowan Old Style\", \"Palatino Linotype\", Palatino, Georgia, \"Times New Roman\", serif",
      "note": "The script-family posters load Noto Serif plus per-script faces (Noto Sans Phoenician, Noto Sans Old Italic, Uncial Antiqua, UnifrakturMaguntia) as content, not chrome."
    },
    "spacing": { "unit": "8px", "scale": [8, 16, 24, 32, 40, 48, 64] },
    "variants": {
      "world-languages": {
        "name": "Paper (world-languages)",
        "status": "live, canonical",
        "source": ["https://world-languages.com/shared/theme.css", "https://world-languages.com/alphabet/"],
        "verified": "2026-09-09",
        "colors": {
          "--bg": "#f4efe6",
          "--bg-band": "#ebe3d5",
          "--surface": "rgba(253, 251, 247, 0.97)",
          "--ink-bright": "#17150f",
          "--ink": "#35312a",
          "--ink-muted": "#7c756a",
          "--rule": "rgba(53, 49, 42, 0.20)",
          "--accent": "#1c5f9e",
          "--btn-bg": "rgba(253, 251, 247, 0.9)",
          "--btn-border": "rgba(53, 49, 42, 0.18)",
          "--border": "rgba(53, 49, 42, 0.22)"
        },
        "structure": {
          "sheet-width": "min(1520px, 100vw)",
          "sheet-compact": "min(780px, calc((100svh - 120px) * 0.8), 100vw)",
          "border-radius": "4px on controls, 5px on tooltips",
          "control-bar": "position: fixed; bottom: 14px; centered; backdrop-filter: blur(6px)"
        },
        "note": "theme.css owns color, page.css owns layout, controls.css owns the control bar. Five charts were carrying byte-identical private copies before the split."
      },
      "diachronica": {
        "name": "Parchment",
        "status": "live",
        "mood": "Warmer and yellower than world-languages, vermilion accent, soft shadow, generous radius.",
        "source": ["https://diachronica.com/"],
        "verified": "2026-09-09",
        "colors": {
          "--bg": "#f6efe0",
          "--bg-grain": "#efe6d2",
          "--surface": "#fffdf7",
          "--surface-2": "#f3ead7",
          "--ink": "#2a2218",
          "--ink-muted": "#6b5d49",
          "--ink-faint": "#71634b",
          "--accent": "#c0341d",
          "--accent-soft": "#e8c9bf",
          "--border": "#e2d6bd",
          "gold": "#b8860b",
          "atlas": "#2f6f6a",
          "wiktionary": "#8a7d63"
        },
        "effects": { "--shadow": "0 1px 2px rgba(42, 34, 24, .06), 0 8px 24px rgba(42, 34, 24, .08)" },
        "structure": {
          "--radius": "16px",
          "safe-area": "--safe-t: env(safe-area-inset-top, 0px); --safe-b: env(safe-area-inset-bottom, 0px)"
        },
        "note": "--ink-faint #71634b is documented in the source as holding 4.5:1 on both parchment surfaces. Keep that when restyling. The gold, atlas and wiktionary colors are source-attribution markers, not decoration."
      },
      "heritage": {
        "name": "Heritage",
        "status": "datavis legacy",
        "mood": "Memorial. Cream ground, Playfair display, dark red headings.",
        "colors": {
          "--bg": "#f3efe6",
          "--ink": "#2d2d2d",
          "--ink-muted": "#5c5c5c",
          "--accent": "#8b0000",
          "--surface": "rgba(255, 253, 250, 0.90)",
          "--border": "#d4c5b0",
          "axis-line": "#5c4d3c",
          "stem-green": "#2e3b1f",
          "flower-blue": "#779ecb"
        },
        "typography": {
          "font-display": "'Playfair Display', serif",
          "font-body": "'Lato', sans-serif"
        },
        "effects": {
          "bg-gradient": "linear-gradient(#edeae2, #d4d4d4, #6e7f8f)"
        },
        "structure": { "--radius": "4px" },
        "examples": ["/datavis/poems/forget-me-not/"]
      }
    }
  },

  "swiss": {
    "meta": {
      "name": "Swiss",
      "mood": "The grid is the design. Achromatic ground, one accent, hairline or no separator, sharp corners, left-aligned.",
      "contract": "grid"
    },
    "typography": {
      "font-ui": "Helvetica Neue, Helvetica, Arial, sans-serif",
      "font-data": "Consolas, 'Courier New', monospace"
    },
    "spacing": { "unit": "8px", "scale": [8, 16, 24, 32, 40, 48, 64] },
    "rules": {
      "max-colors-per-composition": 3,
      "text-alignment": "left",
      "border-radius": "0"
    },
    "variants": {
      "classic": {
        "name": "Swiss International",
        "status": "reference",
        "mood": "Black, white, red. Mathematical spacing on an 8px grid.",
        "colors": {
          "--bg": "#ffffff",
          "--bg-secondary": "#f8f9fa",
          "--bg-dark": "#000000",
          "--text": "#000000",
          "--muted": "#666666",
          "--text-light": "#ffffff",
          "--accent": "#ff0000",
          "--accent-dark": "#cc0000",
          "--line": "#e0e0e0",
          "--line-dark": "#333333",
          "gray-100": "#f8f9fa",
          "gray-200": "#e9ecef",
          "gray-400": "#ced4da",
          "gray-600": "#6c757d",
          "gray-800": "#343a40",
          "gray-900": "#212529"
        },
        "examples": ["/games/", "/design/swiss/"]
      },
      "catalog": {
        "name": "Catalog",
        "status": "live",
        "mood": "Light, quiet, listing-first. The chrome disappears and the items are the page.",
        "source": ["https://lukesteuber.com/downloads/"],
        "verified": "2026-09-09",
        "colors": {
          "--bg": "#f7f7f5",
          "--text": "#171717",
          "--muted": "#666666",
          "--line": "#d8d8d3",
          "--link": "#174ea6"
        },
        "structure": { "color-scheme": "light" },
        "note": "Five tokens for a whole public download index. The restraint is the point: nothing here needs a sixth."
      },
      "trophy-wall": {
        "name": "Trophy Wall",
        "status": "live",
        "mood": "Zero-gutter poster grid on near-black. The images tile edge to edge and the seam between them is the only line.",
        "source": ["https://lukesteuber.com/downloads/grid/"],
        "verified": "2026-09-09",
        "colors": {
          "--bg": "#0a0a0a",
          "--text": "#f5f5f5",
          "--muted": "#999999",
          "--muted-dim": "#888888",
          "--line": "#222222",
          "--tile-bg": "#000000",
          "--focus": "#60a5fa"
        },
        "structure": {
          "gap": "0",
          "grid": "repeat(3, minmax(0, 1fr)) to 640px, then 3, 4 at 960px, 5 at 1280px",
          "aspect-ratio": "1080 / 1596",
          "width": "min(calc(100% - 2rem), 1200px) on the header, 100% on the wall",
          "focus": "outline: 3px solid #60a5fa; outline-offset: -3px; z-index: 1"
        },
        "note": "The inset focus ring is deliberate: with gap 0 an outset ring would be clipped by the neighbouring cell."
      }
    }
  },

  "gothic": {
    "meta": {
      "name": "Gothic",
      "mood": "Fog and distance. Near-black ground, lavender and ice mist, serif display, text that drifts.",
      "contract": "surface"
    },
    "typography": { "font-display": "'Cormorant Garamond', Georgia, serif" },
    "spacing": { "unit": "8px" },
    "variants": {
      "spectral": {
        "name": "Spectral",
        "status": "datavis legacy",
        "colors": {
          "--bg": "#030508",
          "mist-lavender": "rgba(180, 160, 255, 0.02)",
          "mist-ice": "rgba(140, 200, 255, 0.015)",
          "--fg": "#a8b0c8",
          "text-title": "#3a4550",
          "text-location": "#d0d8ff",
          "text-city": "#6a7590",
          "text-loading": "rgba(180, 160, 255, 0.3)",
          "btn-bg": "rgba(59, 130, 246, 0.1)",
          "btn-border": "rgba(59, 130, 246, 0.3)",
          "btn-text": "#3b82f6",
          "tooltip-bg": "rgba(8, 10, 18, 0.95)",
          "tooltip-border": "rgba(180, 160, 255, 0.2)",
          "disturbed": "rgba(255, 100, 100, 0.5)",
          "scrollbar": "rgba(180, 160, 255, 0.3)"
        },
        "effects": { "distort": "translate(-1px, 0.5px) skew(-0.3deg)" },
        "structure": { "--radius": "4px" },
        "examples": ["/datavis/poems/whispers/", "/datavis/dev/quirky/ghost-map.html"]
      }
    }
  },

  "canvas": {
    "meta": {
      "name": "Canvas",
      "mood": "No chrome at all. A black page, a full-bleed canvas, and a palette that only exists inside the drawing.",
      "contract": "none",
      "note": "This is the anti-theme: there is no page furniture to token. What carries identity is the palette array the sketch draws with, so that is what is recorded here."
    },
    "structure": {
      "page": "html, body { margin: 0; padding: 0; height: 100%; background: #000; overflow: hidden; cursor: pointer; }",
      "canvas": "canvas { display: block; }"
    },
    "variants": {
      "mandaza": {
        "name": "Mandaza",
        "status": "live",
        "source": ["https://mandaza.app/"],
        "verified": "2026-09-09",
        "palettes": {
          "vivid": ["#ff006e", "#fb5607", "#ffbe0b", "#8338ec", "#3a86ff"],
          "depth": ["#03045e", "#0077b6", "#48cae4", "#90e0ef", "#caf0f8"],
          "warm-sand": ["#f48c06", "#ffba08", "#fdd99b", "#f1d4af"],
          "citrus": ["#fee440", "#ffed66", "#fffb96", "#fff3b0"],
          "neon": ["#ff71ce", "#ff5e5b"]
        },
        "note": "Full-bleed generative sketch, click to advance. Palettes are saturated because they are the entire composition; do not reuse them as page chrome."
      }
    }
  },

  "product": {
    "meta": {
      "name": "Product",
      "mood": "Application shell. Component-library tokens in oklch, one brand hue, neutral everything else.",
      "contract": "product",
      "stack": "Tailwind 4 + shadcn/ui",
      "note": "Added in v2 because geepers.ai and ideatiles.app are real, live, and were documented nowhere. They share a contract with each other and with any future app on the same stack; what differs is the brand hue and the radius."
    },
    "variants": {
      "geepers": {
        "name": "Geepers",
        "status": "live",
        "mood": "Warm terracotta on a warm off-white. Every neutral carries a little of the brand hue.",
        "source": ["https://geepers.ai/"],
        "verified": "2026-09-09",
        "colors": {
          "--radius": "0.875rem",
          "--background": "oklch(98.2% .009 76)",
          "--foreground": "oklch(23.5% .018 48)",
          "--card": "oklch(99.7% .003 78)",
          "--card-foreground": "oklch(22% .02 50)",
          "--popover": "oklch(100% 0 0)",
          "--popover-foreground": "oklch(22% .02 50)",
          "--primary": "oklch(58% .176 35)",
          "--primary-foreground": "oklch(99% 0 0)",
          "--secondary": "oklch(95% .02 240)",
          "--secondary-foreground": "oklch(35% .05 240)",
          "--muted": "oklch(95.5% .008 76)",
          "--muted-foreground": "oklch(49% .016 55)",
          "--accent": "oklch(94% .03 60)",
          "--accent-foreground": "oklch(30% .03 50)",
          "--destructive": "oklch(58% .22 25)",
          "--border": "oklch(91% .012 74)",
          "--input": "oklch(91% .012 74)",
          "--ring": "oklch(58% .176 35)"
        },
        "charts": {
          "--chart-1": "oklch(65% .18 35)",
          "--chart-2": "oklch(60% .15 240)",
          "--chart-3": "oklch(70% .12 150)",
          "--chart-4": "oklch(75% .1 60)",
          "--chart-5": "oklch(55% .2 300)"
        },
        "note": "The neutrals are hue-shifted toward the brand (76, 74, 55 rather than 0), which is why the greys read warm. Copy that trick, not just the primary."
      },
      "ideatiles": {
        "name": "Idea Tiles",
        "status": "live",
        "mood": "Amber-gold primary on true neutrals. Brighter and flatter than geepers.",
        "source": ["https://ideatiles.app/"],
        "verified": "2026-09-09",
        "colors": {
          "--radius": "0.75rem",
          "--background": "oklch(98% 0 0)",
          "--foreground": "oklch(15% .01 0)",
          "--card": "oklch(100% 0 0)",
          "--popover": "oklch(100% 0 0)",
          "--primary": "oklch(85% .15 85)",
          "--primary-foreground": "oklch(15% .02 85)",
          "--secondary": "oklch(96% .005 0)",
          "--secondary-foreground": "oklch(35% .01 0)",
          "--muted": "oklch(95% .005 0)",
          "--muted-foreground": "oklch(50% .01 0)",
          "--accent": "oklch(95% .005 0)",
          "--destructive": "oklch(55% .25 25)",
          "--border": "oklch(90% .005 0)",
          "--input": "oklch(90% .005 0)",
          "--ring": "oklch(85% .15 85)"
        },
        "charts": {
          "--chart-1": "oklch(75% .15 200)",
          "--chart-2": "oklch(70% .18 350)",
          "--chart-3": "oklch(65% .15 280)",
          "--chart-4": "oklch(80% .12 85)",
          "--chart-5": "oklch(60% .2 25)"
        },
        "typography": { "--app-font-family": "Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif" },
        "structure": { "--font-size-multiplier": "1, user-adjustable" },
        "note": "--primary at 85% lightness needs a dark foreground; --primary-foreground is oklch(15% .02 85) for that reason. Do not pair this primary with white text."
      }
    }
  },

  "$retired": {
    "bioluminescent": "→ instrument.deep-sea (plus aurora, cosmic, mission-control, neon-lab variants)",
    "ethereal": "→ instrument.topographic",
    "earthy": "→ instrument.documentary",
    "glassmorphic": "→ instrument.glass",
    "heritage": "→ paper.heritage",
    "gothic": "→ gothic.spectral",
    "swiss": "→ swiss.classic"
  }
}
