:root {
  --bg: #0A0D10; --panel: #14181C; --panel2: #101317; --sunk: #0D1014;
  --line: #23282D; --line2: #1C2126; --text: #E9E6E0; --dim: #8A9099; --dim2: #B9BEC4;
  --accent: #FF5A1F; --teal: #7FE0C4; --amber: #F5B544; --shadow: 0 18px 40px rgba(0,0,0,.45);
  --gridline: rgba(255,255,255,.028);
}
[data-theme="light"] {
  --bg: #F1EFEA; --panel: #FFFFFF; --panel2: #FAF8F4; --sunk: #EDEAE3;
  --line: #DBD6CC; --line2: #E7E3DA; --text: #171B1F; --dim: #6C737B; --dim2: #3B4147;
  --accent: #CC3F19; --teal: #0C7F63; --amber: #A9720A; --shadow: 0 14px 34px rgba(30,26,20,.12);
  --gridline: rgba(23,27,31,.045);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: var(--bg); }
body { -webkit-font-smoothing: antialiased; font-family: Archivo, sans-serif; color: var(--text); }
a { color: var(--accent); text-decoration: none; }
input, select, button { font-family: inherit; }
select { appearance: none; }
.mono { font-family: 'IBM Plex Mono', monospace; }

@keyframes vFade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes pulseDot { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes growBar { from { transform: scaleY(.02); } to { transform: scaleY(1); } }
@keyframes drawCurve { from { stroke-dashoffset: 1400; } to { stroke-dashoffset: 0; } }

.shell {
  min-height: 100vh; display: grid; grid-template-columns: 230px 1fr; color: var(--text);
  background: var(--bg);
  background-image: linear-gradient(var(--gridline) 1px, transparent 1px), linear-gradient(90deg, var(--gridline) 1px, transparent 1px);
  background-size: 44px 44px;
}
.view { animation: vFade .3s ease both; }

/* ---- sidebar ---- */
.aside {
  border-right: 1px solid var(--line); background: var(--panel2); position: sticky; top: 0;
  height: 100vh; overflow-y: auto; display: flex; flex-direction: column; gap: 22px; padding: 22px 16px;
}
.brand { display: flex; align-items: center; gap: 11px; padding: 0 6px; }
.brand-name { font-size: 15px; font-weight: 800; letter-spacing: .06em; }
.brand-name span { color: var(--accent); }
.brand-sub { font-family: 'IBM Plex Mono', monospace; font-size: 8.5px; letter-spacing: .17em; color: var(--dim); text-transform: uppercase; }
.nav { display: flex; flex-direction: column; gap: 4px; }
/* ---- native interactive elements ----
   Buttons and anchors carry user-agent styling (font, padding, border,
   text-decoration) that would fight the design system. Neutralise it once here
   so a <button class="btn"> and a <div class="btn"> render identically, and
   every control keeps a visible focus ring for keyboard users. */
button, a.nav-item, a.btn {
  font: inherit;
  color: inherit;
  text-decoration: none;
  -webkit-appearance: none;
  appearance: none;
}
button { border: 0; background: none; padding: 0; margin: 0; text-align: inherit; }
:where(button, a, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Skip link — the first tab stop on every page. Without it a keyboard user
   walks the whole sidebar before reaching the content, on every navigation.
   Off-screen until focused, then it lands where a sighted user expects it. */
.skip-link {
  position: absolute; left: 12px; top: -100px; z-index: 200;
  padding: 10px 16px; border-radius: 8px;
  background: var(--accent); color: #0A0D10;
  font-size: 13px; font-weight: 700; text-decoration: none;
  transition: top .15s ease;
}
.skip-link:focus { top: 12px; }

/* Visible to a screen reader, invisible on screen. Used for the search box's
   instructions and its live result count — a sighted user can see the dropdown
   fill in, a screen-reader user is told. `clip-path` rather than
   `display:none`, which would hide it from assistive tech as well. */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; white-space: nowrap;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}

/* Global search dropdown */
.hdr-sug { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 14px; border-bottom: 1px solid var(--line2); cursor: pointer; }
.hdr-sug:last-child { border-bottom: none; }
.hdr-sug:hover { background: var(--panel2, rgba(127,127,127,.07)); }
/* Keyboard highlight. Distinct from :hover so arrowing through results is
   visible even while the mouse sits over a different row. */
.hdr-sug.active { background: var(--accent); color: #0A0D10; }
.hdr-sug.active .hdr-sug-sub,
.hdr-sug.active .hdr-sug-field { color: #0A0D10; opacity: .75; }
.hdr-sug-group {
  padding: 8px 14px; border-bottom: 1px solid var(--line2);
  /* Opaque, because it is sticky and rows scroll underneath it. */
  background: var(--panel);
  font-family: 'IBM Plex Mono', monospace; font-size: 9px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--dim);
  position: sticky; top: 0; z-index: 1;
}

/* `inert` is what actually removes the page behind an open dialog from the tab
   order. Browsers do not style it, so the visual cue has to be added by hand. */
[inert] { pointer-events: none; user-select: none; }

.nav-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px;
  border-radius: 8px; cursor: pointer; border-left: 2px solid transparent; transition: background .18s ease;
  background: none; color: var(--dim2); font-size: 13px; font-weight: 600;
  width: 100%; text-align: left;
}
.nav-item:hover { background: var(--sunk); }
.nav-item.active { border-left-color: var(--accent); color: var(--text); background: var(--sunk); }
.nav-label { display: flex; align-items: center; gap: 9px; min-width: 0; }
.nav-icon { display: block; width: 17px; height: 17px; flex: 0 0 17px; }
.nav-item.active .nav-icon { color: var(--accent); }
.nav-badge { font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: var(--dim); }
.side-card { border: 1px solid var(--line); border-radius: 10px; padding: 13px; background: var(--panel); }
.side-card-label { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .16em; color: var(--dim); text-transform: uppercase; }
.bar-track { height: 5px; background: var(--sunk); border-radius: 3px; margin-top: 11px; overflow: hidden; }
.bar-fill { height: 5px; border-radius: 3px; transition: width .5s ease; background: var(--accent); }
.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 12px; }
.theme-toggle { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 10px; border: 1px solid var(--line); border-radius: 9px; padding: 10px 12px; cursor: pointer; background: var(--panel); color: inherit; }
.theme-toggle:hover { border-color: var(--accent); }

/* ---- header ---- */
.header {
  display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 16px 30px;
  border-bottom: 1px solid var(--line); background: var(--panel2); position: sticky; top: 0; z-index: 40;
}
.crumbs { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }
.crumb { font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim2); cursor: pointer; }
.crumb.current { color: var(--text); cursor: default; }
.search-box { display: flex; align-items: center; gap: 9px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); padding: 0 12px; height: 36px; width: 300px; }
.search-box input { flex: 1; min-width: 0; background: transparent; border: none; outline: none; color: var(--text); font-family: 'IBM Plex Mono', monospace; font-size: 12px; }
.live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--teal); animation: pulseDot 1.9s infinite; }
.avatar { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: var(--sunk); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; color: var(--dim2); }

main.content { min-width: 0; display: flex; flex-direction: column; }
.page { padding: 26px 30px 40px; display: flex; flex-direction: column; gap: 18px; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.page-title { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: -.015em; }
.page-sub { margin: 7px 0 0; font-size: 13px; color: var(--dim); max-width: 620px; }

.btn { display: inline-flex; align-items: center; gap: 8px; padding: 10px 15px; border-radius: 8px; font-size: 12.5px; font-weight: 700; cursor: pointer; border: 1px solid var(--line); background: var(--panel); color: var(--text); }
.btn-accent { background: var(--accent); color: #0A0D10; border-color: var(--accent); box-shadow: var(--shadow); }
.btn-ghost { background: transparent; }
.pill-select, .field-select, .field-input { height: 36px; border: 1px solid var(--line); border-radius: 7px; background: var(--panel); color: var(--text); padding: 0 12px; font-size: 12.5px; }
.field-select { background-image: linear-gradient(45deg,transparent 50%,var(--dim) 50%),linear-gradient(135deg,var(--dim) 50%,transparent 50%); background-position: calc(100% - 16px) 15px, calc(100% - 11px) 15px; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 30px; }

/* ---- KPI cards ---- */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }
.kpi-card { border: 1px solid var(--line); border-radius: 12px; padding: 18px; background: var(--panel); box-shadow: var(--shadow); transition: transform .2s ease, border-color .2s ease; }
.kpi-card:hover { transform: translateY(-3px); border-color: var(--accent); }
.kpi-top { display: flex; align-items: center; justify-content: space-between; }
.kpi-label { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
.kpi-dot { width: 6px; height: 6px; border-radius: 50%; }
.kpi-value-row { display: flex; align-items: baseline; gap: 6px; margin-top: 11px; }
.kpi-value { font-size: 28px; font-weight: 800; letter-spacing: -.02em; }
.kpi-unit { font-size: 12px; color: var(--dim); }
.kpi-spark { display: flex; align-items: flex-end; gap: 3px; height: 26px; margin-top: 12px; }
.kpi-spark div { flex: 1; border-radius: 2px 2px 0 0; }
.kpi-trend { font-size: 11.5px; margin-top: 10px; }

/* ---- panels / cards ---- */
.panel { border: 1px solid var(--line); border-radius: 12px; background: var(--panel); box-shadow: var(--shadow); overflow: hidden; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 15px 20px; border-bottom: 1px solid var(--line); }
.panel-title { font-size: 13.5px; font-weight: 700; }
.panel-sub { font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: var(--dim); margin-top: 3px; }
.panel-body { padding: 20px; }
.two-col { display: grid; grid-template-columns: 1.5fr 1fr; gap: 16px; align-items: start; }
.two-col-even { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 980px) { .two-col, .two-col-even { grid-template-columns: 1fr; } }

.bars-wrap { display: flex; align-items: flex-end; gap: 14px; height: 172px; }
.bar-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; height: 100%; }
.bar-total { font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: var(--dim2); text-align: center; }
.bar-stack { display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; transform-origin: bottom; animation: growBar .55s ease both; }
.bar-plan { background: var(--teal); border-radius: 3px 3px 0 0; opacity: .55; }
.bar-act { background: var(--accent); border-radius: 0 0 3px 3px; }
.bar-labels { display: flex; gap: 14px; margin-top: 9px; border-top: 1px solid var(--line2); padding-top: 9px; }
.bar-labels div { flex: 1; text-align: center; font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: var(--dim); }
.legend { display: flex; gap: 14px; }
.legend-item { display: flex; align-items: center; gap: 6px; }
.legend-item .sw { width: 9px; height: 9px; border-radius: 2px; }
.legend-item span { font-size: 11px; color: var(--dim); }

.curve-stats { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line2); }
.curve-stats .k { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.curve-stats .v { font-size: 17px; font-weight: 700; margin-top: 5px; }

.stat-row { padding: 14px 20px; border-bottom: 1px solid var(--line2); }
.stat-row:last-child { border-bottom: none; }
.stat-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.stat-label { font-size: 12.5px; font-weight: 600; }
.stat-val { font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--dim2); }

.crew-head, .crew-row { display: grid; grid-template-columns: 1.2fr .7fr .7fr .8fr; gap: 10px; padding: 13px 20px; align-items: center; }
/* .crew-row is a <button> so the roster can be opened from the keyboard. */
.crew-row { width: 100%; text-align: left; background: none; color: inherit; cursor: pointer; }
.crew-head { padding: 10px 20px; border-bottom: 1px solid var(--line2); font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.crew-row { border-bottom: 1px solid var(--line2); }
.crew-row .name { font-size: 12.5px; font-weight: 600; }
.crew-row .cell { font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--dim2); }
.crew-row:hover { background: var(--sunk); }
.crew-roster-empty { padding: 12px 20px; font-size: 11px; color: var(--dim); border-bottom: 1px solid var(--line2); }
.crew-roster { background: var(--sunk); border-bottom: 1px solid var(--line2); }
.crew-roster-head, .crew-roster-row { display: grid; grid-template-columns: 1.1fr 1fr 1fr; gap: 10px; padding: 9px 20px 9px 34px; align-items: center; }
.crew-roster-head { font-family: 'IBM Plex Mono', monospace; font-size: 8.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); padding-top: 10px; }
.crew-roster-row { padding-bottom: 10px; }
.crew-roster-row .name { font-size: 12px; font-weight: 600; }
.crew-roster-row .field-input, .crew-roster-row .field-select { height: 30px; font-size: 11.5px; width: 100%; }

/* ---- projects ---- */
.project-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }
/* A <button>, so it needs the button defaults stripped: left-aligned text,
   inherited colour and font, full width in the grid. */
.project-card { display: block; width: 100%; text-align: left; font: inherit; color: inherit;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel); padding: 19px; cursor: pointer; box-shadow: var(--shadow); transition: transform .2s ease, border-color .2s ease; }
.project-card:hover { transform: translateY(-3px); border-color: var(--accent); }
.project-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.project-code { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; letter-spacing: .1em; color: var(--dim); }
.project-name { font-size: 16px; font-weight: 700; margin-top: 5px; line-height: 1.3; }
.project-meta { font-size: 12px; color: var(--dim); margin-top: 4px; }
.tag-pill { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .1em; text-transform: uppercase; padding: 5px 9px; border-radius: 20px; border: 1px solid; flex: none; }
.facts-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line2); }
.facts-grid .k { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.facts-grid .v { font-size: 14px; font-weight: 700; margin-top: 4px; }

/* Location chip. Quieter than a status pill — a location is context, not a
   state, and it should not compete with the thing that says whether the work
   is done. */
.loc-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: 'IBM Plex Mono', monospace; font-size: 10px;
  letter-spacing: .06em;
  padding: 3px 8px; border-radius: 5px;
  border: 1px solid var(--line2); background: var(--sunk); color: var(--dim2);
  white-space: nowrap;
}

/* ---- workpack rows ---- */
/* Buttons where the row navigates, plain divs where it doesn't — the selector
   styles both, and `display:flex` plus the font/colour resets are what stop a
   <button> looking like a <button>. */
.wp-row {
  display: flex; align-items: center; width: 100%; text-align: left;
  font: inherit; color: inherit;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
  padding: 14px 18px; margin-bottom: 10px; cursor: pointer;
  transition: border-color .15s ease;
}
.wp-row:hover { border-color: var(--accent); }
.wp-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- line register table ---- */
.table-wrap { border: 1px solid var(--line); border-radius: 12px; background: var(--panel); box-shadow: var(--shadow); overflow-x: auto; }
.table-head, .table-row {
  display: grid; grid-template-columns: 220px 120px 130px 1fr 120px 150px 130px; gap: 12px; padding: 13px 20px; min-width: 1040px; align-items: center;
}
.table-head { border-bottom: 1px solid var(--line); font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.table-row { border-bottom: 1px solid var(--line2); cursor: pointer; transition: background .16s ease; }
.table-row:hover { background: var(--sunk); }
.table-row.active { background: rgba(255,90,31,.08); box-shadow: inset 3px 0 0 var(--accent); }

/* An eighth column, present only when the viewer has something to put in it.
   Without the wrapper class the register is exactly as it was — this is not a
   column everyone pays for in horizontal space. */
.table-wrap.has-actions .table-head,
.table-wrap.has-actions .table-row { grid-template-columns: 220px 120px 130px 1fr 120px 150px 130px 44px; min-width: 1096px; }

/* Deliberately quiet: it sits on every row of a list people scroll, so it
   reads as an affordance rather than an invitation. It only looks dangerous
   once you are pointing at it. */
.row-x {
  width: 26px; height: 26px; padding: 0; border-radius: 7px;
  border: 1px solid transparent; background: transparent;
  color: var(--dim); font: inherit; font-size: 12px; line-height: 1;
  cursor: pointer; opacity: 0; transition: opacity .16s ease, color .16s ease, border-color .16s ease;
}
.table-row:hover .row-x, .row-x:focus-visible { opacity: 1; }
.row-x:hover { color: var(--accent); border-color: var(--accent); }
/* Keyboard users never get :hover, so the button must not be invisible to
   them — focus alone reveals it, above. */
.row-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The same quiet button, but it opens a menu rather than doing something — so
   it must not go accent-red on hover the way the old bare ✕ did. */
.row-x.row-menu:hover, .row-x.row-menu[aria-expanded="true"] { color: var(--text); border-color: var(--line); }
.row-x.row-menu[aria-expanded="true"] { opacity: 1; }

/* The register's row menu.
   Fixed, not absolute, and a single element reused by every row — because
   .table-wrap scrolls (overflow-x: auto makes overflow-y auto too), so a
   popover living inside a row is clipped by the table it belongs to. Fixed
   positioning takes it out of that box entirely, and one shared element keeps a
   register of several hundred lines from carrying several hundred hidden
   menus. */
.card-pop.row-pop { position: fixed; top: 0; right: auto; z-index: 60; }
.line-progress { display: flex; align-items: center; gap: 9px; }
.line-progress .bar-track { flex: 1; margin-top: 0; }
.status-pill { font-size: 10.5px; font-weight: 600; padding: 5px 10px; border-radius: 20px; border: 1px solid; }

/* A status pill you can change. Same shape, weight and colour rules as
   .status-pill, so a workpack's status reads the same whether you are the
   planner who can edit it or the technician who can't.
   `select { appearance: none }` is global, so the chevron has to be drawn —
   without it this is a pill with no affordance and nobody discovers it. */
.status-select {
  font-family: inherit; font-size: 10.5px; font-weight: 600;
  height: 28px; padding: 0 26px 0 10px;
  border-radius: 20px; border: 1px solid; background-color: transparent;
  cursor: pointer; outline: none;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 14px) 12px, calc(100% - 10px) 12px;
  background-size: 4px 4px;
  background-repeat: no-repeat;
}
.status-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The dropdown list itself is drawn by the OS and does not inherit the pill's
   colour — it would render coloured-on-transparent and be unreadable. */
.status-select option { color: var(--text); background: var(--panel); }
.filters-panel { border: 1px solid var(--line); border-radius: 12px; background: var(--panel); box-shadow: var(--shadow); padding: 16px 18px; display: flex; flex-direction: column; gap: 14px; }
.filters-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
/* Was a <div>; now a real <label>, which is inline by default — the explicit
   display keeps the original block layout and its bottom margin. */
.filter-label { display: block; font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); margin-bottom: 6px; }

/* ---- line detail ---- */
.line-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.line-head-left { display: flex; align-items: center; gap: 16px; }
.icon-btn { width: 36px; height: 36px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); display: flex; align-items: center; justify-content: center; font-size: 15px; color: var(--dim2); cursor: pointer; }
.icon-btn:hover { border-color: var(--accent); }
.line-no { font-family: 'IBM Plex Mono', monospace; font-size: 20px; font-weight: 600; letter-spacing: -.01em; }
.line-meta { font-size: 12.5px; color: var(--dim); margin-top: 4px; }
.progress-chip { border: 1px solid var(--line); border-radius: 9px; padding: 7px 14px; background: var(--panel); }

.model-viewer { position: relative; height: 430px; background: var(--imgbg, #000); overflow: hidden; cursor: grab; }
.model-viewer.dragging { cursor: grabbing; }
.model-inner { position: absolute; inset: 0; transform-origin: center center; transition: transform .12s ease-out; }
.model-inner.no-transition { transition: none; }
.model-viewer img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.pin { position: absolute; transform: translate(-50%, -50%); border-radius: 50%; cursor: pointer; box-shadow: 0 0 0 4px rgba(255,90,31,.12); }
.pin-tag { position: absolute; top: -3px; left: 15px; font-family: 'IBM Plex Mono', monospace; font-size: 9px; background: rgba(10,13,16,.8); color: #C9CED4; padding: 1px 5px; border-radius: 4px; white-space: nowrap; }
.model-zoom-controls {
  position: absolute; right: 14px; bottom: 14px; display: flex; align-items: center; gap: 6px;
  background: rgba(10,13,16,.86); border: 1px solid #2B3238; border-radius: 8px; padding: 5px;
}
.model-zoom-controls .zbtn {
  width: 28px; height: 28px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700; color: #C9CED4; cursor: pointer; user-select: none;
}
.model-zoom-controls .zbtn:hover { background: rgba(255,255,255,.06); }
.model-zoom-controls .zlabel { font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8A9099; min-width: 44px; text-align: center; }
.model-zoom-controls .zfit { padding: 0 10px; height: 28px; border-left: 1px solid #2B3238; display: flex; align-items: center; font-size: 11.5px; font-weight: 600; color: #C9CED4; cursor: pointer; }
.model-viewer-hint { position: absolute; left: 14px; bottom: 14px; font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: #5C6268; }

/* ---- guided torque sequence ---- */
.pass-box { flex: 1; min-width: 104px; border: 1px solid var(--line); background: var(--panel2); border-radius: 9px; padding: 13px; cursor: pointer; }
.pass-box.active { border-color: var(--accent); background: var(--sunk); }
.pass-box:hover { border-color: var(--accent); }

/* ---- assembly evidence: photos + checklist ---- */
.shot-card { border: 1px dashed var(--line); background: var(--panel2); border-radius: 10px; cursor: pointer; overflow: hidden; min-height: 176px; display: flex; flex-direction: column; }
.shot-card:hover { border-color: var(--accent); }
.shot-card.done { border-style: solid; border-color: var(--teal); }
.shot-card img { width: 100%; height: 110px; object-fit: cover; display: block; }
.shot-placeholder { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 90px; }
.checklist-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 16px; background: var(--panel2); border-bottom: 1px solid var(--line2); }
.checklist-row:last-child { border-bottom: none; }
.yn-toggle { display: flex; gap: 6px; flex: none; }
.yn-btn { padding: 6px 14px; border-radius: 6px; border: 1px solid var(--line); font-size: 11.5px; font-weight: 700; color: var(--dim2); cursor: pointer; background: var(--panel); }
.yn-btn:hover { border-color: var(--accent); }
.yn-btn.active.yes { background: var(--teal); border-color: var(--teal); color: #0A0D10; }
.yn-btn.active.no { background: var(--accent); border-color: var(--accent); color: #0A0D10; }
.model-tools { position: absolute; right: 14px; bottom: 14px; display: flex; align-items: center; gap: 6px; background: rgba(10,13,16,.86); border: 1px solid #2B3238; border-radius: 8px; padding: 5px; }
.model-tools > div { width: 28px; height: 28px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 15px; font-weight: 700; color: #C9CED4; cursor: pointer; }

.specs-grid { padding: 16px 18px; display: grid; grid-template-columns: 1fr 1fr; gap: 15px 14px; }
.specs-grid .k { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .13em; text-transform: uppercase; color: var(--dim); }
.specs-grid .v { font-size: 13px; font-weight: 600; margin-top: 4px; }

.insp-row { display: flex; align-items: flex-start; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--line2); }
.insp-row .stripe { width: 3px; align-self: stretch; border-radius: 2px; flex: none; }
.insp-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.insp-detail { font-size: 11.5px; color: var(--dim); margin-top: 3px; }
.insp-result { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; margin-top: 5px; }

.doc-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--line2); color: var(--text); }
.doc-row:hover { background: var(--sunk); }
.doc-name { font-size: 12.5px; font-weight: 600; }
.doc-meta { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; color: var(--dim); margin-top: 3px; }
.doc-kind { font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; border: 1px solid; border-radius: 5px; padding: 4px 8px; flex: none; }

.joints-list { display: flex; flex-direction: column; }
.joint-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--line2); cursor: pointer; }
.joint-row:hover { background: var(--sunk); }

/* ---- modal ---- */
.modal-overlay { position: fixed; inset: 0; z-index: 95; background: rgba(6,8,10,.82); display: flex; align-items: flex-start; justify-content: center; padding: 40px 24px; overflow: auto; animation: vFade .2s ease both; }
.modal { width: min(880px, 100%); border: 1px solid var(--line); border-radius: 14px; background: var(--panel); box-shadow: var(--shadow); overflow: hidden; }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 20px 22px; border-bottom: 1px solid var(--line); background: var(--panel2); }
.modal-badge { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); border: 1px solid var(--accent); border-radius: 4px; padding: 3px 7px; }
.modal-title { font-size: 16px; font-weight: 800; }
.modal-desc { font-size: 12px; color: var(--dim); margin-top: 7px; max-width: 560px; line-height: 1.6; }
.modal-body { padding: 20px 22px; display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; }
.modal-body .full { grid-column: 1 / -1; }
.modal-body .divider { grid-column: 1 / -1; height: 1px; background: var(--line2); }
/* .field-label is for captions that head a group of controls (a button group,
   say) rather than one input — those aren't a <label>, but must look identical. */
.field label, .field .field-label { display: block; font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); margin-bottom: 7px; }
.field input, .field select { width: 100%; height: 38px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel2); color: var(--text); padding: 0 12px; font-family: 'IBM Plex Mono', monospace; font-size: 12.5px; outline: none; }
.field select { padding-right: 30px; background-image: linear-gradient(45deg,transparent 50%,var(--dim) 50%),linear-gradient(135deg,var(--dim) 50%,transparent 50%); background-position: calc(100% - 16px) 17px, calc(100% - 11px) 17px; background-size: 5px 5px; background-repeat: no-repeat; }
.auto-box { border: 1px solid var(--accent); border-radius: 11px; background: var(--sunk); padding: 17px; display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 16px; }
.auto-box .k { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .13em; text-transform: uppercase; color: var(--dim); }
.auto-box .v { font-size: 22px; font-weight: 800; margin-top: 5px; }
.auto-box .accent .k, .auto-box .accent .v { color: var(--accent); }
.modal-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 17px 22px; border-top: 1px solid var(--line); background: var(--panel2); flex-wrap: wrap; }

/* ---- torque job ---- */
.stage-tabs { display: flex; flex-wrap: wrap; gap: 2px; border: 1px solid var(--line); border-radius: 11px; background: var(--panel); box-shadow: var(--shadow); overflow: hidden; }
.bolt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; padding: 18px; }
.bolt-cell { border: 1px solid var(--line); border-radius: 9px; padding: 12px; background: var(--panel2); }
.bolt-cell.done { border-color: var(--teal); }
.bolt-cell .label { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.bolt-cell input { width: 100%; margin-top: 8px; height: 32px; border: 1px solid var(--line); border-radius: 6px; background: var(--sunk); color: var(--text); padding: 0 8px; font-family: 'IBM Plex Mono', monospace; font-size: 12px; outline: none; }
.bolt-cell .meta { margin-top: 6px; font-size: 10px; color: var(--dim); font-family: 'IBM Plex Mono', monospace; }

.empty-state { padding: 34px 20px; text-align: center; font-size: 13px; color: var(--dim); }
.toast { position: fixed; bottom: 20px; right: 20px; background: var(--panel); border: 1px solid var(--teal); color: var(--text); padding: 12px 18px; border-radius: 9px; box-shadow: var(--shadow); font-size: 12.5px; z-index: 200; animation: vFade .2s ease both; }

/* ---- mobile / off-canvas nav ---- */
.hamburger-btn { display: none; width: 36px; height: 36px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); align-items: center; justify-content: center; cursor: pointer; flex: none; }
.hamburger-btn span, .hamburger-btn::before, .hamburger-btn::after { content: ''; display: block; width: 16px; height: 1.5px; background: var(--dim2); position: relative; }
.hamburger-btn::before { transform: translateY(-5px); position: absolute; }
.hamburger-btn::after { transform: translateY(5px); position: absolute; }
.nav-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 90; opacity: 0; pointer-events: none; transition: opacity .2s ease; }
.nav-overlay.open { opacity: 1; pointer-events: auto; }

@media (max-width: 860px) {
  .shell { grid-template-columns: 1fr; }
  .aside {
    position: fixed; top: 0; left: 0; z-index: 100; width: 260px; max-width: 82vw;
    transform: translateX(-100%); transition: transform .25s ease; box-shadow: var(--shadow);
  }
  .aside.open { transform: translateX(0); }
  .hamburger-btn { display: flex; }
  .header { padding: 14px 16px; gap: 12px; flex-wrap: wrap; }
  .crumbs { order: 2; width: 100%; }
  .search-box { width: auto; flex: 1; min-width: 0; }
  .page { padding: 18px 16px 32px; }
  .page-title { font-size: 22px; }
  .model-viewer { height: 260px; }
  .toast { left: 16px; right: 16px; bottom: 16px; }
  .avatar { display: none; }
}

/* ---- notch / home-indicator safe areas ----
   The page is served with viewport-fit=cover and the iOS shell runs the web
   view edge to edge, so the layout has to keep its own content clear of the
   notch, the status bar and the home indicator. env() resolves to 0 in every
   browser that isn't behind a cutout, so this is inert on desktop. */
.header {
  padding-top: max(14px, env(safe-area-inset-top));
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
.page {
  padding-bottom: max(32px, calc(env(safe-area-inset-bottom) + 24px));
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
.aside { padding-top: env(safe-area-inset-top); }
.toast { bottom: max(16px, calc(env(safe-area-inset-bottom) + 12px)); }
.modal-overlay {
  padding-top: max(40px, calc(env(safe-area-inset-top) + 16px));
  padding-bottom: max(40px, calc(env(safe-area-inset-bottom) + 16px));
}

@media (max-width: 520px) {
  .kpi-value { font-size: 24px; }
  .facts-grid { grid-template-columns: repeat(2, 1fr); }
  .bolt-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .modal-overlay { padding: 16px 10px; }
  .search-box input::placeholder { font-size: 11px; }
}

/* ---- accounts / sign in ---- */
.auth-shell {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 24px; background: var(--bg);
  background-image: linear-gradient(var(--gridline) 1px, transparent 1px), linear-gradient(90deg, var(--gridline) 1px, transparent 1px);
  background-size: 34px 34px;
}
.auth-card {
  width: 100%; max-width: 400px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--panel); box-shadow: var(--shadow); padding: 30px 28px 26px;
  animation: vFade .25s ease both;
}
.auth-tabs { display: flex; border: 1px solid var(--line); border-radius: 9px; overflow: hidden; margin-bottom: 20px; }
.auth-tab { flex: 1; text-align: center; padding: 10px 8px; font-size: 12px; font-weight: 700; color: var(--dim); cursor: pointer; background: var(--panel2); }
/* The inactive tab is a <button>; the active one is plain text. */
button.auth-tab { font: inherit; font-size: 12px; font-weight: 700; }
.auth-tab.active { background: var(--accent); color: #0A0D10; }
.auth-card .field { margin-bottom: 14px; }
.auth-error {
  border: 1px solid var(--accent); background: var(--sunk); color: var(--accent);
  border-radius: 8px; padding: 9px 12px; font-size: 12px; margin-bottom: 14px; line-height: 1.5;
}
.auth-hint { margin-top: 14px; text-align: center; font-size: 11px; color: var(--dim); line-height: 1.6; }
/* Replaces the old two-tab switcher — there is only one way in now. */
.auth-title { font-size: 15px; font-weight: 800; margin-bottom: 18px; }
.linklike { color: var(--accent); font-size: 11px; font-weight: 600; cursor: pointer; text-decoration: underline; }

/* ---- Team page ---- */
.team-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.crew-card { border: 1px solid var(--line); border-radius: 11px; background: var(--panel); padding: 15px; display: flex; flex-direction: column; gap: 10px; }
.crew-card .crew-name { font-size: 14px; font-weight: 700; }
.code-chip {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  border: 1px dashed var(--accent); border-radius: 8px; background: var(--sunk); padding: 9px 11px;
}
.code-chip .code { font-family: 'IBM Plex Mono', monospace; font-size: 15px; font-weight: 600; letter-spacing: .06em; color: var(--accent); }
.people-row { display: grid; grid-template-columns: 1.4fr .9fr .9fr .8fr auto; gap: 10px; padding: 12px 16px; align-items: center; border-bottom: 1px solid var(--line2); }
.people-head { display: grid; grid-template-columns: 1.4fr .9fr .9fr .8fr auto; gap: 10px; padding: 11px 16px; font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .16em; text-transform: uppercase; color: var(--dim); border-bottom: 1px solid var(--line); }
.role-pill { display: inline-block; padding: 3px 8px; border-radius: 20px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; border: 1px solid var(--line); color: var(--dim2); }
.role-pill.admin { border-color: var(--accent); color: var(--accent); }
.role-pill.foreman { border-color: var(--amber); color: var(--amber); }
/* The one-time temporary password. Deliberately loud: it is shown once and
   never again, so it must not be mistaken for ordinary body text. */
.temp-pass { border: 1px solid var(--amber); border-radius: 10px; background: var(--sunk); padding: 14px; }
.temp-pass .val { font-family: 'IBM Plex Mono', monospace; font-size: 21px; font-weight: 700; letter-spacing: .08em; color: var(--amber); margin: 8px 0; word-break: break-all; }
@media (max-width: 720px) {
  .people-row, .people-head { grid-template-columns: 1fr auto; }
  .people-row .hide-sm, .people-head .hide-sm { display: none; }
}
.auth-submit { cursor: pointer; }

.account-box {
  display: flex; align-items: center; gap: 10px; border: 1px solid var(--line); border-radius: 9px;
  padding: 9px 10px; background: var(--panel);
}

/* An archived crew is present but plainly inactive. */
.crew-card.archived { opacity: .62; border-style: dashed; }

/* ---- leak test workspace ----
   Laid out to match the piping command-centre design: a wide left column for
   the test itself, a narrow right column for the boundary that holds it and the
   sign-off that closes it. Cards are padded rather than split by a head rule,
   labels are mono and letter-spaced, and the numbers that matter — pressure,
   decay, how far through the hold — are tiles rather than a line of text. */
.leak-workspace { padding: 2px 0 10px; }

.leak-workspace .lw-head { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; margin-bottom:16px; }
.leak-workspace .lw-head-left { display:flex; align-items:flex-start; gap:14px; }
.leak-workspace .lw-title { margin:0; font-size:30px; font-weight:800; letter-spacing:-.02em; }
.leak-workspace .lw-sub { margin:8px 0 0; font-family:'IBM Plex Mono',monospace; font-size:11.5px; color:var(--dim); }
.leak-workspace .lw-status { margin:0 0 18px; font-size:11.5px; color:var(--dim); min-height:15px; }

.leak-workspace .leak-columns { display:grid; grid-template-columns:1.55fr 1fr; gap:18px; align-items:start; }
.leak-workspace .card { border:1px solid var(--line); border-radius:14px; background:var(--panel); box-shadow:var(--shadow); padding:26px; margin-bottom:18px; }
.leak-workspace .card-head { display:flex; align-items:baseline; justify-content:space-between; gap:14px; margin-bottom:20px; }
.leak-workspace .card-head h2 { margin:0; font-size:15.5px; font-weight:700; }
.leak-workspace .card-meta { font-family:'IBM Plex Mono',monospace; font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:var(--dim); white-space:nowrap; }
.leak-workspace .card-note { margin:-12px 0 20px; font-size:11.5px; color:var(--dim); line-height:1.6; }

.leak-workspace .lw-label { display:block; font-family:'IBM Plex Mono',monospace; font-size:9px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); margin-bottom:9px; }
.leak-workspace .lw-field { margin-bottom:18px; }
.leak-workspace .lw-grid .lw-field, .leak-workspace .lw-grid > * { margin-bottom:0; }
.leak-workspace input:not([type=checkbox]), .leak-workspace select, .leak-workspace textarea {
  display:block; width:100%; box-sizing:border-box; height:46px; padding:0 15px; margin:0;
  background:var(--sunk); color:var(--text); border:1px solid var(--line); border-radius:9px;
  font:inherit; font-size:13.5px;
}
.leak-workspace textarea { height:auto; min-height:84px; padding:13px 15px; line-height:1.6; resize:vertical; }
.leak-workspace input::placeholder, .leak-workspace textarea::placeholder { color:var(--dim); }
.leak-workspace input:focus, .leak-workspace select:focus, .leak-workspace textarea:focus { outline:none; border-color:var(--dim); }
.leak-workspace select {
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--dim) 50%),linear-gradient(135deg,var(--dim) 50%,transparent 50%);
  background-position:calc(100% - 20px) 21px, calc(100% - 15px) 21px;
  background-size:5px 5px; background-repeat:no-repeat; padding-right:38px;
}
.leak-workspace .lw-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:17px; }

.leak-workspace .lw-tiles { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:14px; margin-bottom:22px; }
.leak-workspace .tile { border:1px solid var(--line); border-radius:11px; background:var(--sunk); padding:16px 18px; }
.leak-workspace .tile .k { font-family:'IBM Plex Mono',monospace; font-size:9px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); }
.leak-workspace .tile .v { font-size:27px; font-weight:800; letter-spacing:-.02em; margin-top:11px; }
.leak-workspace .tile .v span { font-size:12.5px; font-weight:400; color:var(--dim); margin-left:4px; }
.leak-workspace .tile .v.none { font-size:14px; font-weight:400; color:var(--dim); letter-spacing:0; margin-top:15px; }
.leak-workspace .tile .foot { font-size:11px; color:var(--dim); }
.leak-workspace .hold-bar { height:4px; border-radius:2px; background:var(--line2); overflow:hidden; margin:17px 0 10px; }
.leak-workspace .hold-bar i { display:block; height:4px; background:var(--teal); }

.leak-workspace .lw-log { display:grid; grid-template-columns:190px 1fr; gap:13px; align-items:end; }
.leak-workspace .lw-actions { display:flex; gap:11px; flex-wrap:wrap; }
.leak-workspace table { width:100%; border-collapse:collapse; margin-top:24px; }
.leak-workspace th { text-align:left; font-family:'IBM Plex Mono',monospace; font-size:9px; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); font-weight:400; padding:0 0 13px; border-bottom:1px solid var(--line2); }
.leak-workspace td { padding:13px 0; border-bottom:1px solid var(--line2); font-size:12.5px; }
.leak-workspace th:nth-child(3), .leak-workspace td:nth-child(3),
.leak-workspace th:nth-child(4), .leak-workspace td:nth-child(4) { text-align:right; }
.leak-workspace .lw-empty { padding:26px 0 2px; font-size:13px; color:var(--dim); border-bottom:0; }

.leak-workspace .iso { display:flex; gap:13px; align-items:flex-start; padding:0 0 19px; cursor:pointer; }
.leak-workspace .iso input[type=checkbox] { flex:none; width:17px; height:17px; margin:1px 0 0; accent-color:var(--teal); cursor:pointer; }
.leak-workspace .iso b { display:block; font-size:13.5px; font-weight:700; }
.leak-workspace .iso em { display:block; font-family:'IBM Plex Mono',monospace; font-style:normal; font-size:11px; color:var(--dim); margin-top:4px; line-height:1.55; }
.leak-workspace .iso-none { font-size:12.5px; color:var(--dim); line-height:1.6; margin:0 0 4px; }
.leak-workspace .iso-add { margin-top:2px; padding-top:20px; border-top:1px solid var(--line2); }

.leak-workspace .accept { display:block; width:100%; margin-top:8px; padding:17px; border-radius:11px; border:1px solid var(--line); background:var(--sunk); color:var(--dim); font:inherit; font-size:13.5px; font-weight:700; text-align:center; cursor:not-allowed; }
.leak-workspace .accept.ready { border-color:var(--teal); color:var(--teal); background:var(--panel); cursor:pointer; }
.leak-workspace .blockers { margin:14px 0 0; padding:0; list-style:none; }
.leak-workspace .blockers li { font-size:11.5px; color:var(--dim); padding:5px 0; line-height:1.55; }
.leak-workspace .fine { font-size:11px; color:var(--dim); line-height:1.6; margin:0 0 18px; }
.leak-workspace button[disabled] { opacity:.5; cursor:not-allowed; }

@media(max-width:1000px) {
  .leak-workspace .leak-columns { grid-template-columns:1fr; }
  .leak-workspace .lw-grid, .leak-workspace .lw-tiles { grid-template-columns:1fr 1fr; }
  .leak-workspace .lw-title { font-size:24px; }
}

/* ---- lessons learned ----
   Mounted at the bottom of whatever record it belongs to, so it has to read as
   a section of that page rather than a widget bolted on. Same panel head, same
   field styling, same empty-state voice as everything above it. */
.lessons { display: block; }
.lessons .lesson {
  border: 1px solid var(--line); border-left: 3px solid var(--line2);
  border-radius: 11px; background: var(--panel);
  padding: 16px 18px; margin-bottom: 11px;
}
.lessons .lesson-top { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.lessons .lesson-top h4 { margin: 0; font-size: 13.5px; font-weight: 700; line-height: 1.45; }
.lessons .lesson-impact {
  flex: none; font-family: 'IBM Plex Mono', monospace; font-size: 9px;
  letter-spacing: .12em; text-transform: uppercase;
  border: 1px solid; border-radius: 20px; padding: 3px 8px;
}
.lessons .lesson-detail {
  margin: 10px 0 0; font-size: 12.5px; line-height: 1.65; color: var(--text);
  white-space: pre-wrap;
}
.lessons .lesson-foot {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 13px; padding-top: 12px; border-top: 1px solid var(--line2);
}
.lessons .lesson-foot .mono { font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: var(--dim); }
.lessons .lesson-foot .mono:first-child {
  letter-spacing: .12em; text-transform: uppercase; color: var(--dim2);
}
.lessons .lesson-foot > :nth-child(2) { margin-right: auto; }
.lessons .lesson-link {
  border: 0; background: none; padding: 0; cursor: pointer;
  font: inherit; font-size: 11px; color: var(--dim); text-decoration: underline;
}
.lessons .lesson-link:hover { color: var(--text); }
.lessons .lesson-danger:hover { color: var(--accent); }
.lessons .lesson-link[disabled] { opacity: .5; cursor: not-allowed; }

.lessons .lesson-form {
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
  padding: 20px 20px 16px; margin-bottom: 16px;
}
.lessons .lesson-hint { margin: 0 0 16px; font-size: 11.5px; line-height: 1.6; color: var(--dim); }
.lessons .lesson-form .field { margin-bottom: 14px; }
.lessons .lesson-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.lessons .lesson-form-foot {
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line2);
}
.lessons textarea {
  width: 100%; box-sizing: border-box; padding: 12px 14px; line-height: 1.6; resize: vertical;
  background: var(--sunk); color: var(--text); border: 1px solid var(--line);
  border-radius: 9px; font: inherit; font-size: 13px;
}
.lessons textarea:focus { outline: none; border-color: var(--dim); }

@media (max-width: 680px) {
  .lessons .lesson-form-row { grid-template-columns: 1fr; }
}

/* ---- declared project progress ----
   Ten steps rather than a slider: a hand-set 73% implies a precision nobody
   has, and a slider on a tablet in gloves is a fight. Filled up to the chosen
   value so the row reads as a gauge at a glance. */
.progress-set { border: 1px solid var(--line); border-radius: 14px; background: var(--panel); padding: 22px 24px; margin-bottom: 20px; }
.progress-head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; }
.progress-source { font-family: 'IBM Plex Mono', monospace; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); }

.progress-steps { display: grid; grid-template-columns: repeat(10, 1fr); gap: 6px; }
.pstep {
  height: 42px; border: 1px solid var(--line); border-radius: 8px; background: var(--sunk);
  color: var(--dim); font-family: 'IBM Plex Mono', monospace; font-size: 11px; font-weight: 600;
  cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.pstep:hover:not([disabled]) { border-color: var(--accent); color: var(--text); }
.pstep.on { background: rgba(255,90,31,.16); border-color: rgba(255,90,31,.45); color: var(--text); }
/* The chosen step itself, so the row reads as "up to here" rather than a blur. */
.pstep.edge { background: var(--accent); border-color: var(--accent); color: #0b0c0d; }
.pstep[disabled] { cursor: default; opacity: .55; }
.pstep:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.progress-foot { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 15px; flex-wrap: wrap; }
.progress-measured { font-size: 11.5px; color: var(--dim); line-height: 1.6; }
.progress-measured strong { color: var(--text); font-weight: 700; }
.progress-clear { border: 0; background: none; padding: 0; cursor: pointer; font: inherit; font-size: 11px; color: var(--dim); text-decoration: underline; white-space: nowrap; }
.progress-clear:hover { color: var(--accent); }
.progress-note { margin: 13px 0 0; font-size: 12px; color: var(--dim); font-style: italic; line-height: 1.6; }

.progress-why { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line2); }
.progress-why label { display: block; font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); margin-bottom: 9px; }
.progress-why-row { display: flex; gap: 10px; flex-wrap: wrap; }
.progress-why-row input {
  flex: 1; min-width: 220px; height: 40px; padding: 0 14px; box-sizing: border-box;
  background: var(--sunk); color: var(--text); border: 1px solid var(--line); border-radius: 9px;
  font: inherit; font-size: 13px;
}
.progress-why-row input:focus { outline: none; border-color: var(--dim); }

@media (max-width: 720px) {
  .progress-steps { grid-template-columns: repeat(5, 1fr); }
}

/* ---- project card actions ----
   The card is itself a <button>, so these controls are SIBLINGS positioned over
   it, never children: a button inside a button is invalid markup and a screen
   reader announces the pair as one confused control. */
.project-cell { position: relative; }
.card-menu {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 28px; height: 28px; padding: 0; border-radius: 7px;
  border: 1px solid transparent; background: var(--panel);
  color: var(--dim); font: inherit; font-size: 15px; line-height: 1;
  cursor: pointer; opacity: 0;
  transition: opacity .16s ease, color .16s ease, border-color .16s ease;
}
/* Stays visible while its own menu is open, or the menu appears to belong to
   nothing once the pointer moves onto it. */
.project-cell:hover .card-menu,
.card-menu:focus-visible,
.card-menu[aria-expanded="true"] { opacity: 1; }
.card-menu:hover, .card-menu[aria-expanded="true"] { color: var(--text); border-color: var(--line); }
.card-menu:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The status pill also lives at the card's top-right, so it moves over to make
   room — but only on cards that actually carry a menu. (It was a .tag-pill
   until the status became a real status; the rule has to follow it, or the ⋯
   sits on top of the word.) */
.project-cell:has(.card-menu) .status-pill { margin-right: 30px; }

.card-pop {
  position: absolute; top: 44px; right: 12px; z-index: 3;
  min-width: 170px; padding: 6px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel2); box-shadow: var(--shadow);
}
.card-pop[hidden] { display: none; }
.card-pop button {
  display: block; width: 100%; text-align: left;
  padding: 9px 11px; border: 0; border-radius: 7px; background: none;
  color: var(--text); font: inherit; font-size: 12.5px; cursor: pointer;
}
.card-pop button:hover { background: var(--sunk); }
.card-pop button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.card-pop button.danger { color: var(--accent); }

/* The status block at the top of the card menu. A heading, because three
   colour-dotted rows with no label read as three unrelated actions rather than
   one choice with three answers. */
.card-pop-head {
  font-family: 'IBM Plex Mono', monospace; font-size: 9px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--dim);
  padding: 5px 11px 4px;
}
.card-pop button.card-pop-status {
  display: flex; align-items: center; gap: 9px;
}
/* The status it already has is not a thing you can pick, so it is disabled —
   but it must still read as the current answer rather than as unavailable.
   Full-strength text with its dot filled says "this one", and the cursor says
   there is nothing to click. */
.card-pop button.card-pop-status:disabled { cursor: default; }
.card-pop button.card-pop-status.on { color: var(--text); font-weight: 600; }
/* Each dot carries its own status colour inline, which is the whole point of
   it — the dim ones are the choices, the full one is where the project is. */
.card-pop button.card-pop-status .dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none; opacity: .45;
}
.card-pop button.card-pop-status.on .dot { opacity: 1; }
.card-pop-rule { height: 1px; background: var(--line); margin: 6px 5px; }

/* ---- placing pins on a line model ----
   A pin nobody has placed must not look like a pin somebody put there. Every
   joint is created at the same default coordinate, so without this distinction
   a drawing shows a dozen confident markers that mean nothing. */
.pin.unplaced {
  border-style: dashed !important;
  background: transparent !important;
  box-shadow: none;
  opacity: .75;
}
.pin.unplaced .pin-tag { color: var(--dim); border: 1px dashed var(--line); }

/* Placing mode: the drawing stops panning and the pins become draggable. */
.model-viewer.placing { cursor: default; }
.model-viewer.placing .pin { cursor: grab; }
.model-viewer.placing .pin.dragging { cursor: grabbing; z-index: 5; }
.model-viewer.placing .pin { box-shadow: 0 0 0 6px rgba(255,90,31,.18); }
.model-viewer.placing .pin.unplaced { box-shadow: 0 0 0 6px rgba(255,90,31,.10); }
/* No transition while a finger is dragging one — it lags behind the touch. */
.pin.dragging { transition: none; }

button[data-place-toggle][aria-pressed="true"] {
  border-color: var(--accent); color: var(--accent);
}

/* Work pack builder — one editable step row. On a phone the activity text gets
   the full width and craft / hours / remove sit underneath it. */
.wb-act { display: grid; grid-template-columns: 28px 1fr 130px 70px 30px; gap: 8px; align-items: start; padding: 8px 0; border-bottom: 1px solid var(--line2); }
.wb-act .wb-no { font-size: 11px; color: var(--dim); padding-top: 10px; }
@media (max-width: 640px) {
  .wb-act { grid-template-columns: 1fr 70px 34px; grid-template-areas: "no no no" "text text text" "craft hrs del"; }
  .wb-act .wb-no { grid-area: no; padding-top: 0; }
  .wb-act textarea { grid-area: text; }
  .wb-act [data-k="craft"] { grid-area: craft; }
  .wb-act [data-k="hrs"] { grid-area: hrs; }
  .wb-act [data-del] { grid-area: del; }
}

/* Work pack bill of materials grid. Scrolls sideways inside its own box so a
   16-column BOM never pushes the page wider than the screen. */
.bom-wrap { overflow: auto; max-height: 560px; border: 1px solid var(--line); border-radius: 10px; }
.bom-table { border-collapse: separate; border-spacing: 0; font-size: 12px; width: max-content; min-width: 100%; }
.bom-table th { position: sticky; top: 0; z-index: 1; background: var(--panel2); text-align: left; font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); padding: 9px 8px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.bom-table td { padding: 3px 4px; border-bottom: 1px solid var(--line2); vertical-align: middle; }
.bom-table tbody tr:hover td { background: var(--panel2); }
.bom-cell { width: 100%; height: 30px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--text); padding: 0 8px; font-size: 12px; font-family: inherit; }
.bom-cell:hover { border-color: var(--line); }
.bom-cell:focus { border-color: var(--accent); outline: none; background: var(--panel); }
.bom-cell.bom-bad { border-color: var(--accent); background: rgba(255, 90, 31, .08); }

/* Work pack update — one execution step with its progress control. */
.wp-step { display: grid; grid-template-columns: 30px minmax(0,1fr) auto auto auto; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--line2); font-size: 12.5px; }
.wp-step-ctl { display: inline-flex; gap: 6px; align-items: center; }
@media (max-width: 640px) {
  .wp-step { grid-template-columns: 26px minmax(0,1fr) auto; }
  .wp-step > span:nth-of-type(2), .wp-step > span:nth-of-type(3) { display: none; }
}

/* Dashboard work packs panel */
.dash-pack-counts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.dash-pack-counts > div { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; background: var(--panel2); }
.dash-pack-counts .k { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.dash-pack-counts .v { font-size: 20px; font-weight: 800; margin-top: 3px; }
a.dash-pack { display: block; text-decoration: none; color: inherit; border-radius: 8px; }
a.dash-pack:hover .stat-label { color: var(--accent); }
@media (max-width: 640px) { .dash-pack-counts { grid-template-columns: repeat(2, 1fr); } }

/* Work-pack workspace: compact metadata and section tabs, inspired by the IWP reference. */
.wp-workspace { --wp-border: var(--line); }
.wp-fixed-header { position: sticky; top: 0; z-index: 5; background: var(--bg, #101417); padding-top: 10px; }
.wp-breadcrumb { color: var(--dim); font-size: 12px; margin-bottom: 16px; }
.wp-breadcrumb span { margin: 0 10px; }
.wp-workspace .page-head { margin-bottom: 16px; }
.wp-workspace .page-title { font-size: 23px; }
.wp-workspace .page-sub { max-width: 900px; }
.wp-header-fields, .wp-summary-fields { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin: 0 0 20px; }
.wp-header-fields { grid-template-columns: 2fr .65fr 1.1fr 1.5fr; }
.wp-data-field dt { font-size: 11px; color: var(--dim); margin-bottom: 7px; }
.wp-data-field dd { margin: 0; min-height: 38px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel); font-size: 13px; overflow-wrap: anywhere; white-space: pre-wrap; }
.wp-tabs { display: flex; overflow-x: auto; border: 1px solid var(--line); background: var(--panel); }
.wp-tabs button { flex: 1 0 auto; padding: 15px 17px; border: 0; border-bottom: 3px solid transparent; background: transparent; color: var(--dim); font: inherit; font-size: 12px; cursor: pointer; }
.wp-tabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); background: var(--panel2); }
.wp-tabs button:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
.wp-tab-panel { border: 1px solid var(--line); border-top: 0; border-radius: 0 0 8px 8px; padding: 20px; min-height: 400px; background: var(--panel); }
.wp-tab-panel[hidden] { display: none !important; }
.wp-section-heading { font-size: 14px; background: var(--panel2); padding: 12px 14px; margin: 0 0 18px; border-radius: 4px; }
.wp-summary-note { font-size: 13px; color: var(--dim); line-height: 1.6; margin: 12px 0 18px; }
.wp-table-scroll { overflow-x: auto; }
.wp-data-table { border-collapse: collapse; width: 100%; font-size: 13px; }
.wp-data-table th { text-align: left; font-size: 11px; color: var(--dim); background: var(--panel2); }
.wp-data-table th, .wp-data-table td { padding: 12px 14px; border-bottom: 1px solid var(--line); }
@media (max-width: 850px) { .wp-header-fields, .wp-summary-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); } .wp-fixed-header { position: static; } }
@media (max-width: 520px) { .wp-header-fields, .wp-summary-fields { grid-template-columns: 1fr; gap: 10px; } .wp-tab-panel { padding: 12px; } }

/* Project information stays horizontal at every viewport size. */
.pd-summary-scroll { max-width: 100%; overflow-x: auto; border: 1px solid var(--line); border-radius: 6px; }
.pd-summary-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pd-summary-table { width: max-content; min-width: 100%; }
.pd-summary-table th, .pd-summary-table td { min-width: 140px; white-space: nowrap; padding: 7.5px 18px; }
.pd-summary-table th:first-child, .pd-summary-table td:first-child { position: sticky; left: 0; z-index: 1; background: var(--panel); min-width: 240px; max-width: 360px; white-space: normal; overflow-wrap: anywhere; border-right: 1px solid var(--line); }
.pd-summary-table th:first-child { background: var(--panel2); }
.project-grid.project-register { display: block; max-width: 100%; overflow-x: auto; padding-bottom: 12px; }
.project-register .project-cell { min-width: 1580px; margin-bottom: 4px; }
.project-register .project-card { display: grid; grid-template-columns: 250px 200px 120px 120px 120px 140px 140px 190px 70px; gap: 16px; align-items: center; width: 100%; text-align: left; padding: 9px 48px 9px 18px; }
.project-register .pr-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; overflow-wrap: anywhere; font-size: 13px; }
.project-register .pr-label { color: var(--dim); font-size: 10px; text-transform: uppercase; letter-spacing: .06em; }
.project-register .project-name { font-size: 15px; margin: 0; }
.project-register .project-meta { margin: 0; }
.project-register .bar-track { display: block; width: 100%; margin: 0; }

.project-register .project-cell:has(.card-menu) .status-pill { margin-right: 0; }

.imported-line-model { margin: 18px 0; padding: 18px; }
.model-import-note { color: var(--dim); font-size: 12px; line-height: 1.6; }
.model3d-layout { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 18px; }
.model3d-canvas { width: 100%; height: 460px; display: block; border-radius: 8px; touch-action: none; cursor: grab; }
.model3d-canvas:focus-visible { outline: 2px solid var(--accent); }
.model3d-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 10px 0; }
.model3d-selection { font-size: 12px; overflow-wrap: anywhere; }
.model3d-register { height: 440px; overflow: auto; margin-top: 12px; }
.model3d-register th { position: sticky; top: 0; }
.model3d-register .btn { white-space: normal; height: auto; text-align: left; }
.model3d-selected td { background: var(--panel2); border-bottom-color: var(--accent); }
@media(max-width:900px) { .model3d-layout { grid-template-columns: 1fr; } .model3d-canvas { height: 350px; } }

/* Engineering viewer: decoded header, wide model, compact branch register. */
.model3d-engineering { --model-canvas:#101820; }
.model3d-header { display:flex; flex-wrap:wrap; align-items:end; gap:16px 28px; margin-bottom:14px; }
.model3d-header h2 { margin:0; font-size:24px; letter-spacing:-.5px; }
.model3d-source { color:var(--dim); font-size:11px; margin-top:4px; overflow-wrap:anywhere; }
.model3d-decode { display:flex; flex-wrap:wrap; gap:10px 20px; margin:0; }
.model3d-decode dt { color:var(--dim); font-size:9px; text-transform:uppercase; letter-spacing:1px; }
.model3d-decode dd { margin:3px 0 0; font:12px var(--mono,monospace); }
.model3d-engineering .model3d-layout { grid-template-columns:minmax(0,1fr) 340px; gap:12px; }
.model3d-stage { position:relative; border:1px solid var(--border,#303b43); border-radius:6px; overflow:hidden; min-width:0; }
.model3d-engineering .model3d-canvas { height:620px; border-radius:0; }
.model3d-overlay-tools { position:absolute; top:10px; left:10px; right:10px; margin:0; gap:5px; }
.model3d-engineering .btn { padding:5px 8px; font-size:11px; min-height:28px; height:auto; }
.model3d-engineering .btn:disabled { opacity:.45; }
.model3d-engineering .model3d-selection { position:absolute; top:58px; right:10px; width:245px; max-width:calc(100% - 20px); max-height:230px; overflow:auto; background:var(--panel,#1a2125); border:1px solid var(--border,#303b43); border-radius:6px; padding:10px 12px; font-size:11px; box-sizing:border-box; }
.model3d-selection strong { font-size:13px; }
.model3d-selection p { color:var(--dim); margin:5px 0 0; line-height:1.5; }
.model3d-selection dl { display:grid; grid-template-columns:auto 1fr; gap:5px 10px; margin:8px 0 0; }
.model3d-selection dt { color:var(--dim); }
.model3d-selection dd { margin:0; overflow-wrap:anywhere; font-family:var(--mono,monospace); }
.model3d-legend { position:absolute; bottom:10px; left:10px; right:10px; display:flex; flex-wrap:wrap; gap:5px 12px; background:var(--panel,#1a2125); border-radius:4px; padding:8px; font-size:10px; }
.model3d-legend span { display:flex; align-items:center; gap:5px; }
.model3d-legend i,.model3d-component i { display:inline-block; width:9px; height:9px; border-radius:2px; flex-shrink:0; }
.model3d-sidebar { display:flex; flex-direction:column; min-width:0; height:620px; border:1px solid var(--border,#303b43); border-radius:6px; background:var(--panel,#1a2125); overflow:hidden; }
.model3d-stats { display:grid; grid-template-columns:repeat(4,1fr); border-bottom:1px solid var(--border,#303b43); }
.model3d-stats div { padding:9px 8px; border-right:1px solid var(--border,#303b43); }
.model3d-stats b { display:block; font-size:20px; }
.model3d-stats small { color:var(--dim); font-size:8px; text-transform:uppercase; white-space:nowrap; }
.model3d-search { display:block; padding:9px; font-size:10px; color:var(--dim); }
.model3d-search input { margin-top:4px; width:100%; }
.model3d-engineering .model3d-register { flex:1; min-height:100px; height:auto; margin:0; }
.model3d-register table { width:100%; border-collapse:collapse; table-layout:fixed; }
.model3d-register td { padding:3px 0; border-bottom:1px solid var(--border,#303b43); }
.model3d-register td:last-child { width:80px; }
.model3d-branch th { text-align:left; padding:8px 10px; color:var(--dim); font-size:11px; background:var(--panel,#1a2125); text-transform:uppercase; z-index:1; }
.model3d-component { display:flex; align-items:center; gap:6px; border:0; border-left:3px solid transparent; background:none; color:inherit; width:100%; cursor:pointer; text-align:left; padding:6px 8px; font-size:11px; }
.model3d-component span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; }
.model3d-component small { color:var(--dim); font-size:9px; }
.model3d-component[aria-pressed="true"] { border-left-color:#3db2f0; background:#3db2f01a; }
.model3d-component:focus-visible { outline:2px solid #3db2f0; outline-offset:-2px; }
.model3d-pagination { justify-content:space-between; margin:0; padding:8px; font-size:9px; }
.model3d-note { padding:10px; margin:0; color:var(--dim); line-height:1.5; font-size:10px; border-top:1px solid var(--border,#303b43); overflow-wrap:anywhere; }
@media(max-width:1000px) { .model3d-engineering .model3d-layout { grid-template-columns:1fr; } .model3d-sidebar { height:500px; } .model3d-engineering .model3d-canvas { height:520px; } }
@media(max-width:560px) { .model3d-engineering .model3d-selection { top:90px; width:190px; max-height:160px; } }

.model3d-context-status { position:absolute; left:12px; bottom:62px; right:12px; margin:0; color:var(--dim); font-size:10px; background:var(--panel,#1a2125); padding:5px 8px; border-radius:4px; pointer-events:none; }
.model3d-engineering [data-context][aria-pressed="true"] { border-color:#3db2f0; color:#3db2f0; }

.civ-frame { display:block;width:100%;height:calc(100vh - 170px);min-height:680px;border:0;border-radius:8px; }
/* Line Model page: the 3D model gets most of the width; the line picker is a
   narrow column beside it (it only needs to show line numbers). The viewer
   inside the frame keeps a 340px component register, so the extra width all
   goes to the model canvas. Stacks below 1100px. */
.two-col.lm-layout { grid-template-columns: minmax(0, 3fr) minmax(260px, 1fr); }
@media (max-width: 1100px) { .two-col.lm-layout { grid-template-columns: 1fr; } }
@media(max-width:820px){.civ-frame{height:1000px;min-height:620px;}}

/* ---- line register: column widths (2026-10-31) ----
   Line IDs and tag numbers from model exports run 25–40 characters, which
   overflowed the fixed 120/130px columns and printed on top of the next one,
   while the short System value took all the spare width. Columns now share the
   width by how much text they carry, long identifiers wrap inside their own
   cell, and the progress bar stays visible on the hovered row (its track was
   the same colour as the hover background). Scoped to the register so the
   other .table-* lists keep their own layouts. */
.table-wrap:has(#line-rows) .table-head,
#line-rows .table-row {
  grid-template-columns: minmax(170px,1.15fr) minmax(170px,1.25fr) minmax(190px,1.4fr) minmax(90px,.55fr) minmax(130px,.75fr) 150px 104px;
  min-width: 1160px;
}
.table-wrap.has-actions:has(#line-rows) .table-head,
.table-wrap.has-actions #line-rows .table-row {
  grid-template-columns: minmax(170px,1.15fr) minmax(170px,1.25fr) minmax(190px,1.4fr) minmax(90px,.55fr) minmax(130px,.75fr) 150px 104px 36px;
  min-width: 1200px;
}
#line-rows .table-row > div { min-width: 0; overflow-wrap: anywhere; line-height: 1.45; }
#line-rows .status-pill { white-space: nowrap; display: inline-block; }
#line-rows .table-row:hover .bar-track { background: var(--line); }

/* ---- Testing & Turnover (2026-10-31) ----
   From the Testing & Turnover design: systems table with A/B progress, system
   and tag records with field grids, tab strips, OK / N/A / Punch answers and a
   gated sign-off. Built on the app's colour tokens so light and dark both work. */
.tv .tv-actions, .tv .tv-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.tv .tv-row { margin: 0 0 12px; }
.tv .tv-spacer { flex: 1; }
.tv .tv-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; margin-bottom: 16px; }
.tv .tv-kpi { padding: 16px; }
.tv .tv-kv { font-family: 'IBM Plex Mono', monospace; font-size: 26px; font-weight: 700; margin-top: 6px; }
.tv .tv-kv.ok, .tv .tv-okt { color: var(--teal); } .tv .tv-kv.bad, .tv .tv-badt { color: var(--accent); font-weight: 700; }
.tv .tv-kv.info { color: #5b8def; } .tv .tv-kv.warn { color: #d9822b; }
.tv .tv-ks, .tv .tv-dim { font-size: 12.5px; color: var(--dim); }
.tv .tv-flabel { font-size: 10.5px; font-weight: 700; color: var(--dim); text-transform: uppercase; letter-spacing: .05em; }
.tv .tv-table-wrap { overflow-x: auto; }
.tv .tv-table { width: 100%; min-width: 820px; border-collapse: collapse; font-size: 13.5px; }
.tv .tv-table th { text-align: left; font-size: 11px; font-weight: 600; color: var(--dim); padding: 10px 16px; border-bottom: 1px solid var(--line); background: var(--panel2); }
.tv .tv-table td { padding: 11px 16px; border-bottom: 1px solid var(--line2); vertical-align: middle; }
.tv .tv-table tr.tv-sel td { background: rgba(255,90,31,.08); }
.tv .tv-w { width: 190px; } .tv .tv-r { text-align: right; }
.tv .tv-strong { font-weight: 600; }
.tv .tv-bar { display: flex; align-items: center; gap: 8px; } .tv .tv-bar .mono { font-size: 12px; }
.tv .tv-bar-track { flex: 1; height: 8px; border-radius: 4px; background: var(--sunk); overflow: hidden; }
.tv .tv-bar-fill { height: 100%; border-radius: 4px; } .tv .tv-bar-fill.a { background: var(--teal); } .tv .tv-bar-fill.b { background: #5b8def; }
.tv .tv-chip { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 600; white-space: nowrap; border: 1px solid currentColor; }
.tv .tv-ok { color: var(--teal); } .tv .tv-warn { color: #d9822b; } .tv .tv-bad { color: var(--accent); } .tv .tv-info { color: #5b8def; } .tv .tv-dim.tv-chip, .tv .tv-chip.tv-dim { color: var(--dim); }
.tv .tv-cat { font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 4px; background: var(--sunk); color: var(--dim2); }
.tv .tv-cat.a { background: var(--accent); color: #fff; }
.tv .tv-link { background: none; border: 0; padding: 0; cursor: pointer; color: var(--accent); font-weight: 600; text-align: left; font-size: 13px; }
.tv .tv-big { font-size: 17px; font-weight: 700; }
.tv .tv-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 17px; font-weight: 700; margin-bottom: 14px; }
.tv .tv-between { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; }
.tv .tv-fields { padding: 16px 18px; display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px 16px; margin-bottom: 14px; }
.tv .tv-fval { font-size: 13.5px; margin-top: 4px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--sunk); min-height: 20px; overflow-wrap: anywhere; }
.tv .tv-why { font-size: 13px; color: var(--dim2); background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; padding: 10px 12px; margin-bottom: 14px; }
.tv .tv-tabs { display: flex; flex-wrap: wrap; overflow-x: auto; border: 1px solid var(--line); border-radius: 8px 8px 0 0; background: var(--panel); }
.tv .tv-tab { display: flex; align-items: center; gap: 8px; padding: 13px 18px; min-height: 46px; border: 0; background: none; cursor: pointer; font-size: 13.5px; color: var(--dim); border-bottom: 3px solid transparent; white-space: nowrap; }
.tv .tv-tab.on { color: var(--text); font-weight: 700; border-bottom-color: var(--accent); }
.tv .tv-count { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--sunk); }
.tv .tv-body { margin-top: 14px; display: flex; flex-direction: column; gap: 14px; }
.tv .tv-head { padding: 10px 16px; font-size: 13px; font-weight: 700; background: var(--panel2); border-bottom: 1px solid var(--line); }
.tv .tv-pad { padding: 8px 16px 14px; }
.tv .tv-form .tv-grid { padding: 16px; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }
.tv label { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; font-weight: 600; }
.tv label input, .tv label select { padding: 9px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--sunk); color: var(--text); font-size: 13.5px; min-height: 40px; }
.tv .tv-note { font-size: 12px; color: var(--dim); margin: 0 16px 8px; }
.tv .tv-err { font-size: 12.5px; color: var(--accent); font-weight: 600; margin: 0 16px; min-height: 1em; }
.tv .tv-foot { padding: 12px 16px; display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; border-top: 1px solid var(--line); }
.tv .tv-foot.tv-between { justify-content: space-between; }
.tv .tv-pillbtn { min-height: 36px; padding: 6px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600; cursor: pointer; border: 1px solid var(--line); background: var(--panel); color: var(--dim2); }
.tv .tv-pillbtn.on { background: var(--text); color: var(--panel); border-color: var(--text); }
.tv .tv-file { cursor: pointer; }
.tv .tv-dark { background: var(--text); color: var(--panel); border-color: var(--text); }
.tv .tv-check { border-bottom: 1px solid var(--line2); padding: 12px 0; display: flex; flex-direction: column; gap: 10px; }
.tv .tv-check-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; align-items: center; }
.tv .tv-check-text { flex: 1 1 300px; min-width: 0; font-size: 13.5px; }
.tv .tv-auto { font-size: 11.5px; color: var(--teal); margin-top: 3px; }
.tv .tv-ans { display: flex; gap: 6px; }
.tv .tv-ansbtn { min-width: 64px; min-height: 40px; padding: 8px 12px; border-radius: 6px; font-size: 12.5px; font-weight: 600; cursor: pointer; border: 1px solid var(--line); background: var(--panel); color: var(--dim2); }
.tv .tv-ansbtn.on.ok { background: var(--teal); border-color: var(--teal); color: #fff; }
.tv .tv-ansbtn.on.na { background: var(--dim2); border-color: var(--dim2); color: var(--panel); }
.tv .tv-ansbtn.on.punch, .tv .tv-ansbtn.on[data-cat="A"] { background: var(--accent); border-color: var(--accent); color: #fff; }
.tv .tv-ansbtn.on[data-cat="B"] { background: var(--dim2); border-color: var(--dim2); color: var(--panel); }
.tv .tv-ansbtn:disabled { opacity: .55; cursor: not-allowed; }
.tv .tv-punch { border: 1px solid var(--accent); background: rgba(255,90,31,.06); border-radius: 6px; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.tv .tv-punch .tv-foot { border: 0; padding: 0; }
.tv .tv-jbtn { min-height: 34px; padding: 5px 12px; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 12.5px; border: 1px solid var(--line); background: var(--panel); color: var(--text); }
.tv .tv-jbtn.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.tv .tv-eq { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; margin-top: 8px; font-size: 13px; }
.tv .tv-okbtn { background: var(--teal); border-color: var(--teal); color: #fff; }
.tv .tv-list { list-style: none; margin: 0; padding: 4px 16px; }
.tv .tv-list li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; padding: 11px 0; border-bottom: 1px solid var(--line2); font-size: 13.5px; }
.tv .tv-ico { display: inline-block; width: 16px; font-weight: 700; } .tv .tv-ico.ok { color: var(--teal); } .tv .tv-ico.bad { color: var(--accent); }
.tv .tv-hist { list-style: none; margin: 0; padding: 4px 16px 14px; }
.tv .tv-hist li { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 9px 0; border-bottom: 1px solid var(--line2); font-size: 12.5px; }
.tv .tv-hist li > span:first-child, .tv .tv-hist li > span:nth-child(2) { min-width: 150px; }
.tv .tv-signwrap { display: flex; flex-wrap: wrap; gap: 24px; padding-top: 14px; }
.tv .tv-gates { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; font-size: 13.5px; flex: 1 1 260px; }
.tv .tv-signform { display: flex; flex-direction: column; gap: 12px; flex: 1 1 300px; }
.tv .tv-signform .tv-err, .tv .tv-signform .tv-note { margin: 0; }
.tv .tv-signed { background: rgba(20,184,166,.12); color: var(--teal); border-radius: 6px; padding: 10px 12px; font-size: 13px; font-weight: 600; }

/* CTR-sized scaffold & barricade steps in the work pack builder (CIQ-SPEC-003
   §6.3a). Hours on these rows are computed, so the hours cell is text, not an
   input. Touch targets are 44 px for gloved / tablet use. */
.ctr-quick { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; background: var(--panel2); }
.ctr-lbl { display: block; font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); margin-bottom: 6px; }
.ctr-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ctr-tot { margin-bottom: 12px; }
.ctr-tot:empty { display: none; }
.ctr-tot-head { font-size: 10.5px; color: var(--dim); margin-bottom: 4px; }
.ctr-tot-row { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; font-size: 12.5px; }
.ctr-pill { font-family: 'IBM Plex Mono', monospace; font-size: 11px; padding: 2px 8px; border: 1px solid var(--line); border-radius: 999px; }
.ctr-pill.warn { border-color: var(--amber); color: var(--amber); }
.ctr-pill.bad { border-color: var(--accent); color: var(--accent); }

.wb-ctr .ctr-main { min-width: 0; }
.wb-ctr.open { border-bottom-color: transparent; }
.ctr-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.ctr-tag { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; padding: 2px 7px; border-radius: 6px; background: var(--sunk); border: 1px solid var(--line); }
.ctr-sub { font-size: 10.5px; color: var(--dim); }
.ctr-flag { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; color: var(--accent); }
.ctr-flag.amber { color: var(--amber); }
.ctr-flag.bad { color: var(--accent); font-weight: 700; }
.ctr-hrs { font-size: 12px; font-weight: 700; padding-top: 10px; text-align: right; }

.ctr-ed { border: 1px solid var(--line); border-radius: 10px; padding: 14px; margin: 0 0 12px 36px; background: var(--panel2); display: flex; flex-direction: column; gap: 14px; }
.ctr-sec { display: block; }
.ctr-chip-btn { min-height: 44px; padding: 6px 12px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: inherit; font: inherit; font-size: 12.5px; cursor: pointer; display: inline-flex; flex-direction: column; align-items: flex-start; justify-content: center; }
.ctr-chip-btn small { font-size: 10px; color: var(--dim); }
.ctr-chip-btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.ctr-chip-btn:focus-visible, .ctr-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ctr-dims { display: flex; flex-wrap: wrap; gap: 12px; }
.ctr-dim { display: flex; flex-direction: column; gap: 4px; }
.ctr-dim label { font-size: 11.5px; color: var(--dim); }
.ctr-num { display: flex; align-items: center; gap: 4px; }
.ctr-num .icon-btn { width: 44px; height: 44px; font-size: 18px; }
.ctr-num input { width: 78px; height: 44px; text-align: center; }
.ctr-dim input[data-ctr-ovr] { height: 44px; }
.ctr-check { display: flex; gap: 8px; align-items: center; font-size: 12.5px; min-height: 44px; cursor: pointer; }
.ctr-check input { width: 18px; height: 18px; accent-color: var(--accent); }

.ctr-band { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; }
.ctr-band-seg { padding: 6px 8px; border-radius: 6px; background: var(--sunk); font-size: 11.5px; display: flex; flex-direction: column; opacity: .55; border: 1px solid transparent; }
.ctr-band-seg small { font-size: 10px; color: var(--dim); }
.ctr-band-seg.on { opacity: 1; border-color: var(--line); font-weight: 600; }
.ctr-band-seg.review.on, .ctr-band-seg.stamped.on { border-color: var(--amber); color: var(--amber); }
.ctr-band-seg.blocked.on { border-color: var(--accent); color: var(--accent); }

.ctr-card { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: var(--panel); }
.ctr-card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.ctr-card-total { font-size: 12px; font-weight: 700; }
.ctr-work { margin: 0; padding-left: 20px; font-size: 12.5px; line-height: 1.7; }
.ctr-src { font-size: 10.5px; color: var(--dim); margin-top: 6px; }
.ctr-err { border: 1px solid var(--accent); color: var(--accent); border-radius: 8px; padding: 8px 10px; font-size: 12.5px; margin-top: 8px; }
.ctr-fx { margin-top: 10px; }
.ctr-fx-item { font-size: 12.5px; padding: 6px 10px; border-radius: 6px; background: var(--sunk); margin-bottom: 4px; }
.ctr-fx-item.constraint { border-left: 0; color: var(--amber); }
.ctr-link { background: none; border: 0; padding: 0; min-height: 44px; color: var(--accent); font: inherit; font-size: 12.5px; text-decoration: underline; cursor: pointer; }

.ctr-pack-tag { font-size: 10.5px; color: var(--dim); margin-top: 3px; }
.ctr-pack { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-bottom: 14px; }
.ctr-pack-list { margin-top: 8px; font-size: 12.5px; }
.ctr-pack-list > div { padding: 2px 0; }
.ctr-pack-list .warn { color: var(--amber); }

@media (max-width: 640px) {
  .wb-act .ctr-main { grid-area: text; }
  .wb-act .ctr-hrs { grid-area: hrs; padding-top: 10px; }
  .ctr-ed { margin-left: 0; }
  .ctr-band { grid-template-columns: repeat(2, 1fr); }
}
