/*
 * ui-tokens.css, design tokens for the UI rebuild (issue #518).
 *
 * Load order in the new shell (#519):
 *   <link rel="stylesheet" href="/static/css/ui-tokens.css">
 *   <link rel="stylesheet" href="/static/css/ui.css">
 *
 * This file defines variables only. It declares no selectors that paint
 * anything, so it is safe to load next to the old app.css + pages.css
 * during the strangler migration. Every name is prefixed --ui- and none
 * of those names exist in app.css or pages.css, so neither file can
 * shadow the other. app.css owns --color-*, --bg-*, --space-*, --text-*;
 * this file never writes those.
 *
 * THEME CONTRACT
 *   no class on <html>   -> dark   (the default; issue #518)
 *   .theme-dark          -> dark   (explicit, same values)
 *   .theme-light         -> light
 *   .theme-auto          -> follows prefers-color-scheme
 * The shell stamps one of those three classes on <html> before paint.
 * The theme classes are not tied to :root, so any container can hold a
 * themed island; the styleguide uses that to show both themes at once.
 * The old base.html toggle writes .dark-mode; that class is a no-op here
 * because dark is already the unqualified default, so an old page that
 * happens to load this file still renders dark.
 *
 * LAYERING
 *   1. Ramps      raw hex, the only place a hex literal appears.
 *   2. Roles      surface/text/line/accent/status. Components read these.
 *   3. Scales     space, type, radius, shadow, motion, z-index, layout.
 * Components must never reference a ramp step directly. Re-theming the
 * app means re-pointing the role block, nothing else.
 *
 * CONTRAST
 * Every foreground/background pair in the role block was checked against
 * WCAG 2.1: 4.5:1 for text, 3:1 for control boundaries and status dots.
 * Ratios are in the comments. Changing a role value means re-checking it.
 */

/* ============================================================
   1. RAMPS
   ============================================================ */

:root {
  /* Neutral graphite. Near-zero chroma with a slight cool cast so blue,
     green, amber and red all stay separable on top of it. */
  --ui-ramp-ink-950: #0b0c0e;
  --ui-ramp-ink-900: #111317;
  --ui-ramp-ink-850: #16181d;
  --ui-ramp-ink-800: #1c1f25;
  --ui-ramp-ink-750: #23262d;
  --ui-ramp-ink-700: #2f333b;
  --ui-ramp-ink-600: #454b55;
  --ui-ramp-ink-500: #6b7280;
  --ui-ramp-ink-400: #838b99;
  --ui-ramp-ink-300: #a7aeb9;
  --ui-ramp-ink-200: #d7dbe1;
  --ui-ramp-ink-150: #e4e7eb;
  --ui-ramp-ink-100: #eceef2;
  --ui-ramp-ink-50:  #f6f7f9;
  --ui-ramp-ink-0:   #ffffff;

  /* Accent blue. Doubles as the "info" status: with red reserved for
     live and the warm band spent on warn/danger, one cool hue carries
     both the primary action and the informational status. */
  --ui-ramp-blue-300: #7ab4f9;
  --ui-ramp-blue-400: #5aa2f7;
  --ui-ramp-blue-500: #2f7fe0;
  --ui-ramp-blue-600: #1c62c4;
  --ui-ramp-blue-700: #164e9c;
  --ui-ramp-blue-tint-dark:  #101b2b;
  --ui-ramp-blue-tint-light: #e7f0fc;

  --ui-ramp-green-300: #6fd79a;
  --ui-ramp-green-400: #4fc07d;
  --ui-ramp-green-600: #157f4c;
  --ui-ramp-green-700: #10613a;
  --ui-ramp-green-tint-dark:  #12241a;
  --ui-ramp-green-tint-light: #e6f4ec;

  --ui-ramp-amber-300: #f0c162;
  --ui-ramp-amber-400: #e0a83a;
  --ui-ramp-amber-600: #8a5a06;
  --ui-ramp-amber-700: #7a4e05;
  --ui-ramp-amber-tint-dark:  #251d0e;
  --ui-ramp-amber-tint-light: #fbf0dc;

  --ui-ramp-orange-300: #f79c68;
  --ui-ramp-orange-400: #f0803c;
  --ui-ramp-orange-500: #b4491a;
  --ui-ramp-orange-600: #a8400f;
  --ui-ramp-orange-700: #9c3a13;
  --ui-ramp-orange-tint-dark:  #26170f;
  --ui-ramp-orange-tint-light: #fdeade;

  /* Red. Reserved for live capture. Nothing else in the system may use
     this ramp; see the note on --ui-live below. */
  --ui-ramp-red-300: #ff7b76;
  --ui-ramp-red-400: #ff5c57;
  --ui-ramp-red-600: #c02f28;
  --ui-ramp-red-700: #a82c26;
  --ui-ramp-red-ink:          #1a0708;
  --ui-ramp-red-tint-dark:    #2a1213;
  --ui-ramp-red-tint-light:   #fdeaea;
}

/* ============================================================
   2. ROLES, dark (default)
   ============================================================ */

:root,
.theme-dark {
  color-scheme: dark;

  /* Surfaces, back to front. */
  --ui-canvas:         var(--ui-ramp-ink-950);
  --ui-surface:        var(--ui-ramp-ink-900);
  --ui-surface-raised: var(--ui-ramp-ink-850);
  --ui-overlay:        var(--ui-ramp-ink-800);
  --ui-field:          var(--ui-ramp-ink-850);
  --ui-hover:          rgba(255, 255, 255, 0.045);
  --ui-active:         rgba(255, 255, 255, 0.075);
  --ui-selected:       #172130;
  --ui-scrim:          rgba(4, 6, 10, 0.62);

  /* Lines. --ui-line and --ui-line-strong are decorative rules; they are
     deliberately below 3:1 so a dense table does not turn into a grid of
     cages. --ui-control-line is the boundary of an interactive control
     and clears 3:1 on every surface above (3.41 on overlay, 4.05 on
     canvas), which is what WCAG 1.4.11 asks for. */
  --ui-line:         var(--ui-ramp-ink-750);
  --ui-line-strong:  var(--ui-ramp-ink-700);
  --ui-control-line: var(--ui-ramp-ink-500);

  /* Text. Ratios against --ui-canvas / --ui-surface / --ui-overlay:
     text 16.9 / 16.0 / 14.2, text-2 8.8 / 8.3 / 7.4,
     text-3 5.7 / 5.4 / 4.8. */
  --ui-text:          var(--ui-ramp-ink-100);
  --ui-text-2:        var(--ui-ramp-ink-300);
  --ui-text-3:        var(--ui-ramp-ink-400);
  --ui-text-disabled: var(--ui-ramp-ink-500);
  --ui-text-on-fill:  var(--ui-ramp-ink-0);

  /* Accent. On dark the filled button is the luminous one and carries a
     near-black label (7.13:1); white on blue-500 (the closest solid,
     not this ramp step) only reaches 4.01 and fails, and white on this
     ramp step (blue-400) is worse still at 2.64, which is why
     --ui-accent-on is ink, not white. */
  --ui-accent:        var(--ui-ramp-blue-400);
  --ui-accent-hover:  var(--ui-ramp-blue-300);
  --ui-accent-fill:   var(--ui-ramp-blue-400);
  --ui-accent-on:     #06121f;
  --ui-accent-line:   var(--ui-ramp-blue-500);
  --ui-accent-tint:   var(--ui-ramp-blue-tint-dark);
  --ui-accent-text:   var(--ui-ramp-blue-400);

  --ui-ok:        var(--ui-ramp-green-400);
  --ui-ok-text:   var(--ui-ramp-green-300);
  --ui-ok-tint:   var(--ui-ramp-green-tint-dark);

  --ui-warn:      var(--ui-ramp-amber-400);
  --ui-warn-text: var(--ui-ramp-amber-300);
  --ui-warn-tint: var(--ui-ramp-amber-tint-dark);

  /* Failure is orange, not red. Red belongs to live capture and nothing
     else, so the warm band carries both warn and danger and the eye
     never has to ask which red it is looking at. */
  --ui-danger:      var(--ui-ramp-orange-400);
  --ui-danger-text: var(--ui-ramp-orange-300);
  --ui-danger-tint: var(--ui-ramp-orange-tint-dark);
  --ui-danger-fill: var(--ui-ramp-orange-500);
  --ui-danger-on:   var(--ui-ramp-ink-0);

  /* Live. The only red surface in the system (#526). */
  --ui-live:      var(--ui-ramp-red-400);
  --ui-live-text: var(--ui-ramp-red-300);
  --ui-live-tint: var(--ui-ramp-red-tint-dark);
  --ui-live-fill: var(--ui-ramp-red-400);
  --ui-live-on:   var(--ui-ramp-red-ink);

  /* Recording indicator for the dictation mic (#522). Aliased to live on
     purpose: a hot mic is a live capture. Re-point this one line if the
     Live section is to keep red exclusively. */
  --ui-recording: var(--ui-live);

  --ui-ring-color: var(--ui-ramp-blue-300);

  --ui-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.45);
  --ui-shadow-2: 0 6px 16px rgba(0, 0, 0, 0.5);
  --ui-shadow-3: 0 20px 48px rgba(0, 0, 0, 0.62);

  --ui-skeleton-base:  var(--ui-ramp-ink-800);
  --ui-skeleton-sheen: var(--ui-ramp-ink-700);
}

/* ============================================================
   2b. ROLES, light
   ============================================================ */

.theme-light {
  color-scheme: light;

  --ui-canvas:         var(--ui-ramp-ink-50);
  --ui-surface:        var(--ui-ramp-ink-0);
  --ui-surface-raised: var(--ui-ramp-ink-0);
  --ui-overlay:        var(--ui-ramp-ink-0);
  --ui-field:          var(--ui-ramp-ink-0);
  --ui-hover:          rgba(15, 23, 42, 0.04);
  --ui-active:         rgba(15, 23, 42, 0.07);
  --ui-selected:       var(--ui-ramp-blue-tint-light);
  --ui-scrim:          rgba(15, 23, 42, 0.38);

  --ui-line:         var(--ui-ramp-ink-150);
  --ui-line-strong:  #d3d7dd;
  --ui-control-line: #767c85;

  /* text 16.6 / 17.8, text-2 7.2 / 7.7, text-3 4.6 / 4.9
     against --ui-canvas / --ui-surface. */
  --ui-text:          #15181d;
  --ui-text-2:        #4c545f;
  --ui-text-3:        #69717d;
  --ui-text-disabled: #8b919a;
  --ui-text-on-fill:  var(--ui-ramp-ink-0);

  /* On light the filled button is the deep one and carries white
     (5.84:1). Same rule as dark, mirrored: the fill always sits at the
     far end of the luminance range from its own label. */
  --ui-accent:        var(--ui-ramp-blue-600);
  --ui-accent-hover:  var(--ui-ramp-blue-700);
  --ui-accent-fill:   var(--ui-ramp-blue-600);
  --ui-accent-on:     var(--ui-ramp-ink-0);
  --ui-accent-line:   var(--ui-ramp-blue-600);
  --ui-accent-tint:   var(--ui-ramp-blue-tint-light);
  --ui-accent-text:   var(--ui-ramp-blue-600);

  --ui-ok:        var(--ui-ramp-green-600);
  --ui-ok-text:   var(--ui-ramp-green-700);
  --ui-ok-tint:   var(--ui-ramp-green-tint-light);

  --ui-warn:      var(--ui-ramp-amber-600);
  --ui-warn-text: var(--ui-ramp-amber-700);
  --ui-warn-tint: var(--ui-ramp-amber-tint-light);

  --ui-danger:      var(--ui-ramp-orange-500);
  --ui-danger-text: var(--ui-ramp-orange-700);
  --ui-danger-tint: var(--ui-ramp-orange-tint-light);
  --ui-danger-fill: var(--ui-ramp-orange-600);
  --ui-danger-on:   var(--ui-ramp-ink-0);

  --ui-live:      var(--ui-ramp-red-600);
  --ui-live-text: var(--ui-ramp-red-700);
  --ui-live-tint: var(--ui-ramp-red-tint-light);
  --ui-live-fill: var(--ui-ramp-red-600);
  --ui-live-on:   var(--ui-ramp-ink-0);

  --ui-recording: var(--ui-live);

  --ui-ring-color: var(--ui-ramp-blue-600);

  --ui-shadow-1: 0 1px 2px rgba(15, 23, 42, 0.08);
  --ui-shadow-2: 0 6px 16px rgba(15, 23, 42, 0.1);
  --ui-shadow-3: 0 20px 48px rgba(15, 23, 42, 0.16);

  --ui-skeleton-base:  #eceef2;
  --ui-skeleton-sheen: #f8f9fb;
}

/* .theme-auto follows the operating system. The light half is a copy of
   the block above because a custom property block cannot be @extended;
   keep the two in sync when re-theming. */
@media (prefers-color-scheme: light) {
  .theme-auto {
    color-scheme: light;

    --ui-canvas:         var(--ui-ramp-ink-50);
    --ui-surface:        var(--ui-ramp-ink-0);
    --ui-surface-raised: var(--ui-ramp-ink-0);
    --ui-overlay:        var(--ui-ramp-ink-0);
    --ui-field:          var(--ui-ramp-ink-0);
    --ui-hover:          rgba(15, 23, 42, 0.04);
    --ui-active:         rgba(15, 23, 42, 0.07);
    --ui-selected:       var(--ui-ramp-blue-tint-light);
    --ui-scrim:          rgba(15, 23, 42, 0.38);

    --ui-line:         var(--ui-ramp-ink-150);
    --ui-line-strong:  #d3d7dd;
    --ui-control-line: #767c85;

    --ui-text:          #15181d;
    --ui-text-2:        #4c545f;
    --ui-text-3:        #69717d;
    --ui-text-disabled: #8b919a;
    --ui-text-on-fill:  var(--ui-ramp-ink-0);

    --ui-accent:        var(--ui-ramp-blue-600);
    --ui-accent-hover:  var(--ui-ramp-blue-700);
    --ui-accent-fill:   var(--ui-ramp-blue-600);
    --ui-accent-on:     var(--ui-ramp-ink-0);
    --ui-accent-line:   var(--ui-ramp-blue-600);
    --ui-accent-tint:   var(--ui-ramp-blue-tint-light);
    --ui-accent-text:   var(--ui-ramp-blue-600);

    --ui-ok:        var(--ui-ramp-green-600);
    --ui-ok-text:   var(--ui-ramp-green-700);
    --ui-ok-tint:   var(--ui-ramp-green-tint-light);

    --ui-warn:      var(--ui-ramp-amber-600);
    --ui-warn-text: var(--ui-ramp-amber-700);
    --ui-warn-tint: var(--ui-ramp-amber-tint-light);

    --ui-danger:      var(--ui-ramp-orange-500);
    --ui-danger-text: var(--ui-ramp-orange-700);
    --ui-danger-tint: var(--ui-ramp-orange-tint-light);
    --ui-danger-fill: var(--ui-ramp-orange-600);
    --ui-danger-on:   var(--ui-ramp-ink-0);

    --ui-live:      var(--ui-ramp-red-600);
    --ui-live-text: var(--ui-ramp-red-700);
    --ui-live-tint: var(--ui-ramp-red-tint-light);
    --ui-live-fill: var(--ui-ramp-red-600);
    --ui-live-on:   var(--ui-ramp-ink-0);

    --ui-recording: var(--ui-live);

    --ui-ring-color: var(--ui-ramp-blue-600);

    --ui-shadow-1: 0 1px 2px rgba(15, 23, 42, 0.08);
    --ui-shadow-2: 0 6px 16px rgba(15, 23, 42, 0.1);
    --ui-shadow-3: 0 20px 48px rgba(15, 23, 42, 0.16);

    --ui-skeleton-base:  #eceef2;
    --ui-skeleton-sheen: #f8f9fb;
  }
}

/* ============================================================
   3. SCALES (theme independent)
   ============================================================ */

:root {
  /* --- Type ------------------------------------------------ */
  /* System stacks only. No webfont, no CDN, no build step: the app is
     used from the field over a box uplink and a font round trip there is
     a blank page. */
  --ui-font-ui: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  /* Editorial serif, page and section titles only. This is the one piece
     of the old amber/navy restyle worth keeping; swap it to
     var(--ui-font-ui) to go all-sans. */
  --ui-font-display: "Iowan Old Style", Charter, Georgia, "Times New Roman",
    serif;
  --ui-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    "Liberation Mono", monospace;

  --ui-fs-3xs: 0.6875rem; /* 11px, rail labels, table micro-labels */
  --ui-fs-2xs: 0.75rem;   /* 12px, captions, badge text */
  --ui-fs-xs:  0.8125rem; /* 13px, dense table cells */
  --ui-fs-sm:  0.875rem;  /* 14px, body default */
  --ui-fs-md:  0.9375rem; /* 15px, reading text, transcripts */
  --ui-fs-lg:  1.0625rem; /* 17px, card titles */
  --ui-fs-xl:  1.3125rem; /* 21px, section titles */
  --ui-fs-2xl: 1.625rem;  /* 26px, page titles */
  --ui-fs-3xl: 2rem;      /* 32px, stat values */

  --ui-lh-tight:  1.2;
  --ui-lh-snug:   1.35;
  --ui-lh-normal: 1.5;
  --ui-lh-loose:  1.7;

  --ui-fw-regular:  400;
  --ui-fw-medium:   500;
  --ui-fw-semibold: 600;
  --ui-fw-bold:     700;

  --ui-tracking-caps:  0.08em;
  --ui-tracking-id:    0.02em;
  --ui-tracking-tight: -0.01em;

  /* --- Space (4px base) ------------------------------------ */
  --ui-space-0:   0;
  --ui-space-px:  1px;
  --ui-space-05:  0.125rem; /* 2 */
  --ui-space-1:   0.25rem;  /* 4 */
  --ui-space-2:   0.5rem;   /* 8 */
  --ui-space-3:   0.75rem;  /* 12 */
  --ui-space-4:   1rem;     /* 16 */
  --ui-space-5:   1.25rem;  /* 20 */
  --ui-space-6:   1.5rem;   /* 24 */
  --ui-space-8:   2rem;     /* 32 */
  --ui-space-10:  2.5rem;   /* 40 */
  --ui-space-12:  3rem;     /* 48 */
  --ui-space-16:  4rem;     /* 64 */

  /* --- Radius ---------------------------------------------- */
  --ui-radius-xs:   3px;
  --ui-radius-sm:   5px;
  --ui-radius-md:   8px;
  --ui-radius-lg:   12px;
  --ui-radius-xl:   16px;
  --ui-radius-pill: 999px;

  /* --- Motion ---------------------------------------------- */
  --ui-dur-1: 120ms;
  --ui-dur-2: 180ms;
  --ui-dur-3: 260ms;
  --ui-ease-out:    cubic-bezier(0.2, 0.8, 0.3, 1);
  --ui-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);

  /* --- Z layers -------------------------------------------- */
  --ui-z-base:     0;
  --ui-z-sticky:   100;
  --ui-z-rail:     200;
  --ui-z-dropdown: 300;
  --ui-z-scrim:    400;
  --ui-z-drawer:   410;
  --ui-z-palette:  500;
  --ui-z-toast:    600;
  --ui-z-tooltip:  700;

  /* --- Breakpoints ------------------------------------------
     CSS cannot read a custom property inside a media query, so the
     numbers below are duplicated as literals in ui.css. They live here
     so JS can read them (getComputedStyle(document.documentElement)
     .getPropertyValue('--ui-bp-md')) and so there is one written record
     of the contract every section codes against:

       < 768px            phone. Rail becomes a bottom tab bar, drawers
                          become full-screen sheets, tables scroll in
                          their own container. Audit width: 375px.
       >= 768px           the slim rail appears. Audit width: 768px.
       >= 1200px          content gets its max width and detail pages may
                          run a second column. Audit width: 1440px.
     ---------------------------------------------------------- */
  --ui-bp-sm: 480px;
  --ui-bp-md: 768px;
  --ui-bp-lg: 1200px;
  --ui-bp-xl: 1440px;

  /* --- Layout ---------------------------------------------- */
  --ui-rail-w:     76px;
  --ui-tabbar-h:   56px;
  --ui-header-h:   52px;
  --ui-drawer-w:   480px;
  --ui-palette-w:  640px;
  --ui-content-max: 1280px;
  --ui-prose-max:  72ch;
  --ui-row-h:      40px;
  --ui-row-h-dense: 32px;
  --ui-tap-min:    44px;
  --ui-focus-ring: 0 0 0 2px var(--ui-canvas), 0 0 0 4px var(--ui-ring-color);
}
