/* Bridge Chartering — additions on top of the reference design system.
   Uses the same tokens (--navy, --sand, --live, ...) defined in reference.css. */

/* ---------- buttons ---------- */
.ghostbtn{background:var(--paper);border:1px solid var(--line);color:var(--navy);font-size:13px;
  font-weight:600;padding:9px 15px;border-radius:10px;transition:.14s;display:inline-flex;align-items:center;gap:7px}
.ghostbtn:hover{border-color:var(--steel2);box-shadow:var(--shadow)}
.ghostbtn:disabled{opacity:.5;cursor:default}
.dangerbtn{color:#b0613e}
.tinybtn{font-size:11.5px;font-weight:600;padding:5px 10px;border-radius:7px;background:var(--sand2);
  border:1px solid var(--line2);color:var(--navy);transition:.12s}
.tinybtn:hover{background:var(--sand);border-color:var(--line)}
.tinybtn.primary{background:var(--navy);color:#fff;border-color:var(--navy)}
.tinybtn.primary:hover{background:var(--navy2)}

/* ---------- chartering sub-tabs ---------- */
.subtabs{display:flex;gap:6px;margin:4px 0 18px;flex-wrap:wrap;border-bottom:1px solid var(--line2);padding-bottom:0}
.subtab{font-size:13px;font-weight:600;color:#8a93a3;padding:9px 14px;border-radius:9px 9px 0 0;
  border-bottom:2px solid transparent;transition:.13s;display:inline-flex;align-items:center;gap:7px}
.subtab:hover{color:var(--navy)}
.subtab.on{color:var(--navy);border-bottom-color:var(--live)}
.tabct{font-size:10.5px;font-weight:700;background:var(--sand);color:#6a7280;border-radius:9px;
  padding:1px 7px;min-width:16px;text-align:center}
.tabct:empty{display:none}
.subtab.on .tabct{background:var(--livebg);color:var(--live)}
.chpane{display:none}
.chpane.on{display:block;animation:fadein .3s ease}

/* ---------- item cards ---------- */
.itemgrid{display:flex;flex-direction:column;gap:10px}
.itemcard{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:14px 16px;transition:.15s}
.itemcard:hover{border-color:#cfd8e4}
.itemcard .ih{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.itemcard .ttl{font-size:14px;font-weight:600;color:var(--ink);display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.itemcard .meta{font-size:11.5px;color:#8a93a3;margin-top:4px;display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.itemcard .acts{display:flex;gap:7px;flex-wrap:wrap;flex:none;align-items:center}
.itemcard .ibody{display:none;margin-top:12px;border-top:1px dashed var(--line2);padding-top:12px}
.itemcard.openit .ibody{display:block}
.expander{font-size:12px;font-weight:600;color:var(--steel);background:none;padding:4px}
.expander:hover{color:var(--navy)}

/* lifecycle badges */
.st{font-size:10px;font-weight:700;padding:2.5px 8px;border-radius:5px;letter-spacing:.04em;text-transform:uppercase}
.st-new{background:#e8eef7;color:#3a567f}
.st-open{background:var(--livebg);color:var(--live)}
.st-matched{background:#f4ecdc;color:#8a6a26}
.st-in_negotiation{background:var(--warnbg);color:var(--warn)}
.st-fixed{background:#e7f1ee;color:#2f7d6b}
.st-withdrawn{background:#f0ede6;color:#a39a86}
.st-expired{background:#f8ece6;color:#b0613e}

/* confidence tiers — qualitative, deliberately not a percentage */
.conf{font-family:'Fraunces',serif;font-weight:600;font-size:15px;letter-spacing:-.01em}
.conf-High{color:var(--live)} .conf-Medium{color:var(--gold)} .conf-Low{color:#b06a4e}
.conf small{font-family:'Inter';font-size:10px;color:#9aa2b1;font-weight:500;display:block;letter-spacing:.06em;text-transform:uppercase}

.origin-badge{font-size:10px;font-weight:700;padding:2.5px 8px;border-radius:5px;background:#eef1f7;color:#3a567f;letter-spacing:.03em}

/* Vetting Flag pill (build reference §2) — commercial PSC/detention risk read,
   never presented as gospel, so styled as a hint chip, not a pass/fail stamp. */
.vet{font-size:10px;font-weight:700;padding:2.5px 8px;border-radius:5px;letter-spacing:.03em;cursor:help}
.vet-elevated_risk{background:#f8ece6;color:#b0613e}
.vet-normal{background:var(--livebg);color:var(--live)}
.vet-insufficient_data{background:var(--sand2);color:#8a93a3}
.vetbox{background:var(--paper);border:1px solid var(--line2);border-radius:10px;padding:12px 13px;margin-bottom:4px}
.vetbox .facts{margin-top:8px}
.vetbox .rationale{margin-top:0}

/* S&P module (build reference §3) — reuses .itemcard/.kvgrid/.sect etc.
   from the chartering module; only the doc-type pill and pane class are new. */
.sppane{display:none}
.sppane.on{display:block;animation:fadein .3s ease}
.doctype{font-size:10px;font-weight:700;padding:2.5px 8px;border-radius:5px;letter-spacing:.03em;text-transform:uppercase}
.doctype-recap{background:#e8eef7;color:#3a567f}
.doctype-moa{background:var(--livebg);color:var(--live)}
.doctype-other{background:var(--sand2);color:#8a93a3}

/* fields grid inside item detail */
.kvgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:7px 18px;margin:10px 0}
.kv{font-size:12.5px}
.kv .k{color:#9aa2b1;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600}
.kv .v{color:var(--ink);font-weight:500;margin-top:1px}
.rawmail{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11.5px;line-height:1.6;color:#5d6577;
  background:var(--sand2);border:1px solid var(--line2);border-radius:9px;padding:11px 13px;white-space:pre-wrap;
  max-height:180px;overflow-y:auto;margin-top:8px}
.sect{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--steel);font-weight:600;margin:16px 0 8px;
  display:flex;align-items:center;gap:10px}
.sect::after{content:"";flex:1;height:1px;background:var(--line2)}

/* deep link chips */
.linkchip{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:600;color:var(--navy);
  background:var(--sand2);border:1px solid var(--line2);padding:4px 10px;border-radius:7px;text-decoration:none;transition:.12s}
.linkchip:hover{border-color:var(--steel2)}
.linkchip svg{width:12px;height:12px;flex:none}
.linknote{font-size:11.5px;color:#9aa2b1;font-style:italic;display:inline-flex;align-items:center;gap:6px}

/* prefilter audit rows */
.pfrow{display:flex;gap:10px;align-items:flex-start;padding:8px 0;border-bottom:1px dashed var(--line2);font-size:12.5px}
.pfrow:last-child{border-bottom:none}
.pfflag{flex:none;font-size:10px;font-weight:700;padding:2.5px 8px;border-radius:5px;margin-top:1px;letter-spacing:.03em}
.pfflag.pass{background:var(--livebg);color:var(--live)}
.pfflag.fail{background:#f8ece6;color:#b0613e}
/* NOT EVALUABLE is neither a pass nor a rejection: nothing about the pairing
   was checked. It must not borrow `.fail`'s colour, or the page says Bridge
   rejected a pairing it never assessed. Base rule, no media query involved. */
.pfflag.warn{background:#f4f0e2;color:#8a7328}
.pfrow .who{font-weight:600;color:var(--ink)}
.pfrow .why{color:#6a7280;margin-top:2px;line-height:1.45}

/* B2 candidate list. BASE RULES, AND THEY SIT ABOVE THE NARROW-VIEWPORT MEDIA
   BLOCK DELIBERATELY: at equal specificity source order wins, so a base rule
   written AFTER a media query silently defeats it. This codebase has shipped a
   mobile drawer that could not be closed for exactly that reason -- every rule
   individually correct and the whole thing inert. `tests/test_b2_display.py`
   pins the ordering, because nothing about that defect is visible in a diff. */
.candgrp{margin-top:2px}
.candhead{cursor:pointer}
.candsub{font-weight:400;color:#6a7280;font-size:11px;letter-spacing:0;text-transform:none}
.candchev{color:#8a94a6;font-size:11px;transition:transform .15s}
.candgrp.open .candchev{transform:rotate(180deg)}
.candbody{display:none}
.candgrp.open .candbody{display:block}
.candrow{padding:8px 0;border-bottom:1px dashed var(--line2);font-size:12.5px}
.candrow:last-child{border-bottom:none}

/* The voyage-estimate form on a candidate row (fixed 1 Oct 2026). Each field
   is its label above its own input; the grid follows the CARD's width, not the
   window's -- a card opened from the triage board is half the window -- so a
   container query: 1 column, 2 from 340px, 4 from 640px. Same field style as
   the demolition worksheet (.dmfield). tests/test_tce_form_layout.py. */
.tceform{container-type:inline-size;margin-top:8px;padding:10px 12px 12px;
  background:var(--paper);border:1px solid var(--line);border-radius:10px}
.tceform .sect{margin-top:2px}
.tcegrid{display:grid;grid-template-columns:minmax(0,1fr);gap:10px 14px}
@container (min-width:340px){.tcegrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* Freight holds an input AND its unit, so it takes two columns: one column
     left the rate box under a readable width. */
  .tcefield.tcewide{grid-column:span 2}}
@container (min-width:640px){.tcegrid{grid-template-columns:repeat(4,minmax(0,1fr))}}
.tcefield{display:flex;flex-direction:column;gap:5px;min-width:0}
.tcelbl{font-size:11px;font-weight:600;color:var(--steel);letter-spacing:.04em;text-transform:uppercase}
.tcefield input,.tcefield select{width:100%;min-width:0;border:1px solid var(--line);border-radius:9px;
  padding:7px 10px;font-size:13px;font-family:inherit;outline:none;background:#fdfdfb}
.tcefield input:focus,.tcefield select:focus{border-color:var(--steel2)}
.tcepair{display:flex;gap:6px}
.tcepair input{flex:1 1 auto}
.tcepair select{flex:0 0 auto;width:auto;padding:7px 6px}
.tcehint{font-size:11px;color:var(--steel)}
.tcecalc{margin-top:12px}
.tceout{margin-top:10px}
.candwho{font-weight:600;color:var(--ink)}
.candfacts{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 14px;margin-top:3px}
.candfact{color:#4a5260;font-size:11.5px}
.candfact:empty{display:none}
.candwhy{color:#6a7280;margin-top:2px;line-height:1.45}
/* The sort control. BASE RULES ABOVE THE MEDIA BLOCK -- source order decides at
   equal specificity, and a base rule written after a media query is inert. */
.candsort{display:flex;align-items:center;gap:8px;margin:0 0 10px;
  color:#6a7280;font-size:11.5px}
.candsort select{font-size:11.5px;padding:2px 4px;border:1px solid var(--line2);
  border-radius:4px;background:#fff;color:var(--ink)}
/* The superseded-basis marker. DISTINCT FROM `.candage`, which is also a small
   grey line under a candidate: two different notes rendering identically is how
   a reader stops reading either. Italic and indented behind a rule, so it reads
   as an aside about the row rather than as another fact about the ship.
   BASE RULE, ABOVE THE MEDIA BLOCK -- source order decides at equal
   specificity, and a base rule written after a media query is inert. */
.candpolicy{color:#8a7250;font-size:11.5px;font-style:italic;margin-top:3px;
  padding-left:7px;border-left:2px solid #e0d3b8}
.coverage{color:#4a5260;font-size:12.5px;line-height:1.5;margin:14px 0 2px}
/* A row Bridge does not match: the card's one-liner and the detail's block.
   BASE RULES, ABOVE THE MEDIA BLOCK at line ~431 -- source order decides at
   equal specificity, and this repository has already shipped a mobile drawer
   whose every rule was individually correct and collectively inert because two
   blocks hundreds of lines apart were in the wrong order. Read as COMPUTED
   STYLE in the browser check, never off this file: a rule can be present and
   do nothing. */
.poolnote{color:#7a5c2e;font-size:11.5px;line-height:1.5;margin:4px 0 0}
/* The split fix's control: an email that held more offerings than reached the
   board. Warning-toned, not an error -- nothing failed that the broker must
   fix; the rest are one click away in the source. */
.shortnote{color:#7a4a12;background:#fbf1e1;border-left:3px solid #d99a3c;
  font-size:12px;line-height:1.5;margin:6px 0 0;padding:4px 8px;border-radius:3px}
/* The same fact, on a CLOSED fold header: how many short rows it hides. */
.shorttag{color:#7a4a12;background:#fbf1e1;border:1px solid #e8c48a;border-radius:10px;
  font-size:11px;padding:1px 7px;margin-left:6px;white-space:nowrap}
.poolblock p{margin:0 0 8px}
.poolblock p:last-child{margin-bottom:0}
.candwhyq{font-weight:600;color:#4a5260;margin-right:6px}
/* The Stage 1 panel is BROKER-VISIBLE and ungated. Until there is a role to
   gate to, it gets a visible boundary: a rule above it and a shaded block, so
   the broker can see where his list ends and Bridge's own working begins.
   BASE RULES, ABOVE THE MEDIA BLOCK -- source order decides at equal
   specificity, and a base rule written after a media query is inert. */
.opsplit{margin-top:26px;padding:2px 14px 10px;border-top:2px solid var(--line2);
  background:#f7f8fa;border-radius:0 0 8px 8px}
.opsub{color:#6a7280;font-size:11.5px;line-height:1.5;margin:-2px 0 6px}
.pfrule{font-size:10px;font-weight:700;color:#9aa2b1;text-transform:uppercase;letter-spacing:.05em;margin-left:6px}

/* pairing cards (matches view + item detail) */
.pairingcard{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:15px 17px;margin-bottom:11px}
.pairingcard.ismatch{border-color:#cfdcd6;background:linear-gradient(180deg,#fafdfb,var(--paper))}
.pairingcard .ph2{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;margin-bottom:10px}
.pairingcard .pair{font-weight:600;font-size:14px;color:var(--navy)}
.pairingcard .pair .vs{color:#b9c0cc;font-weight:400;font-size:11.5px;margin:0 6px}
.pairingcard .verdict-line{display:flex;align-items:center;gap:10px;flex:none}
.vbadge{font-size:10px;font-weight:700;padding:3px 9px;border-radius:5px;letter-spacing:.05em;text-transform:uppercase}
.vbadge.match{background:var(--livebg);color:var(--live)}
.vbadge.reject{background:#f8ece6;color:#b0613e}
.pairingcard .facts{margin-bottom:10px}
.pairingcard .foot2{margin-top:11px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.pairingcard .srclinks{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}

/* draft output */
.draftbox{margin-top:11px;border:1px solid #cfdcd6;border-radius:10px;overflow:hidden}
.draftbox .dsubj{background:var(--sand2);border-bottom:1px solid var(--line2);padding:9px 13px;font-size:12.5px;font-weight:600;color:var(--ink)}
.draftbox .dtext{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12px;line-height:1.6;color:#3a4254;
  padding:12px 13px;white-space:pre-wrap;background:var(--paper)}
.draftbox .dfoot{padding:8px 13px;border-top:1px solid var(--line2);display:flex;gap:8px;align-items:center;background:#fbfdfc}
/* BESIDE THE COPY CONTROL, NOT AT THE FAR END (22 Sep 2026, §6.6). This read
   `margin-left:auto`, which pushed the one sentence warning a reader to check
   the draft 341px away from the button that puts it on the clipboard —
   measured on the rendered page, not inferred. The draft's only defence was
   placed where nobody reads it. Larger and darker for the same reason: it is
   the notice, not a footnote. */
.draftbox .dnote{font-size:12px;color:#5c6478;flex:1 1 auto;min-width:0}
/* A FIGURE IN NEITHER MESSAGE BRIDGE READ. Marks, never refuses: refusing
   would drop legitimate drafts over an ordinary number, and a broker who
   cannot get a draft stops asking for one. */
.draftbox .dwarn{background:#fff6e5;border-bottom:1px solid #f0dcb4;color:#7a5a15;
  padding:8px 13px;font-size:12px;line-height:1.5}
.draftbox mark.unsourced{background:#ffe9b8;color:#6b4e0c;border-radius:3px;
  padding:0 2px;font-weight:600}

/* filter bar (working pool / history) */
.filterbar{display:flex;gap:9px;margin-bottom:14px;flex-wrap:wrap}
.filterbar input,.filterbar select{border:1px solid var(--line);border-radius:9px;padding:8px 12px;font-family:inherit;
  font-size:13px;background:var(--paper);outline:none;color:var(--ink)}
.filterbar input:focus,.filterbar select:focus{border-color:var(--steel2)}

/* empty states */
.emptystate{padding:36px 20px;text-align:center;color:#8a93a3;font-size:13px;background:var(--paper);
  border:1px dashed var(--line);border-radius:12px;line-height:1.6}
.emptystate b{color:var(--navy)}

/* ---------- bell + notification panel ---------- */
.bellbtn{position:relative;width:36px;height:36px;border-radius:9px;display:flex;align-items:center;justify-content:center;
  color:var(--navy);border:1px solid var(--line);background:var(--paper);transition:.13s}
.bellbtn:hover{border-color:var(--steel2)}
.bellct{position:absolute;top:-5px;right:-5px;background:#c2553a;color:#fff;font-size:9.5px;font-weight:700;
  min-width:16px;height:16px;border-radius:8px;display:flex;align-items:center;justify-content:center;padding:0 4px}
.notipanel{position:fixed;top:0;right:0;height:100vh;width:420px;max-width:94vw;background:var(--paper);
  box-shadow:-12px 0 40px rgba(17,35,63,.16);transform:translateX(100%);transition:.24s cubic-bezier(.4,0,.2,1);
  z-index:45;display:flex;flex-direction:column}
.notipanel.on{transform:none}
.notiact{padding:11px 20px;border-bottom:1px solid var(--line2);display:flex;align-items:center;gap:10px}
.noti{border:1px solid var(--line2);border-radius:10px;padding:11px 13px;font-size:12.5px;line-height:1.5;color:#3a4254;position:relative;
  overflow-wrap:anywhere;word-break:break-word}
.noti.unread{border-color:#cfdcd6;background:linear-gradient(180deg,#fbfdfc,var(--paper))}
.noti .nh{display:flex;align-items:center;gap:8px;margin-bottom:5px;flex-wrap:wrap}
.noti .ntime{font-size:10.5px;color:#9aa2b1;margin-left:auto}
.nkind{font-size:9.5px;font-weight:700;padding:2px 7px;border-radius:5px;letter-spacing:.05em;text-transform:uppercase}
.nkind.instant{background:var(--livebg);color:var(--live)}
.nkind.digest{background:var(--warnbg);color:var(--warn)}
.nkind.queued{background:#f0ede6;color:#a39a86}

/* ---------- modal ---------- */
.mscrim{position:fixed;inset:0;background:rgba(17,35,63,.35);backdrop-filter:blur(2px);z-index:55}
.modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:620px;max-width:94vw;max-height:88vh;
  overflow-y:auto;background:var(--paper);border-radius:15px;box-shadow:0 24px 70px rgba(17,35,63,.3);z-index:56;padding:22px 24px}
.modal h3{font-family:'Fraunces',serif;font-weight:600;font-size:19px;color:var(--navy);margin-bottom:6px}
.modal .msub{font-size:12.5px;color:#8a93a3;margin-bottom:14px;line-height:1.5}
.modal textarea{width:100%;min-height:170px;border:1px solid var(--line);border-radius:10px;padding:11px 13px;
  font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12.5px;line-height:1.55;resize:vertical;outline:none;background:#fdfdfb}
.modal textarea:focus{border-color:var(--steel2)}
.modal select,.modal input[type=text],.modal input[type=number]{width:100%;border:1px solid var(--line);border-radius:9px;
  padding:9px 12px;font-family:inherit;font-size:13px;background:var(--paper);outline:none;margin-top:4px}
.modal label{font-size:11.5px;font-weight:600;color:var(--steel);letter-spacing:.04em;text-transform:uppercase;display:block;margin-top:13px}
.modal .mfoot{display:flex;gap:9px;margin-top:18px;align-items:center}
.modal .mnote{font-size:11.5px;color:#9aa2b1;line-height:1.5;background:var(--sand2);border:1px solid var(--line2);
  border-radius:8px;padding:9px 12px;margin-top:12px}

/* ---------- usage & settings tables ---------- */
.dtable{width:100%;border-collapse:collapse;font-size:12.5px;background:var(--paper);border:1px solid var(--line);
  border-radius:12px;overflow:hidden}
.dtable-wrap{border:1px solid var(--line);border-radius:12px;overflow:auto;background:var(--paper)}
.dtable-wrap table{width:100%;border-collapse:collapse;font-size:12.5px}
.dtable-wrap th{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--steel);font-weight:600;
  text-align:left;padding:10px 14px;background:var(--sand2);border-bottom:1px solid var(--line2);white-space:nowrap}
.dtable-wrap td{padding:9px 14px;border-bottom:1px solid var(--line2);color:#3a4254;vertical-align:top}
.dtable-wrap tr:last-child td{border-bottom:none}
.dtable-wrap td.num{text-align:right;font-variant-numeric:tabular-nums;font-weight:600;color:var(--ink)}

.setform{background:var(--paper);border:1px solid var(--line);border-radius:13px;padding:20px 22px;max-width:560px}
.setform .row2{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:center;padding:13px 0;border-bottom:1px solid var(--line2)}
.setform .row2:last-of-type{border-bottom:none}
.setform .sl2{font-size:13.5px;font-weight:600;color:var(--ink)}
.setform .sd2{font-size:12px;color:#8a93a3;margin-top:3px;line-height:1.5;max-width:340px}
.setform select,.setform input{border:1px solid var(--line);border-radius:9px;padding:8px 12px;font-family:inherit;
  font-size:13px;background:var(--paper);outline:none;min-width:120px}
.modebadge{font-size:10.5px;font-weight:700;padding:4px 10px;border-radius:6px;letter-spacing:.04em}
.modebadge.mock{background:var(--warnbg);color:var(--warn)}
.modebadge.live{background:var(--livebg);color:var(--live)}

/* MOA draft generator (Bridge_SP_MOA_Build_Spec.md) — fill engine output
   lives inside the S&P deal detail. Checklist groups mirror the vetting
   pill palette: missing=red, non-standard=gold, deadline=blue-neutral. */
.moapanel{margin-top:4px}
.moatop{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:2px}
.moadraft{background:var(--paper);border:1px solid var(--line2);border-radius:10px;padding:13px 15px;margin-top:10px}
.moameta{display:flex;gap:12px;font-size:11px;color:#9aa2b1;margin-bottom:10px;letter-spacing:.02em}
.moameta span:first-child{font-weight:700;color:var(--navy)}

.checklist{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}
.clgroup{border-radius:9px;padding:9px 12px}
.clhead{font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;margin-bottom:5px}
.clrow{font-size:12.5px;line-height:1.5;padding:3px 0}
.clrow:not(:last-child){border-bottom:1px dashed rgba(0,0,0,.06)}
.cl-missing{background:#f8ece6}
.cl-missing .clhead{color:#b0613e}
.cl-missing .clrow{color:#8a5140}
.cl-non_standard{background:var(--warnbg)}
.cl-non_standard .clhead{color:var(--warn)}
.cl-non_standard .clrow{color:#8a6a26}
.cl-deadline{background:#e8eef7}
.cl-deadline .clhead{color:#3a567f}
.cl-deadline .clrow{color:#3a4254}

.ackrow{display:flex;align-items:flex-start;gap:8px;font-size:12.5px;color:var(--ink);line-height:1.5;
  cursor:pointer;margin-bottom:11px}
.ackrow input{margin-top:2px;flex:none}
.moaacts{display:flex;align-items:center;gap:9px;flex-wrap:wrap}

/* Vetting Desk (VETTING_DESK_SPEC.md) — standalone premium module, peer to
   S&P. Own input panel (paste/PDF tabs) since screening is the whole view,
   not a modal action; result renders below once a screen completes. */
.vdinput{background:var(--paper);border:1px solid var(--line);border-radius:13px;padding:18px 20px;margin-bottom:18px}
.vdtabs{display:flex;gap:6px;margin-bottom:14px}
.vdpane{display:none}
.vdpane.on{display:block}
.vdpane textarea{width:100%;min-height:160px;border:1px solid var(--line);border-radius:10px;padding:11px 13px;
  font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12.5px;line-height:1.55;resize:vertical;outline:none;background:#fdfdfb}
.vdpane textarea:focus{border-color:var(--steel2)}
.vdupload{display:flex;align-items:center;gap:12px;padding:20px;border:1px dashed var(--line);border-radius:10px;background:var(--sand2)}
.vdfoot{display:flex;align-items:center;gap:12px;margin-top:13px;flex-wrap:wrap}

.vdresult{background:var(--paper);border:1px solid var(--line);border-radius:13px;padding:20px 22px;margin-top:6px}
.vdkv{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:7px 18px;margin:10px 0}
.vdcontingency{font-size:12px;color:var(--warn);background:var(--warnbg);border-radius:8px;padding:8px 12px;margin-top:6px}

.vdheadline{font-family:'Fraunces',serif;font-weight:600;font-size:16px;color:var(--navy);margin:8px 0 6px}
.vdread{font-size:13px;line-height:1.6;color:#3a4254;margin-bottom:12px}
.vddisprow{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:6px}
.disppill{font-size:11px;font-weight:700;padding:4px 11px;border-radius:6px;letter-spacing:.03em}
.disp-proceed{background:var(--livebg);color:var(--live)}
.disp-note{background:var(--warnbg);color:var(--warn)}
.disp-query{background:#e8eef7;color:#3a567f}
.disp-caution{background:#f8ece6;color:#b0613e}
.vdconf{font-size:12px;color:#8a93a3;font-style:italic}

.vdwatch{margin:8px 0 4px;padding-left:20px;font-size:13px;line-height:1.7;color:#3a4254}

.vdfindings{display:flex;flex-direction:column;gap:10px;margin-top:8px}
.vdfinding{border:1px solid var(--line2);border-radius:10px;padding:11px 13px;background:var(--sand2)}
.vdfhead{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.chanpill{font-size:10px;font-weight:700;padding:2.5px 8px;border-radius:5px;letter-spacing:.03em;text-transform:uppercase;
  background:#eef1f7;color:#3a567f}
.vdref{font-size:11.5px;color:#8a93a3;font-weight:600}
.vdopresp{font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:5px;margin-left:auto}
.vdopresp.yes{background:var(--livebg);color:var(--live)}
.vdopresp.no{background:#f8ece6;color:#b0613e}
.vdfarea{font-size:12px;color:#6a7280;font-weight:600;margin-bottom:3px}
.vdfcomment{font-size:12.5px;line-height:1.5;color:var(--ink)}

.vdnotes{font-size:11.5px;color:#9aa2b1;font-style:italic;margin-top:12px;line-height:1.5}
.vddisclaimer{font-size:11px;color:#9aa2b1;line-height:1.5;background:var(--sand2);border:1px solid var(--line2);
  border-radius:8px;padding:10px 13px;margin-top:14px}
.vdacts{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-top:14px}

.vdhistory{background:#e8eef7;border-radius:10px;padding:11px 13px;margin-bottom:16px}
.vdhisthead{font-size:11.5px;font-weight:700;color:#3a567f;margin-bottom:6px}
.vdhistlist{display:flex;flex-direction:column;gap:3px}
.vdhistrow{display:flex;gap:14px;font-size:12px;color:#3a4254}
.vdhistrow span:first-child{color:#6a7280;min-width:110px}

/* Demolition recycling-economics (Bridge_Demolition_Build_Spec.md) — a
   FEATURE inside S&P, not a standalone module: lives as a third subtab
   inside #sp-tabs. Persistent worksheet form (not a modal) for the same
   reason as Vetting Desk's paste panel — entering the numbers IS the
   primary action. Reuses .sect/.vdheadline/.vdread/.vdconf/.vdwatch/
   .vddisclaimer/.vdacts/.tinybtn from elsewhere in this file rather than
   duplicating those rules. */
.dminput{background:var(--paper);border:1px solid var(--line);border-radius:13px;padding:18px 20px;margin-bottom:18px}
.dmrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px 16px;margin-bottom:6px}
.dmfield label{font-size:11px;font-weight:600;color:var(--steel);letter-spacing:.04em;text-transform:uppercase;display:block;margin-bottom:5px}
.dmfield input,.dmfield select{width:100%;border:1px solid var(--line);border-radius:9px;padding:8px 11px;
  font-size:13px;outline:none;background:#fdfdfb}
.dmfield input:focus,.dmfield select:focus{border-color:var(--steel2)}

.dmprices{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px 16px;margin-bottom:6px}
.dmprices .dmfield label{font-weight:700}

.dmdeductions{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}
.dmdedrow{display:grid;grid-template-columns:1fr 150px 130px auto;gap:9px;align-items:center}
.dmdedrow input[type=text]{border:1px solid var(--line);border-radius:9px;padding:8px 11px;font-size:12.5px;background:#fdfdfb}
.dmdedrow select{border:1px solid var(--line);border-radius:9px;padding:8px 9px;font-size:12.5px;background:#fdfdfb}
.dmdedrow input[type=number]{border:1px solid var(--line);border-radius:9px;padding:8px 11px;font-size:12.5px;background:#fdfdfb;text-align:right}

.dmfoot{display:flex;align-items:center;gap:12px;margin-top:15px;flex-wrap:wrap}

.dmresult{background:var(--paper);border:1px solid var(--line);border-radius:13px;padding:20px 22px;margin-top:6px}
.dmtable{width:100%;border-collapse:collapse;font-size:12.5px;margin-top:8px}
.dmtable th{text-align:left;font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;color:#8a93a3;
  font-weight:700;padding:6px 10px;border-bottom:1px solid var(--line2)}
.dmtable td{padding:8px 10px;border-bottom:1px solid var(--line2);color:var(--ink)}
.dmtable tr.dmrow-ineligible td{color:#9aa2b1}
.dmeligpill{font-size:10px;font-weight:700;padding:2.5px 8px;border-radius:5px;letter-spacing:.03em}
.dmeligpill.yes{background:var(--livebg);color:var(--live)}
.dmeligpill.no{background:#f8ece6;color:#b0613e}
.dmreason{font-size:10.5px;color:#9aa2b1;margin-top:3px;line-height:1.4;max-width:320px}

.dmbestline{font-size:12.5px;color:#3a4254;margin-top:12px;padding:10px 13px;background:var(--sand2);
  border-radius:8px}

.dmleanline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:6px}
.dmleanpill{font-size:11px;font-weight:700;padding:4px 11px;border-radius:6px;letter-spacing:.03em;text-transform:capitalize}
.dmlean-scrap-favourable{background:var(--livebg);color:var(--live)}
.dmlean-marginal{background:var(--warnbg);color:var(--warn)}
.dmlean-trade-on-favourable{background:#e8eef7;color:#3a567f}

/* Billing / modules page rebuild (Bridge_Build2_Billing_Rebuild_Spec.md) —
   extends reference.css's .entcard/.entrow/.eg/.price/.st (which only
   supported a flat two-state live/lock badge) with: nested add-on rows,
   a fourth "available" state, an add-on tag, an upgrade affordance, and a
   one-time setup line. Status is rendered purely from billing.js's config
   — no entitlement enforcement lives here (that's Build 3). */
.entrow.addon{padding-left:52px;background:var(--sand2)}
.entrow.addon .eg{width:30px;height:30px}
.entrow.addon .ei .en{font-size:13px;font-weight:500}
.addontag{font-size:9.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#8a93a3;
  background:var(--sand);border-radius:5px;padding:1.5px 6px;margin-right:7px;vertical-align:1px}
.tiernote{font-size:11px;color:#9aa2b1;margin-top:3px;line-height:1.5}

.entrow .eg.avail{background:#eef1f7;color:#3a567f}
.entrow .price .st.included{color:var(--live)}
.entrow .price .st.active{color:var(--live)}
.entrow .price .st.available{color:#3a567f}
.entrow .price .st.locked{color:var(--lock)}
.upgradebtn{font-size:11px;font-weight:600;color:var(--navy);background:var(--sand);border:1px solid var(--line2);
  border-radius:7px;padding:3px 9px;margin-top:5px;transition:.12s}
.upgradebtn:hover{background:var(--sand2);border-color:var(--steel2)}

.entrow.onetime{background:var(--paper);border:1px dashed var(--line);border-radius:11px}
.entrow.onetime .price .st.onetime{color:var(--steel);font-weight:600}

/* Entitlement locking (Bridge_Build3_Entitlement_Lock_Spec.md) — the
   greyed/locked state shown in place of a premium add-on's real UI
   (Vetting Flag panel, MOA generator panel, Demolition subtab) whenever
   isEntitled() is false. One shared block (entitlements.js's
   lockedPanelHtml()) reused across all three, so they look consistent. */
.vet-locked{background:var(--lockbg);color:var(--lock)}
.lockedpanel{background:var(--paper);border:1px dashed var(--line);border-radius:12px;padding:16px 18px;color:#6a7280}
.lockedhead{display:flex;align-items:center;gap:10px;color:var(--lock)}
.lockedname{font-size:14px;font-weight:600;color:var(--ink);margin-left:2px}
.lockeddesc{font-size:12.5px;line-height:1.6;color:#8a93a3;margin:9px 0 12px}

/* Hidden admin demo toggle (Bridge_Build3b_Admin_Toggle_Spec.md) -- only
   ever in the DOM behind ?admin=1 (see entitlements.js). Deliberately
   styled unlike any real product chrome (dashed amber border, fixed
   corner) so it reads as an internal tool, never mistaken for a feature a
   prospect might see. */
.adminpanel{position:fixed;bottom:16px;right:16px;z-index:80;background:#fffaf0;
  border:1.5px dashed var(--warn);border-radius:11px;padding:12px 14px;
  box-shadow:0 10px 30px rgba(17,35,63,.18);min-width:240px}
.adminhead{font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--warn);margin-bottom:8px}
.adminrow{display:flex;align-items:center;gap:8px;padding:5px 0;border-top:1px dashed var(--line2)}
.adminrow:first-of-type{border-top:none}
.adminname{font-size:12.5px;font-weight:600;color:var(--ink);flex:1}
.adminstatus{font-size:10px;font-weight:700;padding:2px 7px;border-radius:5px;letter-spacing:.03em}
.adminstatus.active{background:var(--livebg);color:var(--live)}
.adminstatus.locked{background:var(--lockbg);color:var(--lock)}
.admintogglebtn{font-size:11px;font-weight:600;padding:3px 9px;border-radius:7px;
  background:var(--sand);border:1px solid var(--line2);color:var(--navy)}
.admintogglebtn:hover{background:var(--sand2);border-color:var(--steel2)}
.admintogglebtn:disabled{opacity:.5}

@media(max-width:760px){
  .modal{width:94vw}
  .runbar{gap:8px}
  .dmdedrow{grid-template-columns:1fr;gap:6px}
  .entrow.addon{padding-left:30px}
}

/* ============ LOGIN ============
   Sits above everything (z-index over the modal scrim at 55) because it is not
   a dialog over the app -- it is what stands in front of the app when there is
   no session. Fixed and full-viewport so no part of the shell is readable or
   clickable behind it. */
.loginview{position:fixed;inset:0;z-index:200;display:none;align-items:center;justify-content:center;
  background:var(--navy,#11233f);padding:24px}
.loginbox{width:380px;max-width:94vw;background:#fff;border-radius:14px;padding:30px 28px 24px;
  box-shadow:0 24px 60px rgba(6,16,32,.42)}
/* Matches the rail lockup: the sign-in screen is the first screen a client
   sees, so a mark on the rail alone would leave the loudest surface bare. */
.loginmark{display:flex;align-items:center;gap:7px;margin-bottom:18px}
.loginmark .logo{height:40px;width:auto;display:block;flex:none}
.loginmark .b{font-family:'Fraunces',serif;font-weight:600;font-size:21px;color:var(--navy,#11233f)}
.loginmark .by{font-size:12px;color:#7d8ba1}
.loginbox h1{font-family:'Fraunces',serif;font-weight:600;font-size:23px;color:var(--navy,#11233f);margin-bottom:4px}
.loginsub{font-size:13px;color:#6b7a90;margin-bottom:20px}
.loginbox label{display:block;font-size:12px;font-weight:600;color:#48566b;margin-bottom:5px}
/* 16px IS A FUNCTIONAL REQUIREMENT ON iOS, NOT A TYPOGRAPHIC CHOICE. Safari
   auto-zooms the page when a text input under 16px takes focus, and does
   not zoom back out afterwards. At 14px that happened on the FIRST TAP of
   the FIRST SCREEN a client ever sees, leaving them zoomed into a login
   box with the rest of the page off-screen. Do not reduce this. */
.loginbox input{width:100%;padding:10px 12px;border:1px solid #d5dce6;border-radius:8px;font-size:16px;
  margin-bottom:14px;font-family:inherit;color:var(--navy,#11233f);background:#fff}
.loginbox input:focus{outline:none;border-color:#4a7fc1;box-shadow:0 0 0 3px rgba(74,127,193,.16)}
.loginerr{background:#fdeceb;border:1px solid #f2c4c0;color:#9c2a20;border-radius:8px;
  padding:9px 11px;font-size:13px;margin-bottom:14px}
.loginbox button{width:100%;padding:11px;border:0;border-radius:8px;background:var(--navy,#11233f);
  color:#fff;font-size:14px;font-weight:600;font-family:inherit;cursor:pointer}
.loginbox button:hover{background:#1b3358}
.loginbox button:disabled{opacity:.6;cursor:default}
.loginfoot{font-size:11.5px;color:#8b98ab;margin-top:16px;line-height:1.5}
/* Your account (gate 14, L2): the login form's field treatment, 16px inputs
   for the same iOS reason as the login box above. */
.acctform{max-width:420px;margin-top:20px;background:#fff;border:1px solid #e3e8ef;border-radius:13px;padding:20px}
.acctform label{display:block;font-size:12px;font-weight:600;color:#48566b;margin-bottom:5px}
.acctform input{width:100%;padding:10px 12px;border:1px solid #d5dce6;border-radius:8px;font-size:16px;
  margin-bottom:14px;font-family:inherit;color:var(--navy,#11233f);background:#fff}
.acctform input:focus{outline:none;border-color:#4a7fc1;box-shadow:0 0 0 3px rgba(74,127,193,.16)}
.accthint{font-size:12px;color:#6b7a90;margin:-4px 0 14px;line-height:1.5}
.acctok{background:#eaf6ee;border:1px solid #bfe3cb;color:#1e6b3a;border-radius:8px;
  padding:9px 11px;font-size:13px;margin-bottom:14px}
.acctform button{padding:10px 16px;border:0;border-radius:8px;background:var(--navy,#11233f);
  color:#fff;font-size:14px;font-weight:600;font-family:inherit;cursor:pointer}
.acctform button:disabled{opacity:.6;cursor:default}
/* The second factor (gate 14, L6): the code step, enrolment's QR and setup
   key, and the recovery codes shown once. The code input keeps the 16px rule
   above by being a .loginbox input; the tick box opts out of its full width. */
.loginbox .remember{display:flex;align-items:center;gap:8px;font-weight:500;color:#48566b;
  font-size:13px;margin:-4px 0 14px;cursor:pointer}
.loginbox .remember input{width:auto;margin:0;flex:none}
.enrolqr{width:200px;height:200px;margin:4px auto 12px;border:1px solid #e3e8ef;border-radius:8px;
  padding:6px;background:#fff}
.enrolqr svg{width:100%;height:100%;display:block}
.enrolkey{display:block;font-family:ui-monospace,Consolas,monospace;font-size:13px;letter-spacing:.04em;
  background:#f3f6fa;border:1px solid #e3e8ef;border-radius:6px;padding:8px 10px;margin:0 0 16px;
  word-break:break-all;color:var(--navy,#11233f);user-select:all}
.recoverycodes{columns:2;column-gap:18px;margin:0 0 18px 22px;padding:0;
  font-family:ui-monospace,Consolas,monospace;font-size:14px;color:var(--navy,#11233f)}
.recoverycodes li{margin-bottom:6px}
.loginfoot a{color:#4a7fc1}
.acctsection{max-width:420px;margin-top:20px;background:#fff;border:1px solid #e3e8ef;border-radius:13px;padding:20px}
.acctsection h2{font-family:'Fraunces',serif;font-weight:600;font-size:18px;color:var(--navy,#11233f);margin-bottom:6px}
.acctsection .acctform{margin-top:12px;border:0;padding:0}
.acctsection .linkbtn{padding:9px 14px;border:1px solid #d5dce6;border-radius:8px;background:#fff;
  color:var(--navy,#11233f);font-size:13px;font-weight:600;font-family:inherit;cursor:pointer;margin-top:4px}
.tenant .signout{margin-left:auto;background:transparent;border:1px solid rgba(255,255,255,.22);
  color:rgba(255,255,255,.72);border-radius:6px;padding:4px 8px;font-size:11px;font-family:inherit;cursor:pointer}
.tenant .signout:hover{border-color:rgba(255,255,255,.45);color:#fff}

/* ===== Operator dashboard (ops.js) =====
   FOUR SEVERITIES, FOUR TREATMENTS. Three greys would defeat the point of
   separating the evidence cases at all: an operator acts differently on
   "never came up" (fix the service definition) than on "too early to tell"
   (wait) than on "you switched this off" (decide whether you meant to).
   `unproven` is hatched rather than merely pale, so it reads as NOT MEASURED
   rather than as a muted version of fine. */
.opsheadline{font-size:23px;font-weight:650;letter-spacing:-.01em;padding:14px 18px;
  border-radius:12px;border:1px solid var(--line);margin-top:18px}
.opsheadline.ok{background:var(--livebg);color:var(--live);border-color:#cfe3dc}
.opsheadline.bad{background:var(--alertbg);color:var(--alert);border-color:#eccfcf}
.opsheadline.unproven{background:var(--sand2);color:var(--steel);
  border-style:dashed;border-color:var(--steel2)}

.opsmeta{font-size:12px;color:var(--steel);margin:8px 2px 0}
/* Sorting is paused (Outage B, R1): the board line, above everything else on
   the board, in the draft-warning amber -- a state to know, not an alarm. */
.pausedline{margin:8px 0 10px;padding:10px 14px;border-radius:8px;font-size:13.5px;
  background:#fff6e5;border:1px solid #f0dcb4;color:#7a5a15}
.stalebanner{margin-top:10px;padding:11px 14px;border-radius:10px;font-size:13.5px;
  font-weight:600;background:var(--alertbg);color:var(--alert);border:1px solid #eccfcf}
/* The whole page dims when its own figures are stale, so a frozen board cannot
   be mistaken for a calm one at a glance across a room. */
#v-ops.stalepage .opsrows,#v-ops.stalepage .opsheadline,
#v-ops.stalepage .factstrip,#v-ops.stalepage .opsmeasure{opacity:.45;filter:grayscale(.6)}

.opsrows{display:flex;flex-direction:column;gap:10px;margin-top:14px}
.opsrow{background:var(--paper);border:1px solid var(--line);border-radius:11px;padding:12px 14px}
.opsrow[data-severity="unproven"]{border-style:dashed;border-color:var(--steel2);
  background:repeating-linear-gradient(135deg,var(--sand2),var(--sand2) 7px,var(--paper) 7px,var(--paper) 14px)}
.opshead{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.opsname{font-weight:640;color:var(--navy)}
.opssentence{margin-top:7px;font-size:13.5px;color:var(--ink);line-height:1.5}
.opsrunbook{margin-top:6px;font-size:11.5px;color:var(--steel);font-style:italic}

.sevchip{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  padding:3px 8px;border-radius:6px}
.sevchip.ok{background:var(--livebg);color:var(--live)}
.sevchip.bad{background:var(--alertbg);color:var(--alert)}
.sevchip.known{background:var(--warnbg);color:var(--warn)}
.sevchip.unproven{background:transparent;color:var(--steel);
  border:1px dashed var(--steel2)}

/* The evidence label is SERVER TEXT. It exists because severity cannot carry
   the distinction: no_clock and polling_switched_off are both `unproven`. */
.evchip{font-size:11px;color:var(--navy);background:var(--sand);
  border:1px solid var(--line);border-radius:6px;padding:2px 8px}

.mockband{margin-top:16px;padding:13px 16px;border-radius:11px;font-weight:640;font-size:14px;
  background:var(--warnbg);color:var(--warn);border:2px solid var(--gold)}
.opsmeasure{margin-top:14px;font-size:13px;color:var(--ink);background:var(--sand2);
  border:1px solid var(--line2);border-radius:10px;padding:11px 14px}
.opsspend{margin-top:8px;border-collapse:collapse}
.opsspend th,.opsspend td{padding:2px 18px 2px 0;text-align:left;vertical-align:top}
.factstrip{margin-top:14px;display:flex;gap:18px;flex-wrap:wrap;font-size:12px;color:var(--steel);
  border-top:1px solid var(--line2);padding-top:11px}
.factstrip b{color:var(--navy);font-weight:600}

/* ===== Mail status (client_status.js) =====
   The desk's own view. Two states only -- flowing or not -- because the client
   cannot act on the difference between `blind` and `never_came_up`, and a page
   offering them four shades of uncertainty is a page that worries them without
   telling them anything. The sentence carries the detail. */
.mailstate{border-radius:12px;border:1px solid var(--line);padding:16px 18px;margin-top:18px}
.mailstate.ok{background:var(--livebg);border-color:#cfe3dc}
.mailstate.bad{background:var(--alertbg);border-color:#eccfcf}
.mailhead{font-size:20px;font-weight:650;letter-spacing:-.01em}
.mailstate.ok .mailhead{color:var(--live)}
.mailstate.bad .mailhead{color:var(--alert)}
.mailsentence{margin-top:7px;font-size:14px;line-height:1.55;color:var(--ink)}
.mailmeta{margin-top:8px;font-size:12px;color:var(--steel)}
.mailcard{margin-top:12px;background:var(--paper);border:1px solid var(--line);
  border-radius:11px;padding:14px 16px}
.mailcardhead{font-weight:640;color:var(--navy);font-size:13.5px}
.mailcard .ghostbtn{margin-top:10px}
.mailasof{margin-top:14px;font-size:12px;color:var(--steel);text-align:right}


/* ---------- V5: the icon rail (5 Sep 2026) ----------
   APPENDED AT FILE END DELIBERATELY: these override .rail's base width at
   equal specificity, and at equal specificity SOURCE ORDER WINS — a base
   rule written after its override shipped a drawer that could not close
   (the catalogued media-query defeat). Keep this block last. */
.railmintoggle{position:absolute;top:10px;right:8px;background:none;border:0;color:inherit;cursor:pointer;opacity:.6;padding:4px}
.railmintoggle:hover{opacity:1}
.railmintoggle:focus-visible{outline:2px solid currentColor;border-radius:4px}
body.railmin .rail{width:58px;min-width:58px;overflow:hidden}
body.railmin .rail .t,body.railmin .rail .lbl,body.railmin .rail .sub,
body.railmin .rail .b,body.railmin .rail .by,body.railmin .rail .who,
body.railmin .rail .railftr{display:none}
body.railmin .rail .logo{width:32px;height:auto}
body.railmin .rail .nav button{justify-content:center;padding-left:0;padding-right:0}
body.railmin .rail .tenant{justify-content:center}
body.railmin .railmintoggle svg{transform:rotate(180deg)}
@media (max-width:760px){
  body.railmin .rail{width:auto;min-width:0}
  /* The collapse toggle is a DESKTOP control. On a phone the rail is a
     drawer and this button sat exactly over #railx, intercepting the close
     tap -- the couldn't-close-the-drawer defect class reproduced by the
     control added to shrink the rail, caught by the guard built from the
     original incident (test_every_panel_that_opens_can_be_closed[rail],
     5 Sep 2026). */
  .railmintoggle{display:none}
}

/* ===== Client account pages, 22 Sep 2026 =====================================
   Styles for the three pages ruled honest this round. Kept together and dated
   so a reader meets one decision rather than five orphans. */

/* THE RAIL'S MODULE STATUS. The span ships CLASSLESS and carries no colour of
   its own: `paintModuleStatus()` adds `.dotlive` for an entitled module and a
   `.lockic` lock glyph for a locked one. A boot where that never runs shows
   NOTHING rather than a green dot on a module the desk has not bought —
   absent, not false, which is the whole point of the change. */
.moddot{flex:none;display:inline-flex;align-items:center}

/* The quota position — the one number the Usage tab now renders. */
.quotaline{display:flex;align-items:baseline;gap:10px;margin-top:6px}
.quotanum{font-family:Fraunces,Georgia,serif;font-size:30px;font-weight:600;color:var(--ink)}
.quotalbl{font-size:13px;color:#6b7687}

/* An agreed matching rule: a value the desk cannot edit here. Deliberately NOT
   styled as a disabled input — a greyed-out field reads as "editable, but not
   by you right now", which invites the client to look for the way to enable it.
   A plain value reads as a fact, which is what it is. */
.agreedval{font-family:Fraunces,Georgia,serif;font-size:19px;font-weight:600;
  color:var(--ink);white-space:nowrap;padding-left:18px}

/* The plan line on Modules & billing, above the contracted modules. */
.entrow.planline{background:#f7f9fc}
.entrow.planline .en{font-weight:600}

/* The Google mailbox connection indicator (connector G2). Red when not
   connected, the module green when it is; the hint names the account that
   must approve, visible before any click. */
.gconn{position:relative;align-items:center;gap:8px}
.gconnbtn{font-size:12px;font-weight:600;padding:6px 11px;border-radius:20px;border:0;
  cursor:pointer;text-decoration:none;white-space:nowrap;font-family:inherit}
.gconnbtn.ok{background:var(--livebg);color:var(--live)}
.gconnbtn.bad{background:var(--alertbg);color:var(--alert)}
.gconnhint{font-size:11.5px;color:var(--steel);max-width:220px}
.gconnpanel{position:absolute;right:0;top:calc(100% + 6px);z-index:30;width:300px;
  background:#fff;border:1px solid var(--line);border-radius:10px;padding:12px;
  box-shadow:var(--shadow);font-size:13px;display:flex;flex-direction:column;gap:8px}
.gnotice{align-items:center;justify-content:space-between;gap:12px;margin:0 28px 10px;
  padding:10px 14px;border-radius:9px;font-size:13px;background:var(--livebg);color:var(--live)}
.gnotice.bad{background:var(--alertbg);color:var(--alert)}
/* The hint stays on a phone: the ruling is that the approving account is
   named before any flow starts, on every screen. */
@media(max-width:760px){.gconnhint{max-width:140px;font-size:11px}.gnotice{margin:0 12px 10px}}

/* THE HEADER WRAPS RATHER THAN OVERFLOWING (ruled 13 Oct 2026, product lane).
   At 375 px the not-connected header made the page 617 px wide, 710 px with
   Disconnect beside it, the button off screen; the key-unreadable sentence
   (659 px) and even Connected (574 px) overflowed too. The bar was a fixed
   58 px row that could not wrap, and the indicator a nowrap pill. Now the bar
   grows a row when it must, the actions wrap under the crumb, and on a phone
   the pill's sentence wraps inside it. Unchanged on a wide screen, where
   nothing needs to wrap: 58 px is kept as the minimum.
   BASE RULES BEFORE THE MEDIA QUERY, deliberately -- at equal specificity
   source order wins, and a base rule after its media block is the defect this
   file's mobile drawer once shipped (CLAUDE.md, "A FIX WHOSE OWN BASE RULE
   DEFEATED THE MEDIA QUERY"). */
.topbar{height:auto;min-height:58px;flex-wrap:wrap;row-gap:8px;padding-top:8px;padding-bottom:8px}
.topact{flex-wrap:wrap;justify-content:flex-end;min-width:0;max-width:100%}
.gconn{flex-wrap:wrap;min-width:0;max-width:100%}
@media(max-width:760px){
  .topbar{padding-left:16px;padding-right:16px}
  .gconnbtn{white-space:normal;border-radius:12px}
}
