/* ═══════════════════════════════════════════════════════════════════════
   SKOPEIN · assets/tokens.css · APERTURE v3.0
   Linked BEFORE app.css and style.css on every page, so the console and
   the landing cannot drift on a single value.

   Two levers to know before reading further:
     --stroke   was 2px, is now 1px. Every border in the codebase,
                including the inline ones, thins itself.
     --dim      same name, lighter value. Fixes the failing tertiary
                text everywhere it is used, inline included.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  color-scheme: dark;

  /* ── 1 · graphite ramp · v2.1 hexes, unchanged. This IS the brand. ── */
  --g-50:#F4F6F7;  --g-100:#E8EBED; --g-200:#D3D8DC; --g-300:#B0B8BF;
  --g-400:#8D97A1; --g-500:#6A7581; --g-600:#4D5761; --g-700:#353D46;
  --g-800:#232930; --g-900:#171C21; --g-950:#0F1317;
  --g-990:#0A0D10;                    /* new · the ground BEHIND the glass */

  /* ── 2 · the one signal ─────────────────────────────────────────── */
  --signal-300:#FF9633; --signal-500:#FF7A00;
  --signal-600:#E06900; --signal-800:#9E4A00;   /* amber as ink on light  */
  --signal-rgb:255,122,0;

  /* ── 3 · status · state only, never decoration ──────────────────── */
  --ok:#4CC97B;   --ok-rgb:76,201,123;    --ok-ink:#0E7A3C;
  --warn:#FFB020; --warn-rgb:255,176,32;  --warn-ink:#8A5A00;
  --crit:#FF6B5E; --crit-rgb:255,107,94;  --crit-ink:#B3261E;

  /* ── 4 · ground ───────────────────────────────────────────────────
     Not flat. Blur needs something to blur; glass needs something to
     float over. Two very low graphite washes, no hue, plus the
     graticule at 5%. Nothing here is amber.                          */
  --bg:var(--g-990);
  --bg-field:
    radial-gradient(120% 80% at 12% -10%, rgba(232,235,237,.055), transparent 62%),
    radial-gradient(100% 70% at 92% 4%,   rgba(232,235,237,.028), transparent 58%);
  --bg-grid:linear-gradient(rgba(53,61,70,.55) 1px, transparent 1px),
            linear-gradient(90deg, rgba(53,61,70,.55) 1px, transparent 1px);
  --bg-grid-size:48px 48px;
  --bg-grid-opacity:.05;

  /* ── 5 · PLATE · translucent, NEVER blurred. Content lives here. ──
     0.66 of #1C2229 over #0A0D10 composites to ≈#161B21, which is why
     every contrast figure below holds regardless of what is behind.  */
  --surface:rgba(28,34,41,.66);
  --surface-solid:#1C2229;
  --raised:rgba(38,45,53,.72);
  --raised-solid:#262D35;
  --sunken:rgba(10,13,16,.55);          /* inputs, media wells         */
  --surface-quiet:rgba(24,29,35,.38);   /* paused / withdrawn / held   */
  --well:var(--g-990);                  /* the ground under imagery    */

  /* ── 6 · GLASS · translucent AND blurred. Floating chrome only. ─── */
  --glass:rgba(20,25,30,.72);
  --glass-thick:rgba(18,22,27,.88);     /* sheets · deliberately opaque:
                                           never nest blur inside blur */
  --glass-blur:blur(18px) saturate(150%);
  --glass-blur-thin:blur(12px) saturate(130%);
  --scrim:rgba(6,9,12,.62);
  --scrim-blur:blur(6px);

  /* ── 7 · edges · the specular recipe ─────────────────────────────── */
  --line:rgba(255,255,255,.09);         /* hairline, plates            */
  --line-strong:rgba(255,255,255,.16);  /* hairline, interactive       */
  --line-solid:#232930;                 /* where alpha will not do     */
  --glass-line:rgba(255,255,255,.11);
  /* the light catches the top-left arc and dies by the middle */
  --specular:linear-gradient(158deg,
      rgba(255,255,255,.22) 0%,
      rgba(255,255,255,.07) 26%,
      rgba(255,255,255,0)   56%,
      rgba(255,255,255,.04) 100%);
  --sheen:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,0) 44%);
  --hi:inset 0 1px 0 rgba(255,255,255,.075);   /* specular top edge     */
  --lo:inset 0 -1px 0 rgba(0,0,0,.30);         /* seated base           */

  /* ── 8 · depth · neutral black only. No coloured shadows. ────────── */
  --sh-1:0 1px 2px rgba(0,0,0,.30), 0 8px 24px -18px rgba(0,0,0,.55);
  --sh-2:0 2px 6px rgba(0,0,0,.32), 0 18px 40px -22px rgba(0,0,0,.62);
  --sh-3:0 8px 24px rgba(0,0,0,.38), 0 40px 80px -32px rgba(0,0,0,.70);
  --sh-sheet:0 -6px 44px rgba(0,0,0,.62);

  /* ── 9 · ink · every ratio measured on the composited plate ──────── */
  --text:var(--g-100);      /* #E8EBED · 14.7:1                        */
  --muted:#A3ACB5;          /*            7.7:1 · secondary body       */
  --dim:#8B96A1;            /*            5.8:1 · hints, feet, meta    */
  --faint:var(--g-500);     /* #6A7581 ·  3.7:1 · NON-TEXT ONLY        */
  --accent:var(--signal-500);
  --accent-hover:var(--signal-300);
  --accent-ink:var(--signal-500);   /* amber as TEXT/BORDER · 6.7:1    */
  --on-accent:var(--g-950);         /* amber fills always carry this   */
  --wash:rgba(var(--signal-rgb),.10);
  --wash-strong:rgba(var(--signal-rgb),.16);
  --ring:rgba(var(--signal-rgb),.24);
  --edge-on:var(--g-300);   /* the lit edge of a chosen control · NON-TEXT */
  --tint:rgba(255,255,255,.06);       /* a pill's fill, on any plate    */
  --tint-off:rgba(255,255,255,.045);  /* a switched-off pill's fill     */
  --press:inset 0 1px 2px rgba(0,0,0,.28);   /* a field pressed INTO the plate */

  /* ── 10 · shape · concentric rule: inner = outer − padding ───────── */
  --r-1:6px;    /* chips' inner marks, skeleton lines                  */
  --r-2:10px;   /* buttons, inputs, small tiles                        */
  --r-3:14px;   /* nested cards, thumbnails, notes                     */
  --r-4:18px;   /* cards, panels, rules, incidents, stat tiles         */
  --r-5:24px;   /* desktop modals, empty states, the auth card         */
  --r-6:32px;   /* bottom sheets (top corners), the landing plate      */
  --r-full:999px;
  --stroke:1px;         /* WAS 2px · thins every inline border, free   */
  --stroke-frame:2px;   /* detection frame + focus ring. Nothing else. */

  /* ── 11 · space · 4px base; 24/32/40 remain the section rhythm ───── */
  --s-1:4px;  --s-2:8px;  --s-3:12px; --s-4:16px; --s-5:20px;
  --s-6:24px; --s-8:32px; --s-10:40px; --s-14:56px; --s-18:72px;
  --grid:24px;              /* v2.1 name kept; now section rhythm only */
  --tap:44px;

  /* ── 12 · type ───────────────────────────────────────────────────── */
  /* Geist has no Arabic letters, so each Arabic letter is drawn by the
     Arabic web face ("Skopein Arabic", IBM Plex Sans Arabic renamed as its
     licence asks, fonts.css) and each Latin letter and digit by Geist, in
     one line. Both Arabic faces carry an Arabic-only unicode-range, so a
     page with no Arabic on it never downloads the web face and draws
     exactly as before (25 Sep 2026, docs/ARABIC-DESIGN-2026-09-25.md 5.2);
     the one Arabic word on an English console page, the «العربية» switch,
     is drawn in the local "Arabic Fallback" (app.css). */
  --sk-sans:"Geist","Skopein Arabic","Arabic Fallback","Geist Fallback",
            -apple-system,BlinkMacSystemFont,"Segoe UI Variable Text","Segoe UI",
            Tahoma,Roboto,"Helvetica Neue",Arial,sans-serif;
  --sk-mono:"Geist Mono","Skopein Arabic","Arabic Fallback","Geist Mono Fallback",
            ui-monospace,SFMono-Regular,"SF Mono",Menlo,"Cascadia Mono",Consolas,
            "Liberation Mono",monospace;
  --sk-display:var(--sk-sans);
  --sk-greek:"Noto Sans","Segoe UI",system-ui,sans-serif;
  --sk-semi-mono:var(--sk-sans);   /* RETIRED · alias kept so #r-prompt lives */

  --t-2xs:11.5px;  /* mono machine labels, pills, chips                */
  --t-xs:12.5px;   /* .hint, card feet, form labels                    */
  --t-sm:13.5px;   /* buttons, table meta                              */
  --t-base:15.5px; /* body · up from 15, this is read outdoors         */
  --t-md:17px;     /* the watch-rule sentence · the hero of rules.html */
  --t-lg:20px;     /* h3, panel titles                                 */
  --t-xl:24px;     /* h2                                               */
  --t-2xl:clamp(26px,6vw,34px);   /* h1                                */
  --t-stat:clamp(28px,7vw,36px);  /* .stat .v                          */
  --t-display:clamp(30px,7.4vw,52px);  /* landing hero only            */

  --lh-tight:1.12; --lh-snug:1.35; --lh-say:1.45; --lh-body:1.6;
  --track-display:-.028em; --track-head:-.018em;
  --label-size:11.5px; --label-tracking:.08em; --label-weight:500;
  --measure:62ch;

  /* ── 13 · motion · the v2.1 ease survives; it is part of the voice ─ */
  --ease:cubic-bezier(.16,1,.3,1);          /* everything that settles  */
  --ease-sheet:cubic-bezier(.32,.72,0,1);   /* sheets and drawers       */
  --ease-spring:cubic-bezier(.34,1.4,.64,1);/* the switch knob ONLY     */
  --d-1:120ms; --d-2:180ms; --d-3:260ms; --d-4:320ms;

  /* ── 14 · layout + layers ────────────────────────────────────────── */
  --side-w:264px; --top-h:56px; --tabbar-h:56px;
  --safe-t:env(safe-area-inset-top,0px);
  --safe-b:env(safe-area-inset-bottom,0px);
  --content-max:1180px;
  --z-scrim:40; --z-tabbar:45; --z-side:50; --z-top:30;
  --z-ovl:60; --z-toast:80;

  /* ── 15 · the drawing dialog ─────────────────────────────────────── */
  --zone-veil:rgba(10,13,16,.68);   /* read by zones.js at open         */
  --zone-corner:9px;                /* was 7 · a finger, not a mouse    */
}

@media (min-width:901px){
  :root{ --top-h:60px; --t-base:15px }
}

/* ═══ LIGHT · the main theme since 26 Sep 2026, by the owner's decision.
   Every page ships data-theme="light"; dark is the choice people make in
   Appearance, which the pre-paint stamps on <html> before paint.       ═══
   Amber becomes ink (#9E4A00, 6.1:1) wherever it is TEXT or a BORDER.
   Amber FILLS stay #FF7A00 with graphite-950 on them (7.2:1), so every
   solid button, tag and detection frame is unchanged between themes.
   That single split is why light costs one block.                     */
:root[data-theme="light"]{
  color-scheme:light;
  --bg:#F2F4F6;
  --bg-field:
    radial-gradient(120% 80% at 12% -10%, rgba(15,19,23,.045), transparent 62%),
    radial-gradient(100% 70% at 92% 4%,   rgba(15,19,23,.022), transparent 58%);
  --bg-grid:linear-gradient(rgba(15,19,23,.55) 1px, transparent 1px),
            linear-gradient(90deg, rgba(15,19,23,.55) 1px, transparent 1px);
  --bg-grid-opacity:.04;

  --surface:rgba(255,255,255,.78);  --surface-solid:#FFFFFF;
  --raised:rgba(255,255,255,.94);   --raised-solid:#F6F8FA;
  --sunken:rgba(255,255,255,.70);
  --surface-quiet:rgba(255,255,255,.45);
  --well:var(--g-200);

  --glass:rgba(255,255,255,.72);
  --glass-thick:rgba(250,251,253,.92);

  --line:rgba(15,19,23,.10); --line-strong:rgba(15,19,23,.18);
  --line-solid:#D6DDE4;      --glass-line:rgba(255,255,255,.80);
  --specular:linear-gradient(158deg,
      rgba(255,255,255,.95) 0%, rgba(255,255,255,.45) 26%,
      rgba(255,255,255,0) 56%, rgba(15,19,23,.035) 100%);
  --sheen:linear-gradient(180deg, rgba(255,255,255,.85), rgba(255,255,255,0) 44%);
  --hi:inset 0 1px 0 rgba(255,255,255,.90);
  --lo:inset 0 -1px 0 rgba(15,19,23,.06);

  --sh-1:0 1px 2px rgba(15,19,23,.06), 0 8px 24px -18px rgba(15,19,23,.20);
  --sh-2:0 2px 6px rgba(15,19,23,.08), 0 18px 40px -22px rgba(15,19,23,.24);
  --sh-3:0 8px 24px rgba(15,19,23,.10), 0 40px 80px -32px rgba(15,19,23,.28);
  --sh-sheet:0 -4px 32px rgba(15,19,23,.18);
  --scrim:rgba(30,38,46,.38);

  --text:#131920;      /* 17.8:1 on white */
  --muted:#4A5560;     /*  7.5:1          */
  --dim:#5C6772;       /*  5.7:1          */
  --faint:#939DA7;     /* NON-TEXT ONLY   */
  --accent-ink:var(--signal-800);   /* 6.1:1 · amber as text on light  */
  --on-accent:var(--g-950);         /* amber fills keep graphite ink   */
  --ok:var(--ok-ink); --warn:var(--warn-ink); --crit:var(--crit-ink);
  --wash:rgba(var(--signal-rgb),.12);
  --ring:rgba(var(--signal-rgb),.30);
  --edge-on:var(--g-600);
  --tint:rgba(15,19,23,.045);  --tint-off:rgba(15,19,23,.03);
  --press:inset 0 1px 2px rgba(15,19,23,.08);
  --zone-veil:rgba(242,244,246,.72);   /* a white veil, not a dark one  */
}

/* ═══ ARABIC · the machine voice without capitals, mono or tracking ════
   25 Sep 2026, docs/ARABIC-DESIGN-2026-09-25.md 5.3. The English label voice
   is uppercase + mono + letter-spacing. Arabic has no capitals and no
   monospace, and ANY letter-spacing pulls joined Arabic letters apart, so
   the Arabic voice is carried by size, weight and colour alone.

   Here and not in app.css because every page loads this file, and install,
   privacy and terms load no app.css. Keyed on the page's lang, which the
   pre-paint script sets on the console pages and each public file states
   for itself: an English page never matches any of it.

   Weight 600 where English asks 500: only 400 and 600 of the Arabic face
   ship, and a 500 request would fall to 400 (5.1). */
:root[lang="ar"]{
  --label-size:12.5px; --label-tracking:0; --label-weight:600;
  --t-2xs:12.5px;      --track-head:0;     --track-display:0;
  --lh-tight:1.3;      --lh-snug:1.5;      --lh-say:1.6;  --lh-body:1.75;
}
/* (0,3,0): beats rules like .inc .foot (0,2,0) although app.css loads
   later. Left-to-right islands · codes, addresses, numbers · keep their
   tracking. Anything more specific that still spaces Arabic is caught on
   the screenshots (design 14, item 5). */
:root[lang="ar"] *:not([dir="ltr"],[dir="ltr"] *){letter-spacing:0}
:root[lang="ar"] .label:not([dir="ltr"]),:root[lang="ar"] .pill,:root[lang="ar"] th{
  font-family:var(--sk-sans);text-transform:none}
/* Arabic in the machine voice (.mono) is drawn in the sans (step 4, found on
   the screenshots): the mono face's spaces are as wide as its letters, so
   «رُصدت حركة» and «كاميرا 02 · اليوم» came apart word from word. Codes,
   addresses and times keep the mono inside their left-to-right islands
   (dir="ltr"), as design 5.3 says. */
:root[lang="ar"] .mono:not([dir="ltr"]){font-family:var(--sk-sans)}
/* Arabic has no italic; a slanted Arabic word reads as a mistake */
:root[lang="ar"] em,:root[lang="ar"] i{font-style:normal;font-weight:600}

/* ═══ DEGRADATION · one code path, four triggers ═══════════════════════
   Every glass rule reads these tokens and never writes a literal, so the
   whole system degrades to a clean, fully opaque, hairline-bordered
   console with no visual bugs and no second stylesheet.               */

@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :root{ --glass:rgba(20,25,30,.965); --glass-thick:rgba(18,22,27,.98);
         --glass-blur:none; --glass-blur-thin:none; --scrim-blur:none;
         --scrim:rgba(6,9,12,.86) }
  :root[data-theme="light"]{ --glass:rgba(255,255,255,.97);
         --glass-thick:#FFFFFF }
}

@media (prefers-reduced-transparency:reduce){
  :root{ --glass:var(--surface-solid); --glass-thick:var(--surface-solid);
         --surface:var(--surface-solid); --raised:var(--raised-solid);
         --surface-quiet:var(--surface-solid);
         --glass-blur:none; --glass-blur-thin:none; --scrim-blur:none;
         --specular:none; --sheen:none; --hi:none;
         --line:var(--g-700); --line-strong:var(--g-600);
         --scrim:rgba(6,9,12,.88); --bg-grid-opacity:0 }
  :root[data-theme="light"]{ --line:var(--g-200); --line-strong:var(--g-300);
         --glass:var(--surface-solid); --glass-thick:var(--surface-solid);
         --surface:var(--surface-solid); --raised:var(--raised-solid);
         --surface-quiet:var(--surface-solid);
         --specular:none; --sheen:none; --hi:none;
         --scrim:rgba(30,38,46,.62); --bg-grid-opacity:0 }
}

@media (prefers-contrast:more){
  :root{ --line:rgba(255,255,255,.30); --line-strong:rgba(255,255,255,.46);
         --muted:#C3CCD4; --dim:#AAB4BD;
         --surface:var(--surface-solid); --raised:var(--raised-solid);
         --glass-blur:none; --glass-blur-thin:none }
  :root[data-theme="light"]{ --line:rgba(15,19,23,.30); --line-strong:rgba(15,19,23,.46);
         --muted:#3A444E; --dim:#46515C;
         --surface:var(--surface-solid); --raised:var(--raised-solid) }
}

@media (forced-colors:active){
  :root{ --specular:none; --sheen:none; --hi:none; --lo:none;
         --sh-1:none; --sh-2:none; --sh-3:none; --sh-sheet:none;
         --glass-blur:none; --glass-blur-thin:none; --scrim-blur:none;
         --bg-grid-opacity:0 }
  .panel,.stat,.rule,.inc,.modal,.toast,.btn,.pill,.chip,.note,.conn,.tbl-wrap{
    border:1px solid CanvasText; background:Canvas; color:CanvasText;
    forced-color-adjust:none }
  .frame,.stat.key::before,.stat.key::after{ border-color:Highlight }
}

@media (prefers-reduced-motion:reduce){
  :root{ --d-1:0ms; --d-2:0ms; --d-3:0ms; --d-4:0ms }
  *,*::before,*::after{ animation-duration:.001ms !important;
    animation-iteration-count:1 !important; transition-duration:.001ms !important }
}

/* ═══ RUNTIME KILL SWITCH · the answer to a stutter you cannot reproduce.
       Wired to Account → Appearance → "Reduce transparency".          */
:root[data-glass="off"]{
  --glass:var(--surface-solid); --glass-thick:var(--surface-solid);
  --glass-blur:none; --glass-blur-thin:none; --scrim-blur:none;
}
