/* =====================================================================
 * Tim Dixon Design System — Colour & Type tokens
 * ds-version: 2026-06-08b
 *
 * Source of truth: uploads/brand.md and the design system
 * shipped inside timdixon82/Image-Colour-Contrast-Checker
 * (DESIGN_GUIDELINES.md).
 *
 * ── FOUR REQUIRED THEMES ──────────────────────────────────────────────
 * EVERY surface, component and asset in this design system must support
 * all four colour options. Set <html data-theme="…"> to one of:
 *
 *   (unset / "light")  LIGHT       — vivid brand identity, light
 *   "dark"             DARK        — vivid brand identity, dark
 *   "muted-light"      MUTED LIGHT — fully compliant, light
 *   "muted-dark"       MUTED DARK  — fully compliant, dark
 *
 * LIGHT & DARK keep the original vivid look and stay WCAG 2.2 AAA, but
 * their saturated accents land in the Vestibular/Cognitive WARN band
 * (never HIGH/FAIL/HARSH). MUTED LIGHT & MUTED DARK clear every one of
 * the five checkers in the Vestibular & Accessible Design Checker
 * (https://tastheartist.com/vestibular-accessible-design-checker/):
 *   1. WCAG 2.2  2. APCA  3. Vestibular  4. Cognitive  5. Colour-vision
 *
 * The original vivid hues live in the brand archive tokens below
 * (--brand-navy / --brand-orange / --brand-sky) for logo + graphics.
 *
 * theme.js sets data-theme on <html> BEFORE CSS parses, resolving the OS
 * prefers-color-scheme when no preference is saved. With JS disabled the
 * LIGHT palette (AAA) is the default. Preview/consumer surfaces may also
 * set data-theme directly on <html>.
 * ===================================================================== */

/* Roboto — brand primary. Self-hosted variable font (covers all
   weights 100–900 in one file). Falls back to the native system
   stack if the font file fails to load.                            */
@font-face {
  font-family: 'Roboto';
  src: url('fonts/Roboto-VariableFont.ttf') format('truetype-variations'),
       url('fonts/Roboto-VariableFont.ttf') format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Roboto';
  src: url('fonts/Roboto-Italic-VariableFont.ttf') format('truetype-variations'),
       url('fonts/Roboto-Italic-VariableFont.ttf') format('truetype');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

:root {
  /* ── Brand accent colours (WARN-level) ───────────────────────────────
     The single brand identity — navy, orange, sky — as used across the
     Light & Dark themes. These are saturated "warn" accents (vestibular
     WARN, WCAG AAA); the Muted themes desaturate them to SAFE. There is
     no separate vivid set. Use for logo, wordmark and large accents. ── */
  --brand-navy:   #0C3B64;
  --brand-orange: #EB9C52;
  --brand-sky:    #52C7EB;

  /* ═══════════════════════════════════════════════════════════════════
   * THEME 1 · LIGHT  (default)
   * The original vivid identity, tuned so nothing scores HIGH or FAIL —
   * worst case is a vestibular/shimmer WARN on the saturated accents.
   * Still WCAG 2.2 AAA. Switch via <html data-theme="…">:
   *   (default)      → light
   *   "dark"         → vivid dark
   *   "muted-light"  → fully compliant light (all SAFE/PASS)
   *   "muted-dark"   → fully compliant dark  (all SAFE/PASS)
   * ═════════════════════════════════════════════════════════════════ */
  --bg:            #F4F6F8;        /* Page background      sat 17      */
  --bg-card:       #FFFFFF;        /* Card / surface                   */
  --fg:            #1A1A1A;        /* Body text   16.1:1 · Lc 99       */
  --fg-muted:      #46505E;        /* Secondary    7.5:1 · Lc 83       */
  --border:        #D1D5DB;        /* Dividers, input borders          */

  --accent:        #0C3B64;        /* Deep brand navy — interactive    */
  --accent-hover:  #0A3052;        /* Darker on hover                  */
  --accent-text:   #FFFFFF;        /* Text on accent button            */
  --accent-subtle: rgba(12, 59, 100, 0.08);

  --warm:          #EB9C52;        /* Brand orange — FILL only (not    */
  --warm-hover:    #E88E38;        /* text on light: too low contrast) */
  --warm-text:     #1A1A1A;        /* Dark text on the orange fill     */

  --pass:          #105528;        /* Success text  7.4:1 · AAA        */
  --pass-bg:       #D9F0E1;        /* Success badge bg                 */
  --fail:          #8B1F1F;        /* Error text    7.1:1 · AAA        */
  --fail-bg:       #F6DEDE;        /* Error badge bg                   */
  --danger:        var(--fail);    /* alias of --fail for destructive action elements */
  --danger-bg:     var(--fail-bg);
  --warn:          #544012;        /* Caution text  8.2:1 · WARN sat 65*/
  --warn-bg:       #F6E8C8;        /* Caution badge bg                 */
  --neutral:       #46505E;        /* Neutral text  7.0:1 · Lc 78      */
  --neutral-bg:    #ECEEF1;        /* Neutral badge / code bg          */
  --code-bg:       #ECEEF1;

  --shadow:        0 1px 3px rgba(0,0,0,0.06),
                   0 4px 12px rgba(0,0,0,0.05);
  --radius:        10px;

  /* ── Type ── Roboto primary, system stack as fallback.
     Roboto is web-loaded (see @import below). Native system fonts
     render instantly while Roboto downloads; Arial sits at the end
     as the universal fallback.                                       */
  --font-sans:     "Roboto", -apple-system, BlinkMacSystemFont,
                   "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --font-mono:     "SF Mono", Menlo, Consolas,
                   "Liberation Mono", monospace;

  /* Type scale — anchored to timdixon.net live values             */
  --text-xs:       0.78rem;   /* ~12.5px  small / meta            */
  --text-sm:       0.85rem;   /* ~13.6px  secondary               */
  --text-base:     1rem;      /* 16px     body                    */
  --text-lg:       1.1rem;    /* 17.6px   H3                      */
  --text-xl:       1.4rem;    /*  22.4px  H2                      */
  --text-2xl:      1.9rem;    /*  30.4px  H1                      */
  --text-3xl:      2.4rem;    /*  38.4px  hero (rarely used)      */

  --leading-tight: 1.3;
  --leading-body:  1.6;
  --leading-long:  1.65;

  --weight-regular: 400;
  --weight-semi:    500;   /* Roboto Medium (closest to 600) */
  --weight-bold:    700;
  --weight-black:   900;   /* Roboto Black  (closest to 800) */

  /* Tracking — only ever a touch tightened on the H1 */
  --tracking-h1:   -0.3px;

  /* ── Spacing scale (4px grid) ────────────────────────────────────── */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-8:  32px;
  --space-10: 40px;

  /* ── Touch target (WCAG 2.5.8) ───────────────────────────────────── */
  --hit:      44px;
}

/* ═══════════════════════════════════════════════════════════════════════
 * THEME 1 (explicit) · LIGHT — mirrors the :root defaults so the theme
 * also applies when set explicitly via data-theme="light". Theme scopes
 * use a bare [data-theme] selector (not :root[…]) so a theme can be
 * applied to ANY subtree, e.g. <div data-theme="dark">…</div>, not just
 * the document root.
 * ═══════════════════════════════════════════════════════════════════════ */
[data-theme="light"] {
  --bg:            #F4F6F8;
  --bg-card:       #FFFFFF;
  --fg:            #1A1A1A;
  --fg-muted:      #46505E;
  --border:        #D1D5DB;
  --accent:        #0C3B64;
  --accent-hover:  #0A3052;
  --accent-text:   #FFFFFF;
  --accent-subtle: rgba(12, 59, 100, 0.08);
  --warm:          #EB9C52;
  --warm-hover:    #E88E38;
  --warm-text:     #1A1A1A;
  --pass:          #105528;
  --pass-bg:       #D9F0E1;
  --fail:          #8B1F1F;
  --fail-bg:       #F6DEDE;
  --danger:        var(--fail);    /* alias of --fail for destructive action elements */
  --danger-bg:     var(--fail-bg);
  --warn:          #544012;        /* 8.2:1 · WARN sat 65              */
  --warn-bg:       #F6E8C8;
  --neutral:       #46505E;
  --neutral-bg:    #ECEEF1;
  --code-bg:       #ECEEF1;
}

/* ═══════════════════════════════════════════════════════════════════════
 * THEME 2 · DARK — vivid identity on deep navy.
 * Only PASS / WARN (no FAIL · no HIGH · no HARSH). WCAG AAA.
 *
 * ⚠ DARK-MODE TEXT RULE (addresses vestibular feedback): the brand navy
 * surface #061528 is itself 74 %-saturated, so ANY text on it scores a
 * vestibular WARN by design — that is the cost of the authentic navy.
 * Body/secondary TEXT therefore uses low-saturation tokens (--fg sat 21,
 * --fg-muted sat 40) so small text never shimmers (cognitive PASS). The
 * vivid --accent (orange) and --sky are for LARGE elements only — buttons,
 * headings, icons, rules — never small body text. Minimum body size 16px,
 * minimum any-text 12.5px. For a fully shimmer-free dark UI use MUTED DARK.
 * ═══════════════════════════════════════════════════════════════════════ */
[data-theme="dark"] {
  --bg:            #061528;        /* Brand navy surface  sat 74 (WARN)*/
  --bg-card:       #0D2440;        /* Raised card                      */
  --fg:            #E2E7EC;        /* Body text   14.7:1 · Lc 91       */
  --fg-muted:      #9BBCD4;        /* Low-sat blue-grey 9.2:1 · Lc 63
                                      TEXT must stay low-sat: saturated
                                      brand hues are for accents/large
                                      elements only, never small text. */
  --border:        #1C3A5C;

  --accent:        #EB9C52;        /* Brand orange — primary on dark   */
  --accent-hover:  #ECBB83;
  --accent-text:   #061528;        /* Navy text on orange              */
  --accent-subtle: rgba(235, 156, 82, 0.16);

  --warm:          #52C7EB;        /* Brand sky — distinct 2nd accent  */
  --warm-hover:    #6AC5E7;
  --warm-text:     #061528;        /* Navy text on sky                 */

  --sky:           #52C7EB;        /* Vivid brand sky accent           */

  --code-bg:       #15314F;
  --neutral-bg:    #15314F;
  --neutral:       #9FB6CC;        /* 6.3:1 · Lc 56                    */
  --pass:          #8FD3A2;        /* 7.9:1 · Lc 66                    */
  --pass-bg:       #10331F;
  --fail:          #F0A6A6;        /* 8.0:1 · Lc 62                    */
  --fail-bg:       #3A1A1A;
  --danger:        var(--fail);    /* alias of --fail for destructive action elements */
  --danger-bg:     var(--fail-bg);
  --warn:          #DDB84B;        /* 7.1:1 · WARN sat 68 (large/chip) */
  --warn-bg:       #3A2C0C;

  /* Dark elevation: soft, slightly deeper than light so cards read on
     navy — paired with --border, not a heavy halo. Stays flat/low. */
  --shadow:        0 1px 3px rgba(0,0,0,0.22),
                   0 4px 12px rgba(0,0,0,0.18);
}

/* ═══════════════════════════════════════════════════════════════════════
 * THEME 3 · MUTED LIGHT — fully compliant. Every pairing SAFE / PASS
 * across all five checkers (WCAG · APCA · Vestibular · Cognitive · CVD).
 * ═══════════════════════════════════════════════════════════════════════ */
[data-theme="muted-light"] {
  --bg:            #EDF0F3;
  --bg-card:       #FFFFFF;
  --fg:            #2B3138;        /* 13.1:1 · Lc 99                   */
  --fg-muted:      #434C56;        /* 7.20:1 on #EDF0F3 · 8.41:1 on #FFFFFF · AAA ✓ */
  --border:        #D2D8DE;

  --accent:        #234A73;        /* Slate-navy (sat 53)              */
  --accent-hover:  #1B3A5C;
  --accent-text:   #FFFFFF;
  --accent-subtle: rgba(35, 74, 115, 0.08);

  --warm:          #703D1F;        /* Chestnut (sat 57)                */
  --warm-hover:    #5E331A;
  --warm-text:     #FFFFFF;

  --pass:          #1E5631;
  --pass-bg:       #DDEEE2;
  --fail:          #862020;
  --fail-bg:       #F0DCDC;
  --danger:        var(--fail);    /* alias of --fail for destructive action elements */
  --danger-bg:     var(--fail-bg);
  --warn:          #4E3C18;        /* 8.5:1 · SAFE sat 53              */
  --warn-bg:       #EDE6D2;
  --neutral:       #4A535D;
  --neutral-bg:    #E7EAED;
  --code-bg:       #E7EAED;
}

/* ═══════════════════════════════════════════════════════════════════════
 * THEME 4 · MUTED DARK — fully compliant dark. All SAFE / PASS.
 * ═══════════════════════════════════════════════════════════════════════ */
[data-theme="muted-dark"] {
  --bg:            #142536;        /* sat 46                           */
  --bg-card:       #1E3147;
  --fg:            #E2E7EC;        /* 12.5:1 · Lc 89                   */
  --fg-muted:      #98C7D7;        /* 8.5:1 · Lc 66                   */
  --border:        #2C3F54;

  --accent:        #E3C196;        /* Warm sand (sat 58)              */
  --accent-hover:  #E8D3BA;
  --accent-text:   #142536;
  --accent-subtle: rgba(227, 193, 150, 0.16);

  --warm:          #8EBDE1;        /* Cool light blue — distinct 2nd   */
  --warm-hover:    #A6CBE8;        /* accent (warm sand vs cool blue)  */
  --warm-text:     #142536;

  --code-bg:       #27384C;
  --neutral-bg:    #283A4E;
  --neutral:       #C2CCD6;        /* 7.1:1 · Lc 67                    */
  --pass:          #A7D9B5;        /* 8.3:1 · Lc 71                    */
  --pass-bg:       #1C3528;
  --fail:          #E6A9A9;        /* 7.5:1 · Lc 61                    */
  --fail-bg:       #3A2020;
  --danger:        var(--fail);    /* alias of --fail for destructive action elements */
  --danger-bg:     var(--fail-bg);
  --warn:          #DFC686;        /* 7.9:1 · SAFE sat 58              */
  --warn-bg:       #332B12;

  /* Dark elevation (see [data-theme="dark"]) — soft, border-paired. */
  --shadow:        0 1px 3px rgba(0,0,0,0.22),
                   0 4px 12px rgba(0,0,0,0.18);
}

/* =====================================================================
 * Semantic element styles. Drop colors_and_type.css into any project
 * and the bare HTML elements look correct without further CSS.
 * ===================================================================== */

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  min-height: 100vh;
}

h1, h2, h3, h4, h5, h6 {
  color: var(--fg);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-3);
}

h1 {
  font-size: var(--text-2xl);    /* 1.9rem  / 30.4px */
  font-weight: var(--weight-black); /* 800           */
  letter-spacing: var(--tracking-h1);
}

h2 { font-size: var(--text-xl);  font-weight: var(--weight-bold); } /* 1.4rem / 700 */
h3 { font-size: var(--text-lg);  font-weight: var(--weight-semi); } /* 1.1rem / 600 */
h4 { font-size: var(--text-base);font-weight: var(--weight-semi); }

p           { margin: 0 0 var(--space-3); }
p.muted,
.text-muted { color: var(--fg-muted); font-size: var(--text-sm); }
small       { font-size: var(--text-xs); color: var(--fg-muted); }

code,
kbd,
pre {
  font-family: var(--font-mono);
  font-size: 0.85em;
  background: var(--code-bg);
  padding: 1px 6px;
  border-radius: 4px;
}

a         { color: var(--accent); text-underline-offset: 2px; }
a:hover   { color: var(--accent-hover); text-decoration: underline; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
