/* ============================================================================
   Purpose: THE SINGLE SOURCE OF TRUTH.
   Every colour, size, space, radius, duration and easing used anywhere in this
   theme is declared here as a token. Nothing downstream may use a raw value.
   Retheming the entire product must be possible by editing this file alone.

   System name: "Diagnostic Bay"
   Derived from the CarzSpa logo - gold shield (#F5A800) on black wordmark.
   The base is a cool near-black lacquer ramp, as if a black car is sitting
   under the raking lights of a paint-inspection bay. Depth comes from inner
   light and hairlines, never from soft drop shadows.

   Scales: 4-point system throughout. No 13 / 15 / 18 px. Ever.
   ========================================================================= */

:root {

  /* ==========================================================================
     1 · COLOUR - LACQUER RAMP (surfaces, darkest → lightest)
     ========================================================================= */
  --c-void:            #060708;  /* page backdrop, behind everything          */
  --c-base:            #0A0B0D;  /* body                                      */
  --c-elev-1:          #101216;  /* cards, rig                                */
  --c-elev-2:          #16181D;  /* option buttons, inputs                    */
  --c-elev-3:          #1D2026;  /* hover state of the above                  */
  --c-elev-4:          #252932;  /* pressed / active chrome                   */

  /* Hairlines. Depth in this system is drawn, not blurred. */
  --c-line:            rgba(255, 255, 255, 0.07);
  --c-line-2:          rgba(255, 255, 255, 0.13);
  --c-line-3:          rgba(255, 255, 255, 0.22);

  /* ==========================================================================
     2 · COLOUR - BRAND & CHANNELS
     The product has exactly two measurement channels and they must never
     swap colour anywhere in the interface:
       SHIELD  (physical risk → PPF)      = gold, from the logo
       WEATHER (chemical risk → Coating)  = cyan, the "water" channel
     ========================================================================= */
  --c-shield:          #F5A800;
  --c-shield-hi:       #FFC44D;
  --c-shield-lo:       #B87C00;
  --c-shield-ghost:    rgba(245, 168, 0, 0.12);
  --c-shield-veil:     rgba(245, 168, 0, 0.04);

  --c-weather:         #FF7A1A;
  --c-weather-hi:      #FFA65C;
  --c-weather-lo:      #B04A00;
  --c-weather-ghost:   rgba(255, 122, 26, 0.12);
  --c-weather-veil:    rgba(255, 122, 26, 0.04);

  /* Semantic. `clear` is the ₹0 / buy-nothing outcome - it must feel like a
     win, not an absence, so it gets its own positive colour. */
  --c-danger:          #FF6B5E;
  --c-danger-ghost:    rgba(255, 107, 94, 0.10);
  --c-clear:           #57D98A;
  --c-clear-ghost:     rgba(87, 217, 138, 0.10);

  /* ==========================================================================
     3 · COLOUR - INK
     ========================================================================= */
  --c-ink:             #F4F2EF;  /* headings, answers                         */
  --c-ink-2:           #A9A6A1;  /* body copy                                 */
  --c-ink-3:           #6F6C68;  /* labels, meta, disabled                    */
  --c-ink-inv:         #08090A;  /* on gold / on white                        */

  /* ==========================================================================
     4 · COLOUR - LIGHT & GLASS
     The two effects that carry the "bay" metaphor.
     ========================================================================= */
  --grad-lacquer:      linear-gradient(180deg, #0A0B0D 0%, #0E1014 55%, #08090B 100%);
  --grad-rig:          linear-gradient(180deg, #14161B 0%, #0E1014 100%);
  --grad-shield:       linear-gradient(135deg, #FFC44D 0%, #F5A800 48%, #C98A00 100%);
  --grad-weather:      linear-gradient(135deg, #FFA65C 0%, #FF7A1A 48%, #B04A00 100%);
  --grad-sheen:        linear-gradient(105deg,
                         rgba(255,255,255,0) 0%,
                         rgba(255,255,255,0.09) 45%,
                         rgba(255,255,255,0.14) 50%,
                         rgba(255,255,255,0.09) 55%,
                         rgba(255,255,255,0) 100%);

  /* ---------------------------------------------------------------------------
     THE INSTRUMENT SET
     The question panel is the only thing on the page competing with a lit 3D
     car, and a plain dark card loses that fight. These give it the same
     vocabulary as the bay: light spilled from one side, a measured surface,
     and marks that read as equipment rather than as decoration.

     The measuring-equipment character used to live on the 3D turntable, as
     ring strokes and 72 bay ticks. It could not stay there - see section 8b,
     any repeated shape on the plate fights the gradient it sits on. In the DOM
     it costs nothing and fights nothing, so it moved here.
     ------------------------------------------------------------------------ */

  /* Warm light spilling onto the panel from the car's side of the layout. The
     bay lights the whole stage, so the panel should not look like it is in a
     different room. Two stops only - a wider ramp banded visibly on an
     8-bit dark surface. */
  --grad-rig-spill:    radial-gradient(120% 90% at 0% 0%,
                         rgba(245, 168, 0, 0.055) 0%,
                         rgba(245, 168, 0, 0.018) 38%,
                         rgba(245, 168, 0, 0) 68%);

  /* Ruled surface. Deliberately at the edge of visible: read as a texture at a
     glance, gone when you look straight at it. Anything stronger turns the
     panel into graph paper and starts competing with the options. */
  --grad-rig-grid:     repeating-linear-gradient(0deg,
                         rgba(255, 255, 255, 0.014) 0 1px,
                         transparent 1px 32px),
                       repeating-linear-gradient(90deg,
                         rgba(255, 255, 255, 0.014) 0 1px,
                         transparent 1px 32px);

  /* The panel's top edge, lit from the middle like the plate's rim. */
  --grad-rig-edge:     linear-gradient(90deg,
                         transparent 0%,
                         rgba(245, 168, 0, 0.34) 22%,
                         rgba(245, 168, 0, 0.52) 50%,
                         rgba(245, 168, 0, 0.34) 78%,
                         transparent 100%);

  /* Smoked glass. For controls that float over the 3D stage and must stay
     readable against whatever the car happens to be doing behind them. */
  --c-glass:           rgba(6, 7, 8, 0.55);

  /* WhatsApp's own green. The ONE colour in this theme that is not ours and
     must not be re-themed: it is on the button because it is recognised
     before it is read, and a gold WhatsApp button loses exactly that. */
  --c-whatsapp:        #25D366;
  --c-whatsapp-hi:     #3BE07A;

  /* Corner crop marks, and the length of one arm. */
  --c-mark:            rgba(245, 168, 0, 0.30);
  --rig-mark-arm:      14px;

  /* A lit numeral, for values that are readouts rather than text. */
  --glow-text-shield:  0 0 12px rgba(245, 168, 0, 0.45);

  /* Glass over an instrument dial. A dome catches the room along one edge and
     goes dark at the opposite one; a flat white wash just fogs the dial. */
  --grad-glass:        linear-gradient(155deg,
                         rgba(255, 255, 255, 0.10) 0%,
                         rgba(255, 255, 255, 0.03) 30%,
                         rgba(255, 255, 255, 0) 52%,
                         rgba(0, 0, 0, 0.14) 100%);

  /* The mark left at the highest reading a channel has taken. Deliberately
     paler than the channel's own colour - it is a memory of a value, not a
     value. */
  --c-peak:            rgba(255, 255, 255, 0.55);

  /* Page grain.
     Large dark gradients band on 8-bit displays, which is the same problem the
     turntable had (section 8b). feTurbulence as a data URI is one line, needs
     no request, and costs nothing to animate because it never animates. */
  --grad-grain:        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");

  /* Corners fall away, so the lit middle of the page reads as lit. */
  --grad-vignette:     radial-gradient(120% 85% at 50% 42%,
                         rgba(0, 0, 0, 0) 42%,
                         rgba(0, 0, 0, 0.18) 76%,
                         rgba(0, 0, 0, 0.42) 100%);

  /* The opposite of --shadow-inset-top: a dark line along the top edge, so a
     field reads as cut INTO the panel rather than sitting on it. */
  --shadow-inset-sunk: inset 0 1px 0 rgba(0, 0, 0, 0.50);

  /* Cuts the progress rail into a segmented gauge instead of a plain bar. Sits
     OVER the fill, so the fill still animates its width exactly as before. */
  --grad-rail-ticks:   repeating-linear-gradient(90deg,
                         transparent 0 5px,
                         var(--c-base) 5px 7px);

  /* The face of an option's number key. A keycap, not a box: lighter at the
     top edge where a real one would catch the room. */
  --grad-key-cap:      linear-gradient(180deg,
                         rgba(255, 255, 255, 0.07) 0%,
                         rgba(255, 255, 255, 0.02) 44%,
                         rgba(0, 0, 0, 0.16) 100%);

  /* The sweep that fills an option row from its leading edge on hover. Reads
     as a meter taking a reading, which is what the whole page is about. */
  --grad-opt-sweep:    linear-gradient(90deg,
                         rgba(245, 168, 0, 0.10) 0%,
                         rgba(245, 168, 0, 0.035) 34%,
                         transparent 72%);

  --glow-shield:       0 0 32px rgba(245, 168, 0, 0.40);
  --glow-shield-soft:  0 0 64px rgba(245, 168, 0, 0.16);
  --glow-weather:      0 0 32px rgba(255, 122, 26, 0.40);
  --glow-weather-soft: 0 0 64px rgba(255, 122, 26, 0.16);

  /* Elevation. Used sparingly - hairlines do most of the work. */
  --shadow-sm:         0 4px 12px rgba(0, 0, 0, 0.40);
  --shadow-md:         0 8px 32px rgba(0, 0, 0, 0.48);
  --shadow-lg:         0 16px 64px rgba(0, 0, 0, 0.56);
  --shadow-inset-top:  inset 0 1px 0 rgba(255, 255, 255, 0.06);

  /* ==========================================================================
     5 · SPACING - STRICT 4-POINT SCALE
     Every margin, padding, gap and offset in this theme resolves to one of
     these. If a value you want is not here, you want the wrong value.
     ========================================================================= */
  --space-4:    4px;   --space-8:    8px;   --space-12:  12px;  --space-16:  16px;
  --space-20:  20px;   --space-24:  24px;   --space-32:  32px;  --space-40:  40px;
  --space-48:  48px;   --space-56:  56px;   --space-64:  64px;  --space-80:  80px;
  --space-96:  96px;   --space-128:128px;   --space-160:160px;  --space-192:192px;

  /* The one height every desktop question panel is held at.
     NOT a spacing value - it is a measurement, and it is load-bearing.

     The questions run from 3 options to 5 and their headings wrap to one line
     or two, so the panel's natural height varies from 520px to 654px across
     the set. That is not just a jump in the copy: the scroll handoff ENDS at
     the panel's bottom edge and the car parks on the panel's base, so a
     shorter question pulls the car up into the gauges. Holding one height is
     what stops it.

     Measure with the real heading text. An earlier pass measured every
     question against whichever heading happened to already be in the DOM,
     which silently held the heading at two lines for all fifteen and reported
     a taller worst case than exists.

     704 is the tallest question in the current set (Q4, five options, 676px at
     every desktop width) plus one wrapped line of headroom. Re-measure after
     any copy change - add an option or a longer question and this is the
     number that has to move. See HANDOVER section 8. */
  --rig-panel-h: 704px;

  /* ==========================================================================
     6 · TYPE
     Archivo  - display / headings. Heavy, tight, engineered.
     Inter    - body. Neutral, high legibility at small sizes on dark.
     JetBrains Mono - data. Scores, codes, labels, prices, tick numerals.
     ========================================================================= */
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Every step divisible by 4. */
  --fs-12: 0.75rem;   --fs-16: 1rem;      --fs-20: 1.25rem;   --fs-24: 1.5rem;
  --fs-28: 1.75rem;   --fs-32: 2rem;      --fs-40: 2.5rem;    --fs-48: 3rem;
  --fs-56: 3.5rem;    --fs-64: 4rem;      --fs-80: 5rem;      --fs-96: 6rem;

  /* Semantic aliases - components reference these, never the raw steps. */
  /* One step below the scale's floor, for a single job: the gauge's one-line
     explanation on a phone, where the channel has a 160px column and
     "Weather & chemical -> coating" needs 173px at 12px. Measured, not picked.

     It is deliberately NOT part of the ramp above and must not spread. Below
     12px is under the comfortable reading floor - it is survivable here only
     because this line is a caption under a number that already says the same
     thing, never because small text is fine. */
  --fs-10:      0.625rem;

  --fs-micro:   var(--fs-12);
  --fs-caption: var(--fs-12);
  --fs-body:    var(--fs-16);
  --fs-lead:    var(--fs-20);
  --fs-h6:      var(--fs-20);
  --fs-h5:      var(--fs-24);
  --fs-h4:      var(--fs-28);
  --fs-h3:      var(--fs-32);
  --fs-h2:      var(--fs-40);
  --fs-h1:      var(--fs-56);
  --fs-display: var(--fs-80);

  /* Fluid pairs for the two headlines that must scale. Both ends are 4-pt. */
  --fs-hero:    clamp(1.75rem, 1.15rem + 1.6vw, 2.5rem); /* 28 → 40 */
  --fs-verdict: clamp(2rem,   1.00rem + 3.2vw, 4rem);    /* 32 → 64 */
  --fs-sec:     clamp(1.75rem, 1.15rem + 1.9vw, 2.5rem); /* 28 → 40 */

  --lh-tight:  1.0;    --lh-snug:  1.15;   --lh-heading: 1.25;
  --lh-normal: 1.5;    --lh-loose: 1.75;

  --tracking-display: -0.03em;
  --tracking-tight:   -0.02em;
  --tracking-normal:  0;
  --tracking-wide:    0.08em;
  --tracking-label:   0.16em;

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;
  --weight-black:    900;

  --measure:      68ch;  /* max line length for body copy */
  --measure-tight: 48ch; /* for leads and card copy       */

  /* ==========================================================================
     7 · RADII - 4-point
     Squared-off by default. This is an instrument, not a consumer app.
     ========================================================================= */
  --radius-0:    0px;
  --radius-4:    4px;
  --radius-8:    8px;
  --radius-12:  12px;
  --radius-16:  16px;
  --radius-24:  24px;
  --radius-full: 9999px;

  /* ==========================================================================
     8 · LAYOUT
     ========================================================================= */
  --container-max:  1200px;
  --container-rig:  960px;   /* the diagnostic instrument is narrower */
  /* The phone gutter. 16 was symmetric but so tight that the question panel
     read as running off the right edge; 20 is the smallest step on the scale
     that reads as a deliberate margin on both sides. */
  --container-pad:  var(--space-20);
  --grid-gap:       var(--space-16);
  --section-pad:    var(--space-64);

  /* ==========================================================================
     9 · MOTION
     Durations and easings are tokens. No component invents its own timing.
     ========================================================================= */
  --dur-instant: 120ms;
  --dur-fast:    200ms;
  --dur-base:    320ms;
  --dur-slow:    640ms;
  --dur-cine:   1200ms;

  --ease-out:    cubic-bezier(0.16, 1.00, 0.30, 1.00); /* expo out - the default */
  --ease-in-out: cubic-bezier(0.65, 0.00, 0.35, 1.00);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1.00); /* needle overshoot       */

  /* ==========================================================================
     10 · Z-INDEX - named, so no component ever guesses a number
     ========================================================================= */
  --z-base:    0;
  --z-raised:  10;
  --z-sticky:  60;
  --z-nudge:   70;
  --z-overlay: 80;
}

/* ---------------------------------------------------------------------------
   Responsive token overrides. Only layout rhythm changes with viewport -
   colour, type character and motion identity stay constant.
   ------------------------------------------------------------------------ */
@media (min-width: 768px) {
  :root {
    --container-pad: var(--space-24);
    --grid-gap:      var(--space-24);
    --section-pad:   var(--space-80);
  }
}

@media (min-width: 1024px) {
  :root {
    --container-pad: var(--space-32);
    --section-pad:   var(--space-128);
  }
}

/* ---------------------------------------------------------------------------
   Reduced motion collapses every duration to zero at the token level, so no
   component has to remember to check. animations.js checks it too.
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-instant: 1ms; --dur-fast: 1ms; --dur-base: 1ms;
    --dur-slow:    1ms; --dur-cine: 1ms;
  }
}
