/* AlphaCore — the operations console.

   One surface: warm paper. The whole interface is ink on bone, and colour is
   held back until you point at something — which is what lets a hundred and two
   departments sit on one page without shouting. Type does the work instead: a
   light serif with wide tracking for names and places, a quiet sans for the
   interface, a mono for anything that is a figure or an identifier.

   Two skins now, and the second is the same design after dark rather than a
   different one: ink on bone becomes bone on ink. Every value below is
   redefined once in the dark block and nowhere else, so a component cannot
   drift between them — if a colour is hard-coded in a rule instead of read
   from a token, it is a bug in both. */

:root {
  /* Paper and ink */
  --paper: #f2f0ea;          /* the page itself — warm bone, never white */
  --paper-raise: #f8f7f3;    /* a panel lifted off it */
  --paper-sunk: #eae7df;     /* a well pressed into it */
  --paper-veil: #fbfaf7;     /* overlays, dialogs */
  --seam: #ded9cf;           /* hairline — the only border weight that exists */
  --seam-soft: #e9e5dc;
  --ink: #191714;            /* near-black, warm */
  --ink-mute: #6a645b;
  --ink-faint: #9d968a;
  --ink-ghost: #cfc9bd;      /* the huge type behind the map */

  /* The single accent. Terracotta, taken from the thin red marks on the
     reference lines — used for live state, the current thing, and nothing else. */
  --accent: #b8503a;
  --accent-soft: #cf7a63;
  --accent-wash: rgba(184, 80, 58, 0.08);

  /* Status, muted to sit on paper rather than glow on it */
  --ok: #5d7f5f;
  --warn: #a07a35;
  --bad: #a8443a;
  --steel: #4a6d76;

  /* Compatibility: older rules still name the previous tokens. Mapping them
     here keeps one source of truth while the components are restyled. */
  --bg: var(--paper);
  --bg-raise: var(--paper-raise);
  --bg-panel: var(--paper-raise);
  --bg-sunk: var(--paper-sunk);
  --ember: var(--accent);
  --ember-soft: var(--accent-soft);
  --edge: var(--seam);
  --shadow-pop: 0 18px 48px rgba(25, 23, 20, 0.10);
  --shadow-soft: 0 2px 10px rgba(25, 23, 20, 0.04);

  /* The three values that describe how light falls on the page. They were
     literals until the dark skin arrived and proved that a hard-coded colour is
     a component that cannot follow the theme. */
  --grain-light: rgba(255, 253, 248, 0.9);   /* the sheet catching light top-left */
  --grain-warm: rgba(184, 80, 58, 0.035);    /* the faintest warmth bottom-right */
  --scrim: rgba(242, 240, 234, 0.72);        /* what a dialog lays over the page */

  /* Type. The serif carries the identity; on Arabic it falls to Sakkal Majalla,
     which is the closest thing to this voice that ships with the system. */
  --font-display: 'Cambria', 'Constantia', 'Sakkal Majalla', Georgia, 'Times New Roman', serif;
  --font-ui: 'Segoe UI', -apple-system, 'Sakkal Majalla', Tahoma, system-ui, sans-serif;
  --font-mono: 'Cascadia Mono', 'Consolas', ui-monospace, 'Courier New', monospace;

  /* Tracking is a design element here, not a flourish: it is what makes a
     six-letter word read as a place rather than a label. */
  --track-wide: 0.34em;
  --track-mid: 0.18em;
  --track-tight: 0.06em;

  /* 4px rhythm, but the shell breathes at a larger scale than the tables */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px; --s8: 72px;
  --r-sm: 4px; --r-md: 8px; --r-lg: 12px; --r-pill: 999px;
  --rail: 62px;
  --t-fast: 140ms; --t-mid: 260ms; --t-slow: 520ms;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  color-scheme: light;
}

/* ---------------------------------------------------------------------------
   After dark.

   Not a black interface — the same warm paper seen at night. The greys keep
   their brown cast, the accent lifts because terracotta at 18% luminance on a
   dark ground reads as mud, and the status colours come up enough to be legible
   without becoming the neon that light-mode was designed to avoid.

   Only tokens are redefined. Nothing below this block knows which skin it is
   wearing, which is the whole point: one design, two lights.
   --------------------------------------------------------------------------- */
:root[data-theme="dark"] {
  --paper: #16150f;          /* the page — warm charcoal, never pure black */
  --paper-raise: #1d1b15;
  --paper-sunk: #100f0b;
  --paper-veil: #211f18;
  --seam: #322e25;           /* the hairline still reads as one weight */
  --seam-soft: #262319;
  --ink: #efe9dc;            /* bone, the colour the page used to be */
  --ink-mute: #a49b8a;
  --ink-faint: #746c5e;
  --ink-ghost: #2b2820;      /* the huge type behind the map, now barely raised */

  /* Terracotta held at the same hue and lifted in luminance until it carries
     on a dark ground. Same role, same restraint: live state and nothing else. */
  --accent: #e0714f;
  --accent-soft: #f0977a;
  --accent-wash: rgba(224, 113, 79, 0.12);

  --ok: #86ab86;
  --warn: #cfa257;
  --bad: #e0776a;
  --steel: #7fa7b0;

  --shadow-pop: 0 18px 48px rgba(0, 0, 0, 0.55);
  --shadow-soft: 0 2px 10px rgba(0, 0, 0, 0.28);

  /* The same light, at night: a cool lift from the top-left instead of a warm
     one, and a scrim that darkens rather than washes out. */
  --grain-light: rgba(255, 250, 235, 0.045);
  --grain-warm: rgba(224, 113, 79, 0.05);
  --scrim: rgba(10, 9, 6, 0.72);
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* Arabic reads a touch larger at the same optical size. */
html[lang="ar"] body { font-size: 15px; line-height: 1.7; }
html[dir="rtl"] .mono, html[dir="rtl"] .num, html[dir="rtl"] input[type="number"] { direction: ltr; text-align: start; }

:where(a, button, input, select, textarea):focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Atmosphere: a single warm gradient, no fake depth. */
body::before {
  content: "";
  position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(1100px 520px at 8% -10%, var(--accent-wash), transparent 65%);
}

.app {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: var(--rail) 1fr;
  min-height: 100vh;
}
.app.nav-open { grid-template-columns: var(--rail) 232px 1fr; }

/* ---------- Sidebar ---------- */
.side {
  border-right: 1px solid var(--seam);
  background: linear-gradient(180deg, var(--bg-raise), var(--bg));
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}

.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 16px 16px;
  border-bottom: 1px solid var(--seam);
}
.brand-glyph {
  color: var(--ember);
  font-size: 20px;
  text-shadow: 0 0 14px rgba(255, 107, 44, 0.6);
}
.brand-name { display: flex; flex-direction: column; }
.brand-name span:first-child {
  font-weight: 700; letter-spacing: 0.24em; font-size: 15px;
  font-stretch: 75%;
}
.brand-sub {
  font-size: 9px; letter-spacing: 0.3em; color: var(--ink-mute);
  font-weight: 500;
}

nav { display: flex; flex-direction: column; padding: 10px 8px; gap: 2px; flex: 1; overflow-y: auto; }
.nav-sec {
  font-size: 8.5px; letter-spacing: 0.32em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 700; padding: 10px 12px 3px;
}
.nav-sec:first-child { padding-top: 2px; }
nav a {
  color: var(--ink-mute); text-decoration: none;
  font-size: 12.5px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase;
  font-stretch: 85%;
  padding: 9px 12px; border-radius: 3px;
  border-left: 2px solid transparent;
  display: flex; align-items: center; justify-content: space-between;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
nav a:hover { color: var(--ink); background: var(--seam-soft); }
nav a.active {
  color: var(--ink);
  background: linear-gradient(90deg, rgba(255, 107, 44, 0.12), transparent 70%);
  border-left-color: var(--ember);
}
.nav-count {
  font-family: var(--font-mono); font-size: 10.5px;
  background: var(--warn); color: #1b1508;
  border-radius: 8px; padding: 0 6px; min-width: 18px; text-align: center;
}
.nav-count:empty { display: none; }

.side-foot { border-top: 1px solid var(--seam); padding: 12px 14px; display: grid; gap: 10px; }
.acting label {
  display: block; font-size: 9.5px; letter-spacing: 0.25em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 4px;
}
.acting input {
  width: 100%; background: var(--bg); border: 1px solid var(--seam);
  color: var(--steel); font-family: var(--font-mono); font-size: 12px;
  padding: 6px 8px; border-radius: 3px;
}
.foot-row { display: flex; justify-content: space-between; align-items: center; }
.ver { color: var(--ink-faint); font-family: var(--font-mono); font-size: 11px; }

/* ---------- Main ---------- */
.main { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 20px 28px 14px;
  border-bottom: 1px solid var(--seam);
  position: sticky; top: 0; z-index: 5;
  background: var(--bg); background: color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.topbar h1 {
  font-size: 26px; font-weight: 650; font-stretch: 70%;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.top-right { display: flex; align-items: center; gap: 12px; }
.clock { font-family: var(--font-mono); font-size: 12px; color: var(--ink-faint); }

.view { padding: 24px 28px 60px; display: grid; gap: 20px; animation: rise 0.35s ease both; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- Chips & badges ---------- */
.chip {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em;
  border: 1px solid var(--seam); border-radius: 3px; padding: 3px 8px;
  color: var(--ink-mute); background: var(--bg-raise);
}
.chip-ok { color: var(--ok); border-color: var(--seam); border-color: color-mix(in srgb, var(--ok) 40%, var(--seam)); }
.chip-bad { color: var(--bad); border-color: var(--seam); border-color: color-mix(in srgb, var(--bad) 40%, var(--seam)); }
.chip-warn { color: var(--warn); border-color: var(--seam); border-color: color-mix(in srgb, var(--warn) 40%, var(--seam)); }
.chip-ember { color: var(--ember-soft); border-color: var(--seam); border-color: color-mix(in srgb, var(--ember) 45%, var(--seam)); }
.chip-dim { opacity: 0.8; }

.state { font-family: var(--font-mono); font-size: 11px; padding: 2px 7px; border-radius: 3px; }
.state-done { color: var(--ok); background: rgba(120, 191, 109, 0.1); }
.state-queued, .state-leased { color: var(--ink-mute); background: var(--seam-soft); }
.state-running { color: var(--steel); background: rgba(94, 195, 201, 0.1); animation: pulse 1.4s ease-in-out infinite; }
.state-awaiting_human { color: var(--warn); background: rgba(255, 176, 32, 0.12); }
.state-failed, .state-cancelled { color: var(--bad); background: rgba(229, 83, 61, 0.1); }
.state-escalated { color: var(--ember-soft); background: rgba(255, 107, 44, 0.12); }
@keyframes pulse { 50% { opacity: 0.5; } }

/* ---------- Panels & grids ---------- */
.grid { display: grid; gap: 14px; }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1100px) { .grid-4 { grid-template-columns: repeat(2, 1fr); } .grid-3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 780px) { .app { grid-template-columns: 1fr; } .side { position: static; height: auto; } .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; } }

.panel {
  background: var(--bg-panel);
  border: 1px solid var(--seam);
  border-radius: 4px;
  padding: 16px 18px;
}
.panel-title {
  font-size: 10.5px; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--ink-mute); font-weight: 600; margin-bottom: 12px;
  display: flex; justify-content: space-between; align-items: center;
}

/* Stat tiles */
.tile { position: relative; overflow: hidden; }
.tile .big {
  font-family: var(--font-ui); font-stretch: 65%; font-weight: 700;
  font-size: 40px; line-height: 1; letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
}
.tile .unit { font-size: 16px; color: var(--ink-mute); font-weight: 500; margin-left: 2px; }
.tile .sub { margin-top: 6px; font-size: 12px; color: var(--ink-mute); font-family: var(--font-mono); }
.tile::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, var(--ember), transparent 70%);
  opacity: 0.55;
}
.tile.tile-steel::after { background: linear-gradient(90deg, var(--steel), transparent 70%); }
.tile.tile-warn::after { background: linear-gradient(90deg, var(--warn), transparent 70%); }

/* Meters */
.meter { margin-top: 10px; }
.meter-track { height: 6px; background: var(--seam-soft); border-radius: 3px; overflow: hidden; }
.meter-fill {
  height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--ember), var(--ember-soft));
  box-shadow: 0 0 10px rgba(255, 107, 44, 0.45);
  transition: width 0.6s ease;
}
.meter-fill.cool { background: linear-gradient(90deg, #3e8f94, var(--steel)); box-shadow: 0 0 10px rgba(94, 195, 201, 0.35); }
.meter-fill.hot { background: linear-gradient(90deg, var(--bad), var(--warn)); }
.meter-label { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 11px; color: var(--ink-mute); margin-bottom: 5px; }

/* ---------- Tables ---------- */
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 600; padding: 6px 10px 8px;
  border-bottom: 1px solid var(--seam);
}
td {
  padding: 8px 10px; border-bottom: 1px solid var(--seam-soft);
  font-size: 12.5px; vertical-align: top;
}
tr:last-child td { border-bottom: none; }
tbody tr { transition: background 0.12s; }
tbody tr:hover { background: rgba(255, 255, 255, 0.02); }
td.mono, .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
td.num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
th.num { text-align: right; }
.rowlink { cursor: pointer; }

/* ---------- Buttons & forms ---------- */
.btn {
  font-family: var(--font-ui); font-stretch: 85%; font-weight: 600;
  font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase;
  background: transparent; color: var(--ink);
  border: 1px solid var(--seam); border-radius: 3px;
  padding: 7px 14px; cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s, box-shadow 0.15s;
}
.btn:hover { border-color: var(--ember); color: var(--ember-soft); box-shadow: 0 0 12px rgba(255, 107, 44, 0.18); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--ember); border-color: var(--ember); color: #170b04; }
.btn-primary:hover { background: var(--ember-soft); color: #170b04; box-shadow: 0 0 16px rgba(255, 138, 40, 0.4); }
.btn-ok { border-color: var(--seam); border-color: color-mix(in srgb, var(--ok) 50%, var(--seam)); color: var(--ok); }
.btn-ok:hover { border-color: var(--ok); color: var(--ok); box-shadow: 0 0 12px rgba(120, 191, 109, 0.25); }
.btn-bad { border-color: var(--seam); border-color: color-mix(in srgb, var(--bad) 50%, var(--seam)); color: var(--bad); }
.btn-bad:hover { border-color: var(--bad); color: var(--bad); box-shadow: 0 0 12px rgba(229, 83, 61, 0.25); }
.btn-sm { padding: 4px 10px; font-size: 10.5px; }

input[type="text"], textarea, select {
  background: var(--bg); border: 1px solid var(--seam); border-radius: 3px;
  color: var(--ink); font-family: var(--font-mono); font-size: 12.5px;
  padding: 8px 10px; width: 100%;
}
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--seam); border-color: color-mix(in srgb, var(--ember) 60%, var(--seam)); }
textarea { resize: vertical; min-height: 70px; }
.form-row { display: grid; gap: 10px; margin-bottom: 10px; }
.form-inline { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.form-inline > * { flex: 1; min-width: 140px; }
.form-inline > .btn, .form-inline > .btn-primary { flex: 0; min-width: auto; }
label.fl { display: block; font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 4px; }

/* ---------- Misc ---------- */
.sparkline { width: 100%; height: 72px; }
.empty { color: var(--ink-faint); font-family: var(--font-mono); font-size: 12px; padding: 14px 4px; }
.kv { display: grid; grid-template-columns: 140px 1fr; gap: 4px 14px; font-size: 12.5px; }
.kv dt { color: var(--ink-faint); font-size: 10.5px; letter-spacing: 0.15em; text-transform: uppercase; padding-top: 2px; }
.kv dd { font-family: var(--font-mono); }
pre.json {
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.5;
  background: var(--bg); border: 1px solid var(--seam-soft); border-radius: 3px;
  padding: 10px 12px; overflow-x: auto; max-height: 300px; color: #c9c2b4;
}
.reason { color: var(--warn); font-family: var(--font-mono); font-size: 11.5px; }

/* Gate progress (products) */
.gatebar { display: flex; gap: 3px; margin: 8px 0; }
.gatebar span {
  flex: 1; height: 8px; border-radius: 2px; background: var(--seam-soft);
  position: relative;
}
.gatebar span.passed { background: linear-gradient(90deg, var(--ember), var(--ember-soft)); box-shadow: 0 0 6px rgba(255, 107, 44, 0.35); }
.gatebar span.active { background: var(--steel); animation: pulse 1.6s ease-in-out infinite; }
.gatebar span:hover::after {
  content: attr(data-t); position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%);
  background: var(--bg-raise); border: 1px solid var(--seam); border-radius: 3px;
  font-family: var(--font-mono); font-size: 10px; color: var(--ink); padding: 2px 7px; white-space: nowrap; z-index: 9;
}

/* Tribunal timeline */
.round { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--seam-soft); }
.round:last-child { border-bottom: none; }
.round-badge {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  border: 1px solid var(--seam); color: var(--ink-mute); background: var(--bg-raise);
}
.round-advocate .round-badge { color: var(--steel); border-color: var(--seam); border-color: color-mix(in srgb, var(--steel) 45%, var(--seam)); }
.round-critic .round-badge { color: var(--warn); border-color: var(--seam); border-color: color-mix(in srgb, var(--warn) 45%, var(--seam)); }
.round-judge .round-badge { color: var(--ember-soft); border-color: var(--seam); border-color: color-mix(in srgb, var(--ember) 50%, var(--seam)); }
.round-validator .round-badge { color: var(--ok); border-color: var(--seam); border-color: color-mix(in srgb, var(--ok) 45%, var(--seam)); }
.round-redteam .round-badge { color: var(--bad); border-color: var(--seam); border-color: color-mix(in srgb, var(--bad) 50%, var(--seam)); }
.round-body { min-width: 0; flex: 1; }
.round-label { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-mute); margin-bottom: 4px; font-weight: 600; }

/* Agent cards */
.agent-card { display: grid; gap: 8px; }
.agent-head { display: flex; justify-content: space-between; align-items: center; }
.agent-id { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }
.agent-name { font-weight: 650; font-stretch: 80%; font-size: 15px; letter-spacing: 0.04em; }
.agent-meta { display: flex; gap: 6px; flex-wrap: wrap; }

/* System map */
.sysmap { width: 100%; height: auto; display: block; }
.sysmap .map-node rect { fill: var(--bg-raise); stroke: var(--seam); transition: stroke 0.15s, filter 0.15s; }
.sysmap a:hover .map-node rect { stroke: var(--ember); filter: drop-shadow(0 0 6px rgba(255, 107, 44, 0.25)); }
.sysmap .map-node.warn rect { stroke: var(--seam); stroke: color-mix(in srgb, var(--warn) 45%, var(--seam)); }
.sysmap .map-node.ember rect { stroke: var(--seam); stroke: color-mix(in srgb, var(--ember) 45%, var(--seam)); }
.sysmap .map-node.steel rect { stroke: var(--seam); stroke: color-mix(in srgb, var(--steel) 45%, var(--seam)); }
.sysmap .map-node.ok rect { stroke: var(--seam); stroke: color-mix(in srgb, var(--ok) 40%, var(--seam)); }
.sysmap .map-node.bad rect { stroke: var(--bad); }
.sysmap .mt { fill: var(--ink); font-family: var(--font-ui); font-size: 12px; font-weight: 650; letter-spacing: 0.08em; }
.sysmap .mt.small { font-size: 10.5px; }
.sysmap .mv { fill: var(--ink-mute); font-family: var(--font-mono); font-size: 10px; }
.sysmap .mg { fill: var(--ink-faint); font-family: var(--font-ui); font-size: 9.5px; font-weight: 600; letter-spacing: 0.25em; }
.sysmap .map-group { fill: none; stroke: var(--seam-soft); stroke-dasharray: 3 4; }
.sysmap .map-edge { stroke: var(--ink-faint); stroke-width: 1.2; fill: none; }
.sysmap .map-edge.dashed { stroke-dasharray: 4 4; opacity: 0.45; }
.sysmap .me { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 9px; }
.sysmap .mid { text-anchor: middle; }
.sysmap .core-ring {
  fill: none; stroke: rgba(255, 107, 44, 0.3); stroke-width: 1.2;
  stroke-dasharray: 3 11;
  animation: coreSpin 70s linear infinite;
  transform-origin: 500px 330px;
}
@keyframes coreSpin { to { transform: rotate(360deg); } }
.sysmap .core-disc { fill: var(--bg-raise); }
.sysmap .core-glyph {
  fill: var(--ember); font-size: 26px; text-anchor: middle;
  filter: drop-shadow(0 0 10px rgba(255, 107, 44, 0.7));
}
.sysmap .orbit-guide { fill: none; stroke: var(--seam-soft); stroke-width: 1; opacity: 0.55; }
.map-legend { margin-top: 8px; font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-faint); }

/* Login */
#login {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  background: var(--bg); background: color-mix(in srgb, var(--bg) 92%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
#login[hidden] { display: none; }
.login-panel {
  width: 340px; background: var(--bg-panel); border: 1px solid var(--seam);
  border-top: 2px solid var(--ember); border-radius: 6px; padding: 28px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.login-panel input { margin-top: 4px; }

/* Metro map */
.metro { width: 100%; height: auto; display: block; }
.metro .m-line { fill: none; stroke-width: 3.5; stroke-linejoin: round; opacity: 0.85; }
.metro .m-station circle { fill: var(--bg-raise); stroke-width: 2.6; transition: r 0.15s, filter 0.15s; }
.metro a:hover .m-station circle { filter: drop-shadow(0 0 6px currentColor); }
.metro .m-name { fill: var(--ink); font-family: var(--font-ui); font-size: 10.5px; font-weight: 650; letter-spacing: 0.1em; text-anchor: middle; }
.metro .m-val { fill: var(--ink-mute); font-family: var(--font-mono); font-size: 9px; text-anchor: middle; }
.metro .m-lbl { font-family: var(--font-ui); font-size: 9px; font-weight: 700; letter-spacing: 0.28em; text-anchor: end; }
.metro .m-term circle { fill: var(--bg-raise); }
.metro .m-term .core-glyph { font-size: 20px; }

/* Interactive map v4 — dimming, flow dots, terminal pulse, tooltip */
.metro [data-line] { transition: opacity 0.18s ease; }
.metro .dimmed { opacity: 0.12; }
.metro .m-dot { pointer-events: none; opacity: 0.9; }
.metro a[data-station] { cursor: pointer; }
.metro .m-term-pulse { fill: none; stroke-width: 1.5; opacity: 0.5; transform-origin: 913px 343px; animation: term-pulse 3.2s ease-out infinite; }
@keyframes term-pulse {
  0% { transform: scale(1); opacity: 0.55; }
  70% { transform: scale(1.55); opacity: 0; }
  100% { transform: scale(1.55); opacity: 0; }
}
#map-tip {
  position: absolute; z-index: 6; pointer-events: none; width: 236px;
  background: var(--bg-raise); border: 1px solid var(--edge);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  padding: 10px 12px; border-radius: 4px;
}
#map-tip .tip-head { font-family: var(--font-ui); font-weight: 700; font-size: 12px; letter-spacing: 0.08em; }
#map-tip .tip-val { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-mute); margin: 3px 0 6px; }
#map-tip .tip-body { font-size: 11.5px; color: var(--ink); line-height: 1.45; }
#map-tip .tip-go { font-family: var(--font-mono); font-size: 9.5px; color: var(--ink-faint); margin-top: 7px; }

/* Cross-line connectors — the Nexus mesh between departments */
.metro .m-cross { transition: opacity 0.18s ease; }
.metro .m-cross path { fill: none; stroke: var(--ink-faint); stroke-width: 1.2; stroke-dasharray: 3 5; opacity: 0.38; }
.metro .m-cross text { font-family: var(--font-mono); font-size: 8.5px; fill: var(--ink-faint); opacity: 0; transition: opacity 0.18s; }
.metro .m-cross.hot path { stroke: var(--ember); stroke-dasharray: none; opacity: 1; filter: drop-shadow(0 0 4px rgba(255, 107, 44, 0.5)); }
.metro .m-cross.hot text { opacity: 1; fill: var(--ember); }
.metro .m-cross.dimmed { opacity: 0.05; }

/* Journeys — value-chain rows + stage stepper */
.journey-row { display: block; text-decoration: none; color: var(--ink); border: 1px solid var(--edge); border-radius: 4px; padding: 12px 14px; margin-bottom: 10px; transition: border-color 0.15s, background 0.15s; }
.journey-row:hover { border-color: var(--ember); background: var(--bg-raise); }
.jr-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.jr-track { height: 6px; background: var(--bg-sunk, rgba(255,255,255,0.05)); border-radius: 3px; overflow: hidden; margin-top: 8px; }
.jr-fill { height: 100%; background: linear-gradient(90deg, var(--ember), #b78bff); border-radius: 3px; transition: width 0.4s ease; }
.jstage { display: flex; gap: 12px; }
.jstage .js-rail { display: flex; flex-direction: column; align-items: center; width: 18px; flex: none; }
.jstage .js-dot { width: 13px; height: 13px; border-radius: 50%; border: 2.5px solid var(--edge); background: var(--bg-raise); flex: none; margin-top: 4px; }
.jstage .js-rail::after { content: ''; flex: 1; width: 2px; background: var(--edge); margin-top: 2px; }
.jstage:last-child .js-rail::after { display: none; }
.jstage.active .js-dot { box-shadow: 0 0 8px var(--ember); animation: js-blink 1.6s ease-in-out infinite; }
.jstage.awaiting_human .js-dot { box-shadow: 0 0 8px var(--warn); }
.jstage.pending { opacity: 0.55; }
.jstage.skipped { opacity: 0.35; }
@keyframes js-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
.jstage .js-body { flex: 1; padding-bottom: 16px; min-width: 0; }
.jstage .js-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.jstage .js-sum { font-size: 12px; color: var(--ink-mute); margin-top: 5px; }

/* The society — chat, channels, relationships */
.chan-bar { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 12px; }
.chan {
  background: none; border: 1px solid var(--edge); border-radius: 12px; cursor: pointer;
  color: var(--ink-mute); font-family: var(--font-mono); font-size: 11px; padding: 4px 11px;
  transition: border-color 0.15s, color 0.15s;
}
.chan:hover { border-color: var(--ember); color: var(--ink); }
.chan.on { border-color: var(--ember); color: var(--ember); }
.chan .chan-n { color: var(--ink-faint); font-size: 9.5px; }
.chat { display: grid; gap: 12px; max-height: 62vh; overflow-y: auto; padding-right: 6px; }
.msg { display: grid; grid-template-columns: 30px 1fr; gap: 10px; }
.msg-av {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  font-family: var(--font-ui); font-size: 10.5px; font-weight: 700; color: #16130f; flex: none;
}
.msg-head { display: flex; flex-wrap: wrap; gap: 7px; align-items: baseline; font-size: 12px; }
.msg-head .msg-role { color: var(--ink-faint); font-size: 10.5px; }
.msg-head .msg-to { color: var(--steel); font-family: var(--font-mono); font-size: 10.5px; }
.msg-head .msg-time { color: var(--ink-faint); font-family: var(--font-mono); font-size: 9.5px; margin-left: auto; }
.msg-text { font-size: 12.5px; line-height: 1.6; color: var(--ink); margin-top: 3px; white-space: pre-wrap; }
.rel-row { display: grid; grid-template-columns: 190px 1fr 120px 34px; gap: 9px; align-items: center; padding: 5px 0; font-size: 11.5px; }
.rel-pair { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink); }
.rel-bar { height: 5px; background: rgba(255, 255, 255, 0.06); border-radius: 3px; overflow: hidden; }
.rel-bar span { display: block; height: 100%; background: linear-gradient(90deg, var(--steel), var(--ok)); }
.rel-bar.friction span { background: linear-gradient(90deg, var(--warn), var(--bad)); }
.rel-label { color: var(--ink-mute); font-size: 11px; }

/* Autonomy mode — the loudest surface in the product, on purpose */
.autonomy-live { border-color: var(--bad); box-shadow: inset 0 0 0 1px rgba(229, 83, 61, 0.25); }
.autonomy-live::before {
  content: ''; display: block; height: 2px; margin: -14px -14px 12px;
  background: linear-gradient(90deg, var(--bad), var(--warn), var(--bad));
  background-size: 200% 100%; animation: au-scan 3s linear infinite;
}
@keyframes au-scan { 0% { background-position: 0% 0; } 100% { background-position: 200% 0; } }
.danger-note { border-left: 2px solid var(--bad); padding: 4px 0 4px 12px; margin-top: 8px; }
.danger-note .dn-title {
  font-family: var(--font-ui); font-size: 10.5px; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--bad); margin-bottom: 6px;
}
.danger-note p { font-size: 12.5px; line-height: 1.65; margin: 0 0 8px; color: var(--ink); }
.danger-note p:last-child { margin-bottom: 0; }

/* Org personas + owner console */
.persona { margin: 6px 0; font-size: 12px; line-height: 1.6; }
.persona .pk {
  display: inline-block; min-width: 66px; font-family: var(--font-mono); font-size: 9.5px;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint);
}
.owner-switch {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--edge); font-size: 12.5px;
}
.owner-switch:last-of-type { border-bottom: none; }
.owner-switch .os-sub { display: block; color: var(--ink-mute); font-size: 11px; margin-top: 2px; }

/* Request desk — the route strip */
.route { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin: 6px 0; }
.route-stop {
  display: flex; align-items: center; gap: 6px; padding: 4px 9px;
  border: 1px solid var(--edge); border-radius: 12px; text-decoration: none;
  font-family: var(--font-mono); font-size: 10px; color: var(--ink-mute);
  transition: border-color 0.15s, color 0.15s;
}
.route-stop:hover { border-color: var(--ember); color: var(--ink); }
.route-stop.done { border-color: var(--edge); border-color: color-mix(in srgb, var(--ok) 45%, var(--edge)); color: var(--ink); }
.route-stop.done .rs-mark { color: var(--ok); }
.route-stop.active { border-color: var(--ember); color: var(--ink); animation: js-blink 1.6s ease-in-out infinite; }
.route-stop.active .rs-mark { color: var(--ember); }
.route-stop.awaiting_human { border-color: var(--warn); color: var(--ink); }
.route-stop.awaiting_human .rs-mark { color: var(--warn); }
.route-stop.failed .rs-mark { color: var(--bad); }

/* Approvals inbox */
.inbox-row {
  display: grid; grid-template-columns: 1fr 52px auto; gap: 12px; align-items: start;
  padding: 10px 0 10px 11px; border-left: 2px solid var(--edge); margin: 6px 0;
}
.inbox-row.high { border-left-color: var(--warn); }
.inbox-row.low { border-left-color: var(--edge); opacity: 0.82; }
.inbox-row .ib-title { color: var(--ink); text-decoration: none; font-size: 12.5px; font-weight: 600; }
.inbox-row .ib-title:hover { color: var(--ember); }
.inbox-row .ib-sub { color: var(--ink-mute); font-size: 11.5px; margin-top: 2px; }
.inbox-row .ib-age { color: var(--ink-faint); font-size: 10.5px; text-align: right; padding-top: 2px; }
.inbox-row .ib-actions { display: flex; gap: 5px; align-items: flex-start; }

/* Constellation map v6 */
.constellation { width: 100%; height: auto; display: block; }
/* v7 atlas: the SVG scales to the viewport so the whole company is always on
   screen; pan/zoom handles detail. */
.constellation.atlas {
  height: clamp(460px, calc(100vh - 235px), 900px);
  touch-action: none; -webkit-user-select: none; user-select: none; cursor: grab;
}
.constellation.atlas:active { cursor: grabbing; }
.constellation .cx-hit { fill: none; stroke: transparent; stroke-width: 12; pointer-events: stroke; cursor: pointer; }
.constellation .cx-edge.trace {
  opacity: 0.95; stroke-dasharray: 8 6;
  animation: cx-flow 0.8s linear infinite;
  filter: drop-shadow(0 0 6px currentColor);
}
@keyframes cx-flow { to { stroke-dashoffset: -14; } }
.constellation .cx-div { cursor: pointer; }
.constellation .cx-div:hover { opacity: 1; text-decoration: underline; }
/* Radial labels: every section name runs along its own ray, so texts cannot
   collide; the stroke halo keeps them readable where edges pass underneath. */
.constellation .cx-rlab {
  fill: var(--ink); font-family: var(--font-ui); font-size: 10.5px; font-weight: 650;
  letter-spacing: 0.04em; pointer-events: none;
  paint-order: stroke; stroke: var(--bg-raise); stroke-width: 3.2px; stroke-linejoin: round;
}
.constellation .cx-rcount { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 9px; font-weight: 400; }
.constellation .cx-arc { fill: none; stroke-width: 1.7; opacity: 0.35; cursor: pointer; }
.constellation .cx-arc:hover { opacity: 0.8; }
.constellation .cx-arc.dimmed { opacity: 0.08; }
/* v8 mainboard: chips, copper nets, bus lanes, packets, silkscreen. */
.board .b-bg { stroke: none; }
.board .b-frame { fill: none; stroke: var(--edge); stroke-width: 1.6; pointer-events: none; }
.board .hole { fill: none; stroke: var(--edge); stroke-width: 1.5; pointer-events: none; }
.board .silk {
  fill: var(--ink-faint); font-family: var(--font-mono); font-size: 9px;
  letter-spacing: 0.18em; opacity: 0.6; pointer-events: none;
}
.board .zone-rect { fill: none; stroke-width: 1; stroke-dasharray: 5 6; opacity: 0.35; cursor: pointer; }
.board .zone-rect:hover { opacity: 0.85; }
.board .cx-div.zlab { text-anchor: start; font-size: 9.5px; letter-spacing: 0.2em; }
.board .cx-edge { opacity: 0.42; stroke-linecap: round; }
.board .cx-edge.dormant { opacity: 0.1; }
.board .cx-edge.lit { opacity: 1; }
.board .chip-body { fill: var(--bg-raise); stroke-width: 1.3; }
.board a:hover .chip-body { filter: drop-shadow(0 0 8px currentColor); stroke-width: 2; }
.board [data-node].lit .chip-body { stroke-width: 2; filter: drop-shadow(0 0 7px currentColor); }
.board .chip-name { fill: var(--ink); font-family: var(--font-ui); font-size: 10px; font-weight: 650; letter-spacing: 0.03em; pointer-events: none; }
.board .chip-count { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8.5px; pointer-events: none; }
.board .pin { fill: var(--ink-faint); opacity: 0.45; pointer-events: none; }
.board .chip-led { fill: var(--ink-faint); opacity: 0.3; }
.board .chip-led.on { fill: var(--ok); opacity: 1; animation: led-blink 2.8s ease-in-out infinite; }
@keyframes led-blink { 50% { opacity: 0.4; } }
.board .cx-pkt { pointer-events: none; filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.5)); }
.board .cpu-body { fill: var(--bg-raise); stroke-width: 2.2; }
.board .cpu-pulse { fill: none; stroke-width: 1.4; opacity: 0.5; animation: term-pulse 3.4s ease-out infinite; }
.board a[data-node="core"]:hover .cpu-body { filter: drop-shadow(0 0 12px currentColor); }
/* live layer: chips flash when their section acts; the ticker narrates */
.board [data-node].ping .chip-body { animation: chip-ping 1.8s ease-out; }
@keyframes chip-ping {
  0% { filter: drop-shadow(0 0 16px currentColor); stroke-width: 3.2; }
  100% { filter: none; }
}
.map-ticker {
  position: absolute; left: 12px; bottom: 36px; width: 330px; z-index: 4;
  font-family: var(--font-mono); font-size: 9.5px; line-height: 1.5;
  background: var(--bg-raise); background: color-mix(in srgb, var(--bg-raise) 82%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid var(--edge); border-radius: 8px; padding: 7px 10px;
  pointer-events: none;
}
.map-ticker .tk-row { display: flex; gap: 8px; white-space: nowrap; overflow: hidden; }
.map-ticker .tk-time { color: var(--ember); flex: none; }
.map-ticker .tk-act { color: var(--ink); overflow: hidden; text-overflow: ellipsis; }
.map-ticker .tk-who { color: var(--ink-faint); margin-left: auto; flex: none; }
.map-ticker .tk-idle { color: var(--ink-faint); }
/* the iteration engine: route picker, peer reviews, auditor findings */
.route-picker { display: flex; flex-wrap: wrap; gap: 5px; }
.route-picker button {
  background: transparent; color: var(--ink-mute); border: 1px solid var(--edge); border-radius: 6px;
  cursor: pointer; font-family: var(--font-mono); font-size: 10px; padding: 4px 9px;
}
.route-picker button:hover { color: var(--ink); border-color: var(--ink-faint); }
.route-picker button.on { background: var(--ember); color: #17110c; border-color: var(--ember); font-weight: 700; }
.ws-reviews { display: grid; gap: 8px; margin-top: 10px; }
.ws-rev { border-left: 2px solid var(--steel, #5ec3c9); padding: 4px 0 4px 10px; }
.ws-audit { border-left: 2px solid var(--bad); padding: 6px 0 6px 10px; margin-top: 10px; }
/* map style switcher — four ways to read the same company */
.map-style-picker { display: inline-flex; gap: 0; margin-right: 8px; border: 1px solid var(--edge); border-radius: 7px; overflow: hidden; vertical-align: middle; }
.map-style-picker button {
  background: transparent; color: var(--ink-mute); border: none; cursor: pointer;
  font-family: var(--font-mono); font-size: 10px; padding: 4px 10px; letter-spacing: 0.06em;
}
.map-style-picker button + button { border-left: 1px solid var(--edge); }
.map-style-picker button:hover { color: var(--ink); }
.map-style-picker button.on { background: var(--ember); color: #17110c; font-weight: 700; }
/* v9 metro */
.metroV9 .mt-line { fill: none; stroke-width: 5; stroke-linecap: round; opacity: 0.75; cursor: pointer; }
.metroV9 .mt-line:hover { opacity: 1; }
.metroV9 .mt-dot { fill: var(--bg-raise); stroke-width: 3; }
.metroV9 a:hover .mt-dot { filter: drop-shadow(0 0 7px currentColor); }
.metroV9 [data-node].lit .mt-dot { stroke-width: 4; filter: drop-shadow(0 0 7px currentColor); }
.metroV9 [data-node].ping .mt-dot { animation: chip-ping 1.8s ease-out; }
.metroV9 .mt-lab {
  fill: var(--ink); font-family: var(--font-ui); font-size: 10.5px; font-weight: 650; pointer-events: none;
  paint-order: stroke; stroke: var(--bg-raise); stroke-width: 3px; stroke-linejoin: round;
}
.metroV9 .mt-cnt { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8.5px; text-anchor: middle; pointer-events: none; }
.metroV9 .cx-edge { opacity: 0.14; }
.metroV9 .cx-edge.lit, .metroV9 .cx-edge.trace { opacity: 1; }
.metroV9 .cx-edge.dormant { opacity: 0.05; }
/* v10 flow line */
.flowV10 .fl-pill { fill: var(--bg-raise); stroke-width: 1.3; }
.flowV10 a:hover .fl-pill { filter: drop-shadow(0 0 8px currentColor); stroke-width: 2; }
.flowV10 [data-node].lit .fl-pill { stroke-width: 2; filter: drop-shadow(0 0 7px currentColor); }
.flowV10 [data-node].ping .fl-pill { animation: chip-ping 1.8s ease-out; }
.flowV10 .fl-lab { fill: var(--ink); font-family: var(--font-ui); font-size: 9.6px; font-weight: 650; pointer-events: none; }
.flowV10 .fl-cnt { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8px; pointer-events: none; }
.flowV10 .cx-edge { opacity: 0.3; }
.flowV10 .cx-edge.dormant { opacity: 0.08; }
.flowV10 .chip-led { fill: var(--ink-faint); opacity: 0.3; }
.flowV10 .chip-led.on { fill: var(--ok); opacity: 1; animation: led-blink 2.8s ease-in-out infinite; }
.flowV10 .silk { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.18em; opacity: 0.65; }
.map-ctl { position: absolute; top: 44px; right: 12px; display: flex; flex-direction: column; gap: 4px; z-index: 5; }
.map-ctl button {
  width: 30px; height: 30px; border-radius: 6px; cursor: pointer;
  background: var(--bg-raise); color: var(--ink); border: 1px solid var(--edge);
  font-size: 15px; line-height: 1;
}
.map-ctl button:hover { border-color: var(--ember); color: var(--ember); }
/* The panel that used to dock inside the canvas is gone — what you click on
   the map now opens as a real window (#map-dialog .md-box, further down). */
#map-dialog .md-box .ms-head { font-family: var(--font-ui); font-weight: 800; font-size: 15px; letter-spacing: 0.02em; }
#map-dialog .md-box .ms-sub { color: var(--ink-mute); font-size: 11px; margin-top: 2px; text-transform: capitalize; }
#map-dialog .md-box .ms-hint { color: var(--ink-faint); font-size: 11.5px; margin-top: 6px; line-height: 1.45; }
#map-dialog .md-box .ms-actions { display: flex; gap: 6px; margin-top: 10px; }
#map-dialog .md-box .ms-sec {
  margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--edge);
  font-size: 9.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-mute);
}
/* Arrow, name and count travel together; the slack falls at the end of the
   line. A 1fr name column was drawn for a 296px dock and left a canyon in the
   middle of a 560px window. */
#map-dialog .md-box .ms-row {
  display: grid; grid-template-columns: 14px max-content 1fr; gap: 3px 8px; align-items: baseline;
  padding: 6px 4px; border-radius: 6px; cursor: pointer;
}
#map-dialog .md-box .ms-cnt { justify-self: start; }
#map-dialog .md-box .ms-row:hover { background: rgba(255, 255, 255, 0.05); }
#map-dialog .md-box .ms-row b { font-size: 12.5px; font-weight: 600; }
#map-dialog .md-box .ms-dir { color: var(--ink-faint); }
#map-dialog .md-box .ms-cnt { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }
/* The kind tag is an inline-block, so `plaintext` took its direction from the
   English description after it and pushed the whole line to the wrong edge.
   Isolating instead keeps the line with the page while the English run inside
   still reads left-to-right. */
#map-dialog .md-box .ms-lbl {
  grid-column: 2 / -1; color: var(--ink-faint); font-size: 12px; line-height: 1.45;
  unicode-bidi: isolate;
}
#map-dialog .md-box .ms-trace .ms-lbl b { color: var(--ember); font-family: var(--font-mono); font-size: 10px; }
.constellation .cx-orbit { fill: none; stroke: var(--edge); stroke-dasharray: 2 8; opacity: 0.4; }
.constellation .cx-spoke { stroke: var(--ink-faint); stroke-width: 0.5; opacity: 0.13; transition: opacity 0.18s; }
.constellation .cx-spoke.dimmed { opacity: 0.03; }
.constellation .cx-edge { fill: none; opacity: 0.3; transition: opacity 0.18s, stroke-width 0.18s; }
.constellation .cx-edge.dormant { stroke-dasharray: 3 6; opacity: 0.12; }
.constellation .cx-edge.lit { opacity: 0.95; filter: drop-shadow(0 0 5px currentColor); }
.constellation .cx-edge.dimmed { opacity: 0.04; }
.constellation a[data-node] { cursor: pointer; }
.constellation .cx-node { transition: opacity 0.18s; }
.constellation [data-node].dimmed { opacity: 0.16; }
.constellation .cx-halo { opacity: 0; transition: opacity 0.18s; }
.constellation [data-node].lit .cx-halo, .constellation a:hover .cx-halo { opacity: 0.16; }
.constellation .cx-dot { fill: var(--bg-raise); stroke-width: 2.4; transition: r 0.15s; }
.constellation a:hover .cx-dot { filter: drop-shadow(0 0 7px currentColor); }
.constellation .cx-label {
  fill: var(--ink); font-family: var(--font-ui); font-size: 9.5px; font-weight: 650;
  letter-spacing: 0.06em; text-anchor: middle; pointer-events: none;
}
.constellation .cx-count { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8.5px; text-anchor: middle; pointer-events: none; }
.constellation .cx-div {
  font-family: var(--font-ui); font-size: 10px; font-weight: 800; letter-spacing: 0.26em;
  text-anchor: middle; opacity: 0.75;
  paint-order: stroke; stroke: var(--bg-raise); stroke-width: 3.5px; stroke-linejoin: round;
}
.constellation .cx-core-ring { fill: var(--bg-raise); stroke-width: 2.5; }
.constellation .cx-core-pulse { fill: none; stroke-width: 1.4; opacity: 0.5; transform-origin: 500px 430px; animation: term-pulse 3.4s ease-out infinite; }
.constellation .cx-core-glyph { font-size: 26px; fill: var(--ember); text-anchor: middle; }
.constellation .cx-core-score { font-family: var(--font-ui); font-size: 22px; font-weight: 800; text-anchor: middle; }
.constellation .cx-core-sub { font-family: var(--font-mono); font-size: 8.5px; fill: var(--ink-mute); text-anchor: middle; letter-spacing: 0.1em; }
#map-tip .tip-rel { display: grid; gap: 2px; margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--edge); }
#map-tip .tip-rel span { font-family: var(--font-mono); font-size: 9.5px; color: var(--ink-mute); }
#map-tip .tip-rel b { color: var(--ember); }

/* Harmony — plan cards and score bars */
.harm-part { display: grid; grid-template-columns: 18px 1fr auto; gap: 8px; align-items: center; padding: 4px 0; font-size: 12px; }
.harm-part .hp-ok { font-size: 13px; }
.harm-part .hp-detail { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-faint); }
.plan-step { border-left: 2px solid var(--ember); padding: 7px 0 7px 11px; margin: 8px 0; }
.plan-step .ps-action { font-family: var(--font-mono); font-size: 11px; color: var(--ember); }
.plan-step .ps-why { font-size: 12px; color: var(--ink); margin-top: 2px; }
.plan-step .ps-result { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-mute); margin-top: 3px; }
.plan-step.failed { border-left-color: var(--ink-faint); opacity: 0.6; }

/* System Design — document grid */
.doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 6px; margin-top: 8px; }
.doc-chip {
  display: grid; grid-template-columns: 22px 1fr 16px; gap: 6px; align-items: center;
  padding: 7px 9px; border: 1px solid var(--edge); border-radius: 3px;
  text-decoration: none; color: var(--ink-mute); font-size: 11.5px; transition: border-color 0.15s, color 0.15s;
}
.doc-chip:hover { border-color: var(--ember); color: var(--ink); }
.doc-chip .dc-seq { font-family: var(--font-mono); font-size: 10px; color: var(--ink-faint); }
.doc-chip .dc-state { text-align: right; }
.doc-chip.done { color: var(--ink); border-color: var(--edge); border-color: color-mix(in srgb, var(--ok) 40%, var(--edge)); }
.doc-chip.done .dc-state { color: var(--ok); }
.doc-chip.writing { border-color: var(--ember); animation: js-blink 1.6s ease-in-out infinite; }
.doc-chip.awaiting_human { border-color: var(--warn); }
.doc-chip.awaiting_human .dc-state { color: var(--warn); }

/* Intelligence — rule builder + people blocks */
.rule-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 8px; }
.rule-card {
  display: flex; gap: 9px; align-items: flex-start; padding: 9px 11px;
  border: 1px solid var(--edge); border-radius: 4px; cursor: pointer; font-size: 12px;
  transition: border-color 0.15s, background 0.15s;
}
.rule-card:hover { border-color: var(--ember); background: var(--bg-raise); }
.rule-card input { margin-top: 2px; flex: none; }
.rule-card .rule-detail { display: block; color: var(--ink-mute); font-size: 11px; line-height: 1.45; margin-top: 3px; }
.people-block { margin-top: 8px; border-top: 1px dashed var(--edge); padding-top: 6px; }
.person-row {
  display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: center;
  padding: 3px 0; font-size: 11.5px;
}

/* 360° connections block */
.conn-group { border-left: 2px solid var(--edge); padding: 4px 0 4px 10px; margin: 8px 0; }
.conn-dept { font-family: var(--font-ui); font-size: 10.5px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--steel); text-decoration: none; }
.conn-dept:hover { color: var(--ember); }

/* Relationship graph rows */
.graph-row {
  display: grid; grid-template-columns: 110px 16px 110px 1fr 110px 46px;
  gap: 8px; align-items: center; padding: 7px 8px; border-radius: 3px;
  text-decoration: none; color: var(--ink); font-size: 12px;
}
.graph-row:hover { background: var(--bg-raise); }
.graph-row .gr-from, .graph-row .gr-to { font-family: var(--font-mono); font-size: 11px; color: var(--ink); }
.graph-row .gr-to { color: var(--steel); }
.graph-row .gr-arrow { color: var(--ink-faint); text-align: center; }
.graph-row .gr-label { color: var(--ink-mute); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.graph-row .gr-bar { height: 5px; background: rgba(255, 255, 255, 0.06); border-radius: 3px; overflow: hidden; }
.graph-row .gr-bar span { display: block; height: 100%; background: linear-gradient(90deg, var(--ember), #b78bff); }
.graph-row .gr-count { font-family: var(--font-mono); font-size: 11px; text-align: right; color: var(--ink-mute); }

/* Design Studio gallery */
.design-thumb { width: 100%; height: auto; display: block; border: 1px solid var(--edge); border-radius: 4px; margin-top: 8px; background: #0d0b08; }

/* Toast */
#toast {
  position: fixed; bottom: 22px; right: 22px; z-index: 50;
  display: grid; gap: 8px;
}
.toast {
  background: var(--bg-raise); border: 1px solid var(--seam);
  border-left: 3px solid var(--ember);
  color: var(--ink); font-family: var(--font-mono); font-size: 12px;
  padding: 10px 14px; border-radius: 3px; max-width: 380px;
  animation: rise 0.25s ease both;
}
.toast.err { border-left-color: var(--bad); color: #f0b3a9; }

/* ============================================================
   Shell v2 â€” icon rail, flyout, top bar, command palette.
   Authored with logical properties so RTL is a direction flip,
   not a second stylesheet.
   ============================================================ */

.rail {
  position: sticky; top: 0; height: 100vh; z-index: 30;
  background: var(--bg-raise);
  border-inline-end: 1px solid var(--seam);
  display: flex; flex-direction: column; align-items: center;
  padding: var(--s3) 0 var(--s2);
  gap: var(--s1);
}
.rail-brand {
  width: 38px; height: 38px; border-radius: var(--r-md);
  display: grid; place-items: center; margin-bottom: var(--s2);
  background: var(--ember); color: #fff; font-size: 17px;
  text-decoration: none; flex: none;
}
.rail-btn {
  width: 44px; height: 44px; border: none; background: transparent; cursor: pointer;
  border-radius: var(--r-md); color: var(--ink-mute);
  display: grid; place-items: center; position: relative;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.rail-btn svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.rail-btn:hover { background: var(--seam-soft); color: var(--ink); }
.rail-btn.on { background: var(--accent-wash); color: var(--ember); }
.rail-btn.on::before {
  content: ""; position: absolute; inset-inline-start: -1px; inset-block: 11px;
  width: 3px; border-radius: var(--r-pill); background: var(--ember);
}
.rail-dot {
  position: absolute; top: 6px; inset-inline-end: 6px;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--r-pill);
  background: var(--warn); color: #14100c; font: 600 10px/16px var(--font-mono);
  text-align: center;
}
.rail-dot:empty { display: none; }
.rail-spacer { flex: 1; }
.rail-tip {
  position: absolute; inset-inline-start: calc(100% + 8px); top: 50%; transform: translateY(-50%);
  background: var(--ink); color: var(--bg); padding: 4px 9px; border-radius: var(--r-sm);
  font-size: 11.5px; white-space: nowrap; pointer-events: none; opacity: 0;
  transition: opacity var(--t-fast) var(--ease); z-index: 40;
}
.rail-btn:hover .rail-tip { opacity: 1; }

.flyout {
  position: sticky; top: 0; height: 100vh; overflow-y: auto; z-index: 20;
  background: var(--bg-raise); border-inline-end: 1px solid var(--seam);
  padding: var(--s4) var(--s3) var(--s5);
  display: flex; flex-direction: column; gap: 2px;
}
.flyout[hidden] { display: none; }
.flyout-head {
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 700; padding: 0 var(--s2) var(--s3);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
}
.flyout-head .fh-count { font-family: var(--font-mono); letter-spacing: 0; }
.flyout a {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  padding: 9px var(--s3); border-radius: var(--r-sm);
  color: var(--ink-mute); text-decoration: none; font-size: 13.5px; font-weight: 500;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.flyout a:hover { background: var(--seam-soft); color: var(--ink); }
.flyout a.active { background: var(--accent-wash); color: var(--ember); font-weight: 600; }
.flyout a .fly-n { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }

.topbar {
  position: sticky; top: 0; z-index: 15;
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s5);
  background: var(--bg); background: color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--seam);
}
.topbar h1 { font-size: 19px; font-weight: 650; letter-spacing: -0.01em; }
.top-search {
  flex: 1; max-width: 420px; margin-inline: auto;
  display: flex; align-items: center; gap: var(--s2);
  background: var(--bg-sunk); border: 1px solid var(--seam);
  border-radius: var(--r-pill); padding: 7px var(--s4);
  color: var(--ink-faint); font-size: 13px; cursor: pointer;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.top-search:hover { border-color: var(--ember); color: var(--ink-mute); }
.top-search kbd {
  margin-inline-start: auto; font-family: var(--font-mono); font-size: 10.5px;
  background: var(--bg-raise); border: 1px solid var(--seam); border-radius: var(--r-sm); padding: 1px 6px;
}
.top-right { display: flex; align-items: center; gap: var(--s2); }
.icon-btn {
  width: 34px; height: 34px; border-radius: var(--r-md); border: 1px solid var(--seam);
  background: var(--bg-raise); color: var(--ink-mute); cursor: pointer;
  display: grid; place-items: center; font-size: 14px;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.icon-btn:hover { color: var(--ember); border-color: var(--ember); }
.icon-btn.wide { width: auto; padding: 0 var(--s3); font: 600 12px var(--font-mono); letter-spacing: 0.06em; }
.who-chip {
  display: flex; align-items: center; gap: var(--s2); cursor: pointer;
  border: 1px solid var(--seam); background: var(--bg-raise);
  border-radius: var(--r-pill); padding: 4px var(--s3) 4px 4px; color: var(--ink);
}
.who-chip .avatar {
  width: 26px; height: 26px; border-radius: 50%; background: var(--ember); color: #fff;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
}
.who-chip .who-name { font-size: 12.5px; font-weight: 600; }
.who-chip .who-role { font-size: 10.5px; color: var(--ink-faint); }

/* Command palette */
#palette {
  position: fixed; inset: 0; z-index: 200; display: grid; place-items: start center;
  padding-top: 12vh; background: rgba(16, 13, 10, 0.55);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
#palette[hidden] { display: none; }
.pal-box {
  width: min(620px, 92vw); background: var(--bg-panel);
  border: 1px solid var(--seam); border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop); overflow: hidden;
}
.pal-box input {
  width: 100%; border: none; background: transparent; color: var(--ink);
  font-family: var(--font-ui); font-size: 16px; padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--seam);
}
.pal-box input:focus { outline: none; }
.pal-list { max-height: 52vh; overflow-y: auto; padding: var(--s2); }
.pal-item {
  display: flex; align-items: center; gap: var(--s3);
  padding: 10px var(--s3); border-radius: var(--r-sm); cursor: pointer;
  color: var(--ink-mute);
}
.pal-item .pal-title { color: var(--ink); font-weight: 550; font-size: 13.5px; }
.pal-item .pal-div {
  margin-inline-start: auto; font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint);
}
.pal-item.sel, .pal-item:hover { background: var(--accent-wash); }
.pal-item.sel .pal-title { color: var(--ember); }
.pal-empty { padding: var(--s5); text-align: center; color: var(--ink-faint); font-size: 13px; }
.pal-foot {
  padding: var(--s2) var(--s4); border-top: 1px solid var(--seam);
  font-size: 11px; color: var(--ink-faint); display: flex; gap: var(--s4);
}

/* Diagrams keep Latin reading order even in Arabic. */
.constellation, .board { direction: ltr; }

/* The phone layout used to live here and had not worked for a while: the
   paper stylesheet below redefines .rail after this point and quietly won, so
   the rail stayed a 100vh column and pushed the document 193px wider than the
   screen. It is now one block at the end of the file, where it wins. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}


/* ============================================================
   Post-review fixes, from looking at the rendered console
   ============================================================ */

/* The map is an instrument, not a document: it keeps its dark canvas in both
   themes. Copper on white was unreadable, and the metaphor only works on a
   dark board anyway. */
.board .b-canvas { fill: #14100c; }
.board .b-bg { stroke: none; }
.board .b-frame { fill: none; stroke: #33291f; stroke-width: 1.6; pointer-events: none; }
.board .hole { fill: none; stroke: #3a3026; stroke-width: 1.5; pointer-events: none; }
.board .chip-body { fill: #1c1713; }
.board .chip-name { fill: #f5efe6; }
.board .chip-count, .board .silk { fill: #8d8171; }
.board .pin { fill: #5a4f42; }
.board .cpu-body { fill: #1c1713; }
.board .cx-core-glyph { fill: #ff7a3c; }
.board .cx-core-sub { fill: #a1968a; }
.board .cx-core-score { fill: #ff7a3c; }
.board .cx-div.zlab { paint-order: stroke; stroke: #14100c; stroke-width: 3px; }
.board .cx-rlab { stroke: #14100c; }
.map-panel { padding-bottom: var(--s5); }

/* The live ticker sat on top of the legend; give it the map's own corner. */
/* The map is always drawn LTR, so the ticker uses physical sides — otherwise
   it lands on the operations zone when the interface flips to Arabic. */
.map-ticker {
  bottom: 78px; top: auto; left: auto; right: 62px;
  width: 290px; background: rgba(20, 16, 12, 0.86); border-color: #33291f; color: #f5efe6;
  direction: ltr;
}
.map-ctl { left: auto; right: 12px; }
.panel-title { flex-wrap: wrap; gap: var(--s2); row-gap: var(--s1); }
.map-ticker .tk-act { color: #f5efe6; }
.map-ticker .tk-who, .map-ticker .tk-idle { color: #8d8171; }

/* Bidi: a line of English inside an Arabic page must keep its own direction,
   otherwise trailing punctuation jumps to the wrong end. */
html[dir="rtl"] :is(td, th, li, p, .map-legend, .panel-title, .empty, .sub,
  .ms-lbl, .tip-body, .reason, .big, .chip, .agent-id, .fly-n) {
  unicode-bidi: plaintext;
}
html[dir="rtl"] .btn, html[dir="rtl"] button { unicode-bidi: plaintext; }

/* Arabic numerals stay Latin â€” finance and IDs must read the same in both
   languages, and mixing numeral systems is how reconciliation errors start. */
html[lang="ar"] { font-variant-numeric: lining-nums tabular-nums; }


/* Forms wrap properly at the new spacing: a full-width control (a route
   picker, a textarea) takes its own row instead of being squeezed into a
   column beside the inputs. */
.form-inline { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.form-inline > textarea,
.form-inline > div[style*="width:100%"] { flex: 1 0 100%; }
.form-inline > .route-picker { flex: 1 0 100%; }
.view { padding: var(--s5); display: grid; gap: var(--s4); }
.panel { border-radius: var(--r-md); }

/* The flow legend: what each kind of line means, and the measured proof that
   the company branches, loops and double-checks. */
.flow-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4);
  padding-top: var(--s3); margin-top: var(--s2); border-top: 1px solid var(--seam);
  font-size: 11.5px; color: var(--ink-mute);
}
.flow-legend .fl-k { display: inline-flex; align-items: center; gap: 6px; }
.flow-legend .fl-k i {
  width: 26px; height: 0; border-top: 2px solid var(--ink-faint); display: inline-block;
}
.flow-legend .fl-flow i { border-top-color: var(--ember); }
.flow-legend .fl-loop i { border-top: 2px dashed var(--bad); }
.flow-legend .fl-review i { border-top: 2px dotted var(--steel); }
.flow-legend .fl-audit i { border-top: 2px dashed var(--warn); }
.flow-legend .fl-gate i { border-top: 2px dotted var(--ink); }
.flow-legend .fl-memory i { border-top: 2px dashed var(--ok); }
.flow-legend .fl-stats {
  flex: 1 0 100%; font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint);
  padding-top: var(--s1);
}
/* Loops and audits should read even when the whole board is busy. */
.cx-edge[data-kind="loop"] { opacity: 0.85; }
.cx-edge[data-kind="audit"], .cx-edge[data-kind="review"] { opacity: 0.6; }
.board .cx-edge[data-kind="loop"] { opacity: 0.95; }

/* Live ticker, now a strip beneath the board: three most recent events, wide
   and quiet, never covering a department. */
.map-ticker {
  position: static; width: auto; margin-top: var(--s2);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 2px var(--s4);
  background: var(--bg-sunk); border: 1px solid var(--seam); border-radius: var(--r-sm);
  padding: var(--s2) var(--s3); direction: ltr;
}
.map-ticker .tk-row { display: flex; gap: var(--s2); font-family: var(--font-mono); font-size: 10.5px; }
.map-ticker .tk-time { color: var(--ember); }
.map-ticker .tk-act { color: var(--ink); }
.map-ticker .tk-who { color: var(--ink-faint); margin-inline-start: auto; }
.map-ticker .tk-idle { color: var(--ink-faint); }

/* A selected relationship explains itself: its kind, its live weight, and the
   mechanism behind it. */
#map-dialog .md-box .edge-kind { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s3); font-size: 12px; color: var(--ink); }
#map-dialog .md-box .edge-kind i { width: 30px; height: 0; flex: none; border-top: 2px solid var(--ember); }
#map-dialog .md-box .edge-loop i { border-top: 2px dashed var(--bad); }
#map-dialog .md-box .edge-review i { border-top: 2px dotted var(--steel); }
#map-dialog .md-box .edge-audit i { border-top: 2px dashed var(--warn); }
#map-dialog .md-box .edge-gate i { border-top: 2px dotted var(--ink); }
#map-dialog .md-box .edge-memory i { border-top: 2px dashed var(--ok); }
#map-dialog .md-box .ms-metric { margin-top: var(--s2); font-size: 12px; color: var(--ink-mute); }
#map-dialog .md-box .ms-metric b { font-family: var(--font-mono); font-size: 20px; color: var(--ember); }
.edge-tag {
  display: inline-block; font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 1px 5px; border-radius: var(--r-sm); border: 1px solid var(--seam); color: var(--ink-faint);
}
.edge-tag.edge-loop { color: var(--bad); border-color: var(--seam); border-color: color-mix(in srgb, var(--bad) 45%, var(--seam)); }
.edge-tag.edge-review { color: var(--steel); border-color: var(--seam); border-color: color-mix(in srgb, var(--steel) 45%, var(--seam)); }
.edge-tag.edge-audit { color: var(--warn); border-color: var(--seam); border-color: color-mix(in srgb, var(--warn) 45%, var(--seam)); }
.edge-tag.edge-gate { color: var(--ink); }
.edge-tag.edge-memory { color: var(--ok); border-color: var(--seam); border-color: color-mix(in srgb, var(--ok) 45%, var(--seam)); }
.constellation .cx-hit { cursor: pointer; }

/* v11 circle (circos) */
.circos .ci-field { fill: none; stroke: var(--seam); stroke-dasharray: 2 7; opacity: 0.5; }
.circos .ci-divarc { fill: none; stroke-width: 7; stroke-linecap: butt; opacity: 0.55; cursor: pointer; }
.circos .ci-divarc:hover { opacity: 1; }
.circos .ci-seg { fill: none; stroke-linecap: butt; opacity: 0.85; transition: stroke-width 0.15s var(--ease); }
.circos a:hover .ci-seg { opacity: 1; filter: drop-shadow(0 0 7px currentColor); }
.circos [data-node].lit .ci-seg { opacity: 1; filter: drop-shadow(0 0 6px currentColor); }
.circos [data-node].ping .ci-seg { animation: chip-ping 1.8s ease-out; }
.circos .ci-lab { fill: var(--ink); font-family: var(--font-ui); font-size: 11px; font-weight: 550; pointer-events: none; }
.circos .ci-n { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 9px; }
.circos .cx-edge { opacity: 0.22; }
.circos .cx-edge.lit, .circos .cx-edge.trace { opacity: 1; }
.circos .cx-edge.dormant { opacity: 0.07; }
.circos .cx-div { font-size: 10px; letter-spacing: 0.2em; }

/* v12 matrix */
.matrix .mx-head { font-family: var(--font-ui); font-size: 11.5px; font-weight: 650; cursor: pointer; }
.matrix .mx-head.mx-col { text-anchor: start; }
.matrix .mx-n { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8.5px; }
.matrix .mx-axis { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.2em; }
.matrix .mx-cell rect { transition: fill-opacity 0.15s var(--ease), stroke 0.15s var(--ease); }
.matrix .mx-cell.has { cursor: pointer; }
.matrix .mx-cell.has:hover rect { stroke: var(--ember); stroke-width: 1.6; }
.matrix .mx-v { fill: var(--ink); font-family: var(--font-mono); font-size: 15px; font-weight: 600; text-anchor: middle; pointer-events: none; }
.matrix .mx-e { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8.5px; text-anchor: middle; pointer-events: none; }
.matrix .silk { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.06em; }

/* the style switcher reads as a set of views, not a row of words */
.map-style-picker button { display: inline-flex; align-items: center; gap: 5px; padding: 4px 9px; }
.map-style-picker button b { font-size: 12px; font-weight: 400; }

/* The map dialog: a window over the board, not a panel inside it. While it is
   open the page behind is inert, so a drag meant for the window never pans the
   map underneath. */
#map-dialog {
  position: fixed; inset: 0; z-index: 180;
  display: grid; place-items: center;
  padding: var(--s5);
  background: rgba(14, 11, 8, 0.58);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  animation: md-in 160ms var(--ease);
}
#map-dialog[hidden] { display: none; }
@keyframes md-in { from { opacity: 0; } to { opacity: 1; } }
#map-dialog .md-box {
  position: relative;
  width: min(560px, 100%); max-height: min(78vh, 720px); overflow-y: auto;
  background: var(--bg-panel); color: var(--ink);
  border: 1px solid var(--seam); border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop);
  padding: var(--s5) var(--s5) var(--s4);
  animation: md-rise 200ms var(--ease);
}
@keyframes md-rise { from { transform: translateY(14px) scale(0.985); } to { transform: none; } }
#map-dialog .md-box:focus { outline: none; }
#map-dialog .md-x {
  position: absolute; top: var(--s3); inset-inline-end: var(--s3);
  width: 30px; height: 30px; border-radius: var(--r-sm);
  background: transparent; border: 1px solid var(--seam); color: var(--ink-mute);
  cursor: pointer; font-size: 13px; line-height: 1;
}
#map-dialog .md-x:hover { color: var(--bad); border-color: var(--bad); }
#map-dialog .ms-head { font-size: 20px; font-weight: 700; padding-inline-end: 40px; }
#map-dialog .ms-sub { font-size: 12.5px; margin-top: 2px; }
#map-dialog .ms-hint { font-size: 13px; line-height: 1.6; margin-top: var(--s3); }
#map-dialog .ms-actions { margin-top: var(--s4); }
/* The row grid was drawn for a 296px dock; in a 560px window a 1fr name column
   throws the count to the far edge and leaves a canyon in between. Pack the
   arrow, the name and the count together and let the slack fall at the end. */
#map-dialog .ms-row { padding: var(--s2); }
#map-dialog .ms-row:hover { background: var(--accent-wash); }
/* the board keeps its cursor to itself while the window is up */
body.map-modal-open .constellation { pointer-events: none; cursor: default; }
body.map-modal-open .map-ctl, body.map-modal-open .map-style-picker { pointer-events: none; opacity: 0.45; }

@media (max-width: 640px) {
  #map-dialog { place-items: end center; padding: 0; }
  #map-dialog .md-box {
    width: 100%; max-height: 88vh;
    border-radius: var(--r-lg) var(--r-lg) 0 0; border-bottom: none;
  }
}

/* Trace flow: a mode the map stays in, not a flash while a panel is open. */
/* Pinned to the viewport, not to the panel: the map is taller than the screen,
   and a control you have to scroll to find is a control you do not use. */
.trace-hud {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 120;
  width: min(880px, calc(100vw - 120px));
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4);
  padding: var(--s2) var(--s3);
  background: var(--bg-panel); background: color-mix(in srgb, var(--bg-panel) 94%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid var(--ember); border-radius: var(--r-md);
  box-shadow: var(--shadow-pop);
  direction: ltr;
}
.trace-hud[hidden] { display: none; }
.trace-hud .th-main { display: flex; align-items: center; gap: var(--s2); font-size: 13px; }
.trace-hud .th-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--ember); flex: none;
  animation: th-pulse 1.5s ease-in-out infinite;
}
@keyframes th-pulse { 50% { opacity: 0.25; } }
.trace-hud .th-txt { color: var(--ink-mute); font-size: 12px; }
.trace-hud .th-txt b, .trace-hud .th-main > b { color: var(--ink); }
.trace-hud .th-hops { display: flex; gap: 4px; flex-wrap: wrap; margin-inline-start: auto; }
.trace-hud .th-hop {
  display: inline-flex; align-items: baseline; gap: 4px;
  background: transparent; border: 1px solid var(--seam); color: var(--ink-faint);
  border-radius: var(--r-sm); padding: 3px 8px; cursor: pointer;
  font-family: var(--font-mono); font-size: 11px;
}
.trace-hud .th-hop i { font-style: normal; font-size: 9px; opacity: 0.65; }
.trace-hud .th-hop:hover { color: var(--ink); border-color: var(--ink-faint); }
.trace-hud .th-hop.on { background: var(--accent-wash); border-color: var(--ember); color: var(--ember); }
.trace-hud .th-stop { flex: none; }

/* Hop stamps: how far each department is from the origin. */
#hop-layer .hop-badge circle { fill: var(--ember); stroke: var(--bg); stroke-width: 1.5; }
#hop-layer .hop-badge text {
  fill: #17110c; font-family: var(--font-mono); font-size: 10px; font-weight: 700; text-anchor: middle;
}
#hop-layer .hop-badge { animation: hop-in 320ms var(--ease) backwards; }
#hop-layer .hop-origin circle { fill: var(--ok); }
@keyframes hop-in { from { opacity: 0; transform: scale(0.4); } }
.constellation [data-node].trace-origin .chip-body,
.constellation [data-node].trace-origin .cx-dot,
.constellation [data-node].trace-origin .mt-dot,
.constellation [data-node].trace-origin .fl-pill,
.constellation [data-node].trace-origin .ci-seg { filter: drop-shadow(0 0 10px var(--ok)); }

/* The floor — the room where humans and AI employees talk. */
.chat-wrap { display: grid; grid-template-columns: 250px 1fr; gap: var(--s4); height: calc(100vh - 190px); min-height: 520px; }
.chat-side {
  background: var(--bg-raise); border: 1px solid var(--seam); border-radius: var(--r-md);
  padding: var(--s3); overflow-y: auto; display: flex; flex-direction: column; gap: 2px;
}
.cs-sec { font-size: 9.5px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-faint); margin: var(--s3) 0 var(--s1); font-weight: 700; }
.cs-ch, .cs-person {
  display: flex; align-items: center; gap: var(--s2); width: 100%;
  background: transparent; border: none; color: var(--ink-mute); cursor: pointer;
  padding: 6px var(--s2); border-radius: var(--r-sm); font-size: 13px; text-align: start;
}
.cs-ch:hover, .cs-person:hover { background: var(--seam-soft); color: var(--ink); }
.cs-ch.on { background: var(--accent-wash); color: var(--ember); font-weight: 600; }
.cs-unread { margin-inline-start: auto; background: var(--ember); color: #fff; border-radius: var(--r-pill); font: 600 10px/16px var(--font-mono); min-width: 17px; text-align: center; font-style: normal; padding: 0 4px; }
.cs-person .mono { font-size: 11px; }
.cs-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-faint); flex: none; }
.cs-dot.on { background: var(--ok); }
.cs-dot.busy { background: var(--warn); animation: th-pulse 1.4s ease-in-out infinite; }
.cs-dot.human { background: var(--steel); }

.chat-main { display: flex; flex-direction: column; background: var(--bg-raise); border: 1px solid var(--seam); border-radius: var(--r-md); overflow: hidden; }
.chat-head { display: flex; justify-content: space-between; align-items: center; gap: var(--s3); padding: var(--s3) var(--s4); border-bottom: 1px solid var(--seam); }
.chat-topic { font-size: 11.5px; color: var(--ink-faint); }
.chat-stat { font-size: 10.5px; color: var(--ink-faint); }
.chat-log { flex: 1; overflow-y: auto; padding: var(--s4); display: flex; flex-direction: column; gap: var(--s3); }

.chat-msg { display: grid; grid-template-columns: 34px 1fr; gap: var(--s3); }
.cm-avatar {
  width: 34px; height: 34px; border-radius: var(--r-md); display: grid; place-items: center;
  font: 700 12px var(--font-mono); background: var(--seam); color: var(--ink-mute);
}
.chat-msg.agent .cm-avatar { background: var(--seam); background: color-mix(in srgb, var(--ember) 22%, var(--seam)); color: var(--ember); }
.chat-msg.human .cm-avatar { background: var(--seam); background: color-mix(in srgb, var(--steel) 22%, var(--seam)); color: var(--steel); }
.cm-head { display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap; }
.cm-head b { font-size: 13px; }
.cm-kind { font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
.cm-time { font-family: var(--font-mono); font-size: 10px; color: var(--ink-faint); }
.cm-text { font-size: 13.5px; line-height: 1.6; margin-top: 2px; }
.cm-text code { font-family: var(--font-mono); font-size: 12px; background: var(--bg-sunk); padding: 1px 5px; border-radius: 4px; }
.chat-at { color: var(--ember); font-weight: 600; }
.cm-action { margin-top: var(--s2); padding: var(--s2) var(--s3); border-radius: var(--r-sm); font-size: 12px; border-inline-start: 3px solid var(--ok); background: var(--bg-sunk); }
.cm-action.bad { border-inline-start-color: var(--bad); }
.cm-refs { margin-top: var(--s2); display: flex; gap: var(--s2); flex-wrap: wrap; }
.chat-ref { font-size: 11.5px; color: var(--steel); text-decoration: none; border: 1px solid var(--seam); border-radius: var(--r-pill); padding: 2px 9px; }
.chat-ref:hover { border-color: var(--steel); }
.cm-tools { display: flex; gap: 4px; margin-top: 4px; opacity: 0; transition: opacity var(--t-fast) var(--ease); }
.chat-msg:hover .cm-tools { opacity: 1; }
.cm-tools button { background: transparent; border: 1px solid var(--seam); border-radius: var(--r-sm); color: var(--ink-faint); cursor: pointer; font-size: 11px; padding: 1px 6px; }
.cm-tools button:hover { color: var(--ink); border-color: var(--ink-faint); }
.cm-reacts { display: flex; gap: 4px; margin-top: 4px; }
.cm-reacts span { font-size: 11px; border: 1px solid var(--seam); border-radius: var(--r-pill); padding: 1px 7px; }
.chat-msg.thinking .cm-text { color: var(--ink-faint); font-style: italic; }
.cm-typing i { display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: var(--ember); margin-inline-end: 2px; animation: th-pulse 1.1s ease-in-out infinite; }
.cm-typing i:nth-child(2) { animation-delay: 0.18s; }
.cm-typing i:nth-child(3) { animation-delay: 0.36s; }

.chat-compose { border-top: 1px solid var(--seam); padding: var(--s3) var(--s4); position: relative; }
.chat-input-row { display: flex; gap: var(--s2); align-items: flex-end; }
.chat-input-row textarea { flex: 1; resize: vertical; font-family: var(--font-ui); font-size: 13.5px; }
.chat-hint { font-size: 11px; color: var(--ink-faint); margin-top: var(--s2); }
.chat-replying { font-size: 11.5px; color: var(--ink-mute); margin-bottom: var(--s2); }
.chat-replying button { background: none; border: none; color: var(--bad); cursor: pointer; }
.chat-suggest {
  position: absolute; bottom: 78px; inset-inline-start: var(--s4); z-index: 10;
  background: var(--bg-panel); border: 1px solid var(--seam); border-radius: var(--r-md);
  box-shadow: var(--shadow-pop); overflow: hidden; min-width: 300px;
}
.chat-suggest button {
  display: flex; justify-content: space-between; gap: var(--s3); width: 100%;
  background: transparent; border: none; color: var(--ink); cursor: pointer;
  padding: 7px var(--s3); font-size: 12.5px; text-align: start;
}
.chat-suggest button:hover { background: var(--accent-wash); }
.chat-suggest i { color: var(--ink-faint); font-size: 10px; font-style: normal; }

@media (max-width: 860px) {
  .chat-wrap { grid-template-columns: 1fr; height: auto; }
  .chat-side { max-height: 220px; }
  .chat-log { min-height: 420px; }
}

/* Selecting an employee on the memory page scrolls to its playbook and says so. */
.panel.just-opened { animation: panel-flash 1.3s var(--ease); }
@keyframes panel-flash {
  0% { border-color: var(--ember); box-shadow: 0 0 0 3px var(--accent-wash); }
  100% { border-color: var(--seam); box-shadow: none; }
}

/* Marketing funnel: four stages, each narrower than the one before it. */
.funnel { display: flex; gap: var(--s2); align-items: stretch; }
.fn-step {
  flex: 1; display: flex; flex-direction: column; gap: 2px;
  background: var(--bg-sunk); border: 1px solid var(--seam); border-radius: var(--r-md);
  padding: var(--s3) var(--s4); position: relative;
}
.fn-step + .fn-step { margin-inline-start: -6px; }
.fn-step b { font-family: var(--font-mono); font-size: 24px; font-weight: 600; color: var(--ember); }
.fn-step span { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-mute); }
.fn-step i { font-style: normal; font-size: 11px; color: var(--ink-faint); font-family: var(--font-mono); }
.fn-step:nth-child(2) { opacity: 0.92; }
.fn-step:nth-child(3) { opacity: 0.84; }
.fn-step:nth-child(4) { opacity: 0.76; border-color: var(--ok); }

/* ============================================================
   The Hive â€” departments as cells, districts as neighbourhoods.
   Relationships stay hidden until you ask for them: two hundred
   lines at rest is noise, the same lines one cell at a time is
   an answer.
   ============================================================ */
.hive { background: transparent; }
.hive .hv-district {
  fill: none; stroke-width: 1.2; stroke-dasharray: 3 9; opacity: 0.28;
  cursor: pointer; transition: opacity var(--t-mid) var(--ease);
}
.hive .hv-district:hover { opacity: 0.8; }
.hive .hv-dname {
  font-family: var(--font-ui); font-size: 17px; font-weight: 700;
  letter-spacing: 0.22em; text-anchor: middle; text-transform: uppercase;
  opacity: 0.85; cursor: pointer;
  paint-order: stroke; stroke: var(--bg); stroke-width: 4px; stroke-linejoin: round;
}
.hive .hv-dn { font-family: var(--font-mono); font-size: 14px; opacity: 0.55; letter-spacing: 0; }

.hive .hv-hex {
  fill: var(--bg-raise); stroke-width: 1.4; opacity: 0.95;
  transition: fill var(--t-fast) var(--ease), stroke-width var(--t-fast) var(--ease);
}
.hive .hv-glow { fill: none; stroke-width: 0; opacity: 0; transition: opacity var(--t-fast) var(--ease); }
.hive a:hover .hv-hex,
.hive [data-node].lit .hv-hex { fill: var(--bg-raise); fill: color-mix(in srgb, currentColor 16%, var(--bg-raise)); stroke-width: 2.6; }
.hive a:hover .hv-glow,
.hive [data-node].lit .hv-glow { opacity: 0.5; stroke-width: 9; filter: blur(7px); }
.hive [data-node].dimmed { opacity: 0.14; }
.hive [data-node].ping .hv-hex { animation: chip-ping 1.8s ease-out; }
.hive .hv-label {
  fill: var(--ink); font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
  text-anchor: middle; pointer-events: none;
}
.hive .hv-count {
  fill: var(--ink-faint); font-family: var(--font-mono); font-size: 11.5px;
  text-anchor: middle; pointer-events: none;
}
.hive .hv-led { fill: var(--ink-faint); opacity: 0.35; }
.hive .hv-led.on { fill: var(--ok); opacity: 1; animation: led-blink 3s ease-in-out infinite; }

/* Links: invisible at rest, revealed for whatever you point at. */
.hive .hv-link { opacity: 0; transition: opacity var(--t-mid) var(--ease); }
.hive .hv-link.lit, .hive .hv-link.trace { opacity: 0.9; }
.hive .hv-link.dimmed { opacity: 0; }
.hive .cx-hit { stroke-width: 16; }

.hive .hv-corehex { fill: var(--bg-raise); stroke-width: 2.6; }
/* Without fill-box, an SVG scale() pivots on the viewBox origin and the pulse
   ring drifts off across the canvas instead of breathing in place. */
.hive .hv-corepulse {
  fill: none; stroke-width: 1.4; opacity: 0.45; animation: term-pulse 3.6s ease-out infinite;
  transform-box: fill-box; transform-origin: center;
}
.hive .cx-core-glyph { font-size: 30px; }
.hive .cx-core-score { font-size: 26px; }
.hive .silk { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em; }

/* ============================================================
   The Stream â€” six stages, real volume, and the two arcs that
   are not progress.
   ============================================================ */
.stream .st-ribbon { transition: opacity var(--t-mid) var(--ease); }
.stream .st-spark {
  fill: none; stroke-width: 1.6; opacity: 0.8; stroke-dasharray: 3 14;
  animation: st-move 1.4s linear infinite;
}
@keyframes st-move { to { stroke-dashoffset: -34; } }
.stream .st-pillar {
  fill: var(--bg-raise); stroke-width: 2;
  transition: fill var(--t-fast) var(--ease), stroke-width var(--t-fast) var(--ease);
}
.stream a:hover .st-pillar { fill: var(--bg-raise); fill: color-mix(in srgb, currentColor 18%, var(--bg-raise)); stroke-width: 3; }
.stream [data-node].lit .st-pillar { stroke-width: 3; }
.stream [data-node].dimmed { opacity: 0.25; }
.stream [data-node].ping .st-pillar { animation: chip-ping 1.8s ease-out; }
.stream .st-num {
  font-family: var(--font-mono); font-size: 30px; font-weight: 600;
  text-anchor: middle; pointer-events: none;
}
.stream .st-label {
  fill: var(--ink); font-family: var(--font-ui); font-size: 14px; font-weight: 650;
  text-anchor: middle; pointer-events: none;
}
.stream .st-sub {
  fill: var(--ink-mute); font-family: var(--font-ui); font-size: 11px;
  text-anchor: middle; pointer-events: none;
}
.stream .st-chip {
  fill: var(--ink-faint); font-family: var(--font-mono); font-size: 10px;
  text-anchor: middle; pointer-events: none;
}
.stream .st-loop, .stream .st-gatearc {
  fill: none; stroke-width: 2.2; stroke-dasharray: 9 6;
  marker-end: url(#mk-arrow-back);
}
.stream .st-loop { stroke: var(--bad); opacity: 0.85; }
.stream .st-gatearc { stroke: var(--ink-mute); opacity: 0.7; stroke-dasharray: 2 7; }
.stream .st-arclabel {
  fill: var(--bad); font-family: var(--font-mono); font-size: 12px; text-anchor: middle;
  paint-order: stroke; stroke: var(--bg); stroke-width: 4px; stroke-linejoin: round;
}
.stream .st-arclabel.low { fill: var(--ink-mute); }
.stream .silk { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.16em; }


/* ============================================================
   Live presence — a quiet bar that says the company is running
   and who else is looking. It never blocks anything: if the
   socket dies the pages keep working on their timers.
   ============================================================ */
#live-bar {
  position: fixed; inset-block-end: 10px; inset-inline-start: 50%;
  transform: translateX(-50%); z-index: 90;
  display: flex; align-items: center; gap: var(--s3);
  padding: 6px var(--s4); border-radius: 999px;
  background: var(--bg-panel); background: color-mix(in srgb, var(--bg-panel) 92%, transparent);
  border: 1px solid var(--seam); box-shadow: var(--shadow-pop);
  font-size: 11.5px; color: var(--ink-mute);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  max-width: min(760px, 92vw); overflow: hidden; white-space: nowrap;
  opacity: 0.92; transition: opacity var(--t-mid) var(--ease);
}
#live-bar:hover { opacity: 1; }
#live-bar .lb-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--ok); box-shadow: 0 0 8px var(--ok);
  animation: led-blink 2.4s ease-in-out infinite;
}
#live-bar.off .lb-dot { background: var(--ink-faint); box-shadow: none; animation: none; }
#live-bar .lb-txt { letter-spacing: 0.1em; text-transform: uppercase; font-size: 9.5px; }
#live-bar .lb-who { color: var(--ink); }
#live-bar .lb-who b { font-weight: 600; }
#live-bar .lb-feed { color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; }
#live-bar .lb-actor { color: var(--ember); }
@media (max-width: 700px) { #live-bar .lb-feed { display: none; } }

/* ==========================================================================
   PAPER — the surface restated.

   Everything above is the previous console, kept because a hundred pages read
   from it. This block is the new voice, and it is deliberately last so it wins
   without a specificity war: the same components, wearing paper.

   Three rules run through all of it. One border weight — a hairline, never a
   box. One accent, held back until you point at something. And type carrying
   the identity instead of colour: a light serif with wide tracking says where
   you are, and everything else gets out of its way.
   ========================================================================== */

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13.5px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
html[lang="ar"] body { font-size: 15px; line-height: 1.85; }

/* The page has a grain rather than a gradient: a barely-there warmth from the
   top left, the way light falls on a sheet lying on a desk. */
body::before {
  content: "";
  position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(1400px 700px at 12% -8%, var(--grain-light), transparent 60%),
    radial-gradient(900px 500px at 92% 108%, var(--grain-warm), transparent 62%);
}

:where(a, button, input, select, textarea):focus-visible {
  outline: 1.5px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- the rail: quieter, and it does not glow ---------- */
.rail {
  background: transparent;
  border-inline-end: 1px solid var(--seam);
  padding-block: var(--s4);
}
.rail-brand {
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--seam);
  border-radius: 50%;
  width: 34px; height: 34px;
  box-shadow: none;
}
.rail-btn {
  color: var(--ink-faint);
  border-radius: 50%;
  width: 38px; height: 38px;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.rail-btn svg { stroke-width: 1.25; }
.rail-btn:hover { background: transparent; color: var(--ink); }
.rail-btn.on { background: var(--ink); color: var(--paper); }
.rail-btn.on::before { display: none; }
.rail-dot {
  background: var(--accent); color: var(--paper);
  font-size: 9px; font-family: var(--font-mono);
  border: none; min-width: 15px; height: 15px; line-height: 15px;
}
.rail-tip {
  background: var(--ink); color: var(--paper);
  border: none; border-radius: 2px;
  font-size: 10px; letter-spacing: var(--track-tight); text-transform: uppercase;
  box-shadow: none;
}

/* ---------- the flyout: a list, not a menu ---------- */
.flyout {
  background: var(--paper);
  border-inline-end: 1px solid var(--seam);
  box-shadow: none;
}
.flyout-head {
  font-family: var(--font-display);
  font-size: 12px; font-weight: 400;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--ink-mute);
  border-bottom: 1px solid var(--seam);
  padding-block: var(--s4);
}
.flyout a {
  position: relative;
  color: var(--ink-mute);
  font-size: 13px; letter-spacing: 0; text-transform: none;
  border-radius: 2px; padding: 7px 12px;
}
.flyout a:hover { background: var(--paper-sunk); color: var(--ink); }
.flyout a.active { background: transparent; color: var(--ink); font-weight: 600; }
.flyout a.active::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 9px;
  width: 2px; height: 16px; background: var(--accent);
}

/* ---------- the top bar: a masthead ---------- */
.topbar, .topbar2 {
  background: var(--paper); background: color-mix(in srgb, var(--paper) 92%, transparent);
  border-bottom: 1px solid var(--seam);
  padding: var(--s5) var(--s6) var(--s4);
}
.topbar h1, #page-title {
  font-family: var(--font-display);
  font-size: 19px; font-weight: 400; font-stretch: normal;
  letter-spacing: var(--track-mid); text-transform: uppercase;
  color: var(--ink);
}
html[lang="ar"] #page-title { letter-spacing: 0; font-size: 22px; }

/* ---------- panels: hairlines, no shadows, no fills ---------- */
.panel {
  background: transparent;
  border: none;
  border-top: 1px solid var(--seam);
  border-radius: 0;
  padding: var(--s5) 0 var(--s6);
  box-shadow: none;
}
.panel-title {
  font-family: var(--font-display);
  font-size: 10.5px; font-weight: 400;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--s4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
}
html[lang="ar"] .panel-title { letter-spacing: var(--track-mid); font-size: 12px; }

/* The tiles are the one place a number is allowed to be large. */
.panel.tile { border-top: 1px solid var(--seam); padding: var(--s4) 0 var(--s5); }
.tile .big {
  font-family: var(--font-display);
  font-size: 40px; font-weight: 400; line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin-top: var(--s2);
}
.tile .sub {
  font-family: var(--font-ui); font-size: 11.5px; color: var(--ink-faint);
  margin-top: var(--s2); line-height: 1.5;
}
.tile::after { display: none; }
.tile.tile-ok .big { color: var(--ok); }
.tile.tile-bad .big { color: var(--bad); }
.tile.tile-warn .big { color: var(--warn); }
.tile.tile-steel .big { color: var(--steel); }

/* ---------- tables: rules, not boxes ---------- */
table { border-collapse: collapse; }
th {
  font-family: var(--font-display);
  font-size: 9.5px; font-weight: 400;
  letter-spacing: var(--track-mid); text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--seam);
  padding: var(--s2) var(--s3);
  background: transparent;
}
html[lang="ar"] th { letter-spacing: var(--track-tight); font-size: 11px; }
td {
  border-bottom: 1px solid var(--seam-soft);
  padding: 9px var(--s3);
  font-size: 13px;
  vertical-align: top;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background var(--t-fast) var(--ease); }
tbody tr:hover { background: var(--paper-sunk); }
td b, td strong { font-weight: 600; }

/* ---------- buttons: text first, chrome second ---------- */
.btn {
  background: transparent;
  border: 1px solid var(--seam);
  color: var(--ink-mute);
  border-radius: 2px;
  font-family: var(--font-ui);
  font-size: 11.5px; font-weight: 500;
  letter-spacing: var(--track-tight); text-transform: uppercase;
  padding: 7px 13px;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
html[lang="ar"] .btn { letter-spacing: 0; text-transform: none; font-size: 12.5px; }
.btn:hover { border-color: var(--ink); color: var(--ink); box-shadow: none; background: transparent; }
.btn-primary { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn-primary:hover { background: var(--accent); border-color: var(--accent); color: var(--paper); box-shadow: none; }
.btn-ok { border-color: var(--ok); color: var(--ok); }
.btn-ok:hover { background: var(--ok); border-color: var(--ok); color: var(--paper); }
.btn-bad { border-color: var(--seam); color: var(--ink-mute); }
.btn-bad:hover { border-color: var(--bad); color: var(--bad); background: transparent; }
.btn-sm { font-size: 10.5px; padding: 5px 10px; }

/* ---------- chips: a word with a hairline, not a badge ---------- */
.chip {
  background: transparent;
  border: 1px solid var(--seam);
  border-radius: var(--r-pill);
  color: var(--ink-mute);
  font-family: var(--font-ui);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: var(--track-tight);
  padding: 2px 9px;
}
.chip-ok { color: var(--ok); border-color: var(--seam); border-color: color-mix(in srgb, var(--ok) 35%, var(--seam)); }
.chip-bad { color: var(--bad); border-color: var(--seam); border-color: color-mix(in srgb, var(--bad) 35%, var(--seam)); }
.chip-warn { color: var(--warn); border-color: var(--seam); border-color: color-mix(in srgb, var(--warn) 35%, var(--seam)); }
.chip-ember { color: var(--accent); border-color: var(--seam); border-color: color-mix(in srgb, var(--accent) 35%, var(--seam)); }
.chip-steel { color: var(--steel); border-color: var(--seam); border-color: color-mix(in srgb, var(--steel) 35%, var(--seam)); }
.chip-dim { color: var(--ink-faint); opacity: 1; }

/* ---------- inputs: a line to write on ---------- */
input, select, textarea {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--seam);
  border-radius: 0;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
  padding: 6px 2px;
  transition: border-color var(--t-fast) var(--ease);
}
/* The pre-paper stylesheet gave input[type="text"] a filled box with a border,
   and that selector outranks the bare `input` above it — so text fields looked
   boxed while password, number and date fields beside them were a line. One
   surface, one input. Width stays 100%: forms across the app depend on it. */
input[type="text"] {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--seam);
  border-radius: 0;
  font-family: var(--font-ui);
  font-size: 13px;
  padding: 6px 2px;
}
input:focus, select:focus, textarea:focus { outline: none; border-bottom-color: var(--ink); }
input[type="text"]:focus { border-bottom-color: var(--ink); }
input::placeholder, textarea::placeholder { color: var(--ink-faint); }
textarea { border: 1px solid var(--seam); border-radius: 2px; padding: var(--s3); }

/* ---------- the view: wider gutters, air between panels ---------- */
.view { padding: var(--s6) var(--s6) var(--s8); gap: var(--s5); }
.grid { gap: var(--s5); }
.empty { color: var(--ink-faint); font-size: 12.5px; padding: var(--s5) 0; text-align: start; }
.sub { color: var(--ink-faint); font-size: 11.5px; }
.mono { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: -0.01em; }

.map-legend {
  color: var(--ink-faint); font-size: 11.5px; line-height: 1.65;
  margin-top: var(--s4); padding-top: var(--s3);
  border-top: 1px solid var(--seam-soft);
  max-width: 78ch;
}
.map-legend b { color: var(--ink-mute); font-weight: 600; }

/* ---------- the search and the palette ---------- */
.pal-box { background: var(--paper-veil); border: 1px solid var(--seam); box-shadow: var(--shadow-pop); border-radius: var(--r-sm); }
.pal-box input { border: none; border-bottom: 1px solid var(--seam); font-size: 15px; padding: var(--s4); }
.pal-item { border-radius: 2px; font-size: 13px; }
.pal-item.on, .pal-item:hover { background: var(--paper-sunk); }

/* ---------- dialogs and the live bar, on paper ---------- */
#map-dialog { background: var(--scrim); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
#map-dialog .md-box {
  background: var(--paper-veil);
  border: 1px solid var(--seam);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-pop);
}
#map-dialog .md-box .ms-head { font-family: var(--font-display); font-weight: 400; letter-spacing: var(--track-tight); }
#map-dialog .md-box .ms-sec {
  font-family: var(--font-display); font-size: 9.5px; font-weight: 400;
  letter-spacing: var(--track-wide); text-transform: uppercase; color: var(--ink-faint);
  border-top: 1px solid var(--seam);
}
#live-bar {
  background: var(--paper-veil); background: color-mix(in srgb, var(--paper-veil) 94%, transparent);
  border: 1px solid var(--seam);
  box-shadow: var(--shadow-soft);
  color: var(--ink-faint);
}
#live-bar .lb-dot { background: var(--accent); box-shadow: none; }
#live-bar .lb-actor { color: var(--accent); }
.trace-hud {
  background: var(--paper-veil); border: 1px solid var(--seam);
  box-shadow: var(--shadow-pop); color: var(--ink-mute);
}
.toast { background: var(--ink); color: var(--paper); border: none; border-radius: 2px; }

.map-ticker {
  background: transparent; border: none; border-top: 1px solid var(--seam-soft);
  font-size: 10.5px;
}
.map-ticker .tk-act { color: var(--ink-mute); }
.map-ticker .tk-who, .map-ticker .tk-idle { color: var(--ink-faint); }

/* ==========================================================================
   THE ATLAS — one map, two depths.

   Far: every district as a tree radiating from a dense core, names set in the
   serif at wide tracking around the rim. Near: one district, its departments
   as filled chips with the district name ghosted enormous behind them.

   The lines are hairlines and the nodes are small, because at this density the
   drawing has to be quiet enough that the labels can be read over it.
   ========================================================================== */
.atlas-wrap { position: relative; }
.atlas-svg {
  width: 100%; height: auto; display: block; cursor: grab;
  max-height: calc(100vh - 196px);
}
.atlas-svg:active { cursor: grabbing; }

/* the MAP / DASHBOARDS switch */
.atlas-switch {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid var(--seam); border-radius: 2px; padding: 2px;
}
.atlas-switch button {
  background: transparent; border: none; cursor: pointer;
  font-family: var(--font-display); font-size: 9.5px; font-weight: 400;
  letter-spacing: var(--track-mid); text-transform: uppercase;
  color: var(--ink-faint); padding: 5px 14px; border-radius: 1px;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.atlas-switch button:hover { color: var(--ink); }
.atlas-switch button.on { background: var(--ink); color: var(--paper); }
html[lang="ar"] .atlas-switch button { letter-spacing: var(--track-tight); font-size: 11px; }

/* district names around the rim */
.at-dname {
  font-family: var(--font-display); font-size: 15px; font-weight: 400;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  fill: var(--ink-mute); text-anchor: middle; cursor: pointer;
  transition: fill var(--t-fast) var(--ease);
}
.at-dname:hover { fill: var(--ink); }
.at-dsub {
  font-family: var(--font-ui); font-size: 9px; letter-spacing: 0.12em;
  fill: var(--ink-faint); text-anchor: middle; text-transform: lowercase;
  pointer-events: none;
}

/* branches and leaves */
.at-branch {
  fill: none; stroke: var(--ink-faint); stroke-width: 0.7; opacity: 0.5;
  transition: stroke var(--t-mid) var(--ease), opacity var(--t-mid) var(--ease);
}
.at-leaf {
  fill: var(--ink); stroke: none;
  transition: fill var(--t-fast) var(--ease), r var(--t-fast) var(--ease);
}
.at-leaf-ring { fill: var(--paper); stroke: var(--ink); stroke-width: 0.9; }
.at-hit { fill: transparent; cursor: pointer; }

/* Colour is the reward for pointing at something: the district you are on
   takes its own hue, and everything else recedes rather than competing. */
.atlas-svg.focused .at-branch { opacity: 0.14; }
.atlas-svg.focused .at-leaf { fill: var(--ink-ghost); }
.atlas-svg.focused .at-dname { fill: var(--ink-ghost); }
.atlas-svg .at-district.lit .at-branch { opacity: 1; stroke: currentColor; stroke-width: 0.9; }
.atlas-svg .at-district.lit .at-leaf { fill: currentColor; }
.atlas-svg .at-district.lit .at-dname { fill: currentColor; }
.atlas-svg .at-district.lit .at-dsub { fill: var(--ink-mute); }

/* the core: a dense little cloud, the orchestrator and the chain */
.at-core-dot { fill: var(--ink); opacity: 0.55; }
.at-core-ring { fill: none; stroke: var(--seam); stroke-width: 0.6; }
.at-core-label {
  font-family: var(--font-display); font-size: 8.5px; letter-spacing: var(--track-mid);
  text-transform: uppercase; fill: var(--ink-faint); text-anchor: middle;
}

/* ---- the near view ---- */
.at-ghost {
  font-family: var(--font-display); font-weight: 400;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  fill: var(--ink-ghost); opacity: 0.5; text-anchor: middle;
  pointer-events: none; -webkit-user-select: none; user-select: none;
}
.at-cluster {
  font-family: var(--font-display); font-size: 9.5px; letter-spacing: var(--track-mid);
  text-transform: uppercase; fill: var(--ink-faint); text-anchor: middle;
}
.at-cluster-n { font-family: var(--font-ui); font-size: 7.5px; letter-spacing: 0.1em; fill: var(--ink-ghost); }
.at-chip { fill: var(--ink); transition: fill var(--t-fast) var(--ease); }
.at-chip-ring { fill: var(--paper); stroke: var(--ink); stroke-width: 1; }
.at-chip-glyph { stroke: none; pointer-events: none; }

.at-node { cursor: pointer; }
.at-node:hover .at-chip { fill: var(--accent); }
.at-node:hover .at-chip-ring { stroke: var(--accent); }
.at-nlabel {
  font-family: var(--font-ui); font-size: 8.5px; letter-spacing: 0.02em;
  fill: var(--ink-mute); text-anchor: middle; pointer-events: none;
  opacity: 0; transition: opacity var(--t-fast) var(--ease);
}
.at-node:hover .at-nlabel { opacity: 1; }
.at-edge { fill: none; stroke: var(--ink-faint); stroke-width: 0.7; opacity: 0.55; }
.at-edge-mark { stroke: var(--accent); stroke-width: 0.9; opacity: 0.8; }

/* the arrows that walk you around the rim */
.at-step {
  fill: none; stroke: var(--ink-faint); stroke-width: 1.1; cursor: pointer;
  transition: stroke var(--t-fast) var(--ease);
}
.at-step:hover { stroke: var(--ink); }
.at-step-hit { fill: transparent; cursor: pointer; }

/* the footnote under the drawing */
.at-foot {
  font-family: var(--font-ui); font-size: 8px; letter-spacing: 0.16em;
  text-transform: uppercase; fill: var(--ink-ghost);
}

/* Arabic is a connected script: letter-spacing pulls the joins apart and turns
   a word into a row of orphans. The tracking that carries the identity in Latin
   is removed here, and the sizes come up to match the optical weight. */
html[lang="ar"] .at-dname { letter-spacing: 0; font-size: 17px; }
html[lang="ar"] .at-dsub { letter-spacing: 0; font-size: 10.5px; }
html[lang="ar"] .at-cluster { letter-spacing: 0; font-size: 12px; }
html[lang="ar"] .at-cluster-n { letter-spacing: 0; font-size: 9px; }
html[lang="ar"] .at-ghost { letter-spacing: 0; }
html[lang="ar"] .at-core-label,
html[lang="ar"] .at-foot { letter-spacing: 0; font-size: 10px; }
html[lang="ar"] .at-nlabel { font-size: 10px; }


/* ==========================================================================
   The way in.

   The first screen anybody sees, so it carries the whole design in one panel:
   paper, a hairline, the serif at wide tracking, and nothing else. It used to
   print the default credentials underneath the form — which is a published
   password, not a hint.
   ========================================================================== */
#login {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background: var(--paper);
  padding: var(--s5);
}
#login[hidden] { display: none; }

#login::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(1200px 620px at 50% -12%, var(--grain-light), transparent 62%),
    radial-gradient(700px 400px at 80% 112%, var(--grain-warm), transparent 60%);
}

.login-panel {
  position: relative;
  width: min(400px, 100%);
  border: 1px solid var(--seam);
  border-radius: var(--r-sm);
  background: var(--paper-veil);
  box-shadow: var(--shadow-pop);
  padding: var(--s7) var(--s6) var(--s5);
  text-align: center;
}

.login-mark {
  color: var(--accent);
  font-size: 22px; line-height: 1;
  margin-bottom: var(--s4);
}
.login-name {
  font-family: var(--font-display);
  font-size: 24px; font-weight: 400;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--ink);
  /* Tracking pushes the word off-centre; half of it back on the end restores it. */
  text-indent: var(--track-wide);
}
.login-tag {
  font-size: 11.5px; color: var(--ink-faint);
  margin-top: var(--s2) ;
}
html[lang="ar"] .login-name { letter-spacing: 0; text-indent: 0; font-size: 27px; }

.login-form { display: block; text-align: start; margin-top: var(--s6); }
.login-form[hidden] { display: none; }
.login-form .fl {
  display: block;
  font-family: var(--font-display);
  font-size: 9.5px; font-weight: 400;
  letter-spacing: var(--track-mid); text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--s1);
}
html[lang="ar"] .login-form .fl { letter-spacing: var(--track-tight); font-size: 11px; }
.login-form input { width: 100%; font-size: 14px; padding: 7px 2px; }
.login-gap { margin-top: var(--s4); }
.login-go { width: 100%; margin-top: var(--s5); }

.login-note {
  font-size: 12px; line-height: 1.6; color: var(--ink-mute);
  border-inline-start: 2px solid var(--accent);
  padding-inline-start: var(--s3);
  margin-bottom: var(--s5);
  text-align: start;
}
.login-err {
  min-height: 18px; margin-top: var(--s3);
  font-size: 12px; color: var(--bad); text-align: center;
}
.login-err:empty { min-height: 0; margin-top: 0; }

.login-foot {
  display: flex; justify-content: center; gap: var(--s2);
  margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid var(--seam-soft);
}

/* ==========================================================================
   The phone.

   Everything above assumes a mouse, a wide screen, and a rail you can hover.
   A phone has none of those, so below 860px the shell rearranges rather than
   shrinks: the rail and the flyout become a drawer you pull in, and a bar of
   four thumb-sized targets takes over the bottom of the screen.

   This block sits at the end of the file on purpose. The paper layer redefines
   .rail and .topbar further up, and a breakpoint that loses to the rules it is
   meant to override is not a breakpoint — it is a comment.
   ========================================================================== */

/* The bar and the drawer do not exist on a desktop, so they cost it nothing. */
.tabbar, .nav-scrim { display: none; }

@media (max-width: 860px) {
  /* ---------- the shell ---------- */
  .app, .app.nav-open {
    grid-template-columns: 1fr;
    /* The bar is fixed; this keeps the last row of every page above it,
       including on phones whose home indicator eats another 34px. */
    padding-bottom: calc(58px + env(safe-area-inset-bottom));   /* clears .tabbar */
  }

  /* ---------- the drawer: the rail and the flyout, pulled in ---------- */
  .rail {
    position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 60;
    width: 62px; height: 100dvh;
    background: var(--paper);
    border-inline-end: 1px solid var(--seam);
    padding-block: calc(var(--s4) + env(safe-area-inset-top)) calc(var(--s4) + env(safe-area-inset-bottom));
    overflow-y: auto; overscroll-behavior: contain;
    transform: translateX(-100%);
    transition: transform var(--t-mid, 0.22s) var(--ease);
  }
  html[dir="rtl"] .rail { transform: translateX(100%); }

  .flyout {
    position: fixed; inset-block: 0; inset-inline-start: 62px; z-index: 59;
    width: min(272px, calc(100vw - 62px)); height: 100dvh;
    padding-block: calc(var(--s4) + env(safe-area-inset-top)) calc(var(--s6) + env(safe-area-inset-bottom));
    overflow-y: auto; overscroll-behavior: contain;
    box-shadow: var(--shadow-pop);
    transform: translateX(-120%);
    transition: transform var(--t-mid, 0.22s) var(--ease);
  }
  html[dir="rtl"] .flyout { transform: translateX(120%); }
  /* The flyout is hidden by an attribute when no division is chosen; on a
     phone the drawer opens on the rail alone, which is a legitimate state. */
  .flyout[hidden] { display: flex; visibility: hidden; }

  .app.mnav .rail,
  .app.mnav .flyout { transform: translateX(0); }
  .app.mnav .flyout[hidden] { visibility: hidden; }

  .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 58;
    /* Always a dim, never the paper-coloured --scrim: a light veil over a light
       page reads as a rendering fault rather than as a backdrop. */
    background: rgba(20, 16, 12, 0.45);
    opacity: 0; pointer-events: none;
    transition: opacity var(--t-mid, 0.22s) var(--ease);
  }
  .app.mnav ~ .nav-scrim,
  .nav-scrim.on { opacity: 1; pointer-events: auto; }
  .nav-scrim[hidden] { display: block; }

  /* Touch has no hover, so the tooltip would only ever appear stuck. */
  .rail-tip { display: none; }
  .rail-brand { margin-bottom: var(--s3); }
  .rail-btn { width: 42px; height: 42px; }

  /* ---------- the top bar ---------- */
  .topbar {
    padding: calc(var(--s3) + env(safe-area-inset-top)) var(--s4) var(--s3);
    gap: var(--s2);
  }
  .topbar h1 {
    font-size: 15px;
    /* A long department name must not push the chips off the screen. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
  }
  /* Search moved to the bar at the bottom, where a thumb can reach it. */
  .top-search { display: none; }
  .top-right { gap: var(--s1); margin-inline-start: auto; }
  .who-chip { display: none; }             /* it is the fourth tab now */
  #poll-chip { display: none; }
  .chip { font-size: 9.5px; padding: 2px 6px; }

  /* ---------- the page ---------- */
  .view { padding: var(--s4) var(--s4) var(--s6); gap: var(--s4); }
  /* A grid item defaults to min-width:auto, which means "never shrink below
     your content". One wide table therefore stretched its panel to 865px and
     took the document with it — the scroll box inside was doing its job, but
     nothing above it was constrained enough to make it necessary. */
  .view > *, .panel, .tscroll, .form-inline > * { min-width: 0; }
  .view > * { max-width: 100%; }
  .grid, .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .panel { padding: var(--s4); }
  .form-inline { flex-direction: column; align-items: stretch; }
  .form-inline > * { min-width: 0; width: 100%; }
  .map-legend { font-size: 11px; }

  /* A table is the one thing that genuinely cannot reflow, so it scrolls
     inside its own box. The wrapper is added after each render — see
     wrapWideThings() — because the tables are written by ninety renderers
     and none of them should have to know about phones. */
  .tscroll {
    overflow-x: auto;
    margin-inline: calc(var(--s4) * -1); padding-inline: var(--s4);
  }
  .tscroll > table { min-width: max-content; }
  .tscroll > table td, .tscroll > table th { white-space: nowrap; }

  /* Same for the maps and the graphs: pan them, do not squash them. */
  .atlas-wrap, .map-wrap, .svg-scroll { overflow-x: auto; }

  /* ---------- dialogs become sheets ---------- */
  #palette { align-items: flex-start; padding: 0; }
  .pal-box {
    width: 100%; max-width: none; max-height: 100dvh; border-radius: 0;
    padding-top: env(safe-area-inset-top);
  }
  .pal-list { max-height: 60dvh; }
  #map-dialog .md-box { padding-bottom: calc(var(--s5) + env(safe-area-inset-bottom)); }

  /* ---------- the way in ---------- */
  #login { padding: var(--s4); align-items: center; }
  .login-panel { width: 100%; max-width: 400px; padding: var(--s6) var(--s5) var(--s4); }

  /* ---------- the bar ---------- */
  .tabbar {
    /* One number for the bar's height, because two things depend on it: the
       page's bottom padding and the live ticker that floats above it. When
       they were written separately they disagreed by three pixels, which is
       exactly enough for the ticker to sit on top of the bar. */
    --tabbar-h: 58px;
    height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
    display: grid; grid-template-columns: repeat(4, 1fr);
    position: fixed; inset-inline: 0; bottom: 0; z-index: 55;
    background: var(--paper);
    background: color-mix(in srgb, var(--paper) 92%, transparent);
    -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
    border-top: 1px solid var(--seam);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .tab {
    /* 44px is the smallest target a thumb hits reliably; this is 58. */
    min-height: 58px;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; position: relative;
    border: none; background: none; cursor: pointer;
    color: var(--ink-faint); text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition: color var(--t-fast) var(--ease);
  }
  .tab svg {
    width: 21px; height: 21px;
    fill: none; stroke: currentColor; stroke-width: 1.35;
    stroke-linecap: round; stroke-linejoin: round;
  }
  .tab span {
    font-family: var(--font-display); font-size: 8.5px;
    letter-spacing: var(--track-mid); text-transform: uppercase;
  }
  html[lang="ar"] .tab span { letter-spacing: 0; font-size: 10px; text-transform: none; }
  .tab:active { color: var(--ink); }
  .tab.on { color: var(--ink); }
  .tab.on::before {
    content: ""; position: absolute; top: 0; inset-inline: 26%;
    height: 2px; background: var(--accent);
  }
  .tab-dot {
    position: absolute; top: 8px; inset-inline-end: 22%;
    min-width: 15px; height: 15px; padding: 0 4px; border-radius: var(--r-pill);
    background: var(--accent); color: var(--paper);
    font: 400 9px/15px var(--font-mono); text-align: center;
  }
  .tab-dot:empty { display: none; }
}

/* A phone in landscape, and a small tablet: the drawer is unnecessary but the
   bar still is not, so only the widths change. */
@media (max-width: 860px) and (min-width: 620px) {
  .flyout { width: 300px; }
  .view { padding-inline: var(--s5); }
  .grid-2, .grid-4 { grid-template-columns: 1fr 1fr; }
}

/* Installed to a home screen there is no browser chrome to scroll away, so the
   app can own the full height and stop bouncing like a web page. */
@media (display-mode: standalone) {
  html, body { overscroll-behavior-y: none; }
}

/* Touch devices, at any width: nothing should depend on hovering. */
@media (hover: none) {
  .rail-tip { display: none; }
  /* A tap on a row must not leave it looking selected afterwards. */
  .row:hover, tr:hover { background: inherit; }
}

/* The overview's own row: a centred switch with the wiring count and the way
   to the relationship table pinned to the end of the line. It used to carry
   that positioning in an inline style, which no breakpoint can override — so
   on a phone the two halves printed on top of each other. */
.atlas-bar { justify-content: center; position: relative; }
.atlas-aside {
  position: absolute; inset-inline-end: 0;
  display: flex; gap: var(--s2); align-items: center;
}

@media (max-width: 860px) {
  /* No room for a pin: the row becomes two centred lines. */
  .atlas-bar { flex-wrap: wrap; gap: var(--s2); }
  .atlas-aside { position: static; flex-wrap: wrap; justify-content: center; }

  /* The live ticker is fixed to the bottom of the screen, which is where the
     bar now lives. It sits above it rather than under it. */
  #live-bar {
    inset-block-end: calc(58px + env(safe-area-inset-bottom) + 12px);
    max-width: calc(100vw - 24px);
  }
  /* With the drawer open the ticker is floating over a menu, which is noise. */
  .app.mnav ~ #live-bar, .app.mnav #live-bar { display: none; }
}

/* A submit that used to close a row now follows the last field instead. On a
   wide screen it should not stretch across the whole panel to say one word. */
.form-go { align-self: flex-start; margin-top: var(--s2); }
@media (max-width: 860px) { .form-go { align-self: stretch; width: 100%; } }

/* The revenue funnel: one column per stage, and there are seven of them. Each
   is flex:1, which still will not go below its own content — so on a phone the
   row keeps its proportions and scrolls rather than crushing the numbers. */
.fn-bars > div { min-width: 40px; }

@media (max-width: 860px) {
  .fn-bars { overflow-x: auto; }
  .fn-bars > div { min-width: 52px; }
  /* The marketing funnel is four wide cards, which is two rows on a phone. */
  .funnel { flex-wrap: wrap; }
  .fn-step { flex: 1 1 44%; }
  .fn-step + .fn-step { margin-inline-start: 0; }
}

/* Said only after the second refusal, when a plain 'no' has stopped being
   information and started being a wall. */
.login-hint {
  display: block; margin-top: var(--s3);
  font-size: 11px; line-height: 1.6; color: var(--ink-faint);
  text-align: start;
}
.login-hint::first-line { font-weight: inherit; }
