/* ============================================================================
   THE SHARED LAYER — every token both properties use, plus the reset they both
   assume. Loaded first by the homepage and by everything the Worker renders.

   There used to be two token sets: pulse.css named its colours (--void,
   --glass, --glow, --muted) and was dark-only, while theme.css named its roles
   (--surface, --text-mid) and carried light and dark from one file. Two
   vocabularies for one palette is how two properties on one Worker drift into
   two different looks, and the colour-named half could not express a light mode
   at all — a token called --void has nothing to say about white.

   So: ROLE NAMES, everywhere, in three blocks that differ only in their values.
   A rule that says `color: var(--rose)` breaks the moment the mode flips; a
   rule that says `color: var(--brand)` does not. Page CSS consumes these and
   never redefines them.

   Light is the default, and it descends from the invoice — rose and periwinkle
   on paper white — because the documents this thing produces get printed and a
   dark invoice is a bad invoice. Dark is Pulse. Its rule survives the merge:
   --accent is LIGHT, not paint. It belongs in box-shadow and in hairline
   borders, almost never in a fill, and never a large one.

   Mode resolution, in precedence order:
     1. :root                                 -> light (the default)
     2. @media (prefers-color-scheme: dark)   -> Pulse, when the OS asks
     3. [data-theme="dark"] / ="light"        -> an explicit choice wins
   The media query is guarded with :not([data-theme="light"]) so choosing light
   on a dark-set OS actually sticks. The dark block is written twice rather than
   shared, because a selector list containing an unmatched condition drops the
   whole rule in some engines.
   ============================================================================ */

:root {
  /* --- ground & surfaces ------------------------------------------------- */
  --bg:          #fdfcfe;
  --bg-wash-1:   #fbeef4;   /* the invoice's three washes; see each body rule */
  --bg-wash-2:   #eef1fd;
  --bg-wash-3:   #eafafa;
  --surface:     #ffffff;
  --surface-2:   #fbfafc;   /* inset wells, table stripes, meta cards        */
  --line:        #eceaf1;
  --line-strong: #e4e1e9;
  --line-hot:    rgba(91, 98, 184, .34);   /* a LIT edge: focus, active card */

  /* --- translucent panes -------------------------------------------------- */
  /* Glass is a homepage primitive, but which whites and how much of them is a
     palette decision, so the values live here with the rest of the palette. */
  --glass:       rgba(255, 255, 255, .55);
  --glass-hi:    rgba(255, 255, 255, .82);
  --glass-inset: rgba(255, 255, 255, .90);
  --sheen:       rgba(255, 255, 255, .55);
  --panel:       rgba(255, 255, 255, .80);  /* slide-over base under glass    */
  --panel-solid: rgba(255, 255, 255, .96);  /* ...when it covers the viewport */
  --scrim:       rgba(91, 86, 99, .30);

  /* --- type -------------------------------------------------------------- */
  --text:        #1f1d24;
  --text-mid:    #5b5663;
  --text-faint:  #8b8593;

  /* --- accent ------------------------------------------------------------ */
  --accent:      #5b62b8;   /* periwinkle — links, focus, active state       */
  --accent-wash: #f2f3fd;
  --accent-glow: rgba(91, 98, 184, .20);   /* the halo; never a fill         */
  --brand:       #b05377;   /* rose — money, totals, the comped tag          */
  --brand-wash:  #fdf2f6;

  /* --- semantic: status only, never decoration --------------------------- */
  --ok:          #2f8f6a;
  --warn:        #b5791f;
  --bad:         #c0524a;
  --neutral:     #8b8593;

  /* --- elevation --------------------------------------------------------- */
  --shadow-1:     0 1px 2px rgba(31, 29, 36, .04);
  --shadow-2:     0 1px 2px rgba(31, 29, 36, .04), 0 12px 32px -12px rgba(91, 86, 99, .16);
  --shadow-lift:  0 18px 46px rgba(31, 29, 36, .14);   /* a card off the page */
  --shadow-panel: -30px 0 70px rgba(31, 29, 36, .16);  /* the slide-over      */
  --ring:         0 0 0 3px rgba(91, 98, 184, .18);

  /* --- the ground, as a reusable layer stack ------------------------------ */
  /* Held in a variable because more than one element paints this exact backdrop
     and has to stay seamless with it — see the arcs in style.css, which repaint
     it with background-attachment: fixed so the gradients line up with the
     fixed .room-bg behind them. */
  --room-layers:
    radial-gradient(120% 90%  at 18% 30%, rgba(176,  83, 119, .07), transparent 55%),
    radial-gradient(140% 120% at 80% 90%, rgba( 91,  98, 184, .07), transparent 60%),
    linear-gradient(180deg,               rgba(255, 255, 255, .30), rgba(255, 255, 255, .70));

  /* --- families ---------------------------------------------------------- */
  /* Three fonts, three jobs. Display carries headlines at low weight; tech
     carries labels and eyebrows at wide tracking; mono carries anything the
     machine produced — hours, money, refs, timestamps. Mixing these jobs is
     what makes a dashboard look improvised. */
  --font-display: 'Outfit', 'Segoe UI Variable Display', system-ui, sans-serif;
  --font-tech:    'Chakra Petch', 'Segoe UI', system-ui, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, 'Cascadia Mono', monospace;
  --font-body:    'Segoe UI Variable Text', 'Segoe UI', system-ui, sans-serif;

  /* --- tracking ---------------------------------------------------------- */
  /* Wide letter-spacing at small sizes is the signature. Display text goes the
     other way — tight, because Outfit at 200 opens up on its own. */
  --track-display: -0.02em;
  --track-label:    0.14em;
  --track-eyebrow:  0.42em;

  /* --- geometry & motion (mode-independent) ------------------------------- */
  --r:        18px;
  --r-sm:     10px;
  --r-pill:   999px;
  --ease:     cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur:      0.25s;
  --dur-slow: 0.8s;
}

/* --- PULSE (dark) --------------------------------------------------------- */
/* Only the tokens change. No rule in any stylesheet is mode-aware. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:          #0a1414;
    --bg-wash-1:   #0f1f1f;
    --bg-wash-2:   #0d1c1e;
    --bg-wash-3:   #101f1e;
    --surface:     #122020;
    --surface-2:   #0f1a1a;
    --line:        rgba(127, 233, 224, .16);
    --line-strong: rgba(127, 233, 224, .28);
    --line-hot:    rgba(127, 233, 224, .42);

    --glass:       rgba(20, 42, 42, .42);
    --glass-hi:    rgba(40, 72, 72, .55);
    --glass-inset: rgba(255, 255, 255, .05);
    --sheen:       rgba(127, 233, 224, .05);
    --panel:       rgba(10, 20, 20, .78);
    --panel-solid: rgba(10, 20, 20, .94);
    --scrim:       rgba(6, 12, 12, .55);

    --text:        #dcefed;
    --text-mid:    #8aa9a7;
    --text-faint:  #5d7977;

    --accent:      #7fe9e0;
    --accent-wash: rgba(127, 233, 224, .10);
    --accent-glow: rgba(127, 233, 224, .22);
    --brand:       #e9a6bf;
    --brand-wash:  rgba(233, 166, 191, .10);

    --ok:          #67e0a3;
    --warn:        #f2c97d;
    --bad:         #f08179;
    --neutral:     #6f8584;

    --shadow-1:     0 1px 2px rgba(0, 0, 0, .30);
    --shadow-2:     0 1px 2px rgba(0, 0, 0, .30), 0 16px 40px -16px rgba(0, 0, 0, .55);
    --shadow-lift:  0 18px 46px rgba(0, 0, 0, .45);
    --shadow-panel: -30px 0 70px rgba(0, 0, 0, .50);
    --ring:         0 0 0 3px rgba(127, 233, 224, .22);

    --room-layers:
      radial-gradient(120% 90%  at 18% 30%, rgba(127, 233, 224, .08), transparent 55%),
      radial-gradient(140% 120% at 80% 90%, rgba( 10,  20,  20, .70), transparent 60%),
      linear-gradient(180deg,               rgba( 10,  20,  20, .35), rgba(10, 20, 20, .72));
  }
}

:root[data-theme="dark"] {
  --bg:          #0a1414;
  --bg-wash-1:   #0f1f1f;
  --bg-wash-2:   #0d1c1e;
  --bg-wash-3:   #101f1e;
  --surface:     #122020;
  --surface-2:   #0f1a1a;
  --line:        rgba(127, 233, 224, .16);
  --line-strong: rgba(127, 233, 224, .28);
  --line-hot:    rgba(127, 233, 224, .42);

  --glass:       rgba(20, 42, 42, .42);
  --glass-hi:    rgba(40, 72, 72, .55);
  --glass-inset: rgba(255, 255, 255, .05);
  --sheen:       rgba(127, 233, 224, .05);
  --panel:       rgba(10, 20, 20, .78);
  --panel-solid: rgba(10, 20, 20, .94);
  --scrim:       rgba(6, 12, 12, .55);

  --text:        #dcefed;
  --text-mid:    #8aa9a7;
  --text-faint:  #5d7977;

  --accent:      #7fe9e0;
  --accent-wash: rgba(127, 233, 224, .10);
  --accent-glow: rgba(127, 233, 224, .22);
  --brand:       #e9a6bf;
  --brand-wash:  rgba(233, 166, 191, .10);

  --ok:          #67e0a3;
  --warn:        #f2c97d;
  --bad:         #f08179;
  --neutral:     #6f8584;

  --shadow-1:     0 1px 2px rgba(0, 0, 0, .30);
  --shadow-2:     0 1px 2px rgba(0, 0, 0, .30), 0 16px 40px -16px rgba(0, 0, 0, .55);
  --shadow-lift:  0 18px 46px rgba(0, 0, 0, .45);
  --shadow-panel: -30px 0 70px rgba(0, 0, 0, .50);
  --ring:         0 0 0 3px rgba(127, 233, 224, .22);

  --room-layers:
    radial-gradient(120% 90%  at 18% 30%, rgba(127, 233, 224, .08), transparent 55%),
    radial-gradient(140% 120% at 80% 90%, rgba( 10,  20,  20, .70), transparent 60%),
    linear-gradient(180deg,               rgba( 10,  20,  20, .35), rgba(10, 20, 20, .72));
}

/* ============================================================================
   THE RESET — only what both properties assume. Everything else about how a
   page paints belongs to that page's own stylesheet.
   ============================================================================ */

*, *::before, *::after { box-sizing: border-box; }

/* Decorative motion must COLLAPSE here, not merely slow down. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
