:root{
  --steel-950:#0f1215;
  --steel-900:#181c20;
  --steel-800:#22262b;
  --steel-700:#2c3137;
  --steel-600:#3d434b;
  --line:#39404a;
  --text:#eef1f3;
  --text-dim:#aeb6bd;   /* brightened for shop-floor legibility */
  --text-faint:#868e96; /* brightened -- was near-invisible on dark bg */
  /* ISC Manufacturing orange (iscmfg.com) is the accent: actions, selection,
     active state. Always dark ink on it -- white on this orange fails contrast. */
  --accent:#f58220;
  --accent-ink:#1c0c00;
  /* "Ready to start" stays yellow so it can't be mistaken for the accent or for amber (due soon). */
  --ready:#f5b400;
  --red:#e34b3a;
  --red-bg:#2e1613;
  --amber:#e2a13d;
  --amber-bg:#2e2210;
  --green:#4fae57;
  --green-bg:#132f16;
  --blue:#5aa3d8;
  --blue-bg:#12242f;
  --radius:10px;
  /* Condensed face for labels and numbers: fits more on a phone-width row
     and reads like plant signage. The system stack covers offline loads. */
  --font-body:"Barlow",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
  --font-display:"Barlow Condensed","Arial Narrow","Roboto Condensed",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --plate:linear-gradient(180deg,#252a30,#1d2126);
  --plate-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 2px 0 rgba(0,0,0,.35),0 8px 20px rgba(0,0,0,.22);
  --hazard:repeating-linear-gradient(-45deg,var(--accent) 0 9px,#15181b 9px 18px);
  --rivets:
    radial-gradient(circle at 12px 12px,#5d656e 0 2.4px,transparent 3px),
    radial-gradient(circle at calc(100% - 12px) 12px,#5d656e 0 2.4px,transparent 3px),
    radial-gradient(circle at 12px calc(100% - 12px),#5d656e 0 2.4px,transparent 3px),
    radial-gradient(circle at calc(100% - 12px) calc(100% - 12px),#5d656e 0 2.4px,transparent 3px);
  /* Right-pointing chevron belt. Tile is 14px wide; belt-run moves exactly one tile. */
  --chevrons:
    linear-gradient(to bottom left,transparent 38%,rgba(245,130,32,.8) 38% 62%,transparent 62%) 0 0/14px 50% repeat-x,
    linear-gradient(to top left,transparent 38%,rgba(245,130,32,.8) 38% 62%,transparent 62%) 0 100%/14px 50% repeat-x;
  font-size:16px;
  color-scheme:dark;   /* native scrollbars, dropdowns and date pickers render dark */
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
html,body{margin:0;padding:0;height:100%;}
body{
  background:var(--steel-950);
  color:var(--text);
  font-family:var(--font-body);
  -webkit-font-smoothing:antialiased;
  overscroll-behavior-y:none;
}
button{font-family:inherit;}
::selection{background:var(--accent);color:#1a1400;}

#app{position:relative;z-index:1;display:flex;flex-direction:column;height:100vh;height:100dvh;}

.ic{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;}

/* ---------- Conveyor backdrop ---------- */
/* Decorative only. Everything that moves is a transform on its own layer,
   so it stays on the compositor instead of repainting -- these run all
   shift on cheap floor tablets. */
.conveyor-bg{
  position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background:
    radial-gradient(ellipse at 50% -10%,rgba(245,130,32,.07),transparent 55%),
    linear-gradient(rgba(90,163,216,.045) 1px,transparent 1px) 0 0/120px 120px,
    linear-gradient(90deg,rgba(90,163,216,.045) 1px,transparent 1px) 0 0/120px 120px,
    linear-gradient(rgba(90,163,216,.022) 1px,transparent 1px) 0 0/24px 24px,
    linear-gradient(90deg,rgba(90,163,216,.022) 1px,transparent 1px) 0 0/24px 24px,
    var(--steel-950);
}
.conveyor-bg::after{
  content:'';position:absolute;inset:0;
  background:radial-gradient(ellipse at center,transparent 50%,rgba(0,0,0,.5));
}
/* A screw conveyor seen side-on in cutaway: trough back plate, bolted top
   flange, and hanger bearings that stay put while the flights turn past. */
.cv{
  --d:clamp(120px,19vmin,200px);
  position:absolute;left:-8%;right:-8%;
  height:calc(var(--d) * 1.2);
  display:flex;align-items:center;overflow:hidden;
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(0,0,0,.3));
  border-bottom:4px solid #3a4148;
  opacity:.28;
}
.cv::before{
  content:'';position:absolute;top:0;left:0;right:0;height:8px;z-index:1;
  background:radial-gradient(circle,#8f98a0 0 1.8px,transparent 2.4px) 0 50%/30px 8px repeat-x,#4b535c;
  box-shadow:0 2px 3px rgba(0,0,0,.4);
}
.cv::after{
  content:'';position:absolute;inset:0;z-index:1;
  background:
    radial-gradient(circle at 50% 50%,#6a737c 0 10px,#2d3339 10.5px 13px,transparent 13.5px) 0 0/calc(var(--d) * 3.5) 100% repeat-x,
    linear-gradient(90deg,transparent calc(50% - 5px),#4b535c calc(50% - 5px) calc(50% + 5px),transparent calc(50% + 5px)) 0 0/calc(var(--d) * 3.5) 50% repeat-x;
}
/* One tile is exactly one flight pitch, so sliding one tile reads as one full turn. */
.cv-screw{
  flex-shrink:0;width:calc(100% + var(--d));height:var(--d);
  background:url(assets/screw-flight.svg) 0 0/var(--d) var(--d) repeat-x;
  animation:auger-turn 2.6s linear infinite;
  will-change:transform;
}
@keyframes auger-turn{
  from{transform:translateX(calc(var(--d) * -1));}
  to{transform:translateX(0);}
}
.cv-main{top:56%;}
.cv-incline{--d:clamp(80px,12vmin,130px);top:12%;transform:rotate(-9deg);opacity:.16;}
.cv-incline .cv-screw{animation-duration:1.9s;}

/* ---------- App bar ---------- */
.appbar{
  position:relative;
  background:linear-gradient(180deg,#121416,#060707);   /* near-black, like the iscmfg.com header */
  padding:calc(8px + env(safe-area-inset-top)) 10px 17px;
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-shrink:0;
  gap:10px;
  box-shadow:0 6px 16px rgba(0,0,0,.35);
}
/* Title kept to a single line -- it previously wrapped to three lines on
   a phone, eating roughly a quarter of the screen before any actual
   content. min-width:0 is what lets the ellipsis work inside a flex row. */
.appbar .brand{display:flex;align-items:center;gap:10px;min-width:0;flex:1;}
.brand-mark{
  width:38px;height:38px;border-radius:9px;flex-shrink:0;
  box-shadow:0 2px 0 rgba(0,0,0,.45),0 0 0 1px rgba(0,0,0,.35);
}
.brand-text{display:flex;flex-direction:column;line-height:1.15;min-width:0;}
.appbar .brand .name{
  font-family:var(--font-display);font-size:20px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* Brightened from --text-dim: the shift/date line was near-unreadable
   against the dark header in shop lighting. */
.appbar .brand .sub{font-size:12px;color:#b8c0c7;letter-spacing:.02em;margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.appbar .right{display:flex;align-items:center;gap:8px;flex-shrink:0;}
/* The "Screw Conveyor Mfg" pill was nowrap decoration competing with the
   title for horizontal space. Hidden on narrow screens where that space
   is needed for content; still shown on wider screens. */
.appbar .stamp{
  background:var(--accent);color:var(--accent-ink);font-family:var(--font-display);font-weight:800;font-size:13px;letter-spacing:.1em;
  padding:6px 10px;border-radius:4px;text-transform:uppercase;white-space:nowrap;
  box-shadow:inset 0 0 0 2px rgba(28,12,0,.5),0 2px 0 rgba(0,0,0,.4);
}
@media (max-width: 560px){
  .appbar .stamp{display:none;}
}
/* 44px is the minimum reliable touch target -- these were 38px, which is
   genuinely hard to hit accurately with work gloves on. */
.refresh-btn{
  background:linear-gradient(180deg,#2a3036,#1f2328);border:1px solid #3d444c;color:var(--text);
  width:44px;height:44px;border-radius:10px;display:flex;align-items:center;justify-content:center;
  flex-shrink:0;box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 2px 0 rgba(0,0,0,.4);
}
.refresh-btn .ic{width:22px;height:22px;}
.refresh-btn:active{background:var(--steel-700);box-shadow:inset 0 2px 4px rgba(0,0,0,.4);}
.refresh-btn.spinning .ic{animation:spin .7s linear;}
@keyframes spin{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}

/* Moving belt along the foot of the header -- the one bit of motion
   that's always in view. */
.belt{
  position:absolute;left:0;right:0;bottom:0;height:9px;overflow:hidden;
  background:#0b0d0f;border-top:1px solid #000;
}
.belt::before{
  content:'';position:absolute;top:0;bottom:0;left:-14px;right:0;
  background:var(--chevrons);
  animation:belt-run .8s linear infinite;will-change:transform;
}
@keyframes belt-run{to{transform:translateX(14px);}}

/* ---------- Metrics strip ---------- */
/* Cards previously scrolled off the right edge with no visual cue that
   more existed. scroll-snap makes swiping land cleanly on a card, and
   the fade on the right edge signals there's more to see. */
.metrics-strip{
  display:flex;gap:8px;overflow-x:auto;padding:10px 12px;
  background:linear-gradient(180deg,#121518,#15181c);
  border-bottom:1px solid #000;flex-shrink:0;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;scroll-snap-type:x proximity;position:relative;
}
.metrics-strip::-webkit-scrollbar{display:none;}
.metrics-wrap{position:relative;flex-shrink:0;}
.metrics-wrap::after{
  content:'';position:absolute;top:0;right:0;bottom:0;width:28px;pointer-events:none;
  background:linear-gradient(to right, transparent, var(--steel-900));
}
/* Styled as panel readouts: a status lamp that lights in the metric's
   colour, and a big tabular number that doesn't jitter as it changes. */
.metric-card{
  --lamp:var(--text);
  background:linear-gradient(180deg,#1a1e22,#14171a);border:1px solid #2c3238;border-radius:var(--radius);
  padding:10px 14px;min-width:112px;min-height:60px;flex-shrink:0;text-align:left;position:relative;
  -webkit-appearance:none;cursor:pointer;scroll-snap-align:start;color:var(--text);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04),inset 0 -2px 0 rgba(0,0,0,.35);
}
.metric-card::after{
  content:'';position:absolute;top:10px;right:10px;width:8px;height:8px;border-radius:50%;
  background:var(--lamp);box-shadow:0 0 8px var(--lamp);
}
.metric-card:active{background:var(--steel-700);}
.metric-card:hover{border-color:var(--steel-600);}
/* Active filter now visually obvious -- previously you couldn't tell
   which metric you'd tapped to filter by. */
.metric-card.active{
  border-color:var(--accent);background:linear-gradient(180deg,#262b30,#1d2125);
  box-shadow:inset 0 0 0 1px var(--accent),0 0 12px rgba(245,130,32,.18);
}
/* A zero count is not something to act on, so it recedes rather than
   competing visually with counts that actually need attention. */
.metric-card.is-zero{opacity:.45;}
.metric-card.is-zero .num{color:var(--text-faint);}
.metric-card.is-zero::after{background:var(--steel-600);box-shadow:none;}
.metric-card .num{
  font-family:var(--font-display);font-size:30px;font-weight:700;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--lamp);
}
.metric-card .lbl{
  font-family:var(--font-display);font-size:13px;font-weight:600;color:#b8c0c7;
  text-transform:uppercase;letter-spacing:.06em;margin-top:5px;padding-right:12px;
}
.metric-card.m-red{--lamp:var(--red);}
.metric-card.m-amber{--lamp:var(--amber);}
.metric-card.m-green{--lamp:var(--green);}
.metric-card.m-blue{--lamp:var(--blue);}
.metric-card.m-yellow{--lamp:var(--ready);}

/* ---------- Main content ---------- */
main{flex:1;overflow-y:auto;padding:12px 12px 90px 12px;-webkit-overflow-scrolling:touch;}
/* Caps line length on wide desktop windows. Without this a job
   description stretches the full monitor width, which is genuinely
   hard to scan -- the app is phone-first but gets used on desktop too. */
main > *{max-width:1100px;margin-left:auto;margin-right:auto;}
.section-title{
  font-family:var(--font-display);font-size:15px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  color:var(--text);margin:16px 0 8px 0;padding-left:9px;border-left:4px solid var(--accent);line-height:1.2;
  display:flex;align-items:center;justify-content:space-between;
}
.section-title .count-badge{
  background:#0b0d0f;color:var(--accent);font-size:13px;padding:2px 9px;border-radius:4px;
  border:1px solid #2c3238;font-variant-numeric:tabular-nums;
}
/* Fades out at the bottom edge so the backdrop isn't cut by a hard band. */
.sticky-bar{
  position:sticky;top:0;z-index:5;padding-top:2px;padding-bottom:6px;
  background:linear-gradient(var(--steel-950) 85%,rgba(15,18,21,0));
}

/* ---------- Focus banner ---------- */
.focus-banner{
  background:var(--hazard) 0 0/8px 100% no-repeat,var(--rivets),var(--plate);
  border:1px solid var(--line);border-radius:var(--radius);
  padding:12px 28px 12px 24px;margin-bottom:12px;box-shadow:var(--plate-shadow);
}
.focus-banner-head{
  font-family:var(--font-display);font-size:15px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;
  color:var(--accent);margin-bottom:8px;
}
.focus-jobs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px;}
.focus-job-chip{
  background:#111417;border:1px solid #2c3238;border-radius:6px;padding:5px 9px;
  font-family:var(--font-display);font-size:15px;font-weight:700;letter-spacing:.03em;
  display:inline-flex;align-items:center;gap:6px;
}
.focus-job-chip .fd{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;}
.focus-calm{color:var(--green);font-size:14px;font-weight:600;margin-bottom:10px;}

/* ---------- Buttons ---------- */
.btn{
  border:none;border-radius:8px;font-family:var(--font-display);font-weight:700;font-size:16px;
  letter-spacing:.05em;text-transform:uppercase;padding:11px 16px;
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-height:44px;
}
.btn-primary{
  background:linear-gradient(180deg,#ff9a3d,#f07812);color:var(--accent-ink);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 2px 0 #8a4204;
}
.btn-primary:active{background:#d9690b;box-shadow:inset 0 2px 4px rgba(0,0,0,.25);transform:translateY(1px);}
.btn-outline{background:rgba(255,255,255,.02);border:1.5px solid #4a525b;color:var(--text);}
.btn-outline:active{background:var(--steel-800);}
.btn-danger{
  background:linear-gradient(180deg,#ec5a48,#d63f2e);color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 2px 0 #7a2217;
}
.btn-ghost{background:var(--steel-800);color:var(--text);}
.btn-block{width:100%;}
.btn-sm{padding:9px 13px;font-size:15px;min-height:44px;}  /* raised to the 44px touch target -- was 40px */
.btn:disabled{background:var(--steel-700);color:var(--text-faint);cursor:not-allowed;box-shadow:none;transform:none;}
.fab-row{display:flex;gap:8px;margin-top:6px;}

/* Confirmation dialog body. Sized for reading at arm's length on a bench,
   with room above the buttons so a destructive one isn't tapped blind. */
.confirm-message{
  font-size:15px;line-height:1.5;color:var(--text);
  margin:0 0 16px 0;
}

/* ---------- Filter chips ---------- */
.chip-row{display:flex;gap:6px;overflow-x:auto;padding-bottom:4px;scrollbar-width:none;}
.chip-row::-webkit-scrollbar{display:none;}
.chip{
  flex-shrink:0;background:linear-gradient(180deg,#20252a,#1a1e22);border:1px solid var(--line);color:var(--text-dim);
  font-family:var(--font-display);font-size:15px;font-weight:700;padding:10px 16px;border-radius:22px;
  text-transform:uppercase;letter-spacing:.05em;
  min-height:44px;-webkit-appearance:none;  /* raised from 40px */
}
.chip.active{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);box-shadow:0 0 0 3px rgba(245,130,32,.15);}

/* ---------- Job cards ---------- */
.job-card{
  background:var(--plate);border:1px solid var(--line);border-left:6px solid var(--steel-600);
  border-radius:var(--radius);padding:14px;margin-bottom:12px;position:relative;cursor:pointer;
  box-shadow:var(--plate-shadow);
}
.job-card:active{background:var(--steel-700);}
.job-card.due-overdue{border-left-color:var(--red);background:linear-gradient(90deg,var(--red-bg),transparent 45%),var(--plate);}
.job-card.due-soon{border-left-color:var(--amber);background:linear-gradient(90deg,var(--amber-bg),transparent 45%),var(--plate);}
.job-card.due-ok{border-left-color:var(--green);}
.job-card.due-complete{border-left-color:var(--text-faint);opacity:.75;}
/* Card body sits in a row beside the blueprint thumbnail, so the drawing
   reads as the card's anchor rather than as decoration wedged between
   the customer name and the priority badge. */
.job-card-main{display:flex;gap:12px;align-items:flex-start;}
.job-card-body{flex:1;min-width:0;}
.job-card-top{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;}
.job-ident{min-width:0;}

/* Blueprint thumbnail. Fixed square so cards keep a consistent height
   whatever the drawing's aspect ratio; object-fit crops rather than
   distorting. Its own data-action beats the card's via .closest(). */
.job-thumb-btn{
  position:relative;flex-shrink:0;padding:0;border:none;background:none;
  width:84px;height:84px;border-radius:8px;overflow:hidden;cursor:pointer;
  display:block;-webkit-appearance:none;
}
.job-thumb{
  width:84px;height:84px;display:block;
  object-fit:cover;border-radius:8px;border:1px solid var(--steel-600);
  background:#fff;
}
/* Makes the thumbnail's tap target discoverable rather than relying on
   people guessing the picture is clickable. */
.job-thumb-hint{
  position:absolute;left:0;right:0;bottom:0;
  background:rgba(0,0,0,.72);color:var(--accent);
  font-family:var(--font-display);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;
  padding:3px 0;text-align:center;pointer-events:none;
}
.job-thumb-btn:active .job-thumb{opacity:.75;}
/* Placeholder keeps every card's text starting at the same x-position,
   whether or not a drawing has been scanned yet. */
.job-thumb-empty{
  width:84px;height:84px;flex-shrink:0;border-radius:8px;
  border:1px dashed var(--steel-600);
  background:linear-gradient(rgba(90,163,216,.08) 1px,transparent 1px) 0 0/12px 12px,
             linear-gradient(90deg,rgba(90,163,216,.08) 1px,transparent 1px) 0 0/12px 12px,#12161a;
  display:flex;align-items:center;justify-content:center;
  font-size:24px;opacity:.5;
}
@media (max-width: 560px){
  .job-thumb-btn, .job-thumb, .job-thumb-empty{width:64px;height:64px;}
}
.job-num{font-family:var(--font-display);font-weight:800;font-size:21px;letter-spacing:.03em;line-height:1.1;}
.job-cust{font-size:14px;color:var(--text-dim);margin-top:2px;}
.job-desc{font-size:14px;color:var(--text);margin-top:7px;line-height:1.45;}
.badge{
  font-family:var(--font-display);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;
  padding:2px 8px;border-radius:4px;border:1.5px solid currentColor;white-space:nowrap;
}
.badge-high{color:var(--red);background:var(--red-bg);}
.badge-medium{color:var(--amber);background:var(--amber-bg);}
.badge-low{color:var(--blue);background:var(--blue-bg);}
.job-meta-row{display:flex;flex-wrap:wrap;gap:12px;margin-top:10px;font-size:13px;color:var(--text-dim);}
.job-meta-row b{color:var(--text);font-weight:700;}
.due-tag{font-family:var(--font-display);font-weight:800;text-transform:uppercase;font-size:12px;letter-spacing:.06em;}
.due-tag.due-overdue{color:var(--red);}
.due-tag.due-soon{color:var(--amber);}
.due-tag.due-ok{color:var(--green);}
.due-tag.due-complete{color:var(--text-faint);}

.gauge{margin-top:10px;}
.gauge-track{
  height:12px;border-radius:5px;background:#101316;
  background-image:repeating-linear-gradient(90deg,transparent,transparent calc(10% - 1px),var(--steel-700) 10%);
  box-shadow:inset 0 1px 3px rgba(0,0,0,.5);
  overflow:hidden;position:relative;
}
.gauge-fill{
  height:100%;border-radius:5px 0 0 5px;transition:width .2s;
  background:repeating-linear-gradient(-45deg,var(--accent) 0 7px,#d86a10 7px 14px);
}
.gauge-label{font-family:var(--font-display);font-size:13px;color:var(--text-dim);margin-top:5px;text-align:right;font-weight:700;letter-spacing:.04em;}

.job-card-actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;align-items:center;}
/* Secondary buttons size to their content instead of stretching across
   a wide desktop card -- a full-width "Edit" button reads as more
   important than it is. Advance keeps priority since it's the action
   people are usually reaching for. */
.job-card-actions .btn{white-space:nowrap;}
.job-card-actions .btn-primary{flex:1;min-width:180px;}
@media (max-width: 560px){
  /* Narrow screens: let them share the row evenly so every target
     stays comfortably wide enough to hit with gloves on. */
  .job-card-actions .btn{flex:1;min-width:0;}
}

/* ---------- Board ---------- */
/* Each column reads as a numbered station on the line, with a belt
   running toward the next one. */
.board-wrap{
  display:flex;gap:10px;overflow-x:auto;padding-bottom:8px;-webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity;counter-reset:station;
  scrollbar-width:thin;scrollbar-color:var(--steel-600) transparent;
}
.board-col{
  flex:0 0 80vw;max-width:320px;scroll-snap-align:start;counter-increment:station;
  background:linear-gradient(180deg,#171a1e,#121518);
  border:1px solid #2c3238;border-radius:var(--radius);display:flex;flex-direction:column;max-height:100%;
  box-shadow:0 8px 20px rgba(0,0,0,.3);
}
.board-col-head{
  padding:10px 12px 18px;display:flex;justify-content:space-between;align-items:center;
  position:sticky;top:0;overflow:hidden;background:var(--plate);border-radius:var(--radius) var(--radius) 0 0;
}
.board-col-head::after{
  content:'';position:absolute;left:-14px;right:0;bottom:0;height:8px;
  background:var(--chevrons),#0b0d0f;
  animation:belt-run .8s linear infinite;will-change:transform;
}
.board-col-head .t{font-family:var(--font-display);font-size:16px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;line-height:1.15;}
.board-col-head .t::before{
  content:"STN " counter(station,decimal-leading-zero);display:block;
  font-size:11px;font-weight:800;letter-spacing:.16em;color:var(--accent);
}
.board-col-head .c{
  font-family:var(--font-display);font-size:14px;font-weight:700;color:var(--accent);
  background:#0b0d0f;border:1px solid #2c3238;padding:2px 9px;border-radius:4px;
}
.board-col-body{
  padding:8px;overflow-y:auto;flex:1;min-height:120px;
  background:repeating-linear-gradient(180deg,transparent 0 26px,rgba(255,255,255,.028) 26px 28px);
}
.board-col-body.drag-over{background:var(--steel-800);}
.board-card{
  background:var(--plate);border:1px solid var(--line);border-radius:8px;padding:9px 10px;margin-bottom:8px;
  cursor:grab;box-shadow:0 2px 0 rgba(0,0,0,.35);
}
.board-card:active{cursor:grabbing;}
.board-card .bn{font-family:var(--font-display);font-weight:800;font-size:17px;letter-spacing:.03em;}
.board-card .bc{font-size:12px;color:var(--text-dim);}
.board-card .ba{font-size:12px;color:var(--text-dim);margin-top:4px;}
.board-card-actions{display:flex;gap:6px;margin-top:8px;}
.icon-btn{
  background:var(--steel-700);border:none;color:var(--text);border-radius:6px;width:40px;height:40px;
  font-size:17px;display:flex;align-items:center;justify-content:center;flex-shrink:0;
}
.move-btn{
  flex:1;background:var(--steel-700);border:none;color:var(--text);border-radius:6px;height:40px;
  font-family:var(--font-display);font-size:14px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
}
.empty-col{color:var(--text-faint);font-size:13px;text-align:center;padding:16px 4px;}

/* ---------- Blockers ---------- */
.blocker-card{
  background:var(--plate);border:1px solid var(--line);border-left:5px solid var(--red);
  border-radius:var(--radius);padding:12px;margin-bottom:10px;box-shadow:var(--plate-shadow);
}
.blocker-card.resolved{border-left-color:var(--green);opacity:.7;}
.blocker-top{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;}
.sev-badge{
  font-family:var(--font-display);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;
  padding:2px 8px;border-radius:4px;color:#fff;flex-shrink:0;
}
.sev-critical{background:var(--red);}
.sev-high{background:#b5502f;}
.sev-medium{background:var(--amber);color:var(--accent-ink);}
.sev-low{background:var(--steel-600);}
.status-pill{
  font-family:var(--font-display);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;
  padding:4px 10px;border-radius:20px;border:1.5px solid currentColor;
}
.status-open{color:var(--red);}
.status-inprogress{color:var(--amber);}
.status-resolved{color:var(--green);}

/* ---------- Notes ---------- */
.note-card{
  background:var(--plate);border:1px solid var(--line);border-radius:var(--radius);padding:12px;margin-bottom:10px;
  box-shadow:var(--plate-shadow);
}
.note-head{display:flex;justify-content:space-between;font-size:12px;color:var(--text-dim);margin-bottom:6px;}
.note-type-tag{
  font-family:var(--font-display);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;
  padding:1px 7px;border-radius:4px;margin-right:6px;
}
.note-progress{background:var(--blue-bg);color:var(--blue);}
.note-issue{background:var(--red-bg);color:var(--red);}
.note-next{background:var(--green-bg);color:var(--green);}
.note-body{font-size:14px;line-height:1.45;}
.note-author{font-size:12px;color:var(--text-faint);margin-top:6px;font-style:italic;}

/* ---------- Activity log ---------- */
.act-row{
  background:var(--plate);border:1px solid var(--line);border-left:3px solid var(--steel-600);
  border-radius:8px;padding:10px 12px;margin-bottom:8px;
}
.act-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:3px;}
.act-who{font-family:var(--font-display);font-size:15px;font-weight:800;letter-spacing:.03em;color:var(--accent);}
.act-when{font-size:11px;color:var(--text-faint);white-space:nowrap;}
.act-action{font-size:13px;font-weight:700;}
.act-detail{font-size:13px;color:var(--text-dim);margin-top:2px;line-height:1.4;word-break:break-word;}

/* ---------- Forms / Modal ---------- */
.modal-overlay{
  position:fixed;inset:0;background:rgba(0,0,0,.65);display:flex;align-items:flex-end;justify-content:center;
  z-index:200;
}
.modal-sheet{
  background:var(--hazard) 0 0/100% 6px no-repeat,linear-gradient(180deg,#1b1f24,#15181c);
  border-radius:16px 16px 0 0;box-shadow:0 -10px 40px rgba(0,0,0,.5);
  width:100%;max-width:520px;max-height:90vh;overflow-y:auto;padding:20px 16px calc(20px + env(safe-area-inset-bottom));
}
.modal-title{
  font-family:var(--font-display);font-size:21px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;
  margin-bottom:12px;display:flex;justify-content:space-between;align-items:center;
}
.modal-close{background:var(--steel-800);border:none;color:var(--text);width:36px;height:36px;border-radius:8px;font-size:16px;}
.field{margin-bottom:12px;}
.field label{
  display:block;font-family:var(--font-display);font-size:13px;font-weight:700;text-transform:uppercase;
  letter-spacing:.08em;color:var(--text-dim);margin-bottom:5px;
}
.field input,.field select,.field textarea{
  width:100%;background:#111417;border:1.5px solid var(--steel-600);color:var(--text);
  border-radius:8px;padding:12px;font-size:16px;font-family:inherit;
  box-shadow:inset 0 2px 4px rgba(0,0,0,.35);
}
.field textarea{min-height:70px;resize:vertical;}
.field input:focus,.field select:focus,.field textarea:focus{outline:2px solid var(--accent);border-color:var(--accent);}
.preset-row{display:flex;gap:6px;margin-top:8px;}
.preset-row button{
  flex:1;background:var(--steel-700);border:none;color:var(--text);border-radius:6px;padding:8px 4px;
  font-size:13px;font-weight:700;min-height:36px;
}
.stage-picker{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.stage-picker button{
  background:var(--plate);border:1.5px solid var(--steel-600);color:var(--text);border-radius:8px;
  padding:12px 8px;font-family:var(--font-display);font-size:15px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;min-height:48px;
}
.stage-picker button.current{border-color:var(--accent);color:var(--accent);}

/* ---------- Sign-in / account screens ---------- */
/* Full-screen rather than a bottom sheet: it's the first thing anyone
   sees, and there is nothing behind it to peek at until they're signed in. */
body:has(.auth-screen) #app{visibility:hidden;}
body:has(.auth-screen) .cv-main{opacity:.42;}
body:has(.auth-screen) .cv-incline{opacity:.24;}
.modal-overlay.auth-screen{
  align-items:flex-start;overflow-y:auto;
  background:radial-gradient(ellipse at 50% 45%,rgba(15,18,21,.2),rgba(15,18,21,.7));
  padding:calc(24px + env(safe-area-inset-top)) 16px calc(24px + env(safe-area-inset-bottom));
}
/* Auto margins centre the stack when it fits and collapse to zero when the
   signup form is taller than the screen, so the top never gets clipped. */
.auth-stack{margin:auto;width:100%;max-width:420px;}
.auth-brand{text-align:center;margin-bottom:18px;}
.auth-logo{
  display:block;margin:0 auto 12px;width:88px;height:88px;border-radius:20px;
  box-shadow:0 10px 28px rgba(0,0,0,.55),0 0 0 1px rgba(0,0,0,.4);
}
.auth-name{
  font-family:var(--font-display);font-weight:800;font-size:30px;letter-spacing:.06em;
  text-transform:uppercase;line-height:1.05;text-shadow:0 2px 12px rgba(0,0,0,.6);
}
.auth-sub{
  display:inline-block;margin-top:8px;background:var(--accent);color:var(--accent-ink);
  font-family:var(--font-display);font-weight:800;font-size:13px;letter-spacing:.14em;text-transform:uppercase;
  padding:4px 10px;border-radius:4px;box-shadow:inset 0 0 0 2px rgba(28,12,0,.5);
}
.auth-screen .modal-sheet{
  max-width:none;max-height:none;overflow:visible;border-radius:14px;border:1px solid #2f353c;
  padding:24px 20px 20px;
  background:var(--hazard) 0 0/100% 6px no-repeat,var(--rivets),linear-gradient(180deg,#1d2126,#16191d);
  box-shadow:0 24px 60px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,255,255,.05);
}

/* ---------- Assistant ---------- */
.chat-log{display:flex;flex-direction:column;gap:10px;margin-bottom:12px;}
.chat-msg{max-width:92%;padding:10px 12px;border-radius:10px;font-size:14px;line-height:1.5;white-space:pre-wrap;}
.chat-msg.user{align-self:flex-end;background:var(--accent);color:var(--accent-ink);font-weight:600;}
.chat-msg.ai{align-self:flex-start;background:var(--plate);border:1px solid var(--line);display:flex;flex-direction:column;align-items:flex-start;gap:8px;}
.chat-msg.ai.loading{color:var(--text-dim);font-style:italic;}
.copy-btn{
  background:var(--steel-700);border:none;color:var(--text-dim);font-family:var(--font-display);font-size:13px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;padding:6px 11px;border-radius:6px;align-self:flex-start;
}
.prompt-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px;}
.prompt-grid button{
  background:var(--plate);border:1px solid var(--line);color:var(--text);border-radius:8px;
  padding:10px 8px;font-size:13px;font-weight:600;text-align:left;min-height:56px;line-height:1.3;
}
.chat-input-row{
  display:flex;gap:8px;position:sticky;bottom:0;padding-top:12px;
  background:linear-gradient(to top,var(--steel-950) 80%,rgba(15,18,21,0));
}
.chat-input-row input{
  flex:1;background:#111417;border:1.5px solid var(--steel-600);color:var(--text);
  border-radius:8px;padding:12px;font-size:16px;box-shadow:inset 0 2px 4px rgba(0,0,0,.35);
}
.chat-input-row input:focus{outline:2px solid var(--accent);border-color:var(--accent);}

/* ---------- Tab bar ---------- */
.tabbar{
  position:fixed;bottom:0;left:0;right:0;display:flex;
  background:linear-gradient(180deg,#1b1f23,#121518);
  border-top:1px solid #000;box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 -8px 20px rgba(0,0,0,.35);
  padding-bottom:env(safe-area-inset-bottom);z-index:100;
}
/* Was --text-faint (#6b737b) at 9px -- inactive tabs were genuinely hard
   to read. Brighter inactive colour, slightly larger text, and a top
   accent bar so the active tab is obvious at a glance rather than
   relying on colour alone (which also helps if someone's colour-blind). */
.tab-btn{
  flex:1;background:none;border:none;color:#8d959d;display:flex;flex-direction:column;
  align-items:center;gap:4px;padding:9px 1px 8px;font-family:var(--font-display);font-size:12px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;min-height:60px;position:relative;min-width:0;
}
.tab-btn .ic{width:24px;height:24px;}
/* The label is wrapped so it can be sized and, as a last resort,
   truncated. Seven tabs at 12px with letter-spacing overflowed their
   share of a phone's width and ran into each other -- "ASSISTANT" and
   "ACTIVITY" arrived as one word. Tightened below, and ellipsised
   rather than allowed to collide on anything narrower still. */
.tab-btn .tab-lbl{
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
@media (max-width:480px){
  /* 9px so all seven labels fit as whole words: a truncated "ASSISTA..."
     is harder to read at a glance than the same word one point smaller,
     and the ellipsis above is only the backstop for narrower still. */
  .tab-btn{font-size:9px;letter-spacing:0;padding-left:0;padding-right:0;gap:3px;}
  .tab-btn .ic{width:22px;height:22px;}
}
.tab-btn.active{color:var(--accent);background:linear-gradient(180deg,rgba(245,130,32,.12),rgba(245,130,32,0) 70%);}
.tab-btn.active .ic{filter:drop-shadow(0 0 6px rgba(245,130,32,.5));}
.tab-btn.active::before{
  content:'';position:absolute;top:0;left:12%;right:12%;height:3px;
  background:var(--accent);border-radius:0 0 3px 3px;
}
.tab-btn .dot{
  position:absolute;top:4px;right:calc(50% - 20px);width:8px;height:8px;background:var(--red);
  border-radius:50%;box-shadow:0 0 6px var(--red);
}

.empty-state{text-align:center;padding:40px 20px;color:var(--text-faint);}
.empty-state .big{font-size:32px;margin-bottom:8px;}
.hidden{display:none !important;}
.search-input{
  width:100%;background:#111417;border:1.5px solid var(--steel-600);color:var(--text);
  border-radius:8px;padding:11px 12px;font-size:16px;margin-bottom:10px;font-family:inherit;
  box-shadow:inset 0 2px 4px rgba(0,0,0,.35);
}
.search-input:focus{outline:2px solid var(--accent);border-color:var(--accent);}

/* ---------- Blueprint extraction ---------- */
.field input[type=file]{
  background:var(--steel-800);border:1.5px dashed var(--steel-600);padding:12px;color:var(--text-dim);font-size:13px;
}
.bp-preview-img{
  width:100%;max-height:220px;object-fit:contain;border-radius:8px;border:1px solid var(--line);
  background:var(--steel-800);margin-top:10px;
}
.bp-file-chip{
  background:var(--steel-800);border:1px solid var(--line);border-radius:8px;padding:10px 12px;
  font-size:13px;margin-top:10px;
}
.bom-list{display:flex;flex-direction:column;gap:8px;}
.bom-row{background:var(--plate);border:1px solid var(--line);border-radius:8px;padding:10px 12px;}
.bom-item{font-weight:700;font-size:14px;}
.bom-spec{font-size:13px;color:var(--text-dim);margin-top:2px;}
/* The drawing's own wording. Monospaced and quoted so it reads as copied
   text rather than one of our labels -- it should look like the paper. */
.bom-drawn{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:12px;color:var(--text-dim);margin-top:3px;letter-spacing:.01em;
  border-left:2px solid var(--steel-600);padding-left:7px;
}
.bom-partno{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11px;color:var(--text-faint);margin-top:3px;letter-spacing:.02em;
}
.bom-qty{font-family:var(--font-display);font-size:13px;color:var(--text-faint);margin-top:4px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;}
.bp-hint{font-size:12px;color:var(--text-faint);margin-top:6px;line-height:1.4;}
.bp-preview-img{cursor:zoom-in;}

/* ---------- A job's own page ---------- */
.job-page{padding-bottom:8px;}
.job-page-bar{
  display:flex;align-items:center;gap:10px;margin:0 0 12px 0;padding-bottom:10px;
  border-bottom:1px solid var(--line);
}
.job-page-title{
  font-family:var(--font-display);font-size:22px;font-weight:800;letter-spacing:.02em;
  text-transform:uppercase;margin-right:auto;
}

/* ---------- Callout diagram: the real drawing, ballooned ----------
   The sheet keeps a gutter either side for labels; leader lines are an
   SVG stretched over the whole box, so its user units are percentages
   and the line ends line up with the absolutely-positioned labels. */
/* The drawing alone sets this box's height, and that is load-bearing:
   every leader line's endpoints are percentages of THIS box, and the
   part it points at is a percentage of the drawing. Pad the box out or
   centre the drawing inside it and the two stop agreeing -- the leaders
   then stop short in mid-air while the arrows sit somewhere else. */
.cv-diagram{position:relative;margin-bottom:10px;}
/* Stacking matters here: a leader line runs from the margin to a part in
   the middle of the sheet, so nearly all of it lies OVER the drawing. The
   sheet comes first in the DOM and would otherwise paint on top of every
   line, hiding the lot. */
.cv-sheet-wrap{position:relative;display:block;z-index:1;}
.cv-leaders{z-index:2;}
.cv-arrows,.cv-tag,.cv-label{z-index:3;}
/* Arrows live over the sheet, in its own coordinate space. */
.cv-arrows{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;}
.cv-sheet{
  display:block;width:100%;height:auto;border-radius:6px;
  background:var(--steel-950);border:1px solid var(--line);
}
/* Cropped to the machine: this box IS the frame, and the sheet inside is
   scaled up and shifted so the frame is what shows through. */
.cv-sheet-crop{
  position:relative;overflow:hidden;width:100%;border-radius:6px;
  background:var(--steel-950);border:1px solid var(--line);
}
.cv-sheet-zoom{
  position:absolute;max-width:none;height:auto;border:0;border-radius:0;
}
.cv-under{display:flex;justify-content:flex-end;margin:-2px 0 8px 0;}
.cv-leaders{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;opacity:.9;}
/* The number sits at the far end of the arrow, clear of the part. Only
   shown where there's no margin label to carry it -- see the phone rules
   below. Small: it identifies the arrow, it isn't the callout itself. */
.cv-tag{
  display:none;position:absolute;transform:translate(-50%,-50%);
  min-width:15px;height:15px;padding:0 3px;border-radius:8px;
  align-items:center;justify-content:center;
  font-family:var(--font-display);font-size:10px;font-weight:800;color:#0d0f11;
  box-shadow:0 0 0 1.5px rgba(0,0,0,.5);
}
.cv-label{
  position:absolute;transform:translateY(-50%);width:var(--cv-gutter,21%);
  display:flex;align-items:flex-start;gap:5px;font-size:11px;line-height:1.25;
}
.cv-label-left{left:0;justify-content:flex-start;}
.cv-label-right{right:0;}
.cv-num{
  flex-shrink:0;min-width:17px;height:17px;padding:0 3px;border-radius:9px;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-size:11px;font-weight:800;color:#0d0f11;
}
.cv-label-text{min-width:0;}
.cv-label-item{display:block;font-weight:700;}
.cv-label-drawn{
  display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:10px;color:var(--text-faint);word-break:break-word;
}
.cv-label-qty{color:var(--text-faint);font-weight:600;font-variant-numeric:tabular-nums;}
.cv-diagram-empty{
  padding:16px;text-align:center;font-size:12px;color:var(--text-faint);
  border:1px dashed var(--line);border-radius:8px;margin-bottom:10px;
}
.cv-pages{margin-bottom:8px;}
/* Wide enough for margins: labels live in the gutters, legend is redundant. */
.cv-legend{display:none;}

@media (max-width:700px){
  /* No room for margins on a phone: the sheet takes the full width and
     the labels become a numbered legend under it. The balloons carry the
     same numbers, so it reads the same either way. */
  .cv-sheet-wrap{margin-left:0 !important;width:100% !important;}
  .cv-leaders,.cv-label{display:none;}
  /* No margin label to hold the number here, so it rides the arrow. */
  .cv-tag{display:flex;}
  .cv-legend{
    display:grid;grid-template-columns:1fr 1fr;gap:6px 10px;
    list-style:none;padding:10px 0 0 0;margin:0;
  }
  .cv-legend-row{display:flex;align-items:flex-start;gap:5px;font-size:11px;line-height:1.25;}
}
@media (max-width:420px){
  .cv-legend{grid-template-columns:1fr;}
}

/* ---------- Component map: pins on the real scanned drawing ---------- */
.bp-map{position:relative;width:100%;margin-bottom:10px;border-radius:8px;overflow:hidden;background:var(--steel-950);border:1px solid var(--line);}
.bp-map-img{display:block;width:100%;height:auto;}
.bp-pin{position:absolute;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;max-width:120px;}
.bp-pin-dot{width:11px;height:11px;border-radius:50%;box-shadow:0 0 0 3px rgba(0,0,0,.55),0 0 0 4px rgba(255,255,255,.25);}
.bp-pin-label{
  margin-top:3px;font-size:10px;font-weight:700;line-height:1.2;text-align:center;white-space:nowrap;
  text-shadow:0 1px 2px rgba(0,0,0,.9),0 0 4px rgba(0,0,0,.9);
}

/* ---------- Fullscreen blueprint viewer ---------- */
.bp-fullscreen{
  position:fixed;inset:0;background:#0b0d0f;z-index:400;display:flex;flex-direction:column;
}
.bp-fs-bar{
  display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 12px;
  background:var(--steel-900);border-bottom:1px solid var(--line);flex-shrink:0;
}
.bp-fs-title{font-family:var(--font-display);font-size:16px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;}
.bp-fs-stage{flex:1;overflow:hidden;position:relative;touch-action:none;background:#0b0d0f;}
.bp-fs-img{
  position:absolute;top:0;left:0;transform-origin:0 0;user-select:none;-webkit-user-drag:none;
  max-width:none;
}
.bp-fs-hint{
  position:absolute;bottom:12px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.65);
  color:var(--text-dim);font-size:11px;padding:6px 12px;border-radius:20px;pointer-events:none;
}

.model-swatch{width:10px;height:10px;border-radius:3px;flex-shrink:0;}
.eng-table{background:var(--steel-900);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;margin-bottom:10px;}
.eng-group{font-family:var(--font-display);font-size:13px;font-weight:800;letter-spacing:.08em;color:var(--accent);background:var(--steel-800);padding:7px 12px;text-transform:uppercase;}
.eng-row{display:grid;grid-template-columns:1fr auto;gap:2px 10px;padding:8px 12px;border-bottom:1px solid var(--steel-800);}
.eng-row:last-child{border-bottom:none;}
.eng-label{font-size:13px;color:var(--text-dim);}
.eng-val{font-size:14px;font-weight:700;text-align:right;}
.eng-extra{font-size:11px;color:var(--text-faint);font-weight:400;}
.eng-meta{grid-column:1/-1;display:flex;gap:8px;align-items:center;}
.eng-src{font-size:11px;color:var(--text-faint);}
.cf{font-family:var(--font-display);font-size:11px;font-weight:800;padding:1px 6px;border-radius:4px;letter-spacing:.06em;}
.cf-high{background:var(--green-bg);color:var(--green);}
.cf-med{background:var(--amber-bg);color:var(--amber);}
.cf-low{background:var(--steel-700);color:var(--text-dim);}
.cf-inf{background:var(--blue-bg);color:var(--blue);}
.cf-none{background:var(--steel-800);color:var(--text-faint);}
.cf-conflict{background:var(--red-bg);color:var(--red);}
.val-box{border-radius:var(--radius);padding:10px 12px;margin-bottom:10px;border:1px solid var(--line);}
.val-box.val-ok{background:var(--green-bg);border-color:var(--green);}
.val-box.val-warn{background:var(--amber-bg);border-color:var(--amber);}
.val-box.val-conflict,.val-box.val-bad{background:var(--red-bg);border-color:var(--red);}
.val-head{font-family:var(--font-display);font-size:14px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;margin-bottom:6px;}
.val-line{font-size:13px;line-height:1.45;margin-bottom:3px;}
.vc-error,.vc-conflict{color:var(--red);}
.vc-warn{color:var(--amber);}
.vc-ok{color:var(--green);}
.bom-group-head{
  font-family:var(--font-display);font-size:14px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--accent);
  margin:12px 0 6px 0;display:flex;align-items:center;gap:7px;
}

/* ---------- Procedure checklist ---------- */
.checklist-progress{
  background:var(--plate);border:1px solid var(--line);border-radius:var(--radius);padding:10px 12px;
  margin-bottom:14px;
}
.checklist-progress .cp-label{font-family:var(--font-display);font-size:13px;color:var(--text-dim);font-weight:700;text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px;display:flex;justify-content:space-between;}
.checklist-step{margin-bottom:16px;}
.checklist-step-head{
  font-family:var(--font-display);font-size:15px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--accent);
  margin-bottom:8px;display:flex;justify-content:space-between;align-items:center;
}
.checklist-item{
  display:flex;align-items:flex-start;gap:10px;padding:9px 4px;border-bottom:1px solid var(--steel-800);
  cursor:pointer;
}
.checklist-item:last-child{border-bottom:none;}
.checklist-check{
  flex-shrink:0;width:22px;height:22px;border-radius:6px;border:1.5px solid var(--steel-600);
  display:flex;align-items:center;justify-content:center;margin-top:1px;font-size:14px;font-weight:800;
}
.checklist-item.done .checklist-check{background:var(--green);border-color:var(--green);color:#0c1f0e;}
.checklist-item.done .checklist-text{color:var(--text-faint);text-decoration:line-through;}
.checklist-text{font-size:14px;line-height:1.4;}
.checklist-badge{
  font-family:var(--font-display);font-size:12px;font-weight:800;padding:1px 8px;border-radius:20px;background:var(--steel-700);color:var(--text-dim);
  margin-left:6px;letter-spacing:.04em;
}
.checklist-badge.complete{background:var(--green-bg);color:var(--green);}
.toast{
  position:fixed;bottom:80px;left:50%;transform:translateX(-50%);
  background:linear-gradient(180deg,#2a3036,#22272c);border:1px solid #3d444c;border-left:4px solid var(--accent);
  color:var(--text);padding:10px 18px;border-radius:10px;font-size:14px;font-weight:600;z-index:300;
  box-shadow:0 8px 24px rgba(0,0,0,.5);max-width:88vw;text-align:center;
}

/* ---------- BOM edit mode (add/remove/reorder components) ---------- */
/* The AI scanner isn't always right, so the hardware list is editable.
   These styles only apply in edit mode -- read-only rows are unchanged. */
.bom-row-editing{
  display:flex;align-items:center;gap:10px;
  background:var(--steel-800);border:1px solid var(--line);
  border-radius:8px;padding:10px;margin-bottom:6px;
}
.bom-row-main{flex:1;min-width:0;}
.bom-row-controls{display:flex;gap:6px;flex-shrink:0;}
/* 40px squares -- big enough to hit reliably with gloves on, which is
   the whole point of these being buttons rather than a drag handle. */
.bom-row-btn{
  width:40px;height:40px;border-radius:8px;
  background:var(--steel-700);border:1px solid var(--steel-600);
  color:var(--text);font-size:16px;line-height:1;
  display:flex;align-items:center;justify-content:center;
  -webkit-appearance:none;flex-shrink:0;
}
.bom-row-btn:active{background:var(--steel-600);}
.bom-row-btn:disabled{opacity:.3;}
.bom-row-btn-danger{color:var(--red);border-color:#5a2a24;}
.bom-add-form{
  display:flex;gap:6px;flex-wrap:wrap;align-items:center;
  padding:8px;margin:0 0 14px 0;
  background:var(--steel-900);border:1px dashed var(--steel-600);border-radius:8px;
}
.bom-add-form input{
  flex:1;min-width:110px;
  background:var(--steel-800);border:1px solid var(--line);color:var(--text);
  border-radius:6px;padding:10px;font-size:16px;   /* 16px avoids iOS zoom-on-focus */
  min-height:44px;-webkit-appearance:none;
}
.bom-add-form input::placeholder{color:var(--text-faint);}
/* Marks components a person typed in, vs. ones the scanner extracted. */
.chip-tiny{
  display:inline-block;font-family:var(--font-display);font-size:11px;font-weight:700;text-transform:uppercase;
  letter-spacing:.06em;padding:1px 6px;border-radius:10px;
  background:var(--steel-700);color:var(--text-dim);vertical-align:middle;margin-left:4px;
}

/* Category dropdown on each BOM row -- lets a mis-scanned part be moved
   to the right category, which the up/down arrows can't do (they only
   reorder within one category, and categories are often a single item). */
.bom-category-select{
  width:100%;margin-top:8px;
  background:var(--steel-900);border:1px solid var(--steel-600);color:var(--text);
  border-radius:6px;padding:9px 8px;font-size:14px;min-height:44px;
  -webkit-appearance:none;appearance:none;
}

/* ---------- Part tips (help for new assemblers) ---------- */
/* Blue is the info colour here, so a tip never reads as a warning
   (amber/red) or an action (yellow). Tap targets stay 40px+ for gloves. */
.tip-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px;}
.tip-chip{
  background:var(--steel-800);border:1px solid var(--line);color:var(--blue);
  border-radius:20px;padding:0 12px;min-height:40px;font-size:13px;font-weight:700;
  -webkit-appearance:none;
}
.tip-chip.active,.tip-btn.active{background:var(--blue-bg);border-color:var(--blue);}
.tip-card{
  background:var(--blue-bg);border:1px solid var(--line);border-left:3px solid var(--blue);
  border-radius:8px;padding:10px 12px;margin-bottom:10px;
}
.tip-name{font-size:14px;font-weight:800;margin-bottom:4px;}
.tip-aka{font-size:12px;font-weight:600;color:var(--text-dim);}
.tip-line{display:grid;grid-template-columns:64px 1fr;gap:8px;font-size:13px;line-height:1.4;margin-top:4px;}
.tip-line b{font-family:var(--font-display);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--blue);padding-top:2px;}
/* Hardware row with a tip: info button on the right, card drops in below. */
.bom-row-tip{display:flex;flex-wrap:wrap;align-items:flex-start;column-gap:10px;}
.bom-row-tip .tip-slot{flex-basis:100%;}
.bom-row-tip .tip-card{margin:10px 0 0 0;}
.tip-btn{
  width:40px;height:40px;border-radius:8px;flex-shrink:0;
  background:var(--steel-700);border:1px solid var(--steel-600);color:var(--blue);
  font-size:18px;line-height:1;display:flex;align-items:center;justify-content:center;
  -webkit-appearance:none;
}
/* "Look up a part" -- for parts no checklist step names. 16px avoids iOS zoom-on-focus. */
.tip-guide{margin:0 0 16px 0;}
.tip-guide-select{
  width:100%;background:var(--steel-800);border:1px solid var(--steel-600);color:var(--blue);
  border-radius:8px;padding:9px 10px;font-size:16px;font-weight:700;min-height:44px;
  -webkit-appearance:none;appearance:none;
}
.tip-guide-select option{color:var(--text);background:var(--steel-800);}
.tip-guide .tip-card{margin:8px 0 0 0;}

/* ---------- Admin dashboard ---------- */
.admin-head{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
.admin-title{
  font-family:var(--font-display);font-size:24px;font-weight:800;
  text-transform:uppercase;letter-spacing:.06em;
}
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));gap:8px;margin-bottom:10px;}
/* Four tiles land 3-across on a phone, leaving the fourth orphaned on a
   row of its own. Two-by-two divides evenly. Only for sets of four --
   the admin dashboard's five are better off as they are. */
@media (max-width:480px){
  .stat-grid-4{grid-template-columns:repeat(2,1fr);}
}
.stat-note{
  font-size:11px;color:var(--text-faint);margin-top:3px;line-height:1.3;
}
.stat-tile{
  background:var(--plate);border:1px solid var(--line);border-radius:var(--radius);
  padding:10px 12px;box-shadow:var(--plate-shadow);
}
.stat-tile .n{font-family:var(--font-display);font-size:28px;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;}
.stat-tile .l{
  font-family:var(--font-display);font-size:12px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--text-dim);margin-top:4px;
}
.team-row{
  background:var(--plate);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px;margin-bottom:8px;box-shadow:var(--plate-shadow);
}
.team-row.inactive{opacity:.55;}
.team-top{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;}
.team-name{font-family:var(--font-display);font-size:19px;font-weight:800;letter-spacing:.02em;}
.team-meta{font-size:12px;color:var(--text-faint);margin-top:2px;}
.team-controls{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap;align-items:center;}
.team-controls select{
  flex:1;min-width:150px;background:#111417;border:1.5px solid var(--steel-600);color:var(--text);
  border-radius:8px;padding:10px;font-size:16px;min-height:44px;font-family:inherit;
}
.team-controls select:disabled{opacity:.5;}
.role-tag{
  font-family:var(--font-display);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;
  padding:2px 8px;border-radius:4px;border:1.5px solid currentColor;white-space:nowrap;
}
.role-admin{color:var(--accent);background:rgba(245,130,32,.12);}
.role-a{color:var(--green);background:var(--green-bg);}
.role-b{color:var(--blue);background:var(--blue-bg);}
.role-lead{color:var(--ready);background:rgba(245,180,0,.1);}
/* Audit detail is machine-written, so it gets a monospace block rather
   than being reflowed as prose. */
.audit-detail{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.5;
  color:var(--text-dim);background:#0e1114;border:1px solid var(--line);border-radius:6px;
  padding:8px 10px;margin-top:6px;white-space:pre-wrap;word-break:break-word;
}
.filter-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px;}
.filter-grid .full{grid-column:1/-1;}
.filter-grid select,.filter-grid input{
  width:100%;background:#111417;border:1.5px solid var(--steel-600);color:var(--text);
  border-radius:8px;padding:10px;font-size:16px;min-height:44px;font-family:inherit;
  box-shadow:inset 0 2px 4px rgba(0,0,0,.35);
}
.filter-grid select:focus,.filter-grid input:focus{outline:2px solid var(--accent);border-color:var(--accent);}

/* Motion is decoration here, never information -- honour the OS setting. */
@media (prefers-reduced-motion: reduce){
  .cv-screw,.belt::before,.board-col-head::after{animation:none;}
}

/* ---------- Error log (engineering / purchasing) ---------- */
.err-card{
  background:var(--plate);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px;margin-bottom:8px;box-shadow:var(--plate-shadow);
  /* The department's colour down the edge, so a scan of the list reads
     as "who" before you read a word of it. */
  border-left:3px solid var(--line);
}
.err-card.corrected{opacity:.62;}
.err-top{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:6px;}
.err-dept{
  font-family:var(--font-display);font-size:11px;font-weight:800;text-transform:uppercase;
  letter-spacing:.06em;color:#14181c;padding:3px 8px;border-radius:999px;white-space:nowrap;
}
.err-cat{font-family:var(--font-display);font-size:14px;font-weight:700;margin-bottom:4px;}
.err-cost{
  font-family:var(--font-display);font-size:12px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--accent);margin-top:6px;
}
.err-fix{
  font-size:12px;color:var(--text-dim);margin-top:6px;line-height:1.45;
  border-left:2px solid var(--steel-600);padding-left:8px;
}
.err-check{
  display:flex;align-items:center;gap:9px;font-size:13px;color:var(--text-dim);
  padding:8px 2px;cursor:pointer;
}
.err-check input{width:18px;height:18px;flex:none;}

/* A bar per row, sized against the largest, so the shape of the data
   reads without pulling in a chart library for four lists.

   One line per row: label, bar, count. Stacking the label above the
   track cost two lines to use a sliver of the width and left a wide
   empty gap between the label and its number -- the bar goes there. */
/* One grid per chart, three columns: label, bar, count. The label column
   is max-content, so it is exactly as wide as the longest label in THAT
   chart -- a fixed percentage left a dead gap between a short label like
   "Testing" and the start of its bar. Every bar still begins at the same
   x, which is the whole point: bars you cannot line up cannot be
   compared. */
.err-bars{
  display:grid;grid-template-columns:minmax(0,max-content) minmax(80px,1fr) auto;
  column-gap:12px;row-gap:8px;align-items:center;margin-bottom:4px;
}
.err-bar-label{min-width:0;font-size:13px;line-height:1.25;}
.err-bar-sub{display:block;font-size:11px;color:var(--text-faint);}
.err-bar-track{height:8px;border-radius:4px;background:var(--steel-800);overflow:hidden;}
.err-bar-fill{height:100%;border-radius:4px;}
.err-bar-n{
  min-width:1.4em;text-align:right;
  font-family:var(--font-display);font-variant-numeric:tabular-nums;font-size:14px;
}
@media (max-width:480px){
  /* A long category name would otherwise take the whole row on a phone
     and leave the bar a stub, so the column is capped and truncates. */
  .err-bars{grid-template-columns:minmax(0,42%) minmax(48px,1fr) auto;column-gap:9px;}
  .err-bar-label{font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .err-bar-sub{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
}

/* Counts baked into the department filter chips -- what "by department"
   used to need a whole chart for. */
.chip-dot{
  display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;
  vertical-align:baseline;
}
.chip-n{
  margin-left:6px;font-variant-numeric:tabular-nums;opacity:.7;font-weight:800;
}
.err-breakdown{
  border-left:2px solid var(--line);padding-left:10px;margin:2px 0 4px;
}

/* ---------- AI provider connection test ---------- */
.ai-test{
  background:var(--plate);border:1px solid var(--line);border-radius:var(--radius);
  padding:12px;margin-bottom:10px;box-shadow:var(--plate-shadow);
}
.ai-test-title{
  font-family:var(--font-display);font-size:13px;font-weight:800;text-transform:uppercase;
  letter-spacing:.06em;margin-bottom:8px;
}
.ai-test-row{border-left:2px solid var(--line);padding:0 0 0 9px;margin-bottom:9px;}
.ai-test-row.ok{border-left-color:var(--green);}
.ai-test-row.bad{border-left-color:var(--red);}
.ai-test-head{font-size:13px;font-weight:700;}
.ai-test-row.ok .ai-test-head{color:var(--green);}
.ai-test-row.bad .ai-test-head{color:var(--red);}
.ai-test-detail{font-size:12px;color:var(--text-dim);line-height:1.45;margin-top:2px;}
/* The provider's own words, monospaced and selectable so they can be
   copied into a search or a support ticket verbatim. */
.ai-test-raw{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11px;color:var(--text-faint);line-height:1.45;margin-top:4px;
  white-space:pre-wrap;word-break:break-word;user-select:text;
}
