/* Roof Platform — design system (2026-11-05 rehaul): ONE font stack
   (-apple-system / SF native + Inter embedded), strict size/weight scale,
   gray hierarchy #1d1d1f / #6e6e73 / #f5f5f7, white 16px-radius cards,
   generous spacing, >=44px tap targets. --accent is the tenant variable:
   it defaults to the platform orange and is overridden per company where
   a surface renders tenant branding. The same tokens drive the
   homeowner-facing quote surfaces. */
@font-face{font-family:Inter;src:url("fonts/Inter-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Inter;src:url("fonts/Inter-600.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:Inter;src:url("fonts/Inter-700.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap}
:root{
  --accent:#ff6b35; --accent-dark:#e8541f; --ink:#1d1d1f; --muted:#6e6e73;
  --tertiary:#86868b; --line:#d2d2d7; --bg:#f5f5f7; --card:#ffffff;
  --ok:#12805c; --danger:#b3261e; --radius:16px;
}
*{box-sizing:border-box}
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text",Inter,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  background:var(--bg);color:var(--ink);font-size:16px;line-height:1.5}
a{color:var(--accent-dark)}
.topbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;
  background:var(--card);border-bottom:1px solid var(--line);padding:12px 20px}
.brand{font-weight:700;font-size:20px;letter-spacing:-0.01em;color:var(--ink);text-decoration:none}
.nav{display:flex;gap:6px;flex-wrap:wrap}
.nav a{display:inline-flex;align-items:center;min-height:44px;color:var(--ink);text-decoration:none;padding:9px 13px;border-radius:999px;font-weight:600}
.nav a:hover{background:var(--bg)}
.who{display:flex;gap:10px;align-items:center}
.who-co{font-weight:700}.who-name{color:var(--muted)}
.wrap{max-width:960px;margin:0 auto;padding:24px 16px 48px}
.wrap-narrow{max-width:480px}
.foot{text-align:center;color:var(--muted);font-size:13px;padding:18px}
h1{font-size:28px;font-weight:600;margin:6px 0 4px;letter-spacing:-0.02em;line-height:1.15}
h2{font-size:20px;font-weight:600;margin:22px 0 8px;letter-spacing:-0.01em;line-height:1.2}
h3{font-size:17px;font-weight:600;margin:18px 0 6px;letter-spacing:-0.01em;line-height:1.25}
.sub{color:var(--muted);margin:0 0 18px}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:20px;margin:0 0 16px;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--accent);color:#fff;border:0;border-radius:12px;
  min-height:48px;padding:13px 22px;font-size:16px;font-weight:600;cursor:pointer;text-decoration:none}
.btn:hover{background:var(--accent-dark)}
.btn-ghost{background:#fff;color:var(--ink);border:1px solid var(--line)}
.btn-ghost:hover{background:var(--bg)}
.btn-small{min-height:44px;padding:8px 14px;font-size:14px;border-radius:10px}
.btn-danger{background:#fff;color:var(--danger);border:1px solid #f0c6c2}
label{display:block;font-weight:600;font-size:14px;margin:14px 0 6px}
input[type=text],input[type=email],input[type=password],input[type=tel],input[type=number],input[type=date],textarea,select{
  width:100%;min-height:48px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;font-size:16px;background:#fff;color:var(--ink);
  /* Fix round 2 (P8): this shared rule set size but never the family,
     and a browser's UA sheet gives <textarea> a monospace default
     (text inputs get the system font from the UA, textareas do not),
     so textareas alone fell off the platform stack. Set it here, at
     the standard-input level, for every form control. */
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text",Inter,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
input[type=text]:focus,input[type=email]:focus,input[type=password]:focus,input[type=tel]:focus,input[type=number]:focus,input[type=date]:focus,textarea:focus,select:focus{
  border-color:var(--accent);outline:none;box-shadow:0 0 0 3px rgba(255,107,53,.16)}
textarea{min-height:90px}
/* Password show/hide eye toggle (assets/pw-toggle.js wraps the input) */
.pw-wrap{position:relative;display:block}
.pw-wrap input[type=password],.pw-wrap input[type=text]{padding-right:54px}
.pw-eye{position:absolute;top:50%;right:6px;transform:translateY(-50%);width:44px;height:44px;
  display:inline-flex;align-items:center;justify-content:center;background:transparent;border:0;
  border-radius:10px;color:var(--muted);cursor:pointer;padding:0}
.pw-eye:hover{background:var(--bg);color:var(--ink)}
.pw-eye svg{width:22px;height:22px;display:block}
.flash{background:#e6f6ef;border:1px solid #bfe6d4;color:var(--ok);border-radius:12px;
  padding:12px 16px;margin-bottom:16px;font-weight:600}
.error{background:#fdecea;border:1px solid #f5c6c2;color:var(--danger);border-radius:12px;
  padding:12px 16px;margin-bottom:16px;font-weight:600}
.list{list-style:none;margin:0;padding:0}
.list li{display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:14px 4px;border-bottom:1px solid var(--line)}
.list li:last-child{border-bottom:0}
.item-main{font-weight:700}.item-sub{color:var(--muted);font-size:14px}
/* Job view Estimates rows (fix D2, Nov 6): the signed-record actions
   ("Signing record" + "Signed PDF") were a nowrap span that pushed
   the job view to 468px at a 390px phone width. Scoped to the
   Estimates list only: the row may wrap, the text block may shrink,
   and the actions wrap under it — buttons keep the 44px .btn-small
   tap height and their labels stay on one line each. */
.est-list li{flex-wrap:wrap}
.est-list li>div{min-width:0;flex:1 1 180px;overflow-wrap:anywhere}
.est-actions{display:inline-flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;
  max-width:100%;margin-left:auto}
.est-actions .btn{white-space:nowrap}
.pill{display:inline-block;padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600;
  background:var(--bg);color:var(--muted)}
.pill-on{background:#e6f6ef;color:var(--ok)} .pill-off{background:#fdecea;color:var(--danger)}
.searchrow{display:flex;gap:10px;margin-bottom:16px}
.searchrow input{flex:1}
.switchrow{display:flex;justify-content:space-between;align-items:center;gap:14px;
  padding:16px 4px;border-bottom:1px solid var(--line)}
.switchrow:last-child{border-bottom:0}
.switch{position:relative;width:58px;height:44px;flex:0 0 58px}
.switch input{opacity:0;width:100%;height:100%;position:absolute;margin:0;cursor:pointer}
.track{position:absolute;inset:6px 0;background:#d2d2d7;border-radius:999px;transition:.15s;pointer-events:none}
.track:before{content:"";position:absolute;width:26px;height:26px;left:3px;top:3px;
  background:#fff;border-radius:50%;transition:.15s}
.switch input:checked + .track{background:var(--ok)}
.switch input:checked + .track:before{transform:translateX(26px)}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:14px}
.toolcard{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.toolcard .t{font-weight:700;font-size:17px;margin-bottom:4px}
.logo-preview{max-height:80px;max-width:260px;display:block;margin:8px 0}
.avatar-img{width:40px;height:40px;border-radius:50%;object-fit:cover;flex:0 0 40px;border:1px solid var(--line)}
.avatar-fallback{width:40px;height:40px;border-radius:50%;flex:0 0 40px;display:inline-flex;align-items:center;justify-content:center;
  background:var(--bg);border:1px solid var(--line);color:var(--muted);font-weight:700;font-size:14px}
.who .avatar-img{width:32px;height:32px;flex-basis:32px}
.empty{color:var(--muted);text-align:center;padding:28px 10px}
pre.state{background:#f5f5f7;border:1px solid var(--line);color:var(--ink);border-radius:12px;padding:14px;overflow:auto;font-size:13px}
/* Homeowner-facing quote card (demo of the branded share page pattern) */
.quote-card{max-width:520px;margin:0 auto;background:#fff;border-radius:20px;overflow:hidden;
  border:1px solid var(--line);box-shadow:0 8px 30px rgba(0,0,0,.08)}
.quote-head{padding:22px;text-align:center;color:#fff}
.quote-head img{max-height:56px;max-width:200px}
.quote-body{padding:22px;text-align:center}
.quote-price{font-size:40px;font-weight:700;margin:6px 0}
.quote-cta{display:block;margin:14px 0 0;padding:16px;border-radius:14px;color:#fff;
  font-weight:700;font-size:18px;text-decoration:none}
/* Settings area — design-system tokens: hairlines, air, one accent */
.settabs{display:flex;gap:4px;flex-wrap:wrap;margin:10px 0 22px;padding:4px;
  background:#fff;border:1px solid #d2d2d7;border-radius:12px;width:fit-content;max-width:100%}
.settabs a{display:inline-flex;align-items:center;min-height:44px;padding:0 18px;border-radius:10px;
  color:#6e6e73;text-decoration:none;font-weight:600;font-size:15px;white-space:nowrap}
.settabs a:hover{color:#1d1d1f;background:#f5f5f7}
.settabs a.on{background:#1d1d1f;color:#fff}
.roleform{display:inline-flex;gap:8px;align-items:center;margin-left:10px}
.roleform select{width:auto;min-height:44px;padding:8px 10px;border:1px solid #d2d2d7;
  border-radius:10px;font-size:14px;background:#f5f5f7;color:#1d1d1f}
/* Team rows (users.php): controls must wrap inside the card at phone
   width — a role <select> + Save button used to overflow the card. */
.team-list li.team-row{flex-wrap:wrap}
.team-list li.team-row>*{min-width:0;max-width:100%}
.team-actions{min-width:0;max-width:100%}
.team-list .roleform{flex-wrap:wrap;max-width:100%}
.team-list .roleform select{min-width:0;max-width:100%}
/* Batch 7 fix1 (F-T1): designed file control — the native OS file
   widget never renders. A styled button + chosen-filename text wrap
   the real input (visually hidden, same name/handler underneath);
   a small script on the page updates the filename on change. */
.filepick{position:relative;display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap;max-width:100%;cursor:pointer;margin:0;font-weight:400}
.filepick-input{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden}
.filepick-btn{display:inline-flex;align-items:center;min-height:44px;padding:10px 16px;border:1px solid var(--line);border-radius:10px;background:#fff;color:var(--ink);font-size:14px;font-weight:600;white-space:nowrap}
.filepick:hover .filepick-btn{background:var(--bg)}
.filepick-input:focus-visible + .filepick-btn{box-shadow:0 0 0 3px rgba(255,107,53,.16);border-color:var(--accent)}
.filepick-name{font-size:13.5px;color:var(--muted);overflow-wrap:anywhere}
/* Avatar file picker on the Team UI: >=44px tap target (the native
   button alone renders ~20px tall). */
input[type=file].file44{min-height:44px}
input[type=file].file44::file-selector-button{min-height:44px;padding:10px 14px;margin-right:10px;
  border:1px solid var(--line);border-radius:10px;background:#fff;color:var(--ink);
  font:inherit;font-size:14px;font-weight:600;cursor:pointer}
@media (max-width:640px){
  .team-actions{width:100%}
}
@media (max-width:480px){
  .settabs{width:100%}
  .settabs a{flex:1 1 auto;justify-content:center;padding:0 8px}
  .roleform{margin-left:0;margin-top:8px}
}

/* ---- Jobs: cards, board, job view (Nov 6) ---- */
.jobcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:14px}
.jobcard{display:flex;gap:14px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px;text-decoration:none;color:var(--ink);min-height:118px;box-sizing:border-box}
.jobcard:hover{border-color:#b9b9be}
.jobcard.dragging{opacity:.45}
.jc-thumb{flex:0 0 84px;width:84px;height:84px;border-radius:12px;background:var(--bg);overflow:hidden;
  display:flex;align-items:center;justify-content:center}
.jc-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.jc-thumb-ph{font-size:34px;color:var(--tertiary)}
.jc-main{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.jc-name{font-weight:700;font-size:16.5px;letter-spacing:-0.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jc-addr{color:var(--muted);font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jc-jobtitle{font-size:13.5px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jc-meta{color:var(--muted);font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jc-foot{margin-top:auto;display:flex;align-items:center;gap:10px;padding-top:6px}
.jc-chip{display:inline-flex;align-items:center;min-height:24px;padding:2px 10px;border-radius:999px;
  font-size:12px;font-weight:700;letter-spacing:.01em}
.jc-upd{color:var(--tertiary);font-size:12px}
.board{display:flex;gap:14px;overflow-x:auto;padding-bottom:14px;align-items:flex-start}
.board-col{flex:0 0 356px;min-width:0;background:var(--bg);border:1px solid var(--line);border-radius:var(--radius);padding:10px}
.board-col header{display:flex;justify-content:space-between;align-items:center;font-weight:700;font-size:15px;padding:2px 4px 10px}
.board-count{background:var(--card);border:1px solid var(--line);border-radius:999px;font-size:12.5px;padding:1px 9px;color:var(--muted)}
.board-drop{display:flex;flex-direction:column;gap:10px;min-height:130px}
.board-col.over{outline:2px dashed var(--accent);outline-offset:-4px}
.board-empty{color:var(--tertiary);font-size:13.5px;text-align:center;margin:8px 0}
.board-col-off{opacity:.75}
.board-phone-note{display:none}
@media (max-width:760px){.board-phone-note{display:block;color:var(--muted)}}
.jc-photos{display:flex;gap:12px;flex-wrap:wrap}
.jc-photos figure{margin:0;width:150px}
.jc-photos img{width:150px;height:112px;object-fit:cover;border-radius:12px;display:block}
.jc-photos figcaption{font-size:12.5px;color:var(--muted);margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Job view — identity statement + measurement (Nov 6 completion) */
.job-ident{font-size:17px;line-height:1.5;color:var(--ink);margin:2px 0 4px}
.job-ident-sub{color:var(--muted);font-size:14px;margin:0 0 18px}
.meas-line{display:flex;gap:14px;align-items:baseline;flex-wrap:wrap}
.meas-sq{font-size:30px;font-weight:700;letter-spacing:-0.02em}
.meas-unit{font-size:15px;color:var(--muted);font-weight:600}

/* Scout round 2 adoptions (Nov 6): card aging footer, touch board */
.jc-age{color:var(--tertiary);font-size:12px;white-space:nowrap}
.board-move{display:none}
@media (max-width:760px){
  .board{flex-direction:column;overflow-x:visible}
  .board-col{flex:1 1 auto;width:100%}
  .board-move{display:block}
  .board-move select{width:100%;min-height:48px;margin-top:-2px}
}

/* Import clients (Nov 6): the system landing lane reads as its own thing
   on the board — warm alert panel, never mistaken for a working status. */
.board-col-import{background:#fdf3e0;border-color:#e8cf9a}
.board-col-import header{color:#7a5200}
.board-import-tag{display:inline-block;font-size:12px;font-weight:600;background:#b3261e;color:#fff;border-radius:999px;padding:2px 9px;margin-left:6px;vertical-align:2px}
.board-import-sort{margin:0 4px 10px;font-size:14px;font-weight:600}

/* Production module (Phase A, Nov 6) */
.jc-over{display:inline-block;padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600;background:#fdf3e0;color:#9a6a00}
.prod-banner{background:#fdf3e0;color:#7a5200;border-radius:12px;padding:12px 16px;margin:0 0 14px;font-size:14.5px;font-weight:600}
.prod-state{display:inline-block;width:22px;font-weight:700}
.prod-ok{color:var(--ok,#0d6e4f)}
.prod-no{color:var(--muted,#6e6e73)}
.prod-na{color:var(--muted,#6e6e73)}
.prod-missing{margin:12px 0 0;font-size:15px;font-weight:600;color:#b3261e}
.prod-ready-line{margin:12px 0 0;font-size:15px;font-weight:600;color:#0d6e4f}
.prod-override{margin-top:16px;background:var(--bg,#f5f5f7);border-radius:12px;padding:14px 16px}

/* ---- Production calendar (Phase B, Nov 6) ---- */
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px;margin-top:14px}
.cal-dow{font-size:12.5px;font-weight:600;color:var(--muted,#6e6e73);text-align:center;padding:4px 0}
.cal-cell{background:var(--bg,#f5f5f7);border:1px solid var(--line,#d2d2d7);border-radius:10px;padding:6px;min-height:86px;overflow:hidden}
.cal-cell.cal-out{opacity:.45}
.cal-cell.cal-sel{border-color:var(--ink,#1d1d1f);background:#fff}
.cal-daynum{display:block;font-weight:700;font-size:13.5px;color:var(--ink,#1d1d1f);text-decoration:none;min-height:44px}
.cal-hol{font-size:11.5px;color:#b3261e;font-weight:600;margin:2px 0}
.cal-job{font-size:12px;line-height:1.35;margin-top:4px;background:#fff;border:1px solid var(--line,#d2d2d7);border-radius:8px;padding:4px 6px}
.cal-job a{font-weight:600;color:var(--ink,#1d1d1f);text-decoration:none;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal-job span{display:block;color:var(--muted,#6e6e73);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal-job .cal-wx{color:#8a5d00;font-weight:600}
.wx-chip{display:inline-block;font-size:11.5px;font-weight:600;line-height:1;padding:4px 8px;border-radius:999px;white-space:nowrap}
.cal-job .wx-chip{margin-top:3px;font-size:10.5px;padding:3px 6px}
@media (max-width:760px){.cal-cell{min-height:64px;padding:4px}.cal-job{font-size:11px;padding:3px 4px}.cal-daynum{font-size:12.5px}}

/* Weather band on phone month cells (Nov 7 polish): a ~44px cell cannot
   fit the chip pill, so at phone width the pill is hidden in month
   cells and the job entry carries the band as color alone — a 3px
   left border in the band color. The day list below the calendar
   keeps the full chip at every width; desktop month cells keep the
   pill exactly as before. */
@media (max-width:760px){
.cal-job .wx-chip{display:none}
.cal-job .cal-wx{display:none}
.cal-job.wxb-green{border-left:3px solid #1e7a34}
.cal-job.wxb-yellow{border-left:3px solid #8a5d00}
.cal-job.wxb-red{border-left:3px solid #b3261e}
}

/* Nagatha header portrait (trial-waits round 2, Nov 7): the WAITING
   start screen exits before supervisor.php's inline <style> block, so
   this rule lives in the shared sheet and both the waiting and the
   entitled renders get the round avatar. The inline copy on the
   entitled path stays — the rules are identical. */
.sup-head-ava{border-radius:50%;vertical-align:-14px;margin-right:10px}
/* Settings rows at phone width (trial-waits round 2, Nov 7): a
   .switchrow never wrapped, so a wide action button (the Nagatha
   card's "Start free trial") squeezed its copy into a narrow ribbon.
   Same wrap pattern as .est-list above: at phone width the row wraps,
   the text block takes the full width and the action sits below it.
   Desktop rendering is untouched — this is a media query only. */
@media (max-width:760px){
.switchrow{flex-wrap:wrap}
.switchrow>div{min-width:0;flex:1 1 100%}
}

/* Reviews scorecard at phone width (fix round 2, P1 + fix round 3):
   the full column set lives on desktop; at <=760px the table stops
   being a wide table and restacks — each rep is a compact block:
   line 1 the rep name (full, may wrap) with the Score prominent at
   the top right of the block, line 2 the key stats in plain words
   at muted size (Completed N · Posted N · Post rate N%).
   Detail columns (Asked/Answered/Positive/Negative/Probable) stay
   desktop-only. No horizontal scroll at phone width. */
.scorecard-table{min-width:640px}
@media (max-width:760px){
.scorecard-wrap{overflow-x:visible!important}
.scorecard-table{display:block;min-width:0;width:100%!important}
.scorecard-table thead{display:none}
.scorecard-table tbody{display:block}
.scorecard-table tr{display:block;position:relative;padding:12px 0;border-bottom:1px solid #f0f0f2}
.scorecard-table tbody tr:last-child{border-bottom:0}
.scorecard-table td{border-bottom:0!important}
.sc-phone-hide{display:none!important}
.sc-name{display:block;padding:0 96px 2px 0!important;text-align:left!important;font-weight:600;color:var(--ink);line-height:1.35;overflow-wrap:anywhere}
.sc-score{position:absolute;top:12px;right:0;display:block;padding:0!important;text-align:right!important;font-weight:700;color:var(--ink);font-size:17px;line-height:1.35;white-space:nowrap}
.sc-score::before{content:attr(data-label) " ";font-size:13px;font-weight:600;color:var(--muted)}
.sc-stat{display:inline;padding:0!important;text-align:left!important;color:var(--muted);font-size:14px;line-height:1.5}
.sc-stat::before{content:attr(data-label) " "}
}

/* Production Scorecard design fix round (Nov 7, 2026 — D3/D7/D8/D9):
   production metrics rows top-align their values (D3); the cause
   picker's current cause is a dark-ink selected state, NOT the orange
   action fill (D7, settabs a.on language); on phones the
   Needs-attention item stacks with Open job full-width at the bottom
   (D8) and picker buttons pair two-per-row (D9). */
.prod-list li{align-items:flex-start}
.btn-current{background:#1d1d1f;color:#fff;border:1px solid #1d1d1f}
.btn-current:hover{background:#1d1d1f}
@media (max-width:760px){
  .na-list li{flex-direction:column;align-items:stretch}
  .cause-picker .btn{flex:1 1 42%}
  .cause-picker>span{flex:1 1 100%}
}

/* Phase C design polish (Nov 7, 2026):
   P4 — material-order line rows wrap at phone width: the item name
   takes the full first line, qty + unit sit on a second line inside
   the card, fully visible and tappable. Desktop keeps one line. */
.ord-lines li{flex-wrap:wrap}
.ord-lines .ord-name{flex:1 1 200px;min-width:0}
.ord-lines .ord-qty{flex:0 1 100px}
.ord-lines .ord-unit{flex:0 1 110px}
@media (max-width:760px){
  .ord-lines .ord-name{flex:1 1 100%}
  .ord-lines .ord-qty{flex:1 1 40%}
  .ord-lines .ord-unit{flex:1 1 40%}
}
/* P5 — money summary: the five figures share one baseline even when
   a label wraps to a second (sub-)line: labels grow, values sit at
   the bottom of each cell. */
.money-sum{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-bottom:6px}
.money-sum>div{display:flex;flex-direction:column}
.money-sum .ms-val{margin-top:auto;font-size:19px;font-weight:700}
.money-sum .ms-sub{display:block;font-size:12.5px}
/* P13 — payment-schedule phases: name · trigger · % on ONE line at
   desktop, each field with its own small visible label; the row
   stacks at phone width. */
.ps-phase{display:flex;gap:10px;flex-wrap:wrap;align-items:end}
.ps-phase>label{display:block;margin:0}
.ps-phase .ps-name{flex:1 1 220px}
.ps-phase .ps-trig{flex:0 1 260px}
.ps-phase .ps-pct{flex:0 0 120px}
.ps-phase .ps-lab{display:block;font-weight:600;font-size:12.5px;color:var(--muted);margin-bottom:4px}
@media (max-width:760px){
  .ps-phase>label{flex:1 1 100%}
  .ps-phase .ps-pct{flex:1 1 100%}
}
/* P14 — calendar delivery-moved marker (month chip). */
.cal-moved{display:block;color:#8a5d00;font-weight:700;white-space:normal}

/* Production Mailbox design polish (Nov 7, 2026):
   D13 — the intake queue's two-candidate conflict picker stacks at
   phone width so the job names/addresses the choice turns on stay
   readable; desktop keeps the side-by-side comparison. */
.mail-conflict-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:8px}
@media (max-width:760px){.mail-conflict-grid{grid-template-columns:1fr}}

/* Production follow-ons fix FD2 (Nov 7, 2026): the On-time completion
   row on the Production scorecard (public/reviews.php) is a flex li
   whose value column crushed the label at phone width — the populated
   value wrapped mid-parenthetical ("50% (1 of / 2)") and the zero-state
   collecting-data sentence squeezed the label sub-line into five lines
   (160px-tall row). Scoped to this row only (dedicated classes in
   reviews.php; no other scorecard row is touched): the populated value
   never wraps, the label block may shrink (min-width:0) so its sub-line
   wraps before the value does, and at <=760px the row stacks — label
   full-width, value / collecting-data sentence on its own full-width
   line under it. In the stacked phone rendering only, the zero
   sentence's redundant "On-time:" prefix is hidden (it duplicates the
   row's own "On-time completion" label); desktop rendering is
   unchanged, full sentence included. */
.ontime-row>.ontime-label{min-width:0}
.ontime-row>.ontime-value{white-space:nowrap}
@media (max-width:760px){
  .ontime-row{flex-direction:column;align-items:stretch}
  .ontime-row>.ontime-zero{display:block;width:100%}
  .ontime-row .ontime-prefix{display:none}
}

/* ==== Batch 1 design overhaul (2026-11-08): shell, Home, Settings map,
   instant roof settings, Production segmented control. Same tokens:
   -apple-system/SF + Inter, #1d1d1f / #6e6e73 / #f5f5f7, white 16px
   cards, >=44px targets, one primary action per screen. ==== */

/* --- Shell topbar: brand lockup | 6-item nav | search + New + avatar --- */
.topbar{flex-wrap:nowrap;gap:16px;padding:10px 20px;position:relative;z-index:40}
.brand{display:inline-flex;align-items:center;gap:10px;min-height:44px;white-space:nowrap}
.brand-logo{max-height:36px;max-width:150px;display:block}
.brand-name{font-size:17px}
.nav{flex-wrap:nowrap}
.nav a.on{background:var(--bg);color:var(--ink)}
.shell-tools{display:flex;gap:10px;align-items:center;margin-left:auto}
.shell-search input[type=search]{width:230px;min-height:44px;padding:10px 14px;border-radius:999px;background:var(--bg);border:1px solid transparent}
.shell-search input[type=search]:focus{background:#fff;border-color:var(--accent)}
.menu-wrap{position:relative}
.avatar-btn{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;border:0;background:transparent;padding:0;cursor:pointer}
.avatar-btn .avatar-img{width:40px;height:40px}
.avatar-btn .avatar-fallback{width:40px;height:40px;font-size:15px}
.menu{position:absolute;top:52px;right:0;min-width:210px;background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:0 12px 34px rgba(0,0,0,.14);padding:6px;z-index:60}
.menu[hidden]{display:none}
.menu a{display:flex;align-items:center;min-height:44px;padding:9px 12px;border-radius:10px;color:var(--ink);text-decoration:none;font-size:15px;font-weight:600}
.menu a:hover{background:var(--bg)}
.menu-head{padding:10px 12px 8px;border-bottom:1px solid var(--bg);margin-bottom:4px}
.menu-name{font-weight:700;font-size:15px}
.menu-sub{color:var(--muted);font-size:13px}
.menu a.menu-out{color:var(--muted);font-weight:500;border-top:1px solid var(--bg);margin-top:4px}
.menu-up{top:auto;bottom:58px}
.shell-new{white-space:nowrap}
.shell-search-icon{display:none}

/* --- Phone bottom nav: Home · Jobs · ＋ · Production · More --- */
.bottomnav{display:none}
@media (max-width:760px){
  .topbar{flex-wrap:wrap;gap:8px;padding:10px 14px}
  .nav{display:none}
  .brand-name{font-size:16px}
  .shell-search{display:none}
  .shell-search-icon{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;color:var(--ink);text-decoration:none}
  .shell-new-wrap{display:none}
  body{padding-bottom:72px}
  .bottomnav{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:50;background:#fff;border-top:1px solid var(--line);padding:6px 8px calc(6px + env(safe-area-inset-bottom));align-items:stretch;justify-content:space-around}
  .bottomnav>a,.bnav-more,.bnav-plus{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:6px 10px;border-radius:12px;color:var(--ink);text-decoration:none;font-size:13px;font-weight:600;background:transparent;border:0;cursor:pointer;font-family:inherit}
  .bottomnav>a.on{background:var(--bg)}
  .bnav-plus{font-size:24px;font-weight:400;width:52px;background:var(--ink);color:#fff;border-radius:999px}
  .bottomnav .menu{min-width:190px}
}

/* --- Home: pipeline / today / tools row --- */
.pipe-row{display:flex;gap:10px;flex-wrap:wrap}
.pipe-chip{display:flex;flex-direction:column;gap:1px;flex:1 1 130px;background:var(--bg);border-radius:12px;padding:12px 14px;text-decoration:none;color:var(--ink);min-height:44px}
.pipe-chip:hover{background:#ececf0}
.pipe-name{font-weight:700;font-size:15px}
.pipe-nums{color:var(--muted);font-size:13.5px}
.pipe-foot{color:var(--muted);margin:12px 0 0;font-size:14.5px}
.tools-row{display:flex;gap:6px 18px;flex-wrap:wrap}
.tool-link{display:inline-flex;align-items:center;min-height:44px;font-weight:600;color:var(--ink);text-decoration:none;padding:6px 2px}
.tool-link:hover{color:var(--accent-dark);text-decoration:underline}

/* --- Settings: landing index + left rail --- */
.set-crumb{display:flex;gap:8px;align-items:center;font-size:14px;color:var(--muted);margin:2px 0 14px;flex-wrap:wrap}
.set-crumb a{color:var(--ink);text-decoration:none;font-weight:600}
.set-crumb .on{color:var(--ink);font-weight:600}
.set-layout{display:flex;gap:26px;align-items:flex-start}
.set-rail{flex:0 0 208px;position:sticky;top:16px}
.set-main{flex:1;min-width:0}
.set-main>.card:first-child,.set-main>h2:first-child{margin-top:0}
.set-group{margin-bottom:18px}
.set-group-name{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--tertiary);margin:0 0 6px;padding:0 10px}
.set-rail a{display:flex;align-items:center;min-height:44px;padding:9px 10px;border-radius:10px;color:var(--ink);text-decoration:none;font-weight:600;font-size:15px}
.set-rail a:hover{background:#fff}
.set-rail a.on{background:#fff;border:1px solid var(--line)}
.set-group-foot{border-top:1px solid var(--line);padding-top:10px}
.set-index-group{margin-bottom:20px}
.set-index-group .set-group-name{padding:0 2px}
.set-index-card{padding:6px 10px;margin:0}
.set-row{display:flex;align-items:center;gap:12px;min-height:56px;padding:10px 8px;border-bottom:1px solid var(--bg);text-decoration:none;color:var(--ink)}
.set-row:last-child{border-bottom:0}
.set-row-main{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}
.set-row-label{font-weight:700;font-size:16px}
.set-row-desc{color:var(--muted);font-size:14px}
.set-row-chev{color:var(--tertiary);font-size:22px}
.set-index-foot{color:var(--muted);font-size:14px;margin:4px 2px 0}
@media (max-width:760px){
  .set-layout{flex-direction:column;gap:0}
  .set-rail{display:none}
  .set-main{width:100%}
}

/* --- Production segmented control (List | Calendar, one door) --- */
.seg{display:inline-flex;gap:4px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:4px;margin:4px 0 12px}
.seg a{display:inline-flex;align-items:center;min-height:44px;padding:0 20px;border-radius:10px;color:var(--muted);text-decoration:none;font-weight:600;font-size:15px}
.seg a.on{background:var(--ink);color:#fff}

/* --- Instant Roof Estimator settings (§A7) --- */
.tier-list{display:flex;flex-direction:column}
.tier-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:12px 2px;border-bottom:1px solid var(--bg)}
.tier-row:last-child{border-bottom:0}
.tier-img{width:52px;height:52px;border-radius:10px;object-fit:cover;flex:0 0 52px;border:1px solid var(--line)}
.tier-name{font-weight:700;font-size:15.5px;flex:1 1 170px;min-width:140px}
.tier-rank{color:var(--muted);font-weight:600}
.tier-price{display:inline-flex;align-items:center;gap:6px;font-weight:600;color:var(--muted);font-size:14.5px;margin:0}
.tier-price input{width:104px;min-height:44px}
.tier-warn{flex:0 0 100%;font-size:13.5px;font-weight:600;color:#9a6700;line-height:1.4}
.notlive{display:inline-block;vertical-align:middle;margin-left:8px;background:var(--bg);border:1px solid var(--line);color:var(--muted);border-radius:999px;padding:2px 10px;font-size:12.5px;font-weight:700;letter-spacing:.02em;white-space:nowrap}
.tier-on{display:inline-flex;align-items:center;gap:7px;font-weight:600;font-size:14.5px;margin:0;min-height:44px}
.tier-on input{width:20px;height:20px}
.instant-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px 26px}
.instant-inline{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-weight:600}
@media (max-width:640px){.instant-grid{grid-template-columns:1fr}}

/* --- Batch 2: Jobs board / list / job page (Nov 8, 2026 — §A14/§A15/§A16) --- */
/* Card v2 (Pattern 12): address is the headline, value top-right, name and
   title print only when they add information; the thumbnail placeholder
   sits BEHIND the image so a missing/failed aerial shows the designed
   placeholder, never a broken-image glyph. */
.jc-thumb{position:relative}
.jc-thumb-ph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.jc-thumb img{position:absolute;inset:0}
.jc-top{display:flex;align-items:baseline;gap:10px;min-width:0}
.jc-addr2{font-weight:700;font-size:16.5px;letter-spacing:-0.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}
.jc-value{font-weight:700;font-size:15px;white-space:nowrap}
.jc-name2{color:var(--muted);font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jc-asg{margin-left:auto;flex:0 0 auto;width:26px;height:26px;border-radius:50%;background:var(--bg);border:1px solid var(--line);color:var(--muted);font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center}
.jc-foot{flex-wrap:wrap;row-gap:4px}

/* Board: breaks out of the 960px reading wrap to full width (§A14) —
   a board is a wide-screen tool. Horizontal scroll stays INSIDE the
   board, columns keep their settled width. */
.board-head{margin-bottom:6px}
.board-head-top{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.board-head-top .seg{margin:0}
.board-head-top .btn{margin-left:auto}
.board-tools{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:12px 0 8px}
.board-tools input[type="search"]{flex:1 1 260px;min-height:48px}
.board-tools select{min-height:48px}
.board{width:min(1680px,calc(100vw - 32px));position:relative;left:50%;transform:translateX(-50%)}
.board-head,.board-phone-note{width:auto}
@media (max-width:760px){
  .board{width:100%;left:0;transform:none}
  .board-head-top .btn{margin-left:0}
}

/* Job hero (Patterns 20/21/28) */
.job-hero{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;margin-bottom:14px}
.job-hero-photo{position:relative;height:210px;background:var(--bg);overflow:hidden}
.job-hero-photo img{width:100%;height:100%;object-fit:cover;display:block}
.job-hero-ph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:54px;color:var(--tertiary)}
.job-hero-status{position:absolute;left:14px;bottom:14px}
.job-hero-status .jc-chip{font-size:13.5px;min-height:28px;padding:4px 12px;box-shadow:0 1px 4px rgba(0,0,0,.18)}
.job-hero-body{padding:16px 18px 18px}
.job-hero-name{font-size:16px;color:var(--muted);margin:2px 0 0;font-weight:600}
.job-actions{display:flex;gap:18px;flex-wrap:wrap;margin:14px 0 4px}
.job-act{display:flex;flex-direction:column;align-items:center;gap:5px;text-decoration:none;color:var(--ink);font-size:13px;font-weight:600;min-width:56px}
.job-act-ic{width:52px;height:52px;border-radius:50%;background:var(--bg);border:1px solid var(--line);display:flex;align-items:center;justify-content:center;font-size:21px}
.job-status-form{margin-top:12px;border-top:1px solid var(--bg);padding-top:12px}
.job-status-form label{display:block;font-weight:600;font-size:14px;color:var(--muted);margin-bottom:8px}
.job-status-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.job-status-row select{min-height:48px;min-width:220px}
.job-next{display:flex;gap:10px;align-items:center;background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:10px 14px;margin:0 0 14px;font-size:15px}
.job-next-label{font-weight:700;white-space:nowrap}
.job-next a{font-weight:600}
.job-money{padding:14px 18px}
.job-money .money-sum{margin:0}
.ms-due{color:#b3261e}

/* Job tabs + progressive disclosure */
.jobtabs{margin:0 0 14px}
.jobtabs button{display:inline-flex;align-items:center;min-height:44px;padding:0 20px;border:0;background:transparent;border-radius:10px;color:var(--muted);font:inherit;font-weight:600;font-size:15px;cursor:pointer}
.jobtabs button.on{background:var(--ink);color:#fff}
.card-toggle{float:right;min-height:44px;padding:0 14px;border:1px solid var(--line);background:#fff;border-radius:10px;font:inherit;font-weight:600;font-size:14px;color:var(--muted);cursor:pointer}
.card-sum{color:var(--muted);font-size:14.5px;margin:2px 0 0}

/* Persistent bottom action bar — phone only (Pattern 39) */
.job-bottombar{display:none}
@media (max-width:760px){
  .job-bottombar{display:flex;gap:10px;position:fixed;left:0;right:0;bottom:64px;z-index:40;background:#fff;border-top:1px solid var(--line);padding:10px 14px calc(10px + env(safe-area-inset-bottom))}
  .job-bottom-next{flex:1;display:inline-flex;align-items:center;justify-content:center;min-height:48px;border-radius:12px;background:var(--ink);color:#fff;text-decoration:none;font-weight:700;font-size:15px;padding:0 12px;text-align:center}
  .job-bottom-call{display:inline-flex;align-items:center;justify-content:center;min-height:48px;border-radius:12px;border:1px solid var(--line);color:var(--ink);text-decoration:none;font-weight:700;padding:0 18px}
  body{padding-bottom:86px}
  .job-hero-photo{height:160px}
}

/* --- Batch 2 fix1 (Nov 8, 2026): design re-review fix round F1–F8 --- */
/* F2: card text never clips mid-word — address/meta wrap at word
   boundaries (address may take two lines) instead of nowrap ellipsis. */
.jc-addr2{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:break-word;line-height:1.25}
.jc-name2,.jc-jobtitle,.jc-meta{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:break-word}
/* F8: no-image cards go compact — a small icon chip instead of the big
   empty thumbnail block, so list/board shorten. */
.jc-thumb-chip{flex:0 0 40px;width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:19px;color:var(--tertiary)}
.jobcard--compact{align-items:flex-start}
/* F1: board header is ONE row at the board's full breakout width —
   Board|List · search · assignee · ＋ New job. Phone wraps to two
   compact rows (controls row, then the search row), never a form stack. */
.board-head{width:min(1680px,calc(100vw - 32px));position:relative;left:50%;transform:translateX(-50%);margin-bottom:10px}
.board-bar{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.board-bar .seg{margin:0;flex:0 0 auto}
.board-bar .board-tools{display:flex;gap:10px;align-items:center;flex:1 1 auto;margin:0;flex-wrap:nowrap}
.board-bar .board-tools input[type="search"]{flex:1 1 200px;min-width:130px;min-height:48px}
.board-bar .board-tools select{min-height:48px;flex:0 1 auto}
.board-bar .board-new{margin-left:0;flex:0 0 auto}
.board-hint{margin:6px 0 0;font-size:13px}
@media (max-width:760px){
  .board-head{width:100%;left:0;transform:none}
  .board-bar{row-gap:8px}
  .board-bar .board-tools{order:3;flex:1 1 100%;flex-wrap:wrap}
  .board-bar .board-tools input[type="search"]{flex:1 1 160px}
  .board-bar .board-new{margin-left:auto}
}
/* F4: no-photo hero is a compact designed band, not an empty gray slab —
   the status identity rides in the band; the address headline below does
   the rest of the work. */
.job-hero-photo--empty{height:88px;display:flex;align-items:center;gap:12px;padding:0 18px;background:linear-gradient(135deg,#f5f5f7 0%,#e8edf4 100%)}
.job-hero-photo--empty .job-hero-ph{position:static;font-size:30px}
.job-hero-nophoto{color:var(--muted);font-size:14px;font-weight:600}
.job-hero-photo--empty .job-hero-status{position:static;margin-left:auto}
@media (max-width:760px){.job-hero-photo--empty{height:76px}}
/* F6: status pill-menu (JS-enhanced; the plain form is the fallback). */
.status-pillui{display:flex;align-items:center;gap:10px}
.status-pillui[hidden]{display:none}
.status-pillui-label{font-weight:600;font-size:14px;color:var(--muted)}
.status-pillwrap{position:relative;display:inline-flex}
.status-pill{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:6px 16px;border-radius:999px;border:1px solid var(--line);font:inherit;font-size:15px;font-weight:700;cursor:pointer}
.status-menu{position:absolute;top:calc(100% + 6px);left:0;min-width:230px;background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:0 8px 28px rgba(0,0,0,.14);z-index:30;padding:6px}
.status-menu[hidden]{display:none}
.status-menu-item{display:flex;align-items:center;width:100%;min-height:44px;padding:0 12px;background:none;border:0;border-radius:8px;font:inherit;font-size:15px;font-weight:600;color:var(--ink);cursor:pointer;text-align:left}
.status-menu-item:hover{background:var(--bg)}
.status-menu-item.is-current{color:var(--muted)}
/* F7: phone bottom bar carries only the short button form of the next
   step; a spacer keeps page-end content clear of the fixed bars. */
.job-bottom-spacer{display:none}
@media (max-width:760px){.job-bottom-spacer{display:block;height:84px}}
/* fix1b: the status menu must escape the hero — the hero's overflow:hidden
   (kept for the photo's rounded corners in Batch 2) clipped the open menu.
   Corners move onto the photo band itself; the hero no longer clips. */
.job-hero{overflow:visible}
.job-hero-photo{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}
/* fix1b: board row balance — search gets the width, assignee stays compact. */
.board-bar .board-tools input[type="search"]{flex:2 1 280px}
.board-bar .board-tools select{flex:1 1 170px;max-width:260px}

/* --- Batch 2 mop-up (Nov 8, 2026): M1/M2/M4/M6 phone-chrome items --- */
/* M6: the board hint leads with the affordance the device actually has —
   the per-card "Move to…" menu on touch/phone, drag wording on desktop. */
.board-hint .hint-touch{display:none}
@media (max-width:760px){
  .board-hint .hint-touch{display:inline}
  .board-hint .hint-drag{display:none}
  /* M1: board phone header is exactly TWO compact rows (bar ≈98px at
     390px). Row 1: Jobs + Board|List segmented + ＋ New job, compacted so
     all three fit one line. Row 2: the tools form on its own full-width
     line, its three controls sharing the row without wrapping. Desktop's
     one-row header above is untouched. */
  .board-bar{row-gap:8px}
  .board-bar h1{font-size:24px}
  .board-bar .seg a{min-height:36px;padding:0 12px;font-size:14px}
  .board-bar .board-new{margin-left:auto;min-height:44px;padding:8px 14px;font-size:15px;white-space:nowrap}
  .board-bar .board-tools{order:3;flex:1 1 100%;flex-wrap:nowrap;gap:6px}
  .board-bar .board-tools input[type="search"]{flex:1 1 0;min-width:0;min-height:44px;padding:10px 12px}
  .board-bar .board-tools select{flex:0 1 104px;min-width:0;min-height:44px;padding:10px 8px}
  .board-bar .board-tools .btn{min-height:44px;padding:8px 12px;font-size:14px;white-space:nowrap}
  /* M2: jobs LIST phone search — the input gets its own full-width row so
     its placeholder reads in full; Search / Clear / Find references share
     the row beneath. Scoped to the list's form (other .searchrow users
     unchanged); desktop unchanged. */
  .jobs-search{flex-wrap:wrap}
  .jobs-search input{flex:1 1 100%}
  /* M4: phone bottom action bar clearance — spacer grows 84px → 100px, and
     pages carrying the job bottom bar get the extra trailing body padding
     that actually lifts the footer clear of the fixed bar stack at scroll
     end (the spacer sits before the footer, so on its own it cannot move
     the footer; measured: footer bottom ends ~15px above the bar top). */
  .job-bottom-spacer{height:100px}
  body:has(.job-bottombar){padding-bottom:148px}
}

/* --- Batch 3 (Nov 8, 2026): Estimates list + Estimate builder --- */
.est-head{display:flex;gap:14px;align-items:flex-start;justify-content:space-between;flex-wrap:wrap}
.est-head h1{margin-bottom:4px}
.est-newbtn{flex:0 0 auto;margin-top:6px}
.est-step-label{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);margin:0 0 6px}
.est-step-head{font-size:13px;margin:22px 0 8px;color:var(--ink)}
.est-row{cursor:pointer}
.est-title{color:var(--ink);text-decoration:none;font-weight:600}
.est-title:hover{text-decoration:underline}
.est-total{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap;padding:0 6px}
.est-kebab{position:relative;display:inline-block}
.est-kebab>summary{list-style:none;cursor:pointer;min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;font-size:19px;font-weight:700;color:var(--muted);border-radius:10px}
.est-kebab>summary::-webkit-details-marker{display:none}
.est-kebab>summary:hover{background:var(--bg);color:var(--ink)}
.est-kebab-menu{position:absolute;right:0;top:calc(100% + 4px);min-width:190px;background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:0 8px 28px rgba(0,0,0,.14);z-index:40;padding:6px}
.est-kebab-menu a{display:flex;align-items:center;min-height:44px;padding:0 12px;border-radius:8px;color:var(--ink);text-decoration:none;font-weight:600;font-size:14.5px}
.est-kebab-menu a:hover{background:var(--bg)}
.est-kebab-danger{display:flex;align-items:center;width:100%;min-height:44px;padding:0 12px;background:none;border:0;border-radius:8px;font:inherit;font-weight:600;font-size:14.5px;color:var(--danger);cursor:pointer;text-align:left}
.est-kebab-danger:hover{background:#fdecea}
.est-client-results{display:flex;flex-direction:column;gap:6px;margin-top:8px}
.est-client-hit{display:flex;align-items:center;min-height:44px;padding:8px 12px;background:#fff;border:1px solid var(--line);border-radius:10px;font:inherit;font-size:14.5px;font-weight:600;color:var(--ink);cursor:pointer;text-align:left}
.est-client-hit:hover{background:var(--bg)}
.est-client-none{color:var(--muted)}
.est-life{display:flex;gap:12px;align-items:center;flex-wrap:wrap;background:#fff;border:1px solid var(--line);border-radius:16px;padding:12px 16px;margin-bottom:14px}
.est-life-total{font-size:19px;font-weight:700;font-variant-numeric:tabular-nums}
.est-life-actions{margin-left:auto;display:inline-flex;gap:8px;align-items:center;flex-wrap:wrap}
.est-context{margin-bottom:14px}
.b3details>summary{cursor:pointer;font-weight:600;min-height:44px;display:flex;align-items:center;color:var(--ink)}
@media (max-width:760px){
  .est-life-actions{margin-left:0}
  .est-total{padding:0}
}
#clientSearch{width:100%;box-sizing:border-box}

/* --- Batch 3 fix1 (Nov 8, 2026): D1/F-1..F-7, P-1..P-6 --- */
/* The hidden attribute must win over .btn's inline-flex (F-1 toggle). */
[hidden]{display:none!important}
/* P-1: action-needed pill (Signed · picks pending) reads amber. */
.pill-amber{background:#fdf3e0;color:#9a6a00}
/* Dark filled secondary (strip Save, signing-link actions) — filled but
   NOT the orange primary (F-5: one orange per screen state). */
.btn-dark{background:#1d1d1f;color:#fff;border:1px solid #1d1d1f}
.btn-dark:hover{background:#000}
/* P-2: the create flow's customer search is a standard platform input. */
input[type=search]{font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text",Inter,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
#clientSearch{width:100%;min-height:48px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;font-size:16px;background:#fff;color:var(--ink)}
#clientSearch:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 3px rgba(255,107,53,.16)}
/* F-2: status filter chips on the estimates list. */
.est-filterchips{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 14px}
.est-chip{display:inline-flex;align-items:center;min-height:44px;padding:8px 16px;border:1px solid var(--line);border-radius:999px;background:#fff;color:var(--ink);text-decoration:none;font-weight:600;font-size:14.5px}
.est-chip.on{background:#1d1d1f;color:#fff;border-color:#1d1d1f}
/* F-7: signed banner + lifecycle actions never strand a half-empty row. */
.signed-banner{background:#e6f6ef;border:1px solid #bfe6d4;color:#0d6e4f;border-radius:16px;padding:14px 18px;font-weight:700;margin-bottom:14px}
.est-life-actions{flex-wrap:nowrap}
.est-life .item-sub{min-width:0;flex:1 1 auto}
.est-life-actions .btn{white-space:nowrap}
@media (min-width:761px){.est-life{flex-wrap:nowrap}}
.signed-lock input,.signed-lock select,.signed-lock textarea{background:#f5f5f7!important;color:#6e6e73}
/* P-3: disclosure pill inside a <summary>. */
.b3-pill{margin-left:auto;min-height:44px;display:inline-flex;align-items:center;padding:0 14px;border:1px solid var(--line);background:#fff;border-radius:10px;font-weight:600;font-size:14px;color:var(--muted)}
.b3details>summary{display:flex;align-items:center;gap:10px}
/* D1/F-3/F-6: slim money strip — fixed, outside the form, one line:
   Contract total · Margin % · action. White card language, never the
   full profit card; the in-flow profit card under Line items carries
   the detail. A spacer keeps page-end content clear of it. */
.money-strip{position:fixed;left:50%;transform:translateX(-50%);bottom:12px;width:min(960px,calc(100vw - 24px));z-index:55;background:#fff;border:1px solid var(--line);border-radius:14px;box-shadow:0 6px 24px rgba(0,0,0,.12);padding:8px 14px;display:flex;gap:10px 18px;align-items:center;flex-wrap:wrap}
.money-strip .ms-k{font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.money-strip .ms-v{font-size:17px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.money-strip .ms-sub{font-size:12.5px;color:var(--muted);white-space:nowrap}
.money-strip .btn{margin-left:auto;flex:0 0 auto}
.money-strip-spacer{height:76px}
@media (max-width:760px){
  .est-life-actions{flex-wrap:wrap;margin-left:0}
  .money-strip{bottom:76px;padding:8px 12px;gap:6px 12px}
  .money-strip .ms-sub{flex:1 1 100%;order:3;white-space:normal}
  .money-strip-spacer{height:118px}
  /* F-2: compact phone header — subtitle hidden, slimmer search card,
     so at least 3 estimate rows show in the first phone screen. */
  .est-head .sub{display:none}
  .est-head h1{font-size:24px;margin:0}
  .est-head{margin-bottom:8px}
  .est-newbtn{margin-top:0;min-height:44px;padding:8px 14px;font-size:15px}
  .est-searchcard{padding:12px 14px;margin-bottom:10px}
  .est-searchcard label{display:none}
  .est-filterchips{margin-bottom:10px;flex-wrap:nowrap;overflow-x:auto;padding-bottom:2px}
  .est-chip{min-height:40px;padding:6px 13px;white-space:nowrap}
  /* F-2 (cont.): search on one line; rows compact — the kebab rides the
     row's top-right instead of taking its own line, so >=3 rows fit the
     first phone screen. */
  .est-searchcard form{flex-wrap:nowrap!important}
  .est-searchcard form>div{min-width:0!important}
  .est-list li{padding:10px 2px}
  .est-list .item-sub{font-size:13px}
  .est-row{position:relative}
  .est-row>div{padding-right:44px}
  .est-row .est-kebab{position:absolute;top:4px;right:0}
  .est-row .est-total{padding-right:48px}
}

/* Design overhaul Batch 4 — Production (§A19, Nov 8, 2026).
   Presentation only: quiet row-open chevrons replace per-row orange
   buttons; the Mail intake entry in the Production header carries its
   waiting count as a badge; the calendar's day view (Pattern 31) is a
   list grouped by day with crew chips and a Today pill. One orange
   primary per screen state: Production list + calendar day view =
   "Build a crew day"; calendar month view = "Save schedule". */
.row-open{display:inline-flex;align-items:center;min-height:44px;padding:6px 4px;font-weight:600;font-size:15px;color:var(--accent-dark);text-decoration:none;white-space:nowrap}
.row-open:hover{text-decoration:underline}
.prod-head-actions{display:flex;align-items:center;gap:10px 22px;flex-wrap:wrap;margin:0 0 16px}
.prod-mail-link{display:inline-flex;align-items:center;gap:8px;min-height:44px;font-weight:600;font-size:15px;color:var(--ink);text-decoration:none}
.prod-mail-link:hover{text-decoration:underline}
.mail-badge{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:24px;padding:0 7px;border-radius:999px;background:var(--accent);color:#fff;font-size:13px;font-weight:700;line-height:1}
.cal-viewseg{margin-top:0}
.cal-day-head{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap}
.cal-day-nav{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}
.cal-today-pill{display:inline-flex;align-items:center;min-height:44px;padding:0 14px;font-size:14px}
.day-group{margin-top:18px}
.day-group-head{font-size:16px;font-weight:600;margin:0 0 2px;letter-spacing:-0.01em}
.day-empty{color:var(--muted);font-size:14.5px;margin:4px 0 0;padding:6px 4px}
.crew-chip{display:inline-block;padding:2px 10px;border-radius:999px;background:#e8f0e9;color:#205c2e;font-size:12.5px;font-weight:700;vertical-align:1px;margin-left:6px;white-space:nowrap}

/* Design overhaul Batch 6 — Reviews (§A20, Nov 8, 2026).
   Presentation only: needs-attention good news collapses to a one-line
   confirmation; per-person scorecard cards lead and the 10-column table
   moves behind a Details disclosure (formula footnotes travel with it);
   the window switch becomes dark chips, so the page's one orange
   primary is the header's log-an-observed-review action and the
   settings page's one orange is Save review requests. */
.rev-head{display:flex;gap:14px;align-items:flex-start;justify-content:space-between;flex-wrap:wrap}
.rev-head .sub{margin-bottom:0}
.rev-head .btn{flex:0 0 auto;margin-top:6px}
.rev-ok{display:flex;gap:10px;align-items:center;background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:14px 18px;margin:0 0 16px;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.rev-ok-check{color:var(--ok);font-weight:700;font-size:18px;line-height:1}
.rev-ok-sub{color:var(--muted)}
.rev-wins{display:flex;gap:8px;flex-wrap:wrap}
.rev-win{display:inline-flex;align-items:center;min-height:44px;padding:8px 16px;border:1px solid var(--line);border-radius:999px;background:#fff;color:var(--ink);text-decoration:none;font-weight:600;font-size:14.5px}
.rev-win.on{background:#1d1d1f;color:#fff;border-color:#1d1d1f}
.rev-pcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:14px;margin:0 0 6px}
.rev-pcard{border:1px solid var(--line);border-radius:14px;padding:16px 18px;background:#fff}
.rev-pcard-name{font-weight:700;font-size:16px;margin-bottom:2px}
.rev-pcard-big{font-size:36px;font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums}
.rev-pcard-cap{color:var(--muted);font-size:13.5px;margin-bottom:8px}
.rev-pcard-rate{font-weight:600;font-size:14.5px}
.rev-pcard-trend{font-size:13.5px;font-weight:600;margin-top:2px}
.trend-up{color:var(--ok)} .trend-down{color:var(--danger)} .trend-flat{color:var(--muted)}
.rev-details{margin-top:10px;border-top:1px solid #f0f0f2;padding-top:6px}
@media (max-width:760px){.rev-head .btn{margin-top:0}}

/* Design overhaul Batch 6 fix round — F-2 (Nov 8, 2026): the Details
   scorecard is the FULL table on phone too. The legacy phone restack
   (fix round 2/3, above) turned .scorecard-table into per-rep blocks
   and hid five columns via .sc-phone-hide, so the "Details — the full
   scorecard" label was false at phone width. Inside the Details
   disclosure only, the table now stays a table at every width and
   its wrapper scrolls sideways on phone — all ten columns, same
   content as desktop. Desktop rendering is untouched (the overrides
   live inside the phone media query; the swipe hint is phone-only). */
.rev-dhint{display:none}
@media (max-width:760px){
.rev-dhint{display:block}
.rev-details .scorecard-wrap{overflow-x:auto!important;-webkit-overflow-scrolling:touch}
.rev-details .scorecard-table{display:table;min-width:640px;width:100%!important;border-collapse:collapse}
.rev-details .scorecard-table thead{display:table-header-group}
.rev-details .scorecard-table tbody{display:table-row-group}
.rev-details .scorecard-table tr{display:table-row;position:static;padding:0;border-bottom:0}
.rev-details .scorecard-table th,.rev-details .scorecard-table td{display:table-cell!important}
.rev-details .scorecard-table td{border-bottom:1px solid #f0f0f2!important}
.rev-details .sc-name{padding:8px 6px!important;text-align:left!important}
.rev-details .sc-score{position:static;font-size:inherit;padding:8px 6px!important;text-align:right!important}
.rev-details .sc-stat{padding:8px 6px!important;text-align:right!important;color:inherit;font-size:inherit}
.rev-details .sc-score::before,.rev-details .sc-stat::before{content:none}
}
