/* ============================================================
   Traveler — visual identity for a modular / tiny-home builder.
   Concept: the drafting table & cut list. Birch plywood warmth,
   architect's-ink navy, saw-blade orange, kraft paper. Hairline
   rules and stamped labels evoke a materials takeoff sheet.
   ============================================================ */
:root{
  --paper:#F5F1E8; --paper-2:#EFE9DA; --card:#FFFDF8;
  --ink:#1F2A33; --ink-soft:#4A5761; --ink-faint:#8A949B;
  --line:#D8CFBC; --line-strong:#BFB49B;
  --saw:#D5622A; --saw-deep:#B44E1E;
  --pine:#5C7A52; --clay:#C0492E; --amber:#C8891F; --timber:#8A6A45;
  --shipped:#3E6C8C;
  --bg:var(--paper); --surface:var(--card); --surface-2:var(--paper-2);
  --surface-3:#E7DFCD; --text:var(--ink); --text-muted:var(--ink-soft);
  --text-dim:var(--ink-faint); --teal:var(--pine); --rust:var(--clay);
  --radius:5px;
  --display:'Archivo',sans-serif; --body:'Inter',sans-serif; --mono:'Spline Sans Mono','IBM Plex Mono',monospace;
}
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--bg);
  background-image:linear-gradient(rgba(31,42,51,.035) 1px,transparent 1px),linear-gradient(90deg,rgba(31,42,51,.035) 1px,transparent 1px);
  background-size:22px 22px;
  color:var(--text);font-family:var(--body);-webkit-font-smoothing:antialiased;min-height:100vh}
button{font-family:inherit;cursor:pointer}
input,select,textarea{font-family:inherit}
::selection{background:var(--saw);color:#fff}
::-webkit-scrollbar{height:11px;width:11px}::-webkit-scrollbar-track{background:var(--surface-2)}
::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:6px;border:2px solid var(--surface-2)}
h1,h2,h3{margin:0}
:focus-visible{outline:2px solid var(--saw);outline-offset:2px}

header{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:24px;flex-wrap:wrap;
  padding:14px 26px;background:rgba(245,241,232,.94);backdrop-filter:blur(8px);border-bottom:2px solid var(--ink)}
.brand{display:flex;align-items:baseline;gap:11px}
.brand h1{font-family:var(--display);font-weight:800;font-size:25px;letter-spacing:.02em;text-transform:uppercase}
.brand .sub{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;color:var(--saw);text-transform:uppercase;font-weight:500}
.header-stats{display:flex;gap:6px;margin-left:auto}
.hstat{display:flex;flex-direction:column;align-items:center;min-width:58px;padding:4px 10px;border:1px solid var(--line);border-radius:var(--radius);background:var(--card)}
.hstat .n{font-family:var(--display);font-size:21px;font-weight:700;line-height:1.1}
.hstat .l{font-family:var(--mono);font-size:8.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--text-muted);margin-top:2px;white-space:nowrap}
.hstat.warn{border-color:var(--amber)} .hstat.warn .n{color:var(--amber)}
.hstat.bad{border-color:var(--clay)} .hstat.bad .n{color:var(--clay)}
.header-actions{display:flex;gap:10px}

.btn{font-family:var(--display);font-weight:600;font-size:12.5px;letter-spacing:.02em;text-transform:uppercase;
  border:1.5px solid var(--ink);background:var(--card);color:var(--ink);padding:9px 15px;border-radius:var(--radius);transition:transform .08s,background .15s,color .15s}
.btn:hover{background:var(--ink);color:var(--paper)} .btn:active{transform:translateY(1px)}
.btn.primary{background:var(--saw);border-color:var(--saw);color:#fff}
.btn.primary:hover{background:var(--saw-deep);border-color:var(--saw-deep)}
.btn.sm{padding:6px 11px;font-size:11px} .btn.danger{border-color:var(--clay);color:var(--clay)}.btn.danger:hover{background:var(--clay);color:#fff}
.btn:disabled{opacity:.4;cursor:not-allowed}
.ghost{background:none;border:none;color:var(--text-muted);font-size:17px;line-height:1} .ghost:hover{color:var(--saw)}

.tabbar{display:flex;gap:0;padding:0 26px;border-bottom:1px solid var(--line);background:var(--surface)}
.tab{font-family:var(--display);font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;background:none;border:none;color:var(--text-muted);padding:14px 18px;border-bottom:3px solid transparent;margin-bottom:-1px}
.tab.active{color:var(--ink);border-bottom-color:var(--saw)} .tab:hover{color:var(--ink)}

.filterbar{display:flex;gap:10px;padding:13px 26px;border-bottom:1px solid var(--line);background:var(--surface)}
.search{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:8px 11px;font-size:13px;min-width:250px}
.search:focus{border-color:var(--saw);outline:none}
#lineFilter{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:8px 10px;font-size:13px}

main{padding:22px 26px 64px}
.view{display:none} .view.active{display:block}
.empty{padding:44px;text-align:center;color:var(--text-muted);font-family:var(--mono);font-size:13px;border:1.5px dashed var(--line-strong);border-radius:var(--radius);background:var(--card)}
.count-pill{font-family:var(--mono);font-size:11px;color:var(--saw);background:rgba(213,98,42,.1);padding:1px 8px;border-radius:10px;margin-left:6px;font-weight:500}
.td-sub{display:block;font-family:var(--mono);font-size:10.5px;color:var(--text-dim)}

.dash-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.panel{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:20px;position:relative}
.panel::before{content:'';position:absolute;left:0;right:0;top:0;height:4px;background:var(--ink);border-radius:var(--radius) var(--radius) 0 0}
.panel.span-2{grid-column:1/-1}
.panel h2{font-family:var(--display);font-size:15px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;display:flex;align-items:center}
.panel-sub{font-size:12px;color:var(--text-muted);line-height:1.55;margin:7px 0 16px}
.risk-bars{display:flex;flex-direction:column;gap:9px}
.forecast-detail-head{margin:18px 0 8px;font-family:var(--display);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--ink);border-top:1px solid var(--line);padding-top:14px}
.forecast-detail-note{margin-top:16px;font-family:var(--mono);font-size:11.5px;color:var(--text-dim);border-top:1px solid var(--line);padding-top:14px}
.attention-list{display:flex;flex-direction:column;gap:9px}
.attention-row{border:1px solid var(--line);border-left:3px solid var(--clay);border-radius:var(--radius);padding:9px 12px;cursor:pointer;background:var(--surface-2)}
.attention-row:hover{border-color:var(--saw);border-left-color:var(--saw)}
.att-main{display:flex;justify-content:space-between;align-items:center;gap:8px}
.att-name{font-weight:600;font-size:13px}
.att-meta{font-family:var(--mono);font-size:10px;color:var(--text-dim);margin-top:4px}
.risk-bar-row{display:flex;align-items:center;gap:11px}
.rb-label{font-family:var(--mono);font-size:11px;width:74px;text-transform:uppercase}
.rb-track{flex:1;height:9px;background:var(--surface-3);border-radius:5px;overflow:hidden}
.rb-fill{height:100%;border-radius:5px} .rb-count{font-family:var(--mono);font-size:12px;width:24px;text-align:right;font-weight:500}
.cap-list{display:flex;flex-direction:column;gap:13px}
.cap-row{padding:12px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2)}
.cap-row.over{border-color:var(--clay);background:rgba(192,73,46,.05)}
.cap-head{display:flex;justify-content:space-between;align-items:baseline}
.cap-name{font-family:var(--display);font-size:13px;font-weight:600;text-transform:uppercase;letter-spacing:.03em}
.cap-meta{font-family:var(--mono);font-size:10.5px;color:var(--text-dim)}
.cap-track{display:flex;gap:5px;margin-top:9px}
.cap-slot{width:28px;height:9px;border-radius:2px;background:var(--surface-3);border:1px solid var(--line)}
.cap-slot.full{background:var(--pine);border-color:var(--pine)} .cap-slot.over{background:var(--clay);border-color:var(--clay)}
.cap-warn{margin-top:9px;font-family:var(--mono);font-size:10.5px;color:var(--clay)}

.data-table{width:100%;border-collapse:collapse}
.data-table th{text-align:left;font-family:var(--mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;color:var(--text-muted);border-bottom:1.5px solid var(--ink);padding:9px 12px}
.data-table td{padding:12px;border-bottom:1px solid var(--line);font-size:13px}
.data-table tr[data-open]{cursor:pointer} .data-table tr[data-open]:hover td{background:var(--surface-2)}
.td-name{font-weight:600;cursor:pointer} .td-name:hover{color:var(--saw)}
.badge{color:#fff;font-family:var(--mono);font-size:9.5px;padding:2px 8px;border-radius:3px;text-transform:uppercase;letter-spacing:.04em;font-weight:500}
.suggest{color:var(--pine);font-weight:600}
.status-pill{display:inline-block;font-family:var(--mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.04em;border:1px solid;border-radius:20px;padding:2px 9px;font-weight:600}

.g-legend{display:flex;gap:18px;margin-bottom:13px;flex-wrap:wrap}
/* Duplicate control in the build panel footer. Sits with the destructive action but
   reads as neutral, and keeps its count input adjacent so the number is obviously
   attached to the button. */
.dup-group{display:inline-flex;align-items:center;gap:8px;margin-left:auto}
.dup-group label{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:8.5px;
  text-transform:uppercase;letter-spacing:.03em;color:var(--text-dim)}
.dup-group input{width:52px;text-align:center;background:var(--card);border:1px solid var(--line-strong);
  border-radius:var(--radius);padding:5px 6px;font-family:var(--mono);font-size:12px}

/* Sheet-size picker next to Print. Same shape as the view-mode toggle. */
.print-pick{display:inline-flex;border:1px solid var(--line-strong);border-radius:var(--radius);overflow:hidden}
.print-pick-btn{background:var(--card);border:0;padding:5px 10px;font-family:var(--mono);font-size:8.5px;
  text-transform:uppercase;letter-spacing:.04em;font-weight:700;color:var(--text-muted);cursor:pointer}
.print-pick-btn + .print-pick-btn{border-left:1px solid var(--line-strong)}
.print-pick-btn:hover{background:var(--surface-2)}
.print-pick-btn.active{background:var(--saw);color:#fff}

/* Gantt view mode toggle: Plan (duration forecast) vs Line simulation. */
.g-mode{display:inline-flex;border:1px solid var(--line-strong);border-radius:var(--radius);overflow:hidden;margin-left:auto}
.g-mode-btn{background:var(--card);border:0;padding:5px 11px;font-family:var(--mono);font-size:8.5px;
  text-transform:uppercase;letter-spacing:.04em;font-weight:700;color:var(--text-muted);cursor:pointer}
.g-mode-btn + .g-mode-btn{border-left:1px solid var(--line-strong)}
.g-mode-btn:hover{background:var(--surface-2)}
.g-mode-btn.active{background:var(--timber);color:#fff}

/* The planned dates, drawn as a thin baseline strip UNDER the simulated bar rather
   than behind it. Behind was the first attempt and it is invisible: same height, an
   opaque bar on top, and the simulation almost always runs longer than the plan — so
   the ghost was completely hidden in exactly the case it exists to show. A baseline
   below the bar is the standard convention and makes plan-vs-actual a direct
   left-to-right length comparison. */
.g-bar-ghost{position:absolute;top:calc((var(--g-row-h) + var(--g-bar-h)) / 2 + 3px);height:4px;
  border:1px dashed var(--line-strong);border-radius:2px;background:transparent;pointer-events:none;z-index:0}
.g-legend .lg i.ghost{border:1px dashed var(--line-strong);background:transparent;height:4px}
.g-legend .lg i.blk{background:var(--clay);border-radius:50%;width:8px;height:8px}

/* A pulse where this build was held: behind a slower build, or queued for the booth.
   Sits clear ABOVE the bar — centred on it, these markers landed on top of the build
   name and were unreadable. */
.g-block{position:absolute;top:calc((var(--g-row-h) - var(--g-bar-h)) / 2 - 9px);width:7px;height:7px;
  border-radius:50%;background:var(--amber);border:1px solid var(--card);z-index:3;pointer-events:auto}
.g-block.booth{background:var(--clay)}

/* Mode explanation strip. */
.g-note{margin:0 0 10px;padding:8px 12px;border-left:3px solid var(--timber);background:var(--surface-2);
  border-radius:var(--radius);font-size:11.5px;color:var(--text-muted);line-height:1.55}
.g-note.warn{border-left-color:var(--amber);background:color-mix(in srgb,var(--amber) 8%,var(--card))}
.g-note strong{color:var(--ink)}
.g-note-warn{color:var(--clay);font-weight:600}

.g-legend .lg{display:flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10.5px;color:var(--text-muted);text-transform:uppercase}
.g-legend i{width:12px;height:12px;border-radius:2px;display:inline-block}
.g-legend i.tent{border:1.5px dashed var(--text-muted)} .g-legend i.tgt{width:0;height:12px;border-left:2px dashed var(--ink);border-radius:0}
.g-wrap{border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--card);overflow:hidden}
.g-scroll{overflow-x:auto;position:relative}
.g-inner{display:block}
/* ---------------------------------------------------------------------------
   Display scale for the two dense tabs (Gantt, Build Hours).
   --tab-zoom 0.8 reproduces what browser zoom at 80% gives, as a default so the
   whole schedule fits without scrolling. Set it to 1 to go back to full size.

   IMPORTANT: CSS zoom scales every length inside the element, INCLUDING the
   vh-based max-height on the scroll containers. Left alone, the rows get 20%
   shorter and so does the box holding them, so exactly the same number of rows
   would be visible and the zoom would achieve nothing. The scroll containers
   therefore divide their height by --tab-zoom to cancel that out, leaving the
   viewport-filling box the same visual size while the content inside it shrinks.
   --------------------------------------------------------------------------- */
:root{--tab-zoom:0.8;--g-row-h:56px;--g-bar-h:26px}
#ganttRoot,#hoursRoot{zoom:var(--tab-zoom)}

.g-label-sp,.g-label{flex:0 0 234px;width:234px;min-width:234px;max-width:234px;box-sizing:border-box;position:sticky;left:0;z-index:4;background:var(--card);border-right:1.5px solid var(--line-strong)}
.g-head{display:flex;border-bottom:1.5px solid var(--ink)}
.g-label-sp{height:34px;display:flex;align-items:center;padding:0 13px;font-family:var(--mono);font-size:10px;text-transform:uppercase;color:var(--text-dim);z-index:6}
.ticks{position:relative;height:34px}.tick{position:absolute;top:0;bottom:0;border-left:1px solid var(--line)}
.tick span{position:absolute;top:10px;left:5px;font-family:var(--mono);font-size:10px;color:var(--text-dim)}
.g-body{position:relative}
.g-gridlines{position:absolute;top:0;bottom:0;z-index:0;pointer-events:none}
.g-gridline{position:absolute;top:0;bottom:0;width:1px;background:var(--line)}
.g-row{display:flex;border-bottom:1px solid var(--line)}.g-row:last-child{border-bottom:none}
.g-row.group .g-label{background:var(--paper-2);font-family:var(--display);font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--ink);display:flex;align-items:center;padding:0 13px;height:30px}
.g-row.group .g-track{background:var(--paper-2);height:30px}
/* Row height comes from --g-row-h so the label, the track and the bar's vertical
   centring can never drift apart. Raised from 48px to fit two lines of build name;
   every row uses it, so rows stay uniform regardless of name length. */
.g-row:not(.group) .g-label{padding:7px 13px;display:flex;flex-direction:column;justify-content:center;height:var(--g-row-h);cursor:pointer}
.g-row:not(.group) .g-label:hover{background:var(--surface-2)}
/* Build names wrap to two lines instead of being cut off with an ellipsis. The
   clamp is what keeps rows uniform: a longer name wraps, it never grows the row. */
.g-name{font-weight:600;font-size:12px;line-height:1.2;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:break-word;max-width:100%;min-width:0}
.g-meta{font-family:var(--mono);font-size:9.5px;color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;min-width:0}
.g-track{position:relative;flex:0 0 auto;height:var(--g-row-h)}
.g-bar{position:absolute;top:calc((var(--g-row-h) - var(--g-bar-h)) / 2);height:var(--g-bar-h);border-radius:3px;display:flex;align-items:center;padding:0 9px;font-size:11px;font-weight:600;color:#fff;overflow:hidden;white-space:nowrap;cursor:pointer;border:1px solid rgba(0,0,0,.18);box-shadow:0 1px 2px rgba(31,42,51,.12)}
.g-bar.tentative{background:repeating-linear-gradient(45deg,var(--surface-2),var(--surface-2) 5px,var(--paper) 5px,var(--paper) 10px)!important;border:1.5px dashed var(--line-strong);color:var(--text-muted)}
.g-bar:hover{filter:brightness(1.06)}
.g-target{position:absolute;top:4px;bottom:4px;width:0;border-left:2px dashed var(--ink);z-index:3}
.g-target-flag{position:absolute;top:-1px;left:0;width:0;height:0;border-top:5px solid var(--ink);border-right:7px solid transparent;pointer-events:none}
/* Target COMPLETION is a separate checkpoint from target ship: a build leaves the line
   weeks or months before it leaves the yard, so the two need distinguishing at a glance.
   Solid pine for completion, dashed ink for ship. */
.g-target-complete{border-left:2px solid var(--pine);border-left-style:solid}
.g-target-complete .g-target-flag{border-top-color:var(--pine)}
.g-legend .lg i.tgt-complete{width:0;height:0;border-left:2px solid var(--pine);height:11px}
.g-nodate{position:absolute;top:50%;left:11px;transform:translateY(-50%);font-family:var(--mono);font-size:11px;color:var(--text-dim);border:1px dashed var(--line-strong);border-radius:3px;padding:4px 10px;cursor:pointer}
.g-nodate:hover{color:var(--saw);border-color:var(--saw)}
.today{position:absolute;top:0;bottom:0;width:2px;background:var(--saw);z-index:3}
.today span{position:absolute;top:-1px;left:4px;background:var(--saw);color:#fff;font-family:var(--mono);font-size:9px;padding:2px 6px;border-radius:2px;text-transform:uppercase;letter-spacing:.04em;z-index:3}

.board{display:flex;gap:16px;align-items:flex-start;overflow-x:auto}
.b-col{flex:0 0 306px;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);display:flex;flex-direction:column}
.b-col-head{display:flex;justify-content:space-between;padding:12px 13px;border-bottom:1.5px solid var(--ink);font-family:var(--display);font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;flex:0 0 auto}
.b-zone{padding:11px;display:flex;flex-direction:column;gap:11px;min-height:80px;max-height:560px;overflow-y:auto;flex:1 1 auto}
.b-card{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:12px;cursor:grab;box-shadow:0 1px 2px rgba(31,42,51,.06)}
.b-card:hover{border-color:var(--saw)} .b-card:active{cursor:grabbing}
.b-card-top{display:flex;justify-content:space-between;align-items:center}
.b-id{font-family:var(--mono);font-size:9.5px;color:var(--text-dim);letter-spacing:.03em}
.b-name{font-family:var(--display);font-weight:600;font-size:13.5px;margin:7px 0 2px;line-height:1.25}
.b-client{font-size:11.5px;color:var(--text-muted)}
.b-meta{display:flex;justify-content:space-between;margin-top:9px;font-family:var(--mono);font-size:10px;color:var(--text-dim)}
.b-empty{color:var(--text-dim);font-family:var(--mono);font-size:12px;text-align:center;padding:16px}

/* ---------- reports / analytics ---------- */
.rep-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:18px;flex-wrap:wrap}
.rep-title{font-family:var(--display);font-size:19px;font-weight:800;text-transform:uppercase;letter-spacing:.03em}
.kpi-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:18px}
.kpi{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:15px 16px;display:flex;flex-direction:column;gap:3px;position:relative;overflow:hidden}
.kpi::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--line-strong)}
.kpi.good::before{background:var(--pine)} .kpi.warn::before{background:var(--amber)} .kpi.bad::before{background:var(--clay)}
.kpi-label{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted)}
.kpi-value{font-family:var(--display);font-size:28px;font-weight:700;line-height:1.1}
.kpi.good .kpi-value{color:var(--pine)} .kpi.warn .kpi-value{color:var(--amber)} .kpi.bad .kpi-value{color:var(--clay)}
.kpi-sub{font-family:var(--mono);font-size:10px;color:var(--text-dim)}
.trend{font-family:var(--mono);font-size:11px;margin-left:auto;text-transform:uppercase;letter-spacing:.04em;color:var(--text-dim)}
.trend.good{color:var(--pine)} .trend.bad{color:var(--clay)}
.throughput-controls{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:6px;flex-wrap:wrap}
.tp-year-label{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);display:flex;align-items:center;gap:7px}
.tp-year-label select{min-width:88px}
.tp-year-total{font-family:var(--mono);font-size:11px;color:var(--saw);font-weight:600}
.bar-chart{display:flex;align-items:flex-end;gap:5px;height:160px;padding-top:10px}
.bc-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;justify-content:flex-end;gap:4px}
.bc-count{font-family:var(--mono);font-size:9.5px;color:var(--text-muted);font-weight:600;min-height:12px}
.bc-bar{width:72%;min-height:2px;background:var(--saw);border-radius:2px 2px 0 0;transition:height .3s}
.bc-x{font-family:var(--mono);font-size:8.5px;color:var(--text-dim)}
.util-list{display:flex;flex-direction:column;gap:12px}
.util-row{display:flex;flex-direction:column;gap:5px}
.util-head{display:flex;justify-content:space-between;font-size:12.5px}
.util-head span:first-child{font-family:var(--display);font-weight:600;text-transform:uppercase;font-size:12px;letter-spacing:.03em}
.util-state{font-family:var(--mono);font-size:10.5px}
.util-state.constrained{color:var(--clay)} .util-state.balanced{color:var(--pine)} .util-state.underused{color:var(--text-dim)}
.util-track{height:10px;background:var(--surface-3);border-radius:5px;overflow:hidden}
.util-fill{height:100%;border-radius:5px}
.util-fill.constrained{background:var(--clay)} .util-fill.balanced{background:var(--pine)} .util-fill.underused{background:var(--line-strong)}
.mini-bar-wrap{display:inline-block;width:70px;height:7px;background:var(--surface-3);border-radius:4px;overflow:hidden;margin-right:8px;vertical-align:middle}
.mini-bar{height:100%;background:var(--timber);border-radius:4px}
.ratio-good{color:var(--pine);font-weight:600} .ratio-warn{color:var(--amber);font-weight:600} .ratio-bad{color:var(--clay);font-weight:600}
.rep-note{margin-top:18px;background:var(--surface-2);border:1px solid var(--line-strong);border-left:4px solid var(--saw);border-radius:var(--radius);padding:14px 16px;font-size:12.5px;color:var(--text-muted);line-height:1.55}

.settings-intro{font-size:13px;color:var(--text-muted);max-width:780px;line-height:1.6}
.settings-actions{display:flex;gap:10px;align-items:center;margin:16px 0 20px;flex-wrap:wrap}
.settings-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:18px;align-items:start}
.settings-card{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:18px}
.settings-card h3{font-family:var(--display);font-size:13.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;margin-bottom:13px;display:flex;align-items:center}
.opt-list{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--radius);overflow-y:auto;overflow-x:hidden;margin-bottom:13px;max-height:200px}
.opt-row{display:flex;align-items:center;gap:10px;padding:8px 12px;border-bottom:1px solid var(--line);background:var(--surface-2)}
.opt-row:nth-child(even){background:var(--card)}.opt-row:last-child{border-bottom:none}
.opt-dot{width:11px;height:11px;border-radius:3px;flex:0 0 auto}.opt-num{font-family:var(--mono);font-size:10px;color:var(--text-dim);width:20px}
.opt-label{flex:1;font-size:13px}.opt-usage{font-family:var(--mono);font-size:10px;color:var(--text-dim)}
.rm{background:none;border:none;color:var(--text-dim);font-size:15px;padding:2px 6px;line-height:1}.rm:hover{color:var(--clay)}
.add-row{display:flex;gap:8px;align-items:center}
.add-row>input{flex:1;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:8px 11px;font-size:13px}
.add-row>input:focus{border-color:var(--saw);outline:none}
.add-line-row{display:grid !important;grid-template-columns:minmax(80px,1fr) 52px 52px 0 46px;gap:7px;align-items:end}
.add-line-row .btn{grid-column:5}
.add-line-row .le-name{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:7px 9px;font-size:13px;min-width:0;width:100%}
.add-line-row .le-name:focus{border-color:var(--saw);outline:none}
.add-line-row .btn{white-space:nowrap;padding:7px 10px}
.cap-field{display:flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10px;text-transform:uppercase;color:var(--text-muted);border:1px solid var(--line-strong);border-radius:var(--radius);padding:0 8px 0 10px;background:var(--surface-2)}
.cap-field .cap-input{width:46px;border:none;background:transparent;padding:8px 0;font-size:13px;font-family:var(--body)}
.cap-field .cap-input:focus{outline:none}

.overlay{position:fixed;inset:0;background:rgba(31,42,51,.52);display:none;align-items:flex-start;justify-content:center;padding:40px 20px;overflow-y:auto;z-index:100}
.overlay.open{display:flex}
.modal{background:var(--card);border:1.5px solid var(--ink);border-radius:var(--radius);width:100%;max-width:700px;box-shadow:0 18px 50px rgba(31,42,51,.25)}
.modal-head{display:flex;justify-content:space-between;padding:19px 22px;border-bottom:1.5px solid var(--ink);background:var(--surface-2);border-radius:4px 4px 0 0}
.modal-head h2{font-family:var(--display);font-size:18px;font-weight:700;text-transform:uppercase;letter-spacing:.02em}
.mono-sub{font-family:var(--mono);font-size:11px;color:var(--text-muted);letter-spacing:.02em}
.modal-body{padding:20px 22px;display:flex;flex-direction:column;gap:18px;max-height:76vh;overflow-y:auto}
.modal-foot{padding:15px 22px;border-top:1px solid var(--line);display:flex;justify-content:space-between;background:var(--surface-2);border-radius:0 0 4px 4px}
.forecast-banner{border:1px solid var(--line);border-left-width:4px;border-radius:var(--radius);padding:12px 15px;background:var(--surface-2)}
.forecast-banner>div:first-child{display:flex;align-items:center;gap:11px}
.fb-label{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted)}
.fb-detail{font-size:12px;color:var(--text-muted);margin-top:6px}
.field-grid{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.field{display:flex;flex-direction:column;gap:5px}
.field>span{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted)}
.field input,.field select,.field textarea{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);color:var(--text);padding:8px 11px;font-size:13px}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--saw);outline:none}
.section-head{display:flex;justify-content:space-between;align-items:center;border-top:1.5px solid var(--ink);padding-top:15px;gap:12px}
.section-head h3{font-family:var(--display);font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}
.section-head-actions{display:flex;align-items:center;gap:12px}

.stage-list{display:grid;grid-template-columns:1fr 1fr;grid-auto-rows:min-content;gap:0;border:1px solid var(--line-strong);border-radius:var(--radius);overflow:visible;flex-shrink:0}
/* ---------------------------------------------------------------------------
   Stage progress: a segmented 5% bar plus a typed value, replacing a range slider.
   A slider needs a precise drag to hit a value, is poor on touch, and implies
   continuous precision when the judgement is coarse. Clicking a segment is one
   action, and the number box covers the case where an exact figure is known.
   --------------------------------------------------------------------------- */
.pg{display:inline-flex;align-items:center;gap:6px;min-width:0}
.pg-track{display:inline-flex;gap:1px;align-items:stretch;height:20px;padding:2px;
  background:var(--surface-2);border:1px solid var(--line-strong);border-radius:5px}
.pg-seg{width:7px;padding:0;border:0;border-radius:1px;background:var(--line);cursor:pointer;
  transition:background .12s ease,transform .12s ease}
.pg-seg:hover{background:var(--timber);transform:scaleY(1.15)}
.pg-seg.major{border-radius:0;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 18%,transparent)}
.pg-seg.on{background:var(--pine)}
.pg-seg.on:hover{background:var(--clay)}
.pg-num{width:52px;text-align:right;background:var(--card);border:1px solid var(--line-strong);
  border-radius:var(--radius);padding:3px 5px;font-family:var(--mono);font-size:12px}
.pg-num::-webkit-outer-spin-button,.pg-num::-webkit-inner-spin-button{opacity:1}
.pg-unit{font-family:var(--mono);font-size:10px;color:var(--text-dim)}
@media (max-width:640px){.pg-seg{width:9px}.pg-track{height:24px}}

.stage-row{display:grid;grid-template-columns:20px minmax(0,1fr) 44px 44px 56px 34px;gap:6px;align-items:center;padding:8px 10px;border-bottom:1px solid var(--line);background:var(--surface-2);min-width:0}
.stage-row:nth-child(4n+1),.stage-row:nth-child(4n){background:var(--card)}
.stage-list .stage-row:nth-last-child(-n+2){border-bottom:none}
.st-order{font-family:var(--mono);font-size:10px;color:var(--saw);font-weight:500;min-width:0}
.st-label{font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;cursor:default}
.st-days{background:var(--card);border:1px solid var(--line-strong);border-radius:3px;padding:5px 5px;font-size:12px;width:100%;min-width:0}
.st-hours{background:var(--card);border:1px solid var(--line-strong);border-radius:3px;padding:5px 4px;font-size:12px;width:100%;min-width:0}
.st-range{min-width:0;width:100%;accent-color:var(--saw)}
.st-prog{font-family:var(--mono);font-size:10.5px;color:var(--text-muted);text-align:right;font-weight:500;min-width:0}
.mat-list{display:flex;flex-direction:column;gap:9px}
.mat-row{display:grid;grid-template-columns:1.5fr 1.2fr 1fr 1fr 32px;gap:8px;align-items:center}
.mat-row input,.mat-row select{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:3px;padding:6px 9px;font-size:12px;width:100%}

@media(max-width:820px){
  .dash-grid{grid-template-columns:1fr}.field-grid{grid-template-columns:1fr}
  .header-stats{width:100%;margin:10px 0 0;justify-content:space-between;gap:5px;flex-wrap:wrap}
  .hstat{min-width:0;flex:1}
  .stage-list{grid-template-columns:1fr}
  .stage-row{grid-template-columns:22px 1fr 52px 42px}
  .st-range{display:none}
  main{padding:16px 14px 48px}
  .search{min-width:0;flex:1}
  .filterbar{flex-wrap:wrap}
  /* wide tables scroll inside their panel rather than widening the page */
  .panel{overflow-x:auto}
  .kpi-row{grid-template-columns:1fr 1fr}
  .modal-body{max-height:82vh}
  .field-grid{gap:10px}
  .mat-row{grid-template-columns:1fr 1fr;gap:6px}
}
/* global guard: never let the page scroll sideways; contain wide children */
html,body{max-width:100%;overflow-x:hidden}
.data-table{min-width:0}
.board{max-width:100%}
@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

.field .hint{font-style:normal;text-transform:none;letter-spacing:0;color:var(--text-dim);font-size:9px}

/* build-name full-width field */
.field-wide{grid-column:1/-1}
/* settings: inline line editing + workdays/week */
.card-hint{font-size:11px;color:var(--text-dim);margin:0 0 12px;line-height:1.5}
.line-edit-list{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}
.line-edit-row{display:grid;grid-template-columns:minmax(80px,1fr) 52px 52px 0 46px;gap:7px;align-items:end}
.line-edit-row .le-count{display:none}
.line-edit-row .rm{align-self:center;justify-self:center}
.line-edit-row .le-name{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:7px 9px;font-size:13px;min-width:0;width:100%}
.line-edit-row .le-name:focus{border-color:var(--saw);outline:none}
.line-edit-row .rm{align-self:center}
.le-num{display:flex;flex-direction:column;align-items:stretch;gap:2px;min-width:0}
.le-num>span{font-family:var(--mono);font-size:8px;text-transform:uppercase;letter-spacing:.02em;color:var(--text-dim);text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.le-num input{width:100%;border:1px solid var(--line-strong);background:var(--surface-2);border-radius:var(--radius);padding:7px 2px;font-size:13px;font-family:var(--body);text-align:center;min-width:0}
.le-num input:focus{outline:none;border-color:var(--saw)}
.le-count{display:none}
@media(max-width:820px){

  .line-edit-row .le-count{display:none}
}

/* ---------- mini working-days timeline (dashboard + board) ---------- */
.mini-tl{margin:6px 0 2px}
.mtl-track{position:relative;height:7px;background:var(--surface-3);border-radius:4px;margin-right:9px}
.mtl-bar{position:absolute;left:0;top:0;height:100%;border-radius:4px;min-width:2px}
.mtl-today{position:absolute;top:-3px;width:2px;height:13px;background:var(--ink);border-radius:1px;z-index:2}
.mtl-today::after{content:'';position:absolute;top:-3px;left:-2px;width:6px;height:6px;border-radius:50%;background:var(--ink)}
.mtl-target{position:absolute;right:-9px;top:50%;transform:translateY(-50%);z-index:3}
.mtl-target-flag{display:block;width:0;height:0;border-top:6px solid transparent;border-bottom:6px solid transparent;border-left:9px solid var(--saw);filter:drop-shadow(0 1px 1px rgba(0,0,0,.15))}
.mtl-dates{display:flex;justify-content:space-between;font-family:var(--mono);font-size:8.5px;color:var(--text-dim);margin-top:3px}
.mtl-dates span:nth-child(2){color:var(--text-muted);font-weight:600}
.mtl-target-date{color:var(--saw)!important;font-weight:600}
.td-timeline{min-width:130px}
.td-timeline .mini-tl{margin:0}

/* ---------- bay tracking (dashboard line capacity) ---------- */
.bay-list{display:flex;flex-direction:column;gap:5px;margin-top:8px}
.bay-slot{display:flex;align-items:center;gap:8px;padding:8px 9px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2);font-size:12px;min-height:38px;transition:border-color .12s,background .12s}
.bay-slot.open{opacity:.75}
.bay-slot.filled{border-left:3px solid var(--pine)}
.bay-slot.conflict{border-left:3px solid var(--timber);background:color-mix(in srgb,var(--timber) 8%,var(--surface-2))}
.bay-slot.drop-hover{border-color:var(--saw);border-style:dashed;background:color-mix(in srgb,var(--saw) 10%,var(--surface-2))}
.bay-num{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);min-width:44px;flex:0 0 auto}
.bay-occupant{flex:1;display:flex;flex-wrap:wrap;gap:5px;min-width:0}
.bay-chip{display:inline-block;background:var(--card);border:1px solid var(--line-strong);border-radius:20px;padding:3px 10px;font-size:11.5px;font-weight:600;cursor:grab;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:none}
.bay-chip:hover{border-color:var(--saw)}
.bay-chip:active,.bay-chip.dragging{cursor:grabbing;opacity:.5}
.bay-empty{font-size:11.5px;color:var(--text-dim);font-style:italic}
.bay-flag{font-family:var(--mono);font-size:9px;color:var(--clay);white-space:nowrap;flex:0 0 auto}

/* bay conflict warning in the build modal */
.bay-warning{margin:12px 0 0;padding:10px 13px;border:1px solid var(--clay);border-left:4px solid var(--clay);border-radius:var(--radius);background:color-mix(in srgb,var(--clay) 7%,var(--card));font-size:12.5px;color:var(--clay);line-height:1.5}
/* Sharing a bay is a normal way the floor operates, not an error, so this note is
   informational: same shape as .bay-warning but in neutral ink with no icon. */
.bay-shared{margin:12px 0 0;padding:10px 13px;border:1px solid var(--line-strong);border-left:4px solid var(--timber);border-radius:var(--radius);background:var(--surface-2);font-size:12.5px;color:var(--text-muted);line-height:1.5}

/* ---------------------------------------------------------------------------
   Line Routing card. Spans the full settings grid because it is a matrix, not a
   list: stage assignments on the left, resulting bay load on the right, so an
   imbalance is visible while you are still mapping rather than after.
   --------------------------------------------------------------------------- */
.lr-card{grid-column:1/-1}
.lr-tabs{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:10px}
.lr-tab{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:6px 11px;font-family:var(--mono);font-size:9px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-muted);cursor:pointer;font-weight:700}
.lr-tab:hover{border-color:var(--timber)}
.lr-tab.active{background:var(--timber);border-color:var(--timber);color:#fff}
/* Line-level route stops: where foam happens, and whether the line has a trailer
   pre-station. Sits between the line tabs and the stage table because it frames how
   the rest of the card is read. */
.lr-stops{display:flex;flex-wrap:wrap;align-items:center;gap:10px 18px;margin:0 0 12px;padding:10px 12px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2)}
.lr-stops label{display:inline-flex;align-items:center;gap:7px;font-size:12px;color:var(--text-muted)}
.lr-stops select{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);
  padding:5px 26px 5px 8px;font-size:12px;font-family:var(--body)}
.lr-stop-check input{width:14px;height:14px;margin:0;cursor:pointer}
.lr-stops .lr-note{flex:1 0 100%;margin:2px 0 0}

.lr-warn{margin:0 0 10px;padding:7px 10px;border-left:3px solid var(--amber);background:color-mix(in srgb,var(--amber) 8%,var(--card));font-size:11.5px;color:var(--text-muted);border-radius:var(--radius)}
.lr-split{display:grid;grid-template-columns:minmax(280px,1fr) minmax(320px,1.2fr);gap:16px;align-items:start}
@media (max-width:900px){.lr-split{grid-template-columns:1fr}}

.lr-table-wrap{max-height:420px;overflow-y:auto;border:1px solid var(--line);border-radius:var(--radius)}
.lr-table{width:100%;border-collapse:collapse;font-size:12px}
.lr-table thead th{position:sticky;top:0;background:var(--paper-2);z-index:2;text-align:left;padding:7px 9px;font-family:var(--mono);font-size:8.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-dim);border-bottom:1px solid var(--line-strong)}
.lr-table td{padding:5px 9px;border-bottom:1px solid var(--line);vertical-align:middle}
.lr-table tr:last-child td{border-bottom:none}
.lr-table tr.lr-unassigned{background:color-mix(in srgb,var(--amber) 6%,transparent)}
.lr-stage{font-weight:600;color:var(--ink)}
.lr-bay{width:100%;min-width:0;background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:5px 24px 5px 7px;font-size:12px;font-family:var(--body)}
.lr-bay:focus{border-color:var(--saw);outline:none}
.lr-mr{text-align:center;width:44px}
.lr-mr input{width:14px;height:14px;margin:0;cursor:pointer}

.lr-load{border:1px solid var(--line);border-radius:var(--radius);padding:10px 12px;background:var(--surface-2)}
.lr-load-head,.lr-load-row{display:grid;grid-template-columns:52px 1fr 54px 66px 44px;gap:8px;align-items:center}
.lr-load-head{font-family:var(--mono);font-size:8px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-dim);padding-bottom:6px;border-bottom:1px solid var(--line)}
.lr-load-row{padding:4px 0;font-size:11.5px}
.lr-load-bay{font-weight:600;color:var(--text-muted)}
.lr-load-track{height:9px;background:var(--card);border:1px solid var(--line);border-radius:5px;overflow:hidden}
.lr-load-fill{display:block;height:100%;background:var(--pine)}
.lr-load-row.neck .lr-load-fill{background:var(--clay)}
.lr-load-row.neck .lr-load-bay{color:var(--clay)}
.lr-load-row.starved .lr-load-cap{color:var(--clay);font-weight:700}
.lr-load-num,.lr-load-days{font-family:var(--mono);font-size:10.5px;text-align:right;color:var(--text-muted)}
.lr-load-cap{font-family:var(--mono);font-size:9.5px;color:var(--text-dim)}
.lr-summary{margin-top:10px;padding-top:9px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:5px;font-size:11.5px;color:var(--text-muted)}
.lr-summary strong{color:var(--ink)}
.lr-note{font-size:10.5px;color:var(--text-dim);font-style:italic}
.lr-summary .lr-warn{margin:4px 0 0}

/* Multi-select bay picker in the build panel. */
.bay-pick{display:flex;flex-wrap:wrap;gap:5px;align-items:center}
.bay-pick-opt{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--card);font-size:11.5px;cursor:pointer;user-select:none}
.bay-pick-opt:hover{border-color:var(--timber)}
.bay-pick-opt.on{background:color-mix(in srgb,var(--timber) 12%,var(--card));border-color:var(--timber);font-weight:600}
.bay-pick-opt input{margin:0;width:12px;height:12px}
.bay-pick-hint{flex:1 0 100%;font-size:11px;color:var(--text-dim);margin-top:2px}

/* ---------- build history timeline (reports) ---------- */
.rep-head-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.hist-day{margin-bottom:16px}
.hist-day-head{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--saw);font-weight:600;padding-bottom:6px;border-bottom:1px solid var(--line);margin-bottom:8px}
.hist-row{display:grid;grid-template-columns:64px 12px minmax(120px,1.4fr) 2.6fr;gap:10px;align-items:center;padding:5px 0;font-size:12.5px}
.hist-time{font-family:var(--mono);font-size:10px;color:var(--text-dim);text-align:right}
.hist-dot{width:8px;height:8px;border-radius:50%;background:var(--line-strong);justify-self:center}
.hist-dot.good{background:var(--pine)} .hist-dot.accent{background:var(--saw)} .hist-dot.bad{background:var(--clay)}
.hist-build{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.hist-event{color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.hist-event.good{color:var(--pine);font-weight:500} .hist-event.accent{color:var(--saw);font-weight:500} .hist-event.bad{color:var(--clay)}
@media(max-width:820px){.hist-row{grid-template-columns:52px 10px 1fr;row-gap:2px}.hist-event{grid-column:3}}

/* draft (unsaved new build) footer note */
.draft-note{font-size:11.5px;color:var(--text-dim);font-style:italic;margin-right:auto;align-self:center}

/* ---------- Shop Overview (floor plan) ---------- */
.shop-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap;margin-bottom:8px}
.shop-legend{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.shop-legend .lg{display:flex;align-items:center;gap:5px;font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-muted)}
.shop-legend .lg i{width:11px;height:11px;border-radius:2px;display:inline-block}
.shop-empty-swatch{border:1.5px dashed var(--line-strong);background:transparent!important}
.shop-map-wrap{border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--card);padding:10px;overflow:hidden;display:flex;justify-content:center}
.shop-map{position:relative;line-height:0;aspect-ratio:1096/532;width:100%;max-height:calc(100vh - 314px);max-width:calc((100vh - 314px) * 1096 / 532)}
.shop-img{position:absolute;inset:0;width:100%;height:100%;object-fit:fill;display:block;border-radius:3px}
.shop-img.img-missing{display:none}
.shop-img-missing{display:none;position:absolute;inset:0;align-items:center;justify-content:center;text-align:center;padding:24px;font-size:12.5px;line-height:1.6;color:var(--text-muted);background:var(--surface-2);border:1px dashed var(--line-strong);border-radius:3px}
.shop-img-missing code{font-family:var(--mono);font-size:11px;background:var(--card);padding:1px 5px;border-radius:3px;border:1px solid var(--line)}
.shop-map.no-img .shop-img-missing{display:flex}
.shop-band{position:absolute;background:var(--card);border-radius:4px;z-index:1}
.shop-bay{position:absolute;box-sizing:border-box;border:2px solid transparent;border-radius:4px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;line-height:1.1;padding:2px;transition:transform .08s,box-shadow .12s;overflow:hidden;z-index:2}
/* Occupied bays previously carried `box-shadow:0 0 0 1px var(--card)` as a
   separator. Same problem as .shop-bay.empty below, just 1px instead of 2px:
   it painted outside the box and bled over the adjacent bay. Adjacent occupied
   bays still need separating — without it a run of green bays merges into one
   blob — so the separation moves INSIDE the box: .shop-bay already reserves a
   2px border, and tinting it to the band colour gives every bay a light inset
   frame. Two neighbours therefore show a 4px gap, entirely within their own
   bounds, overlapping nothing. */
.shop-bay.occupied{background:var(--bay-color);border-color:var(--card);color:#fff}
/* `empty` is also a generic empty-state utility class (see .empty around line 67,
   restyled again in planner-theme.css). That rule sets a large padding and an
   ::before illustration, and it collides with .shop-bay.empty here.
   .shop-bay{padding:2px} and .empty{padding:...} have identical specificity
   (0,1,0), so before the theme existed the bays kept 2px only because
   .shop-bay came later in this file. planner-theme.css loads third and won that
   tiebreak, giving every open bay 44px of horizontal padding — and because
   box-sizing is border-box a box cannot shrink below its own padding, the inline
   width:6.259% was discarded and every empty bay rendered 92px wide instead of
   75.55px, overlapping its neighbours by 16.45px. Spray Foam, also .empty, blew
   out from 37.8px to 92px and swallowed Bay 3.
   Setting these here at (0,2,0) makes the bays immune to that collision
   regardless of stylesheet order, and content:none drops the illustration.
   border-radius and font are pinned for the same reason: the generic rule sets
   both, so open bays were rendering with a 2px radius against the occupied bays'
   4px until these were restated. */
.shop-bay.empty{background:var(--surface-2);border:2px dashed var(--line-strong);padding:2px;border-radius:4px;font-family:inherit;font-size:inherit}
.shop-bay.empty::before{content:none}
.shop-bay:hover{transform:scale(1.03);box-shadow:0 3px 10px rgba(31,42,51,.25);z-index:5}
.shop-bay-num{font-family:var(--mono);font-size:11px;font-weight:700}
.shop-bay.empty .shop-bay-num{color:var(--text-muted)}
/* Bays are tall and narrow (roughly 74 x 163px at a typical window size), so a
   2-line clamp was truncating most real build names — "Ofland - Workforce.."
   — while leaving most of the cell empty. There is room for four lines with
   plenty to spare. overflow-wrap keeps a single long token from spilling out. */
.shop-bay-build{font-family:var(--body);font-size:9.5px;font-weight:600;text-align:center;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;max-width:100%;overflow-wrap:anywhere}
.shop-bay-open{font-family:var(--mono);font-size:8px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-dim)}
.shop-line-labels{display:flex;gap:24px;flex-wrap:wrap;margin-top:8px}
.shop-line-label{font-size:12.5px;color:var(--text-muted)}
.shop-line-label strong{color:var(--ink);font-family:var(--display);text-transform:uppercase;font-size:11px;letter-spacing:.04em}

/* ---------- Spray Foam bay (Shop Overview) ---------- */
.shop-bay.spray-foam.empty{border-style:solid;border-color:var(--timber);background:color-mix(in srgb,var(--timber) 14%,var(--surface-2))}
.shop-bay.spray-foam .shop-bay-num{color:var(--timber);font-size:9px}
.shop-bay.spray-foam.occupied .shop-bay-num{color:#fff}
.shop-bay.spray-foam .shop-bay-open{font-size:7px}

/* Carried (traveled) work marker. A build sitting in a bay with unfinished work
   from earlier bays is behind, and that is invisible from position alone — two
   builds in the same bay can be a fortnight apart. The badge shows how many stages
   are outstanding and roughly how many hours; the full list is in the tooltip.
   'gated' means at least one of them was flagged move-ready, i.e. a gate was
   waived to let the build through. */
.shop-carry{position:absolute;top:2px;right:2px;padding:1px 4px;border-radius:3px;
  background:var(--amber);color:#2A2622;font-family:var(--mono);font-size:8px;font-weight:700;
  letter-spacing:.02em;line-height:1.4;pointer-events:none}
.shop-bay.gated .shop-carry{background:var(--clay);color:#fff}
.shop-bay.behind{box-shadow:inset 0 0 0 2px var(--amber)}
.shop-bay.gated{box-shadow:inset 0 0 0 2px var(--clay)}
.shop-bay.compact .shop-carry{font-size:7px;padding:0 3px;top:1px;right:1px}

/* A line divides into lanes when any of its bays holds more than one build, so
   every cell in that row gets shorter. Shrink the type and drop the secondary
   label so the contents still fit rather than clipping. */
.shop-bay.compact{padding:1px}
.shop-bay.compact .shop-bay-num{font-size:9px}
.shop-bay.compact .shop-bay-build{font-size:8.5px;-webkit-line-clamp:2;line-height:1.1}
.shop-bay.compact .shop-bay-open{font-size:7px}

/* Drag feedback. A build box is the drag handle; open slots and other build boxes
   are drop targets. drop-hover = move here, drop-hover-add = Shift, i.e. add this
   bay to the build's set rather than replacing it. */
.shop-build{cursor:grab}
.shop-build.dragging{opacity:.4;cursor:grabbing}
.shop-bay.drop-hover{outline:2px solid var(--timber);outline-offset:-2px;filter:brightness(1.04)}
.shop-bay.drop-hover-add{outline:2px dashed var(--pine);outline-offset:-2px;filter:brightness(1.06)}

/* ---------- Bay picker modal ---------- */
.modal.modal-sm{max-width:440px}
.bp-list{display:flex;flex-direction:column;gap:6px}
.bp-row{display:grid;grid-template-columns:12px 1fr auto;align-items:center;gap:10px;width:100%;text-align:left;padding:10px 12px;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);cursor:pointer;font-family:inherit;transition:border-color .12s,background .12s}
.bp-row:hover{border-color:var(--saw);background:color-mix(in srgb,var(--saw) 7%,var(--surface-2))}
.bp-dot{width:9px;height:9px;border-radius:50%}
.bp-name{font-weight:600;font-size:13px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.bp-meta{font-family:var(--mono);font-size:10px;color:var(--text-dim);white-space:nowrap}
.bp-empty{padding:20px;text-align:center;color:var(--text-muted);font-size:12.5px;line-height:1.6}

/* ---------- build hours summary (reconciliation) ---------- */
.hours-summary{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-top:12px}
.hs-cell{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:9px 12px;display:flex;flex-direction:column;gap:2px}
.hs-label{font-family:var(--mono);font-size:8.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-dim)}
.hs-val{font-family:var(--display);font-size:18px;font-weight:700;color:var(--ink)}
.hs-var.over{border-color:var(--clay)} .hs-var.over .hs-val{color:var(--clay)}
.hs-var.under{border-color:var(--pine)} .hs-var.under .hs-val{color:var(--pine)}
.hs-note{margin-top:8px;font-size:12px;font-weight:600;padding:7px 12px;border-radius:var(--radius)}
.hs-note.over{color:var(--clay);background:color-mix(in srgb,var(--clay) 8%,var(--card));border:1px solid var(--clay)}
.hs-note.under{color:var(--pine);background:color-mix(in srgb,var(--pine) 8%,var(--card));border:1px solid var(--pine)}
.hs-note.even{color:var(--text-muted);background:var(--surface-2)}

/* header label for the stage hours column */
.stage-list-head{display:grid;grid-template-columns:20px minmax(0,1fr) 44px 44px 56px 34px;gap:6px;padding:0 10px 4px;font-family:var(--mono);font-size:8px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-dim)}
.stage-list-head span{text-align:center}

/* ---------- Build Hours matrix ---------- */
.hours-head{margin-bottom:8px}
.hours-filters{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.hf{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);display:flex;align-items:center;gap:6px}
.hf select{min-width:120px}
.hf-search{min-width:180px;padding:7px 10px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--card);font-size:12.5px}
.hours-filters .btn{margin-left:auto}
.hours-grid-wrap{overflow:auto;border:1px solid var(--line-strong);border-radius:var(--radius);max-height:calc((100vh - 300px) / var(--tab-zoom))}
.hours-grid{border-collapse:separate;border-spacing:0;font-size:12px;min-width:100%}
.hours-grid th,.hours-grid td{border-bottom:1px solid var(--line);border-right:1px solid var(--line);white-space:nowrap}
.hours-grid thead th{position:sticky;top:0;z-index:3;background:var(--surface-2);font-family:var(--mono);font-size:8.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-muted);font-weight:600;padding:8px 6px;text-align:center;vertical-align:bottom}
.bh-stage{max-width:64px;overflow:hidden;text-overflow:ellipsis}
.bh-name-head,.bh-name{position:sticky;left:0;z-index:5;background:var(--card);text-align:left;min-width:190px;max-width:230px;padding:6px 10px;font-weight:600;overflow:hidden;white-space:normal}
.hours-grid thead .bh-name-head{z-index:7;background:var(--surface-2)}
.bh-name{cursor:pointer}
.bh-name:hover{color:var(--saw)}
.bh-sub{display:block;font-family:var(--mono);font-size:8.5px;font-weight:400;color:var(--text-dim);text-transform:uppercase}
.bh-cell{padding:0}
.bh-input{width:52px;border:none;background:transparent;padding:7px 4px;font-size:12px;text-align:center;font-family:var(--mono);color:var(--ink)}
.bh-input:hover{background:var(--surface-2)}
.bh-input:focus{outline:2px solid var(--saw);outline-offset:-2px;background:var(--card)}
.bh-goal-input{width:56px;color:var(--timber);font-weight:600}
.bh-total{text-align:center;font-family:var(--mono);font-weight:700;background:var(--surface-2);padding:7px 8px}
.bh-goal{text-align:center;padding:0}
.bh-var{text-align:center;font-family:var(--mono);font-weight:700;padding:7px 8px}
.bh-var.over{color:var(--clay)} .bh-var.under{color:var(--pine)} .bh-var.even{color:var(--text-muted)}
.bh-status{padding:6px 10px;text-align:center}
.bh-status-pill{font-family:var(--mono);font-size:8.5px;text-transform:uppercase;letter-spacing:.03em;padding:2px 8px;border-radius:20px;border:1px solid;font-weight:600}
.bh-status-pill.active{color:var(--saw);border-color:var(--saw)}
.bh-status-pill.done{color:var(--shipped);border-color:var(--shipped)}
/* Two summary rows are pinned to the bottom of the scroll area: Totals, then
   Average beneath it. Both are position:sticky, so the upper one has to be
   offset by the height of the lower one or they stack on top of each other.
   --bh-avg-h is measured after render (see setSummaryRowOffset in app.js)
   because row height depends on font and zoom; the 30px fallback only applies
   for the first paint before that runs. */
.bh-totals-row td{position:sticky;bottom:var(--bh-avg-h,30px);z-index:4;background:var(--paper-2);font-weight:700;box-shadow:inset 0 2px 0 var(--ink);padding:7px 8px;vertical-align:middle;height:auto}
.bh-totals-row .bh-name{position:sticky;left:0;bottom:var(--bh-avg-h,30px);background:var(--paper-2);z-index:6;box-shadow:inset 0 2px 0 var(--ink);display:table-cell;padding:7px 10px}
/* Average row: same pinning, one step quieter than Totals so Totals still reads
   as the primary summary. No top rule — it sits directly under Totals. */
.bh-avg-row td{position:sticky;bottom:0;z-index:4;background:var(--paper-2);font-weight:600;padding:7px 8px;vertical-align:middle;height:auto;color:var(--text-muted)}
.bh-avg-row .bh-name{position:sticky;left:0;bottom:0;background:var(--paper-2);z-index:6;display:table-cell;padding:7px 10px;font-weight:700;color:var(--text-muted)}
.bh-avg-cell{text-align:center;font-family:var(--mono);font-size:11px}

/* --- Summary rows must stay opaque, whatever else is loaded ------------------
   planner-theme.css adds `tbody tr:hover > td{background:var(--wrb-hover-tint)}`,
   and that tint is rgba(...,.035) — 96.5% transparent. Specificity there is
   (0,1,3), which beats a plain `.bh-avg-row td` at (0,1,1), so on hover these
   sticky rows lost their opaque background and the stage-hour cells scrolling
   underneath showed straight through them.

   The corrective rules used to live in planner-theme.css, which meant the fix
   only worked if that file was up to date. These live here instead, next to the
   rest of the table, at (0,2,3) — high enough to win on specificity alone rather
   than on stylesheet order, so nothing can undo them. The hover tint is
   reapplied composited over each row's own opaque base, so the feedback looks
   identical but nothing behind can bleed through.

   z-index is also raised above the body rows' sticky name column (which sits at
   5); at 4 a body name cell would have painted over the summary rows. */
.hours-grid tbody tr.bh-totals-row > td,
.hours-grid tbody tr.bh-avg-row > td{background:var(--paper-2);z-index:7}
.hours-grid tbody tr.bh-totals-row > td.bh-name,
.hours-grid tbody tr.bh-avg-row > td.bh-name{background:var(--paper-2);z-index:8}
.hours-grid tbody tr.bh-totals-row:hover > td,
.hours-grid tbody tr.bh-avg-row:hover > td,
.hours-grid tbody tr.bh-totals-row:hover > td.bh-name,
.hours-grid tbody tr.bh-avg-row:hover > td.bh-name{
  background:color-mix(in srgb, var(--ink) 3.5%, var(--paper-2));
}
.bh-total-cell{text-align:center;font-family:var(--mono);font-size:11px}

/* ---------- drag-to-reorder ---------- */
.drag-handle{cursor:grab;color:var(--text-dim);font-size:12px;user-select:none;padding-right:2px}
.opt-row[draggable="true"]{cursor:default}
.opt-row.reorder-dragging{opacity:.4}
.opt-row.reorder-over{border-top:2px solid var(--saw)}
.hours-grid thead th.bh-stage[draggable="true"]{cursor:grab}
.hours-grid thead th.bh-stage.reorder-dragging{opacity:.4}
.hours-grid thead th.bh-stage.reorder-over{border-left:2px solid var(--saw);background:color-mix(in srgb,var(--saw) 12%,var(--surface-2))}
.card-hint{font-size:11px;color:var(--text-dim);margin:0 0 8px;line-height:1.5}

/* Build Hours target ship column */
.bh-target-head,.bh-target{text-align:center;font-family:var(--mono);font-size:11px;white-space:nowrap;padding:7px 10px;color:var(--text-muted)}

/* editable settings option/stage names */
.opt-edit{flex:1;min-width:0;background:transparent;border:1px solid transparent;border-radius:3px;padding:4px 6px;font-size:12.5px;font-family:inherit;color:var(--ink)}
.opt-edit:hover{border-color:var(--line)}
.opt-edit:focus{outline:none;border-color:var(--saw);background:var(--card)}

/* Build Hours: name colored by variance, alternating rows, last-updated column */
.bh-name-var.over{color:var(--clay)} .bh-name-var.over .bh-sub{color:var(--clay);opacity:.7}
.bh-name-var.under{color:var(--pine)} .bh-name-var.under .bh-sub{color:var(--pine);opacity:.7}
.bh-name-var.even{color:var(--text-muted)}
.bh-updated-head,.bh-updated{text-align:center;font-family:var(--mono);font-size:10px;white-space:nowrap;padding:7px 10px;color:var(--text-dim)}
.hours-grid tbody tr.bh-alt td{background:var(--surface-2)}
.hours-grid tbody tr.bh-alt .bh-name{background:var(--surface-2)}
.hours-grid tbody tr.bh-alt .bh-total{background:var(--surface-3)}
.hours-grid tbody tr:not(.bh-alt):not(.bh-totals-row) .bh-input:hover{background:var(--surface-2)}
.hours-grid tbody tr.bh-alt .bh-input:hover{background:var(--surface-3)}

/* Build Hours: row-highlight toggle */
/* The name cell MUST stay a real table cell. This rule used to set
   `.bh-name{display:flex}` so the ★ button and name could sit side by side —
   but .bh-name is a <td> that is also `position:sticky; left:0`. Changing a
   table cell's display takes it out of the table layout model (the browser
   wraps it in an anonymous cell box), which broke the frozen first column:
   the hour inputs scrolled out from underneath it, and since .bh-input:hover
   paints its own background, hovering the name lit up the stage-hour cells
   showing through. The flex layout now lives on an inner wrapper div instead,
   leaving the cell itself a plain sticky table-cell. */
.bh-name{display:table-cell}
.bh-name-inner{display:flex;align-items:center;gap:6px;min-width:0;overflow:hidden}
.bh-name-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis}
.bh-highlight-btn{flex:0 0 auto;background:transparent;border:none;cursor:pointer;color:var(--line-strong);font-size:13px;line-height:1;padding:2px;border-radius:3px}
.bh-highlight-btn:hover{color:var(--amber)}
.bh-highlight-btn.active{color:var(--amber)}
.hours-grid tbody tr.bh-highlighted td{background:color-mix(in srgb,var(--amber) 20%,var(--card))!important;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--amber) 35%,transparent)}
.hours-grid tbody tr.bh-highlighted .bh-name{background:color-mix(in srgb,var(--amber) 24%,var(--card))!important}
.hours-grid tbody tr.bh-highlighted .bh-input{background:transparent}

/* ---------- build attachments (files & documents) ---------- */
.attach-groups{display:flex;flex-direction:column;gap:16px;margin-top:4px}
.attach-group{border:1px solid var(--line);border-radius:var(--radius);padding:12px;background:var(--surface-2)}
.attach-label{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);font-weight:600;margin-bottom:9px}
.attach-drop{border:1.5px dashed var(--line-strong);border-radius:var(--radius);padding:14px;text-align:center;background:var(--card);transition:border-color .12s,background .12s}
.attach-drop.drag-over{border-color:var(--saw);background:color-mix(in srgb,var(--saw) 8%,var(--card))}
.attach-drop-text{font-size:12px;color:var(--text-muted)}
.attach-browse{background:none;border:none;color:var(--saw);font-weight:600;cursor:pointer;text-decoration:underline;padding:0;font-size:12px;font-family:inherit}
.attach-linkrow{display:flex;gap:7px;margin-top:9px}
.attach-linkinput{flex:1;min-width:0;padding:7px 10px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--card);font-size:12px}
.attach-list{display:flex;flex-direction:column;gap:6px;margin-top:10px}
.attach-item{display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);font-size:12.5px}
.ai-icon{flex:0 0 auto;font-size:13px}
.ai-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink);text-decoration:none}
a.ai-name:hover{color:var(--saw);text-decoration:underline}
.ai-download{background:none;border:none;cursor:pointer;text-align:left;font-family:inherit;font-size:12.5px}
.ai-download:hover{color:var(--saw);text-decoration:underline}
.ai-size{flex:0 0 auto;font-family:var(--mono);font-size:9.5px;color:var(--text-dim)}
.ai-rm{flex:0 0 auto;background:none;border:none;color:var(--text-dim);cursor:pointer;font-size:12px;padding:2px 4px;border-radius:3px}
.ai-rm:hover{color:var(--clay);background:color-mix(in srgb,var(--clay) 10%,transparent)}

/* ---------- build modal tabs ---------- */
.modal-tabs{display:flex;gap:2px;padding:0 22px;border-bottom:1px solid var(--line);background:var(--card)}
.modal-tab{background:none;border:none;border-bottom:2px solid transparent;padding:11px 4px;margin-right:20px;font-family:var(--display);font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-dim);cursor:pointer;transition:color .12s,border-color .12s}
.modal-tab:hover{color:var(--text-muted)}
.modal-tab.active{color:var(--ink);border-bottom-color:var(--saw)}
.mt-badge{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;padding:0 4px;border-radius:9px;background:var(--saw);color:#fff;font-family:var(--mono);font-size:9px;font-weight:700;vertical-align:middle}
.modal-panel{display:flex;flex-direction:column;gap:18px}
.modal-panel[hidden]{display:none}

/* ---------- Build Hours resizable columns ---------- */
.hours-grid th{position:relative}
.col-resize{position:absolute;top:0;right:0;width:7px;height:100%;cursor:col-resize;z-index:8;user-select:none}
.col-resize:hover{background:color-mix(in srgb,var(--saw) 40%,transparent)}
body.col-resizing{cursor:col-resize;user-select:none}
body.col-resizing *{cursor:col-resize!important}
.bh-stage .th-label{cursor:grab;display:inline-block;max-width:100%;white-space:normal;word-break:normal;overflow-wrap:normal;vertical-align:bottom}
/* when a stage column is widened, let the header label wrap to show in full */
.hours-grid thead th.bh-stage{white-space:normal;word-break:normal;overflow-wrap:normal;hyphens:none;min-width:62px}

/* ---------- Dashboard: Line Capacity cards (redesigned) ---------- */
.line-cards{display:flex;flex-direction:column;gap:14px}
.line-card{padding:14px 15px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--card);transition:border-color .15s}
.line-card.over{border-color:var(--clay)}
.lc-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:9px}
.lc-name{font-family:var(--display);font-size:14px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--ink)}
.lc-count{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--ink)}
.lc-of{color:var(--text-dim);font-weight:400}
.lc-fill-track{height:4px;background:var(--surface-3);border-radius:2px;overflow:hidden;margin-bottom:12px}
.lc-fill-bar{height:100%;background:var(--pine);border-radius:2px;transition:width .3s ease}
.lc-fill-bar.over{background:var(--clay)}
.lc-bays{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:7px}
.lc-bay{position:relative;min-height:56px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2);padding:6px 8px;display:flex;flex-direction:column;gap:3px;transition:border-color .12s,background .12s}
.lc-bay.filled{border-left:3px solid var(--bc,var(--pine));background:var(--card)}
.lc-bay.open{opacity:.6}
/* Formerly .conflict, styled as an error. Two active builds in one bay is now a
   supported arrangement, so this reads as a neutral "shared" marker instead. */
.lc-bay.conflict{border-color:var(--timber);border-left:3px solid var(--timber);background:color-mix(in srgb,var(--timber) 7%,var(--card));opacity:1}
.lc-bay.drop-hover{border-color:var(--saw);border-style:dashed;background:color-mix(in srgb,var(--saw) 10%,var(--surface-2));opacity:1}
.lc-baynum{font-family:var(--mono);font-size:8.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-dim);font-weight:600}
.lc-occ{display:flex;flex-wrap:wrap;gap:3px;flex:1;align-items:flex-start}
.lc-build{display:block;width:100%;font-size:11px;font-weight:600;color:var(--ink);cursor:grab;line-height:1.3;overflow-wrap:break-word;word-break:break-word;white-space:normal;user-select:none}
.lc-build:hover{color:var(--saw)}
.lc-build:active,.lc-build.dragging{cursor:grabbing;opacity:.5}
.lc-open{font-size:10.5px;color:var(--text-dim);font-style:italic}
.lc-flag{position:absolute;top:5px;right:6px;color:var(--clay);font-size:11px}
.lc-warn{margin-top:9px;font-family:var(--mono);font-size:10px;color:var(--clay)}

/* ---------- Crew (people) settings ---------- */
.crew-edit-list{display:flex;flex-direction:column;gap:9px;margin-bottom:12px;max-height:230px;overflow-y:auto;overflow-x:hidden;padding-right:2px}
.crew-filter{display:flex;align-items:center;gap:7px;margin-bottom:10px;font-family:var(--mono);font-size:8.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-dim)}
/* Room for the native arrow so a long role name can't run underneath it. */
.crew-filter select{flex:1;min-width:0;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:6px 26px 6px 8px;font-size:12px;font-family:var(--body)}
.crew-filter select:focus{border-color:var(--saw);outline:none}
.crew-edit-row select.ce-role{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:7px 26px 7px 8px;font-size:12.5px;font-family:var(--body);min-width:0;width:100%}
.crew-edit-row select.ce-role:focus{border-color:var(--saw);outline:none}
.add-crew-row select.ac-role{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:8px 26px 8px 8px;font-size:12.5px;font-family:var(--body);min-width:0;width:100%}
.add-crew-row select.ac-role:focus{border-color:var(--saw);outline:none}
.crew-edit-row{display:grid;grid-template-columns:1fr 68px 24px;grid-template-areas:"name name del" "role hrs hrs";gap:6px 7px;align-items:center;padding:8px 9px;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius)}
.crew-edit-row .ce-name{grid-area:name;font-weight:600}
.crew-edit-row .rm{grid-area:del;justify-self:center}
.crew-edit-row .ce-role{grid-area:role}
.crew-edit-row .ce-num{grid-area:hrs}
.crew-edit-row input{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:7px 9px;font-size:13px;min-width:0;width:100%}
.crew-edit-row input:focus{border-color:var(--saw);outline:none}
.ce-num{display:flex;align-items:center;gap:5px;font-family:var(--mono);font-size:8px;text-transform:uppercase;color:var(--text-dim);white-space:nowrap}
.ce-num input{width:100%;text-align:center}
/* Four columns (name, role, hrs, button) never fit the settings card, which is
   about 270px wide: it left ~57px each for the name input and the role select, so
   "Name…" rendered as "Nam" and the select's native arrow sat on top of its own
   text. Name now takes a full row of its own and the rest share the second row —
   the same two-row shape .crew-edit-row already uses. */
.add-crew-row{display:grid;grid-template-columns:1fr auto auto;grid-template-areas:"name name name" "role hrs btn";gap:7px;align-items:stretch}
.add-crew-row .ac-name{grid-area:name}
.add-crew-row .ac-role{grid-area:role}
.add-crew-row .cap-field{grid-area:hrs}
.add-crew-row .btn{grid-area:btn}
.add-crew-row>input{width:100%}
.add-crew-row .cap-field{display:flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9px;text-transform:uppercase;color:var(--text-muted);border:1px solid var(--line-strong);border-radius:var(--radius);padding:0 8px;background:var(--surface-2)}
.add-crew-row .cap-field input{width:38px;border:none;background:transparent;padding:8px 0;font-size:13px;font-family:var(--body)}
.add-crew-row .cap-field input:focus{outline:none}
.add-crew-row .btn{white-space:nowrap;align-self:stretch}

/* ---------- build modal: Crew assignment (drag lanes) ---------- */
.crew-pool{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:10px 12px;margin-bottom:12px;transition:border-color .12s,background .12s}
.crew-pool-cols{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:9px}
.crew-role-col{display:flex;flex-direction:column;gap:5px}
.crew-role-head{font-family:var(--mono);font-size:8.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--timber);font-weight:700;display:flex;align-items:center;gap:5px;padding-bottom:4px;border-bottom:1px solid var(--line)}
.crew-role-n{background:var(--surface-3);color:var(--text-dim);border-radius:8px;padding:0 5px;font-size:8px;font-weight:700}
.crew-role-chips{display:flex;flex-direction:column;gap:4px;align-items:flex-start}
.crew-role-chips .crew-chip{width:100%}
.crew-pool.drop-hover{border-color:var(--saw);border-style:dashed;background:color-mix(in srgb,var(--saw) 8%,var(--surface-2))}
.crew-lanes{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.crew-lane{display:flex;flex-direction:column;gap:6px;align-items:stretch;padding:9px 10px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface-2);min-height:70px;transition:border-color .12s,background .12s}
.crew-lane.drop-hover{border-color:var(--saw);border-style:dashed;border-width:2px;background:color-mix(in srgb,var(--saw) 10%,var(--card))}
.crew-lane-label{font-family:var(--mono);font-size:9px;text-transform:uppercase;letter-spacing:.03em;color:var(--text-dim);font-weight:600;line-height:1.25;border-bottom:1px solid var(--line);padding-bottom:5px}
.crew-pool .crew-lane-label{margin-bottom:7px;padding-top:0;border-bottom:none}
.crew-lane-chips{display:flex;flex-wrap:wrap;gap:4px;flex:1;align-content:flex-start;min-height:24px}
.crew-lane-empty{font-size:11px;color:var(--text-dim);font-style:italic}
.crew-chip{display:inline-flex;align-items:center;gap:5px;border-radius:20px;padding:5px 11px;font-size:11.5px;font-weight:600;cursor:grab;font-family:inherit;user-select:none;transition:all .12s}
.crew-chip.pool{background:var(--surface-3);border:1px solid var(--line-strong);color:var(--ink)}
.crew-chip.pool em{font-style:normal;color:var(--text-dim);font-weight:400;font-size:10px}
.crew-chip.assigned{background:var(--pine);border:1px solid var(--pine);color:#fff}
.crew-chip:hover{border-color:var(--saw)}
.crew-chip.dragging{opacity:.45}
.crew-chip:active{cursor:grabbing}
.crew-chip-x{background:none;border:none;color:rgba(255,255,255,.8);cursor:pointer;font-size:11px;padding:0;line-height:1;font-family:inherit}
.crew-chip-x:hover{color:#fff}

/* ---------- build modal: Inspections (redesigned cards) ---------- */
.insp-list{display:flex;flex-direction:column;gap:12px}
.insp-card{border:1px solid var(--line-strong);border-radius:var(--radius);padding:14px;background:var(--surface-2)}
.insp-card.passed{border-left:3px solid var(--pine)}
.insp-card.failed{border-left:3px solid var(--clay)}
.insp-card-head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:12px;flex-wrap:wrap}
.insp-name{font-size:13.5px;font-weight:700;color:var(--ink)}
.insp-opts{display:flex;gap:5px}
.insp-opt{background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:5px 12px;font-size:11px;font-weight:600;color:var(--text-muted);cursor:pointer;font-family:inherit;transition:all .12s}
.insp-opt:hover{border-color:var(--saw)}
.insp-opt.on{color:#fff}
.insp-opt.on.passed{background:var(--pine);border-color:var(--pine)}
.insp-opt.on.failed{background:var(--clay);border-color:var(--clay)}
.insp-clear{color:var(--text-dim)}
.insp-fields{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px}
.insp-fields .field{margin:0}
.insp-sub-label{font-family:var(--mono);font-size:9px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-dim);font-weight:600;margin-bottom:6px}
.insp-photos-wrap{margin-bottom:12px}
.insp-drop{border:1.5px dashed var(--line-strong);border-radius:var(--radius);padding:12px;text-align:center;background:var(--card);transition:border-color .12s,background .12s}
.insp-drop.drag-over{border-color:var(--saw);background:color-mix(in srgb,var(--saw) 8%,var(--card))}
.insp-photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:8px;margin-top:9px}
.insp-photo{position:relative;aspect-ratio:1;border-radius:var(--radius);overflow:hidden;border:1px solid var(--line-strong)}
.insp-photo img{width:100%;height:100%;object-fit:cover;display:block}
.insp-photo-x{position:absolute;top:3px;right:3px;width:18px;height:18px;border-radius:50%;background:rgba(31,42,51,.75);color:#fff;border:none;cursor:pointer;font-size:10px;line-height:1;display:flex;align-items:center;justify-content:center}
.insp-photo-x:hover{background:var(--clay)}
.mt-badge.fail{background:var(--clay)}
.mt-badge.ok{background:var(--pine)}

/* ---------- Dashboard: Labor Capacity ---------- */
.labor-summary{display:flex;gap:14px;margin:6px 0 12px}
.labor-stat{flex:1;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:11px 14px;display:flex;flex-direction:column;gap:3px}
.labor-stat.over{border-color:var(--clay)}
.labor-stat.ok{border-color:var(--pine)}
.ls-num{font-family:var(--display);font-size:22px;font-weight:700;color:var(--ink)}
.labor-stat.over .ls-num{color:var(--clay)}
.labor-stat.ok .ls-num{color:var(--pine)}
.ls-label{font-family:var(--mono);font-size:9px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-dim)}
.labor-track{position:relative;height:8px;background:var(--surface-3);border-radius:4px;overflow:hidden;margin-bottom:10px}
.labor-bar{height:100%;background:var(--pine);border-radius:4px;transition:width .3s}
.labor-bar.over{background:var(--clay)}
.labor-warn{font-size:12.5px;color:var(--clay);font-weight:600;padding:9px 12px;background:color-mix(in srgb,var(--clay) 7%,var(--card));border:1px solid var(--clay);border-radius:var(--radius)}
.labor-ok-note{font-size:12.5px;color:var(--pine);padding:9px 12px;background:color-mix(in srgb,var(--pine) 6%,var(--card));border:1px solid var(--pine);border-radius:var(--radius)}
.labor-detail-head{font-family:var(--mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-dim);margin:14px 0 7px}
.labor-builds{display:flex;flex-direction:column;gap:5px}
.labor-build-row{display:flex;justify-content:space-between;align-items:center;padding:8px 11px;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius);cursor:pointer;transition:border-color .12s}
.labor-build-row:hover{border-color:var(--saw)}
.lb-name{font-size:12.5px;font-weight:600;color:var(--ink)}
.lb-demand{font-family:var(--mono);font-size:11.5px;font-weight:700;color:var(--timber)}

/* ---------- Dashboard: What-If Scenario ---------- */
.scenario-controls{display:flex;gap:12px;align-items:flex-end;margin:6px 0 12px;flex-wrap:wrap}
.scenario-controls .field{margin:0}
.scenario-controls select,.scenario-controls input{min-width:180px}
.scenario-compare{display:grid;grid-template-columns:1fr auto 1fr;gap:14px;align-items:center;margin-bottom:12px}
.sc-col{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:12px 14px}
.sc-head{font-family:var(--mono);font-size:9px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-dim);margin-bottom:8px}
.sc-row{font-size:12.5px;color:var(--text-muted);margin-bottom:5px;display:flex;justify-content:space-between;gap:10px;align-items:center}
.sc-row b{color:var(--ink)}
.sc-arrow{font-size:20px;color:var(--saw);font-weight:700}
.sc-delta{text-align:center;font-weight:700;font-size:13px;padding:9px;border-radius:var(--radius);margin-bottom:12px}
.sc-delta.later{color:var(--clay);background:color-mix(in srgb,var(--clay) 8%,var(--card));border:1px solid var(--clay)}
.sc-delta.earlier{color:var(--pine);background:color-mix(in srgb,var(--pine) 8%,var(--card));border:1px solid var(--pine)}
.sc-delta.same{color:var(--text-muted);background:var(--surface-2)}
.sc-actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
@media(max-width:640px){.scenario-compare{grid-template-columns:1fr}.sc-arrow{transform:rotate(90deg)}}

/* Crew card spans full settings width so its rows have room */
.settings-card-wide{grid-column:1/-1}

/* ---------- print size picker (screen) ---------- */
.print-pick select{font-family:var(--body)}
.g-legend .print-pick{margin-left:auto}

/* ---------- PRINT ----------
   Prints ONLY the target chart (Build Hours grid or Gantt), scaled to fill the
   sheet. Selectors below match the real DOM in index.html: <header>, nav.tabbar,
   .filterbar, main > section.view, .overlay. */
@media print{
  /* Nothing prints by default — we opt the target back in below. */
  body.printing > header,
  body.printing > nav.tabbar,
  body.printing > .filterbar,
  body.printing > .overlay{display:none !important}

  /* Only the view being printed is shown. */
  body.printing main > .view{display:none !important}
  body.printing.printing-hours main > #view-hours{display:block !important}
  body.printing.printing-gantt main > #view-gantt{display:block !important}

  /* Strip in-view chrome: titles, descriptions, filters, legends, buttons. */
  body.printing .hours-head,
  body.printing .hours-filters,
  body.printing .g-legend,
  body.printing .print-pick,
  body.printing [data-print],
  body.printing .col-resize,
  body.printing .bh-highlight-btn,
  body.printing .empty{display:none !important}

  /* Edge-to-edge on a clean white sheet (drop the kraft tint + grid texture). */
  html,body,body.printing{background:#fff !important;background-image:none !important;margin:0 !important;padding:0 !important;width:auto !important;height:auto !important;min-height:0 !important}
  body.printing main{margin:0 !important;padding:0 !important;max-width:none !important;background:none !important}
  body.printing main > .view{margin:0 !important;padding:0 !important;background:none !important}
  body.printing #hoursRoot,body.printing #ganttRoot{margin:0 !important;padding:0 !important;background:none !important}

  /* Release the on-screen scroll containers so everything prints. */
  body.printing .hours-grid-wrap,
  body.printing .g-wrap,
  body.printing .g-scroll{max-height:none !important;height:auto !important;overflow:visible !important;border:none !important;border-radius:0 !important}
  /* Print at full size — the on-screen 80% default would otherwise shrink the
     printed output as well, on top of the browser's own print scaling. */
  #ganttRoot,#hoursRoot{zoom:1 !important}

  /* --- Build Hours grid --- */
  body.printing-hours .hours-grid{font-size:7.5pt;border-collapse:collapse;width:100% !important;table-layout:auto}
  body.printing-hours .hours-grid thead{display:table-header-group}
  body.printing-hours .hours-grid tr{page-break-inside:avoid;break-inside:avoid}
  body.printing-hours .hours-grid th,
  body.printing-hours .hours-grid td{border:0.5pt solid #8a8a8a !important;padding:2.5pt 3pt;position:static !important;background:#fff !important;color:#000 !important;box-shadow:none !important;max-width:none !important;min-width:0 !important;width:auto !important}
  body.printing-hours .hours-grid th{font-size:6.5pt;font-weight:700;background:#ececec !important;white-space:normal;vertical-align:bottom}
  /* Stage columns are numerous and narrow — rotate their headers so each name
     reads as whole words instead of wrapping one letter per line. */
  body.printing-hours .hours-grid thead th.bh-stage{writing-mode:vertical-rl;transform:rotate(180deg);white-space:nowrap !important;min-width:0 !important;width:auto !important;padding:3pt 1.5pt !important;height:78pt;text-align:left;vertical-align:middle}
  body.printing-hours .hours-grid thead th.bh-stage .th-label{white-space:nowrap !important;max-width:none;overflow:visible}
  body.printing-hours .hours-grid .bh-name{text-align:left;font-weight:600;white-space:normal}
  body.printing-hours .hours-grid .bh-sub{display:block;font-size:5.5pt;color:#555 !important}
  body.printing-hours .hours-grid .bh-input{border:none !important;background:transparent !important;font-size:7.5pt;width:100%;text-align:center;padding:0;color:#000 !important;-webkit-appearance:none;appearance:none}
  body.printing-hours .bh-totals-row td{font-weight:700;border-top:1pt solid #000 !important;background:#ececec !important}
  body.printing-hours .bh-avg-row td{font-weight:600;background:#f4f4f4 !important;color:#000 !important}
  body.printing-hours .bh-alt td{background:#f6f6f6 !important}
  body.printing-hours .bh-status-pill{border:none !important;background:transparent !important;color:#000 !important;padding:0;font-size:6.5pt}

  /* --- Gantt --- */
  body.printing-gantt .g-inner{background:#fff !important}
  body.printing-gantt .g-row{page-break-inside:avoid;break-inside:avoid;border-bottom:0.5pt solid #b0b0b0 !important}
  body.printing-gantt .g-label,body.printing-gantt .g-label-sp{background:#fff !important;border-right:1pt solid #555 !important}
  body.printing-gantt .g-row:not(.group) .g-label{font-size:11px}
  body.printing-gantt .g-row.group .g-label{background:#ececec !important;font-size:12px}
  /* Faint on-screen gridlines are invisible on paper — darken them. */
  body.printing-gantt .g-gridline{border-left:0.5pt solid #c4c4c4 !important;background:none !important}
  body.printing-gantt .tick{border-left:0.5pt solid #9a9a9a !important}
  body.printing-gantt .tick span{color:#333 !important;font-size:10px}
  body.printing-gantt .g-bar,body.printing-gantt .bar{border:0.5pt solid #444 !important}
  body.printing-gantt .today{border-color:#c0392b !important}

  /* Preserve bar/status colors. */
  body.printing *{-webkit-print-color-adjust:exact !important;print-color-adjust:exact !important}
}

/* ---------- build modal: build-level inspection contact ---------- */
.insp-build-info{background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius);padding:13px 14px;margin-bottom:14px}
.insb-title{font-family:var(--mono);font-size:9px;text-transform:uppercase;letter-spacing:.04em;color:var(--timber);font-weight:700;margin-bottom:10px}
.insp-build-info .insp-fields{margin-bottom:0}

/* ---------- Deployment modes: read-only banner + auth ---------- */
.mode-banner{background:var(--timber);color:#fff;font-family:var(--mono);font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;text-align:center;padding:5px 10px;font-weight:700}
.mode-banner.warn{background:var(--clay)}

/* Hide every editing affordance for viewers. */
body.readonly #newBuildBtn,
body.readonly .add-row,
body.readonly .rm,
body.readonly .drag-handle,
body.readonly .col-resize,
body.readonly [data-del-line],
body.readonly [data-del-stage],
body.readonly [data-del-opt],
body.readonly [data-del-crew],
body.readonly [data-crew-remove],
body.readonly .crew-chip-x,
body.readonly .insp-photo-x,
body.readonly .attach-remove,
body.readonly .insp-drop,
body.readonly .attach-drop,
body.readonly .modal-foot .btn.danger,
body.readonly #deleteBuildBtn,
body.readonly .tab[data-tab="settings"],
body.readonly .settings-actions,
body.readonly .scenario-actions,
body.readonly .bh-highlight-btn{display:none !important}

/* Dismiss controls stay fully usable in a read-only session. The generic
   `[data-locked]` styling below strips borders and backgrounds from locked fields;
   without this, a close button that slipped through would render as invisible
   furniture. Closing a dialog is not an edit. */
body.readonly [data-close-build],
body.readonly [data-close-picker],
body.readonly [data-cancel-draft],
body.readonly [data-close-modal],
body.readonly .modal-close{display:inline-flex !important;opacity:1 !important;cursor:pointer !important;pointer-events:auto !important}

/* Inputs stay visible (they carry the data) but read flat, not editable. */
body.readonly input[data-locked],
body.readonly textarea[data-locked],
body.readonly select[data-locked]{background:transparent !important;border-color:transparent !important;cursor:default;color:var(--ink)}
body.readonly .insp-opt[data-locked]{opacity:1}
body.readonly .crew-chip{cursor:default}
body.readonly .g-bar,body.readonly .lc-build,body.readonly .td-name{cursor:pointer}

.auth-box{display:flex;align-items:center;gap:9px;margin-right:10px}
.auth-box:empty{display:none}
.auth-box .btn{white-space:nowrap}
.auth-who{font-family:var(--mono);font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted)}
.auth-overlay{display:flex;align-items:center;justify-content:center}
.auth-modal{max-width:380px;width:92%}
.auth-err{color:var(--clay);font-size:12.5px;font-weight:600;padding:8px 10px;background:color-mix(in srgb,var(--clay) 8%,var(--card));border:1px solid var(--clay);border-radius:var(--radius)}

/* ---------- Admin: People & Access ---------- */

.admin-list{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;margin-top:12px}
.admin-row{display:flex;align-items:center;gap:10px;padding:9px 11px;background:var(--card);flex-wrap:wrap}
.admin-row.is-me{background:color-mix(in srgb,var(--timber) 5%,var(--card))}
.admin-who{flex:1 1 200px;min-width:0;display:flex;flex-direction:column;gap:2px}
.admin-email{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.admin-you{font-family:var(--mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);border:1px solid var(--line);border-radius:3px;padding:0 4px;margin-left:4px;font-weight:500}
.admin-meta{font-size:11px;color:var(--text-muted)}
.admin-warn{color:var(--clay);font-weight:600}
.admin-role{font-size:12.5px;padding:4px 6px;min-width:96px}
.admin-acts{display:flex;gap:6px;flex-shrink:0}
.admin-add{margin-top:14px;padding-top:13px;border-top:1px solid var(--line)}
.admin-add-title{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);margin-bottom:8px}
.admin-add-fields{display:flex;gap:7px;flex-wrap:wrap}
.admin-add-fields input{flex:1 1 170px;min-width:0;padding:6px 9px;font-size:13px}
.admin-add-fields select{padding:6px 9px;font-size:13px}
.admin-add-hint{font-size:11.5px;color:var(--text-muted);line-height:1.5;margin-top:8px}
.admin-msg{font-size:12.5px;font-weight:600;padding:7px 10px;border-radius:var(--radius);margin-top:10px}
.admin-msg.info{background:color-mix(in srgb,var(--timber) 8%,var(--card));color:var(--ink)}
.admin-msg.ok{background:color-mix(in srgb,#157A6E 10%,var(--card));color:#0f5c53}
.admin-msg.err{background:color-mix(in srgb,var(--clay) 9%,var(--card));color:var(--clay)}
.admin-err{color:var(--clay);font-weight:600}
.admin-note{font-size:12px;line-height:1.55;color:var(--text-muted);background:color-mix(in srgb,var(--sand,#CE8214) 8%,var(--card));border:1px solid var(--line);border-radius:var(--radius);padding:9px 11px;margin-top:11px}

/* Viewers never reach Settings, but keep the panel out of read-only mode entirely. */
body.readonly #adminPeopleRoot{display:none !important}

/* Longer app name needs to survive narrow screens without crowding the header. */
@media (max-width:720px){
  .brand{flex-wrap:wrap;gap:0 8px}
  .brand h1{font-size:19px}
  .brand .sub{font-size:9.5px}
}
@media (max-width:420px){
  .brand h1{font-size:17px;letter-spacing:0}
}

/* A stored file that could not be signed (deleted from the bucket, or expired
   permissions) — show it as visibly missing rather than a broken-image icon. */
.insp-photo img.signed-missing{opacity:.4;background:repeating-linear-gradient(45deg,var(--line) 0 6px,transparent 6px 12px)}
.insp-photo img[data-signed-done="pending"]{opacity:.5}

/* ---------- People & Access: Settings card summary ---------- */
.admin-summary{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-top:10px}
.admin-summary-count{font-size:14.5px;font-weight:700}
.admin-summary-sub{font-size:12px;color:var(--text-muted);margin-top:2px}

/* ---------- People & Access: modal ---------- */
#peopleModal{max-width:720px}
.admin-toolbar{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.admin-toolbar .search{flex:1 1 auto;min-width:0}
.admin-showing{font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--text-muted);white-space:nowrap}
#peopleModal .admin-list{max-height:46vh;overflow-y:auto;margin-top:0}
.admin-foot-note{font-size:11.5px;color:var(--text-muted);margin-right:auto}
.modal-foot{display:flex;align-items:center;gap:10px}

/* Credential status tones */
.admin-st-ok{color:var(--text-muted)}
.admin-st-warn{color:#8a6410;font-weight:600}
.admin-st-bad{color:var(--clay);font-weight:700}

/* ---------- Settings: collapsible tiles ---------- */
.settings-card[data-tile] > .settings-card-body{display:none}
.settings-card[data-tile].tile-open > .settings-card-body{display:block}

.tile-head{display:flex;align-items:center;gap:10px;cursor:pointer;user-select:none;outline:none}
.tile-head h3{margin:0;flex:1 1 auto}
.tile-head:focus-visible{outline:2px solid var(--timber);outline-offset:3px;border-radius:4px}
.tile-chevron{font-size:19px;line-height:1;color:var(--text-muted);transition:transform .15s ease;flex-shrink:0}
.settings-card.tile-open > .tile-head .tile-chevron{transform:rotate(90deg)}

/* People & Access: the whole card is the control, so it never expands in place */
.tile-clickable{cursor:pointer;transition:border-color .12s ease,background .12s ease}
.tile-clickable:hover{border-color:var(--timber)}
.tile-clickable:focus-visible{outline:2px solid var(--timber);outline-offset:2px}
.tile-clickable .tile-head{cursor:pointer}
.tile-sub{font-size:13px;font-weight:600;margin-top:8px}
.tile-note{font-size:11.5px;color:var(--text-muted);margin-top:2px}

/* ---------- Gantt: freeze the date header ----------
   position:sticky resolves against the nearest scroll container, so the header
   can only freeze if the element that scrolls vertically is .g-scroll itself.
   Previously the page scrolled and .g-scroll only scrolled horizontally, which
   is why top:0 had nothing to stick to. Giving the chart its own viewport makes
   it behave like a spreadsheet: header frozen on top, labels frozen at left
   (.g-label already handles that axis). */
.g-scroll{overflow:auto;max-height:calc((100vh - 300px) / var(--tab-zoom));min-height:calc(300px / var(--tab-zoom))}
.g-head{position:sticky;top:0;z-index:7;background:var(--card)}
.g-head .ticks{background:var(--card)}

@media (max-width:900px){
  .g-scroll{max-height:calc((100vh - 260px) / var(--tab-zoom));min-height:calc(260px / var(--tab-zoom))}
}

/* Printing lays the whole chart out flat, so nothing should be pinned. */
@media print{
  .g-scroll{max-height:none !important;min-height:0 !important;overflow:visible !important}
  .g-head{position:static !important}
}
body.printing .g-head{position:static !important}
body.printing .g-scroll{max-height:none !important;min-height:0 !important}

/* The removed paper-size picker carried margin-left:auto, which pushed the Print
   button to the right of the legend. Keep that alignment on the button itself. */
.g-legend [data-print]{margin-left:auto}

/* ---------- Settings: consolidated Export card ---------- */
.export-row{display:flex;gap:8px;margin-top:11px;flex-wrap:wrap}
.export-row select{flex:1 1 190px;min-width:0;padding:6px 9px;font-size:13px}

/* ---------- Gantt: out-of-window note (print only) ---------- */
.g-print-note{display:none}
@media print{
  body.printing-gantt .g-print-note{display:block;margin-top:8pt;font-size:8pt;line-height:1.45;color:#000}
}

/* ---------- Shop Overview printing ---------- */
@media print{
  body.printing.printing-shop main > #view-shop{display:block !important}
  body.printing-shop .shop-legend,
  body.printing-shop .panel-sub{display:none !important}
  body.printing-shop .shop-map-wrap{border:none !important}
}

/* ---------- Build Hours: wrapped names, uniform rows ---------- */
/* Numeric cells stay on one line; only the Build column wraps. The inner span
   is clamped to two lines so a long name can't make one row taller than the
   rest — table cells ignore overflow, so the clamp has to live on the span. */
.hours-grid tbody tr{height:52px}
.hours-grid tbody td{height:52px;vertical-align:middle}
.bh-name-text{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;white-space:normal;overflow-wrap:anywhere;line-height:1.22}
.bh-name .bh-sub{display:block;font-weight:500;font-size:10.5px;line-height:1.2}

/* ---------- Shop Overview printing ---------- */
@media print{
  /* Browsers strip background colours in print by default, which is why the
     empty bays vanished — their fill and the occupied bays' status colours are
     both backgrounds. Force exact colour reproduction for the map. */
  body.printing-shop .shop-map,
  body.printing-shop .shop-img,
  body.printing-shop .shop-band,
  body.printing-shop .shop-bay{-webkit-print-color-adjust:exact !important;print-color-adjust:exact !important}

  /* Empty bays: solid, dark, unmistakably present on paper. */
  body.printing-shop .shop-bay.empty{background:#fff !important;border:1.2pt dashed #333 !important;box-shadow:none !important}
  body.printing-shop .shop-bay.empty .shop-bay-num{color:#000 !important}
  body.printing-shop .shop-bay.empty .shop-bay-open{color:#444 !important}
  body.printing-shop .shop-bay.occupied{color:#fff !important;box-shadow:none !important}
  body.printing-shop .shop-bay{transition:none !important}

  /* Fill the sheet: the map is width:100% with a fixed aspect ratio, so lifting
     the on-screen height caps is all it takes. */
  body.printing-shop .shop-map{width:100% !important;max-width:none !important;max-height:none !important}
  body.printing-shop .shop-map-wrap{display:block !important;padding:0 !important;border:none !important;overflow:visible !important}
  body.printing-shop .shop-head{margin-bottom:6pt !important}
  body.printing-shop .rep-title{font-size:12pt !important;margin:0 !important}
}

/* A build whose saved dates cannot be read. Named in the row so it can be found and fixed. */
.g-bad-date{color:var(--rust);font-weight:600;cursor:help}

/* ---------- Board: fit all five status columns on screen ----------
   Adding Shipped made five fixed 306px columns (~1,600px) — wider than a laptop, so
   the last column sat off the right edge. Columns now share the available width
   equally, with a floor so cards stay readable; below that floor (~1,200px of board)
   the board scrolls sideways exactly as before. */
.board .b-col{flex:1 1 0;min-width:220px}

/* ---------- Staging marker ----------
   Shown when the app is using the staging (test) database.
   * The banner is positioned above the full-screen sign-in wall (z-index 99999) so
     it shows before sign-in. Inside the app it scrolls away like the page.
   * The header and the tab bar (the part that stays in view while scrolling) keep a
     red stripe along their top edge, and the tab title reads [TEST], so staging stays
     obvious at any scroll position. A pinned banner was avoided on purpose: header
     and tab bar are already sticky (top 0 / 66px in theme-c.css) and would have been
     partly covered. */
.mode-banner.staging{position:relative;z-index:100000;background:#B42318;color:#fff}
html.staging header,html.staging nav.tabbar{box-shadow:inset 0 4px 0 #B42318}
