/* ============================================================================
   DESIGN TOKENS — GENERATED FILE. Do not hand-edit.

   Source: firebase_frontend/src/styles/tokens.json. Regenerate with
   `node tools/design-tokens.mjs` (`npm run design:tokens` from
   firebase_frontend/) after any edit to tokens.json — including an edit that
   comes back from a Claude Design `/design-sync` round trip, see
   docs/GUIDE_DESIGN_SYNC.md.

   WHAT THIS FILE IS, AND IS NOT (#444/#406):

   - Loaded on EVERY page (#1137): app/index.html and .harness.html link
     `/shared/tokens.css` before `/shared/styles.css`. Names both files
     define (`--text-*`/`--weight-*`) resolve to styles.css's legacy
     values on `:root`, so legacy screens are unchanged; the React screens
     named in tokens.json's `characterScopes` get the Character ramp from
     the scoped block below instead of eleven copied lines each.
   - The /design gallery imports this file too, after styles.css, so there
     its `:root` --text-* (Character) wins, as it always has.

   WHERE EVERY VALUE CAME FROM — seeded from docs/DESIGN_INVENTORY.md, not
   invented; full rationale (why `--color-text-muted` is Calm's `--ink-soft`
   and not `--ink-mute`, why `--color-accent`/`--color-danger` are NOT the
   legacy `--accent`/`--danger`, why `--stage-off` is not Calm's own
   `--st-off`) is in tools/design-tokens.mjs's own header and this file's git
   history — the short version is: every one of those three legacy values
   measures below 4.5:1 contrast on white (verified by
   tools/token-contrast.mjs), so the token holds the nearest ALREADY-REAL
   value in the same palette/hue family that passes, never a newly invented
   colour. Type scale: `public/shared/styles.css`'s own `--text-3xs` …
   `--text-5xl` / `--weight-normal` … `--weight-bold`, byte-identical.
   Spacing: GUIDE_SPACING_SCALE.md §4's ten-step proposal, verbatim. Radii:
   the inventory's most-repeated border-radius values plus the pill shape
   (999px) every chip/badge already uses. Shadows: four values already
   repeated across 2+ route CSS files in the inventory. Motion: durations/
   easing already in real, repeated use in `event.css`/`styles.css`.

   Run `node tools/token-contrast.mjs` to print the full text/background
   contrast matrix this file is held to (every pair ≥ 4.5:1).
   SIZE LAYER (#1137): tokens.json's `size` pairs. Desktop on `:root`,
   phone in the one `@media` block at the end — see
   docs/GUIDE_MOBILE_TOKENS.md, and tools/design-token-lint.mjs for the rule
   that keeps component CSS from resizing itself per breakpoint.
   ROLE LAYER (#1137): tokens.json's `role` — thread row vs message.
   ============================================================================ */
:root {
  --color-bg: #f8f7f6;
  --color-surface: #ffffff;
  --color-border: #e7e3e1;
  --color-text: #1b1718;
  --color-text-muted: #57504f;
  --color-accent: #c4006b;
  --color-success: #15803d;
  --color-success-bg: #dcfce7;
  --color-warning: #b45309;
  --color-warning-bg: #fef3c7;
  --color-danger: #b91c1c;
  --color-danger-bg: #fee2e2;
  --color-danger-border: #f8b4b4;

  --stage-ready: #15803d;        --stage-ready-bg: #dcfce7;
  --stage-prep: #b45309;        --stage-prep-bg: #fef3c7;
  --stage-confirmed: #1d4ed8;        --stage-confirmed-bg: #dbeafe;
  --stage-pipeline: #6d28d9;        --stage-pipeline-bg: #ede9fe;
  --stage-idle: #57504f;        --stage-idle-bg: #f3f1f0;
  --stage-off: #6e6765;        --stage-off-bg: #f3f1f0;

  --text-3xs: 12px;
  --text-2xs: 12px;
  --text-xs: 12px;
  --text-sm: 12px;
  --text-base: 13px;
  --text-lg: 14px;
  --text-xl: 14px;
  --text-2xl: 16px;
  --text-3xl: 16px;
  --text-4xl: 20px;
  --text-5xl: 24px;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 600;

  --space-1: 2px;
  --space-2: 4px;
  --space-3: 6px;
  --space-4: 8px;
  --space-5: 10px;
  --space-6: 12px;
  --space-7: 14px;
  --space-8: 16px;
  --space-9: 20px;
  --space-10: 24px;
  --space-11: 28px;
  --space-12: 32px;
  --space-13: 40px;
  --space-14: 48px;
  --space-15: 56px;
  --space-16: 64px;

  --radius-sm: 4px;
  --radius-md: 4px;
  --radius-lg: 6px;
  --radius-full: 4px;
  --radius-pill: 999px;
  --radius-sheet: 10px;

  --border-hair: 1px;
  --border-thick: 2px;
  --border-spine: 3px;

  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
  --shadow-chip: none;
  --shadow-md: 0 8px 30px rgba(0, 0, 0, 0.18);
  --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.3);
  --shadow-rise: 0 -18px 36px -20px rgba(23, 26, 29, 0.35);
  --shadow-control: inset 0 1px 0 rgba(255, 255, 255, .75), 0 1px 1.5px -.5px rgba(23, 26, 29, .14);
  --shadow-bar: 0 6px 14px -12px rgba(23, 26, 29, .45);
  --shadow-float: 0 6px 18px -6px rgba(23, 26, 29, .32), 0 1px 3px rgba(23, 26, 29, .12);

  --motion-fast: 120ms;
  --motion-base: 180ms;
  --motion-slow: 260ms;
  --motion-ease: cubic-bezier(0.4, 0, 0.2, 1);

  --layout-sheet: 800px;
  --layout-menu: 228px;
  --layout-menu-wide: 280px;
  --layout-dialog: 440px;
  --layout-rail: 212px;
  --layout-list: 352px;
  --layout-popover: 230px;
  --layout-search: 240px;
  --layout-search-min: 120px;
  --layout-select-min: 160px;
  --layout-field: 220px;
  --layout-page-content: 1180px;

  /* size layer — desktop values; the phone values are in the ONE block below */
  --control-h-xs: 22px;
  --control-h-sm: 24px;
  --control-h-md: 32px;
  --control-h-lg: 36px;
  --control-px: 12px;
  --control-px-sm: 8px;
  --control-gap: 6px;
  --field-min-h: auto;
  --row-min-h: auto;
  --fs-control: 13px;
  --fs-body: 13px;
  --fs-meta: 12px;
  --fs-title: 16px;
  --fs-display: 24px;
  --fs-field: 13px;
  --icon: 16px;
  --page-pad: 20px;
  --section-gap: 16px;
  --radius-control: 4px;
  --bar-top-h: 58px;
  --bar-bottom-h: 0px;
  --hit-min: 0px;
  --hit-gap: 0px;
  --msg-gap: 8px;
  --msg-pad-y: 10px;
  --msg-pad-x: 14px;
  --msg-meta-fs: 12px;
  --msg-side-indent: 48px;
  --msg-clamp-lines: 12;
}

/* Role tokens — what a thing IS decides its mark (tokens.json `role`):
   a thread ROW in a list carries the accent stripe (--thread-accent-*); a
   MESSAGE inside an open thread never does (--msg-*). */
:root, :where(.dash-page, .ev-page, .em-page, .cl-page, .vn-page, .sf-page, .eq-page, .crm-page, .ir-page, .ps-page, .pts-page, .sd-page, .mg-page, .vd-page, .ym-page, .rc-page, .tnd, .tnd-mobile) {
  --thread-accent-w: var(--border-spine);
  --thread-accent-r: var(--radius-sm);
  --msg-bg: var(--card);
  --msg-divider: var(--line);
  --msg-radius: var(--radius-lg);
  --msg-bubble-ours-bg: color-mix(in srgb, var(--tint-confirmed) 45%, var(--card));
  --msg-bubble-unknown-bg: color-mix(in srgb, var(--tint-prep) 45%, var(--card));
  --msg-max-w: 48rem;
}

/* The Character type ramp (type.size) for the screens listed in
   tokens.json's characterScopes — zero specificity, so a page root's own
   rule can still say something else, and nothing here outranks it. */
:where(.dash-page, .ev-page, .em-page, .cl-page, .vn-page, .sf-page, .eq-page, .crm-page, .ir-page, .ps-page, .pts-page, .sd-page, .mg-page, .vd-page, .ym-page, .rc-page, .tnd, .tnd-mobile) {
  --text-3xs: 12px;
  --text-2xs: 12px;
  --text-xs: 12px;
  --text-sm: 12px;
  --text-base: 13px;
  --text-lg: 14px;
  --text-xl: 14px;
  --text-2xl: 16px;
  --text-3xl: 16px;
  --text-4xl: 20px;
  --text-5xl: 24px;
  --radius: var(--radius-md);
}

/* ==========================================================================
   THE PHONE BLOCK — the only place a phone size is written (#1137).
   A phone (≤767px) and a touch screen in landscape (≤500px tall). Tokens
   only: no selector in here styles a component. A component that needs a
   different LAYOUT on a phone (a grid that stacks, a duplicate it hides)
   keeps its own block for that; one that only needs to be a different SIZE
   reads these tokens and has no block at all.
   ========================================================================== */
@media (max-width: 767px), (pointer: coarse) and (max-height: 500px) {
  :root {
    --control-h-xs: 28px;
    --control-h-sm: 28px;
    --control-h-md: 34px;
    --control-h-lg: 40px;
    --control-px: 12px;
    --control-px-sm: 10px;
    --control-gap: 6px;
    --field-min-h: 44px;
    --row-min-h: 44px;
    --fs-control: 14px;
    --fs-body: 14px;
    --fs-meta: 12px;
    --fs-title: 18px;
    --fs-display: 20px;
    --fs-field: 16px;
    --icon: 18px;
    --page-pad: 16px;
    --section-gap: 12px;
    --radius-control: 4px;
    --bar-top-h: 44px;
    --bar-bottom-h: 58px;
    --hit-min: 44px;
    --hit-gap: 8px;
    --msg-gap: 6px;
    --msg-pad-y: 8px;
    --msg-pad-x: 12px;
    --msg-meta-fs: 12px;
    --msg-side-indent: 20px;
    --msg-clamp-lines: 10;
  }
  :where(.dash-page, .ev-page, .em-page, .cl-page, .vn-page, .sf-page, .eq-page, .crm-page, .ir-page, .ps-page, .pts-page, .sd-page, .mg-page, .vd-page, .ym-page, .rc-page, .tnd, .tnd-mobile) {
    --text-base: 14px;
    --text-lg: 15px;
  }
}

/* Any touch screen at any width: fields at 16px so iOS Safari never zooms. */
@media (pointer: coarse) {
  :root {
    --fs-field: 16px;
  }
}
