/* User Panel — the schuckconsulting.com theme, token for token.

   These are the SAME values as menace/src/core/brand.js, which were read off the
   live site with getComputedStyle rather than eyeballed. Client pages, internal
   pages, reports and email all resolve to one palette, so the portal, the PDF a
   client downloads from it and the mail it arrived in are visibly one firm.
   If the site changes, change brand.js and mirror it here.

   The two typefaces are self-hosted, not fetched from Google. The CSP is
   default-src 'self', so a CDN font would be blocked, and a portal behind a
   login should not be announcing its visitors to a third party either. */
@font-face{font-family:'Albert Sans';font-style:normal;font-weight:400 900;font-display:swap;
  src:url(/AlbertSans.woff2) format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 900;font-display:swap;
  src:url(/Inter.woff2) format('woff2')}
:root{
  --brand:#58CBF5; --brand-deep:#0E8FC2; --sand:#cfcabe;
  /* the site's own dark bands */
  --dark:#1D202B; --dark-panel:#202636; --dark-deep:#0D0F16;
  --bg:#F9F9F9; --panel:#ffffff; --panel-2:#F4F6F8; --line:#E3E6EA;
  --ink:#111111; --dim:#494C4F; --faint:#8A8F94;
  --cyan:#58CBF5; --cyan-ink:#0E8FC2;
  --ok:#12833C; --need:#A9670A; --build:#0E8FC2; --bad:#C0392B;
  --ok-bg:#E7F4EC; --need-bg:#FBF0DA; --build-bg:#DFF1FA; --bad-bg:#F9E4E1;
  --shadow:0 1px 2px rgba(17,26,34,.05), 0 6px 18px rgba(17,26,34,.05);
  --shadow-sm:0 1px 2px rgba(17,26,34,.05);
  /* Modern design: one consistent radius scale + subtle motion (brand colours unchanged) */
  --r-lg:16px; --r-md:10px; --r-sm:8px; --r-xs:6px; --r-pill:999px; --tr:.16s ease;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --sans:'Inter',ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --head:'Albert Sans',ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --bg:#14161E; --panel:#1D202B; --panel-2:#202636; --line:#2C3140;
  --ink:#E9EDF2; --dim:#A6AEB8; --faint:#7A828D;
  --cyan-ink:#58CBF5; --brand-deep:#58CBF5;
  --ok:#35D94C; --need:#FFB020; --build:#58CBF5; --bad:#FF6A5A;
  --ok-bg:#0F2417; --need-bg:#26200C; --build-bg:#0B2432; --bad-bg:#2A1210;
  --shadow:0 1px 0 rgba(0,0,0,.4), 0 18px 40px rgba(0,0,0,.4);
}}
:root[data-theme="dark"]{
  --bg:#14161E; --panel:#1D202B; --panel-2:#202636; --line:#2C3140;
  --ink:#E9EDF2; --dim:#A6AEB8; --faint:#7A828D;
  --cyan-ink:#58CBF5; --brand-deep:#58CBF5;
  --ok:#35D94C; --need:#FFB020; --build:#58CBF5; --bad:#FF6A5A;
  --ok-bg:#0F2417; --need-bg:#26200C; --build-bg:#0B2432; --bad-bg:#2A1210;
  --shadow:0 1px 0 rgba(0,0,0,.4), 0 18px 40px rgba(0,0,0,.4);
}

*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);line-height:1.55;
     -webkit-font-smoothing:antialiased}
a{color:var(--cyan-ink)}
.wrap{flex:1;min-width:0;padding:clamp(16px,3vw,34px) clamp(16px,3vw,26px) 70px}
.eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--cyan-ink);margin:0}
h1{font-family:var(--head);font-weight:800;font-size:clamp(24px,3.6vw,34px);line-height:1.08;margin:5px 0 0;letter-spacing:-.02em}
h2{font-family:var(--head);font-weight:800;font-size:19px;margin:0;letter-spacing:-.01em}
.mono{font-family:var(--mono);font-size:12px;font-variant-numeric:tabular-nums}

/* top bar */
.bar{background:var(--dark);border-bottom:3px solid var(--brand)}
.bar strong{color:#fff;font-family:var(--head);font-weight:800;letter-spacing:-.01em}
.bar .in{max-width:1080px;margin:0 auto;padding:12px clamp(16px,3vw,26px);display:flex;gap:14px;
         align-items:center;flex-wrap:wrap}
.bar .who{margin-left:auto;display:flex;gap:12px;align-items:center;font-size:13px;color:#A6AEB8}
.bar .sys{font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--brand)}
.navlinks{display:flex;gap:7px;flex-wrap:wrap}
.navlinks a{padding:5px 12px;border:1px solid rgba(255,255,255,.16);border-radius:999px;background:transparent;
            text-decoration:none;font-size:12.5px;color:#C8CDD6}
.navlinks a:hover{color:#fff;border-color:var(--brand)}
.navlinks a.here{color:var(--dark);border-color:var(--brand);font-weight:600;background:var(--brand)}

/* Light / Auto / Dark. A form, not a script — this portal serves no JavaScript
   at all, so each option is a real submit button and the server re-renders. */
.themesw{display:flex;margin:0;border:1px solid rgba(255,255,255,.18);border-radius:999px;overflow:hidden}
.themesw button{border:0;background:transparent;color:#C8CDD6;cursor:pointer;font-family:var(--mono);
  font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:6px 11px;display:flex;gap:5px;
  align-items:center;line-height:1.4}
.themesw button+button{border-left:1px solid rgba(255,255,255,.14)}
.themesw button:hover{color:#fff;background:rgba(255,255,255,.07)}
.themesw button.on{background:var(--brand);color:var(--dark);font-weight:700}
.bar .who form.inline{margin:0}
.bar .who .btn.ghost{width:auto;margin:0;padding:6px 13px}
/* the word goes at narrow widths, the glyph carries it */
/* Icon-only, so it is the same compact size at every width. */

.head{border-bottom:3px solid var(--brand);padding-bottom:15px;margin-bottom:22px}
.head .lede{color:var(--dim);margin:9px 0 0;max-width:74ch;font-size:14.5px}

/* The account total, top right. The brand cyan on the site's dark band is the
   loudest thing the palette has, which is what this is meant to be: the figure a
   client came to check, readable before anything else on the page. */
.head.withcost{display:flex;gap:22px;align-items:flex-start;justify-content:space-between;flex-wrap:wrap}
.head.withcost .hmain{flex:1 1 380px;min-width:0}
.costbox{flex:0 0 auto;background:var(--dark);border-radius:11px;padding:14px 20px 15px;
         border:1px solid var(--dark);box-shadow:var(--shadow);text-align:right;min-width:190px}
.costbox .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--brand)}
.costbox .v{font-family:var(--head);font-weight:800;font-size:31px;line-height:1.12;margin-top:5px;
            color:var(--brand);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.costbox .n{font-size:12px;color:#C8CDD6;margin-top:4px}
.costbox .asof{font-family:var(--mono);font-size:10px;color:#7A828D;margin-top:6px}
@media (max-width:640px){
  .head.withcost{flex-direction:column}
  .costbox{width:100%;text-align:left}
}

.strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;background:var(--line);
       border:1px solid var(--line);border-radius:10px;overflow:hidden;margin:0 0 26px}
.cell{background:var(--panel);padding:12px 14px;display:block;color:inherit;text-decoration:none;transition:background .12s}
a.cell:hover,a.cell:focus-visible{background:var(--panel-2)}
.cell .k{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint)}
.cell .v{font-family:var(--head);font-weight:800;font-size:20px;margin-top:3px;font-variant-numeric:tabular-nums}
.cell .n{font-size:11.5px;color:var(--dim);margin-top:1px}

.card{border:1px solid var(--line);border-radius:11px;background:var(--panel);box-shadow:var(--shadow);
      padding:17px 19px;margin-bottom:20px}
.card .chead{display:flex;gap:10px;align-items:baseline;justify-content:space-between;flex-wrap:wrap;margin-bottom:12px}
.card .meta{font-family:var(--mono);font-size:11px;color:var(--faint);letter-spacing:.06em}

.pill{display:inline-block;font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;
      padding:3px 8px;border-radius:99px;font-weight:700;white-space:nowrap}
.p-ok{background:var(--ok-bg);color:var(--ok)}
.p-need{background:var(--need-bg);color:var(--need)}
.p-build{background:var(--build-bg);color:var(--build)}
.p-bad{background:var(--bad-bg);color:var(--bad)}
.p-flat{background:var(--panel-2);color:var(--faint)}

.cols{display:grid;grid-template-columns:1fr 1fr;gap:18px}
@media (max-width:760px){.cols{grid-template-columns:1fr}}

.scope ul{margin:7px 0 0;padding-left:19px;color:var(--dim);font-size:13.5px;line-height:1.7}
.scope .out li{color:var(--faint)}
.ver{border-left:2px solid var(--line);padding:2px 0 2px 13px;margin-top:14px}
.ver.now{border-left-color:var(--brand)}
.ver .vh{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
.ver .vh b{font-size:14px}

.feed{list-style:none;margin:0;padding:0}
.feed li{padding:12px 0;border-bottom:1px solid var(--line)}
.feed li:last-child{border-bottom:none}
.feed .ft{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
.feed .ft b{font-size:14.5px}
.feed p{margin:5px 0 0;color:var(--dim);font-size:13.5px}
/* The plain-English brief on a paywalled document. Numbered so a buyer can refer
   to an item ("what is number 7?"), and numbered in the same cyan as the pay
   button so the two read as one design. var(--cyan-ink) rather than a literal
   #58CBF5: it resolves to the bright cyan on the dark theme and to the darker
   #0E8FC2 on the light one, which is the only version that holds 4.5:1 on white. */
.feed.brief li{display:flex;gap:12px;align-items:flex-start;padding:11px 0}
.feed.brief .n{flex:none;min-width:1.6em;font-weight:800;color:var(--cyan-ink);
  font-size:15px;line-height:1.5;font-variant-numeric:tabular-nums}
.feed.brief .ft{display:block;line-height:1.5}
.empty{color:var(--faint);font-family:var(--mono);font-size:12px}

/* Documents. The two actions sit on one line with the filename and size beside
   them, so a client can see what they are about to open before they open it. */
.feed.docs li{padding:15px 0}
.docs .dl{display:flex;flex-wrap:wrap;gap:9px;align-items:center;margin-top:10px}
.docs .dl .btn{padding:7px 15px;border-radius:7px;font-family:var(--mono);font-size:10.5px;
               letter-spacing:.13em;text-transform:uppercase;font-weight:700;text-decoration:none;
               display:inline-block;line-height:1.5}
/* View is the quiet one, Download is the brand action: opening in a tab is the
   cheaper move and should not shout louder than saving a copy. */
.docs .dl .btn:first-child:not(.primary){background:var(--panel);color:var(--dim);border-color:var(--line)}
.docs .dl .btn:first-child:not(.primary):hover{border-color:var(--brand);color:var(--ink)}
.docs .dl .btn+.btn{margin-left:0}
.docs .dl .mono{font-size:11px}

/* ---- sign in: "Centered Card" — values taken from the mockup ---- */
body.d2{min-height:100vh;background:var(--bg);display:grid;place-items:center;padding:clamp(20px,4vw,48px);
  background-image:radial-gradient(circle at 12% 8%,color-mix(in srgb,var(--brand) 16%,transparent),transparent 42%),
    radial-gradient(circle at 88% 96%,color-mix(in srgb,var(--sand) 34%,transparent),transparent 44%)}
.d2 .card{width:100%;max-width:432px;background:var(--panel);border:1px solid var(--line);border-radius:18px;
  padding:clamp(24px,4vw,38px);box-shadow:0 24px 60px rgba(11,42,56,.13);margin:0}
.d2 .card img{height:28px;margin:0 auto 22px;display:block}
.d2 .card img.logo-l{display:block}
.d2 .card img.logo-d{display:none}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .d2 .card img.logo-l{display:none}
  :root:not([data-theme="light"]) .d2 .card img.logo-d{display:block}}
:root[data-theme="dark"] .d2 .card img.logo-l{display:none}
:root[data-theme="dark"] .d2 .card img.logo-d{display:block}
.d2 h1{text-align:center;font-size:21px;margin:0 0 4px;letter-spacing:-.015em}
.d2 .sub{text-align:center;color:var(--dim);font-size:13.5px;margin:0 0 24px}
.d2 .foot{text-align:center;font-size:12.5px;color:var(--faint);margin-top:22px}
.d2 .foot a{color:var(--cyan-ink);text-decoration:none}
.d2 .foot a:hover{text-decoration:underline}

.tabs{display:flex;gap:0;margin:0 0 20px;border:1px solid var(--line);border-radius:10px;overflow:hidden;
      background:var(--panel-2)}
.tabs a{flex:1;text-align:center;padding:10px 8px;text-decoration:none;font-size:14px;color:var(--dim)}
.tabs a.on{color:var(--ink);font-weight:650;background:var(--panel)}
.tabs a:hover:not(.on){color:var(--ink)}

.f label{display:block;font-size:13px;font-weight:600;color:var(--ink);margin:14px 0 6px;
         font-family:var(--sans);letter-spacing:0;text-transform:none}
.f label .opt{font-weight:400;color:var(--faint)}
.f input[type=email],.f input[type=password],.f input[type=text],.f input[type=tel],.f input:not([type]){
      width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:9px;background:var(--panel-2);
      color:var(--ink);font-family:var(--sans);font-size:14.5px}
.f input::placeholder{color:var(--faint)}
.f input:focus{outline:2px solid color-mix(in srgb,var(--brand) 50%,transparent);outline-offset:1px;
               border-color:var(--brand)}
.two{display:grid;grid-template-columns:1fr 1fr;gap:0 12px}
.gate{font-size:12.5px;color:var(--dim);background:var(--panel-2);border:1px solid var(--line);border-radius:9px;
      padding:10px 12px;margin:0 0 16px}
.rowbits{display:flex;align-items:center;justify-content:space-between;margin:14px 0 0;font-size:13px}
.rowbits a{color:var(--cyan-ink);text-decoration:none;font-weight:600}
.rowbits a:hover{text-decoration:underline}
.rowbits label{display:flex;align-items:center;gap:7px;margin:0;font-weight:400;color:var(--dim);font-size:13px}
.rowbits input{width:auto;margin:0;accent-color:var(--brand)}
.go{width:100%;margin-top:18px;padding:12px;border-radius:9px;border:1px solid var(--brand);cursor:pointer;
    background:var(--brand);color:#062733;font-family:var(--sans);font-size:14.5px;font-weight:650}
.go:hover{filter:brightness(1.07)}
.or{display:flex;align-items:center;gap:12px;margin:18px 0;color:var(--faint);font-size:11.5px;
    font-family:var(--mono);letter-spacing:.14em;text-transform:uppercase}
.or:before,.or:after{content:"";flex:1;height:1px;background:var(--line)}
.alt{width:100%;font-family:var(--sans);font-size:14px;font-weight:600;padding:11px;border:1px solid var(--line);
     border-radius:9px;background:var(--panel);color:var(--ink);cursor:pointer;display:flex;align-items:center;
     justify-content:center;gap:9px;text-decoration:none;box-sizing:border-box}
.alt:hover{border-color:var(--brand)}
.ms{width:15px;height:15px;display:grid;grid-template:1fr 1fr/1fr 1fr;gap:1.5px;flex:0 0 15px}
.ms i{display:block}
.ms i:nth-child(1){background:#F25022}
.ms i:nth-child(2){background:#7FBA00}
.ms i:nth-child(3){background:#00A4EF}
.ms i:nth-child(4){background:#FFB900}
.err{margin:0 0 16px;background:var(--bad-bg);color:var(--bad);border-radius:9px;padding:11px 13px;font-size:13.5px}
.notice{margin:0 0 16px;background:var(--build-bg);color:var(--build);border-radius:9px;padding:11px 13px;font-size:13.5px}

/* the signed-in pages keep their own button style */
.btn{padding:12px;border-radius:9px;border:1px solid var(--brand);cursor:pointer;background:var(--brand);
     color:#062733;font-family:var(--sans);font-size:14px;font-weight:650}
.btn.ghost{background:var(--panel);color:var(--dim);border-color:var(--line);font-family:var(--mono);
           font-size:11px;letter-spacing:.14em;text-transform:uppercase;font-weight:700}
.btn.ghost:hover{border-color:var(--brand);color:var(--ink)}

/* account + staff console */
table.kv{width:100%;border-collapse:collapse;font-size:14px}
table.kv th{text-align:left;font-weight:600;color:var(--dim);font-size:13px;padding:8px 12px 8px 0;
            white-space:nowrap;vertical-align:top;width:1%}
table.kv td{padding:8px 0;border-bottom:1px solid var(--line)}
table.kv tr:last-child td{border-bottom:none}
/* A Notes field can be a real multi-line spec sheet, not just a sentence —
   plain HTML collapses its line breaks, so preserve them without needing a
   textarea's monospace look. */
.notes-pre{white-space:pre-wrap;font-family:var(--sans)}
.ok-note{background:var(--ok-bg);color:var(--ok);border-radius:9px;padding:11px 13px;font-size:13.5px;margin-bottom:14px}
form.inline{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:9px}
form.inline select{padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--panel-2);
                   color:var(--ink);font-family:var(--sans);font-size:13px}
button.mini{padding:7px 14px;border-radius:8px;border:1px solid var(--line);background:var(--panel);
            color:var(--dim);font-family:var(--sans);font-size:13px;font-weight:600;cursor:pointer}
button.mini:hover{border-color:var(--brand);color:var(--ink)}
button.mini.go{width:auto;margin:0;background:var(--brand);border-color:var(--brand);color:#062733}
.card .f label{margin-top:12px}
.card .hint{margin-top:12px}

/* internal pages: the freshness stamp */
.asof{font-family:var(--mono);font-size:11.5px;color:var(--faint);margin:-8px 0 20px;letter-spacing:.03em}
.asof.stale{color:var(--need)}
.asof b{color:var(--dim);font-weight:600}
.asof.stale b{color:var(--need)}

/* public status page */
.statusbanner{display:flex;align-items:center;gap:12px;border-radius:11px;padding:15px 18px;margin-bottom:22px;
  border:1px solid var(--line);font-size:15.5px}
.statusbanner.ok{background:var(--ok-bg);border-color:color-mix(in srgb,var(--ok) 35%,transparent);color:var(--ok)}
.statusbanner.bad{background:var(--bad-bg);border-color:color-mix(in srgb,var(--bad) 40%,transparent);color:var(--bad)}
.statusbanner .sdot{width:10px;height:10px;border-radius:50%;background:currentColor;flex:0 0 10px}
.statusbanner .when{margin-left:auto;font-family:var(--mono);font-size:11px;opacity:.75}
.srow{display:flex;align-items:center;gap:16px;padding:14px 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
.srow:last-of-type{border-bottom:none}
.sname{flex:1 1 220px;font-weight:600;font-size:15px}
.sname .sblurb{display:block;font-weight:400;font-size:12.5px;color:var(--faint);margin-top:2px}
.sstrip{display:flex;gap:2px;align-items:center;flex:0 0 auto}
.sstrip i{display:block;width:4px;height:22px;border-radius:2px;background:var(--ok);opacity:.85}
.sstrip i.down{background:var(--bad);opacity:1}
.sstrip .sempty{font-family:var(--mono);font-size:11px;color:var(--faint)}
.sstate{flex:0 0 auto;display:flex;align-items:center;gap:9px;min-width:170px;justify-content:flex-end}
.suptime{font-family:var(--mono);font-size:12px;color:var(--dim);font-variant-numeric:tabular-nums}
.sdetail{font-family:var(--mono);font-size:11.5px;color:var(--bad);padding:0 0 12px}
.bar .who a{text-decoration:none;font-size:13px}
@media (max-width:640px){.sstate{min-width:0;width:100%;justify-content:flex-start}.sstrip{order:3}}

/* CRM rows — same feed styling as the rest of the panel, plus money figures */
.mrow{margin:6px 0 0;display:flex;gap:14px;flex-wrap:wrap}
.mfig{font-family:var(--mono);font-size:12.5px;color:var(--dim);font-variant-numeric:tabular-nums}
.f select{width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:9px;background:var(--panel-2);
  color:var(--ink);font-family:var(--sans);font-size:14.5px}
button.mini[disabled]{opacity:.4;cursor:not-allowed}

/* Raise a request. The one place a client writes INTO the CRM, so it reads as a
   deliberate form rather than a comment box: full-width field, clear send. */
.reqf{display:grid;gap:6px;max-width:640px}
.reqf label{font-size:12.5px;color:var(--dim);margin-top:6px}
.reqf .opt{color:var(--faint)}
.reqf input,.reqf textarea{font-family:var(--sans);font-size:14px;padding:10px 12px;border-radius:9px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);width:100%}
.reqf textarea{resize:vertical}
.reqf input:focus,.reqf textarea:focus{outline:2px solid var(--brand);outline-offset:1px;border-color:var(--brand)}
.reqf .btn{width:auto;justify-self:start;margin-top:10px;padding:9px 20px;font-size:13px}
.notice-ok{background:var(--ok-bg);color:var(--ok);border-radius:9px;padding:10px 13px;margin:0 0 12px;font-size:13.5px}
.notice-bad{background:var(--bad-bg);color:var(--bad);border-radius:9px;padding:10px 13px;margin:0 0 12px;font-size:13.5px}
.feed.reqs{margin-top:16px;border-top:1px solid var(--line);padding-top:6px}

/* ---------- Users ---------- */
/* The dot carries the whole meaning of this page, so it is sized to be readable
   at a glance in a screenshot, and never relies on colour alone: each one has a
   title and an aria-label saying which of the three states it is. */
.dot{display:inline-block;width:11px;height:11px;border-radius:50%;vertical-align:middle;
  box-shadow:0 0 0 3px color-mix(in srgb, currentColor 12%, transparent)}
.dot.green{background:#1FA971;color:#1FA971}
.dot.red{background:#D6453D;color:#D6453D}
/* A machine that is switched off is not a fault, so it must not borrow the red
   that means something is wrong. Neutral grey, and the state is still written
   out in the cell beside it. */
.dot.grey{background:var(--faint);color:var(--faint)}

/* Figures that line up in a column. Scoped to tables so it cannot collide with
   the .num inside .netconsole, which sets its own font and size. */
table.grid td.num,table.grid th.num{text-align:right;font-variant-numeric:tabular-nums}

table.grid{width:100%;border-collapse:collapse;font-size:14px}
table.grid th{text-align:left;font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--faint);font-weight:600;padding:0 10px 8px;
  border-bottom:1px solid var(--line);white-space:nowrap}
/* Dates and the button are read as single units — a wrapped "Aug 18, 10:35 / AM"
   or a two-line button label both read as sloppy in a screenshot. This assumes
   columns 3 and 4 are always short values, which the line-items table (Client,
   then a long free-text Description) breaks — that combination blew the whole
   page out to the description's full unwrapped width. `.li-grid` opts back
   into normal wrapping for those two columns. */
table.grid td:nth-child(3),table.grid td:nth-child(4){white-space:nowrap}
table.li-grid{table-layout:fixed}
table.li-grid td:nth-child(3),table.li-grid td:nth-child(4){white-space:normal;overflow-wrap:break-word}
table.li-grid td{overflow-wrap:break-word}
/* Vendor page: Item # | Qty | Client | Description | Type | Billed | Cost | (action) */
table.li-grid:not(.li-grid-client) th:nth-child(1),
table.li-grid:not(.li-grid-client) th:nth-child(2){width:6%}
table.li-grid:not(.li-grid-client) th:nth-child(3){width:14%}
table.li-grid:not(.li-grid-client) th:nth-child(4){width:34%}
table.li-grid:not(.li-grid-client) th:nth-child(5){width:14%}
table.li-grid:not(.li-grid-client) th:nth-child(6){width:14%}
table.li-grid:not(.li-grid-client) th:nth-child(7){width:10%}
table.li-grid:not(.li-grid-client) th:nth-child(8){width:8%}
/* Client account page: Qty | Description | Type | Billed | Cost */
table.li-grid-client th:nth-child(1){width:8%}
table.li-grid-client th:nth-child(2){width:44%}
table.li-grid-client th:nth-child(3){width:18%}
table.li-grid-client th:nth-child(4){width:18%}
table.li-grid-client th:nth-child(5){width:12%}
table.grid .btn{white-space:nowrap}
table.grid td{padding:11px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
table.grid tr:last-child td{border-bottom:0}
table.grid .c{text-align:center}
table.grid .r{text-align:right}
table.grid .meta{font-size:12px;color:var(--faint)}
/* A table of accounts is the one place in this panel that can genuinely outgrow a
   phone, so it scrolls inside its own card rather than pushing the page sideways. */
.card:has(table.grid){overflow-x:auto}

.btn.small{font-size:12px;padding:6px 11px}
.card.ok{border-color:color-mix(in srgb, var(--brand) 45%, var(--line))}
.card.warn{border-color:#D6453D}
.code-out{font-size:21px;letter-spacing:.09em;font-weight:700;margin:10px 0 6px}

/* On a phone a six-column table is a 1050px sideways scroll inside a card, which
   is technically usable and actually horrible. Below 640px each row becomes its
   own block and every value carries its column name, so nothing scrolls and
   nothing loses its meaning. The dot and the button get their own full-width
   lines because those are the two things this page exists for. */
@media (max-width: 640px) {
  table.grid, table.grid tbody, table.grid tr, table.grid td { display: block; width: 100% }
  table.grid thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0) }
  table.grid tr { padding: 14px 2px; border-bottom: 1px solid var(--line) }
  table.grid tr:last-child { border-bottom: 0 }
  table.grid td { border: 0; padding: 3px 0; text-align: left }
  table.grid td[data-label]::before {
    content: attr(data-label);
    display: inline-block; min-width: 108px;
    font-family: var(--mono); font-size: 9.5px; letter-spacing: .13em;
    text-transform: uppercase; color: var(--faint); font-weight: 600;
  }
  /* Status reads as a heading for the row rather than a labelled field. */
  table.grid td[data-label="Status"] { padding-bottom: 6px }
  table.grid td[data-label="Status"]::before { content: none }
  table.grid td.act { padding-top: 10px }
  table.grid td.act .btn { width: 100%; text-align: center }
  table.grid td.c, table.grid td.r { text-align: left }
  .card:has(table.grid) { overflow-x: visible }
  .code-out { font-size: 17px; word-break: break-all }
}

/* ---------- responsive backstops ---------- */
/* A grid or flex child defaults to min-width:auto, which means it refuses to
   shrink below its widest unbreakable content — one long token in a feed item
   and the whole page scrolls sideways on a phone. These four rules are the
   general fix, so a future page inherits it rather than rediscovering it. */
.cols > *, .strip > *, .card { min-width: 0 }
.chead { flex-wrap: wrap; gap: 6px 12px }
.chead h2 { min-width: 0 }
/* Long unbroken strings — an agent id, a URL, an email — wrap rather than push. */
.feed li, .feed .ft, .feed .ft b, .feed p, .card p, .lede { overflow-wrap: anywhere }
/* A pill carries a client name, which can be longer than a phone is wide. It
   keeps its shape but is allowed to wrap and to break, rather than setting the
   page's minimum width. */
.pill { max-width: 100%; white-space: normal; overflow-wrap: anywhere }

@media (max-width: 640px) {
  /* Reclaim the side padding a phone cannot spare, and stop the nav pills from
     forcing a minimum width. */
  .wrap, .page { padding-left: 14px; padding-right: 14px }
  .nav { flex-wrap: wrap }
  h1 { overflow-wrap: anywhere }
  .mono { overflow-wrap: anywhere }
}

/* ---------- password reveal ---------- */
.pw { position: relative; display: block }
.pw input { width: 100%; padding-right: 44px }
.pw-eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; width: 32px; height: 32px;
  border: 0; border-radius: 7px; background: none; cursor: pointer;
  color: var(--faint); padding: 0;
}
.pw-eye:hover { color: var(--ink); background: var(--panel-2) }
.pw-eye:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px }
/* One icon, two states: the slash is hidden until the password is showing, so
   the button always says what pressing it will do next. */
.pw-eye .eye-shut { opacity: 0 }
.pw-eye.on { color: var(--brand) }
.pw-eye.on .eye-shut { opacity: 1 }

/* ---- Review: approve, deny, comment, section by section ------------------
   No JavaScript is available on this page (the CSP allows one hashed script
   and nothing else), so every control is a form. The layout has to make three
   forms per section read as one calm block rather than a wall of inputs. */

.rmeta{display:grid;gap:10px}
.rstat{display:flex;gap:14px;align-items:baseline;flex-wrap:wrap}
.rstat .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--faint);min-width:170px}
.rstat .v{font-size:14px;color:var(--ink)}

.rsec{scroll-margin-top:78px}                 /* the sticky bar must not cover the anchor */
.rsec .rbody{font-size:14.5px;line-height:1.6}
.rsec .rbody table{width:100%;border-collapse:collapse;font-size:12.5px;margin:10px 0;display:block;overflow-x:auto}
.rsec .rbody th{text-align:left;background:var(--panel-2);padding:6px 8px;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.rsec .rbody td{padding:6px 8px;border-top:1px solid var(--line);vertical-align:top}
.rsec .rbody ul,.rsec .rbody ol{padding-left:20px}
.rsec .rbody li{margin-bottom:4px}

/* Everyone's current position, side by side. On a shared review the italic is
   the organisation, because a first name alone does not say which side spoke. */
.rpos{display:flex;flex-wrap:wrap;gap:6px;margin:12px 0 0;padding-top:12px;border-top:1px solid var(--line)}
.pos{display:inline-block;font-size:11.5px;line-height:1.45;padding:4px 9px;border-radius:7px}
.pos b{font-weight:600}
.pos i{font-style:normal;opacity:.75}

.ract{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:12px}
.ract input[type=text]{flex:1 1 260px;min-width:0}
.btn.ok{background:var(--ok-bg);color:var(--ok);border-color:transparent}
.btn.no{background:var(--bad-bg);color:var(--bad);border-color:transparent}

.rcom{list-style:none;margin:14px 0 0;padding:12px 0 0;border-top:1px solid var(--line)}
.rcom-i{margin-bottom:14px;padding-left:12px;border-left:2px solid var(--line)}
.rcom-i p{margin:4px 0 0;font-size:13.5px}
.rcom-r{list-style:none;margin:8px 0 0;padding:8px 0 0 12px;border-left:2px solid var(--build)}
.rcom-r p{margin:3px 0 0;font-size:13px}
.rreply{display:flex;gap:6px;margin-top:7px}
.rreply input{flex:1 1 auto;min-width:0}
.rcomform{display:flex;gap:8px;align-items:flex-start;margin-top:12px}
.rcomform textarea{flex:1 1 auto;min-width:0}

@media (max-width:620px){
  .rstat{display:block}
  .rstat .k{display:block;margin-bottom:2px}
  .ract,.rcomform,.rreply{flex-direction:column;align-items:stretch}
}

/* ---- Questions and the running total ------------------------------------
   A question is not a passage to read, it is money and scope waiting on an
   answer. It gets a number, its cost impact stated before the argument, and a
   link onward to the next one still open. */

.rcost .rcost-g{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:12px 0}
.rc{background:var(--panel-2);border-radius:9px;padding:10px 12px}
.rc .k{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.13em;text-transform:uppercase;color:var(--faint)}
.rc .v{display:block;font-size:20px;font-weight:600;margin:3px 0 1px}
.rc .v.up{color:var(--need)}
.rc .n{display:block;font-size:11px;color:var(--faint);line-height:1.35}
.rc.big{outline:2px solid var(--accent)}
.rc.big .v{color:var(--accent)}

.rcost-l{list-style:none;margin:8px 0 0;padding:0}
.rcost-l li{display:flex;gap:9px;align-items:baseline;padding:5px 0;border-top:1px solid var(--line);font-size:13px}
.rcost-l li a{flex:1 1 auto;min-width:0}
.rcost-l li b{font-family:var(--mono);font-size:12px;white-space:nowrap}

.rsec.isq{border-left:2px solid var(--accent)}
.qn{font-family:var(--mono);font-size:12px;color:var(--accent);letter-spacing:.06em}
.qcost{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;background:var(--panel-2);
  border-radius:8px;padding:8px 11px;margin:0 0 12px;font-size:12.5px}
.qcost b{font-family:var(--mono);white-space:nowrap}
.qcost span{color:var(--dim)}
.qnext{margin:14px 0 0;padding-top:11px;border-top:1px solid var(--line);font-size:13px}
.btn.sm{font-size:11px;padding:4px 9px}
.rcom-i form.inline{display:inline-block;margin-top:6px}

/* A project review is 100 items. The phase header is what makes it a plan. */
.gh{display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  margin:26px 0 8px;padding:0 4px 6px;border-bottom:2px solid var(--accent)}
.gh h3{margin:0;font-size:15px}
.gh span{font-family:var(--mono);font-size:10px;letter-spacing:.11em;text-transform:uppercase;color:var(--faint)}
.rsec.ist{padding-top:14px;padding-bottom:14px}
.rsec.ist .rbody{font-size:13.5px}
.hintline{font-size:11.5px;color:var(--faint)}

/* ---- Phase gates, and who a phase is pending on -------------------------
   A count tells you a phase is stuck. A NAME tells you who can unstick it,
   which is the difference between a status board and one somebody acts on. */
.gates{list-style:none;margin:10px 0 0;padding:0}
.gates li{display:grid;grid-template-columns:86px 1fr 54px minmax(160px,1.2fr);gap:10px;
  align-items:baseline;padding:7px 0;border-top:1px solid var(--line);font-size:13px}
.gates .gs{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;
  padding:2px 6px;border-radius:4px;text-align:center}
.g-passed .gs{background:var(--ok-bg);color:var(--ok)}
.g-open   .gs{background:var(--build-bg);color:var(--build)}
.g-locked .gs{background:var(--panel-2);color:var(--faint)}
.g-held   .gs{background:var(--bad-bg);color:var(--bad)}
.gates .gc{font-family:var(--mono);font-size:12px;color:var(--faint);text-align:right}
.gates .gp{font-size:12px;color:var(--dim)}
.g-locked .gl,.g-locked .gp{opacity:.6}

.gw{font-size:12.5px;color:var(--dim);margin:-2px 4px 10px;padding:6px 10px;
  background:var(--panel-2);border-radius:7px}
.gw.locked{color:var(--faint)}
.gw b{color:var(--ink);font-weight:600}
.pend{font-size:12px;color:var(--faint);margin-top:10px;padding-top:9px;border-top:1px solid var(--line)}
@media (max-width:620px){ .gates li{grid-template-columns:1fr;gap:3px} .gates .gc{text-align:left} }

/* ---------- tools ---------- */
.tools { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; margin-top: 6px }
.tool { display: block; padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px;
        background: var(--panel-2); text-decoration: none; color: inherit }
.tool:hover { border-color: var(--brand); background: var(--panel) }
.tool b { display: block; font-size: 15px; margin-bottom: 3px }
.tool span { display: block; font-size: 12.5px; color: var(--faint); line-height: 1.5 }
/* A nested strip sits inside a card, so it loses the outer card's border. */
.strip.inner { margin-top: 4px; border: 0; border-radius: 0 }

/* ---------- crew spend ---------- */
.spend-hero { display: flex; align-items: baseline; gap: 10px; margin: 4px 0 14px }
.spend-now { font-family: var(--head); font-size: 46px; font-weight: 700; letter-spacing: -.03em; line-height: 1 }
.spend-of { font-size: 15px; color: var(--faint) }

.cap-bar { height: 10px; border-radius: 99px; background: var(--panel-2);
           border: 1px solid var(--line); overflow: hidden }
.cap-bar span { display: block; height: 100%; border-radius: 99px; background: var(--brand) }
.cap-bar.warn span { background: #E0A02A }
.cap-bar.bad  span { background: #D6453D }
.cap-legend { display: flex; justify-content: space-between; margin-top: 8px;
              font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
              text-transform: uppercase; color: var(--faint) }
.cap-legend b { color: var(--ink) }

/* The trend is drawn with CSS heights rather than a chart library — no script is
   allowed on these pages, and eight bars do not need one. */
.trend { display: grid; grid-template-columns: repeat(8, 1fr); gap: 6px; align-items: end; margin-top: 6px }
.tcol { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0 }
.tval { font-family: var(--mono); font-size: 10.5px; color: var(--faint); white-space: nowrap }
.tbar { width: 100%; height: 120px; display: flex; align-items: flex-end;
        background: var(--panel-2); border-radius: 5px; overflow: hidden }
.tbar span { width: 100%; background: var(--brand); border-radius: 5px 5px 0 0 }
.tbar span.over { background: #D6453D }
.tday { font-size: 11.5px; color: var(--dim); white-space: nowrap }
.truns { font-family: var(--mono); font-size: 9.5px; color: var(--faint); white-space: nowrap }

@media (max-width: 640px) {
  /* Eight bars will not fit a phone legibly, so the window halves rather than
     shrinking to slivers nobody can read. */
  .trend { grid-template-columns: repeat(4, 1fr) }
  .trend .tcol:nth-child(-n+4) { display: none }
  .spend-now { font-size: 36px }
  .tbar { height: 92px }
}

/* ---------- CSP-safe sizing ----------
   `style-src 'self'` blocks style attributes outright, so a computed width or
   height cannot be written inline. These classes carry the value instead; the
   view rounds to a whole percent and names the class. */
.w-0{width:0%}
.w-1{width:1%}
.w-2{width:2%}
.w-3{width:3%}
.w-4{width:4%}
.w-5{width:5%}
.w-6{width:6%}
.w-7{width:7%}
.w-8{width:8%}
.w-9{width:9%}
.w-10{width:10%}
.w-11{width:11%}
.w-12{width:12%}
.w-13{width:13%}
.w-14{width:14%}
.w-15{width:15%}
.w-16{width:16%}
.w-17{width:17%}
.w-18{width:18%}
.w-19{width:19%}
.w-20{width:20%}
.w-21{width:21%}
.w-22{width:22%}
.w-23{width:23%}
.w-24{width:24%}
.w-25{width:25%}
.w-26{width:26%}
.w-27{width:27%}
.w-28{width:28%}
.w-29{width:29%}
.w-30{width:30%}
.w-31{width:31%}
.w-32{width:32%}
.w-33{width:33%}
.w-34{width:34%}
.w-35{width:35%}
.w-36{width:36%}
.w-37{width:37%}
.w-38{width:38%}
.w-39{width:39%}
.w-40{width:40%}
.w-41{width:41%}
.w-42{width:42%}
.w-43{width:43%}
.w-44{width:44%}
.w-45{width:45%}
.w-46{width:46%}
.w-47{width:47%}
.w-48{width:48%}
.w-49{width:49%}
.w-50{width:50%}
.w-51{width:51%}
.w-52{width:52%}
.w-53{width:53%}
.w-54{width:54%}
.w-55{width:55%}
.w-56{width:56%}
.w-57{width:57%}
.w-58{width:58%}
.w-59{width:59%}
.w-60{width:60%}
.w-61{width:61%}
.w-62{width:62%}
.w-63{width:63%}
.w-64{width:64%}
.w-65{width:65%}
.w-66{width:66%}
.w-67{width:67%}
.w-68{width:68%}
.w-69{width:69%}
.w-70{width:70%}
.w-71{width:71%}
.w-72{width:72%}
.w-73{width:73%}
.w-74{width:74%}
.w-75{width:75%}
.w-76{width:76%}
.w-77{width:77%}
.w-78{width:78%}
.w-79{width:79%}
.w-80{width:80%}
.w-81{width:81%}
.w-82{width:82%}
.w-83{width:83%}
.w-84{width:84%}
.w-85{width:85%}
.w-86{width:86%}
.w-87{width:87%}
.w-88{width:88%}
.w-89{width:89%}
.w-90{width:90%}
.w-91{width:91%}
.w-92{width:92%}
.w-93{width:93%}
.w-94{width:94%}
.w-95{width:95%}
.w-96{width:96%}
.w-97{width:97%}
.w-98{width:98%}
.w-99{width:99%}
.w-100{width:100%}
.h-0{height:0%}
.h-1{height:1%}
.h-2{height:2%}
.h-3{height:3%}
.h-4{height:4%}
.h-5{height:5%}
.h-6{height:6%}
.h-7{height:7%}
.h-8{height:8%}
.h-9{height:9%}
.h-10{height:10%}
.h-11{height:11%}
.h-12{height:12%}
.h-13{height:13%}
.h-14{height:14%}
.h-15{height:15%}
.h-16{height:16%}
.h-17{height:17%}
.h-18{height:18%}
.h-19{height:19%}
.h-20{height:20%}
.h-21{height:21%}
.h-22{height:22%}
.h-23{height:23%}
.h-24{height:24%}
.h-25{height:25%}
.h-26{height:26%}
.h-27{height:27%}
.h-28{height:28%}
.h-29{height:29%}
.h-30{height:30%}
.h-31{height:31%}
.h-32{height:32%}
.h-33{height:33%}
.h-34{height:34%}
.h-35{height:35%}
.h-36{height:36%}
.h-37{height:37%}
.h-38{height:38%}
.h-39{height:39%}
.h-40{height:40%}
.h-41{height:41%}
.h-42{height:42%}
.h-43{height:43%}
.h-44{height:44%}
.h-45{height:45%}
.h-46{height:46%}
.h-47{height:47%}
.h-48{height:48%}
.h-49{height:49%}
.h-50{height:50%}
.h-51{height:51%}
.h-52{height:52%}
.h-53{height:53%}
.h-54{height:54%}
.h-55{height:55%}
.h-56{height:56%}
.h-57{height:57%}
.h-58{height:58%}
.h-59{height:59%}
.h-60{height:60%}
.h-61{height:61%}
.h-62{height:62%}
.h-63{height:63%}
.h-64{height:64%}
.h-65{height:65%}
.h-66{height:66%}
.h-67{height:67%}
.h-68{height:68%}
.h-69{height:69%}
.h-70{height:70%}
.h-71{height:71%}
.h-72{height:72%}
.h-73{height:73%}
.h-74{height:74%}
.h-75{height:75%}
.h-76{height:76%}
.h-77{height:77%}
.h-78{height:78%}
.h-79{height:79%}
.h-80{height:80%}
.h-81{height:81%}
.h-82{height:82%}
.h-83{height:83%}
.h-84{height:84%}
.h-85{height:85%}
.h-86{height:86%}
.h-87{height:87%}
.h-88{height:88%}
.h-89{height:89%}
.h-90{height:90%}
.h-91{height:91%}
.h-92{height:92%}
.h-93{height:93%}
.h-94{height:94%}
.h-95{height:95%}
.h-96{height:96%}
.h-97{height:97%}
.h-98{height:98%}
.h-99{height:99%}
.h-100{height:100%}

/* Small utilities replacing style="" attributes, which the CSP blocks. Named for
   what they do, not what they set, so a future page reaches for the right one. */
.faint { color: var(--faint) }
.dim-sm { color: var(--dim); font-size: 13.5px }
.note-top { margin: 14px 0 0 }
.note-tight { margin: 12px 0 0 }
.gap-below { margin-bottom: 18px }
.nudge { margin-top: 5px }
.state-val { font-size: 19px }
.warn-inline { background: var(--need-bg); color: var(--need); margin-bottom: 18px }
.meta-pad { color: var(--need); padding-top: 10px }
.faint-inline { color: var(--faint); margin-left: 8px }
.dim-below { color: var(--dim); font-size: 13.5px; margin: 6px 0 0 }
/* Second line inside a notice: says what happened next, quieter than the notice
   itself. A real class because the CSP forbids a style attribute. */
.note-sub { font-size: 12.5px; opacity: .82; margin: 7px 0 0; line-height: 1.5 }
.dim-above { color: var(--dim); font-size: 13.5px; margin: 0 0 6px }
.tight-top { margin: 0 0 4px }
.codebox { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
           padding: 11px 13px; word-break: break-all }
.bad-text { color: var(--bad) }
.build-pad { color: var(--build); padding-top: 10px }

/* ---------- all-networks war room ----------
   Option 1, the dense grid: one table, no card per network, the eye scanning
   columns rather than hunting boxes. House typefaces throughout — this page
   wears Schuck's identity, so the direction sets the LAYOUT, not the brand. */
.wr-kpis { display: flex; flex-wrap: wrap; gap: 30px; margin: 0 0 18px }
.wr-kpi span { display: block; font-family: var(--mono); font-size: 9.5px;
               letter-spacing: .16em; color: var(--faint); margin-bottom: 2px }
.wr-kpi b { font-family: var(--head); font-size: 30px; font-weight: 800;
            letter-spacing: -.02em; line-height: 1; color: var(--brand) }
.wr-kpi.attn b { color: #E0A02A }

.wr-card { padding-left: 0; padding-right: 0 }
table.grid.wr { font-size: 12.5px }
table.grid.wr th, table.grid.wr td { padding: 8px 10px }
table.grid.wr td.c, table.grid.wr th.c { text-align: center }
.wr-name { font-weight: 700; font-size: 14px; text-decoration: none }
.wr-name:hover { text-decoration: underline }
/* Status words, not dots: at this density a word is faster to read than a
   legend you have to remember. */
.wr-ok    { color: #1FA971; font-family: var(--mono); font-size: 11px }
.wr-un    { color: var(--faint); font-family: var(--mono); font-size: 11px }
.wr-na    { color: var(--faint); font-family: var(--mono); font-size: 11px }
.wr-flag  { color: #E0A02A; font-family: var(--mono); font-size: 11px }
.wr-clean { color: #1FA971; font-family: var(--mono); font-size: 11px }
/* A row needing attention is marked on its edge, so colour is never the only
   signal and the flag column still reads if you are colour-blind. */
tr.wr-attn td:first-child { box-shadow: inset 3px 0 0 #E0A02A }
tr.wr-none td:first-child { box-shadow: inset 3px 0 0 var(--line) }

.wr-assign { display: grid; gap: 8px }
.wr-arow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap }
.wr-arow b { min-width: 130px; font-size: 13.5px }
.wr-arow select { flex: 1; min-width: 180px }

@media (max-width: 640px) {
  .wr-kpis { gap: 18px }
  .wr-kpi b { font-size: 24px }
  .wr-arow b { min-width: 0; width: 100% }
}

/* Selects were inheriting the OS control skin, which reads as a light-mode
   widget dropped into a dark page. Styled explicitly, with the native arrow
   replaced so it is legible on the dark surface. */
select {
  appearance: none; -webkit-appearance: none;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 9px 34px 9px 12px; font: inherit; font-size: 13.5px;
  background-image: linear-gradient(45deg, transparent 50%, var(--faint) 50%),
                    linear-gradient(135deg, var(--faint) 50%, transparent 50%);
  background-position: right 16px center, right 11px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
select:hover { border-color: var(--brand) }
select:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px }
option { background: var(--panel); color: var(--ink) }

/* ---- "what does this mean" -------------------------------------------------
   A client rang up unable to answer a document because she could not tell what
   it was asking. Every section can now carry a plain-English note, reached by
   pointing at the mark beside the heading.

   Hover is for a mouse and :focus-within is for everything else: the span is
   focusable, so a tap on a phone and a Tab from the keyboard both open it. The
   text lives in the markup rather than a title attribute so it wraps, styles,
   and is read out properly. */
.why { position: relative; display: inline-flex; vertical-align: middle;
       margin-left: 7px; cursor: help }
.why .q { width: 17px; height: 17px; border-radius: 50%; display: grid;
          place-items: center; font-size: 11px; font-weight: 700; line-height: 1;
          background: color-mix(in srgb, var(--brand) 20%, var(--panel));
          color: var(--brand-deep); border: 1px solid var(--brand);
          font-family: var(--sans) }
.why:hover .q, .why:focus .q, .why:focus-within .q { background: var(--brand); color: #06222E }
.why:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 50% }
.why .tip {
  position: absolute; left: 50%; top: calc(100% + 9px); transform: translateX(-50%);
  width: max-content; max-width: min(340px, 78vw); z-index: 40;
  background: var(--panel); color: var(--ink); border: 1px solid var(--brand);
  border-radius: 11px; padding: 11px 13px; font-size: 13.5px; font-weight: 400;
  line-height: 1.5; letter-spacing: normal; text-transform: none;
  box-shadow: 0 10px 30px rgba(0,0,0,.22);
  opacity: 0; visibility: hidden; transition: opacity .12s;
}
.why .tip b { display: block; font-size: 10.5px; letter-spacing: .14em;
              text-transform: uppercase; color: var(--faint); margin-bottom: 5px }
.why .tip::before {                      /* the pointer up to the mark */
  content: ''; position: absolute; left: 50%; top: -5px; width: 8px; height: 8px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--panel); border-left: 1px solid var(--brand); border-top: 1px solid var(--brand);
}
.why:hover .tip, .why:focus .tip, .why:focus-within .tip { opacity: 1; visibility: visible }

/* Near the right edge the bubble would run off the page, so the last one on a
   row anchors to its right instead of centring. */
.chead .why:last-child .tip { left: auto; right: -8px; transform: none }
.chead .why:last-child .tip::before { left: auto; right: 14px; transform: rotate(45deg) }

.card.howto { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 7%, var(--panel)) }
.card.howto p { margin: 0 }

@media (max-width: 640px) {
  .why .tip { position: fixed; left: 12px; right: 12px; top: auto; bottom: 14px;
              transform: none; max-width: none; width: auto }
  .why .tip::before { display: none }
}

/* ---- review head: title left, the running total right ---------------------
   The figure people ask about first should not be four scrolls down. It is the
   client's own contributed/invoiced total, the same number the account page
   shows, so the two can never disagree. */
.head.rhead { display: flex; align-items: flex-start; justify-content: space-between;
              gap: 22px; flex-wrap: wrap }
.head.rhead > div:first-child { flex: 1 1 320px; min-width: 0 }
.runtot { flex: 0 0 auto; text-align: right; border: 1px solid var(--line);
          border-radius: 12px; padding: 12px 16px; background: var(--panel) }
.runtot .k { display: block; font-family: var(--mono); font-size: 9.5px;
             letter-spacing: .14em; text-transform: uppercase; color: var(--faint) }
.runtot .v { display: block; font-size: 26px; font-weight: 600; letter-spacing: -.02em;
             line-height: 1.1; margin-top: 3px }
.runtot .w { display: block; font-family: var(--mono); font-size: 10px;
             color: var(--faint); letter-spacing: .04em; margin-top: 3px }
@media (max-width: 620px) {
  .runtot { text-align: left; width: 100% }
}

/* The file itself is the link. A button pair said "pick one of two things";
   there was only ever one thing, and it has a name. */
.filelink { margin: 4px 0 0 }
.filelink a { font-family: var(--mono); font-size: 13.5px; color: var(--brand-deep);
              text-decoration: underline; text-underline-offset: 3px; word-break: break-all }
.filelink a:hover { color: var(--ink) }

/* ---- one box, three small buttons, one paperclip --------------------------
   Was two stacked inputs and two full-width buttons, which asked the reader to
   work out which box a thought belonged in. There is one box now; what you type
   goes on whichever of the three answers you choose. */
.rbox { margin-top: 14px }
textarea[data-grow] {
  width: 100%; min-height: 44px; resize: none; overflow: hidden;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 11px;
  padding: 12px 13px; font: inherit; font-size: 14px; line-height: 1.5;
}
textarea[data-grow]:focus { outline: none; border-color: var(--brand) }
textarea[data-grow]::placeholder { color: var(--faint) }

.rbar { display: flex; align-items: center; gap: 8px; margin-top: 9px; flex-wrap: wrap }
.rbar .spacer { flex: 1 }

/* Small on purpose. A decision button the size of a banner reads as pressure. */
.sbtn {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--dim);
  border-radius: 8px; padding: 6px 13px; font: inherit; font-size: 12.5px;
  font-weight: 600; cursor: pointer; line-height: 1.4;
}
.sbtn:hover { color: var(--ink); border-color: var(--brand) }
.sbtn.ok:hover { color: var(--ok); border-color: var(--ok); background: var(--ok-bg) }
.sbtn.no:hover { color: var(--bad); border-color: var(--bad); background: var(--bad-bg) }
.sbtn.ch:hover { color: var(--need); border-color: var(--need); background: var(--need-bg) }
.sbtn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px }

.clip {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 1px dashed var(--line); border-radius: 8px; padding: 5px 11px;
  color: var(--faint); font-size: 12.5px; max-width: 260px;
}
.clip:hover { color: var(--ink); border-color: var(--brand) }
.clip.has { color: var(--brand-deep); border-style: solid; border-color: var(--brand) }
.clip input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none }
.clip:focus-within { outline: 2px solid var(--brand); outline-offset: 2px }
.clip .fname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }

/* What people attached, shown in place rather than as a list of downloads. */
.rfiles { list-style: none; margin: 14px 0 0; padding: 0;
          display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 11px }
.rfile { background: var(--panel-2); border: 1px solid var(--line); border-radius: 11px;
         padding: 10px; overflow: hidden }
.rfile img, .rfile video { display: block; width: 100%; height: auto; max-height: 260px;
                           object-fit: contain; border-radius: 7px; background: var(--bg) }
.rfile p { margin: 8px 0 0; font-size: 12.5px; display: flex; flex-direction: column; gap: 2px }
.rfile p a { color: var(--brand-deep); word-break: break-all }

/* ---- signing off the whole document ---------------------------------------
   The one action that takes something away from other people, so it reads as a
   deliberate step rather than another button in the row. */
.card.signoff { border-color: var(--brand) }
.card.warn-note { border-color: var(--need) }
.plainlist { margin: 10px 0 0; padding-left: 20px }
.plainlist li { margin-bottom: 9px; font-size: 14px; line-height: 1.55 }
.bad-hint { margin-top: 14px; padding: 11px 13px; border-radius: 9px;
            background: var(--need-bg); color: var(--need) }
.lbl { display: block; font-size: 13px; color: var(--dim); margin-bottom: 7px }
a.sbtn { text-decoration: none; display: inline-flex; align-items: center }
a.sbtn.ok { color: var(--ok); border-color: var(--ok) }
a.sbtn.ok:hover { background: var(--ok-bg) }

/* The version list. One row per round, oldest at the bottom. */
.vlist { list-style: none; margin: 0; padding: 0 }
.vlist li { display: grid; gap: 4px 14px; align-items: baseline;
            grid-template-columns: 54px 108px 1fr auto auto;
            padding: 11px 0; border-bottom: 1px solid var(--line); font-size: 13.5px }
.vlist li:last-child { border-bottom: 0 }
.vlist li.now { color: var(--ink) }
.vlist .vv { font-family: var(--mono); font-size: 12px; color: var(--cyan-ink); font-weight: 600 }
.vlist .vs { font-size: 12.5px; color: var(--dim) }
.vlist li.now .vs { color: var(--cyan-ink); font-weight: 600 }
.vlist .vw, .vlist .vc { color: var(--faint); font-size: 12.5px }
.vlist .vl { display: flex; gap: 12px }
.vlist .vl a { color: var(--brand-deep); font-size: 12.5px }
@media (max-width: 640px) {
  .vlist li { grid-template-columns: 54px 1fr }
  .vlist .vw, .vlist .vc { grid-column: 2 }
  .vlist .vl { grid-column: 1 / -1 }
}
.qnote { margin: 8px 0 0; font-size: 13.5px; color: var(--dim) }

/* ---- waiting on the client ------------------------------------------------
   One row per person who is holding something up, hardest blocker first. */
.nudges { list-style: none; margin: 0; padding: 0 }
.nudges li { display: grid; align-items: center; gap: 4px 14px;
             grid-template-columns: 132px 1fr 150px auto;
             padding: 13px 0; border-bottom: 1px solid var(--line) }
.nudges li:last-of-type { border-bottom: 0 }
.nudges .nwho { display: flex; flex-direction: column; gap: 1px; min-width: 0 }
.nudges .nwho b { font-size: 14px }
.nudges .nwho span { font-size: 11.5px; overflow: hidden; text-overflow: ellipsis }
.nudges .nacct { font-size: 13px; color: var(--dim) }
.nudges .ndet { grid-column: 2 / 4; font-size: 13px; color: var(--dim); margin-top: -2px }
.nudges .nlast { grid-column: 2 / 4; font-size: 11px }
.nudges form.inline { grid-row: 1 / span 3; grid-column: 4; align-self: center }
@media (max-width: 720px) {
  .nudges li { grid-template-columns: 1fr }
  .nudges .ndet, .nudges .nlast, .nudges form.inline { grid-column: 1; grid-row: auto }
}

/* ==========================================================================
   Network Console (/networks) — directions 5 + 3 + 4, chosen by Charles.
   Everything is scoped under .netconsole so its generic class names cannot
   touch the rest of the panel. Ported from the approved artifact; inline styles
   became classes because the panel's CSP is style-src 'self'.
   ========================================================================== */
:root{
  --panel-3:#E7EDF1; --info-bg:#DFF1FA; --line-soft:#E8EDF1;
  --land:#E9EEF2; --land-line:#C6D2DB; --water:#F4F6F8;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --panel-3:#1A2A36; --info-bg:#0B2432; --line-soft:#1B2833;
  --land:#16242F; --land-line:#2C4051; --water:#14161E;
}}
:root[data-theme="dark"]{
  --panel-3:#1A2A36; --info-bg:#0B2432; --line-soft:#1B2833;
  --land:#16242F; --land-line:#2C4051; --water:#14161E;
}

.netconsole .console{background:var(--panel);border:1px solid var(--line);border-radius:6px;overflow:hidden;box-shadow:var(--shadow)}
.netconsole .chrome{background:var(--panel-2);border-bottom:1px solid var(--line);padding:0 14px;display:flex;align-items:stretch;gap:2px;flex-wrap:wrap}
.netconsole .chrome .path{font-family:var(--mono);font-size:11px;color:var(--faint);align-self:center;padding-right:12px;margin-right:6px;border-right:1px solid var(--line)}
.netconsole .tab{font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;background:none;border:0;border-bottom:2px solid transparent;color:var(--faint);padding:11px 13px;cursor:pointer}
.netconsole .tab:hover{color:var(--ink)}
.netconsole .tab[aria-selected="true"]{color:var(--brand-deep);border-bottom-color:var(--brand)}
.netconsole .tab:focus-visible{outline:2px solid var(--brand);outline-offset:-3px}
.netconsole .chrome .who{margin-left:auto;align-self:center;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--brand-deep)}
.netconsole .view[hidden]{display:none}
.netconsole .body{display:grid;grid-template-columns:1fr 316px}
.netconsole .mapcol{border-right:1px solid var(--line);background:#070C11;position:relative;min-width:0}

/* --------------------------------------------------------------------------
   The satellite map. Imagery comes through this server's own tile route, so
   everything here is same-origin and the page's CSP never had to be widened.

   Structure: .tiles and .marks are two absolutely-positioned layers carrying
   the SAME transform, so beacons stay welded to the ground while panning. Tile
   and beacon offsets are measured from a per-zoom origin rather than from the
   world corner — at zoom 19 the world is 134 million pixels wide and browsers
   lose sub-pixel precision long before that.
   -------------------------------------------------------------------------- */
.earth{position:relative;height:560px;overflow:hidden;background:#03060A;
       cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none}
.earth.grab{cursor:grabbing}
/* Mid-flight the map is the camera's, not the mouse's: the pointer must not
   land on a beacon that is still moving under it. */
.earth.flying{cursor:default}
.earth.flying .beacon{pointer-events:none}
.earth .tiles{position:absolute;left:0;top:0;width:0;height:0;transform-origin:0 0;will-change:transform}
.earth .marks{position:absolute;left:0;top:0;width:0;height:0;z-index:3}
.earth img.t{position:absolute;width:256px;height:256px;opacity:0;transition:opacity .28s ease;
             pointer-events:none;-webkit-user-drag:none}
.earth img.t.on{opacity:1}
/* Coming down from orbit the grid is deliberately a level or two coarse and gets
   stretched. Smoothing it reads as altitude rather than as a broken image. */
.earth.flying img.t{transition:none;image-rendering:auto}

/* The beacon: a radio glyph inside a ring, with strobes going out from it.
   Colour is set once on the anchor and everything else inherits it through
   currentColor, so state lives in ONE place. */
.earth .beacon{position:absolute;width:0;height:0;display:block;text-decoration:none;z-index:4;color:#3BFF95}
.earth .beacon.s-ok{color:#2BFF88}
.earth .beacon.s-need{color:#FFB01F}
.earth .beacon.s-bad{color:#FF3B30}
.earth .beacon .core{position:absolute;left:0;top:0;transform:translate(-50%,-50%);
  width:30px;height:30px;border-radius:50%;background:rgba(4,10,14,.74);
  border:1.6px solid currentColor;display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 16px currentColor,0 0 4px rgba(0,0,0,.9)}
.earth .beacon.approx .core{border-style:dashed}
.earth .beacon svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;
                   stroke-linecap:round;display:block}
.earth .beacon svg .hub{fill:currentColor;stroke:none}
.earth .beacon .ping{position:absolute;left:0;top:0;width:30px;height:30px;margin:-15px 0 0 -15px;
  border-radius:50%;border:2px solid currentColor;opacity:0;pointer-events:none}
.earth .beacon .tag{position:absolute;left:22px;top:-22px;white-space:nowrap;
  background:rgba(5,11,16,.86);border:1px solid rgba(255,255,255,.16);border-left:2px solid currentColor;
  border-radius:4px;padding:5px 10px;display:flex;flex-direction:column;gap:1px;max-width:280px}
.earth .beacon .tag b{color:#FFF;font-size:12.5px;font-weight:600;line-height:1.25}
.earth .beacon .tag em{color:#D7E2EC;font-style:normal;font-size:11.5px;line-height:1.25;
  overflow:hidden;text-overflow:ellipsis}
.earth .beacon .tag .addr{color:#93A5B4;font-size:10.5px;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis}
.earth .beacon.approx .tag .addr{color:#FFB01F}
.earth .beacon .tag i{color:currentColor;font-style:normal;font-family:var(--mono);
  font-size:9px;letter-spacing:.09em;text-transform:uppercase;margin-top:1px}
.earth .beacon:hover .tag,.earth .beacon:focus-visible .tag,.earth .beacon.sel .tag{
  background:rgba(5,11,16,.96);border-color:currentColor}
.earth .beacon:hover,.earth .beacon:focus-visible{z-index:9}
/* The sides a crowded label can move to, picked in JS once the map is still. */
.earth .beacon .tag.left{left:auto;right:22px;border-left:1px solid rgba(255,255,255,.16);
  border-right:2px solid currentColor;align-items:flex-end;text-align:right}
.earth .beacon .tag.below{top:18px}
.earth .beacon .tag.above{top:auto;bottom:18px}
/* Labels are for when you have arrived. On the way down, and from any height
   where the sites sit on top of each other, they are a pile of overlapping
   boxes — so they fade out and come back as the ground does. */
.earth .beacon .tag{transition:opacity .4s ease}
.earth.flying .beacon .tag,.earth.lowzoom .beacon .tag{opacity:0}
.earth.lowzoom:not(.flying) .beacon:hover .tag,
.earth.lowzoom:not(.flying) .beacon:focus-visible .tag{opacity:1}
.earth .beacon.sel .core{box-shadow:0 0 24px currentColor,0 0 0 2px rgba(255,255,255,.55)}
.earth .beacon:focus-visible{outline:none}
.earth .beacon:focus-visible .core{outline:2px solid #FFF;outline-offset:3px}
@media (prefers-reduced-motion:no-preference){
  .earth .beacon .ping{animation:strobe 2.4s cubic-bezier(.2,.75,.35,1) infinite}
  .earth .beacon .ping.p2{animation-delay:1.2s}
  /* A network that is down strobes faster and wider. Urgency you can read from
     across the room is the point of putting it on a map at all. */
  .earth .beacon.s-bad .ping{animation-duration:1.3s}
  .earth .beacon.s-bad .ping.p2{animation-delay:.65s}
  @keyframes strobe{0%{transform:scale(.5);opacity:.95}70%{transform:scale(3.6);opacity:0}100%{opacity:0}}
}
.earth .ectl{position:absolute;right:12px;top:12px;z-index:6;display:flex;flex-direction:column;gap:5px;align-items:flex-end}
.earth .ectl button{width:32px;height:32px;border-radius:4px;border:1px solid rgba(255,255,255,.24);
  background:rgba(5,11,16,.82);color:#DCE6EE;font-size:16px;line-height:1;cursor:pointer;font-family:inherit}
.earth .ectl button.wide{width:auto;height:28px;padding:0 11px;font-family:var(--mono);
  font-size:10px;letter-spacing:.12em;text-transform:uppercase}
.earth .ectl button:hover{border-color:var(--brand);color:var(--brand)}
.earth .ectl button:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.earth .ereadout{position:absolute;left:12px;top:12px;z-index:6;font-family:var(--mono);font-size:10px;
  color:#C4D2DE;background:rgba(5,11,16,.7);padding:3px 7px;border-radius:3px;letter-spacing:.05em}
.earth .ecred{position:absolute;right:9px;bottom:7px;z-index:6;font-size:9.5px;color:rgba(255,255,255,.66);
  background:rgba(5,11,16,.55);padding:2px 6px;border-radius:3px}
.earth .enone{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  text-align:center;color:#93A5B4;font-size:13px;z-index:5;padding:24px}
.earth.solo{height:420px;border:1px solid var(--line);border-radius:6px}
.solomap{margin:0 0 18px}
.solomap .approxnote{margin-top:7px}

.netconsole .maplegend{position:absolute;left:12px;bottom:12px;z-index:6;background:rgba(5,11,16,.82);
  border:1px solid rgba(255,255,255,.16);border-radius:4px;padding:9px 11px;display:flex;flex-direction:column;gap:5px}
.netconsole .maplegend .li{display:flex;align-items:center;gap:7px;font-size:11.5px;color:#C4D2DE;white-space:nowrap}
.netconsole .maplegend .sw{width:9px;height:9px;border-radius:50%;flex:0 0 auto}
.netconsole .maplegend .sw.f-bad{background:#FF3B30;box-shadow:0 0 7px #FF3B30}
.netconsole .maplegend .sw.f-need{background:#FFB01F;box-shadow:0 0 7px #FFB01F}
.netconsole .maplegend .sw.f-ok{background:#2BFF88;box-shadow:0 0 7px #2BFF88}
.netconsole .maplegend .sw.ring{background:transparent;border:1.5px dashed rgba(255,255,255,.6)}
.netconsole .maplegend .sw.none{background:transparent}
.netconsole .maplegend .hd{font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.55)}

/* One network's headline facts, above its tables. */
.glance{display:grid;grid-template-columns:repeat(auto-fit,minmax(146px,1fr));gap:10px;margin:0 0 18px}
.glance .g{border:1px solid var(--line);border-radius:6px;background:var(--panel);padding:10px 12px;min-width:0}
.glance .k{font-family:var(--mono);font-size:9px;letter-spacing:.13em;text-transform:uppercase;color:var(--faint)}
.glance .v{font-family:var(--mono);font-size:16.5px;margin-top:3px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.glance .n{font-size:11.5px;color:var(--faint);margin-top:2px;line-height:1.35}
.netconsole .rail{display:flex;flex-direction:column;min-width:0}
.netconsole .railhead{padding:12px 14px;border-bottom:1px solid var(--line);display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.netconsole .railhead .t{font-weight:600;font-size:14.5px;line-height:1.2}
.netconsole .railhead .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--faint)}
.netconsole .seg{display:flex;border-bottom:1px solid var(--line)}
.netconsole .seg button{flex:1;background:none;border:0;border-bottom:2px solid transparent;color:var(--faint);font-family:var(--mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;padding:9px 6px;cursor:pointer}
.netconsole .seg button:hover{color:var(--ink)}
.netconsole .seg button[aria-selected="true"]{color:var(--brand-deep);border-bottom-color:var(--brand)}
.netconsole .seg button:focus-visible{outline:2px solid var(--brand);outline-offset:-3px}
.netconsole .pane{padding:14px;display:flex;flex-direction:column;gap:13px;flex:1}
.netconsole .pane[hidden]{display:none}
.netconsole .dgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.netconsole .stat{border:1px solid var(--line);border-radius:4px;padding:8px 10px;background:var(--panel-2)}
.netconsole .stat .l{font-family:var(--mono);font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.netconsole .stat .v{font-family:var(--mono);font-size:17px;font-variant-numeric:tabular-nums;margin-top:2px}
.netconsole .stat .v.bad{color:var(--bad)} .netconsole .stat .v.need{color:var(--need)} .netconsole .stat .v.ok{color:var(--ok)}
.netconsole .cap{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:5px}
.netconsole .spark{display:flex;align-items:flex-end;gap:2px;height:34px;padding-bottom:2px;border-bottom:1px solid var(--line)}
.netconsole .spark u{flex:1;background:var(--brand);opacity:.55;min-height:3px;border-radius:1px;display:block}
.netconsole .spark u.hi{opacity:1}
.netconsole .spark u.warn{background:var(--bad);opacity:1}
.netconsole .evt{display:flex;flex-direction:column;gap:6px}
.netconsole .evt .row{display:flex;gap:8px;align-items:baseline;font-size:12.5px;color:var(--dim)}
.netconsole .evt .row time{font-family:var(--mono);font-size:10.5px;color:var(--faint);flex:0 0 44px}
.netconsole .acts{display:flex;gap:7px;flex-wrap:wrap;margin-top:auto;padding-top:6px}
.netconsole .btn{font-size:11.5px;padding:6px 11px;border:1px solid var(--line);border-radius:3px;background:var(--panel-2);color:var(--dim);font-family:inherit;cursor:pointer}
.netconsole .btn:hover{color:var(--ink);border-color:var(--brand)}
.netconsole .btn:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.netconsole .btn.pri{background:var(--brand);border-color:var(--brand);color:#08222E;font-weight:600}
.netconsole .btn.pri:hover{color:#08222E}
.netconsole .btn[disabled]{opacity:.45;cursor:not-allowed}
.netconsole .pill{display:inline-flex;font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;padding:2px 7px;border-radius:3px;white-space:nowrap}
.netconsole .pill.ok{background:var(--ok-bg);color:var(--ok)}
.netconsole .pill.need{background:var(--need-bg);color:var(--need)}
.netconsole .pill.bad{background:var(--bad-bg);color:var(--bad)}
.netconsole .dlist{display:flex;flex-direction:column;gap:7px}
.netconsole .drow{border:1px solid var(--line);border-radius:4px;padding:8px 10px;background:var(--panel-2);display:flex;flex-direction:column;gap:5px}
.netconsole .drow .top{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.netconsole .drow .nm{font-size:12.5px;font-weight:600;line-height:1.25}
.netconsole .drow .mt{font-family:var(--mono);font-size:10px;color:var(--faint);letter-spacing:.03em}
.netconsole .drow .rowacts{display:flex;gap:5px;flex-wrap:wrap}
.netconsole .drow .rowacts .btn{padding:3px 8px;font-size:10.5px}
.netconsole .more{font-family:var(--mono);font-size:10.5px;color:var(--faint);letter-spacing:.06em;text-align:center;padding:4px}
.netconsole .bar{display:flex;gap:7px;flex-wrap:wrap;align-items:center;padding:12px 14px;border-bottom:1px solid var(--line)}
.netconsole .search{flex:1 1 220px;border:1px solid var(--line);border-radius:3px;background:var(--panel-2);padding:7px 10px;font-family:var(--mono);font-size:11.5px;color:var(--ink);min-width:0}
.netconsole .search::placeholder{color:var(--faint)}
.netconsole .search:focus-visible{outline:2px solid var(--brand);outline-offset:-1px}
.netconsole .chip{font-size:11.5px;padding:5px 11px;border:1px solid var(--line);border-radius:999px;color:var(--dim);background:var(--panel-2);white-space:nowrap;font-family:inherit;cursor:pointer}
.netconsole .chip:hover{color:var(--ink)}
.netconsole .chip[aria-pressed="true"]{border-color:var(--brand);color:var(--brand-deep);font-weight:600;background:var(--info-bg)}
.netconsole .chip:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.netconsole .tablewrap{overflow-x:auto}
.netconsole table{border-collapse:collapse;width:100%;font-size:12.5px;min-width:660px}
.netconsole th{text-align:left;font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--faint);font-weight:400;padding:9px 12px;border-bottom:1px solid var(--line);white-space:nowrap}
.netconsole td{padding:9px 12px;border-bottom:1px solid var(--line-soft);vertical-align:middle;white-space:nowrap}
.netconsole tbody tr:hover{background:var(--panel-2)}
.netconsole tbody tr.on{background:var(--info-bg)}
.netconsole .num{font-variant-numeric:tabular-nums;font-family:var(--mono);font-size:11.5px}
.netconsole td .nm{font-weight:600}
.netconsole .sub{color:var(--faint);font-size:10.5px;font-family:var(--mono);letter-spacing:.03em}
.netconsole .own{color:var(--brand-deep);font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase}
.netconsole input[type=checkbox]{accent-color:var(--brand);width:14px;height:14px;cursor:pointer}
.netconsole .bulk{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:11px 14px;border-top:1px solid var(--line);background:var(--info-bg)}
.netconsole .scope{display:inline-flex;align-items:center;gap:7px;font-size:11.5px;padding:5px 8px 5px 11px;border:1px solid var(--brand);border-radius:999px;background:var(--info-bg);color:var(--brand-deep);font-weight:600;white-space:nowrap}
.netconsole .scope button{background:none;border:0;color:inherit;cursor:pointer;font-size:14px;line-height:1;padding:0 2px}
.netconsole .scope button:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.netconsole .bulk[hidden]{display:none}
.netconsole .bulk .warn[hidden]{display:none}
.netconsole .scope[hidden]{display:none}
.netconsole .bulk .n{font-size:12.5px}
.netconsole .bulk .n b{font-weight:600}
.netconsole .bulk .warn{font-size:12px;color:var(--bad);display:flex;align-items:center;gap:6px}
.netconsole .bulk .sp{margin-left:auto;display:flex;gap:7px;flex-wrap:wrap}
.netconsole .empty{padding:26px 14px;text-align:center;color:var(--faint);font-size:13px}
.netconsole .strip{display:flex;border-top:1px solid var(--line);background:var(--panel-2);flex-wrap:wrap}
.netconsole .strip .cell{padding:10px 14px;border-right:1px solid var(--line);display:flex;gap:8px;align-items:baseline}
.netconsole .strip .cell:last-child{border-right:0;margin-left:auto}
.netconsole .strip .n{font-family:var(--mono);font-size:15px;font-variant-numeric:tabular-nums}
.netconsole .strip .n.bad{color:var(--bad)}
.netconsole .strip .l{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--faint)}
.netconsole .noloc{padding:12px 14px;border-top:1px solid var(--line);background:var(--need-bg);color:var(--need);font-size:12.5px}
/* location admin */
.netconsole .locadmin{margin-top:18px;border:1px solid var(--line);border-radius:6px;background:var(--panel);overflow:hidden}
.netconsole .locadmin h2{font-size:13px;margin:0;padding:11px 14px;border-bottom:1px solid var(--line);background:var(--panel-2);font-family:var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--faint);font-weight:400}
.netconsole .locrow{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:10px 14px;border-bottom:1px solid var(--line-soft)}
.netconsole .locrow:last-child{border-bottom:0}
.netconsole .locrow .lname{font-weight:600;font-size:13px;flex:1 1 160px;min-width:0;
  display:flex;flex-direction:column;gap:1px}
.netconsole .locrow .lname .lwho{font-weight:400;font-size:11px;color:var(--faint)}
.netconsole .locrow .lcur{font-family:var(--mono);font-size:11px;color:var(--faint);flex:0 0 auto}
.netconsole .locrow .lcur .warn{color:var(--need)}
.netconsole .locrow.isapprox{background:var(--need-bg)}
.netconsole .locrow form{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.netconsole .locrow input{border:1px solid var(--line);border-radius:3px;background:var(--panel-2);padding:5px 8px;font-family:var(--mono);font-size:11px;color:var(--ink);width:92px}
.netconsole .locrow input.city{width:150px}
.netconsole .locrow input.addr{width:200px}
@media (max-width:820px){
  .netconsole .body{grid-template-columns:1fr}
  .netconsole .mapcol{border-right:0;border-bottom:1px solid var(--line)}
  .earth{height:400px}
  .earth.solo{height:280px}
  .netconsole .maplegend{position:static;margin:0;padding:10px 12px;border:0;border-top:1px solid var(--line);
    border-radius:0;background:var(--panel-2);flex-direction:row;flex-wrap:wrap;gap:10px}
  .netconsole .maplegend .li{color:var(--dim)}
  .netconsole .maplegend .hd{color:var(--faint)}
}
.netconsole th.cb{width:34px}

/* The review button leads on a document row — commenting is the action, viewing
   the PDF is the fallback. */
.btn.primary { background: var(--brand); color: #06202B; border-color: var(--brand); font-weight: 600 }
.btn.primary:hover { filter: brightness(1.08) }
/* Appended after .dl .btn, which was repainting every button in the row. The
   review button is the action; View and Download are the fallback. */
.dl .btn.primary { background: var(--brand); color: #06202B; border-color: var(--brand); font-weight: 700 }
.dl .btn:not(.primary) { background: transparent; color: var(--ink); border: 1px solid var(--line) }
.dl .btn:not(.primary):hover { border-color: var(--brand); color: var(--brand) }

.docs .dl .btn.primary{background:var(--brand);color:#06202B;border-color:var(--brand);font-weight:700}

/* Inline email feedback. Deliberately quiet: a hint under the field, not an
   alarm, and the field only turns red once the person has left it. */
.mailnote { font-size: 12.5px; color: #E0A02A; margin-top: 5px; min-height: 1px }
input[type=email].bad { border-color: #E0A02A }
input[type=email].bad:focus-visible { outline-color: #E0A02A }


/* ============================================================
   SECTION RAIL
   Replaces the flat .navlinks strip. Same grouped shape for every
   role — a client sees fewer groups, never a different navigation.
   .navlinks styles are left in place: other views still use the
   class, and removing them is a separate job from this one.
   ============================================================ */
.shell{max-width:1280px;margin:0 auto;display:flex;gap:0;align-items:flex-start}
.rail{width:216px;flex:none;align-self:stretch;padding:18px 12px 40px;
      background:var(--dark);min-height:calc(100vh - 58px)}
.rail .rgrp{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;
            color:#6F7887;font-weight:600;padding:16px 10px 6px}
.rail .rgrp:first-child{padding-top:4px}
.rail a{display:flex;align-items:center;gap:9px;font-size:13.5px;color:#C3CAD4;
        padding:7px 10px;border-radius:6px;text-decoration:none;line-height:1.35}
.rail a:hover{background:rgba(255,255,255,.06);color:#fff}
.rail a.here{background:rgba(88,203,245,.15);color:var(--brand);font-weight:600}
.rail a:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.rail .rdot{width:5px;height:5px;border-radius:50%;background:#4A5262;flex:none}
.rail a:hover .rdot{background:#8A93A2}
.rail a.here .rdot{background:var(--brand)}

/* A collapsible rail group (Clients today) — the heading becomes a <summary>,
   styled to sit exactly where the plain .rgrp heading used to so the two look
   identical closed. The marker is custom because the native disclosure
   triangle does not take dark-theme colors reliably across browsers. */
.rail .rgrp-d{margin:0}
.rail summary.rgrp{cursor:pointer;display:flex;align-items:center;gap:6px;
                    list-style:none;user-select:none}
.rail summary.rgrp::-webkit-details-marker{display:none}
.rail summary.rgrp::before{content:'▸';font-size:9px;color:#6F7887;transition:transform .12s}
.rail .rgrp-d[open] summary.rgrp::before{transform:rotate(90deg)}
.rail summary.rgrp:hover{color:#9AA3B2}
.rail summary.rgrp:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:4px}
.rail .rgrp-n{margin-left:auto;font-size:9.5px;color:#4A5262}
.rail .rgrp-body{display:flex;flex-direction:column}

/* Under 900px the rail stops being a column and becomes a scrolling row above
   the content. The group headings stay inline so the grouping survives the
   reflow instead of collapsing back into the flat strip this replaced. */
@media (max-width:900px){
  .shell{flex-direction:column}
  .rail{width:100%;min-height:0;align-self:auto;padding:8px 10px;
        display:flex;gap:4px;overflow-x:auto;-webkit-overflow-scrolling:touch;
        border-bottom:1px solid rgba(255,255,255,.08)}
  .rail .rgrp{padding:0 4px 0 12px;display:flex;align-items:center;white-space:nowrap;
              border-left:1px solid rgba(255,255,255,.12)}
  .rail .rgrp:first-child{border-left:0;padding-left:4px}
  .rail a{white-space:nowrap;padding:6px 10px}
  .rail .rdot{display:none}
}


/* ---- onward links: the dead-end fix -------------------------------------
   Sits at the foot of every page. Deliberately quiet — it is a way out, not a
   call to action, so it must not compete with the page's own primary button. */
.onward{margin-top:34px;padding-top:18px;border-top:1px solid var(--line)}
.onward-h{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
          color:var(--faint);font-weight:600;margin-bottom:10px}
.onward-row{display:flex;gap:10px;flex-wrap:wrap}
.onward-row a{display:flex;flex-direction:column;gap:2px;text-decoration:none;
              background:var(--panel);border:1px solid var(--line);
              border-radius:6px;padding:10px 14px;min-width:168px;flex:1 1 168px;max-width:280px}
.onward-row a:hover{border-color:var(--brand);background:var(--panel-2)}
.onward-row a:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.onward-row a .t{font-size:13.5px;font-weight:600;color:var(--ink)}
.onward-row a .t::after{content:' \2192';color:var(--brand-deep)}
.onward-row a .s{font-size:11.5px;color:var(--faint);line-height:1.4}
@media (max-width:560px){.onward-row a{min-width:100%;max-width:none}}


/* ---- wordmark in the top bar (public status page) -----------------------
   The existing logo rules are scoped to `.d2 .card`, the sign-in card, so they
   do not reach the bar. Same light/dark pair, swapped on theme rather than
   filtered — the mark carries dark ink that vanishes on the dark bar. */
.bar .barlogo{display:inline-flex;align-items:center;line-height:0;text-decoration:none}
.bar .barlogo img{height:26px;width:auto;display:block}
.bar .barlogo img.logo-l{display:none}
.bar .barlogo img.logo-d{display:block}
@media (max-width:520px){.bar .barlogo img{height:22px}}

/* Theme switch: three square icon buttons. Sized to the 44px touch target on a
   phone and tighter on a pointer device, where a mis-tap costs nothing. */
.themesw button{display:grid;place-items:center;width:38px;height:32px;padding:0;line-height:0}
.themesw button svg{display:block}
.themesw button.on svg{stroke-width:2}
@media (max-width:640px){.themesw button{width:44px;height:40px}}

/* ---------- Files and image proofing ----------------------------------------
   The pins are positioned against the IMAGE's own box, so .proof is the
   positioning context and the image fills it exactly. A pin's left/top are
   percentages of that box, which is what makes the same pin land in the same
   place at any width. */
.p-warn{background:var(--need-bg);color:var(--need)}

.filerow .dl{margin:.4rem 0 0}
.crumbs a{color:var(--dim)}
.inline-form{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin:.5rem 0 0}
.inline-form input[type=text],.inline-form input:not([type]){min-width:12rem}
.inline-form label{display:flex;align-items:center;gap:.4rem}

.proof{position:relative;display:inline-block;max-width:100%;line-height:0;
  border:1px solid var(--line);border-radius:6px;overflow:hidden;cursor:crosshair;
  background:var(--panel-2)}
.proof img{display:block;max-width:100%;height:auto}

.pin{position:absolute;transform:translate(-50%,-50%);width:26px;height:26px;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:11px;line-height:1;font-weight:700;
  color:#fff;background:var(--bad);border:2px solid #fff;border-radius:50%;
  box-shadow:0 1px 4px rgba(0,0,0,.4);cursor:pointer;padding:0}
.pin.done{background:var(--ok)}
.pin.ghost{background:var(--brand-deep);opacity:.75;pointer-events:none}
.pin.static{position:static;transform:none;margin-right:.45rem;vertical-align:middle;
  width:22px;height:22px;cursor:default}

.pinform{margin-top:.75rem}
.feed.pins li.resolved{opacity:.68}
.feed.pins li.flash{outline:2px solid var(--brand);outline-offset:4px;border-radius:4px}
.replies{list-style:none;margin:.4rem 0 .4rem 1rem;padding:0 0 0 .8rem;border-left:2px solid var(--line)}
.replies p{margin:.15rem 0 .5rem}

@media (prefers-reduced-motion:reduce){.feed.pins li.flash{outline-width:3px}}

/* `hidden` has to beat the display the class sets, or the ghost pin and the
   pin form show up before anyone has clicked anything. */
[hidden]{display:none !important}

/* Service line-item form: a checkbox reveals the tax-rate fields with no JS,
   since script-src is a hash allowlist and won't run an inline onchange. */
form:has(#li-taxable:checked) #tax-rate-fields[hidden]{display:block !important}

/* `.stack` (the add-a-service form, line-item form, and a few others) had no
   rule of its own, so its <label>s fell back to inline and ran together —
   the "everything on one wrapped line" look. Give it the same block-label
   shape `.f` already has, plus a light grid for rows of short fields
   (`.gf-row`) so a quantity/client/cost trio sits side by side instead of
   stacking full width. */
.stack{display:block}
.stack label{display:block;font-size:13px;font-weight:600;color:var(--ink);margin:14px 0 6px}
.stack label>span{display:block;margin-bottom:6px}
.stack label.check{display:flex;align-items:center;gap:7px;font-weight:400;margin:14px 0 0}
.stack label.check input{width:auto;margin:0;accent-color:var(--brand)}
.stack input[type=text],.stack input[type=email],.stack input:not([type]),
.stack select,.stack textarea{
  width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:9px;background:var(--panel-2);
  color:var(--ink);font-family:var(--sans);font-size:14.5px;box-sizing:border-box}
.stack .act{margin-top:16px}
.gf-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:0 12px}

/* Add/edit-service form: name and the two facts that matter for billing are
   answered up front; the rest of the account paperwork is real but rarely
   filled in on day one, so it starts collapsed rather than making a
   30-second "just get it in the system" add feel like a compliance form. */
.stack details.more{margin-top:18px;border-top:1px solid var(--line);padding-top:4px}
.stack details.more summary{cursor:pointer;font-size:13px;font-weight:600;color:var(--dim);
  padding:10px 0;list-style:none}
.stack details.more summary::-webkit-details-marker{display:none}
.stack details.more summary::before{content:"▸ ";color:var(--faint)}
.stack details.more[open] summary::before{content:"▾ "}
.stack details.more summary .meta{font-weight:400}

/* ---------- Storage: the explorer window -----------------------------------
   Three panes on a desktop, stacked on a phone. The middle pane is the only one
   that scrolls horizontally, and it does so inside its own box: a file name is
   allowed to be long without the whole page sliding sideways. */
.explorer { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 0;
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  background: var(--panel); box-shadow: var(--shadow) }
.explorer.with-detail { grid-template-columns: 190px minmax(0, 1fr) 290px }
@media (max-width: 1400px) { .explorer.with-detail { grid-template-columns: 170px minmax(0, 1fr) 260px } }

.ex-rail { background: var(--panel-2); border-right: 1px solid var(--line); padding: 10px 0; min-width: 0 }
.ex-group + .ex-group { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line) }
.ex-gh { font-family: var(--mono); font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--faint); padding: 0 12px 6px }
.ex-item { display: flex; align-items: center; gap: 8px; padding: 6px 12px; text-decoration: none;
  color: var(--dim); font-size: 13.5px; line-height: 1.3 }
.ex-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.ex-item.sub { padding-left: 22px }
.ex-item:hover { background: var(--panel); color: var(--ink) }
.ex-item.on { background: var(--build-bg); color: var(--cyan-ink); font-weight: 600 }
.ex-item .ic { color: var(--brand-deep) }

.ic { width: 15px; height: 15px; flex: 0 0 auto }
.tool-ic { width: 30px; height: 30px; color: var(--brand-deep); display: block; margin-bottom: 8px }
.tool.big { grid-column: 1 / -1 }

.ex-main { min-width: 0; display: flex; flex-direction: column }
.ex-bar { display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 10px 14px; border-bottom: 1px solid var(--line) }
.ex-crumbs { margin: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.ex-crumbs a { color: var(--dim); text-decoration: none }
.ex-crumbs a:hover { color: var(--cyan-ink); text-decoration: underline }
.ex-crumbs span { color: var(--faint); margin: 0 2px }
.ex-scroll { overflow-x: auto }

/* A minimum width so a squeezed pane SCROLLS rather than crushing every column
   into two characters. The scroll lives on .ex-scroll, not on the page. */
.ex-table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: 13.5px }
.ex-table col.c-name { width: auto }
.ex-table th { text-align: left; font-family: var(--mono); font-size: 9.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint); font-weight: 400; padding: 8px 12px;
  border-bottom: 1px solid var(--line) }
.ex-table td { padding: 8px 12px; border-bottom: 1px solid var(--line); vertical-align: middle }
.ex-table tr:last-child td { border-bottom: 0 }
.ex-table tbody tr:hover { background: var(--panel-2) }
.ex-table tbody tr.on { background: var(--build-bg) }
.ex-n a { display: flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; font-weight: 600 }
.ex-n a:hover span { text-decoration: underline }
.ex-n .ic { color: var(--brand-deep) }
.ex-real { font-size: 11px; color: var(--faint); margin: 2px 0 0 23px }
.ex-k, .ex-s, .ex-d { color: var(--faint); font-family: var(--mono); font-size: 11px; white-space: nowrap }
.ex-a { white-space: nowrap; text-align: right; width: 1% }
.ex-a .btn { padding: 3px 9px; font-size: 11.5px }
.ex-a .pill { vertical-align: middle; margin-left: 3px }
.ex-n { width: 99% }
.ex-n a span { overflow-wrap: anywhere }

.ex-empty { color: var(--faint); font-size: 13px; padding: 0 12px }
.ex-empty.pad { padding: 24px 14px }
.ex-err, .ex-ok { margin: 0; padding: 8px 14px; font-size: 13px }
.ex-err { background: var(--bad-bg); color: var(--bad) }
.ex-ok { background: var(--ok-bg); color: var(--ok) }
.ex-note { padding: 12px 14px; margin: 0; border-top: 1px solid var(--line) }

.ex-drop { border-top: 1px solid var(--line); padding: 10px 14px; background: var(--panel-2) }
.ex-drop form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 }
.ex-drop form + form { margin-top: 8px }
.ex-drop input[type=text], .ex-drop input:not([type]) { flex: 1 1 160px; min-width: 0 }

.ex-detail { border-left: 1px solid var(--line); padding: 12px 14px; min-width: 0; overflow-wrap: anywhere }
.ex-dh { display: flex; align-items: center; gap: 8px; margin-bottom: 4px }
.ex-dh .ic { color: var(--brand-deep) }
.ex-dh b { font-size: 14.5px; line-height: 1.3 }
.ex-thumb { display: block; max-width: 100%; height: auto; border: 1px solid var(--line);
  border-radius: 6px; margin: 10px 0 }
.ex-thread { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line) }
.ex-thread .feed li { font-size: 13px }
.ex-detail form { margin-top: 8px }
.ex-detail .inline-form input, .ex-detail .inline-form select { min-width: 0; flex: 1 1 120px }

@media (max-width: 900px) {
  .explorer, .explorer.with-detail { grid-template-columns: minmax(0, 1fr) }
  .ex-rail { border-right: 0; border-bottom: 1px solid var(--line) }
  .ex-detail { border-left: 0; border-top: 1px solid var(--line) }
  .ex-k, .ex-d { display: none }
  .ex-table thead th:nth-child(2), .ex-table thead th:nth-child(4) { display: none }
}
.ex-badges { margin: 3px 0 0 23px; display: flex; gap: 4px; flex-wrap: wrap }
.ex-badges .pill { font-size: 9px; padding: 1px 5px }
/* The detail pane is narrow by design, so its buttons wrap as whole buttons
   rather than breaking a label in half across two lines. */
.ex-detail .dl { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 }
.ex-detail .dl .btn { white-space: nowrap }
.ex-detail .inline-form { gap: 6px }

/* ---- Org chart --------------------------------------------------------
   Ported from menace/web/org.html, which builds itself in the browser from
   /org.json. The panel strips scripts and the CSP forbids an inline <style>,
   so the same design is rendered on the server here and these rules moved
   into the served stylesheet.

   Everything is namespaced under .orgchart: the source used bare .head,
   .empty and .who, all of which already mean something else in this panel. */
.orgchart .top{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:clamp(18px,3vw,30px)}
.orgchart .synced{font-family:var(--mono);font-size:11px;color:var(--faint);letter-spacing:.04em;text-align:right;white-space:nowrap}
.orgchart .synced .day{opacity:.7}

/* Charles -> Morpheus -> departments. Two head boxes with a spine between. */
.orgchart .boxhead{background:var(--panel);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);
  padding:16px 18px;max-width:420px;margin:0 auto;text-align:center}
.orgchart .boxhead .who{font-size:18px;font-weight:600;letter-spacing:-.01em}
.orgchart .boxhead .role{color:var(--dim);font-size:13px}
.orgchart .boxhead .role.sub{font-family:var(--mono);font-size:11px;color:var(--faint);letter-spacing:.04em;margin-top:3px}
.orgchart .boxhead.boss{border-color:var(--cyan)}
.orgchart .spine{width:2px;height:26px;background:var(--line);margin:0 auto}

.orgchart .depts{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;margin-top:8px}
.orgchart .dept{background:var(--panel);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);overflow:hidden}
.orgchart .dept-h{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 16px;
  background:var(--panel-2);border-bottom:1px solid var(--line)}
.orgchart .dept-h h2{margin:0;font-size:13px;letter-spacing:.12em;text-transform:uppercase;font-family:var(--mono);color:var(--cyan-ink)}
.orgchart .dept-h .n{font-family:var(--mono);font-size:11px;color:var(--faint)}
.orgchart .person{display:grid;grid-template-columns:auto 1fr;gap:12px;padding:14px 16px;border-top:1px solid var(--line)}
.orgchart .person:first-of-type{border-top:0}
.orgchart .dot{width:12px;height:12px;border-radius:50%;margin-top:5px;background:var(--cyan);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--line) 60%,transparent)}
.orgchart .person .who{font-weight:600;font-size:15px;letter-spacing:-.01em}
.orgchart .person .role{color:var(--cyan-ink);font-size:12px;font-family:var(--mono);letter-spacing:.04em}
.orgchart .person .desc{color:var(--dim);font-size:13px;margin-top:3px}
.orgchart .person .stats{margin-top:6px;font-family:var(--mono);font-size:11px;color:var(--faint);letter-spacing:.04em}
.orgchart .person .stats b{color:var(--ok);font-weight:600}
.orgchart .person .stats .f{color:var(--bad);font-weight:600}
.orgchart .person.is-lead{background:color-mix(in srgb,var(--cyan) 5%,transparent)}
.orgchart .person .star{margin-left:7px;font-family:var(--mono);font-size:10px;letter-spacing:.08em;color:var(--need)}
.orgchart .tagline{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:999px;font-family:var(--mono);
  font-size:10px;letter-spacing:.08em;text-transform:uppercase;background:var(--build-bg);color:var(--build)}
.orgchart .none-yet{color:var(--dim)}
/* Employment state, from the personnel file HR keeps. ONBOARDING is deliberately
   the loud one: it means the seat is filled but the hire is not finished. */
.orgchart .emp{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:999px;font-family:var(--mono);
  font-size:10px;letter-spacing:.08em;border:1px solid transparent;vertical-align:middle}
.orgchart .emp.e-active{background:color-mix(in srgb,var(--ok) 14%,transparent);color:var(--ok);
  border-color:color-mix(in srgb,var(--ok) 35%,transparent)}
.orgchart .emp.e-onboarding{background:color-mix(in srgb,var(--need) 16%,transparent);color:var(--need);
  border-color:color-mix(in srgb,var(--need) 40%,transparent)}
.orgchart .emp.e-on_leave{background:var(--build-bg);color:var(--build)}
.orgchart .emp.e-offboarded{background:color-mix(in srgb,var(--bad) 12%,transparent);color:var(--bad);
  border-color:color-mix(in srgb,var(--bad) 32%,transparent)}
.orgchart .person .empline{margin-top:5px;font-family:var(--mono);font-size:11px;color:var(--faint);letter-spacing:.04em}
.orgchart .person .empline span{margin-right:10px}
.orgchart .person .empline .eid{color:var(--dim)}
.orgchart .synced .pending{color:var(--need)}

/* The address sits under the title, where you look when you want to reach this
   one. Agents answer on their department's shared mailbox, so that is what is
   shown, and a department without one says so rather than leaving a gap. */
.orgchart .person .mail{display:block;margin:3px 0 0;font-family:var(--mono);font-size:11.5px;
  color:var(--cyan);text-decoration:none;letter-spacing:.01em;word-break:break-all}
.orgchart .person .mail:hover{text-decoration:underline}
.orgchart .person .mail.none{color:var(--faint)}
/* Department detail: the agent cards stack rather than sitting on a chart. */
.orgchart .d-people{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:10px}
.orgchart .node{display:grid;grid-template-columns:auto 1fr;gap:9px;align-items:start;text-decoration:none;
  background:var(--panel);border:1px solid var(--line);border-left:2px solid var(--agent,var(--cyan));
  border-radius:9px;padding:10px 12px}
.orgchart .node:hover{border-color:var(--cyan)}
.orgchart .nbody{display:block;min-width:0}
.orgchart .nname{display:block;font-weight:600;font-size:13.5px;letter-spacing:-.01em}
.orgchart .nlead{margin-left:6px;font-family:var(--mono);font-size:9px;letter-spacing:.1em;color:var(--need)}
.orgchart .nrole{display:block;font-family:var(--mono);font-size:10.5px;color:var(--cyan-ink);
  letter-spacing:.03em;margin-top:1px}
.orgchart .ndesc{display:block;color:var(--dim);font-size:12.5px;margin-top:4px;line-height:1.45}
.orgchart .nstat{display:block;font-family:var(--mono);font-size:10.5px;color:var(--faint);margin-top:5px}
/* The department name on the chart is the way into its detail page. */
.orgchart .dept-h .dlink{margin:0;font-size:13px;letter-spacing:.12em;text-transform:uppercase;
  font-family:var(--mono);color:var(--cyan-ink);text-decoration:none}
.orgchart .dept-h .dlink:hover{text-decoration:underline}

/* ---- money ---------------------------------------------------------------
   The Payments section, the virtual terminal and the client's pay page. Built
   out of the classes already here — .card, .grid, .pill, .glance — so a page
   about money looks like the rest of the panel rather than like a plug-in. */

/* The charge form. Two rows of fields that reflow to one column on a phone,
   because the terminal gets used standing up with a client on the line. */
.payform label{display:block;font-size:13px;font-weight:600;color:var(--ink);margin:0 0 6px}
.payform label .opt{font-weight:400;color:var(--faint)}
.payform input,.payform select{width:100%;padding:10px 11px;border:1px solid var(--line);border-radius:8px;
  background:var(--panel-2);color:var(--ink);font-family:var(--sans);font-size:14px;box-sizing:border-box}
.payform input:focus,.payform select:focus{outline:2px solid color-mix(in srgb,var(--brand) 50%,transparent);
  outline-offset:1px;border-color:var(--brand)}
.payrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px;margin:0 0 14px}
.payrow label.wide{grid-column:1/-1}
.payform .acts{display:flex;flex-wrap:wrap;gap:10px;margin:4px 0 0}

.payfilter{display:flex;flex-wrap:wrap;gap:0;border:1px solid var(--line);border-radius:8px;overflow:hidden;
  background:var(--panel-2);margin:0 0 14px;width:fit-content}
.payfilter a{padding:7px 14px;text-decoration:none;font-family:var(--mono);font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--faint);border-right:1px solid var(--line)}
.payfilter a:last-child{border-right:0}
.payfilter a:hover{color:var(--ink)}
.payfilter a.on{background:var(--panel);color:var(--ink);font-weight:700}

/* An amount is a number to be compared down a column, so it is tabular
   everywhere it appears. */
table.payments td.mono,table.kv td.mono{font-variant-numeric:tabular-nums}
.big-amount{font-size:22px;font-variant-numeric:tabular-nums}
.small-mono{font-size:11px;color:var(--faint);overflow-wrap:anywhere}

/* Stripe draws its own fields into this box. It is given a minimum height so the
   page does not jump when the iframe finishes loading. */
.payelement{border:1px solid var(--line);border-radius:9px;background:var(--panel-2);padding:14px;
  min-height:120px;margin:0 0 16px}
.payalert{border-radius:9px;padding:11px 13px;font-size:13.5px;margin:0 0 14px;
  background:var(--panel-2);color:var(--dim)}
.payalert.bad{background:var(--bad-bg);color:var(--bad)}
.payalert.ok{background:var(--ok-bg);color:var(--ok)}

/* The pay page reuses the sign-in card, where the primary action is a <button>.
   Here it is a link, so it needs the box the button already had. */
a.go{display:block;text-align:center;text-decoration:none;box-sizing:border-box}
/* `.acts` already exists inside the network console only. These are the ones on
   a card, laid out the same way without reaching into that component. */
.card>.acts{display:flex;flex-wrap:wrap;gap:10px;align-items:center}

/* The policy checklist. `table.grid` pins columns three and four to nowrap for
   the ledger's sake, which here squeezed the label into a two-word column while
   the "where in Stripe" text held a line to itself. This table sets its own. */
table.policies td,
table.policies td:nth-child(3),
table.policies td:nth-child(4){white-space:normal}
table.policies td:first-child{width:1%}
table.policies td:nth-child(2){width:auto}
table.policies td:nth-child(3){width:34%;font-family:var(--mono);font-size:11px}
table.policies td:last-child{width:1%;white-space:nowrap}
.payalert.warn{background:var(--need-bg);color:var(--need)}

/* ============================================================
   MODERN design layer — Schuck brand kept (cyan #58CBF5 + wordmark).
   Applied last so it harmonizes radii, softens shadows, and adds
   subtle motion across the WHOLE panel. Colours/fonts untouched.
   ============================================================ */
/* Containers & surfaces → one large radius */
.card,.d2 .card,.costbox,.tiles,.tile,.glance,.feed,.docs,.explorer,.ex-main,.ex-rail,.ex-detail,
.codebox,.code-out,.empty,.gate,.gates,.statusbanner,.boxhead,.note,.payalert,.map{
  border-radius:var(--r-lg);
}
.card{box-shadow:var(--shadow);transition:box-shadow var(--tr),transform var(--tr)}
.card:hover{box-shadow:0 2px 6px rgba(17,26,34,.06),0 12px 30px rgba(17,26,34,.08)}
/* Buttons → medium radius + subtle motion */
.btn,button.mini,.docs .dl .btn,.who .btn.ghost{
  border-radius:var(--r-md);
  transition:background var(--tr),border-color var(--tr),transform var(--tr),box-shadow var(--tr),filter var(--tr);
}
.btn:hover{filter:brightness(1.03);box-shadow:var(--shadow-sm)}
.btn:active{transform:translateY(1px)}
button.mini:hover{border-color:var(--brand)}
/* Inputs → medium radius, brand focus ring (already brand elsewhere) */
.f input,.f select,.reqf input,.reqf textarea,form.inline select,.pw input{border-radius:var(--r-md)}
/* Chips / tags / small controls → small radius; pills stay pills */
.chip,.tag{border-radius:var(--r-sm)}
.pill{border-radius:var(--r-pill)}
/* Network console + map controls → match Modern (were 3-4px) */
.netconsole .btn{border-radius:var(--r-sm)}
.earth .ectl button{border-radius:var(--r-sm)}
/* Tables → rounded, clipped corners */
table.policies,.ex-table{border-radius:var(--r-md);overflow:hidden}
/* Links → subtle colour motion */
a{transition:color var(--tr)}
.gap-above { margin-top: 20px }

/* ============================================================================
   Overview page (/brief) — the local Morpheus daily brief (menace/web/daily.html)
   reproduced on the server. The `.ov-` namespace keeps it clear of the shared
   panel classes; colours come from the tokens at the top of this file, never
   hard-coded. Bar fills carry their length as an .ov-w-N width bucket because
   the strict CSP forbids the style attribute the local page used.
   ========================================================================== */

/* width buckets (rounded to 5%) — the CSP-safe stand-in for style="width:X%".
   Scales rather than widths: a width transition thrashes layout on every tick,
   scaleX is a compositor-only transform, and the fill's own left:0/top:0/
   bottom:0 plus this scaleX(0..1) from the left edge lands in the identical
   place a width bucket would. */
.ov-w-0{transform:scaleX(0)}.ov-w-5{transform:scaleX(.05)}.ov-w-10{transform:scaleX(.1)}
.ov-w-15{transform:scaleX(.15)}.ov-w-20{transform:scaleX(.2)}.ov-w-25{transform:scaleX(.25)}
.ov-w-30{transform:scaleX(.3)}.ov-w-35{transform:scaleX(.35)}.ov-w-40{transform:scaleX(.4)}
.ov-w-45{transform:scaleX(.45)}.ov-w-50{transform:scaleX(.5)}.ov-w-55{transform:scaleX(.55)}
.ov-w-60{transform:scaleX(.6)}.ov-w-65{transform:scaleX(.65)}.ov-w-70{transform:scaleX(.7)}
.ov-w-75{transform:scaleX(.75)}.ov-w-80{transform:scaleX(.8)}.ov-w-85{transform:scaleX(.85)}
.ov-w-90{transform:scaleX(.9)}.ov-w-95{transform:scaleX(.95)}.ov-w-100{transform:scaleX(1)}

/* top-of-page alert banners */
.ov-alert{display:flex;align-items:center;gap:11px;padding:12px 16px;border-radius:var(--r-md);
  margin:0 0 14px;font-size:13.5px;font-weight:600;border:1px solid}
.ov-alert-dot{width:9px;height:9px;border-radius:50%;background:currentColor;flex:0 0 auto;
  box-shadow:0 0 8px currentColor}
.ov-alert a{margin-left:auto;color:inherit;font-weight:700;white-space:nowrap}
.ov-alert--crit{background:var(--bad-bg);color:var(--bad);border-color:color-mix(in srgb,var(--bad) 40%,transparent)}
.ov-alert--ok{background:color-mix(in srgb,var(--ok,#2ecc71) 14%,transparent);color:var(--ok,#2ecc71);border-color:color-mix(in srgb,var(--ok,#2ecc71) 40%,transparent)}
.ov-alert--warn{background:var(--need-bg);color:var(--need);border-color:color-mix(in srgb,var(--need) 40%,transparent)}

/* hero: spend meter + cap bar */
.ov-meter{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:18px 20px 16px;box-shadow:var(--shadow);margin:0 0 18px}
.ov-meter-h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}
.ov-meter-t{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint)}
.ov-meter-amt{font-family:var(--mono);font-variant-numeric:tabular-nums}
.ov-meter-amt b{font-size:22px;font-weight:800;letter-spacing:-.01em}
.ov-cap{color:var(--dim);font-size:14px}
.ov-bar{position:relative;height:14px;border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--line) 60%,transparent);overflow:hidden;margin:13px 0 6px;border:1px solid var(--line)}
/* No width here on purpose. The fill ALWAYS carries an .ov-w-N bucket class
   (ov-w-0 included), and those buckets are defined earlier in this file at the
   same specificity — so a width declared here silently won on source order and
   pinned every bar to zero. The green never appeared no matter what the number
   above it said. */
.ov-fill{position:absolute;left:0;top:0;bottom:0;width:100%;transform-origin:left;border-radius:var(--r-sm);
  background:linear-gradient(90deg,var(--ok),color-mix(in srgb,var(--ok) 70%,var(--cyan)));transition:transform .9s cubic-bezier(.4,0,.2,1)}
.ov-bar--warn .ov-fill{background:linear-gradient(90deg,var(--need),color-mix(in srgb,var(--need) 60%,#e0a))}
.ov-bar--crit .ov-fill{background:linear-gradient(90deg,var(--bad),#ff8a5a)}
.ov-meter-sub{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;
  font-family:var(--mono);font-size:11px;color:var(--faint);letter-spacing:.04em}

/* KPI tiles */
.ov-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:14px}
.ov-tiles--5{grid-template-columns:repeat(5,1fr)}
.ov-tiles--3{grid-template-columns:repeat(3,1fr)}
.ov-tile{background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r-md);padding:10px 12px}
.ov-tile .n{font-family:var(--mono);font-size:19px;font-variant-numeric:tabular-nums;font-weight:700;line-height:1}
.ov-tile .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);margin-top:6px}
.ov-tile--ok .n{color:var(--ok)} .ov-tile--bad .n{color:var(--bad)} .ov-tile--build .n{color:var(--build)}
@media (max-width:640px){.ov-tiles,.ov-tiles--5,.ov-tiles--3{grid-template-columns:repeat(2,1fr)}}

/* grouped section headers */
.ov-group{margin:26px 0 0}
/* Overview's Activity feed only — .feed itself is shared by Needs your call's
   reply cards and a dozen other pages, so the tighter row height is scoped
   here rather than changed globally. */
.ov-activity .feed li{padding:7px 0}
.ov-activity .feed .ft b{font-size:13px}
.ov-activity .feed p{margin:2px 0 0;font-size:12.5px}
.ov-group-h{display:flex;align-items:baseline;gap:12px;margin:0 0 13px;padding-bottom:9px;border-bottom:1px solid var(--line)}
.ov-group-h h2{font-size:15px;margin:0}
.ov-tag{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);margin-left:auto}

/* Waiting on you — agent inbox (read-only) */
.ov-inbox{display:flex;flex-direction:column;gap:12px}
.ov-msg{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-md);padding:15px 18px;box-shadow:var(--shadow)}
.ov-msg-h{display:flex;align-items:baseline;gap:9px;margin-bottom:8px}
.ov-msg-who{font-weight:700;color:var(--cyan-ink);font-size:15px;letter-spacing:-.01em}
.ov-msg-arrow{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.ov-msg-ts{margin-left:auto;font-family:var(--mono);font-size:10.5px;color:var(--faint)}
.ov-msg-text{font-size:14px;color:var(--ink);white-space:pre-wrap;line-height:1.55}

/* Still open — the crew's unfinished queue */
.ov-open{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.ov-orow{display:grid;grid-template-columns:118px 1fr auto;gap:12px;align-items:baseline;padding:11px 15px;background:var(--panel)}
.ov-orow--late{background:color-mix(in srgb,var(--bad) 7%,var(--panel))}
.ov-owho{font-family:var(--mono);font-size:11.5px;color:var(--cyan-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-owhat{font-size:13.5px;color:var(--ink);line-height:1.5}
.ov-okind{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-right:7px}
.ov-owhen{font-family:var(--mono);font-size:10.5px;color:var(--faint);text-align:right;white-space:nowrap}
.ov-owhen b{display:block;font-weight:700;color:var(--dim)}
.ov-orow--late .ov-owhen b{color:var(--bad)}
@media (max-width:640px){.ov-orow{grid-template-columns:1fr auto;gap:3px}.ov-owho{grid-column:1/-1}}

/* Claude platform status */
.ov-cstat{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-md);padding:15px 18px;box-shadow:var(--shadow)}
.ov-cstat--hit{border-color:color-mix(in srgb,var(--bad) 45%,var(--line));background:color-mix(in srgb,var(--bad) 5%,var(--panel))}
.ov-cstat--warn{border-color:color-mix(in srgb,var(--need) 45%,var(--line));background:color-mix(in srgb,var(--need) 5%,var(--panel))}
.ov-cs-head{display:flex;align-items:center;gap:11px;flex-wrap:wrap}
.ov-cs-dot{width:10px;height:10px;border-radius:50%;background:var(--ok);flex:0 0 auto;box-shadow:0 0 8px color-mix(in srgb,var(--ok) 70%,transparent)}
.ov-cstat--warn .ov-cs-dot{background:var(--need);box-shadow:0 0 8px color-mix(in srgb,var(--need) 70%,transparent)}
.ov-cstat--hit .ov-cs-dot{background:var(--bad);box-shadow:0 0 8px color-mix(in srgb,var(--bad) 70%,transparent)}
.ov-cstat--unk .ov-cs-dot{background:var(--faint);box-shadow:none}
.ov-cs-desc{font-size:15px;font-weight:700;letter-spacing:-.01em}
.ov-cs-when{margin-left:auto;font-family:var(--mono);font-size:10.5px;color:var(--faint);letter-spacing:.04em;white-space:nowrap}
.ov-cs-when a{color:var(--cyan-ink);text-decoration:none}
.ov-cs-when a:hover{text-decoration:underline}
.ov-cs-comps{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1px;margin-top:13px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.ov-cs-c{display:flex;align-items:center;gap:9px;padding:9px 12px;background:var(--panel-2);font-size:13px}
.ov-cs-c-dot{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:0 0 auto}
.ov-cs-c--bad .ov-cs-c-dot{background:var(--bad)} .ov-cs-c--warn .ov-cs-c-dot{background:var(--need)} .ov-cs-c--maint .ov-cs-c-dot{background:var(--build)}
.ov-cs-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-cs-st{margin-left:auto;font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--faint)}
.ov-cs-c--bad .ov-cs-st{color:var(--bad)} .ov-cs-c--warn .ov-cs-st{color:var(--need)} .ov-cs-c--maint .ov-cs-st{color:var(--build)}
.ov-cs-inc{margin-top:12px;border-left:2px solid var(--bad);padding:2px 0 2px 12px}
.ov-cs-inc--maint{border-left-color:var(--build)}
.ov-cs-ih{font-size:13.5px;font-weight:700}
.ov-cs-ih a{color:var(--cyan-ink);text-decoration:none;font-family:var(--mono);font-size:10.5px;margin-left:8px;white-space:nowrap}
.ov-cs-im{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--faint);margin-top:3px}
.ov-cs-ib{font-size:12.5px;color:var(--dim);margin-top:5px;line-height:1.5}
.ov-cs-note{margin-top:12px;font-size:12.5px;color:var(--dim);border-top:1px dashed var(--line);padding-top:10px}
.ov-cs-note b{color:var(--ink);font-weight:600}
.ov-cs-note--blame b{color:var(--bad)}

/* Crew health failure list */
.ov-fails{margin-top:10px;display:flex;flex-direction:column;gap:5px}
.ov-fl{font-family:var(--mono);font-size:11.5px;color:var(--dim);display:flex;gap:10px}
.ov-fl-ts{color:var(--faint)}
.ov-fl b{color:var(--bad);font-weight:700}

/* Plan usage this cycle */
.ov-plan{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.ov-prow{display:grid;grid-template-columns:1.15fr 82px 1.35fr 118px auto;gap:10px;align-items:center;padding:6px 14px;background:var(--panel);font-size:12.5px}
.ov-prow--risk{background:color-mix(in srgb,var(--bad) 5%,var(--panel))}
.ov-pv{font-weight:700;overflow:hidden;text-overflow:ellipsis}
.ov-pv i{display:block;font-style:normal;font-family:var(--mono);font-size:10px;color:var(--faint);letter-spacing:.04em;margin-top:2px}
.ov-pk{font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;padding:3px 6px;border-radius:var(--r-xs);text-align:center;background:var(--panel-2);color:var(--faint)}
.ov-pk--ok{color:var(--ok);background:var(--ok-bg)}
.ov-pk--watch{color:var(--need);background:var(--need-bg)}
.ov-pk--critical,.ov-pk--over{color:var(--bad);background:color-mix(in srgb,var(--bad) 15%,transparent)}
.ov-pk--needs-plan{color:var(--build);background:var(--build-bg)}
.ov-pbar{position:relative;height:9px;border-radius:var(--r-xs);background:color-mix(in srgb,var(--line) 60%,transparent);overflow:hidden;border:1px solid var(--line)}
/* Same reason as .ov-fill — the .ov-w-N bucket supplies the transform. */
.ov-pfill{position:absolute;left:0;top:0;bottom:0;width:100%;transform-origin:left;border-radius:var(--r-xs);background:var(--ok);transition:transform .9s cubic-bezier(.4,0,.2,1)}
.ov-pbar--warn .ov-pfill{background:var(--need)} .ov-pbar--crit .ov-pfill{background:var(--bad)}
.ov-pu{font-family:var(--mono);font-size:10.5px;color:var(--faint);margin-top:2px;letter-spacing:.03em}
.ov-pn{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:12px;text-align:right;white-space:nowrap}
.ov-pn b{font-size:14px;font-weight:700}
.ov-pa{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:700;text-align:right;white-space:nowrap}
.ov-pa i{color:var(--faint);font-style:normal;font-weight:400}
.ov-padvice{grid-column:1/-1;color:var(--dim);font-size:12px;line-height:1.45;margin-top:-2px}
@media (max-width:760px){.ov-prow{grid-template-columns:1fr 74px;row-gap:8px}.ov-pbarwrap,.ov-pn,.ov-pa{grid-column:1/-1;text-align:left}}

/* Tool & service costs ledger */
.ov-cost{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.ov-crow{display:grid;grid-template-columns:1.1fr 74px 92px 1.5fr auto;gap:10px;align-items:center;padding:10px 14px;background:var(--panel);font-size:13px}
.ov-cv{font-weight:700}
.ov-ck{font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;padding:3px 6px;border-radius:var(--r-xs);text-align:center;background:var(--panel-2);color:var(--faint)}
.ov-ck--prepaid{color:var(--need);background:var(--need-bg)}
.ov-ck--monthly{color:var(--build);background:var(--build-bg)}
.ov-ck--usage{color:var(--ok);background:var(--ok-bg)}
.ov-cc{font-family:var(--mono);font-size:11px;color:var(--dim)}
.ov-cnote{color:var(--dim);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ov-ca{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:700;text-align:right;white-space:nowrap}
.ov-ca i{color:var(--faint);font-style:normal;font-size:10px;font-weight:400}
@media (max-width:640px){.ov-crow{grid-template-columns:1fr auto;gap:4px}.ov-ck,.ov-cc,.ov-cnote{display:none}}

/* Answering a question straight from the Overview. No JS on this page, so it is
   a plain form per question — the answer posts, queues, and the agent gets it. */
.qa{margin:10px 0 2px;display:flex;flex-direction:column;gap:8px}
.qa textarea{width:100%;background:var(--panel-2);color:inherit;border:1px solid var(--line);
  border-radius:var(--r-sm);padding:8px 10px;font:inherit;font-size:13.5px;resize:vertical}
.qa textarea:focus{outline:none;border-color:var(--cyan)}
.qa-row{display:flex;gap:8px;flex-wrap:wrap}
.qa-task{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--dim)}
.qa-task input{accent-color:var(--cyan)}

/* The thread behind a question: what was asked, what you answered, what the
   task did. Collapsed by default — the chain matters when you need it and is
   noise when you don't. <details> needs no JavaScript, which this page has none of. */
.thr{margin:9px 0 2px;border-left:2px solid var(--line);padding-left:12px}
.thr summary{cursor:pointer;font-family:var(--mono);font-size:11px;letter-spacing:.06em;
  color:var(--cyan-ink);padding:2px 0}
.thr summary:hover{text-decoration:underline}
.thr-l{list-style:none;margin:8px 0 4px;padding:0;display:flex;flex-direction:column;gap:9px}
.thr-l li{border-left:2px solid var(--line);padding:2px 0 2px 11px}
.thr-l li.thr-a{border-left-color:var(--cyan)}
.thr-l li.thr-t{border-left-color:var(--ok)}
/* A message in the conversation. Charles's own are tinted like his answers so
   the two sides of a thread read apart at a glance. */
.thr-l li.thr-c{border-left-color:var(--line)}
.thr-l li.thr-c.thr-me{border-left-color:var(--cyan)}
.thr-l li p{margin:3px 0 0;font-size:13px;line-height:1.5}
.thr-k{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.thr-d{font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;color:var(--dim);margin-left:7px}
.thr-u{color:var(--dim)}

/* Page-size control on the overview lists. Plain links, because the panel
   serves no JavaScript — a <select> would need an onchange to do anything.
   Replaces the old dead-end "+ 180 more waiting" line. */
.ov-show{margin:10px 0 0;color:var(--faint);font-family:var(--mono);font-size:12px}
.ov-show a{color:var(--dim);text-decoration:none;padding:1px 5px;border-radius:4px}
.ov-show a:hover{color:var(--fg);background:var(--hover,rgba(127,127,127,.14))}
.ov-show .ov-show-on{color:var(--fg);padding:1px 5px;border-radius:4px;background:var(--hover,rgba(127,127,127,.18))}

/* Billing reminders: the two selects sit on one line. Was a style attribute,
   which `style-src 'self'` in the panel's CSP silently drops. */
.gap-left{margin-left:18px}

/* ---- Jump-to search, in the top bar ----------------------------------------
   The panel is thirty-odd pages deep in places: a legal section sits four
   clicks from the front door, and a client's documents took three. This is the
   shortcut past all of it — type a name, land on the page. A plain GET form on
   purpose: the panel's CSP allows one hashed script and nothing else, so an
   autocomplete widget would have to be inline JavaScript that never runs. */
.bar .jump{display:flex;gap:6px;align-items:center;margin-left:8px}
.bar .jump input{width:min(30vw,260px);padding:6px 10px;border-radius:6px;
  border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.07);
  color:#fff;font:inherit;font-size:13px}
.bar .jump input::placeholder{color:#8B95A1}
.bar .jump input:focus{outline:2px solid var(--brand);outline-offset:1px;
  background:rgba(255,255,255,.12)}
/* Below the tablet breakpoint the bar is already tight; the box goes full width
   on its own row rather than squeezing the name and Sign out off the edge. */
@media (max-width:720px){
  .bar .jump{order:3;width:100%;margin-left:0}
  .bar .jump input{width:100%}
}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* The results page when a search matches more than one thing. */
.golist{list-style:none;margin:0;padding:0}
.golist li{border-bottom:1px solid var(--line)}
.golist li:last-child{border-bottom:0}
.golist a{display:flex;gap:12px;align-items:baseline;padding:11px 4px;
  text-decoration:none;color:var(--fg)}
.golist a:hover{background:var(--hover,rgba(127,127,127,.10))}
.golist .k{font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint);min-width:92px}

/* Social Posts — Awaiting Your Approval */
.social-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px}
.social-card{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--panel-2);
  display:flex;flex-direction:column}
/* A managed client's own posts carry THEIR brand color, not the panel's cyan —
   the actual color per client is a generated rule from socialAccentStyle
   (server-computed, allowed by hash); this just gives that rule somewhere to
   land. Left border only: tinting the whole card would fight the photo. */
.social-card.social-accent{border-left-width:4px}
.pill.accent{color:#fff}
.social-color-input{width:8em;font-family:var(--mono)}
.social-img{width:100%;aspect-ratio:1/1;object-fit:cover;background:var(--panel)}
.social-img-none{display:flex;align-items:center;justify-content:center;color:var(--faint);
  font-family:var(--mono);font-size:11px;text-transform:uppercase;letter-spacing:.1em}
.social-body{padding:12px;display:flex;flex-direction:column;gap:8px}
.social-meta{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}
.social-text{margin:0;font-size:14px;line-height:1.5;white-space:pre-wrap}
.social-by{font-size:11px}
.social-actions{display:flex;gap:8px;margin-top:4px}
.social-actions form.inline{margin:0}
.social-actions .btn{padding:9px 14px;font-size:13px}
.social-reschedule{margin-top:2px;gap:6px}
.social-reschedule input[type="datetime-local"]{flex:1;min-width:0;padding:6px 8px;
  border:1px solid var(--line);border-radius:8px;background:var(--panel-2);
  color:var(--ink);font-family:var(--sans);font-size:12px}
.social-reschedule .btn{padding:6px 10px;font-size:12px}
.social-view-toggle{display:flex;gap:8px;margin-top:10px}
.social-status{font-weight:600}
.social-platform{display:flex;align-items:center;gap:6px}
.social-platform-icon{flex:none;border-radius:5px}

/* ---- Money: invoices and the client list ----------------------------------
   The amount is pushed to the right edge of the row and set in the mono face,
   so a column of them lines up on the decimal and you can scan the total
   without reading the names. */
.feed.inv .ft, .feed.cli .ft{justify-content:space-between}
.feed.inv .amt{font-family:var(--mono);font-size:14px;font-weight:700;
  white-space:nowrap;margin-left:auto}
/* A past-due note is a sentence of context from the ledger, not a heading:
   dimmer than the row it belongs to, and clipped rather than wrapped forever. */
.feed.inv .note-line{color:var(--faint);font-style:italic}

/* Question detail on the overview: a drafted post arrives here to be pasted
   somewhere else. It used to be truncated at 400 characters, which meant a
   ~1,400-character morning post could not even be READ on the panel, never mind
   copied. Full text now, capped by height with its own scroll so 200 open
   questions still make a readable page. (2026-09-05) */
.qdet-w{position:relative;margin:6px 0 0}
.qdet{white-space:pre-wrap;max-height:16em;overflow-y:auto;margin:0;padding-right:4.5rem}
.qrel{font-size:.85em;margin:6px 0;padding:6px 10px;border-left:3px solid var(--accent,#4fc3f7);opacity:.9}
.qrel a{font-family:monospace}
.qrec{white-space:pre-wrap;max-height:28em;overflow-y:auto;overflow-wrap:anywhere}
.qcopy{position:absolute;top:0;right:0}
@media (max-width:640px){
  .qdet{max-height:22em;padding-right:0}
  .qcopy{position:static;display:inline-block;margin-top:8px}
}

/* ---- Users list: search bar, table with initials avatars, Filters panel ---- */
.ul-wrap{display:grid;grid-template-columns:minmax(0,1fr) 250px;gap:16px;align-items:start}
.ul-bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.ul-search{flex:1 1 260px;min-width:0;padding:11px 14px;border:1px solid var(--line);border-radius:999px;
  background:var(--panel-2);color:var(--ink);font-family:var(--sans);font-size:14.5px}
.ul-card{padding:0;overflow-x:auto}
.ul-table{width:100%;border-collapse:collapse}
.ul-table th{text-align:left;padding:12px 14px;font-size:12.5px;color:var(--dim);font-weight:600;border-bottom:1px solid var(--line);white-space:nowrap}
.ul-table td{padding:12px 14px;border-bottom:1px solid var(--line);vertical-align:middle}
.ul-table tbody tr:last-child td{border-bottom:0}
.ul-table tbody tr:hover{background:var(--panel-2)}
.ul-table td{white-space:nowrap}
.ul-table td.mono{font-size:13px}
.ul-av{width:56px}
.ul-avatar{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:50%;
  background:var(--panel-2);border:1px solid var(--line);color:var(--ink);font-size:13px;font-weight:600}
.ul-filters{position:sticky;top:12px}
.ul-filters details{border-top:1px solid var(--line);padding:10px 0}
.ul-filters summary{cursor:pointer;font-weight:600;padding:2px 0 8px}
.ul-opt{display:flex;gap:8px;align-items:center;padding:5px 2px;font-size:14px;cursor:pointer}
.ul-filters .go{width:100%;margin-top:6px}
@media (max-width:1280px){
  .ul-wrap{grid-template-columns:1fr}
  .ul-filters{position:static;order:-1;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:0 24px}
  .ul-filters .chead,.ul-filters .go{grid-column:1/-1}
  .ul-filters details{border-top:0}
}

/* ---- Person page: header with back/avatar/name, tabs, label-left rows ---- */
.up-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:6px 0 14px;border-bottom:1px solid var(--line);margin-bottom:16px}
.up-back{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;
  border:1px solid var(--line);color:var(--ink);text-decoration:none;font-size:18px}
.up-back:hover{border-color:var(--brand);color:var(--brand)}
.up-avatar{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:50%;
  background:var(--panel-2);border:1px solid var(--line);color:var(--ink);font-size:18px;font-weight:600;flex:none}
.up-who{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 200px}
.up-who b{font-size:19px}
.up-who span{color:var(--dim);font-size:14px}
.up-tabs{display:flex;gap:4px;flex-wrap:wrap;margin-left:auto}
.up-tabs a{padding:10px 14px;color:var(--dim);text-decoration:none;font-weight:600;border-bottom:2px solid transparent}
.up-tabs a:hover{color:var(--ink)}
.up-tabs a.on{color:var(--ink);border-bottom-color:var(--brand)}
.up-card{padding:6px 24px 18px}
.up-form{min-width:0}
.up-h{font-size:16px;margin:18px 0 4px;display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.up-row{display:grid;grid-template-columns:220px minmax(0,1fr);gap:16px;align-items:center;padding:14px 0;border-top:1px solid var(--line)}
.up-row > label{font-weight:600}
.up-row .req{color:var(--bad)}
.up-ctl input,.up-ctl select{width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:9px;background:var(--panel-2);
  color:var(--ink);font-family:var(--sans);font-size:14.5px;box-sizing:border-box}
.up-ctl input:focus,.up-ctl select:focus{outline:2px solid color-mix(in srgb,var(--brand) 50%,transparent);outline-offset:1px}
.up-ctl .hint{margin:6px 0 0}
.up-ctl .go{margin-top:8px}
.up-save{padding:14px 0 6px;border-top:1px solid var(--line)}
.up-panel{padding:6px 0}
@media (max-width:700px){.up-row{grid-template-columns:1fr;gap:6px}.up-tabs{margin-left:0;width:100%}}

/* ---- Internal (staff) pages use the width they are given ---- */
body.staff .shell{max-width:1800px}
body.staff .bar .in{max-width:1800px}
body.staff .cols{grid-template-columns:repeat(auto-fit,minmax(360px,1fr))}
body.staff .head .lede{max-width:80ch}
.up-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(460px,1fr));gap:0 40px;align-items:start}
.up-grid .up-row{grid-template-columns:170px minmax(0,1fr)}
@media (max-width:700px){.up-grid{grid-template-columns:1fr}.up-grid .up-row{grid-template-columns:1fr}}
/* Autonomy page. The CSP is style-src 'self', so inline style="" is dropped: these are classes. */
table.grid td.nw,table.grid td.nw .pill{white-space:nowrap;overflow-wrap:normal}
table.grid td.wrap{white-space:normal;overflow-wrap:anywhere}
.wk{display:flex;gap:10px;align-items:center;margin:4px 0}
.wk .lbl{width:92px;flex:none}
.wk .bar{display:inline-block;height:10px;border-radius:3px;background:currentColor;opacity:.55}
.wk .w0{width:0}.wk .w5{width:5%}.wk .w10{width:10%}.wk .w15{width:15%}.wk .w20{width:20%}.wk .w25{width:25%}.wk .w30{width:30%}
.wk .w35{width:35%}.wk .w40{width:40%}.wk .w45{width:45%}.wk .w50{width:50%}.wk .w55{width:55%}.wk .w60{width:60%}.wk .w65{width:65%}
