/* CNJ Dashboard — implementation of claude_design project 0735fbda (CNJ Dashboard.dc.html). */
*{box-sizing:border-box}
:root{
  /* Legacy names, aliased onto the Dispatch tokens (cnj-tokens.css). */
  --ln:var(--line);--ln2:var(--line-strong);
  --tx:var(--fg);--tx2:var(--fg-2);--tx3:var(--fg-3);
  --ac:var(--accent-text);--acs:var(--accent-wash);
  --ok:var(--ok);--wr:var(--accent-text);--er:var(--crit);--bl:var(--info);
  --mono:var(--font-mono);
}
html,body{margin:0;padding:0;background:var(--bg)}
body{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-family:var(--font-text);color:var(--tx);font-size:14px;line-height:1.42;min-height:100vh}
a{color:var(--ac);text-decoration:none}
a:hover{color:#ffa46e}
input,button{font-family:inherit;color:inherit}
input:focus,button:focus{outline:none}
input::placeholder{color:#55555e}
button{cursor:pointer;border:0;background:none;padding:0}
[hidden]{display:none!important}
::selection{background:rgba(255,122,47,.28)}
::-webkit-scrollbar{width:8px;height:6px}
::-webkit-scrollbar-thumb{background:#2b2b32;border-radius:0}
::-webkit-scrollbar-track{background:transparent}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes fadeUp{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}

.mono{font-family:var(--mono)}
.eyebrow{font-family:var(--mono);font-size:9px;letter-spacing:.11em;text-transform:uppercase;color:var(--tx3)}

/* ---------- login ---------- */
.login{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}
.login-inner{width:100%;max-width:340px;animation:fadeUp .25s ease}
.login-brand{display:flex;align-items:center;gap:10px;margin-bottom:18px}
.brand-mark{width:30px;height:30px;border-radius:0;background:var(--ac);color:var(--accent-ink);display:grid;place-items:center;font-size:11px;font-weight:800;letter-spacing:.02em}
.login-brand b{font-size:15px;font-weight:700;letter-spacing:-.01em}
.login-card{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:20px;box-shadow:0 20px 50px -30px #000}
.login-card h1{font-size:14.5px;font-weight:700;margin:0 0 4px}
.login-card .sub{font-size:12.5px;color:var(--tx2);margin:0 0 16px}
.login-card .eyebrow{font-size:9.5px;margin-bottom:6px}
.login-card input{width:100%;height:38px;background:var(--bg);border:1px solid var(--ln2);border-radius:0;padding:0 11px;font-size:13.5px;transition:border-color .15s,box-shadow .15s}
.login-card input:focus{border-color:var(--ac);outline:2px solid var(--focus);outline-offset:-1px}
.login-err{display:flex;align-items:center;gap:6px;margin-top:9px;font-size:12px;color:var(--er)}
.login-err i{width:5px;height:5px;border-radius:0;background:var(--er)}
.login-card button{width:100%;height:38px;margin-top:14px;border-radius:0;background:var(--ac);color:var(--accent-ink);font-size:13.5px;font-weight:700;transition:filter .15s,transform .1s}
.login-card button:hover{filter:brightness(1.08)}
.login-card button:active{transform:scale(.99)}

/* ---------- header ---------- */
#refresh{width:32px;height:32px;border-radius:0;border:1px solid var(--ln2);background:var(--surface);display:grid;place-items:center;color:var(--tx2);transition:color .15s,background .15s}
#refresh:hover{color:var(--tx);background:var(--surface-3)}
#refresh svg.spin{animation:spin .62s linear}

/* ---------- period bar ---------- */
.range-label{font-family:var(--mono);font-size:10px;color:var(--tx3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

main.shell{padding-top:14px;padding-bottom:90px}
.view{animation:fadeUp .2s ease}

/* ---------- shared bits ---------- */
.card{background:var(--surface);border:1px solid var(--ln);border-radius:0}
.pill{display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 8px;border-radius:0;font-size:11px;font-weight:600;white-space:nowrap}
.pill.ok{color:var(--ok);background:rgba(62,207,142,.13)}
.pill.wr{color:var(--wr);background:rgba(240,178,63,.13)}
.pill.mu{color:#8b8b93;background:rgba(139,139,147,.14)}
.pill.er{color:var(--er);background:rgba(242,85,90,.13)}
.pill.bl{color:var(--bl);background:rgba(91,156,255,.13)}
.pill.ac{color:var(--ac);background:var(--acs)}
.sec-head{display:flex;align-items:baseline;justify-content:space-between;margin:16px 2px 8px;gap:10px}
.sec-head .t{font-size:12.5px;font-weight:700}
.sec-head .s{font-family:var(--mono);font-size:10px;color:var(--tx3)}
.empty-card{padding:44px 20px;text-align:center}
.empty-ic{width:34px;height:34px;border-radius:0;border:1px solid var(--ln2);display:grid;place-items:center;margin:0 auto 11px;color:var(--tx3)}
.empty-ic.ok{border-color:var(--ok);color:var(--ok)}
.empty-t{font-size:13px;font-weight:600}
.empty-s{font-size:12px;color:var(--tx3);margin-top:3px}
.btn-ghost{margin-top:13px;height:31px;padding:0 13px;border-radius:0;border:1px solid var(--ln2);background:var(--surface-2);font-size:12.5px;font-weight:600;color:var(--tx);transition:border-color .15s,color .15s}
.btn-ghost:hover{border-color:var(--ac);color:var(--ac)}

/* ---------- KPI cards ---------- */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(138px,1fr));gap:8px}
.kpi{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:11px 12px 10px}
.kpi .v{font-size:23px;font-weight:700;letter-spacing:-.02em;margin-top:5px;font-variant-numeric:tabular-nums}
.kpi .d-row{display:flex;align-items:center;gap:5px;margin-top:5px}
.kpi .delta{font-family:var(--mono);font-size:10px;font-weight:700}
.kpi .delta.good{color:var(--ok)}
.kpi .delta.bad{color:var(--er)}
.kpi .d-sub{font-size:10.5px;color:var(--tx3)}

/* ---------- chart ---------- */
.chart-card{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:13px 13px 9px;margin-top:8px;position:relative}
.chart-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.chart-head .t{font-size:12.5px;font-weight:700}
.chart-head .s{font-size:11px;color:var(--tx3);margin-top:2px}
.legend{display:flex;gap:11px;font-family:var(--mono);font-size:9.5px;color:var(--tx2)}
.legend span{display:flex;align-items:center;gap:5px}
.legend i{width:7px;height:7px;border-radius:0;display:block}
#chart-wrap{position:relative}
#chart-wrap svg{display:block;overflow:visible}
#chart-wrap svg text{fill:var(--fg-3);font-family:var(--mono)}
.bar-g rect.seg{transition:opacity .12s}
svg.hovering .bar-g:not(.hot) rect.seg{opacity:.32}
.tip{position:absolute;top:0;min-width:132px;background:var(--surface-3);border:1px solid var(--ln2);border-radius:0;padding:8px 9px;pointer-events:none;box-shadow:0 12px 30px -12px #000;z-index:5}
.tip .tl{font-family:var(--mono);font-size:9.5px;color:var(--tx3);margin-bottom:5px}
.tip .tr{display:flex;align-items:center;gap:6px;font-size:11.5px}
.tip .tr+.tr{margin-top:3px}
.tip .tr i{width:6px;height:6px;border-radius:0;display:block}
.tip .tr b{margin-left:auto;font-variant-numeric:tabular-nums}

/* ---------- site cards ---------- */
.sites{display:grid;grid-template-columns:repeat(auto-fill,minmax(228px,1fr));gap:8px}
.site-card{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:12px;transition:border-color .15s,background .15s,transform .15s}
.site-card:hover{border-color:var(--ln2);background:var(--surface-2);transform:translateY(-1px)}
.site-top{display:flex;align-items:center;gap:7px}
.site-top i{width:6px;height:6px;border-radius:0;flex:0 0 auto;display:block}
.site-top b{font-size:13px;font-weight:700;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}
.site-grade{flex:0 0 auto}
.site-grade .pill{height:18px;font-size:10px;padding:0 6px}
.site-dom{display:block;font-family:var(--mono);font-size:10px;color:var(--tx3);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.site-dom:hover{color:var(--ac)}
.site-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:11px}
.site-stats .n{font-size:15px;font-weight:700;font-variant-numeric:tabular-nums}
.site-stats .l{font-family:var(--mono);font-size:8.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--tx3);margin-top:1px}
.site-hr{height:1px;background:var(--ln);margin:11px -12px 9px}
.site-last{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.site-last i{width:5px;height:5px;border-radius:0;flex:0 0 auto;display:block}
.c-ok{color:var(--ok)}.c-wr{color:var(--wr)}.c-er{color:var(--er)}
.bg-ok{background:var(--ok)}.bg-wr{background:var(--wr)}.bg-er{background:var(--er)}.bg-bl{background:var(--bl)}.bg-tx3{background:var(--tx3)}

/* ---------- calls ---------- */
.calls-controls{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:10px}
.search{position:relative;flex:1 1 190px;min-width:150px}
.search svg{position:absolute;left:10px;top:50%;transform:translateY(-50%)}
.search input{width:100%;height:34px;background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:0 10px 0 29px;font-size:13px;transition:border-color .15s,box-shadow .15s}
.search input:focus{border-color:var(--ac);outline:2px solid var(--focus);outline-offset:-1px}
.filters{display:flex;gap:4px;flex-wrap:wrap}
.filters button{height:34px;padding:0 11px;border-radius:0;font-size:12.5px;font-weight:500;border:1px solid var(--ln);color:var(--tx2);background:var(--surface);transition:all .15s;white-space:nowrap}
.filters button.on{font-weight:700;border-color:var(--ac);color:var(--ac);background:var(--acs)}
.tbl-card{background:var(--surface);border:1px solid var(--ln);border-radius:0;overflow:hidden}
.tbl-head{display:grid;gap:10px;padding:8px 14px;border-bottom:1px solid var(--ln);background:var(--surface-2);font-family:var(--mono);font-size:9px;letter-spacing:.11em;text-transform:uppercase;color:var(--tx3)}
.grid-calls{grid-template-columns:96px 1fr 150px 108px 66px 66px 40px}
.grid-leads{grid-template-columns:96px 150px 210px 1fr 118px}
.grid-costs{grid-template-columns:1fr 58px 82px 58px 82px 66px 84px 92px;gap:8px}
.blk-btn{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;padding:2px 7px;margin-left:6px;border:1px solid var(--ln);border-radius:0;background:transparent;color:#8a8a92;cursor:pointer;opacity:0;transition:opacity .12s}
.row-wrap:hover .blk-btn{opacity:1}
.blk-btn:hover{color:#ff6b60;border-color:rgba(255,69,58,.4)}
@media (max-width:860px){.blk-btn{opacity:.7}}
.health-strip{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px;margin-bottom:22px}
.health-chip{display:flex;align-items:center;gap:12px;border:1px solid var(--ln);border-radius:0;padding:10px 13px;background:var(--card, rgba(255,255,255,.03))}
.hc-grade{font-family:var(--mono);font-weight:800;font-size:22px;width:34px;height:34px;border-radius:0;display:flex;align-items:center;justify-content:center;flex:0 0 auto}
.g-A .hc-grade{background:rgba(52,199,89,.16);color:#4cd964}
.g-B .hc-grade{background:rgba(10,132,255,.16);color:#64a8ff}
.g-C .hc-grade{background:rgba(255,255,255,.08);color:#c9c9cf}
.g-D .hc-grade{background:rgba(255,159,10,.16);color:#ffb340}
.g-F .hc-grade{background:rgba(255,69,58,.18);color:#ff6b60}
.hc-name{font-weight:700;font-size:13.5px;letter-spacing:-.01em}
.hc-sub{font-family:var(--mono);font-size:11.5px;opacity:.65;margin-top:2px}
.grid-gsc{grid-template-columns:180px 120px 140px 120px 1fr}
.gsc-row{display:grid;grid-template-columns:180px 120px 140px 120px 1fr;gap:10px;align-items:center;padding:var(--rowY) 14px;font-family:var(--mono);font-size:13px}
.gsc-row .m-lab{display:none}
@media (max-width:860px){
  .grid-gsc{display:none}
  .gsc-row{display:flex;flex-wrap:wrap;gap:4px 10px;padding:11px 13px}
  .gsc-row .cell-site{flex:1 1 100%;font-weight:700}
  .gsc-row .m-lab{display:inline;opacity:.55;font-size:11px;text-transform:uppercase;letter-spacing:.04em}
  .gsc-row .cell-contact{flex:1 1 100%}
}
.tr{text-align:right}
.row-wrap{border-bottom:1px solid var(--ln);transition:background .12s}
.row-wrap:hover{background:var(--surface-2)}
.row-wrap:last-child{border-bottom:0}
.call-row{display:grid;grid-template-columns:96px 1fr 150px 108px 66px 66px 40px;gap:10px;align-items:center;padding:var(--rowY) 14px}
.cell-time{font-family:var(--mono);font-size:11px;color:var(--tx3);white-space:nowrap}
.cell-site{font-size:12.5px;color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cell-caller{font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}
.cell-dur{font-family:var(--mono);font-size:11px;color:var(--tx2);text-align:right}
.cell-cost{font-family:var(--mono);font-size:11px;color:var(--tx3);text-align:right}
.play-btn{width:28px;height:28px;border-radius:0;border:1px solid var(--ln2);color:var(--tx2);background:transparent;display:grid;place-items:center;flex:0 0 auto;transition:all .15s;justify-self:end}
.play-btn:hover{color:var(--tx);border-color:var(--tx3)}
.play-btn.playing{border-color:var(--ac);color:var(--ac);background:var(--acs)}
.cell-act{display:flex;gap:6px;justify-content:flex-end;align-items:center}
a.dl-btn{text-decoration:none}
.vm-dl{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border-radius:0;border:1px solid var(--ln2);color:var(--tx2);font-size:12px;font-weight:600;text-decoration:none;transition:all .15s}
.vm-dl:hover{color:var(--tx);border-color:var(--tx3)}
.prog-row{display:flex;align-items:center;gap:9px;padding:0 14px 11px}
.prog-track{flex:1;height:3px;border-radius:0;background:var(--surface-3);overflow:hidden}
.prog-fill{height:100%;background:var(--ac);border-radius:0;width:0%;transition:width .25s linear}
.prog-label{font-family:var(--mono);font-size:10px;color:var(--tx3);white-space:nowrap}
.tbl-foot{padding:9px 14px;font-family:var(--mono);font-size:10px;color:var(--tx3);display:flex;justify-content:space-between;gap:10px}
@media(max-width:859px){
  .tbl-head{display:none}
  .call-row{display:flex;flex-wrap:wrap;align-items:center;gap:5px 9px;padding:11px 13px}
  .call-row .cell-caller{order:1;flex:1 0 100%;font-size:14.5px;font-weight:700;letter-spacing:-.01em}
  .call-row .cell-time{order:2;font-size:10.5px;flex:0 0 auto}
  .call-row .cell-site{order:3;font-size:11px;color:var(--tx3);flex:1 1 auto}
  .call-row .pill{order:4;flex:0 0 auto}
  .call-row .cell-dur{order:5;min-width:34px}
  .call-row .cell-cost{order:6;min-width:44px}
  .call-row .play-btn{order:7}
}

/* ---------- voicemails ---------- */
.vm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:8px}
.vm-card{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:13px;transition:border-color .15s}
.vm-card:hover{border-color:var(--ln2)}
.vm-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.vm-caller{font-size:19px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.vm-meta{display:flex;align-items:center;gap:7px;margin-top:3px;font-size:11.5px;color:var(--tx2);flex-wrap:wrap}
.vm-meta .site{color:var(--tx)}
.vm-meta i{width:3px;height:3px;border-radius:0;background:var(--tx3);display:block}
.vm-player{display:flex;align-items:center;gap:9px;margin-top:11px;background:var(--bg);border:1px solid var(--ln);border-radius:0;padding:8px 10px}
.vm-player .play-btn{width:30px;height:30px;color:var(--tx)}
.wave{flex:1;display:flex;align-items:flex-end;gap:2px;height:20px}
.wave i{flex:1;display:block;border-radius:0;background:var(--ln2);transition:background .2s}
.wave i.lit{background:var(--ac)}
.vm-time{font-family:var(--mono);font-size:10px;color:var(--tx3);white-space:nowrap}
.vm-actions{display:flex;gap:7px;margin-top:10px}
.vm-call{flex:1;height:36px;border-radius:0;background:var(--ac);color:var(--accent-ink);display:flex;align-items:center;justify-content:center;gap:7px;font-size:13px;font-weight:700;transition:filter .15s}
.vm-call:hover{filter:brightness(1.08);color:var(--accent-ink)}
.vm-done{height:36px;padding:0 12px;border-radius:0;border:1px solid var(--ln2);background:var(--surface-2);font-size:12.5px;font-weight:600;color:var(--tx2);transition:color .15s,border-color .15s}
.vm-done:hover{color:var(--ok);border-color:var(--ok)}
.empty-big{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:52px 20px;text-align:center}

/* ---------- leads ---------- */
.lead-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:8px;margin-bottom:10px}
.lead-kpi{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:11px 12px}
.lead-kpi .vrow{display:flex;align-items:baseline;gap:6px;margin-top:5px}
.lead-kpi .v{font-size:22px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.lead-kpi .dot{width:7px;height:7px;border-radius:0}
.lead-kpi .s{font-size:10.5px;color:var(--tx3);margin-top:3px}
.lead-row{display:grid;grid-template-columns:96px 150px 210px 1fr 118px;gap:10px;align-items:center;padding:var(--rowY) 14px}
.cell-who{min-width:0}
.cell-req{font-size:12px;color:var(--tx2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lead-sms{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;margin-left:6px;border:1px solid var(--ln);border-radius:0;padding:1px 6px;color:var(--tx2)}
.lead-sms:hover{color:var(--ac);border-color:var(--ac)}
.lead-status{height:28px;border-radius:0;border:1px solid var(--ln2);background:var(--bg);color:var(--tx);font-size:12px;font-weight:600;padding:0 8px;appearance:none;-webkit-appearance:none;width:100%;color-scheme:dark}
.lead-status.wr{border-color:var(--wr);color:var(--wr)}
.lead-status.ok{border-color:var(--ok);color:var(--ok)}
.lead-status.bl{border-color:var(--bl);color:var(--bl)}
.lead-status.mu{color:var(--tx3)}
.cell-name{font-size:13px;font-weight:600}
.cell-contact{font-size:12px;color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media(max-width:859px){
  .lead-row{display:flex;flex-wrap:wrap;align-items:center;gap:4px 9px;padding:11px 13px}
  .lead-row .cell-who{order:1;flex:1 0 100%}
  .lead-row .cell-name{font-size:14px;font-weight:700;letter-spacing:-.01em}
  .lead-row .cell-time{order:2;font-size:10.5px}
  .lead-row .cell-site{order:3;font-size:11px;color:var(--tx3);flex:1 1 auto}
  .lead-row .cell-req{order:4;flex:1 0 100%;white-space:normal}
  .lead-row .cell-contact{font-size:11.5px}
  .lead-row > div:last-child{order:5;flex:1 0 100%}
}

/* ---------- costs ---------- */
.cost-kpi.accent{background:var(--surface-2);border-color:var(--ln2)}
.cost-kpi.accent .v{color:var(--ac)}
.cost-kpi .v{font-size:21px}
.cost-kpi.big .v{font-size:23px}
.cost-kpi .s{font-size:10.5px;color:var(--tx3);margin-top:3px}
.cost-row{display:grid;grid-template-columns:1fr 58px 82px 58px 82px 66px 84px 92px;gap:8px;align-items:center;padding:var(--rowY) 14px}
.cost-row .name{font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cost-cell{font-family:var(--mono);font-size:11px;color:var(--tx2);text-align:right;font-variant-numeric:tabular-nums}
.cost-total-cell{font-family:var(--mono);font-size:11.5px;font-weight:700;color:var(--tx);text-align:right;font-variant-numeric:tabular-nums}
.cost-foot{display:grid;grid-template-columns:1fr 58px 82px 58px 82px 66px 84px 92px;gap:8px;align-items:center;padding:11px 14px;background:var(--surface-2)}
.cost-foot .name{font-size:12.5px;font-weight:700}
.cost-foot .cost-cell{color:var(--tx);font-weight:700}
.cost-foot .grand{color:var(--ac)}
.cost-note{font-size:11px;color:var(--tx3);margin:9px 2px 0}
@media(max-width:859px){
  .cost-row{display:grid;grid-template-columns:1fr auto;gap:3px 10px;padding:11px 13px}
  .cost-row .name{font-size:13px;font-weight:700;letter-spacing:-.01em}
  .cost-cell{grid-column:1/-1;font-size:10.5px;color:var(--tx3);display:flex;justify-content:space-between;gap:8px}
  .cost-row .cost-total-cell{grid-row:1;grid-column:2;font-size:13px}
  .cost-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 13px}
  .cost-foot .cost-cell{display:none}
  .cost-foot .grand{font-size:13px}
}

/* ---------- routing ---------- */
.route-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(296px,1fr));gap:8px}
.route-card{background:var(--surface);border:1px solid var(--ln);border-radius:0;padding:13px}
.route-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.route-top b{font-size:13px;font-weight:700;letter-spacing:-.01em}
.route-track{font-family:var(--mono);font-size:9.5px;color:var(--tx3)}
.route-fields{display:flex;flex-direction:column;gap:9px;margin-top:11px}
.route-fields .eyebrow{margin-bottom:4px}
.route-fields input{width:100%;height:34px;background:var(--bg);border:1px solid var(--ln);border-radius:0;padding:0 10px;font-size:13px;font-variant-numeric:tabular-nums;transition:border-color .15s,box-shadow .15s}
.route-fields input:focus{border-color:var(--ac);outline:2px solid var(--focus);outline-offset:-1px}
.route-chk{display:flex;align-items:center;gap:9px;margin-top:11px;width:100%;text-align:left;color:var(--tx2)}
.route-chk:hover{color:var(--tx)}
.route-chk .box{width:17px;height:17px;border-radius:0;flex:0 0 auto;display:grid;place-items:center;border:1px solid var(--ln2);background:transparent;color:var(--accent-ink);transition:all .15s}
.route-chk.on .box{border-color:var(--ac);background:var(--ac)}
.route-chk .box svg{opacity:0;transition:opacity .15s}
.route-chk.on .box svg{opacity:1}
.route-chk .lbl{font-size:12.5px}
.route-foot{display:flex;align-items:center;gap:10px;margin-top:12px}
.route-save{height:34px;padding:0 14px;border-radius:0;background:var(--surface-3);border:1px solid var(--ln2);font-size:12.5px;font-weight:700;color:var(--tx);transition:all .15s}
.route-save:hover{border-color:var(--ac);color:var(--ac)}
.route-msg{font-size:11.5px;font-weight:600;opacity:0;transition:opacity .2s}
.route-msg.show{opacity:1}
.route-msg.ok{color:var(--ok)}
.route-msg.bad{color:var(--er)}
.route-sub{margin:0 2px 9px}
.route-sub .t{font-size:12.5px;font-weight:700}
.route-sub .s{font-size:11.5px;color:var(--tx3);margin-top:2px}

/* ---------- schedule ---------- */
.sched-top{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;margin:0 2px 10px}
.sched-top .t{font-size:14px;font-weight:700}
.sched-top .s{font-size:11.5px;color:var(--tx3);margin-top:2px}
.btn-primary{height:34px;padding:0 14px;border-radius:0;background:var(--ac);color:var(--accent-ink);font-size:12.5px;font-weight:700;white-space:nowrap;transition:filter .15s}
.btn-primary:hover{filter:brightness(1.08)}
.btn-primary:disabled{opacity:.55;cursor:default}
.btn-danger{height:34px;padding:0 12px;border-radius:0;border:1px solid rgba(242,85,90,.4);background:transparent;color:var(--er);font-size:12.5px;font-weight:600;margin-left:auto}
.btn-danger:hover{background:rgba(242,85,90,.12)}
.link-btn{font-size:11.5px;font-weight:600;color:var(--ac)}
.link-btn:hover{color:#ffa46e}
.sched-strip{margin-bottom:10px}
.sched-grid{display:grid;grid-template-columns:minmax(0,1fr) 290px;gap:10px;align-items:start}
.sched-main{min-width:0}
.sched-cal-card{padding:12px}
.sched-side{display:flex;flex-direction:column;gap:10px;position:sticky;top:calc(var(--hh,90px) + 10px)}
.side-card{padding:12px}
.side-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.side-head b{font-size:12.5px;font-weight:700}
.badge-n{min-width:18px;height:18px;padding:0 5px;border-radius:0;display:inline-flex;align-items:center;justify-content:center;font-family:var(--mono);font-size:10px;font-weight:700;background:rgba(240,178,63,.16);color:var(--wr)}
.side-help{font-size:11px;color:var(--tx3);margin:5px 0 9px;line-height:1.4}
.side-empty{font-size:11.5px;color:var(--tx3);padding:8px 0 2px}
.us-item{display:flex;align-items:center;gap:8px;padding:8px 8px;border:1px solid var(--ln);border-radius:0;background:var(--bg);margin-bottom:6px;cursor:grab;transition:border-color .15s}
.us-item:hover{border-color:var(--ln2)}
.us-item:active{cursor:grabbing}
.us-main{min-width:0;flex:1}
.us-name{font-size:12.5px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.us-meta{font-size:10.5px;color:var(--tx3);margin-top:2px;font-variant-numeric:tabular-nums}
.us-meta b{color:var(--tx2)}
.us-scope{font-size:11px;color:var(--tx2);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.us-act{display:flex;gap:4px;align-items:center}
.us-go{height:26px;padding:0 9px;border-radius:0;border:1px solid var(--ln2);background:var(--surface-2);font-size:11px;font-weight:700;color:var(--tx)}
.us-go:hover{border-color:var(--ac);color:var(--ac)}
.us-x{width:26px;height:26px;border-radius:0;color:var(--tx3);font-size:16px;line-height:1}
.us-x:hover{color:var(--er)}
.sub-row{display:flex;align-items:center;gap:9px;padding:7px 0;border-bottom:1px solid var(--ln)}
.sub-row:last-child{border-bottom:0}
.sub-row i{width:9px;height:9px;border-radius:0;flex:0 0 auto;display:block}
.sub-row.blocked{opacity:.55}
.sub-main{flex:1;min-width:0}
.sub-name{font-size:12.5px;font-weight:600}
.sub-meta{font-size:10.5px;color:var(--tx3);margin-top:1px}
.sub-meta a{color:var(--tx2)}
.fc-nonbusiness{background:rgba(255,255,255,.025)}
.side-head-r{display:flex;align-items:center;gap:8px;color:var(--tx3)}
.side-head .chev{display:none;transition:transform .15s}
@media(max-width:1023px){
  .sched-grid{grid-template-columns:1fr}
  .sched-side{position:static;order:-1}
  .sched-side .side-card:last-child{display:none}
  #us-head{cursor:pointer;user-select:none}
  .side-head .chev{display:block}
  #us-card.open .chev{transform:rotate(180deg)}
  #us-card:not(.open) .side-help,#us-card:not(.open) #us-list{display:none}
}
@media(max-width:859px){
  .sched-cal-card{padding:8px}
  .sched-strip{grid-template-columns:repeat(3,1fr);gap:6px}
  .sched-strip .kpi{padding:9px 10px 8px}
  .sched-strip .kpi .v{font-size:19px}
  .sched-strip .kpi:nth-child(n+4){display:none}
}

/* FullCalendar theme */
.fc{--fc-border-color:var(--line);--fc-page-bg-color:transparent;--fc-neutral-bg-color:var(--surface-2);--fc-neutral-text-color:var(--fg-2);
  --fc-today-bg-color:var(--accent-wash);--fc-now-indicator-color:var(--accent);
  --fc-button-bg-color:var(--surface-2);--fc-button-border-color:var(--line-strong);--fc-button-text-color:var(--fg);
  --fc-button-hover-bg-color:var(--surface-3);--fc-button-hover-border-color:var(--line-strong);
  --fc-button-active-bg-color:var(--accent);--fc-button-active-border-color:var(--accent);
  --fc-event-border-color:transparent;--fc-list-event-hover-bg-color:var(--surface-3);--fc-highlight-color:var(--accent-wash);
  --fc-more-link-bg-color:var(--surface-3);--fc-more-link-text-color:var(--fg);
  font-size:12.5px}
.fc .fc-toolbar{gap:8px;flex-wrap:wrap}
.fc .fc-toolbar.fc-header-toolbar{margin-bottom:10px}
.fc .fc-toolbar-title{font-size:15px;font-weight:700;letter-spacing:-.01em}
.fc .fc-button{height:30px;padding:0 10px;font-size:12px;font-weight:600;border-radius:0!important;text-transform:none;box-shadow:none!important;display:inline-flex;align-items:center}
.fc .fc-button-primary:not(:disabled).fc-button-active{color:var(--accent-ink);font-weight:700}
.fc .fc-button-group{gap:2px}
.fc .fc-button .fc-icon{font-size:14px}
.fc .fc-col-header-cell-cushion{font-family:var(--mono);font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--tx3);padding:7px 4px}
.fc .fc-daygrid-day-number{font-family:var(--mono);font-size:11px;color:var(--tx2);padding:5px 7px}
.fc .fc-day-today .fc-daygrid-day-number{color:var(--ac);font-weight:700}
.fc .fc-timegrid-slot-label-cushion,.fc .fc-timegrid-axis-cushion{font-family:var(--mono);font-size:10px;color:var(--tx3)}
.fc .fc-timegrid-slot{height:2em}
.fc .fc-event{border-radius:0;padding:0;cursor:pointer;border-width:1px;font-size:11.5px}
.fc .fc-daygrid-event{margin:1px 3px}
.fc-ev{padding:2px 6px;display:flex;flex-direction:column;gap:1px;min-width:0;overflow:hidden;line-height:1.25}
.fc-ev-t{font-family:var(--mono);font-size:9.5px;opacity:.75}
.fc-ev-title{font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fc-ev-sub{font-size:10px;opacity:.8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fc-daygrid-event .fc-ev{flex-direction:row;align-items:center;gap:5px}
.fc-daygrid-event .fc-ev-sub::before{content:'·';margin-right:4px}
/* A site visit is time blocked to go and look, not work booked — drawn hollow so
   it never reads as a job with nobody on it. */
.fc .ev-visit{background:transparent!important;border:1px dotted var(--tx2)!important;opacity:.85}
.fc .ev-visit .fc-ev{color:var(--tx2)}
.fc .ev-unassigned{background:transparent!important;border:1px dashed var(--ac)!important}
.fc .ev-unassigned .fc-ev{color:var(--ac)}
.fc .ev-pending{border-style:dashed!important;opacity:.9}
.fc .ev-done{opacity:.55}
.fc .ev-done .fc-ev-title{text-decoration:line-through}
.fc .ev-manual:not(.ev-unassigned){background:#2a2a31!important;border-color:var(--line-strong)!important}
.fc .ev-manual .fc-ev{color:var(--tx2)}
.fc .fc-list{border-radius:0;overflow:hidden}
.fc .fc-list-day-cushion{background:var(--surface-2)!important;font-size:11.5px;font-weight:700}
.fc .fc-list-event td{padding:9px 10px}
.fc .fc-list-event-time{font-family:var(--mono);font-size:11px;color:var(--tx2);white-space:nowrap}
.fc .fc-list-event-dot{border-width:5px}
.fc .fc-list-event .fc-ev{padding:0}
.fc .fc-list-event.ev-unassigned .fc-list-event-dot{border-color:var(--ac)}
.fc .fc-popover{background:var(--surface-2);border:1px solid var(--ln2);border-radius:0;box-shadow:0 20px 40px -20px #000}
.fc .fc-popover-header{background:var(--surface-3);font-size:11.5px}
.fc .fc-daygrid-more-link{font-size:10.5px;color:var(--tx2)}
.fc .fc-timegrid-now-indicator-line{border-width:1.5px}
.fc a{color:inherit}
@media(max-width:859px){
  .fc .fc-toolbar-title{display:none}
  .fc .fc-button{height:28px;padding:0 8px;font-size:11px}
  .fc .fc-timegrid-slot{height:1.7em}
}

/* drawer */
#sched-drawer{position:fixed;inset:0;z-index:80}
.dr-back{position:absolute;inset:0;background:rgba(0,0,0,.55);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);animation:fadeIn .15s ease}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes slideIn{from{transform:translateX(30px);opacity:0}to{transform:none;opacity:1}}
@keyframes slideUp{from{transform:translateY(30px);opacity:0}to{transform:none;opacity:1}}
.dr-panel{position:absolute;top:0;right:0;bottom:0;width:min(420px,100%);background:var(--surface);border-left:1px solid var(--ln);display:flex;flex-direction:column;animation:slideIn .18s ease;box-shadow:-20px 0 60px -30px #000}
.dr-panel.busy{pointer-events:none;opacity:.7}
.dr-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:16px 16px 12px;border-bottom:1px solid var(--ln)}
.dr-title{font-size:15px;font-weight:700;letter-spacing:-.01em}
.dr-sub{margin-top:5px;display:flex;gap:6px;flex-wrap:wrap}
.dr-close{width:30px;height:30px;border-radius:0;border:1px solid var(--ln2);color:var(--tx2);font-size:18px;line-height:1;display:grid;place-items:center}
.dr-close:hover{color:var(--tx);background:var(--surface-3)}
.dr-body{padding:14px 16px 20px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:11px}
.dr-fld{flex:1;min-width:0}
.dr-fld .eyebrow{margin-bottom:5px}
.dr-fld input,.dr-fld select,.dr-fld textarea{width:100%;height:36px;background:var(--bg);border:1px solid var(--ln2);border-radius:0;padding:0 10px;font-size:13px;color:var(--tx);transition:border-color .15s,box-shadow .15s;color-scheme:dark}
.dr-fld textarea{height:auto;padding:8px 10px;resize:vertical;line-height:1.4;font-family:inherit}
.dr-fld select{appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%239797a2' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:26px}
.dr-fld input:focus,.dr-fld select:focus,.dr-fld textarea:focus{border-color:var(--ac);outline:2px solid var(--focus);outline-offset:-1px;outline:none}
.dr-row{display:flex;gap:9px;align-items:flex-end}
.dr-row>.dr-fld{flex:1}
.dr-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--tx2);cursor:pointer;min-height:36px;white-space:nowrap}
.dr-chk input{accent-color:var(--ac);width:15px;height:15px;margin:0}
.dr-toggles{display:flex;flex-direction:column;gap:2px;padding:6px 0 0;border-top:1px solid var(--ln)}
.dr-toggles .dr-chk{white-space:normal;min-height:30px;line-height:1.3}
.dr-margin{flex:1;padding-bottom:2px}
.dr-margin-v{font-size:15px;font-weight:700;font-variant-numeric:tabular-nums;height:36px;display:flex;align-items:center}
.dr-info{font-size:11.5px;color:var(--tx3);display:flex;flex-direction:column;gap:3px;padding-top:8px;border-top:1px solid var(--ln)}
.dr-desc{white-space:pre-wrap;background:var(--bg);border:1px solid var(--ln);border-radius:0;padding:8px 10px;color:var(--tx2);font-size:11.5px;max-height:160px;overflow:auto;margin-top:4px}
.dr-foot{display:flex;gap:8px;align-items:center;padding-top:6px;flex-wrap:wrap}
.dr-foot .btn-ghost{margin-top:0;height:34px}
.dr-msg{font-size:12px;font-weight:600;opacity:0;transition:opacity .2s;min-height:16px}
.dr-msg.show{opacity:1}
.dr-msg.ok{color:var(--ok)}
.dr-msg.bad{color:var(--er)}
body.drawer-open{overflow:hidden}
@media(max-width:600px){
  .dr-panel{top:auto;left:0;width:100%;max-height:92vh;border-left:0;border-top:1px solid var(--ln2);border-radius:0 0 0;animation:slideUp .2s ease}
  .dr-row{flex-direction:column;align-items:stretch;gap:9px}
  .dr-chk{min-height:auto}
}
#sched-toast{position:fixed;left:50%;bottom:22px;transform:translate(-50%,10px);background:var(--surface-3);border:1px solid var(--ln2);color:var(--tx);padding:9px 14px;border-radius:0;font-size:12.5px;font-weight:600;box-shadow:0 20px 40px -20px #000;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:90;max-width:min(92vw,520px);text-align:center}
#sched-toast.show{opacity:1;transform:translate(-50%,0)}
#sched-toast.bad{border-color:rgba(242,85,90,.5);color:#ff8a8e}

/* ---------- money ---------- */
.money-top{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;margin:0 2px 10px;flex-wrap:wrap}
.month-nav{display:flex;align-items:center;gap:6px}
.month-nav b{font-size:16px;font-weight:800;letter-spacing:-.01em;min-width:150px;text-align:center}
.month-nav button{width:30px;height:30px;border-radius:0;border:1px solid var(--ln2);background:var(--surface);color:var(--tx2);font-size:18px;line-height:1}
.month-nav button:hover:not(:disabled){color:var(--tx);border-color:var(--tx3)}
.month-nav button:disabled{opacity:.35;cursor:default}
.money-sub{font-size:11.5px;color:var(--tx3)}
.money-kpis .kpi .v{font-size:21px}
.goal-bar{position:relative;height:6px;border-radius:0;background:var(--surface-3);margin:8px 2px 14px;overflow:visible}
.goal-bar i{display:block;height:100%;border-radius:0;background:var(--ac)}
.goal-today{position:absolute;top:-4px;width:2px;height:14px;background:var(--tx2);border-radius:0}
.money-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:10px;margin-top:10px}
.money-card{padding:13px 14px}
.mc-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:8px}
.mc-head b{font-size:12.5px;font-weight:700}
.mc-head .s{font-family:var(--mono);font-size:10px;color:var(--tx3)}
.split-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.split-v{font-size:22px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums;margin-top:4px}
.split-s{font-size:11px;color:var(--tx3);margin-top:3px}
.payee-row{display:grid;grid-template-columns:1fr auto auto;gap:10px;align-items:center;padding:7px 0;border-bottom:1px solid var(--ln);font-size:12.5px}
.payee-row:last-child{border-bottom:0}
.payee-row .mono{font-variant-numeric:tabular-nums;font-size:12px}
.grid-jobs{grid-template-columns:52px 1fr 76px 66px 66px 110px 92px 120px}
.job-row{display:grid;grid-template-columns:52px 1fr 76px 66px 66px 110px 92px 120px;gap:10px;align-items:center;padding:var(--rowY) 14px}
.job-row .mono{font-size:12px;font-variant-numeric:tabular-nums}
.job-row .blk-btn{opacity:.7;margin-left:0}
.owed-row{display:grid;grid-template-columns:1fr 50px 110px auto;gap:10px;align-items:center;padding:var(--rowY) 14px}
.mm-panel{position:absolute;left:50%;top:14vh;transform:translateX(-50%);width:min(420px,94vw);background:var(--surface);border:1px solid var(--ln2);border-radius:0;box-shadow:0 30px 60px -30px #000;animation:slideUp .18s ease}
#money-modal{position:fixed;inset:0;z-index:85}
#money-modal .dr-body{gap:10px}
@media(max-width:859px){
  .split-row{grid-template-columns:1fr 1fr}
  .job-row{display:flex;flex-wrap:wrap;gap:4px 10px;padding:11px 13px}
  .job-row .cell-who{flex:1 0 100%}
  .job-row .cell-time{order:-1;flex:0 0 100%;font-size:10.5px}
  .job-row .mono{font-size:11.5px}
  .job-row .cell-act{flex:1 0 100%;justify-content:flex-start}
  .owed-row{grid-template-columns:1fr auto;gap:4px 10px}
  .owed-row > div:nth-child(2){display:none}
}

/* ---------- today ---------- */
.today-head{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;margin:0 2px 10px;flex-wrap:wrap}
.today-head .t{font-size:18px;font-weight:800;letter-spacing:-.02em}
.today-head .s{margin-top:5px;display:flex;gap:6px;flex-wrap:wrap}
.today-kpis .kpi .v{font-size:21px}
.today-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px;align-items:start}
.today-col{display:flex;flex-direction:column;gap:10px;min-width:0}
.today-card{padding:13px 14px}
.tj-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:9px 0;border-bottom:1px solid var(--ln);color:var(--tx)}
.tj-row:last-child{border-bottom:0}
.tj-row:hover .tj-main b{color:var(--ac)}
.tj-time{font-family:var(--mono);font-size:11px;color:var(--tx3);width:64px;flex:0 0 auto}
.tj-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.tj-main b{font-size:13.5px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tj-addr{font-size:11.5px;color:var(--tx3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tj-right{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.tj-right .mono{font-size:12px;font-variant-numeric:tabular-nums;color:var(--tx2)}
.tw-row{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--ln)}
.tw-row:last-child{border-bottom:0}
.tw-main{flex:1;min-width:0}
.tw-main b{font-size:13px;font-weight:700}
.tw-body{font-size:11.5px;color:var(--tx3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tw-right{display:flex;align-items:center;gap:6px;flex:0 0 auto}
.tw-right .mono{font-size:12px;font-variant-numeric:tabular-nums}
.tw-right .us-x{font-size:13px;color:var(--ok)}
.tw-right a.us-go{text-decoration:none;display:inline-flex;align-items:center}
@media(max-width:859px){
  .today-grid{grid-template-columns:1fr}
  .today-kpis{grid-template-columns:repeat(3,1fr);gap:6px}
  .today-kpis .kpi{padding:9px 10px 8px}
  .today-kpis .kpi .v{font-size:19px}
  .tj-time{width:52px}
  .tw-body{white-space:normal}
}

/* ---------- grouped nav + bottom bar ---------- */
.more-sheet{display:none}
@media(max-width:859px){
  main.shell{padding-bottom:96px}
  .more-sheet{display:block;position:fixed;inset:0;z-index:70}
  .more-back{position:absolute;inset:0;background:rgba(0,0,0,.5)}
  .more-panel{position:absolute;left:0;right:0;bottom:0;background:var(--surface);border-top:1px solid var(--ln2);border-radius:0 0 0;padding:14px 14px calc(70px + env(safe-area-inset-bottom));display:flex;flex-wrap:wrap;gap:8px;animation:slideUp .18s ease}
  .more-panel .eyebrow{flex:1 0 100%}
  .more-panel button{height:38px;padding:0 14px;border-radius:0;border:1px solid var(--ln2);background:var(--surface-2);font-size:13px;font-weight:600;color:var(--tx)}
}
/* ---------- pipeline board ---------- */
.board{display:flex;gap:10px;overflow-x:auto;padding-bottom:8px;align-items:flex-start;scroll-snap-type:x proximity}
.bcol{flex:0 0 268px;width:268px;min-width:0;background:var(--surface);border:1px solid var(--ln);border-radius:0;scroll-snap-align:start;max-height:78vh;display:flex;flex-direction:column}
.bcol-body,.pcard,.pcard>*{min-width:0}
.pc-top{min-width:0}
.pc-top b{min-width:0;flex:1}
.bcol.closed{opacity:.8}
.bcol-head{display:flex;justify-content:space-between;align-items:baseline;padding:10px 12px;border-bottom:1px solid var(--ln);position:sticky;top:0;background:var(--surface-2);border-radius:0 0 0}
.bcol-head b{font-size:12.5px;font-weight:700}
.bcol-head .s{font-family:var(--mono);font-size:10px;color:var(--tx3)}
.bcol-body{overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:8px}
.pcard{background:var(--bg);border:1px solid var(--ln);border-radius:0;padding:10px 11px;display:flex;flex-direction:column;gap:5px}
.pcard:hover{border-color:var(--ln2)}
.pc-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.pc-top b{font-size:13px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pc-top .mono{font-size:12px;font-variant-numeric:tabular-nums;color:var(--ac)}
.pc-sub{font-size:11px;color:var(--tx3)}
.pc-scope{font-size:12px;color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pc-last{font-size:11.5px;color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pc-last i{font-style:normal;color:var(--tx3);font-family:var(--mono)}
.pc-pills{display:flex;gap:4px;flex-wrap:wrap}
.pc-pills .pill{height:18px;font-size:10px;padding:0 6px}
.pc-foot{display:flex;justify-content:space-between;align-items:center;gap:6px;margin-top:2px}
.pc-act{display:flex;gap:4px;align-items:center}
.pc-act .lead-sms{margin-left:0;cursor:pointer}
/* job drawer (2026-08-27) */
#job-drawer{position:fixed;inset:0;z-index:80}
.pcard[data-id]{cursor:pointer}
.jd-q{font-weight:600;color:var(--ac);font-variant-numeric:tabular-nums;margin-left:6px;font-size:14px}
.jd-label{font-size:12px;color:var(--tx3);margin-top:3px;line-height:1.35}
.jd-stmt{display:flex;flex-direction:column;gap:2px;font-size:12.5px}
.st-row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:3px 0}
.st-row .st-l{min-width:0;color:var(--tx2);display:flex;gap:6px;align-items:baseline;flex-wrap:wrap}
.st-row .st-l i{font-style:normal;color:var(--tx3);font-size:11px}
.st-row .st-n{font-variant-numeric:tabular-nums;white-space:nowrap}
.st-row.st-top .st-l,.st-row.st-top .st-n{font-weight:700;color:var(--tx);font-size:13.5px}
.st-row.st-total{border-top:1px solid var(--ln);margin-top:3px;padding-top:6px}
.st-row.st-total .st-l,.st-row.st-total .st-n{font-weight:700;color:inherit}
.st-row.st-total .st-l{color:var(--tx)}
.st-group{font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);margin-top:8px}
.st-group i{font-style:normal;letter-spacing:0;text-transform:none;font-family:inherit}
.job-row[data-job]{cursor:pointer}
.job-row[data-job]:hover{background:var(--surface-2)}
.jd-phone{font-family:var(--mono);font-size:11.5px;color:var(--tx2);margin-right:2px}
.jd-phone:hover{color:var(--tx);text-decoration:underline}
.jd{gap:0;padding:0}
.jd-sec{padding:14px 16px;border-bottom:1px solid var(--ln);display:flex;flex-direction:column;gap:8px}
.jd-sec>.eyebrow{margin-bottom:2px}
.jd .dr-row{display:flex;gap:8px}
.jd .dr-foot{padding-top:4px;border-top:0}
.jd .dr-foot .stage-sel{height:34px;padding:0 8px}
.jd .dr-foot .btn-ghost{margin-top:0;height:34px}
.pc-money{display:flex;gap:18px;font-variant-numeric:tabular-nums}
.pc-money b{font-size:15px;font-weight:700}
.pc-money b.due{color:var(--wr)}
.pc-money .l{display:block;font-family:var(--mono);font-size:8.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--tx3);margin-bottom:1px}
.pc-x-btns{display:flex;gap:6px;flex-wrap:wrap;margin-top:2px}
.pc-x-btns .btn-ghost{margin-top:0;height:32px}
.pc-note{font-size:12px;color:var(--tx3);line-height:1.45}
.pc-tl{display:flex;flex-direction:column;gap:4px;font-size:12px}
.pc-tl>div{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.pc-tl b{min-width:64px;font-weight:700}
.pc-tl i{font-style:normal;font-family:var(--mono);font-size:10.5px;color:var(--tx3)}
.pc-tl span{color:var(--tx3);flex-basis:100%;padding-left:72px;font-size:11.5px}
.pc-rows{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--tx2)}
.pc-rows .mono{color:var(--tx);font-variant-numeric:tabular-nums;font-family:var(--mono);font-size:11.5px}
.pc-other{display:flex;flex-direction:column;gap:4px;margin-top:2px}
.pc-jump{text-align:left;font-size:12px;color:var(--bl);background:none;border:0;padding:0;cursor:pointer}
.pc-jump:hover{text-decoration:underline}
.stage-sel{height:24px;border-radius:0;border:1px solid var(--ln2);background:var(--surface-2);color:var(--tx2);font-size:11px;font-weight:600;padding:0 6px;appearance:none;-webkit-appearance:none;color-scheme:dark}
@media(max-width:859px){
  .board{flex-direction:column;overflow:visible}
  .bcol{flex:1 1 auto;max-height:none}
  .bcol-body{max-height:60vh}
}
/* ---------- crew ---------- */
.crew-card.blocked{opacity:.7}
.crew-meta{font-size:12.5px;color:var(--tx2);margin-top:6px}
.crew-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:10px}
.crew-stats .n{font-size:16px;font-weight:700;font-variant-numeric:tabular-nums}
.crew-stats .l{font-family:var(--mono);font-size:8.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--tx3);margin-top:1px}
.crew-pills{display:flex;gap:4px;flex-wrap:wrap;margin-top:10px}
.crew-notes{font-size:11.5px;color:var(--tx3);margin-top:9px;line-height:1.4;max-height:70px;overflow:hidden}

.fc .ev-subdone{box-shadow:inset 0 0 0 2px var(--ok)}

/* availability */
.fc-off{display:flex;flex-wrap:wrap;gap:2px;margin-top:2px}
.fc-off span{font-family:var(--mono);font-size:8.5px;letter-spacing:.02em;color:var(--er);background:rgba(242,85,90,.12);border-radius:0;padding:0 4px;line-height:14px;white-space:nowrap}
.fc .fc-daygrid-day-top{flex-direction:column;align-items:flex-end}
.fc .fc-daygrid-day-top .fc-daygrid-day-number{display:flex;flex-direction:column;align-items:flex-end}
.fc .fc-col-header-cell-cushion{display:inline-flex;flex-direction:column;align-items:center}
.fc .fc-col-header-cell-cushion .fc-off{justify-content:center}
.crew-avail{font-size:12px;color:var(--tx2);margin-top:10px;display:flex;flex-direction:column;gap:2px}
.crew-avail .eyebrow{font-size:8.5px}

.crew-hist{margin-top:10px;border-top:1px solid var(--ln);padding-top:8px}
.crew-hist summary{cursor:pointer;font-size:12.5px;font-weight:700;color:var(--tx2);list-style:none;display:flex;align-items:center;gap:6px}
.crew-hist summary::before{content:'';width:0;height:0;border:4px solid transparent;border-left:6px solid var(--tx3);transition:transform .15s}
.crew-hist[open] summary::before{transform:rotate(90deg)}
.crew-hist .payee-row{font-size:12px}
.crew-hist .payee-row{grid-template-columns:minmax(0,1fr) auto auto}
.crew-hist .payee-row>span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.crew-hist .payee-row>span:first-child .cell-contact{white-space:nowrap}

.crew-pick{display:flex;flex-direction:column;gap:4px}
.crew-row{display:grid;grid-template-columns:18px 1fr 110px;gap:9px;align-items:center;padding:6px 8px;border:1px solid var(--ln);border-radius:0;background:var(--bg);cursor:pointer}
.crew-row:has(input:checked){border-color:var(--ac)}
.crew-row.dis{opacity:.5;cursor:default}
.crew-row input[type=checkbox]{accent-color:var(--ac);width:15px;height:15px;margin:0}
.crew-name{font-size:13px;font-weight:600;display:flex;flex-direction:column;min-width:0}
.crew-name small{font-size:10.5px;font-weight:500;color:var(--er)}
.crew-pay{height:30px;background:var(--surface-2);border:1px solid var(--ln2);border-radius:0;padding:0 8px;font-size:12.5px;color:var(--tx);width:100%;font-variant-numeric:tabular-nums}
.crew-pay:disabled{opacity:.35}
.crew-pay:focus{border-color:var(--ac);outline:none}
/* Job vs site visit — the one choice that changes what every schedule action does. */
.kind-pick{display:flex;gap:6px}
.kind-opt{flex:1;display:flex;align-items:center;gap:7px;padding:7px 9px;border:1px solid var(--ln);background:var(--bg);cursor:pointer;font-size:12.5px;font-weight:600}
.kind-opt:has(input:checked){border-color:var(--ac);background:var(--surface-2)}
.kind-opt input{accent-color:var(--ac);width:15px;height:15px;margin:0}
/* The job's people, derived and read-only on the schedule drawer. */
.dr-people{font-size:13px;color:var(--tx);line-height:1.5;padding:7px 9px;background:var(--surface-2);border:1px solid var(--ln)}
.dr-people__acts{margin-top:4px}

/* ---------- workspaces ---------- */
@media(max-width:859px){
}
/* lead manager */
.lead-rec{display:grid;grid-template-columns:230px 1fr auto;gap:10px;align-items:center;padding:var(--rowY) 14px}
.lead-rec.is-new{box-shadow:inset 3px 0 0 var(--wr)}
.lr-top{display:flex;flex-direction:column;gap:4px;align-items:flex-start}
.lr-top .cell-site{font-size:11.5px}
.lr-main{min-width:0}
.lr-main b{font-size:13.5px;font-weight:700}
.lr-snip{font-size:12px;color:var(--tx2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.lr-act{display:flex;gap:5px;align-items:center;flex-wrap:wrap;justify-content:flex-end;max-width:420px}
.lr-act .lead-sms{margin-left:0;cursor:pointer;background:none}
.lr-act .us-go{text-decoration:none;display:inline-flex;align-items:center}
.lr-act .lead-status{width:auto;height:26px;font-size:11px}
.bcol.net{border-color:var(--ac)}
.bcol.net .bcol-head{background:var(--acs)}
@media(max-width:859px){
  .lead-rec{display:flex;flex-direction:column;align-items:stretch;gap:6px;padding:11px 13px}
  .lr-top{flex-direction:row;flex-wrap:wrap;align-items:center}
  .lr-act{justify-content:flex-start;max-width:none}
}

@media(max-width:859px){ .site-chip{display:none} }

.tw-row.held{opacity:.75}

.us-item.us-done{cursor:default;opacity:.85;border-style:dashed}

/* bank */
.bank-row{display:grid;grid-template-columns:1fr 110px auto;gap:10px;align-items:center;padding:9px 0;border-bottom:1px solid var(--ln)}
.bank-row:last-child{border-bottom:0}
.bank-main{min-width:0}.bank-main b{font-size:13px}
.bank-row .mono{font-size:12.5px;font-variant-numeric:tabular-nums;text-align:right}
.bank-act{display:flex;gap:5px;flex-wrap:wrap;justify-content:flex-end}
.bank-act .lead-sms{margin-left:0;cursor:pointer;background:none}
.grid-recon{grid-template-columns:70px repeat(7,1fr)}
.recon-row{display:grid;grid-template-columns:70px repeat(7,1fr);gap:8px;padding:var(--rowY) 14px;font-size:12px}
.bank-pick{display:flex;flex-direction:column;gap:6px;max-height:50vh;overflow:auto}
.bank-job{display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:left;padding:8px 10px;border:1px solid var(--ln);border-radius:0;background:var(--bg);color:var(--tx)}
.bank-job:hover{border-color:var(--ac)}
.bank-job b{font-size:13px}.bank-job span{font-size:11.5px;color:var(--tx3)}
@media(max-width:859px){.bank-row{grid-template-columns:1fr auto}.bank-act{grid-column:1/-1;justify-content:flex-start}.grid-recon{display:none}.recon-row{display:flex;flex-wrap:wrap;gap:4px 10px}.recon-row>div:first-child{flex:1 0 100%;font-weight:700}}

.money-segs{margin:10px 0 2px}
.money-segs button .badge-n{margin-left:6px}

/* Universal list filter (injected above any list with 6+ rows) */
.rowfilter{display:flex;align-items:center;gap:8px;padding:6px 0 8px}
.rowfilter .search{flex:1 1 160px}
.rowfilter .search input{height:30px;font-size:12.5px}
.rowfilter .s{font-family:var(--mono);font-size:11px;color:var(--tx3);white-space:nowrap}
.tbl-card .rowfilter{padding:8px 12px;border-bottom:1px solid var(--ln)}

/* Estimate draft modal */
.est-pre{white-space:pre-wrap;font:12px/1.5 var(--font-text),system-ui,sans-serif;color:var(--tx2);background:var(--surface-2);border:1px solid var(--ln);border-radius:0;padding:10px 12px;max-height:38vh;overflow:auto;margin:0}
.est-ta{width:100%;background:var(--surface-2);border:1px solid var(--ln);border-radius:0;padding:10px 12px;font:13px/1.45 var(--font-text),system-ui,sans-serif;color:var(--tx);resize:vertical}
.est-ta:focus{border-color:var(--ac);outline:2px solid var(--focus);outline-offset:-1px;outline:0}
.pc-pills .est-open{cursor:pointer;border:0}


/* ==========================================================================
   DISPATCH SKIN — the redesign's language applied to the legacy class names.
   Anything below this line wins over the older rules above it.
   ========================================================================== */
body{font:var(--t-body);color:var(--fg);background:var(--bg)}
a:hover{color:var(--info)}
input::placeholder,textarea::placeholder{color:var(--fg-4)}
::-webkit-scrollbar-thumb{background:var(--line-strong)}
.view{animation:none}
.views{padding:var(--s5) var(--s6) var(--s10)}
@media(max-width:700px){.views{padding:var(--s3) var(--s3) calc(var(--s10) + 84px)}}

/* Shell: rail buttons, phone top bar, page header, period bar */
.rail__ibtn{width:26px;height:26px;border:1px solid var(--rail-chip);background:none;color:var(--rail-fg-dim);display:grid;place-items:center;cursor:pointer;font:400 13px/1 var(--font-text)}
.rail__ibtn:hover{color:var(--rail-fg);border-color:var(--rail-fg-mute)}
.rail__foot .stamp{color:var(--rail-fg-mute);font:400 11px/1.4 var(--font-mono);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rail__link .badge{margin-left:auto;font:600 11px/1 var(--font-mono);background:var(--rail-chip);color:var(--rail-fg);padding:3px 6px;border-radius:0;height:auto;min-width:0}
.rail__link .badge.attn{background:var(--accent);color:var(--accent-ink)}
.topbar{display:flex;align-items:center;gap:10px;padding:8px 14px 10px;background:var(--rail);color:var(--rail-fg);position:sticky;top:0;z-index:25;padding-top:calc(8px + var(--safe-t))}
.topbar .rail__mark{width:22px;height:22px;font-size:9px;line-height:22px}
.topbar__ws{display:flex;gap:2px}
.topbar__ws button{display:flex;align-items:center;gap:6px;padding:7px 11px;border:0;background:var(--rail-2);color:var(--rail-fg-dim);font:600 11px/1 var(--font-display);cursor:pointer}
.topbar__ws button[aria-pressed='true']{background:var(--rail-fg);color:var(--rail)}
.topbar__ws .ws__dot{width:6px;height:6px}
.topbar__stamp{color:var(--rail-fg-mute);font:400 10px/1 var(--font-mono)}
.phead{gap:var(--s4)}
.phead__text{min-width:0}
.phead__acts{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;justify-content:flex-end}
.phead__sub:empty{display:none}
@media(max-width:700px){.phead{padding:12px 16px 10px;top:0}.phead__title{font:var(--t-display-sm)}.phead--inv{position:static}}
.period-bar{display:flex;align-items:center;gap:var(--s3);padding:10px var(--s6);background:var(--surface);border-bottom:1px solid var(--line)}
.period-bar[hidden]{display:none}
@media(max-width:700px){.period-bar{padding:10px var(--s4)}.period-bar .stamp{display:none}}
.site-chip{font:var(--t-num-micro);color:var(--fg-3);border:1px solid var(--line);padding:3px 6px}

/* Type roles */
.today-head .t,.sec-head .t,.side-head .t,.chart-head .t,.dr-title,.empty-t,.login-card h1,.month-nav .t{font-family:var(--font-display);letter-spacing:var(--track-tight);font-weight:800}
.eyebrow{font:var(--t-label-sm);letter-spacing:.13em;text-transform:uppercase;color:var(--fg-3)}
.mono,.cell-time,.cell-cost,.cell-dur,.range-label,.updated,.stamp,.kpi .v,.v{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.c-ok{color:var(--ok)}.c-wr{color:var(--accent-text)}.c-er{color:var(--crit)}.c-bl{color:var(--info)}

/* Surfaces: ruled, square, no shadow */
.card,.tbl-card,.money-card,.today-card,.crew-card,.site-card,.route-card,.vm-card,.chart-card,.side-card,.empty-card,.lead-kpi,.cost-kpi,.sched-cal-card,.hc-name,.tip,.mm-panel,.dr-panel,.more-panel{background:var(--surface);border:1px solid var(--line);border-radius:0;box-shadow:none}
.card{padding:0}
.card>.mc-head:first-child,.money-card>.mc-head:first-child,.today-card>.mc-head:first-child{margin:0}
.mc-head,.side-head{display:flex;align-items:center;gap:var(--s2);padding:9px var(--s4);background:var(--surface-3);border-bottom:1px solid var(--line);font:var(--t-label-sm);letter-spacing:.13em;text-transform:uppercase;color:var(--fg-2);margin:0}
.mc-head b,.side-head .t{font:inherit;letter-spacing:inherit;text-transform:inherit}
.mc-head .s,.side-head .s,.side-head-r{margin-left:auto;font:500 11px/1 var(--font-mono);color:var(--fg-3);letter-spacing:0;text-transform:none}
.mc-head .link-btn{margin-left:auto;letter-spacing:0;text-transform:none}
.card>.side-empty,.card>.cost-note,.card>.tw-row,.card>.payee-row,.card>.bank-row,.card>.d-row{margin:0}
.side-empty,.empty-s,.cost-note{color:var(--fg-3);font:var(--t-meta)}
.side-empty{padding:14px var(--s4)}
.empty-card{padding:var(--s10) var(--s5);text-align:center}
.empty-t{font:var(--t-h2)}

/* Rows: every row carries a stripe (state classes are stamped by dash.js from the chips inside) */
.tw-row,.d-row,.bank-row,.job-row,.payee-row,.lead-row,.call-row,.recon-row,.sub-row,.us-item,.owed-row,.tj-row,.gsc-row,.cost-row,.crew-row,.hist,.vrow{border-left:3px solid transparent;padding-left:calc(var(--s4) - 3px);padding-right:var(--s4);border-bottom:1px solid var(--line);background:var(--surface);border-radius:0}
.tw-row:last-child,.payee-row:last-child,.bank-row:last-child,.d-row:last-child{border-bottom:0}
.s-attn{border-left-color:var(--accent)!important}.s-ok{border-left-color:var(--ok)!important}.s-crit{border-left-color:var(--crit)!important}.s-info{border-left-color:var(--info)!important}.s-mute{border-left-color:var(--line-strong)!important;background:var(--surface-2)}
.tw-row:hover,.bank-row:hover,.payee-row:hover,.row-wrap:hover,.d-row:hover{background:var(--surface-2)}
.tw-main b,.bank-main b,.cell-name,.us-name,.lr-top b{font:var(--t-row)}
.tw-body,.cell-contact,.us-meta,.lr-snip,.pc-sub,.pc-scope,.pc-last,.d-sub{font:var(--t-meta);color:var(--fg-3)}
.row-wrap{border-left:0}
.tbl-head{background:var(--surface-3);border-bottom:1px solid var(--line);font:var(--t-label-sm);letter-spacing:.13em;text-transform:uppercase;color:var(--fg-2);padding:9px var(--s4)}
.tbl-foot{font:var(--t-num-micro);color:var(--fg-3);padding:10px var(--s4);border-top:1px solid var(--line)}

/* Chips — the whole status vocabulary */
.pill,.pc-pills .pill,.crew-pills .pill,.lead-status{display:inline-flex;align-items:center;gap:5px;height:auto;font:600 9px/1 var(--font-text);letter-spacing:.09em;text-transform:uppercase;padding:4px 6px;border-radius:0;background:var(--mute-wash);color:var(--mute);white-space:nowrap}
.pill.ok{background:var(--ok-wash);color:var(--ok)}
.pill.wr,.pill.ac{background:var(--accent-wash);color:var(--accent-text-2)}
.pill.er{background:var(--crit-wash);color:var(--crit)}
.pill.bl{background:var(--info-wash);color:var(--info)}
.pill.mu{background:var(--mute-wash);color:var(--mute)}
.pill.hermes{background:transparent;border:1px solid var(--line);color:var(--fg-3);font-size:8px;padding:3px 4px}
.badge{font:600 10px/1 var(--font-mono);background:var(--surface-inv);color:var(--on-inv);padding:3px 6px;border-radius:0;height:auto;min-width:0}
.badge-n{font:600 10px/1 var(--font-mono);background:var(--surface-inv);color:var(--on-inv);padding:3px 6px;border-radius:0;margin-left:6px}

/* Buttons: one accent primary per view; bordered secondaries; text ghosts */
.btn-primary,.us-go,.login-card button,.route-save,.play-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);font:var(--t-btn);background:var(--accent);color:var(--accent-ink);border:1px solid transparent;border-radius:0;padding:0 16px;height:40px;cursor:pointer;white-space:nowrap;transition:background var(--dur-1) var(--ease)}
.btn-primary:hover,.us-go:hover{background:var(--accent-dim);color:var(--accent-ink)}
.us-go{height:32px;padding:0 11px;font:var(--t-btn-sm)}
.btn-primary:disabled,.us-go:disabled{background:var(--surface-2);color:var(--fg-4);border-color:var(--line)}
.btn-ghost,.lead-sms,.blk-btn,.bank-act .lead-sms,.stage-sel,.dr-close,.us-x,.vm-actions button{display:inline-flex;align-items:center;justify-content:center;font:600 11px/1 var(--font-display);border:1px solid var(--line-strong);background:var(--surface-2);color:var(--fg-2);border-radius:0;padding:0 10px;height:32px;cursor:pointer;text-transform:none;letter-spacing:0;text-decoration:none;opacity:1}
.btn-ghost:hover,.lead-sms:hover,.blk-btn:hover{background:var(--surface);color:var(--fg);border-color:var(--fg-4)}
.link-btn{border:0;background:none;color:var(--info);font:600 12px/1 var(--font-text);padding:0;height:auto;cursor:pointer}
.link-btn:hover{text-decoration:underline;color:var(--info)}
.btn-danger{background:transparent;color:var(--crit);border:1px solid var(--crit);font:var(--t-btn);height:40px;padding:0 14px;border-radius:0;cursor:pointer}
.btn-danger:hover{background:var(--crit-wash)}
.blk-btn:hover{color:var(--fg)}
.stage-sel{height:32px;padding:0 8px;font:600 11px/1 var(--font-text)}
.row-wrap .blk-btn{opacity:1}

/* Toolbar: search, quick filters, segments */
.calls-controls{gap:var(--s3);margin-bottom:var(--s3)}
.search input{border:1px solid var(--line-strong);background:var(--surface-2);height:38px;border-radius:0;font:400 14px/1 var(--font-text);color:var(--fg);padding-left:30px}
.search input:focus{border-color:var(--focus);outline:2px solid var(--focus);outline-offset:-1px;box-shadow:none;background:var(--surface)}
.filters{display:flex;gap:6px;flex-wrap:wrap}
.filters button,.money-segs button{border:1px solid var(--line-strong);background:var(--surface-2);padding:0 12px;min-height:38px;height:auto;font:600 12px/1 var(--font-text);color:var(--fg-2);border-radius:0;cursor:pointer}
.filters button:hover{background:var(--surface);color:var(--fg)}
.filters button.on,.money-segs button.on{background:var(--surface-inv);color:var(--on-inv);border-color:var(--surface-inv)}
.money-segs{display:flex;gap:0;border-bottom:1px solid var(--line);margin:0 0 var(--s4);flex-wrap:wrap}
.money-segs button{border:0;background:none;min-height:40px;padding:11px 15px 12px;font:var(--t-tab);font-weight:600;color:var(--fg-3);border-radius:0}
.money-segs button.on{background:none;color:var(--fg);font-weight:700;box-shadow:inset 0 -3px 0 var(--accent);border:0}
.money-segs .badge-n{background:var(--surface-inv);color:var(--on-inv)}
/* The bank feed failed. An empty review queue is the success state, so a failure has
   to look different from "clear" rather than identical to it (audit P1-11). */
.badge-n--bad,.money-segs .badge-n--bad{background:var(--crit);color:#fff}
.rowfilter{padding:8px var(--s4);border-bottom:1px solid var(--line);background:var(--surface)}
.rowfilter .search input{height:34px;font-size:13px}

/* KPI strips: context, never the headline */
.kpis,.today-kpis,.money-kpis,.lead-kpis{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:0;border:0;border-top:2px solid var(--line-heavy);border-bottom:1px solid var(--line);background:var(--surface);margin:0 0 var(--s4);overflow-x:auto}
.kpi,.lead-kpi,.cost-kpi{border:0;border-left:1px solid var(--line);border-radius:0;padding:var(--s3) var(--s4);background:var(--surface)}
.kpi:first-child,.lead-kpi:first-child{border-left:0}
.kpi .eyebrow{color:var(--fg-3)}
.kpi .v,.lead-kpi .v,.cost-kpi .v{font:500 21px/1.25 var(--font-mono);font-variant-numeric:tabular-nums;padding-top:5px;color:var(--fg)}
.kpi .v.c-wr{color:var(--accent-text)}.kpi .v.c-ok{color:var(--ok)}.kpi .v.c-er{color:var(--crit)}
.kpi .d-row,.kpi .d-sub{font:var(--t-micro);color:var(--fg-3)}
@media(max-width:700px){.kpis,.today-kpis,.money-kpis,.lead-kpis{grid-auto-columns:minmax(130px,1fr)}}

/* Home: three fixed columns */
.home3{display:grid;grid-template-columns:minmax(300px,1fr) minmax(360px,1.25fr) minmax(280px,.95fr);gap:0;border:1px solid var(--line);background:var(--surface)}
.home3>.col{border-right:1px solid var(--line);min-width:0}
.home3>.col:last-child{border-right:0}
.home3 .ghead{padding:9px var(--s4)}
@media(max-width:1100px){.home3{grid-template-columns:1fr 1fr}.home3>.col:last-child{grid-column:1/-1;border-top:1px solid var(--line)}}
@media(max-width:700px){.home3{grid-template-columns:1fr;border-left:0;border-right:0}.home3>.col{border-right:0;border-bottom:1px solid var(--line)}}
.hrow{display:flex;align-items:center;gap:var(--s3);padding:11px var(--s4) 11px calc(var(--s4) - 3px);border-left:3px solid transparent;border-bottom:1px solid var(--line);background:var(--surface)}
.hrow:hover{background:var(--surface-2)}
.hrow__body{flex:1;min-width:0}
.hrow__title{font:var(--t-row);display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
.hrow__meta{font:var(--t-meta);color:var(--fg-3);padding-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hrow__num{font:var(--t-num);font-variant-numeric:tabular-nums;flex-shrink:0}
.hrow__time{font:var(--t-num-micro);color:var(--fg-3);flex-shrink:0}
.hrow__time.late{color:var(--crit);font-weight:500}
.hrow .actions{flex-shrink:0}
.hrow--attn{border-left-color:var(--accent)}.hrow--info{border-left-color:var(--info)}.hrow--ok{border-left-color:var(--ok)}.hrow--crit{border-left-color:var(--crit)}.hrow--mute{border-left-color:var(--line-strong);background:var(--surface-2)}
.hrow--unassigned{border-left-style:dashed;border-left-color:var(--accent-dim)}
.hempty{padding:14px var(--s4);font:var(--t-body);color:var(--fg-2);border-bottom:1px solid var(--line)}
.hmoney{display:grid;grid-template-columns:1fr 1fr 1fr;border-bottom:1px solid var(--line)}
.hmoney>div{padding:12px var(--s4);border-right:1px solid var(--line)}
.hmoney>div:last-child{border-right:0}
.hmoney .eyebrow{color:var(--fg-3)}
.hmoney .v{font:500 18px/1.25 var(--font-mono);padding-top:5px}
.hmoney .s{font:var(--t-micro);color:var(--fg-3);padding-top:2px}
.hnote{padding:10px var(--s4);font:var(--t-meta);color:var(--fg-3);border-bottom:1px solid var(--line)}
/* The one line Home says out loud that is not a list: "N of your last M leads never
   got a reply" (audit P1-15). It is not an error, so it is amber, not red. */
.hnote--warn{background:var(--wr-wash,rgba(240,178,63,.10));color:var(--fg-2);border-left:3px solid var(--wr)}
.hnote--warn b{color:var(--fg)}
/* An error card that can be retried, rather than a dead end (audit P1-1). */
.empty-card--bad{border-left:3px solid var(--crit)}
.empty-card--bad .empty-t{color:var(--crit-text,var(--crit))}
.empty-card--bad .btn{margin-top:12px}

/* Board (Work) */
.board{gap:var(--s3);padding:0;overflow-x:auto;align-items:flex-start}
.bcol{background:var(--surface-3);border:1px solid var(--line);border-radius:0;min-width:262px}
.bcol.net .bcol-head{background:var(--info-wash);color:var(--info)}
.bcol-head{padding:10px var(--s3);border-bottom:1px solid var(--line);font:var(--t-label-sm);letter-spacing:.13em;text-transform:uppercase;color:var(--fg-2);background:transparent}
.bcol-head b{font:inherit}
.bcol-head .s{font:500 11px/1 var(--font-mono);color:var(--fg-3);letter-spacing:0;text-transform:none}
.bcol[data-col="Requests"] .bcol-head,.bcol[data-col="Quotes"] .bcol-head{background:var(--accent-wash);color:var(--accent-text-2)}
.bcol-body{gap:1px;padding:1px}
.pcard{background:var(--surface);border:0;border-left:3px solid transparent;border-radius:0;padding:10px var(--s3) 10px calc(var(--s3) - 3px);box-shadow:none}
.pcard:hover{background:var(--surface-2)}
.pcard.s-attn{border-left-color:var(--accent)}.pcard.s-info{border-left-color:var(--info)}.pcard.s-ok{border-left-color:var(--ok)}.pcard.s-crit{border-left-color:var(--crit)}.pcard.s-mute{border-left-color:var(--line-strong);background:var(--surface-2)}
.pc-top b{font:var(--t-row-sm)}
.pc-top .mono{font:var(--t-num-sm)}
.pc-foot{padding-top:8px}
.lane-seg{display:flex;gap:6px;overflow-x:auto;padding:0 0 10px;scrollbar-width:none}
.lane-seg button{border:1px solid var(--line-strong);background:var(--surface-2);color:var(--fg-2);padding:0 13px;min-height:44px;font:600 12px/1 var(--font-text);white-space:nowrap;flex-shrink:0;cursor:pointer}
.lane-seg button[aria-pressed='true']{background:var(--surface-inv);color:var(--on-inv);border-color:var(--surface-inv);font-weight:700}
.lane-seg button i{font-style:normal;color:var(--accent-text);margin-left:5px}
.lane-seg button[aria-pressed='true'] i{color:var(--accent)}
@media(max-width:700px){
  .board{display:block;padding:0}
  .board .bcol{display:none;min-width:0;width:100%;border:0;background:transparent}
  .board .bcol[data-active='1']{display:block}
  .board .bcol-head{display:none}
  .board .bcol-body{padding:0;gap:0}
  .pcard{border-bottom:1px solid var(--line);padding:12px var(--s4) 12px calc(var(--s4) - 3px)}
}

/* Drawer / modal / forms */
.dr-back{background:var(--scrim)}
.dr-panel{border-left:0;box-shadow:var(--shadow-drawer);width:min(520px,100%)}
.dr-head{border-bottom:1px solid var(--line);padding:var(--s4) var(--s5)}
.dr-title{font:var(--t-h1)}
.dr-sub{font:var(--t-meta);color:var(--fg-3);padding-top:5px}
.dr-fld input,.dr-fld select,.dr-fld textarea,.est-ta,.route-fields input,.route-fields select,.block-form input{border:1px solid var(--line-strong);background:var(--surface-2);border-radius:0;min-height:40px;font:400 14px/1.35 var(--font-text);color:var(--fg);padding:8px 12px}
.dr-fld input:focus,.dr-fld select:focus,.dr-fld textarea:focus{outline:2px solid var(--focus);outline-offset:-1px;border-color:var(--focus);box-shadow:none;background:var(--surface)}
.dr-foot{border-top:1px solid var(--line);padding:var(--s4) var(--s5);background:var(--surface);position:sticky;bottom:0}
.dr-msg.show.bad{color:var(--crit)}
.dr-toggles{background:var(--info-wash);border-left:3px solid var(--info)}
.mm-panel{border:1px solid var(--line-strong);border-radius:2px;box-shadow:var(--shadow-menu)}
.bank-job{border:1px solid var(--line);border-radius:0;background:var(--surface);border-left:3px solid transparent}
.bank-job:hover{background:var(--accent-row);border-left-color:var(--accent)}
.est-pre{font:var(--t-meta);color:var(--fg-2);background:var(--surface-2);border:1px solid var(--line);border-radius:0}

/* Calendar bridges: legacy event classes onto the new stripe language */
.fc .fc-toolbar-title{font:var(--t-h1)}
.fc .fc-button{border-radius:0!important;font:var(--t-btn-sm)!important;text-transform:none;background:var(--surface-2)!important;border:1px solid var(--line-strong)!important;color:var(--fg-2)!important;box-shadow:none!important}
.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background:var(--surface-inv)!important;color:var(--on-inv)!important;border-color:var(--surface-inv)!important}
.fc .fc-button:hover{background:var(--surface)!important;color:var(--fg)!important}
.fc-event,.fc .fc-daygrid-event,.fc .fc-timegrid-event{border:0!important;border-left:3px solid var(--ev-color,var(--crew-1))!important;background:var(--surface-2)!important;color:var(--fg)!important;border-radius:0!important;box-shadow:none!important}
.fc .ev-unassigned{border-left-style:dashed!important;border-left-color:var(--accent-dim)!important;background:transparent!important;box-shadow:inset 0 0 0 1px var(--line-strong)!important}
.fc .ev-done{color:var(--fg-3)!important;background:transparent!important;border-left-color:var(--ok)!important}
.fc .ev-done .fc-ev-title::after{content:' ✓';color:var(--ok)}
.fc .ev-manual:not(.ev-unassigned){background:var(--surface-2)!important}
.fc .fc-off{background:var(--mute-wash)}
.fc-ev-t{font-family:var(--font-mono);color:var(--fg-3)}
.us-item{border-left:3px solid var(--accent)}
.us-item.held{border-left-color:var(--line-strong);background:var(--surface-2)}
#sched-toast{background:var(--surface-inv);color:var(--on-inv);border:0;box-shadow:var(--shadow-toast);border-radius:2px}
#sched-toast.bad{color:var(--crit-text);background:var(--crit-wash)}

/* Crew cards → rows on a ruled surface */
.crew-card{padding:0}
.crew-name{font:var(--t-h2)}
.crew-stats .v{font:500 18px/1.2 var(--font-mono)}

/* Grades + misc leftovers */
.g-A .hc-grade{background:var(--ok-wash);color:var(--ok)}
.g-B .hc-grade{background:var(--info-wash);color:var(--info)}
.g-C .hc-grade{background:var(--mute-wash);color:var(--mute)}
.g-D .hc-grade{background:var(--accent-wash);color:var(--accent-text-2)}
.g-F .hc-grade{background:var(--crit-wash);color:var(--crit)}
.pill.mu{color:var(--mute);background:var(--mute-wash)}
.fc .fc-popover{background:var(--surface);border:1px solid var(--line-strong);box-shadow:var(--shadow-menu)}
.tip{box-shadow:var(--shadow-menu)}

/* Login */
.login{background:var(--bg)}
.login-brand b{font:700 15px/1 var(--font-display)}
.login-card{background:var(--surface);border:1px solid var(--line-strong);box-shadow:none;padding:24px}
.login-card h1{font:var(--t-h1);margin:0 0 6px}
.login-card .sub{font:var(--t-body);color:var(--fg-3);margin:0 0 18px}
.login-card .eyebrow{margin-bottom:6px}
.login-card input{height:44px;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:0;font:400 15px/1 var(--font-text);color:var(--fg);padding:0 12px}
.login-card button{width:100%;height:46px;margin-top:16px;font:700 14px/1 var(--font-display)}
.login-err{color:var(--crit)}
.login-err i{background:var(--crit)}

/* Phone tab bar sizing, more-sheet */
.more-panel{border-radius:0}
.more-sheet .more-back{background:var(--scrim)}
.more-panel .ws-go{background:var(--surface-2);border:1px solid var(--line-strong);color:var(--fg);font:var(--t-btn)}

.msent{font:var(--t-h1);line-height:1.3;padding:18px var(--s5);background:var(--surface);border:1px solid var(--line);margin-bottom:var(--s3)}
.msent b{font-family:var(--font-mono);font-weight:500}
.msent .link-btn{font:600 13px/1 var(--font-text);margin-left:8px}

/* ---- fixes after first screenshot pass ---- */
.topbar,.lane-seg{display:none}
@media(max-width:700px){
  .topbar{display:flex}
  .lane-seg{display:flex}
  .tabbar{display:flex}
  .only-phone.tabbar,.only-phone.topbar{display:flex}
}
/* Cards keep their inner padding; group heads and rows bleed to the card edge */
.card,.money-card,.today-card,.crew-card,.side-card,.route-card,.vm-card,.chart-card{padding:14px 16px}
.tbl-card{padding:0}
.card>.mc-head,.money-card>.mc-head,.today-card>.mc-head,.crew-card>.mc-head,.side-card>.mc-head,.side-card>.side-head{margin:-14px -16px 12px}
.card>.tw-row,.card>.payee-row,.card>.bank-row,.card>.d-row,.card>.hist,.card>.rowfilter,.card>.side-empty,.card>.sub-row,.card>.owed-row,.card>.us-item,.card>.calls-controls,.card>.filters,.card>.tbl-foot{margin-left:-16px;margin-right:-16px}
.card>.calls-controls,.card>.filters{padding-left:16px;padding-right:16px}
.card>.tw-row:last-child,.card>.payee-row:last-child,.card>.bank-row:last-child,.card>.d-row:last-child,.card>.hist:last-child{margin-bottom:-14px;border-bottom:0}
.mc-head+.rowfilter{margin-top:-12px}
/* Work board: scrolling lanes of fixed width, like the design */
.board{display:flex;gap:var(--s3);overflow-x:auto;padding:0 0 var(--s3);align-items:flex-start;grid-template-columns:none}
.bcol{width:272px;min-width:272px;flex:0 0 272px}
.bcol-body{max-height:none}
/* Schedule: the page header owns the title and the New job button */
.sched-top{display:none}
.money-sub{display:none}
.money-top{margin-bottom:var(--s3)}

/* ---- second pass ---- */
.bcol-head{flex-shrink:0;position:sticky;top:0;z-index:2;background:var(--surface-3)}
.bcol.net .bcol-head{background:var(--info-wash)}
.bcol[data-col="Requests"] .bcol-head,.bcol[data-col="Quotes"] .bcol-head{background:var(--accent-wash)}
.bank-row:not(.s-attn):not(.s-ok):not(.s-crit):not(.s-info):not(.s-mute){border-left-color:var(--accent)}
.rail__foot .stamp{white-space:normal;line-height:1.3;font-size:10px}
#phead.phead--inv{background:var(--rail);color:var(--rail-fg);border-bottom-color:var(--rail-line)}
#phead.phead--inv .phead__sub{color:var(--rail-fg-dim)}

/* spacing tokens fixed */
/* ---- third pass ---- */
.play-btn{width:34px;height:34px;padding:0;font-size:12px}
.play-btn svg{width:14px;height:14px}
.tbl-card .lead-row,.tbl-card .call-row,.tbl-card .gsc-row,.tbl-card .cost-row{padding-left:13px;padding-right:12px}
@media(max-width:700px){.money-card>.mc-head{flex-wrap:wrap}.money-card>.mc-head .s{margin-left:0;white-space:normal;line-height:1.5}}

/* ---- finishing pass: crew table, inbox selection, job sheet, login ---- */
.ctbl .ctbl__row{display:grid;grid-template-columns:minmax(220px,1.4fr) 120px 120px minmax(150px,1fr) minmax(190px,1.2fr) 118px;gap:14px;align-items:center}
.ctbl .tbl-head.ctbl__row{padding:9px 16px}
.ctbl .tbl-row{padding:14px 16px 14px 13px;border-left:3px solid transparent;border-bottom:1px solid var(--line);cursor:pointer}
.ctbl .tbl-row:hover{background:var(--surface-2)}
.ctbl .ctbl__row--blocked{background:var(--surface-2)}
.ctbl .ctbl__row--blocked b,.ctbl .ctbl__row--blocked .mono{color:var(--fg-data)}
.ctbl__detail{background:var(--surface);border-bottom:1px solid var(--line)}
.ctbl__detail-grid{display:grid;grid-template-columns:1fr 1fr}
.ctbl__detail-grid>div:first-child{border-right:1px solid var(--line)}
.ctbl__detail .payee-row{margin:0}
@media(max-width:900px){.ctbl .ctbl__row{grid-template-columns:1fr auto;grid-template-areas:'p paid' 'up up' 'av av' 'pp pp' 'act act';row-gap:8px}.ctbl .tbl-head{display:none}.ctbl .tbl-row>div:nth-child(1){grid-area:p}.ctbl .tbl-row>div:nth-child(2){grid-area:paid}.ctbl .tbl-row>div:nth-child(3){grid-area:up;text-align:left}.ctbl .tbl-row>div:nth-child(4){grid-area:av}.ctbl .tbl-row>div:nth-child(5){grid-area:pp}.ctbl .tbl-row>div:nth-child(6){grid-area:act}.ctbl__detail-grid{grid-template-columns:1fr}.ctbl__detail-grid>div:first-child{border-right:0;border-bottom:1px solid var(--line)}}
.bank-row--sel{grid-template-columns:22px 1fr 110px auto}
.bank-row.s-sel{background:var(--accent-row)}
.bank-selall{padding:6px 16px;border-bottom:1px solid var(--line);margin:0 -16px}
.bulk{margin:0 -16px 8px;top:auto;position:static}
@media(max-width:700px){.bank-row--sel{grid-template-columns:22px 1fr auto}.bank-row--sel .bank-act{grid-column:2/-1}.bulk{flex-wrap:wrap}}
.dr-body--sheet{padding:0;gap:0}
.dr-body--sheet .fset{padding:14px 20px;border-bottom:1px solid var(--line);display:grid;gap:12px;margin:0;border-left:0;border-right:0;border-top:0}
.dr-body--sheet .fset__legend{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--fg-2);padding:0 0 2px}
.dr-body--sheet .dr-info{padding:12px 20px;border-bottom:1px solid var(--line)}
.dr-body--sheet .dr-toggles{background:transparent;border:0;padding:0;display:grid;gap:6px}
.dr-body--sheet .notice{margin-bottom:4px}
.dr-body--sheet .dr-foot{display:flex;align-items:center;gap:10px}
.dr-body--sheet .dr-msg{padding:0 20px 12px}
.login-card{border-top:3px solid var(--accent)}
.login-inner{max-width:380px}

/* ===== Agent A: Home + Work ===== */
/* Append-only. Home became a phone-first Today list; Work lost its on-card stage
   select and gained one Call/Text language. No token or component is redefined —
   these are the new pieces only. */

/* --- Call / Text, the two things you do with a person --- */
.acts{display:inline-flex;gap:6px;align-items:center;flex-shrink:0}
.act{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:34px;padding:0 12px;border-radius:0;font:600 12.5px/1 var(--font-text);cursor:pointer;white-space:nowrap;border:1px solid var(--line-strong);background:var(--surface);color:var(--fg);transition:background .12s,border-color .12s}
.act:hover{background:var(--surface-2);border-color:var(--fg-3);color:var(--fg)}
.act--ghost{background:transparent}
/* Exactly one thing on a screen is solid yellow: the next action. */
.act--primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:700}
.act--primary:hover{background:var(--accent-dim);border-color:var(--accent-dim);color:var(--accent-ink)}
.act--danger{background:var(--crit);border-color:var(--crit);color:#fff;font-weight:700}
.act--danger:hover{filter:brightness(1.06);color:#fff}
@media(max-width:700px){.act{min-height:40px;padding:0 14px}}

/* --- Home: one column, always. A phone screen has one column; so does this. --- */
.home1{display:flex;flex-direction:column;border:1px solid var(--line);border-left:0;border-right:0;background:var(--surface)}
@media(min-width:1101px){.home1{border-left:1px solid var(--line);border-right:1px solid var(--line);max-width:920px}}
.home1 .ghead{padding:9px var(--s4)}
/* An appointment on the truck: the hour leads on every width; on a phone the body
   keeps the hour beside it and Call/Text drop to their own line. */
.hrow--truck{align-items:flex-start;cursor:pointer}
.hrow--truck .hrow__time{font:var(--t-num);color:var(--fg);min-width:56px;padding-top:2px}
.hrow--truck .actions{display:flex;gap:6px;align-items:center;padding-top:2px}
.hrow--truck .hrow__meta{white-space:normal;overflow:visible;text-overflow:clip}
@media(max-width:700px){
  .hrow--truck{flex-wrap:wrap}
  .hrow--truck .hrow__body{flex:1 1 0;min-width:0}
  .hrow--truck .actions{flex:1 1 100%;justify-content:flex-end}
}
.hrow--person{align-items:flex-start;cursor:pointer}
.hrow--person .hrow__time{padding-top:2px}
.hrow--person .actions{display:flex;gap:6px;align-items:center;padding-top:2px}
.hrow .hrow__title .hrow__num{margin-left:auto}
/* The amount rides on the title line and never collides with a long name. */
.hrow--person .hrow__title{gap:var(--s2)}
.hrow--person .hrow__title .hrow__num{margin-left:auto;padding-left:var(--s2)}
/* The subtitle may wrap: "24d late" must stay readable, not be clipped. */
.hrow--person .hrow__meta{white-space:normal;overflow:visible;text-overflow:clip}
/* On a phone the actions drop under the text instead of squeezing it. */
@media(max-width:700px){
  .hrow--person{flex-wrap:wrap}
  .hrow--person .hrow__body{flex:1 1 100%}
  .hrow--person .hrow__time{order:2}
  .hrow--person .actions{order:3;margin-left:auto;flex-wrap:wrap;justify-content:flex-end}
}
/* Reports: closed on a phone, because a report is never why you opened this. */
.hrep{border-bottom:1px solid var(--line);background:var(--surface)}
.hrep>summary{display:flex;align-items:center;gap:var(--s2);padding:11px var(--s4);cursor:pointer;font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--fg-2);list-style:none;min-height:44px;box-sizing:border-box}
.hrep>summary::-webkit-details-marker{display:none}
.hrep>summary::after{content:'+';margin-left:8px;font:600 15px/1 var(--font-text);color:var(--fg-3)}
.hrep[open]>summary::after{content:'\2212'}
.hrep__note{margin-left:auto;font:var(--t-num-micro);color:var(--fg-3);text-transform:none;letter-spacing:0}
.hrep>summary:hover{background:var(--surface-2)}
.hrep .hrow:last-child,.hrep .hmoney{border-bottom:0}

/* --- Work board: the card is a button, nothing else on it competes --- */
.pcard[role='button']:focus-visible,.hrow[role='button']:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.pc-act{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.pc-last{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-clamp:2;overflow:hidden}
/* Item 8: below 860px the board is a list of one lane, not four columns. */
@media(max-width:859px){
  .board{display:block;padding:0}
  .board .bcol{display:none;min-width:0;width:100%;border:0;background:transparent}
  .board .bcol[data-active='1']{display:block}
  .board .bcol-head{display:none}
  .board .bcol-body{padding:0;gap:0;max-height:none}
  .lane-seg{display:flex}
  .pcard{border-bottom:1px solid var(--line);padding:12px var(--s4) 12px calc(var(--s4) - 3px)}
}

/* --- Drawer: stage lives here now --- */
.jd-stage{display:grid;gap:10px}
.jd-stage__now{display:flex;flex-direction:column;gap:3px}
.jd-stage__now b{font:var(--t-row);font-weight:700}
.jd-stage__now span{font:var(--t-meta);color:var(--fg-2)}
/* Booked, not yet done: a sentence where the primary button would have been. */
.jd-booked{font:var(--t-meta);color:var(--fg-2);border-left:2px solid var(--ln2);padding:2px 0 2px 9px;margin:8px 0 0}
.jd-stage__acts{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.jd-more{min-width:44px;letter-spacing:.12em;font-size:14px}
.jd-contact{display:flex;gap:6px;padding-top:8px}
.jd-phone{font:var(--t-meta);color:var(--fg-2)}
.est-list{margin:0;padding:0 0 0 16px;display:flex;flex-direction:column;gap:6px;font:var(--t-body);color:var(--fg-2)}
.est-list li{line-height:1.5}
.est-list b{color:var(--fg)}

/* --- Confirm sheet: says what will happen, in words --- */
.cfm{position:fixed;inset:0;z-index:120;display:grid;place-items:center}
.cfm__back{position:absolute;inset:0;background:rgba(0,0,0,.44)}
.cfm__panel{position:relative;width:min(400px,92vw);background:var(--surface);border:1px solid var(--line-strong);padding:20px;display:grid;gap:10px;box-shadow:0 18px 48px rgba(0,0,0,.28)}
.cfm__t{font:600 16px/1.3 var(--font-text);color:var(--fg)}
.cfm__b{font:var(--t-body);color:var(--fg-2)}
.cfm__acts{display:flex;gap:8px;justify-content:flex-end;padding-top:6px}
@media(max-width:700px){.cfm{place-items:end center}.cfm__panel{width:100%;border-left:0;border-right:0;border-bottom:0;padding-bottom:calc(20px + env(safe-area-inset-bottom))}.cfm__acts{flex-direction:column-reverse}.cfm__acts .act{width:100%;min-height:46px}}

/* --- The ⋯ menu: where everything destructive lives --- */
.mnu{position:fixed;inset:0;z-index:120}
.mnu__back{position:absolute;inset:0;background:rgba(0,0,0,.28)}
.mnu__panel{position:absolute;right:12px;top:60px;min-width:210px;background:var(--surface);border:1px solid var(--line-strong);box-shadow:0 14px 40px rgba(0,0,0,.26);display:flex;flex-direction:column;padding:4px}
.mnu__item{text-align:left;background:none;border:0;padding:11px 12px;min-height:44px;font:var(--t-row);color:var(--fg);cursor:pointer}
.mnu__item:hover{background:var(--surface-2)}
.mnu__item--danger{color:var(--crit)}
@media(max-width:700px){.mnu__panel{position:fixed;left:0;right:0;bottom:0;top:auto;min-width:0;border-left:0;border-right:0;border-bottom:0;padding-bottom:env(safe-area-inset-bottom)}}

/* --- Undo: no stage change is a one-way door --- */
.toast{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(18px + env(safe-area-inset-bottom));z-index:130;display:flex;align-items:center;gap:14px;background:var(--surface-inv);color:var(--on-inv);padding:12px 16px;font:var(--t-row);box-shadow:0 12px 32px rgba(0,0,0,.3);max-width:calc(100vw - 24px)}
.toast__undo{background:none;border:0;color:var(--accent);font:700 13px/1 var(--font-text);cursor:pointer;padding:4px;min-height:32px}
.toast__undo:hover{text-decoration:underline}
@media(max-width:700px){.toast{bottom:calc(72px + env(safe-area-inset-bottom));left:12px;right:12px;transform:none}}

/* ===== Agent B: Schedule + Crew ===== */


/* --- The strip is three facts now, so it does not need to hide columns on a phone. --- */
.sched-strip{grid-template-columns:repeat(3,1fr)}
@media(max-width:700px){
  /* Three facts, one line each, no wrapped sub-captions eating a third of the
     screen before you have seen a single job. */
  .sched-strip{grid-template-columns:repeat(3,1fr);gap:6px}
  .sched-strip .kpi{padding:8px 10px}
  .sched-strip .kpi .v{font-size:18px}
  .sched-strip .kpi .d-sub{font-size:10.5px;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
}

/* --- Callback windows: 12:15 and 5:30, the half hours kept for returning calls.
       A stripe you can see through, never a block you can click. --- */
.fc .fc-bg-event.ev-callback,.fc .ev-callback{background:repeating-linear-gradient(135deg,var(--accent-wash) 0 6px,transparent 6px 12px);opacity:1;border-left:2px solid var(--accent);pointer-events:none}
.fc .ev-callback .fc-event-title{display:block;padding:1px 5px;font:var(--t-label-sm);letter-spacing:.04em;text-transform:uppercase;color:var(--fg-3);white-space:nowrap;overflow:hidden;pointer-events:none}
.fc .fc-daygrid .ev-callback,.fc .fc-list .ev-callback{display:none} /* only meaningful on a time grid */

/* --- Unscheduled cards: a person, then where, then one thing to do. --- */
/* A customer's name is the one thing on this card that must never be clipped —
   "Elizabeth Lar…" is exactly the failure this card was rebuilt to fix. It wraps
   to two lines instead, and the card stacks its actions underneath. */
.us-item{flex-wrap:wrap;align-items:flex-start}
.us-main{flex:1 1 100%;min-width:0}
.us-name{white-space:normal;overflow:visible;text-overflow:clip;font:var(--t-row);line-height:1.25}
.us-where{font:var(--t-meta);color:var(--fg-3);margin-top:2px;white-space:normal;overflow-wrap:anywhere}
.us-item .us-meta{margin-top:3px}
.us-item .us-meta:empty{display:none}
.us-act{flex:1 1 100%;justify-content:flex-start;gap:var(--s2);margin-top:var(--s2)}
.us-act .us-go{height:34px}
/* The ⋯ button. Everything that cannot be undone with one tap lives behind it —
   so it has to look like a real control, not a stray glyph beside a yellow slab. */
.us-more{width:38px;height:34px;min-height:34px;border:1px solid var(--line);background:var(--surface);color:var(--fg-3);font-size:16px;line-height:1;cursor:pointer;border-radius:0;letter-spacing:1px;flex:0 0 auto}
.us-more:hover{border-color:var(--fg-3);color:var(--fg)}
@media(max-width:700px){
  /* Thumb-sized targets on the phone; Schedule takes the width it deserves as
     the one primary action. */
  .us-act .us-go{flex:1 1 auto;height:40px}
  .us-more{width:48px;height:40px;min-height:40px}
}

/* --- The phone component. Identical on Schedule's crew rail, in the assign
       drawer, and on the Crew table: the number is tappable and Call/Text sit
       beside it, so reaching a sub is never a copy-paste job. --- */
.crew-ph{display:inline-flex;align-items:center;gap:var(--s2);flex-wrap:wrap;min-width:0}
.crew-ph__n{font-variant-numeric:tabular-nums;color:inherit;text-decoration:none;border-bottom:1px solid var(--line)}
.crew-ph__n:hover{border-bottom-color:currentColor}
.crew-ph .acts{gap:4px}
.crew-ph .act{height:26px;padding:0 9px;font-size:11px}
/* The warning is the whole reason the row exists — it never gets an ellipsis. */
.crew-warn{color:var(--crit);font-weight:600;white-space:normal;overflow:visible;text-overflow:clip;display:inline-block}
.sub-row .sub-meta{white-space:normal;overflow:visible}
.crew-contact{font:var(--t-meta);color:var(--fg-3);margin-top:3px;white-space:normal;overflow:visible;text-overflow:clip}
/* Call/Text inside the assign drawer's crew rows. */
.crew-reach{display:block;margin-top:3px;font:var(--t-meta);font-weight:400}
.crew-reach .act{height:24px;padding:0 8px;font-size:10.5px}

/* --- Crew: the acronym key. Said once in English, then dismissable forever;
       the same words survive as tooltips on every chip. --- */
.crew-key{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;padding:10px var(--s4);margin-bottom:var(--s2);background:var(--surface-2);border:1px solid var(--line);font:var(--t-meta);color:var(--fg-3)}
.crew-key span{white-space:nowrap}
.crew-key b{color:var(--fg);font-weight:700}
.crew-key__x{margin-left:auto;border:1px solid var(--line);background:var(--surface);color:inherit;font:var(--t-label);padding:5px 10px;min-height:28px;cursor:pointer;border-radius:0}
.crew-key__x:hover{border-color:var(--fg-3)}
@media(max-width:700px){.crew-key{gap:var(--s2) var(--s3)}.crew-key__x{margin-left:0;width:100%}}

/* A crew is more than one person, so it does not get initials pretending otherwise. */
.av--crew{font-size:15px;letter-spacing:0;filter:grayscale(.35)}

/* Availability hides until somebody actually books time off; the grid closes up
   behind it (and the phone layout's positional areas shift with it). */
.ctbl.ctbl--noavail .ctbl__row{grid-template-columns:minmax(220px,1.4fr) 120px 120px minmax(190px,1.2fr) 150px}
@media(max-width:900px){
  .ctbl.ctbl--noavail .ctbl__row{grid-template-columns:1fr auto;grid-template-areas:'p paid' 'up up' 'pp pp' 'act act'}
  .ctbl.ctbl--noavail .tbl-row>div:nth-child(4){grid-area:pp}
  .ctbl.ctbl--noavail .tbl-row>div:nth-child(5){grid-area:act}
  .ctbl.ctbl--noavail .tbl-row>div:nth-child(6){display:none}
}
/* "Paid per job on the ledger…" is a sentence, not a chip — let it wrap. */
.ctbl .actions .cell-contact{white-space:normal;line-height:1.4;text-align:left}

/* --- "Tony · East Brunswick · $945" does not fit one 90px week column on one
       line. Clipping it back to "Tony · East…" would undo the whole point, so in
       the time grid the title wraps instead: a tall enough block shows all three
       facts, a 30-minute block shows the first two. The day grid (month view) has
       one line per event by nature and keeps the ellipsis. --- */
/* Wrap between words, never inside one: "Haris" split across two lines as
   "Hari / s" is less readable than the ellipsis it replaced. A narrow column
   (two overlapping jobs) falls back to clipping the tail, which still leaves the
   name — the first and most important field — intact. */
.fc-timegrid-event .fc-ev-title{white-space:normal;overflow-wrap:normal;word-break:keep-all;text-overflow:clip;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.fc-timegrid-event .fc-ev{overflow:hidden}
/* Agenda rows have the whole width — never truncate there. */
.fc-list-event .fc-ev-title,.fc-list-event .fc-ev-sub{white-space:normal;overflow:visible;text-overflow:clip}

/* --- On a phone the crew table drops its header row, so "$1,500 / 3 jobs" sat
       under "$1,375 / 3 jobs" with nothing saying which was paid and which is
       booked. Each stacked cell names itself instead. --- */
@media(max-width:900px){
  .ctbl .tbl-row>div:nth-child(2)::before{content:'Paid this year';display:block;font:var(--t-label-sm);letter-spacing:.05em;text-transform:uppercase;color:var(--fg-3);margin-bottom:2px}
  .ctbl .tbl-row>div:nth-child(3)::before{content:'Upcoming';display:block;font:var(--t-label-sm);letter-spacing:.05em;text-transform:uppercase;color:var(--fg-3);margin-bottom:2px}
  .ctbl .tbl-row>div:nth-child(2),.ctbl .tbl-row>div:nth-child(3){text-align:right}
  .ctbl.ctbl--noavail .tbl-row>div:nth-child(3){text-align:left}
}
/* ===== Agent C: visual ===== */
/* One accent yellow = the one next tap. Everything below either takes yellow away from
   something that was not a next action, or gives structure back to what is left.
   Radius, air and one danger red follow. Nothing here changes what a screen says. */

/* --- 1. Yellow, taken back ------------------------------------------------
   Yellow used to mean "this is a UI part". It now means "press this". Chrome that
   merely marks position (a selected tab, the workspace dot, a count) goes to ink. */
.money-segs button.on { box-shadow: inset 0 -3px 0 var(--fg); }          /* tab underline: ink, not accent */
.tab[aria-selected='true'] { box-shadow: inset 0 -3px 0 var(--fg); }
.ws__btn[aria-pressed='true'] .ws__dot { background: var(--rail-fg); border-color: var(--rail-fg); }
.rail__link .badge.attn { background: var(--rail-fg); color: var(--rail); }
.rail__count--attn { background: var(--rail-fg); color: var(--rail); }
/* Row stripes: an attention stripe is a category, not a button. Ink at low weight
   keeps the scan order without spending the accent 15 times down one list. */
.hrow--attn, .row--attn, .tbl__row--attn, .pcard.s-attn, .s-attn { border-left-color: var(--line-heavy) !important; }
.us-item { border-left-color: var(--line-heavy); }
.bank-row:not(.s-attn):not(.s-ok):not(.s-crit):not(.s-info):not(.s-mute) { border-left-color: var(--line-strong); }
/* "+ New job" and the Schedule buttons on cards are secondary: they open a form, they
   are never the one thing the screen is asking for. */
/* #ph-acts is the page header's action slot — "+ New job", "+ Add crew". It is present
   on every screen, so it can never be that screen's one next tap. */
#ph-acts .btn--primary, #ph-acts .btn-primary,
.us-go.us-sched, .sched-btn, .us-item .us-go {
  background: var(--surface); color: var(--fg); border: 1px solid var(--line-heavy);
}
#ph-acts .btn--primary:hover, #ph-acts .btn-primary:hover,
.us-go.us-sched:hover, .sched-btn:hover,
.us-item .us-go:hover { background: var(--surface-2); color: var(--fg); }
/* The phone bar: "+ New job" is always there on every screen, so it can never be "the
   one next tap" for the screen you are on. Ink on the dark bar, and the current-tab
   underline goes to the rail's own foreground. */
.tabbar__fab { background: var(--rail-fg); color: var(--rail); }
.tabbar__item--action { color: var(--rail-fg); }
.tabbar__item[aria-current='page'] { box-shadow: inset 0 3px 0 var(--rail-fg); }
/* Board column heads name a lane; they are not a call to action. */
.bcol[data-col="Requests"] .bcol-head, .bcol[data-col="Quotes"] .bcol-head {
  background: var(--surface-3); color: var(--fg-2);
}
/* An amount is a fact. Ink for money that is simply owed; the accent stays for the
   one action, and red stays for money that is actually late. */
.pc-money b.due, .pc-amt { color: var(--fg); }
/* The WAITING ON YOU pill is a state, not an action. */
.chip--attn, .pill.wr, .pill.ac { background: var(--surface-3); color: var(--fg-2); }

/* `.us-go` was globally accent, which made every "+ payment" / "+ pay" a primary. A
   row-level add is a secondary action: bordered ink. The screens that really do have one
   next tap opt back in by id/class below. */
.us-go, .us-go:hover {
  background: var(--surface); color: var(--fg); border: 1px solid var(--line-strong);
}
.us-go:hover { background: var(--surface-2); }
.payee-fix .btn-ghost { background: var(--surface); color: var(--fg); border: 1px solid var(--line-strong); }
/* The rail marks position, not action: the current page keeps its ink stripe. */
.rail__link[aria-current='page'] { box-shadow: inset var(--stripe) 0 0 var(--rail-fg); }
/* Money keeps exactly one accented action per surface:
   This month -> "Sort N bank items"; Bank -> the row you are working; Books -> none. */
#sort-bank, #sort-bank:hover { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
#sort-bank:hover { background: var(--accent-dim); }

/* --- 2. Air and radius ---------------------------------------------------- */
.card, .tbl-card, .money-card, .today-card, .crew-card, .site-card, .route-card,
.vm-card, .chart-card, .side-card, .empty-card, .sched-cal-card { border-radius: 14px; overflow: hidden; }
/* Cards already pull their rows flush with a negative margin, so the padding they were
   given stays — only the radius and the row rhythm change. */
.mm-panel, .dr-panel, .more-panel, .cfm__panel, .mnu__panel { border-radius: 20px; }
@media (max-width: 700px) {
  /* A sheet is anchored to an edge — only the edges it leaves free get a radius. */
  .cfm__panel, .mnu__panel { border-radius: 20px 20px 0 0; }
}
/* Rows breathe: more line height and a taller minimum, so a dense list still scans. */
.tw-row, .d-row, .bank-row, .job-row, .payee-row, .lead-row, .recon-row,
.sub-row, .us-item, .owed-row, .crew-row {
  padding-top: 12px; padding-bottom: 12px; line-height: 1.45;
}
.mc-head, .side-head, .tbl-head { padding: 11px var(--s4); }
.msent { padding: 20px var(--s5); border-radius: 14px; }
/* The dense P&L strip keeps mono and keeps its density — it is a table of figures. */
.split-row .split-v, .kpi .v, .mono, .num { font-variant-numeric: tabular-nums; }
/* Body copy is one family, two weights. Mono never carries a sentence. */
.tw-body, .cell-contact, .cost-note, .side-empty, .empty-s, .dr-sub {
  font-family: var(--font-text);
}
.mc-head .s, .side-head .s, .side-head-r { font-family: var(--font-text); font-weight: 500; }
.tbl-foot { font: var(--t-meta); color: var(--fg-3); }

/* --- 3. One danger red ----------------------------------------------------
   Red is only: late money, DO NOT DISPATCH, 1099 REQUIRED, a destructive confirm.
   Everything that used red as "attention" moves to ink or to the accent wash. */
.pill.er { background: var(--crit-wash); color: var(--crit-text); }
.c-er { color: var(--crit); }

/* --- 4. Money: the pieces this pass added --------------------------------- */
/* The one next tap on This month. */
.msent-act { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; margin: 0 0 var(--s4); }
.msent-act .btn-primary { min-height: var(--tap); padding: 0 20px; border-radius: 10px; }
/* Books sub-toggle: a quieter control than the three primary tabs above it. */
.books-subs { display: flex; gap: var(--s2); flex-wrap: wrap; margin: 0 0 var(--s4); }
.books-subs button { border-radius: 10px; min-height: 38px; }
/* Bank: + green in, − black out. The sign is the fact; colour only confirms it. */
.bank-amt { color: var(--fg); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bank-amt--in { color: var(--ok); }
/* Bank decisions: full verbs never wrap to an ellipsis, and every target clears 44px. */
.bank-act { gap: var(--s2); }
.bank-act .btn-primary, .bank-act .btn-ghost {
  min-height: var(--tap); padding: 0 14px; border-radius: 10px; white-space: nowrap;
  font: var(--t-btn); text-overflow: clip; overflow: visible;
}
.bank-act .btn-ghost { background: var(--surface); color: var(--fg); border: 1px solid var(--line-strong); }
.bank-act .btn-ghost:hover { background: var(--surface-2); }
/* The likely decision on each row is solid INK, not accent. Twenty-three yellow buttons
   down one list is twenty-three "press me"s — the accent stops meaning anything. Yellow
   on this screen belongs to the single next tap (the row you are working), which the
   focused/first row takes below. */
.bank-act .btn-primary { background: var(--surface-inv); color: var(--on-inv); border: 1px solid var(--surface-inv); }
.bank-act .btn-primary:hover { background: var(--fg-2); color: var(--on-inv); }
/* The top row of the inbox is the one you are being asked to decide, and its primary
   decision is the screen's one accent. Every row below it keeps the ink primary, so the
   list reads as "start here" rather than twenty-three competing yellows. Hovering or
   tabbing to another row moves the accent to it. */
.bank-row--next .bank-act .btn-primary,
.bank-row:hover .bank-act .btn-primary,
.bank-row:focus-within .bank-act .btn-primary {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
}
/* The lane counts on the Work filter are data, not a target. */
.lane-seg button i, .lane-seg button[aria-pressed='true'] i { color: var(--fg-3); }
/* A row that still needs a human decision. */
.needs-name {
  font: var(--t-label-sm); letter-spacing: .08em; text-transform: uppercase;
  background: var(--surface-3); color: var(--fg-2); padding: 3px 6px; border-radius: 6px;
  margin-left: var(--s2); white-space: nowrap;
}
.cell-note { display: block; font: var(--t-meta); color: var(--fg-3); margin-top: 2px; }
/* The line under a bank row is the question that decides it ("business or personal?").
   Truncating it hid the decision, so it wraps instead. */
.bank-row .tw-body { white-space: normal; overflow: visible; text-overflow: clip; }
.payee-row--wide { grid-template-columns: minmax(0,1fr) auto auto auto; }
.payee-row--wide > span:first-child { min-width: 0; }
.payee-fix .btn-ghost { min-height: 36px; border-radius: 8px; }
/* Reconcile: "matches" is the quiet answer, an "off by" is the loud one. */
.grid-recon2 { grid-template-columns: 120px repeat(4, 1fr) 130px; }
.recon-row { grid-template-columns: 120px repeat(4, 1fr) 130px; }
.recon-m { font: var(--t-row); }
.recon-ok { color: var(--fg-4); }
/* A gap is information, not an alarm: ink for the number, accent text only for what is
   still waiting on a decision. Red on this table meant "broken" about missing history. */
.recon-off { color: var(--fg-2); }
.recon-unsorted { color: var(--accent-text); font-weight: 600; }
.msent--sm { font: var(--t-h2); line-height: 1.45; padding: 16px var(--s4); }

/* --- 5. Phone: the bank inbox is a list of decisions ---------------------- */
@media (max-width: 859px) {
  .bank-row { grid-template-columns: auto minmax(0,1fr) auto; row-gap: var(--s2); align-items: start; }
  .bank-main { grid-column: 2; }
  .bank-amt { grid-column: 3; text-align: right; font: var(--t-num); }
  /* Buttons get their own full-width row and stay tappable, never truncated. */
  .bank-act { grid-column: 1 / -1; justify-content: flex-start; gap: var(--s2); }
  .bank-act .btn-primary, .bank-act .btn-ghost { min-height: var(--tap); flex: 1 1 auto; }
  .bank-act .btn-primary { flex-basis: 100%; }
  .payee-row--wide { grid-template-columns: minmax(0,1fr) auto; row-gap: 6px; }
  .payee-row--wide .pill, .payee-fix { grid-column: 1 / -1; justify-self: start; }
  .grid-recon2 { display: none; }
  .recon-row { display: flex; flex-wrap: wrap; gap: 6px 12px; }
  .recon-row > .recon-m { flex: 1 0 100%; font-weight: 700; }
  .books-subs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .books-subs button { flex: 0 0 auto; }
}

/* ===== planned crew · supplies · sheets ===== */

/* A payout that is only a plan: assigned on the calendar, not yet earned. The
   row is quieter than a real ledger line so the eye still reads money-spent
   first, but the amount stays legible — it is real committed money. */
.st-row.st-planned .st-l,.st-row.st-planned .st-n{color:var(--tx3)}
.st-row.st-planned .st-n{font-variant-numeric:tabular-nums}
/* The tip half of a payment, on the line under it: the same money, split so the
   figure that met the balance and the figure that did not are both readable. */
.st-row.st-tip .st-l{padding-left:12px;color:var(--tx3)}
.st-row.st-tip .st-n{color:var(--tx3);font-variant-numeric:tabular-nums}
/* Role on a statement line. An inferred one is a button because it is still a
   question; a settled one is a quiet pill because it is only context. */
.st-role{margin-left:6px;vertical-align:baseline}
button.st-role{cursor:pointer;border:0;font:inherit;font-size:11px;padding:1px 7px}
button.st-role:hover{filter:brightness(1.08)}

/* The job-vs-truck rule, written once under the Overhead list. */
.ov-rule{font-size:11.5px;line-height:1.55;color:var(--tx3);border-top:1px solid var(--ln);margin-top:10px;padding-top:10px}

/* --- prompt sheet: one field, the same panel as the confirm --- */
.cfm__fld{display:grid;gap:5px}
.cfm__fld input{width:100%;height:44px;padding:0 12px;background:var(--surface);border:1px solid var(--line-strong);color:var(--fg);font:15px/1 var(--font-text);border-radius:0}
.cfm__fld input:focus{outline:2px solid var(--accent);outline-offset:-2px}

/* --- pick sheet: big tappable rows, each saying when to pick it --- */
.cfm__panel--pick{display:flex;flex-direction:column;gap:8px;max-height:86vh;overflow:hidden}
/* The list is the only part that scrolls: the title says WHICH jobs these are and
   Cancel is the way out, so neither may be pushed off the screen by a long list. */
.cfm__panel--pick .cfm__t,.cfm__panel--pick .cfm__b,.cfm__panel--pick .cfm__acts{flex:0 0 auto}
.pk__list{display:grid;gap:4px;flex:1 1 auto;min-height:0;max-height:min(58vh,420px);overflow-y:auto;margin:2px -4px 0;padding:0 4px;-webkit-overflow-scrolling:touch}
.pk__row{display:grid;gap:2px;text-align:left;width:100%;min-height:52px;padding:9px 12px;background:var(--surface);border:1px solid var(--line-strong);color:var(--fg);cursor:pointer;border-radius:0}
.pk__row:hover{background:var(--mute-wash)}
.pk__row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
/* The current value reads as chosen without becoming a second primary action. */
.pk__row.is-on{border-color:var(--fg);background:var(--mute-wash)}
.pk__l{font:600 14px/1.25 var(--font-text);color:var(--fg)}
.pk__h{font-size:11.5px;line-height:1.35;color:var(--tx3)}

/* --- toast tones: the alert() replacements --- */
.toast--bad{background:var(--er);color:#fff}
.toast--ok{background:var(--ok);color:#08210f}

@media(max-width:700px){
  /* Full-width targets on the phone, clear of the home indicator. */
  .pk__row{min-height:56px}
  .cfm__fld input{height:48px;font-size:16px} /* 16px: iOS must not zoom on focus */
}

/* ===== L2: Sites · Search · Routing · Spend ===== */
/* The network side is a triage inbox for eleven phones. Everything here either
   makes one line say the whole story about a site, or stops a screen from
   printing a number it cannot back up. Append-only — nothing above is moved. */

/* --- Network net: rent minus cost, said out loud ---------------------------
   It used to be an em dash, because rent is zero. Zero is an answer; a dash is
   not. The card states the subtraction so "-$60.00" is never a mystery. */
.net-card {
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s4);
  flex-wrap: wrap;
  background: var(--surface-inv); color: var(--on-inv);
  padding: var(--s4); margin-bottom: var(--s3);
}
.net-card .eyebrow { color: var(--on-inv-dim); }
.net-v { font: 500 30px/1.1 var(--font-mono); font-variant-numeric: tabular-nums; margin-top: 5px; letter-spacing: var(--track-tight); }
.net-card--down .net-v { color: var(--accent); }
.net-s { font: var(--t-meta); color: var(--on-inv-dim); margin-top: 4px; font-variant-numeric: tabular-nums; }
.net-r { font: var(--t-meta); color: var(--on-inv-dim); text-align: right; }
.net-r .lnk {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--on-inv); font: var(--t-meta); text-decoration: underline; text-underline-offset: 2px;
}
.net-r .lnk:hover { color: var(--accent); }

/* Four tiles, and Call spend is not one of them — a $0.58 number had a box the
   size of the call count. Spend has its own tab.
   The shared .kpis strip scrolls sideways; with four tiles that hid the fourth
   one off-screen on a phone, so these two wrap into a grid instead. */
.kpis--4, .kpis--3 { grid-auto-flow: row; overflow-x: visible; }
.kpis--4 { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.kpis--3 { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.kpis--4 > .kpi, .kpis--3 > .kpi { border-top: 1px solid var(--line); }
@media (max-width: 700px) {
  .kpis--4, .kpis--3 { grid-template-columns: 1fr 1fr; }
}
.kpi-sub { font: var(--t-micro); color: var(--fg-3); margin-top: 5px; }

/* --- Sites: one line per site ---------------------------------------------
   Full name always (the grid used to truncate "Edison Drywall" to "Edison D…"),
   the domain as the one outbound link, and the money on the right where he
   scans for it. The whole row is a button into that site's routing. */
.sitelist { display: flex; flex-direction: column; border: 1px solid var(--line); background: var(--surface); }
.site-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s4);
  width: 100%; text-align: left; padding: var(--s3) var(--s4);
  border: 0; border-bottom: 1px solid var(--line); border-left: var(--stripe) solid transparent;
  background: none; cursor: pointer; font: inherit; color: inherit;
  transition: background var(--dur-1) var(--ease);
}
.site-row:last-child { border-bottom: 0; }
.site-row:hover { background: var(--surface-2); border-left-color: var(--line-heavy); }
.site-row__main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.site-row__name { font: var(--t-row); letter-spacing: var(--track-tight); display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.site-row__name .pill { height: 18px; font-size: 10px; padding: 0 6px; }
.site-row__dom a { font: var(--t-num-micro); color: var(--fg-3); text-decoration: none; }
.site-row__dom a:hover { color: var(--fg); text-decoration: underline; text-underline-offset: 2px; }
.site-row__last { display: flex; align-items: center; gap: 6px; font: var(--t-meta); color: var(--fg-2); }
.site-row__last i { width: 6px; height: 6px; flex: 0 0 auto; }
.site-row__side { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; text-align: right; flex: 0 0 auto; }
.site-row__money { font: var(--t-row-sm); font-variant-numeric: tabular-nums; }
.site-row__money .tx3 { color: var(--fg-3); font-weight: 400; }
.site-row__cost, .site-row__fwd { font: var(--t-micro); color: var(--fg-3); font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  /* On a phone the row stacks; the money still lands last, so the thumb scan
     order stays name -> lead -> money. */
  .site-row { flex-direction: column; gap: 6px; }
  .site-row__side { align-items: flex-start; text-align: left; }
  .net-card { flex-direction: column; align-items: flex-start; }
  .net-r { text-align: left; }
}

/* --- Search: a rank chip that tells the truth ------------------------------
   Average position is better when it goes DOWN, so a green "+8" on a rank that
   slid from 42 to 50 was a lie. Colour follows better/worse, never up/down. */
.chip--up, .chip--down, .chip--flat {
  display: inline-flex; align-items: center; height: 18px; padding: 0 6px;
  font: 600 10.5px/1 var(--font-mono); border-radius: 0; white-space: nowrap;
}
.chip--up { color: var(--ok); background: rgba(62,207,142,.14); }
.chip--down { color: var(--crit); background: rgba(242,85,90,.13); }
.chip--flat { color: var(--fg-3); background: var(--surface-3); }

/* --- Routing: what is set, and what is only a default ---------------------- */
/* A configured value is ink. An empty field shows its placeholder in grey and
   the placeholder says what actually happens, so "blank" is never ambiguous. */
.route-fields input { color: var(--fg-3); }
.route-fields input.is-set,
.route-fields input:focus { color: var(--fg); font-weight: 600; }
.route-fields input::placeholder { color: var(--fg-3); opacity: 1; font-weight: 400; }
.rt-fld { display: block; }
.rt-fld > .eyebrow { display: block; margin-bottom: 4px; }

/* Rent is a state first, an amount second. "0 = not rented" asked him to know a
   convention; a two-way switch just says which it is. */
.rt-rent__row { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.seg.rt-seg { display: inline-flex; flex: 0 0 auto; border: 1px solid var(--line-strong); background: var(--surface-2); }
.seg.rt-seg .seg__btn {
  height: 34px; padding: 0 12px; border: 0; background: none; cursor: pointer;
  font: var(--t-btn-sm); color: var(--fg-2);
}
.seg.rt-seg .seg__btn[aria-pressed='true'] { background: var(--fg); color: var(--surface); }
.rt-dollar { display: inline-flex; align-items: center; gap: 4px; flex: 1 1 120px; min-width: 120px; }
.rt-dollar[hidden] { display: none; }
.rt-cur, .rt-per { font: var(--t-num-micro); color: var(--fg-3); flex: 0 0 auto; }
.rt-dollar input { min-width: 0; }
.rt-renter[hidden] { display: none; }

/* info@ was a text field nobody typed in. It is a mailbox: link it. */
.route-mail { font: var(--t-micro); color: var(--fg-3); margin-top: var(--s2); }
.route-mail a { color: var(--fg-2); }
.route-mail a:hover { color: var(--fg); }

/* Save appears only on the card you changed. Eleven standing yellow buttons
   read as eleven unsaved decisions; one reads as the one you just made. */
.route-save[hidden] { display: none; }
.route-card.is-dirty { border-color: var(--line-heavy); }
.route-card--focus { box-shadow: inset var(--stripe) 0 0 var(--accent); border-color: var(--line-heavy); }

/* --- Spend: one total, and it is the sum of the rows ----------------------- */
/* Account-wide lines are already inside every site's row. Printing them again
   as their own $0.00 tiles said "we spent nothing on phone numbers". */
.cost-shared {
  border: 1px solid var(--line); border-left: var(--stripe) solid var(--line-heavy);
  background: var(--surface-2); padding: var(--s3) var(--s4);
  font: var(--t-meta); color: var(--fg-2); margin: var(--s3) 0;
}
.cost-shared b { color: var(--fg); font-variant-numeric: tabular-nums; }

/* The site column was 180px, which cut "Ocean County Chimney Repair" mid-word.
   The name is the row's subject; the top query can take the squeeze instead. */
.grid-gsc { grid-template-columns: 230px 108px 132px 128px 1fr; }
.gsc-row .cell-site { white-space: normal; }
/* The rank chip is a sentence fragment ("up 6.9"), not a code. */
.chip--up, .chip--down { text-transform: none; }
/* Spend's header row: "text cost" and "recording" ran together at 1280. */
.grid-costs, .cost-foot { grid-template-columns: 1fr 52px 78px 50px 74px 82px 74px 88px; }

/* The two workspace rows used to read as two Home buttons, because nothing said
   which one you were in. The name under the logo says it; the rows below become
   a labelled switch, and the one you are in stays visible so it is a choice of
   two, not a single mystery button. */
.rail__wsname {
  font: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--accent); padding-bottom: var(--s2);
}
.ws__label {
  font: var(--t-num-micro); color: var(--rail-fg-dim, var(--on-inv-dim));
  padding-bottom: 4px;
}

/* The GSC-lag sentence is a note, not an empty state — it was inheriting the
   empty-card's tall centred box and eating a third of the phone screen. */
#view-search > .empty-card:first-child { padding: var(--s3) var(--s4); text-align: left; }
/* Three tiles in a two-column grid left a hole; the third takes the full row. */
@media (max-width: 700px) {
  .kpis--3 > .kpi:last-child { grid-column: 1 / -1; }
}


/* ===== L1: Leads + Calls ===== */
/* Append-only, 2026-08-27. Leads became one row per CALLER that opens a sheet;
   Calls kept its bones and lost the collisions. Nothing above is redefined. */

/* --- A NEW badge must not read as disabled. Agent C's pass folded .pill.wr into
   the grey chip, which is right for "planned" and wrong for "somebody is waiting":
   the one status that means act now carries the accent. --- */
.pill--new{background:var(--accent-wash);color:var(--accent-text-2);font-weight:700}

/* --- Leads: the one line of counts that replaced six zero-tiles --- */
.ln-tally{display:flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap;padding:var(--s3) var(--s4);background:var(--surface);border:1px solid var(--line);border-radius:20px;font:var(--t-row)}
.ln-tally b{font:var(--t-h1);font-variant-numeric:tabular-nums;line-height:1}
.ln-tally b.c-ok{color:var(--ok)}
.ln-tally b.c-wr{color:var(--accent-text-2)}
.ln-tally i{font:var(--t-meta);color:var(--fg-3);font-style:normal;margin-left:auto;padding-left:var(--s3)}
@media(max-width:700px){.ln-tally i{margin-left:0;padding-left:0;flex:1 0 100%}}

/* --- Leads: a section head inside the card ("Needs action · 4") --- */
.ln-head{display:flex;align-items:center;gap:var(--s2);padding:11px var(--s4);background:var(--surface-3);border-bottom:1px solid var(--line);font:var(--t-label-sm);letter-spacing:.13em;text-transform:uppercase;color:var(--fg-2)}
.ln-head i{font:var(--t-num-micro);font-style:normal;color:var(--fg-3);letter-spacing:0}

/* --- One caller, one row, one tap. The whole row is the target. --- */
.ln-row{display:flex;align-items:flex-start;gap:var(--s3);padding:13px var(--s4);cursor:pointer;text-align:left;width:100%;box-sizing:border-box}
.ln-row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.ln-row.is-new{box-shadow:inset 3px 0 0 var(--accent)}
.ln-main{min-width:0;flex:1}
.ln-name{font:var(--t-row);color:var(--fg);display:flex;align-items:baseline;gap:6px;min-width:0}
.ln-name>:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* "×30" is how many times this number came in — the reason the row exists. */
.ln-n{font:var(--t-num-micro);color:var(--fg-3);flex:0 0 auto}
.ln-sub{font:var(--t-body);color:var(--fg-2);padding-top:3px}
.ln-sites{font:var(--t-meta);color:var(--fg-3);padding-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ln-right{display:flex;flex-direction:column;align-items:flex-end;gap:5px;flex:0 0 auto}
/* humanWhen, never a clipped ":58 AM" — it gets its own column and never wraps. */
.ln-when{font:var(--t-num-micro);color:var(--fg-3);white-space:nowrap}
@media(max-width:700px){
  .ln-row{flex-wrap:wrap;padding:13px var(--s4) 12px}
  .ln-main{flex:1 1 100%}
  .ln-right{flex-direction:row;align-items:center;flex:1 1 100%;justify-content:flex-start;gap:var(--s2);padding-top:6px}
  .ln-when{margin-left:auto}
}

/* --- The collapsed spam group. Folded away, never deleted. --- */
.ln-fold,.cl-fold{border-bottom:1px solid var(--line);background:var(--surface)}
.ln-fold>summary,.cl-fold>summary{display:flex;align-items:center;gap:var(--s2);padding:11px var(--s4);min-height:44px;box-sizing:border-box;cursor:pointer;list-style:none;font:var(--t-label-sm);letter-spacing:.13em;text-transform:uppercase;color:var(--fg-2)}
.ln-fold>summary::-webkit-details-marker,.cl-fold>summary::-webkit-details-marker{display:none}
.ln-fold>summary::after,.cl-fold>summary::after{content:'+';margin-left:8px;order:9;font:600 15px/1 var(--font-text);color:var(--fg-3)}
.ln-fold[open]>summary::after,.cl-fold[open]>summary::after{content:'\2212'}
.ln-fold>summary:hover,.cl-fold>summary:hover{background:var(--surface-2)}
.ln-fold>summary i,.cl-fold>summary i{margin-left:auto;font:var(--t-num-micro);font-style:normal;color:var(--fg-3);letter-spacing:0;text-transform:none}
.ln-fold .ln-row{opacity:.72}
.cl-fold .call-row{opacity:.72}

/* --- The lead sheet: same drawer as a job, same 20px radius (set above). --- */
#lead-drawer{position:fixed;inset:0;z-index:110}
.ls-dec{gap:10px}
.ls-btns{display:flex;gap:var(--s2);flex-wrap:wrap}
.ls-hint{font:var(--t-meta);color:var(--fg-3)}
.ls-now{display:flex;flex-direction:column;gap:3px}
.ls-now b{font:var(--t-row)}
.ls-now span{font:var(--t-meta);color:var(--fg-3)}
@media(max-width:700px){.ls-btns{flex-direction:column}.ls-btns .act{width:100%;min-height:46px}}

/* --- The history: every call and form from this number, in full. --- */
.ls-hist{display:flex;flex-direction:column;gap:var(--s3)}
.ls-item{border:1px solid var(--line);border-radius:14px;padding:var(--s3);display:flex;flex-direction:column;gap:6px;background:var(--surface)}
.ls-item.is-new{border-color:var(--line-strong)}
.ls-when{font:var(--t-num-micro);color:var(--fg-3)}
.ls-kind{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.ls-dur{font:var(--t-num-micro);color:var(--fg-3)}
/* The message is never truncated: "65 Leigh avenue 08542" is the whole point of
   opening the sheet, and a delivery address that ends in "…" is worthless. */
.ls-body{font:var(--t-body);color:var(--fg);white-space:normal;overflow-wrap:anywhere}
.ls-meta{font:var(--t-meta);color:var(--fg-3);overflow-wrap:anywhere}
.ls-meta a{color:var(--fg-2)}
.ls-rec{display:flex;align-items:center;gap:var(--s2)}
.ls-rec .prog-track{flex:1;min-width:40px}
.ls-rec .prog-label{flex:0 0 auto}
.ls-dl{font:var(--t-meta);color:var(--fg-2);text-decoration:underline;flex:0 0 auto}
.ls-more{width:100%;justify-content:center}

/* --- Calls: the collisions, fixed ---
   "11:47 AMPrinceton Excavation" was one grid column too narrow for humanWhen,
   so the two cells touched. TIME gets the room it needs and every cell keeps a
   real gap; COST sits in its own column instead of under the play button. */
.grid-calls,.call-row{grid-template-columns:152px minmax(0,1fr) 200px 104px 54px 62px 76px;gap:var(--s3)}
.cl-card .cell-time{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The number plus a "Blocked" pill has to fit without eating the number itself. */
.cl-card .cell-caller{display:flex;align-items:center;gap:6px;min-width:0}
.cl-card .cell-caller .pill{flex:0 0 auto}
.cl-card .cell-out{min-width:0}
.cl-card .cell-cost{white-space:nowrap}
.cl-card .cell-act{gap:6px;justify-content:flex-end;min-width:0}
/* The ⋯: where block lives now, so a real customer is never one tap from being
   rejected on all 11 lines. */
.cl-more{width:34px;height:34px;flex:0 0 auto;display:grid;place-items:center;border:1px solid var(--line-strong);background:transparent;color:var(--fg-3);border-radius:0;cursor:pointer;font:600 13px/1 var(--font-text);letter-spacing:.1em}
.cl-more:hover{color:var(--fg);border-color:var(--fg-4);background:var(--surface-2)}
/* Listening is one option among several, not the loudest thing on the row: the
   play button is a quiet icon here, not the page's solid-yellow primary. */
.cl-card .cell-act .play-btn{width:34px;height:34px;padding:0;background:transparent;border:1px solid var(--line-strong);color:var(--fg-2)}
.cl-card .cell-act .play-btn:hover{background:var(--surface-2);color:var(--fg);border-color:var(--fg-4)}
.cl-card .cell-act .play-btn.playing{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
/* Same in the lead sheet, where the row is already a card. */
.ls-rec .play-btn{width:34px;height:34px;padding:0;background:transparent;border:1px solid var(--line-strong);color:var(--fg-2)}
.ls-rec .play-btn:hover{background:var(--surface-2);color:var(--fg)}
.ls-rec .play-btn.playing{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
@media(max-width:1100px){.grid-calls,.call-row{grid-template-columns:140px minmax(0,1fr) 156px 92px 50px 60px 44px}.cl-card .cell-act .play-btn{display:none}}
/* On a phone the row is a stack, and the caller's name is the headline. Order is
   the reading order: who, when + where, what happened, how long, what it cost. */
@media(max-width:860px){
  /* Wrapped into two lines with a fixed ⋯ gutter on the right: line one is who
     and when, line two is which site, what happened, how long, what it cost.
     The ⋯ used to land between the number and the time, because it took the
     auto margin off the caller cell. */
  .cl-card .call-row{display:flex;flex-wrap:wrap;align-items:center;gap:5px 10px;padding:12px calc(var(--s4) + 44px) 12px var(--s4);position:relative}
  .cl-card .cell-caller{order:1;flex:1 1 auto;font:var(--t-row);white-space:normal}
  .cl-card .cell-time{order:2;flex:0 0 auto;margin-left:auto;font:var(--t-num-micro);color:var(--fg-3)}
  .cl-card .cell-site{order:3;flex:1 1 100%;font:var(--t-meta);color:var(--fg-3);white-space:normal}
  .cl-card .cell-out{order:4;flex:0 0 auto}
  .cl-card .cell-dur{order:5;flex:0 0 auto;min-width:34px;text-align:left}
  .cl-card .cell-cost{order:6;flex:0 0 auto;min-width:46px;text-align:left;margin-left:auto}
  /* The ⋯ is a fixed gutter, not part of the wrap, so it never splits the row. */
  .cl-card .cell-act{position:absolute;top:50%;right:calc(var(--s4) - 4px);transform:translateY(-50%);margin:0}
  .cl-card .cl-more{width:40px;height:40px}
  .cl-card .prog-row{padding:0 var(--s4) 11px}
}
/* one-time Twilio charges, shown apart from monthly spend */
.cost-shared--once{opacity:.85;margin-top:6px}
/* pipeline funnel (2026-08-28) */
.funnel{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 14px;margin:0 0 12px;background:var(--surface);border:1px solid var(--ln)}
.funnel__step{display:flex;flex-direction:column;min-width:64px}
.funnel__step b{font-size:20px;font-weight:700;font-variant-numeric:tabular-nums;line-height:1.1}
.funnel__step span{font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--tx3);margin-top:2px}
.funnel>i{font-style:normal;color:var(--tx3)}
.funnel__note{flex-basis:100%;font-size:12px;color:var(--tx3);margin-top:2px}

/* ===== Insights =====
   One column on every screen — the page is read on a phone between jobs, and a
   second column would only make the sentences narrower. Bars are divs: no chart
   library, and no yellow (yellow is the accent and belongs to actions). The
   strongest bar in a block uses --bl, the accent-free blue. */
#view-insights { max-width: 640px; }
.ins-seg { margin: 0 0 var(--s5); }
.ins-blk { padding: var(--s5) 0; border-top: 1px solid var(--ln); }
.ins-blk:first-of-type { border-top: 0; }
.ins-blk__h { display: flex; align-items: baseline; gap: var(--s3); margin: 0 0 var(--s2); font: var(--t-h2); letter-spacing: var(--track-tight); }
.ins-blk__n { font: var(--t-num-micro); color: var(--tx3); letter-spacing: 0; }
/* The sentence is the answer; the bars under it are only the evidence. */
.ins-say { margin: 0 0 var(--s4); font: var(--t-body); color: var(--tx2); }
.ins-sub { margin: var(--s4) 0 var(--s2); font: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--tx3); }
.ins-note { margin-top: var(--s2); font: var(--t-micro); color: var(--tx3); }

.ins-bar { display: flex; align-items: center; gap: var(--s3); width: 100%; padding: 7px 0; text-align: left; background: none; border: 0; }
.ins-bar[disabled] { cursor: default; }
.ins-bar:not([disabled]):hover .ins-bar__l { color: var(--tx); }
.ins-bar__l { flex: 0 0 104px; font: var(--t-row-sm); color: var(--tx2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ins-bar__track { flex: 1 1 auto; height: 10px; background: var(--surface-3); }
.ins-bar__fill { display: block; height: 100%; background: var(--tx3); }
.ins-bar--strong .ins-bar__fill { background: var(--bl); }
.ins-bar__n { flex: 0 0 auto; min-width: 34px; text-align: right; font: var(--t-num-micro); color: var(--tx2); }

/* Untagged is a to-do, not a scold: it sits first and offers the tap that fixes it. */
.ins-untag { display: flex; align-items: center; gap: var(--s2); width: 100%; padding: var(--s3); margin-bottom: var(--s2);
  text-align: left; background: var(--surface-2); border: 1px dashed var(--ln2); font: var(--t-row-sm); color: var(--tx2); }
.ins-untag b { font: var(--t-num-sm); color: var(--tx); }
.ins-untag__go { margin-left: auto; font: var(--t-micro); color: var(--bl); }
/* "Before tagging existed" is context, not a chore: solid border, muted, and it
   never offers to be fixed — those jobs are not going to be back-tagged. */
.ins-untag--old { border-style: solid; border-color: var(--ln); background: none; color: var(--tx3); }
.ins-untag--old b { color: var(--tx2); }
.ins-untag--old .ins-untag__go { color: var(--tx3); }
/* The basis line sits directly under a number that would otherwise be read as
   "every call that rang". */
.ins-note--basis { margin: -2px 0 var(--s2); }

/* The Improve line: dark, because it is the one thing on the page that is telling
   him something rather than showing him something. */
.ins-improve { display: block; width: 100%; text-align: left; padding: var(--s4); margin-bottom: var(--s5); background: var(--surface-inv); color: var(--on-inv); }
.ins-improve[disabled] { cursor: default; }
.ins-improve__k { display: block; font: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--on-inv-dim); margin-bottom: var(--s2); }
.ins-improve__s { display: block; font: var(--t-row); color: var(--on-inv); }
.ins-improve__t { display: block; margin-top: var(--s2); font: var(--t-micro); color: var(--on-inv-dim); }

.ins-jobs { display: flex; flex-direction: column; }
.ins-job { display: block; width: 100%; text-align: left; padding: var(--s3) 0; border-bottom: 1px solid var(--ln); background: none; }
.ins-job:last-child { border-bottom: 0; }
.ins-job__n { display: block; font: var(--t-row); color: var(--tx); }
.ins-job__m { display: block; margin-top: 2px; font: var(--t-meta); color: var(--tx3); }
/* The sheet scrolls its list, not its head — a long list must never push the
   title (which is the only thing saying WHICH jobs these are) off the screen. */
.ins-sheet-wrap { position: fixed; inset: 0; z-index: 90; }
.ins-sheet-wrap .dr-back { position: absolute; inset: 0; background: var(--scrim); }
.ins-sheet-wrap .mm-panel { width: min(520px, 96vw); top: 8vh; max-height: 80vh; display: flex; flex-direction: column; overflow: hidden; }
.ins-sheet-wrap .dr-head { flex: 0 0 auto; }
.ins-sheet-wrap .dr-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; }
/* On a phone it is a bottom sheet, like every other sheet in the app: the list
   reaches up from the thumb rather than floating in the middle of the screen. */
@media (max-width: 560px) {
  .ins-sheet-wrap .mm-panel { top: auto; bottom: 0; left: 0; transform: none; width: 100%;
    max-height: 86vh; border-radius: 20px 20px 0 0; padding-bottom: env(safe-area-inset-bottom); }
}

@media (max-width: 560px) {
  .ins-bar__l { flex-basis: 92px; }
  .ins-bar__n { font-size: 10px; }
}

/* ===== Merge / third parties (2026-08-28) ===== */
/* The handler's "Same person as X (job #N)?" question, answered in the drawer's
   Stage row with two buttons instead of a hunt through the ⋯ menu. */
/* Asks under History: a record of what the handler asked, worked in Quo — no controls. */
.jd-asks { margin-top: 12px; }
.jd-asks .eyebrow i { font-style: normal; text-transform: none; letter-spacing: 0; color: var(--fg-3); margin-left: 6px; }
.jd-ask { display: flex; gap: 10px; align-items: baseline; padding: 6px 0; border-top: 1px solid var(--line); font: var(--t-meta); }
.jd-ask__t { flex: 1; min-width: 0; color: var(--fg); }
.jd-ask__s { flex-shrink: 0; color: var(--fg-3); font-variant-numeric: tabular-nums; }
.jd-ask--done .jd-ask__t { color: var(--fg-3); text-decoration: line-through; }
/* People on this job who are not the customer: the HOA officer, the realtor,
   whoever pays. Each row carries the way to reach them, which is why they exist. */
.jd-parties { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--ln); }
.jd-party { padding: 6px 0; }
.jd-party + .jd-party { border-top: 1px dashed var(--ln); }
.jd-party__who { font: var(--t-row); color: var(--tx); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.jd-party__note { font: var(--t-meta); color: var(--tx3); margin-top: 2px; }
/* "pays · on site" — the two facts the calendar event and the crew text read. */
.jd-party__flags { font: var(--t-meta); color: var(--tx2); }
.jd-party__acts { margin-top: 6px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* The role + flags sheet (personSheet): identity fields on top when the person is
   being typed in, the role list in the middle, the two flags underneath. */
.ps__ids { display: grid; gap: 6px; flex: 0 0 auto; }
.ps__f { display: grid; gap: 2px; }
.ps__f input { height: 34px; background: var(--surface-2); border: 1px solid var(--ln2); border-radius: 0; padding: 0 9px; font-size: 13px; color: var(--tx); }
.ps__f input:focus { border-color: var(--ac); outline: none; }
.ps__flags { display: grid; gap: 4px; flex: 0 0 auto; padding-top: 6px; border-top: 1px solid var(--ln); }
.ps__flags .dr-chk b { font-weight: 700; }

/* ===== PWA: offline line, install hint, update toast (2026-08-28) ===== */

/* "showing data from 12:14 PM · offline" — sits above the page head, full
   width, quiet. It is a fact about the data, not an error, so it uses the
   muted surface rather than red: the numbers below it are real, just old. */
.offbar {
  padding: 7px var(--s4);
  background: var(--surface-3); color: var(--fg-2);
  font: var(--t-meta); letter-spacing: .01em;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 8px;
}
.offbar::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--fg-3); flex: none;
}

/* Add to Home Screen, iOS Safari only. Sits above the tab bar, clears the home
   indicator, and is dismissed for good with the x. */
.a2hs {
  position: fixed; left: 10px; right: 10px;
  bottom: calc(var(--s3) + var(--safe-b));
  z-index: 140;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 12px 12px 14px;
  background: var(--surface-inv); color: var(--on-inv);
  box-shadow: var(--shadow-toast);
  animation: slideUp .22s var(--ease);
}
.a2hs__b { display: flex; flex-direction: column; gap: 3px; }
.a2hs__b b { font: var(--t-row); }
.a2hs__b span { font: var(--t-meta); color: var(--on-inv-dim); }
.a2hs__b span b { color: var(--on-inv); font: 700 12px/1.45 var(--font-text); }
.a2hs__x {
  margin-left: auto; flex: none;
  width: 30px; height: 30px; border: 0; background: none;
  color: var(--on-inv-dim); font-size: 20px; line-height: 1; cursor: pointer;
}
/* On a phone the hint clears the tab bar; on a desktop it never renders, but
   keep it out of the rail's way anyway. */
@media (max-width: 700px) { .a2hs { bottom: calc(74px + var(--safe-b)); } }
@media (min-width: 701px) { .a2hs { left: auto; right: 18px; max-width: 380px; } }

/* A new service worker took over. Same shape as the undo toast — one line and
   one button — because it is the same kind of message: something happened, and
   here is the one thing you can do about it. */
.toast--update { z-index: 150; }

/* Undo for a handler write, at the top of the drawer's Timeline. The button is
   a ghost action (never primary — undoing is a correction, not the next step)
   with the consequence spelled out underneath, the same shape as every other
   place the dashboard says what a tap will do before it does it. */
.jd-undo { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.jd-undo .act { align-self: flex-start; }
.jd-undo__s { font-size: 12px; color: var(--tx3); line-height: 1.45; }

/* ===== Bank freshness caption (2026-08-29) =====
   How old the bank numbers are, said in one line above the numbers themselves. It sits
   on the Money tab header and again on the Bank inbox card, so "as of" is never a thing
   the operator has to go looking for.

   Reserved height (min-height + the same font in all three states) is the point: the
   line changes from muted to warning to error between polls, and a caption that grows
   a second line would push the KPI row down under the operator's thumb. The warning
   text wraps INSIDE the reserved box instead. All colours are tokens, so light and dark
   both come out right without a second rule. */
.bank-fresh {
  font: var(--t-meta);
  color: var(--fg-3);
  min-height: 17px;
  line-height: 1.45;
  margin: 6px 2px 0;
}
.bank-fresh--top { margin: -2px 2px 10px; }
.bank-fresh--card { margin: 6px 0 4px; }
/* SimpleFIN is behind — the sync is healthy, so this is amber, not red. */
.bank-fresh--warn { color: var(--accent-text); }
/* The sync itself failed after its last good run: the numbers below are stale by an
   unknown amount, which is the one bank state that is actually broken. */
.bank-fresh--err { color: var(--crit); }

/* --- Contract & Quote sheets (docs/CONTRACTS_IN_APP.md) ---
   Same panel as the confirm/pick sheets, but taller and scrollable: these two
   carry a form, and on a phone the fields must not push the buttons off the
   screen. Only the body scrolls, so Generate is always reachable. */
.cfm__panel--doc{display:flex;flex-direction:column;gap:10px;width:min(460px,94vw);max-height:90vh;overflow:hidden}
.cfm__panel--doc .cfm__t,.cfm__panel--doc .cfm__acts{flex:0 0 auto}
.doc__body{display:grid;gap:9px;flex:1 1 auto;min-height:0;overflow-y:auto;margin:0 -4px;padding:2px 4px;-webkit-overflow-scrolling:touch}
.cfm__panel--doc .cfm__acts{flex-wrap:wrap;gap:6px}
.cfm__panel--doc .cfm__acts .act{flex:1 1 auto;text-align:center;text-decoration:none;display:inline-flex;align-items:center;justify-content:center}

/* Paperwork block in the drawer: the PDFs that already exist, as buttons. */
.jd-docs{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.jd-docs .act{text-decoration:none}

/* The quote's itemised table: what it is, what it costs, and a way to drop the
   line. Wide enough to type in on a phone, narrow enough that the price stays
   beside the label instead of wrapping under it. */
.qz-lines{display:grid;gap:5px}
.qz-line{display:grid;grid-template-columns:1fr 84px 32px;gap:5px;align-items:center}
.qz-line input{height:42px;padding:0 10px;background:var(--surface);border:1px solid var(--line-strong);color:var(--fg);font:14px/1 var(--font-text);border-radius:0;min-width:0}
.qz-line input:focus{outline:2px solid var(--accent);outline-offset:-2px}
.qz-line .qz-p{text-align:right;font-family:var(--font-mono,ui-monospace,monospace)}
.qz-x{height:42px;background:transparent;border:1px solid var(--ln);color:var(--tx3);font-size:18px;line-height:1;cursor:pointer;border-radius:0}
.qz-x:hover{color:var(--fg);border-color:var(--line-strong)}
.qz-tiers{margin-top:2px}
/* The running total, in the same statement voice the Money block uses. */
.qz-sum{display:grid;gap:2px;border-top:1px solid var(--ln);padding-top:8px;margin-top:2px}
.qz-check{display:flex;gap:8px;align-items:flex-start;font:13px/1.4 var(--font-text);color:var(--tx2);cursor:pointer;padding:2px 0}
.qz-check input{margin-top:1px;flex:0 0 auto;width:18px;height:18px;accent-color:var(--accent)}

/* The one question that turns a receipt into a pass-through: "is he paying this
   back?". A row, not a field, because it is a yes/no about money that is already
   typed in — and it sits directly above the amount it changes. */
.mm-check { display: flex; align-items: center; gap: 9px; padding: 10px 12px; margin-top: 8px;
  border: var(--border) solid var(--line); border-radius: var(--r1); background: var(--surface-2); cursor: pointer; }
.mm-check input[type=checkbox] { accent-color: var(--accent); width: 16px; height: 16px; margin: 0; flex: none; }
.mm-check span { font: var(--t-row-sm); color: var(--fg); }

/* =====================================================================
   The two drawers, split (2026-09-04). Spec: scratchpad drawers/Main.dc.html
   (JOB) and Appointment.dc.html (APPOINTMENT).
   JOB = the money and the stage. Leads with the name and the price; owns
   What, When-as-a-list, Money, Who, Notes; one button, Mark done.
   APPOINTMENT = a block of time. Leads with the date and the hours under a
   band in the calendar's colour; owns which kind of time it is, When, who's
   going, notes for the crew; one button, Save.
   Same structure at 390px and at the 520px desktop drawer.
   ===================================================================== */
:root{--visit:#0E8C78}
[data-theme='dark']{--visit:#62C6B4}
@media (prefers-color-scheme: dark){:root:not([data-theme='light']){--visit:#62C6B4}}

/* --- shared bones --- */
.dr-panel.jd-panel,.dr-panel.ap-panel{display:flex;flex-direction:column}
.jd-top{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:44px}
.jd-eyebrow{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--fg-4)}
.jd-panel .dr-close,.ap-panel .dr-close{width:44px;height:44px;border:0;background:transparent;color:var(--fg-3);font-size:22px;line-height:1;display:grid;place-items:center;margin-right:-12px}
.jd-panel .dr-close:hover,.ap-panel .dr-close:hover{color:var(--fg);background:var(--surface-2)}
.jd-head,.ap-head{display:block;padding:8px 20px 0;border-bottom:0}
.jd-body{padding:0 20px 28px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:0}
.jd-sec{padding:22px 0 0;border:0;display:flex;flex-direction:column;gap:8px}
.jd-sec:last-child{padding-bottom:8px}
.jd-label{font:var(--t-label);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--fg-4)}
.jd-list{display:flex;flex-direction:column;border-top:1px solid var(--line)}
.jd-row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:44px;border-bottom:1px solid var(--line);font:400 15px/1.3 var(--font-text);color:var(--fg)}
.jd-row .mono{font:500 15px/1 var(--font-mono);color:var(--fg);font-variant-numeric:tabular-nums;white-space:nowrap}
.jd-row--total{min-height:48px;border-bottom:1px solid var(--line-heavy);font-weight:700}
.jd-row--total .mono{font:600 17px/1 var(--font-mono)}
.jd-row .c-ok{color:var(--ok)}
/* A tip is money he was given, not money he was owed (2026-09-07). It is indented
   under Paid so it reads as part of that payment rather than a line of its own in
   the price, and it never touches the balance below it. */
.jd-row--tip{min-height:36px;padding-left:14px;font-size:14px;color:var(--fg-3)}
.jd-row--tip .mono{font:500 14px/1 var(--font-mono)}
/* A CLAIM: money somebody SAID was sent and the bank has not shown. Muted, and
   never summed into Collected — bank is truth, text is a claim. */
.jd-row--expect{min-height:36px;font-size:14px;color:var(--fg-3);font-style:italic}
.jd-row--expect .mono{font:500 12px/1 var(--font-mono);color:var(--fg-4);font-style:normal}
.jd-add{display:flex;align-items:center;min-height:44px;padding:0;border:0;background:transparent;font:600 14px/1 var(--font-text);color:var(--info);cursor:pointer;text-align:left;width:100%}
.jd-add:hover{color:var(--fg)}
.jd-primary{flex:1 1 0;min-height:46px;display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--accent);color:var(--accent-ink);border:1px solid var(--accent);border-radius:0;font:700 14px/1 var(--font-display);cursor:pointer;padding:0 16px;white-space:nowrap}
.jd-primary:hover{background:var(--accent-dim);border-color:var(--accent-dim)}
.jd-primary:disabled{opacity:.55;cursor:default}
.jd-text{font:400 15px/1.45 var(--font-text);color:var(--fg);white-space:pre-wrap;word-break:break-word}
.jd-text--muted{color:var(--fg-2)}
.jd-tap{cursor:text;min-height:24px;position:relative;padding-right:0}
.jd-tap:hover{background:var(--surface-2);box-shadow:0 0 0 6px var(--surface-2)}
.jd-tap.is-empty{color:var(--fg-4);font-style:italic}
.jd-edit{width:100%;min-height:96px;border:1px solid var(--focus);background:var(--surface);font:400 15px/1.45 var(--font-text);color:var(--fg);padding:10px 12px;resize:vertical;outline:none}
.jd-details{border-top:1px solid var(--line);margin-top:4px}
.jd-details>summary{list-style:none;cursor:pointer;min-height:44px;display:flex;align-items:center;justify-content:space-between;gap:8px;font:600 14px/1.2 var(--font-text);color:var(--fg-2)}
.jd-details>summary::-webkit-details-marker{display:none}
.jd-details>summary::after{content:'';width:7px;height:7px;border-right:1.8px solid var(--fg-4);border-bottom:1.8px solid var(--fg-4);transform:rotate(45deg);margin-right:6px;transition:transform var(--dur-2) var(--ease)}
.jd-details[open]>summary::after{transform:rotate(-135deg)}
.jd-details__body{display:flex;flex-direction:column;gap:12px;padding:2px 0 14px}
.jd-fields{display:grid;gap:12px}
.jd-fields .dr-row{display:flex;gap:10px}
.jd-fields .dr-fld .eyebrow{margin-bottom:6px}
.jd-chev{flex-shrink:0;color:var(--fg-4)}

/* --- JOB header: name, price, what is still owed, stage chips, one button --- */
.jd-name{font:800 26px/1.05 var(--font-display);letter-spacing:var(--track-tight);color:var(--fg);padding-top:2px;word-break:break-word}
.jd-priceline{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding-top:6px}
.jd-price{font:500 22px/1 var(--font-mono);color:var(--fg);font-variant-numeric:tabular-nums}
.jd-price--none{font:400 15px/1.4 var(--font-text);color:var(--fg-3)}
.jd-owe{font:400 14px/1.4 var(--font-text);color:var(--fg-3)}
.jd-owe--paid{color:var(--ok)}
.jd-chips{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding-top:14px}
.jd-chips .chip{height:22px;padding:0 9px;font:700 11px/1 var(--font-text);letter-spacing:.04em;display:inline-flex;align-items:center}
.jd-acts{display:flex;gap:8px;padding-top:16px}
.jd-acts .jd-more{width:46px;height:46px;min-width:46px;display:grid;place-items:center;border:1px solid var(--line-strong);background:transparent;color:var(--fg-2);border-radius:0;font-size:18px;letter-spacing:0;cursor:pointer}
.jd-acts .jd-more:hover{background:var(--surface-2);color:var(--fg)}
.jd-head .jd-booked{margin:14px 0 0;padding:10px 12px;background:var(--surface-2);border-left:3px solid var(--info);font:var(--t-body);color:var(--fg-2)}
/* Stage chip colour = what the stage means. */
.chip--stage-New,.chip--stage-Contacted,.chip--stage-Quoted{background:var(--mute-wash);color:var(--mute)}
.chip--stage-Won{background:var(--accent-wash);color:var(--accent-text-2)}
.chip--stage-Scheduled{background:var(--info-wash);color:var(--info)}
.chip--stage-Done{background:var(--ok-wash);color:var(--ok)}
.chip--stage-Lost,.chip--stage-Spam,.chip--stage-Duplicate{background:var(--crit-wash);color:var(--crit)}
.chip--stage-Referred,.chip--stage-Applicant{background:var(--mute-wash);color:var(--mute)}

/* --- JOB · WHEN: the appointments, as a short list --- */
.jd-appt{display:flex;align-items:center;gap:12px;min-height:56px;border:0;border-bottom:1px solid var(--line);background:transparent;padding:0;width:100%;text-align:left;cursor:pointer;color:var(--fg)}
.jd-appt:hover{background:var(--surface-2)}
.jd-appt:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.jd-bar{width:4px;align-self:stretch;background:var(--info);flex-shrink:0}
.jd-appt__main{display:flex;flex-direction:column;gap:3px;flex:1 1 0;min-width:0;padding:8px 0}
.jd-appt__t{font:600 15px/1.25 var(--font-text);color:var(--fg)}
.jd-appt__t .chip{margin-left:6px;vertical-align:1px}
.jd-appt__when{font:500 13px/1 var(--font-mono);color:var(--fg-data);font-variant-numeric:tabular-nums}
.jd-appt--done .jd-appt__t{color:var(--fg-2)}
.jd-empty{font:var(--t-body);color:var(--fg-3);min-height:44px;display:flex;align-items:center;border-bottom:1px solid var(--line)}
.jd-workdate{font:var(--t-meta);color:var(--fg-3);padding-top:6px}

/* --- JOB · MONEY --- */
.jd-money .jd-row:first-child{border-top:0}
.jd-paper{display:flex;gap:8px;flex-wrap:wrap;align-items:center;padding-top:10px}
.jd-paper .jd-label{flex:1 0 100%}
.jd-docs{flex:1 0 100%;display:flex;flex-direction:column;gap:2px;padding-top:6px}
.jd-doc{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:6px 0;border-top:1px solid var(--line, #e6e3dd);text-decoration:none;color:var(--fg)}
.jd-doc__name{font:500 14px/1.3 var(--font-text)}
.jd-doc__date{font:500 12px/1 var(--font-mono);color:var(--fg-muted, #777);white-space:nowrap}
.jd-money .jd-stmt{padding-top:6px}
.jd-money .pc-x-btns{padding-top:8px}

/* --- JOB · WHO --- */
.jd-who__addr{font:600 15px/1.25 var(--font-text);color:var(--fg)}
.jd-who__phone{font:500 14px/1 var(--font-mono);color:var(--fg-data);padding-top:3px}
.jd-who__phone a{color:inherit;text-decoration:none}
.jd-who__phone a:hover{text-decoration:underline}
.jd-who__acts{padding-top:6px}
.jd-who__acts .acts{display:flex;gap:8px}
.jd-who__acts .acts .act{flex:1 1 0;height:44px;min-height:44px;font:700 13px/1 var(--font-display);border:1px solid var(--fg);color:var(--fg);background:transparent}
.jd-who__acts .acts .act--primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.jd-who__acts .acts .act:hover{background:var(--surface-2)}
.jd-who__acts .acts .act--primary:hover{background:var(--accent-dim)}
.jd-who__meta{font:var(--t-meta);color:var(--fg-3);display:flex;flex-direction:column;gap:3px;padding-top:6px}
.jd-who .jd-parties{padding-top:12px}
.jd-who .jd-parties>.eyebrow{margin-bottom:6px}

/* --- JOB · save bar: only when something changed --- */
.jd-savebar{display:flex;align-items:center;gap:10px;padding:12px 20px calc(12px + env(safe-area-inset-bottom));border-top:1px solid var(--line);background:var(--surface);position:sticky;bottom:0;box-shadow:0 -8px 20px rgba(20,23,26,.06)}
.jd-savebar[hidden]{display:none}
.jd-savebar .act{min-height:46px}
.jd-savebar .dr-msg{margin-left:auto}

/* --- APPOINTMENT: band, date, hours, job card --- */
.ap-band{height:6px;background:var(--ap-color,var(--info));flex-shrink:0}
.ap-eyebrow{color:var(--ap-color,var(--info))}
.ap-date{font:800 26px/1.05 var(--font-display);letter-spacing:var(--track-tight);color:var(--fg);padding-top:2px}
.ap-hours{font:500 22px/1 var(--font-mono);color:var(--fg);padding-top:6px;font-variant-numeric:tabular-nums}
.ap-pills{display:flex;gap:6px;flex-wrap:wrap;padding-top:10px}
.ap-pills:empty{display:none}
.ap-body{padding:0 20px 28px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:0}
.ap-job{display:flex;align-items:center;gap:12px;margin:16px 0 0;min-height:60px;padding:8px 12px 8px 14px;background:var(--surface-2);border:1px solid var(--line);width:100%;text-align:left;cursor:pointer;color:var(--fg);border-radius:0}
.ap-job:hover{border-color:var(--line-strong);background:var(--surface-3)}
.ap-job__main{display:flex;flex-direction:column;gap:3px;flex:1 1 0;min-width:0}
.ap-job__n{font:600 15px/1.25 var(--font-text);color:var(--fg)}
.ap-job__s{font:400 13px/1.3 var(--font-text);color:var(--fg-3)}
.ap-seg{display:flex;border:1px solid var(--fg)}
.ap-seg__opt{flex:1 1 0;height:44px;display:flex;align-items:center;justify-content:center;font:700 13px/1 var(--font-display);color:var(--fg);cursor:pointer;position:relative}
.ap-seg__opt input{position:absolute;opacity:0;width:0;height:0}
.ap-seg__opt:has(input:checked){background:var(--surface-inv);color:var(--on-inv)}
.ap-seg__opt:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:-2px}
.ap-help{font:400 12px/1.45 var(--font-text);color:var(--fg-4)}
.ap-row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:48px;border-bottom:1px solid var(--line);cursor:pointer}
.ap-row__l{font:400 15px/1 var(--font-text);color:var(--fg);flex-shrink:0}
.ap-row__in{border:0;background:transparent;font:500 15px/1 var(--font-mono);color:var(--fg);text-align:right;padding:8px 0;min-height:44px;max-width:62%;font-variant-numeric:tabular-nums;color-scheme:light dark}
.ap-row__in:focus{outline:2px solid var(--focus);outline-offset:-2px;background:var(--surface-2)}
.ap-row .toggle{min-height:44px}
.ap-row .toggle__track{width:44px;height:26px}
.ap-row .toggle__track::after{width:20px;height:20px}
.ap-row .toggle input:checked+.toggle__track::after{transform:translateX(18px)}
/* Who's going: checked rows read as people going; the rest wait behind + Add crew. */
.ap-crew .crew-row{display:none;grid-template-columns:32px 1fr 92px;gap:12px;align-items:center;min-height:56px;padding:6px 0;border:0;border-bottom:1px solid var(--line);background:transparent;border-radius:0}
.ap-crew .crew-row:has(input:checked),.ap-crew.ap-crew--all .crew-row{display:grid}
.ap-crew .crew-row input[type=checkbox]{position:absolute;opacity:0;width:0;height:0}
.ap-crew .crew-row.dis{opacity:.5}
.ap-av{width:32px;height:32px;display:grid;place-items:center;background:var(--crew-1);color:#fff;font:700 13px/1 var(--font-display);position:relative}
.ap-crew .crew-row:not(:has(input:checked)) .ap-av{background:transparent;border:1.5px dashed var(--line-strong);color:var(--fg-3)}
.ap-crew .crew-name{font:600 15px/1.25 var(--font-text);color:var(--fg);gap:3px}
.ap-crew .crew-name small{font:400 13px/1.3 var(--font-text);color:var(--fg-3)}
.ap-crew .crew-name small.crew-off{color:var(--crit)}
.ap-crew .crew-name small.crew-off:empty{display:none}
.ap-crew .crew-name .crew-reach{display:inline-flex;gap:6px;margin-top:2px}
.ap-crew .crew-pay{height:36px;border:1px solid var(--line-strong);background:var(--surface-2);font:500 15px/1 var(--font-mono);color:var(--fg);text-align:right;padding:0 8px;width:100%}
.ap-crew .crew-pay:disabled{opacity:.35}
.ap-crew .crew-pay:focus{border-color:var(--focus);outline:2px solid var(--focus);outline-offset:-1px}
.ap-crew .crew-pay-blank{display:block}
.ap-crew .crew-row:not(:has(input:checked)) .crew-pay{visibility:hidden}
.ap-crew .crew-row:not(:has(input:checked)) .crew-name small.ap-going{display:none}
.ap-notes{width:100%;min-height:96px;font:400 15px/1.45 var(--font-text);color:var(--fg);padding:12px 14px;background:var(--surface-2);border:1px solid var(--line);resize:vertical}
.ap-notes:focus{outline:2px solid var(--focus);outline-offset:-1px;border-color:var(--focus);background:var(--surface)}
.ap-texts .dr-toggles{background:transparent;border:0;padding:0;display:grid;gap:6px}
.ap-texts .dr-chk{white-space:normal;min-height:32px;line-height:1.3}
.ap-texts .notice{margin-bottom:6px}
.ap-meta{font:var(--t-meta);color:var(--fg-3);display:flex;flex-direction:column;gap:4px;padding-top:12px}
.ap-meta a{color:var(--info)}
.ap-margin{font:var(--t-meta);color:var(--fg-3);padding-top:6px}
.ap-margin b{font-family:var(--font-mono);font-weight:500}
.ap-foot{display:flex;flex-direction:column;gap:14px;padding:22px 0 0}
.ap-foot .jd-primary{width:100%}
.ap-foot__row{display:flex;gap:8px}
.ap-foot__row .act{flex:1 1 0;min-height:44px}
.ap-remove{display:flex;align-items:center;justify-content:center;min-height:44px;border:0;background:transparent;font:600 14px/1 var(--font-text);color:var(--crit);cursor:pointer;width:100%}
.ap-remove:hover{text-decoration:underline}
.ap-panel .dr-msg{padding:6px 0 0}
/* Unlinked or lead-network events: the few fields that still live here. */
.ap-fields{display:grid;gap:12px}
.ap-fields .dr-row{display:flex;gap:10px}
.jd-details__hint{font:400 13px/1.3 var(--font-text);color:var(--fg-4);margin-left:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}
.jd-label-line{font:var(--t-meta);color:var(--fg-3);padding-top:4px}
.jd-panel .pc-tl{font-size:12.5px}
.jd-panel .jd-party{padding:8px 0;border-bottom:1px solid var(--line)}
.jd-panel .jd-party__acts{display:flex;gap:6px;flex-wrap:wrap;padding-top:6px}
.jd-panel .pc-other{padding-top:6px}
.ap-people{margin-top:8px;padding:10px 12px;background:var(--surface-2);border-left:3px solid var(--info);font:var(--t-body);color:var(--fg-2);display:flex;flex-direction:column;gap:4px}
.ap-people .dr-chk{min-height:32px}
