/* Terramorph Dashboard — "work order" system.
   An operations tool, not a brochure: a pine sidebar with the pages grouped by job, a compact title bar,
   hairline-ruled lists and ledger-style numbers. Archivo Narrow (equipment-decal condensed) for titles and figures,
   Archivo for reading, IBM Plex Mono for anything you'd read off a ticket: times, job and unit numbers, phones.
   Brand colors from terramorphllc.com (pine, forest, gold, cream), used sparingly. No gradients, glows or fade-ins.
   hub.js builds the shell (sidebar, title bar, phone tab bar) around each page's .wrap. */
@import url("https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700&family=Archivo+Narrow:wght@500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap");

:root{
  --bg:#F2F0EA; --panel:#FFFFFF; --panel-2:#F8F7F3; --sunk:#ECE9E1; --ink:#15190F; --ink-2:#3B4237; --muted:#6B7266; --faint:#9AA096;
  --line:#E2DED4; --line-2:#D2CCBF;
  --accent:#1D4C2F; --accent-2:#26603C; --accent-ink:#FFFFFF; --accent-soft:#E3EDE5; --soft:#EFECE5;
  --gold:#A87A22; --gold-2:#C8962E; --gold-soft:#F4EAD2;
  --good:#22713F; --good-bg:#E4F1E7; --warn:#946000; --warn-bg:#F7EDD6; --bad:#B0302A; --bad-bg:#F8E3E1;
  --team:#2B5B9E; --team-bg:#E3EBF7;
  --side:#0F2318; --side-2:#163122; --side-ink:#E7ECE6; --side-muted:#8FA393; --side-line:rgba(231,236,230,.09);
  --hero-1:#0F2318; --hero-2:#163122; --hero-ink:#F2F0EA; --hero-muted:#AEB9AF; --hero-line:rgba(242,240,234,.14);
  --shadow:0 1px 0 rgba(21,25,15,.04); --shadow-lift:0 12px 32px -12px rgba(21,25,15,.28),0 2px 6px rgba(21,25,15,.06);
  --r:10px; --r-sm:7px;
  --brand:"Archivo Narrow","Arial Narrow",system-ui,sans-serif; --serif:var(--brand);
  --body:"Archivo",system-ui,-apple-system,"Segoe UI",sans-serif; --mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;
  --side-w:236px; --top-h:58px;
  color-scheme:light;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --bg:#0E100F; --panel:#151816; --panel-2:#1A1D1B; --sunk:#111312; --ink:#E9EBE6; --ink-2:#C4C9C1; --muted:#8C938A; --faint:#5F665D;
  --line:#242825; --line-2:#323833;
  --accent:#86C49B; --accent-2:#A2D4B2; --accent-ink:#0B1A10; --accent-soft:#17271D; --soft:#1D211E;
  --gold:#D9AE55; --gold-2:#E7C377; --gold-soft:#2B2414;
  --good:#7CCB97; --good-bg:#15291C; --warn:#E7B456; --warn-bg:#2C2312; --bad:#F08B83; --bad-bg:#331816;
  --team:#93B8F2; --team-bg:#172338;
  --side:#0A1610; --side-2:#11211A; --side-line:rgba(231,236,230,.07);
  --shadow:none; --shadow-lift:0 16px 40px -14px rgba(0,0,0,.7),0 2px 8px rgba(0,0,0,.4);
  color-scheme:dark}}
:root[data-theme="dark"]{
  --bg:#0E100F; --panel:#151816; --panel-2:#1A1D1B; --sunk:#111312; --ink:#E9EBE6; --ink-2:#C4C9C1; --muted:#8C938A; --faint:#5F665D;
  --line:#242825; --line-2:#323833;
  --accent:#86C49B; --accent-2:#A2D4B2; --accent-ink:#0B1A10; --accent-soft:#17271D; --soft:#1D211E;
  --gold:#D9AE55; --gold-2:#E7C377; --gold-soft:#2B2414;
  --good:#7CCB97; --good-bg:#15291C; --warn:#E7B456; --warn-bg:#2C2312; --bad:#F08B83; --bad-bg:#331816;
  --team:#93B8F2; --team-bg:#172338;
  --side:#0A1610; --side-2:#11211A; --side-line:rgba(231,236,230,.07);
  --shadow:none; --shadow-lift:0 16px 40px -14px rgba(0,0,0,.7),0 2px 8px rgba(0,0,0,.4);
  color-scheme:dark}

*{box-sizing:border-box} [hidden]{display:none!important}
html,body{margin:0}
html{-webkit-text-size-adjust:100%}
body{background:var(--bg);color:var(--ink);font-family:var(--body);font-size:14.5px;line-height:1.5;-webkit-font-smoothing:antialiased;min-height:100vh;overflow-x:hidden;font-feature-settings:"ss01"}
a{color:var(--accent);text-underline-offset:2px}
::selection{background:var(--gold-soft);color:var(--ink)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.wrap{max-width:1240px;margin:0;padding:22px 28px 96px;position:relative}
@media (max-width:999px){.wrap{padding:16px 16px calc(96px + env(safe-area-inset-bottom,0px))}}

/* ================= shell (built by hub.js) ================= */
body.shell{display:grid;grid-template-columns:var(--side-w) minmax(0,1fr)}
.rail{position:sticky;top:0;height:100vh;height:100dvh;background:var(--side);color:var(--side-ink);display:flex;flex-direction:column;border-right:1px solid var(--side-line);z-index:30}
.rail .brandrow{display:flex;align-items:center;gap:10px;padding:16px 18px 14px;text-decoration:none;color:inherit;border-bottom:1px solid var(--side-line)}
.rail .brandrow img{width:30px;height:auto}
.rail .brandrow b{font-family:var(--brand);font-weight:700;font-size:1.08rem;letter-spacing:.16em;line-height:1}
.rail .brandrow small{display:block;font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;color:var(--side-muted);margin-top:4px}
.rail nav{flex:1;overflow-y:auto;padding:8px 10px 12px;scrollbar-width:thin;scrollbar-color:var(--side-2) transparent}
.rail .grp{font-size:.68rem;font-weight:600;color:var(--side-muted);padding:14px 10px 5px;letter-spacing:.02em}
/* Folding sidebar sections (2026-10-29) */
.rail button.grp{display:flex;align-items:center;justify-content:space-between;width:100%;background:none;border:0;font-family:inherit;text-align:left;cursor:pointer;border-radius:8px}
.rail button.grp:hover:not(:disabled){color:var(--side-ink,inherit)} .rail button.grp:disabled{cursor:default;opacity:1}
.rail button.grp i{font-style:normal;font-size:.62rem;font-weight:700;opacity:.7;display:inline-flex;align-items:center;gap:4px}
.rail button.grp i::after{content:"›";font-size:.95rem;line-height:1;transition:transform .15s}
.rail .grpw.open button.grp i::after{transform:rotate(90deg)}
.rail .grpw:not(.open) .grpl{display:none}
.rail nav a{display:flex;align-items:center;gap:11px;padding:7px 10px;margin:1px 0;border-radius:6px;color:#C9D3CA;text-decoration:none;font-weight:500;font-size:.9rem;position:relative}
.rail nav a svg{width:17px;height:17px;flex:none;opacity:.7}
.rail nav a:hover{background:var(--side-2);color:#fff}
.rail nav a[aria-current="page"]{background:var(--side-2);color:#fff;font-weight:600}
.rail nav a[aria-current="page"]::before{content:"";position:absolute;left:-10px;top:7px;bottom:7px;width:3px;border-radius:0 2px 2px 0;background:var(--gold-2)}
.rail nav a[aria-current="page"] svg{opacity:1;color:var(--gold-2)}
.rail nav a .cnt{margin-left:auto;font-family:var(--mono);font-size:.7rem;font-weight:600;color:#0F2318;background:var(--gold-2);border-radius:4px;padding:0 5px;line-height:1.5}
.rail .me{border-top:1px solid var(--side-line);padding:10px 12px;display:flex;align-items:center;gap:10px}
.rail .me .av{width:30px;height:30px;border-radius:6px;background:var(--side-2);display:grid;place-items:center;font-family:var(--brand);font-weight:700;font-size:.85rem;color:var(--gold-2);flex:none}
.rail .me .nm{min-width:0;flex:1;line-height:1.25}
.rail .me .nm b{display:block;font-size:.84rem;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rail .me .nm span{font-size:.72rem;color:var(--side-muted);text-transform:capitalize}
.rail .me button,.rail .me a{width:30px;height:30px;display:grid;place-items:center;border-radius:6px;background:none;border:0;color:var(--side-muted);cursor:pointer}
.rail .me button:hover,.rail .me a:hover{background:var(--side-2);color:#fff}
.rail .me svg{width:17px;height:17px}

.main{min-width:0;display:flex;flex-direction:column;min-height:100vh}
.topbar{position:sticky;top:0;z-index:20;height:var(--top-h);display:flex;align-items:center;gap:12px;padding:0 28px;background:color-mix(in srgb,var(--bg) 88%,transparent);
  -webkit-backdrop-filter:saturate(1.4) blur(10px);backdrop-filter:saturate(1.4) blur(10px);border-bottom:1px solid var(--line)}
.topbar .crumb{display:flex;align-items:center;gap:6px;min-width:0;flex:1}
.topbar .up{display:inline-flex;align-items:center;gap:4px;color:var(--muted);text-decoration:none;font-size:.86rem;font-weight:500;white-space:nowrap}
.topbar .up:hover{color:var(--ink)}
.topbar .up svg{width:15px;height:15px}
.topbar .slash{color:var(--faint);font-size:.9rem}
.topbar h1{font-family:var(--brand);font-weight:700;font-size:1.32rem;letter-spacing:.005em;margin:0;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--ink)}
.topbar .info{width:24px;height:24px;border-radius:50%;border:1px solid var(--line-2);background:none;color:var(--muted);display:grid;place-items:center;cursor:pointer;flex:none;padding:0}
.topbar .info svg{width:14px;height:14px}
.topbar .info:hover,.topbar .info[aria-expanded="true"]{color:var(--ink);border-color:var(--ink-2)}
.topbar .tools{display:flex;align-items:center;gap:8px;flex:none}
.topbar .search{display:flex;align-items:center;gap:8px;height:34px;width:230px;padding:0 8px 0 10px;border:1px solid var(--line-2);border-radius:7px;background:var(--panel);color:var(--muted);font:inherit;font-size:.86rem;cursor:pointer;text-align:left}
.topbar .search svg{width:15px;height:15px;flex:none}
.topbar .search span{flex:1}
.topbar kbd,.hint kbd{font-family:var(--mono);font-size:.68rem;padding:1px 5px;border-radius:4px;border:1px solid var(--line-2);color:var(--muted);background:var(--panel-2)}
.topbar .ask{display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 12px;border-radius:7px;border:1px solid var(--accent);background:var(--accent);color:var(--accent-ink);font:inherit;font-size:.86rem;font-weight:600;cursor:pointer}
.topbar .ask svg{width:15px;height:15px}
.topbar .ask:hover{background:var(--accent-2);border-color:var(--accent-2)}
.topbar .ib{width:34px;height:34px;display:grid;place-items:center;border-radius:7px;border:1px solid var(--line-2);background:var(--panel);color:var(--ink-2);cursor:pointer;padding:0}
.topbar .ib svg{width:16px;height:16px}
.topbar .ib:hover,.topbar .search:hover{border-color:var(--ink-2);color:var(--ink)}
.topbar .mark{display:none}
.about{margin:0 28px;padding:12px 14px;border:1px solid var(--line);border-top:0;border-radius:0 0 8px 8px;background:var(--panel);color:var(--ink-2);font-size:.88rem;max-width:760px;line-height:1.55}
.about p{margin:0}

/* + New menu */
.newwrap{position:relative}
.newbtn{display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 12px 0 10px;border-radius:7px;border:1px solid var(--line-2);background:var(--panel);color:var(--ink);font:inherit;font-size:.86rem;font-weight:600;cursor:pointer}
.newbtn svg{width:15px;height:15px}
.newbtn:hover{border-color:var(--ink-2)}
.newmenu{position:absolute;right:0;top:40px;min-width:230px;background:var(--panel);border:1px solid var(--line-2);border-radius:9px;box-shadow:var(--shadow-lift);padding:5px;z-index:50}
.newmenu a{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;color:var(--ink);text-decoration:none;font-size:.88rem}
.newmenu a svg{width:15px;height:15px;color:var(--muted)}
.newmenu a:hover{background:var(--soft)}
/* phone: no sidebar; compact title bar; tab bar at the bottom; everything else in "More" */
.tabbar{display:none}
@media (max-width:999px){
  body.shell{display:block}
  .rail{position:fixed;inset:0 auto 0 0;width:min(84vw,300px);transform:translateX(-102%);transition:transform .22s cubic-bezier(.2,.7,.2,1);box-shadow:none;z-index:90}
  body.menu-open .rail{transform:none;box-shadow:24px 0 60px rgba(0,0,0,.35)}
  .scrim{position:fixed;inset:0;background:rgba(8,14,10,.5);z-index:85}
  .topbar{padding:0 12px;padding-top:env(safe-area-inset-top,0px);height:calc(var(--top-h) - 6px + env(safe-area-inset-top,0px))}
  .topbar .search{width:34px;padding:0;justify-content:center}
  .topbar .search span,.topbar .search kbd,.topbar .ask .lbl{display:none}
  .topbar .ask{width:34px;padding:0;justify-content:center}
  .newbtn{width:34px;padding:0;justify-content:center}.newbtn .lbl{display:none}
  .topbar .mark{display:block;width:26px;height:auto;flex:none}
  .topbar h1{font-size:1.18rem}
  .topbar .crumb .up span{display:none}
  .about{margin:0 12px}
  .tabbar{display:grid;position:fixed;left:0;right:0;bottom:0;z-index:40;grid-template-columns:repeat(5,minmax(0,1fr));background:var(--panel);border-top:1px solid var(--line);padding:4px 4px calc(4px + env(safe-area-inset-bottom,0px))}
  .tabbar a,.tabbar button{display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 2px 4px;border:0;background:none;color:var(--muted);font:inherit;font-size:.66rem;font-weight:600;text-decoration:none;cursor:pointer;min-width:0;border-radius:6px}
  .tabbar svg{width:21px;height:21px}
  .tabbar span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tabbar [aria-current="page"]{color:var(--accent)}
}

/* ================= type ================= */
h1{font-family:var(--brand);font-weight:700;font-size:1.6rem;letter-spacing:0;margin:0 0 6px;line-height:1.1}
.sub{color:var(--muted);margin:0 0 16px;max-width:70ch;font-size:.9rem}
h2{font-family:var(--body);font-size:.95rem;font-weight:600;letter-spacing:-.003em;margin:0 0 10px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;color:var(--ink)}
h3{font-size:.78rem;font-weight:600;color:var(--muted);margin:16px 0 6px;letter-spacing:.01em}
.eyebrow{font-size:.72rem;font-weight:600;color:var(--muted);letter-spacing:.01em}
.who{font-size:.8rem;color:var(--muted)}
.who button{background:none;border:0;color:var(--accent);font:inherit;cursor:pointer;padding:0;text-decoration:underline}
.mono{font-family:var(--mono);font-size:.86em;font-variant-numeric:tabular-nums}
section{margin-top:22px}
b,strong{font-weight:600}

/* ================= surfaces ================= */
.card{position:relative;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:16px 18px;min-width:0;box-shadow:var(--shadow)}
.card + .card{margin-top:14px}
.grid .card + .card,.lay .card + .card,.grid > .card{margin-top:0}
.grid{display:grid;gap:14px}
.grid.two{grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr))}
.grid.three{grid-template-columns:minmax(0,1fr)}
@media (min-width:640px){.grid.three{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1100px){.grid.three{grid-template-columns:repeat(3,minmax(0,1fr))}}
.cardhead{display:flex;justify-content:space-between;align-items:center;gap:8px 12px;flex-wrap:wrap;margin:-2px 0 10px}
.cardhead h2{margin:0}
.cardhead a{font-size:.82rem;font-weight:500;text-decoration:none;color:var(--muted);display:inline-flex;align-items:center;gap:4px}
.cardhead a:hover{color:var(--accent)}

/* Ledger strip: a row of figures in one ruled box, no icons. Used by .grid.four / .grid.five of stat cards and .tiles */
.grid.four,.grid.five{gap:0;grid-template-columns:repeat(auto-fit,minmax(min(100%,170px),1fr));border:1px solid var(--line);border-radius:var(--r);background:var(--panel);overflow:hidden}
.grid.four > .card,.grid.five > .card{border:0;border-radius:0;box-shadow:none;margin:0;box-shadow:-1px 0 0 var(--line),0 -1px 0 var(--line)}
@media (min-width:760px){.grid.four,.grid.five{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr)}}
@media (max-width:520px){.grid.four,.grid.five{grid-template-columns:repeat(2,minmax(0,1fr))}}
.stat{display:flex;flex-direction:column;gap:2px;padding:14px 18px}
.stat .n{font-family:var(--brand);font-size:2.05rem;font-weight:700;line-height:1;letter-spacing:-.01em;font-variant-numeric:tabular-nums;margin:6px 0 4px;color:var(--ink)}
.stat .l{font-size:.78rem;color:var(--muted)}
.stat > .l:first-child{font-size:.76rem;font-weight:600;color:var(--ink-2)}
.stat .n.sm{font-size:.95rem;font-family:var(--body);line-height:1.5;margin:8px 0 2px}
a.stat.link{text-decoration:none;color:inherit}
a.stat.link:hover{background:var(--panel-2)}
.kpi .ico,.tool .ti,.ico{display:none!important}

a.tile{display:flex;flex-direction:column;gap:4px;text-decoration:none;color:inherit}
a.tile:hover{border-color:var(--line-2);background:var(--panel-2)}
a.tile .t{font-weight:600;font-size:.95rem}
a.tile p{margin:0;color:var(--muted);font-size:.85rem}
a.tile .go{margin-top:auto;padding-top:8px;font-weight:500;color:var(--accent);font-size:.84rem}
.tile .n{font-family:var(--brand);font-size:1.9rem;font-weight:700;line-height:1.05;font-variant-numeric:tabular-nums}

/* status: small and square, colored text on a faint tint. Dots don't pulse. */
.pill,.tag{display:inline-flex;align-items:center;gap:5px;font-size:.72rem;font-weight:600;padding:2px 7px;border-radius:4px;background:var(--soft);color:var(--ink-2);white-space:nowrap;line-height:1.45;border:1px solid transparent;vertical-align:1px}
.pill.good,.tag.good,.pill.warn,.tag.warn,.pill.bad,.tag.bad{background:transparent;border-color:var(--line);color:var(--ink)}
.pill.good::before,.tag.good::before,.pill.warn::before,.tag.warn::before,.pill.bad::before,.tag.bad::before{content:"";width:7px;height:7px;border-radius:50%;flex:none;background:var(--good)}
.pill.warn::before,.tag.warn::before{background:var(--warn)} .pill.bad::before,.tag.bad::before{background:var(--bad)} .pill.bad,.tag.bad{color:var(--bad)}
.pill:has(.dot)::before{display:none}
.dot{width:7px;height:7px;border-radius:50%;background:currentColor;display:inline-block;flex:none}

/* lists: hairline rows */
.item{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:3px 14px;align-items:start;padding:12px 0;border-top:1px solid var(--line)}
.item:first-child{border-top:0;padding-top:2px}
.item .what{font-weight:600;font-size:.93rem}
.item .meta{font-size:.8rem;color:var(--muted);margin-top:1px}
.item .say{margin:5px 0 0;font-size:.88rem;color:var(--ink-2)}
.item .side{display:flex;flex-direction:column;align-items:flex-end;gap:6px}
.item.done{opacity:.5}
.item .ic{width:30px;height:30px;border-radius:6px;display:grid;place-items:center;font-weight:700;font-size:.8rem;font-family:var(--mono);background:var(--soft);color:var(--muted)}
.ic.quote{background:var(--good-bg);color:var(--good)} .ic.upset,.ic.fail{background:var(--bad-bg);color:var(--bad)} .ic.reach,.ic.msg{background:var(--warn-bg);color:var(--warn)}
@media (max-width:560px){.item{grid-template-columns:auto minmax(0,1fr)}.item .side{grid-column:2;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-start;margin-top:6px}}

a.mini{display:grid;grid-template-columns:minmax(0,1fr);gap:2px;padding:10px 12px;margin:0 -12px;text-decoration:none;color:inherit;border-top:1px solid var(--line)}
a.mini:first-child{border-top:0}
a.mini:hover{background:var(--panel-2)}
a.mini b{font-weight:600;display:flex;justify-content:space-between;gap:10px;min-width:0;font-size:.9rem}
a.mini span{font-size:.8rem;color:var(--muted)}
a.more{display:inline-block;padding-top:8px;font-size:.82rem;font-weight:500;text-decoration:none}
em.bad{color:var(--bad);font-style:normal;font-weight:600}

/* ================= controls ================= */
:where(button.btn,a.btn){display:inline-flex}
button.btn,a.btn{align-items:center;justify-content:center;gap:6px;font:inherit;font-size:.84rem;font-weight:600;height:34px;padding:0 12px;border-radius:7px;border:1px solid var(--line-2);background:var(--panel);color:var(--ink);cursor:pointer;text-decoration:none;white-space:nowrap;transition:background .12s,border-color .12s}
button.btn:hover,a.btn:hover{border-color:var(--ink-2);background:var(--panel-2)}
button.btn:active,a.btn:active{background:var(--sunk)}
button.btn:disabled{opacity:.5;cursor:default}
button.btn.primary,a.btn.primary,a.btn.gold,button.btn.gold{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
button.btn.primary:hover,a.btn.primary:hover,a.btn.gold:hover,button.btn.gold:hover{background:var(--accent-2);border-color:var(--accent-2)}
a.btn.ghost,button.btn.ghost{background:transparent}
a.btn svg,button.btn svg{width:15px;height:15px}
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]),select,textarea{font:inherit;font-size:.9rem;color:var(--ink);background:var(--panel);border:1px solid var(--line-2);border-radius:7px;padding:7px 10px;min-height:36px;max-width:100%}
textarea{line-height:1.45;padding:9px 10px}
input:focus,select:focus,textarea:focus{outline:0;border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 18%,transparent)}
input::placeholder,textarea::placeholder{color:var(--faint)}
input[type=checkbox],input[type=radio]{accent-color:var(--accent)}
label.f,.f{display:grid;gap:4px;font-size:.78rem;font-weight:600;color:var(--ink-2)}
label.f input,label.f select,label.f textarea{font-weight:400}

.empty{color:var(--muted);padding:14px 0;font-size:.88rem;display:flex;align-items:center;gap:10px}
.filters{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:12px}
.filters button[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.banner{border-radius:var(--r-sm);padding:10px 14px;margin-bottom:14px;font-weight:500;font-size:.88rem;border:1px solid var(--line);border-left:3px solid var(--muted);background:var(--panel);color:var(--ink)}
.banner.bad{border-left-color:var(--bad);background:var(--bad-bg);color:var(--ink)} .banner.bad b{color:var(--bad)}
.banner.warn{border-left-color:var(--warn);background:var(--warn-bg);color:var(--ink)} .banner.warn b{color:var(--warn)}
.banner.good{border-left-color:var(--good);background:var(--good-bg);color:var(--ink)}
ul.plain{margin:0;padding-left:18px} ul.plain li{margin:5px 0}
details summary{cursor:pointer;font-weight:600;font-size:.9rem}
dl.kv{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:6px 16px;margin:12px 0 0;font-size:.88rem}
dl.kv dt{color:var(--muted)} dl.kv dd{margin:0;overflow-wrap:anywhere}
@media (max-width:480px){dl.kv{grid-template-columns:minmax(0,1fr);gap:2px}dl.kv dd{margin-bottom:8px}}
.foot{margin-top:40px;padding-top:14px;border-top:1px solid var(--line);font-size:.74rem;color:var(--faint);font-family:var(--mono)}
.statusline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 16px}
.srcbar{display:grid;grid-template-columns:minmax(90px,170px) minmax(0,1fr) 40px;gap:12px;align-items:center;padding:5px 0;font-size:.86rem}
.srcbar .bl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.srcbar .bt{height:8px;border-radius:2px;background:var(--soft);overflow:hidden}
.srcbar .bt span{display:block;height:100%;background:var(--accent);border-radius:2px}
.srcbar b{font-family:var(--mono);text-align:right;font-variant-numeric:tabular-nums;font-weight:500}
@media (max-width:420px){.srcbar{grid-template-columns:minmax(0,1fr) 40px;gap:4px 10px}.srcbar .bt{grid-column:1/-1;grid-row:2}}
table{border-collapse:collapse}
th{font-size:.74rem;font-weight:600;color:var(--muted);text-align:left}
td,th{font-variant-numeric:tabular-nums}

/* ================= sign-in ================= */
#gate{position:fixed;inset:0;z-index:100;overflow-y:auto;-webkit-overflow-scrolling:touch;display:grid;grid-template-columns:minmax(0,1.1fr) minmax(360px,520px);background:var(--side);color:var(--side-ink)}
#gate .topo{display:none}
#gate::before{content:"RIGHT HAND\A RUNS THE SHOP";white-space:pre;align-self:end;padding:48px;font-family:var(--brand);font-weight:700;font-size:clamp(2.4rem,5vw,4.6rem);line-height:.95;letter-spacing:.04em;color:rgba(231,236,230,.10)}
.gate-card{grid-column:2;align-self:stretch;background:var(--bg);color:var(--ink);padding:48px 44px;display:flex;flex-direction:column;justify-content:safe center;min-height:100%;gap:12px;width:100%}
.gate-card[hidden]{display:none}
.gate-card .glock{display:flex;align-items:center;gap:12px;margin-bottom:18px}
.gate-card .glock img{width:34px}
.gate-card .wordmark{font-family:var(--brand);font-weight:700;letter-spacing:.16em;font-size:1.05rem;color:var(--ink)}
.gate-card h1{font-size:1.9rem;margin:0}
.gate-card p.lead{margin:0 0 6px;color:var(--muted);font-size:.9rem}
.gate-card label{display:flex;flex-direction:column;gap:5px;font-size:.78rem;color:var(--ink-2);font-weight:600}
.gate-card input{font-size:16px!important;min-height:42px!important}
.gate-card .btn.primary{height:42px;font-size:.92rem;margin-top:6px}
.gate-card .msg{font-size:.82rem;color:var(--muted);min-height:1.2em;margin:0}
.gate-two{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.gate-link{font:inherit;font-size:.84rem;font-weight:500;color:var(--accent);background:none;border:0;padding:6px 0 0;cursor:pointer;text-decoration:underline;align-self:flex-start}
@media (max-width:760px){#gate{grid-template-columns:1fr}#gate::before{display:none}.gate-card{grid-column:1;padding:32px 22px}}
@media (max-width:380px){.gate-two{grid-template-columns:1fr}}

/* ================= command palette ================= */
#hubk{position:fixed;inset:0;z-index:110;display:flex;align-items:flex-start;justify-content:center;padding:14vh 16px 16px;background:rgba(8,12,9,.45)}
#hubk .box{width:100%;max-width:580px;background:var(--panel);border:1px solid var(--line-2);border-radius:12px;box-shadow:var(--shadow-lift);overflow:hidden}
#hubk .q{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line)}
#hubk .q svg{width:17px;height:17px;color:var(--muted);flex:none}
#hubk input{flex:1;min-width:0;border:0!important;background:transparent!important;box-shadow:none!important;font-size:16px!important;padding:0!important}
#hubk ul{list-style:none;margin:0;padding:6px;max-height:min(56vh,440px);overflow:auto}
#hubk li a{display:flex;align-items:center;gap:12px;padding:8px 10px;border-radius:6px;color:var(--ink);text-decoration:none;font-size:.9rem}
#hubk li a svg{width:16px;height:16px;color:var(--muted);flex:none}
#hubk li a small{margin-left:auto;color:var(--muted);font-size:.74rem;white-space:nowrap}
#hubk li a[aria-selected="true"]{background:var(--soft)}
#hubk li a[aria-selected="true"] svg{color:var(--accent)}
#hubk .none{padding:16px;color:var(--muted);font-size:.88rem}
#hubk .hint{display:flex;gap:14px;padding:8px 14px;border-top:1px solid var(--line);font-size:.72rem;color:var(--muted)}

/* ================= small shared bits ================= */
.hub-help{display:none}
.ncheck{display:flex;flex-wrap:wrap;gap:4px 12px;align-items:baseline;font-size:.84rem;font-weight:600}
.ncheck>span:first-child{display:inline-flex;align-items:center;gap:7px}
.ncheck>span:first-child::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor}
.ncheck.on>span:first-child{color:var(--good)} .ncheck.off>span:first-child{color:var(--warn)}
.ncheck ul{flex-basis:100%;margin:6px 0 0;padding-left:18px;font-weight:400;font-size:.84rem;line-height:1.5}
.ncheck details{flex-basis:100%;font-weight:400;font-size:.84rem} .ncheck details summary{font-weight:400}
.ncheck .linkish,.linkish{background:none;border:0;color:var(--accent);font:inherit;cursor:pointer;padding:0;text-decoration:underline}
.fresh .linkish{padding:8px 4px;margin:-8px -4px}

/* page tweaks that beat the pages' own inline styles */
body .call{grid-template-columns:72px minmax(0,1fr) auto}
body .call .tm{white-space:nowrap;font-size:.76rem;font-family:var(--mono)}
@media (max-width:560px){body .call{grid-template-columns:64px minmax(0,1fr)}}
body .daytbl tbody tr:hover td{background:var(--panel-2)}
body .daytbl tr.sel td{background:var(--soft)}
body .daytbl td:first-child{white-space:nowrap}

@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}
@media print{.rail,.topbar,.tabbar,.about{display:none!important}body.shell{display:block}}
.newmenu hr{border:0;border-top:1px solid var(--line);margin:5px 4px}

/* ================= App look (2026-10-28, Trent: "mimic the Terramorph app") =================
   Same visual language as the Terramorph iPhone app design: iOS system type, grouped gray ground, white 22px cards with
   no borders, deep forest green with gold, pill buttons and chips, rows with colored icon squares, and a floating frosted
   pill tab bar on phones. Overrides the "work order" tokens above; delete this block to go back. */
:root{
  --bg:#F2F2F7; --panel:#FFFFFF; --panel-2:#F7F7FA; --sunk:#E5E5EA; --ink:#000000; --ink-2:#3A3A3C; --muted:#6C6C70; --faint:#8E8E93;
  --line:#E5E5EA; --line-2:#D1D1D6;
  --accent:#1D4A31; --accent-2:#2F5D46; --accent-ink:#FFFFFF; --accent-soft:#1D4A311C; --soft:#F2F2F7;
  --gold:#B8862F; --gold-2:#D8AA4D; --gold-soft:#F6ECD6;
  --side:#0D2418; --side-2:#16352A; --side-ink:#F1F4F2; --side-muted:#9DB2A6;
  --shadow:0 1px 3px rgba(0,0,0,.05); --shadow-lift:0 12px 34px rgba(0,0,0,.14),0 2px 8px rgba(0,0,0,.05);
  --r:22px; --r-sm:14px;
  --brand:-apple-system,"SF Pro Display",system-ui,"Segoe UI",Roboto,sans-serif; --serif:var(--brand);
  --body:-apple-system,"SF Pro Text",system-ui,"Segoe UI",Roboto,sans-serif; --mono:-apple-system,"SF Pro Text",system-ui,sans-serif;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --bg:#000000; --panel:#1C1C1E; --panel-2:#242426; --sunk:#2C2C2E; --ink:#FFFFFF; --ink-2:#D1D1D6; --muted:#98989F; --faint:#6C6C70;
  --line:#38383A; --line-2:#48484A; --accent:#7FC59A; --accent-2:#9AD3AE; --accent-ink:#06140C; --accent-soft:#7FC59A24; --soft:#2C2C2E;
  --gold:#E3B85C; --gold-2:#F1D384; --gold-soft:#3A2E14; --side:#06140C; --side-2:#10261A; --shadow:none}}
:root[data-theme="dark"]{
  --bg:#000000; --panel:#1C1C1E; --panel-2:#242426; --sunk:#2C2C2E; --ink:#FFFFFF; --ink-2:#D1D1D6; --muted:#98989F; --faint:#6C6C70;
  --line:#38383A; --line-2:#48484A; --accent:#7FC59A; --accent-2:#9AD3AE; --accent-ink:#06140C; --accent-soft:#7FC59A24; --soft:#2C2C2E;
  --gold:#E3B85C; --gold-2:#F1D384; --gold-soft:#3A2E14; --side:#06140C; --side-2:#10261A; --shadow:none}
body{font-size:15px;letter-spacing:-.005em;font-feature-settings:normal}
.mono{font-family:var(--body);font-variant-numeric:tabular-nums;font-size:.95em}
/* titles: iOS large-title weight */
.topbar h1{font-family:var(--brand);font-weight:700;font-size:1.55rem;letter-spacing:.2px}
h1{font-family:var(--brand);font-weight:700;letter-spacing:.2px}
h2{font-size:1.05rem;font-weight:700} h3{font-size:.76rem;font-weight:600;letter-spacing:.4px;text-transform:uppercase;color:var(--muted)}
.topbar{border-bottom:0.5px solid var(--line);background:color-mix(in srgb,var(--bg) 80%,transparent);-webkit-backdrop-filter:saturate(1.8) blur(20px);backdrop-filter:saturate(1.8) blur(20px)}
/* surfaces: white grouped cards, no borders */
.card{border:0;border-radius:22px;box-shadow:var(--shadow);padding:18px 20px}
.grid.four,.grid.five{border:0;border-radius:22px;box-shadow:var(--shadow)}
.grid.four > .card,.grid.five > .card{box-shadow:-0.5px 0 0 var(--line),0 -0.5px 0 var(--line)}
.stat .n{font-family:var(--brand);font-weight:700;letter-spacing:.2px}
.banner{border:0;border-radius:16px;border-left:4px solid var(--muted)}
.item,.call,a.mini{border-top-width:0.5px}
.about{border:0;border-radius:0 0 16px 16px}
/* controls: pills and soft rounded fields */
button.btn,a.btn{height:36px;padding:0 16px;border-radius:999px;border:0;background:var(--soft);color:var(--ink);font-weight:600}
button.btn:hover,a.btn:hover{background:var(--sunk);border:0}
button.btn.primary,a.btn.primary,a.btn.gold,button.btn.gold{background:var(--accent);color:var(--accent-ink);box-shadow:0 4px 12px color-mix(in srgb,var(--accent) 28%,transparent)}
button.btn.primary:hover,a.btn.primary:hover{background:var(--accent-2)}
a.btn.ghost,button.btn.ghost{background:transparent;color:var(--accent)} a.btn.ghost:hover,button.btn.ghost:hover{background:var(--accent-soft)}
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]),select,textarea{border-radius:12px;border:0.5px solid var(--line-2);background:var(--panel);min-height:40px;padding:8px 12px}
.pill,.tag{border-radius:999px;padding:3px 10px;font-weight:600;border:0;background:var(--soft)}
.filters button[aria-pressed="true"],.views button[aria-pressed="true"],.seg button[aria-pressed="true"]{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.filters button,.views button{border-radius:999px}
.seg{border-radius:12px;background:var(--sunk);padding:2px;border:0} .seg button{border-radius:10px;background:transparent}
.seg button[aria-pressed="true"]{background:var(--panel);color:var(--ink);box-shadow:0 2px 6px rgba(0,0,0,.08)}
/* top bar tools */
.topbar .search,.topbar .ib,.newbtn{border-radius:999px;border:0;background:var(--panel);box-shadow:var(--shadow)}
.topbar .ask{border-radius:999px;border:0;background:#0D2418;color:#F1D384;box-shadow:0 4px 12px rgba(13,36,24,.25)}
.topbar .ask:hover{background:#16352A}
/* sidebar: the app's deep green with gold */
.rail nav a{border-radius:10px} .rail nav a[aria-current="page"]{background:color-mix(in srgb,#D8AA4D 16%,transparent);color:#fff}
.rail nav a[aria-current="page"]::before{display:none} .rail .me .av{border-radius:50%}
/* phone: the floating frosted pill tab bar from the app */
@media (max-width:999px){
  .tabbar{left:14px;right:14px;bottom:calc(14px + env(safe-area-inset-bottom,0px));height:64px;padding:0 5px;border-radius:32px;border:0.5px solid rgba(255,255,255,.7);
    background:color-mix(in srgb,var(--panel) 74%,transparent);-webkit-backdrop-filter:blur(24px) saturate(180%);backdrop-filter:blur(24px) saturate(180%);
    box-shadow:0 10px 34px rgba(0,0,0,.14),inset 0 1px 0 rgba(255,255,255,.5);align-items:center}
  .tabbar a,.tabbar button{height:54px;justify-content:center;border-radius:27px;color:var(--ink);font-size:.64rem;padding:0 2px}
  .tabbar svg{width:23px;height:23px}
  .tabbar [aria-current="page"]{color:var(--accent);background:var(--accent-soft)}
  .wrap{padding-bottom:calc(120px + env(safe-area-inset-bottom,0px))}
  .qk-fab{bottom:calc(92px + env(safe-area-inset-bottom,0px))!important}
}
.qk-fab{background:#1D4A31!important;box-shadow:0 8px 22px rgba(13,36,24,.3)!important}
#hubk .box{border:0;border-radius:22px} #hubk li a{border-radius:12px}
dialog{border-radius:22px!important;border:0!important}

/* Nothing on a phone is wider than the screen (Trent, 2026-10-29: "stuff's overlapping and not fitting in boxes"). Grid and
   flex columns may shrink below their content, and text boxes never force a column wider than it is. */
input,select,textarea{min-width:0;max-width:100%;box-sizing:border-box}
.wrap{min-width:0}
.wrap :where(div,label,section,form,article,aside,fieldset,li,dd,dt){min-width:0}
.wrap :where(p,b,span,a,h1,h2,h3,small,td){overflow-wrap:break-word}
/* Money and counts never split across lines; they shrink a little on phones instead. */
.stat .n,.n.sm,.mono,.num,td.num,dd{overflow-wrap:normal;white-space:nowrap}
@media (max-width:600px){.stat .n{font-size:clamp(1.15rem,6vw,1.6rem)}}
@media (max-width:760px){.main{overflow-x:clip}}

/* ================= UI pass (2026-10-29) =================
   Trent: "make sure that everything's clean. There's back buttons. So people understand and they aren't sandwiched or hidden or
   smushed up against something. The UI has to be flawless and clean, but it still has to move really, really smoothly."
   Spacing tokens, the shared Back button and path, room for the floating +, scroll boxes for wide tables and tall pop-ups,
   placeholder bars while lists load, the slide between pages, and a press you can feel on every button. */
:root{--sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:24px;--sp-6:32px;--tap:44px;--edge:16px;
  --fab-clear:112px;--sk:color-mix(in srgb,var(--ink) 9%,transparent)}
@media (max-width:999px){:root{--fab-clear:calc(176px + env(safe-area-inset-bottom,0px))}}

/* The page frame: one round Back, in the same spot and size on every page you drill into (44px to tap), then the path on a computer. */
.topbar .hb-back{position:relative;flex:none;width:40px;height:40px;margin-right:var(--sp-1);display:grid;place-items:center;border-radius:50%;background:var(--panel);color:var(--ink);box-shadow:var(--shadow),0 0 0 .5px var(--line-2);text-decoration:none}
.topbar .hb-back::after{content:"";position:absolute;inset:-4px;border-radius:50%}
.topbar .hb-back svg{width:20px;height:20px}
.topbar .hb-back:hover{background:var(--panel-2)}
.topbar .hb-trail{display:flex;align-items:center;gap:6px;min-width:0;flex:0 1 auto;overflow:hidden;white-space:nowrap;font-size:.86rem}
.topbar .hb-trail a{color:var(--muted);text-decoration:none;font-weight:500;overflow:hidden;text-overflow:ellipsis;max-width:22ch}
.topbar .hb-trail a:hover{color:var(--ink);text-decoration:underline}
.topbar .hb-trail span{color:var(--faint)}
.topbar.drill .crumb{gap:var(--sp-2)}
.topbar .crumb h1{min-width:0}
@media (max-width:999px){
  .topbar.drill .mark,.topbar .hb-trail{display:none}
  .topbar.drill h1{font-size:1.12rem}
  .topbar .tools{gap:6px}
}
@media (pointer:coarse) and (max-width:999px){.topbar .search,.topbar .ask,.newbtn{width:40px;height:40px}}

/* Breathing room: nothing sits under the floating + or the phone tab bar, and nothing touches the screen edge. */
.wrap{padding-bottom:var(--fab-clear)}
@media (max-width:999px){.wrap{padding-left:var(--edge);padding-right:var(--edge);padding-bottom:var(--fab-clear)}}
body .qk-dial{overflow-y:auto;justify-content:safe flex-end}
@media (max-width:999px){body .qk-dial{padding-bottom:calc(164px + env(safe-area-inset-bottom,0px))!important}}
.wrap :is(.bar,.searchrow,.acts,.dacts,.views,.filters,.cardhead,.pager){gap:var(--sp-2)}
@media (pointer:coarse){button.btn,a.btn{min-height:40px}}

/* Wide tables scroll inside their own box (hub.js wraps any table that has no scroll box). */
.hb-tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;overscroll-behavior-x:contain}
@media print{.hb-tscroll{overflow:visible}}
/* Pop-ups and sheets never run off a short screen: they scroll inside. */
/* 2026-10-29: the screen-width cap has no weight (:where), so a page's own dialog width (Mark sent, Send an offer: 520px)
   wins again. dialog[open] used to out-rank it and every pop-up stretched across the whole page. */
dialog[open]{max-height:calc(100dvh - 24px - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));overflow-y:auto;overscroll-behavior:contain}
:where(dialog[open]){max-width:calc(100vw - 24px)}
/* The Save / OK row stays in view at the bottom of a tall pop-up (the New request Save sat below the fold at 850px tall). */
dialog[open] form > .dacts{position:sticky;bottom:0;z-index:1;background:var(--panel);margin:0 -18px -18px;padding:10px 18px 14px;border-top:1px solid var(--line)}
.sheet > div{max-height:calc(100dvh - 24px);overflow-y:auto;overscroll-behavior:contain}

/* Placeholder bars while something loads (hub.js marks short "Loading…" lines). */
.hb-skel{color:transparent!important;user-select:none;min-height:76px;background-image:linear-gradient(var(--sk) 0 0),linear-gradient(var(--sk) 0 0),linear-gradient(var(--sk) 0 0);
  background-size:92% 12px,74% 12px,56% 12px;background-position:0 10px,0 34px,0 58px;background-repeat:no-repeat;animation:hb-pulse 1.3s ease-in-out infinite}
td.hb-skel{height:84px;background-position:10px 14px,10px 38px,10px 62px}
@keyframes hb-pulse{50%{opacity:.5}}
/* A button whose save is on its way (Hub.api, 2026-10-29): off, with a small spinner after its words. */
button.hb-busy,.btn.hb-busy{cursor:progress!important;opacity:.75}
button.hb-busy::after,.btn.hb-busy::after{content:'';display:inline-block;width:.85em;height:.85em;margin-left:.45em;vertical-align:-.1em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:hb-spin .7s linear infinite}
@keyframes hb-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){button.hb-busy::after,.btn.hb-busy::after{animation-duration:2s}}

/* Press feedback: buttons give a little under the finger. */
html{-webkit-tap-highlight-color:transparent}
:is(button.btn,a.btn,.newbtn,.topbar .search,.topbar .ask,.topbar .ib,.hb-back,.tabbar a,.tabbar button,.filters button,.views button,.seg button,.qk-dial button i){transition:transform .12s cubic-bezier(.2,.7,.2,1),background-color .12s}
:is(button.btn,a.btn,.newbtn,.topbar .search,.topbar .ask,.topbar .ib,.hb-back,.tabbar a,.tabbar button,.filters button,.views button,.seg button):active:not(:disabled){transform:scale(.96)}
.qk-fab:active{transform:scale(.94)}
:is(a.stat.link,a.tile,a.mini,.row,.item,table tbody tr):active{background:var(--panel-2)}

/* The slide between pages (cross-document View Transitions): the sidebar, title bar and tab bar hold still while the page fades
   up into place. Off for anyone who turns motion down. */
@view-transition{navigation:auto}
/* The names (hub-page, hub-rail, hub-top, hub-tabs, hub-fab) are set by hub.js only while a slide runs, so pop-ups inside a page
   still sit above the title bar the rest of the time. */
::view-transition-old(hub-page){animation:hb-out .12s ease-in both}
::view-transition-new(hub-page){animation:hb-in .24s cubic-bezier(.2,.7,.2,1) both}
::view-transition-old(hub-rail),::view-transition-new(hub-rail),::view-transition-old(hub-tabs),::view-transition-new(hub-tabs),::view-transition-old(hub-fab),::view-transition-new(hub-fab){animation-duration:.12s}
::view-transition-group(hub-top){animation-duration:.18s}
@keyframes hb-out{to{opacity:0}}
@keyframes hb-in{from{opacity:0;transform:translateY(8px)}}
@media (prefers-reduced-motion:reduce){@view-transition{navigation:none}::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}.hb-skel{animation:none}}

/* Small (i) tooltip for a helper line a page folds away (Hub.tip). */
.hb-tip{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:50%;border:0;background:var(--soft);color:var(--muted);cursor:pointer;padding:0;position:relative;vertical-align:middle;flex:none}
.hb-tip::after{content:"";position:absolute;inset:-11px}
.hb-tip svg{width:14px;height:14px}
.hb-tip[aria-expanded="true"]{background:var(--accent-soft);color:var(--accent)}
.hb-tipbox{position:absolute;z-index:45;max-width:min(320px,calc(100vw - 32px));background:var(--panel);color:var(--ink-2);border-radius:14px;box-shadow:var(--shadow-lift);padding:10px 12px;font-size:.84rem;line-height:1.45;font-weight:400}
/* Big number + label you can tap to drill in, and the small trend line beside it. */
a.stat.link{cursor:pointer;position:relative}
a.stat.link::after{content:"›";position:absolute;right:14px;top:12px;color:var(--faint);font-size:1.1rem;line-height:1}
.hb-spark{display:block;width:100%;height:34px;margin-top:6px;color:var(--accent);overflow:visible}
.hb-more{display:flex;justify-content:center;margin-top:var(--sp-2)}
/* A "More" button that folds rarely used links away (details.hb-menu > summary.btn + links). */
details.hb-menu{position:relative;display:inline-block}
details.hb-menu > summary{list-style:none;cursor:pointer} details.hb-menu > summary::-webkit-details-marker{display:none}
details.hb-menu > summary::after{content:"";width:6px;height:6px;border:solid currentColor;border-width:0 1.6px 1.6px 0;transform:rotate(45deg) translateY(-2px);margin-left:2px}
details.hb-menu > div{position:absolute;right:0;top:calc(100% + 6px);z-index:40;min-width:210px;background:var(--panel);border-radius:16px;box-shadow:var(--shadow-lift);padding:6px;display:grid}
details.hb-menu > div a,details.hb-menu > div button{display:flex;align-items:center;min-height:42px;padding:0 12px;border-radius:10px;color:var(--ink);text-decoration:none;font:inherit;font-size:.9rem;background:none;border:0;text-align:left;cursor:pointer}
details.hb-menu > div a:hover,details.hb-menu > div button:hover{background:var(--soft)}
details.hb-find > summary{display:flex;align-items:center;justify-content:space-between;gap:8px;font-weight:700;font-size:1.05rem;min-height:40px}
details.hb-find > summary::after{content:"";width:8px;height:8px;border:solid var(--muted);border-width:0 2px 2px 0;transform:rotate(45deg);transition:transform .15s;margin-right:4px}
details.hb-find[open] > summary::after{transform:rotate(-135deg)}
details.hb-find > summary::-webkit-details-marker{display:none} details.hb-find[open] > summary{margin-bottom:10px}
body:has(.topbar .hb-back.pane) .wrap .lay.open button.back{display:none!important}
/* "More" looks like the other buttons; small round (i) and segmented tabs are easy to hit with a thumb. */
details.hb-menu > summary.btn{display:inline-flex;align-items:center;gap:6px;height:36px;padding:0 16px;border-radius:999px;background:var(--soft);color:var(--ink);font-size:.84rem;font-weight:600;white-space:nowrap;user-select:none}
details.hb-menu > summary.btn:hover{background:var(--sunk)} details.hb-menu[open] > summary.btn{background:var(--sunk)}
@media (pointer:coarse){details.hb-menu > summary.btn{min-height:40px}.wrap :is(#view,#tabs,#mode,#days,.seg,.views,.filters) > button{min-height:36px}}
.topbar .info{position:relative;width:28px;height:28px}
.topbar .info::after{content:"";position:absolute;inset:-8px;border-radius:50%}
/* Phones: a search box gets its own full row instead of being squeezed to a few letters, and a long row of view tabs slides
   sideways in one line instead of stacking five rows deep. */
@media (max-width:600px){
  .wrap :is(.bar,.searchrow) > input[type=search]{flex:1 1 100%}
  .wrap .views{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;margin-left:-2px;margin-right:-2px;padding:2px;scroll-snap-type:x proximity}
  .wrap .views::-webkit-scrollbar{display:none}
  .wrap .views > button{flex:none;scroll-snap-align:start}
}
a.stat.link{padding-right:32px}

/* ================= Polish pass (2026-10-29) =================
   Trent: "I'm going after the small little tiny details that literally make the thing look like shit and make it not look like a
   premium CRM." Small, shared fixes found by opening every page at 1440px, in dark mode and at phone width. */
/* Sidebar: the signed-in name had 11px left beside four icons, so "Trent Lincoln" showed as "T.". The name gets its own row
   with the avatar; the four icons sit in an even row under it. */
.rail .me{flex-wrap:wrap;row-gap:6px}
.rail .me .nm{flex:1 1 calc(100% - 40px)}
.rail .me > a,.rail .me > button{flex:1 1 0;width:auto;height:32px}
/* Small print stays readable: footers used the faintest grey (2.9:1 on the page); they now use the muted grey (4.6:1). */
.foot{color:var(--muted)}
/* Gold words on the pale gold chips ("Follow up", "4 not booked yet") were 2.8:1. A deeper gold for text only, light mode. */
:root:not([data-theme="dark"]){--gold:#8C6418}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--gold:#E3B85C}}
/* Headings break into even lines instead of leaving one word alone on the last line ("8 crews out, 8 stops to / go"). */
h1,h2,.hd h2,.cardhead h2,.card h3,.stat .l{text-wrap:balance}
p,li,.sub,.empty{text-wrap:pretty}
/* Money in a figure row matched the big counts beside it at half their size ($555,188 next to 946). Same face, a step smaller. */
.stat .n.sm{font-family:var(--brand);font-weight:700;font-size:clamp(1.2rem,1.7vw,1.55rem);line-height:1.05;margin:6px 0 4px;letter-spacing:.2px}
/* Scroll boxes inside a page get a thin scrollbar that matches the theme instead of a bright grey bar in dark mode. */
.wrap *{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--ink) 22%,transparent) transparent}
/* Text links that act as buttons ("Refresh from Jobber now", "Check now") are 19px tall; on a phone the tap area grows to 40px
   without moving anything. */
@media (pointer:coarse){.linkish{position:relative}.linkish::after{content:"";position:absolute;inset:-11px -4px}}
/* Map zoom buttons: rounded like everything else, and big enough for a thumb. */
.maplibregl-ctrl-group{border-radius:12px!important;overflow:hidden;box-shadow:var(--shadow-lift)!important}
.maplibregl-ctrl-group button{width:34px!important;height:34px!important}
@media (pointer:coarse){.maplibregl-ctrl-group button{width:40px!important;height:40px!important}}
/* "Find any past quote": the (i) sat alone in the middle of the row; it now sits right after the words. */
details.hb-find > summary > .hb-tip{margin-right:auto}
/* The empty right-hand pane on Clients and Requests ("Pick a client…") was one small line in the corner of a short box. It is now
   a calm, centred note the height of the list beside it. */
.card#detail > p.who:only-child{display:grid;place-items:center;min-height:min(60vh,420px);margin:0;text-align:center;color:var(--muted);font-size:.95rem}
/* Notice bars: a 4px left border on a 16px-round box bent into a crescent "(" at the left edge. The colour mark is now a straight,
   rounded bar inside the box. */
.banner{border:0!important;position:relative;padding-left:22px}
.banner::before{content:"";position:absolute;left:10px;top:10px;bottom:10px;width:3px;border-radius:3px;background:var(--bl,var(--muted))}
.banner.bad{--bl:var(--bad)} .banner.warn{--bl:var(--warn)} .banner.good{--bl:var(--good)}
/* Every fold-open row uses the same chevron as "Find any past quote", not the browser's small black triangle. */
.wrap details:not(.hb-menu):not(.hb-find):not(.load):not(.settings):not(.g) > summary{list-style:none;cursor:pointer}
.wrap details:not(.hb-menu):not(.hb-find):not(.load):not(.settings):not(.g) > summary::-webkit-details-marker{display:none}
.wrap details:not(.hb-menu):not(.hb-find):not(.load):not(.settings):not(.g) > summary::before{content:"";display:inline-block;width:6px;height:6px;border:solid currentColor;border-width:0 1.8px 1.8px 0;transform:rotate(-45deg);transition:transform .15s;margin:0 9px 0 2px;vertical-align:.12em;opacity:.7}
.wrap details:not(.hb-menu):not(.hb-find):not(.load):not(.settings):not(.g)[open] > summary::before{transform:rotate(45deg);vertical-align:.25em}
/* Cards laid out by a grid already have the grid's gap; the extra 14px "card after card" margin pushed the second card down
   (Business health: "Quotes" sat 14px lower than "Clients"; Home's right column had 28px gaps instead of 14px). */
.bh > .card + .card,.home > .col > .card + .card{margin-top:0}
@media (pointer:coarse){.wrap details:not(.hb-menu):not(.hb-find):not(.load):not(.settings):not(.g) > summary{padding-block:10px}}

/* Dropdowns (2026-10-30, Trent: the word sat off-center and the arrow was "terribly off center"). Our own chevron, inset the
   same as the text padding and centered on the box; the text sits on the same line height as the search boxes beside it. */
select:not([multiple]):not([size]){-webkit-appearance:none;appearance:none;line-height:1.25;padding-right:38px;cursor:pointer;text-overflow:ellipsis;
  background-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27none%27 stroke=%27%23858C80%27 stroke-width=%271.8%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M4 6l4 4 4-4%27/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 13px center;background-size:14px 14px}
select:not([multiple]):not([size])::-ms-expand{display:none}

/* ================= Color and motion (2026-10-30, Trent approved all six parts of the preview: "do all of it") =================
   Color only where it carries meaning, and a little motion. Every page and every future page picks these up from here.
   1. Home banner: pine gradient with a warm gold glow (--banner, used by Home's .db only).
   2. One status system: green done/paid, amber waiting, red overdue/broken, blue scheduled/on its way, grey draft.
      Dot chips: <span class="st paid|wait|late|sched|draft">Label</span> (Hub.st(kind, label) writes one; Hub.stKind(status) maps a
      record's status word to the kind). The older .pill/.tag .good/.warn/.bad (+ .info/.idle) wear the same five colors.
   3. Number cards: add .w-good|.w-warn|.w-bad|.w-info|.w-gold|.w-accent|.w-idle to a .card/.stat/.tile for a soft wash in that
      meaning's color; its .n takes the color, counts up on first load (hub.js) and the card lifts under the mouse.
   4. One quiet accent per menu section (hub.js sets html[data-sec]): the sidebar dot, the picked item, a thin bar by the title.
   5. Crew colors: --crew1..5, picked from the crew's name by Hub.crewColor(name), the same on every page.
   6. Motion: content fades up when it changes (.hb-fade, hub.js), loading spots shimmer (.hb-skel), cards lift. All of it is off
      under prefers-reduced-motion (the rule near the top of this file, and the block at the end of this one).
   Contrast (WCAG AA) checked for every pair, light and dark, against the real card and page colors (2026-10-30). */
:root{
  --info:#2457A8; --info-bg:#E3ECF8; --idle:#5F665A; --idle-bg:#ECEAE3;
  --sec-today:#1D4C2F; --sec-sales:#2457A8; --sec-field:#5E6B1F; --sec-money:#A87A22; --sec-ai:#6A4C93; --sec-admin:#4A5560;
  --crew1:#2E6FDB; --crew2:#B86614; --crew3:#7A4CC2; --crew4:#178573; --crew5:#C2417A;
  --lift:0 12px 32px -12px rgba(21,25,15,.28),0 2px 6px rgba(21,25,15,.06);
  --banner:radial-gradient(120% 140% at 100% 0%,rgba(200,150,46,.28),transparent 55%),linear-gradient(135deg,#163A24,#1D4C2F 55%,#26603C);
  --ease-out:cubic-bezier(.22,.9,.24,1);
  --sk-hi:color-mix(in srgb,var(--ink) 3%,transparent);
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --info:#8DB3F2; --info-bg:#152238; --idle:#A9AFA4; --idle-bg:#202420;
  --sec-today:#86C49B; --sec-sales:#8DB3F2; --sec-field:#B9C76A; --sec-money:#D9AE55; --sec-ai:#B79BE0; --sec-admin:#A7B3BD;
  --crew1:#6E9EEC; --crew2:#E9A35C; --crew3:#A98BE0; --crew4:#4FC2AE; --crew5:#E27AA6;
  --lift:0 16px 40px -14px rgba(0,0,0,.7),0 2px 8px rgba(0,0,0,.4);
  --banner:radial-gradient(120% 140% at 100% 0%,rgba(200,150,46,.28),transparent 55%),linear-gradient(135deg,#163A24,#1D4C2F 55%,#26603C);
  --sk-hi:color-mix(in srgb,var(--ink) 17%,transparent)}}
:root[data-theme="dark"]{
  --info:#8DB3F2; --info-bg:#152238; --idle:#A9AFA4; --idle-bg:#202420;
  --sec-today:#86C49B; --sec-sales:#8DB3F2; --sec-field:#B9C76A; --sec-money:#D9AE55; --sec-ai:#B79BE0; --sec-admin:#A7B3BD;
  --crew1:#6E9EEC; --crew2:#E9A35C; --crew3:#A98BE0; --crew4:#4FC2AE; --crew5:#E27AA6;
  --lift:0 16px 40px -14px rgba(0,0,0,.7),0 2px 8px rgba(0,0,0,.4);
  --banner:radial-gradient(120% 140% at 100% 0%,rgba(200,150,46,.28),transparent 55%),linear-gradient(135deg,#163A24,#1D4C2F 55%,#26603C);
  --sk-hi:color-mix(in srgb,var(--ink) 17%,transparent)}

/* 2. Status chips. Only these five kinds wear the chip, so a page's own .st (Money's figure rows, My day's checklist) is untouched. */
.st:is(.paid,.wait,.late,.sched,.draft){display:inline-flex;align-items:center;gap:6px;font-size:.72rem;font-weight:600;line-height:1.45;letter-spacing:0;
  border-radius:999px;padding:3px 10px 3px 8px;white-space:nowrap;vertical-align:1px;min-width:0;text-transform:none}
.st:is(.paid,.wait,.late,.sched,.draft)::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.st.paid{background:var(--good-bg);color:var(--good)} .st.wait{background:var(--warn-bg);color:var(--warn)} .st.late{background:var(--bad-bg);color:var(--bad)}
.st.sched{background:var(--info-bg);color:var(--info)} .st.draft{background:var(--idle-bg);color:var(--idle)}
.st-legend{display:flex;flex-wrap:wrap;gap:8px}
/* The older status pills speak the same five colors. */
.pill.good,.tag.good{background:var(--good-bg);color:var(--good)} .pill.warn,.tag.warn{background:var(--warn-bg);color:var(--warn)}
.pill.bad,.tag.bad{background:var(--bad-bg);color:var(--bad)} .pill.info,.tag.info{background:var(--info-bg);color:var(--info)}
.pill.idle,.tag.idle{background:var(--idle-bg);color:var(--idle)}
.pill:is(.good,.warn,.bad,.info,.idle)::before,.tag:is(.good,.warn,.bad,.info,.idle)::before{content:"";width:7px;height:7px;border-radius:50%;flex:none;background:currentColor}
.pill:has(.dot)::before{display:none}
/* A dot on its own (a row's status light). */
.sd{display:inline-block;width:8px;height:8px;border-radius:50%;flex:none;background:var(--idle)}
.sd.paid{background:var(--good)} .sd.wait{background:var(--warn)} .sd.late{background:var(--bad)} .sd.sched{background:var(--info)} .sd.draft{background:var(--idle)}

/* 3. Number cards: a soft wash in the figure's meaning, the figure in that color, a small lift under the mouse. */
.w-good{--w:var(--good);--w-bg:var(--good-bg)} .w-warn{--w:var(--warn);--w-bg:var(--warn-bg)} .w-bad{--w:var(--bad);--w-bg:var(--bad-bg)}
.w-info{--w:var(--info);--w-bg:var(--info-bg)} .w-gold{--w:var(--gold);--w-bg:var(--gold-soft)} .w-accent{--w:var(--accent);--w-bg:var(--accent-soft)} .w-idle{--w:var(--ink);--w-bg:var(--idle-bg)}
/* [class] lifts the wash over a page's own `background:` shorthand on its tile (Shop, Subs and Crew Clock tiles, 2026-10-30). */
:is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle)[class]{background-image:linear-gradient(155deg,var(--w-bg),transparent 70%)}
:is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle) :is(.n,.v,.num-big){color:var(--w)}
/* The small words on a wash use the darker grey: the muted grey dips under 4.5:1 on the strongest corner of a light wash. */
:is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle) :is(.l,.e,small,.who){color:var(--ink-2)}
:is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle) > :is(span,label):not(.n):not(.v):not([data-count]){color:var(--ink-2)}
/* Washed link cards keep their wash under the mouse (a.stat.link and a.tile set the background shorthand on hover). */
:is(a.stat.link,a.tile):is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle):hover{background-image:linear-gradient(155deg,var(--w-bg),transparent 70%)}
:is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle,.lift){transition:transform .25s var(--ease-out),box-shadow .25s var(--ease-out),background-color .15s}
@media (hover:hover){
  :is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle,.lift):hover{transform:translateY(-2px);box-shadow:var(--lift);position:relative;z-index:1}
  /* Inside a ruled strip of figures the cells share edges, so they light up instead of lifting out of the box. */
  :is(.grid.four,.grid.five) > :is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle,.lift):hover{transform:none;box-shadow:-0.5px 0 0 var(--line),0 -0.5px 0 var(--line);background-color:var(--panel-2)}
  :is(.grid.four,.grid.five):has(> :is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle,.lift)){transition:transform .25s var(--ease-out),box-shadow .25s var(--ease-out)}
  :is(.grid.four,.grid.five):has(> :is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle,.lift)):hover{transform:translateY(-2px);box-shadow:var(--lift)}
}

/* 4. Section accent: html[data-sec] names the page's menu section; the rail is always dark pine, so it uses the dark shades. */
html[data-sec="today"]{--sec:var(--sec-today)} html[data-sec="sales"]{--sec:var(--sec-sales)} html[data-sec="field"]{--sec:var(--sec-field)}
html[data-sec="money"]{--sec:var(--sec-money)} html[data-sec="ai"]{--sec:var(--sec-ai)} html[data-sec="admin"]{--sec:var(--sec-admin)}
.rail{--sec-today:#86C49B;--sec-sales:#8DB3F2;--sec-field:#B9C76A;--sec-money:#D9AE55;--sec-ai:#B79BE0;--sec-admin:#A7B3BD}
.rail .grpw[data-sec="today"]{--sec:var(--sec-today)} .rail .grpw[data-sec="sales"]{--sec:var(--sec-sales)} .rail .grpw[data-sec="field"]{--sec:var(--sec-field)}
.rail .grpw[data-sec="money"]{--sec:var(--sec-money)} .rail .grpw[data-sec="ai"]{--sec:var(--sec-ai)} .rail .grpw[data-sec="admin"]{--sec:var(--sec-admin)}
.rail .grpw[data-sec] > .grp{justify-content:flex-start;gap:8px}
.rail .grpw[data-sec] > .grp::before{content:"";width:7px;height:7px;border-radius:2.5px;background:var(--sec);flex:none;opacity:.9}
.rail .grpw[data-sec] > .grp i{margin-left:auto}
.rail .grpw[data-sec] nav a[aria-current="page"],.rail .grpw[data-sec] a[aria-current="page"]{background:color-mix(in srgb,var(--sec) 16%,transparent)}
.rail .grpw[data-sec] a[aria-current="page"] svg{color:var(--sec);opacity:1}
.rail .grpw[data-sec] a[aria-current="page"]::before{display:block;content:"";position:absolute;left:-6px;top:8px;bottom:8px;width:3px;border-radius:3px;background:var(--sec)}
html[data-sec] .topbar .crumb > h1::before{content:"";display:inline-block;width:4px;height:.92em;border-radius:3px;background:var(--sec);margin-right:10px;vertical-align:-.08em}
@media print{html[data-sec] .topbar .crumb > h1::before{display:none}}

/* 5. Crew colors: a crew's swatch, lane edge and tint. Pages set --c (Hub.crewColor) on the row. */
.crew-sw{display:inline-block;width:10px;height:10px;border-radius:50%;flex:none;background:var(--c,var(--idle))}
.crew-lane{border-left:4px solid var(--c,var(--idle));background:color-mix(in srgb,var(--c,var(--idle)) 7%,var(--panel))}

/* 6. Motion. Content that changes fades up into place (hub.js adds .hb-fade after a tab pick or when a placeholder fills in). */
.hb-fade{animation:hb-fadeup .35s var(--ease-out) both}
@keyframes hb-fadeup{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
/* Loading spots shimmer (replaces the grey pulse): three rounded bars with a soft light sweeping across. Hub.skeleton(lines) writes one;
   a short "Loading…" line anywhere in a page becomes one by itself. */
.hb-skel{color:transparent!important;user-select:none;min-height:76px;animation:hb-shimmer 1.3s linear infinite;
  background:linear-gradient(90deg,var(--sk) 25%,var(--sk-hi) 50%,var(--sk) 75%) 0 0/200% 100% no-repeat!important;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='76'%3E%3Crect y='10' width='92%25' height='12' rx='6'/%3E%3Crect y='34' width='74%25' height='12' rx='6'/%3E%3Crect y='58' width='56%25' height='12' rx='6'/%3E%3C/svg%3E") 0 0/100% 76px no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='76'%3E%3Crect y='10' width='92%25' height='12' rx='6'/%3E%3Crect y='34' width='74%25' height='12' rx='6'/%3E%3Crect y='58' width='56%25' height='12' rx='6'/%3E%3C/svg%3E") 0 0/100% 76px no-repeat}
.hb-skel[data-lines="1"]{min-height:32px}
td.hb-skel{height:84px;-webkit-mask-position:10px 4px;mask-position:10px 4px}
/* A small one inside a line of text (a figure still on its way). */
.hb-sk{display:inline-block;height:.8em;width:3em;vertical-align:-.05em;border-radius:5px;background:linear-gradient(90deg,var(--sk) 25%,var(--sk-hi) 50%,var(--sk) 75%) 0 0/200% 100%;animation:hb-shimmer 1.3s linear infinite}
@keyframes hb-shimmer{from{background-position:100% 0}to{background-position:-100% 0}}
@media (prefers-reduced-motion:reduce){.hb-fade,.hb-skel,.hb-sk{animation:none!important}
  :is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle,.lift),:is(.w-good,.w-warn,.w-bad,.w-info,.w-gold,.w-accent,.w-idle,.lift):hover{transform:none!important;transition:none!important}}
