/* TRU Operating System — design tokens.
 *
 * The single source of colour, spacing, radius, focus and affordance for the
 * shell (spec: specs/cortana-first-shell.md, R4/R5; TRU-18).
 *
 * WHERE THIS FILE LIVES AND WHY.
 *
 * It used to live only in cloudflare/deploy/jarvis-os/, layered over a sealed
 * bundle through a <link> tag. The bundle is no longer sealed — the shell
 * source is vendored at apps/shell/ — so the tokens now govern the app from
 * inside it: deck.css @imports this file, which means Vite inlines it into the
 * built stylesheet and `npm run dev` resolves it too. (A root-absolute
 * /tru-tokens.css never resolved there; only the deployed page ever had it.)
 *
 * The two copies under cloudflare/ are BUILD OUTPUT now, written by
 * tools/build-shell.mjs from this file. They still exist because the overlay
 * modules (jarvis-console.js, jarvis-hologram*.js) are separate first-party
 * scripts that consume var(--tru-*) at runtime and load before the bundle's
 * stylesheet does. Do not hand-edit them; edit here and rebuild. The mirror
 * assertions in tests/test_design_tokens.py and tests/test_console_layout.py
 * hold the three copies identical.
 *
 * THE COLOUR RULE (R4). The base is deep blue, matched to Cortana herself.
 *   - CYAN is the shell's accent: what you can act on, what is active, what
 *     has focus. It is her colour.
 *   - GREEN is status and nothing else: healthy, ok, complete, connected. A
 *     green button is a defect — "go" is an action, not a state, and belongs
 *     in cyan. tests/test_design_tokens.py enforces this by hue: any
 *     green-hued token must carry "status" in its name.
 *   - AMBER is warning and attention only (TRU-18 AC-3). It was the shell's
 *     chrome accent — active tabs, the wordmark, the boot reactor, hover
 *     glows — and every one of those has moved to cyan. What amber still
 *     marks: paused, pending, held, not-connected, needs-confirmation,
 *     caveats, and the warn LED.
 *   - RED is danger and overdue.
 */

:root {
  /* -- depth: page -> panel -> raised surface --------------------------- */
  --tru-bg-0: #04070e;        /* page depth; also the app's radial base */
  --tru-bg-1: #0a101d;        /* panels, cards */
  --tru-bg-2: #0c1728;        /* raised chrome, gradient tops */
  --tru-bg-3: #0d2036;        /* highest chrome (buttons, gem) */
  --tru-bg-teal: #04121b;     /* the console's dark teal well */
  --tru-surface: #101a2e;     /* inputs, editable fields */

  /* -- text ------------------------------------------------------------- */
  --tru-text: #dbe5f2;
  --tru-text-soft: #93a4c4;
  --tru-text-mut: #8496af;
  --tru-text-faint: #55647c;

  /* -- Cortana's own colour, as accent ---------------------------------- */
  --tru-accent: #3ee8ff;
  --tru-accent-pale: #a9e9fb;
  --tru-link: #2f7fc4;

  /* -- accent at the alphas the shell actually uses --------------------- */
  --tru-glow-50: rgba(62, 232, 255, .5);
  --tru-glow-35: rgba(62, 232, 255, .35);
  --tru-glow-22: rgba(62, 232, 255, .22);
  --tru-glow-10: rgba(62, 232, 255, .1);

  /* -- borders (the blue-grey hairlines) -------------------------------- */
  --tru-border: rgba(146, 176, 226, .18);
  --tru-border-soft: rgba(146, 176, 226, .16);
  --tru-border-faint: rgba(146, 176, 226, .14);

  /* -- status. GREEN LIVES HERE AND NOWHERE ELSE (R4) ------------------- */
  --tru-status-ok: #4ade80;
  --tru-status-ok-wash: rgba(74, 222, 128, .14);
  --tru-warn: #ffa02e;
  --tru-danger: #ff4d5e;

  /* -- structure --------------------------------------------------------- */
  --tru-s1: 4px;  --tru-s2: 8px;  --tru-s3: 12px;  --tru-s4: 16px;  --tru-s5: 24px;
  --tru-r1: 8px;  --tru-r2: 11px; --tru-r3: 14px;
  --tru-focus: 0 0 0 2px var(--tru-glow-35);

  /* -- affordance (R5: buttons feel real) ------------------------------- */
  --tru-lift: 0 10px 30px -8px var(--tru-glow-35);
  --tru-press: translateY(1px);
  --tru-ease: .16s ease;

  /* ======================================================================
   * TRU-18 additions. Everything above shipped with B1 and is unchanged;
   * everything below is what the source tree needs in order to stop
   * carrying its own parallel palette in hex.
   * ==================================================================== */

  /* -- the accent family, at the weights the source actually uses -------
   * These replace the ~60 hand-typed rgba(62,232,255,…) and rgba(255,160,46,…)
   * literals that were scattered through deck.css and shell.css. Named for
   * the JOB, not the number, so a call site reads as intent: a border you can
   * act on is --tru-accent-line whether it is a button, a chip or a row. */
  --tru-accent-2: #7ff0ff;                        /* brighter accent for text on dark */
  --tru-accent-line: rgba(62, 232, 255, .40);     /* interactive border, resting */
  --tru-accent-line-soft: rgba(62, 232, 255, .32);
  --tru-accent-line-strong: rgba(62, 232, 255, .55);
  --tru-accent-wash: rgba(62, 232, 255, .14);     /* selected/on background */
  --tru-accent-wash-soft: rgba(62, 232, 255, .06);
  --tru-accent-ink: rgba(62, 232, 255, .12);      /* inset tint behind an icon */

  /* -- glow tiers. Additive to a shadow tier; sized to the surface.
   * --glow-amber* used to hold these jobs; TRU-18 moves every chrome glow
   * onto the accent and leaves amber's tiers for genuine warnings. */
  --tru-glow-accent-sm: 0 0 12px rgba(62, 232, 255, .35);
  --tru-glow-accent:    0 0 14px 3px rgba(62, 232, 255, .45), 0 0 30px 8px rgba(62, 232, 255, .18);
  --tru-glow-accent-lg: 0 0 34px 10px rgba(62, 232, 255, .55), 0 0 90px 30px rgba(62, 232, 255, .22), 0 0 180px 70px rgba(62, 232, 255, .10);
  --tru-glow-accent-text: 0 0 12px rgba(62, 232, 255, .5);

  /* -- warning: amber's remaining, deliberate territory ----------------- */
  --tru-warn-2: #ffc46a;                          /* warn text on dark */
  --tru-warn-line: rgba(255, 160, 46, .40);       /* warning border */
  --tru-warn-line-soft: rgba(255, 160, 46, .30);
  --tru-warn-wash: rgba(255, 160, 46, .13);
  --tru-warn-wash-soft: rgba(255, 160, 46, .06);
  --tru-glow-warn-sm: 0 0 12px rgba(255, 160, 46, .35);
  --tru-glow-warn: 0 0 14px 3px rgba(255, 150, 40, .50), 0 0 34px 8px rgba(255, 120, 20, .22);

  /* -- danger ------------------------------------------------------------ */
  --tru-danger-2: #ff8b96;
  --tru-danger-line: rgba(255, 77, 94, .40);
  --tru-danger-line-strong: rgba(255, 77, 94, .55);
  --tru-danger-wash: rgba(255, 77, 94, .13);
  --tru-danger-wash-soft: rgba(255, 77, 94, .06);
  --tru-glow-danger: 0 0 12px 2px rgba(255, 77, 94, .60);

  /* -- status, at the weights the source uses --------------------------- */
  --tru-status-ok-line: rgba(74, 222, 128, .40);
  --tru-status-ok-glow: 0 0 10px 2px rgba(74, 222, 128, .55);

  /* -- neutral / muted: the honest "nothing wired here yet" language ---- */
  --tru-mut-wash: rgba(85, 101, 138, .08);
  --tru-hover-wash: rgba(146, 176, 226, .05);

  /* -- affordance, continued (R5 / TRU-18 AC-4) -------------------------
   * The three states every interactive control in the shell shares. B1
   * defined --tru-lift/--tru-press/--tru-focus and nothing ever consumed
   * them; shell.css's AFFORDANCE LAYER is what finally does.
   * --tru-lift-sm is the row/card version — the same gesture at a weight
   * that does not make a table row look like it is floating. */
  --tru-lift-sm: 0 6px 18px -6px rgba(0, 0, 0, .45);
  --tru-press-hard: translateY(1px) scale(.995);   /* cards and tiles */

  /* ======================================================================
   * MOTION (TRU-20). One system, so nothing in the shell invents its own
   * timing. The --dur- and --ease- names in deck.css are aliases of these.
   *
   * THE RULE, since the one this source inherited no longer applies:
   * motion has to be caused by something. A surface moves when it ARRIVES
   * (entry), when its VALUE CHANGES (state), when you TOUCH it (affordance),
   * or when it is genuinely LIVE and the motion reflects that. A surface
   * that loops because looping looks good is decoration, and decoration is
   * what makes an interface feel busy instead of alive.
   *
   * The old doctrine capped every screen at three moving things. Eric lifted
   * that on 2026-08-03 — he wants the shell breathing — so the ceiling is
   * gone and the causation rule above is what replaces it. The budget that
   * remains is a performance one: transform and opacity only, because those
   * are the two the compositor can animate without touching layout.
   * ==================================================================== */
  --tru-m-fast: 120ms;      /* affordance: hover, press, focus */
  --tru-m: 200ms;           /* state change */
  --tru-m-slow: 320ms;      /* a surface leaving or arriving */
  --tru-m-enter: 520ms;     /* the full entry gesture */
  --tru-m-value: 650ms;     /* a number or a bar moving to a new value */

  --tru-ease-out: cubic-bezier(.22, .61, .36, 1);     /* arriving; decelerates */
  --tru-ease-in-out: cubic-bezier(.45, 0, .25, 1);    /* breathing; symmetric */
  --tru-ease-snap: cubic-bezier(.2, .9, .3, 1.15);    /* lands with a little overshoot */

  /* Staged reveal. Rows arrive in sequence so the eye can follow what
   * changed instead of being handed a finished table. 55ms is the step: fast
   * enough that eight rows are done in under half a second, slow enough to
   * read as a sequence rather than a flicker. --tru-stagger-cap stops a long
   * ledger from taking three seconds to finish arriving. */
  --tru-stagger: 55ms;
  --tru-stagger-cap: 8;     /* rows past this all share the last delay */
  --tru-enter-y: 10px;      /* how far a surface travels in */
  --tru-enter-scale: .985;  /* and how much smaller it starts */

  /* Ambient. Only for surfaces that are actually live. Deliberately slow —
   * a breath you can count is a distraction; these read as "not frozen". */
  --tru-breathe: 4.2s;
  --tru-drift: 7s;
  --tru-pulse: 1.8s;
  --tru-rotate: 36s;

  /* -- conversation layout (R1b): one source of geometry -----------------
   *
   * The desktop talking state is [app][her stage][chat panel]. The console
   * offsets itself by her stage's width and the app pads itself by both, so
   * all three must derive from the SAME numbers -- the hologram once ran off
   * the bottom of Eric's screen precisely because two modules each had their
   * own idea of her size. Width is height * 5/7, her canvas aspect.
   * vh here; dvh override below for browsers that have it. */
  --tru-talk-stage-h: min(420px, calc(100vh - 160px));
  --tru-talk-stage-w: calc(min(420px, calc(100vh - 160px)) * 5 / 7);
  --tru-talk-panel-w: min(420px, calc(100vw - var(--tru-talk-stage-w) - 64px));

  /* -- her-room (R1c, phones): she takes the top, the chat takes the rest.
   * 46vh clears AC3's >=45% floor with a margin instead of sitting on it. */
  --tru-room-stage-h: 46vh;
}

@supports (height: 100dvh) {
  :root {
    --tru-talk-stage-h: min(420px, calc(100dvh - 160px));
    --tru-talk-stage-w: calc(min(420px, calc(100dvh - 160px)) * 5 / 7);
    --tru-room-stage-h: 46dvh;
  }
}
