/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   يقِظ · YAQIDH — DESIGN SYSTEM
   ═══════════════════════════════════════════════════════════════════════════════════════════════

   WHY THIS FILE EXISTS (2026-08-21)
   ---------------------------------
   `styles.css` had grown to 196 KB holding 583 hardcoded hex values against 1067 `var()` sites.
   Three different reds were live at once — `--sev-critical:#D7263D`, `--uae-red:#FF3B30` and a
   hardcoded `#e11d2a` used 31 times, more often than any token. On a platform where RED IS A
   SEMANTIC — it means "a fire is confirmed" — having three of it is not an aesthetic untidiness,
   it is an ambiguity in a life-safety signal. The national board rendered a value of `0` in red.

   `--uae-red:#FF3B30` was never a UAE colour at all: it is Apple's iOS system red. Sampled from the
   client's own `mustajeeb-logo.png`, the real marks are a deep oxide red `#AC100C` and the flag
   green `#04843B`. Tailwind's cool greys (`#e5e7eb`, `#6b7280`, `#d1d5db`) had also leaked in over
   a warm cream ground, which is what made the surface read faintly muddy.

   THE RULE THIS FILE ENFORCES — TWO NAMESPACES THAT NEVER MIX
   ----------------------------------------------------------
     SOVEREIGN  (--uae-*)  identity and chrome. The flag, the seal, the header. NEVER a status.
     SIGNAL     (--sig-*)  state, and only state. ISO 3864 / ISO 7010 / NFPA 170. NEVER decoration.

   The signal values are not invented here. They are lifted from `vendor/safety-pictograms.js`,
   which already carries this grammar and says why: «that grammar is what a resident has already
   been trained by on the walls of their own building». An operator who sees red on this platform
   is reading the same red as the extinguisher cabinet in the corridor.

   The two namespaces resolve what would otherwise be a collision: green is BOTH the flag and the
   universal "safe condition" colour. Keeping them in separate namespaces means header green is
   never mistaken for an all-clear — and it costs nothing, because ISO safe-green `#00843D` and the
   logo's flag green `#04843B` are the same colour to the eye. The standard and the flag agree.

   HOW IT APPLIES
   --------------
   Loaded AFTER `styles.css`, so redefining `:root` here re-points all 1067 existing `var()` sites
   at the new palette in one move. The 583 hardcoded hexes are NOT fixed by that and are being
   retired surface by surface — login and the command bar are done here; the rest still hold their
   old literals and will drift until they are converted. That is a known, deliberate half-state.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── PALETTE — "National Command Room.dc.html", read through the design MCP ─────────────────────
     One family across both canvases: the sign-in desk and the command room share every value, so
     signing in and arriving on the board is one surface rather than two that resemble each other. */
  --uae-red:#B4122B;          /* THE red. See the note below on what this cost.               */
  --uae-red-hover:#980F23;
  --uae-red-active:#7E0C1D;
  --uae-green:#0E7A46;
  --uae-green-hover:#0B6339;
  --uae-black:#0C1613;        /* header ground, active tab/nav, focus ring                    */
  --uae-white:#FFFFFF;

  /* ── SIGNAL ──────────────────────────────────────────────────────────────────────────────────
     NOTE, deliberately recorded. An earlier pass here split identity red from signal red — deep
     oxide #AC100C for "who we are", bright ISO #D7182A for "there is a fire" — so that chrome could
     never be mistaken for a live alarm. Both canvases collapse that: ONE red, #B4122B, does the
     logout button, the section rule, the selected account and the high-risk KPI alike. The owner
     chose these canvases, so the single red stands and the distinction is gone.

     What carries severity instead, and what must therefore be protected: VALUE and POSITION, not
     hue. The KPI rail and numeral share a colour; amber #E0A82E and blue #1E6F9F are far enough
     from the red in luminance to survive deuteranopia; and a live incident is never signalled by
     colour alone. If a red-on-red confusion ever shows up in use, this is the note to revisit. */
  --sig-fire:#B4122B;
  --sig-safe:#0E7A46;
  --sig-warn:#E0A82E;
  --sig-mandatory:#1E6F9F;

  --sev-critical:#8E0E22;
  --sev-high:#B4122B;
  --sev-elevated:#D2691E;
  --sev-medium:#E0A82E;
  --sev-low:#0E7A46;
  --sev-info:#1E6F9F;

  /* ── GROUND — warm sand ──────────────────────────────────────────────────────────────────────
     #F4F2ED for the board, a shade warmer than the sign-in desk's #F7F5F0 shelf. Cards are white
     and sit on it; #FBFAF7 is the recessed tone for inputs, footers and nested tiles. */
  --bg:#F4F2ED;
  --bg2:#E8E4DB;
  --card:#FFFFFF;
  --card2:#FBFAF7;
  --ink:#131C18;
  --ink2:#46524C;
  --mut:#6E7A73;
  --mut2:#96A09A;
  --line:#E3DFD6;
  --line-soft:#EFECE5;
  --line-strong:#DCD8CF;

  /* Dark-header tones, used by the command bar and the map panel. */
  --hdr:#0C1613;
  --hdr-raise:#131F1B;
  --hdr-line:#24322C;
  --hdr-edge:#2A3832;
  --hdr-tint:#1A2723;
  --hdr-ink:#EDF1EF;
  --hdr-mut:#7E8D86;
  --hdr-chip:#A9B7B0;

  /* ── ROLE ALIASES — the 1067 existing var() sites resolve through these. ───────────────────── */
  --brand:var(--uae-green);
  --sovereign:var(--uae-white);
  --ok:var(--sig-safe);
  --warn:#8A6E1F;
  --info:var(--sig-mandatory);
  --danger:var(--uae-red);
  --fire:var(--uae-red);
  --red:var(--uae-red);
  --orange:var(--sev-elevated);
  --yellow:var(--sig-warn);
  --blue:var(--sig-mandatory);
  --green:var(--sig-safe);
  --resource-water:var(--sig-mandatory);
  --status-pumpoff:var(--sig-mandatory);

  /* Canvas radii: 6 for controls, 8 for inputs and inner tiles, 9 for KPIs, 10 for cards. */
  --r-sm:6px;
  --r:8px;
  --r-lg:10px;

  --shadow-sm:0 1px 2px rgba(12,22,19,.06);
  --shadow:0 1px 2px rgba(12,22,19,.05),0 6px 18px rgba(12,22,19,.07);
  --shadow-lift:0 12px 28px rgba(12,22,19,.18);

  /* ── TYPE ────────────────────────────────────────────────────────────────────────────────────
     IBM Plex Sans Arabic ships 400/500/700 here; the canvases use 600 in places, which maps to 700
     rather than being synthesised. `--msj-mono` stands in for IBM Plex Mono, which the canvases
     load from Google Fonts and this platform may not (no CDN). Mono marks MACHINE-WRITTEN values —
     counts, versions, timestamps, ids — and that role survives the substitution intact. */
  --msj-mono:ui-monospace,Menlo,Consolas,monospace;
  --w-reg:400; --w-med:500; --w-bold:700;
  --t-legend:11px;
  --t-xs:11.5px;
  --t-sm:12.5px;
  --t-base:13px;
  --t-lg:14px;
  --t-xl:19px;
  --t-2xl:26px;
  --t-3xl:34px;
  --t-data:26px;
}

/* ═══ PANEL LEGEND ══════════════════════════════════════════════════════════════════════════════
   The one structural device this system adds. A fire annunciator panel labels its zones in small
   engraved capitals above a hairline; that is what a section heading is here. It is used ONLY where
   the label names a real group of controls or readings — it encodes grouping, not decoration, so it
   never appears over a single item. */
.ds-legend{
  display:flex;align-items:center;gap:10px;
  font-size:var(--t-legend);font-weight:var(--w-bold);
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink2);margin:0 0 12px;
}
.ds-legend::after{content:"";flex:1;height:1px;background:var(--line)}
/* Arabic does not have capitals and letter-spacing breaks its joined script — the tracking and the
   uppercasing are switched off wherever the text is actually Arabic. */
[dir=rtl] .ds-legend{letter-spacing:0;text-transform:none;font-size:var(--t-sm)}

/* ═══ THE FLAG SPINE ════════════════════════════════════════════════════════════════════════════
   `.uae-bar` was a 12px stripe of four stacked colours hugging a card edge — an ornament that
   happened to use national colours. The UAE flag is not four stacked bands: it is a red vertical
   hoist against three horizontal bands, green over white over black. Drawn correctly it becomes a
   structural edge that says whose system this is, and it costs the same 12px.

   This is the one place the sovereign palette appears at full saturation. Everything else on the
   surface is quiet so that this, and a live fire signal, are the only things that shout. */
.uae-bar{
  position:absolute;inset-block:0;inset-inline-start:0;width:14px;height:auto;margin:0;
  border:0;border-radius:0;overflow:hidden;
  background:
    linear-gradient(to bottom,
      var(--uae-green) 0 33.333%,
      var(--uae-white) 33.333% 66.666%,
      var(--uae-black) 66.666% 100%);
}
.uae-bar::before{
  content:"";position:absolute;inset-block:0;inset-inline-start:0;width:5px;
  background:var(--uae-red);
}
/* The flag's white band is the same white as the plate beside it, so on a light card the spine
   reads as a red-green-black bar with a gap in it. A hairline on the inner edge gives the white
   band an edge to end at — without it the national mark looks broken rather than white. */
.uae-bar::after{
  content:"";position:absolute;inset-block:0;inset-inline-end:0;width:1px;
  background:var(--line-strong);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   SIGN-IN DESK — "Mustajeeb Sign In v3"
   ═══════════════════════════════════════════════════════════════════════════════════════════════
   Every value below is the canvas file's own, read through the design MCP rather than sampled off a
   screenshot. Where a value is NOT the canvas's, it says so and why.

   The canvas expresses hover and focus as `style-hover` / `style-focus` attributes that its React
   runtime applies; here they are real pseudo-classes, which is the same design with none of the
   runtime. `sc-for` loops became the markup `renderPersonas()` already produces.

   MONO: the canvas asks for IBM Plex Mono from Google Fonts. No CDN here, and it is not vendored,
   so `--msj-mono` is the system stack `styles.css` already uses. The role of the face is what
   matters and survives the substitution: mono marks MACHINE-WRITTEN values — usernames, counts,
   badges, versions, plates. Arabic names stay in Plex Sans. Vendoring Plex Mono would close the
   remaining gap and change nothing structural.

   WEIGHT: the canvas uses 600 in nine places. IBM Plex Sans Arabic ships 400/500/700 here, so 600
   maps to 700. Left at 600 the browser synthesises it, which smears Arabic letterforms far more
   than it does Latin. */

:root{
  --msj-mono:ui-monospace,Menlo,Consolas,monospace;

  /* Canvas palette, verbatim */
  --msj-red:#B4122B;          /* primary — button, SIGN IN kicker, Civil Defence group   */
  --msj-red-hover:#980F23;
  --msj-red-active:#7E0C1D;
  --msj-green:#0E7A46;        /* status, building-people group, permission dots          */
  --msj-black:#0C1613;        /* active tab, user badge, focus ring, neighbours group    */
  --msj-ink:#131C18;
  --msj-sand:#E9E6DF;         /* the flag's third band                                   */

  --msj-page:#FFFFFF;
  --msj-shelf:#F7F5F0;        /* roster ground                                           */
  --msj-inset:#FBFAF7;        /* inputs, ready card                                      */
  --msj-rule:#EAE7E0;
  --msj-border:#E4E0D7;
  --msj-input-border:#DCD8CF;
  --msj-tabwell:#EDEAE3;
  --msj-badge:#F1EEE7;
  --msj-reveal:#EFECE5;
  --msj-reveal-hover:#E5E1D8;

  /* Group identity. The canvas gives each constituency a colour and a tint, and uses BOTH for the
     tab, the selected chip and the detail chip — so a selected account is legible as belonging to
     a group without reading its label. */
  --msj-cd:#B4122B;    --msj-cd-tint:#FDF3F4;
  --msj-res:#0E7A46;   --msj-res-tint:#EFF6F2;
  --msj-nb:#0C1613;    --msj-nb-tint:#F2F3F2;
}

/* ── Shell ───────────────────────────────────────────────────────────────────────────────────── */
.login{
  position:fixed;inset:0;z-index:50;display:block;padding:0;overflow:auto;
  background:var(--msj-page);color:var(--msj-ink);
}
.msj{
  min-height:100vh;display:flex;flex-direction:column;
  background:var(--msj-page);color:var(--msj-ink);
}

/* THE FLAG. 4px, four equal bands. The third band is SAND, not white — the canvas's own choice and
   the right one: a white band on a white page is a gap, so the national mark would read as broken. */
.msj-flag{height:4px;display:flex;flex:0 0 auto}
.msj-flag i{flex:1}
.msj-flag i:nth-child(1){background:var(--msj-red)}
.msj-flag i:nth-child(2){background:var(--msj-green)}
.msj-flag i:nth-child(3){background:var(--msj-sand)}
.msj-flag i:nth-child(4){background:var(--msj-black)}

.msj-head{
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding:18px 44px;border-bottom:1px solid var(--msj-rule);flex:0 0 auto;
}
.msj-brand{display:flex;align-items:center;gap:14px;min-width:0}
/* The canvas draws a hatched 44px placeholder where the seal goes. The real seal is a vertical
   lockup on white, so it is cropped to the shield (x330-918 / y36-805 of the 1254px artwork) and
   set on white — the same mounting the header bar uses. */
/* THE SEAL. `mustajeeb-logo.png` is a 1254px vertical lockup — shield, wordmark, three tagline
   rows — printed on white. Asking the browser to fit all five into 44px is what made it look
   pixellated: a 28:1 downscale of fine artwork (circuit traces, three firefighters, a skyline, the
   falcon) resolves to mush, and the white plate it is printed on shows as a box.

   `mustajeeb-seal.png` is generated from it once, at authoring time: cropped to the shield alone
   (x326-922 / y32-818, measured off the alpha rather than guessed), the surrounding white removed
   by flood-filling from the CORNERS — not by a white->alpha threshold, which would have punched
   holes through the flag's white band and the skyline inside the shield — then resampled with
   LANCZOS to 4x the slot and lightly unsharpened. 1.1 MB becomes 42 KB, and because the ground is
   transparent the mark needs no plate: it sits on the page here and on the dark command bar
   unchanged. The wordmark is not lost — it is set in live type beside this, where it can carry
   both scripts and switch language. */
.msj-seal{display:block;flex:0 0 auto;line-height:0}
.msj-seal img{height:44px;width:auto;max-width:none;display:block}
.msj-brandtext{display:flex;flex-direction:column;gap:2px;min-width:0}
.msj-title{font-size:16px;font-weight:700;line-height:1.3}
.msj-plate{font-family:var(--msj-mono);font-size:10px;color:#8B948E;letter-spacing:.12em}

.msj-headright{display:flex;align-items:center;gap:18px}
.msj-sys{display:flex;align-items:center;gap:8px;font-size:12px;color:#5F6A64;white-space:nowrap}
.msj-dot{width:7px;height:7px;border-radius:50%;background:var(--msj-green);flex:0 0 auto}
.msj-head .lang-pick{display:flex;gap:4px;margin:0}
.msj-head .lang-pick button{
  border:1px solid var(--msj-border);border-radius:6px;padding:6px 11px;
  font-family:var(--msj-mono);font-size:11px;letter-spacing:.04em;cursor:pointer;
  background:#fff;color:#7B857F;
}
.msj-head .lang-pick button:hover{background:var(--msj-inset);color:var(--msj-ink)}
.msj-head .lang-pick button.active{background:var(--msj-black);border-color:var(--msj-black);color:#fff}

/* ── Two panes ───────────────────────────────────────────────────────────────────────────────── */
.msj-body{flex:1;display:grid;grid-template-columns:400px minmax(0,1fr);min-height:0}

.msj-signin{
  padding:44px 44px 32px;border-inline-end:1px solid var(--msj-rule);
  display:flex;flex-direction:column;gap:16px;min-width:0;
}
.msj-kicker{font-family:var(--msj-mono);font-size:10px;color:var(--msj-red);letter-spacing:.16em}
.msj-h{font-size:26px;font-weight:700;line-height:1.25;margin:0}
.msj-sub{font-size:13px;color:#6C766F;line-height:1.6;margin:0 0 10px}

.msj-field{display:flex;flex-direction:column;gap:7px}
.msj-lbl{font-size:12px;font-weight:700;color:#4E5854}
.msj-signin input{
  width:100%;height:48px;padding:0 14px;
  border:1px solid var(--msj-input-border);border-radius:8px;background:var(--msj-inset);
  font-family:var(--msj-mono);font-size:15px;color:var(--msj-ink);outline:none;
  transition:border-color .12s ease,background .12s ease,box-shadow .12s ease;
}
.msj-signin input:focus{
  border-color:var(--msj-black);background:#fff;box-shadow:0 0 0 3px rgba(12,22,19,.08);
}
.msj-pw{position:relative;display:block}
.msj-pw input{letter-spacing:.14em}
.msj-reveal{
  position:absolute;inset-block:0;inset-inline-end:6px;margin:auto 0;height:32px;padding:0 10px;
  border:0;border-radius:6px;background:var(--msj-reveal);color:#5A645E;
  font-family:inherit;font-size:11px;font-weight:700;cursor:pointer;
}
.msj-reveal:hover{background:var(--msj-reveal-hover)}
/* Both captions live in the button; the stylesheet picks one. Keeps the label bound to `data-i18n`
   so a language switch relabels it, and keeps every user-facing string out of login-desk.js. */
.msj-reveal .msj-hide{display:none}
.msj-reveal[aria-pressed=true] .msj-show{display:none}
.msj-reveal[aria-pressed=true] .msj-hide{display:inline}

.msj-go{
  height:52px;border:0;border-radius:8px;background:var(--msj-red);color:#fff;
  font-family:inherit;font-size:16px;font-weight:700;cursor:pointer;
  transition:background 140ms ease;margin-top:2px;
}
.msj-go:hover{background:var(--msj-red-hover)}
.msj-go:active{background:var(--msj-red-active)}
.login-err{color:var(--msj-red);font-size:12.5px;font-weight:500;min-height:0}
.login-err:empty{display:none}

.msj-ready{
  display:flex;flex-direction:column;gap:8px;padding:14px 16px;
  border:1px solid var(--msj-border);border-radius:10px;background:var(--msj-inset);
}
.msj-ready[hidden]{display:none}
.msj-ready-name{font-size:12.5px;font-weight:700;color:#2C3630}
.msj-ready-hint{font-family:var(--msj-mono);font-size:11px;color:var(--msj-green)}

/* Pushed to the foot of the pane, so the form stays at the top where it is used and the mark sits
   under it rather than between the operator and the button. `min-height:0` on the flex child lets
   it shrink before it starts pushing the trust chips off a short viewport. */
.msj-lockup{margin-top:auto;padding-top:18px;display:flex;justify-content:center;min-height:0}
/* Capped in BOTH axes. Width alone let a tall mark push the trust chips past the fold on a laptop,
   which turned a screen that should never scroll into one that did; `max-height` in vh makes the
   lockup yield to the viewport instead of the other way round. It is the last thing on the pane and
   the least load-bearing, so it is the right thing to shrink. */
.msj-lockup img{
  width:100%;max-width:170px;max-height:23vh;height:auto;
  object-fit:contain;display:block;opacity:.96;
}
/* Below this there is not enough room for the mark AND the form, and the form wins. */
@media (max-height:620px){ .msj-lockup{display:none} }

.login-trust{display:flex;flex-wrap:wrap;gap:8px;padding-top:20px}
.ltrust{
  padding:6px 11px;border:1px solid var(--msj-border);border-radius:999px;
  font-size:11px;color:#7B857F;background:transparent;
}

/* ── Roster ──────────────────────────────────────────────────────────────────────────────────── */
.msj-roster{
  background:var(--msj-shelf);padding:32px 44px 36px;
  display:flex;flex-direction:column;gap:24px;min-width:0;
}
.msj-rosterhead{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;flex-wrap:wrap}
.msj-rostertitle{display:flex;flex-direction:column;gap:6px;min-width:0}
.msj-rt{font-size:18px;font-weight:700}
.msj-rs{font-size:13px;color:#6E7A73}

.msj-tabs{display:flex;gap:6px;background:var(--msj-tabwell);border-radius:10px;padding:4px}
.msj-tab{
  border:0;border-radius:7px;padding:9px 14px;
  font-family:inherit;font-size:13px;font-weight:700;cursor:pointer;
  display:flex;align-items:center;background:transparent;color:#6E7A73;
}
.msj-tab .msj-count{font-family:var(--msj-mono);font-size:11px;opacity:.6;margin-inline-start:8px}
.msj-tab[aria-selected=true]{background:var(--msj-black);color:#F4F5F3}

/* renderPersonas() emits three .persona-group blocks; the tab bar shows one at a time. Its own
   heading is redundant once a tab names it, so the heading is hidden rather than removed — app.js
   still writes it, and it stays available to a screen reader through the group's label. */
.persona-group[hidden]{display:none}
.persona-grp-h{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.login-personas{display:block}
.persona-grp-row{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:12px;align-content:start;
}

.persona-chip{
  display:flex;align-items:center;gap:12px;padding:14px;
  border:1.5px solid var(--msj-border);border-radius:10px;background:#fff;
  cursor:pointer;text-align:start;font-family:inherit;color:var(--msj-ink);
  transition:border-color 120ms ease,background 120ms ease;
}
.persona-chip:hover{border-color:#CFC9BC;background:#fff;transform:none;box-shadow:none}
/* The badge. app.js renders a Lucide icon here; login-desk.js swaps in the canvas's initials and
   keeps the icon as the fallback for any account the map does not name. */
.persona-chip>.li,.persona-chip>.msj-badge{
  flex:none;width:38px;height:38px;border-radius:8px;
  display:grid;place-items:center;padding:0;
  background:var(--msj-badge);color:#5E6A63;
  font-family:var(--msj-mono);font-size:11px;font-weight:500;
}
.persona-chip>.li svg{width:17px;height:17px}
.persona-chip>span{
  font-size:13.5px;font-weight:700;line-height:1.35;min-width:0;
  unicode-bidi:plaintext;overflow-wrap:break-word;
}
.persona-chip>small{font-family:var(--msj-mono);font-size:11.5px;color:#7C8781;unicode-bidi:plaintext}
/* app.js's chip is icon + name + username as three siblings; the canvas stacks name over username
   in a column beside the badge. Grid puts them there without app.js emitting a wrapper. */
.persona-chip{display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-areas:"b n" "b u";column-gap:12px;row-gap:4px;align-items:center}
.persona-chip>.li,.persona-chip>.msj-badge{grid-area:b}
.persona-chip>span{grid-area:n;align-self:end}
.persona-chip>small{grid-area:u;align-self:start}

/* Selection takes the ACTIVE GROUP's colour, so which constituency you are entering as is legible
   from the chip alone. Set per group rather than once, because the canvas does. */
#loginPersonas .persona-chip.sel{background:var(--msj-cd-tint);border-color:var(--msj-cd);box-shadow:none}
#loginPersonas .persona-chip.sel>.li,#loginPersonas .persona-chip.sel>.msj-badge{background:var(--msj-cd);color:#fff}
#loginPersonas .persona-group[data-grp=bp] .persona-chip.sel{background:var(--msj-res-tint);border-color:var(--msj-res)}
#loginPersonas .persona-group[data-grp=bp] .persona-chip.sel>.li,
#loginPersonas .persona-group[data-grp=bp] .persona-chip.sel>.msj-badge{background:var(--msj-res)}
#loginPersonas .persona-group[data-grp=nb] .persona-chip.sel{background:var(--msj-nb-tint);border-color:var(--msj-nb)}
#loginPersonas .persona-group[data-grp=nb] .persona-chip.sel>.li,
#loginPersonas .persona-group[data-grp=nb] .persona-chip.sel>.msj-badge{background:var(--msj-nb)}

/* ── The detail card ─────────────────────────────────────────────────────────────────────────────
   The canvas's footer strip. app.js fills #personaDesc with name / user / role / body / caps, so
   those parts are restyled in place rather than the panel being rebuilt. */
.persona-desc{
  margin-top:auto;flex:0 0 auto;
  border:1px solid var(--msj-border);border-radius:12px;background:#fff;
  padding:20px 24px;display:block;min-height:0;position:static;
}
.persona-desc:has(.pd-hint){
  color:#6E7A73;font-size:13px;
}
.persona-desc .pd-hint{font-size:13px;color:#6E7A73;line-height:1.6}
.persona-desc .pd-hint b{color:#2C3630;font-weight:700}
.persona-desc .pd-name{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  font-size:16px;font-weight:700;color:var(--msj-ink);margin:0;
}
.persona-desc .pd-name .li{width:17px;height:17px;color:#7C8781}
.persona-desc .pd-user{
  display:inline-block;padding:4px 10px;border-radius:6px;
  background:var(--msj-black);color:#F0F2F0;
  font-family:var(--msj-mono);font-size:11px;font-weight:400;margin:8px 0 0;
}
.persona-desc .pd-role{
  display:inline-block;padding:4px 10px;border-radius:6px;
  background:var(--msj-cd-tint);color:var(--msj-cd);
  font-size:11px;font-weight:700;margin:8px 0 0;border:0;
}
.persona-desc .pd-role .sep{opacity:.5;font-weight:400;margin:0 4px}
.persona-desc .pd-body{font-size:13px;color:#5D6862;line-height:1.6;margin-top:10px}
.persona-desc .pd-body.en{color:#7C8781;font-size:12px;direction:ltr;text-align:left;margin-top:3px}
.persona-desc .pd-caps{
  margin:12px 0 0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:8px 18px;
}
.persona-desc .pd-caps li{display:flex;align-items:flex-start;gap:7px;font-size:12px;color:#46524C;line-height:1.5}
/* The canvas marks each permission with a 4px green dot. app.js emits a check icon; it is scaled to
   the dot's weight so the row reads as a list of facts rather than a list of confirmations. */
.persona-desc .pd-caps li .li{width:11px;height:11px;color:var(--msj-green);flex:0 0 auto;margin-top:3px}
.persona-desc .pd-caps li .en{display:block;color:#8B958F;font-size:11px;direction:ltr;text-align:left;font-weight:400}
.persona-desc .pd-close{
  position:absolute;inset-inline-end:14px;inset-block-start:14px;
  border:0;background:transparent;color:#8B958F;cursor:pointer;padding:4px;border-radius:6px;
}
.persona-desc .pd-close:hover{background:var(--msj-inset);color:var(--msj-ink)}
.persona-desc:has(.pd-name){position:relative}

/* ── Narrow ──────────────────────────────────────────────────────────────────────────────────────
   The canvas is authored at 1440x900 and says nothing about small screens. Below 980px the two
   panes stack: a 400px credential column beside a roster is a desk, and a phone is not one. */
@media (max-width:980px){
  .msj-body{grid-template-columns:1fr}
  .msj-signin{border-inline-end:0;border-bottom:1px solid var(--msj-rule);padding:28px 22px 22px}
  .msj-roster{padding:24px 22px 30px}
  .msj-head{padding:14px 22px;gap:14px;flex-wrap:wrap}
  .msj-rosterhead{align-items:flex-start}
  .msj-tabs{width:100%;overflow-x:auto}
  .login-trust{margin-top:18px}
  .persona-grp-row{grid-template-columns:1fr}
}

/* ═══ THE FIRE GATE ═════════════════════════════════════════════════════════════════════════════
   The screen asks «هل هناك حريق؟» before it asks who you are. Nothing else in this product is as
   characteristic as that, so it is the one moment given full signal weight: the affirmative is ISO
   fire red at full strength, the negative is quiet. The two are deliberately NOT symmetrical —
   offering "yes, there is a fire" and "no" as a matched pair of buttons would be a design that has
   forgotten what it is asking. */
.login-card.fire-gate{width:min(440px,calc(100vw - 32px));text-align:center}
.login-card.fire-gate .login-identity{border-inline-end:0;padding:32px 30px 28px}
.fg-q{font-size:var(--t-2xl);font-weight:var(--w-bold);color:var(--ink);margin:10px 0 4px}
.fg-btns{display:grid;gap:9px;margin-top:22px}
.fg-yes{
  padding:16px;font-size:var(--t-lg);font-weight:var(--w-bold);font-family:inherit;
  background:var(--sig-fire);color:#fff;border:1px solid var(--sig-fire);
  border-radius:var(--r-sm);cursor:pointer;
}
.fg-yes:hover{background:#B0121F;border-color:#B0121F}
.fg-no{
  padding:11px;font-size:var(--t-base);font-weight:var(--w-med);font-family:inherit;
  background:transparent;color:var(--ink2);
  border:1px solid var(--line-strong);border-radius:var(--r-sm);cursor:pointer;
}
.fg-no:hover{background:var(--bg2);color:var(--ink)}

/* ═══ QUALITY FLOOR ═════════════════════════════════════════════════════════════════════════════ */

/* Focus must be visible on both the dark bar and the light plate, so it is drawn in mandatory blue
   with a white inner ring rather than relying on a single colour to carry against either ground. */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--sig-mandatory);
  outline-offset:2px;
  box-shadow:0 0 0 4px color-mix(in srgb,var(--sig-mandatory) 22%,transparent);
}
.topbar :where(a,button):focus-visible{
  outline-color:#FFFFFF;
  box-shadow:0 0 0 4px rgba(255,255,255,.22);
}

/* Every measured value is tabular. A count that changes width as it ticks reads as motion in the
   corner of an operator's eye, and on this platform motion is supposed to mean something. */
.kpi .v,.kpi-val,.badge-count,.stat-value,[data-metric]{font-variant-numeric:tabular-nums}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   PALETTE B — "SAND" · the docs/YAQIDH_VISUAL_BRIEF.md reading
   ═══════════════════════════════════════════════════════════════════════════════════════════════
   A/B VARIANT, NOT A SECOND DESIGN SYSTEM. Same duty-desk layout, same type scale, same structure —
   only the colour decisions change, so the comparison isolates the one thing actually in dispute.

   Switch with `?palette=sand` (or `?palette=red` to go back). Toggle lives in index.html.

   WHAT THIS VARIANT ASSERTS, in the brief's own words:
     · "must NOT introduce red or orange as an aesthetic accent — doing so spends a colour the
        interface needs for meaning"
     · "--uae-red #FF3B30 — flag spine only, never decorative"
     · "warm sand and off-white, with deep green as the only saturated note"
     · "no gradients, no gloss"
     · "Restraint reads as reliability. Drama on the login screen undermines the thing being sold."

   Palette A (the default, red) argues the opposite: that institutional identity and operational
   signal can share a hue when they are separated by DEPTH — deep oxide #AC100C for who we are,
   bright ISO #D7182A for what is happening — and that they never meet, because a sign-in door
   carries no incident state.

   The disagreement is genuinely about one question: is depth alone enough separation for a red on a
   fire platform? This file exists so that question gets answered by looking rather than arguing.

   NOTE — these are the brief's literal token values, including `--bg:#F5F3EF`. That warm cream is
   the ground I argued against on other grounds (it desaturates the reds it has to carry, and every
   map here is a dark tile). Reproducing it faithfully is the point: a rigged comparison is useless.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

:root[data-palette="sand"]{
  /* Ground — the brief's warm sand, verbatim */
  --bg:#F5F3EF;
  --bg2:#EDE8E0;
  --card:#FFFFFF;
  --card2:#F1ECE4;
  --ink:#1C1917;
  --ink2:#44403C;
  --mut:#756E6A;
  --line:#E7E0D6;
  --line-strong:#D8CEC0;

  /* Identity — green is the only saturated note. Red survives ONLY in the flag spine. */
  --uae-green:#009A49;
  --brand:#0E7C5A;

  /* Signal keeps its ISO values: this variant disputes DECORATIVE red, not the severity ramp.
     Both palettes agree that a confirmed fire is #D7182A. */
}

/* ── The crest field ─────────────────────────────────────────────────────────────────────────────
   Flat, not graded — the brief forbids gradients, and on a field this size the ban is defensible:
   a gradient reads as depth, and depth on a login is the "drama" the brief is trying to avoid. */
:root[data-palette="sand"] .desk-crest{
  background:#0E7C5A;
}
/* White on #0E7C5A measures 5.18:1 — AA for normal text. The red variant could afford 55% white for
   its secondary lines; on this lighter green the same opacity drops under 3:1, so every secondary
   level is raised rather than carried over. Contrast is not a per-palette preference. */
:root[data-palette="sand"] .crest-en{color:rgba(255,255,255,.74)}
:root[data-palette="sand"] .crest-org{color:rgba(255,255,255,.88)}
:root[data-palette="sand"] .crest-motto [lang=ar]{color:rgba(255,255,255,.96)}
:root[data-palette="sand"] .crest-motto [lang=en]{color:rgba(255,255,255,.78)}
:root[data-palette="sand"] .crest-motto{border-top-color:rgba(255,255,255,.26)}
:root[data-palette="sand"] .desk-crest .ltrust{
  border-color:rgba(255,255,255,.34);color:rgba(255,255,255,.90);
}
:root[data-palette="sand"] .desk-crest .ltrust .li{color:rgba(255,255,255,.72)}

/* The flag spine is where red is allowed to live, and the only place. */
:root[data-palette="sand"] .desk-crest .uae-bar::before{background:#C8102E}

/* ── The act ─────────────────────────────────────────────────────────────────────────────────────
   Sign-in takes the identity green here. Under Palette A this button is institutional red; under
   the brief that red would be the single most prominent decorative use of a severity colour on the
   whole surface, which is exactly what it forbids. */
:root[data-palette="sand"] .desk-go{
  background:var(--brand);border-color:var(--brand);
}
:root[data-palette="sand"] .desk-go:hover{background:#0A6249;border-color:#0A6249}

/* Constituency markers. Palette A gives Civil Defence the oxide red; here it takes the identity
   green, so no red appears outside the spine. */
:root[data-palette="sand"] .persona-group:nth-child(1) .persona-grp-h::before{background:var(--brand)}

/* Shadows go warm to sit on a warm ground — a cool shadow on sand reads as grey dirt, which is the
   mirror image of the note in the main sheet about warm shadows on a cool ground. */
:root[data-palette="sand"]{
  --shadow-sm:0 1px 2px rgba(28,25,23,.05);
  --shadow:0 1px 2px rgba(28,25,23,.04),0 6px 18px rgba(28,25,23,.07);
  --shadow-lift:0 2px 6px rgba(28,25,23,.06),0 16px 36px rgba(28,25,23,.12);
}
:root[data-palette="sand"] .crest-plaque{box-shadow:0 10px 30px rgba(0,0,0,.22)}

/* The command bar stays dark in both variants. It was never part of this disagreement — the brief
   is about the login field, and a dark instrument header is what stops the working surface from
   competing with a live signal. */

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   THE NATIONAL COMMAND ROOM
   ═══════════════════════════════════════════════════════════════════════════════════════════════
   Implementation of "National Command Room.dc.html" (design project 2ec15f26, read via the design
   MCP, 2026-08-22). The brief was explicit: take the COLOURING and the STRUCTURE, not the literal
   design, and delete nothing that is already on the board.

   So this file adds no markup and removes no panel. It is a restyle of classes app.js and
   index.html already emit, and every one of them was already the right shape — the canvas turns out
   to have been drawn FROM this dashboard, so `.ov-tier` was already the tier rule, `.card`/`.card-h`
   were already the card, `#kpi-row` was already the six-across strip and `.grid.two` was already
   the map-beside-list split. What changes is the surface: warm sand ground, white cards, a single
   3px accent rail per tier and per KPI, mono for every machine-written number, and one dark band at
   the top instead of a page-wide white one.

   The canvas mock shows invented figures (57 / 0 / 4 / 1 / 2 / 4 and a chart pair). None of them
   are copied. Every number on this board still comes from the API it came from before. */

/* Warm sand under everything, and the scrollbar tuned to it — the default white gutter cuts a cold
   stripe down a warm page. */
body{background:var(--bg);color:var(--ink)}
::selection{background:var(--uae-red);color:#fff}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:#D6D2C8;border-radius:6px}
::-webkit-scrollbar-track{background:transparent}

/* ═══ THE COMMAND BAR ═══════════════════════════════════════════════════════════════════════════
   Two bands, which is the canvas's real structural move: a DARK identity band carrying who you are
   and how healthy the platform is, and a WHITE navigation band beneath it carrying where you can
   go. Previously both lived on one surface and competed. No markup changed — `.topbar` is already a
   grid whose `nav` area spans the full width on its own row, so the nav band is a background on a
   row that already existed. */
.topbar{
  background:var(--hdr);border-bottom:0;color:var(--hdr-ink);
  position:relative;row-gap:0;
}
.topbar>.uae-bar{display:none}          /* the flag band belongs to the sign-in door, not the board */

.topbar .brand .t{color:#fff;font-size:var(--t-lg);font-weight:var(--w-bold);letter-spacing:0}
.topbar .brand .sub{color:var(--hdr-mut);font-size:10.5px;font-weight:var(--w-reg)}
.topbar .brand-seal{background:none;border-radius:0;padding:0;width:auto;height:auto;overflow:visible;display:block;line-height:0}
.topbar .brand-seal .logo-img{height:34px;width:auto;max-width:none;margin:0;display:block}

/* Scope pill — the canvas's raised inset chip, not a filled brand colour. */
.topbar .scopebar{
  display:flex;align-items:center;gap:8px;
  padding:5px 10px;border-radius:7px;background:var(--hdr-raise);border:1px solid var(--hdr-line);
}
.topbar .crumb{color:var(--hdr-chip);font-weight:var(--w-med);font-size:12px;background:transparent;border:0;padding:2px 4px}
.topbar .crumb.active,.topbar .crumb[aria-selected=true]{
  color:#fff;font-weight:var(--w-bold);background:transparent;border:0;
}
.topbar .crumb .li{width:14px;height:14px}
.topbar .crumb-sep{color:#3A4B44}

.topbar .status{gap:8px}
.topbar .chip{
  background:var(--hdr-raise);border:1px solid var(--hdr-line);color:var(--hdr-chip);
  border-radius:var(--r-sm);font-family:var(--msj-mono);font-size:11px;font-weight:var(--w-reg);
  padding:5px 9px;
}
.topbar .chip:hover{background:var(--hdr-tint);color:#fff}
.topbar .chip.ver{background:transparent;border-color:transparent;color:#6C7C75;font-size:10.5px;padding:5px 4px}
/* Platform health. `#st-llm.degraded` set `color:var(--ink)` — legible on the old white bar and
   black-on-black the moment the bar went dark. The canvas gives the degraded state its own amber
   ground rather than only a dot, so it reads as a condition and not as another status pill. */
.topbar #st-llm,.topbar #st-fresh,.topbar #whoami{color:var(--hdr-chip)}
.topbar #st-llm.ok{background:var(--hdr-raise);border-color:var(--hdr-line);color:var(--hdr-chip)}
.topbar #st-llm.ok::before{background:#21A366;box-shadow:none}
.topbar #st-llm.degraded{background:#2A1F0B;border-color:#3D2E10;color:#E0A82E}
.topbar #st-llm.degraded::before{background:#E0A82E;box-shadow:none}
.topbar #st-llm.down{background:#2A0F13;border-color:#40161C;color:#E8697C}
.topbar #st-llm.down::before{background:#E8697C;box-shadow:none}

.topbar .iconbtn,.topbar .lang{
  background:var(--hdr-raise);border:1px solid var(--hdr-line);color:var(--hdr-chip);
  border-radius:var(--r-sm);box-shadow:none;
}
.topbar .iconbtn:hover,.topbar .lang:hover{background:var(--hdr-tint);color:#fff;border-color:var(--hdr-edge);box-shadow:none}
/* Sign-out is the canvas's one filled red control up here. Nothing else on the bar is allowed red,
   so a live alarm below still owns the colour. */
.topbar .logout{
  background:var(--uae-red);border:1px solid var(--uae-red);color:#fff;
  border-radius:var(--r-sm);font-size:12px;font-weight:var(--w-bold);padding:7px 12px;box-shadow:none;
}
.topbar .logout:hover{background:var(--uae-red-hover);border-color:var(--uae-red-hover);filter:none}
.topbar .badge-count{background:var(--uae-red);color:#fff;border:0;font-family:var(--msj-mono);font-weight:var(--w-med)}

/* ── The white navigation band ───────────────────────────────────────────────────────────────── */
/* (superseded by the full-bleed band at the foot of this file) */

.topbar .tb-nav .chip,.topbar .tb-nav .chip.gear{
  background:transparent;border:0;color:#5F6A64;
  font-family:inherit;font-size:var(--t-sm);font-weight:var(--w-med);
  border-radius:7px;padding:7px 12px;
}
.topbar .tb-nav .chip:hover,.topbar .tb-nav .chip.gear:hover{background:var(--bg);color:var(--ink);box-shadow:none}
.topbar .tb-nav .chip.active,.topbar .tb-nav .chip[aria-current=page],.topbar .tb-nav .chip.gear.active{
  background:var(--uae-black);color:#F4F5F3;font-weight:var(--w-bold);border-color:transparent;
}
.topbar .tb-nav .tb-cluster{border-color:var(--line)}

/* ═══ DEMO BANNER ═══════════════════════════════════════════════════════════════════════════════
   Synthetic data is labelled, never presented as real — the canvas gives that rule its own amber
   band rather than a footnote, which is the correct weight for it. */
.demo-banner{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:7px 20px;background:#FDF6E3;border-bottom:1px solid #EFE3C4;
  color:#6B5518;font-size:var(--t-xs);border-radius:0;margin:0;
}
.demo-banner.hidden{display:none}
.demo-banner b,.demo-banner strong{
  padding:2px 7px;border-radius:4px;background:#E0A82E;color:#2A1F0B;
  font-family:var(--msj-mono);font-size:10px;font-weight:var(--w-med);
}
.demo-banner code,.demo-banner .mono{font-family:var(--msj-mono);font-size:11px;color:#8A6E1F;background:none}

/* ═══ PAGE TITLE ════════════════════════════════════════════════════════════════════════════════ */
.band-title{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  font-size:var(--t-xl);font-weight:var(--w-bold);color:var(--ink);margin:0 0 2px;
}
.band-title .li{width:17px;height:17px;color:var(--mut);align-self:center}
.band-title small,.band-title .sub{font-size:var(--t-sm);color:var(--mut);font-weight:var(--w-reg)}

/* ═══ TIER RULE ═════════════════════════════════════════════════════════════════════════════════
   The canvas's signature structural device, and the board already had the element for it. A 3px
   rail, the tier name, then a hairline running to the end of the row. The rail colour is what tells
   the three tiers apart at a glance: situation is red, response is green, analysis is black.

   The icon each tier carried is not deleted — it is the element now drawn as the rail, so the slot
   keeps its meaning and nothing is removed from the DOM. */
.ov-tier{
  display:flex;align-items:center;gap:10px;
  font-size:var(--t-sm);font-weight:var(--w-bold);color:var(--ink);
  /* The canvas sets a 14px gap between sections, which is right for its mock and too tight here:
     the real board's panels are taller and denser, so at 14px the tier rule read as belonging to
     the card above it rather than heading the one below. The rule needs clear air ABOVE it and
     little below — that asymmetry is what makes it group downward. */
  margin:30px 0 2px;padding:0;background:none;border:0;
}
/* ...except the first, which already sits under the page title. */
.ov-tier:first-of-type,.band-title + .ov-tier{margin-top:12px}
.ov-tier>span:first-child{
  flex:none;width:3px;height:15px;border-radius:2px;background:var(--tier,#5E6A63);
  padding:0;display:block;overflow:hidden;
}
.ov-tier>span:first-child .li{display:none}
.ov-tier::after{content:"";flex:1;height:1px;background:var(--line)}
.ov-tier.tier-situation{--tier:var(--uae-red)}
.ov-tier.tier-act{--tier:var(--uae-green)}
.ov-tier.tier-analyse{--tier:var(--uae-black)}

/* ═══ KPI STRIP ═════════════════════════════════════════════════════════════════════════════════
   Six across, each a white tile with a 3px accent rail and its value set in mono at 26px in that
   same accent. The accent is `--kc`, which app.js already computed per metric — it was only being
   spent on an icon chip.

   The icon is hidden rather than removed: its ELEMENT is what draws the rail now (it is the only
   node carrying the colour), so the markup is untouched and one line brings the glyph back. Hiding
   it is the canvas's structure — a KPI tile there is rail, number, label, and nothing else, which
   is why its numbers read from across a room and the old tile's did not. */
.kpi-row{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px}
.kpi{
  position:relative;display:flex;align-items:stretch;gap:0;
  border:1px solid var(--line);border-radius:9px;background:var(--card);
  overflow:hidden;padding:0;box-shadow:none;min-width:0;
}
.kpi:hover{border-color:var(--line-strong);box-shadow:var(--shadow-sm)}
.kpi-ic{
  flex:none;width:3px;min-width:3px;height:auto;align-self:stretch;
  background:var(--kc,#5E6A63);border-radius:0;padding:0;margin:0;border:0;
  display:block;overflow:hidden;
}
.kpi-ic .li,.kpi-ic svg,.kpi-share{display:none}
.kpi-tx{display:flex;flex-direction:column;gap:2px;padding:12px 14px;min-width:0}
.kpi-tx .v{
  font-family:var(--msj-mono);font-size:var(--t-2xl);font-weight:var(--w-med);
  line-height:1;color:var(--kc,var(--ink));font-variant-numeric:tabular-nums;
}
.kpi-tx .k{font-size:var(--t-xs);color:var(--mut);line-height:1.3;font-weight:var(--w-reg)}

@media (max-width:1240px){ .kpi-row{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (max-width:680px){ .kpi-row{grid-template-columns:repeat(2,minmax(0,1fr))} }

/* ═══ CARDS ═════════════════════════════════════════════════════════════════════════════════════ */
.card{
  border:1px solid var(--line);border-radius:var(--r-lg);background:var(--card);
  box-shadow:none;overflow:hidden;
}
.card.kpis{border:0;background:none;border-radius:0;overflow:visible}
.card.kpis>.card-h{display:none}   /* the tier rule above it already names this strip */
.card-h{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:11px 14px;border-bottom:1px solid var(--line-soft);background:transparent;
  font-size:var(--t-base);font-weight:var(--w-bold);color:var(--ink);
}
.card-h .li{width:15px;height:15px;color:var(--mut)}
.card-h small,.card-h .sub{font-family:var(--msj-mono);font-size:11px;color:var(--mut2);font-weight:var(--w-reg)}
.card-h .chip,.card-h .badge{
  padding:2px 8px;border-radius:5px;background:#EFF6F2;color:var(--uae-green);
  border:0;font-family:var(--msj-mono);font-size:11px;font-weight:var(--w-reg);
}
.card-h .iconbtn,.card-h button.mini{
  width:27px;height:27px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--card2);color:var(--mut);box-shadow:none;
}
.card-h .iconbtn:hover,.card-h button.mini:hover{background:#F1EEE7;color:var(--ink)}

.grid.two,.grid.two.situation{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:10px;align-items:stretch;
}
@media (max-width:1080px){ .grid.two,.grid.two.situation{grid-template-columns:1fr} }
.ov-col{display:flex;flex-direction:column;gap:10px;min-width:0}

/* ═══ EMPTY STATES ══════════════════════════════════════════════════════════════════════════════
   The canvas hatches an empty panel instead of leaving it blank white, and rings the tick in the
   safe-condition green. A quiet board is a RESULT — "no active fires" — not a failure to load, and
   the hatch is what makes those two read differently at a glance. */
.triage:empty,.devices:empty{min-height:120px}
.empty,.emptystate,.ov-empty{
  display:grid;place-items:center;padding:30px 20px;text-align:center;
  background:repeating-linear-gradient(135deg,#FDFCFA 0 10px,#FBFAF7 10px 20px);
  color:var(--ink);font-size:var(--t-lg);font-weight:var(--w-med);
}
.empty small,.emptystate small,.ov-empty small{
  display:block;margin-top:4px;font-size:12px;color:#7A847E;font-weight:var(--w-reg);
}
.empty .li,.emptystate .li,.ov-empty .li{
  width:40px;height:40px;padding:9px;border-radius:50%;
  border:1.5px solid #BFE3D0;background:#F3FAF6;color:var(--uae-green);margin-bottom:9px;
}

/* ═══ MAP ═══════════════════════════════════════════════════════════════════════════════════════
   The board's maps are dark tiles. On the old warm-cream page each one sat as a black rectangle
   with nothing mediating it; the canvas makes that deliberate by giving the panel the same dark
   ground and matching its controls to it, so the map reads as an instrument set into the card. */
.leaflet-map,#map,#cmap{background:#0F1A17}
.leaflet-container{background:#0F1A17}
.leaflet-control-zoom a,.leaflet-bar a{
  background:#16211D;color:#C8D2CD;border:0;border-bottom:1px solid var(--hdr-edge);
}
.leaflet-control-zoom a:hover,.leaflet-bar a:hover{background:#1E2C27;color:#fff}
.leaflet-bar{border:1px solid var(--hdr-edge);border-radius:var(--r-sm);overflow:hidden;box-shadow:none}
.leaflet-control-attribution{
  background:rgba(12,22,19,.82)!important;color:var(--hdr-mut)!important;
  font-family:var(--msj-mono);font-size:10px;
}
.leaflet-control-attribution a{color:#9AA9A2!important}

/* ═══ CONTROLS ══════════════════════════════════════════════════════════════════════════════════ */
input[type=text],input[type=search],input[type=number],input:not([type]),select,textarea{
  border:1px solid var(--line-strong);border-radius:var(--r);background:var(--card2);
  color:var(--ink);font-family:inherit;
}
input[type=text]:focus,input[type=search]:focus,input[type=number]:focus,
input:not([type]):focus,select:focus,textarea:focus{
  outline:none;border-color:var(--uae-black);background:var(--card);
  box-shadow:0 0 0 3px rgba(12,22,19,.07);
}
/* The canvas's primary action is GREEN — ask, generate, proceed. Red is spent only on sign-out and
   on severity, which is what keeps it meaning something on a board about fire. */
.btn-primary,button.primary,.ask-btn{
  background:var(--uae-green);border:0;color:#fff;border-radius:var(--r);
  font-family:inherit;font-size:var(--t-base);font-weight:var(--w-bold);
}
.btn-primary:hover,button.primary:hover,.ask-btn:hover{background:var(--uae-green-hover)}

/* Suggestion chips — pill, recessed, quiet until hovered. */
.chip.suggest,.qchip,.copilot-chip{
  padding:7px 11px;border:1px solid var(--line);border-radius:999px;
  background:var(--card2);color:var(--ink2);font-size:var(--t-xs);
}
.chip.suggest:hover,.qchip:hover,.copilot-chip:hover{background:#F1EEE7;border-color:#CFCABF}

/* Agent tiles. `--ac` already carries each agent's colour; the canvas leaves the tile neutral and
   brings the accent in on hover, so seven of them side by side read as a set rather than a
   fruit bowl. */
.agentbar{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:7px}
.agbtn,.agentbar button.mini{
  display:flex;align-items:center;gap:9px;padding:11px 12px;
  border:1px solid var(--line);border-radius:var(--r);background:var(--card2);
  color:var(--ink);font-family:inherit;font-size:var(--t-sm);font-weight:var(--w-med);
  text-align:start;box-shadow:none;
}
.agbtn:hover,.agentbar button.mini:hover{background:var(--card);border-color:var(--ac,var(--uae-red));box-shadow:none}
.agbtn .ag-ic{
  flex:none;width:26px;height:26px;border-radius:var(--r-sm);
  background:#EFECE5;color:#5E6A63;display:grid;place-items:center;padding:0;
}
.agbtn .ag-ic .li{width:14px;height:14px}
.agbtn:hover .ag-ic{background:color-mix(in srgb,var(--ac,var(--uae-red)) 12%,#fff);color:var(--ac,var(--uae-red))}

/* Tab wells — the analysis switcher and any sibling group. */
.tabs,.tabbar,.seg{display:flex;gap:4px;background:#F1EEE7;border-radius:var(--r);padding:3px;flex-wrap:wrap}
.tabs>button,.tabbar>button,.seg>button{
  border:0;border-radius:var(--r-sm);padding:7px 12px;background:transparent;color:var(--mut);
  font-family:inherit;font-size:12px;font-weight:var(--w-bold);cursor:pointer;white-space:nowrap;
}
.tabs>button.active,.tabbar>button.active,.seg>button.active,
.tabs>button[aria-selected=true],.tabbar>button[aria-selected=true]{background:var(--uae-black);color:#F4F5F3}

/* Nested tiles inside a card sit on the recessed tone, not on white-on-white. */
.dash-kpis .kpi,.subkpi{
  border:1px solid var(--line-soft);border-radius:var(--r);background:var(--card2);
}
.dash-kpis .kpi .v{color:#A8B2AC;font-size:20px}

footer,.app-footer{
  border-top:1px solid var(--line);background:var(--card);
  padding:11px 20px;font-size:var(--t-xs);color:#8B958F;
}
footer .mono,.app-footer .mono{font-family:var(--msj-mono);font-size:10.5px}

/* ── Analysis tab well ───────────────────────────────────────────────────────────────────────────
   These are `.dash-tabs > .dash-tab`, not the generic `.tabs` group, and they were still carrying
   the old blue outline-selected treatment. The canvas uses one device for "which one am I in"
   everywhere — a recessed well with the active item filled near-black — and it is already what the
   command-bar nav and the sign-in roster use, so this makes the third place agree with the other
   two rather than inventing a fourth. */
.dash-tabs{
  display:flex;gap:4px;flex-wrap:wrap;
  background:#F1EEE7;border-radius:var(--r);padding:3px;border:0;
}
.dash-tab{
  border:0;border-radius:var(--r-sm);padding:7px 12px;background:transparent;color:var(--mut);
  font-family:inherit;font-size:12px;font-weight:var(--w-bold);cursor:pointer;white-space:nowrap;
  box-shadow:none;
}
.dash-tab:hover{background:var(--card);color:var(--ink);border-color:transparent}
.dash-tab.active,.dash-tab[aria-selected=true]{
  background:var(--uae-black);color:#F4F5F3;border-color:transparent;box-shadow:none;
}
.dash-tab.active .li,.dash-tab[aria-selected=true] .li{color:#F4F5F3}

/* Agent glyphs go neutral with the chip that holds them. Seven agents each rendering their own
   accent turned a row of equal-weight choices into a colour chart; the accent is not lost, it comes
   back on hover along with the border, which is the moment it actually distinguishes something. */
.agbtn .ag-ic .li{color:#5E6A63}
.agbtn:hover .ag-ic .li{color:var(--ac,var(--uae-red))}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   NAV BAND · DROPDOWNS · LANGUAGE MENU · ANALYSIS   (second pass, 2026-08-22)
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── FULL-BLEED NAV BAND ─────────────────────────────────────────────────────────────────────────
   The white band was reaching only as far as the nav's own box. `.topbar` carries 119.5px of
   horizontal padding at this width, so ~102px of dark header showed past each end and the row read
   as half black, half white — the bug rather than the design.

   A negative margin cannot fix it honestly: that padding is fluid, so any fixed number is wrong at
   some other width. The band is painted by a pseudo-element pinned far past both edges instead, so
   it reaches the viewport no matter what the padding resolves to. It sits behind the links
   (`z-index:0` against their `position:relative`), never over them. */
/* THE TWO BANDS — fourth and final attempt, painted on the bar itself.

   `.topbar` carries `padding-inline: max(24px, calc((100% - 1720px)/2 + 24px))` so the header lines
   up with the page grid; styles.css explains why and it is right. A CHILD therefore cannot reach the
   viewport edge, and three attempts to make one do so all failed differently:

     1. A pseudo-element inset to `-100vw`. An absolutely positioned box still contributes to
        SCROLLABLE overflow, so the document grew to ~3 viewports and the page collapsed.
     2. Moving the gutter onto the grid areas. Percentage padding on a GRID ITEM resolves against its
        grid AREA, not the container, so `max()` fell through to 24px and the header silently lost
        its page-grid alignment.
     3. `box-shadow` offset by ±100vw. The arithmetic is simply wrong: the nav is NARROWER than the
        viewport (1672px inside 1920px), so a copy shifted a full viewport left spans [-1800,-128]
        and never re-enters the screen. It painted nothing, which is the black at both ends.

   The bar itself is already full width — x=0, the whole viewport. So the two bands are one hard-stop
   gradient on `.topbar`: dark down to the identity row's height, white from there. No child has to
   escape its padding, nothing overflows, and it is exact at every width because the stop is the same
   variable that sets the row height. */
.topbar{
  --tb-band:54px;
  /* The gradient stop and the identity row are driven by ONE variable, and the row is pinned to it
     explicitly. If the row were left to size itself, any future content that made it taller would
     push the nav down while the colour stop stayed at 54px — cutting a white stripe across the dark
     band with nothing in the CSS to explain why. Tied together, they cannot disagree. */
  grid-template-rows:var(--tb-band) auto;
  background:linear-gradient(to bottom,
    var(--hdr) 0 var(--tb-band),
    var(--card) var(--tb-band) 100%);
  border-bottom:1px solid var(--line);
}
/* Narrow screens give the identity row a second line to work with; the band follows the variable, so
   the gradient moves with it. */
@media (max-width:820px){ .topbar{--tb-band:78px} }
.topbar .tb-nav{
  background:transparent;box-shadow:none;
  margin-inline:0;padding:4px 0;border:0;
  min-height:42px;align-items:center;row-gap:2px;
  position:relative;z-index:1;
}

/* ── NAV ITEMS ───────────────────────────────────────────────────────────────────────────────── */
.topbar .tb-nav .chip,.topbar .tb-nav .chip.gear,.topbar .tb-nav .nav-group-toggle{
  background:transparent;border:0;color:#5F6A64;box-shadow:none;
  font-family:inherit;font-size:var(--t-sm);font-weight:var(--w-med);
  border-radius:7px;padding:7px 12px;
}
.topbar .tb-nav .chip .li{width:15px;height:15px}
.topbar .tb-nav .chip:hover,.topbar .tb-nav .chip.gear:hover,
.topbar .tb-nav .nav-group-toggle:hover{background:var(--bg);color:var(--ink);box-shadow:none}
.topbar .tb-nav .chip.active,.topbar .tb-nav .chip[aria-current=page],
.topbar .tb-nav .chip.gear.active,.topbar .tb-nav .nav-group.open .nav-group-toggle{
  background:var(--uae-black);color:#F4F5F3;font-weight:var(--w-bold);
}
.topbar .tb-nav .chip.active .li,.topbar .tb-nav .chip.gear.active .li{color:#F4F5F3}
/* The cluster hairline was drawn for a dark bar; on white it reads as a stray tick. */
.topbar .tb-nav .tb-cluster{border-color:var(--line)}

/* Caret. The canvas draws it as two borders on a rotated square rather than a glyph, and flips it
   to point up while the menu is open. The app ships a Lucide chevron in that slot, so the rotation
   is applied to the icon instead — same behaviour, and no icon is thrown away. */
.ng-chev{display:inline-flex;transition:transform 140ms ease;opacity:.55}
.ng-chev .li{width:13px;height:13px}
.nav-group.open .ng-chev{transform:rotate(180deg);opacity:.9}
.nav-group-toggle.ng-caret{padding-inline:7px}

/* ── DROPDOWN PANEL ──────────────────────────────────────────────────────────────────────────────
   White panel, 286px, 10px radius, a real drop shadow, and rows that highlight on the sand tone.
   Was a translucent tinted sheet inheriting the old header treatment.

   The canvas's rows carry a description and a count beside each label. `DEMO_ACCOUNTS`-style
   per-item copy does not exist for these thirty-odd nav entries in four languages, so the rows here
   are label-only; adding the descriptions would be a content job, not a styling one, and inventing
   them is not an option on a platform that labels what is real. */
.nav-group{position:relative;display:inline-flex}
.nav-group-menu{
  position:absolute;inset-inline-start:0;top:calc(100% + 6px);
  display:none;flex-direction:column;gap:2px;
  width:286px;max-width:calc(100vw - 32px);padding:6px;
  border:1px solid var(--line);border-radius:var(--r-lg);background:var(--card);
  box-shadow:0 14px 30px rgba(12,22,19,.16);
  z-index:35;
}
.nav-group.open .nav-group-menu{display:flex}
.topbar .tb-nav .nav-group-menu .chip.gear{
  justify-content:flex-start;width:100%;gap:10px;
  border-radius:7px;padding:9px 10px;
  font-size:var(--t-sm);font-weight:var(--w-med);color:var(--ink);background:transparent;
}
.topbar .tb-nav .nav-group-menu .chip.gear .li{width:15px;height:15px;color:var(--mut)}
.topbar .tb-nav .nav-group-menu .chip.gear:hover{background:var(--bg);color:var(--ink)}
.topbar .tb-nav .nav-group-menu .chip.gear:active{background:#E9E5DC}
/* The canvas marks one row in the panel with a tinted ground and a 3px inset rail. It puts that on
   the FIRST row; here it goes on the ACTIVE one, which is what the device actually means — "this is
   where you are" — and the app already tracks that state. */
.topbar .tb-nav .nav-group-menu .chip.gear.active{
  background:#FDF3F4;color:var(--ink);font-weight:var(--w-bold);
  box-shadow:inset 3px 0 0 var(--uae-red);
}
html[dir=rtl] .topbar .tb-nav .nav-group-menu .chip.gear.active{box-shadow:inset -3px 0 0 var(--uae-red)}
.topbar .tb-nav .nav-group-menu .chip.gear.active::before,
.topbar .tb-nav .nav-group-menu .chip.gear.active::after{display:none}
.topbar .tb-nav .nav-group-menu .chip.gear.active .li{color:var(--uae-red)}

/* Menus near the end of the bar would run off-screen if they opened from the same edge. */
.tb-nav>.nav-group:nth-last-child(-n+3) .nav-group-menu{inset-inline-start:auto;inset-inline-end:0}

/* ── LANGUAGE MENU ───────────────────────────────────────────────────────────────────────────────
   Lives in the dark session cluster, so its trigger takes the header's chip treatment while its
   panel is the same white sheet as every other dropdown. */
.lang-group .nav-group-toggle,.topbar .lang.nav-group-toggle{
  display:inline-flex;align-items:center;gap:6px;
  background:var(--hdr-raise);border:1px solid var(--hdr-line);color:var(--hdr-chip);
  border-radius:var(--r-sm);padding:6px 10px;
  font-family:var(--msj-mono);font-size:11px;font-weight:var(--w-med);letter-spacing:.04em;
  box-shadow:none;
}
.lang-group .nav-group-toggle:hover,.topbar .lang.nav-group-toggle:hover{
  background:var(--hdr-tint);color:#fff;border-color:var(--hdr-edge);box-shadow:none;
}
.lang-group.open .nav-group-toggle{background:#1E2C27;border-color:#3A4B44;color:#EDF1EF}
.lang-group .nav-group-menu{
  width:190px;inset-inline-start:auto;inset-inline-end:0;top:calc(100% + 8px);z-index:40;
}
.lang-group .nav-group-menu button{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:9px 10px;border:0;border-radius:7px;background:transparent;
  font-family:inherit;font-size:var(--t-sm);color:var(--ink);text-align:start;cursor:pointer;
}
.lang-group .nav-group-menu button:hover{background:var(--bg)}
.lang-group .lg-code{
  flex:none;min-width:30px;padding:2px 6px;border-radius:5px;
  background:#F1EEE7;color:var(--mut);
  font-family:var(--msj-mono);font-size:10.5px;text-align:center;
}
.lang-group .lg-name{min-width:0;font-weight:var(--w-med)}
/* app.js marks the live language with `.active` on the same `[data-lang]` buttons the sign-in desk
   uses, so the current language is legible in the menu without this file tracking it. */
.lang-group .nav-group-menu button.active{background:#FDF3F4;box-shadow:inset 3px 0 0 var(--uae-red)}
html[dir=rtl] .lang-group .nav-group-menu button.active{box-shadow:inset -3px 0 0 var(--uae-red)}
.lang-group .nav-group-menu button.active .lg-code{background:var(--uae-red);color:#fff}

/* ── ANALYSIS — "لوحة من سؤال" ───────────────────────────────────────────────────────────────────
   The section was a white slab holding a white query row, six white tiles and two bare plots with
   nothing separating any of them. The canvas gives it three levels — card, recessed controls,
   recessed chart tiles — so the eye can tell the question from the answer. */
#dashboard .card,.dash-wrap{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg)}
.dash-q,.dashq-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
#dashq{
  flex:1;min-width:0;height:42px;padding:0 13px;
  border:1px solid var(--line-strong);border-radius:var(--r);background:var(--card2);
  font-family:inherit;font-size:var(--t-base);color:var(--ink);
}
#dashq:focus{outline:none;border-color:var(--uae-black);background:var(--card);box-shadow:0 0 0 3px rgba(12,22,19,.07)}
#dashgo{
  height:42px;padding:0 18px;border:0;border-radius:var(--r);
  background:var(--uae-green);color:#fff;
  font-family:inherit;font-size:var(--t-base);font-weight:var(--w-bold);cursor:pointer;
}
#dashgo:hover{background:var(--uae-green-hover)}

/* Chart tiles. Transparent plots on a recessed tile, name in the tile header — the plot no longer
   draws its own title (see analytics._layout) so nothing is printed twice. */
/* Two across on a wide board rather than three narrow ones — a 340px minimum let a third column
   in at this width and every chart lost the room its category labels needed. */
.dash-plots{display:grid;grid-template-columns:repeat(auto-fit,minmax(520px,1fr));gap:12px}
@media (max-width:900px){ .dash-plots{grid-template-columns:1fr} }
.dash-plotcard{
  margin:0;padding:12px 14px;display:flex;flex-direction:column;gap:8px;min-width:0;
  border:1px solid var(--line-soft);border-radius:var(--r);background:var(--card2);
}
.dash-plotcap{
  font-size:var(--t-sm);font-weight:var(--w-bold);color:var(--ink);
  line-height:1.35;unicode-bidi:plaintext;
}
.dash-plot{min-width:0}
.dash-plot .main-svg{background:transparent!important}
.js-plotly-plot .modebar{background:transparent!important}
.js-plotly-plot .modebar-btn path{fill:var(--mut2)!important}
.js-plotly-plot .modebar-btn:hover path{fill:var(--ink)!important}

/* Example prompts under the box read as suggestions, not as results. */
.nl2-ex{
  padding:7px 11px;border:1px solid var(--line);border-radius:999px;
  background:var(--card2);color:var(--ink2);font-size:var(--t-xs);cursor:pointer;
}
.nl2-ex:hover{background:#F1EEE7;border-color:#CFCABF}

/* An aggregate that legitimately returns nothing. Styled as a RESULT, using the same hatched
   ground as the board's other empty states, so "the count is zero" never gets mistaken for
   "the chart failed to load". */
.plot-empty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;
  min-height:190px;padding:24px 16px;border-radius:var(--r-sm);
  background:repeating-linear-gradient(135deg,#FDFCFA 0 10px,#FBFAF7 10px 20px);
  color:#8B958F;font-size:var(--t-sm);text-align:center;
}
.plot-empty .li{width:26px;height:26px;color:#BDC6C1}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   HEADER CLUSTER + MENUS — "National Command Room.dc.html", third pass
   ═══════════════════════════════════════════════════════════════════════════════════════════════
   Values are the canvas's own. One deliberate departure, stated up front: the canvas sets the bar to
   `padding: 0 20px`, because its mock has no page container. This app's board is a `.band` capped at
   1720px, and styles.css gives the header the SAME expression so the brand lands exactly above the
   title it heads. Copying a flat 20px here would re-open the bug that comment describes — the header
   sitting ~100px inside the content it introduces. The grid gutter stays; everything else follows
   the canvas. */

/* The hairline between "who this is" and "what you are looking at".

   Drawn as a pseudo-element on `.brand`, NOT as its own element. `.topbar` places its children by
   named grid areas, so a bare <span> with no area was auto-placed into a THIRD implicit row and
   silently added 54px to the header — the bar measured 151px instead of 96px and the cause was
   invisible in the markup. A pseudo-element is a flex child of the brand block and costs the grid
   nothing. */
.topbar .brand::after{
  content:"";flex:none;width:1px;height:26px;background:#22302A;margin-inline-start:6px;
}

/* ── SCOPE PILL ──────────────────────────────────────────────────────────────────────────────────
   A raised inset chip holding a label, a rule, and a live state. The app's breadcrumb already has
   exactly those three parts — overview crumb, separator, incident crumb — so this is the same
   elements given the canvas's treatment, not a new control. */
.topbar .scopebar{
  display:flex;align-items:center;gap:8px;white-space:nowrap;
  padding:6px 11px;border-radius:7px;
  background:var(--hdr-raise);border:1px solid var(--hdr-line);
}
.topbar .scopebar .crumb{
  background:transparent;border:0;padding:0;
  font-size:12px;font-weight:var(--w-bold);color:#fff;
}
.topbar .scopebar .crumb .li{width:14px;height:14px;color:#8FA39A}
/* The «‹» becomes the canvas's 1px rule. Hidden with a transparent colour rather than
   `display:none`, so the element keeps its place in the flow app.js manages. */
.topbar .crumb-sep{
  flex:none;width:1px;height:14px;background:#2A3832;
  color:transparent;font-size:0;padding:0;overflow:hidden;
}
/* The live half of the pill. Green while the board is quiet — and that is a STATE, not decoration,
   so it takes the safe-condition colour and turns red the moment the incident badge is showing. */
.topbar .scopebar .crumb-inc{
  display:inline-flex;align-items:center;gap:6px;
  font-size:11.5px;font-weight:var(--w-med);color:#6FB894;
}
.topbar .scopebar .crumb-inc::before{
  content:"";flex:none;width:6px;height:6px;border-radius:50%;background:#21A366;
}
.topbar .scopebar .crumb-inc .li{display:none}
.topbar .scopebar:has(#incBadge:not(.hidden)) .crumb-inc{color:#E8879A}
.topbar .scopebar:has(#incBadge:not(.hidden)) .crumb-inc::before{background:var(--uae-red)}

/* ── STATUS CLUSTER ──────────────────────────────────────────────────────────────────────────── */
.topbar .status{display:flex;align-items:center;gap:8px;white-space:nowrap}
.topbar .chip.ver{
  background:transparent;border-color:transparent;padding:5px 4px;
  font-family:var(--msj-mono);font-size:10.5px;color:#6C7C75;font-weight:var(--w-reg);
}
.topbar .chip{
  background:var(--hdr-raise);border:1px solid var(--hdr-line);color:var(--hdr-chip);
  border-radius:var(--r-sm);padding:5px 9px;
  font-family:var(--msj-mono);font-size:11px;font-weight:var(--w-reg);
}
/* Square icon buttons, 30px, matching the canvas exactly. */
.topbar .iconbtn{
  width:30px;height:30px;padding:0;display:grid;place-items:center;
  background:var(--hdr-raise);border:1px solid var(--hdr-line);color:var(--hdr-chip);
  border-radius:var(--r-sm);box-shadow:none;
}
.topbar .iconbtn:hover{background:var(--hdr-tint);color:#fff;border-color:var(--hdr-edge);box-shadow:none}
.topbar .iconbtn .li{width:15px;height:15px}

/* ── ACCOUNT TRIGGER ─────────────────────────────────────────────────────────────────────────── */
.user-trigger{
  display:inline-flex;align-items:center;gap:7px;
  padding:5px 10px;border-radius:var(--r-sm);cursor:pointer;
  background:var(--hdr-raise);border:1px solid var(--hdr-line);color:#CDD6D2;
  font-family:inherit;font-size:11.5px;box-shadow:none;
}
.user-trigger:hover{background:var(--hdr-tint);color:#EDF1EF}
.user-group.open .user-trigger{background:#1E2C27;border-color:#3A4B44;color:#EDF1EF}
.user-trigger .chip{
  background:transparent;border:0;padding:0;color:inherit;
  font-family:inherit;font-size:11.5px;font-weight:var(--w-med);
}
/* The initials disc. This is the ONE place a filled brand red appears in the session cluster
   besides sign-out, and it is identity rather than state — an avatar cannot be mistaken for an
   alarm because it never changes colour. */
.user-av{
  flex:none;width:20px;height:20px;border-radius:50%;
  background:var(--uae-red);color:#fff;
  display:grid;place-items:center;
  font-family:var(--msj-mono);font-size:9px;font-weight:var(--w-med);letter-spacing:0;
}
.user-trigger .ng-chev{opacity:.6}
.user-trigger .ng-chev .li{width:11px;height:11px;color:#7E8D86}

.topbar .logout{
  background:var(--uae-red);border:1px solid var(--uae-red);color:#fff;
  border-radius:var(--r-sm);padding:7px 12px;
  font-family:inherit;font-size:12px;font-weight:var(--w-bold);box-shadow:none;
}
.topbar .logout:hover{background:var(--uae-red-hover);border-color:var(--uae-red-hover);filter:none}

/* ── ACCOUNT MENU ────────────────────────────────────────────────────────────────────────────── */
.user-group{position:relative;display:inline-flex}
.user-menu{
  width:262px;padding:0;overflow:hidden;
  inset-inline-start:auto;inset-inline-end:0;top:calc(100% + 8px);
  border:1px solid var(--line);border-radius:var(--r-lg);background:var(--card);
  box-shadow:0 12px 28px rgba(12,22,19,.18);z-index:40;
}
.um-head{
  display:flex;flex-direction:column;gap:2px;
  padding:12px 14px;border-bottom:1px solid var(--line-soft);
}
.um-name{font-size:var(--t-sm);font-weight:var(--w-bold);color:var(--ink)}
.um-meta{font-family:var(--msj-mono);font-size:11px;color:#8B958F}
.um-items{display:flex;flex-direction:column;padding:6px}
.um-item{
  display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;
  padding:9px 10px;border:0;border-radius:var(--r-sm);background:transparent;
  font-family:inherit;font-size:var(--t-sm);color:#2C3630;
  text-align:start;text-decoration:none;cursor:pointer;
}
.um-item:hover{background:var(--bg);color:var(--ink)}
.um-item.hidden{display:none}
.um-tag{
  flex:none;font-family:var(--msj-mono);font-size:10.5px;color:#A8B2AC;
  max-width:9ch;overflow:hidden;text-overflow:ellipsis;
}
.um-tag:empty{display:none}
/* Sign-out is the only destructive row, and the canvas marks it by colour and weight rather than by
   moving it somewhere unexpected. */
.um-item.um-danger{color:var(--uae-red);font-weight:var(--w-bold)}
.um-item.um-danger:hover{background:#FDF3F4;color:var(--uae-red-hover)}

/* ── NAV DROPDOWN ROWS ───────────────────────────────────────────────────────────────────────────
   The canvas stacks a label over a description. Those descriptions already exist in this app: every
   nav link carries a `title`, translated through `data-i18n-title`, which until now was only ever
   shown as a browser tooltip on hover. header-desk.js lifts it into the row, so the menu explains
   itself in four languages without a word of new copy being written or invented.

   The canvas also puts a count on each row. Those are NOT reproduced: its numbers are mock values,
   and this platform does not print a figure it has not measured. */
.topbar .tb-nav .nav-group-menu .chip.gear{
  display:grid;grid-template-columns:auto minmax(0,1fr);
  grid-template-areas:"ic lbl" "ic desc";
  column-gap:10px;row-gap:2px;align-items:center;
  width:100%;padding:9px 10px;border-radius:7px;
  background:transparent;color:var(--ink);
  font-size:var(--t-sm);font-weight:var(--w-med);text-align:start;
}
.topbar .tb-nav .nav-group-menu .chip.gear>[data-licon],
.topbar .tb-nav .nav-group-menu .chip.gear>.li{grid-area:ic;align-self:center}
.topbar .tb-nav .nav-group-menu .chip.gear .chip-lbl{grid-area:lbl;min-width:0;line-height:1.3}
.topbar .tb-nav .nav-group-menu .chip.gear .nav-desc{
  grid-area:desc;min-width:0;
  font-size:11px;font-weight:var(--w-reg);color:#8B958F;line-height:1.35;
  overflow:hidden;text-overflow:ellipsis;
}
.topbar .tb-nav .nav-group-menu .chip.gear:has(.nav-desc){align-items:start}
.topbar .tb-nav .nav-group-menu .chip.gear.active .nav-desc{color:#A8767F}

/* ── HEADER HEIGHT ───────────────────────────────────────────────────────────────────────────────
   The canvas is a 54px identity band over a 42px nav band. This bar was 116px because it carried
   11px of top padding and a 6px row-gap between the two. Pinning the first row to 54px and closing
   the gap lands it at the canvas's 96px, and the nav band now meets the identity band directly —
   which is what makes them read as two bands rather than as one tall header with a stripe in it. */
.topbar{padding-top:0;padding-bottom:0;row-gap:0;align-content:start}
.topbar>.brand,.topbar>.scopebar,.topbar>.status,.topbar>.tb-divider{
  align-self:center;min-height:54px;
}
.topbar>.brand,.topbar>.status{display:flex;align-items:center}
.topbar .brand{gap:12px}
.topbar .brand .t{font-size:14px;line-height:1.25}
.topbar .brand .sub{font-size:10.5px;line-height:1.3}
.topbar .brand-seal .logo-img{height:34px}

/* ── ONE CONTROL PER NAV GROUP ───────────────────────────────────────────────────────────────────
   `.nav-group-split` styled a link welded to a caret — two halves with squared inner corners and a
   divider between them. «الإدارة» is a single button now, so those rules have nothing to act on;
   they are neutralised here rather than deleted from styles.css, which still owns them for any
   group that has not been converted.

   The button also has to show the active state that used to live on its link half. `:has()` reads
   it from the menu instead: if the section you are in is a row inside this group, the group's own
   button is the one that is highlighted. */
.tb-nav .nav-group-split>.chip.gear:not(.ng-caret),
.tb-nav .nav-group-split>.ng-caret{border-radius:7px;padding-inline:12px}
.nav-group-split .ng-caret::before,.nav-group-split .ng-caret::after{content:none}

.topbar .tb-nav .nav-group:has(.nav-group-menu .chip.gear.active)>.nav-group-toggle{
  background:var(--uae-black);color:#F4F5F3;font-weight:var(--w-bold);
}
.topbar .tb-nav .nav-group:has(.nav-group-menu .chip.gear.active)>.nav-group-toggle .li{color:#F4F5F3}
/* A labelled toggle needs the same padding as a plain nav link; the caret-only version was 7px. */
.topbar .tb-nav .nav-group-toggle{display:inline-flex;align-items:center;gap:6px;padding:7px 12px}
.topbar .tb-nav .nav-group-toggle.ng-caret{padding-inline:7px}
