/* ============================================================================
   White Sand OS — Frontend Convergence design tokens  (FE-06)
   ----------------------------------------------------------------------------
   WHY THIS FILE EXISTS SEPARATELY FROM css/tokens.css
   `css/tokens.css` is the shipped ramp: seven themes (default dark, light,
   black, sand, midnight, ocean, hc) that every existing screen already reads.
   It is not rewritten here, and not one of its declarations is changed —
   rewriting it is exactly the visual regression FE-06 is forbidden to cause.

   This file adds ONE new, additive layer on top: the `--ds-*` namespace that
   the convergence surfaces (Operating Space navigation, Department Consoles,
   Activity Workspaces, entity context) reference. Because every color token is
   an ALIAS onto the existing ramp, the new layer inherits all seven themes for
   free and can never drift from the rest of the app.

   CASCADE SAFETY — this file declares custom properties ONLY, and every name it
   declares begins with `--ds-`. It therefore cannot change the computed value of
   any property any existing screen reads. The one exception is the documented
   `:root:not([data-theme])` block at the bottom, which is unreachable in the
   shipped shell (index.html always stamps data-theme) and is mutually exclusive
   with every [data-theme] block by construction.
   Both facts are enforced by tests/designSystem.test.mjs.

   CONTRACT — the token list is frozen in js/design/tokens.js. Adding, renaming
   or removing a token here without updating that manifest fails the tests.
   ========================================================================== */

:root {
  /* ===== COLOR ==========================================================
     Aliases onto the ramp in css/tokens.css. Contrast for every pair a
     primitive actually paints is verified in tests/designSystem.test.mjs
     across all seven themes; the numbers are tabulated in
     docs/frontend-convergence/DESIGN_SYSTEM.md. */

  /* Surfaces — the planes a convergence surface may paint on. */
  --ds-color-surface-canvas:  var(--surface-0);
  --ds-color-surface-raised:  var(--surface-1);
  --ds-color-surface-sunken:  var(--surface-inset);
  --ds-color-surface-overlay: var(--surface-3);
  --ds-color-surface-hover:   var(--surface-2);
  --ds-color-surface-inverse: var(--text);
  --ds-color-scrim:           color-mix(in srgb, var(--bg) 62%, transparent);

  /* Text. `primary` and `secondary` clear 4.5:1 on every surface above in every
     theme. `muted` clears only 3:1 — it is a large-text / non-essential-metadata
     color and primitives.css never sets a sentence in it. */
  --ds-color-text-primary:   var(--text);
  --ds-color-text-secondary: var(--text-2);
  --ds-color-text-muted:     var(--text-3);
  --ds-color-text-inverse:   var(--surface-1);
  --ds-color-text-on-accent: var(--text-on-brand);

  /* Borders. Separators are decorative: they sit at ~1.2–2.1:1 against their
     surface in most themes, so no primitive may convey meaning with a border
     alone — every state also carries a label, and status borders use the
     status ink (>= 3:1), not these. */
  --ds-color-border-subtle:  var(--line-soft);
  --ds-color-border-default: var(--line);
  --ds-color-border-strong:  var(--line-strong);

  /* Accent. `--ds-color-accent` is the identity red: a UI / large-text color
     (white on it is 4.12:1, and only 2.81:1 in the hc theme). The primary
     action therefore fills with `--ds-color-accent-strong`, where the label
     clears 5.63:1 in every theme. */
  --ds-color-accent:         var(--brand);
  --ds-color-accent-strong:  var(--brand-strong);
  --ds-color-accent-hover:   var(--brand-strong);
  --ds-color-accent-surface: var(--brand-tint);
  --ds-color-accent-border:  var(--brand);

  /* Status — five tones x three roles.
     `-surface` is the chip/banner plane, `-fg` the ink used for the dot, the
     border and any icon, and the LABEL on a status surface is always
     --ds-color-text-primary (>= 10.4:1 in every theme). That is what keeps the
     tinted look while staying AA: colored ink on a colored tint does not. */
  --ds-color-status-success-fg:      var(--ok);
  --ds-color-status-success-surface: var(--ok-tint);
  --ds-color-status-success-border:  var(--ok);
  --ds-color-status-warning-fg:      var(--warn);
  --ds-color-status-warning-surface: var(--warn-tint);
  --ds-color-status-warning-border:  var(--warn);
  --ds-color-status-danger-fg:       var(--danger);
  --ds-color-status-danger-surface:  var(--danger-tint);
  --ds-color-status-danger-border:   var(--danger);
  --ds-color-status-info-fg:         var(--info);
  --ds-color-status-info-surface:    var(--info-tint);
  --ds-color-status-info-border:     var(--info);
  --ds-color-status-neutral-fg:      var(--text-2);
  --ds-color-status-neutral-surface: var(--surface-2);
  --ds-color-status-neutral-border:  var(--line-strong);

  /* Focus. Single source for the visible keyboard ring. */
  --ds-color-focus-ring: var(--color-focus-ring);

  /* ===== SPACING — 4pt scale ============================================ */
  --ds-space-0:  0;
  --ds-space-1:  var(--sp-1);   /*  4px */
  --ds-space-2:  var(--sp-2);   /*  8px */
  --ds-space-3:  var(--sp-3);   /* 12px */
  --ds-space-4:  var(--sp-4);   /* 16px */
  --ds-space-5:  var(--sp-5);   /* 20px */
  --ds-space-6:  var(--sp-6);   /* 24px */
  --ds-space-8:  var(--sp-8);   /* 32px */
  --ds-space-10: var(--sp-10);  /* 40px */
  --ds-space-12: var(--sp-12);  /* 48px */

  /* ===== TYPOGRAPHY =====================================================
     Two real stacks, each with system fallbacks that actually exist on the
     platforms this ships to, so a blocked/absent webfont degrades to a face
     with the right script coverage rather than to a default serif.
     IBM Plex Sans Arabic leads both stacks: it carries Latin as well as Arabic,
     so mixed AR/EN strings — which every White Sand screen has — keep one set
     of metrics instead of visibly switching face mid-line. */
  --ds-font-arabic: 'IBM Plex Sans Arabic', 'Noto Sans Arabic', 'Segoe UI',
                    Tahoma, 'Geeza Pro', 'Arabic Typesetting', system-ui, sans-serif;
  --ds-font-latin:  'IBM Plex Sans Arabic', 'Segoe UI', system-ui, -apple-system,
                    'Helvetica Neue', Arial, sans-serif;
  --ds-font-body:   var(--ds-font-arabic);
  /* Numbers, codes and numeric table columns are Archivo, always (self-hosted
     in css/tokens.css); Arabic-Indic digits fall back to IBM Plex. */
  --ds-font-numeric: var(--font-num);
  --ds-font-mono:    var(--mono);

  --ds-text-xs:  var(--fs-xs);   /* 11px   — chips, meta */
  --ds-text-sm:  var(--fs-sm);   /* 12.5px — dense UI, table cells */
  --ds-text-md:  var(--fs-md);   /* 13.5px — body default */
  --ds-text-lg:  var(--fs-lg);   /* 15px   — panel titles */
  --ds-text-xl:  var(--fs-xl);   /* 18px   — section titles */
  --ds-text-2xl: var(--fs-2xl);  /* 23px   — page title */
  --ds-text-3xl: var(--fs-3xl);  /* 30px   — hero numerals */

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

  --ds-leading-tight:   1.25;  /* headings */
  --ds-leading-snug:    1.4;   /* dense rows */
  --ds-leading-normal:  var(--lh);  /* 1.55 — body */
  --ds-leading-relaxed: 1.75;  /* long-form Arabic prose */

  --ds-tracking-tight:  -.01em;
  --ds-tracking-normal: 0;
  --ds-tracking-wide:   .06em;

  /* ===== RADIUS ========================================================= */
  --ds-radius-xs:   var(--r-xs);
  --ds-radius-sm:   var(--r-sm);
  --ds-radius-md:   var(--r-md);
  --ds-radius-lg:   var(--r-lg);
  --ds-radius-xl:   var(--r-xl);
  --ds-radius-pill: var(--r-pill);

  /* ===== ELEVATION ====================================================== */
  --ds-elevation-0:       none;
  --ds-elevation-1:       var(--sh-sm);
  --ds-elevation-2:       var(--sh-md);
  --ds-elevation-3:       var(--sh-lg);
  --ds-elevation-overlay: var(--sh-pop);

  /* ===== MOTION =========================================================
     Reduced motion is honored at the TOKEN level below, so a primitive that
     transitions with var(--ds-duration-*) needs no media query of its own. */
  --ds-duration-instant: 1ms;
  --ds-duration-fast:    var(--t-fast);  /* .14s — hover, focus */
  --ds-duration-base:    var(--t);       /* .22s — enter/exit */
  --ds-duration-slow:    var(--t-slow);  /* .40s — layout, progress */
  --ds-ease-standard:    var(--ease);
  --ds-ease-emphasized:  var(--ease-out);

  /* ===== DENSITY ========================================================
     One multiplier drives control height and row padding — deliberately NOT
     the whole spacing scale, so a density change cannot reflow a page's
     rhythm, only the controls' comfort. Set data-density on any container. */
  --ds-density-scale:      1;
  --ds-control-height:     calc(38px * var(--ds-density-scale));
  --ds-control-height-sm:  calc(30px * var(--ds-density-scale));
  --ds-control-height-lg:  calc(46px * var(--ds-density-scale));
  --ds-row-padding-block:  calc(var(--ds-space-3) * var(--ds-density-scale));
  --ds-row-padding-inline: var(--ds-space-4);
  /* Never scaled: the pointer-target floor is an accessibility minimum. */
  --ds-tap-target-min:     var(--tap);

  /* ===== FOCUS GEOMETRY =================================================
     A two-stop ring: an offset in the surface color, then the ring itself, so
     it stays visible on a colored chip, a table row and a modal alike. */
  --ds-focus-ring-width:  2px;
  --ds-focus-ring-offset: 2px;
  --ds-focus-ring:
    0 0 0 var(--ds-focus-ring-offset) var(--ds-color-surface-canvas),
    0 0 0 calc(var(--ds-focus-ring-offset) + var(--ds-focus-ring-width)) var(--ds-color-focus-ring);

  /* ===== LAYOUT + STACKING ==============================================
     z-index values are chosen to interleave correctly with the existing shell:
     .qb-topbar 30, .topbar 40, .overlay/.drawer-host 150, .cmdk-overlay 180,
     .toast-host 200, .tour-overlay 400. */
  --ds-layout-max:    var(--content-max);
  --ds-layout-narrow: var(--content-narrow);
  --ds-layout-gutter: var(--ds-space-6);
  --ds-z-sticky:  30;
  --ds-z-overlay: 150;
  --ds-z-modal:   151;
  --ds-z-toast:   200;
}

/* ---- Script-aware body face ------------------------------------------------
   i18n-core.js applyLang() sets <html lang> to "ar" or "en" alongside dir. */
:root[lang="en"] { --ds-font-body: var(--ds-font-latin); }

/* ---- Density presets -------------------------------------------------------
   Applied with data-density on any element; the tokens cascade to its subtree. */
[data-density="compact"]     { --ds-density-scale: .82; }
[data-density="comfortable"] { --ds-density-scale: 1.12; }

/* ---- Reduced motion --------------------------------------------------------
   css/base.css already neutralises animation/transition globally under this
   query. Collapsing the duration tokens as well means a convergence primitive
   is correct even in a context that does not load base.css. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --ds-duration-fast: var(--ds-duration-instant);
    --ds-duration-base: var(--ds-duration-instant);
    --ds-duration-slow: var(--ds-duration-instant);
  }
}

/* ============================================================================
   prefers-color-scheme fallback
   ----------------------------------------------------------------------------
   The shell's theme mechanism is the [data-theme] attribute (seven themes,
   persisted as ws_theme, applied before first paint by js/theme-init.js), and
   FE-06 REUSES it rather than introducing a second one — the --ds-* aliases
   above already follow it.

   What that mechanism cannot do is serve a host page that stamps no theme at
   all: it would get the :root default, which is dark, even when the OS asks for
   light. The block below closes exactly that gap. It is:
     • mutually exclusive with every [data-theme] rule, by construction —
       :not([data-theme]) and [data-theme="…"] can never both match; and
     • unreachable in the shipped shell, because index.html hard-stamps
       data-theme="light" on <html> and theme-init.js only ever replaces it.
   So it cannot change what any existing screen renders. It is kept in step with
   the real light theme by a test that compares it declaration-by-declaration
   with the [data-theme="light"] block in css/tokens.css — drift fails the build.
   ========================================================================== */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --bg: #EDEDEB;
    --surface-0: #F6F6F4;
    --surface-1: #FFFFFF;
    --surface-2: #FAFAF9;
    --surface-3: #FFFFFF;
    --surface-inset: #F4F4F2;
    --line: #E6E6E4;
    --line-strong: #D8D8D6;
    --line-soft: color-mix(in srgb, var(--line) 70%, transparent);
    --text: #141414;
    --text-2: #6B6B6B;
    --text-3: #8A8A8A;
    --brand-glow: color-mix(in srgb, var(--brand) 20%, transparent);
    --ok: #1B8A4C;
    --ok-tint: #E7F3EC;
    --warn: #B7770F;
    --warn-tint: #FFF4E0;
    --danger: #ED322D;
    --danger-tint: #FDEAE9;
    --info: #2f6fe0;
    --sh-sm: 0 1px 2px rgba(20,20,20,.06);
    --sh-md: 0 6px 22px rgba(20,20,20,.09);
    --sh-lg: 0 18px 50px rgba(20,20,20,.14);
    --sh-pop: 0 12px 32px rgba(0,0,0,.14);
    color-scheme: light;
  }
}
