/* ============================================================================
   tokens.css — Undercover Consultancy Qatar
   Custom properties only. No component styles live in this file, ever.
   Every other stylesheet reads from here; nothing hard-codes a value.

   ---------------------------------------------------------------------------
   RULES OF USE — these are the design contract, not suggestions
   ---------------------------------------------------------------------------
   1. --ember appears at most THREE times in any viewport. It means "act" or
      "this is the one number that matters". Nothing else.
   2. Body text is --ink or --stone. Body text is NEVER --ember.
   3. Inline links are --ink with a 1px --ember underline. Never a full-orange
      word — that is how the old site turned every paragraph into a keyword farm.
   4. --slate carries anything that reads as DATA: charts, scorecards, map
      fills, stat rails. This exists so orange never has to mean both
      "act" and "analyse" at the same time.
   5. Status colours (--good/--warning/--serious/--critical) appear ONLY in
      scorecard, validation and system-state contexts, and always alongside an
      icon or a label. Never colour alone. Never reused as a chart series hue.
   6. Contrast: text >= 4.5:1, UI borders and chart marks >= 3:1.
      --ember on --paper passes for LARGE text only (>=24px, or >=19px bold).
      For small orange text use --ember-deep.
   7. Only `transform` and `opacity` are animated. No exceptions.
   8. Logical properties only. Never left/right — the site ships EN/AR.
   9. Nothing renders below 15px. --fs-label (12px) is the single exception and
      is reserved for uppercase mono metadata, where it reads at 15px optical
      size because of the tracking. It is never used for reading copy.
   ========================================================================= */

:root {
  color-scheme: light;

  /* --- Brand + neutrals ------------------------------------------------- */
  --ember:        #C8541F;   /* primary accent — actions, the one key number   */
  --ember-deep:   #A8410F;   /* hover / pressed / small orange text            */
  --ember-wash:   #FBEFE7;   /* tinted band, used sparingly                    */
  --ink:          #14110F;   /* headings, dark grounds — warm near-black       */
  --ink-2:        #221D19;   /* raised surface on dark grounds                 */
  --slate:        #2E4756;   /* the "data" voice                               */
  --stone:        #6B6158;   /* muted body, captions, marginalia               */
  --paper:        #FBF9F6;   /* page ground                                    */
  --mist:         #F1EDE7;   /* alternate band, input fill                     */
  --line:         #E3DBD2;   /* hairline rules and borders                     */
  --line-strong:  #C9BEB1;   /* emphasised rules, table heads                  */

  /* --- Status — reserved. Never a chart series colour. ------------------ */
  --good:      #2F6B4F;
  --warning:   #A56A00;
  --serious:   #B4531C;
  --critical:  #A8261C;

  /* --- Semantic surface/content roles ----------------------------------- */
  --bg:            var(--paper);
  --bg-alt:        var(--mist);
  --surface:       #FFFFFF;
  --surface-sunk:  var(--mist);
  --fg:            var(--ink);
  --fg-muted:      var(--stone);
  --fg-on-dark:    #F5F1EC;
  --fg-on-dark-muted: #A79C91;
  --border:        var(--line);
  --border-strong: var(--line-strong);
  --border-on-dark: #352E27;
  --focus-ring:    var(--ember);

  /* The footer needs its own ground rather than borrowing --ink. In dark mode
     --ink (#14110F) and --bg (#100D0B) are four values apart and the footer
     disappeared into the page — it read as more page, not as a footer. This
     token is defined per theme so the footer is always a distinct surface. */
  --footer-bg:     var(--ink);
  --footer-rule:   var(--ember);

  /* Dark full-bleed bands — the stat band and the closing CTA — have the same
     problem the footer had: on a dark page, --ink is four values from --bg and
     the band stops reading as a band. Defined per theme for the same reason. */
  --band-ink-bg:   var(--ink);

  /* --- Chart scales — see docs/dashboard/README.md ----------------------- */
  /* Categorical: SIX colours, FIXED ORDER, never cycled, never reassigned by
     rank. Six is the number of GCC markets — the only categorical dimension in
     this product that reaches that size. A seventh series folds into "Other",
     becomes small multiples, or uses a composite encoding.

     Validated by tools/validate-palette.mjs, not by eye:
       normal vision, all pairs      dE 15.0   (floor 15)
       simulated CVD, all pairs      dE 10.0   (floor 8)
       every mark vs its surface     >= 3:1 contrast
     An eight-colour version of this palette was tried first and FAILED at
     dE 6.5 under deuteranopia. Do not add a seventh or eighth hue without
     re-running the validator. */
  --cat-1: #2E4756;  --cat-2: #C8541F;  --cat-3: #6E91D8;
  --cat-4: #6B5BA5;  --cat-5: #712800;  --cat-6: #34856A;
  /* Sequential: one hue, light to dark. Never a rainbow.                   */
  --seq-1: #EAEEF0;  --seq-2: #C3CED5;  --seq-3: #94A6B1;
  --seq-4: #64808F;  --seq-5: #40606F;  --seq-6: #2E4756;
  /* Diverging: two hues, NEUTRAL GRAY midpoint. Deliberately not red-green. */
  --div-neg: #B4531C;  --div-mid: #EFEAE4;  --div-pos: #2E6B72;
  --chart-grid: var(--line);
  --chart-axis: var(--stone);

  /* --- Typography -------------------------------------------------------- */
  --font-display: "Archivo", "Archivo Fallback", system-ui, sans-serif;
  --font-body:    "IBM Plex Sans", "IBM Plex Sans Fallback", system-ui, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --font-arabic:  "IBM Plex Sans Arabic", "Noto Naskh Arabic", system-ui, sans-serif;

  /* Fluid between the 390px and 1280px design widths. Clamps are authored
     from the two-point scale in the spec, not invented per component. */
  --fs-display: clamp(2.375rem, 1.31rem + 4.37vw, 4rem);      /* 38 -> 64 */
  --fs-h1:      clamp(1.875rem, 1.21rem + 2.73vw, 2.75rem);   /* 30 -> 44 */
  --fs-h2:      clamp(1.5rem, 1.14rem + 1.46vw, 2rem);        /* 24 -> 32 */
  --fs-h3:      clamp(1.1875rem, 1.06rem + 0.51vw, 1.375rem); /* 19 -> 22 */
  --fs-lead:    clamp(1.125rem, 1.03rem + 0.38vw, 1.3125rem); /* 18 -> 21 */
  --fs-body:    clamp(1rem, 0.98rem + 0.11vw, 1.0625rem);     /* 16 -> 17 */
  --fs-small:   0.9375rem;                                    /* 15       */
  --fs-label:   0.75rem;                                      /* 12 mono  */
  --fs-stat:    clamp(2.75rem, 1.19rem + 6.4vw, 4.25rem);     /* 44 -> 68 */

  --lh-display: 1.00;  --lh-h1: 1.08;  --lh-h2: 1.16;  --lh-h3: 1.26;
  --lh-lead: 1.50;     --lh-body: 1.62; --lh-small: 1.55; --lh-label: 1.40;
  --lh-stat: 0.96;

  --tracking-display: -0.02em;
  --tracking-label:   0.12em;

  --weight-regular: 400;  --weight-medium: 500;
  --weight-semi:    600;  --weight-bold:   700;

  --measure:      68ch;   /* running text cap */
  --measure-legal: 65ch;  /* long-form legal / article body */

  /* --- Space — the whole scale. Nothing off-scale, ever. ----------------- */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 24px;  --sp-6: 32px;  --sp-7: 48px;  --sp-8: 64px;
  --sp-9: 96px;  --sp-10: 128px; --sp-11: 160px;

  /* Section rhythm. Vary DELIBERATELY per section — tight for a dense index,
     loose for a manifesto. Consistent rhythm is not identical rhythm. */
  --section-y:       var(--sp-8);   /* 64 mobile */
  --section-y-tight: var(--sp-7);   /* 48 mobile */
  --section-y-loose: var(--sp-9);   /* 96 mobile */

  /* --- Grid -------------------------------------------------------------- */
  --container:   1280px;
  --gutter:      var(--sp-4);
  --grid-gap:    var(--sp-5);
  --grid-cols:   12;

  /* --- Radius — this is the entire vocabulary. No pills, no rounded-2xl. -- */
  --r-input: 2px;   /* inputs, chips  */
  --r-btn:   4px;   /* buttons        */
  --r-card:  6px;   /* images, cards  */
  --r-flat:  0;     /* bands, tables  */

  /* --- Icon tile — the marker that replaced the ordinal counters. --------
     Radius is --r-card deliberately: the vocabulary above is the whole
     vocabulary, and a tile does not earn a fifth value. --ember-wash is
     already redefined for dark mode, so the tint follows the theme with no
     second declaration. ----------------------------------------------------- */
  --icon-tile:       46px;  /* pillars, edge, hero-adjacent markers */
  --icon-tile-sm:    34px;  /* dense index rows                     */
  --icon-tile-glyph: 22px;
  --icon-tile-bg:    var(--ember-wash);
  --icon-tile-fg:    var(--ember);

  /* --- Elevation — borders carry structure; shadow is rare. -------------- */
  --shadow-raised:  0 1px 2px rgba(20,17,15,.05), 0 12px 32px -20px rgba(20,17,15,.20);
  --shadow-overlay: 0 2px 6px rgba(20,17,15,.08), 0 32px 64px -24px rgba(20,17,15,.32);
  --rule:        1px solid var(--border);
  --rule-strong: 1px solid var(--border-strong);

  /* --- Motion ------------------------------------------------------------ */
  --ease-out:    cubic-bezier(.23, 1, .32, 1);
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --ease-drawer: cubic-bezier(.32, .72, 0, 1);
  /* NEVER ease-in on a UI element: it delays the first frame, which is the
     exact moment the user is looking at. */

  --dur-press:    140ms;
  --dur-tooltip:  160ms;
  --dur-hover:    160ms;
  --dur-dropdown: 200ms;
  --dur-panel:    260ms;
  --dur-reveal:   420ms;
  --dur-image:    620ms;   /* clip-path hero reveal — the one expressive move */
  /* Exit is always faster than enter. */
  --dur-exit:     140ms;

  /* --- Layers ------------------------------------------------------------ */
  --z-base: 0; --z-sticky: 20; --z-header: 40; --z-dropdown: 50;
  --z-drawer: 60; --z-modal: 70; --z-toast: 80; --z-skiplink: 90;

  --header-h:      96px;
  --header-h-condensed: 64px;
  --tap:           44px;   /* minimum touch target */
}

/* ---------------------------------------------------------------------------
   DARK THEME — opt-in only.

   Light is the unconditional default. The site deliberately does NOT follow
   `prefers-color-scheme`: a first-time visitor always lands on the light
   theme, and dark is reached through the header switch, which persists the
   choice in localStorage under `uc-theme`.

   This block redefines TOKENS ONLY — never a component rule — and it may only
   override colour, chart and shadow tokens. `npm run audit:theme` fails the
   build if it ever touches a geometry token, because that would make the two
   themes two different designs rather than one design in two palettes.

   Every token below also has a base definition in :root above. A custom
   property with no base definition fails silently, which is why that is checked
   rather than trusted.
   ------------------------------------------------------------------------ */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:            #100D0B;
  --bg-alt:        #17130F;
  --surface:       var(--ink-2);
  /* Must differ from --bg — see the note in the media-query block above. */
  --surface-sunk:  #1B1613;
  --fg:            #F5F1EC;
  --fg-muted:      #A79C91;
  --border:        #302923;
  --border-strong: #4A4038;
  --ember:         #E46A32;
  --ember-deep:    #F08048;
  --ember-wash:    #2A1A11;
  --slate:         #7FA0B2;
  --mist:          #1B1613;
  --good:     #56A97F;  --warning: #D19B33;
  --serious:  #D97841;  --critical: #DE5B50;
  --seq-1: #1B252B; --seq-2: #2C3D47; --seq-3: #435A67;
  --seq-4: #5E7A88; --seq-5: #8098A6; --seq-6: #A8BCC7;
  --div-neg: #D97841; --div-mid: #2E2823; --div-pos: #4FA5AC;
  --cat-1: #7FA0B2; --cat-2: #E46A32; --cat-3: #DDDD97;
  --cat-4: #4569A3; --cat-5: #82D7FF; --cat-6: #9C5859;
  --chart-grid: #302923;
  --chart-axis: #A79C91;
  /* Lighter than --bg (#100D0B), not darker: on a dark page a footer reads
     as a surface that sits above the ground, the same way a panel does. */
  --footer-bg:   #1E1815;
  --footer-rule:   var(--ember);
  --band-ink-bg:   #1E1815;
  --shadow-raised:  0 1px 2px rgba(0,0,0,.4), 0 12px 32px -20px rgba(0,0,0,.7);
  --shadow-overlay: 0 2px 6px rgba(0,0,0,.5), 0 32px 64px -24px rgba(0,0,0,.8);
}

/* ---------------------------------------------------------------------------
   Larger viewports: open the section rhythm and the gutter.
   ------------------------------------------------------------------------ */
@media (min-width: 768px) {
  :root {
    --gutter: var(--sp-5);
    --section-y:       var(--sp-9);
    --section-y-tight: var(--sp-8);
    --section-y-loose: var(--sp-10);
  }
}
@media (min-width: 1280px) {
  :root {
    --section-y:       var(--sp-10);
    --section-y-tight: var(--sp-9);
    --section-y-loose: var(--sp-11);
  }
}

/* ---------------------------------------------------------------------------
   Arabic: sibling face, looser leading, display sizes stepped down one notch.
   Never letter-space, fake-bold or uppercase Arabic.
   ------------------------------------------------------------------------ */
:root:lang(ar), [lang="ar"] {
  --font-display: var(--font-arabic);
  --font-body:    var(--font-arabic);
  --lh-display: 1.20; --lh-h1: 1.28; --lh-h2: 1.34; --lh-h3: 1.45;
  --lh-lead: 1.80;    --lh-body: 1.75; --lh-small: 1.72;
  --tracking-display: 0;
  --tracking-label:   0;
  --fs-display: clamp(2rem, 1.19rem + 3.33vw, 3.25rem);   /* 32 -> 52 */
  --fs-h1:      clamp(1.625rem, 1.13rem + 2.05vw, 2.375rem);
  --fs-stat:    clamp(2.5rem, 1.41rem + 4.48vw, 3.5rem);
  --measure:    58ch;   /* Arabic runs wider per character */
}

/* ---------------------------------------------------------------------------
   Reduced motion: fewer and gentler, not none. Opacity and colour survive;
   every transform and translation is removed.
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-press: 1ms; --dur-image: 1ms; --dur-reveal: 200ms;
    --dur-panel: 120ms; --dur-dropdown: 120ms;
  }
}
