/* =====================================================================
   ANOME.

   Mobile-first at 392px. Approving from a phone is the case this is
   built for, not the degraded one.

   Glow is semantic and rationed. Brightness means attention: amber
   waits, rose is running out, emerald is settled. Anything clear stays
   dim. If everything glows, nothing reads.
   ===================================================================== */

/* Self-hosted. A Google Fonts request from every approval would leak
   usage of an internal system to a third party. */
@font-face { font-family: Inter; src: url(/fonts/inter-400.woff2) format("woff2");
  font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: Inter; src: url(/fonts/inter-500.woff2) format("woff2");
  font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: Inter; src: url(/fonts/inter-600.woff2) format("woff2");
  font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url(/fonts/plexmono-400.woff2) format("woff2");
  font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url(/fonts/plexmono-500.woff2) format("woff2");
  font-weight: 500; font-style: normal; font-display: swap; }

:root {
  --bg: #070A11;

  --card: linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.028));
  --card-open: linear-gradient(180deg, rgba(255,255,255,.075), rgba(255,255,255,.04));
  --edge: rgba(255,255,255,.085);
  --edge-hi: rgba(255,255,255,.22);

  --ink: #E7ECF3;
  --ink-dim: #97A1B4;   /* design system names only txt/txt-2; this sits between
                           them, because two greys could not carry metadata,
                           secondary text and disabled state at once */
  --ink-faint: #6F798A;

  --amber: #F59E0B;
  --rose: #F43F5E;
  --emerald: #10B981;
  --cyan: #22D3EE;      /* agents - reserved, nothing uses it yet */
  --violet: #8B5CF6;
  --slate: #94A3B8;
  --blue: #4C8DF6;
  --azure: #5B99FF;     /* the primary button gradient, per section 5 */
  --azure-deep: #2F6FE0;

  --r: 14px;
  --r-sm: 10px;
  --r-xs: 8px;
  --pill: 99px;

  --ui: Inter, -apple-system, "Segoe UI", system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --pad: 18px;
  }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html { background: var(--bg); }

/* Depth, not colour. Two large soft fields over near-black - blue
   falling from the top-left, violet rising from the bottom-right - both
   far too faint to read as hue on their own. */
body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  font: 400 13px/1.55 var(--ui);
  letter-spacing: -.003em;
  -webkit-font-smoothing: antialiased;
  background:
    radial-gradient(95% 62% at 6% -6%, rgba(64, 122, 255, .10) 0%, transparent 62%),
    radial-gradient(85% 58% at 104% 106%, rgba(139, 92, 246, .085) 0%, transparent 60%),
    var(--bg);
  background-attachment: fixed;
  padding-bottom: env(safe-area-inset-bottom);
  }

/* ---------------------------------------------------------------- bar */
.bar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px;
  padding: calc(11px + env(safe-area-inset-top)) var(--pad) 11px;
  background: rgba(7,10,17,.78);
  backdrop-filter: blur(20px) saturate(140%);
  border-bottom: 1px solid var(--edge);
  }

.brand { font: 600 9px/1 var(--ui); letter-spacing: .22em; color: var(--ink-dim); }

/* The acting seat may never be ambiguous. It is in the bar on every
   screen, at every width. */
.acting {
  margin-left: auto;
  display: flex; align-items: center; gap: 7px;
  padding: 6px 12px;
  background: var(--card);
  border: 1px solid var(--edge-hi);
  border-radius: var(--pill);
  min-width: 0;
  }
.acting .eye {
  font: 500 9px/1 var(--mono);
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-faint); white-space: nowrap;
  }
.acting select {
  font: 600 12.5px var(--ui);
  color: var(--ink); background: transparent; border: 0;
  padding: 0 15px 0 0; max-width: 34vw; appearance: none;
  text-overflow: ellipsis; overflow: hidden; white-space: nowrap;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-dim) 50%),
    linear-gradient(135deg, var(--ink-dim) 50%, transparent 50%);
  background-size: 4px 4px, 4px 4px;
  background-position: right 4px center, right 0 center;
  background-repeat: no-repeat;
  }
.acting select option { background: #10141d; color: var(--ink); }
.acting .basis { font: 400 9px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }
.acting .basis.delegated { color: var(--amber); }

.person { display: none; font: 400 11.5px var(--ui); color: var(--ink-faint); }

/* --------------------------------------------------------------- tabs */
.tabs {
  display: flex; gap: 2px;
  padding: 10px var(--pad) 0;
  border-bottom: 1px solid var(--edge);
  overflow-x: auto; scrollbar-width: none;
  }
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
  font: 500 12.5px var(--ui);
  color: var(--ink-faint); background: none; border: 0;
  border-bottom: 2px solid transparent;
  padding: 8px 11px 10px; cursor: pointer; white-space: nowrap;
  }
.tabs button.on { color: var(--ink); border-bottom-color: var(--azure); }

main { padding: 18px var(--pad) 100px; }

h2 { font: 600 17px/1.25 var(--ui); letter-spacing: -.02em; margin: 0 0 4px; }
.sub { color: var(--ink-faint); font-size: 12px; margin: 0 0 18px; max-width: 62ch; }

/* Section labels are quiet metadata, not headings. */
.label {
  font: 500 9px/1 var(--mono);
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-faint);
  }

/* ------------------------------------------------------------ stepper */
.stepper { margin-bottom: 18px; }
.stepper .dots {
  display: flex; align-items: center; gap: 8px;
  overflow-x: auto; scrollbar-width: none; padding: 4px 0;
  }
.stepper .dots::-webkit-scrollbar { display: none; }
.stepper .dot {
  flex: none;
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  font: 500 10px/1 var(--mono);
  background: rgba(255,255,255,.045);
  border: 1px solid var(--edge);
  color: var(--ink-faint);
  }
.stepper .dot.done {
  background: rgba(95,211,166,.16);
  border-color: rgba(95,211,166,.45);
  color: var(--emerald);
  }
.stepper .dot.here {
  background: radial-gradient(circle at 50% 38%, #7FB0FF, var(--azure-deep));
  border-color: transparent;
  color: #fff;
  box-shadow: 0 0 0 4px rgba(91,153,255,.20), 0 3px 14px -4px rgba(91,153,255,.7);
  }
.stepper .legend {
  display: flex; justify-content: space-between; margin-top: 11px;
  font: 400 9px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-faint);
  }

/* -------------------------------------------------------------- cards */
.card {
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: var(--r);
  backdrop-filter: blur(10px);
  padding: 14px;
  margin-bottom: 8px;
  }

/* Glow only where the state earns it. */
.card.attn   { border-color: rgba(242,183,92,.30); box-shadow: 0 8px 34px -16px rgba(242,183,92,.5); }
.card.urgent { border-color: rgba(242,119,138,.38); box-shadow: 0 8px 38px -14px rgba(242,119,138,.55); }
.card.blocked { opacity: .86; }
.card.here { border-color: rgba(91,153,255,.42); box-shadow: 0 8px 34px -16px rgba(91,153,255,.6); }

.headline {
  font: 600 21px/1.2 var(--ui);
  letter-spacing: -.02em;
  margin: 10px 0 4px;
  }
.detail { font-size: 13px; color: var(--ink-dim); margin-bottom: 3px; }
.detail .strong { color: var(--ink); }
.origin { font-size: 12px; color: var(--ink-faint); margin-bottom: 13px; }
.origin .seat { color: var(--ink-dim); }

/* ---------------------------------------------------------------- pips */
/* Colour never carries meaning alone - every state has its own glyph. */
.pips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 13px; }
.pip {
  display: inline-flex; align-items: center; gap: 6px;
  font: 500 10.5px/1 var(--mono); letter-spacing: .02em;
  padding: 6px 10px; border-radius: var(--pill);
  border: 1px solid var(--edge); color: var(--ink-dim);
  white-space: nowrap;
  }
.pip .g { font-size: .9em; }
.pip.wait     { color: var(--amber);   border-color: rgba(242,183,92,.34); }
.pip.expiring { color: var(--rose);    border-color: rgba(242,119,138,.40); }
.pip.ok       { color: var(--emerald); border-color: rgba(95,211,166,.34); }
.pip.money    { color: var(--ink); border-color: var(--edge-hi); background: rgba(255,255,255,.045); }
.pip.stop     { color: var(--ink-faint); }

/* The domain pill's colour is chosen on the domain row and constrained
   to this palette by migration 007. Degrees live here because what a
   name looks like on screen is the interface's business; which name a
   domain wears is the database's. */
.hue-blue    { --hue: 217; --hex: #4C8DF6; }
.hue-cyan    { --hue: 189; --hex: #22D3EE; }
.hue-violet  { --hue: 258; --hex: #8B5CF6; }
.hue-emerald { --hue: 160; --hex: #10B981; }
.hue-amber   { --hue: 38;  --hex: #F59E0B; }
.hue-rose    { --hue: 350; --hex: #F43F5E; }
.hue-slate   { --hue: 215; --hex: #94A3B8; }

.pip.type {
  color: var(--ink);
  border-color: hsla(var(--hue), 72%, 66%, .38);
  background: hsla(var(--hue), 72%, 60%, .09);
  }
.pip.type.hue-slate { color: var(--ink-dim); }
.pip.type .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: hsl(var(--hue), 78%, 66%);
  box-shadow: 0 0 7px hsla(var(--hue), 78%, 66%, .8);
  }

/* ------------------------------------------------------------ payload */
.panel {
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  background: rgba(255,255,255,.016);
  overflow: hidden;
  }
.panel .kv {
  display: grid; grid-template-columns: 84px 1fr; gap: 12px;
  /* Section 6: payload rows are compact, roughly 20px tall, not 40. */
  padding: 3px 12px; border-bottom: 1px solid rgba(255,255,255,.055);
  align-items: baseline;
  }
.panel .kv:last-child { border-bottom: 0; }
.panel .k { font: 400 11.5px/1.3 var(--ui); color: var(--ink-faint); overflow-wrap: anywhere; }
.panel .v { font: 400 12.5px/1.3 var(--mono); color: var(--ink); overflow-wrap: anywhere; }

@media (min-width: 520px) { .panel .kv { grid-template-columns: 128px 1fr; } }

/* ------------------------------------------------------------ details */
/* Minimal by default: anything not needed to decide is folded away, and
   each fold is a card in its own right. */
details.fold {
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  background: rgba(255,255,255,.015);
  margin-top: 8px;
  overflow: hidden;
  }
details.fold[open] { background: var(--card-open); }
details.fold > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 9px;
  padding: 12px 13px;
  font: 500 9px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-dim); user-select: none;
  }
details.fold > summary::-webkit-details-marker { display: none; }
details.fold > summary::before {
  content: "+"; width: 16px; height: 16px; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--edge-hi); border-radius: 5px;
  font: 400 11px/1 var(--mono); color: var(--ink-dim);
  }
details.fold[open] > summary::before { content: "–"; }
details.fold > summary:hover { color: var(--ink); }
details.fold .body { padding: 0 13px 13px; }
details.fold + label.field { margin-top: 16px; }

.stamp { font: 400 11px/1.75 var(--mono); color: var(--ink-faint); overflow-wrap: anywhere; }
.stamp b { color: var(--ink-dim); font-weight: 400; }

/* ------------------------------------------------------------ buttons */
.actions { display: flex; gap: 8px; margin-top: 14px; }

button.btn {
  font: 600 13px var(--ui);
  padding: 12px 20px;
  border-radius: var(--pill);
  border: 1px solid var(--edge);
  background: rgba(255,255,255,.03);
  color: var(--ink-dim);
  cursor: pointer;
  min-height: 44px;
  transition: background .15s, color .15s, border-color .15s, box-shadow .15s;
  }

/* Approve carries the weight. Reject is nearly invisible until you go
   for it - it is not the dangerous one, it is just the other one. */
button.btn.primary {
  flex: 1;
  color: #fff;
  border-color: transparent;
  background:
    linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,0) 42%),
    linear-gradient(180deg, var(--azure) 0%, var(--azure-deep) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.35),
    0 6px 22px -8px rgba(91,153,255,.75);
  }
button.btn.primary:hover { filter: brightness(1.07); }

button.btn.quiet { background: transparent; border-color: transparent; }
button.btn.quiet:hover { background: rgba(255,255,255,.05); border-color: var(--edge); color: var(--ink); }

button.btn:disabled {
  background: rgba(255,255,255,.02);
  border-color: var(--edge);
  color: var(--ink-faint);
  box-shadow: none;
  filter: none;
  cursor: not-allowed;
  }

.nav { display: flex; gap: 8px; margin-top: 8px; }
.nav button { flex: 1; }

/* ------------------------------------------------------------ blocked */
.blockers {
  margin-top: 13px;
  border: 1px solid rgba(242,119,138,.28);
  border-radius: var(--r-sm);
  background: rgba(242,119,138,.045);
  padding: 12px 13px;
  }
.blockers .lead { color: var(--rose); margin-bottom: 8px; }
.blockers ul { margin: 0; padding-left: 15px; }
.blockers li { font-size: 12px; color: var(--ink-dim); margin-bottom: 4px; overflow-wrap: anywhere; }
.blockers li:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- form */
label.field { display: block; margin-bottom: 13px; }
label.field > span { display: block; margin-bottom: 7px; font-size: 11.5px; color: var(--ink-dim); }
label.field .req { display: inline; color: var(--amber); }

input, select, textarea {
  /* 16px, not 13px: anything smaller makes iOS zoom the page on focus. */
  font: 400 16px var(--ui);
  width: 100%;
  padding: 12px 13px;
  background: rgba(255,255,255,.028);
  color: var(--ink);
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  min-height: 46px;
  }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: rgba(91,153,255,.5);
  box-shadow: 0 0 0 3px rgba(91,153,255,.13);
  }
textarea { min-height: 82px; resize: vertical; font-family: var(--ui); }
select option { background: #10141d; }
.hint { font-size: 11.5px; color: var(--ink-faint); margin: -4px 0 13px; }

/* ----------------------------------------------------------- seat map */
.tree { list-style: none; padding: 0; margin: 0; }
.tree ul { list-style: none; margin: 0; padding-left: 14px; border-left: 1px solid var(--edge); }
.seat-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.seat-name { font: 600 15px var(--ui); letter-spacing: -.015em; }
.seat-key { font: 400 10.5px var(--mono); color: var(--ink-faint); letter-spacing: .04em; }
.occupant { font-size: 12px; color: var(--ink-dim); margin-top: 4px; }
.occupant.vacant { color: var(--rose); }
.grants { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }

/* --------------------------------------------------------------- menu */
/* Same glass, same radii, same mono labels as everything else. The
   three dots sit where the sign-out button used to. */
.menu-wrap { position: relative; }

.menu-btn {
  font: 600 15px/1 var(--ui);
  letter-spacing: .06em;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--pill);
  color: var(--ink-faint);
  cursor: pointer;
  padding: 7px 10px;
  }
.menu-btn:hover, .menu-btn[aria-expanded="true"] {
  color: var(--ink);
  border-color: var(--edge);
  background: var(--card);
  }

.menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 30;
  min-width: 168px;
  padding: 6px;
  background: rgba(14, 19, 29, .97);
  backdrop-filter: blur(18px);
  border: 1px solid var(--edge-hi);
  border-radius: var(--r-sm);
  box-shadow: 0 18px 44px -18px rgba(0, 0, 0, .9);
  }
.menu button {
  display: block;
  width: 100%;
  text-align: left;
  font: 500 12.5px var(--ui);
  color: var(--ink-dim);
  background: none;
  border: 0;
  border-radius: var(--r-xs);
  padding: 9px 11px;
  cursor: pointer;
  }
.menu button:hover { background: rgba(255, 255, 255, .055); color: var(--ink); }

/* -------------------------------------------------------------- panel */
/* Configuration, not operation. It can breathe more than the approval
   screen does. */
.scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(4, 6, 11, .72);
  backdrop-filter: blur(3px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 0;
  }

.panel-sheet {
  width: 100%;
  min-height: 100vh;
  background: var(--bg);
  border: 0;
  padding: calc(14px + env(safe-area-inset-top)) var(--pad)
           calc(56px + env(safe-area-inset-bottom));
  }

.panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 26px;
  }
.panel-head h2 { margin: 0; flex: 1; }
.panel-close {
  font: 400 18px/1 var(--ui);
  background: none;
  border: 1px solid var(--edge);
  border-radius: var(--pill);
  color: var(--ink-dim);
  cursor: pointer;
  padding: 7px 12px;
  }
.panel-close:hover { color: var(--ink); border-color: var(--edge-hi); }

.section { margin-bottom: 30px; }
.section > .label { margin-bottom: 10px; }
.section .why {
  font-size: 12px;
  color: var(--ink-faint);
  margin: -4px 0 12px;
  max-width: 62ch;
  }
.section .ok { color: var(--emerald); font-size: 12px; margin-top: 10px; }

@media (min-width: 700px) {
  .scrim { padding: 6vh 20px; align-items: flex-start; }
  .panel-sheet {
    max-width: 620px;
    min-height: 0;
    border: 1px solid var(--edge);
    border-radius: var(--r);
    background: linear-gradient(180deg, #0C1119, #080B12);
    box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .95);
    padding: 26px 28px 32px;
    }
  }

/* ------------------------------------------------------------ sign in */
/* Signed out, the chrome is meaningless - there is no seat to show. */
body.signed-out .bar > *:not(.brand),
body.signed-out .tabs { display: none; }

.signin { max-width: 340px; margin: 8vh auto 0; }
.signin-brand {
  font: 600 9px/1 var(--ui); letter-spacing: .22em;
  color: var(--ink-dim); margin-bottom: 22px; text-align: center;
  }
.signin .actions { margin-top: 18px; }
.signin .btn { flex: 1; }
.signin-note {
  margin-top: 14px; font-size: 12px; color: var(--rose);
  min-height: 1.2em; text-align: center;
  }

.signout {
  font: 500 11.5px var(--ui);
  background: none; border: 0; color: var(--ink-faint);
  cursor: pointer; padding: 6px 2px;
  }
.signout:hover { color: var(--ink); }

/* ------------------------------------------------------------- banner */
.banner {
  position: fixed; z-index: 40;
  left: var(--pad); right: var(--pad);
  bottom: calc(16px + env(safe-area-inset-bottom));
  background: rgba(14,19,29,.95);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(242,119,138,.42);
  border-radius: var(--r);
  padding: 14px 16px;
  box-shadow: 0 20px 56px -20px rgba(0,0,0,.92);
  }
.banner.good { border-color: rgba(95,211,166,.42); }
.banner .who { color: var(--rose); margin-bottom: 8px; padding-right: 20px; }
.banner.good .who { color: var(--emerald); }
.banner .msg { font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; }
.banner .code { font: 400 10.5px var(--mono); color: var(--ink-faint); margin-top: 8px; overflow-wrap: anywhere; }
.banner .x {
  position: absolute; top: 7px; right: 9px;
  background: none; border: 0; color: var(--ink-faint);
  font-size: 15px; cursor: pointer; padding: 4px 6px;
  }

.empty { color: var(--ink-faint); text-align: center; padding: 52px 0; font-size: 12.5px; }

/* --------------------------------------------------------------- wide */
@media (min-width: 760px) {
  :root { --pad: 28px; }
  .person { display: block; }
  .bar { gap: 16px; }
  .acting select { max-width: none; }
  main { max-width: 700px; margin: 0 auto; padding-top: 28px; }
  }

/* =====================================================================
   SEAT MAP - design system section 7.

   Horizontal by default: root on the left, vertically centred, children
   stacked in a column on the right, joined by curved bezier paths.

   Opacity on those paths is semantic, not decorative. A branch with
   nothing waiting sits dim. The escalating branch is the only thing on
   this canvas that moves, because motion is reserved for the one thing
   that needs a human.
   ===================================================================== */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 18px;
  }
.stat {
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  padding: 11px 12px;
  }
.stat .n { font: 600 19px/1.1 var(--ui); letter-spacing: -.02em; }
.stat .n.none { color: var(--ink-faint); }
.stat .k {
  font: 500 9px/1.4 var(--mono);
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-faint); margin-top: 5px;
  }
.stat.debt .n { color: var(--rose); }
.stat.debt .n.none { color: var(--ink-faint); }

.map-tools { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.map-tools .spacer { flex: 1; }
.orient {
  display: flex; gap: 2px; padding: 3px;
  background: var(--card); border: 1px solid var(--edge);
  border-radius: var(--pill);
  }
.orient button {
  font: 500 10px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  background: none; border: 0; border-radius: var(--pill);
  color: var(--ink-faint); cursor: pointer; padding: 7px 11px;
  }
.orient button.on { background: rgba(76,141,246,.16); color: var(--ink); }

.map {
  position: relative;
  overflow-x: auto;
  /* visible would force both axes to scroll; the stage sizes itself to
     its content instead, so there is nothing to clip vertically. */
  overflow-y: hidden;
  scrollbar-width: none;
  }
.map::-webkit-scrollbar { display: none; }

.map-canvas { position: relative; min-width: 100%; }

.map svg.wires {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  overflow: visible;
  }

/* The escalating branch, and only that one. */
@keyframes flow-back { to { stroke-dashoffset: 26; } }
.wire.escalating { animation: flow-back 1.1s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .wire.escalating { animation: none; }
  }

/* Root halo. Soft, blue, behind the card - not a glow on the card. */
.halo {
  position: absolute;
  width: 250px; height: 250px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(76,141,246,.20) 0%, rgba(76,141,246,.07) 42%, transparent 68%);
  pointer-events: none;
  }

/* Compact by design: a dot, the title, one badge. Nothing else. */
.seat-node {
  position: absolute;
  display: flex; align-items: center; gap: 9px;
  background: var(--card);
  border: 1px solid var(--edge);
  border-radius: var(--r);
  backdrop-filter: blur(10px);
  padding: 11px 13px;
  cursor: pointer;
  text-align: left;
  font: inherit; color: var(--ink);
  transition: border-color .15s, box-shadow .15s;
  }
.seat-node:hover { border-color: var(--edge-hi); }
.seat-node.acting { border-color: rgba(76,141,246,.5); box-shadow: 0 0 26px -12px rgba(76,141,246,.75); }

.seat-node .dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  }
.seat-node .dot.occupied { background: var(--emerald); box-shadow: 0 0 9px rgba(16,185,129,.75); }
.seat-node .dot.vacant   { background: var(--rose);    box-shadow: 0 0 9px rgba(244,63,94,.75); }
.seat-node .dot.external { background: var(--violet);  box-shadow: 0 0 9px rgba(139,92,246,.75); }

.seat-node .t {
  font: 600 14.5px/1.2 var(--ui); letter-spacing: -.005em;
  white-space: nowrap;
  }

.seat-node .badge {
  font: 500 10px/1 var(--mono);
  padding: 4px 8px; border-radius: var(--pill);
  border: 1px solid currentColor;
  margin-left: auto;
  }
.seat-node .badge.waiting    { color: var(--amber); }
.seat-node .badge.escalating { color: var(--rose); }

/* ------------------------------------------------------- detail panel */
/* Everything the card does not say. Slides in from the right. */
@keyframes slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } }

.drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  z-index: 55;
  width: min(430px, 100vw);
  background: linear-gradient(180deg, #0C1119, #080B12);
  border-left: 1px solid var(--edge-hi);
  box-shadow: -30px 0 70px -30px rgba(0,0,0,.95);
  overflow-y: auto;
  padding: calc(16px + env(safe-area-inset-top)) 20px
           calc(40px + env(safe-area-inset-bottom));
  animation: slide-in .18s ease-out;
  }
@media (prefers-reduced-motion: reduce) { .drawer { animation: none; } }
.drawer .panel-head { margin-bottom: 20px; }
.drawer .seat-key { display: block; margin-top: 3px; }

/* ---------------------------------------------- canvas: create + wire */
/* A seat with no reporting line is a valid state, not an error. It reads
   as detached rather than as broken: dimmer, dashed, and it says so. */
.seat-node.unattached {
  opacity: .72;
  border-style: dashed;
  border-color: rgba(255,255,255,.16);
  }
.seat-node .detached {
  font: 400 9px/1 var(--mono);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint);
  margin-left: auto;
  white-space: nowrap;
  }

/* The grab point for a reporting cord. Sized for a fingertip. */
.wire-handle {
  position: absolute;
  width: 26px; height: 26px;
  border-radius: 50%;
  display: grid; place-items: center;
  cursor: grab;
  touch-action: none;
  }
.wire-handle::after {
  content: "";
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--blue);
  border: 2px solid var(--bg);
  box-shadow: 0 0 8px rgba(76,141,246,.8);
  opacity: .55;
  transition: opacity .15s, transform .15s;
  }
.seat-node:hover + .wire-handle::after,
.wire-handle:hover::after { opacity: 1; transform: scale(1.15); }
.wire-handle.dragging { cursor: grabbing; }

/* The cord in flight. Same language as a settled connector, plus a
   label, because what it is about to mean must not be guessed at. */
.wire.dragging { stroke-dasharray: 6 6; }
.cord-label {
  position: absolute;
  transform: translate(-50%, -50%);
  font: 500 9px/1 var(--mono);
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-dim);
  background: rgba(10,14,22,.94);
  border: 1px solid var(--edge-hi);
  border-radius: var(--pill);
  padding: 5px 9px;
  pointer-events: none;
  white-space: nowrap;
  }

.seat-node.drop-target { border-color: var(--blue); box-shadow: 0 0 22px -8px rgba(76,141,246,.9); }

/* Create-here popup */
.spot {
  position: absolute;
  z-index: 12;
  background: rgba(14,19,29,.97);
  backdrop-filter: blur(18px);
  border: 1px solid var(--edge-hi);
  border-radius: var(--r-sm);
  box-shadow: 0 18px 44px -18px rgba(0,0,0,.9);
  padding: 6px;
  }
.spot button {
  font: 500 12px var(--ui);
  background: none; border: 0; border-radius: var(--r-xs);
  color: var(--ink-dim); cursor: pointer; padding: 8px 11px; white-space: nowrap;
  }
.spot button:hover { background: rgba(255,255,255,.06); color: var(--ink); }

.map { touch-action: pan-x pan-y; }

/* ---------------------------------------------------------- update nudge */
/* Bottom corner, dismissible, not a modal. Nothing is blocked by it,
   because nothing about it is urgent - the running shell is fine, it is
   only not the newest. */
.update-nudge {
  position: fixed;
  z-index: 45;
  right: var(--pad);
  bottom: calc(16px + env(safe-area-inset-bottom));
  left: auto;
  max-width: min(310px, calc(100vw - var(--pad) * 2));
  background: rgba(14, 19, 29, .96);
  backdrop-filter: blur(16px);
  border: 1px solid var(--edge-hi);
  border-radius: var(--r);
  padding: 13px 14px;
  box-shadow: 0 18px 46px -20px rgba(0, 0, 0, .92);
  }
.update-nudge .line {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--ink);
  }
.update-nudge .dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--blue);
  box-shadow: 0 0 8px rgba(76, 141, 246, .85);
  }
/* Amber, because it is a caution about timing rather than a failure. */
.update-nudge .warn {
  margin-top: 7px;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--amber);
  }
.update-nudge .row { display: flex; gap: 6px; margin-top: 12px; }
.update-nudge button {
  font: 600 12px var(--ui);
  border-radius: var(--pill);
  padding: 8px 14px;
  cursor: pointer;
  border: 1px solid transparent;
  }
.update-nudge .go {
  color: #fff;
  background:
    linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,0) 42%),
    linear-gradient(180deg, var(--azure) 0%, var(--azure-deep) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 4px 16px -6px rgba(91,153,255,.7);
  }
.update-nudge .later {
  background: transparent;
  color: var(--ink-faint);
  }
.update-nudge .later:hover { color: var(--ink); border-color: var(--edge); }

/* z-index 45 sits under the settings panel (50) and the seat drawer (55):
   an update is never the most important thing on screen. */
/* Out of the way of the message banner, which sits centred. */
@media (max-width: 520px) {
  .update-nudge { left: var(--pad); max-width: none; }
  }

/* ------------------------------------------------------- confirm sheet */
/* Re-authentication and a lapsed session ask the same question, so they
   look the same. It sits over the app rather than replacing it: whatever
   was half-typed underneath is still there when it closes. */
.confirm-scrim {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(4, 6, 11, .74);
  backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: var(--pad);
  }
.confirm {
  width: min(360px, 100%);
  background: linear-gradient(180deg, #0C1119, #080B12);
  border: 1px solid var(--edge-hi);
  border-radius: var(--r);
  padding: 22px 22px 20px;
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .95);
  }
.confirm h3 { font: 600 17px/1.25 var(--ui); letter-spacing: -.02em; margin: 0 0 6px; }
.confirm .why { margin: 0 0 16px; }
.confirm .who { font: 400 11.5px var(--mono); color: var(--ink-faint); margin-bottom: 14px; }
.confirm .note { margin-top: 12px; font-size: 12px; color: var(--rose); min-height: 1.1em; }
.confirm .keep {
  margin-top: 12px; font-size: 11.5px; color: var(--emerald);
  }

/* ------------------------------------------------------------ 2fa */
.qr {
  background: #fff;
  border-radius: var(--r-sm);
  padding: 10px;
  width: 220px;
  margin: 0 auto 14px;
  }
.qr svg { display: block; width: 100%; height: auto; }

.secret-text {
  font: 500 14px/1.5 var(--mono);
  letter-spacing: .12em;
  text-align: center;
  color: var(--ink);
  background: rgba(255,255,255,.045);
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  padding: 11px;
  word-break: break-all;
  }

.codes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 12px 0;
  }
.codes code {
  font: 500 13px/1.6 var(--mono);
  letter-spacing: .08em;
  text-align: center;
  background: rgba(255,255,255,.045);
  border: 1px solid var(--edge);
  border-radius: var(--r-xs);
  padding: 8px 4px;
  }
.codes-warn { color: var(--amber); font-size: 12px; margin-top: 4px; }

/* ---------------------------------------------------------- flow edges */
/* Shape carries the distinction, not colour: reporting is a curved
   bezier, flow is elbowed. The difference survives grayscale, and
   neither can be read as authority - which is never a line at all. */
.flow {
  fill: none;
  stroke: var(--cyan);
  stroke-width: 1.4;
  stroke-opacity: .55;
  stroke-linecap: square;
  stroke-linejoin: miter;
  stroke-dasharray: 1 5;
  }
.flow.disabled { stroke-opacity: .18; stroke-dasharray: 1 8; }
.flow-head { fill: var(--cyan); opacity: .7; }
.flow-head.disabled { opacity: .25; }

.layers { display: flex; gap: 2px; padding: 3px; background: var(--card);
  border: 1px solid var(--edge); border-radius: var(--pill); }
.layers button {
  font: 500 10px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  background: none; border: 0; border-radius: var(--pill);
  color: var(--ink-faint); cursor: pointer; padding: 7px 11px;
  }
.layers button.on { background: rgba(34,211,238,.16); color: var(--ink); }
