/*!
 * tdb-tokens.css - TUNING-DATABASE design system
 * v2.0.0 - 2026-08-28 - calibration: workshop
 *
 * GENERATED by tools/palette/emit.py. Do not hand-edit: change the OKLCH
 * definitions in tools/palette/build.py and regenerate, or the contrast
 * guarantees below stop being true.
 *
 * Warm amber signal on cool graphite. Complements the cool product screenshots.
 *
 * Both themes come from one set of OKLCH numbers, which is the whole point.
 * The previous system defined colours here and then let three separate
 * light-mode layers repaint them afterwards - and a repaint cannot know what
 * is behind the text it is repainting, which is why light mode had a class of
 * bug that could not be fixed from inside those layers.
 *
 * Measured on this calibration:
 *   dark    heading  13.9:1   body   9.2:1   muted-on-card   5.3:1   button ink   8.1:1
 *   light   heading  16.2:1   body   9.6:1   muted-on-card   5.7:1   button ink   5.7:1
 *   dark ground luminance 0.0069 - the previous ground was 0.0024, near enough
 *   to pure black that headings sat at 18.5:1 and bloomed.
 */

/* === DARK - the default ================================================= */
:root {
  /* elevation ladder - on a dark ground a surface rises by getting LIGHTER,
     on paper it rises by getting whiter and casting a shadow. The band is
     the alternating section background: it is what gives a long page rhythm. */
  --tdb-sunk:    #080d12;
  --tdb-ground:  #10141a;
  --tdb-band:    #161b21;
  --tdb-surface: #1d2228;
  --tdb-raised:  #272c32;
  --tdb-line:    #32373e;

  /* ink - --tdb-faint measures 2.7:1 on a card and is NOT for text.
     Dividers, disabled affordances and decorative rules only. */
  --tdb-text:  #dfdfe0;
  --tdb-body:  #b5b7ba;
  --tdb-muted: #939598;
  --tdb-faint: #616366;

  /* signal */
  --tdb-accent:     #f1932f;
  --tdb-accent-ink: #0d1116;
  --tdb-support:    #3aadd4;

  /* fixed ink - these deliberately do NOT flip with the theme. Text on a
     white chip stays dark in both themes, because the chip stays white in
     both themes. Reaching for --tdb-text there is exactly how a retrofit
     ends up putting near-white on near-white. */
  --tdb-on-light: #14181d;
  --tdb-on-dark:  #eceef1;

  --tdb-shadow-sm: 0 1px 2px rgba(0,0,0,.45);
  --tdb-shadow-md: 0 6px 18px -6px rgba(0,0,0,.55);
  --tdb-shadow-lg: 0 20px 48px -20px rgba(0,0,0,.70);
  --tdb-shadow-accent: 0 10px 30px -12px color-mix(in srgb, var(--tdb-accent) 55%, transparent);

  /* atmosphere - a light source, so the page reads as a space not a sheet */
  --tdb-wash-accent:  color-mix(in srgb, var(--tdb-accent) 13%, transparent);
  --tdb-wash-support: color-mix(in srgb, var(--tdb-support) 11%, transparent);
  --tdb-success: #3fbf7f;
  --tdb-warning: #e0a33c;
  --tdb-danger:  #ef6f6f;
  --tdb-info:    #6fa8e8;
  /* -- compatibility ----------------------------------------------------
     Every name the previous token file published, kept pointing at the new
     system. Thirty-three call sites depend on these and none of them need to
     change. New work should use the names above. */
  --tdb-bg:            var(--tdb-ground);
  --tdb-bg-elev:       var(--tdb-surface);
  --tdb-surface-hover: var(--tdb-raised);
  --tdb-border:        var(--tdb-line);
  --tdb-border-hover:  color-mix(in srgb, var(--tdb-accent) 45%, var(--tdb-line));
  --tdb-divider:       var(--tdb-line);
  --tdb-text-muted:    var(--tdb-muted);
  --tdb-text-faint:    var(--tdb-faint);
  --tdb-brand:         var(--tdb-accent);
  --tdb-brand-soft:    var(--tdb-support);
  --tdb-brand-deep:    color-mix(in srgb, var(--tdb-accent) 78%, #000);
  --tdb-purple:        var(--tdb-support);
  --tdb-pink:          var(--tdb-support);
  --tdb-shadow-brand:  var(--tdb-shadow-accent);
  --tdb-panel:         var(--tdb-surface);
  --tdb-hair:          color-mix(in srgb, var(--tdb-line) 60%, transparent);
  --tdb-hair-s:        color-mix(in srgb, var(--tdb-line) 40%, transparent);
  --tdb-hair-strong:   var(--tdb-line);
  --tdb-fg:            var(--tdb-text);
  --tdb-card-bg:       var(--tdb-surface);
  --tdb-accent-soft:   color-mix(in srgb, var(--tdb-accent) 14%, transparent);
  --tdb-cyan:          var(--tdb-support);
  --tdb-border-strong: color-mix(in srgb, var(--tdb-line) 70%, var(--tdb-muted));

  /* --- SPACING (8-point) ------------------------------------------------ */
  --tdb-space-1: .25rem;  --tdb-space-2: .5rem;   --tdb-space-3: .75rem;
  --tdb-space-4: 1rem;    --tdb-space-5: 1.25rem; --tdb-space-6: 1.5rem;
  --tdb-space-8: 2rem;    --tdb-space-10: 2.5rem; --tdb-space-12: 3rem;
  --tdb-space-16: 4rem;   --tdb-space-20: 5rem;   --tdb-space-24: 6rem;

  /* --- RADII ------------------------------------------------------------ */
  --tdb-radius-sm: 4px;   --tdb-radius-md: 8px;   --tdb-radius-lg: 12px;
  --tdb-radius-xl: 18px;  --tdb-radius-2xl: 24px; --tdb-radius-pill: 50rem;

  /* --- MOTION ----------------------------------------------------------- */
  --tdb-dur-fast: 140ms; --tdb-dur-base: 240ms; --tdb-dur-slow: 420ms;
  --tdb-ease-out:    cubic-bezier(.16,1,.3,1);
  --tdb-ease-in-out: cubic-bezier(.4,0,.2,1);
  --tdb-ease-spring: cubic-bezier(.34,1.56,.64,1);

  /* --- Z-INDEX ---------------------------------------------------------- */
  --tdb-z-base: 1;   --tdb-z-dropdown: 10; --tdb-z-sticky: 20;
  --tdb-z-fixed: 30; --tdb-z-modal: 50;    --tdb-z-toast: 60;

  /* --- TYPE --------------------------------------------------------------
     Archivo carries a width axis, so display and body come from one family:
     the width contrast is the typographic idea, not an arbitrary pairing.
     JetBrains Mono for what this site is full of - SW and HW numbers, ECU
     families, hex offsets, power figures. */
  --tdb-font-sans: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --tdb-font-display: var(--tdb-font-sans);
  --tdb-font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --tdb-wdth-display: 112;
  --tdb-wdth-body: 100;

  --tdb-fs-xs: .75rem;    --tdb-fs-sm: .875rem;  --tdb-fs-base: 1rem;
  --tdb-fs-lg: 1.125rem;  --tdb-fs-xl: 1.25rem;  --tdb-fs-2xl: 1.5rem;
  --tdb-fs-3xl: 1.875rem; --tdb-fs-4xl: 2.25rem; --tdb-fs-5xl: 3rem;
  --tdb-fs-6xl: 3.75rem;

  --tdb-fw-normal: 400; --tdb-fw-medium: 500; --tdb-fw-semibold: 600;
  --tdb-fw-bold: 700;   --tdb-fw-black: 800;

  --tdb-lh-tight: 1.1; --tdb-lh-snug: 1.3; --tdb-lh-base: 1.6; --tdb-lh-relaxed: 1.75;
  --tdb-tracking-tight: -.022em; --tdb-tracking-normal: 0; --tdb-tracking-wide: .05em;
  --tdb-measure: 66ch;

  /* --- LAYOUT ----------------------------------------------------------- */
  --tdb-container-narrow: 720px; --tdb-container-base: 1140px;
  --tdb-container-wide: 1240px;  --tdb-container-xwide: 1440px;
  --tdb-bp-mobile: 575.98px;  --tdb-bp-tablet: 767.98px;
  --tdb-bp-laptop: 991.98px;  --tdb-bp-desktop: 1199.98px;
}

/* === LIGHT ==============================================================
   Selected by body.light-mode, which is the contract theme-toggle.js and the
   rest of the site already use. Only colour tokens change here; every scale
   above is shared, so a spacing or type decision lives in exactly one place. */
body.light-mode {
  /* elevation ladder - on a dark ground a surface rises by getting LIGHTER,
     on paper it rises by getting whiter and casting a shadow. The band is
     the alternating section background: it is what gives a long page rhythm. */
  --tdb-sunk:    #e8e9eb;
  --tdb-ground:  #f9fafc;
  --tdb-band:    #f1f2f3;
  --tdb-surface: #fdfeff;
  --tdb-raised:  #feffff;
  --tdb-line:    #dbdee2;

  /* ink - --tdb-faint measures 3.8:1 on a card and is NOT for text.
     Dividers, disabled affordances and decorative rules only. */
  --tdb-text:  #1b1d1f;
  --tdb-body:  #414245;
  --tdb-muted: #646669;
  --tdb-faint: #818386;

  /* signal */
  --tdb-accent:     #a54d00;
  --tdb-accent-ink: #ffffff;
  --tdb-support:    #007196;

  /* fixed ink - these deliberately do NOT flip with the theme. Text on a
     white chip stays dark in both themes, because the chip stays white in
     both themes. Reaching for --tdb-text there is exactly how a retrofit
     ends up putting near-white on near-white. */
  --tdb-on-light: #14181d;
  --tdb-on-dark:  #eceef1;

  --tdb-shadow-sm: 0 1px 2px rgba(16,20,26,.06);
  --tdb-shadow-md: 0 8px 22px -10px rgba(16,20,26,.16);
  --tdb-shadow-lg: 0 24px 56px -24px rgba(16,20,26,.24);
  --tdb-shadow-accent: 0 10px 30px -12px color-mix(in srgb, var(--tdb-accent) 55%, transparent);

  /* atmosphere - a light source, so the page reads as a space not a sheet */
  --tdb-wash-accent:  color-mix(in srgb, var(--tdb-accent) 9%, transparent);
  --tdb-wash-support: color-mix(in srgb, var(--tdb-support) 8%, transparent);
  --tdb-success: #1a7f4b;
  --tdb-warning: #8a5a08;
  --tdb-danger:  #b3261e;
  --tdb-info:    #1a5fb4;
}

/* First visit with no stored preference: follow the operating system. Today a
   first visit is always dark no matter what the visitor's machine asks for. */
@media (prefers-color-scheme: light) {
  body.tdb-theme-auto {
  /* elevation ladder - on a dark ground a surface rises by getting LIGHTER,
     on paper it rises by getting whiter and casting a shadow. The band is
     the alternating section background: it is what gives a long page rhythm. */
  --tdb-sunk:    #e8e9eb;
  --tdb-ground:  #f9fafc;
  --tdb-band:    #f1f2f3;
  --tdb-surface: #fdfeff;
  --tdb-raised:  #feffff;
  --tdb-line:    #dbdee2;

  /* ink - --tdb-faint measures 3.8:1 on a card and is NOT for text.
     Dividers, disabled affordances and decorative rules only. */
  --tdb-text:  #1b1d1f;
  --tdb-body:  #414245;
  --tdb-muted: #646669;
  --tdb-faint: #818386;

  /* signal */
  --tdb-accent:     #a54d00;
  --tdb-accent-ink: #ffffff;
  --tdb-support:    #007196;

  /* fixed ink - these deliberately do NOT flip with the theme. Text on a
     white chip stays dark in both themes, because the chip stays white in
     both themes. Reaching for --tdb-text there is exactly how a retrofit
     ends up putting near-white on near-white. */
  --tdb-on-light: #14181d;
  --tdb-on-dark:  #eceef1;

  --tdb-shadow-sm: 0 1px 2px rgba(16,20,26,.06);
  --tdb-shadow-md: 0 8px 22px -10px rgba(16,20,26,.16);
  --tdb-shadow-lg: 0 24px 56px -24px rgba(16,20,26,.24);
  --tdb-shadow-accent: 0 10px 30px -12px color-mix(in srgb, var(--tdb-accent) 55%, transparent);

  /* atmosphere - a light source, so the page reads as a space not a sheet */
  --tdb-wash-accent:  color-mix(in srgb, var(--tdb-accent) 9%, transparent);
  --tdb-wash-support: color-mix(in srgb, var(--tdb-support) 8%, transparent);
  --tdb-success: #1a7f4b;
  --tdb-warning: #8a5a08;
  --tdb-danger:  #b3261e;
  --tdb-info:    #1a5fb4;
  }
}

/* === PHOTO-BACKED SURFACES ==============================================
   The hero sits over a photograph. The photograph does not get lighter when
   the page does, so nothing written on it may flip either. Pinning the whole
   local palette here is more reliable than chasing each declaration, and it
   covers the parallel --text / --muted names as well as the --tdb-* ones.

   This is also the one case the contrast audit cannot see: the photograph is a
   positioned SIBLING, not an ancestor, so a composited measurement reads the
   hero as text on the page background and reports a clean pass while the words
   are unreadable. Look at the render, not only the number.                   */
.tdbh, #hero, .hs-slide, .hero-copy {
  --tdb-text:  #dfdfe0;
  --tdb-body:  #b5b7ba;
  --tdb-muted: #b5b7ba;
  --text:      #dfdfe0;
  --text-2:    #b5b7ba;
  --text-3:    #b5b7ba;
  --muted:     #b5b7ba;
  --fg:        #dfdfe0;
  --tdb-support: #3aadd4;
  --tdb-accent: #f1932f;
  --tdb-accent-ink: #0d1116;
}

/* === REDUCED MOTION ===================================================== */
@media (prefers-reduced-motion: reduce) {
  :root { --tdb-dur-fast: 0ms; --tdb-dur-base: 0ms; --tdb-dur-slow: 0ms; }
}

/* === UTILITIES (opt-in, unchanged from v1) ============================== */
.tdb-container { max-width: var(--tdb-container-wide); margin: 0 auto; padding: 0 var(--tdb-space-6); }
.tdb-container-narrow { max-width: var(--tdb-container-narrow); margin: 0 auto; padding: 0 var(--tdb-space-6); }
.tdb-stack > * + * { margin-top: var(--tdb-space-4); }
.tdb-stack-sm > * + * { margin-top: var(--tdb-space-2); }
.tdb-stack-lg > * + * { margin-top: var(--tdb-space-6); }
.tdb-cluster { display: flex; flex-wrap: wrap; gap: var(--tdb-space-3); }
.tdb-text-brand { color: var(--tdb-accent); }
.tdb-text-success { color: var(--tdb-success); }
.tdb-text-muted { color: var(--tdb-muted); }
.tdb-text-faint { color: var(--tdb-faint); }

/* Section rhythm. Alternating these is what stops a very long page from
   reading as one endless sheet. */
.tdb-band { background: var(--tdb-band); }
.tdb-sunk { background: var(--tdb-sunk); }

*:focus-visible {
  outline: 2px solid var(--tdb-accent);
  outline-offset: 2px;
  border-radius: var(--tdb-radius-sm);
}

.tdb-btn, button.tdb-btn, a.tdb-btn, .tdb-touch-target {
  min-height: 44px; min-width: 44px;
  display: inline-flex; align-items: center; justify-content: center;
}
