/* ============================================================================
 * tokens.css — Team Portal design tokens (Phase 1 Task 1)
 *
 * Source of truth: window.dcTok in the Claude Design handoff bundle
 * (project/redesign/icons-and-mockups.jsx) + the metrics catalogued in
 * docs/research/design-analysis/design-system-impl.md SS2.
 *
 * These custom properties are a PUBLIC API: every later component stylesheet
 * consumes them. Do not rename or retune values without a design-delta entry;
 * tests/test_design_tokens.py pins the canonical values.
 *
 * The portal is LIGHT-ONLY. No dark-theme overrides belong in this file or
 * any portal stylesheet (UCheck PWA and RAPID are separate, sanctioned
 * exceptions that do not live here).
 * ========================================================================= */

/* ---- Self-hosted fonts (woff2 only; never the trial Industry fonts) ------
 * Inter ships as the variable font: one file covers the full 100-900 weight
 * axis (the portal uses 400-800). JetBrains Mono ships as static weights
 * 400/500/600 because the upstream release provides no variable woff2. */

@font-face {
  font-family: 'Inter';
  src: url('../fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('../fonts/JetBrainsMono-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('../fonts/JetBrainsMono-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('../fonts/JetBrainsMono-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ---- Base reset ------------------------------------------------------------
 * Zero the browser's default 8px body margin. tokens.css is the one sheet every
 * page loads (portal shell + the standalone login/activate/reset/onboarding
 * surfaces), so the reset belongs here — a full-viewport page must reach every
 * edge with no white gutter and no 16px of phantom scroll. */
body {
  margin: 0;
}

/* Border-box everywhere. Lives HERE (not components.css) because the standalone
 * login/activate/reset/set-pin/onboarding surfaces link tokens.css but NOT
 * components.css — without the reset they rendered content-box, so width:100%
 * cards + padding overflowed the viewport (horizontal scroll; the session-
 * expired Sign-in button spilled past both phone edges). Audit A1/A2/A3. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

:root {
  /* ---- Palette (dcTok) -------------------------------------------------- */
  --tp-bg: #F7F8FA;              /* page background */
  --tp-surface: #FFFFFF;         /* cards / rail / topbar / inputs */
  --tp-ink: #0F1722;             /* primary text; primary button fill */
  --tp-ink-2: #384153;           /* secondary text; neutral badge solid */
  --tp-muted: #6B7385;           /* tertiary text / icons / eyebrows */
  --tp-hairline: #E5E8EE;        /* default 1px border */
  --tp-hairline-2: #EEF1F5;      /* subtle divider; neutral soft fill */
  --tp-brand: #2456E6;           /* links/selection/focus/active nav — NEVER button fills */
  --tp-brand-soft: #E7EDFE;

  /* ---- Status tones (solid / soft pairs) -------------------------------- */
  --tp-info: #2456E6;
  --tp-info-soft: #E7EDFE;
  --tp-warn: #B6651A;
  --tp-warn-soft: #FCEFDC;
  --tp-danger: #B42318;
  --tp-danger-soft: #FBE5E2;
  --tp-ok: #1F7A4D;
  /* okSoft normalized to the dcTok value; the slightly-different green seen
   * in some mockups is drift (see tests/test_design_tokens.py). */
  --tp-ok-soft: #DDF1E5;
  /* Fifth badge tone: neutral = ink-2 solid on hairline-2 soft. */
  --tp-neutral: #384153;
  --tp-neutral-soft: #EEF1F5;

  /* ---- Promoted recurring literals (research-flagged) -------------------- */
  --tp-table-header-bg: #FAFBFD; /* table header row fill */
  --tp-mono-chip-bg: #F2F4F8;    /* mono identifier chip fill */
  --tp-avatar-bg: #D9DEEA;       /* default avatar fill */
  --tp-scrim: rgba(15,23,34,0.32);       /* popover / light overlay scrim */
  --tp-scrim-heavy: rgba(15,23,34,0.5);  /* modal scrim */

  /* ---- Font stacks -------------------------------------------------------
   * Inter for UI; JetBrains Mono for identifiers ONLY (claim IDs, plates,
   * codes) — never for body copy. */
  --tp-font-ui: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --tp-font-mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, monospace;

  /* ---- Type scale ---------------------------------------------------------
   * Negative letter-spacing applies on sizes above 22px (ds-reference uses
   * -0.4). Eyebrow tracking is 0.12em (~1.3px at 11px), uppercase. */
  --tp-type-display-size: 28px;
  --tp-type-display-weight: 700;
  --tp-type-display-tracking: -0.4px;
  --tp-type-title-size: 22px;        /* page title */
  --tp-type-title-weight: 600;
  --tp-type-subtitle-size: 18px;
  --tp-type-subtitle-weight: 600;
  --tp-type-body-size: 14px;
  --tp-type-body-weight: 400;
  --tp-type-body-dense-size: 13px;   /* dense tables/lists (13-13.5) */
  --tp-type-body-strong-size: 13px;
  --tp-type-body-strong-weight: 600;
  --tp-type-label-size: 12px;
  --tp-type-label-weight: 600;
  --tp-type-eyebrow-size: 11px;      /* uppercase */
  --tp-type-eyebrow-weight: 700;
  --tp-type-eyebrow-tracking: 0.12em;
  --tp-type-mono-id-size: 13px;
  --tp-type-mono-id-weight: 500;

  /* ---- Spacing (4-based rhythm) ------------------------------------------ */
  --tp-space-6: 6px;
  --tp-space-8: 8px;
  --tp-space-12: 12px;
  --tp-space-16: 16px;
  --tp-space-24: 24px;
  --tp-space-32: 32px;

  /* ---- Radii -------------------------------------------------------------- */
  --tp-radius-chip: 6px;        /* chips / kbd hints */
  --tp-radius-control: 8px;     /* buttons, inputs, nav items */
  --tp-radius-card: 12px;
  --tp-radius-card-lg: 14px;    /* large cards (Mission Control) */
  --tp-radius-tile: 18px;       /* icon/module tiles */
  --tp-radius-pill: 999px;      /* badges / pills */

  /* ---- Elevation ----------------------------------------------------------- */
  --tp-shadow-raised: 0 1px 2px rgba(15,23,34,0.06), 0 1px 0 rgba(15,23,34,0.02);
  --tp-shadow-overlay: 0 8px 28px rgba(15,23,34,0.12);   /* modals / sheets */
  --tp-shadow-lift: 0 6px 22px rgba(15,23,34,0.10);      /* hover lift (module cards) */
  /* The standalone hero card — a single centered card on an otherwise empty
   * page (auth / session / onboarding). Softer and further-thrown than the
   * in-page elevations; one token so the three surfaces stop drifting apart. */
  --tp-shadow-hero: 0 12px 44px rgba(15,23,34,0.08);
  /* Responsive overlay casts (responsive-kit.jsx). The drawer casts to the
   * right as it slides in from the left edge; the bottom sheet casts upward. */
  --tp-shadow-drawer: 8px 0 30px rgba(15,23,34,0.28);    /* off-canvas nav drawer */
  --tp-shadow-sheet: 0 -8px 24px rgba(15,23,34,0.18);    /* bottom sheet */

  /* ---- Control heights ------------------------------------------------------ */
  --tp-control-h-sm: 34px;      /* compact buttons */
  --tp-control-h-md: 36px;      /* default buttons, topbar search */
  --tp-control-h-input: 38px;   /* inputs / selects */
  --tp-control-h-topbar: 56px;
  --tp-control-h-topbar-phone: 52px;  /* phone topbar (see Responsive system) */

  /* ---- Layout ----------------------------------------------------------------- */
  /* The single sidebar width. D-110 retired the 56px icon-rail tier: the
   * sidebar shows in full whenever it fits, otherwise it becomes an
   * off-canvas drawer (no intermediate icon-only state). */
  --tp-sidebar-w: 236px;

  /* ---- Responsive system (responsive-kit.jsx) ---------------------------------
   * Three breakpoints (phone < 768 / tablet 768-1023 / desktop >= 1024).
   * Below tablet the sidebar becomes an off-canvas drawer and overlays
   * become full-screen sheets / bottom sheets with >=44px touch targets.
   * The drawer scrim reuses --tp-scrim-heavy (same rgba(15,23,34,0.5)). */
  --tp-bp-tablet: 768px;
  --tp-bp-desktop: 1024px;
  --tp-drawer-w-phone: 86%;       /* off-canvas drawer width on phone... */
  --tp-drawer-w-phone-max: 300px; /* ...capped here */
  --tp-drawer-w-tablet: 280px;    /* fixed drawer width on tablet */
  --tp-radius-sheet: 22px;        /* bottom-sheet top corners (a --tp-radius-* value; lives here with the sheet system) */
  --tp-touch-min: 44px;           /* minimum interactive target below tablet */
  --tp-touch-cta: 46px;           /* phone sheet / docked-bar CTA height (the
                                     primary action sits a notch above the
                                     44px floor so it reads as the target) */
  /* phone topbar height is --tp-control-h-topbar-phone, co-located with the other control heights above */

  /* ---- Motion ------------------------------------------------------------------ */
  --tp-spin-dur: 0.7s;            /* spinner sweep (.rk-spin / rk-spin keyframe, linear) */
  --tp-indet-dur: 1.1s;           /* indeterminate progress sweep (rk-indet keyframe) */
  --tp-disclosure-dur: 0.15s;     /* expand/collapse motion (R9): nav-folder height + phone
                                     search expand — pinned to the portal-nav chevron's 0.15s
                                     so the chevron rotation and the panel reveal stay in lockstep
                                     (owner-requested motion polish, Phase 1 sign-off) */
  --tp-spinner-track-on-fill: rgba(255, 255, 255, 0.35); /* spinner ring on a filled (ink/ok) BusyButton — the bundle's Spinner track on color===#fff */
  --tp-pop-in-dur: 140ms;         /* anchored-popover ENTER — fade + scale 0.97→1 out of the
                                     caret. The one designed timing in the Page Details motion
                                     spec with no shipped primitive to match, ruled onto the
                                     shared .tp-popover (build spec PD-A13) */
  --tp-pop-out-dur: 110ms;        /* anchored-popover EXIT — fade ONLY, no scale
                                     ("dismissal shouldn't animate"). Shorter than the enter
                                     on purpose: leaving should not cost the user time */

  /* ---- Device chrome / safe areas (Phase 4.6) --------------------------------
   * The ONLY place env(safe-area-inset-*) may appear — CI-guarded
   * (tests/test_device_chrome.py). Zero in an ordinary browser tab; non-zero
   * once base.html's viewport-fit=cover puts the shell under the Dynamic
   * Island / rounded corners / gesture bar in standalone display. Fixed or
   * edge-docked surfaces consume the token (topbar, drawer, bottom sheets,
   * docked bars, toasts) — never raw env(). The 0px fallback keeps every
   * calc() valid where env() is unsupported. */
  --tp-safe-top: env(safe-area-inset-top, 0px);
  --tp-safe-right: env(safe-area-inset-right, 0px);
  --tp-safe-bottom: env(safe-area-inset-bottom, 0px);
  --tp-safe-left: env(safe-area-inset-left, 0px);

  /* Orientation-INDEPENDENT device-chrome constants (2026-08-06 safe-area
   * audit). Plain lengths, NOT env() reads: the hardware geometry they describe
   * does not change when the device rotates — env() already reports the four
   * insets per orientation itself — so these never sit behind an orientation
   * media query, and being ordinary lengths they leave the CI guard above
   * untouched. */
  --tp-safe-corner: 16px;      /* min clearance from a display corner — nothing interactive inside it */
  --tp-safe-radius: 55px;      /* the true display corner radius that clearance is measured against */
  --tp-safe-gutter: 16px;      /* standard content gutter; the side rule is max(gutter, safe-side) — the
                                  LARGER of the two, never the two stacked */
  --tp-safe-tap: var(--tp-touch-min);  /* absolute tap-target floor — ALIAS of
                                   * --tp-touch-min (:190): one value, two
                                   * vocabularies (the safe-area handoff names
                                   * it this). Never diverge them. */
  --tp-safe-tap-field: 52px;   /* primary-action floor on field surfaces — wet/gloved hands
                                  (consumers arrive with UCheck 6.3) */

  /* ---- Damage Claims: the DC-A12 red pen -------------------------------
   * The pen is a DRAWING colour, not a theme colour: it is what the submitter
   * drew with and what the reviewer must see, so it does not track the palette.
   * Published here anyway because the app-wide rule is that no stylesheet
   * carries a raw hex — a value with a name is a value somebody can find. All
   * three are verbatim from the design bundle (`damage-claim-system.jsx`
   * MARKUP_STROKE + the portal pen's own chip colours).
   */
  --tp-pen-ink: #E11D48;
  --tp-pen-chip-bg: #FCE7EC;
  --tp-pen-chip-ink: #A8112E;
}
