/* =====================================================================
   MyStratos — visual system
   Palette inherited from the MyStratos brand bible: Void Obsidian #0B1021,
   Bioluminescent Teal #00F5D4, Electric Indigo #4C008F. Data Crimson
   #D91E18 is functional only — it marks drift, risk and overdue work, and
   is never decorative. The signature device is the segment "rail": a
   glowing spine on every card and column that ties an item to its lane.
   ===================================================================== */

:root {
  /* Brand surfaces */
  --obsidian: #0B1021;
  --obsidian-2: #111A2E;
  --obsidian-3: #16203A;
  --teal: #00F5D4;
  --teal-dim: #0FBFAA;
  --indigo: #4C008F;
  --indigo-lift: #7B3FD4;
  --crimson: #D91E18;

  /* Working tokens */
  --navy: var(--obsidian);
  --navy-2: var(--obsidian-2);
  --gold: var(--teal);
  --ink: #E6EAF2;
  --ink-soft: #C3CCDD;
  --muted: #8A96AE;
  --line: #1E2A44;
  --line-soft: #17223A;
  --paper: #0B1021;
  --surface: #111A2E;
  --surface-2: #16203A;
  --white: #FFFFFF;
  --green: #00F5D4;
  --amber: #E8A33D;
  --red: var(--crimson);

  /* ---- theme surfaces -------------------------------------------------
     The light view overrides these and almost nothing else. Values here are
     exactly what the interface used before they became variables, so the
     default set is unchanged by definition rather than by inspection.

     "deep" is the dark chrome — the sidebar, the login panel — which in the
     light view becomes a light chrome tint. The toast keeps its own pair
     because a dark toast on a light page is the readable choice, and
     following the chrome would make it disappear into it. */
  --deep: var(--navy);
  --on-deep: #fff;
  --on-deep-soft: #C6D0DE;
  --on-deep-dim: #B4C0D0;
  --on-deep-faint: #7E8C9E;
  --deep-2: #0a1729;

  /* Overlays that lift a surface off its background. White on a dark theme,
     ink on a light one — which is why they cannot stay written inline. */
  --lift-1: rgba(255,255,255,.02);
  --lift-2: rgba(255,255,255,.03);
  --lift-3: rgba(255,255,255,.06);
  --lift-4: rgba(255,255,255,.09);
  --lift-5: rgba(255,255,255,.14);
  --lift-6: rgba(255,255,255,.22);
  --nav-edge: rgba(255,255,255,.10);
  --nav-edge-hover: rgba(255,255,255,.22);

  --overlay: rgba(14,32,56,.44);
  --scrim: rgba(11,16,33,.86);
  --input-bg: rgba(0,0,0,.25);
  --column-bg: #EDF0F4;
  --accent-2: #17d8ff;
  --on-accent: #04121F;
  --toast-bg: var(--navy);
  --toast-ink: #fff;
  --btn-primary-bg: var(--navy);
  --btn-primary-ink: #fff;
  --focus-ring: rgba(46,107,138,.12);
  --tint: rgba(46,107,138,.07);
  --tint-2: rgba(46,107,138,.09);
  --tint-line: rgba(46,107,138,.4);
  --danger-ink: #FFB4B1;
  --danger-ink-2: #FF8A85;
  --prop-ink: #C9A9FF;
  --flash: #F5C518;

  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow-md: 0 6px 18px rgba(0,0,0,.45);
  --shadow-lg: 0 24px 60px rgba(0,0,0,.6);
  --glow: 0 0 0 1px rgba(0,245,212,.25), 0 0 22px rgba(0,245,212,.18);
  --radius: 10px;
  --radius-sm: 7px;
  --sidebar: 400px;   /* wide enough that no rail label wraps (ruled 2026-08-29) */
  --font-display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}
.app-loading {
  height: 100vh; display: grid; place-items: center;
  color: var(--muted); font-size: 15px;
}
button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; font-size: 14px; }
a { color: var(--teal); }

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  padding: 8px 14px; border-radius: var(--radius-sm); font-weight: 500; font-size: 13.5px;
  transition: background .12s, border-color .12s, transform .05s;
}
.btn:hover { background: var(--line-soft); }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--btn-primary-bg); border-color: var(--btn-primary-bg); color: var(--btn-primary-ink); }
.btn-primary:hover { background: var(--navy-2); }
.btn-gold { background: var(--gold); border-color: var(--gold); color: var(--navy); font-weight: 600; }
.btn-gold:hover { filter: brightness(1.04); }
.btn-ghost { border-color: transparent; background: transparent; color: var(--muted); }
.btn-ghost:hover { background: var(--line-soft); color: var(--ink); }
.btn-sm { padding: 5px 10px; font-size: 12.5px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---------------------------------------------------------------- login */
.login-wrap { min-height: 100vh; display: grid; grid-template-columns: 1.1fr 1fr; }
.login-brand {
  background: linear-gradient(155deg, var(--deep) 0%, var(--deep-2) 100%);
  color: var(--on-deep); padding: 64px; display: flex; flex-direction: column; justify-content: center;
}
.login-brand .mark {
  font-family: var(--font-display); font-size: 44px; font-weight: 600; letter-spacing: -.5px;
  margin: 0 0 6px;
}
.login-brand .mark b { color: var(--gold); font-weight: 600; }
.login-brand .tag { color: var(--on-deep-soft); font-size: 16px; max-width: 30ch; line-height: 1.5; }
.login-brand .tag-more { font-size: 13.5px; max-width: 44ch; opacity: .8; margin-top: 14px; }
.login-brand .rails { display: flex; gap: 8px; margin-top: 40px; }
.login-brand .rail { height: 5px; flex: 1; border-radius: 3px; opacity: .85; }
.login-form { display: grid; place-items: center; padding: 40px; }
.login-card { width: 100%; max-width: 340px; }
.login-card h2 { font-family: var(--font-display); font-weight: 600; font-size: 24px; margin: 0 0 4px; color: var(--navy); }
.login-card p.sub { color: var(--muted); margin: 0 0 24px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12.5px; font-weight: 600; color: var(--muted); margin-bottom: 5px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); outline: none;
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--teal); box-shadow: 0 0 0 3px var(--focus-ring); }
.form-error { color: var(--red); font-size: 13px; margin: 4px 0 12px; }

/* ---------------------------------------------------------------- app chrome */
.shell { display: grid; grid-template-columns: var(--sidebar) 1fr; height: 100vh; }
.sidebar {
  background: var(--deep); color: var(--on-deep-soft); display: flex; flex-direction: column;
  padding: 18px 12px; gap: 4px;
}
.sidebar .brand {
  font-family: var(--font-display); font-size: 22px; font-weight: 600; color: var(--on-deep);
  padding: 4px 10px 16px; letter-spacing: -.3px;
}
.sidebar .brand b { color: var(--gold); }
.nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 9px 11px; font-size: 14px; font-weight: 500;
  color: var(--on-deep-dim); border-radius: var(--radius-sm);
  /* A real edge, in both palettes. These are controls, and a control that
     looks like a link until you hover it reads as decoration. The border is
     the chrome's own line rather than the accent, so fourteen of them stacked
     up stay quiet — the accent is reserved for the one that is active. */
  background: var(--lift-1);
  border: 1px solid var(--nav-edge);
  transition: background .12s, border-color .12s, color .12s;
}
.nav-item:hover { background: var(--lift-3); border-color: var(--nav-edge-hover); color: var(--on-deep); }
.nav-item.active { border-color: transparent; }

/* Shut, not hidden. The dot is the only ornament — a padlock glyph at this
   size reads as an error state rather than an invitation. */
.nav-item.locked { color: var(--on-deep-dim); }
.nav-item.locked .lock { margin-left: auto; font-size: 8px; color: var(--gold); opacity: .85; }
.nav-item.locked:hover { border-color: var(--gold); color: var(--on-deep); }

/* Frozen: available to look at, not to change. Deliberately duller than
   locked, because there is nothing to buy here. */
.nav-item.frozen { opacity: .55; }
.nav-item.frozen .lock { margin-left: auto; font-size: 11px; color: var(--on-deep-faint); }
.nav-item.frozen:hover { opacity: .8; background: var(--lift-2); }
.nav-item.active { background: var(--teal); color: var(--white); }
.nav-item .count {
  margin-left: auto; font-family: var(--font-mono); font-size: 11px;
  background: var(--lift-5); padding: 1px 7px; border-radius: 10px;
}
.nav-item.active .count { background: var(--lift-6); }
.nav-sep { height: 1px; background: var(--lift-4); margin: 10px 6px; }
.sidebar .foot { margin-top: auto; padding: 8px 10px; font-size: 12px; color: var(--on-deep-faint); }
.sidebar .foot .who { color: var(--on-deep-soft); font-weight: 500; }
.tenant-switch {
  margin: 2px 4px 12px; padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--lift-3); border: 1px solid var(--lift-4); color: var(--on-deep);
  font-size: 13px; width: calc(100% - 8px);
}

.main { overflow: hidden; display: flex; flex-direction: column; background: var(--paper); }
.topbar {
  display: flex; align-items: center; gap: 12px; padding: 14px 24px;
  border-bottom: 1px solid var(--line); background: var(--surface);
}
.topbar h1 { font-family: var(--font-display); font-weight: 600; font-size: 20px; margin: 0; color: var(--navy); }
.topbar .spacer { flex: 1; }
.topbar .search {
  padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  width: 240px; background: var(--paper);
}
.content { flex: 1; overflow: auto; padding: 22px 24px; }
.content.board-scroll { overflow: hidden; padding: 0; }

/* ---------------------------------------------------------------- filters bar */
.filterbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 12px 24px; border-bottom: 1px solid var(--line); background: var(--surface); }
.chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 20px;
  border: 1px solid var(--line); background: var(--surface); font-size: 12.5px; color: var(--muted); font-weight: 500;
}
.chip.active { border-color: var(--teal); color: var(--teal); background: var(--tint); }
.seg-select { padding: 7px 11px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }

/* ---------------------------------------------------------------- board */
.board { display: flex; gap: 0; height: 100%; overflow-x: auto; overflow-y: hidden; padding: 0; }
.board-segment {
  display: flex; flex-direction: column; min-width: 0; border-right: 1px solid var(--line);
  background: var(--paper);
}
.board-segment-head {
  display: flex; align-items: center; gap: 9px; padding: 13px 16px 11px;
  border-bottom: 1px solid var(--line); background: var(--surface); position: sticky; top: 0; z-index: 2;
}
.board-segment-head .dot { width: 11px; height: 11px; border-radius: 3px; flex: none; }
.board-segment-head .name { font-family: var(--font-display); font-weight: 600; font-size: 15px; color: var(--navy); }
.board-segment-head .n { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.board-columns { display: flex; gap: 12px; padding: 14px; overflow-x: auto; height: 100%; align-items: flex-start; }
.column {
  width: 268px; min-width: 268px; background: var(--column-bg); border-radius: var(--radius);
  display: flex; flex-direction: column; max-height: 100%;
}
.column-head {
  display: flex; align-items: center; gap: 8px; padding: 10px 12px 8px; font-weight: 600; font-size: 12.5px;
  text-transform: uppercase; letter-spacing: .5px; color: var(--navy);
}
.column-head .cnt { font-family: var(--font-mono); font-size: 11px; color: var(--muted); font-weight: 500; }
.column-head .wip { margin-left: auto; font-size: 10.5px; color: var(--amber); }
.column-head.over .wip { color: var(--red); font-weight: 700; }
.column-body { padding: 0 8px 10px; overflow-y: auto; flex: 1; min-height: 24px; }
.column-body.drag-over { background: var(--tint-2); border-radius: 8px; outline: 2px dashed var(--tint-line); outline-offset: -4px; }
.column-add { padding: 6px 8px 10px; }
.column-add button { width: 100%; justify-content: center; color: var(--muted); border-style: dashed; background: transparent; }

.card {
  background: var(--surface); border-radius: var(--radius-sm); box-shadow: var(--shadow-sm);
  padding: 10px 12px 10px 14px; margin-bottom: 8px; position: relative; cursor: grab;
  border: 1px solid transparent; transition: box-shadow .12s, border-color .12s;
}
.card:hover { box-shadow: var(--shadow-md); border-color: var(--line); }
.card.dragging { opacity: .4; }
.card::before { content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 4px; border-radius: 3px; background: var(--rail, var(--teal)); }
.card .title { font-size: 13.5px; line-height: 1.4; color: var(--ink); margin-bottom: 7px; }
.card .meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.card .ref { font-family: var(--font-mono); font-size: 10.5px; color: var(--muted); }
.badge { font-size: 10px; padding: 1px 7px; border-radius: 10px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; }
.badge.kind { background: var(--line-soft); color: var(--teal); }
.badge.rel { background: rgba(230,180,80,.18); color: #8a6a1f; }
.badge.p0 { background: rgba(159,18,57,.12); color: var(--red); }
.badge.p1 { background: rgba(180,83,9,.12); color: var(--amber); }
.card .owner { font-size: 11px; color: var(--muted); margin-left: auto; }
.card .blocked { color: var(--red); font-size: 10.5px; font-weight: 600; display: inline-flex; align-items: center; gap: 3px; }
.card .dots { position: absolute; top: 8px; right: 8px; opacity: 0; color: var(--muted); background: none; border: 0; padding: 2px 5px; border-radius: 5px; font-size: 15px; line-height: 1; }
.card:hover .dots { opacity: 1; }
.card .dots:hover { background: var(--line-soft); }

/* ---------------------------------------------------------------- inbox */
.inbox-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.inbox-head .lead { font-family: var(--font-display); font-size: 19px; color: var(--navy); font-weight: 600; }
.inbox-list { display: flex; flex-direction: column; gap: 9px; max-width: 940px; }
.inbox-row {
  display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: start;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 13px 15px; box-shadow: var(--shadow-sm);
}
.inbox-row .src { font-size: 11px; color: var(--muted); margin-bottom: 3px; display: flex; gap: 8px; align-items: center; }
.inbox-row .src .path { font-style: italic; }
.inbox-row .ttl { font-size: 14.5px; color: var(--ink); font-weight: 500; line-height: 1.4; }
.inbox-row .body { font-size: 12.5px; color: var(--muted); margin-top: 4px; line-height: 1.5; max-width: 68ch; }
.inbox-actions { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; min-width: 210px; }
.suggest {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--muted);
}
.suggest .seg { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; }
.suggest .seg .dot { width: 9px; height: 9px; border-radius: 3px; }
.conf { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.seg-picker { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }
.seg-btn {
  padding: 4px 9px; border-radius: 14px; border: 1px solid var(--line); background: var(--surface);
  font-size: 11.5px; font-weight: 600; color: var(--muted);
}
.seg-btn.on { color: var(--white); border-color: transparent; }

/* ---------------------------------------------------------------- roadmap */
.roadmap { display: flex; flex-direction: column; gap: 2px; }
.rm-lane { display: grid; grid-template-columns: 150px 1fr; border-bottom: 1px solid var(--line); }
.rm-lane-label { padding: 12px; font-weight: 600; color: var(--navy); display: flex; align-items: center; gap: 8px; }
.rm-lane-label .dot { width: 10px; height: 10px; border-radius: 3px; }
.rm-track { position: relative; padding: 10px 0; min-height: 54px; }
.rm-bar {
  position: absolute; height: 26px; border-radius: 6px; display: flex; align-items: center;
  padding: 0 8px; font-size: 11px; color: #fff; white-space: nowrap; overflow: hidden;
  box-shadow: var(--shadow-sm); cursor: pointer;
}
.rm-bar .rf { font-family: var(--font-mono); opacity: .82; margin-right: 6px; font-size: 10px; }
.rm-axis { display: grid; grid-template-columns: 150px 1fr; border-bottom: 2px solid var(--line); }
.rm-axis .ticks { display: flex; }
.rm-axis .tick { flex: 1; font-size: 11px; color: var(--muted); padding: 6px 8px; border-left: 1px solid var(--line-soft); }
.rm-links-note { font-size: 12px; color: var(--muted); margin: 10px 0; display: flex; align-items: center; gap: 8px; }

/* ---------------------------------------------------------------- flow */
.flow-seg { margin-bottom: 26px; }
.flow-seg h3 { font-family: var(--font-display); font-weight: 600; color: var(--navy); font-size: 16px; margin: 0 0 10px; display: flex; align-items: center; gap: 8px; }
.flow-seg h3 .dot { width: 11px; height: 11px; border-radius: 3px; }
.flow-row { display: flex; align-items: stretch; gap: 0; overflow-x: auto; }
.flow-node {
  min-width: 132px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px; text-align: center; cursor: pointer; transition: box-shadow .12s;
}
.flow-node:hover { box-shadow: var(--shadow-md); }
.flow-node .n { font-family: var(--font-mono); font-size: 22px; color: var(--navy); font-weight: 500; }
.flow-node .lbl { font-size: 11.5px; color: var(--muted); margin-top: 3px; text-transform: uppercase; letter-spacing: .4px; }
.flow-node .warn { font-size: 10.5px; color: var(--red); margin-top: 4px; }
.flow-arrow { display: flex; align-items: center; color: var(--line); padding: 0 4px; font-size: 20px; }

/* ---------------------------------------------------------------- grid */
.grid-table { width: 100%; border-collapse: collapse; background: var(--surface); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm); }
.grid-table th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); padding: 10px 12px; border-bottom: 1px solid var(--line); background: var(--paper); position: sticky; top: 0; }
.grid-table td { padding: 9px 12px; border-bottom: 1px solid var(--line-soft); font-size: 13px; vertical-align: top; }
.grid-table tr:hover td { background: var(--paper); cursor: pointer; }
.grid-table .ref { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); white-space: nowrap; }

/* ---------------------------------------------------------------- documents */
.doc-drop {
  border: 2px dashed var(--line); border-radius: var(--radius); padding: 34px; text-align: center;
  color: var(--muted); background: var(--surface); max-width: 640px; transition: border-color .12s, background .12s;
}
.doc-drop.over { border-color: var(--teal); background: var(--tint); }
.doc-drop .big { font-family: var(--font-display); font-size: 18px; color: var(--navy); margin-bottom: 6px; }
.doc-list { margin-top: 22px; display: flex; flex-direction: column; gap: 10px; max-width: 720px; }
.doc-row { display: flex; align-items: center; gap: 12px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 15px; }
.doc-row .nm { font-weight: 600; color: var(--ink); }
.doc-row .st { font-size: 11px; color: var(--muted); font-family: var(--font-mono); }
.chunk { display: grid; grid-template-columns: 24px 1fr; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line-soft); }
.chunk .path { font-size: 11px; color: var(--teal); font-style: italic; margin-bottom: 2px; }
.chunk .tx { font-size: 13px; color: var(--ink); }

/* ---------------------------------------------------------------- KPI strip */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 20px; }
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.kpi .v { font-family: var(--font-display); font-size: 27px; color: var(--navy); font-weight: 600; }
.kpi .k { font-size: 12px; color: var(--muted); margin-top: 2px; }
.kpi .spark { display: flex; gap: 3px; margin-top: 8px; }
.kpi .spark i { height: 5px; border-radius: 2px; flex: 1; }

/* ---------------------------------------------------------------- modal */
.modal-back { position: fixed; inset: 0; background: var(--overlay); display: grid; place-items: center; z-index: 50; padding: 20px; }
.modal {
  background: var(--surface); border-radius: 14px;
  /* A visible edge in BOTH themes: the drop shadow reads the depth, the
     1px keyline reads the boundary even where the shadow fades out. */
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg), 0 0 0 1px rgba(0,0,0,.06);
  width: 100%; max-width: 620px; max-height: 90vh; overflow: auto;
}
.modal.wide { max-width: 860px; }
.modal-head { display: flex; align-items: center; gap: 10px; padding: 18px 22px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--surface); }
.modal-head h3 { font-family: var(--font-display); font-weight: 600; font-size: 18px; color: var(--navy); margin: 0; }
.modal-head .ref { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }
.modal-head .x { margin-left: auto; border: 0; background: none; font-size: 22px; color: var(--muted); line-height: 1; padding: 2px 6px; border-radius: 6px; }
.modal-head .x:hover { background: var(--line-soft); }
.modal-body { padding: 20px 22px; }
.modal-foot { padding: 14px 22px; border-top: 1px solid var(--line); display: flex; gap: 9px; justify-content: flex-end; position: sticky; bottom: 0; background: var(--surface); }
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.hist { font-size: 12.5px; }
.hist .h { display: flex; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.hist .h .by { font-weight: 600; }
.hist .h .by.MODEL { color: var(--teal); }
.hist .h .by.HUMAN { color: var(--navy); }

/* context menu */
.ctxmenu { position: fixed; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); z-index: 60; min-width: 190px; padding: 5px; }
.ctxmenu button { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 8px 11px; border-radius: 6px; font-size: 13px; color: var(--ink); }
.ctxmenu button:hover { background: var(--line-soft); }
.ctxmenu .sep { height: 1px; background: var(--line-soft); margin: 4px 6px; }
.ctxmenu .head { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); padding: 6px 11px 3px; }
/* The card menu: wide enough for lane and time to sit side by side. */
.ctxmenu.wide { min-width: 380px; max-width: 460px; }
.ctxmenu .ctx-cols { display: flex; gap: 6px; align-items: flex-start; }
.ctxmenu .ctx-col { flex: 1 1 0; min-width: 0; }
.ctxmenu .ctx-col button { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The sidebar's two families of buttons, each on its own shaded ground —
   the split between what the AI does and where a person works, readable
   before a single label is. */
.nav-group {
  margin: 4px 10px 12px; padding: 6px;
  background: var(--lift-3);
  border: 1px solid var(--nav-edge);
  border-radius: 12px;
  box-shadow: inset 0 1px 0 var(--lift-6), var(--shadow-sm);
}
.nav-group-title {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 1.6px; color: var(--on-deep-faint);
  padding: 4px 10px 6px;
}

/* Background saves in flight: the arrow keeps its hourglass until the queue
   drains — visible work, never a blocked pointer. */
body.bg-saving, body.bg-saving * { cursor: progress; }

/* Long labels — translations above all — wrap to the button's width for up
   to two lines, then truncate with an ellipsis. The full wording is always
   in the tooltip. */
.nav-item .nav-label {
  flex: 1 1 auto; min-width: 0; overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  line-clamp: 2; white-space: normal; word-break: break-word;
  text-overflow: ellipsis; line-height: 1.25; text-align: left;
}
/* Every ordinary button survives a long translation: wrap within its own
   width instead of pushing the layout, never overflow it. */
.btn { max-width: 100%; white-space: normal; overflow-wrap: break-word; }

/* The language toggle wears the translation state in its corner. */
.lang-toggle { position: relative; }
.lang-state { position: absolute; top: -7px; right: -7px; font-size: 10px; line-height: 1; }
.lang-state.done { color: var(--green); }

/* Translations being made: the pointer says so without ever blocking. */
body.i18n-working, body.i18n-working * { cursor: progress; }

/* The pointer's sidecar: what the hourglass is doing, in one word. */
#cursor-note {
  position: fixed; z-index: 90; pointer-events: none; display: none;
  padding: 2px 8px; border-radius: 6px; font-size: 11px;
  background: var(--toast-bg); color: var(--toast-ink);
  box-shadow: var(--shadow-sm); white-space: nowrap;
}

/* Accept/Reject on a review row: exactly the width of their word — a
   verdict, not a billboard. */
.inbox-verdict { display: flex; flex-direction: column; gap: 4px; margin-right: 10px; flex: 0 0 auto; align-self: center; }
.inbox-verdict .btn { padding: 4px 10px; font-size: 12px; white-space: nowrap; width: auto; }

/* toast */
.toasts { position: fixed; bottom: 22px; right: 22px; display: flex; flex-direction: column; gap: 8px; z-index: 70; }
.toast { background: var(--toast-bg); color: var(--toast-ink); padding: 11px 16px; border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); font-size: 13.5px; max-width: 340px; }
.toast.err { background: var(--red); }
.toast.ok { background: var(--green); }
/* A run that finished but left work undone: not an error, not a success. */
.toast.warn { background: var(--amber); }

.empty { text-align: center; color: var(--muted); padding: 60px 20px; }
.empty .big { font-family: var(--font-display); font-size: 19px; color: var(--navy); margin-bottom: 6px; }
.spin { display: inline-block; width: 15px; height: 15px; border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; border-radius: 50%; animation: sp .7s linear infinite; }
@keyframes sp { to { transform: rotate(360deg); } }
.muted { color: var(--muted); }
.mono { font-family: var(--font-mono); }

@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

@media (max-width: 820px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar { position: fixed; left: 0; top: 0; bottom: 0; width: 220px; z-index: 40; transform: translateX(-100%); transition: transform .2s; }
  .sidebar.open { transform: none; }
  .login-wrap { grid-template-columns: 1fr; }
  .login-brand { display: none; }
  .rm-lane, .rm-axis { grid-template-columns: 96px 1fr; }
  .row2 { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------- settings */
.seg-card{margin-bottom:20px;max-width:900px;background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:16px 18px}
.seg-head{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.seg-dot{width:12px;height:12px;border-radius:3px;flex:none}
.seg-title{font-family:var(--font-display);font-size:16px;font-weight:600;color:var(--navy)}
.seg-desc{margin:0 0 12px}
.seg-desc-text{font-size:12.5px;line-height:1.5;display:block}
.color-dot{width:26px;height:26px;padding:0;border:1px solid var(--line);border-radius:6px;background:none;cursor:pointer}
.stage-editor{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.stage-chip{display:inline-flex;align-items:center;gap:6px;cursor:grab;user-select:none}
.stage-chip.dragging{opacity:.4}
.stage-chip.drop-target{outline:2px solid var(--gold);outline-offset:2px}
.grip{color:var(--muted);font-size:11px;letter-spacing:-1px}
.chip-x{border:none;background:none;color:var(--muted);cursor:pointer;font-size:15px;line-height:1;padding:0 2px}
.chip-x:hover{color:var(--danger)}
.editable{cursor:text;border-radius:4px;padding:1px 4px;margin:-1px -4px}
.editable:hover{background:rgba(230,180,80,.16)}
.editable.editing{background:var(--surface);outline:2px solid var(--gold);cursor:text}
.btn-quiet{background:none;border:1px solid var(--line);color:var(--muted)}


/* ---------------------------------------------------------------- dark surfaces */
body { background: var(--obsidian); color: var(--ink); }
input, select, textarea {
  background: var(--obsidian) !important;
  color: var(--ink) !important;
  border: 1px solid var(--line) !important;
}
input:focus, select:focus, textarea:focus {
  outline: none !important;
  border-color: var(--teal) !important;
  box-shadow: var(--glow) !important;
}
input::placeholder, textarea::placeholder { color: var(--muted); }
option { background: var(--obsidian); color: var(--ink); }
.grid-table th { color: var(--muted); border-bottom-color: var(--line); background: var(--obsidian-2); }
.grid-table td { border-bottom-color: var(--line-soft); color: var(--ink-soft); }
.grid-table tr:hover td { background: var(--obsidian-3); }
.chip { background: var(--obsidian-3); border: 1px solid var(--line); color: var(--ink-soft); }
.muted { color: var(--muted); }
.btn {
  background: var(--obsidian-3);
  border: 1px solid var(--line);
  color: var(--ink);
}
/* Hover must LIGHTEN on a dark theme. The base rule earlier in this file sets
   `background: var(--line-soft)` on hover, which was written for a light
   surface; here it is darker than the button itself, so pointing at a button
   made it look disabled or vanish. Overriding the background — not only the
   border — is what actually fixes it. */
.btn:hover {
  border-color: var(--teal-dim);
  background: var(--surface-2);
  color: var(--ink);
}
.btn:active { background: var(--obsidian-2); }
.btn-primary, .btn-gold {
  background: linear-gradient(135deg, var(--teal) 0%, var(--accent-2) 100%);
  color: var(--on-accent);
  border: none;
  font-weight: 600;
}
/* Brightness only: the gradient and the dark ink on it stay exactly as they
   are, so the button cannot turn into a dark rectangle mid-click. */
.btn-primary:hover, .btn-gold:hover {
  filter: brightness(1.08);
  background: linear-gradient(135deg, var(--teal) 0%, var(--accent-2) 100%);
  color: var(--on-accent);
}
.btn-primary:active, .btn-gold:active { filter: brightness(0.96); }
.btn-danger:hover { background: rgba(217,30,24,.12); color: var(--crimson); }
.btn-quiet:hover { background: var(--surface-2); color: var(--ink-soft); }
.link-btn:hover { color: var(--teal); background: none; }

/* Disabled must not read as hoverable. */
.btn:disabled, .btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn:disabled:hover, .btn[disabled]:hover { background: var(--obsidian-3); border-color: var(--line); }
.btn-danger { background: transparent; border: 1px solid var(--crimson); color: var(--crimson); }
.seg-card, .login-card, .modal, .card, .col, .panel { background: var(--surface); border-color: var(--line); }

/* EVERY heading coloured `--navy`, not just the login one.
   That token meant "the darkest ink available" on the light palette this
   design started from, and it now aliases to obsidian — so on the dark
   surface each of these renders black on near-black. The text was always
   there; it just could not be seen. Fixing them one at a time as they are
   reported would take a dozen rounds, so they are all listed here. */
.login-card h2,
.topbar h1,
.board-segment-head .name,
.column-head,
.inbox-head .lead,
.rm-lane-label,
.flow-seg h3,
.flow-node .n,
.doc-drop .big,
.kpi .v,
.modal-head h3,
.hist .h .by.HUMAN,
.empty .big,
/* The About window: small-medium, centered, text-centered. Vanishes on any
   key or click, so it carries no buttons and must never hold a form. */
.about-modal { max-width: 420px; width: min(420px, 92vw); text-align: center; padding: 30px 28px; }

.modal h2, .modal h3, .panel h2, .seg-card h2 {
  color: var(--ink);
}
.login-card p.sub, .login-card .code-hint { color: var(--muted); }
.editable:hover { background: rgba(0,245,212,.12); }
.editable.editing { background: var(--obsidian); outline-color: var(--teal); }
.color-dot { background: var(--obsidian); }

/* ---------------------------------------------------------------- brand mark */
.brandmark { display: flex; align-items: center; gap: 10px; }
.brandmark img { width: 30px; height: 30px; border-radius: 7px; }
.brandmark .name { font-family: var(--font-display); font-weight: 600; letter-spacing: -.2px; color: var(--ink); font-size: 17px; }
.brandmark .name b { color: var(--teal); font-weight: 600; }
.login-logo { width: 96px; height: 96px; border-radius: 22px; box-shadow: var(--glow); margin-bottom: 22px; }

/* ---------------------------------------------------------------- code step */
.code-input {
  width: 100%;
  font-family: var(--font-mono);
  font-size: 30px;
  letter-spacing: 14px;
  text-align: center;
  padding: 16px 10px !important;
  color: var(--teal) !important;
}
.code-hint { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin: 0 0 16px; }
.code-hint b { color: var(--ink); font-weight: 600; }
.dev-code {
  margin-top: 14px; padding: 10px 12px; border: 1px dashed var(--amber);
  border-radius: 8px; color: var(--amber); font-size: 12px; line-height: 1.5;
}
.link-btn { background: none; border: none; color: var(--teal); cursor: pointer; font-size: 12.5px; padding: 0; }
.link-btn:hover { text-decoration: underline; }
.paused-banner {
  background: rgba(217,30,24,.12); border: 1px solid var(--crimson); color: var(--danger-ink);
  padding: 9px 14px; border-radius: 8px; font-size: 12.5px; margin: 0 0 14px;
}
.admin-h{font-family:var(--font-display);font-size:15px;font-weight:600;color:var(--ink);margin:0 0 4px}
.chip-row{display:flex;gap:7px;flex-wrap:wrap;margin-top:6px}
.form-notice{background:rgba(0,245,212,.10);border:1px solid rgba(0,245,212,.35);color:var(--teal);
  padding:9px 12px;border-radius:8px;font-size:12.5px;margin-bottom:14px;line-height:1.5}

/* =====================================================================
   The plan grid, and everything that goes with proposals.

   The grid is the product's one distinctive screen: lanes down the side,
   timeline groups across the top. A proposal is drawn with a dashed outline and
   a confidence badge so it never reads as a settled fact — the visual weight of
   an unconfirmed item has to be lower than a confirmed one, or the user will
   trust the model's guesses by default, which is the failure mode this whole
   design exists to avoid.
   ===================================================================== */

.content.plan-scroll { overflow: auto; padding: 0; }
.plan {
  display: grid;
  align-items: stretch;
  min-width: max-content;
}
.plan-corner, .plan-head, .plan-lane {
  position: sticky; z-index: 3;
  background: var(--obsidian-2);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 8px;
  padding: 11px 13px;
  font-size: 12.5px;
}
.plan-corner { top: 0; left: 0; z-index: 5; border-right: 1px solid var(--line); }
.plan-head   { top: 0; font-family: var(--font-display); font-weight: 600; color: var(--ink); }
.plan-head .nm { line-height: 1.25; }
.plan-lane {
  left: 0; z-index: 4;
  border-right: 1px solid var(--line);
  font-family: var(--font-display); font-weight: 600; color: var(--ink);
  align-items: flex-start;
}
.plan-lane .nm { line-height: 1.3; }
.plan-lane .dot, .plan-head .dot { width: 10px; height: 10px; border-radius: 3px; flex: none; margin-top: 3px; }
.plan-lane .lock { font-size: 10px; opacity: .55; margin-left: auto; }

.plan-cell {
  position: relative;
  border-right: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  padding: 8px 8px 26px;
  min-height: 86px;
  background: var(--paper);
}
.plan-cell.drag-over { background: rgba(0,245,212,.07); outline: 2px dashed rgba(0,245,212,.45); outline-offset: -3px; }
.plan-add {
  position: absolute; left: 8px; bottom: 5px;
  border: 1px dashed var(--line); background: transparent; color: var(--muted);
  border-radius: 6px; width: 22px; height: 18px; line-height: 1; font-size: 13px; opacity: 0;
  transition: opacity .12s;
}
.plan-cell:hover .plan-add { opacity: 1; }
.plan-add:hover { border-color: var(--teal); color: var(--teal); }

.pcard {
  position: relative;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-sm);
  padding: 8px 10px 8px 13px; margin-bottom: 7px; cursor: grab;
  transition: box-shadow .12s, border-color .12s, opacity .12s;
}
.pcard::before {
  content: ""; position: absolute; left: 0; top: 7px; bottom: 7px; width: 3px;
  border-radius: 3px; background: var(--rail, var(--teal));
}
.pcard:hover { box-shadow: var(--shadow-md); border-color: var(--teal-dim); }
.pcard.dragging { opacity: .35; }
.pcard .ttl { font-size: 12.5px; line-height: 1.35; color: var(--ink); margin-bottom: 5px; }
.pcard .meta { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pcard .ref { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); }
.pcard .owner { font-size: 10.5px; color: var(--muted); }

/* A proposal is visibly provisional: dashed, dimmer, and it says how sure it is. */
.pcard.proposed { border-style: dashed; border-color: var(--indigo-lift); background: rgba(76,0,143,.10); }
.pcard.proposed .ttl { color: var(--ink-soft); }
.pcard.rejected { opacity: .45; border-color: var(--line); }
.pcard.rejected .ttl { text-decoration: line-through; }

.pcard-actions { position: absolute; top: 5px; right: 5px; display: flex; gap: 3px; opacity: 0; transition: opacity .12s; }
.pcard:hover .pcard-actions { opacity: 1; }
.pcard-actions button {
  border: none; border-radius: 5px; width: 20px; height: 20px; line-height: 1;
  font-size: 11px; cursor: pointer;
}
.pcard-actions .yes { background: var(--teal); color: var(--on-accent); }
.pcard-actions .no { background: rgba(217,30,24,.18); color: var(--crimson); }
.pcard-actions .no:hover { background: var(--crimson); color: var(--white); }

.badge.conf { font-family: var(--font-mono); letter-spacing: 0; }
.badge.conf.high { background: rgba(0,245,212,.16); color: var(--teal); }
.badge.conf.mid  { background: rgba(232,163,61,.16); color: var(--amber); }
.badge.conf.low  { background: rgba(217,30,24,.16); color: var(--danger-ink-2); }
.badge.prop { background: rgba(123,63,212,.20); color: var(--prop-ink); }
.badge.rej  { background: rgba(217,30,24,.14); color: var(--danger-ink-2); }
.badge.done { background: rgba(0,245,212,.12); color: var(--teal-dim); }

.card.proposed { border-style: dashed; border-color: var(--indigo-lift); }
.card.rejected { opacity: .45; }
.card.rejected .title { text-decoration: line-through; }

.pill { font-size: 10px; padding: 1px 7px; border-radius: 10px; font-weight: 600; letter-spacing: .3px; }
.pill.proposed { background: rgba(123,63,212,.22); color: var(--prop-ink); }

.prop-banner {
  background: rgba(76,0,143,.16); border: 1px dashed var(--indigo-lift); color: var(--ink-soft);
  padding: 11px 14px; border-radius: 8px; font-size: 12.5px; line-height: 1.55; margin-bottom: 16px;
}

.swatch { display: inline-block; width: 9px; height: 9px; border-radius: 2px; flex: none; }
.lock { font-size: 10px; opacity: .6; }
.sub-h { font-size: 12px; font-weight: 600; color: var(--muted); margin: 16px 0 6px; }
.warnline { font-size: 11px; color: var(--amber); margin-top: 3px; line-height: 1.45; }

/* ---------------------------------------------------------------- undo / redo */
.history-controls { display: inline-flex; gap: 5px; }
.history-controls .btn { font-family: var(--font-mono); font-size: 12px; }
.toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--muted); white-space: nowrap;
}
.toggle input { width: auto !important; }

.hist-list { display: flex; flex-direction: column; gap: 1px; margin-top: 14px; }
.hist-row {
  display: grid; grid-template-columns: 96px 1fr auto; gap: 12px; align-items: center;
  padding: 9px 12px; background: var(--surface); border: 1px solid var(--line-soft);
}
.hist-row:first-child { border-radius: 8px 8px 0 0; }
.hist-row:last-child { border-radius: 0 0 8px 8px; }
.hist-row.undone { opacity: .5; }
.hist-row.undone .what > div:first-child { text-decoration: line-through; }
.hist-row .when { font-size: 11px; white-space: nowrap; }
.hist-row .what { font-size: 13px; min-width: 0; }

.toast.with-action { display: flex; align-items: center; gap: 14px; }
.toast-undo {
  border: 1px solid rgba(4,18,31,.35); background: rgba(4,18,31,.14); color: inherit;
  border-radius: 6px; padding: 3px 9px; font-size: 12px; font-weight: 600; cursor: pointer;
}
.toast-undo:hover { background: rgba(4,18,31,.26); }

/* ---------------------------------------------------------------- lanes & groups */
.lane-block { padding: 14px 0; border-top: 1px solid var(--line-soft); }
.lane-block:first-of-type { border-top: none; }
.group-list { display: flex; flex-direction: column; gap: 9px; }
.group-chip {
  background: var(--obsidian-3); border: 1px solid var(--line); border-radius: 9px;
  padding: 10px 12px; cursor: grab;
}
.group-chip.dragging { opacity: .4; }
.group-chip.drop-target { outline: 2px solid var(--teal); outline-offset: 2px; }
.gc-head { display: flex; align-items: center; gap: 9px; }
.gc-name { font-family: var(--font-display); font-weight: 600; font-size: 14px; color: var(--ink); }
.gc-desc { margin-top: 5px; }
.gc-desc-text { font-size: 12px; line-height: 1.5; display: block; color: var(--ink-soft); }
.seg-toggle { display: inline-flex; gap: 5px; }

/* ---------------------------------------------------------------- capture */
.doc-drop { max-width: 720px; margin: 0 auto; }
.doc-row .ic { font-size: 18px; width: 24px; text-align: center; flex: none; }
.doc-list { max-width: 820px; margin-left: auto; margin-right: auto; }
.chunks { max-height: 46vh; overflow: auto; margin-top: 6px; }
.chunk-toolbar {
  display: flex; align-items: center; gap: 14px; padding: 8px 0;
  border-bottom: 1px solid var(--line); font-size: 12px; color: var(--muted);
}
/* What the document is about. Sits above the candidates because it changes how
   they should be read, and an answer given afterwards is an answer given too
   late. Amber when the proposal is uncertain: the person is being asked, not
   told, and the colour is the difference. */
.content-type-row {
  padding: 10px 12px; margin-bottom: 14px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--lift-1);
}
.content-type-row label { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.content-type-row label > span { font-size: 13px; color: var(--ink); font-weight: 600; }
.content-type-row select { flex: 1 1 220px; min-width: 200px; }
.content-type-row .code-hint { margin: 8px 0 0; }
.content-type-row.unsure { border-color: var(--amber); }
.content-type-row.unsure label > span { color: var(--amber); }

.chunk.taken { opacity: .5; }
.chunk .badge { margin-top: 4px; margin-right: 5px; display: inline-block; }

/* ---------------------------------------------------------------- knowledge */
/* Three layers side by side, because the question is never "what does it say"
   but "why is it saying that here" — and the answer is always which layer won. */
.kn-split { display: grid; grid-template-columns: 260px 1fr; gap: 18px; align-items: start; }
@media (max-width: 900px) { .kn-split { grid-template-columns: 1fr; } }

.kn-list { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.kn-group {
  padding: 8px 12px; font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); background: var(--lift-2); border-bottom: 1px solid var(--line);
}
.kn-item {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 9px 12px; background: none; border: none; border-bottom: 1px solid var(--line);
  color: var(--ink); font-size: 12.5px; cursor: pointer;
}
.kn-item:last-child { border-bottom: none; }
.kn-item:hover { background: var(--lift-2); }
.kn-item.active { background: var(--lift-3); color: var(--teal); }
.kn-item .kn-dot { margin-left: auto; color: var(--amber); font-size: 9px; }

.kn-layer { border: 1px solid var(--line); border-radius: 8px; padding: 12px; margin-top: 14px; }
.kn-layer.locked { opacity: .75; }
.kn-layer-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; font-size: 12.5px; }
.kn-layer-head .spacer { flex: 1; }
.kn-text {
  width: 100%; box-sizing: border-box; font-family: var(--mono, monospace); font-size: 12px;
  line-height: 1.55; padding: 10px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--input-bg); color: var(--ink); resize: vertical; white-space: pre-wrap;
}
.kn-effective {
  border: 1px solid var(--teal); border-radius: 8px; padding: 12px; margin-top: 6px;
}
.kn-effective pre {
  margin: 0; font-size: 12px; line-height: 1.55; white-space: pre-wrap;
  max-height: 260px; overflow: auto; color: var(--ink);
}
.kn-proposal {
  border: 1px solid var(--line); border-left: 3px solid var(--amber);
  border-radius: 8px; padding: 12px; margin-bottom: 12px;
}

/* ---------------------------------------------------------------- recorder */
.rec-panel {
  background: var(--obsidian); border: 1px solid var(--line); border-radius: 10px;
  padding: 18px; text-align: center; margin-bottom: 16px;
}
.level { display: flex; align-items: flex-end; justify-content: center; gap: 2px; height: 34px; margin-bottom: 10px; }
.level i {
  display: block; width: 4px; height: 3px; border-radius: 2px;
  background: var(--teal); transition: height .06s linear;
}
.rec-clock { font-family: var(--font-mono); font-size: 26px; color: var(--ink); }
/* The last thirty seconds. Crimson is the functional alarm colour, and this is
   the one moment in the recorder where something is about to be taken away. */
.rec-clock.near-limit { color: var(--crimson); }
/* Paused: the clock is dimmed and stops moving, so a glance tells you nothing is
   being captured. Slow, not urgent — pausing to think is a normal thing to do. */
.rec-clock.is-paused { color: var(--muted); animation: rec-breathe 2.4s ease-in-out infinite; }
@keyframes rec-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.rec-controls { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.rec-controls .rec-btn { min-width: 116px; }
.rec-status { font-size: 12px; color: var(--muted); margin: 6px 0 14px; min-height: 32px; line-height: 1.5; }
.rec-btn { min-width: 170px; justify-content: center; }
.rec-player { width: 100%; margin-top: 14px; }

/* ---------------------------------------------------------------- waking overlay */
.waking {
  position: fixed; inset: 0; z-index: 90;
  background: var(--scrim); backdrop-filter: blur(3px);
  display: none; place-items: center; padding: 24px;
}
.waking.on { display: grid; }
.waking-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-lg); padding: 30px 34px; max-width: 420px; text-align: center;
}
.waking-pulse {
  width: 46px; height: 46px; margin: 0 auto 18px; border-radius: 50%;
  background: var(--teal); opacity: .9; animation: wake 1.5s ease-in-out infinite;
}
@keyframes wake {
  0%, 100% { transform: scale(.72); opacity: .35; }
  50%      { transform: scale(1);   opacity: .95; }
}
.waking-title { font-family: var(--font-display); font-size: 19px; font-weight: 600; color: var(--ink); }
.waking-sub { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin-top: 8px; }
.waking-count { font-family: var(--font-mono); font-size: 12px; color: var(--teal); margin-top: 14px; min-height: 18px; }

@media (max-width: 980px) {
  .plan-lane, .plan-corner { position: static; }
  .hist-row { grid-template-columns: 1fr auto; }
  .hist-row .when { display: none; }
}

/* ---------------------------------------------------------------- projects */

/* A band inside a cell, not a box around one. The cards stay the visual unit —
   a project is a grouping of them, not a container that competes for attention. */
.proj-band {
  display: flex; align-items: center; gap: 6px;
  margin: 8px 0 4px; padding-left: 6px;
  border-left: 3px solid var(--proj);
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted);
}
.proj-band:first-child { margin-top: 0; }
.proj-no {
  font-family: var(--font-mono); font-weight: 600;
  color: var(--proj); font-size: 11px;
}
.proj-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* On the card the project is just its number: the name is in the band above and
   on hover, and a full name on every card would crowd out the title. */
.badge.proj {
  font-family: var(--font-mono);
  color: var(--proj); border-color: var(--proj); background: transparent;
}

/* ---------------------------------------------------------------- dependencies */

/* One overlay across the whole grid. pointer-events are off so the layer never
   swallows a click meant for a card, and back on for the paths themselves so a
   line can still be selected. */
.dep-layer {
  position: absolute; inset: 0;
  pointer-events: none; overflow: visible; z-index: 3;
}
.dep {
  fill: none; stroke: var(--muted); stroke-width: 1.5; opacity: .5;
  pointer-events: stroke; cursor: pointer;
  transition: opacity .12s ease, stroke-width .12s ease;
}
/* A generous invisible hit area, because a 1.5px line is not something anyone
   can reliably click. */
.dep { stroke-linecap: round; }
.dep:hover { opacity: .9; stroke-width: 2.5; }
/* BLOCKS is the dependency that actually stops work, so it is the one drawn in
   the alarm colour. Everything else is a relationship, not an obstruction. */
.dep.blocks { stroke: var(--crimson); opacity: .65; }
.dep.on { stroke: var(--teal); opacity: 1; stroke-width: 3; }

.plan { position: relative; }

/* ---------------------------------------------------------------- viewport */

/* The application owns its zoom. `.main` is the window; `.content` is the
   surface that moves and scales inside it. The sidebar and the toolbar stay put
   deliberately: at 40% a scaled toolbar would be unreadable, and at 250% it
   would be off screen — either way the user could not zoom back out. */
.main { position: relative; overflow: hidden; }
.zoom-canvas {
  /* A native scroller: the zoom lives on the grid inside it (see zoomApply),
     so this element's scrollWidth/scrollHeight are always the visual truth. */
  overflow: auto;
}

/* Cursor states. The hand appears whenever panning is available — the tool is
   selected or space is down — so the pointer always says what a drag will do. */
body.tool-hand .zoom-canvas,
body.tool-hand .zoom-canvas * { cursor: grab; }
body.panning .zoom-canvas,
body.panning .zoom-canvas * { cursor: grabbing !important; }
/* Nothing gets accidentally selected while dragging the surface around. */
body.panning { user-select: none; }

.zoom-bar {
  position: absolute; right: 18px; bottom: 18px; z-index: 40;
  display: flex; align-items: center; gap: 2px;
  padding: 4px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line);
  /* A floating tool wants a real shadow in both themes — the keyline keeps
     its edge where the shadow fades into a same-tone background. */
  box-shadow: var(--shadow-lg), 0 0 0 1px rgba(0,0,0,.06);
}
.zoom-grip {
  cursor: grab; user-select: none; touch-action: none;
  padding: 0 6px; color: var(--muted); font-size: 13px; line-height: 30px;
}
.zoom-grip:active { cursor: grabbing; }
.zoom-btn {
  min-width: 30px; height: 30px; padding: 0 8px;
  display: inline-grid; place-items: center;
  border: 0; background: transparent; color: var(--ink-soft);
  border-radius: 999px; font-size: 14px; line-height: 1;
}
.zoom-btn:hover { background: var(--line-soft); color: var(--ink); }
.zoom-btn.on { background: var(--teal); color: var(--obsidian); }
.zoom-pct {
  min-width: 52px; height: 30px; padding: 0 6px;
  border: 0; background: transparent; color: var(--ink);
  font-family: var(--font-mono); font-size: 12px; border-radius: 999px;
}
.zoom-pct:hover { background: var(--line-soft); }
.zoom-sep { width: 1px; height: 18px; background: var(--line); margin: 0 4px; }

/* =====================================================================
   Multi-select, marquee, connection mode, plan filters, shortcuts.

   The selection grammar is PowerPoint's on purpose: a rubber band, Ctrl+click,
   Ctrl+A, click-empty-to-drop. Familiarity is the feature — nobody reads a
   manual for a planning grid.
   ===================================================================== */

.pcard.sel {
  border-color: var(--teal);
  box-shadow: 0 0 0 2px rgba(0, 245, 212, .38), var(--shadow-md);
}
.pcard.sel.proposed { border-style: solid; }

/* The card a connection is being drawn from, and the crosshair everywhere else
   while it is: the cursor is what says "you are in connect mode". */
.pcard.link-src { outline: 2px dashed var(--teal); outline-offset: 2px; }
body.linking .plan .pcard,
body.linking .plan .pcard * { cursor: crosshair; }

.marquee {
  position: absolute; z-index: 45;
  border: 1.5px dashed var(--teal);
  background: rgba(0, 245, 212, .07);
  border-radius: 4px;
  pointer-events: none;
}
/* Text must not smear while the band is being dragged. */
.plan { user-select: none; }

.sel-count {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: 20px; z-index: 55;
  padding: 8px 16px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--teal);
  color: var(--ink); font-size: 12.5px;
  box-shadow: var(--shadow-lg);
}

/* ---------------------------------------------------------------- plan filters */
#plan-filterbar .swatch { width: 9px; height: 9px; border-radius: 2px; display: inline-block; margin-right: 5px; }
#plan-filterbar .spacer { flex: 1; }
.filter-sep { width: 1px; height: 18px; background: var(--line); margin: 0 6px; }
/* Forces the wrap so Lanes sit on the first line and Time on the second —
   deliberate layout, not overflow. */
.filter-break { flex-basis: 100%; height: 0; }
.chip-clear { color: var(--red); border-color: rgba(217, 30, 24, .4); }

/* The applied-shortcut chip: gold star, and it says so when the filters have
   drifted from what was saved. */
.sc-active {
  font-size: 12px; color: var(--teal); white-space: nowrap;
  padding: 4px 10px; border: 1px solid var(--teal); border-radius: 999px;
  background: rgba(0, 245, 212, .06);
}
.sc-active.dirty { color: var(--muted); border-color: var(--line); background: none; }

/* ---------------------------------------------------------------- shortcuts */
.sc-pop { min-width: 320px; max-width: 380px; }
.sc-item {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; border-radius: 6px; cursor: pointer;
}
.sc-item:hover { background: var(--line-soft); }
.sc-item.dragging { opacity: .4; }
.sc-item.drag-over { outline: 1.5px dashed var(--teal); outline-offset: -1px; }
.sc-slot { font-family: var(--font-mono); font-size: 11px; color: var(--muted); width: 20px; flex: none; }
.sc-name { flex: 1; font-size: 13px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sc-act, .sc-del {
  border: 0; background: none; color: var(--muted);
  width: 24px; height: 24px; border-radius: 5px; font-size: 12px; flex: none;
}
.sc-act:hover { background: var(--line); color: var(--ink); }
.sc-del:hover { background: rgba(217, 30, 24, .15); color: var(--red); }
.sc-empty { padding: 10px 12px; font-size: 12.5px; color: var(--muted); max-width: 300px; }
.sc-save { display: grid; grid-template-columns: 1fr; gap: 6px; padding: 6px 8px 8px; }
.sc-save select, .sc-save input {
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--paper); color: var(--ink); font-size: 12.5px; width: 100%;
}
/* `.ctxmenu button` (a class plus a type) outranks `.btn`, so inside this
   popover the Save button was being stripped back to a flat menu row — no
   fill, no border, indistinguishable from the list above it. Restore the
   real button here, where the selector is specific enough to win. */
.sc-pop .sc-save button {
  background: linear-gradient(135deg, var(--teal) 0%, var(--accent-2) 100%);
  color: var(--on-accent); border: none; font-weight: 600;
  text-align: center; padding: 8px 12px; border-radius: var(--radius-sm);
}
.sc-pop .sc-save button:hover { filter: brightness(1.08); }
/* The import row is a real button too, not a menu entry. */
.sc-pop .sc-io button {
  width: 100%; text-align: center; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink); border-radius: var(--radius-sm); padding: 7px 10px;
}
.sc-pop .sc-io button:hover { border-color: var(--teal-dim); color: var(--ink); }
/* The per-row action buttons are icons, and the generic rule would stretch
   each to the full width of the popover, pushing its neighbours out of reach. */
.sc-pop .sc-item button { display: inline-flex; align-items: center; justify-content: center; width: 24px; padding: 0; }
.sc-hint { padding: 2px 10px 6px; font-size: 11px; color: var(--muted); }

/* ---------------------------------------------------------------- language */
.lang-pick { display: block; margin-top: 10px; }
.lang-pick > span {
  display: block; font-size: 10px; letter-spacing: .6px; text-transform: uppercase;
  color: var(--muted); margin-bottom: 4px;
}
.lang-sel {
  width: 100%; padding: 6px 8px; font-size: 12.5px;
  background: var(--obsidian-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.lang-sel option:disabled { color: var(--muted); }

/* The instant toggle. Two halves of one control rather than two buttons,
   because it is one question — which of these am I reading — and a pair of
   buttons invites the reading that they do different things. */
.lang-toggle {
  display: flex; width: 100%; margin-top: 8px; padding: 2px;
  background: var(--lift-2); border: 1px solid var(--lift-4);
  border-radius: var(--radius-sm); gap: 2px;
}
.lang-toggle span {
  flex: 1; text-align: center; padding: 4px 0; border-radius: 5px;
  font-size: 11px; font-weight: 600; letter-spacing: .4px; color: var(--on-deep-faint);
  transition: background .12s, color .12s;
}
.lang-toggle span.on { background: var(--teal); color: var(--on-accent); }

/* Two buttons, lower left, exactly where the eye goes when it wants the
   chrome rather than the work. */
.theme-switch {
  display: flex; gap: 4px; margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--lift-3);
}
.theme-btn {
  flex: 1; padding: 5px 0; border-radius: 5px; font-size: 11px; font-weight: 600;
  letter-spacing: .3px; border: 1px solid var(--lift-4);
  background: transparent; color: var(--on-deep-faint);
  transition: background .12s, color .12s, border-color .12s;
}
.theme-btn:hover { background: var(--lift-3); color: var(--on-deep); }
.theme-btn.on { background: var(--teal); border-color: var(--teal); color: var(--on-accent); }

/* Translation status. Bottom right, out of the way of the sidebar controls
   that caused it, and gone four seconds after it has nothing to say. */
.i18n-pill {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 13px; border-radius: 999px;
  background: var(--toast-bg); color: var(--toast-ink);
  border: 1px solid var(--lift-4); box-shadow: var(--shadow-md);
  font-size: 12px; font-weight: 500;
  opacity: 0; transform: translateY(6px); pointer-events: none;
  transition: opacity .25s, transform .25s;
}
.i18n-pill.on { opacity: 1; transform: translateY(0); }
.i18n-pill.done { color: var(--teal); }
.i18n-pill .spin { width: 12px; height: 12px; border-width: 2px; }
[dir="rtl"] .i18n-pill { right: auto; left: 18px; }

/* ---------------------------------------------------------------- live search */
.search-wrap { position: relative; }
.search-wrap .search { min-width: 260px; }

/* A hit is marked, not moved: double gold line so it reads at a glance even
   next to a teal selection ring, and everything else steps back. */
.pcard.hit {
  outline: 3px double var(--flash);
  outline-offset: 1px;
  border-color: var(--flash);
}
.pcard.dim { opacity: .3; }
.pcard.dim.hit { opacity: 1; }

@keyframes found-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(245, 197, 24, .75); }
  100% { box-shadow: 0 0 0 14px rgba(245, 197, 24, 0); }
}
.pcard.found { animation: found-pulse 1.4s ease-out 1; }

.search-suggest {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 70;
  min-width: 340px; max-width: 460px; max-height: 50vh; overflow: auto;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: 5px;
}
.ss-head { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); padding: 6px 10px 4px; }
.ss-item {
  display: grid; grid-template-columns: auto 1fr; gap: 2px 8px; width: 100%;
  text-align: left; border: 0; background: none; padding: 7px 10px; border-radius: 6px;
}
.ss-item:hover { background: var(--line-soft); }
.ss-ref { font-family: var(--font-mono); font-size: 10px; color: var(--flash); }
.ss-title { font-size: 12.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-where { grid-column: 2; font-size: 10.5px; color: var(--muted); }
.ss-more { font-size: 11px; color: var(--muted); padding: 6px 10px; }

/* ------------------------------------------------------------------ sign-in
   The login buttons do not react to the pointer. No colour change, no filter,
   no border shift — hovering does nothing at all.

   Asked for directly, and it also closes off how this kept breaking. The
   buttons pick up `.btn` and `.btn-primary`, each of which is styled once for
   the light palette this design began as and again for the dark one it became.
   Any hover rule that slips through in the wrong order repaints the one
   control a signed-out user has, and there is no way around it from there.
   Pinning the appearance across every state means no future rule can.

   Last in the file on purpose: these must win, and `!important` alone would
   not settle a tie against another `!important` earlier on. */
.login-card #li-btn,
.login-card #li-btn:hover,
.login-card #li-btn:focus,
.login-card #li-btn:focus-visible,
.login-card #li-btn:active,
.mt-login #mt-btn,
.mt-login #mt-btn:hover,
.mt-login #mt-btn:focus,
.mt-login #mt-btn:focus-visible,
.mt-login #mt-btn:active {
  background: linear-gradient(135deg, var(--teal) 0%, var(--accent-2) 100%) !important;
  color: var(--on-accent) !important;
  border: none !important;
  filter: none !important;
  transform: none !important;
  box-shadow: none !important;
}
/* Disabled still has to read as disabled: it is the only signal that the
   request is in flight, since the label is replaced by a spinner. */
.login-card #li-btn:disabled,
.mt-login #mt-btn:disabled {
  opacity: .55 !important;
  cursor: not-allowed;
}

/* "Sign in" and the other login headings, forced light. Same reasoning as the
   heading block above, but immune to ordering. */
.login-card h2, .mt-login h2, .mt-login .mt-card h2 { color: var(--ink) !important; }

/* =====================================================================
   LIGHT VIEW
   =====================================================================
   A second palette, chosen for long sessions rather than for impact.

   Three decisions that are not arbitrary:

   No pure white anywhere. #FFF at full screen brightness is the single
   biggest cause of eye fatigue in a tool people keep open all day, so the
   page is a warm off-white and cards lift toward white rather than
   starting there. The warmth is deliberate too — a neutral grey reads as
   cold and slightly dirty next to the teal.

   The teal darkens. Bioluminescent Teal is a glow colour: on a dark field
   it carries the brand, on a light one it is illegible at any size worth
   reading. #0B7F70 keeps the hue and earns its contrast, so the brand
   survives the change instead of being abandoned by it.

   The lift overlays invert. Every "slightly raised" surface in the dark
   theme is white at low opacity; here the same surfaces are ink at low
   opacity. Get this wrong and every panel in the interface disappears.
   ===================================================================== */

[data-theme="light"] {
  /* The obsidian family is the dark theme's ground. Left alone it kept
     near-black fills under newly-dark ink — invisible buttons, chips, table
     headers and lane titles until hover repainted them. Redefined once here,
     every rule built on it follows. --navy is different: it is used as a TEXT
     color and as the primary button's hover, so it stays dark on purpose. */
  --obsidian: #EFEDE7;
  --obsidian-2: #E7E3DA;
  --obsidian-3: #ECE7DE;
  --navy: #10141E;
  --navy-2: #232936;

  --teal: #0B7F70;
  --teal-dim: #0A6B5F;
  --accent-2: #1189A6;
  --on-accent: #FFFFFF;
  --gold: var(--teal);
  --green: #0B7F70;
  --amber: #A96A12;
  --indigo-lift: #6B34BE;

  --ink: #1E2430;
  --ink-soft: #3A4453;
  --muted: #66707F;
  --line: #D9D4CA;
  --line-soft: #E8E4DC;
  --paper: #EFEDE7;
  --surface: #F8F6F2;
  --surface-2: #FCFBF8;
  --column-bg: #E7E3DA;

  /* The chrome. Lighter than the page so the sidebar still reads as a
     separate thing, which is the job the dark navy was doing. */
  --deep: #E4E0D6;
  --deep-2: #DAD5C9;
  --on-deep: #1E2430;
  --on-deep-soft: #2F3846;
  --on-deep-dim: #414B5C;
  --on-deep-faint: #6B7585;

  --lift-1: rgba(30,36,48,.02);
  --lift-2: rgba(30,36,48,.035);
  --lift-3: rgba(30,36,48,.06);
  --lift-4: rgba(30,36,48,.10);
  --lift-5: rgba(30,36,48,.08);
  --lift-6: rgba(255,255,255,.34);
  --nav-edge: rgba(30,36,48,.14);
  --nav-edge-hover: rgba(30,36,48,.28);

  --overlay: rgba(40,44,54,.34);
  --scrim: rgba(239,237,231,.88);
  --input-bg: #FFFFFF;
  --focus-ring: rgba(11,127,112,.18);
  --tint: rgba(11,127,112,.07);
  --tint-2: rgba(11,127,112,.10);
  --tint-line: rgba(11,127,112,.40);

  /* A dark toast on a light page. Following the chrome would make it
     vanish into the thing it is trying to interrupt. */
  --toast-bg: #2B3240;
  --toast-ink: #F6F4F0;
  --btn-primary-bg: #2B3240;
  --btn-primary-ink: #F6F4F0;

  --danger-ink: #A31C17;
  --danger-ink-2: #B02722;
  --prop-ink: #5B32A8;
  --flash: #B07E06;

  /* Softer and warmer. The dark theme's shadows are near-black at high
     opacity, which on a light page reads as dirt rather than depth. */
  --shadow-sm: 0 1px 2px rgba(30,36,48,.07);
  --shadow-md: 0 6px 18px rgba(30,36,48,.09);
  --shadow-lg: 0 20px 48px rgba(30,36,48,.16);
  --glow: 0 0 0 1px rgba(11,127,112,.30), 0 0 18px rgba(11,127,112,.12);
}

/* The few places a value cannot carry the change on its own. */
[data-theme="light"] .login-card h2,
[data-theme="light"] .mt-login h2,
[data-theme="light"] .mt-login .mt-card h2 { color: var(--ink) !important; }
[data-theme="light"] .btn-gold { color: var(--on-accent); }
[data-theme="light"] .sidebar .brand b,
[data-theme="light"] .brandmark .name b { color: var(--teal); }
[data-theme="light"] .badge.rel { background: rgba(169,106,18,.14); color: #7A4D08; }
[data-theme="light"] .badge.conf.high { background: rgba(11,127,112,.13); color: var(--teal); }
[data-theme="light"] .badge.done { background: rgba(11,127,112,.11); color: var(--teal-dim); }
[data-theme="light"] .badge.prop { background: rgba(91,50,168,.12); }
[data-theme="light"] .pill.proposed { background: rgba(91,50,168,.13); }
[data-theme="light"] .pcard.proposed { background: rgba(107,52,190,.07); }
[data-theme="light"] .warnline,
[data-theme="light"] .paused-banner { background: rgba(163,28,23,.08); color: #8C1813; }
/* The editable-cell hint is a wash of the accent; at dark-theme opacity it
   is invisible on a light page. */
[data-theme="light"] .editable:hover { background: rgba(11,127,112,.10); }
[data-theme="light"] .kn-text { background: var(--input-bg); }
/* The base input rule pins background: var(--obsidian) !important — a value
   the light block never overrides, leaving dark ink on a near-black field.
   Same !important, higher specificity, readable in both surfaces. */
[data-theme="light"] input,
[data-theme="light"] select,
[data-theme="light"] textarea {
  background: var(--input-bg) !important;
  color: var(--ink) !important;
}
[data-theme="light"] option { background: var(--surface); color: var(--ink); }
[data-theme="light"] .spin { border-color: rgba(30,36,48,.25); border-top-color: var(--ink); }
[data-theme="light"] .toast .spin { border-color: rgba(255,255,255,.4); border-top-color: #fff; }

/* ---------------------------------------------------------------- gated */
/* The three windows that sell what this platform leads to. Quiet and
   confident: a subscription wall that shouts is one people close. */
.gate-eyebrow {
  font-size: 10.5px; letter-spacing: .10em; text-transform: uppercase;
  color: var(--gold); font-weight: 600; margin-bottom: 10px;
}
.gate-lead { font-size: 15px; line-height: 1.6; color: var(--ink); margin: 0 0 20px; }
.gate-points { display: grid; gap: 12px; margin-bottom: 20px; }
.gate-point {
  display: grid; gap: 3px; padding: 11px 13px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--lift-1);
}
.gate-point b { font-size: 13px; color: var(--ink); }
.gate-point span { font-size: 12.5px; line-height: 1.55; color: var(--muted); }

/* The honest paragraph. Amber rather than red: this is not a refusal, it is
   the reason to keep using what they already have. */
.gate-maturity {
  border: 1px solid var(--amber); border-radius: var(--radius-sm);
  padding: 13px 15px; margin-bottom: 18px;
  background: rgba(232,163,61,.07);
}
.gate-maturity b { display: block; color: var(--amber); font-size: 13px; margin-bottom: 6px; }
.gate-maturity p { margin: 0 0 8px; font-size: 12.5px; line-height: 1.6; color: var(--ink-soft); }
.gate-maturity p:last-child { margin-bottom: 0; }

.gate-cta {
  border-top: 1px solid var(--line); padding-top: 14px;
}
.gate-cta b { display: block; font-size: 13px; color: var(--ink); margin-bottom: 4px; }
.gate-cta p { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--muted); }
.gate-cta a { color: var(--teal); font-weight: 600; }

/* ============================================================================
   LIGHT THEME — text sitting on a lane colour
   ============================================================================

   A lane colour comes from the database and is chosen for the lane, not for
   the theme: #4C008F, #2E6B8A, #D91E18 are all dark, and they stay dark when
   the page turns light. The text on top of them, however, inherits --ink,
   which the light theme flips from near-white to near-black. Dark on dark.

   In the dark theme the problem was invisible because --ink was already light,
   which is exactly why this survived until somebody used the light palette in
   anger.

   Fixed by colour rather than by variable: these elements are painted with an
   arbitrary saturated colour, so the only safe foreground is a fixed light one
   — a variable would just follow the theme back into the dark. */

[data-theme="light"] .rm-bar,
[data-theme="light"] .rm-bar .rf,
[data-theme="light"] .seg-btn.on,
[data-theme="light"] .seg-btn.on *,
[data-theme="light"] .chip.active .swatch + *,
[data-theme="light"] .lane-head[style*="background"],
[data-theme="light"] .col-head[style*="background"] {
  color: #FFFFFF;
}

/* The mono reference inside a bar was dimmed with opacity for the dark theme.
   At .82 on a mid-tone lane colour it drops below readable, so it keeps its
   distinction through weight instead. */
[data-theme="light"] .rm-bar .rf { opacity: .95; font-weight: 600; }

/* Toast and primary button already carry their own dark background in this
   theme (--toast-bg, --btn-primary-bg). Stated here so a later edit to the
   palette does not quietly take the foreground with it. */
[data-theme="light"] .toast { color: var(--toast-ink); }
[data-theme="light"] .btn-primary { color: var(--btn-primary-ink); }

/* The sign-in screen forces data-theme="dark" (see paintTheme in app.js), so
   these rules exist for the case that forcing is ever removed rather than for
   today. The brand panel is a deep gradient by design — identity, not themed
   chrome — and anything sitting on it needs light text whatever the palette. */
[data-theme="light"] .login-brand,
[data-theme="light"] .login-brand .tag,
[data-theme="light"] .login-brand .tag-more,
[data-theme="light"] .login-brand .mark { color: #F6F4F0; }

/* The theme switch itself sits on the deep chrome on the sign-in screen. */
[data-theme="light"] .login-brand .theme-btn { color: #F6F4F0; }

/* ============================================================================
   THE MAP VIEWPORT — 4a, 4b, 4c, 4e, 4f
   ============================================================================ */

/* ---- 4b. The tool widget, top-left, under the time filters -----------------
   It was bottom-right, the conventional place for zoom controls. Wrong here:
   the tool it carries decides what a click on a card does, so it belongs where
   the eye already is — beside the filters, above the map it governs — not in
   the corner furthest from the work. */
.zoom-bar {
  position: absolute; right: auto; bottom: auto;
  left: 14px; top: 8px;
  z-index: 40;
}

/* ---- 4f. A horizontal scrollbar above the map ------------------------------
   The map pans by transform, so this bar scrolls a spacer of the same width
   and app.js binds the two (see syncTopScrollbar). The one the browser draws
   under the map stays; this is the second, for reading a lane header and
   travelling sideways without leaving it. */
.map-scroll-top {
  overflow-x: scroll; overflow-y: hidden;   /* scroll, not auto: the rail is always drawn */
  height: 16px; flex: none;
  background: var(--surface); border-bottom: 1px solid var(--line-soft);
  scrollbar-width: thin;                    /* Firefox */
  scrollbar-color: var(--muted) transparent;
}
.map-scroll-inner { height: 1px; }
/* Chrome/Edge: an explicit, visible thumb. */
.map-scroll-top::-webkit-scrollbar { height: 12px; }
.map-scroll-top::-webkit-scrollbar-track { background: transparent; }
.map-scroll-top::-webkit-scrollbar-thumb {
  background: var(--muted); border-radius: 6px;
  border: 3px solid var(--surface); background-clip: padding-box;
}
.map-scroll-top::-webkit-scrollbar-thumb:hover { background: var(--ink); }

/* ---- 4c. The top edge is welded to the filter bar --------------------------
   Paired with zoom.y = 0 in zoomApply. Transform-origin at the top-left is
   what makes a zoom grow downward and sideways from that corner instead of
   outward from the middle, which is what would drag the top edge away. */
/* The canvas scrolls natively in both axes; the grid inside it carries the
   CSS `zoom`, which scales LAYOUT — so the scrollbars are always truthful. */
.plan-scroll { overflow: auto; }

/* ---- 4a. The three panels, centred on the viewport -------------------------
   Sized against the smallest screen in use — 1432x734 — so a panel written to
   fit there fits everywhere, and no scrollbar ever appears inside one. The
   height ceiling is what does the work: content is laid out to fit rather than
   to scroll. Below that floor the viewport itself takes over, because a panel
   taller than the window with no scrollbar would be unreadable. */
.modal-back { place-items: center; padding: 16px; }
.modal.panel-fixed {
  width: min(1180px, calc(100vw - 32px));
  max-width: none;
  max-height: min(660px, calc(100vh - 32px));
  overflow: hidden;                 /* no scrollbars, as asked */
  display: flex; flex-direction: column;
}
.modal.panel-fixed .modal-body {
  flex: 1 1 auto;
  overflow: hidden;
  display: flex; flex-direction: column;
}
/* Only when the window is genuinely smaller than the floor does scrolling come
   back — the alternative is content nobody can reach. */
@media (max-width: 1431px), (max-height: 733px) {
  .modal.panel-fixed { max-height: calc(100vh - 24px); overflow: auto; }
  .modal.panel-fixed .modal-body { overflow: auto; }
}

/* ---- 4e. Tablet mode -------------------------------------------------------
   One class on <body>, so nothing has to know about it twice. Targets go to
   44px, the standard finger target; below that a tap lands next to what was
   aimed at often enough to be maddening. */
body.tablet-mode .zoom-btn { min-width: 44px; height: 44px; font-size: 17px; }
body.tablet-mode .zoom-bar { padding: 6px; gap: 4px; }
body.tablet-mode .btn { min-height: 40px; padding: 9px 16px; }
body.tablet-mode .chip { min-height: 36px; padding: 7px 12px; }

/* Wider scrollbars, for fingers rather than a pointer. */
body.tablet-mode .map-scroll-top { height: 22px; }
body.tablet-mode ::-webkit-scrollbar { width: 20px; height: 20px; }
body.tablet-mode ::-webkit-scrollbar-thumb {
  background: var(--nav-edge-hover); border-radius: 10px; border: 4px solid transparent;
  background-clip: content-box;
}
body.tablet-mode { scrollbar-width: auto; }

/* The card's drag and resize targets grow without the card looking different:
   a pseudo-element extends the hit area outward. Making the visible handles
   bigger would change the density of the whole map. */
body.tablet-mode .pcard { position: relative; }
body.tablet-mode .pcard::after {
  content: ''; position: absolute; inset: -8px; z-index: -1;
}
body.tablet-mode .pcard .resize-handle::after {
  content: ''; position: absolute; inset: -14px;
}

/* The Ctrl latch, lit while held. A tablet has no Ctrl key and multi-select
   needs one. */
body.tablet-mode .zoom-ctrl { font-size: 12px; font-weight: 600; }
.zoom-ctrl.on, .zoom-device.on { background: var(--teal); color: var(--on-accent); }
body.ctrl-latched .pcard { cursor: copy; }

/* Long press must not also select the text under the finger. */
body.tablet-mode .pcard, body.tablet-mode .col, body.tablet-mode .lane-head {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}

/* The Text Grid View — the map as a table. Shares the filters and the
   shortcuts with the matrix; only the layout differs. */
.grid-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.grid-table th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-2); color: var(--ink);
  text-align: left; font-weight: 600; padding: 9px 10px;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.grid-table th[draggable="true"] { cursor: grab; }
.grid-table th[draggable="true"]:active { cursor: grabbing; }
.grid-table td {
  padding: 8px 10px; border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
.grid-table tbody tr:hover { background: var(--lift-2); cursor: pointer; }
.grid-table .ref { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); white-space: nowrap; }
/* The description is the column worth reading, so it gets the room and wraps;
   everything else stays on one line so the row scans. */
.text-grid td:last-child { max-width: 40ch; white-space: pre-wrap; }

/* The inbox row's ask controls. Beside the lane buttons because they are
   decided together: "this goes in Operations and Maria has to confirm it" is
   one thought, not two. */
.inbox-ask { display: flex; align-items: center; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
.inbox-ask .toggle { font-size: 12.5px; color: var(--muted); }
.ask-people { max-height: 240px; overflow-y: auto; border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 8px 10px; background: var(--surface); }

/* The inbox batch editor. The bar appears on the first tick and stays at the
   top of the list, because the Apply button has to be reachable without
   scrolling back from row forty. */
.batch-bar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 10px;
  background: var(--tint); border: 1px solid var(--tint-line);
  border-radius: var(--radius-sm);
}
.batch-bar select { padding: 6px 8px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--input-bg); color: var(--ink); }
.batch-bar select[multiple] { min-width: 180px; }

.inbox-row { position: relative; }
.inbox-tick { margin-right: 10px; margin-top: 2px; align-self: flex-start; }
/* A ticked row is tinted rather than outlined: an outline moves the content by
   a pixel and forty of them flicker as you work down the list. */
.inbox-row.picked { background: var(--tint); }

/* The model's 2nd/3rd lane candidates - their own quiet row in a review card. */
.suggest.alt-picks { margin-top: 2px; padding-top: 4px; border-top: 1px dashed var(--line, rgba(120,120,120,.25)); }
.suggest.alt-picks .chip { cursor: pointer; }

/* Review-page dropdowns: compact, and the model's 2nd/3rd candidates stand
   out in orange inside the open list. */
.inbox-pick { width: auto; max-width: 240px; font-size: 12px; padding: 4px 6px; }
.inbox-pick option.alt-option { color: #E8590C; font-weight: 600; }

/* The model's own proposal inside a review dropdown: bold, starred, unmissable. */
.inbox-pick option.proposed-option { font-weight: 700; }

/* A captured element still being weighed by the AI agent: read-only, and it
   says so with a live pulse rather than a dead label. */
.inbox-row.in-triage { opacity: .85; }
.ai-working {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px; border-radius: 999px; align-self: start;
  font-size: 12px; font-weight: 600; white-space: nowrap;
  color: var(--teal, #0E9F8A);
  background: color-mix(in srgb, var(--teal, #0E9F8A) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--teal, #0E9F8A) 35%, transparent);
}
.ai-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--teal, #0E9F8A);
  animation: ai-pulse 1.2s ease-in-out infinite;
}
@keyframes ai-pulse {
  0%, 100% { transform: scale(.7); opacity: .4; }
  50%      { transform: scale(1.15); opacity: 1; }
}

/* QUEUED IS NOT WORKING, AND IT MUST NOT LOOK LIKE IT.
   A pulsing teal dot is the universal sign of something happening. On a run that is still
   QUEUED nothing is happening at all — no worker has claimed it and nothing has been sent to
   the model — so the pulse is grey and STILL. The animation is what carries the claim here;
   leaving it running under the words "Queued" would make the words the only honest part, and
   nobody reads the words when the light is blinking. */
.ai-working.waiting {
  color: var(--ink-soft, #6B7280);
  background: color-mix(in srgb, var(--ink-soft, #6B7280) 10%, transparent);
  border-color: color-mix(in srgb, var(--ink-soft, #6B7280) 28%, transparent);
}
.ai-working.waiting .ai-dot {
  background: var(--ink-soft, #6B7280);
  animation: none;
  opacity: .55;
}
/* Fainter still than in-triage: a queued row is further from a decision, not nearer. */
.inbox-row.in-triage.queued { opacity: .7; }

/* A proposal the KEYWORD classifier made, because the model call did not answer.
   Amber, not red: it is a usable proposal and the run did the right thing by not blocking.
   But it is word overlap rather than judgement, so it must not wear the same label as a
   proposal a reasoning model weighed — after the Vertex credential was missing on
   2026-09-08, a hundred of these were indistinguishable from model output on screen. */
.suggest .by-rule {
  color: var(--amber, #B45309);
  font-weight: 600;
  cursor: help;
}

/* Live element counts on the map: title, every column, every lane. */
.count-badge { font-size: 11px; color: var(--muted); font-weight: 600; white-space: nowrap; }
#map-count { font-size: 16px; font-weight: 600; }

/* =====================================================================
   Stratos Desktop — the windowing shell (shell.js).

   Z-ORDER CONTRACT with the rest of this file: windows live in #wm-layer at
   z 30 — above the page, below every modal (50), menu (60) and toast (70),
   so nothing the views already open can ever be buried under a window. The
   tour sits at 120, above everything, because a guide that can be covered
   mid-sentence is a guide that loses people.
   ===================================================================== */

/* The rail grew (Praxia expands to its agents), so it can now be taller than
   the viewport. Left alone, the grid row stretches to the tallest child and
   the desktop believes it is that tall too — icons then arrange below the
   fold. The row is pinned to the viewport and the rail scrolls by itself. */
.shell { grid-template-rows: minmax(0, 1fr); }
/* `stable`, not `auto`: opening the Praxia dropdown can make the rows outgrow
   the screen, and with `auto` the scrollbar's arrival shrank every row by its
   width — the whole rail appeared to change width on every expand/collapse. */
.sidebar { overflow-y: auto; overflow-x: hidden; max-height: 100vh; scrollbar-gutter: stable; }

#wm-layer {
  position: fixed; top: 0; left: var(--sidebar); right: 0; bottom: 0;
  z-index: 30; pointer-events: none;   /* the desktop stays clickable through it */
}
/* Right-to-left: the grid places the rail on the RIGHT, so the layer's free
   edge is the left one. Without this every window and the control row sat
   over the Hebrew/Arabic menu. */
html[dir="rtl"] #wm-layer { left: 0; right: var(--sidebar); }
html[dir="rtl"] body.rail-hidden #wm-layer { right: 0; }
#wm-layer > * { pointer-events: auto; }

/* ---- the desktop surface ------------------------------------------- */
.desktop-surface {
  position: relative; overflow: hidden;
  background:
    radial-gradient(1200px 700px at 68% 18%, rgba(76, 0, 143, .16), transparent 60%),
    radial-gradient(900px 600px at 18% 85%, rgba(0, 245, 212, .05), transparent 55%),
    var(--paper);
}
.desktop-surface .paused-banner { position: relative; z-index: 2; }

/* ---------------------------------------------------------------- phase frames
 *
 * One thin box per phase, drawn behind its column of icons, with a two-line heading sitting on
 * the upper border. Ruled 2026-09-09 after a board member said the desk gave him "different
 * pieces that I can use but I have nothing to guide me" — the frames are what turn a rack of
 * icons into three ordered steps.
 *
 * POINTER-EVENTS: NONE IS LOAD-BEARING. The frame overlaps the icons it surrounds, so without
 * this it would swallow the click and the drag of every icon inside it, and the desk would
 * appear frozen. It is decoration and must never be a target.
 */
/* The rail's phase heading is two lines now: the phase, then what it is for. */
.nav-group-title { display: flex; flex-direction: column; gap: 1px; }
/* The second line is the phase's PURPOSE, so it must not wear the heading's small-caps
 * tracking — that formatting says "label", and this is a sentence. `--on-deep-faint` is the
 * rail's own muted ink (the heading above uses it too); there is no `--ink-faint`, which the
 * first draft of this rule invented and would have rendered as the browser's default black. */
.nav-group-sub {
  font-size: 10px; line-height: 1.2; font-weight: 400; letter-spacing: 0;
  color: var(--on-deep-faint); text-transform: none; opacity: .85;
}

.dt-group {
  position: absolute; z-index: 0; pointer-events: none;
  border: 1px solid var(--nav-edge); border-radius: 14px;
  background: color-mix(in srgb, var(--lift-1) 55%, transparent);
}
.dt-group-head {
  /* Straddling the top border, and opaque, so the line appears to break for the words the way
   * a fieldset legend does — done by hand because the heading is two lines and a real
   * <legend> is a single inline box. */
  position: absolute; left: 10px; right: 10px; top: -1px;
  transform: translateY(-46%);
  display: flex; flex-direction: column; gap: 1px;
  padding: 2px 6px; border-radius: 6px;
  background: var(--deep);
}
/* The same font as "Workspace 1" (.ws-label), by ruling: the desk should read as one thing. */
/* TWO LINES, AND THEY WRAP. `white-space: nowrap` with an ellipsis was here, and inside a
 * 104px column what it rendered was "Phase 0 · AI ag…" — the number kept and the meaning cut
 * off, which is the opposite of the useful half. `headingLines()` in shell.js splits the
 * heading at its separator so the number and the words are two spans; wrapping is what
 * catches an operator's rename or a translation that is longer than the English. */
.dt-group-title {
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em; line-height: 1.2;
  color: var(--on-deep-soft); text-align: center; overflow-wrap: break-word;
}
/* The first line is the phase NUMBER and the second is what the phase is; the number is the
 * quieter of the two, because it is an index and the words are the message. */
.dt-group-title:first-child {
  font-size: 10px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--on-deep-faint);
}
/* The phase's PURPOSE sentence is deliberately not on the desk — it does not fit in 104px and
 * two lines was the ruling. It is in the rail, in full, as `.nav-group-sub`, where there is
 * room for a sentence. */
/* An icon must sit ABOVE its frame — the frame is painted first, and both are positioned. */
.dt-icon { z-index: 1; }

.dt-icon {
  cursor: default;
  position: absolute; width: 104px; padding: 8px 4px 6px;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  background: transparent; border: 1px solid transparent; border-radius: 12px;
  cursor: default; user-select: none; -webkit-user-select: none;
  touch-action: none;
}
.dt-icon:hover { background: var(--lift-2); }
.dt-icon.selected { background: var(--lift-3); border-color: var(--nav-edge); }
.dt-icon:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.dt-icon.dragging { opacity: .8; z-index: 5; }
/* THE ART IS 45px — 20% down from 56 (ruled 2026-09-09), and the LABEL FONT IS UNTOUCHED.
 *
 * One number in two places because the container is positioned (the lock badge and the
 * prominent glow hang off it) and the image inside it is sized independently. A custom
 * property so they cannot drift, and so the harness has one value to read: it computes the
 * tile height from this and fails if the tile grows back into the row pitch. */
:root { --dt-art: 45px; }
.dt-icon-art { position: relative; width: var(--dt-art); height: var(--dt-art); }
.dt-icon-art img {
  width: var(--dt-art); height: var(--dt-art); display: block;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .45));
}
.dt-icon-label {
  font-size: 12px; line-height: 1.25; text-align: center; color: var(--ink-soft);
  max-width: 100px; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
}
[data-theme="light"] .dt-icon-label { text-shadow: none; }

/* Shut but visible — the same doctrine as the rail's lock dot. Dimmed, never
   hidden: the desk is where a leader sees what the platform becomes. */
.dt-icon.shut img { filter: grayscale(.8) brightness(.8) drop-shadow(0 6px 14px rgba(0, 0, 0, .45)); opacity: .85; }
.dt-lock {
  position: absolute; right: -2px; bottom: -2px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--obsidian-2);
  border: 1px solid var(--line); display: grid; place-items: center;
}
.dt-lock::after { content: '●'; font-size: 7px; color: var(--teal-dim); }

.dt-running {
  position: absolute; left: 50%; bottom: -9px; transform: translateX(-50%);
  width: 5px; height: 5px; border-radius: 50%; background: var(--teal);
}
.dt-badge, .dock-badge {
  position: absolute; top: -5px; right: -7px;
  background: var(--amber); color: #1a1204; font-weight: 700; font-size: 10.5px;
  border-radius: 999px; padding: 1px 6px; line-height: 1.5; pointer-events: none;
}
.dt-icon.pulse { animation: dt-pulse 1s ease 2; }
/* The frame flashes with its icons — see revealCategory. Its own animation rather than
 * dt-pulse, because that one moves a background on a transparent box and this one has a
 * border to bring forward. */
.dt-group.pulse { animation: dt-group-pulse 1s ease 2; }
@keyframes dt-group-pulse {
  0%, 100% { border-color: var(--nav-edge); }
  50%      { border-color: var(--teal); }
}
@keyframes dt-pulse {
  0%, 100% { box-shadow: none; }
  50% { box-shadow: 0 0 0 3px rgba(0, 245, 212, .35); background: var(--lift-3); }
}
.dt-icon.prominent .dt-icon-art::after {
  content: ''; position: absolute; inset: -6px; border-radius: 18px;
  box-shadow: 0 0 26px rgba(0, 245, 212, .18); pointer-events: none;
}

/* ---- windows -------------------------------------------------------- */
.win {
  position: absolute; display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 12px; overflow: hidden; outline: none;
  box-shadow: var(--shadow-lg);
  min-width: 320px; min-height: 200px;
}
.win.focused {
  border-color: rgba(0, 245, 212, .35);
  box-shadow: var(--shadow-lg), 0 0 0 1px rgba(0, 245, 212, .18);
}
.win.minimised { display: none; }
.win.maximised { border-radius: 0; border-left: none; border-top: none; }
.win.dragging { will-change: transform; }
.win.dragging .win-main { pointer-events: none; }  /* a drag never clicks the content */

.win-bar {
  flex: 0 0 auto; height: 40px; display: flex; align-items: center; gap: 10px;
  padding: 0 12px; background: var(--surface); border-bottom: 1px solid var(--line);
  user-select: none; -webkit-user-select: none; touch-action: none;
}
.win-title {
  /* Optical balance for the lights: their own width (3 x 13px + 2 x 7px gap = 53px) PLUS the
   * signature indent, or the title drifts left of centre by exactly the indent. */
  flex: 1; text-align: center; margin-right: calc(53px + var(--win-lights-indent));
  font-family: var(--font-display); font-size: 13px; font-weight: 600;
  color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.win.focused .win-title { color: var(--ink); }
.win-badge:empty { display: none; }

/* THE SIGNATURE INDENT — x – + , set in from the edge (ruled 2026-09-09).
 *
 * THE BUG IT FIXES. Hide the rail and maximise a window: the layer's rail-toggle button sits
 * at `left: 4px` and is 22px wide, so it occupies x 4→26 — and a maximised window's left edge
 * is x 0, which put its lights at x 12→65, directly underneath the toggle. Two controls in the
 * same place, and the one on top was not the one anybody was aiming at.
 *
 * Computed from the toggle's OWN geometry rather than guessed, so the two cannot drift: the
 * button's offset, plus its width, plus a gap, less the title bar's own padding. Change the
 * button and this follows.
 *
 * PERMANENT ON EVERY WINDOW, and not only on maximised ones, by ruling. A control that moves
 * depending on whether a window happens to be maximised is a control people misclick — and
 * the offset is the product's own signature. macOS puts its three dots hard against the
 * corner; these sit in, and they read x – + rather than the traffic-light order.
 */
:root {
  --rail-btn-x: 4px;
  --rail-btn-w: 22px;
  --win-lights-indent: calc(var(--rail-btn-x) + var(--rail-btn-w) + 8px - 12px);
}
.win-lights { display: flex; gap: 7px; margin-left: var(--win-lights-indent); }
.win-light {
  width: 13px; height: 13px; border-radius: 50%; padding: 0;
  border: 1px solid rgba(0, 0, 0, .35); position: relative;
}
.win-light.close { background: #E5544B; }
.win-light.min   { background: var(--amber); }
.win-light.zoom  { background: #21BE8F; }
.win:not(.focused) .win-light { background: var(--lift-5); }
.win-light::after {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 9px; line-height: 1; color: rgba(0, 0, 0, .55); opacity: 0;
}
.win-light.close::after { content: '×'; }
.win-light.min::after   { content: '–'; }
.win-light.zoom::after  { content: '+'; }
.win-bar:hover .win-light { background-clip: padding-box; }
.win-bar:hover .win-light.close { background: #E5544B; }
.win-bar:hover .win-light.min   { background: var(--amber); }
.win-bar:hover .win-light.zoom  { background: #21BE8F; }
.win-bar:hover .win-light::after { opacity: 1; }

.win-main {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  position: relative; overflow: hidden; background: var(--paper);
}

/* Resize handles: invisible, generous, on all eight edges. */
.win-rs { position: absolute; z-index: 3; }
.rs-n  { top: -4px; left: 10px; right: 10px; height: 8px; cursor: ns-resize; }
.rs-s  { bottom: -4px; left: 10px; right: 10px; height: 8px; cursor: ns-resize; }
.rs-e  { right: -4px; top: 10px; bottom: 10px; width: 8px; cursor: ew-resize; }
.rs-w  { left: -4px; top: 10px; bottom: 10px; width: 8px; cursor: ew-resize; }
.rs-ne { top: -5px; right: -5px; width: 14px; height: 14px; cursor: nesw-resize; }
.rs-sw { bottom: -5px; left: -5px; width: 14px; height: 14px; cursor: nesw-resize; }
.rs-nw { top: -5px; left: -5px; width: 14px; height: 14px; cursor: nwse-resize; }
.rs-se { bottom: -5px; right: -5px; width: 14px; height: 14px; cursor: nwse-resize; }
.win.maximised .win-rs { display: none; }

.snap-preview {
  position: absolute; z-index: 1; border-radius: 12px;
  background: rgba(0, 245, 212, .08); border: 1px solid rgba(0, 245, 212, .35);
  pointer-events: none;
  transition: left .1s ease, top .1s ease, width .1s ease, height .1s ease;
}

/* ---- the dock ------------------------------------------------------- */
.dock {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  display: flex; gap: 10px; align-items: flex-end;
  padding: 8px 12px; border-radius: 16px;
  background: rgba(17, 26, 46, .78); border: 1px solid var(--nav-edge);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-md);
  /* Windows raise by incrementing a counter that never resets, so the dock's
     z must be beyond any focus count a session could reach. The layer is its
     own stacking context; this large number escapes nothing outside it. */
  z-index: 99999;
}
.dock.empty { display: none; }
[data-theme="light"] .dock { background: rgba(255, 255, 255, .8); }
.dock-tile {
  position: relative; width: 44px; height: 44px; padding: 4px;
  background: transparent; border: none; border-radius: 10px;
  transition: transform .12s ease, background .12s ease;
}
.dock-tile img { width: 36px; height: 36px; display: block; }
.dock-tile:hover { transform: translateY(-4px) scale(1.12); background: var(--lift-3); }
.dock-tile:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.dock-tile.min img { opacity: .55; filter: grayscale(.4); }
.dock-foot {
  position: absolute; left: 0; right: 0; bottom: -3px;
  display: flex; align-items: center; justify-content: center; gap: 3px;
}
.dock-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--teal); }
.dock-ws { font-size: 8.5px; line-height: 1; color: var(--on-deep-faint); letter-spacing: .02em; }
.dock-tile { height: 50px; padding-bottom: 8px; }
.dock-tile.min .dock-dot { background: var(--muted); }
.dock-tile.front { background: var(--lift-3); }

/* ---- the rail in launcher mode -------------------------------------- */
.nav-item.running .nav-label { position: relative; }
.nav-item.running .nav-label::before {
  content: ''; position: absolute; left: -11px; top: 50%; transform: translateY(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: var(--teal);
}
.nav-group-title.nav-cat { cursor: pointer; }
.nav-group-title.nav-cat:hover { color: var(--on-deep-soft); }
.nav-subgroup { margin: 2px 0 2px 10px; border-left: 1px solid var(--nav-edge); padding-left: 4px; }
.nav-subtitle .nav-label { font-weight: 600; letter-spacing: .02em; }

/* ---- the gate, as window content ------------------------------------ */
.gate-window { overflow: auto; padding: 26px 30px 30px; flex: 1; min-height: 0; }
.gate-window .gate { max-width: 720px; margin: 0 auto; }
.gate-title {
  max-width: 720px; margin: 0 auto 14px;
  font-family: var(--font-display); font-size: 22px; line-height: 1.25;
}
.gate-actions {
  max-width: 720px; margin: 22px auto 0;
  display: flex; gap: 10px; flex-wrap: wrap;
}

/* ---- self-guided tours ----------------------------------------------- */
.tour-scrim { position: fixed; inset: 0; z-index: 120; background: transparent; }
.tour-spot {
  position: fixed; z-index: 121; border-radius: 12px; pointer-events: none;
  /* One element, one enormous shadow: the scrim IS the shadow, so the
     spotlight needs no compositing tricks and never misaligns with it. */
  box-shadow: 0 0 0 200vmax var(--scrim);
  outline: 1px solid rgba(0, 245, 212, .5);
  transition: left .25s ease, top .25s ease, width .25s ease, height .25s ease;
}
.tour-pop {
  position: fixed; z-index: 122; width: 420px; max-width: calc(100vw - 24px);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 16px 18px;
}
.tour-pop h3 { margin: 2px 0 8px; font-family: var(--font-display); font-size: 16px; }
.tour-pop p { margin: 0 0 14px; font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }
.tour-count { font-size: 11px; color: var(--muted); font-weight: 600; }
.tour-actions { display: flex; gap: 8px; align-items: center; }
.tour-actions .spacer { flex: 1; }

/* ---- desktop context menu ------------------------------------------- */
.shell-menu { display: flex; flex-direction: column; }
.shell-menu .ctx-item {
  display: block; width: 100%; text-align: left; background: transparent;
  border: none; color: var(--ink); font-size: 13px; padding: 7px 12px;
  border-radius: 6px;
}
.shell-menu .ctx-item:hover { background: var(--lift-4); }
.shell-menu .ctx-sep { height: 1px; background: var(--line); margin: 4px 6px; }

/* ---- secondary display surfaces (?surface=N) ------------------------ */
.shell.surface-shell { grid-template-columns: 1fr; }
body.surface-mode #wm-layer { left: 0; }
.surface-veil {
  position: fixed; inset: 0; z-index: 110;   /* over windows, under tours */
  background: var(--scrim); display: grid; place-items: center;
}
.surface-veil-card {
  max-width: 440px; padding: 22px 26px; text-align: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.surface-veil-card b { font-family: var(--font-display); font-size: 15px; }
.surface-veil-card p { color: var(--ink-soft); font-size: 13.5px; margin: 10px 0 0; }

/* Small screens: the rail overlays, so the layer takes the full width. */
@media (max-width: 900px) { #wm-layer { left: 0; } }

/* Reduced motion: the shell's own transitions collapse; shell.js already
   swaps every FLIP for an instant state change with a short crossfade. */
@media (prefers-reduced-motion: reduce) {
  .dock-tile, .tour-spot, .snap-preview { transition: none; }
  .dt-icon.pulse { animation: none; background: var(--lift-3); }
}

/* ---- 2026-08-29: licence borders, Praxia dropdown, rail controls ---------- */

/* The licence IS the border: solid when held, dashed when not. The rail rows
   gain 2px of air so two adjacent borders never read as one line. */
.nav-item.lic-on  { border-style: solid; border-color: var(--nav-edge-hover); }
.nav-item.lic-off { border-style: dashed; border-color: var(--nav-edge-hover); }
.nav-group .nav-item + .nav-item,
.nav-group .nav-item + .nav-drop,
.nav-group .nav-drop + .nav-item { margin-top: 3px; }

/* Praxia: one row, a caret, a list that folds. */
.nav-drop-head .drop-caret { margin-left: auto; font-size: 18px; line-height: 1; opacity: .85; transition: transform .15s; pointer-events: none; }
.nav-drop.open .nav-drop-head .drop-caret { transform: rotate(180deg); }
.nav-drop-head.locked .drop-caret { margin-left: auto; }
.nav-drop-head .led { margin-left: 8px; }
.nav-drop-list { display: none; margin: 3px 0 0 10px; padding-left: 6px; border-left: 1px solid var(--nav-edge); }
.nav-drop.open .nav-drop-list { display: block; }
.nav-drop-list .nav-item { font-size: 13px; padding: 7px 10px; }
.nav-drop-list .nav-item + .nav-item { margin-top: 3px; }

/* Brand row: the wordmark is a link; the chevron hides the rail. */
.brandrow { display: flex; align-items: center; gap: 6px; }
.brandrow .brandmark { flex: 1; text-decoration: none; color: inherit; }
.brandrow .brandmark:hover .name { color: var(--teal); }
.rail-toggle, .rail-show {
  width: 22px; height: 22px; padding: 0; border-radius: 6px; font-size: 16px; line-height: 1;
  background: var(--lift-3); border: 1px solid var(--nav-edge); color: var(--on-deep-soft);
}
.rail-toggle:hover, .rail-show:hover { background: var(--lift-5); color: var(--on-deep); }
/* The menu toggle: a tab sitting ON the boundary between rail and desk,
   inside the window layer, so it is there whether the rail is or not. */
.rail-btn { display: none; }          /* the layer's copy: only while the rail is hidden */
body.rail-hidden .rail-btn { display: block; }
.rail-btn {
  /* The two variables the lights' indent is computed from — see --win-lights-indent. Keeping
   * the numbers in one place is what stops the button and the gap it needs drifting apart. */
  position: absolute; top: 10px; left: var(--rail-btn-x); z-index: 60;
  width: var(--rail-btn-w); height: 22px; border-radius: 6px; padding: 0; font-size: 16px; line-height: 1;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-soft);
  box-shadow: var(--shadow-sm);
}
html[dir="rtl"] .rail-btn { left: auto; right: 4px; }
.rail-btn:hover { background: var(--surface-2); color: var(--teal); box-shadow: var(--shadow-md), var(--glow); }
body.rail-hidden .shell { grid-template-columns: 0 1fr; }
/* The rail stays a grid item at zero width — display:none would drop it out
   of the grid, promote the desktop to column 1 (width 0) and make every icon
   vanish, which is exactly the bug this replaced. */
body.rail-hidden .sidebar { width: 0; min-width: 0; padding-left: 0; padding-right: 0; overflow: hidden; border: 0; }
body.rail-hidden .sidebar > * { display: none; }
body.rail-hidden #wm-layer { left: 0; }

/* The rail is resizable from its right edge. The cursor says so. */
.sidebar { position: relative; }
.rail-resizer {
  position: absolute; top: 0; right: 0; width: 6px; height: 100%;
  cursor: col-resize; z-index: 5; touch-action: none;
}
.rail-resizer:hover { background: rgba(0, 245, 212, .18); }

/* The contextual guided-tour button. */
/* The control row. `--ctl-edge` is the gap to the reading edge; in RTL the
   maximised window's traffic lights sit at the top-LEFT, so the row stays
   on the right, and in LTR the lights sit top-left too — the row is shifted
   just enough that a maximised title bar's lights never hide under it. */
:root { --ctl-edge: 10px; }
[dir="rtl"] :root, html[dir="rtl"] { --ctl-edge: 10px; }
.tour-btn {
  position: absolute; right: var(--ctl-edge); top: 6px; z-index: 60;
  width: 28px; height: 28px; border-radius: 50%; padding: 0;
  font-family: var(--font-display); font-weight: 700; font-size: 15px;
  background: var(--surface); border: 1px solid var(--line); color: var(--teal);
  box-shadow: var(--shadow-md);
}
.tour-btn:hover { background: var(--surface-2); box-shadow: var(--shadow-md), var(--glow); }

/* Licence LEDs: green = held, red = not. On rail rows and on the icons. */
.led { margin-left: 8px; width: 7px; height: 7px; border-radius: 50%; flex: none; }
.led-on  { background: #21BE8F; box-shadow: 0 0 6px rgba(33, 190, 143, .8); }
.led-off { background: #E5544B; box-shadow: 0 0 6px rgba(229, 84, 75, .7); }
.dt-led {
  position: absolute; right: -3px; bottom: -3px; width: 12px; height: 12px;
  border-radius: 50%; border: 2px solid var(--obsidian-2);
}
.dt-led.led-on  { background: #21BE8F; }
.dt-led.led-off { background: #E5544B; }

.shell-menu .ctx-sub { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 4px; display: grid; grid-template-columns: 1fr 1fr; column-gap: 4px; }
.shell-menu .ctx-sub .ctx-sub-title { grid-column: 1 / -1; }
.shell-menu .ctx-sub .ctx-item { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 240px; }
/* The way back out of a sub-menu (the window-tour list). Quieter than an action, because it
 * is navigation rather than a thing that happens. */
.shell-menu .ctx-back { color: var(--muted); font-size: 12px; }
.shell-menu .ctx-back:hover { color: var(--ink); }
.shell-menu .ctx-sub-title { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); padding: 4px 12px 2px; }
.shell-menu .ctx-sub .ctx-item { padding-left: 20px; font-size: 12.5px; }

/* The workspace number, bottom-right, in the disabled-text colour. */
.ws-label {
  position: absolute; right: 14px; bottom: 10px; z-index: 35;
  font-size: 11.5px; color: var(--on-deep-faint); pointer-events: none; user-select: none;
}

/* F11 / full-screen button, left of the ? — same round chrome. */
.fs-btn {
  position: absolute; right: calc(var(--ctl-edge) + 34px); top: 6px; z-index: 60;
  width: 28px; height: 28px; border-radius: 50%; padding: 0;
  font-family: var(--font-display); font-weight: 700; font-size: 9.5px; letter-spacing: .02em;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-soft);
  box-shadow: var(--shadow-md);
}
.fs-btn:hover { background: var(--surface-2); color: var(--teal); box-shadow: var(--shadow-md), var(--glow); }

/* Tablet-mode and Ctrl-latch round buttons, left of F11 — same chrome. */
.tab-btn, .ctrl-btn {
  position: absolute; top: 6px; z-index: 60;
  width: 28px; height: 28px; border-radius: 50%; padding: 0;
  font-family: var(--font-display); font-weight: 700; font-size: 9.5px;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-soft);
  box-shadow: var(--shadow-md);
}
.tab-btn { right: calc(var(--ctl-edge) + 72px); font-size: 14px; }
.ctrl-btn { right: calc(var(--ctl-edge) + 110px); }
.tab-btn:hover, .ctrl-btn:hover { background: var(--surface-2); color: var(--teal); box-shadow: var(--shadow-md), var(--glow); }
.tab-btn.on, .ctrl-btn.on { background: var(--teal); color: var(--on-accent); border-color: var(--teal); }
/* Tablet mode: the desk's own controls grow too. */
body.tablet-mode .tour-btn, body.tablet-mode .fs-btn, body.tablet-mode .tab-btn, body.tablet-mode .ctrl-btn { width: 40px; height: 40px; }
body.tablet-mode .tour-btn { right: var(--ctl-edge); } body.tablet-mode .fs-btn { right: calc(var(--ctl-edge) + 48px); } body.tablet-mode .tab-btn { right: calc(var(--ctl-edge) + 96px); } body.tablet-mode .ctrl-btn { right: calc(var(--ctl-edge) + 144px); }
body.tablet-mode .dock-tile { width: 56px; height: 62px; } body.tablet-mode .dock-tile img { width: 44px; height: 44px; }
body.tablet-mode .win-light { width: 18px; height: 18px; } body.tablet-mode .win-bar { height: 48px; }
body.tablet-mode .nav-item { padding: 12px 12px; min-height: 44px; }
/* Tablet mode grows the art too, and it must come DOWN by the same ruling — 64 was left
 * behind on 2026-09-09 when the desk art went to 45px, and 64 in a 104px row pitch is the
 * very overlap being fixed (a 115px tile). One property, not a width/height pair, so the
 * harness has a single number to read for this mode as well. */
body.tablet-mode { --dt-art: 51px; }
body.tablet-mode .rail-resizer { width: 14px; }
body.tablet-mode .win-rs.rs-n, body.tablet-mode .win-rs.rs-s { height: 14px; }
body.tablet-mode .win-rs.rs-e, body.tablet-mode .win-rs.rs-w { width: 14px; }

/* Maximised window vs the control row: the row overlays the title bar's
   right end. LTR lights are on the left (no clash); the centred title gets
   room on the right. In RTL the lights ARE on the right, so the whole row
   steps left past them. */
.win.maximised .win-bar { padding-right: 200px; }
body.tablet-mode .win.maximised .win-bar { padding-right: 250px; }
html[dir="rtl"] .win-bar { flex-direction: row-reverse; }
html[dir="rtl"] .win-title { margin-right: 0; margin-left: calc(53px + var(--win-lights-indent)); }
html[dir="rtl"] .win-lights { margin-left: 0; margin-right: var(--win-lights-indent); }
html[dir="rtl"] .win.maximised .win-bar { padding-right: 0; padding-left: 200px; }
html[dir="rtl"] .tour-btn, html[dir="rtl"] .fs-btn, html[dir="rtl"] .tab-btn, html[dir="rtl"] .ctrl-btn { right: auto; }
html[dir="rtl"] .tour-btn { left: var(--ctl-edge); }
html[dir="rtl"] .fs-btn { left: calc(var(--ctl-edge) + 34px); }
html[dir="rtl"] .tab-btn { left: calc(var(--ctl-edge) + 72px); }
html[dir="rtl"] .ctrl-btn { left: calc(var(--ctl-edge) + 110px); }
html[dir="rtl"] .ws-label { right: auto; left: 14px; }

/* RTL: the resize grip is on the rail's inner (left) edge. */
html[dir="rtl"] .rail-resizer { right: auto; left: 0; }


/* Keyboard hints: bottom-right, above the workspace label, fade in and out. */
.ws-hint {
  position: absolute; right: 14px; bottom: 30px; z-index: 36;
  font-size: 12px; color: var(--ink-soft); background: var(--surface);
  border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px;
  opacity: 0; transform: translateY(4px); transition: opacity .18s, transform .18s; pointer-events: none;
}
.ws-hint.show { opacity: 1; transform: none; }
html[dir="rtl"] .ws-hint { right: auto; left: 14px; }
@media (prefers-reduced-motion: reduce) { .ws-hint { transition: none; } }

/* The toggle glyphs are drawn, not written: isolated LTR so the bidi
   algorithm can never mirror them inside a Hebrew/Arabic page. */
.rail-toggle, .rail-btn { direction: ltr; unicode-bidi: isolate; font-size: 11px; }

/* ============================================================ strategic twin
   The cockpit. Light like the rest of the product — gen 1's dark palette was
   Power BI chrome, not brand. Nodes are compact pills that expand IN PLACE:
   the grid cell grows, neighbours reflow, and the arrows redraw from the
   nodes' real positions afterwards. */
.tw-wrap { display: flex; flex-direction: column; gap: 8px; min-height: 0; flex: 1; }
.tw-canvas { display: flex; min-height: 0; flex: 1; border: 1px solid var(--line, #dfe5ea); border-radius: 10px; overflow: hidden; background: #fbfcfd; }
.tw-lane-label { display: flex; align-items: center; padding: 0 10px; font-size: 12px; font-weight: 600; color: #40525f; border-top: 1px solid var(--line, #e5eaee); background: #f4f7f9; position: sticky; left: 0; z-index: 3; border-right: 1px solid var(--line, #dfe5ea); }
.tw-corner { position: sticky; left: 0; top: 0; z-index: 4; background: #f4f7f9; border-right: 1px solid var(--line, #dfe5ea); border-bottom: 1px solid var(--line, #e5eaee); }
.tw-scroll { position: relative; overflow: auto; flex: 1; }
.tw-grid { display: grid; grid-auto-flow: row; grid-template-rows: 34px repeat(5, minmax(120px, auto)); min-width: 100%; min-height: 100%; }
.tw-cycle-head { display: flex; align-items: center; gap: 8px; padding: 0 12px; font-size: 12px; font-weight: 700; color: #55656f; border-left: 1px dashed #d7dee4; border-bottom: 1px solid var(--line, #e5eaee); position: sticky; top: 0; background: #f4f7f9; z-index: 2; }
.tw-cycle-head.tw-current { color: #0f8a7a; border-left: 2px solid #0f8a7a; }
.tw-cell { border-left: 1px dashed #e2e8ed; border-top: 1px solid #eef2f5; padding: 10px; display: flex; flex-wrap: wrap; gap: 10px; align-content: flex-start; }
.tw-cell.tw-current-col { background: rgba(15, 138, 122, 0.035); }
.tw-chip.tw-now { background: #0f8a7a; color: #fff; }

.tw-node { position: relative; z-index: 1; border: 2px solid #b9c6cf; border-radius: 14px; background: #fff; padding: 8px 10px; min-width: 96px; max-width: 128px; cursor: pointer; box-shadow: 0 1px 3px rgba(20, 40, 60, 0.08); transition: box-shadow 0.15s, border-color 0.15s, max-width 0.18s ease; user-select: none; }
.tw-node:hover { border-color: #7f97a6; }
.tw-node.tw-sel { border-color: #0f8a7a; box-shadow: 0 0 0 3px rgba(15, 138, 122, 0.22); }
.tw-node.tw-draft { border-style: dashed; }
.tw-node.tw-locked { opacity: 0.65; background: #f2f4f6; }
.tw-node.tw-openN { max-width: 260px; min-width: 230px; z-index: 3; }
.tw-node-head { display: flex; align-items: flex-start; gap: 6px; }
.tw-node-label { font-size: 12px; font-weight: 700; color: #24343f; line-height: 1.25; flex: 1; }
.tw-caret { flex: 0 0 auto; width: 20px; height: 20px; border-radius: 6px; border: 1px solid #ccd6dd; background: #f6f8fa; font-size: 13px; line-height: 1; cursor: pointer; color: #47606f; }
.tw-caret:hover { background: #e9eef2; }
.tw-badge { position: absolute; top: -8px; right: -8px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px; background: #0f8a7a; color: #fff; font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 1px 2px rgba(0,0,0,0.25); }
.tw-card { margin-top: 8px; border-top: 1px solid #e7ecf0; padding-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.tw-card-plan { font-size: 12.5px; color: #1e2c36; }
.tw-card-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; }
.tw-chip { display: inline-flex; align-items: center; padding: 1px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em; background: #e8eef2; color: #44565f; text-transform: uppercase; }

.tw-arrows { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.tw-arrows path, .tw-arrows polygon, .tw-arrows text, .tw-arrows circle { pointer-events: auto; }
.tw-arrow-label { font-size: 11.5px; font-weight: 700; font-family: ui-monospace, Consolas, monospace; }
/* Cockpit right-click menu (nodes and arrows) — gen-1 parity */
.tw-ctx { position: fixed; z-index: 100000; min-width: 190px; background: #fff; border: 1px solid var(--line, #dfe5ea); border-radius: 9px; box-shadow: 0 14px 40px rgba(20, 40, 60, 0.22); padding: 5px; }
.tw-ctx-item { display: block; width: 100%; text-align: left; background: none; border: 0; border-radius: 6px; padding: 7px 11px; font-size: 13px; color: var(--ink, #1f2d3a); cursor: pointer; }
.tw-ctx-item:hover { background: rgba(15, 138, 122, 0.10); }
.tw-ctx-item.danger { color: #c0392b; }
.tw-ctx-item.danger:hover { background: rgba(192, 57, 43, 0.10); }
.tw-ctx-sep { height: 1px; background: var(--line, #dfe5ea); margin: 4px 6px; }

.tw-panel { border: 1px solid var(--line, #dfe5ea); border-radius: 10px; background: #fff; padding: 10px 12px; max-height: 320px; overflow: auto; box-shadow: 0 4px 14px rgba(20, 40, 60, 0.08); }
.tw-panel-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.tw-kpis { display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: 10px; }
.tw-kpis > div { display: flex; flex-direction: column; }
.tw-kpis b { font-size: 18px; color: #17313f; }
.tw-kpis span { font-size: 11px; color: #64747f; }
.tw-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tw-table th { text-align: left; color: #64747f; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; padding: 4px 8px; border-bottom: 1px solid #e5eaee; }
.tw-table td { padding: 5px 8px; border-bottom: 1px solid #f0f3f6; }
.tw-table tr.tw-orphan td { background: #fdf3f2; }
.tw-report-row { padding: 7px 4px; border-bottom: 1px solid #f0f3f6; font-size: 13px; }
.tw-legend { display: flex; gap: 18px; align-items: center; padding: 2px 4px; flex-wrap: wrap; }
.tw-legend-item { display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px; color: #55656f; }
.tw-legend-line { display: inline-block; width: 34px; border-radius: 2px; }

/* RTL: the lane labels move to the right edge with the rest of the shell. */
html[dir="rtl"] .tw-lane-label, html[dir="rtl"] .tw-corner { border-right: none; border-left: 1px solid var(--line, #dfe5ea); right: 0; left: auto; }
html[dir="rtl"] .tw-cycle-head, html[dir="rtl"] .tw-cell { border-left: none; border-right: 1px dashed #e2e8ed; }

.tw-backed { color: #0f8a7a; font-size: 12px; }

/* ------------------------------------------------------------ agents (agents.js) */
.ag-content { overflow: auto; }
.ag-wrap { padding: 16px 24px; display: flex; flex-direction: column; gap: 14px; }
.ag-note { background: var(--tint); border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; font-size: 13px; }
.ag-hint { color: var(--muted); max-width: 720px; }
.ag-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.ag-card { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; background: var(--surface); cursor: pointer; display: flex; flex-direction: column; gap: 6px; }
.ag-card.on { border-color: var(--teal-dim); }
.ag-card.sel { box-shadow: 0 0 0 2px var(--teal); }
.ag-card.shut { opacity: .6; }
.ag-card-top { display: flex; justify-content: space-between; align-items: center; }
.ag-pill { font-size: 11px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.ag-pill.on { border-color: var(--teal-dim); color: var(--teal-dim); }
.ag-bar { height: 5px; background: var(--line); border-radius: 3px; overflow: hidden; }
.ag-bar-fill { height: 100%; background: var(--teal-dim); }
.ag-pane { display: flex; flex-direction: column; gap: 12px; }
.ag-panel { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); padding: 12px 14px; }
.ag-panel-head { font-family: var(--font-display); font-weight: 600; margin-bottom: 8px; color: var(--navy); }
.ag-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.ag-phases { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.ag-phase { border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; font-size: 12.5px; display: flex; flex-direction: column; }
.ag-phase.passed { border-color: var(--teal-dim); }
.ag-phase.active { box-shadow: 0 0 0 2px var(--teal); }
.ag-missing { margin: 0; padding-left: 18px; }
.ag-missing li { margin-bottom: 8px; }
.ag-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ag-table th, .ag-table td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.ag-sugg { border-top: 1px solid var(--line); padding: 8px 0; display: flex; flex-direction: column; gap: 6px; }
.ag-sugg:first-child { border-top: none; }
.ag-feed, .ag-bubbles { display: flex; flex-direction: column; gap: 8px; }
.ag-msg { max-width: 78%; border-radius: 14px; padding: 8px 12px; background: var(--tint); border: 1px solid var(--line); }
.ag-msg.me { align-self: flex-end; background: var(--surface); border-color: var(--teal-dim); }
.ag-msg.them { align-self: flex-start; }
.ag-msg.agent { border-style: dashed; }
.ag-msg-meta { font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.ag-chat-wrap { display: grid; grid-template-columns: 260px 1fr; height: 100%; min-height: 420px; }
.ag-rooms { border-right: 1px solid var(--line); overflow: auto; display: flex; flex-direction: column; }
.ag-room { text-align: left; border: none; border-bottom: 1px solid var(--line); background: none; padding: 10px 12px; cursor: pointer; display: flex; flex-direction: column; gap: 2px; color: inherit; font: inherit; }
.ag-room.sel { background: var(--tint); }
.ag-chat { display: flex; flex-direction: column; height: 100%; }
.ag-chat-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.ag-people { display: flex; gap: 4px; flex-wrap: wrap; }
.ag-bubbles { flex: 1; overflow: auto; padding: 14px; }
.ag-composer { display: flex; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--line); align-items: flex-end; }
.ag-input { flex: 1; resize: none; border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; font: inherit; background: var(--surface); color: inherit; }
.ag-form { display: flex; flex-direction: column; gap: 10px; }
.ag-form label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.ag-form input, .ag-form select, .ag-form textarea { font: inherit; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: inherit; }
.ag-result { display: flex; flex-direction: column; gap: 6px; }
.ag-result > div { display: flex; gap: 12px; }

/* agents — UX pass 2026-09-03: next-step callout, tabs, strip, forms, scores */
.ag-strip { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px; }
.ag-tile { flex: 0 0 210px; text-align: left; border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; background: var(--surface); cursor: pointer; display: flex; flex-direction: column; gap: 6px; color: inherit; font: inherit; }
.ag-tile.on { border-color: var(--teal-dim); }
.ag-tile.sel { box-shadow: 0 0 0 2px var(--teal); }
.ag-tile.shut { opacity: .55; }
.ag-tile-top { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.ag-bar.ghost { background: transparent; border: 1px dashed var(--line); }
.ag-hero { border: 1px solid var(--line); border-radius: 14px; padding: 22px 26px; background: var(--surface); max-width: 720px; display: flex; flex-direction: column; gap: 10px; }
.ag-hero h2 { margin: 0; font-family: var(--font-display); }
.ag-big { align-self: flex-start; padding: 10px 18px; font-size: 15px; }
.ag-head { display: grid; grid-template-columns: 1fr minmax(280px, 380px); gap: 16px; border: 1px solid var(--line); border-radius: 14px; padding: 14px 18px; background: var(--surface); }
.ag-head h2 { margin: 0 0 8px; font-family: var(--font-display); display: flex; gap: 10px; align-items: center; }
.ag-head-main { min-width: 0; }
.ag-head-side { display: flex; flex-direction: column; gap: 10px; }
.ag-stepper { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.ag-step { font-size: 12px; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.ag-step.passed { border-color: var(--teal-dim); color: var(--teal-dim); }
.ag-step.now { background: var(--tint); color: var(--navy); border-color: var(--teal); font-weight: 600; }
.ag-next { border: 1px solid var(--teal-dim); background: var(--tint); border-radius: 12px; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; font-size: 13.5px; }
.ag-next .btn { align-self: flex-start; }
.ag-more { position: relative; display: inline-block; }
.ag-more summary { list-style: none; cursor: pointer; display: inline-block; }
.ag-more summary::-webkit-details-marker { display: none; }
.ag-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 30; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 6px; display: flex; flex-direction: column; gap: 4px; min-width: 220px; box-shadow: 0 8px 24px rgba(0,0,0,.18); }
.ag-menu .btn { text-align: left; justify-content: flex-start; }
.ag-quiet { opacity: .75; }
.ag-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); }
.ag-tab { border: none; background: none; padding: 8px 14px; cursor: pointer; font: inherit; color: var(--muted); border-bottom: 2px solid transparent; display: flex; gap: 6px; align-items: center; }
.ag-tab.sel { color: var(--navy); border-bottom-color: var(--teal); font-weight: 600; }
.ag-count { font-size: 11px; background: var(--tint); border: 1px solid var(--line); border-radius: 999px; padding: 0 7px; }
.ag-list { display: flex; flex-direction: column; gap: 10px; }
.ag-group-head { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: 6px 0 4px; }
.ag-row { display: flex; gap: 12px; align-items: center; border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; background: var(--surface); }
.ag-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ag-row-actions { display: flex; gap: 6px; flex-shrink: 0; }
.ag-empty { text-align: center; color: var(--muted); padding: 34px 20px; display: flex; flex-direction: column; gap: 12px; align-items: center; }
.ag-empty p { max-width: 520px; margin: 0; }
.ag-split { display: grid; grid-template-columns: 250px 1fr; height: 100%; min-height: 420px; }
.ag-room.closed { opacity: .6; }
.ag-day { align-self: center; font-size: 11.5px; color: var(--muted); background: var(--tint); border-radius: 999px; padding: 2px 10px; margin: 4px 0; }
.ag-typing { opacity: .7; font-style: italic; }
.ag-closed { padding: 12px 14px; border-top: 1px solid var(--line); }
.ag-field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.ag-field > span { color: var(--muted); }
.ag-in { font: inherit; padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: inherit; width: 100%; box-sizing: border-box; }
.ag-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ag-checks { display: flex; flex-direction: column; gap: 4px; max-height: 200px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; padding: 6px 8px; }
.ag-check { display: flex; gap: 8px; align-items: center; font-size: 13px; cursor: pointer; }
.ag-scores { display: flex; gap: 10px; }
.ag-score { flex: 1; border: 1px solid var(--line); border-radius: 12px; padding: 8px 12px; display: flex; flex-direction: column; background: var(--tint); }
.ag-score small { color: var(--muted); }
.ag-score b { font-family: var(--font-display); font-size: 28px; line-height: 1.1; }
.ag-score.good { border-color: #1E8E6E; }
.ag-score.bad { border-color: var(--crimson); }
.ag-delta { font-size: 12px; }
.ag-score.good .ag-delta { color: #1E8E6E; }
.ag-score.bad .ag-delta { color: var(--crimson); }
.ag-deltas { margin: 0; padding-left: 20px; }
.ag-deltas li { margin-bottom: 6px; }
@media (max-width: 760px) { .ag-head { grid-template-columns: 1fr; } .ag-split { grid-template-columns: 1fr; } .ag-rooms { max-height: 160px; border-right: none; border-bottom: 1px solid var(--line); } }

/* ================================================================ map columns
   Resizable and collapsible columns on the Business Reality Map (2026-09-08).
   Requirements 1, 2, 5 and 6: drag an edge, collapse to one character, a ⋮ menu
   per header, counts everywhere, and a header that filters when clicked. */

/* THE HEADER IS A POSITIONING CONTEXT for the resize strip and the ⋮ button, and it
   already has `position: sticky` — which establishes one, so nothing more is needed.
   `padding-right` leaves room for the two controls so a long column name does not run
   underneath them. */
.plan-head { padding-right: 30px; }
.plan-head .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Drag to resize. Four pixels wide with a wider invisible grab area, because a 4px target
   is a test of aim rather than a control. The line only appears on hover so the header
   does not look like a table of boxes at rest. */
.col-resize {
  position: absolute; top: 0; right: -3px; bottom: 0;
  width: 9px; cursor: col-resize; z-index: 6;
  background: transparent;
  /* The visible hairline sits in the middle of the grab area. */
  border-left: 3px solid transparent;
}
.col-resize:hover { border-left-color: var(--teal, #0E9F8A); }
/* While dragging, every cursor in the window agrees what is happening — without this the
   pointer flickers back to the arrow the moment it leaves the 9px strip. */
body.col-resizing, body.col-resizing * { cursor: col-resize !important; }
/* And no text gets selected mid-drag. */
body.col-resizing { user-select: none; }

/* The ⋮ menu. Dim until the header is hovered: it is a control for a deliberate act, not
   part of the reading. Always visible on a collapsed header, where it is the only way back
   apart from clicking the sliver. */
.col-menu {
  position: absolute; top: 6px; right: 6px;
  width: 18px; height: 20px; padding: 0;
  border: 0; border-radius: 4px;
  background: transparent; color: var(--ink-soft, #6B7280);
  font-size: 13px; line-height: 1; cursor: pointer;
  opacity: 0; transition: opacity .12s ease;
}
.plan-head:hover .col-menu, .col-menu:focus-visible { opacity: 1; }
.col-menu:hover { background: var(--surface, rgba(255,255,255,.08)); color: var(--ink); }

/* COLLAPSED: one glyph and nothing else (requirement 5).
   The name lives in the `title`, so hovering reads it — which is exactly what was asked
   for, and it is why no ellipsis is used here: at this width an ellipsis IS the label. */
.plan-head.collapsed {
  padding: 11px 2px; justify-content: center; cursor: pointer;
  writing-mode: horizontal-tb;
}
.plan-head.collapsed .nm {
  font-size: 13px; font-weight: 700; letter-spacing: 0;
  text-overflow: clip; text-align: center; width: 100%;
}
.plan-head.collapsed .dot { display: none; }   /* no room, and the letter carries the identity */
.plan-head.collapsed .col-menu { opacity: .7; top: 2px; right: 1px; }
.plan-head.collapsed:hover { background: var(--surface, rgba(255,255,255,.06)); }

/* The cells of a collapsed column: a count, centred, or nothing at all. No cards are built
   for them at all — see the render, which skips them rather than clipping them. */
.plan-cell.collapsed {
  display: flex; align-items: flex-start; justify-content: center;
  padding: 8px 2px; overflow: hidden;
}
.plan-cell.collapsed .collapsed-n {
  font-size: 11px; font-weight: 700;
  color: var(--ink-soft, #6B7280);
  background: var(--surface, rgba(255,255,255,.06));
  border-radius: 999px; padding: 1px 5px;
}

/* A header the map is currently filtered to. Clicking it again lets everything back in, so
   the state has to be visible or the second click is a guess. */
.plan-head.only, .plan-lane.only {
  box-shadow: inset 0 -2px 0 var(--teal, #0E9F8A);
}
.plan-head.only .count-badge, .plan-lane.only .count-badge { color: var(--teal, #0E9F8A); }
/* Only a row that holds something is clickable, and the cursor says which. */
.plan-lane.clickable { cursor: pointer; }
.plan-lane.clickable:hover { background: var(--surface, rgba(255,255,255,.06)); }
.plan-head:not(.collapsed) { cursor: default; }
.plan-head:not(.collapsed):hover { background: var(--surface, rgba(255,255,255,.04)); }

/* ---------------------------------------------------------------- counts on the filters */
/* Requirement 7: the number rides in the button, so what to filter to is readable at a
   glance in a meeting. Dimmer than the label — it is the second thing you read, not the
   first — and tabular figures so a column of chips does not jitter. */
.chip .chip-n {
  margin-left: 5px; opacity: .6;
  font-variant-numeric: tabular-nums;
  font-size: 11px;
}
.chip.active .chip-n { opacity: .85; }
/* Says a column is collapsed on the map, so a chip that filters to a sliver explains
   itself rather than looking like it did nothing. */
.chip .chip-collapsed { margin-left: 4px; opacity: .7; font-size: 10px; }

/* The language picker while a switch is still landing (2026-09-08).
   Disabled, and it must LOOK disabled — a greyed control that still looks clickable gets
   clicked, and a second switch mid-flight discards translations already paid for in tokens.
   The cursor says "wait" rather than "no": this resolves on its own in a second or two. */
.lang-pick.busy { opacity: .6; }
.lang-pick.busy, .lang-pick.busy .lang-sel { cursor: progress; }
.lang-sel:disabled { cursor: progress; }

/* The month's language allowance, under the picker (2026-09-08).
   Small and quiet: it is a fact somebody needs once, not a warning. Turns amber only when
   the allowance is gone, which is the one state that changes what they can do. */
.lang-quota { font-size: 11px; opacity: .6; margin: 3px 0 0 2px; }
.lang-quota.spent { color: var(--amber, #B45309); opacity: .95; }
/* The number sits tight against its words. */
.lang-quota b { font-weight: 700; margin-right: 4px; }

/* ---------------------------------------------------------------- the filter strip folds
   Freddy asked twice for this area to be collapsible, which is what asking for something
   with no visible affordance looks like. The bar now always shows ONE line — the caret and
   the with-data button — and the rows of chips fold away beneath it. Hiding the whole bar
   (what it did before) took the way back off the screen with it. */
#plan-filterbar { display: flex; align-items: flex-start; gap: 8px; flex-wrap: nowrap; }
.filter-rows { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; flex: 1 1 auto; }

/* The caret IS the left-menu toggle: it carries `.rail-toggle` for its shape, so this rule
   only stops it stretching in the flex row and keeps it level with the chips beside it. The
   22x22 square, the radius, the border and the hover all come from .rail-toggle — one
   control, one appearance, wherever a strip of the interface folds away. */
.chip-caret { flex: none; margin-top: 1px; }

/* "With data only" — the one filter that needs no reading, so it sits outside the fold and
   is reachable even with the rows collapsed. */
.chip-data { flex: none; white-space: nowrap; }
.chip-data.active {
  border-color: var(--teal, #0E9F8A);
  color: var(--teal, #0E9F8A);
  background: color-mix(in srgb, var(--teal, #0E9F8A) 12%, transparent);
}

/* A header that filters when clicked has to look like it does (requirement 4). The pointer
   is the whole signal here: without it, a header that behaves like a button reads as a
   label, which is why "every column header becomes a toggle" was reported as not working
   when the handler was already there. */
.plan-head:not(.collapsed) { cursor: default; }
.plan-head.clickable:not(.collapsed) { cursor: pointer; }
.plan-head.clickable:not(.collapsed):hover { background: var(--surface, rgba(255,255,255,.07)); }
.plan-head.clickable .count-badge, .plan-lane.clickable .count-badge { text-decoration: underline dotted; }

/* A header count that is smaller than the row/column really holds, because filters are
   hiding the rest. Dotted underline and a help cursor: the number is true but incomplete,
   and the tooltip says what the full figure is. Without this, "(0)" over a column that holds
   57 elements looks like data loss rather than a filter. */
.count-badge.partial { text-decoration: underline dotted; cursor: help; opacity: .75; }

/* ================================================================ The Journey Explained
 *
 * The paradigm window (journey.js). Wider measure and bigger type than a working surface,
 * because this is read once, carefully, by somebody deciding whether the product is for them —
 * not scanned every day. Ruled 2026-09-09: "visual and graphically not so much texts".
 */
.jn { max-width: 1080px; }
.jn-open {
  font-size: 17px; line-height: 1.5; color: var(--ink);
  margin: 4px 0 18px; font-family: var(--font-display);
}
.jn-close {
  font-size: 15px; line-height: 1.55; color: var(--ink-soft);
  border-top: 1px solid var(--line); padding-top: 14px; margin-top: 22px;
}
.jn-block { margin: 26px 0; }
.jn-h {
  font-family: var(--font-display); font-size: 15px; font-weight: 600;
  margin: 0 0 4px; color: var(--ink);
}
.jn-lead { margin: 0 0 12px; color: var(--ink-soft); font-size: 13.5px; }

/* The diagrams. `width: 100%` with a viewBox and no height: the SVG keeps its own aspect
 * ratio at any window width, which is why this is inline SVG and not an image. */
.jn-svg-wrap {
  border: 1px solid var(--line); border-radius: 14px; padding: 10px 8px;
  background: var(--lift-1); overflow: hidden;
}
.jn-svg { width: 100%; height: auto; display: block; }
.jn-svg-title { font-size: 13px; font-weight: 600; fill: var(--ink); font-family: var(--font-display); }
.jn-svg-sub   { font-size: 11px; fill: var(--ink-soft); }
.jn-svg-out   { font-size: 10.5px; fill: var(--ink-soft); opacity: .9; }
.jn-svg-loop  { font-size: 11px; fill: var(--gold, #E8A33D); }
.jn-svg-big   { font-size: 20px; font-weight: 700; fill: var(--gold, #E8A33D); font-family: var(--font-display); }

/* Four concept cards, two up on a laptop and one up in a narrow window. */
.jn-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.jn-card {
  position: relative; border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px 12px 40px; background: var(--surface);
}
.jn-card b { display: block; margin-bottom: 4px; font-size: 13.5px; color: var(--ink); }
.jn-card p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); }
.jn-num {
  position: absolute; left: 12px; top: 12px;
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: var(--deep);
  background: var(--teal);
}

/* One row per agent: its own icon, its name, and the one thing it does. */
.jn-agents { display: grid; gap: 10px; }
.jn-agent { display: flex; gap: 12px; align-items: flex-start; }
.jn-agent-icon { width: 34px; height: 34px; flex: 0 0 34px; }
.jn-agent b { font-size: 13px; color: var(--ink); }
.jn-agent p { margin: 2px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); }

html[dir="rtl"] .jn-card { padding: 12px 40px 12px 14px; }
html[dir="rtl"] .jn-num { left: auto; right: 12px; }

/* ================================================================ The Company Profile
 *
 * A form, deliberately plain — the company's own facts, not a dashboard. Two columns on a
 * laptop, one in a narrow window; addresses span both because an address in a half-width box
 * is an address nobody can read back.
 */
.cp { max-width: 900px; }
.cp-company { font-family: var(--font-display); font-size: 18px; margin: 2px 0 14px; color: var(--ink); }
.cp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
.cp-field { display: flex; flex-direction: column; gap: 4px; }
.cp-field.wide { grid-column: 1 / -1; }
.cp-label { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.cp-field small { font-size: 11.5px; line-height: 1.4; }
.cp-actions { margin: 20px 0 4px; }

/* What the sector brought in, in the same window as the dropdown that causes it. */
.cp-frameworks { margin-top: 26px; border-top: 1px solid var(--line); padding-top: 16px; }
.cp-frameworks h3 { font-family: var(--font-display); font-size: 14px; margin: 0 0 6px; color: var(--ink); }
.cp-fw-list { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 6px; }
.cp-fw-list li {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); font-size: 12.5px; color: var(--ink-soft);
}
/* In use is the state that matters, so it is the one that is marked. */
.cp-fw-list li.on { border-color: var(--teal); }
.cp-fw-list li b { color: var(--ink); font-weight: 600; }
.cp-fw-state { margin-left: auto; font-size: 11.5px; color: var(--muted); }
.cp-fw-tag {
  font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 5px; background: var(--lift-2); color: var(--muted);
}
html[dir="rtl"] .cp-fw-state { margin-left: 0; margin-right: auto; }
