
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
:root{
  /* v2.2 — warm organic premium theme (light sidebar, line icons). Revert all: git checkout v1.4.7 */
  --bg:#ECEAE5;--surface:#F6F4EF;--surface2:#E5E3DD;--surface3:#DBD8D0;--panel:#EEECE7;
  --border:#DAD7CF;--border2:#CDC9C0;
  --text:#2A241E;--text2:#5E564C;--text3:#756B5D;
  --blue:#3F6E8C;--blue2:#33596F;
  --blue-light:#E7EEF2;--blue-mid:#CFE0E8;
  --green:#687153;--green-light:#E9EBDD;--green-mid:#CFD3B8;
  --orange:#B5832F;--orange-light:#F6EBD4;--orange-mid:#E8D9B5;
  --red:#AC4F40;--red-light:#F4DDD6;--red-mid:#E5C4BB;
  --purple:#8A6E84;--purple-light:#F1ECEF;--purple-mid:#E3D8E0;
  --yellow:#B5832F;--yellow-light:#F6EBD4;--yellow-mid:#E8D9B5;
  --teal:#4F8378;--teal-light:#DCEAE5;
  --brand:#33302C;--brand2:#23211D;--brand-light:#DEDBD4;
  --moss:#7C745B;--rust:#9C5A30;--oak:#B8945C;--mushroom:#C4C7B4;
  --sidebar-bg:#D6D3CC;--sidebar-hover:#CDCAC1;
  --sidebar:268px;   /* was 224 — Dale: the menu felt cramped */--topbar:54px;--brandswitcher:44px;
  --r:13px;--r-sm:9px;--r-xs:6px;
  --xs:0 1px 2px rgba(0,0,0,.04);
  --sm:-4px -4px 10px rgba(255,255,255,.6),5px 5px 14px rgba(105,98,84,.17);--tile:-3px -3px 8px rgba(255,255,255,.65),4px 4px 12px rgba(105,98,84,.15);
  --md:0 4px 8px rgba(0,0,0,.07),0 2px 4px rgba(0,0,0,.04);
  --lg:0 12px 24px rgba(0,0,0,.09),0 4px 8px rgba(0,0,0,.05);
  --xl:0 24px 48px rgba(0,0,0,.12),0 8px 16px rgba(0,0,0,.06);
  --t:.15s ease;
}
/* Price Catalogue rows — one shared grid so materials, charges + their add-rows all line up */
/* price column was 62px — a sheet price like 536.50 was clipped to "536.!" */
.cat-row{display:grid;grid-template-columns:minmax(0,1fr) 112px 108px 10px 70px 120px 74px 78px 14px;gap:6px;align-items:center}
.cat-listrow{padding:6px 10px;border-bottom:1px solid var(--border)}
.cat-in{width:100%;background:var(--surface);border:1px solid var(--border);border-radius:6px;color:var(--text);padding:4px 7px;font-size:12px}
html,body{height:100%;font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
::-webkit-scrollbar{width:5px;height:5px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border2);border-radius:3px}
a{text-decoration:none;color:inherit}
button{cursor:pointer;font-family:'DM Sans',sans-serif;border:none;outline:none}
input,select,textarea{font-family:'DM Sans',sans-serif;outline:none}

/* ── Brand Switcher Bar (hidden — moved to sidebar) ── */
.brand-bar{display:none!important}
.brand-bar-title{font-size:11px;font-weight:700;color:rgba(255,255,255,.3);text-transform:uppercase;letter-spacing:1px;margin-right:4px}
.brand-btn{padding:5px 14px;border-radius:5px;font-size:12px;font-weight:700;cursor:pointer;border:none;transition:all var(--t);display:flex;align-items:center;gap:7px}
.brand-btn-b2b{background:rgba(37,99,235,.15);color:rgba(255,255,255,.5)}
.brand-btn-b2b.active{background:var(--blue);color:var(--white)}
.brand-btn-clikt{background:rgba(160,128,96,.15);color:rgba(255,255,255,.5)}
.brand-btn-clikt.active{background:var(--oak);color:var(--white)}
.brand-indicator{width:7px;height:7px;border-radius:50%;background:currentColor;opacity:.7}
.brand-bar-sep{width:1px;height:20px;background:rgba(255,255,255,.08);margin:0 4px}
.brand-bar-env{font-size:10.5px;color:rgba(255,255,255,.25);margin-left:auto}

/* ── Layout ── */
.app{display:flex;height:100vh;overflow:hidden}
.sb{width:var(--sidebar);background:var(--sidebar-bg);border-right:1px solid var(--border);display:flex;flex-direction:column;flex-shrink:0;overflow:hidden}
.sb-brand{padding:14px 12px 12px;border-bottom:1px solid var(--border)}

/* ── Sidebar brand tabs ── */
.sb-brand-tabs{display:flex;gap:4px;margin-top:10px;background:var(--sidebar-hover);border-radius:9px;padding:3px;box-shadow:inset 2px 2px 4px rgba(105,98,84,.16),inset -1px -1px 3px rgba(255,255,255,.5)}
.sb-brand-tab{flex:1;padding:5px 6px;border-radius:var(--r-xs);font-size:10.5px;font-weight:700;cursor:pointer;border:none;transition:all var(--t);text-align:center;letter-spacing:.2px}
.sb-brand-tab-b2b{background:transparent;color:var(--text2)}
.sb-brand-tab-b2b.active{background:var(--surface);color:var(--brand2);box-shadow:-2px -2px 5px rgba(255,255,255,.7),2px 2px 5px rgba(105,98,84,.18)}
.sb-brand-tab-clikt{background:transparent;color:var(--text2)}
.sb-brand-tab-clikt.active{background:var(--surface);color:#7d5f48;box-shadow:-2px -2px 5px rgba(255,255,255,.7),2px 2px 5px rgba(105,98,84,.18)}
.sb-logo{display:flex;align-items:center;gap:12px}
.sb-mark{width:44px;height:44px;background:transparent;border-radius:10px;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:11px;color:var(--white);letter-spacing:-.3px;flex-shrink:0;transition:background var(--t);overflow:hidden}
.sb-mark-logo{width:44px;height:44px;object-fit:cover;border-radius:10px;display:none}
.sb-mark-svg{width:100%;height:100%;display:flex;align-items:center;justify-content:center}
.sb-txt{font-size:14px;font-weight:700;color:var(--text);letter-spacing:-.2px}
.sb-sub{font-size:10.5px;color:var(--text3);margin-top:2px}
.sb-nav{flex:1;padding:6px 8px 8px;overflow-y:auto}
.sb-sec-label{height:1px;background:var(--border);margin:8px 4px 6px;padding:0;font-size:0;line-height:0;overflow:hidden;display:block}
.sb-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--r-xs);color:var(--text);font-size:12.5px;font-weight:500;cursor:pointer;transition:all var(--t);user-select:none;margin-bottom:1px}
.sb-item:hover{background:var(--sidebar-hover);color:var(--text)}
.sb-item.active{background:var(--brand);color:var(--white);font-weight:700}
.sb-item .icon{width:18px;text-align:center;flex-shrink:0;font-size:17px;opacity:1;display:inline-flex;align-items:center;justify-content:center;line-height:1}
.sb-item.active .icon{opacity:1}
.sb-item .lbl{flex:1}
/* Quick-add: hovering an icon marked .qa morphs it to a "+" (clicking the icon = add new) */
.icon.qa{cursor:pointer;position:relative}
.icon.qa .qa-plus{display:none}
.icon.qa:hover > i:not(.qa-plus){display:none}
.icon.qa:hover .qa-plus{display:inline-flex;color:var(--brand-ink)}
.sb-item.active .icon.qa:hover .qa-plus{color:var(--white)}
.sb-badge{background:var(--red);color:var(--white);font-size:10px;font-weight:800;padding:2px 5px;border-radius:8px;min-width:16px;text-align:center;line-height:1.5}
/* Rolled-up count on a group header = sum of its sub-items' badges (Dale) */
.sb-group-hd .sb-group-badge{margin-left:auto}
.sb-group-hd .sb-group-badge + .sb-group-arrow{margin-left:8px}
.sb-item.active .sb-badge{background:rgba(255,255,255,.45);color:var(--text)}
.sb-foot{padding:10px 8px;border-top:1px solid var(--border)}
/* ── Sidebar collapsible groups ── */
.sb-group{margin-bottom:2px}
.sb-group-hd{display:flex;align-items:center;gap:10px;padding:6px 10px;border-radius:var(--r-xs);color:#4A443C;font-size:10px;font-weight:700;cursor:pointer;transition:all var(--t);user-select:none;letter-spacing:.7px;text-transform:uppercase;margin-top:4px}
.sb-group-hd:hover{color:var(--text);background:var(--sidebar-hover)}
.sb-shortcuts{display:none}   /* phone-only band — see the mobile block */
.sb-mob-close{display:none;position:absolute;top:10px;right:12px;z-index:5;width:38px;height:38px;align-items:center;justify-content:center;border-radius:50%;background:var(--surface2);color:var(--text2);font-size:16px;cursor:pointer}
.sb-group.has-active .sb-group-hd{color:var(--text)}
.sb-group-hd .icon{width:18px;text-align:center;flex-shrink:0;font-size:16px;display:inline-flex;align-items:center;justify-content:center;line-height:1}
.sb-group-hd .lbl{flex:1}
.sb-group-arrow{font-size:10px;color:var(--text3);transition:transform .2s ease;flex-shrink:0;line-height:1}
.sb-group:not(.open) .sb-group-arrow{transform:rotate(-90deg)}
.sb-group-items{overflow:hidden}
.sb-group:not(.open) .sb-group-items{display:none}
.sb-group-items .sb-item{padding-left:20px;font-size:12px;color:var(--text2);font-weight:500}
.sb-group-items .sb-item .icon{font-size:15px;opacity:1}   /* faded icons over warm cream read as tan next to their own label */
.sb-group-items .sb-item.active .icon{opacity:1}
/* Active sub-item sits on the dark brand background — force near-white text so it isn't invisible (the base sub-item rule above re-set it to charcoal at equal specificity). */
.sb-group-items .sb-item.active{color:var(--white);font-weight:700}
.sb-run{width:100%;padding:8px 10px;background:var(--brand);color:var(--white);border-radius:var(--r-xs);font-weight:700;font-size:12px;display:flex;align-items:center;justify-content:center;gap:6px;transition:background var(--t);border:none;cursor:pointer}
.sb-run:hover{background:var(--brand2)}
.sb-run:disabled{background:var(--surface2);color:var(--text3);cursor:not-allowed}
/* Collapsible sidebar (toggled by clicking the logo) */
.sb.sb-collapsed{width:64px}
.sb.sb-collapsed .lbl,.sb.sb-collapsed .sb-txt,.sb.sb-collapsed .sb-sub,.sb.sb-collapsed .sb-brand-tabs,.sb.sb-collapsed .sb-group-arrow,.sb.sb-collapsed .sb-badge,.sb.sb-collapsed .sb-foot{display:none}
.sb.sb-collapsed .sb-item,.sb.sb-collapsed .sb-group-hd{justify-content:center;padding-left:0;padding-right:0;gap:0}
.sb.sb-collapsed .sb-group-items .sb-item{padding-left:0}
.sb.sb-collapsed .sb-logo{justify-content:center;gap:0}
.sb.sb-collapsed .sb-brand{padding:14px 0 12px}

/* ── Main ── */
.main{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0}
.topbar{position:relative;height:var(--topbar);background:var(--surface);border-bottom:1px solid var(--border);display:flex;align-items:center;padding:0 18px;gap:10px;flex-shrink:0;box-shadow:var(--xs)}
#gs-mob-btn{display:none}   /* phone-only search icon — see the mobile block */
#mob-page-hero{display:none}   /* phone-only page-title banner — see the mobile block */
#jobs-lane-actions{display:none}   /* phone-only New Job / sync on the view-toggle lane — desktop keeps the .ph header actions */
#jobs-phase-sel-wrap{display:none}   /* phone-only phase dropdown — desktop keeps the chip row */
.topbar-title{font-size:15px;font-weight:800;color:var(--text);flex:1;letter-spacing:-.3px}
.topbar-search{position:relative}
.topbar-search input{width:220px;padding:6px 10px 6px 28px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--r-xs);font-size:12.5px;color:var(--text);transition:all var(--t)}
.topbar-search input:focus{width:280px;border-color:var(--brand-ink);background:var(--surface)}
.topbar-search .si{position:absolute;left:8px;top:50%;transform:translateY(-50%);color:var(--text3);font-size:12px;pointer-events:none}
/* ── Alerts bell ── */
.alerts-btn{position:relative;width:34px;height:34px;border-radius:var(--r-xs);border:1px solid var(--border);background:var(--surface2);color:var(--text2);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:16px;transition:background var(--t);flex-shrink:0}
.alerts-btn i{font-size:18px;color:var(--text2)}   /* themed ink, not emoji colour */
.alerts-btn:hover{background:var(--surface)}
.alerts-badge{position:absolute;top:3px;right:3px;min-width:16px;height:16px;border-radius:8px;background:var(--red,var(--red));color:var(--white);font-size:10px;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 3px;pointer-events:none;display:none}
.alerts-drawer{position:fixed;top:0;right:-380px;width:370px;height:100vh;background:var(--surface);border-left:1px solid var(--border);box-shadow:var(--md);z-index:800;display:flex;flex-direction:column;transition:right .25s cubic-bezier(.4,0,.2,1)}
.alerts-drawer.open{right:0}
.alerts-drawer-header{padding:14px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;flex-shrink:0}
.alerts-drawer-body{flex:1;overflow-y:auto;padding:10px 0}
.alert-row{padding:10px 16px;border-bottom:1px solid var(--border);cursor:pointer;transition:background var(--t)}
.alert-row:hover{background:var(--surface2)}
.alert-row:last-child{border-bottom:none}
.alert-chip{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:700;padding:2px 7px;border-radius:10px;white-space:nowrap}
.alert-chip-red{background:var(--red-light);color:var(--red)}
.alert-chip-orange{background:var(--orange-mid);color:var(--orange-ink)}
.alert-chip-yellow{background:var(--orange-light);color:var(--warning-text)}
.alert-chip-green{background:var(--green-light);color:var(--success-text)}
.gs-dd{position:absolute;top:calc(100% + 6px);right:0;min-width:360px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-sm);box-shadow:var(--md);z-index:9999;overflow:hidden}
.gs-group-lbl{padding:6px 12px 2px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;color:var(--text3)}
.gs-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;gap:10px;transition:background var(--t)}
.gs-item:hover{background:var(--surface2)}
.gs-item-ico{width:28px;height:28px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0}
.gs-item-body{flex:1;min-width:0}
.gs-item-title{font-size:12.5px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gs-item-sub{font-size:11px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
.gs-item-match{font-size:10.5px;color:var(--text2);margin-top:2px;line-height:1.4;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.gs-item-match .gs-mf{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-right:4px}
.gs-item-match mark{background:var(--orange-light);color:inherit;border-radius:3px;padding:0 1px}
/* Per-result TYPE chip (Dale: "give it a small heading so I can see what it is") */
.gs-type{display:inline-block;font-size:8.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;padding:1px 6px;border-radius:7px;background:var(--surface3);color:var(--text3);margin-right:6px;vertical-align:1px}
/* Landing highlight — the searched record flashes so you can see exactly which one
   it was, instead of hunting the section (Dale). */
@keyframes gsFlash{0%{background:var(--orange-light);box-shadow:0 0 0 3px var(--orange-light)}100%{background:transparent;box-shadow:0 0 0 3px transparent}}
.gs-flash{animation:gsFlash 2.4s ease-out 1;border-radius:8px}
@media (prefers-reduced-motion:reduce){.gs-flash{animation:none;box-shadow:0 0 0 2px var(--orange)}}
.gs-sep{height:1px;background:var(--border);margin:3px 0}
.gs-empty{padding:18px 12px;text-align:center;font-size:12px;color:var(--text3)}
.gs-footer{padding:8px 12px;border-top:1px solid var(--border);font-size:11.5px;color:var(--brand-ink);cursor:pointer;text-align:center;transition:background var(--t)}
.gs-footer:hover{background:var(--surface2)}
.content{flex:1;overflow-y:auto;padding:18px}

/* ── Buttons ── */
.btn{padding:7px 13px;border-radius:var(--r-xs);font-weight:600;font-size:12.5px;display:inline-flex;align-items:center;gap:5px;transition:all var(--t);border:1px solid transparent;white-space:nowrap}
.btn-primary{background:var(--brand);color:var(--white)}
.btn-primary:hover{background:var(--brand2)}
.btn-primary:disabled{background:var(--surface3);color:var(--text3);cursor:not-allowed}
.btn-secondary{background:var(--surface);color:var(--text2);border-color:var(--border2)}
.btn-secondary:hover{background:var(--surface2);color:var(--text)}
.job-filter-btn.active{background:var(--brand);color:var(--white);border-color:var(--brand-ink)}
.btn-sm{padding:4px 9px;font-size:11.5px}
.btn-xs{padding:2px 7px;font-size:11px;border-radius:4px}
.drag-handle{cursor:grab;color:var(--text3);font-size:15px;padding:0 6px 0 0;user-select:none;flex-shrink:0;opacity:0.5;letter-spacing:-1px;line-height:1}
.drag-handle:hover{opacity:1;color:var(--brand-ink)}
.drag-handle:active{cursor:grabbing}
.btn-green{background:var(--green-light);color:var(--green)}
.btn-green:hover{background:var(--green-mid)}
.btn-red{background:var(--red-light);color:var(--red)}
.btn-red:hover{background:var(--red-mid)}
.btn-orange{background:var(--orange-light);color:var(--orange-ink)}
.btn-orange:hover{background:var(--orange-mid)}
.btn-purple{background:var(--purple-light);color:var(--purple)}
.btn-purple:hover{background:var(--purple-mid)}
.btn-blue{background:var(--blue-light);color:var(--blue)}
.btn-blue:hover{background:var(--blue-mid)}
.btn-teal{background:var(--teal-light);color:var(--teal)}
.btn-teal:hover{background:var(--teal-light)}
.btn-yellow{background:var(--yellow-light);color:var(--orange-ink)}
.btn-yellow:hover{background:var(--yellow-mid)}
.btn-action{background:var(--surface);color:var(--text2);border-color:var(--border2);font-size:12px}
.btn-action:hover{background:var(--surface2);color:var(--text);border-color:var(--border)}

/* ── Cards ── */
.card{background:var(--surface);border-radius:var(--r);box-shadow:var(--sm)}
.card-hd{padding:14px 18px 12px;display:flex;align-items:center;gap:8px}
.card-hd h3{font-size:14px;font-weight:700;color:var(--text);letter-spacing:-.2px}
.card-hd h3{font-size:13px;font-weight:700;color:var(--text);flex:1;letter-spacing:-.1px}
.card-bd{padding:16px}

/* ── Pages ── */
.page{display:none}
.page.active{display:block}
#page-reports.active{display:flex;flex-direction:column}
#page-job.active{display:flex;flex-direction:column;height:100%}
.ph{margin-bottom:16px;display:flex;align-items:flex-end;gap:12px}
.ph-info{flex:1}
.ph h2{font-size:20px;font-weight:800;color:var(--text);letter-spacing:-.5px}
.ph p{font-size:12.5px;color:var(--text2);margin-top:2px}

/* ── Stats grid ── */
.stats-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-bottom:16px}
.stat{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;box-shadow:var(--sm);transition:box-shadow var(--t)}
.stat:hover{box-shadow:var(--md)}
.stat-link{cursor:pointer}
.stat-link:hover{box-shadow:var(--md);border-color:var(--brand-ink)}
.stat-lbl{font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.7px;margin-bottom:7px}
.stat-val{font-size:28px;font-weight:800;color:var(--text);letter-spacing:-1.5px;line-height:1;margin-bottom:2px;font-family:var(--font-sans);font-variant-numeric:tabular-nums}
.stat-sub{font-size:11px;color:var(--text3)}
.c-blue .stat-val{color:var(--brand-ink)}
.c-green .stat-val{color:var(--green)}
.c-orange .stat-val{color:var(--orange-ink)}
.c-purple .stat-val{color:var(--purple)}
.c-teal .stat-val{color:var(--teal)}

/* ── Alert cards ── */
.alerts{display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap}
.alert{flex:1;min-width:150px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-sm);padding:10px 12px;display:flex;align-items:center;gap:10px;cursor:pointer;transition:all var(--t);box-shadow:var(--xs)}
.alert:hover{box-shadow:var(--md);transform:translateY(-1px)}
.a-red{border-left:3px solid var(--red)}
.a-orange{border-left:3px solid var(--orange)}
.a-blue{border-left:3px solid var(--brand)}
.a-green{border-left:3px solid var(--green)}
.a-purple{border-left:3px solid var(--purple)}
.a-teal{border-left:3px solid var(--teal)}
.a-grey{border-left:3px solid var(--border2)}
.a-grey .alert-ico{background:var(--surface2)}
.a-grey .alert-info strong{color:var(--text3)}
.alert-ico{width:30px;height:30px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0}
.a-red .alert-ico{background:var(--red-light)}
.a-orange .alert-ico{background:var(--orange-light)}
.a-blue .alert-ico{background:var(--brand-light)}
.a-green .alert-ico{background:var(--green-light)}
.a-purple .alert-ico{background:var(--purple-light)}
.a-teal .alert-ico{background:var(--teal-light)}
.alert-info strong{display:block;font-size:17px;font-weight:800;letter-spacing:-.5px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;line-height:1;margin-bottom:1px}
.alert-info span{font-size:11px;color:var(--text2)}
.a-red .alert-info strong{color:var(--red)}
.a-orange .alert-info strong{color:var(--orange-ink)}
.a-blue .alert-info strong{color:var(--brand-ink)}
.a-green .alert-info strong{color:var(--green)}
.a-purple .alert-info strong{color:var(--purple)}
.a-teal .alert-info strong{color:var(--teal)}

/* ── Two col ── */
.two-col{display:grid;grid-template-columns:1fr 340px;gap:14px;margin-bottom:16px}

/* ── Run card ── */
.run-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:18px;box-shadow:var(--sm)}
.run-card h3{font-size:13.5px;font-weight:800;margin-bottom:4px;letter-spacing:-.2px}
.run-card p{font-size:12px;color:var(--text2);margin-bottom:14px;line-height:1.6}
.run-btns{display:flex;gap:8px;flex-wrap:wrap}
.prog-wrap{display:none;margin-top:12px}
.prog-wrap.show{display:block}
.prog-track{height:4px;background:var(--surface2);border-radius:2px;overflow:hidden;margin-bottom:5px}
.prog-fill{height:100%;background:var(--brand);width:0%;transition:width .4s ease;border-radius:2px}
.prog-lbl{font-size:11px;color:var(--text3)}
.out-box{background:#0b0f1a;border-radius:var(--r-sm);padding:10px;margin-top:10px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:11px;max-height:200px;overflow-y:auto;display:none;line-height:1.7}
.out-box.show{display:block}
.ol{color:rgba(255,255,255,.45);display:block}
.ol.ok{color:#34d399}
.ol.err{color:var(--red)}
.ol.hi{color:#60a5fa}
.ol.sec{color:var(--white);font-weight:600}

/* ── Run Drafts: polished progress + report (replaces the raw black log box) ── */
.run-progress{display:none;margin-top:14px}
.run-progress.show{display:block}
.rp-bar-row{display:flex;align-items:center;gap:10px}
.rp-track{flex:1;height:9px;background:var(--surface2);border-radius:99px;overflow:hidden;box-shadow:var(--in)}
.rp-fill{height:100%;width:0%;background:linear-gradient(90deg,var(--brand),#a98b52);border-radius:99px;transition:width .5s ease}
.rp-pct{font-size:12px;font-weight:700;color:var(--text2);min-width:40px;text-align:right;font-variant-numeric:tabular-nums}
.rp-status{display:flex;align-items:center;gap:8px;margin-top:11px;font-size:12.5px;color:var(--text2)}
.rp-spin{width:13px;height:13px;border:2px solid var(--surface3);border-top-color:var(--brand-ink);border-radius:50%;animation:rpspin .7s linear infinite;flex:none}
@keyframes rpspin{to{transform:rotate(360deg)}}
.rp-tally{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
.rp-chip{font-size:11.5px;padding:4px 11px;border-radius:99px;background:var(--surface2);color:var(--text2);font-weight:600}
.rp-chip b{font-weight:800;color:var(--text)}
.rp-chip.ok b{color:var(--green,var(--green))}
.rp-chip.err b{color:var(--red,var(--red))}
.rp-log-toggle{margin-top:12px;font-size:11px;color:var(--text3);cursor:pointer;user-select:none;display:inline-block}
.rp-log-toggle:hover{color:var(--text2)}
.rp-log{display:none;margin-top:8px;background:var(--surface2);border:1px solid var(--border);border-radius:8px;padding:10px 12px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:11px;max-height:220px;overflow-y:auto;line-height:1.65;color:var(--text3)}
.rp-log.show{display:block}
.rp-log .rl{display:block;white-space:pre-wrap;word-break:break-word}
.rp-log .rl.ok{color:var(--green,var(--green))}
.rp-log .rl.err{color:var(--red,var(--red))}
.rp-log .rl.sec{color:var(--text);font-weight:700;margin-top:5px}

.run-report{display:none;margin-top:14px;border:1px solid var(--border);border-radius:12px;padding:16px;background:var(--surface2);box-shadow:var(--tile)}
.run-report.show{display:block;animation:rrpop .3s ease}
@keyframes rrpop{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.rr-head{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.rr-ico{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;font-size:18px;font-weight:800;flex:none;background:var(--brand);color:var(--white)}
.run-report.warn .rr-ico{background:var(--orange,#c08a2d)}
.run-report.bad .rr-ico{background:var(--red,var(--red))}
.rr-title{font-size:14.5px;font-weight:800;color:var(--text);line-height:1.2}
.rr-sub{font-size:12px;color:var(--text3);margin-top:2px}
.rr-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(80px,1fr));gap:8px;margin-bottom:12px}
.rr-stat{background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:10px 8px;text-align:center}
.rr-stat .n{font-size:20px;font-weight:800;color:var(--text);line-height:1;font-variant-numeric:tabular-nums}
.rr-stat .l{font-size:10px;color:var(--text3);margin-top:5px;text-transform:uppercase;letter-spacing:.04em}
.rr-stat.ok .n{color:var(--green,var(--green))}
.rr-note{font-size:12px;color:var(--text2);line-height:1.6;margin-bottom:13px}
.rr-actions{display:flex;gap:8px;flex-wrap:wrap}

/* Add Lead: address autocomplete dropdown */
.al-sug{position:absolute;left:0;right:0;top:100%;z-index:20;background:var(--surface);border:1px solid var(--border);border-radius:8px;box-shadow:var(--sm);margin-top:2px;max-height:220px;overflow-y:auto;display:none}
.al-sug.show{display:block}
.al-sug-item{padding:8px 11px;font-size:12.5px;cursor:pointer;border-bottom:1px solid var(--border);color:var(--text2);line-height:1.35}
.al-sug-item:last-child{border-bottom:none}
.al-sug-item:hover{background:var(--surface2);color:var(--text)}

/* ── Activity feed ── */
.act-item{display:flex;align-items:center;gap:9px;padding:9px 14px;border-bottom:1px solid var(--border);transition:background var(--t);cursor:pointer}
.act-item:last-child{border-bottom:none}
.act-item:hover{background:var(--bg)}
.act-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.d-drafted{background:var(--brand)}
.d-sent{background:var(--orange)}
.d-won{background:var(--green)}
.d-replied{background:var(--purple)}
.d-closed{background:var(--text3)}
.d-nurture{background:var(--teal)}
.act-body{flex:1;min-width:0}
.act-name{font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.act-sub{font-size:10.5px;color:var(--text2)}
.act-time{font-size:10px;color:var(--text3);flex-shrink:0}

/* ── Sector bars ── */
.sbar{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.sbar-lbl{font-size:11.5px;color:var(--text2);width:130px;flex-shrink:0;text-transform:capitalize;font-weight:500}
.sbar-track{flex:1;height:6px;background:var(--surface2);border-radius:3px;overflow:hidden}
.sbar-fill{height:100%;background:var(--brand);border-radius:3px;transition:width .5s ease}
.sbar-num{font-size:11px;color:var(--text3);width:40px;text-align:right;font-family:var(--font-sans);font-variant-numeric:tabular-nums}

/* ── Filter bar ── */
.filter-bar{display:flex;align-items:center;gap:7px;padding:10px 14px;border-bottom:1px solid var(--border);flex-wrap:wrap;background:var(--surface)}
.sw{position:relative;flex:1;min-width:160px;max-width:260px}
.sw input{width:100%;padding:6px 9px 6px 27px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-xs);font-size:12.5px;color:var(--text);transition:border var(--t)}
.sw input:focus{border-color:var(--brand-ink);background:var(--surface)}
.sw .si{position:absolute;left:8px;top:50%;transform:translateY(-50%);color:var(--text3);font-size:11px;pointer-events:none}
.fsel{padding:6px 8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-xs);color:var(--text2);font-size:12.5px;cursor:pointer}
.fsel:focus{border-color:var(--brand-ink)}
.fc{font-size:11px;color:var(--text3);margin-left:auto;font-family:var(--font-sans);font-variant-numeric:tabular-nums}

/* ── Table ── */
.tbl{overflow-x:auto}
table{width:100%;border-collapse:collapse}
thead th{padding:8px 13px;text-align:left;font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.7px;background:var(--bg);border-bottom:1px solid var(--border);white-space:nowrap}
tbody td{padding:10px 13px;border-bottom:1px solid var(--border);vertical-align:middle;font-size:12.5px}
tbody tr:last-child td{border-bottom:none}
tbody tr{transition:background var(--t);cursor:pointer}
tbody tr:hover{background:var(--bg)}
.cp{font-weight:600;color:var(--text)}
.cs{font-size:10.5px;color:var(--text3);margin-top:1px}
.cm{color:var(--text3);font-size:11.5px}
.ra{display:flex;gap:3px;opacity:0;transition:opacity var(--t)}
tr:hover .ra{opacity:1}
/* Touch devices have no hover — reveal every hover-gated action cluster so row
   actions (leads, customers, jobs table) are actually reachable (audit #19/#20). */
@media (hover: none){
  .ra,.jt-actions,.drag-handle,.exp-i{opacity:1 !important}
}

/* ── Badges ── */
.badge{padding:2px 7px;border-radius:20px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;display:inline-flex;align-items:center;gap:3px;white-space:nowrap}
.badge::before{content:'';width:5px;height:5px;border-radius:50%;flex-shrink:0}
.b-drafted{background:var(--blue-light);color:var(--blue)}
.b-drafted::before{background:var(--blue)}
.b-sent{background:var(--orange-light);color:var(--warning-text)}
.b-sent::before{background:var(--orange)}
.b-won{background:var(--green-light);color:var(--green)}
.b-won::before{background:var(--green)}
.b-closed{background:var(--surface2);color:var(--text3)}
.b-closed::before{background:var(--text3)}
.b-paused{background:var(--yellow-light);color:var(--orange-ink)}
.b-paused::before{background:var(--yellow)}
.b-replied{background:var(--purple-light);color:var(--purple)}
.b-replied::before{background:var(--purple)}
.b-nurture{background:var(--teal-light);color:var(--teal)}
.b-nurture::before{background:var(--teal)}
.b-fu1{background:var(--orange-light);color:var(--orange-ink)}
.b-fu1::before{background:var(--orange)}
.b-fu2{background:var(--orange-light);color:var(--warning-text)}
.b-fu2::before{background:var(--warning-text)}
.b-fu3{background:var(--red-light);color:var(--danger-text)}
.b-fu3::before{background:var(--danger-text)}

/* ── Lead score ── */
.score{display:inline-flex;align-items:center;gap:3px;font-size:10.5px;font-weight:700;padding:2px 6px;border-radius:4px}
.score-high{background:var(--green-light);color:var(--success-text)}
.score-mid{background:var(--orange-light);color:var(--warning-text)}
.score-low{background:var(--red-light);color:var(--red)}

/* ── Sortable columns ── */
.tbl th[data-sort]{cursor:pointer;user-select:none}
.tbl th[data-sort]:hover{color:var(--text)}
.sort-arrow{font-size:10px;margin-left:3px;opacity:0;display:inline-block}
.tbl th.sort-asc,.tbl th.sort-desc{color:var(--brand-ink)}
.tbl th.sort-asc .sort-arrow::after{content:'▲';opacity:1}
.tbl th.sort-desc .sort-arrow::after{content:'▼';opacity:1}

/* ── Rotting indicator ── */
.rotting{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:700;color:var(--red);background:var(--red-light);padding:2px 6px;border-radius:4px}

/* ── Dashboard KPI cards ── */
/* Prominent Xero-style stat tiles (Dale, overhaul chunk 1): bigger bold figures,
   roomier neumorphic tiles — desktop AND mobile. */
/* Stacked KPI tile (Dale: the icon pushed the text sideways and long sub-lines
   wrapped into a mess). Now: icon + title on one line, the bold figure beneath,
   the detail under that. .dkpi-body is display:contents so its children become
   grid items of the tile itself. */
.dkpi-card{background:var(--surface);border-radius:var(--r);padding:14px 16px;cursor:pointer;transition:all var(--t);box-shadow:var(--tile,var(--sm));
  display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-areas:"ico lbl" "num num" "sub sub" "ext ext";column-gap:9px;row-gap:1px;align-items:center}
.dkpi-card:hover{border-color:var(--border2)}
.dkpi-icon{grid-area:ico;width:30px;height:32px;border-radius:50% 50% var(--r-xs) var(--r-xs);display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0}
.dkpi-body{display:contents}
.dkpi-num{grid-area:num;font-size:23px;font-weight:800;color:var(--text);letter-spacing:-.5px;line-height:1.15;font-family:var(--font-sans);font-variant-numeric:tabular-nums;margin-top:7px}
.dkpi-lbl{grid-area:lbl;font-size:12px;font-weight:700;color:var(--text2);white-space:normal;line-height:1.25}
.dkpi-sub{grid-area:sub;font-size:11.5px;font-weight:500;color:var(--text3);margin-top:3px;line-height:1.4}

/* ── Dashboard alert cards (right column) ── */
.dalert{background:var(--surface);border:1px solid var(--border);border-left:4px solid var(--border2);border-radius:var(--r);padding:14px 16px;display:flex;align-items:center;gap:10px;cursor:pointer;transition:all var(--t);box-shadow:var(--sm)}
.dalert:hover{box-shadow:var(--md);transform:translateX(2px)}
.dalert-red{border-left-color:var(--red)}
.dalert-orange{border-left-color:var(--orange-ink)}
.dalert-blue{border-left-color:var(--brand-ink)}
.dalert-neutral{border-left-color:var(--border2)}
.dalert-num{font-size:28px;font-weight:800;letter-spacing:-1.5px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;line-height:1;min-width:36px}
.dalert-red .dalert-num{color:var(--red)}
.dalert-orange .dalert-num{color:var(--orange-ink)}
.dalert-blue .dalert-num{color:var(--brand-ink)}
.dalert-neutral .dalert-num{color:var(--text3)}
.dalert-lbl{flex:1;font-size:12px;color:var(--text2);line-height:1.4}
.dalert-arrow{font-size:18px;color:var(--border2);flex-shrink:0}

/* ── Dashboard pipeline funnel ── */
.pipe-stage{flex:1;text-align:center;padding:4px 8px;cursor:pointer;transition:all var(--t);border-radius:var(--r-xs)}
.pipe-stage:hover{background:var(--bg)}
.pipe-num{font-size:26px;font-weight:800;letter-spacing:-1px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;color:var(--text);line-height:1}
.pipe-lbl{font-size:10.5px;color:var(--text3);font-weight:600;margin-top:4px}
.pipe-arrow{font-size:18px;color:var(--border2);padding:0 2px;flex-shrink:0}

/* ── Settings submenu ── */

/* ── Settings submenu ── */
.sb-settings-sub{overflow:hidden;max-height:0;transition:max-height .2s ease;background:rgba(255,255,255,.05);border-radius:var(--r-xs);margin-top:4px}
.sb-settings-sub.open{max-height:200px}
.sb-settings-sub-item{padding:7px 12px;font-size:11.5px;color:var(--text2);cursor:pointer;display:flex;align-items:center;gap:8px;transition:all var(--t)}
.sb-settings-sub-item:hover{background:var(--sidebar-hover);color:var(--text)}

/* ── Detail Panel ── */
.overlay{position:fixed;inset:0;background:rgba(15,22,35,.35);z-index:200;display:none;backdrop-filter:blur(3px)}
.overlay.open{display:block}
.dp{position:fixed;top:0;right:-580px;width:560px;height:100vh;background:var(--surface);z-index:201;display:flex;flex-direction:column;box-shadow:var(--xl);transition:right .26s cubic-bezier(.4,0,.2,1)}
.dp.open{right:0}
.dp-head{padding:16px 18px;border-bottom:1px solid var(--border);display:flex;align-items:flex-start;gap:10px;flex-shrink:0}
.dp-hi{flex:1;min-width:0}
.dp-name{font-size:16px;font-weight:800;color:var(--text);margin-bottom:4px;letter-spacing:-.4px}
.dp-meta{font-size:11.5px;color:var(--text2);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.dp-close{width:28px;height:28px;border-radius:var(--r-xs);background:var(--surface2);display:flex;align-items:center;justify-content:center;color:var(--text2);font-size:14px;transition:all var(--t);flex-shrink:0;cursor:pointer;border:none}
.dp-close:hover{background:var(--border2);color:var(--text)}
.dp-actions{padding:10px 18px;border-bottom:1px solid var(--border);display:flex;gap:5px;flex-wrap:wrap;flex-shrink:0;background:var(--bg)}
.dp-tabs{display:flex;border-bottom:1px solid var(--border);flex-shrink:0;background:var(--surface)}
.dp-tab{padding:9px 16px;font-size:12px;font-weight:600;color:var(--text3);cursor:pointer;border-bottom:2px solid transparent;transition:all var(--t)}
.dp-tab:hover{color:var(--text2)}
.dp-tab.active{color:var(--brand-ink);border-bottom-color:var(--brand-ink)}
.dp-body{flex:1;overflow-y:auto}
.dp-pane{display:none;padding:16px 18px}
.dp-pane.active{display:block}
.dp-sec-title{font-size:10px;font-weight:800;color:var(--text3);text-transform:uppercase;letter-spacing:.9px;margin-bottom:10px}
.ig{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-bottom:14px}
.ii label{font-size:10px;color:var(--text3);font-weight:700;text-transform:uppercase;letter-spacing:.5px;display:block;margin-bottom:2px}
.ii span,.ii a{font-size:12.5px;color:var(--text);display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ii a{color:var(--brand-ink)}
.ii a:hover{text-decoration:underline}
.soc-links{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px}
.soc-link{padding:4px 9px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-xs);font-size:11px;font-weight:600;color:var(--text2);display:flex;align-items:center;gap:4px;transition:all var(--t)}
.soc-link:hover{background:var(--brand-light);color:var(--brand-ink);border-color:var(--brand-ink)}

/* ── Timeline ── */
.tl-item{display:flex;gap:10px;padding-bottom:14px}
.tl-item:last-child{padding-bottom:0}
.tl-l{display:flex;flex-direction:column;align-items:center;width:16px;flex-shrink:0}
.tl-dot{width:9px;height:9px;border-radius:50%;border:2px solid var(--border2);background:var(--surface);flex-shrink:0;z-index:1;margin-top:3px}
.tl-dot.done{background:var(--green);border-color:var(--green)}
.tl-dot.pending{border-color:var(--brand-ink)}
.tl-dot.overdue{background:var(--red);border-color:var(--red)}
.tl-line{flex:1;width:2px;background:var(--border);margin-top:2px}
.tl-item:last-child .tl-line{display:none}
.tl-c{flex:1;padding-top:1px}
.tl-title{font-size:12.5px;font-weight:600;color:var(--text);margin-bottom:1px}
.tl-date{font-size:11px;color:var(--text3)}
.tl-date.overdue{color:var(--red);font-weight:600}

/* ── Activity log ── */
.al-item{display:flex;gap:8px;padding:7px 0;border-bottom:1px solid var(--border)}
.al-item:last-child{border-bottom:none}
.al-icon{width:22px;height:22px;border-radius:50%;background:var(--surface2);display:flex;align-items:center;justify-content:center;font-size:10px;flex-shrink:0;margin-top:1px}
.al-body{flex:1}
.al-action{font-size:12px;font-weight:600;color:var(--text)}
.al-detail{font-size:11px;color:var(--text2);margin-top:1px}
.al-time{font-size:10px;color:var(--text3);margin-top:1px}

/* ── Email thread ── */
.email-item{border:1px solid var(--border);border-radius:var(--r-sm);margin-bottom:8px;overflow:hidden}
.email-head{padding:9px 12px;background:var(--bg);display:flex;align-items:center;gap:8px;cursor:pointer}
.email-head:hover{background:var(--surface2)}
.email-dir{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex-shrink:0}
.email-out{background:var(--brand-light);color:var(--brand-ink)}
.email-in{background:var(--green-light);color:var(--green)}
.email-subj{font-size:12.5px;font-weight:600;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.email-date{font-size:10.5px;color:var(--text3);flex-shrink:0}
.email-snippet{padding:9px 12px;font-size:12px;color:var(--text2);line-height:1.5;border-top:1px solid var(--border);display:none}
.email-snippet.show{display:block}

/* ── Reminder ── */
.reminder-form{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-sm);padding:12px;margin-bottom:10px}
.reminder-form h4{font-size:11px;font-weight:700;color:var(--text2);margin-bottom:8px;text-transform:uppercase;letter-spacing:.5px}
.rf-row{display:flex;gap:8px;margin-bottom:8px}
.rf-row input{flex:1;padding:7px 9px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-xs);font-size:12.5px;color:var(--text);transition:border var(--t)}
.rf-row input:focus{border-color:var(--brand-ink)}
.reminder-item{display:flex;align-items:flex-start;gap:8px;padding:8px;background:var(--orange-light);border:1px solid var(--orange-mid);border-radius:var(--r-xs);margin-bottom:6px}
.reminder-item.overdue{background:var(--red-light);border-color:var(--red-mid)}
.ri-body{flex:1}
.ri-date{font-size:10.5px;font-weight:700;color:var(--orange-ink);margin-bottom:2px}
.reminder-item.overdue .ri-date{color:var(--red)}
.ri-note{font-size:12px;color:var(--text)}

/* ── Comment ── */
.cmt-area{width:100%;padding:9px 11px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-sm);resize:vertical;min-height:75px;color:var(--text);font-size:12.5px;transition:border var(--t);line-height:1.6}
.cmt-area:focus{border-color:var(--brand-ink);background:var(--surface)}

/* ── Tasks section ── */
.task-item{display:flex;align-items:center;gap:12px;padding:10px 16px;border-bottom:1px solid var(--border);transition:background var(--t)}
.task-item:last-child{border-bottom:none}
.task-item:hover{background:var(--bg)}
.task-ico{width:36px;height:36px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0}
.task-body{flex:1;min-width:0}
.task-name{font-size:13px;font-weight:600;color:var(--text)}
.task-note{font-size:11.5px;color:var(--text2);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.task-right{text-align:right;flex-shrink:0}
.task-due{font-size:11.5px;font-weight:700}
.task-sector{font-size:10.5px;color:var(--text3);margin-top:1px}
.task-actions{display:flex;gap:5px;flex-shrink:0;margin-left:8px}

/* ── Address autocomplete dropdown ── */
.pac-custom{position:absolute;top:100%;left:0;right:0;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-xs);z-index:9999;max-height:220px;overflow-y:auto;box-shadow:0 6px 20px rgba(0,0,0,.22);margin-top:2px}
.pac-item{padding:9px 12px;font-size:13px;cursor:pointer;border-bottom:1px solid var(--border);color:var(--text);line-height:1.3}
.pac-item:last-child{border-bottom:none}
.pac-item:hover{background:var(--bg)}
/* ── Modals ── */
.modal-overlay{position:fixed;inset:0;background:rgba(15,22,35,.5);z-index:300;display:none;align-items:center;justify-content:center;backdrop-filter:blur(4px)}
.modal-overlay.open{display:flex}
.modal{background:var(--surface);border-radius:var(--r);padding:24px;width:420px;box-shadow:var(--xl)}
.cmdk-overlay{position:fixed;inset:0;background:rgba(45,42,37,.34);z-index:9500;display:none;align-items:flex-start;justify-content:center;padding-top:12vh}
.cmdk-box{width:560px;max-width:92vw;max-height:64vh;background:var(--surface);border-radius:var(--r);box-shadow:var(--xl);overflow:hidden;display:flex;flex-direction:column}
.cmdk-input{border:none;outline:none;background:transparent;padding:15px 18px;font-size:15px;color:var(--text)}
.cmdk-input::placeholder{color:var(--text3)}
.cmdk-results{overflow-y:auto;padding:6px;border-top:1px solid var(--border)}
.cmdk-sec{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;color:var(--text3);padding:9px 12px 4px}
.cmdk-item{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:var(--r-sm);cursor:pointer;font-size:13px;color:var(--text)}
.cmdk-item i.ti{font-size:17px;color:var(--text2);width:20px;text-align:center;flex-shrink:0}
.cmdk-item.sel,.cmdk-item:hover{background:var(--surface2)}
.cmdk-item .cmdk-sub{margin-left:auto;font-size:11px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:42%}
.cmdk-empty{padding:22px;text-align:center;color:var(--text3);font-size:13px}
.cmdk-hint{display:flex;gap:16px;padding:9px 16px;border-top:1px solid var(--border);font-size:11px;color:var(--text3)}
#login-screen input[type=text],#login-screen input[type=password]{background:var(--surface2);border:none;border-radius:var(--r-sm);padding:11px 13px;box-shadow:inset 2px 2px 6px rgba(105,98,84,.18),inset -2px -2px 6px rgba(255,255,255,.62);color:var(--text)}
#login-screen input[type=text]:focus,#login-screen input[type=password]:focus{outline:none;box-shadow:inset 2px 2px 5px rgba(105,98,84,.18),inset -2px -2px 5px rgba(255,255,255,.55),0 0 0 2px var(--brand-light)}
.modal h3{font-size:16px;font-weight:800;margin-bottom:6px;letter-spacing:-.3px}
.modal p{font-size:12.5px;color:var(--text2);margin-bottom:16px}
.modal label{font-size:11px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:.5px;display:block;margin-bottom:4px;margin-top:10px}
.modal input,.modal textarea,.modal select{width:100%;padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-xs);font-size:13px;color:var(--text)}
.modal input:focus,.modal textarea:focus,.modal select:focus{border-color:var(--brand-ink);outline:none}
.modal-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:18px}
/* ── Mobile long-press action sheet (mSheet) — slides up from the bottom ── */
.msheet-ov{align-items:flex-end!important;justify-content:center!important;padding:0!important;z-index:9600}
.msheet{background:var(--surface);width:100%;max-width:520px;max-height:88vh;overflow-y:auto;-webkit-overflow-scrolling:touch;border-radius:20px 20px 0 0;padding:6px 10px calc(12px + env(safe-area-inset-bottom));box-shadow:0 -10px 34px rgba(0,0,0,.22);animation:msheetUp .18s cubic-bezier(.2,.8,.2,1)}
@keyframes msheetUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
.msheet-ov.closing{background:transparent}
.msheet-ov.closing .msheet{animation:msheetDown .16s ease-in forwards}
@keyframes msheetDown{to{transform:translateY(100%)}}
.msheet-title{font-size:11.5px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.5px;padding:14px 14px 10px;text-align:center}
.msheet-item{display:flex;align-items:center;gap:13px;width:100%;background:none;border:none;border-radius:12px;padding:15px 16px;font-size:16px;font-weight:600;color:var(--text);text-align:left;cursor:pointer}
.msheet-item:active{background:var(--surface2)}
.msheet-item.danger{color:var(--red)}
.msheet-item .msheet-ic{font-size:17px;width:22px;text-align:center;flex-shrink:0}
/* Xero-style "Create new": tinted rounded-square icon + label over a quiet sub-line */
.msheet-item .msheet-ic.tile{position:relative;overflow:visible;width:36px;height:36px;border-radius:11px;background:var(--brand-light);color:var(--brand-ink);display:flex;align-items:center;justify-content:center;font-size:18px}
/* Small ＋ badge on the corner of every create icon, so the row reads as "add one of these" */
.msheet-item .msheet-ic.tile::after{content:'';position:absolute;right:-3px;bottom:-3px;width:15px;height:15px;border-radius:50%;background:var(--brand);border:2px solid var(--surface);
  background-image:linear-gradient(var(--surface),var(--surface)),linear-gradient(var(--surface),var(--surface));
  background-size:7px 1.6px,1.6px 7px;background-position:center,center;background-repeat:no-repeat}
.msheet-lbl{display:block;min-width:0;font-size:15.5px;line-height:1.25}
.msheet-sub{display:block;font-size:11.5px;font-weight:500;color:var(--text3);margin-top:2px}
.msheet-sep{height:1px;background:var(--border);margin:7px 12px}
.msheet-head{font-size:10.5px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:var(--text3);padding:12px 16px 6px}
.msheet-cancel{justify-content:center;color:var(--text2);background:var(--surface2);margin-top:6px}
/* ── Branded <select> picker (Dale: the native Android dropdown is "gross" —
   huge dark OS-rendered text no CSS can touch). On phones a tap opens this
   instead: brand surface, compact type, current value ticked. ── */
.selsheet{background:var(--surface);width:100%;max-width:560px;border-radius:20px 20px 0 0;box-shadow:0 -10px 34px rgba(0,0,0,.22);display:flex;flex-direction:column;max-height:82vh;animation:msheetUp .18s cubic-bezier(.2,.8,.2,1)}
.selsheet-hd{font-size:12px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:var(--text3);padding:15px 16px 9px;text-align:center;border-bottom:1px solid var(--border)}
.selsheet-find{margin:9px 12px 3px;padding:9px 12px;font-size:14px;border:1px solid var(--border);border-radius:10px;background:var(--bg);color:var(--text);outline:none;width:calc(100% - 24px);box-sizing:border-box}
.selsheet-list{overflow-y:auto;padding:5px 8px calc(8px + env(safe-area-inset-bottom));-webkit-overflow-scrolling:touch}
.selsheet-grp{font-size:10px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:var(--text3);padding:11px 10px 4px}
.selsheet-opt{display:flex;align-items:center;gap:10px;width:100%;background:none;border:none;border-radius:10px;padding:11px 12px;font-size:14px;font-weight:500;color:var(--text);text-align:left;cursor:pointer;line-height:1.35}
.selsheet-opt:active{background:var(--surface2)}
.selsheet-opt.sel{background:var(--brand-light);color:var(--brand-ink);font-weight:700}
.selsheet-opt .selsheet-tick{width:16px;flex-shrink:0;font-size:13px;color:var(--brand-ink)}
.selsheet-opt[disabled]{opacity:.45}
.selsheet-none{padding:16px;text-align:center;font-size:12.5px;color:var(--text3)}

/* ── 👍/👎 on AI outputs (Dale: rate every AI surface; feedback tunes the prompts) ── */
.aifb{display:inline-flex;align-items:center;gap:4px}
.aifb button{border:1px solid var(--border);background:var(--surface);border-radius:7px;padding:2px 8px;font-size:12px;cursor:pointer;line-height:1.5}
.aifb button:hover{background:var(--surface2)}
.aifb .aifb-done{font-size:11px;color:var(--green);font-weight:600;white-space:nowrap}

/* ── Follow-up cols ── */
.fu-cols{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.fu-col{background:var(--surface2);border-radius:var(--r);padding:12px;min-height:180px}
.fu-col-hd{font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.6px;margin-bottom:10px;display:flex;align-items:center;gap:6px;color:var(--text2)}
.fu-cnt{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1px 6px;font-size:10px;color:var(--text3);font-family:var(--font-sans);font-variant-numeric:tabular-nums}
.fu-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-sm);padding:10px;margin-bottom:7px;box-shadow:var(--xs);transition:box-shadow var(--t);cursor:pointer}
.fu-card:hover{box-shadow:var(--sm);border-color:var(--brand-ink)}
.fu-card.ov{border-left:3px solid var(--red)}
.fu-cn{font-size:12px;font-weight:700;color:var(--text);margin-bottom:2px}
.fu-cm{font-size:10.5px;color:var(--text2);margin-bottom:7px}
.fu-ca{display:flex;gap:4px;flex-wrap:wrap}

/* ── Call cards ── */
.cc{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;margin-bottom:8px;box-shadow:var(--sm)}
.cc-top{display:flex;align-items:flex-start;gap:10px;margin-bottom:10px}
.cc-av{width:38px;height:38px;border-radius:var(--r-sm);background:var(--brand-light);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px;color:var(--brand-ink);flex-shrink:0}
.cc-info{flex:1}
.cc-name{font-size:13.5px;font-weight:800;color:var(--text);margin-bottom:2px}
.cc-meta{font-size:11px;color:var(--text2)}
.cc-right{text-align:right}
.cc-phone{font-size:14px;font-weight:800;color:var(--green);display:block;margin-bottom:2px;font-family:var(--font-sans);font-variant-numeric:tabular-nums}
.cc-days{font-size:10px;color:var(--text3)}
.cc-actions{display:flex;gap:6px;flex-wrap:wrap}

/* ── Pipeline ── */
.pipe-sum{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px;margin-bottom:14px}
.pc{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-sm);padding:12px;box-shadow:var(--xs)}
.pc-name{font-size:10.5px;color:var(--text2);margin-bottom:5px;text-transform:capitalize;font-weight:600}
.pc-count{font-size:20px;font-weight:800;color:var(--text);margin-bottom:6px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;letter-spacing:-1px}
.pc-bar{height:3px;background:var(--surface2);border-radius:2px;overflow:hidden}
.pc-fill{height:100%;background:var(--brand);border-radius:2px}

/* ── Reports ── */
.rep-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px}
.rep-stat{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:16px;box-shadow:var(--sm);text-align:center}
.rep-val{font-size:32px;font-weight:800;color:var(--text);font-family:var(--font-sans);font-variant-numeric:tabular-nums;letter-spacing:-1.5px;margin-bottom:3px}
.rep-lbl{font-size:11px;color:var(--text3);font-weight:600;text-transform:uppercase;letter-spacing:.5px}
.rep-bar-row{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.rep-bar-lbl{font-size:11.5px;color:var(--text2);width:130px;flex-shrink:0;text-transform:capitalize}
.rep-bar-track{flex:1;height:20px;background:var(--surface2);border-radius:var(--r-xs);overflow:hidden;position:relative}
.rep-bar-fill{height:100%;border-radius:var(--r-xs);transition:width .5s ease;display:flex;align-items:center;justify-content:flex-end;padding-right:6px}
.rep-bar-val{font-size:10px;font-weight:700;color:var(--white);font-family:var(--font-sans);font-variant-numeric:tabular-nums}
.rep-period-btn{padding:5px 12px;border-radius:14px;font-size:11.5px;font-weight:600;border:1px solid var(--border2);background:var(--bg);color:var(--text3);cursor:pointer;transition:all .15s;white-space:nowrap}
.rep-period-btn:hover{background:var(--surface2);color:var(--text)}
.rep-period-btn.active{background:var(--brand);color:var(--white);border-color:var(--brand-ink)}
.rep-tab{padding:9px 14px;background:none;border:none;border-bottom:2px solid transparent;font-size:12.5px;font-weight:600;color:var(--text3);cursor:pointer;transition:all var(--t);margin-bottom:-1px}
.rep-tab:hover{color:var(--text)}
.rep-tab.active{color:var(--brand-ink);border-bottom-color:var(--brand-ink)}
.rep-kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;margin-bottom:16px}
.rep-kpi{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;box-shadow:var(--sm)}
.rep-kpi-val{font-size:22px;font-weight:800;color:var(--text);font-family:var(--font-sans);font-variant-numeric:tabular-nums;margin-bottom:3px;line-height:1.1}
.rep-kpi-val.fin{font-size:17px;letter-spacing:-.3px}
.rep-kpi-lbl{font-size:10.5px;font-weight:600;color:var(--text3);text-transform:uppercase;letter-spacing:.4px}
.rep-kpi-sub{font-size:11px;color:var(--text3);margin-top:3px}
.rep-inv-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px}
.rep-inv-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;box-shadow:var(--sm)}
.rep-inv-title{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--text3);margin-bottom:10px}
.rep-inv-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.rep-inv-row-lbl{font-size:11.5px;color:var(--text2);display:flex;align-items:center;gap:5px}
.rep-inv-row-val{font-size:13px;font-weight:700;font-family:var(--font-sans);font-variant-numeric:tabular-nums}
.rep-section{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:16px;box-shadow:var(--sm);margin-bottom:14px}
.rep-section-title{font-size:12px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:.5px;margin-bottom:12px;display:flex;align-items:center;justify-content:space-between}
.rep-tbl{width:100%;border-collapse:collapse;font-size:12px}
.rep-tbl th{text-align:left;padding:7px 10px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);border-bottom:1px solid var(--border);white-space:nowrap}
.rep-tbl td{padding:8px 10px;border-bottom:1px solid var(--surface2);vertical-align:middle}
.rep-tbl tr:last-child td{border-bottom:none}
.rep-tbl tr:hover td{background:var(--surface2);cursor:pointer}
.rep-tbl .mono{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-weight:700}
.rep-waterfall{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}
.rep-wf-row{display:flex;align-items:center;gap:10px}
.rep-wf-lbl{font-size:11.5px;color:var(--text2);width:160px;flex-shrink:0}
.rep-wf-bar{flex:1;height:28px;background:var(--surface2);border-radius:5px;overflow:hidden;position:relative}
.rep-wf-fill{height:100%;border-radius:5px;display:flex;align-items:center;padding-left:10px;transition:width .5s ease}
.rep-wf-val{font-size:11px;font-weight:700;color:var(--white);font-family:var(--font-sans);font-variant-numeric:tabular-nums;white-space:nowrap}
.rep-month-chart{display:flex;align-items:flex-end;gap:4px;height:80px;margin-bottom:4px}
.rep-month-bar{flex:1;display:flex;flex-direction:column;align-items:center;gap:1px;cursor:default}
.rep-month-seg{width:100%;border-radius:2px 2px 0 0;min-height:2px;transition:opacity .2s}
.rep-month-seg:hover{opacity:.8}
.rep-month-lbl{font-size:10px;color:var(--text3);white-space:nowrap;transform:rotate(-35deg);transform-origin:top left;margin-top:4px;height:22px}
/* ── Job list view ─────────────────────────── */
/* ── Job list ── */
.jl-wrap{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--sm);overflow:hidden}
.jl-row{display:flex;align-items:center;gap:0;padding:8px 14px;border-bottom:1px solid var(--surface2);cursor:pointer;transition:background .12s}
.jl-row:last-child{border-bottom:none}
.jl-row:hover{background:var(--surface2)}
/* Column widths — fixed so all rows align like a table */
.jl-c-num  {font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:12px;font-weight:800;color:var(--brand-ink);width:46px;flex-shrink:0;letter-spacing:-.2px}
.jl-c-name {width:240px;flex-shrink:0;font-size:12px;font-weight:700;color:var(--text);padding-right:12px;line-height:1.3;overflow-wrap:anywhere}
.jl-c-client{width:130px;flex-shrink:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11.5px;color:var(--text2);padding-right:12px}
.jl-c-note {flex:1;min-width:0;overflow:hidden;font-size:11.5px;color:var(--text3);font-style:italic;padding-right:12px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.35}
.jl-c-phase{width:100px;flex-shrink:0;overflow:hidden;white-space:nowrap}
.jl-c-val  {width:92px;flex-shrink:0;text-align:right;font-size:13px;font-weight:800;font-family:var(--font-sans);font-variant-numeric:tabular-nums;padding-right:8px;line-height:1.3}
.jl-c-col  {width:78px;flex-shrink:0;text-align:right;font-size:11.5px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;color:var(--green);font-weight:600;padding-right:8px;line-height:1.3}
.jl-c-out  {width:78px;flex-shrink:0;text-align:right;font-size:11.5px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;color:var(--orange-ink);font-weight:700;padding-right:8px;line-height:1.3}
.jl-c-badges{display:flex;gap:3px;row-gap:3px;flex-wrap:wrap;flex-shrink:0;align-items:center;align-content:center;width:126px;justify-content:flex-end}
/* Uniform jobs-list indicator chips — ONE geometry (height/shape/font) for every
   badge so the column reads tidy; each chip keeps its own soft self-evident tint. */
.jlb{display:inline-flex;align-items:center;height:18px;padding:0 8px;border-radius:9px;background:var(--surface2);border:1px solid var(--border);font-size:10px;font-weight:800;color:var(--text2);white-space:nowrap;letter-spacing:.2px}
/* ⚡ Next Steps — settings flow chips (toggle .off) */
.ndg-flow-chip{font-size:10px;font-weight:700;padding:2px 7px;border-radius:7px;cursor:pointer;user-select:none;border:1px solid var(--border);background:var(--surface);color:var(--text2)}
.ndg-flow-chip.off{background:var(--surface3);color:var(--text3);text-decoration:line-through}
/* Submittal response composer — Client feedback | Resubmission toggle */
.resp-tt{border:none;background:transparent;color:var(--text3);font-size:11.5px;font-weight:700;padding:5px 13px;border-radius:7px;cursor:pointer;transition:background .12s,color .12s}
.resp-tt.active{background:var(--surface);color:var(--text);box-shadow:0 1px 3px rgba(72,66,56,.14)}
/* ⚡ auto-status badges — gentle neumorphic pills (raised off the panel, colour-coded dot) */
.ndg-badge{display:inline-flex;align-items:center;gap:6px;font-size:10px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;padding:4px 12px;border-radius:999px;background:var(--surface);color:var(--text2);box-shadow:-2px -2px 5px rgba(255,255,255,.65),2px 2px 6px rgba(105,98,84,.16);white-space:nowrap}
.ndg-badge .ndg-badge-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
/* Highlight pulse — used by the ⚡ "next steps" jump and the ? help "Take me there".
   A prominent rust ripple + a held ring so it's clearly visible even when the target
   is already on screen (Dale). */
.help-pulse{animation:helpPulse 1s ease-out 3;border-radius:var(--r);position:relative;z-index:1}
@keyframes helpPulse{
  0%{box-shadow:0 0 0 2px var(--rust),0 0 0 0 color-mix(in srgb,var(--rust) 55%,transparent)}
  70%{box-shadow:0 0 0 2px color-mix(in srgb,var(--rust) 45%,transparent),0 0 0 18px color-mix(in srgb,var(--rust) 0%,transparent)}
  100%{box-shadow:0 0 0 2px color-mix(in srgb,var(--rust) 0%,transparent),0 0 0 0 color-mix(in srgb,var(--rust) 0%,transparent)}
}
@supports not (color:color-mix(in srgb,red,blue)){
  .help-pulse{animation:helpPulseFb 1s ease-out 3}
  @keyframes helpPulseFb{0%{box-shadow:0 0 0 2px rgba(156,90,48,.9),0 0 0 0 rgba(156,90,48,.5)}70%{box-shadow:0 0 0 2px rgba(156,90,48,.4),0 0 0 18px rgba(156,90,48,0)}100%{box-shadow:0 0 0 2px rgba(156,90,48,0),0 0 0 0 rgba(156,90,48,0)}}
}
@media (prefers-reduced-motion:reduce){
  .help-pulse{animation:none;box-shadow:0 0 0 2px var(--rust),0 0 12px 2px color-mix(in srgb,var(--rust) 35%,transparent)}
}
.jl-c-act  {display:none}
/* Column header row inside each phase group */
.jl-col-hd{display:flex;align-items:center;gap:0;padding:4px 14px;background:var(--surface2);border-bottom:1px solid var(--border);font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.5px}
/* Guard: no header label may wrap or bleed into its neighbour at any width (audit #31) */
.jl-col-hd>div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Sticky column header for the flat list view (sits above .jl-wrap) */
.jl-list-hd{position:sticky;top:0;z-index:6;border:1px solid var(--border);border-radius:var(--r) var(--r) 0 0}
.jl-wrap-hdr{border-top:none;border-top-left-radius:0;border-top-right-radius:0}
.jl-phase-pill{display:inline-block;font-size:10px;font-weight:700;letter-spacing:.3px;text-transform:uppercase;padding:2px 7px;border-radius:6px;white-space:nowrap;width:88px;text-align:center;flex-shrink:0;margin-right:12px}
/* Keep old classes alive for any other refs */
.jl-info{flex:1;min-width:0}
.jl-row1{display:flex;align-items:baseline;gap:6px}
.jl-jobname{font-size:13px;font-weight:700;color:var(--text)}
.jl-client{font-size:11.5px;color:var(--text2)}
.jl-company{font-size:11px;color:var(--text3)}
.jl-fin{text-align:right;flex-shrink:0;width:160px}
.jl-quoted{font-size:13px;font-weight:800;color:var(--text);font-family:var(--font-sans);font-variant-numeric:tabular-nums;white-space:nowrap}
.jl-fin-sub{display:flex;gap:8px;justify-content:flex-end;flex-wrap:nowrap}
.jl-collected{font-size:11px;color:var(--green);font-family:var(--font-sans);font-variant-numeric:tabular-nums;white-space:nowrap}
.jl-outstanding{font-size:11px;color:var(--orange-ink);font-weight:700;font-family:var(--font-sans);font-variant-numeric:tabular-nums;white-space:nowrap}
.jl-badges{display:flex;gap:4px;flex-shrink:0;align-items:center}
.jl-date{font-size:10.5px;color:var(--text3);flex-shrink:0;width:46px;text-align:right}
/* ── Mobile job card ── */
.jm-card{background:var(--surface);border-bottom:1px solid var(--surface2);padding:13px 16px;cursor:pointer;transition:background .12s;display:block}
.jm-card:active{background:var(--surface2)}
.jm-card:last-child{border-bottom:none}
/* Row 1: job number left, phase pill right. The NAME sits on its own line beneath,
   slightly smaller, so full job names always fit (Dale 2026-07-24). */
.jm-row1{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:2px}
.jm-num{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:12px;font-weight:700;color:var(--brand-ink);flex-shrink:0;line-height:1.35}
.jm-name{font-size:14px;font-weight:800;color:var(--text);min-width:0;line-height:1.35;overflow-wrap:anywhere;letter-spacing:-.15px;margin-bottom:2px}
.jm-phase{font-size:10px;font-weight:700;padding:2px 9px;border-radius:8px;white-space:nowrap;flex-shrink:0}
.jm-client{font-size:12.5px;color:var(--text3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Footer: task/RFI pill + phase-action progress on the left, value block on the right. */
.jm-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-top:10px}
.jm-foot-l{display:flex;align-items:center;gap:9px;flex-wrap:wrap;min-width:0}
.jm-foot-r{text-align:right;flex-shrink:0}
.jm-taskpill{font-size:11px;font-weight:700;color:var(--text2);background:var(--surface2);border-radius:999px;padding:3px 10px;white-space:nowrap}
.jm-taskpill-rfi{color:var(--red);background:color-mix(in srgb,var(--red) 12%,var(--surface2))}
.jm-prog{display:inline-flex;align-items:center;gap:7px}
.jm-prog-bar{display:inline-block;width:78px;height:5px;background:var(--border2);border-radius:3px;overflow:hidden}
.jm-prog-bar>span{display:block;height:100%;border-radius:3px}
.jm-prog-txt{font-size:11px;font-weight:700;font-family:var(--font-sans);font-variant-numeric:tabular-nums}
.jm-val{font-size:16px;font-weight:800;font-family:var(--font-sans);font-variant-numeric:tabular-nums;letter-spacing:-.3px;line-height:1.1}
.jm-gst{font-size:10px;color:var(--text3);margin-top:1px}
.jm-note{font-size:12.5px;color:var(--text2);margin-top:7px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-left:9px;border-left:2px solid var(--brand)}
/* Phase section header */
.jl-phase-hd{display:flex;align-items:center;gap:10px;padding:9px 14px 7px;background:var(--surface2);border-bottom:1px solid var(--border);cursor:pointer;user-select:none}
.jl-phase-hd:hover{background:var(--bg)}
.jl-ph-chev{font-size:11px;color:var(--text3);flex-shrink:0;width:10px;text-align:center}
.jl-phase-hd:not(:first-child){border-top:2px solid var(--border)}
.jl-ph-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.jl-ph-name{font-size:12px;font-weight:800;color:var(--text);text-transform:uppercase;letter-spacing:.5px}
.jl-ph-count{font-size:11px;color:var(--text3);margin-left:4px}
.jl-ph-val{font-size:12px;font-weight:700;font-family:var(--font-sans);font-variant-numeric:tabular-nums;color:var(--text);margin-left:auto}

/* ── Empty ── */
.empty{text-align:center;padding:44px 20px}
.ei{font-size:36px;margin-bottom:8px}
.et{font-size:14px;font-weight:700;color:var(--text);margin-bottom:4px}
.es{font-size:12px;color:var(--text2);max-width:240px;margin:0 auto}

/* ── Job Detail Page ── */
.jp-tab{padding:11px 16px;background:none;border:none;border-bottom:3px solid transparent;font-size:13px;font-weight:600;color:var(--text2);cursor:pointer;transition:all var(--t);margin-bottom:-1px}
.jp-tab:hover{color:var(--text)}
.jp-tab.active{color:var(--brand-ink);border-bottom-color:var(--brand-ink);font-weight:800}
.jp-module{background:var(--surface);border-radius:var(--r-sm);padding:16px 18px;margin-bottom:12px;box-shadow:var(--tile)}
.dash-panel{background:var(--panel);border-radius:var(--r);padding:18px 18px 4px;box-shadow:var(--sm);margin-bottom:4px}
.dash-panel .card,.dash-panel .dkpi-card{background:var(--surface);box-shadow:var(--tile);border-radius:var(--r-sm)}
.page-content{background:var(--panel);border-radius:var(--r);padding:18px;box-shadow:var(--sm)}
.page-content .card,.page-content .dkpi-card{background:var(--surface);box-shadow:var(--tile);border-radius:var(--r-sm)}
.jp-module-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.jp-module-title{font-size:14px;font-weight:700;color:var(--text);letter-spacing:-.2px}
.jp-row{display:flex;align-items:flex-start;gap:10px;padding:9px 0;border-bottom:1px solid var(--border)}
.jp-row:last-child{border-bottom:none}
.jp-row-main{flex:1;min-width:0}
.jp-row-title{font-size:13px;font-weight:600;color:var(--text);margin-bottom:2px}
.jp-row-sub{font-size:11.5px;color:var(--text3);line-height:1.5}
.jp-row-meta{display:flex;align-items:center;gap:8px;margin-top:4px}
.jp-tag{font-size:10px;font-weight:700;padding:2px 7px;border-radius:10px;text-transform:uppercase;letter-spacing:.4px}
.jp-tag-general{background:var(--surface3);color:var(--text2)}
.jp-tag-supplier{background:var(--yellow-light);color:var(--orange-ink)}
.jp-tag-design{background:var(--blue-light);color:var(--blue)}
.jp-tag-site{background:var(--green-light);color:var(--green)}
.jp-tag-manufacture{background:var(--orange-light);color:var(--orange-ink)}
.jp-tag-system{background:var(--surface2);color:var(--text3)}
.jp-tag-invoice{background:var(--orange-light);color:var(--warning-text)}
.jp-tag-phase{background:var(--purple-light);color:#5b21b6}
.jp-tag-document{background:var(--green-light);color:var(--green)}
.note-system{background:var(--surface2);border-left:3px solid var(--border2);padding:8px 12px;border-radius:0 var(--r-xs) var(--r-xs) 0;opacity:.85}
.note-filter-btn{padding:3px 10px;border-radius:10px;font-size:11px;font-weight:600;border:1px solid var(--border2);background:var(--bg);color:var(--text3);cursor:pointer;transition:all .15s}
.note-filter-btn.active{background:var(--brand);color:var(--white);border-color:var(--brand-ink)}
.jp-status{font-size:11px;font-weight:700;padding:2px 8px;border-radius:10px}
.jp-status-open{background:var(--orange-light);color:var(--orange-ink)}
.jp-status-closed{background:var(--green-light);color:var(--green)}
.jp-status-pending{background:var(--yellow-light);color:var(--orange-ink)}
.jp-status-approved{background:var(--green-light);color:var(--green)}
.jp-status-invoiced{background:var(--purple-light);color:var(--purple)}
.jp-doc-cat{font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.8px;margin:10px 0 5px}
.jp-doc-item{display:flex;align-items:center;gap:8px;padding:6px 8px;background:var(--surface2);border-radius:var(--r-xs);margin-bottom:4px}
.jp-doc-name{flex:1;font-size:12.5px;font-weight:500;color:var(--text);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jp-doc-ver{font-size:10px;color:var(--text3);background:var(--surface3);padding:1px 5px;border-radius:3px;flex-shrink:0}
/* ── Email autocomplete dropdown ── */
.email-ac-dropdown{position:absolute;z-index:9999;background:var(--bg);border:1px solid var(--border2);border-radius:6px;box-shadow:0 4px 16px rgba(0,0,0,.15);min-width:260px;max-width:400px;overflow:hidden}
.email-ac-item{padding:7px 12px;cursor:pointer;display:flex;flex-direction:column;gap:1px;border-bottom:1px solid var(--border)}
.email-ac-item:last-child{border-bottom:none}
.email-ac-item:hover,.email-ac-item.focused{background:var(--surface2)}
.email-ac-name{font-size:13px;font-weight:600;color:var(--text)}
.email-ac-email{font-size:11px;color:var(--text3)}
/* Drive Documents tab */
.dv-cat-header{display:flex;align-items:center;gap:8px;padding:8px 10px;background:var(--surface2);border-radius:var(--r-xs);cursor:pointer;user-select:none;border:1px solid var(--border);margin-bottom:4px}
.dv-cat-header:hover{background:var(--surface3)}
.dv-cat-title{font-size:12px;font-weight:700;color:var(--text);flex:1}
.dv-cat-count{font-size:11px;color:var(--text3);font-weight:600}
.dv-cat-arrow{font-size:11px;color:var(--text3);transition:transform .15s}
.dv-cat-body{padding:4px 0 8px 0;display:none}
.dv-cat-body.open{display:block}
.dv-doc-row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:var(--r-xs);border:1px solid var(--border);background:var(--surface);margin-bottom:4px;cursor:default}
.dv-doc-row:hover{background:var(--surface2)}
.dv-doc-row.dragging{opacity:.4}
.dv-drag-handle{display:flex;flex-direction:column;gap:2px;padding:2px 4px;cursor:grab;flex-shrink:0;opacity:.35}
.dv-drag-handle:hover{opacity:.75}
.dv-drag-handle span{display:block;width:12px;height:2px;background:var(--text2);border-radius:1px}
.dv-cat-body.drag-over{background:var(--blue-light);border:1.5px dashed var(--blue);border-radius:6px}
.dv-doc-icon{font-size:18px;flex-shrink:0;width:24px;text-align:center}
.dv-doc-info{flex:1;min-width:0}
.dv-doc-name{font-size:12.5px;font-weight:600;color:var(--brand-ink);text-decoration:none;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dv-doc-name:hover{text-decoration:underline}
.dv-doc-meta{font-size:10.5px;color:var(--text3);margin-top:1px}
.dv-doc-actions{display:flex;gap:4px;flex-shrink:0}
/* Photo grid */
.dv-photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:8px;padding:6px 0 10px}
.dv-photo-thumb{border-radius:var(--r-xs);overflow:hidden;border:1px solid var(--border);background:var(--surface2);aspect-ratio:1;display:flex;flex-direction:column;cursor:pointer;text-decoration:none}
.dv-photo-thumb:hover{border-color:var(--brand-ink)}
.dv-photo-thumb img{width:100%;height:80%;object-fit:cover;display:block}
.dv-photo-thumb-lbl{padding:3px 5px;font-size:10px;color:var(--text2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;height:20%}
.jp-ts-total{font-size:12px;font-weight:700;color:var(--brand-ink);font-family:var(--font-sans);font-variant-numeric:tabular-nums;margin-top:10px;text-align:right}

/* ── Toasts ── */
.tw{position:fixed;bottom:18px;right:18px;z-index:9999;display:flex;flex-direction:column-reverse;gap:6px;pointer-events:none}
.toast{background:var(--text);color:var(--white);padding:9px 14px;border-radius:var(--r-sm);font-size:12.5px;font-weight:500;box-shadow:var(--lg);transform:translateX(16px);opacity:0;transition:all .2s ease;display:flex;align-items:center;gap:6px;max-width:280px;pointer-events:auto}
.toast.show{transform:translateX(0);opacity:1}
.toast.success{background:var(--green)}
.toast.error{background:var(--red)}
.toast.info{background:var(--brand)}
.toast.warn{background:var(--orange)}

/* ── CRM: Customer cards ── */
.cust-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;margin-bottom:8px;box-shadow:var(--sm);display:flex;align-items:center;gap:12px;cursor:pointer;transition:all var(--t)}
.cust-card:hover{box-shadow:var(--md);transform:translateY(-1px)}
.cust-av{width:40px;height:40px;border-radius:var(--r-sm);background:var(--brand-light);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px;color:var(--brand-ink);flex-shrink:0}
.cust-info{flex:1;min-width:0}
.cust-name{font-size:13.5px;font-weight:700;color:var(--text);margin-bottom:2px}
.cust-meta{font-size:11.5px;color:var(--text2)}
.cust-badge{padding:2px 8px;border-radius:10px;font-size:10px;font-weight:700;background:var(--surface2);color:var(--text3)}
.cust-badge.converted{background:var(--green-light);color:var(--green)}
.tag-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;background:var(--brand-light,#e8f4ff);color:var(--brand-ink);border-radius:10px;font-size:11px;font-weight:600}
.tag-chip .tc-x{cursor:pointer;opacity:.6;font-size:13px;line-height:1}
.tag-chip .tc-x:hover{opacity:1}
.tag-input-wrap{display:flex;flex-wrap:wrap;gap:5px;align-items:center;padding:6px 9px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-sm);min-height:38px;cursor:text;transition:border var(--t)}
.tag-input-wrap:focus-within{border-color:var(--brand-ink);background:var(--surface)}
.tag-input-wrap input{border:none;outline:none;background:transparent;font-size:13px;color:var(--text);flex:1;min-width:80px;padding:0}

/* ── CRM: Job cards ── */
.job-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:16px;margin-bottom:10px;box-shadow:var(--sm)}
.job-card-head{display:flex;align-items:flex-start;gap:10px;margin-bottom:12px}
.job-card-info{flex:1;min-width:0}
.job-card-name{font-size:14px;font-weight:800;color:var(--text);margin-bottom:2px;letter-spacing:-.2px}
.job-card-meta{font-size:11.5px;color:var(--text2)}
.job-card-value{font-size:18px;font-weight:800;color:var(--green);font-family:var(--font-sans);font-variant-numeric:tabular-nums;letter-spacing:-1px}
.pay-rows{border-top:1px solid var(--border);padding-top:7px;display:flex;flex-direction:column;gap:2px}
.pay-row{display:flex;align-items:center;gap:8px;padding:2px 0}
.pay-row-lbl{font-size:11px;font-weight:600;color:var(--text2);width:72px;flex-shrink:0}
.pay-row-amt{font-size:12px;font-weight:700;color:var(--text);font-family:var(--font-sans);font-variant-numeric:tabular-nums;flex:1}
.pay-status{padding:2px 8px;border-radius:10px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.3px}
.pay-status-unpaid{background:var(--orange-light);color:var(--orange-ink)}
.pay-status-paid{background:var(--green-light);color:var(--green)}
.pay-status-partial{background:var(--blue-light);color:var(--blue)}
.pay-status-overdue{background:var(--red-light);color:var(--red)}
.job-status-pill{padding:3px 9px;border-radius:10px;font-size:10.5px;font-weight:700}
.job-status-quoting{background:var(--orange-light);color:var(--warning-text)}
.job-status-design{background:var(--green-light);color:var(--success-text)}
.job-status-manufacture{background:var(--blue-light);color:var(--info-text)}
.job-status-installation{background:var(--teal-light);color:var(--success-text)}
.job-status-defects{background:var(--red-light);color:var(--danger-text)}
.job-status-active{background:var(--green-light);color:var(--success-text)}
.job-status-archived{background:var(--surface);color:var(--text2)}

/* ── Phase view sections ── */
.phase-section{margin-bottom:22px}
.phase-section-hd{display:flex;align-items:center;gap:10px;padding:9px 14px;border-radius:var(--r-sm);margin-bottom:10px}
.phase-section-name{font-size:11.5px;font-weight:800;text-transform:uppercase;letter-spacing:.8px;flex:1}
.phase-section-cnt{font-size:11px;font-weight:700;opacity:.75}
.phase-section-val{font-size:12px;font-weight:700;font-family:var(--font-sans);font-variant-numeric:tabular-nums;opacity:.9}
.phase-section-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:10px}
.phase-hd-quoting{background:var(--orange-light);color:var(--warning-text)}
.phase-hd-design{background:var(--green-light);color:var(--success-text)}
.phase-hd-manufacture{background:var(--blue-light);color:var(--info-text)}

/* ── Jobs table view ── */
.jobs-tbl thead th{background:var(--surface);padding:10px 14px;font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.7px;white-space:nowrap;border-bottom:2px solid var(--border)}
.jobs-tbl tbody td{padding:11px 14px;vertical-align:middle}
.jobs-tbl tbody tr:hover{background:var(--brand-light)}
.jt-num{font-size:11.5px;font-weight:800;color:var(--brand-ink);font-family:var(--font-sans);font-variant-numeric:tabular-nums;letter-spacing:.5px}
.jt-name{font-size:13px;font-weight:700;color:var(--text);line-height:1.3}
.jt-client{font-size:11px;color:var(--text3);margin-top:2px}
.jt-val{font-size:13px;font-weight:700;color:var(--green);font-family:var(--font-sans);font-variant-numeric:tabular-nums}
.jt-phase{display:inline-flex;align-items:center;padding:3px 9px;border-radius:12px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.3px;white-space:nowrap}
.jt-phase-quoting{background:var(--orange-light);color:var(--warning-text)}
.jt-phase-design{background:var(--green-light);color:var(--success-text)}
.jt-phase-manufacture{background:var(--blue-light);color:var(--info-text)}
.jt-phase-installation{background:var(--teal-light);color:var(--success-text)}
.jt-phase-defects{background:var(--red-light);color:var(--danger-text)}
.jt-phase-archived{background:var(--surface);color:var(--text2)}
.jt-inv-dots{display:flex;gap:5px;align-items:center}
.jt-inv-dot{width:9px;height:9px;border-radius:50%;border:1.5px solid var(--border2);display:inline-block}
.jt-inv-dot-paid{background:var(--green);border-color:var(--green)}
.jt-inv-dot-unpaid{background:var(--orange);border-color:var(--orange-ink)}
.jt-inv-dot-none{background:transparent}
.jt-actions{display:flex;gap:4px;opacity:0;transition:opacity var(--t)}
.jobs-tbl tr:hover .jt-actions{opacity:1}
.phase-hd-installation{background:var(--teal-light);color:var(--teal)}
.phase-hd-defects{background:var(--red-light);color:var(--red)}

/* ── Phase strip & gates ── */
.phase-strip{display:flex;align-items:center;flex-wrap:wrap;gap:3px;margin:0}
.phase-pill{font-size:10px;font-weight:700;padding:4px 9px;border-radius:10px;white-space:nowrap;letter-spacing:.2px;line-height:1.5;flex:1;text-align:center}
.phase-pill-done{background:var(--green-light);color:var(--green)}
.phase-pill-active{background:var(--brand);color:var(--white);box-shadow:-1px -1px 3px rgba(255,255,255,.3),2px 2px 6px rgba(105,98,84,.24)}
.phase-pill-future{background:var(--surface2);color:var(--text3);box-shadow:inset 1px 1px 3px rgba(105,98,84,.14),inset -1px -1px 2px rgba(255,255,255,.5)}
.phase-arr{font-size:10px;color:var(--border2);margin:0 1px}
.phase-divider{width:1px;height:22px;background:var(--border2);margin:0 6px;flex-shrink:0}
.phase-gate{display:inline-flex;align-items:center;gap:5px;font-size:11px;padding:4px 9px;border-radius:7px;border:1px solid var(--border);background:var(--surface);white-space:nowrap;flex-wrap:nowrap}
.phase-gate-ok{background:var(--green-light);border-color:var(--green)}
.phase-gate-block{background:var(--orange-light);border-color:var(--orange-mid)}
.pg-ok{color:var(--green);font-size:12px;flex-shrink:0}
.pg-block{color:var(--orange-ink);font-size:12px;flex-shrink:0}
.pg-lbl{color:var(--text2);flex:1}

/* ── Jobs Command Centre ── */
.jobs-tab-btn{background:transparent;border:none;padding:5px 14px;font-size:12px;font-weight:600;color:var(--text2);border-radius:6px;cursor:pointer;transition:background .15s,color .15s}
.jobs-tab-btn:hover{background:var(--bg);color:var(--text)}
/* Selected view = a light raised grey pill, not the dark brand fill (Dale). */
.jobs-tab-active{background:var(--surface3)!important;color:var(--text)!important;box-shadow:var(--xs)}
/* Board view */
.jcc-board{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;align-items:start}
.jcc-phase-col{background:var(--surface);border:1px solid var(--border);border-radius:10px;overflow:hidden}
.jcc-phase-hd{padding:9px 12px 8px;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.6px;display:flex;align-items:center;gap:7px;border-bottom:1px solid var(--border)}
.jcc-phase-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.jcc-phase-body{padding:8px}
.jcc-card{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:10px 11px;margin-bottom:7px;cursor:pointer;transition:border-color .15s,box-shadow .15s}
.jcc-card:last-child{margin-bottom:0}
.jcc-card:hover{border-color:var(--brand-ink);box-shadow:0 2px 8px rgba(0,0,0,.08)}
.jcc-card-num{font-size:10px;font-weight:800;color:var(--brand-ink);font-family:var(--font-sans);font-variant-numeric:tabular-nums;margin-bottom:2px}
.jcc-card-name{font-size:12.5px;font-weight:700;color:var(--text);margin-bottom:2px;line-height:1.3}
.jcc-card-client{font-size:11px;color:var(--text3);margin-bottom:6px}
.jcc-card-badges{display:flex;gap:4px;flex-wrap:wrap;align-items:center}
.jcc-badge-red{background:var(--red-light);color:var(--red);font-size:10px;font-weight:700;padding:2px 6px;border-radius:6px;white-space:nowrap}
.jcc-badge-amber{background:var(--orange-light);color:var(--warning-text);font-size:10px;font-weight:700;padding:2px 6px;border-radius:6px;white-space:nowrap}
.jcc-badge-blue{background:var(--blue-light);color:var(--blue);font-size:10px;font-weight:700;padding:2px 6px;border-radius:6px;white-space:nowrap}
.jcc-badge-green{background:var(--green-light);color:var(--success-text);font-size:10px;font-weight:700;padding:2px 6px;border-radius:6px;white-space:nowrap}
.jcc-health-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;margin-left:auto}
.jcc-health-red{background:var(--red)}
.jcc-health-amber{background:var(--orange)}
.jcc-health-green{background:var(--green)}
.jcc-empty-col{color:var(--text3);font-size:11.5px;text-align:center;padding:18px 10px}
.jcc-card-actions{margin-top:5px;display:flex;flex-direction:column;gap:2px}
.jcc-action-row{font-size:10.5px;color:var(--text2);display:flex;align-items:center;gap:4px;line-height:1.4}
.jcc-action-gate{color:var(--orange-ink);font-weight:700}
.jcc-action-blocked{color:var(--red);font-weight:700}
.jcc-phase-ready{background:var(--green-light);color:var(--success-text);font-size:10px;font-weight:700;padding:2px 6px;border-radius:5px;margin-top:4px;display:inline-block}
/* Gate-critical action highlighting in Work tab */
.action-gate-row{border-left:3px solid var(--orange)!important;background:var(--orange-light)!important;border-radius:0 6px 6px 0}
.action-gate-badge{font-size:10px;font-weight:700;background:var(--orange);color:var(--white);padding:1px 5px;border-radius:4px;margin-left:4px;flex-shrink:0}
.action-blocked-row{border-left:3px solid var(--red)!important;background:var(--red-light)!important;border-radius:0 6px 6px 0}
.action-blocked-reason{font-size:10px;color:var(--red);font-style:italic;margin-top:2px;padding-left:20px}
/* Focus view */
.jcc-focus{display:flex;flex-direction:column;gap:14px}
.jcc-focus-section{background:var(--surface);border:1px solid var(--border);border-radius:10px;overflow:hidden}
.jcc-focus-hd{padding:10px 14px 9px;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.6px;display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--border)}
.jcc-focus-row{display:flex;align-items:center;gap:10px;padding:8px 14px;border-bottom:1px solid var(--border2);cursor:pointer;transition:background .12s}
.jcc-focus-row:last-child{border-bottom:none}
.jcc-focus-row:hover{background:var(--surface2)}
.jcc-focus-job{font-size:10px;font-weight:800;color:var(--brand-ink);font-family:var(--font-sans);font-variant-numeric:tabular-nums;flex-shrink:0;min-width:40px}
.jcc-focus-label{font-size:12.5px;color:var(--text);flex:1}
.jcc-focus-client{font-size:11px;color:var(--text3);flex-shrink:0}
.jcc-focus-phase{font-size:10px;font-weight:600;padding:2px 7px;border-radius:5px;flex-shrink:0}

/* ── CRM: Xero badge ── */
.xero-badge{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:var(--r-xs);font-size:11.5px;font-weight:700}
.xero-connected{background:#13b5ea22;color:#13b5ea}
.xero-disconnected{background:var(--surface2);color:var(--text3)}

/* ── Settings sections ── */
.settings-section{background:var(--surface);border-radius:var(--r-sm);padding:20px;margin-bottom:14px;box-shadow:var(--tile)}
.settings-section h3{font-size:14px;font-weight:800;margin-bottom:4px;letter-spacing:-.2px}
.settings-section p{font-size:12px;color:var(--text2);margin-bottom:14px}
.settings-row{display:flex;align-items:center;gap:12px;margin-bottom:10px}
.settings-row label{font-size:12px;font-weight:600;color:var(--text2);width:140px;flex-shrink:0}
.settings-row input{flex:1;padding:7px 9px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-xs);font-size:12.5px;color:var(--text)}
.settings-row input:focus{border-color:var(--brand-ink);outline:none}
/* Money field — the $ sits INSIDE the input, always attached to it, at every width.
   (Replaces the old sibling "$"-span which the mobile wrap rule pushed onto its own line,
   leaving a dollar sign floating above the field. Matches the absolute-$ pattern used
   elsewhere in the app.) */
.mfld{position:relative;display:inline-flex;align-items:center;flex:0 0 auto}
.mfld>.cur{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text3);font-size:12.5px;line-height:1;pointer-events:none}
.mfld>input{padding-left:20px!important}
.settings-brand-tabs{display:flex;gap:8px;margin-bottom:16px}
.settings-brand-tab{padding:5px 14px;border-radius:var(--r-xs);font-size:12px;font-weight:600;cursor:pointer;border:1px solid var(--border);background:var(--surface);color:var(--text2);transition:all var(--t)}
.settings-brand-tab.active{background:var(--brand);color:var(--white);border-color:var(--brand-ink)}
.settings-layout{display:flex;gap:20px;align-items:flex-start}
.settings-subnav{display:flex;flex-direction:column;gap:4px;width:200px;flex-shrink:0;position:sticky;top:16px}
.settings-navitem{text-align:left;padding:9px 14px;border-radius:var(--r-xs);font-size:13px;font-weight:600;cursor:pointer;border:1px solid transparent;background:transparent;color:var(--text2);transition:all var(--t)}
.settings-navitem:hover{background:var(--surface2);color:var(--text)}
.settings-navitem.active{background:var(--brand);color:var(--white)}
.settings-content{flex:1;min-width:0;background:var(--panel);border-radius:var(--r);padding:18px 18px 4px;box-shadow:var(--sm)}
/* One Save for all of Settings (Dale 2026-07-26): the per-field Save buttons are hidden;
   a single sticky bar saves whatever changed, and leaving prompts. */
.settings-content button[onclick^="save"],.settings-content button[onclick^="paSave"]{display:none!important}
body:has(#page-settings.active) .content{padding-bottom:74px}
#set-savebar{display:none;position:fixed;left:0;right:0;bottom:0;z-index:420;background:var(--surface);border-top:1px solid var(--border);box-shadow:0 -4px 16px rgba(105,98,84,.14);padding:10px 16px calc(10px + env(safe-area-inset-bottom));align-items:center;gap:12px}
#set-savebar .sb-save-status{font-size:12px;color:var(--orange-ink);font-weight:600}
.settings-subnav-select{display:none;width:100%;margin-bottom:14px;padding:9px 10px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-xs);font-size:13px;font-weight:600;color:var(--text)}
.settings-brandlabel{font-size:11px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px}
.settings-empty{padding:10px 12px;font-size:12px;color:var(--text3);font-style:italic}
/* Website Assistant stat tiles: their own clean stacked card (they reuse .dkpi-card
   but have no icon and use .dkpi-val, so the dashboard icon-grid mangled them). */
#wa-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(155px,1fr));gap:12px}
#wa-kpis .dkpi-card{display:block!important;grid-template-columns:none!important;grid-template-areas:none!important;padding:15px 16px;text-align:left;cursor:default}
#wa-kpis .dkpi-card::after{content:none!important}
#wa-kpis .dkpi-val{grid-area:auto;font-size:26px;font-weight:800;color:var(--text);font-family:var(--font-sans);font-variant-numeric:tabular-nums;line-height:1.1;letter-spacing:-.5px}
#wa-kpis .dkpi-lbl{grid-area:auto;font-size:13px;font-weight:700;color:var(--text);margin-top:5px;line-height:1.2}
#wa-kpis .dkpi-sub{grid-area:auto;font-size:11.5px;font-weight:500;color:var(--text3);margin-top:3px;line-height:1.35}
@media(max-width:768px){ #wa-kpis{grid-template-columns:1fr} }
/* Collapsible neumorphic section (Expenses: General Expenses / Auto-Reconciliation) */
.fin-collapse{padding:0;overflow:hidden}
.fin-collapse-hd{display:flex;align-items:center;gap:10px;padding:14px 16px;cursor:pointer;user-select:none}
.fin-collapse-chev{margin-left:auto;color:var(--text3);font-size:12px;transition:transform .2s;flex-shrink:0}
.fin-collapse.open .fin-collapse-chev{transform:rotate(180deg)}
.fin-collapse-body{padding:0 16px 14px}

/* ── AI Chat Widget ── */
#chat-fab{position:fixed;bottom:80px;right:0;width:28px;height:96px;border-radius:8px 0 0 8px;background:var(--brand);color:var(--white);border:none;cursor:pointer;z-index:9100;box-shadow:-3px 0 12px rgba(0,0,0,.18);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;transition:width .15s,background .15s;padding:0}
#chat-fab:hover{width:34px;background:var(--brand-dark,#1446b0)}
#chat-fab .fab-label{writing-mode:vertical-rl;text-orientation:mixed;transform:rotate(180deg);font-size:10px;font-weight:700;letter-spacing:.06em;white-space:nowrap;line-height:1}
#chat-fab svg{width:18px;height:18px;pointer-events:none;flex-shrink:0}
#chat-panel{position:fixed;bottom:24px;right:30px;width:420px;height:580px;background:var(--surface);border:1px solid var(--border);border-radius:16px;box-shadow:0 12px 48px rgba(0,0,0,.18);z-index:9099;display:none;flex-direction:column;overflow:hidden;font-family:DM Sans,sans-serif}
#chat-panel.open{display:flex}
#chat-header{padding:14px 16px;background:var(--brand);color:var(--white);display:flex;align-items:center;gap:10px;flex-shrink:0}
#chat-header .ch-title{font-size:14px;font-weight:700;flex:1}
#chat-header .ch-brand{font-size:11px;font-weight:600;background:rgba(255,255,255,.22);padding:2px 8px;border-radius:20px}
#chat-header .ch-close{width:28px;height:28px;border-radius:50%;background:rgba(255,255,255,.18);border:none;color:var(--white);cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;transition:background .12s;flex-shrink:0}
#chat-header .ch-close:hover{background:rgba(255,255,255,.32)}
#chat-messages{flex:1;overflow-y:auto;padding:14px 14px 8px;display:flex;flex-direction:column;gap:10px}
.cm-bubble{max-width:88%;padding:10px 13px;border-radius:12px;font-size:13px;line-height:1.55;word-break:break-word}
.cm-bubble.ai{background:var(--bg);color:var(--text);border:1px solid var(--border);align-self:flex-start;border-bottom-left-radius:3px}
.cm-bubble.user{background:var(--brand);color:var(--white);align-self:flex-end;border-bottom-right-radius:3px}
.cm-bubble.ai b,.cm-bubble.ai strong{font-weight:700;color:var(--text)}
.cm-bubble.ai ul,.cm-bubble.ai ol{margin:5px 0 5px 16px;padding:0}
.cm-bubble.ai li{margin-bottom:2px}
.cm-bubble.ai code{background:var(--blue-light);padding:1px 5px;border-radius:3px;font-family:monospace;font-size:12px}
.chat-md-table{border-collapse:collapse;width:100%;margin:6px 0;font-size:12px}
.chat-md-table th,.chat-md-table td{border:1px solid var(--border);padding:4px 8px;text-align:left}
.chat-md-table th{background:var(--surface2);font-weight:700}
.chat-md-table td{font-variant-numeric:tabular-nums}
.cm-typing{display:flex;align-items:center;gap:3px;padding:10px 13px;background:var(--bg);border:1px solid var(--border);border-radius:12px;border-bottom-left-radius:3px;align-self:flex-start;width:fit-content}
.cm-typing span{width:7px;height:7px;background:var(--text2);border-radius:50%;animation:cm-dot 1.4s infinite ease-in-out}
.cm-typing span:nth-child(1){animation-delay:0s}
.cm-typing span:nth-child(2){animation-delay:.2s}
.cm-typing span:nth-child(3){animation-delay:.4s}
@keyframes cm-dot{0%,80%,100%{transform:scale(.6);opacity:.4}40%{transform:scale(1);opacity:1}}
#chat-suggestions{padding:6px 10px;display:flex;gap:6px;flex-wrap:wrap;border-top:1px solid var(--border);flex-shrink:0}
.cs-chip{padding:4px 10px;font-size:11.5px;font-weight:600;background:var(--blue-light);color:var(--brand-ink);border:1px solid var(--brand);border-radius:20px;cursor:pointer;white-space:nowrap;transition:background .12s,color .12s}
.cs-chip:hover{background:var(--brand);color:var(--white)}
#chat-input-row{padding:10px 12px;border-top:1px solid var(--border);display:flex;gap:8px;align-items:flex-end;flex-shrink:0}
#chat-input{flex:1;padding:9px 12px;font-size:13px;font-family:DM Sans,sans-serif;border:1.5px solid var(--border);border-radius:10px;resize:none;height:38px;max-height:110px;overflow-y:auto;background:var(--bg);color:var(--text);outline:none;transition:border-color .15s;line-height:1.4}
#chat-input:focus{border-color:var(--brand-ink)}
#chat-send{padding:0;width:36px;height:36px;border-radius:9px;background:var(--brand);color:var(--white);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:opacity .12s}
#chat-send:disabled{opacity:.45;cursor:default}
#chat-send svg{width:18px;height:18px}

/* ── Mobile hamburger (hidden on desktop) ── */
.mob-hamburger{display:none;width:36px;height:36px;border-radius:var(--r-xs);background:transparent;border:none;color:var(--text2);font-size:20px;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;line-height:1}
.sb-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:499}
.sb-overlay.open{display:block}

/* ── Job tab strip class ── */
.jp-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);background:var(--panel);flex-shrink:0;padding:0 18px;margin:10px 16px 0;border-radius:var(--r) var(--r) 0 0;box-shadow:var(--sm)}

/* ── Responsive — mobile ── */
/* ═══ NEEDS YOU stream + utility row + ⓘ explainers (UX redesign Phase 1) ═══ */
.ny-pill{font-size:10.5px;font-weight:700;padding:3px 10px;border-radius:10px;border:1px solid var(--border);background:var(--surface2);color:var(--text3);cursor:pointer;transition:all var(--t)}
.ny-pill:hover{border-color:var(--border2)}
.ny-pill.active{background:var(--brand);border-color:var(--brand-ink);color:var(--white)}
/* ── "Needs you" hierarchy: white breathing-space section header (matches the
   other dashboard cards), each urgency GROUP a quiet coloured left-rail beneath. ── */
.ny-bucket{margin:10px 14px 0;padding-left:11px;border-left:3px solid var(--nyc,var(--border2))}
.ny-bucket:last-child{margin-bottom:10px}
.ny-bh{display:flex;align-items:center;gap:7px;padding:2px 2px 6px;cursor:pointer;user-select:none}
.ny-bh-label{font-size:10.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:var(--nyc,var(--text2))}
.ny-bh-count{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-weight:700;color:var(--text3);font-size:10px}
.ny-bh-chev{margin-left:auto;color:var(--text3);font-size:11px}
.ny-bb{max-height:430px;overflow-y:auto}
.ny-brk{display:none}   /* phone-only flex row break — see the mobile dashboard block */
/* Second sub-line on a KPI tile: a different number from the headline (money not yet
   invoiced, total value of the jobs). Same quiet style as the sub-line above it and
   bracketed in the copy (Dale: a pill made it too prominent). */
.dkpi-ext{grid-area:ext;margin-top:3px;font-size:11.5px;font-weight:500;color:var(--text3);line-height:1.4}
.dkpi-ext:empty{display:none}
#needs-you[data-filter="money"] [data-nysrc]:not([data-nysrc="money"]),
#needs-you[data-filter="approvals"] [data-nysrc]:not([data-nysrc="approvals"]),
#needs-you[data-filter="fulfilment"] [data-nysrc]:not([data-nysrc="fulfilment"]){display:none}
.exp-i{border:none;background:none;color:var(--text3);font-size:11px;cursor:pointer;padding:0 2px;opacity:.65;line-height:1}
.exp-i:hover{opacity:1;color:var(--brand-ink)}
.exp-pop{position:fixed;z-index:9500;width:300px;background:var(--surface);border:1px solid var(--border);border-radius:10px;box-shadow:0 10px 30px rgba(0,0,0,.16);padding:12px 14px}
.uti-link{border:none;background:none;font-size:12px;font-weight:700;color:var(--text2);cursor:pointer;padding:3px 7px;border-radius:6px;display:inline-flex;align-items:center;gap:5px}
.uti-link:hover{background:var(--surface2)}
.uti-sep{color:var(--text3);font-size:11px}
.uti-panel{border-top:1px solid var(--border)}

@media(max-width:768px){
  /* Sidebar becomes a fixed overlay drawer */
  /* Xero-style FULL-SCREEN menu (Dale, overhaul chunk 1): the drawer takes the whole
     screen with big clean touch rows and a ✕ to close; tapping any item still closes. */
  .sb{position:fixed;top:0;left:0;height:100vh;z-index:500;transform:translateX(-100%);transition:transform .25s cubic-bezier(.4,0,.2,1);width:100vw;max-width:100vw}
  .sb.mob-open{transform:translateX(0)}
  .sb-mob-close{display:flex}
  /* Shortcuts band at the top of the full-screen menu (Xero inspiration) */
  /* Equal breathing room above and below the tiles (Dale). Two fixes: (1) the brand
     section's bottom padding left a darker sliver above the light band that read as
     extra space up top — trim it so the band hugs the BTB/Clikt tabs; (2) the band's
     own top/bottom padding is symmetric, so the light space around the tiles matches. */
  .sb-brand{padding-bottom:3px!important}
  .sb-shortcuts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding:12px;background:var(--panel);border-bottom:1px solid var(--border)}
  /* Collapsed menu → hide the top shortcuts band entirely (Dale: the four tiles squash
     into the 64px rail and their labels overlap into garble). Icons-only rail instead. */
  .sb.sb-collapsed .sb-shortcuts{display:none}
  .sb-sc{background:var(--surface);box-shadow:var(--tile);border:none;border-radius:12px;padding:11px 4px 9px;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:6px;cursor:pointer;font:inherit;min-height:74px}
  .sb-sc i{font-size:19px;color:var(--brand-ink)}
  .sb-sc span{font-size:10px;font-weight:700;color:var(--text2);line-height:1.2;text-align:center}
  .sb-sc:active{background:var(--surface2)}
  .sb .sb-item{padding:13px 14px;font-size:15px;border-radius:10px;margin-bottom:2px}
  .sb .sb-item .icon{font-size:19px;width:24px}
  .sb .sb-group-items .sb-item{padding-left:34px;font-size:14px}
  /* Group headers match the standalone item rows on the mobile menu (Dale: Guides &
     SOPs / Settings looked "distorted" next to the small 11px group labels). Same
     15px size + 24px icon so every top-level row reads as one uniform list; uppercase
     is kept as the only marker that a row is an expandable section. */
  .sb .sb-group-hd{padding:13px 14px;font-size:15px;letter-spacing:.3px}
  .sb .sb-group-hd .icon{font-size:19px;width:24px}
  .sb .sb-group-hd .sb-group-arrow{margin-left:auto}
  .sb-nav{padding:8px 12px calc(24px + env(safe-area-inset-bottom))}
  /* Main fills full width */
  .main{width:100%}
  /* Hamburger visible */
  .mob-hamburger{display:flex}
  /* Topbar tighter, and clear of the status bar / notch on an installed PWA so the title
     isn't jammed against the top edge (Dale: "no room above"). env() is 0 on devices with
     no inset, so this is a no-op there. border-box keeps the usable bar height unchanged. */
  .topbar{padding:0 10px;gap:6px;padding-top:env(safe-area-inset-top);height:calc(var(--topbar) + env(safe-area-inset-top))}
  /* Title (job name on the job page) must stay one line + ellipsis, or it wraps and overlaps the content below */
  .topbar-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1 1 0;min-width:0;font-size:14px}
  .topbar-search input{width:120px;font-size:12px}
  .topbar-search input:focus{width:150px}
  /* Content padding */
  .content{padding:10px}
  /* Stats: 2 cols */
  .stats-grid{grid-template-columns:repeat(2,1fr)!important;gap:7px}
  /* Dashboard: stack the 3 action panels to one column; KPIs to 2×2; hide Sync All (auto anyway).
     minmax(0,1fr) — NOT 1fr — so long unbreakable content can't blow the column past the screen. */
  .m-stack{grid-template-columns:minmax(0,1fr)!important}
  .m-stack2{grid-template-columns:repeat(2,minmax(0,1fr))!important}
  /* Finance Overview KPI strip: 5 tiles won't fit a phone (they crammed to ~72px and clipped
     the "$0.00" values). Two per row, values allowed to shrink rather than overflow. */
  .fov-kpis{grid-template-columns:repeat(2,minmax(0,1fr))!important}
  .fov-kpis .dkpi-num{font-size:19px!important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #sync-btn{display:none}
  /* Reports & other multi-col grids collapse so nothing squishes */
  .rep-grid,.rep-inv-grid,.fu-cols{grid-template-columns:minmax(0,1fr)!important}
  .ig{grid-template-columns:minmax(0,1fr)!important}
  /* ── Mobile flow pass 2 (full-app audit) ── */
  /* Page headers: title + action buttons wrap instead of pushing off-screen (Calendar/Financials/Invoices/Expenses) */
  .ph{flex-wrap:wrap;align-items:flex-start;row-gap:8px}
  .ph>div{flex-wrap:wrap}
  .ph-info p{display:none}   /* the intro blurb wastes half a screen on a phone */
  /* The topbar already shows the page title — repeating it as a big h2 burns a
     full band of screen (Dale's "Projects" appeared twice). Actions stay. */
  .ph-info h2{display:none}
  .ph{margin-bottom:2px}
  /* Job action bar: ONE compact row — Edit Job · Timeline · Catch me up · ⋯ More
     (_jpMobileActionCollapse pools every other button into the More sheet). */
  div:has(> #jp-action-bar){flex-wrap:wrap;padding:6px 12px 8px!important}
  #jp-action-bar{display:flex!important;gap:6px;flex:1 1 auto;min-width:0}
  #jp-action-bar>*{margin:0!important;white-space:nowrap;font-size:11.5px;padding:5px 9px}
  #jp-action-bar>*:empty{display:none}
  div:has(> #jp-action-bar)>.btn{font-size:11.5px;padding:5px 9px;white-space:nowrap}
  /* Job header: number on its own line as a small label, project name below it at a
     slightly smaller size so it fits (Dale). The number is a span in the same div, so
     display:block drops the name to the next line. */
  #jp-job-number{display:block;font-size:11.5px;letter-spacing:.4px;margin-bottom:1px}
  #jp-job-name{font-size:16px;font-weight:800;letter-spacing:-.3px}
  #jp-customer-name{font-size:10.5px}
  #jp-site-address-bar{font-size:10.5px}
  #jp-phase-strip{font-size:12px;padding:7px 14px 3px}
  #jp-status-note-bar{font-size:12px}
  /* Overview tab: hide the duplicate phase pills (the header strip above already shows them) */
  .jp-ov-phasestrip{display:none!important}
  /* Floating buttons: quick-add (⚡) and AI chat overlapped bottom-right — stack them */
  #chat-fab{bottom:88px;right:22px}
  #qa-fab{bottom:22px;right:22px}
  /* Wide tables (Customers, Suppliers, finance tables): scroll inside their own container */
  .page table{display:block;overflow-x:auto;max-width:100%;-webkit-overflow-scrolling:touch}
  /* Cross-job registers (RFIs / Submittals / POs): rows wrap into cards — ids + badges on
     line 1, title full-width beneath, project/supplier as a quiet third line. Replaces the
     old sideways-scroll (min-width:780) treatment; accordion + section collapse unchanged. */
  #rfi-all-list,#sub-all-list,#po-all-list{overflow-x:visible}
  #rfi-all-list .jl-list-hd,#sub-all-list .jl-list-hd,#po-all-list .jl-list-hd{display:none!important}
  [id^="xrfi-row-"]>div:first-child,[id^="xsubm-row-"]>div:first-child,[id^="xpo-row-"]>div:first-child{flex-wrap:wrap;row-gap:3px;padding:10px 2px}
  [id^="xrfi-row-"]>div:first-child>span[style*="flex:1"],[id^="xsubm-row-"]>div:first-child>span[style*="flex:1"],[id^="xpo-row-"]>div:first-child>span[style*="flex:1"]{flex:1 1 calc(100% - 22px)!important;order:4;margin-left:22px!important;white-space:normal!important;overflow:visible!important}
  [id^="xrfi-row-"]>div:first-child>span[style*="width:210px"],[id^="xsubm-row-"]>div:first-child>span[style*="width:210px"],[id^="xpo-row-"]>div:first-child>span[style*="width:200px"]{width:calc(100% - 22px)!important;order:5;margin-left:22px;font-size:11.5px!important;color:var(--text3)!important}
  [id^="xrfi-row-"]>div:first-child>div:last-child,[id^="xsubm-row-"]>div:first-child>div:last-child{margin-left:auto}
  /* PO rows also carry money + chips: amount joins line 1 (right), chips shrink + wrap below */
  [id^="xpo-row-"]>div:first-child>span[style*="width:110px"]{width:auto!important;margin-left:auto;font-weight:700!important;color:var(--text)!important}
  [id^="xpo-row-"]>div:first-child>span[style*="width:120px"],[id^="xpo-row-"]>div:first-child>span[style*="width:100px"]{width:auto!important;order:6}
  [id^="xpo-row-"]>div:first-child>span[style*="width:74px"]{width:auto!important;order:7;margin-left:auto}
  /* Expanded detail panels inside register rows must reflow, never widen the page */
  [id^="xrfi-row-"] div,[id^="xsubm-row-"] div,[id^="xpo-row-"] div{min-width:0}
  /* Safety net: nothing may wobble the page itself sideways */
  .content{overflow-x:hidden}
  /* Two-col stack */
  .two-col{grid-template-columns:1fr!important}
  /* Detail panel full width */
  .dp{width:100%;right:-100%}
  .dp.open{right:0}
  /* Modals full screen */
  .modal{width:100%!important;max-width:100%!important;max-height:100%!important;height:100%;border-radius:0!important;margin:0;padding:16px}
  .modal-overlay{align-items:flex-start!important}
  /* …but a bottom SHEET stays bottom-anchored. The flex-start rule above out-ordered
     .msheet-ov and left the sheet hanging off the top, so its last rows (and Cancel)
     were cut off the bottom of the screen — Dale's "window is cut off". */
  .modal-overlay.msheet-ov{align-items:flex-end!important}
  /* Job tabs scrollable */
  .jp-tabs{overflow-x:auto;-webkit-overflow-scrolling:touch;padding:0 10px;scrollbar-width:none}
  .jp-tabs::-webkit-scrollbar{display:none}
  .jp-tab{flex-shrink:0;white-space:nowrap}
  /* Job page header */
  #jp-content{padding:10px}
  #jp-phase-strip{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  #jp-phase-strip::-webkit-scrollbar{display:none}
  .phase-strip{flex-wrap:nowrap}
  /* Job action bar */
  #jp-action-bar{flex-wrap:wrap;gap:4px}
  .dp-actions{flex-wrap:wrap;gap:4px;padding:8px 12px}
  /* Dashboard KPI — full-width Xero-style cards, see the dashboard block below */
  /* Dashboard greeting */
  #dash-greeting{font-size:18px}
  /* Filter bar */
  /* Xero-style filter rows (overhaul chunk 2): search gets its own full-width row,
     the dropdown filters become pill chips beneath it — every list page at once. */
  .filter-bar{padding:10px 12px;gap:7px}
  .filter-bar .sw{flex:1 1 100%!important;max-width:none!important;min-width:0!important;order:-1}
  .filter-bar .sw input{min-height:40px;font-size:14px;border-radius:11px;width:100%}
  .filter-bar .fsel{border-radius:999px;padding:8px 30px 8px 14px;font-size:13px;font-weight:600;min-height:40px;background:var(--surface2);border-color:var(--border2);color:var(--text)}
  .filter-bar .fc{font-size:11px;margin-left:auto}
  .filter-bar .btn{min-height:40px;border-radius:999px}   /* 38 failed the 40px touch target */
  /* JOB-TAB submittal/RFI rows (Dale: "titles cut off — SUB-004 KF…"): same card
     treatment as the cross-job registers — ids/badges line 1, the TITLE takes its
     own full-width line beneath. Expanded detail rows (＋Respond · Approve · Mark
     as closed…) wrap instead of scrolling off-screen. */
  [id^="subm-row-"]>div:first-child,[id^="rfi-row-"]>div:first-child{flex-wrap:wrap;row-gap:3px;padding:10px 2px}
  [id^="subm-row-"]>div:first-child>span[style*="flex:1"],[id^="rfi-row-"]>div:first-child>span[style*="flex:1"]{flex:1 1 calc(100% - 22px)!important;order:4;margin-left:22px!important;white-space:normal!important;overflow:visible!important}
  [id^="subm-row-"]>div:first-child>div:last-child,[id^="rfi-row-"]>div:first-child>div:last-child{margin-left:auto}
  [id^="subm-row-"] div,[id^="rfi-row-"] div{min-width:0}
  [id^="subm-row-"] div[style*="display:flex"],[id^="rfi-row-"] div[style*="display:flex"]{flex-wrap:wrap}
  [id^="subm-row-"] .btn,[id^="rfi-row-"] .btn{min-height:38px}

  /* Comms/Notes email items: the header's no-wrap button cluster (Pin thread · ↗ Gmail,
     margin-left:auto) poked past the screen edge — wrap rows, cluster gets its own
     right-aligned line. */
  .comms-item{min-width:0}
  .comms-item div[style*="display:flex"]{flex-wrap:wrap}
  .comms-item div[style*="margin-left:auto"]{margin-left:0!important;width:100%;justify-content:flex-end;margin-top:4px}
  /* Notes tab: the fixed 340px Notepad column can't fit a phone — stack it below */
  #jp-content div[style*="grid-template-columns:1fr 340px"]{grid-template-columns:1fr!important}

  /* Follow-up / call-list cards: bold name, quiet meta line, thumb-sized actions */
  .fu-card{padding:13px 14px}
  .fu-cn{font-size:15px;font-weight:700}
  .fu-cm{font-size:12px;color:var(--text3);margin-top:2px}
  .fu-ca{margin-top:9px;gap:8px;flex-wrap:wrap;display:flex}
  .fu-ca .btn{min-height:36px;padding:6px 12px;font-size:12px}
  .sw{min-width:100px}
  /* ── Mobile premium pass 3 (Dale 2026-07-10: "premium functioning app") ── */
  /* Wider project tiles (Dale: "take up more screen") — the .page-content panel's
     18px padding ate ~36px; slim it to 7px each side on the jobs page. */
  #page-jobs .page-content{padding:12px 7px}
  /* Quoting pages had triple nesting (content 10 + panel 18 + rep-section 20 = ~48px
     of side gap). Dissolve the outer .page-content panel like the dashboard's, so the
     KPI tiles and pipeline cards sit straight on the page — same width as Projects. */
  [id^="page-quoting-"] .page-content{background:transparent!important;box-shadow:none!important;border:none!important;padding:0!important;border-radius:0!important}
  /* The render wraps its content in an inline padding:16px 20px div — flatten its side
     padding so the cards go full-width (it keeps the desktop panel look untouched). */
  [id^="page-quoting-"] .page-content>div[style*="padding:16px 20px"]{padding-left:0!important;padding-right:0!important;padding-top:0!important}
  /* Reports: #rep-content carries inline margin:8px 16px + padding:18px (~34px each
     side). Slim it so the KPI tiles use the window width, and stack the tiles one per
     row so every amount shows in FULL decimals (Dale — no more $49k rounding). */
  #rep-content{margin:6px 0 16px!important;padding:6px!important}
  #page-reports .rep-kpi-grid{grid-template-columns:1fr!important}
  #page-reports .rep-kpi{display:flex;flex-direction:column}
  #page-reports .rep-kpi-val{font-size:24px}
  /* Toolbar lane: view toggle left, sync-icon + New Job right (Dale moved them here
     from the page header, and the header actions hide on the phone). */
  #jobs-toolbar-lane{margin-bottom:10px}
  .ph-actions-desktop{display:none!important}
  #jobs-lane-actions{display:flex!important}
  #jobs-lane-actions .btn-sm{padding:6px 12px;font-size:12.5px;min-height:40px}   /* 34 failed the 40px touch target */
  /* Phase chips collapse into ONE dropdown on the phone (Dale: "combined into a sleek
     dropdown list") — the select opens as the branded bottom sheet like every other. */
  #jobs-phase-chips{display:none!important}
  #jobs-phase-sel-wrap{display:block;margin-bottom:8px}
  #jobs-phase-sel{width:100%;max-width:100%;min-width:0;min-height:40px;padding:8px 14px;font-size:13.5px;font-weight:600;border:1px solid var(--border);border-radius:11px;background:var(--surface);color:var(--text)}
  #jobs-list-controls>div:nth-child(2){margin-bottom:8px}
  #job-search-input{max-width:none}
  /* Due-today widget: slim */
  #upcoming-tasks-widget{padding:7px 12px;margin-bottom:8px}
  /* The list must scroll clear of the floating ⚡/AI buttons — no chip ever stuck under them */
  .content{padding-bottom:120px}
  /* Job header: tighter vertical rhythm (every saved pixel goes to the tabs) */
  div:has(> #jp-back-btn){padding:6px 12px 4px!important}
  div:has(> div > #jp-job-number){padding:0 12px 6px!important}
  #jp-site-address-bar{padding:0 12px 5px!important}
  #jp-phase-strip{padding:5px 12px 2px!important}
  #jp-status-note-bar{font-size:11.5px;padding:0 14px 7px!important}
  #jp-actions-panel > div:first-child{padding:6px 14px!important}
  /* Job-tab rows (POs, RFIs, submittals…): the no-shrink button cluster was crushing the
     info column to one word per line — info goes full-width first, buttons wrap BELOW it */
  .jp-row{flex-wrap:wrap;gap:6px}
  .jp-row-main{flex:1 1 100%;min-width:100%}
  .jp-row > div:not(.jp-row-main){width:100%;justify-content:flex-start!important;flex-wrap:wrap}
  /* PO modal line items: 6 fixed columns can't fit 380px (the description was pushed
     off-screen = "information missing"). Description takes its own full row; the
     numbers share the row beneath it. Header follows the same shape. */
  #pom-lines > div[style*="grid"]{grid-template-columns:56px minmax(0,1fr) 88px 88px 26px!important;padding:0 10px!important}
  #pom-lines > div[style*="grid"] > span:first-child{grid-column:1 / -1}
  #pom-lines .pli-item > div[style*="grid"]{grid-template-columns:56px minmax(0,1fr) 88px 88px 26px!important}
  #pom-lines .pli-desc{grid-column:1 / -1}
  /* Needs-you rows: calmer on a phone */
  .ndg-row{padding:7px 10px!important}
  .ndg-row .btn{font-size:10.5px;padding:3px 8px}
  /* Tab content: nowrap cells (expense rows, order-summary lines) must TRUNCATE on screen,
     not stretch the tab sideways — flex children default min-width:auto which lets a long
     description widen the whole page (Dale's zoomed-out Finance tab). */
  #jp-content div{min-width:0}
  #jp-content [style*="nowrap"]{max-width:100%}
  /* Expenses table: fixed money columns scroll sideways inside their card */
  .fin-x-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .fin-x-scroll .fin-x-inner{min-width:480px}
  /* Module headers (Expenses / Purchase Orders / …): buttons wrap under the title */
  .jp-module-hd{flex-wrap:wrap;row-gap:6px}
  /* Tables */
  thead th{padding:6px 8px;font-size:10px}   /* 9px column headings were below the legibility floor */
  tbody td{padding:8px 8px;font-size:12px}
  /* Badges smaller */
  .badge{font-size:10px;padding:1px 5px}
  /* Chat panel */
  #chat-panel{width:calc(100vw - 16px);right:8px;bottom:78px;height:65vh}
  /* stacked ABOVE the ⚡ quick-add fab (bottom:22) — they overlapped bottom-right */
  #chat-fab{bottom:88px;right:22px;width:48px;height:48px}
  /* Settings */
  .settings-row{flex-direction:column;align-items:flex-start;gap:4px}
  .settings-row label{width:auto}
  .settings-row input,.settings-row select{width:100%!important;max-width:100%!important}
  /* …but NOT the small number fields that sit inside an inline group. width:100% made
     them fight their siblings for the same flex line and collapse to ~20px, so a deposit
     of 36 rendered as "3(" and both payment-term boxes looked empty. Give them their own
     width back and let the GROUP wrap instead of the field shrinking. */
  .settings-row .dk7inv1,.settings-row .d1mlcqe,.settings-row .d1m80bga{width:100%;flex-wrap:wrap}
  .settings-row .dk7inv1 input,.settings-row .d1mlcqe input,.settings-row .d1m80bga input{
    width:auto!important;flex:0 0 auto;min-width:82px}
  .settings-row .dk7inv1 .u87{margin-left:0}
  /* Money field fills the row on mobile (the $ stays pinned inside it). */
  .settings-row .mfld{display:flex;width:100%}
  /* align-items:stretch — base is flex-start, which in the column layout shrink-wrapped
     the content to its widest child (so every section rendered ~490px wide and clipped).
     Stretch makes the content fill the screen; children then wrap within it. */
  .settings-layout{flex-direction:column;align-items:stretch}
  .settings-content{width:100%}
  .settings-section{width:100%}
  .settings-subnav{display:none}
  .settings-subnav-select{display:block}
  /* ── Settings full mobile cleanup (Dale 2026-07-26): every tab's sections were
     rendering wider than the screen and clipping on the right. Slim the nested panels
     and make each wide pattern wrap/stack so nothing is cut off. ── */
  .settings-content{padding:11px!important}
  .settings-section{padding:14px!important;min-width:0}
  .settings-section input:not([style*="width:auto"]),.settings-section select{max-width:100%}
  /* Financial/brand rows: the inline control cluster wraps; the small fixed inputs keep
     their width, but the grey helper text drops to its own full-width line — so each row
     reads label / input + Save / note, tidy and uniform. */
  .settings-section .settings-row>div{flex-wrap:wrap!important;width:100%;gap:8px}
  .settings-section .settings-row>div>span[style*="text-3"],
  .settings-section .settings-row>div>span[style*="var(--text3)"],
  .settings-section .settings-row>div>span[style*="var(--text2)"]{flex:1 1 100%;margin-left:0!important}
  .settings-section .settings-row select[style*="width:auto"]{width:100%!important}
  /* Two-up brand columns (e.g. Xero connect BTB | Clikt) stack */
  .settings-section [style*="grid-template-columns:1fr 1fr"],
  .settings-section [style*="grid-template-columns: 1fr 1fr"]{grid-template-columns:1fr!important}
  /* Note Tags: hide the column header (rows stack, so columns don't line up) and stack
     each tag's fields — name full width, section + folder side by side beneath. */
  .nt-head{display:none!important}
  .nt-row{flex-wrap:wrap;gap:8px!important}
  .nt-row .nt-label{flex:1 1 100%!important;min-width:0}
  .nt-row .nt-section,.nt-row .nt-folder{flex:1 1 46%!important;width:auto!important;min-width:0}
  /* Automation: the project-type chip cluster fills the row so its chips wrap in place */
  .ndg-rule-row>div:last-child{flex:1 1 100%!important;min-width:0}
  /* Wide tables inside settings (Squarespace imports) scroll inside their card */
  #sq-orders-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  /* Price Catalogue: its 7-column grid (~418px of fixed tracks) can't fit — stack each
     field full width so nothing clips. Reset the Add button's fixed grid-column span. */
  .cat-row{grid-template-columns:1fr!important;gap:6px!important}
  /* S-02: a saved catalogue row has 7 cells; collapsing them all into one column
     stacked seven deep and clipped the supply chip. Give the row an explicit three-
     line shape instead — name, then supplier + price, then how it gets purchased. */
  /* …and drop the nested scrollers. These boxes are max-height:260px with their own
     overflow, which on a phone meant two materials visible inside a scroll area inside
     a scrolling page. Let them flow; the page already scrolls. */
  #cat-materials-list,#cat-charges-list,#po-presets-list-shared{max-height:none!important;overflow:visible!important}
  .cat-row.cat-listrow{
    grid-template-columns:minmax(0,1fr) auto 92px!important;
    row-gap:5px!important;column-gap:8px!important;
    padding:9px 0;border-bottom:1px solid var(--surface2)}
  .cat-row.cat-listrow>*{grid-column:auto!important}
  .cat-listrow>:nth-child(1){grid-column:1/3!important;grid-row:1;font-weight:600}
  .cat-listrow>:nth-child(9){grid-column:3!important;grid-row:1;justify-self:end}
  .cat-listrow>:nth-child(2){grid-column:1!important;grid-row:2}
  .cat-listrow>:nth-child(4){grid-column:2!important;grid-row:2;justify-self:end}
  .cat-listrow>:nth-child(5){grid-column:3!important;grid-row:2;width:100%}
  .cat-listrow>:nth-child(3){grid-column:1/3!important;grid-row:3}
  .cat-listrow>:nth-child(6){grid-column:3!important;grid-row:3;justify-self:end;text-align:right}
  .cat-listrow>:nth-child(7){grid-column:2!important;grid-row:4;justify-self:end}
  .cat-listrow>:nth-child(8){grid-column:3!important;grid-row:4;justify-self:end}
  .cat-row>[style*="grid-column"]{grid-column:1!important}
  /* Saved material / charge rows read as a tidy card on a phone (was every cell on its own
     line, leaving a lone "$" floating above the price). Name + delete on top, supplier and
     status below, and the price ($ pinned to the input + derived rate) grouped on one line. */
  .cat-listrow{grid-template-columns:auto minmax(0,1fr) auto!important;gap:5px 7px!important;
    padding:10px 12px!important;border-bottom:1px solid var(--border);align-items:center}
  .cat-listrow:last-child{border-bottom:none}
  .cat-listrow>*{grid-column:auto!important}
  .cat-listrow>:nth-child(1){grid-column:1/3!important;grid-row:1;font-weight:600;font-size:13px!important;white-space:normal!important}
  .cat-listrow>:nth-child(7){grid-column:3!important;grid-row:1;justify-self:end}
  .cat-listrow>:nth-child(2){grid-column:1/4!important;grid-row:2;width:100%}
  .cat-listrow>:nth-child(3){grid-column:1/4!important;grid-row:3;white-space:normal!important;text-align:left!important}
  .cat-listrow>:nth-child(4){grid-column:1!important;grid-row:4;justify-self:start}
  .cat-listrow>:nth-child(5){grid-column:2!important;grid-row:4}
  .cat-listrow>:nth-child(6){grid-column:3!important;grid-row:4;justify-self:end}
  /* Phase gates compact */
  .phase-gate{font-size:10px;padding:3px 6px}
  /* Alert cards */
  .alert{min-width:110px}
  /* RFI / task badges */
  .sb-badge{font-size:8px;padding:1px 4px}
  /* Jobs list: use mobile cards */
  .jl-row{display:none!important}
  .jl-col-hd{display:none!important}
  .jm-card{display:block!important}
  /* Phase group header compact */
  .jl-phase-hd{padding:7px 12px}
  /* ── Touch targets (audit G001/G002/G009/G010/G011/G012) ──────────────────
     Everything with a tap handler gets a 40px hit area on a phone. Height only —
     no font, colour or spacing change, so nothing re-flows around them. */
  .btn,.jl-phase-hd,.d13zgp64,.dqqhz54{min-height:40px}
  .btn{display:inline-flex;align-items:center;justify-content:center;min-width:40px}
  /* Small inline links/toggles: pad the hit box, keep the text where it is. */
  .d3qv351,.d3mnxkh{display:inline-flex;align-items:center;min-height:40px;padding:0 2px}
  .jl-ph-val{display:none}
  /* ── Mobile pass 4 (2026-07-10 audit: functional/premium/efficient) ── */
  /* Floating ⚡/AI buttons must never sit ON TOP of an open modal, sheet, drawer or
     detail panel and steal taps (modal z300 < fab z9100/9300 — verified bug). */
  body:has(.modal-overlay.open) #qa-fab, body:has(.modal-overlay.open) #chat-fab,
  body:has(.sb.mob-open) #chat-fab,   /* ＋ stays up over the menu (Xero does the same); only the AI bubble hides */
  body:has(.dp.open) #qa-fab, body:has(.dp.open) #chat-fab,
  body:has(.alerts-drawer.open) #qa-fab, body:has(.alerts-drawer.open) #chat-fab,
  body:has(#qa-overlay[style*="flex"]) #chat-fab{display:none!important}
  /* Global search results: was a 550px desktop dropdown hanging 312px off the LEFT edge
     of a 390px phone — pin it as a full-width sheet under the topbar instead. */
  .gs-dd{position:fixed;top:calc(var(--topbar) + 6px);left:8px;right:8px;min-width:0;max-width:none;max-height:65vh;overflow-y:auto}
  /* Jobs TABLE view: row actions are hover-revealed on desktop — no hover on touch */
  .jt-actions{opacity:1}
  /* Explainer popover: never wider than the screen */
  .exp-pop{width:auto;max-width:calc(100vw - 24px)}
  /* Tap targets: filter pills / info ⓘ / QA stepper get a real thumb-sized hit area */
  .ny-pill{padding:5px 10px}
  .exp-i{padding:4px 8px;margin:-4px -4px}
  .qa-step{width:38px;height:38px}
  /* Home-indicator safe area (iPhone): keep the FABs + content clear of the gesture zone */
  #qa-fab{bottom:calc(22px + env(safe-area-inset-bottom))}
  #chat-fab{bottom:calc(88px + env(safe-area-inset-bottom))}
  /* While the menu is open the ＋ floats over it (you can create from anywhere), but at
     22px it landed right on the sidebar footer's power/logout button (Dale). Lift it
     clear of the footer whenever the menu is open. */
  body:has(.sb.mob-open) #qa-fab{bottom:calc(92px + env(safe-area-inset-bottom))!important}
  .content{padding-bottom:calc(120px + env(safe-area-inset-bottom))}
  /* Calendar: swap the 7-col month grid (unusable at 390px) for the day-by-day agenda.
     !important — the agenda div carries inline display:none as its desktop default. */
  #cal-grid-card{display:none!important}
  #cal-agenda{display:block!important}
  /* Expenses page (Financials → Expenses) — Dale: "windows and text cut off … make it
     premium like the Xero app". Six columns can't fit a phone, and hiding Description +
     Type lost information. Each DATA row becomes a card instead: project + amount on the
     headline, then date · supplier, then the full description (wrapped) and the type
     badge. Tapping a row still opens the full bill detail. Only .fin-exp-row is
     restructured — the header / month / total rows keep their grid. */
  /* GRID areas, not flex-wrap: with flex the amount got pushed onto the date's line
     whenever a project name wrapped to two lines, so every row read differently
     (Dale: "the date pushing the amount, the supplier next to the date"). Fixed
     areas mean the amount is ALWAYS top-right and the meta line is always beneath. */
  /* grid-template-columns MUST be !important — the row carries the desktop
     six-column template as an INLINE style, which otherwise wins and leaves the
     areas mapped onto the wrong tracks. */
  #fin-exp-body .fin-exp-row{
    display:grid!important;grid-template-columns:max-content minmax(0,1fr) max-content!important;
    grid-template-areas:"proj proj amt" "date supp supp" "desc desc desc" "type type type"!important;
    gap:3px 8px!important;padding:12px!important;align-items:start}
  #fin-exp-body .fin-exp-row>div{padding:0!important;white-space:normal!important;overflow:visible!important;text-overflow:clip!important;min-width:0;align-self:start!important}
  #fin-exp-body .fin-exp-row>div:nth-child(2){grid-area:proj;font-weight:700;font-size:13.5px;line-height:1.3}
  #fin-exp-body .fin-exp-row>div:nth-child(6){grid-area:amt;font-size:14px;white-space:nowrap!important;justify-self:end}
  #fin-exp-body .fin-exp-row>div:nth-child(1){grid-area:date;font-size:11.5px;white-space:nowrap!important;justify-self:start}
  #fin-exp-body .fin-exp-row>div:nth-child(3){grid-area:supp;font-size:11.5px;justify-self:start}
  #fin-exp-body .fin-exp-row>div:nth-child(4){grid-area:desc;font-size:12px;margin-top:2px;color:var(--text2)}
  #fin-exp-body .fin-exp-row>div:nth-child(5){grid-area:type;margin-top:5px;justify-self:start}
  /* The month header + grand-total rows only ever show a label and a figure on a phone. */
  #fin-exp-body div[style*="grid-column:1/5"]{grid-column:1/3!important}
  #fin-exp-body div[style*="grid-column:1/6"]{grid-column:1/4!important}
  #fin-exp-body div[style*="grid-template-columns:90px 1.8fr"]:not(.fin-exp-row){grid-template-columns:1fr auto!important}
  #fin-exp-body div[style*="grid-template-columns:90px 1.8fr"]:not(.fin-exp-row)>div:nth-child(n+3){display:none}

  /* Unreconciled Xero Expenses banner: same treatment — contact + amount headline,
     date and the FULL description beneath, then the action controls wrapped so
     Link / Split / Dismiss / Rule are all reachable (they were running off-screen). */
  /* The row is a 6-column CSS GRID (inline styles). Flexbox `order` can't reorder grid
     children, which is why items landed on top of each other. Re-place them EXPLICITLY
     as a 3-col grid: headline row, then quiet meta lines, then the controls. */
  #fin-unreconciled-body .unr-row{display:grid!important;grid-template-columns:auto minmax(0,1fr) auto!important;align-items:start;gap:3px 12px!important;padding:14px!important}
  #fin-unreconciled-body .unr-row>div{padding:0!important;min-width:0}
  /* Row 1: checkbox | contact (name+badge) | amount (incl.GST beneath, right-aligned). */
  #fin-unreconciled-body .unr-row>div:nth-child(1){grid-column:1;grid-row:1;margin-top:2px}
  #fin-unreconciled-body .unr-row>div:nth-child(3){grid-column:2;grid-row:1}
  #fin-unreconciled-body .unr-row>div:nth-child(3)>div{white-space:normal!important;overflow:visible!important}
  #fin-unreconciled-body .unr-row>div:nth-child(5){grid-column:3;grid-row:1;text-align:right!important;padding-right:0!important;font-size:13px}
  /* Row 2: date. Row 3: description. Both quiet, both full width under the name. */
  #fin-unreconciled-body .unr-row>div:nth-child(2){grid-column:2/4;grid-row:2;font-size:11px;color:var(--text3);white-space:normal!important;overflow:visible!important}
  #fin-unreconciled-body .unr-row>div:nth-child(4){grid-column:2/4;grid-row:3;padding:0!important;font-size:12px;color:var(--text2);white-space:normal!important;overflow:visible!important;text-overflow:clip!important}
  /* Row 4: project picker + action buttons, full width. */
  #fin-unreconciled-body .unr-row>div:nth-child(6){grid-column:1/4;grid-row:4;display:flex!important;flex-wrap:wrap;margin-top:10px;gap:8px!important}
  /* Banner header: title row wraps cleanly and the "action required" subtitle drops to
     its own line instead of cramming next to the chevron. */
  #fin-unreconciled-banner>div:first-child{align-items:flex-start}
  #fin-unreconciled-banner>div:first-child>div{flex-wrap:wrap;gap:6px 8px}
  #fin-unreconciled-banner>div:first-child>div>span:last-child{flex:1 1 100%;margin-left:26px}
  /* A <select> sizes itself to its LONGEST option (job names run long), so it must be
     explicitly clamped or it pushes past the screen edge. */
  #fin-unreconciled-body .unr-row .fsel{flex:1 1 100%;width:100%;max-width:100%!important;min-width:0;box-sizing:border-box;min-height:40px}
  #fin-unreconciled-body .unr-row .btn{min-height:38px;flex:1 1 auto}
  /* Its header row is meaningless once the rows are cards */
  #fin-unreconciled-body div[style*="grid-template-columns:36px 80px 150px"]:not(.unr-row){display:none!important}

  /* Expenses filter bar: search on its own row, then the four dropdowns as an even
     2-up grid, then the totals on their own line — they were all jammed together
     at ragged widths (Dale: "clustered like that is horrible"). */
  /* NB this bar is an inline-styled flex div, not .filter-bar — match it by the
     search field it contains. */
  #page-fin-expenses div:has(> .sw > #fin-exp-q){display:grid!important;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px!important;align-items:stretch!important}
  #page-fin-expenses div:has(> .sw > #fin-exp-q) > .sw{grid-column:1 / -1;min-width:0!important;max-width:none!important;flex:none!important}
  #page-fin-expenses div:has(> .sw > #fin-exp-q) > .fsel{width:100%;max-width:100%!important;min-width:0;box-sizing:border-box;min-height:40px}
  #page-fin-expenses div:has(> .sw > #fin-exp-q) > span{grid-column:1 / -1;margin-left:0!important;padding-top:8px;border-top:1px solid var(--border);font-size:12px}
  /* The To pay / Total / count cluster was a right-floated flex box that wrapped into a
     cramped 3-column mess (Dale). Full width, its own tidy row: To pay + Total together,
     the count pushed right. */
  #page-fin-expenses div:has(> span > #fin-exp-topay){grid-column:1 / -1!important;margin-left:0!important;display:flex!important;flex-wrap:wrap;align-items:center;gap:6px 18px;padding-top:8px;border-top:1px solid var(--border)}
  #page-fin-expenses div:has(> span > #fin-exp-topay) > span{font-size:12px;flex-shrink:0}
  #page-fin-expenses div:has(> span > #fin-exp-topay) .fc{margin-left:auto}
  /* The 6-column table header (Date/Project/Supplier/…) is meaningless once rows are
     cards — it clipped to a stray "Date  Project". Hide it. */
  #fin-exp-body div[style*="8px 8px 0 0"]{display:none!important}

  /* Give each block of the Expenses page its own neumorphic card so the month list,
     General Expenses and the Rules section read as separate things (they ran together). */
  #page-fin-expenses .page-content>.card,
  #page-fin-expenses .page-content>div>.card{border-radius:var(--r);box-shadow:var(--tile,var(--sm));margin-bottom:14px;overflow:hidden}
  #fin-exp-body{border-radius:var(--r);overflow:hidden}
  /* Month header + grand total: clear banded separators, not bare rows */
  #fin-exp-body div[style*="grid-column:1/5"],
  #fin-exp-body div[style*="grid-column:1/6"]{font-weight:700}
  /* Job-page expenses card: hide the Ex-GST column (inc-GST IS the amount) so the row
     fits without sideways scroll; compress the fixed cells */
  .fin-x-scroll .fin-x-inner{min-width:0}
  .fin-x-inner .fin-ex-col{display:none!important}
  .fin-x-inner div[style*="width:70px"]{width:54px!important}
  .fin-x-inner div[style*="width:90px"]{width:62px!important}
  .fin-x-inner div[style*="width:88px"]{width:82px!important}
  .fin-x-inner div[style*="width:52px"]{width:44px!important}
  .fin-x-inner>div{gap:6px!important}
  /* Job page: the header block used to be a fixed flex column that left the tab content a
     ~100px sliver — on the phone the whole page scrolls instead, and the tab strip sticks
     to the top (top:-10px counters the .content padding). */
  #page-job.active{display:block;height:auto}
  #jp-content{overflow-y:visible;flex:none}
  .jp-tabs{position:sticky;top:-10px;z-index:60}

  /* ── Mobile pass 6 (2026-07-13): legacy data-tables → stacked cards ──
     Invoices / Customers / Suppliers / Active Leads / Pipeline used to scroll
     sideways inside their box (Invoices 679px, Customers 857px in a 375 view).
     They now render each row as a labelled card. _cardStamp() adds .mcard to the
     table and copies each column header into td[data-label] after every render. */
  .tbl:has(table.mcard){overflow:visible}
  table.mcard,table.mcard tbody{display:block;width:100%}
  table.mcard{overflow:visible!important;border-collapse:separate;font-size:13px}
  table.mcard thead{display:none}
  table.mcard tr{display:block;background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--sm);padding:2px 14px;margin-bottom:10px}
  table.mcard td{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:8px 0;border:none;text-align:right;white-space:normal;overflow-wrap:anywhere;font-size:13px;min-height:0;color:var(--text)}
  table.mcard td a,table.mcard td .cm{overflow-wrap:anywhere;word-break:break-word}
  table.mcard td+td{border-top:1px solid var(--border)}
  table.mcard td::before{content:attr(data-label);flex:0 0 38%;color:var(--text3);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.3px;text-align:left}
  table.mcard td:not([data-label])::before{display:none}
  table.mcard td:empty{display:none}
  table.mcard td>div,table.mcard td>span{min-width:0}
  /* One value block per cell (_cardStamp wraps cell content in .mcv): parts stack
     right-aligned under each other; word-wrap at word boundaries, not mid-word. */
  table.mcard td .mcv{display:block;flex:1;min-width:0;text-align:right;overflow-wrap:break-word}
  table.mcard td:first-child .mcv,table.mcard td:has(.cp) .mcv{text-align:left}
  table.mcard td .mcv>div{margin-top:1px}

  /* Invoices/Quotes KPI tiles (Outstanding · Overdue · Showing): 3 cramped boxes
     at 375px — become slim full-width rows, label left + amount right. */
  #page-fin-invoices [style*="grid-template-columns:repeat(3,1fr)"],
  #page-fin-quotes [style*="grid-template-columns:repeat(3,1fr)"]{grid-template-columns:1fr!important;gap:8px!important}
  #page-fin-invoices [style*="grid-template-columns:repeat(3,1fr)"]>.card,
  #page-fin-quotes [style*="grid-template-columns:repeat(3,1fr)"]>.card{display:flex;align-items:center;justify-content:space-between;gap:12px;text-align:left!important;padding:11px 16px!important}
  #page-fin-invoices [style*="grid-template-columns:repeat(3,1fr)"]>.card>div:first-child,
  #page-fin-quotes [style*="grid-template-columns:repeat(3,1fr)"]>.card>div:first-child{margin-bottom:0!important;font-size:12px!important}
  #page-fin-invoices [style*="grid-template-columns:repeat(3,1fr)"]>.card>div:last-child,
  #page-fin-quotes [style*="grid-template-columns:repeat(3,1fr)"]>.card>div:last-child{font-size:16px!important;white-space:nowrap}

  /* Finance Overview (Dale, screenshot 5): the Quotes/Invoices/Expenses trio was
     3 word-per-line columns at 375px — stack them full-width instead. */
  #page-fin-overview [style*="grid-template-columns:repeat(3,1fr)"]{grid-template-columns:1fr!important}
  /* Recent Payments rows: name group takes its own full line; date + amount pair up
     on the line beneath (the fixed date used to wrap vertically "14- 07- 2026"). */
  #fov-recent-payments>div{flex-wrap:wrap;row-gap:4px}
  #fov-recent-payments>div>div:first-child{flex:1 1 100%;min-width:0}
  #fov-recent-payments>div>div:last-child{flex:1 1 100%;justify-content:space-between}
  #fov-recent-payments>div>div:last-child span:first-child{white-space:nowrap}
  /* Title cell (the .cp name, or first col): bigger, left-aligned, no label/divider */
  table.mcard td:has(.cp),table.mcard td:first-child{display:block;text-align:left;border-top:none;padding-top:11px;padding-bottom:5px}
  table.mcard td:has(.cp)::before,table.mcard td:first-child::before{display:none}
  table.mcard td:has(.cp) .cp,table.mcard td:first-child>div:first-child{font-size:15px;font-weight:700}
  table.mcard .cs{font-size:12px}
  /* Actions row (last col): buttons are hover-hidden on desktop (opacity:0) — force
     them visible and wrap them into a full-width row on touch. */
  table.mcard td:last-child{display:flex;justify-content:flex-start;flex-wrap:wrap;gap:8px;text-align:left;border-top:1px solid var(--border);padding-top:11px;margin-top:2px}
  table.mcard td:last-child::before{display:none}
  table.mcard td:last-child .ra{opacity:1;flex-wrap:wrap;gap:8px}
  table.mcard td:last-child .btn{min-height:38px;padding:6px 12px;font-size:12px}
  /* Hide the bulk-select checkbox column in card view (Active Leads) — placed last so
     it wins the source-order tie against the first-child title rule. */
  table.mcard td:has(.c-selbox){display:none}

  /* ── Compact list cards (2026-08-01) ── A phone card that stacks every column becomes a
     ~400px wall (Customers = 9 rows), so you scroll past two records a screen. Hide the
     low-signal columns in CARD VIEW only — the full record is one tap away in the detail
     panel, and the desktop table is untouched. Tighter row padding too. */
  table.mcard td{padding:6px 0}
  #page-customers table.mcard td[data-label="Company"],
  #page-customers table.mcard td[data-label="Source"],
  #page-customers table.mcard td[data-label="Added"]{display:none}
  #page-suppliers table.mcard td[data-label="Website"],
  #page-suppliers table.mcard td[data-label="Added"]{display:none}
  #page-fin-invoices table.mcard td[data-label="Type"]{display:none}
  #page-pipeline table.mcard td[data-label="Website"]{display:none}
  #page-fin-quotes table.mcard td[data-label="Sent"]{display:none}
  /* Reusable: drop any cell from card view (e.g. the Xero-link column, which is a desktop
     convenience and rendered a lone "—" as a phantom actions row on phones). */
  table.mcard td.mcard-hide{display:none!important}
  /* Job Overview quote card: its 7-button action cluster (Xero·PDF·Resend·Follow-up·Sync·
     Accept·Reset) was a flex-shrink:0 block that stayed at max-content (~427px) and overflowed
     the phone, making the WHOLE Overview horizontally scrollable (everything looked shifted).
     Drop the buttons onto their own full-width line so they wrap properly. */
  .jpq-head{flex-wrap:wrap}
  .jpq-actions{flex-basis:100%;justify-content:flex-start}
  /* ── Thumb-friendly touch targets (2026-08-01) ── Buttons were as short as 21px and topbar
     icons 34px on a phone. Standalone icon buttons → 40×40; full-width rows & buttons get a
     minimum height so they're comfortable to tap (Apple HIG ~44; 40 is the pragmatic bar). */
  #gs-mob-btn,#ndg-btn,#alerts-btn,#help-btn,#nav-back-btn,.mob-hamburger,.sb-mob-close{width:40px!important;height:40px!important;min-height:40px}
  #sb-brand-b2b-tab,#sb-brand-clikt-tab{min-height:40px}
  .sb-settings-sub-item{min-height:40px}
  .btn{min-height:40px}
  .rep-tab,.rep-period-btn,.ny-pill,#jt-board,#jt-focus,#jt-list,.ny-bh{min-height:40px}
  select,input:not([type=checkbox]):not([type=radio]):not([type=hidden]){min-height:40px}
  #ny-refresh,#dash-ai-refresh,.ny-pill,#v-A,#v-B,.alerts-btn,.exp-i,#fin-inv-sync-btn{min-width:40px}
  .alerts-btn,#fin-inv-sync-btn,.exp-i{min-height:40px}
  th{font-size:11px}

  /* Reports sub-tab strip + period strip: scroll horizontally instead of overflowing */
  #page-reports > div:first-child > div:last-child{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  #page-reports > div:first-child > div:last-child::-webkit-scrollbar{display:none}
  .rep-tab{flex-shrink:0}
  .rep-tbl-wrap,#rep-content > div[style*="overflow-x"]{border:1px solid var(--border);border-radius:10px}
  /* Reminders "Job Tasks" filter pills: scroll strip (were overflowing at 369px) */
  #job-tasks-filter-bar{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;flex-wrap:nowrap;max-width:100%;padding-bottom:2px}
  #job-tasks-filter-bar::-webkit-scrollbar{display:none}
  #job-tasks-filter-bar .btn{flex-shrink:0}

  /* Horizontal scroll strips get a right-edge fade so it's clear more is off-screen */
  .jp-tabs,#jobs-list-controls>div:first-child,#job-tasks-filter-bar,#page-reports > div:first-child > div:last-child{
    -webkit-mask-image:linear-gradient(to right,var(--black) calc(100% - 22px),transparent);
    mask-image:linear-gradient(to right,var(--black) calc(100% - 22px),transparent)}

  /* Topbar search: widen on focus (overlaps neighbours briefly) so the placeholder
     and typed text aren't clipped at the old 120px lock. */
  .topbar-search input:focus{width:min(60vw,240px)}

  /* KPI tile strips (Invoices/Quotes "Outstanding · Overdue · Showing" etc.) use inline
     repeat(3,1fr)/repeat(4,1fr) grids whose 1fr floor is min-content — a wide $ value
     forced them off-screen. minmax(0,…) lets the tiles shrink; 4-up folds to 2-up. */
  [style*="grid-template-columns:repeat(3,1fr)"],[style*="grid-template-columns: repeat(3, 1fr)"]{grid-template-columns:repeat(3,minmax(0,1fr))!important}
  [style*="grid-template-columns:repeat(4,1fr)"],[style*="grid-template-columns: repeat(4, 1fr)"]{grid-template-columns:repeat(2,minmax(0,1fr))!important}
  [style*="grid-template-columns:repeat(5,1fr)"],[style*="grid-template-columns: repeat(5, 1fr)"]{grid-template-columns:repeat(2,minmax(0,1fr))!important}

  /* ── Dashboard alignment (Dale, screenshot 2): stack the greeting zone left-aligned
     (greeting → date → "all clear" note), pull the Needs-you toolbar (refresh + Suggest)
     out of the right edge onto its own left-aligned row, and turn the Brief-me utility
     strip into a tidy 2-col grid instead of a ragged dot-separated wrap. ── */
  div:has(> #dash-greeting){flex-direction:column;align-items:flex-start;gap:2px!important;margin-bottom:10px!important}
  /* Separate the title block (greeting + date) from the next-steps summary line */
  #dash-daystrip{margin-left:0!important;margin-top:9px!important}

  /* ── Xero-style dashboard (Dale 2026-07-24: "tiles separated with the neomorphic
     border, each taking the full width… more room so it does not look so compressed").
     The white dash-panel wrapper stole ~36px of width and boxed the cards inside
     another box — on a phone the cards ARE the layout, sitting straight on the page
     background with their own tile shadow, exactly like the Xero home screen. ── */
  .dash-panel{background:transparent!important;box-shadow:none!important;padding:0!important;border-radius:0!important}
  .dash-panel>.card,#needs-you{margin-bottom:12px!important}
  /* One stat card per row. NB the element also matches the repeat(4,1fr) rule above,
     so this needs the attribute selector to out-specify it. */
  .m-stack2[style*="grid-template-columns"]{grid-template-columns:minmax(0,1fr)!important;gap:12px!important}
  /* Dale's reference layout: icon + title vertically centred on the LEFT, and the
     value / sub-line / pill stacked left-aligned on the RIGHT. The icon and title
     areas repeat down all three content rows, so each spans the full height and
     centres against the whole block. Fixed title column so the value starts at the
     same x on every card. Chevron leaves the grid and pins right. */
  .dkpi-card{position:relative;padding:15px 30px 15px 15px;column-gap:12px;row-gap:2px;
    grid-template-columns:auto 112px minmax(0,1fr);justify-items:start;text-align:left;align-items:center;
    grid-template-areas:"ico lbl num" "ico lbl sub" "ico lbl ext"}
  .dkpi-card::after{content:'›';position:absolute;right:13px;top:50%;transform:translateY(-50%);font-size:22px;line-height:1;font-weight:600;color:var(--text3)}
  .dkpi-icon{grid-area:ico;align-self:center;width:38px;height:40px;font-size:16px}
  .dkpi-lbl{grid-area:lbl;align-self:center;font-size:14px;font-weight:700;color:var(--text);line-height:1.2}
  .dkpi-num{grid-area:num;font-size:27px;margin-top:0;line-height:1.1}
  .dkpi-sub{grid-area:sub;font-size:12.5px;margin-top:3px}
  .dkpi-ext{grid-area:ext;margin-top:3px;font-size:12px}

  /* ── One continuous header on the dashboard (Dale: "remove 'dashboard' from next to
     the menu bar… integrate the good afternoon and date as part of the top banner").
     The greeting block is full-bleed on the topbar's own surface so the two read as a
     single banner, with the next-steps strip as a quiet sub-band beneath it. ── */
  /* No inline title in the topbar on ANY page — the page name shows as a big heading
     below it instead, so every page matches the dashboard banner (Dale). */
  #topbar-title{display:none}
  /* With the title gone nothing pushes the icon cluster right — pin it there (Dale:
     "the icons on the top need to be on the right!"). */
  #topbar-actions{margin-left:auto!important}
  /* display:block — the hero is a plain stack here, and a negative side margin on a
     flex ITEM doesn't pull it past the parent's padding (the daystrip sat 16px in and
     overhung the right edge by the same). Block layout bleeds it correctly. */
  /* Soft-curved banner (Dale): rounded bottom corners + a downward shadow so the
     header reads as a card floating above the beige page. overflow:hidden clips the
     daystrip sub-band into the rounded bottom. */
  #dash-hero{display:block!important;background:var(--surface);margin:calc(var(--gutter,10px)*-1) calc(var(--gutter,10px)*-1) 14px!important;padding:14px 16px 0;border-radius:0 0 20px 20px;overflow:hidden;box-shadow:0 6px 16px rgba(105,98,84,.13)}
  #dash-hero #dash-greeting{font-size:21px!important;margin:0}
  #dash-hero #dash-date{margin:3px 0 0!important}
  #dash-hero #dash-daystrip{display:block!important;background:var(--surface2);margin:12px -16px 0!important;padding:9px 16px;border-top:1px solid var(--border)}

  /* Generic page-title banner for every non-dashboard page: same surface/heading as
     the greeting hero. It's the first child of .content, so it bleeds to the edges
     with negative margins matching .content's 10px padding. */
  #mob-page-hero{display:block;background:var(--surface);margin:-10px -10px 14px;padding:15px 16px 17px;border-radius:0 0 20px 20px;box-shadow:0 6px 16px rgba(105,98,84,.13)}
  #mob-page-hero h2{font-size:21px;font-weight:800;color:var(--text);letter-spacing:-.5px;margin:0;line-height:1.15}
  body:has(#page-dashboard.active) #mob-page-hero{display:none}   /* dashboard uses its greeting hero */
  /* The job page has its own rich title block (number, name, phase, actions) — the
     banner would just duplicate the job name (Dale), so hide it there too. */
  body:has(#page-job.active) #mob-page-hero{display:none}

  /* Search collapses to an icon; tapping it expands the field across the topbar. */
  #gs-mob-btn{display:flex}
  .topbar-search{display:none}
  body.gs-open .topbar-search{display:block;position:absolute;left:10px;right:10px;top:50%;transform:translateY(-50%);z-index:14}
  body.gs-open .topbar-search input{width:100%!important;min-height:38px;font-size:14px;border-radius:999px;padding-left:32px;background:var(--surface2)}
  body.gs-open .topbar-search .si{left:12px;font-size:14px}
  body.gs-open .topbar>*:not(.topbar-search){visibility:hidden}

  /* Needs-you header (Dale: "have the refresh on the far right in alignment with the
     'needs you'… have the suggest next to the fulfilment so it removes the need for
     the line it is currently on"). display:contents dissolves the toolbar wrapper so
     its buttons become header flex items we can order; .ny-brk forces the row break. */
  #ny-hd{align-items:center}
  #ny-hd #ny-hd-tools{display:contents!important}   /* !important — the span carries an inline display:flex */
  #ny-hd h3{order:1}
  #ny-hd #ny-total{order:2}
  #ny-hd #ny-refresh{order:3;margin-left:auto}
  #ny-hd .ny-brk{order:4;display:block;flex:0 0 100%;height:0;margin:0}
  /* The pills themselves become header items (contents), so ✨ Suggest can sit on the
     same line as Fulfilment instead of claiming a third row of its own. */
  #ny-hd{gap:5px!important;row-gap:6px!important;padding-left:14px;padding-right:14px}
  #ny-hd #ny-filters{display:contents!important}
  #ny-hd #ny-filters>.ny-pill{order:5}
  #ny-hd .ny-pill{padding:4px 8px}
  #ny-hd #dash-ai-refresh{order:6;font-size:10px!important;padding:4px 7px!important}
  #ny-hd [id$="-dismissed"]{order:7;flex:0 0 100%}
  /* Brief-me strip: one neat row per action (variable-length labels made a 2-col
     grid ragged) — icon + text left-aligned, hairline between rows. */
  #dash-utility>div:first-child{display:grid!important;grid-template-columns:1fr;gap:0!important;padding:2px 8px!important}
  #dash-utility .uti-sep{display:none}
  #dash-utility .uti-link{justify-content:flex-start;text-align:left;min-height:44px;padding:6px 8px;font-size:13px}
  #dash-utility .uti-link~.uti-link{border-top:1px solid var(--surface2);border-radius:0}

  /* Modal action footers: were flex-nowrap + justify-end with a margin-right:auto
     secondary group, so on a phone the Delete/secondary buttons were shoved clean
     off the LEFT edge (Dale couldn't reach "Delete PO"). Wrap them, kill the auto
     margin, and give every action a 44px tap target so nothing is ever hidden. */
  .modal-actions{flex-wrap:wrap;gap:8px;justify-content:flex-end}
  .modal-actions>div{margin-right:0!important;flex:1 1 100%;display:flex;flex-wrap:wrap;gap:8px}
  .modal-actions>div>.btn{flex:1 1 auto}
  .modal-actions>.btn{flex:1 1 auto;min-height:44px}
  .modal-actions .btn{min-height:44px}
}
/* ── Tablet (769–1080): desktop layout, widest grids step down so nothing squishes ── */
@media(min-width:769px) and (max-width:1080px){
  .stats-grid{grid-template-columns:repeat(3,minmax(0,1fr))!important}
  .rep-grid,.rep-inv-grid{grid-template-columns:repeat(2,minmax(0,1fr))!important}
  .m-stack,.fu-cols,.ig{grid-template-columns:minmax(0,1fr)!important}
  .two-col{grid-template-columns:minmax(0,1fr)!important}
  /* Registers: the PO row's fixed columns crushed the flexible TITLE to one letter per
     line around ~1013px (audit #9) — scroll inside the card instead of squishing */
  #rfi-all-list,#sub-all-list,#po-all-list{overflow-x:auto;-webkit-overflow-scrolling:touch}
  #rfi-all-list>div,#sub-all-list>div{min-width:760px}
  #po-all-list>div{min-width:1010px}
}
@media(min-width:769px){
  .jm-card{display:none!important}
}

/* ── New Job wizard: full-width gated accordion (2026-08-01) ── */
.modal.jm-wizard{width:calc(100vw - 48px);max-width:1180px;height:calc(100vh - 48px);padding:20px 24px;border-radius:var(--r-lg,16px);display:flex;flex-direction:column;overflow:hidden}
.jm-wiz-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:16px}
.jm-wiz-head h3{margin:0}
.jm-wiz-jobnum{flex-shrink:0;text-align:right;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;color:var(--text3)}
.jm-wiz-jobnum #jm-job-number{display:block;margin-top:3px;width:96px;text-align:center;font-size:20px;font-weight:800;letter-spacing:1px;font-family:var(--font-sans);font-variant-numeric:tabular-nums;padding:5px 6px}
.jm-wiz-body{max-width:none;margin:0 auto;width:100%;flex:1;overflow-y:auto;overflow-x:hidden;padding:2px 4px}
.wiz-step{border:1px solid var(--border);border-radius:12px;margin-bottom:12px;background:var(--surface);box-shadow:var(--sm);overflow:hidden;transition:opacity .2s}
.wiz-step-hd{display:flex;align-items:center;gap:12px;padding:15px 18px;font-size:15.5px;font-weight:700;color:var(--text);user-select:none}
.wiz-step.done .wiz-step-hd{cursor:pointer}
.wiz-step.done .wiz-step-hd:hover{background:var(--surface2)}
.wiz-num{flex-shrink:0;width:26px;height:26px;border-radius:50%;background:var(--surface2);color:var(--text3);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:800}
.wiz-step.active .wiz-num{background:var(--brand);color:var(--white)}
.wiz-step.done .wiz-num{background:var(--green);color:var(--white)}
.wiz-step-title{white-space:nowrap}
.wiz-step-sum{margin-left:auto;font-size:12.5px;font-weight:500;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:50%;text-align:right}
.wiz-step-body{padding:0 18px 16px}
.wiz-step:not(.active) .wiz-step-body{display:none}
.wiz-step.locked{opacity:.5}
.wiz-step-fields>label:first-child{margin-top:0}
.wiz-nav{display:flex;justify-content:flex-end;gap:8px;margin-top:16px;padding-top:12px;border-top:1px solid var(--border)}
.wiz-nav .wiz-back{margin-right:auto}
/* Editing an existing job → show every section open (familiar full form), no gating */
/* Scope step kept open for reference while on Financials — show its body, still editable */
.wiz-step.keep-open .wiz-step-body{display:block}
.wiz-step.keep-open{opacity:1}
.jm-wizard.edit-mode .wiz-step .wiz-step-body{display:block}
.jm-wizard.edit-mode .wiz-step{opacity:1}
.jm-wizard.edit-mode .wiz-nav{display:none}
@media(max-width:768px){ .modal.jm-wizard{width:100%;max-width:100%;padding:16px} .jm-wiz-body{max-width:100%} }
/* New Job wizard — inline client-details panel */
.jm-cd-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;color:var(--text3);margin-bottom:2px}
/* Generic accordion-wizard modal — same shell as the New Job wizard, used by the
   Submittal / RFI / Purchase Order forms (see scripts/build-form-wizards.cjs). */
.modal.wiz-modal{width:calc(100vw - 48px);max-width:1180px;height:calc(100vh - 48px);padding:20px 24px;border-radius:var(--r-lg,16px);display:flex;flex-direction:column;overflow:hidden}
.modal.wiz-modal > h3{font-size:19px;font-weight:800;margin:0;letter-spacing:-.2px;flex-shrink:0}
.wiz-modal-body{flex:1;overflow-y:auto;overflow-x:hidden;padding:2px 4px;margin-top:12px}
.modal.wiz-modal .modal-actions{margin-top:14px;padding-top:14px;border-top:1px solid var(--border);flex-shrink:0}
/* Editing an existing record → show every section open (no gating), like the job wizard */
.wiz-all-open .wiz-step .wiz-step-body{display:block}
.wiz-all-open .wiz-step{opacity:1}
.wiz-all-open .wiz-nav{display:none}
@media(max-width:768px){ .modal.wiz-modal{width:100%;max-width:100%;height:100%;padding:16px;border-radius:0} }
/* Premium modal shell — same look/feel as the New Job wizard, applied to the smaller
   form modals (scope item, and rolling out to supplier/PO/RFI/submittal). */
.modal.premium{width:calc(100vw - 48px);max-width:860px;max-height:calc(100vh - 48px);padding:22px 26px;border-radius:16px;display:flex;flex-direction:column;overflow:hidden}
.modal.premium > h3{font-size:19px;font-weight:800;margin:0;letter-spacing:-.2px}
.premium-body{flex:1;overflow-y:auto;overflow-x:hidden;padding:2px 2px 4px;margin-top:12px}
.modal.premium .modal-actions{margin-top:14px;padding-top:14px;border-top:1px solid var(--border);flex-shrink:0}
@media(max-width:768px){ .modal.premium{width:100%;max-width:100%;padding:16px} }
/* Scope item description — condensed to 2 lines by default, keeps the author's line breaks */
.scope-desc-collapsed{display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.scope-desc-toggle{display:inline-block;margin-top:2px;font-size:10.5px;color:var(--brand-ink);cursor:pointer;font-style:normal;user-select:none;font-weight:600}
.jm-cd-in{width:100%;box-sizing:border-box;padding:6px 9px;font-size:13px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-xs);color:var(--text)}
.jm-cd-in:focus{border-color:var(--brand-ink);outline:none}
/* Address suggestions render IN-FLOW inside the wizard — .wiz-step{overflow:hidden} would
   clip an absolutely-positioned dropdown, so it must not be position:absolute here. */
.jm-wizard #jm-cd-del-suggestions{position:static;box-shadow:none;max-height:190px;margin-top:4px}

/* ═══════════════════════════════════════════════════════════════════════════
   OVERHAUL STAGE 3 — visual polish + flow
   ═══════════════════════════════════════════════════════════════════════════ */

/* V-03 — the job header consumed 764px before the tab strip appeared at 1440x900,
   and 372px of that was the phase Actions checklist. Dale's note in
   renderJpActionsPanel is explicit that the panel should stay OPEN on desktop
   ("so you know what's happening"), so it is NOT collapsed here — it is BOUNDED.
   Everything stays visible and open; long checklists scroll inside the panel
   instead of pushing the tabs off the fold. Mobile keeps its own compact
   collapse (handled in JS) and is deliberately left alone. */
@media (min-width: 769px) {
  #jp-actions-panel { max-height: 190px; overflow-y: auto; }
  /* Tighten the header rhythm — every pixel saved goes to the tabs. */
  #jp-phase-strip   { padding-top: 6px !important; padding-bottom: 2px !important; }
  #jp-status-note-bar { padding-top: 0 !important; padding-bottom: 5px !important; }
  #jp-nudges-bar    { padding-bottom: 2px !important; }
}

/* V-05 — the AI chat tab and the "+" quick-add button both live bottom-right and
   collided with row-level action buttons on a phone (the scope row's Edit/copy/x
   sat underneath them). Separate them vertically and give scrollable panes enough
   bottom padding to clear both. */
@media (max-width: 768px) {
  #qa-fab   { bottom: calc(18px + env(safe-area-inset-bottom)); right: 14px; }
  #chat-fab { bottom: calc(88px + env(safe-area-inset-bottom)); right: 14px; top: auto; }
  #jp-content, #page-job .jp-tab-body { padding-bottom: 150px; }
}

/* The job description is multi-line by design (the AI writes it as separate lines:
   supply line, customisation, price, freight, lead time, weight). It was an
   <input type="text">, which silently strips newlines — which is why descriptions
   read as "Rundle Mall.External surfaces:" run together, in the app AND in Xero. */
.jm-desc-ta{width:100%;box-sizing:border-box;padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-xs);font-size:13px;color:var(--text);font-family:inherit;line-height:1.45;resize:vertical;min-height:76px}
.jm-desc-ta:focus{border-color:var(--brand-ink);outline:none}

/* ═══════════════════════════════════════════════════════════════════════════
   STAGE 3b — PREMIUM PASS on the job page header.
   Dale: "i want it a lot more visually cleaner and premium.. atm its so messy".

   The problem was structural, not decorative: the header was SIX full-bleed sibling
   strips, each with its own left padding (244/258/280px), sitting on three different
   background tones (cream page, grey actions band, white tabs), with four competing
   accent colours and no card boundary anywhere. It read as stacked bands, not a page.

   Fix: one card, one left edge, one background, one accent. Nothing is removed —
   this is alignment, containment and restraint.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 769px) {
  /* ── One card, one background ── */
  #jp-header{
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
    box-shadow: var(--sm);
    margin: 12px 18px 0;
    padding: 4px 0 0;
    overflow: hidden;
  }
  /* ── One left edge. Every strip inside the card aligns to the same gutter. ── */
  #jp-header > div{ padding-left: 20px !important; padding-right: 20px !important; }

  /* ── Title block: give the name room, calm everything under it. ── */
  #jp-header #jp-job-name{ letter-spacing: -0.4px; }
  #jp-customer-name{ font-size: 12px; text-decoration: none; border-bottom: 1px solid var(--border2); display: inline-block; }
  #jp-customer-name:hover{ color: var(--brand); border-bottom-color: var(--brand); }
  #jp-site-address-bar{ color: var(--text3); font-size: 11.5px; }

  /* ── Status line: it was a long italic run-on competing with the title. ── */
  #jp-phase-strip{ font-size: 12px; }
  #jp-status-note-bar{ padding-top: 0 !important; }

  /* ── Action bar: a quiet toolbar, not nine equal shouting buttons. The primary
        action stays dark; everything else recedes to an outline until hovered.   ── */
  #jp-header .btn-action{
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text2);
    font-weight: 600;
    box-shadow: none;
  }
  #jp-header .btn-action:hover{ background: var(--bg); border-color: var(--border2); color: var(--text); }

  /* ── Actions checklist: it is a SIBLING of the header card, so it was breaking the
        card edge and running full-bleed. Continue the same card instead: header loses its
        bottom radius, the panel picks it up, and both share one margin and border. ── */
  #jp-header{ border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom: none; }
  #jp-actions-panel{
    background: var(--bg) !important;
    margin: 0 18px;
    border: 1px solid var(--border);
    border-top: 1px solid var(--border);
    border-bottom-left-radius: var(--r);
    border-bottom-right-radius: var(--r);
    box-shadow: var(--sm);
    padding-bottom: 2px;
  }
  #jp-actions-panel > div{ padding-left: 20px !important; padding-right: 20px !important; }
  #jp-actions-panel .btn-xs{ box-shadow: none; }
  /* The red "Block" chip repeated on every single row read as nine errors. Let it
     recede until the row is hovered — it is an escape hatch, not a status. */
  #jp-actions-panel [class*="btn"][onclick*="lock"]{ opacity: .35; transition: opacity var(--t); }
  #jp-actions-panel > div:hover [class*="btn"][onclick*="lock"]{ opacity: 1; }

  /* ── Tabs: sit them on the page, tied to the card above by the same gutter. ── */
  #page-job .jp-tabs{ margin: 10px 18px 0; padding-left: 8px; border-bottom: 1px solid var(--border); }
  #jp-content{ padding-left: 18px; padding-right: 18px; }
}

@media (min-width: 769px) {
  /* The "✓ Complete Job" button sat after an orphaned 1px divider stub inherited from an
     older layout — it read as a rendering artefact. Hide the stub, give the button air. */
  #jp-header .btn:not(.btn-action) ~ *:empty,
  #jp-header > div > div:empty:not([id]){ display: none; }

  /* Tabs: give them the same gutter as the card and a calm resting state. */
  #page-job .jp-tabs{ background: transparent; margin-top: 14px; }
  #page-job .jp-tab{ font-weight: 600; color: var(--text3); }
  #page-job .jp-tab.active{ color: var(--text); }

  /* Overview: the phase-progress strip was a full card holding two pills and a lot of
     empty space. Let it sit as a slim inline band instead of a card of its own. */
  #jp-content > .jp-module:first-child:has(> div > div[class*="d60aef"]),
  #jp-content > div:first-child > .jp-module:first-child{ padding-top: 10px; padding-bottom: 10px; }
}

/* ── Stage 3b: Job Overview hero cards ─────────────────────────────────────── */
.jp-title-icon{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:9px;background:var(--bg);border:1px solid var(--border);color:var(--text2);font-size:17px;margin-right:10px;vertical-align:middle;flex-shrink:0}
.jp-hero{display:none}
@media (min-width: 769px) {
  .jp-hero{display:block;padding-top:2px;padding-bottom:12px}
  /* The hero replaces the stacked status + next-steps strips on desktop. */
  .jp-hero.on ~ #jp-status-note-bar, .jp-hero.on ~ #jp-nudges-bar{display:none!important}
  .jp-hero-hd{display:flex;align-items:center;gap:8px;padding:4px 0 8px}
  .jp-hero-title{font-size:14px;font-weight:700;color:var(--text);margin-right:auto}
  .jp-hero-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
  .jp-hero-card{background:var(--surface);border:1px solid var(--border);border-radius:11px;padding:12px 14px;min-height:104px;display:flex;flex-direction:column;gap:6px}
  .jp-hero-card-row{flex-direction:row;align-items:center;gap:12px}
  .jp-hero-eyebrow{font-size:10px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--text3)}
  .jp-hero-big{font-size:16.5px;font-weight:700;color:var(--text);display:flex;align-items:center;gap:8px;line-height:1.2}
  .jp-hero-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
  .jp-hero-sub{font-size:11px;color:var(--text3);line-height:1.45;font-style:italic;display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
  .jp-hero-auto{font-style:normal;font-size:8.5px;font-weight:800;letter-spacing:.5px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;padding:1px 4px;color:var(--text3)}
  .jp-hero-next{font-size:12px;font-weight:600;color:var(--text);line-height:1.4;display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;flex:1}
  .jp-hero-mid{font-size:12.5px;font-weight:600;color:var(--text);line-height:1.35}
  .jp-hero-btn{align-self:flex-start;margin-top:auto}
  .jp-hero-card-row .jp-hero-btn{margin-top:4px}
  .jp-hero-ring{width:52px;height:52px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;position:relative}
  .jp-hero-ring::before{content:'';position:absolute;inset:6px;border-radius:50%;background:var(--surface)}
  .jp-hero-ring span{position:relative;font-size:12px;font-weight:800;font-family:var(--font-sans);font-variant-numeric:tabular-nums;color:var(--text)}
  .jp-hero-alert{width:40px;height:40px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:19px;font-weight:800;background:var(--red-light);color:var(--red)}
  .jp-hero-alert.ok{background:var(--green-light);color:var(--green)}
}

/* ── Stage 3b3: hero everywhere + checklist on demand ──────────────────────────
   Dale: the Progress pill AND the full Design Actions list at once is a double-up,
   and mobile must be first-class. The hero now renders at ALL widths and the actions
   checklist is HIDDEN until asked for via the hero's buttons (it opens expanded and
   scrolled into view). The old status/next-steps strips hide wherever the hero is on. */
.jp-hero{display:block;padding:2px 20px 12px}
.jp-hero.on ~ #jp-status-note-bar, .jp-hero.on ~ #jp-nudges-bar{display:none!important}
#jp-header:has(.jp-hero.on) ~ #jp-actions-panel:not(.jp-actions-revealed){display:none!important}
/* Component styles at all widths (previously desktop-only) */
.jp-hero-hd{display:flex;align-items:center;gap:8px;padding:4px 0 8px}
.jp-hero-title{font-size:14px;font-weight:700;color:var(--text);margin-right:auto}
.jp-hero-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.jp-hero-card{background:var(--surface);border:1px solid var(--border);border-radius:11px;padding:12px 14px;min-height:104px;display:flex;flex-direction:column;gap:6px}
.jp-hero-card-row{flex-direction:row;align-items:center;gap:12px}
.jp-hero-eyebrow{font-size:10px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--text3)}
.jp-hero-big{font-size:16.5px;font-weight:700;color:var(--text);display:flex;align-items:center;gap:8px;line-height:1.2}
.jp-hero-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.jp-hero-sub{font-size:11px;color:var(--text3);line-height:1.45;font-style:italic;display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.jp-hero-auto{font-style:normal;font-size:8.5px;font-weight:800;letter-spacing:.5px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;padding:1px 4px;color:var(--text3)}
.jp-hero-next{font-size:12px;font-weight:600;color:var(--text);line-height:1.4;display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;flex:1}
.jp-hero-mid{font-size:12.5px;font-weight:600;color:var(--text);line-height:1.35}
.jp-hero-btn{align-self:flex-start;margin-top:auto}
.jp-hero-card-row .jp-hero-btn{margin-top:4px}
.jp-hero-ring{width:52px;height:52px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;position:relative}
.jp-hero-ring::before{content:'';position:absolute;inset:6px;border-radius:50%;background:var(--surface)}
.jp-hero-ring span{position:relative;font-size:12px;font-weight:800;font-family:var(--font-sans);font-variant-numeric:tabular-nums;color:var(--text)}
.jp-hero-alert{width:40px;height:40px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:19px;font-weight:800;background:var(--red-light);color:var(--red)}
.jp-hero-alert.ok{background:var(--green-light);color:var(--green)}
@media (max-width: 768px) {
  .jp-hero{padding:2px 14px 10px}
  .jp-hero-grid{grid-template-columns:1fr 1fr;gap:8px}
  .jp-hero-card{min-height:0;padding:10px 11px;gap:4px;border-radius:10px}
  .jp-hero-card-row{gap:9px}
  .jp-hero-big{font-size:13.5px}
  .jp-hero-sub{-webkit-line-clamp:2;line-clamp:2;font-size:10.5px}
  .jp-hero-next{font-size:11px;-webkit-line-clamp:3;line-clamp:3}
  .jp-hero-mid{font-size:11.5px}
  .jp-hero-ring{width:42px;height:42px}
  .jp-hero-ring::before{inset:5px}
  .jp-hero-ring span{font-size:10.5px}
  .jp-hero-alert{width:34px;height:34px;font-size:16px}
  .jp-hero-btn{min-height:30px}
  .jp-title-icon{width:28px;height:28px;font-size:14px;border-radius:7px;margin-right:7px}
}

/* Job description preserves the author's line breaks (it is written as separate lines:
   supply, customisation, price, freight, lead time). Without this, \n collapses and the
   text reads run-together even when the stored data is correct. */
.d1vx94h9{white-space:pre-line}

/* Mobile job title: the badges kept flex space and squeezed the title into a one-word-per-
   line column. Badges wrap onto their own row; the title takes the full width at 17px. */
@media (max-width: 768px) {
  .ddnjh1q{flex-wrap:wrap;gap:8px;padding:10px 14px 6px}
  .d1ujuoye{flex:1 1 100%;order:2}
  .d7t0764{font-size:17px;letter-spacing:-0.2px}
  .djezfpk{order:1;margin-left:auto;margin-top:0}
}

/* components.css loads LAST, so equal-specificity overrides above lost the cascade.
   Re-stated with higher specificity so the mobile title fix actually wins. */
@media (max-width: 768px) {
  #jp-header .ddnjh1q{flex-wrap:wrap !important;gap:8px !important;padding:10px 14px 6px !important}
  #jp-header .d1ujuoye{flex:1 1 100% !important;order:2}
  #jp-header .d7t0764{font-size:17px !important;letter-spacing:-0.2px !important}
  #jp-header .djezfpk{order:1;margin-left:auto !important;margin-top:0 !important}
}

/* ═══ Stage 3b4 — MOBILE rebuilt to the approved ChatGPT mocks ═══════════════════
   docs/mockups/gpt-job-mobile.png + gpt-dashboard-mobile.png. One column, one Now
   card, scrolling chip toolbar, tappable one-line rows, 2x2 mono stat tiles. */
@media (max-width: 768px) {
  /* ── Job page: the Now card ── */
  .jp-hero{padding:4px 14px 10px}
  .jp-now{background:var(--surface);border:1px solid var(--border);border-radius:14px;box-shadow:var(--shadow, 0 1px 2px rgba(42,36,30,.05));padding:15px 16px}
  .jp-now-status{display:flex;align-items:center;gap:8px}
  .jp-now-status b{font-size:16px;font-weight:700;letter-spacing:-.2px}
  .jp-now-status .jp-hero-auto{margin-left:auto}
  .jp-now-note{margin-top:6px;font-size:12px;line-height:1.45;color:var(--text3);display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .jp-now-prog{margin-top:13px;display:flex;align-items:center;gap:10px;padding-bottom:12px;border-bottom:1px solid var(--surface2)}
  .jp-now-track{flex:1;height:6px;border-radius:99px;background:var(--surface2);overflow:hidden}
  .jp-now-fill{height:100%;border-radius:99px;background:var(--green);transition:width .3s}
  .jp-now-prog span{font-size:11px;font-weight:600;color:var(--text2);white-space:nowrap}
  .jp-now-next{margin-top:12px;display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;color:var(--text)}
  .jp-now-when{margin-top:6px;display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text2)}
  .jp-now-when em{font-style:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .jp-now-when.late{color:var(--danger-text);font-weight:600}
  .jp-now-next span{color:var(--orange-ink);flex-shrink:0}
  .jp-now-next em{font-style:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .jp-now-btns{margin-top:13px;display:flex;gap:8px}
  .jp-now-btn{flex:1;height:42px;border-radius:11px;font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;gap:7px;border:1px solid transparent;font-family:inherit;cursor:pointer}
  .jp-now-btn.dark{background:var(--brand);color:var(--white)}
  .jp-now-btn.ghost{background:transparent;border-color:var(--border2);color:var(--text2)}
  .jp-now-count{background:var(--red-light);color:var(--red);font-size:11px;font-weight:800;border-radius:99px;padding:1px 7px}

  /* ── Job page: toolbar = ONE scrolling chip row (the ⋯More sheet is retired).
        The container carries a real .jp-toolbar class (index.html) — the first attempt
        targeted it with :has() and lost to the extracted utility classes. ── */
  #jp-header .jp-toolbar{
    display:flex !important;flex-wrap:nowrap !important;overflow-x:auto;gap:8px;scrollbar-width:none;
    -webkit-mask:linear-gradient(90deg,#000 calc(100% - 30px),transparent);
    padding-top:10px !important;padding-bottom:10px !important;border-top:none !important;
  }
  #jp-header .jp-toolbar::-webkit-scrollbar{display:none}
  #jp-header .jp-toolbar #jp-action-bar{display:contents}
  #jp-header .jp-toolbar .btn-action, #jp-header .jp-toolbar .btn{flex:0 0 auto;height:36px;min-height:36px;border-radius:999px;padding:0 14px;background:var(--surface);border:1px solid var(--border);color:var(--text2);font-weight:600;box-shadow:none;white-space:nowrap}

  /* ── Job page: tab strip edge fade (it scrolls — show it) ── */
  #page-job .jp-tabs{-webkit-mask:linear-gradient(90deg,#000 calc(100% - 34px),transparent);scrollbar-width:none}
  #page-job .jp-tabs::-webkit-scrollbar{display:none}

  /* ── Dashboard: needs-you rows become tappable one-liners (buttons hide; the row
        itself fires the primary action; age sits right; chevron affordance) ── */
  .ndg-row .d3mvcui, .dm4ouue .d3mvcui{display:none !important}
  .ndg-row{align-items:center !important;min-height:46px;position:relative;padding-right:26px !important}
  .ndg-row > span:first-child{display:none !important}
  .ndg-row::after{content:'›';position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--border2);font-size:15px}

  /* ── Dashboard: 2x2 mono stat tiles per the mock. The card is grid-area based on
        desktop; on mobile it becomes a simple stacked column (hiding the icon while the
        grid still referenced its area was mangling the layout). ── */
  .dkpi-icon{display:none}
  .dkpi-card{display:flex;flex-direction:column;align-items:flex-start;padding:13px 14px;text-align:left}
  .dkpi-body{display:flex;flex-direction:column;align-items:flex-start;width:100%}
  .dkpi-num{font-size:21px;margin-top:0;order:1}
  .dkpi-lbl{font-size:10.5px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:var(--text3);margin-top:2px;order:2}
  .dkpi-sub{border-top:1px solid var(--surface2);padding-top:6px;margin-top:7px;order:3;width:100%}
  .dkpi-ext{order:4}
  /* Clear the FABs so the last tiles stay tappable */
  #page-dashboard{padding-bottom:150px}
}

@media (max-width: 768px) {
  /* Toolbar chip row (real buttons moved under the Now card by renderJpHero) */
  .jp-chiprow{display:flex;flex-wrap:nowrap;overflow-x:auto;gap:8px;margin-top:11px;padding-bottom:2px;scrollbar-width:none;-webkit-mask:linear-gradient(90deg,#000 calc(100% - 30px),transparent)}
  .jp-chiprow::-webkit-scrollbar{display:none}
  .jp-chiprow .btn{flex:0 0 auto;height:36px;min-height:36px;border-radius:999px;padding:0 14px;background:var(--surface);border:1px solid var(--border);color:var(--text2);font-weight:600;box-shadow:none;white-space:nowrap;font-size:12px}
  .jp-title-icon{display:none}
}

/* ── Stage 4c: Today board (dashboard registers) ───────────────────────────── */
#dash-registers{margin-top:14px}
/* minmax(0,…) not 1fr: a bare 1fr track is min-content floored, so one long job name
   pushes the whole card wider than the page (it did — 519px card in a 350px column). */
.dreg-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}
.dreg-card{min-width:0;background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--sm);padding:6px 16px 8px}
.dreg-hd{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;padding:10px 0 4px}
.dreg-note{font-size:10px;font-weight:600;color:var(--text3)}
.dreg-row{display:flex;align-items:center;gap:10px;padding:10px 0;border-top:1px solid var(--surface2);cursor:pointer;min-height:42px}
.dreg-row:first-of-type{border-top:none}
.dreg-row:hover .dreg-t{color:var(--brand-ink)}
.dreg-t{flex:1;min-width:0;font-size:12.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dreg-det{font-weight:500;color:var(--text2)}
.dreg-sub{display:block;font-weight:400;font-size:11px;color:var(--text3);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dreg-age{font-size:11px;font-weight:700;color:var(--orange-ink);white-space:nowrap}
.dreg-age.ok{color:var(--text3);font-weight:600}
.dreg-chev{color:var(--border2);font-size:14px}
.dreg-empty{padding:12px 0 14px;font-size:12px;color:var(--text3);font-style:italic}
.dreg-mhead,.dreg-mrow{display:grid;grid-template-columns:minmax(0,1.6fr) 1fr 1fr 1fr;gap:8px;align-items:center}
.dreg-mhead{padding:6px 0 6px;font-size:10px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:var(--text3);border-bottom:1px solid var(--surface2)}
.dreg-mhead span:not(:first-child),.dreg-mrow .dreg-money{text-align:right}
.dreg-mrow{padding:9px 0;border-top:1px solid var(--surface2);cursor:pointer;min-height:40px}
.dreg-mrow:first-of-type{border-top:none}
.dreg-mjob{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:11.5px;font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dreg-mjob span{font-family:'DM Sans',sans-serif;font-weight:600;font-size:12px}
.dreg-msub{display:none}
.dreg-money{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:12px}
.dreg-money.bad{color:var(--red);font-weight:500}
.dreg-mfoot{display:grid;grid-template-columns:minmax(0,1.6fr) 1fr 1fr 1fr;gap:8px;align-items:center;
  padding:9px 0 2px;margin-top:2px;border-top:1px solid var(--border);font-size:11px;font-weight:700;color:var(--text3)}
.dreg-mfoot .dreg-money{text-align:right;color:var(--text);font-weight:700}
@media (max-width: 768px) {
  .dreg-grid{grid-template-columns:minmax(0,1fr);gap:10px}
  /* Phone: one number per row — job (with the detail on a sub-line) and what's owed.
     Quoted/collected columns collapse rather than disappearing from the app. */
  .dreg-mhead,.dreg-money.q,.dreg-money.c{display:none}
  .dreg-mrow,.dreg-mfoot{grid-template-columns:minmax(0,1fr) auto}
  .dreg-mjob{white-space:normal}
  .dreg-mjob span{display:block;font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .dreg-msub{display:block;font-family:'DM Sans',sans-serif;font-weight:400;font-size:11px;color:var(--text3);margin-top:2px}
  /* Activity stays short on a phone — the full feed is the dashboard's Activity link */
  .dreg-card:last-child .dreg-row:nth-of-type(n+6){display:none}
}

/* ── Variations register (Stage 4c) ───────────────────────────────────────── */
#fvar-tiles{margin-bottom:14px}
.fvar-big{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:24px;font-weight:500;letter-spacing:-.5px;padding:2px 0 2px}
.fvar-big.bad{color:var(--red)}
#fvar-list .dreg-row{gap:12px}
.fvar-amt{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:12.5px;font-weight:500;white-space:nowrap;text-align:right;min-width:84px}
.fvar-amt.neg{color:var(--text3)}
.fvar-state{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;white-space:nowrap;min-width:104px;text-align:right}
@media (max-width: 768px) {
  #fvar-tiles{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px}
  .fvar-big{font-size:19px}
  .fvar-state{display:none}          /* the colour of the amount + the chip already say it */
  .fvar-amt{min-width:0}
}

/* ── Stage 4b field cards (freight, retention, finishing) ─────────────────── */
.jp-sub-hd{margin:14px 0 0;font-size:10.5px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:var(--text3)}
.jp-freight-gap{margin-top:9px;font-size:12px;color:var(--text2);background:var(--surface2);
  border-radius:var(--r-xs);padding:7px 10px}
.jp-freight-gap.bad{color:var(--danger-text);background:color-mix(in srgb, var(--red) 8%, transparent)}
.jp-freight-gap.ok{color:var(--text3)}
.jp-freight-gap:empty{display:none}
@media (max-width: 768px) {
  .d1fu3r24{grid-template-columns:1fr 1fr}
}

/* ── V-05: the FABs stop covering what you are reading ────────────────────────
   Both FABs are position:fixed, so on a phone they sit on top of whatever row is
   under them — job cards had their money column hidden behind the + button. A fixed
   element can't avoid that by spacing, so they get out of the way instead: scroll
   DOWN (you're reading) and they slide off; scroll UP or stop and they come back.
   Standard on premium mobile apps, and nothing is ever unreachable. */
@media (max-width: 768px) {
  #chat-fab, #qa-fab { transition: transform .22s cubic-bezier(.4,0,.2,1), opacity .18s; }
  body.fabs-away #chat-fab { transform: translateX(120%); opacity: 0; pointer-events: none; }
  body.fabs-away #qa-fab   { transform: translateY(130%); opacity: 0; pointer-events: none; }
}

/* ── B4-04: drawings with a drafter ───────────────────────────────────────── */
.doc-drafter{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px 0 2px;font-size:12.5px;color:var(--text2)}
.doc-drafter .dd-none{color:var(--text3);font-style:italic}
.doc-drafter .dd-out strong{color:var(--text)}
.doc-drafter .dd-back{color:var(--success-text,var(--green));font-weight:600}
.dd-form{display:flex;align-items:center;gap:8px;flex-wrap:wrap;width:100%}
.dd-form .dd-name{width:180px}
.dd-form input[type=date]{width:150px}
.dd-form .dn7a2j4{margin:0}
@media (max-width: 768px){
  .dd-form .dd-name{width:100%}
  .dd-form input[type=date]{width:calc(50% - 34px)}
}

/* Notification category checkboxes */
.push-cats{display:flex;flex-direction:column;gap:7px}
.push-cats label{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--text2);cursor:pointer;min-height:26px}
.push-cats input{width:16px;height:16px;flex:0 0 16px;accent-color:var(--brand-ink)}

/* "✓ Done" on a Needs-you row — quieter than the primary action, louder than dismiss */
.ndg-done{font-size:10px;padding:3px 10px;border-color:var(--border2)}
.ndg-done:hover{background:color-mix(in srgb, var(--green) 14%, transparent);border-color:var(--green);color:var(--success-text,var(--green))}

/* Show/hide toggle inside a password field */
.pw-eye-wrap{position:relative;display:block;width:100%;flex:1 1 auto;min-width:0}
.pw-eye-wrap>input{width:100%}
.pw-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);z-index:2;
  width:34px;height:34px;display:flex;align-items:center;justify-content:center;
  background:transparent;border:0;border-radius:8px;cursor:pointer;color:var(--text3);padding:0}
.pw-eye:hover{color:var(--text);background:var(--surface2)}
.pw-eye i{font-size:17px;line-height:1}

/* ── Inline checkbox rows in modals ───────────────────────────────────────────
   `.modal label` is the FORM-label style: uppercase, 11px, display:block. Applied to
   a checkbox's own label it turned "All day" into a block that wrapped to two lines and
   pushed itself away from its box. These rows are one line: box, label, quiet hint. */
.chk-row{display:flex;align-items:center;gap:10px;cursor:pointer;margin:2px 0;min-height:34px}
/* The ROW is itself a <label>, so `.modal label` (display:block, uppercase, margins)
   outranks a bare .chk-row. Two classes beat one class + one element. */
.modal .chk-row{display:flex;align-items:center;gap:10px;margin:2px 0;min-height:34px;
  text-transform:none;letter-spacing:0;font-size:12.5px;color:var(--text)}
.modal .chk-row .chk-lbl{display:inline;margin:0;padding:0;font-size:12.5px;font-weight:600;
  color:var(--text);text-transform:none;letter-spacing:0}
.modal .chk-row .chk-hint{display:inline;margin:0;font-size:11px;font-weight:400;color:var(--text3);
  text-transform:none;letter-spacing:0}
.chk-row input[type=checkbox]{flex:0 0 16px;accent-color:var(--brand-ink)}
.chk-row-panel{background:var(--surface2);border-radius:var(--r-xs);padding:11px 12px;margin-top:12px;flex-wrap:wrap}
/* hint sits under the label, indented to the text — deliberate, rather than wrapping
   raggedly whenever the two happen not to fit on one line */
.modal .chk-row-panel .chk-hint{flex:1 1 100%;margin-left:26px;margin-top:1px}
@media (max-width:768px){
  .chk-row{flex-wrap:wrap}
  .chk-row .chk-hint{flex:1 1 100%;margin-left:26px}
}

/* ── Actions menu on a Needs-you row ─────────────────────────────────────────── */
.ndg-actions{font-size:10px;padding:3px 10px;border-color:var(--border2)}
.ndg-act-menu{position:fixed;z-index:9650;min-width:238px;max-width:min(94vw,320px);
  background:var(--surface);border:1px solid var(--border);border-radius:12px;
  box-shadow:0 16px 44px rgba(0,0,0,.20);padding:6px;display:flex;flex-direction:column;gap:1px}
/* Glyph in its own fixed column so every label starts on the same x. */
.ndg-act-item{display:grid;grid-template-columns:16px minmax(0,1fr);align-items:center;gap:9px;
  width:100%;text-align:left;background:transparent;border:0;
  padding:9px 10px;border-radius:8px;font-size:12.5px;font-weight:600;color:var(--text);
  cursor:pointer;min-height:38px;line-height:1.3}
.ndg-act-ico{font-size:12px;line-height:1;text-align:center;color:var(--text3)}
.ndg-act-item:hover .ndg-act-ico{color:inherit}
.ndg-act-lbl{min-width:0}
.ndg-act-sep{height:1px;background:var(--border);margin:5px 8px}
.ndg-act-item:hover{background:var(--surface2)}
.ndg-act-item.danger{color:var(--danger-text)}
.ndg-act-item.danger:hover{background:color-mix(in srgb, var(--red) 10%, transparent)}

/* Breathing room before "Complete Project" — it sat flush against "Defects →" */
.jp-adv-gap{margin-left:8px}

/* Purchase order vs supply request */
.pom-doctype{display:flex;flex-direction:column;gap:2px}
.pom-doctype .chk-row{min-height:32px}
.pom-doctype input[type=radio]{width:15px;height:15px;flex:0 0 15px;accent-color:var(--brand-ink)}
.po-req-chip{display:inline-flex;align-items:center;gap:4px;font-size:10px;font-weight:700;
  letter-spacing:.4px;text-transform:uppercase;padding:1px 7px;border-radius:8px;
  background:color-mix(in srgb, var(--blue) 13%, transparent);color:var(--info-text,var(--blue))}

/* Wizard steps: the header and card react to the step opening, so the whole panel moves
   as one rather than the body appearing under a static header. */
.wiz-step{transition:opacity .2s, box-shadow .22s ease, border-color .22s ease}
.wiz-step.active{box-shadow:var(--md,0 4px 14px rgba(0,0,0,.07));border-color:var(--border2)}
.wiz-step-hd{transition:padding .22s cubic-bezier(.4,0,.2,1)}
.wiz-step.locked .wiz-step-hd{padding-top:13px;padding-bottom:13px}
@media (prefers-reduced-motion: reduce){
  .wiz-step,.wiz-step-hd{transition:none}
}

/* Back on its own row: the job number/name now start at the same left edge as the
   cards and tabs underneath, instead of being indented by the arrow's width. */
.jp-backrow{padding:10px 18px 0}
.jp-backrow .btn{padding:5px 12px}
@media (max-width:768px){ .jp-backrow{padding:8px 14px 0} }

/* The status card's headline is the edit affordance — clicking it opens the note. */
.jp-hero-card .jp-hero-big.jp-status-click{cursor:pointer;border-radius:6px;
  transition:color .15s, background .15s;padding:1px 4px;margin-left:-4px}
.jp-hero-card .jp-hero-big.jp-status-click:hover{color:var(--brand-ink);background:var(--surface2)}
.jp-hero-card .jp-hero-big.jp-status-click::after{content:'✎';font-size:11px;opacity:0;
  margin-left:6px;transition:opacity .15s;color:var(--text3)}
.jp-hero-card .jp-hero-big.jp-status-click:hover::after{opacity:1}

/* While editing the status, un-hide the note bar the hero normally replaces —
   the ✎ used to open an editor that the hero's own sibling rule was hiding. */
#jp-header.jp-status-editing .jp-hero.on ~ #jp-status-note-bar,
.jp-status-editing .jp-hero.on ~ #jp-status-note-bar{display:block!important}

/* The briefcase icon indented the job number by 44px, so the title never lined up with
   the cards and tabs below it. It is decorative (and was already hidden on mobile), so
   the number now starts on the same left edge as everything under it. */
.jp-title-icon{display:none!important}

/* ── Sidebar sizing (Dale: "it seems so damn small") ──────────────────────────
   Width comes from --sidebar above. Everything here scales the contents to match —
   type, icons and row height together, so it reads as a bigger menu rather than the
   same small menu in a wider column. */
.sb-item{font-size:14px;padding:10px 12px;gap:12px}
.sb-item .icon{width:22px;font-size:20px}
.sb-group-items .sb-item{font-size:13.5px;padding-left:24px;padding-top:9px;padding-bottom:9px}
.sb-group-items .sb-item .icon{font-size:18px}
.sb-group-hd{font-size:11px;padding:8px 12px;letter-spacing:.8px}
.sb-group-hd i{font-size:18px}
.sb-group-arrow{font-size:10px}
.sb-txt{font-size:19px}
.sb-sub{font-size:11.5px}
.sb-badge{font-size:10px;min-width:18px}
.sb-brand-tab{font-size:12.5px;padding:7px 0}
@media (max-width:1180px){ :root{--sidebar:246px} }

/* ── "+" becomes a tab under the AI tab (Dale) ────────────────────────────────
   Desktop only. The AI tab occupies bottom:80 → 176px; this sits just beneath it on
   the same edge, same width and radius, so they read as one stack. Mobile keeps its
   round FABs (they live at the thumb, and the drawer/safe-area rules depend on them). */
@media (min-width: 769px) {
  body #qa-fab{
    bottom:12px; right:0; width:28px; height:60px;   /* 8px clear of the AI tab so they read as two */
    border-radius:8px 0 0 8px;
    box-shadow:-3px 0 12px rgba(0,0,0,.18);
    flex-direction:column; gap:5px;
    transition:width .15s, background .15s;
  }
  body #qa-fab i{font-size:15px;line-height:1}
  body #qa-fab .fab-label{writing-mode:vertical-rl;text-orientation:mixed;transform:rotate(180deg);
    font-size:10px;font-weight:700;letter-spacing:.06em;white-space:nowrap;line-height:1}
  body #qa-fab:hover{background:var(--brand2)}
}
/* Mobile: it stays a round button, so no vertical label there. */
@media (max-width: 768px) { body #qa-fab .fab-label{display:none} }

/* ── Top-level menu rows read as ONE list (Dale) ──────────────────────────────
   Group headings were 11px UPPERCASE while Dashboard / Products / Guides / Settings
   were 14px title case, and the heading icons had no fixed width — so the labels
   started at different x positions AND in different cases. Same type, same icon
   column, so every label lines up in a single vertical line. */
.sb-group-hd{
  font-size:14px; font-weight:600; letter-spacing:0; text-transform:none;
  color:var(--text); padding:10px 12px; gap:12px;
}
.sb-group-hd .icon,
.sb-item .icon{
  width:22px; min-width:22px; font-size:20px;
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
}
.sb-group-hd .icon i, .sb-item .icon i{font-size:inherit;line-height:1}
.sb-group.has-active .sb-group-hd{color:var(--text);font-weight:700}
/* Children stay a step down so the grouping still reads */
.sb-group-items .sb-item{font-size:13.5px;padding-left:22px}
.sb-group-items .sb-item .icon{width:20px;min-width:20px;font-size:18px}

/* Checklist reorder grip — sits in the gutter the row's padding-left reserves,
   fades up on row hover so it doesn't add noise to a long checklist. */
.jpa-grip{position:absolute;left:0;top:5px;width:13px;line-height:1;font-size:13px;
  color:var(--text3);opacity:.35;cursor:grab;user-select:none;touch-action:none;text-align:center;z-index:2}
.jpa-grip:hover{opacity:1;color:var(--brand-ink)}
.jpa-item:hover>.jpa-grip,.dbwwyzf:hover>.jpa-grip{opacity:.75}
.jpa-grip:active{cursor:grabbing}
.jpa-dragging{background:var(--surface);opacity:.75;box-shadow:0 2px 8px rgba(0,0,0,.12)}

/* ── Wide "simple" modal — same shell as the New Job wizard ────────────────────
   The 420px default clipped anything with a composer in it (the review request
   overflowed sideways and hid its Send button). */
.modal.simple-wide{width:calc(100vw - 48px);max-width:1180px;height:calc(100vh - 48px);
  padding:20px 24px;border-radius:16px;display:flex;flex-direction:column;overflow:hidden}
.modal.simple-wide > .dwdx7cn{flex-shrink:0;margin-bottom:14px;padding-bottom:12px;border-bottom:1px solid var(--border)}
.modal.simple-wide > .dwdx7cn h3{font-size:19px;font-weight:800;letter-spacing:-.2px}
.simple-wide-body{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden;padding:2px 2px 0}
.simple-wide-body > .drt65os{flex:1;min-height:0}
.rvw-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.6fr);gap:14px}
.modal.simple-wide label.rvw-msg{display:flex;flex-direction:column;flex:1;min-height:0;margin-top:0}
.rvw-foot{flex-shrink:0;margin-top:14px;padding-top:14px;border-top:1px solid var(--border)}
@media(max-width:768px){
  .modal.simple-wide{width:100%;max-width:100%;height:100%;border-radius:0;padding:16px}
  .rvw-grid{grid-template-columns:minmax(0,1fr)}
}

/* ── One "Actions ▾" per row, on the right rail ────────────────────────────────
   Replaces the button strip that sat under every row's text and made the list
   three lines tall per item. */
.row-actions{flex-shrink:0;align-self:flex-start;margin-top:1px}
.dm4ouue .row-actions{align-self:center;margin-top:0}
@media(max-width:768px){
  /* The button is the affordance now — the decorative chevron would sit on top of it. */
  .ndg-row:has(.row-actions)::after{content:none}
  .ndg-row:has(.row-actions){padding-right:10px}
}

/* ── "Needs you" — one bordered panel per bucket, rows divided inside ────────────
   Matches Dale's mockup: the section is a single rounded grey-bordered box whose
   rows are separated by full-width dividers (not detached cards), and a collapsed
   section header wears that same box. */
.ny-bucket{margin:12px 14px 0;padding:0;border-left:3px solid var(--nyc,var(--border2))}
.ny-bh{display:flex;align-items:center;gap:10px;padding:9px 14px;border:1px solid transparent;border-radius:12px}
.ny-bucket.ny-collapsed .ny-bh{background:var(--surface);border-color:var(--border)}
/* Butt the panel straight onto the accent bar so the two read as one edge, not two
   floating lines (Dale). Square off that side and let the bar be the left border. */
.ny-bb,.ny-bucket.ny-collapsed .ny-bh{border-left-color:transparent;border-top-left-radius:0;border-bottom-left-radius:0}
.ny-bh-icon{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:8px;
  background:var(--surface2);border:1px solid var(--border);color:var(--nyc,var(--text2));font-size:13px;flex-shrink:0}
.ny-bh-label{font-size:12px;letter-spacing:.7px}
.ny-bh-count{background:var(--surface2);border:1px solid var(--border);border-radius:999px;padding:1px 7px;font-size:10px}
.ny-bh-chev{font-size:13px;color:var(--text3);margin-left:auto;padding-right:4px}
.ny-bb{margin-top:6px;max-height:430px;overflow-y:auto;padding:0;
  background:var(--surface);border:1px solid var(--border);border-radius:12px}

.ny-card{display:flex;align-items:center;gap:12px;padding:12px 14px;cursor:pointer;
  background:transparent;border:0;border-bottom:1px solid var(--border);border-radius:0;transition:background .12s}
.ny-card.ny-last{border-bottom:0}
.ny-card:hover{background:var(--surface2)}
.ny-card-main{flex:1;min-width:0}
.ny-card-job{display:flex;align-items:center;gap:7px;margin-bottom:3px;min-width:0;height:15px}
.ny-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.ny-jobnum{font-family:var(--font-sans);font-variant-numeric:tabular-nums;font-size:10.5px;font-weight:700;color:var(--brand-ink);flex-shrink:0}
.ny-jobname{font-size:11.5px;font-weight:700;color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ny-card-title{font-size:13px;font-weight:600;color:var(--text);line-height:1.35}
.ny-card-sub{font-size:11.5px;color:var(--text3);line-height:1.35;margin-top:1px}

.ny-card-tail{display:flex;align-items:center;gap:8px;flex-shrink:0}
.ny-days{width:26px;text-align:right;font-size:10px;font-weight:700;color:var(--text3);white-space:nowrap;flex-shrink:0}
.ny-card-tail .row-actions,.ny-card-tail .btn{align-self:center;margin-top:0;flex-shrink:0}
.ny-chev{width:12px;text-align:center;color:var(--border2);font-size:15px;flex-shrink:0}
@media(max-width:768px){
  .ny-bucket{margin:10px 8px 0}
  .ny-days{display:none}
  .ny-card{padding:11px 10px}
}

/* ── Dashboard: two-column, denser layout (Dale's mockup) ──────────────────────
   Hero = serif greeting + a four-cell stat strip; KPI row spans both columns;
   the attention stream and money sit left, Projects at a Glance owns the right. */
#dash-hero{align-items:center;gap:16px;margin-bottom:16px}
.dash-hero-txt{min-width:0}
#dash-greeting{font-size:26px;font-weight:800;letter-spacing:-.5px;line-height:1.15}
#dash-hero .dvi04d0{margin:3px 0 0;font-size:12.5px;color:var(--text3)}
#dash-daystrip{margin-left:auto}
#dash-daystrip-body{display:flex;align-items:stretch;background:var(--surface);border:1px solid var(--border);
  border-radius:12px;box-shadow:var(--tile);overflow:hidden}
.dstrip-cell{display:flex;align-items:center;gap:9px;padding:10px 18px;border-left:1px solid var(--border)}
.dstrip-cell:first-child{border-left:0}
.dstrip-cell i{font-size:17px}
.dstrip-txt{display:flex;flex-direction:column;line-height:1.15}
.dstrip-txt b{font-size:15px;font-weight:700;color:var(--text)}
.dstrip-txt span{font-size:11px;color:var(--text3);white-space:nowrap}
.dstrip-clear{display:block;padding:11px 16px;font-size:12px;color:var(--text3)}

.dash-cols{display:grid;grid-template-columns:minmax(0,.78fr) minmax(0,1fr);gap:14px;align-items:start}
.dash-col{min-width:0;display:flex;flex-direction:column;gap:14px}
.dash-cols .card{margin-bottom:0!important}
#needs-you .d1mlb90{white-space:nowrap}
#dash-registers > div{grid-template-columns:minmax(0,1fr)!important;display:grid!important;gap:14px}
#dash-registers{display:flex;flex-direction:column;gap:14px}

/* Denser dashboard chrome — the mock reads more "zoomed" than the old spacing. */
#page-dashboard .dkpi-card{padding:13px 15px}
#page-dashboard .dkpi-num{font-size:26px}
#page-dashboard .card-hd{padding:12px 14px}
#page-dashboard .ny-bucket{margin:10px 12px 0}
#page-dashboard .ny-bucket:last-child{margin-bottom:10px}
#page-dashboard .ny-card{padding:10px 12px}
#page-dashboard .ny-card-title{font-size:12.5px}
#page-dashboard .ny-card-sub,#page-dashboard .ny-jobname{font-size:11px}
@media(max-width:1180px){
  .dash-cols{grid-template-columns:minmax(0,1fr)}
  #dash-daystrip{margin-left:0;width:100%}
  #dash-daystrip-body{width:100%}
  .dstrip-cell{flex:1;justify-content:center;padding:9px 8px}
}
/* Needs-you header in the two-column layout: the mockup keeps only the count and a
   View-all link here — the filter pills and Suggest button did not fit and were
   spilling over the next column. They stay in the DOM (and full-width layouts). */
.ny-viewall{display:none;font-size:11px;font-weight:600;color:var(--text2);cursor:pointer;white-space:nowrap}
.ny-viewall:hover{color:var(--brand-ink)}
@media(min-width:769px){
  .dash-col-l #needs-you .card-hd{gap:8px;flex-wrap:nowrap}
  .dash-col-l #needs-you #ny-filters,
  .dash-col-l #needs-you #ny-hd-tools,
  .dash-col-l #needs-you .ny-brk{display:none}
  .dash-col-l #needs-you .d1h90k4r{font-size:11px;white-space:nowrap;margin-left:auto}
  .dash-col-l #needs-you .ny-viewall{display:inline}
}
/* Projects at a Glance — phase chip leads the row */
.dpg-phase{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.3px;padding:3px 7px;
  border-radius:4px;white-space:nowrap;text-align:center;overflow:hidden;text-overflow:ellipsis}
#dash-projects-card .d13p21bt{font-size:12px;line-height:1.3}
#dash-projects-card .docaqsk{font-size:10.5px}
#dash-projects-card .d143faqf{white-space:nowrap}
#dash-projects-card .d1jwbzom{display:block;font-size:8.5px;letter-spacing:.2px}
#dash-projects-card .d1anznmh{text-align:right;font-size:12px}
#dash-projects-card .diua1tq{min-width:0;overflow:hidden}

/* ── Mobile corrections for the dashboard rework ──────────────────────────────
   The two-column dashboard stacks on a phone, so the half-width header rules
   must not apply, and the Projects table has to stop being a table. */
@media(max-width:768px){

  /* Projects at a Glance → one stacked card per job */
  #dash-projects-card .dth1l13{display:none}
  #dash-projects-card .dolhz1e{display:grid;grid-template-columns:auto 1fr auto;
    grid-template-areas:"phase num val" "job job job" "note note note";
    gap:4px 8px;padding:11px 12px;align-items:center}
  #dash-projects-card .dolhz1e > .dpg-phase{grid-area:phase;justify-self:start}
  #dash-projects-card .dolhz1e > .d9y93tq{grid-area:num}
  #dash-projects-card .dolhz1e > .d1pzgnpd{grid-area:job;min-width:0}
  #dash-projects-card .dolhz1e > .diua1tq{grid-area:note;min-width:0}
  #dash-projects-card .dolhz1e > .d1anznmh{grid-area:val;text-align:right;white-space:nowrap}
  #dash-projects-card .dolhz1e > .d1nd9s0n{display:none}
  #dash-projects-card .d13p21bt{white-space:normal}
}

@media(max-width:768px){
  /* KPI tiles: the desktop chevron was pinned to the vertical middle, which on the
     stacked mobile tile lands exactly on the divider rule. */
  #page-dashboard .dkpi-card::after{top:13px;transform:none;right:11px;font-size:17px}
  #page-dashboard .dkpi-card{padding:13px 26px 13px 14px}
  #page-dashboard .dkpi-num,#page-dashboard .dkpi-lbl,#page-dashboard .dkpi-sub{text-align:left;align-self:stretch}

  /* The View-all link belongs to the half-width column only. */
  #ny-hd .ny-viewall{display:none}
}

@media(max-width:768px){
  /* Day strip scrolls at this width; without the fade the last chip just looked
     chopped off rather than swipeable. */
  #dash-hero #dash-daystrip{overflow-x:auto;scrollbar-width:none;
    -webkit-mask:linear-gradient(90deg,#000 calc(100% - 28px),transparent)}
  #dash-hero #dash-daystrip::-webkit-scrollbar{display:none}
  #dash-daystrip-body{display:flex;flex-wrap:nowrap;gap:0}
  #dash-daystrip-body > *{flex:0 0 auto}
}

@media(max-width:768px){
  /* Finance overview: a fixed 3-up grid at 412px pushed the third card outside the
     viewport, and .content clips rather than scrolls, so it was simply unreachable. */
  .d167ulp3{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:14px}
  .d167ulp3 > *{min-width:0}
}

/* ── Audit fixes ──────────────────────────────────────────────────────────────
   Sidebar rows landed at 39px after the resize — one pixel under the 40px tap
   target. Small brand-tan text was failing contrast at #A98D69; --brand2 (#8C7048)
   keeps the accent and clears it. */
.sb-item{min-height:40px}
.ny-jobnum,#dash-projects-card .d9y93tq{color:var(--brand2)}
.ny-chev{color:var(--text3)}
.dpg-phase{font-size:10px}
#dash-projects-card .d1jwbzom{font-size:10px}

@media(max-width:768px){
  /* Tap targets that fell just under 40px on a phone. */
  /* Both lost to more specific rules the first time: the row buttons are pinned to
     38px by #fin-unreconciled-body, and the checkbox size lives on a util class in
     components.css, which loads last. */
  #fin-unreconciled-body .unr-row .btn,#page-fin-expenses .btn{min-height:40px}
  input.unr-chk{width:20px;height:20px}
  .pw-eye{width:40px;height:40px}
}

/* ── Day-strip drop-downs ─────────────────────────────────────────────────────
   The four tiles are buttons now; each drops a panel the width of the whole strip
   listing the items behind that count. */
.dstrip-cell{background:none;border:none;font:inherit;color:inherit;cursor:pointer;border-radius:8px;transition:background .12s}
.dstrip-cell:hover{background:var(--surface2)}
.dstrip-cell.on{background:var(--surface2);box-shadow:inset 0 -2px 0 var(--brand)}
.dstrip-panel{position:fixed;z-index:9200;background:var(--surface);border:1px solid var(--border);
  border-radius:12px;box-shadow:0 14px 40px rgba(0,0,0,.16);max-height:min(62vh,560px);overflow-y:auto;padding:0 0 4px}
.dstrip-panel-hd{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:8px;padding:10px 12px;
  background:var(--surface);border-bottom:1px solid var(--border);border-radius:12px 12px 0 0;
  font-size:11px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:var(--text2)}
.dstrip-panel-hd > span{background:var(--surface2);border:1px solid var(--border);border-radius:999px;padding:1px 7px;font-size:10px}
.dstrip-panel-hd > button{margin-left:auto}
.dstrip-panel .ny-bb{border:0;border-radius:0;max-height:none;margin:0}
.dstrip-empty{padding:18px 14px;text-align:center;font-size:12px;color:var(--text3)}
