/* ==========================================================================
   Gubbins design tokens - the ONE source of truth (Model Kit).
   Styrene paper, enamel red, blueprint blue, sprue grey, the 18px
   cutting-mat grid, mono part-codes.

   Consumed by BOTH surfaces:
     - the app:  index.html links this file; src/theme.css holds only
       component styles on top of these variables.
     - the site: public/site/index.html links this file the same way.
   Change a colour here and every surface follows. Do not redefine these
   variables anywhere else.

   Theming: light-first on :root. Dark applies when either the page sets
   data-theme="dark" (the app's Customize choice) or the visitor's system
   prefers dark and the page has NOT pinned data-theme="light". The two dark
   blocks below must be kept identical.
   ========================================================================== */

/* Self-hosted variable fonts (latin subsets, served from /fonts; no
   external font requests anywhere). Inter carries the UI; Hanken Grotesk
   is the brand face (the G in the mark and the wordmark). */
@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-latin-var.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/fonts/hanken-grotesk-latin-var.woff2") format("woff2-variations");
  font-weight: 700 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* core surfaces: paper mat -> panel -> raised card */
  --color-bg: #eae6dc;
  --color-surface: #f4f0e6;
  --color-raised: #fbf8f0;
  --color-text: #24272b;
  --color-divider: rgba(36, 39, 43, 0.18);
  --grid: rgba(36, 39, 43, 0.06);

  /* palette */
  --color-accent: #d1462f;   /* enamel red - CTAs and highlights (user-adjustable in the app) */
  --color-blue: #2f6bb0;     /* blueprint blue - links, secondary/technical accents */
  --color-accent-2: #2f6bb0; /* legacy alias for --color-blue; prefer --color-blue */
  --color-metal: #9aa0a4;    /* sprue grey - muted chrome */
  --on-accent: #fff;         /* text that keeps AA contrast on the enamel accent */

  /* ── The ink pair: the same colours, dark enough to READ ──────────
     Added 2026-08-28 after an accessibility pass measured the light theme.
     The accent and the blue are pitched for CTAs, borders, fills and
     highlights, where 3:1 is the bar and they clear it. As SMALL TEXT on
     paper they do not: enamel red is 3.64:1 on the mat and blueprint blue is
     4.38:1, against the 4.5:1 that AA asks for body-sized text. Every one of
     the five contrast failures on the sign-in screen was one of those two
     used as words.
     THE FIX IS A SECOND TOKEN, NOT A DARKER ACCENT. Changing --color-accent
     would repaint every border, fill and focus ring in the product to fix
     text, and it would quietly overrule the accent the person chose in
     Customize. These sit beside it instead: --color-accent stays the brand,
     --color-accent-ink is that brand at reading weight.
     WHY A MIX RATHER THAN A LITERAL: the accent is user-adjustable, so a
     hardcoded ink would be right for enamel and wrong the moment somebody
     picks workshop green. Mixing toward black follows whatever they choose.
     80% is set by the worst of the four (workshop green needs ~81% to reach
     4.6:1 on the mat); the others land darker than they strictly need, which
     costs nothing and keeps one rule instead of four. */
  --color-accent-ink: color-mix(in srgb, var(--color-accent) 80%, #000);
  --color-blue-ink: color-mix(in srgb, var(--color-blue) 92%, #000);

  /* Muted text, as a token rather than a percentage repeated at each use.
     It was color-mix(text 55%), which reads 3.31:1 on the mat: below AA, and
     the reason "Welcome back. Enter your details to continue." failed. 70%
     reads 5.04:1 and is still visibly secondary to full-strength text. */
  --color-muted: color-mix(in srgb, var(--color-text) 70%, transparent);

  /* the brand mark's own colours. FIXED on purpose: the user can retune
     --color-accent in Customize, but the logo stays the logo. */
  --brand-red: #d1462f;
  --brand-sprue: #9aa0a4;
  --brand-ink: #24272b;
  --brand-blue: #2f6bb0;

  /* status colours (danger is deliberately deeper than the red accent so
     errors still read as errors next to enamel-red buttons) */
  --color-danger: #8f2a1c;
  --color-warn: #a8702a;

  /* neutral ramp. Convention (kept from the original theme): 100 is always
     HIGH contrast against the background, 900 always LOW - in light mode the
     ramp runs ink -> paper, in dark mode it flips. Screens rely on this. */
  --color-neutral-100: #24272b;
  --color-neutral-200: #3a3d41;
  --color-neutral-300: #53565a;
  --color-neutral-400: #6f7378;
  --color-neutral-500: #9a9ea2;
  --color-neutral-600: #b3b0a7;
  --color-neutral-700: #ccc8bc;
  --color-neutral-800: #ded9cc;
  --color-neutral-900: #eae4d7;

  /* accent ramp, same 100-high-contrast convention. Derived from the live
     --color-accent so every tint follows the chosen accent in both themes
     with no per-accent hex tables. */
  --color-accent-100: color-mix(in srgb, var(--color-accent) 55%, var(--color-neutral-100));
  --color-accent-200: color-mix(in srgb, var(--color-accent) 68%, var(--color-neutral-100));
  --color-accent-300: color-mix(in srgb, var(--color-accent) 80%, var(--color-neutral-100));
  --color-accent-400: color-mix(in srgb, var(--color-accent) 91%, var(--color-neutral-100));
  --color-accent-500: var(--color-accent);
  --color-accent-600: color-mix(in srgb, var(--color-accent) 82%, var(--color-bg));
  --color-accent-700: color-mix(in srgb, var(--color-accent) 60%, var(--color-bg));
  --color-accent-800: color-mix(in srgb, var(--color-accent) 30%, var(--color-bg));
  --color-accent-900: color-mix(in srgb, var(--color-accent) 15%, var(--color-bg));

  /* success (workshop green) ramp - same convention */
  --ok-100:#1e3826; --ok-200:#2a4c34; --ok-300:#386243; --ok-400:#437752; --ok-500:#4f8a5f; --ok-600:#6da77c; --ok-700:#93c19e; --ok-800:#bfd8c5; --ok-900:#e3eee6;

  /* type */
  --font-heading: "Inter", system-ui, sans-serif;
  --font-heading-weight: 600;
  --font-body: "Inter", system-ui, sans-serif;
  --font-brand: "Hanken Grotesk", "Inter", system-ui, sans-serif;
  /* mono is part of the language: step numbers, part codes, technical labels */
  --font-mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;

  /* cards carry a hairline ring (kit-part outline) plus a soft drop */
  --shadow-sm: 0 0 0 1px rgba(36,39,43,0.14), 0 1px 2px rgba(36,39,43,0.06);
  --shadow-md: 0 0 0 1px rgba(36,39,43,0.14), 0 8px 26px rgba(36,39,43,0.08);
  --shadow-lg: 0 0 0 1px rgba(36,39,43,0.16), 0 16px 40px rgba(36,39,43,0.14);

  --space-1: 2.8px; --space-2: 5.6px; --space-3: 8.4px; --space-4: 11.2px; --space-6: 16.8px; --space-8: 22.4px;
  /* page-level rhythm: the breathing room between long-form page sections
     (the marketing site and any future long pages) */
  --rhythm-section: clamp(72px, 10vw, 128px);
}

/* the night bench: same kit, lights off (the app's explicit choice) */
[data-theme="dark"] {
  --color-bg: #191413;
  --color-surface: #241d1c;
  --color-raised: #2b2321;
  --color-text: #e9e3e2;
  --color-divider: rgba(233, 227, 226, 0.16);
  --grid: rgba(233, 227, 226, 0.05);

  --color-accent: #d86350;
  --color-blue: #4e8ad0;
  --color-accent-2: #4e8ad0;
  --color-metal: #9aa0a4;
  --on-accent: #191413;

  /* THE INK LIFTS TOWARD WHITE HERE, because contrast on a dark ground comes
     from being lighter, which is the exact opposite of the light theme.
     MEASURED AGAINST THE RAISED CARD, and that correction is the point. The
     first version of this aliased the ink to the accent, on the grounds that
     the dark accents clear AA on --color-bg (#191413): enamel 5.06:1,
     blueprint 5.10:1. That was the wrong ground to check. Light text LOSES
     contrast as the surface beneath it gets lighter, and panels sit on
     --color-surface and cards on --color-raised (#2b2321), where the same two
     read 4.26:1 and 4.30:1. Both under AA, on the surface most text actually
     sits on. The hard case on a dark theme is the LIGHTEST surface, not the
     darkest.
     10% covers the four shipped accents with room for a custom one; enamel
     needs 6% and blueprint 5% to clear 4.6:1 on the raised card. */
  --color-accent-ink: color-mix(in srgb, var(--color-accent) 90%, #fff);
  --color-blue-ink: color-mix(in srgb, var(--color-blue) 90%, #fff);

  /* 60% here rather than the light theme's 70%: light text on a dark ground
     carries further, so the same 70% would read as almost full strength and
     lose the distinction muted text exists to make. 60% is 5.82:1 on the
     bench and 5.28:1 on a panel. */
  --color-muted: color-mix(in srgb, var(--color-text) 60%, transparent);

  --brand-red: #d86350;
  --brand-sprue: #5c6066;
  --brand-ink: #e9e3e2;
  --brand-blue: #4e8ad0;

  --color-danger: #e08a7d;
  --color-warn: #d9a866;

  --color-neutral-100: #e9e3e2;
  --color-neutral-200: #cfc6c4;
  --color-neutral-300: #b1a6a3;
  --color-neutral-400: #948784;
  --color-neutral-500: #7c726e;
  --color-neutral-600: #655c58;
  --color-neutral-700: #4e4643;
  --color-neutral-800: #38312f;
  --color-neutral-900: #262120;

  --ok-100:#e6f2e9; --ok-200:#c6ddcd; --ok-300:#a3c8ae; --ok-400:#87b895; --ok-500:#6fb389; --ok-600:#57996f; --ok-700:#437c58; --ok-800:#305c41; --ok-900:#20402c;

  --shadow-sm: 0 0 0 1px rgba(233,227,226,0.14), 0 1px 2px rgba(0,0,0,0.3);
  --shadow-md: 0 0 0 1px rgba(233,227,226,0.14), 0 12px 34px rgba(0,0,0,0.35);
  --shadow-lg: 0 0 0 1px rgba(233,227,226,0.20), 0 16px 44px rgba(0,0,0,0.45);
}

/* system-dark for pages that do not pin a theme (the site). MUST stay
   identical to the [data-theme="dark"] block above. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg: #191413;
    --color-surface: #241d1c;
    --color-raised: #2b2321;
    --color-text: #e9e3e2;
    --color-divider: rgba(233, 227, 226, 0.16);
    --grid: rgba(233, 227, 226, 0.05);

    --color-accent: #d86350;
    --color-blue: #4e8ad0;
    --color-accent-2: #4e8ad0;
    --color-metal: #9aa0a4;
    --on-accent: #191413;

    /* MUST match the [data-theme="dark"] block, and this pair is the one it
       would be easiest to forget. Leaving them out would not fall back to
       nothing, it would fall back to the LIGHT theme's ink, which is mixed
       toward black: near-black text on a near-black bench, for every visitor
       whose system is dark and who never pinned a theme. Silent, and only on
       other people's machines. */
    --color-accent-ink: color-mix(in srgb, var(--color-accent) 90%, #fff);
    --color-blue-ink: color-mix(in srgb, var(--color-blue) 90%, #fff);
    --color-muted: color-mix(in srgb, var(--color-text) 60%, transparent);

    --brand-red: #d86350;
    --brand-sprue: #5c6066;
    --brand-ink: #e9e3e2;
    --brand-blue: #4e8ad0;

    --color-danger: #e08a7d;
    --color-warn: #d9a866;

    --color-neutral-100: #e9e3e2;
    --color-neutral-200: #cfc6c4;
    --color-neutral-300: #b1a6a3;
    --color-neutral-400: #948784;
    --color-neutral-500: #7c726e;
    --color-neutral-600: #655c58;
    --color-neutral-700: #4e4643;
    --color-neutral-800: #38312f;
    --color-neutral-900: #262120;

    --ok-100:#e6f2e9; --ok-200:#c6ddcd; --ok-300:#a3c8ae; --ok-400:#87b895; --ok-500:#6fb389; --ok-600:#57996f; --ok-700:#437c58; --ok-800:#305c41; --ok-900:#20402c;

    --shadow-sm: 0 0 0 1px rgba(233,227,226,0.14), 0 1px 2px rgba(0,0,0,0.3);
    --shadow-md: 0 0 0 1px rgba(233,227,226,0.14), 0 12px 34px rgba(0,0,0,0.35);
    --shadow-lg: 0 0 0 1px rgba(233,227,226,0.20), 0 16px 44px rgba(0,0,0,0.45);
  }
}
