/* ============================================================================
   Pours by Citrine XP — theme.css
   THE single token source. Every surface consumes this file:

     pours-backend/public/dashboard.html   <link rel="stylesheet" href="/theme.css">
     pours-backend/public/portal.html      <link rel="stylesheet" href="/theme.css">
     pours-backend/public/staff.html       <link rel="stylesheet" href="/theme.css">
     interactive-cocktail-experience/src   @import "./theme.css" in globals.css

   Rules
   -----
   1. No surface declares a hex. If a value is missing here, add it here.
   2. Brand_System_Figma.md documents the identity and points at this file.
      It no longer restates the values — one source, not two that agree by hand.
   3. server.js serves public/ from an explicit ALLOWLIST. Adding theme.css
      means widening that regex, or every admin surface loads unstyled and it
      presents as a cache problem. Add a regression assertion for it by name.
   ========================================================================== */

:root {
  /* --- Brand ramp — from the identity, unchanged ------------------------- */
  --p-citrine-300: #F4C95D;
  --p-citrine-500: #E8A317;
  --p-citrine-700: #B87E0F;
  --p-amber-glow:  #FFB84D;
  --p-charcoal-900:#1A1A1E;
  --p-charcoal-700:#2A2A30;
  --p-charcoal-500:#3D3D45;
  --p-cream-100:   #F7F3E9;

  /* The mark's gradient. The P disc, the primary button and the tab icon are
     one gesture — never re-approximate it. */
  --p-mark-gradient: linear-gradient(180deg, #F4C95D 0%, #E8A317 60%, #B87E0F 100%);

  /* --- Surfaces ---------------------------------------------------------- */
  --p-bg:            #141418;  /* page field, one step below any card       */
  --p-surface:       #1A1A1E;  /* default card                              */
  --p-surface-raised:#1E1E23;  /* card that sits on a card, inputs          */
  --p-surface-sunk:  #161619;  /* header wash, rail field                   */
  --p-line:          #2A2A30;  /* structural border                         */
  --p-line-soft:     #212126;  /* row divider inside a card                 */
  --p-line-strong:   #3D3D45;  /* control border, focus target              */

  /* --- Text — four steps, all >= 4.5:1 on --p-surface --------------------- */
  --p-text:    #F7F3E9;  /* primary                                          */
  --p-text-2:  #C9C5BC;  /* body on dark                                     */
  --p-text-3:  #9A9AA4;  /* supporting                                       */
  --p-text-4:  #8F8F99;  /* labels, eyebrows. The floor — nothing dimmer.    */
  --p-text-on-citrine: #1A1A1E;
  --p-text-on-mark:    #FFFFFF; /* the P knockout is white, not cream        */

  /* --- Semantic state ---------------------------------------------------- */
  --p-ok:        #7E9A85;
  --p-warn:      #F4C95D;
  --p-risk:      #E8918D;
  --p-risk-line: #4A2F2F;
  --p-risk-bg:   #1F1A1A;
  --p-warn-line: #4A3F2A;
  --p-warn-bg:   #1F1B14;
  --p-accent-bg: #241E12;  /* selected chip / active citrine field           */

  /* --- Lead-time bands — one vocabulary on every surface -------------------
     Keyed to lead-time.js, which is the only thing that decides a band. The
     token name IS the engine's band key, so there is no lookup table to fall
     out of step: `--p-band-${a.band}` resolves for every value the engine can
     return, and a band added there fails visibly here rather than silently
     rendering unstyled.

     This replaced a three-token set (rush / tight / standard) written against
     fixed day counts — under 10, 10–20, 21+. The engine does not work that way
     and never did: it bands on the RATIO of time available to time the event
     needs, so five days is comfortable for an intimate and impossible for a
     deluxe. `tight` was not a band the engine could ever return, and a fixed
     day count would have shown "Standard" on the Overview for an event the
     quote engine was charging an 18% rush fee on. Dylan's call, 2026-08-07:
     the engine wins.

     The bands escalate in heat. `impossible` deliberately breaks that ramp —
     it is desaturated rather than hotter, because it is not the most urgent
     band, it is a refusal. Nothing about it is fixed by hurrying.
     Every band clears 4.5:1 on --p-surface AND --p-surface-raised, because a
     band is rendered as TEXT, not as a swatch. The first pass of the two new
     colours did not: #D94F4F came out at 4.10 on raised and #8A6E6E at 3.59.
     Adjacent bands are >=15 ΔE apart so the escalation is readable as steps
     rather than as one reddening smear, and emergency is >=18 ΔE from
     --p-risk, which sits beside it on the Overview meaning something else. */
  --p-band-standard:  #7E9A85;  /* ratio >= 1.00 ·  no fee · sage          */
  --p-band-short:     #F4C95D;  /* ratio >= 0.75 · 10% fee · citrine       */
  --p-band-rush:      #FF9A6B;  /* ratio >= 0.50 · 18% fee · warm orange   */
  --p-band-hard-rush: #F26B4E;  /* ratio >= 0.30 · 30% fee · red-orange    */
  --p-band-emergency: #E05C6E;  /* ratio >= 0.15 · 45% fee · crimson — leans away
                                   from the orange ramp because this band is a
                                   decision, not just a hotter version of rush */
  --p-band-impossible:#A18181;  /* below the floor · desaturated ON PURPOSE: not
                                   the most urgent band, a refusal. Nothing about
                                   it is fixed by hurrying, so it must not read
                                   as the top of a heat ramp */

  /* --- Posture — the mode indicator required on every admin surface ------- */
  --p-posture-live:        #7E9A85;
  --p-posture-maintenance: #FF9A6B;
  --p-posture-demo:        #E8A317;

  /* --- Type -------------------------------------------------------------- */
  --p-font-display: Cinzel, "Times New Roman", serif;
  /* Outfit and Cinzel are the only faces on disk — see fonts.css. Do not name
     one here that is not shipped: it resolves to the fallback and looks fine. */
  --p-font-body:    Outfit, -apple-system, BlinkMacSystemFont, Helvetica, sans-serif;
  --p-font-mono:    ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Every figure — money, hours, counts, percentages, times — is mono.
     It is how a number reads as a number across four surfaces. */

  --p-size-hero:    clamp(38px, 4.6vw, 60px);
  --p-size-title:   31px;
  --p-size-h2:      27px;
  --p-size-h3:      19px;
  --p-size-figure:  44px;   /* the one number a card exists to show          */
  --p-size-figure-sm:30px;
  --p-size-body:    14px;
  --p-size-small:   12.5px;
  --p-size-label:   11px;   /* uppercase, tracked                            */
  --p-size-micro:   10.5px;

  --p-track-label: .16em;   /* uppercase eyebrows                            */
  --p-track-mark:  .14em;   /* POURS wordmark                                */
  --p-leading-body:1.65;

  /* --- Space — 8px grid -------------------------------------------------- */
  --p-space-1: 4px;
  --p-space-2: 8px;
  --p-space-3: 12px;
  --p-space-4: 16px;
  --p-space-5: 22px;
  --p-space-6: 30px;
  --p-space-7: 44px;

  /* --- Radius ------------------------------------------------------------ */
  --p-radius-sm: 8px;
  --p-radius:    12px;
  --p-radius-lg: 14px;
  --p-radius-xl: 20px;
  --p-radius-pill: 999px;

  /* --- Controls ---------------------------------------------------------- */
  --p-hit-desktop: 40px;
  --p-hit-touch:   44px;   /* crew app floor — used standing behind a bar     */
  --p-hit-touch-lg:56px;   /* crew list rows                                  */

  /* --- Motion ------------------------------------------------------------ */
  --p-ease: cubic-bezier(.2,.8,.2,1);
  --p-dur-fast: 140ms;
  --p-dur:      180ms;
  --p-dur-slow: 2400ms;    /* sky phase crossfade on the public site          */

  --p-shadow-card: 0 40px 80px rgba(0,0,0,.5);
}

/* ============================================================================
   Primitives. Deliberately few — the surfaces compose from tokens, not from a
   component library. These exist because they must be identical everywhere.
   ========================================================================== */

.p-mark {
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--p-mark-gradient);
  color: var(--p-text-on-mark);
  font-family: var(--p-font-display); font-weight: 700; line-height: 1;
}

.p-figure {
  font-family: var(--p-font-mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--p-text);
}

.p-label {
  font-size: var(--p-size-label);
  letter-spacing: var(--p-track-label);
  text-transform: uppercase;
  color: var(--p-text-4);
}

.p-cta {
  background: var(--p-mark-gradient);
  color: var(--p-text-on-citrine);
  border: none;
  border-radius: var(--p-radius-sm);
  font-family: var(--p-font-body);
  font-weight: 600;
  cursor: pointer;
}
.p-cta:hover { filter: brightness(1.06); }

:where(a) { color: var(--p-citrine-300); text-decoration: none; }
:where(a):hover { color: var(--p-amber-glow); }

:where(button, a, input, select, textarea):focus-visible {
  outline: 2px solid var(--p-citrine-500);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* iOS zooms the page when a focused field is under 16px and does not zoom back.
   Scoped to touch pointers so the dense desktop back office keeps its sizing;
   !important because every per-panel input rule below is more specific. */
@media (pointer: coarse) {
  input, select, textarea { font-size: 16px !important; }
}
