/* Generated from hub-prototype.html by scripts/sync-css.mjs. Do not edit. */

/* ==========================================================================
   Metric Hub prototype.

   Shell is lifted from the Construction Metric portal so the two products
   feel like one family: 250px sidebar rail, --snav-* variables so one light
   override flips the whole rail, off-canvas drawer under 760px.

   Colour is AI Metric's own, not Construction Metric's. Same navy ground,
   but the accent is AI Metric lime #8ddb00 rather than CM teal, because this
   is AI Metric's back office and it should read as AI Metric.

   Semantic colour (good / due / overdue) is deliberately separate from the
   accent. If money state shared the brand hue you could not tell "this is a
   button" from "this is overdue" at a glance, which is the one thing a
   finance screen must never get wrong.
   ========================================================================== */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0}

:root{
  /* Ground and surfaces */
  --navy-deep:#060F24; --navy:#0A1730; --panel:#0B1935;
  --glass:rgba(255,255,255,.05); --line:rgba(255,255,255,.10);
  --hover:rgba(255,255,255,.06);
  /* Brand.
     --green is the accent as TEXT and must clear 4.5:1 on the page ground.
     --green-btn is the accent as a FILLED SURFACE and can stay vivid, because
     the contrast that matters there is the ink sitting on it. Splitting the two
     is what lets light mode keep AI Metric's lime button instead of degrading
     to a muddy dark green: measured, white-on-lime was 3.36:1 and failed, while
     dark-on-lime is 10.5:1. */
  --green:#8ddb00; --green-btn:#8ddb00; --green-bright:#a6ec33; --btn-ink:#0d1a02;
  /* Text */
  --off:#F0F2F5; --muted:#8899aa; --faint:#74869f;
  /* Semantic, never the brand hue */
  --ok:#34d399; --ok-bg:rgba(52,211,153,.12);
  --due:#fbbf24; --due-bg:rgba(251,191,36,.12);
  --over:#f87171; --over-bg:rgba(248,113,113,.12);
  --info:#60a5fa; --info-bg:rgba(96,165,250,.12);
  --radius:14px;
}
/* Light tokens are declared twice on purpose, and the duplication is the point.
   The media query carries the operating system preference, so the page is right
   before any script runs. The attribute selector carries an explicit choice,
   either from the in-app toggle or from a host that stamps data-theme on the
   root, and it has to beat the media query in BOTH directions.
   :not([data-theme="dark"]) is what makes "I chose dark on a light machine"
   stick. Without it the media query would quietly win. */
@media (prefers-color-scheme: light){
  :root:not([data-theme="dark"]){
    --navy-deep:#eef1f6; --navy:#e6ebf3; --panel:#ffffff;
    --glass:#ffffff; --line:rgba(19,32,56,.13);
    --hover:rgba(19,32,56,.06);
    --green:#3f6b00; --green-btn:#8ddb00; --green-bright:#2f5000; --btn-ink:#0d1a02;
    --off:#132038; --muted:#5a6b86; --faint:#5f6f88;
    --ok:#047857; --ok-bg:rgba(4,120,87,.10);
    --due:#8a5406; --due-bg:rgba(138,84,6,.10);
    --over:#b91c1c; --over-bg:rgba(185,28,28,.10);
    --info:#1d4ed8; --info-bg:rgba(29,78,216,.10);
  }
}
:root[data-theme="light"]{
  --navy-deep:#eef1f6; --navy:#e6ebf3; --panel:#ffffff;
  --glass:#ffffff; --line:rgba(19,32,56,.13);
  --hover:rgba(19,32,56,.06);
  --green:#3f6b00; --green-btn:#8ddb00; --green-bright:#2f5000; --btn-ink:#0d1a02;
  --off:#132038; --muted:#5a6b86; --faint:#5f6f88;
  --ok:#047857; --ok-bg:rgba(4,120,87,.10);
  --due:#8a5406; --due-bg:rgba(138,84,6,.10);
  --over:#b91c1c; --over-bg:rgba(185,28,28,.10);
  --info:#1d4ed8; --info-bg:rgba(29,78,216,.10);
}

body{
  font-family:'Plus Jakarta Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif;
  background:var(--navy-deep); color:var(--off);
  font-size:15px; line-height:1.55; font-weight:400;
  -webkit-font-smoothing:antialiased;
}
a{color:var(--green); text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{margin:0; font-weight:600; letter-spacing:-.01em; line-height:1.25}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.num{font-variant-numeric:tabular-nums}
/* Every icon gets a sane default size. Without this, an inline SVG that misses
   its specific rule renders at the full viewBox and takes the page apart: a
   24px dollar sign became 300px tall in the sidebar the first time an icon was
   added without the matching selector. Specific rules below still win on
   specificity, so this only ever catches the ones that would otherwise escape. */
svg{width:1.05em;height:1.05em;flex:none}
.muted{color:var(--muted)}
:is(a,button,input,select,summary,[tabindex]):focus-visible{
  outline:2px solid var(--green); outline-offset:2px; border-radius:6px}

/* ---------- Shell ---------- */
.appgrid{display:grid; grid-template-columns:250px minmax(0,1fr); min-height:100vh}
.appmain{min-width:0; display:flex; flex-direction:column}

.snav{
  position:sticky; top:0; height:100vh; overflow-y:auto;
  display:flex; flex-direction:column; gap:2px; padding:14px 12px;
  background:var(--snav-bg); border-right:1px solid var(--snav-line);
  color:var(--snav-fg); scrollbar-width:thin;
  --snav-bg:#081428; --snav-fg:#e8edf6; --snav-dim:#8fa0b8; --snav-faint:#66788f;
  --snav-line:rgba(255,255,255,.10); --snav-hover:rgba(255,255,255,.06);
  --snav-accent:#8ddb00; --snav-accent-bg:rgba(141,219,0,.14);
  --snav-search-bg:rgba(255,255,255,.05);
}
@media (prefers-color-scheme: light){
  :root:not([data-theme="dark"]) .snav{
    --snav-bg:#f5f8fc; --snav-fg:#17233b; --snav-dim:#5a6b86; --snav-faint:#5f6f88;
    --snav-line:rgba(19,32,56,.11); --snav-hover:rgba(19,32,56,.05);
    --snav-accent:#3f6b00; --snav-accent-bg:rgba(63,107,0,.12);
    --snav-search-bg:rgba(19,32,56,.04);
  }
}
:root[data-theme="light"] .snav{
  --snav-bg:#f5f8fc; --snav-fg:#17233b; --snav-dim:#5a6b86; --snav-faint:#5f6f88;
  --snav-line:rgba(19,32,56,.11); --snav-hover:rgba(19,32,56,.05);
  --snav-accent:#3f6b00; --snav-accent-bg:rgba(63,107,0,.12);
  --snav-search-bg:rgba(19,32,56,.04);
}
.snav a,.snav summary,.snav button{color:var(--snav-fg); text-decoration:none}
.snav a:hover{text-decoration:none}

.sprof{display:flex; align-items:center; gap:10px; padding:6px 6px 12px;
  border-bottom:1px solid var(--snav-line); margin-bottom:8px}
.savatar{flex:none; width:34px; height:34px; border-radius:50%; display:grid; place-items:center;
  background:var(--snav-accent-bg); border:1px solid var(--snav-accent); color:var(--snav-accent);
  font-weight:600; font-size:.78rem; letter-spacing:.03em}
.spname{font-size:.86rem; font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:128px}
.spsub{font-size:.66rem; color:var(--snav-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:128px}
.themebtn{margin-left:auto; flex:none; background:transparent; border:1px solid var(--snav-line);
  color:var(--snav-fg); width:32px; height:32px; border-radius:9px; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; padding:0; line-height:0}
.themebtn:hover{border-color:var(--snav-accent); color:var(--snav-accent)}
.themebtn svg{width:17px; height:17px}
.themebtn .sun{display:none}
@media (prefers-color-scheme: light){
  :root:not([data-theme="dark"]) .themebtn .moon{display:none}
  :root:not([data-theme="dark"]) .themebtn .sun{display:block}
}
:root[data-theme="light"] .themebtn .moon{display:none}
:root[data-theme="light"] .themebtn .sun{display:block}
:root[data-theme="dark"] .themebtn .moon{display:block}
:root[data-theme="dark"] .themebtn .sun{display:none}

.ssearch{display:flex; align-items:center; gap:8px; width:100%; padding:8px 10px; margin:0 0 10px;
  border-radius:9px; border:1px solid var(--snav-line); background:var(--snav-search-bg);
  color:var(--snav-dim); font-size:.8rem; cursor:pointer; font-family:inherit; text-align:left;
  transition:border-color .15s,color .15s}
.ssearch:hover{border-color:var(--snav-accent); color:var(--snav-fg)}
.ssearch svg{width:15px; height:15px; flex:none}
.ssearch kbd{margin-left:auto; font-family:ui-monospace,Menlo,monospace; font-size:.62rem;
  border:1px solid var(--snav-line); border-radius:4px; padding:1px 5px; color:var(--snav-faint)}

.sgl{font-family:ui-monospace,Menlo,monospace; font-size:.6rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--snav-faint); padding:12px 8px 4px; margin:0}
.srow{display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:9px;
  font-size:.85rem; cursor:pointer; border:none; background:transparent; width:100%;
  font-family:inherit; text-align:left; color:var(--snav-fg)}
.srow:hover{background:var(--snav-hover)}
.srow.on{background:var(--snav-accent-bg); color:var(--snav-accent); font-weight:500}
.srow.on svg{color:var(--snav-accent)}
.srow svg{width:17px; height:17px; flex:none; color:var(--snav-dim)}
.srow .cnt{margin-left:auto; font-size:.66rem; font-variant-numeric:tabular-nums;
  background:var(--snav-hover); color:var(--snav-dim); border-radius:20px; padding:1px 7px}
.srow.on .cnt{background:transparent; color:var(--snav-accent)}
.srow .cnt.alert{background:var(--over-bg); color:var(--over)}

details.sgroup>summary{list-style:none; display:flex; align-items:center; gap:10px;
  padding:8px 10px; border-radius:9px; font-size:.85rem; cursor:pointer; user-select:none}
details.sgroup>summary::-webkit-details-marker{display:none}
details.sgroup>summary:hover{background:var(--snav-hover)}
details.sgroup>summary svg.ic{width:17px; height:17px; flex:none; color:var(--snav-dim)}
.chev{margin-left:auto; flex:none; width:7px; height:7px;
  border-right:1.6px solid var(--snav-dim); border-bottom:1.6px solid var(--snav-dim);
  transform:rotate(-45deg); transition:transform .15s}
details.sgroup[open]>summary .chev{transform:rotate(45deg)}
.schild{display:flex; align-items:center; gap:8px; padding:6px 10px 6px 38px; font-size:.8rem;
  color:var(--snav-dim); border-radius:8px; cursor:pointer; border:none; background:transparent;
  width:100%; font-family:inherit; text-align:left}
.schild:hover{color:var(--snav-fg); background:var(--snav-hover)}
.schild.on{color:var(--snav-accent); background:var(--snav-accent-bg); font-weight:500}
.schild .cnt{margin-left:auto; font-size:.64rem; font-variant-numeric:tabular-nums; color:var(--snav-faint)}

.pill-soon{font-size:.55rem; letter-spacing:.08em; text-transform:uppercase; font-weight:600;
  border:1px solid var(--snav-line); color:var(--snav-faint); border-radius:20px; padding:1px 6px; margin-left:auto}
.sfoot{margin-top:auto; padding-top:10px; border-top:1px solid var(--snav-line)}
.sfoot .srow{font-size:.78rem; color:var(--snav-dim); padding:6px 10px}
.sfoot .srow svg{width:15px; height:15px}

/* ---------- Main column ---------- */
.mtop{display:none}
.wrap{max-width:1240px; margin:0 auto; padding:26px 24px 60px; width:100%}
.phead{display:flex; align-items:flex-start; gap:16px; flex-wrap:wrap; margin-bottom:6px}
.phead h1{font-size:1.4rem}
.phead .sub{color:var(--muted); font-size:.88rem; margin-top:3px}
.phead .acts{margin-left:auto; display:flex; gap:8px; flex-wrap:wrap}

.btn{display:inline-flex; align-items:center; gap:7px; background:var(--green-btn); color:var(--btn-ink);
  font-weight:600; padding:8px 16px; border-radius:9px; border:none; cursor:pointer;
  font-family:inherit; font-size:.85rem; text-decoration:none;
  transition:filter .15s ease, transform .07s ease}
.btn:hover{filter:brightness(1.07); text-decoration:none}
.btn:active{transform:translateY(1px) scale(.99)}
.btn svg{width:15px; height:15px}
.btn.ghost{background:transparent; color:var(--off); border:1px solid var(--line)}
.btn.ghost:hover{background:var(--hover); border-color:var(--muted); filter:none}
.btn.sm{padding:5px 11px; font-size:.78rem}

.card{background:var(--glass); border:1px solid var(--line); border-radius:var(--radius); padding:18px}
.card h3{font-size:.98rem; margin-bottom:2px}
.card .ch{display:flex; align-items:center; gap:10px; margin-bottom:14px}
.card .ch .more{margin-left:auto; font-size:.78rem}
.card h3 + .csub{color:var(--muted); font-size:.78rem; margin:0 0 14px}

/* Demo-data notice, deliberately prominent. Nobody should ever mistake
   these figures for the real books. */
.demobar{display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  background:var(--info-bg); border:1px solid var(--info); color:var(--off);
  border-radius:11px; padding:10px 14px; font-size:.82rem; margin-bottom:20px}
.demobar b{color:var(--info)}
.demobar svg{width:16px; height:16px; color:var(--info); flex:none}

/* Stat tiles */
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(168px,1fr)); gap:12px; margin-bottom:20px}
.statc{background:var(--glass); border:1px solid var(--line); border-radius:var(--radius);
  padding:14px 16px; display:flex; flex-direction:column; gap:3px; min-width:0}
.statc .l{font-size:.66rem; text-transform:uppercase; letter-spacing:.08em; color:var(--muted)}
.statc .n{font-size:1.5rem; font-weight:600; font-variant-numeric:tabular-nums; line-height:1.15}
.statc .d{font-size:.73rem; color:var(--muted)}
.statc .n.pos{color:var(--ok)} .statc .n.neg{color:var(--over)} .statc .n.warn{color:var(--due)}
.statc .n.brand{color:var(--green)}
.trend{font-size:.7rem; font-weight:600; display:inline-flex; align-items:center; gap:3px}
.trend.up{color:var(--ok)} .trend.down{color:var(--over)}

/* Needs attention */
.needs{display:flex; flex-direction:column; gap:0; background:var(--glass);
  border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; margin-bottom:20px}
.needs .nh{display:flex; align-items:center; gap:9px; padding:12px 16px; border-bottom:1px solid var(--line)}
.needs .nh h3{font-size:.92rem}
.needs .nh .cnt{font-size:.68rem; background:var(--over-bg); color:var(--over);
  border-radius:20px; padding:2px 9px; font-weight:600}
.nitem{display:flex; align-items:center; gap:12px; padding:11px 16px; border-bottom:1px solid var(--line);
  font-size:.86rem; flex-wrap:wrap}
.nitem:last-child{border-bottom:none}
.nitem .dot{width:7px; height:7px; border-radius:50%; flex:none}
.nitem .dot.over{background:var(--over)} .nitem .dot.due{background:var(--due)} .nitem .dot.info{background:var(--info)}
.nitem .nt{min-width:0; flex:1 1 220px}
/* Title and sub-label are separate lines. Without the explicit block they
   butt straight up against each other ("...41 days lateINV-0032..."), which
   reads as a typo rather than two fields. */
.nitem .nt b{display:block; font-weight:500; line-height:1.35}
.nitem .nm{display:block; color:var(--muted); font-size:.75rem}
.nitem .amt{font-variant-numeric:tabular-nums; font-weight:600; white-space:nowrap}
.nitem .amt.over{color:var(--over)} .nitem .amt.due{color:var(--due)}

/* Two column dash */
.dashcols{display:grid; grid-template-columns:minmax(0,1.35fr) minmax(0,1fr); gap:16px; align-items:start}

/* Kanban */
.kboard{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:10px}
.kcol{background:var(--glass); border:1px solid var(--line); border-radius:12px; padding:10px; min-width:0}
.kcol h4{font-size:.72rem; text-transform:uppercase; letter-spacing:.07em; color:var(--muted);
  margin:0 0 3px; display:flex; align-items:center; gap:6px}
.kcol h4 .kn{margin-left:auto; font-variant-numeric:tabular-nums; color:var(--faint)}
.kcol .kv{font-size:.72rem; color:var(--faint); font-variant-numeric:tabular-nums; margin-bottom:9px}
.kcard{background:var(--panel); border:1px solid var(--line); border-radius:10px; padding:10px;
  margin-bottom:8px; cursor:grab}
.kcard:last-child{margin-bottom:0}
.kcard:hover{border-color:var(--green)}
.kcard .kt{font-size:.84rem; font-weight:500; line-height:1.35}
.kcard .km{color:var(--muted); font-size:.71rem; margin-top:3px; display:flex; gap:8px; flex-wrap:wrap}
.kcard .kval{font-variant-numeric:tabular-nums; color:var(--green); font-weight:600}
.kcard.kdrag{opacity:.4}
.kcol.kover{outline:2px dashed var(--green); outline-offset:-3px; background:var(--hover)}

/* Timeline */
.tl{display:flex; flex-direction:column}
.tlrow{display:flex; gap:11px; padding:9px 0; border-bottom:1px solid var(--line); font-size:.84rem}
.tlrow:last-child{border-bottom:none}
.tlic{flex:none; width:26px; height:26px; border-radius:8px; display:grid; place-items:center;
  background:var(--hover); color:var(--muted)}
.tlic svg{width:14px; height:14px}
.tlrow .tt{min-width:0; flex:1}
.tlrow .tt b{display:block; font-weight:500; line-height:1.35}
.tlrow .tm{display:block; color:var(--muted); font-size:.73rem}
.auto{font-size:.58rem; letter-spacing:.06em; text-transform:uppercase; font-weight:600;
  color:var(--green); border:1px solid var(--green); border-radius:20px; padding:0 6px;
  white-space:nowrap; align-self:center}

/* Deadlines */
.dl{display:flex; flex-direction:column}
.dlrow{display:flex; align-items:center; gap:11px; padding:10px 0; border-bottom:1px solid var(--line)}
.dlrow:last-child{border-bottom:none}
.dlwhen{flex:none; width:52px; text-align:center; border-radius:9px; padding:5px 0;
  background:var(--hover); font-variant-numeric:tabular-nums; line-height:1.15}
.dlwhen .d{font-size:1rem; font-weight:600}
.dlwhen .m{font-size:.6rem; text-transform:uppercase; letter-spacing:.06em; color:var(--muted)}
.dlwhen.over{background:var(--over-bg)} .dlwhen.over .d{color:var(--over)}
.dlwhen.due{background:var(--due-bg)} .dlwhen.due .d{color:var(--due)}
.dlrow .dt{min-width:0; flex:1}
.dlrow .dn{display:block; font-size:.85rem}
.dlrow .dm{display:block; color:var(--muted); font-size:.73rem}
.dlrow .damt{font-variant-numeric:tabular-nums; font-size:.85rem; font-weight:600; white-space:nowrap}

/* Tables */
.tblwrap{overflow-x:auto; border:1px solid var(--line); border-radius:var(--radius); background:var(--glass)}
table{border-collapse:collapse; width:100%; font-size:.85rem; min-width:640px}
thead th{text-align:left; font-size:.64rem; text-transform:uppercase; letter-spacing:.08em;
  color:var(--muted); font-weight:600; padding:11px 14px; border-bottom:1px solid var(--line); white-space:nowrap}
tbody td{padding:11px 14px; border-bottom:1px solid var(--line); vertical-align:middle}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover{background:var(--hover)}
td.r,th.r{text-align:right; font-variant-numeric:tabular-nums}
.who{display:flex; align-items:center; gap:9px; min-width:0}
.av{flex:none; width:28px; height:28px; border-radius:50%; display:grid; place-items:center;
  font-size:.68rem; font-weight:600; background:var(--hover); color:var(--muted)}
.wn{min-width:0}
.wn b{font-weight:500; display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.wn span{color:var(--muted); font-size:.73rem}

.chip{display:inline-flex; align-items:center; gap:5px; font-size:.7rem; font-weight:600;
  border-radius:20px; padding:2px 9px; white-space:nowrap; border:1px solid transparent}
.chip.ok{background:var(--ok-bg); color:var(--ok); border-color:var(--ok)}
.chip.due{background:var(--due-bg); color:var(--due); border-color:var(--due)}
.chip.over{background:var(--over-bg); color:var(--over); border-color:var(--over)}
.chip.info{background:var(--info-bg); color:var(--info); border-color:var(--info)}
.chip.n{background:var(--hover); color:var(--muted); border-color:var(--line)}

.src{display:inline-flex; align-items:center; gap:5px; font-size:.7rem; color:var(--muted)}
.src svg{width:12px; height:12px}

/* Filter pills. Used for category tabs above a table.
   Added after the app used this class and got unstyled inline links: the class
   existed in the Construction Metric portal but had never been carried into
   this design system, so it silently did nothing. */
.filter{display:flex; gap:6px; flex-wrap:wrap; align-items:center}
.filter a{font-size:.78rem; padding:5px 12px; border:1px solid var(--line); border-radius:20px;
  color:var(--off); text-transform:capitalize; white-space:nowrap}
.filter a:hover{border-color:var(--muted); text-decoration:none}
.filter a.on{background:var(--glass); border-color:var(--green); color:var(--green); font-weight:500}

/* Bars */
.bar{height:7px; border-radius:20px; background:var(--hover); overflow:hidden; min-width:70px}
/* Bar fills are graphics, not text, so they use the vivid surface token. */
.bar i{display:block; height:100%; border-radius:20px; background:var(--green-btn)}
/* Semantic fills use their own brighter values rather than the text tokens.
   The text amber is dark enough to clear 4.5:1 on a light ground, which makes
   it read as brown in a 7px bar. Contrast minimums do not apply to a graphic,
   so the fill can be the colour people actually recognise as "warning". */
.bar i.over{background:#ef4444} .bar i.due{background:#f59e0b} .bar i.ok{background:#10b981}

/* Section spacing */
.sec{margin-top:24px}
.sec > h2{font-size:1.02rem; margin-bottom:3px}
.sec > .ssub{color:var(--muted); font-size:.82rem; margin:0 0 14px}
.grid2{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:14px}
.grid3{display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:14px}

/* Empty state */
.empty{text-align:center; padding:34px 20px; color:var(--muted)}
.empty svg{width:30px; height:30px; color:var(--faint); margin-bottom:8px}
.empty p{margin:0 0 4px; font-size:.9rem; color:var(--off)}
.empty span{font-size:.8rem}

/* Views */
.view{display:none}
.view.on{display:block}

/* Integrations */
.intg{display:flex; align-items:center; gap:12px; padding:13px 16px; border-bottom:1px solid var(--line)}
.intg:last-child{border-bottom:none}
.intg .ii{flex:none; width:32px; height:32px; border-radius:9px; display:grid; place-items:center;
  background:var(--hover); color:var(--muted); font-size:.7rem; font-weight:600}
.intg .it{flex:1; min-width:0}
.intg .it b{font-weight:500; font-size:.88rem; display:block}
.intg .it > span{display:block; color:var(--muted); font-size:.76rem; line-height:1.45}

.note{background:var(--glass); border:1px solid var(--line); border-left:3px solid var(--green);
  border-radius:0 11px 11px 0; padding:13px 16px; font-size:.84rem; color:var(--muted); margin-top:16px}
.note b{color:var(--off); font-weight:600}

/* Mobile */
.scrim{display:none}
@media(max-width:960px){ .dashcols{grid-template-columns:minmax(0,1fr)} .kboard{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media(max-width:760px){
  .appgrid{display:block}
  .mtop{display:flex; align-items:center; gap:12px; padding:11px 16px; position:sticky; top:0; z-index:70;
    background:var(--navy-deep); border-bottom:1px solid var(--line)}
  .mtop button{background:transparent; border:1px solid var(--line); color:var(--off); border-radius:9px;
    width:36px; height:36px; display:grid; place-items:center; cursor:pointer; padding:0}
  .mtop button svg{width:18px; height:18px}
  .mtop .mt{font-weight:600; font-size:.95rem}
  .snav{position:fixed; inset:0 auto 0 0; width:min(84vw,300px); z-index:80;
    transform:translateX(-100%); visibility:hidden; transition:transform .22s ease, visibility .22s}
  html[data-nav-open] .snav{transform:none; visibility:visible}
  html[data-nav-open] .scrim{display:block; position:fixed; inset:0; z-index:75; background:rgba(0,0,0,.5)}
  html[data-nav-open]{overflow:hidden}
  .wrap{padding:18px 16px 50px}
  .kboard{grid-template-columns:minmax(0,1fr)}
  .stats{grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}
}
@media(prefers-reduced-motion:reduce){*{transition:none !important; animation:none !important}}

/* ---------------------------------------------------------------- upcoming --
   A chip that expands, not a modal that blocks. The single exception is a call
   inside fifteen minutes, which opens itself.
-------------------------------------------------------------------------- */
.calls{position:fixed;right:18px;bottom:18px;z-index:60;max-width:min(340px,calc(100vw - 36px));
  font-size:.85rem}
.calls summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:9px;
  background:var(--panel);border:1px solid var(--line);border-radius:999px;padding:9px 15px 9px 13px;
  box-shadow:0 6px 22px rgba(0,0,0,.22);user-select:none}
.calls summary::-webkit-details-marker{display:none}
.calls summary:hover{border-color:var(--green)}
.calls .cdot{width:8px;height:8px;border-radius:50%;background:var(--green);flex:0 0 auto}
.calls[data-soon="1"] summary{border-color:var(--due);background:var(--due-bg)}
.calls[data-soon="1"] .cdot{background:var(--due);animation:cpulse 1.8s ease-in-out infinite}
@keyframes cpulse{0%,100%{opacity:1}50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){.calls[data-soon="1"] .cdot{animation:none}}
.calls .cpanel{margin-top:9px;background:var(--panel);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 10px 34px rgba(0,0,0,.3);overflow:hidden}
.calls .chd{display:flex;align-items:center;gap:8px;padding:11px 14px;border-bottom:1px solid var(--line)}
.calls .chd b{font-size:.82rem}
.calls .crow{display:block;padding:11px 14px;border-bottom:1px solid var(--line);color:inherit;text-decoration:none}
.calls .crow:last-child{border-bottom:none}
.calls .crow:hover{background:var(--hover)}
.calls .ct{font-weight:500;font-size:.86rem;line-height:1.3}
.calls .cw{color:var(--muted);font-size:.75rem;margin-top:3px;display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.calls .cnow{color:var(--due);font-weight:700}
.calls .cjoin{display:inline-block;margin-top:8px;font-size:.76rem;font-weight:600;
  background:var(--green-btn);color:var(--btn-ink);padding:5px 11px;border-radius:8px;text-decoration:none}
.calls .cempty{padding:16px 14px;color:var(--muted);font-size:.8rem}
@media (max-width:640px){.calls{right:12px;bottom:12px;left:12px;max-width:none}}

/* ------------------------------------------------------- nested clients ----
   One level deeper than the existing groups, kept visually quieter rather than
   just indented.
-------------------------------------------------------------------------- */
details.sgroup.nested{margin-left:0}
details.sgroup.nested>summary{padding-left:34px;font-size:.83rem}
details.sgroup.nested>summary .chev{margin-left:auto}
.schild.deep{padding-left:52px;font-size:.8rem;opacity:.92}
.schild.deep.muted{opacity:.42;cursor:default}
.schild.deep.muted:hover{background:transparent}

/* ------------------------------------------------------------ contact pills
   A rolodex, not a spreadsheet. Letter headers, a jump bar, each person a card
   whose contact routes are tappable on the card itself.
-------------------------------------------------------------------------- */
.abcbar{display:flex;gap:2px;flex-wrap:wrap;margin:0 0 4px}
.abcbar a,.abcbar span{min-width:24px;text-align:center;padding:3px 0;border-radius:7px;
  font-size:.74rem;font-weight:700}
.abcbar a{color:var(--green);text-decoration:none}
.abcbar a:hover{background:var(--hover)}
.abcbar span{color:var(--muted);opacity:.35}
.abchead{font-size:.78rem;font-weight:800;letter-spacing:.08em;color:var(--green);
  margin:0 0 8px;padding-bottom:5px;border-bottom:1px solid var(--line)}
.pgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:10px}
.pcard{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--line);
  border-radius:14px;padding:11px 13px;background:var(--panel)}
.pcard:hover{border-color:var(--green)}
.pacts{display:flex;gap:6px;flex-wrap:wrap;margin-top:7px}
.pact{display:inline-block;font-size:.72rem;padding:3px 10px;border:1px solid var(--line);
  border-radius:999px;background:var(--glass);color:var(--off);text-decoration:none;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pact:hover{border-color:var(--green);color:var(--green)}
