/* ============================================================
   DEFUSE R — design foundation
   Brand language drawn from the VIDA contractor-portal guide:
   hazard strip, midnight masthead, hi-vis amber action colour.
   ============================================================ */
:root {
  --rail-blue:#2774ae;
  --roads-orange:#ff9d14;     /* hi-vis amber — primary action */
  --services-orange:#ff5700;  /* danger / alert */
  --ai-violet:#7c4dff;        /* AI actions (Capture / Walk) — distinct from amber */
  --ai-violet-2:#9d6bff;
  --midnight:#002532;         /* dominant industrial dark */
  --midnight-2:#001820;
  --asphalt:#1a1f24;
  --slate:#3f4447;
  --concrete:#5a5b5d;
  --paper:#f5f1ec;
  --line:rgba(255,255,255,0.12);
  --line-strong:rgba(255,255,255,0.28);
  --hazard-yellow:#ffeb2c;
  --ok:#22c55e;
  --warn:#ff9d14;
  --down:#f85149;

  --font-display:"Barlow Condensed",Impact,sans-serif;
  --font-body:"Public Sans",system-ui,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,monospace;

  --topbar-h:64px;
  --hazard-h:10px;
}

* { box-sizing:border-box; margin:0; padding:0; }
html, body {
  background:var(--paper);
  color:var(--asphalt);
  font-family:var(--font-body);
  font-size:15px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
  -webkit-text-size-adjust:100%;
  /* iOS: no sideways page drag / rubber-band when there's nothing to scroll horizontally.
     overscroll-behavior-x kills the horizontal bounce; overflow-x:hidden clips any stray
     overflow so the page can't be panned left/right. (Vertical scroll/bounce is unchanged.) */
  overflow-x:hidden;
  /* …but as CLIP where the browser has it (2026-10-05): overflow-x:hidden on BOTH html and body turns body into
     a scroll container that never scrolls, and every position:sticky element then sticks to IT — i.e. never
     (the capture review's bottom action bar sat at the end of the page). clip cuts the stray overflow the same
     way without making a scroll container; the hidden line above stays as the fallback for older browsers. */
  overflow-x:clip;
  overscroll-behavior-x:none;
  max-width:100%;
}
a { color:inherit; text-decoration:none; }
img { display:block; max-width:100%; }
h1,h2,h3 { font-family:var(--font-display); text-transform:uppercase; letter-spacing:0.01em; line-height:1; }
/* <FocusOnNavigate> focuses the page <h1> after navigation (screen-reader context) by
   giving it tabindex="-1"; it isn't interactive, so hide the resulting focus outline. */
[tabindex="-1"]:focus { outline: none; }

/* ---- boot screen (pre-WASM) ---- */
.boot-screen { position:relative; overflow:hidden; min-height:100vh; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:0; padding:40px 20px; color:#fff;
  background:radial-gradient(circle at 50% 32%, #013242 0%, var(--midnight) 58%, #001016 100%); }
/* industrial hazard strips top + bottom */
.boot-hazard { position:absolute; left:0; right:0; height:8px;
  background:repeating-linear-gradient(135deg, var(--hazard-yellow) 0 14px, var(--asphalt) 14px 28px); }
.boot-hazard.top { top:0; } .boot-hazard.bottom { bottom:0; }
.boot-inner { z-index:2; display:flex; flex-direction:column; align-items:center; gap:18px; width:100%; max-width:520px; }
.boot-logo { height:62px; width:auto; max-width:90%; filter:drop-shadow(0 4px 18px rgba(0,0,0,.45)); }
.boot-scene { width:100%; max-width:480px; height:auto; opacity:.96;
  animation:boot-float 4.5s ease-in-out infinite; transform-origin:50% 100%; }
@keyframes boot-float { 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-5px); } }
.boot-sub  { font-family:var(--font-mono); font-size:12px; letter-spacing:0.2em; text-transform:uppercase; color:#9aa3aa; }
/* indeterminate hazard-striped loading bar */
.boot-bar { position:relative; width:220px; height:6px; border-radius:3px; overflow:hidden; background:rgba(255,255,255,.12); }
.boot-bar span { position:absolute; top:0; bottom:0; width:42%; border-radius:3px;
  background:repeating-linear-gradient(135deg, var(--hazard-yellow) 0 8px, var(--asphalt) 8px 16px);
  animation:boot-sweep 1.25s ease-in-out infinite; }
@keyframes boot-sweep { 0%{ left:-42%; } 100%{ left:100%; } }
/* footer brand: VIDA Roads plate + tagline */
.boot-foot { position:absolute; bottom:26px; z-index:2; display:flex; flex-direction:column; align-items:center; gap:8px; }
.boot-plate { background:#fff; border-radius:6px; padding:7px 14px; display:flex; align-items:center;
  box-shadow:0 4px 16px rgba(0,0,0,.35); }
.boot-plate img { height:30px; width:auto; display:block; }
.boot-tag { font-family:var(--font-mono); font-size:11px; letter-spacing:0.18em; text-transform:uppercase; color:#5c6b73; }
/* update notice — shown when the startup version check finds a newer build */
.boot-update { display:flex; align-items:center; gap:14px; max-width:360px; padding:14px 18px;
  border:1px solid rgba(255,157,20,.55); border-radius:12px; background:rgba(255,157,20,.10);
  box-shadow:0 8px 28px rgba(0,0,0,.35); text-align:left; animation:boot-update-in .35s ease-out; }
.boot-update[hidden] { display:none; }
.boot-update-icon { width:30px; height:30px; flex:none; color:var(--roads-orange);
  animation:boot-bob 1.6s ease-in-out infinite; }
.boot-update-text { display:flex; flex-direction:column; gap:4px; }
.boot-update-text strong { font-family:var(--font-display); text-transform:uppercase;
  letter-spacing:0.04em; font-size:18px; color:#fff; }
.boot-update-sub { font-size:12.5px; line-height:1.45; color:#cdd5da; }
/* while updating, the generic "loading…" line is redundant — the notice says it all */
.boot-screen.is-updating .boot-sub { display:none; }
@keyframes boot-update-in { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
@keyframes boot-bob { 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(4px); } }
@media (prefers-reduced-motion: reduce) { .boot-scene, .boot-bar span, .boot-update-icon { animation:none; } }

/* ============= APP SHELL ============= */
.app-shell { min-height:100vh; display:flex; flex-direction:column; }
.hazard-strip {
  height:var(--hazard-h);
  background:repeating-linear-gradient(135deg, var(--hazard-yellow) 0 16px, var(--asphalt) 16px 32px);
  border-bottom:1px solid #000;
}

/* ---- masthead / topbar ---- */
.masthead {
  background:var(--midnight);
  border-bottom:3px solid var(--roads-orange);
  position:sticky; top:0; z-index:50;
}
.nav-row { display:flex; align-items:stretch; gap:0; padding:0 20px; min-height:var(--topbar-h); }

.brand-lockup { display:flex; align-items:center; gap:14px; padding:10px 22px 10px 0; border-right:1px solid var(--line); flex-shrink:0; }
/* Fixed logo size (was an inline height on the img). flex-shrink:0 on the lockup keeps it a
   CONSTANT size — otherwise a crowded masthead flex-shrinks it, so it appeared to grow when the
   burger/nav were removed on entering a project work space (mobile). */
.brand-logo { height:46px; width:auto; display:block; }
.brand-plate { background:#fff; border-radius:6px; padding:7px 12px; display:flex; align-items:center; }
.brand-plate img { height:26px; width:auto; }
.brand-suffix { font-family:var(--font-display); font-weight:900; font-size:24px; letter-spacing:0.06em;
  color:#fff; text-transform:uppercase; }
.brand-suffix .x { color:var(--roads-orange); }

/* ---- primary nav ---- */
nav.primary { display:flex; flex:1; align-items:stretch; overflow-x:auto; }
nav.primary a {
  display:flex; align-items:center; gap:9px; padding:0 18px; white-space:nowrap;
  font-family:var(--font-display); font-weight:700; font-size:15px; letter-spacing:0.05em;
  text-transform:uppercase; color:#cbd3d9; border-right:1px solid var(--line);
  transition:background .15s, color .15s; position:relative;
}
nav.primary a:first-child { border-left:1px solid var(--line); }
nav.primary a:hover { background:var(--midnight-2); color:#fff; }
nav.primary a.active { color:#fff; background:var(--midnight-2); }
/* bottom:0 (not -3px): keep the underline INSIDE the nav box. nav.primary has
   overflow-x:auto, which forces overflow-y to auto too — a pseudo-element poking
   3px below the box adds vertical overflow → a stray vertical scrollbar on the
   navbar whenever a tab is active. */
nav.primary a.active::before { content:""; position:absolute; left:0; right:0; bottom:0; height:3px; background:var(--roads-orange); }
nav.primary a svg { width:18px; height:18px; flex:0 0 18px; color:var(--roads-orange); }

/* ---- right side: connectivity + user ---- */
.nav-aside { display:flex; align-items:center; gap:14px; margin-left:auto; padding-left:18px; }
/* Connectivity indicator: colour only (no text) — glows green online, red offline. */
.net-pill {
  display:inline-flex; align-items:center; justify-content:center; border:1px solid var(--line-strong);
  padding:7px; cursor:pointer; background:transparent; border-radius:50%;
}
.net-pill .dot { width:12px; height:12px; border-radius:50%; transition:background .3s ease; }
.net-pill.online  .dot { background:var(--ok);   animation:net-glow-ok 2.2s ease-in-out infinite; }
.net-pill.managed .dot { background:#f5a623;     animation:net-glow-managed 2.2s ease-in-out infinite; }
.net-pill.offline .dot { background:var(--down); animation:net-glow-down 2.2s ease-in-out infinite; }
.net-pill:hover { border-color:var(--roads-orange); }
@keyframes net-glow-ok      { 0%,100% { box-shadow:0 0 5px 1px var(--ok);   } 50% { box-shadow:0 0 12px 3px var(--ok);   } }
@keyframes net-glow-managed { 0%,100% { box-shadow:0 0 5px 1px #f5a623;     } 50% { box-shadow:0 0 12px 3px #f5a623;     } }
@keyframes net-glow-down    { 0%,100% { box-shadow:0 0 5px 1px var(--down); } 50% { box-shadow:0 0 12px 3px var(--down); } }

/* Connection banner — slow-connection prompt (amber) + managed-mode indicator. */
.conn-banner {
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  padding:9px 16px; font-size:13.5px; line-height:1.4;
  border-bottom:1px solid rgba(245,166,35,.45); background:rgba(245,166,35,.13); color:var(--ink, #221f20);
}
.conn-banner .conn-msg { flex:1 1 240px; }
.conn-banner .conn-actions { display:inline-flex; gap:8px; flex-wrap:wrap; }
.conn-banner .btn-sm { padding:5px 12px; font-size:12.5px; }

/* Outbox badge — count of offline writes queued to sync (sits beside the net pill). */
.outbox-badge {
  display:inline-flex; align-items:center; gap:3px; margin-left:6px; padding:3px 8px;
  border-radius:11px; font-weight:600; font-size:12px; line-height:1; white-space:nowrap;
  color:var(--services-orange); background:rgba(255,87,0,.15); border:1px solid rgba(255,87,0,.42);
}
.outbox-badge .outbox-arrow { font-size:13px; line-height:1; }

/* Failed-writes badge + review panel (dead-lettered outbox ops). */
.outbox-failed-wrap { position:relative; display:inline-flex; }
.outbox-failed {
  display:inline-flex; align-items:center; gap:3px; margin-left:6px; padding:3px 9px;
  border-radius:11px; font-weight:700; font-size:12px; line-height:1; white-space:nowrap; cursor:pointer;
  color:#fff; background:var(--down); border:1px solid var(--down);
}
.outbox-failed-panel {
  position:absolute; top:calc(100% + 8px); right:0; z-index:80; width:300px; max-width:84vw;
  background:var(--midnight-2); color:#e6e9ec; border:1px solid var(--line-strong);
  border-radius:8px; box-shadow:0 10px 26px rgba(0,0,0,.45); padding:11px 13px;
}
.outbox-failed-panel .ofp-head { font-weight:700; margin-bottom:8px; color:var(--down); }
.outbox-failed-panel .ofp-list { list-style:none; margin:0 0 11px; padding:0; max-height:42vh; overflow:auto; }
.outbox-failed-panel .ofp-list li { display:flex; flex-direction:column; gap:1px; padding:6px 0; border-bottom:1px solid var(--line); }
.outbox-failed-panel .ofp-what { font-weight:600; font-size:13px; }
.outbox-failed-panel .ofp-err { font-size:11px; color:#9aa3ab; word-break:break-word; }
.outbox-failed-panel .ofp-actions { display:flex; gap:8px; justify-content:flex-end; }
.outbox-failed-panel .btn { padding:6px 12px; font-size:12px; }

/* User chip is now a button that opens a Sign-out dropdown (clicking it no longer logs out). */
.user-menu { position:relative; }
.user-chip { display:flex; align-items:center; gap:8px; color:#cbd3d9; font-size:13px;
  background:transparent; border:none; cursor:pointer; font-family:inherit; padding:4px 6px; border-radius:6px; }
.user-chip:hover { background:rgba(255,255,255,.08); }
.user-chip .avatar { width:30px; height:30px; border-radius:50%; background:var(--roads-orange); color:#000;
  display:flex; align-items:center; justify-content:center; font-weight:800; font-family:var(--font-display); }
.user-chip .caret { color:#cbd3d9; font-size:11px; }
/* Header user chip is avatar-only — the name + dropdown caret are hidden (the name still shows
   inside the dropdown). Avatar keeps the connectivity dot. */
.user-chip .uname, .user-chip .caret { display:none; }
/* min-width 260 (was 180): a typical user email fits on ONE line in the name block; capped
   to the viewport so a phone never clips the menu off-screen. */
.user-dropdown { position:absolute; right:0; top:calc(100% + 8px); min-width:260px; max-width:min(92vw, 360px); background:#fff;
  border:1px solid rgba(0,0,0,.12); border-radius:8px; box-shadow:0 10px 30px rgba(0,0,0,.3); padding:6px; z-index:1200; }
.user-dropdown-name { padding:8px 10px; font-size:12px; color:#5a6470; border-bottom:1px solid rgba(0,0,0,.08);
  margin-bottom:4px; word-break:break-word; }
.user-dropdown-item { display:block; width:100%; text-align:left; background:transparent; border:none;
  padding:9px 10px; font-size:14px; color:#221f20; cursor:pointer; border-radius:6px; font-family:inherit; }
.user-dropdown-item:hover { background:rgba(0,0,0,.06); }
/* Connection speed dial (ConnectionSpeedDial.txt) — a narrow SVG ring wrapping the avatar, filled to the
   measured connection speed and coloured by band: red = offline (full ring), amber = poor, green = good.
   Replaces the old corner status dot. */
.user-chip .avatar { position:relative; overflow:visible; }
.avatar.conn-dial .avatar-initials { position:relative; z-index:1; }
/* rotate 90° so the arc STARTS at 6 o'clock and fills clockwise (6→9→12→3→6). */
.avatar.conn-dial .dial-ring { position:absolute; inset:-3px; width:calc(100% + 6px); height:calc(100% + 6px);
  transform:rotate(90deg); pointer-events:none; }
.avatar.conn-dial .dial-ring circle { fill:none; stroke-width:3; }
.avatar.conn-dial .dial-track { stroke:rgba(255,255,255,.22); }
.avatar.conn-dial .dial-fill  { stroke:var(--dial-color); stroke-linecap:round; transition:stroke-dasharray .4s ease; }
/* leading-edge marker dot — always visible (at 6 o'clock when there's no connection). */
.avatar.conn-dial .dial-dot { fill:var(--dial-color); stroke:none; }
.avatar.conn-dial.dial-good { --dial-color:var(--ok,#2fbf71); }
.avatar.conn-dial.dial-poor { --dial-color:#f5a623; }
.avatar.conn-dial.dial-off  { --dial-color:var(--down,#e5484d); }
.user-dropdown-item.conn { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.user-dropdown-item.conn .dot { width:10px; height:10px; border-radius:50%; flex:0 0 auto; background:var(--concrete); }
.user-dropdown-item.conn.online  .dot { background:var(--ok); }
.user-dropdown-item.conn.managed .dot { background:#f5a623; }
.user-dropdown-item.conn.offline .dot { background:var(--down); }
.user-dropdown-item.conn .conn-hint { margin-left:auto; font-size:11px; color:#9aa3aa; }
/* Observed transfer speeds (field feedback) — a second line under the mode label: ↑ upload ·
   ↓ download, measured from real transfers (stale readings carry an "(Nm ago)" age). */
.user-dropdown-item.conn .conn-speeds { flex-basis:100%; font-size:11px; color:#8a939b;
  margin-top:2px; padding-left:18px; font-variant-numeric:tabular-nums; }
/* Below the sticky masthead (z-index:50) so the dropdown — which lives inside the
   masthead's stacking context — paints ABOVE the scrim and stays clickable, while the
   scrim still covers page content to catch outside clicks. */
.menu-scrim { position:fixed; inset:0; z-index:40; background:transparent; }

/* ---- mobile nav toggle ---- */
.nav-burger { display:none; background:transparent; border:1px solid var(--line-strong); color:#fff;
  padding:8px 10px; cursor:pointer; align-self:center; }

/* Masthead utility icon buttons (Help / Ask) — HelpFeature.txt. */
.util-btn { display:inline-flex; align-items:center; justify-content:center; align-self:center;
  width:36px; height:36px; border:1px solid var(--line-strong); border-radius:50%; background:transparent;
  color:#cbd3d9; cursor:pointer; text-decoration:none; transition:border-color .15s, color .15s; }
.util-btn:hover { border-color:var(--roads-orange); color:#fff; }
.util-btn.active { border-color:var(--roads-orange); color:var(--roads-orange); }
.util-btn .ico { width:18px; height:18px; }
/* Help + Ask stand out in amber (a shared accent) so they read as the help utilities. */
.util-accent { color:var(--roads-orange); border-color:rgba(255,157,20,.5); }
.util-accent:hover { color:#fff; background:rgba(255,157,20,.16); border-color:var(--roads-orange); }

/* ============= MAIN CONTENT ============= */
/* Desktop bottom padding is modest — the 96px clearance is only needed on mobile (the fixed bottom
   nav), where the media query re-adds it. On desktop there's no bottom nav, so 96px was dead space
   that pushed the in-flow footer past the viewport (most visible on the Projects page). */
.layout-main { flex:1; width:100%; max-width:1480px; margin:0 auto; padding:28px 24px 40px; }
.page-head { display:flex; align-items:flex-end; justify-content:space-between; gap:24px; flex-wrap:wrap; margin-bottom:24px; }
.page-head .eyebrow { font-family:var(--font-mono); font-size:11px; letter-spacing:0.22em; text-transform:uppercase;
  color:var(--services-orange); margin-bottom:10px; display:flex; align-items:center; gap:10px; }
.page-head .eyebrow::before { content:""; width:28px; height:2px; background:var(--services-orange); display:inline-block; }
/* Eyebrow breadcrumb (EyebrowBreadcrumbs.txt): the parent segment is a link back to the list
   (retaining the project filter); the current record follows. Inherits the eyebrow's mono/orange
   styling so it reads as one breadcrumb line on desktop + iPhone. */
.page-head .eyebrow-crumb { flex-wrap:wrap; gap:8px; }
.page-head .eyebrow-crumb .crumb-parent { color:inherit; text-decoration:none; border-bottom:1px solid transparent; }
.page-head .eyebrow-crumb .crumb-parent:hover,
.page-head .eyebrow-crumb .crumb-parent:focus-visible { border-bottom-color:currentColor; }
.page-head .eyebrow-crumb .crumb-sep { opacity:.55; }
.page-head .eyebrow-crumb .crumb-current { color:var(--asphalt); }
.page-head h1 { font-size:clamp(34px,5vw,56px); font-weight:900; color:var(--asphalt); }
/* Action buttons in a page header — flex so icon + text buttons line up (their
   baselines differ otherwise, e.g. an AiSpark button next to a text-only one). */
.head-actions { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }

/* Shared line icons (Icon.razor) — sit on the text baseline when used inline. */
.ico { vertical-align:-0.15em; flex-shrink:0; }

/* Sortable table headers (click to sort; arrow shows the active column/direction). */
.data-table th.sortable { cursor:pointer; user-select:none; white-space:nowrap; }
.data-table th.sortable:hover { color:var(--roads-orange); }

/* ---- cards / tiles ---- */
.tile-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:1px; background:rgba(0,0,0,.1);
  border:1px solid rgba(0,0,0,.1); margin-bottom:24px; }
.tile { background:#fff; padding:24px; display:flex; flex-direction:column; gap:6px; position:relative; transition:background .15s; }
.tile .k { font-family:var(--font-mono); font-size:10px; letter-spacing:0.18em; text-transform:uppercase; color:var(--concrete); }
.tile .v { font-family:var(--font-display); font-weight:800; font-size:38px; line-height:1; color:var(--asphalt); }
.tile .sub { font-size:13px; color:var(--slate); }

.card { background:#fff; border:1px solid rgba(0,0,0,.12); padding:22px; }
.card h2, .card h3 { color:var(--asphalt); margin-bottom:12px; }
.card-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:16px; }

/* ---- buttons ---- */
.btn { font-family:var(--font-display); font-weight:800; text-transform:uppercase; letter-spacing:0.06em;
  font-size:14px; padding:13px 22px; display:inline-flex; align-items:center; gap:10px; border:none; cursor:pointer; transition:all .15s; }
.btn-primary { background:var(--roads-orange); color:#000; clip-path:polygon(9px 0,100% 0,calc(100% - 9px) 100%,0 100%); }
.btn-primary:hover { background:#ffb84d; }
/* AI actions — same rhombus shape as primary, violet to signal "AI" */
.btn-ai { background:var(--ai-violet); color:#fff; clip-path:polygon(9px 0,100% 0,calc(100% - 9px) 100%,0 100%); }
.btn-ai:hover { background:var(--ai-violet-2); }
.btn-ai-ghost { background:transparent; color:var(--ai-violet); border:1px solid rgba(124,77,255,.45); clip-path:polygon(9px 0,100% 0,calc(100% - 9px) 100%,0 100%); }
.btn-ai-ghost:hover { background:rgba(124,77,255,.08); border-color:var(--ai-violet); }
.btn-ghost { background:transparent; color:var(--asphalt); border:1px solid rgba(0,0,0,.25); }
.btn-ghost:hover { border-color:var(--roads-orange); color:var(--services-orange); }
.btn:disabled { opacity:.5; cursor:not-allowed; }
button.ghost { background:transparent; border:1px solid rgba(0,0,0,.25); padding:7px 14px; cursor:pointer; font-family:var(--font-body); font-size:13px; }
button.ghost:hover:not(:disabled) { border-color:var(--roads-orange); }
button.ghost:disabled { opacity:.45; cursor:not-allowed; }
.link { background:none; border:none; color:var(--rail-blue); cursor:pointer; padding:0; font:inherit; text-decoration:underline; }
.link.danger { color:var(--services-orange); }

/* ---- badges / status ---- */
.tag { font-family:var(--font-mono); font-size:10px; letter-spacing:0.12em; text-transform:uppercase; padding:3px 8px; border:1px solid rgba(0,0,0,.2); }
.badge { display:inline-block; font-size:11px; font-weight:600; padding:2px 9px; border-radius:999px; }
.badge.amber { background:rgba(255,157,20,.16); color:#9a5b00; }
.badge.blue  { background:rgba(39,116,174,.16); color:#1c5582; }
.badge.green { background:rgba(34,197,94,.16); color:#157a3a; }
.badge.green-dark { background:#157a3a; color:#fff; }
.badge.orange { background:#f26a00; color:#fff; }   /* Ready to review — a prominent call to action */   /* Submitted capture — solid dark green, distinct from "Ready to review" */
.badge.grey  { background:rgba(0,0,0,.08); color:var(--slate); }
.badge.red   { background:rgba(224,50,45,.16); color:#b3261e; }
.badge.blocked { background:#221f20; color:#ff9d14; }   /* Pending/blocked task — bitumen + amber, distinct from Open (red) */
.badge.blue-dark { background:#1c5582; color:#fff; }   /* DefuserRefinements20260913 — "Ready to submit" (every item reviewed) */
/* Severity badges — ONE scheme across every register (defect Minor/Moderate/Major and safety
   Low/Medium/High share colours, matching the map pin severities); Critical = red on black. */
.badge.sev-low  { background:rgba(46,158,79,.16); color:#157a3a; }
.badge.sev-med  { background:rgba(255,122,0,.16); color:#b35400; }
.badge.sev-high { background:rgba(224,50,45,.16); color:#b3261e; }
.badge.sev-crit { background:#221f20; color:#ff453a; }
/* Project-hierarchy badges — distinct colours for Portfolio / Program / each Contractor. */
.badge.portfolio  { background:rgba(124,77,255,.16); color:#6b2fd6; }   /* purple */
.badge.program    { background:rgba(13,148,136,.16); color:#0f766e; }   /* teal */
.badge.contractor { background:rgba(37,116,174,.16); color:#1c5582; }   /* blue */
/* TeamBinder reference pills on the WP workspace header (WP number · contract no · program code) —
   neutral bitumen tint, monospaced so the codes line up. */
.badge.tbref { background:rgba(34,31,32,.08); color:#221f20;
    font-family:ui-monospace, SFMono-Regular, Consolas, monospace; font-size:11px; }

/* expandable defect rows (Defects page + Projects defects modal) */
.data-table tr.rowexpand { cursor:pointer; }
.data-table tr.rowexpand:hover { background:rgba(0,0,0,.03); }
.data-table tr.expanded { background:rgba(255,87,0,.07); }
.data-table tr.detail-row > td { background:rgba(0,0,0,.02); padding:14px 16px; }

.ok { color:var(--ok); font-weight:700; }
.down { color:var(--down); font-weight:700; }
.warn { color:var(--warn); font-weight:700; }
.muted { color:var(--concrete); }
.small { font-size:12px; }
.mono { font-family:var(--font-mono); }

/* ---- tables ---- */
.table-wrap { overflow-x:auto; border:1px solid rgba(0,0,0,.12); background:#fff; }
table.data-table { width:100%; border-collapse:collapse; font-size:14px; }
.data-table th { text-align:left; font-family:var(--font-mono); font-size:10px; letter-spacing:0.12em; text-transform:uppercase;
  color:var(--concrete); padding:12px 14px; border-bottom:1px solid rgba(0,0,0,.12); white-space:nowrap; }
.data-table td { padding:11px 14px; border-bottom:1px solid rgba(0,0,0,.06); }
.data-table tr:hover td { background:#fffbf3; }

/* ---- forms ---- */
label.field { display:block; margin-bottom:14px; }
label.field > span { display:block; font-family:var(--font-mono); font-size:10px; letter-spacing:0.12em;
  text-transform:uppercase; color:var(--concrete); margin-bottom:5px; }
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=datetime-local], input[type=time], input[type=search],
input[type=tel], input[type=url], input:not([type]), textarea, select {
  /* font-size MUST be ≥16px: iOS Safari zooms the whole page in whenever you focus a form field
     smaller than that, and the zoom persists — which made the app look like it "spilled right"
     (you'd zoomed in by focusing the 15px login fields, then panned the zoomed page). 16px = no zoom. */
  width:100%; padding:10px 12px; border:1px solid rgba(0,0,0,.22); background:#fff; font:inherit; font-size:16px; color:var(--asphalt); }
textarea { min-height:84px; resize:vertical; }
/* iOS renders date/time inputs as a NATIVE control that keeps its intrinsic width no matter
   what width:100% / min-width:0 say — stripping the native appearance makes them size and
   align exactly like the text boxes beside them (the guard the defect edit modal + task
   detail already carried locally; global so the wizard Map step et al. match "Created by").
   min-height keeps the tap target once the native chrome is gone; iOS centres the value by
   default, so left-align to match ordinary inputs. */
input[type=date], input[type=time], input[type=datetime-local] {
  -webkit-appearance:none; appearance:none; display:block; min-width:0; min-height:44px; text-align:left; }
input:focus, textarea:focus, select:focus { outline:2px solid var(--roads-orange); outline-offset:-1px; }

/* ============= MAP COMPONENT (ported) ============= */
.map-wrap { border:1px solid rgba(0,0,0,.14); background:#fff; position:relative; }
.map-canvas { width:100%; height:440px; }

/* ===== Nearby (NearbyFeature.txt) + FloatingSheet — GLOBAL CSS =====
   DefuseR links only css/app.css (index.html has NO *.styles.css scoped bundle) — so ALL DefuseR CSS
   must live here; scoped .razor.css files DO NOT load. Inline (MarkupString) SVG icons carry a viewBox
   but no width/height, so without explicit sizing they render at the SVG default 300x150. */
.nearby-pin svg { width:24px; height:24px; display:block; }
.nearby-recentre svg { width:20px; height:20px; display:block; }
.fsheet-chip-ic svg { width:18px; height:18px; display:block; }

.nearby-head { display:flex; flex-direction:column; gap:6px; padding:10px 12px; background:#fff;
  border:1px solid rgba(0,0,0,.1); border-radius:10px; margin-bottom:10px; }
.nearby-head-row { display:flex; align-items:center; gap:10px; }
.nearby-pin { display:inline-flex; width:26px; height:26px; flex:0 0 auto; color:var(--roads-orange); }
.nearby-addr { flex:1 1 auto; min-width:0; font-weight:600; font-size:14px; line-height:1.25; overflow-wrap:anywhere; }
.nearby-coords { flex:1 1 auto; min-width:0; font-size:12px; color:var(--concrete); }
.nearby-recentre { flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center;
  width:32px; height:32px; color:#221f20; background:rgba(0,0,0,.05); border:1px solid rgba(0,0,0,.12);
  border-radius:8px; cursor:pointer; }
.nearby-recentre:disabled { opacity:.5; }
.nearby-map { margin:0 -4px; }
.nearby-map .map-wrap { border-radius:12px; overflow:hidden; }
.nearby-map .map-canvas { height:calc(100dvh - 250px); min-height:340px; }
.near-list { display:flex; flex-direction:column; gap:6px; }
.near-row { display:flex; align-items:stretch; gap:6px; border:1px solid rgba(0,0,0,.08); border-radius:10px;
  overflow:hidden; background:#fff; }
.near-row.here { border-color:rgba(255,157,20,.55); background:rgba(255,157,20,.08); }
.near-main { flex:1 1 auto; min-width:0; text-align:left; padding:9px 11px; background:transparent; border:0; cursor:pointer; color:inherit; }
.near-title { display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-weight:600; font-size:14px; }
.near-name { overflow:hidden; text-overflow:ellipsis; }
.near-sub { display:flex; flex-wrap:wrap; gap:4px; font-size:12px; color:var(--concrete); margin-top:2px; }
.near-dist { font-weight:700; color:#221f20; }
.near-ref { font-size:12px; color:var(--concrete); }
.near-here { font-size:10px; font-weight:800; letter-spacing:.04em; text-transform:uppercase; color:#221f20;
  background:var(--roads-orange); padding:1px 6px; border-radius:999px; }
.near-open { flex:0 0 auto; display:inline-flex; align-items:center; padding:0 14px; font-size:13px; font-weight:600;
  text-decoration:none; color:#b3410a; background:rgba(0,0,0,.03); border-left:1px solid rgba(0,0,0,.08); }
.near-open:hover { background:rgba(255,157,20,.14); }
.near-empty { padding:16px 8px; text-align:center; color:var(--concrete); font-size:13px; }
.nearby-msg { margin-top:14px; display:flex; flex-direction:column; gap:10px; align-items:flex-start; }

.fsheet { position:fixed; left:0; right:0; bottom:0; z-index:60; display:flex; flex-direction:column-reverse; pointer-events:none; }
@media (max-width:760px) { .fsheet { bottom:calc(56px + env(safe-area-inset-bottom)); } }
.fsheet-bar, .fsheet-body { pointer-events:auto; }
.fsheet-bar { display:flex; align-items:stretch; gap:6px; padding:8px 10px; background:rgba(34,31,32,.96);
  border-top:2px solid var(--roads-orange); box-shadow:0 -6px 22px rgba(0,0,0,.28); }
.fsheet-chip { flex:1 1 0; min-width:0; display:flex; align-items:center; justify-content:center; gap:7px;
  padding:9px 8px; font-family:var(--font-body); font-size:13px; font-weight:600; color:rgba(255,255,255,.82);
  background:rgba(255,255,255,.06); border:1px solid transparent; border-radius:10px; cursor:pointer; }
.fsheet-chip.on { color:#221f20; background:var(--roads-orange); border-color:var(--roads-orange); }
.fsheet-chip-ic { display:inline-flex; width:18px; height:18px; flex:0 0 auto; }
.fsheet-chip-lbl { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.fsheet-chip-n { flex:0 0 auto; min-width:20px; padding:0 6px; font-size:12px; font-weight:700; text-align:center;
  border-radius:999px; background:rgba(255,255,255,.16); }
.fsheet-chip.on .fsheet-chip-n { background:rgba(34,31,32,.18); }
.fsheet-grip { flex:0 0 auto; display:flex; align-items:center; justify-content:center; width:40px;
  background:rgba(255,255,255,.06); border:0; border-radius:10px; cursor:pointer; }
.fsheet-grip-bar { width:20px; height:4px; border-radius:2px; background:rgba(255,255,255,.6); }
.fsheet-body { display:none; max-height:62vh; overflow-y:auto; overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch; background:#fff; border-top:1px solid rgba(0,0,0,.08);
  box-shadow:0 -10px 30px rgba(0,0,0,.22); padding:10px 12px 14px; }
.fsheet-open .fsheet-body { display:block; }
/* on-map overlays (replaced the old top toolbar) */
.map-status, .map-hint { position:absolute; bottom:10px; z-index:5; background:rgba(255,255,255,.92);
  border:1px solid rgba(0,0,0,.12); border-radius:6px; padding:4px 9px; font-size:12px; color:#5a6470; pointer-events:none; }
.map-status { left:10px; font-family:var(--font-mono); letter-spacing:.04em; text-transform:uppercase; }
.map-hint { right:10px; }
/* hovered-project locator — a pulsing ring at the boundary centre so even tiny areas are obvious */
.boundary-highlight { width:12px; height:12px; border-radius:50%; background:#ff5700;
  border:2px solid #fff; pointer-events:none; animation:bh-pulse 1.3s ease-out infinite; }
@keyframes bh-pulse { 0% { box-shadow:0 0 0 0 rgba(255,87,0,.55); } 100% { box-shadow:0 0 0 34px rgba(255,87,0,0); } }
.dgn-tip { position:absolute; z-index:30; pointer-events:none; background:rgba(34,31,32,.92); color:#fff;
  font-size:11px; padding:3px 8px; border-radius:6px; max-width:260px; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; display:none; }
/* DGN element hover pulse (DrawingInventory list rows) */
.dgn-pulse { width:12px; height:12px; border-radius:50%; background:#7c4dff;
  border:2px solid #fff; pointer-events:none; animation:dgnp-pulse 1.1s ease-out infinite; }
@keyframes dgnp-pulse { 0% { box-shadow:0 0 0 0 rgba(124,77,255,.55); } 100% { box-shadow:0 0 0 26px rgba(124,77,255,0); } }
/* Pin stacking (REWORKED — the capture-map saga's root cause lived here: the old ladder put
   photo pins IN FRONT at z6 !important, which beat inline z AND DOM order for three releases):
   photo pointers now sit at the BOTTOM (manual 1, exif/directional 2), defect/safety pins 4,
   item pills 5, the focal ring 999, the playhead 1000. !important stays to outrank any
   per-marker inline z. */
/* MapConsistency.txt (field feedback) — a photo is a simple CIRCLE on its spot; with a compass
   bearing a POINTER comes off the circle in that direction (see .map-pin-dir). The legend's
   .ml-pin / .ml-arrow swatches are the same shapes. */
.map-pin { width:14px; height:14px; border-radius:50%; background:var(--rail-blue);
  border:2px solid #fff; box-shadow:0 1px 4px rgba(0,0,0,.4); cursor:pointer; z-index:2 !important; }
.map-pin.manual { background:var(--services-orange); width:16px; height:16px; z-index:1 !important; }
.map-pin.orig { width:24px; height:24px; }   /* the photo editors' original location — a ring around the updated pin */
/* ObsGlyph (20260918) — a pin wearing a symbol (an observation's 📝): white disc, the symbol inside,
   the section colour on the ring. The legend's .lg-obs is the same swatch. */
.map-pin.glyph { width:22px; height:22px; background:#fff !important; border:2px solid var(--services-orange);
  display:flex; align-items:center; justify-content:center; font-size:12px; line-height:1; }

/* The 0×0 wrapper MapLibre positions (anchor:center → its origin = the geo point); the circle and
   the pointer are its children, so their own transforms survive the library's inline translate. */
.map-pin-wrap { position:absolute; width:0; height:0; z-index:2 !important; cursor:pointer; }
/* hover-highlight a pin (e.g. hovering its thumbnail in the defect detail gallery).
   MapLibre sets an inline transform on marker elements, so the highlight is an
   animated box-shadow PULSE (transform-independent) rather than a scale. */
.map-pin.hl { z-index:10 !important; animation:pin-pulse 1.1s ease-out infinite; }
@keyframes pin-pulse {
  0%   { box-shadow:0 0 0 0 rgba(255,87,0,.7); }
  70%  { box-shadow:0 0 0 16px rgba(255,87,0,0); }
  100% { box-shadow:0 0 0 0 rgba(255,87,0,0); }
}
/* defect markers plotted when a project is selected (colour-coded by severity) */
/* Defect map pins — the feature's icon (default: hard hat) coloured by severity.
   Icons are configurable per feature on the DLM Feature Flags page (Icons lookup). */
.defect-pin { width:20px; height:20px; color:#e0322d; cursor:pointer; z-index:4 !important;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.45)); }
.defect-pin svg { width:100%; height:100%; display:block; }
.defect-pin.sev-minor { color:#2e9e4f; }
.defect-pin.sev-moderate { color:#ff7a00; }   /* lighter than the brand orange — reads as "medium", not red */
.defect-pin.sev-major { color:#e0322d; }
.defect-pin.sev-critical { color:#a01313; }

/* Safety item hazard pins (SafetyFeature.txt) — warning triangle coloured by severity. */
.safety-pin { width:22px; height:22px; cursor:pointer; z-index:4 !important;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.45)); }
.safety-pin svg { width:100%; height:100%; display:block; }
.safety-pin.sev-low { color:#2e9e4f; }
.safety-pin.sev-medium { color:#ff7a00; }
.safety-pin.sev-high { color:#e0322d; }
.safety-pin.sev-critical { color:#a01313; }

/* ---- Unified item markers (all maps): co-located assets/defects/safety cluster into one
   pill showing the types present + counts, bordered by the worst severity; every marker's
   popup lists all items at that location. ---- */
.map-cluster { display:flex; gap:5px; align-items:center; padding:3px 8px; background:#fff;
  border:2px solid #5a5b5d; border-radius:999px; box-shadow:0 1px 6px rgba(0,0,0,.4);
  cursor:pointer; z-index:5 !important; }
.map-cluster.sev-critical { border-color:#a01313; }
.map-cluster.sev-major, .map-cluster.sev-high { border-color:#e0322d; }
.map-cluster.sev-moderate, .map-cluster.sev-medium { border-color:#ff7a00; }
.map-cluster.sev-minor, .map-cluster.sev-low { border-color:#2e9e4f; }
.map-cluster.manual { border-style:dashed; }   /* 20260915 — placed by hand (see the map legend) */
/* 20260915 — the SHARED map legend (Components/MapLegend.razor): the same symbols on every map. */
.map-legend { display:flex; flex-wrap:wrap; gap:4px 12px; font-size:11.5px; color:#3a424d; padding:6px 8px; margin-top:6px;
  background:rgba(255,255,255,.92); border:1px solid rgba(0,0,0,.1); border-radius:8px; }
.map-legend.compact { font-size:11px; gap:2px 10px; padding:4px 8px; }
.ml-row { display:inline-flex; align-items:center; gap:5px; white-space:nowrap; }
.ml-pin { width:11px; height:11px; border-radius:50%; background:var(--rail-blue); border:1.5px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,.15); display:inline-block; margin:0 3px; box-sizing:content-box; }
.ml-pin.manual { background:var(--services-orange); }
.ml-pin.orig { width:14px; height:14px; }   /* the editors' original — the bigger circle */
/* ObsGlyph (20260918) — the observation swatch: the map's glyph pin at legend size */
.lg-obs { display:inline-flex; align-items:center; justify-content:center; width:16px; height:16px; border-radius:50%;
  background:#fff; border:1.5px solid var(--services-orange); box-shadow:0 0 0 1px rgba(0,0,0,.15); font-size:9.5px;
  line-height:1; font-style:normal; vertical-align:-3px; margin:0 2px; box-sizing:content-box; }
/* direction: the same circle with a pointer coming off it */
.ml-arrow { position:relative; width:11px; height:11px; border-radius:50%; background:var(--rail-blue); border:1.5px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,.15); display:inline-block; margin:8px 3px 0; box-sizing:content-box; }
.ml-arrow::before { content:""; position:absolute; left:2px; top:-9px; border-left:3.5px solid transparent; border-right:3.5px solid transparent; border-bottom:9px solid var(--rail-blue); }
.ml-item { display:inline-flex; align-items:center; padding:1px 5px; border:1.5px solid rgba(0,0,0,.22); border-radius:999px; background:#fff; line-height:1; }   /* a light ring — the dark one overpowered the icon */
.ml-item.manual { border-style:dashed; }
.ml-ic { display:inline-flex; width:12px; height:12px; }
.ml-ic svg { width:100%; height:100%; display:block; }
.ml-dot { width:10px; height:10px; border-radius:50%; display:inline-block; }
.ml-route { width:18px; height:0; border-top:3px dashed #7c4dff; display:inline-block; }
.ml-gap { width:18px; height:0; border-top:2px dotted rgba(124,77,255,.6); display:inline-block; }
.wm-legend .map-legend { background:transparent; border:none; border-top:1px solid rgba(0,0,0,.1); border-radius:0; padding:4px 0 0; margin:4px 0 0; }
.mc-chip { display:inline-flex; align-items:center; gap:2px; font:700 11px/1 var(--font-mono); color:#221f20; }
.mc-chip svg { width:13px; height:13px; display:block; }
/* Base kind colours; a chip carrying that kind's worst severity at the location overrides. */
.mc-chip.k-defect svg { color:#e0322d; }
.mc-chip.k-safety svg { color:#ff5700; }
.mc-chip.k-asset  svg { color:#2471b5; }
.mc-chip.sev-minor svg, .mc-chip.sev-low svg { color:#2e9e4f; }
.mc-chip.sev-moderate svg, .mc-chip.sev-medium svg { color:#ff7a00; }
.mc-chip.sev-major svg, .mc-chip.sev-high svg { color:#e0322d; }
.mc-chip.sev-critical svg { color:#a01313; }
.item-pin-asset { width:18px; height:18px; color:#2471b5; cursor:pointer; z-index:4 !important;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.4)); }
.item-pin-asset svg { width:100%; height:100%; display:block; }
/* Map popups must sit ABOVE every pin: the pin elements carry z-index 4/5 (which joins
   page-level stacking), while MapLibre popups default to none — so pins were painting
   over an open popup. All popups lift above pins; the item-cluster popup highest. */
.maplibregl-popup { z-index:30; }
.maplibregl-popup.item-popup { z-index:40; }

/* The shared popup list — one row per item at the clicked location. */
.mc-pop { display:flex; flex-direction:column; gap:7px; min-width:200px; max-height:230px; overflow:auto; padding:2px; }
.mci { display:flex; gap:8px; align-items:flex-start; }
.mci-ico { flex:0 0 auto; width:15px; height:15px; margin-top:1px; }
.mci-ico svg { width:100%; height:100%; display:block; }
.mci-ico.k-defect { color:#e0322d; }
.mci-ico.k-safety { color:#ff5700; }
.mci-ico.k-asset  { color:#2471b5; }
.mci-ico.sev-minor, .mci-ico.sev-low { color:#2e9e4f; }
.mci-ico.sev-moderate, .mci-ico.sev-medium { color:#ff7a00; }
.mci-ico.sev-major, .mci-ico.sev-high { color:#e0322d; }
.mci-ico.sev-critical { color:#a01313; }
.mci-txt { font-size:12px; line-height:1.35; color:#221f20; }
.mci-txt em { color:#777; font-style:normal; }
/* Clickable ref → the compact info panel for that item. */
.mci-ref { background:transparent; border:none; padding:0; font:700 12px/1.35 inherit; cursor:pointer;
  color:#b3410a; text-decoration:underline; text-underline-offset:2px; }
.mci-back { background:transparent; border:none; padding:0 0 6px; font-size:11px; cursor:pointer;
  color:#777; text-align:left; }
.mc-detail { display:flex; flex-direction:column; gap:5px; min-width:220px; max-width:300px; }
.mcd-head { display:flex; align-items:center; gap:7px; }
.mcd-head .mci-ico { width:16px; height:16px; margin:0; }
.mcd-ref { font:700 12px/1 var(--font-mono); color:#221f20; }
.mcd-kind { font-size:10.5px; text-transform:uppercase; letter-spacing:.06em; color:#777; }
.mcd-title { font-weight:700; font-size:13px; line-height:1.3; color:#221f20; }
/* Defect photos in the map marker pop-up detail card — a scrollable thumbnail carousel (lazily loaded).
   One photo shows a single thumb; many show a strip with ‹ › arrows. Tapping a thumb opens the lightbox. */
.mcd-photos { display:flex; align-items:center; gap:4px; margin:4px 0; }
.mcd-strip { display:flex; gap:6px; overflow-x:auto; scroll-snap-type:x mandatory; -webkit-overflow-scrolling:touch; padding-bottom:2px; }
.mcd-strip::-webkit-scrollbar { height:4px; }
.mcd-strip::-webkit-scrollbar-thumb { background:rgba(0,0,0,.2); border-radius:2px; }
.mcd-photos.many .mcd-strip { scroll-snap-align:start; }
.mcd-thumb { width:72px; height:72px; flex:0 0 auto; object-fit:cover; border-radius:6px; border:1px solid rgba(0,0,0,.12); scroll-snap-align:start; cursor:pointer; }
/* A lone photo fills the card width (keeps the previous single-thumb look). */
.mcd-photos:not(.many) .mcd-thumb { width:100%; height:auto; max-height:120px; }
.mcd-nav { flex:0 0 auto; width:22px; height:22px; border:none; border-radius:50%; background:rgba(0,0,0,.55); color:#fff; font-size:15px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; }
.mcd-nav:hover { background:rgba(0,0,0,.75); }

/* Full-screen lightbox for a tapped thumbnail (online only). */
.map-lightbox { position:fixed; inset:0; z-index:1000; background:rgba(0,0,0,.85); display:flex; align-items:center; justify-content:center; padding:16px; }
/* Auto sizing (no object-fit) — the img element IS the picture, so the box overlay's
   normalised coordinates land on it exactly; 92vh viewport cap works inside the hug wrapper. */
.map-lightbox img { max-width:100%; max-height:92vh; border-radius:4px; display:block; }
/* Matches .lightbox-close — one obvious close style across every lightbox. */
.mlb-close { position:absolute; top:14px; right:16px; width:44px; height:44px; border:2px solid var(--defuse-orange, #ff9d14); border-radius:50%; background:rgba(0,0,0,.55); color:#fff; font-size:20px; font-weight:700; cursor:pointer; }
.mlb-close:hover { background:rgba(0,0,0,.8); }
.mcd-facts { font-size:11.5px; color:#5a6470; }
.mcd-facts b { color:#221f20; }
.mcd-desc { font-size:12px; line-height:1.4; color:#3c434b; max-height:110px; overflow:auto; }
.mcd-open { margin-top:3px; font-size:12px; font-weight:700; color:#b3410a; text-decoration:none; }
.mcd-open:hover { text-decoration:underline; }

/* ============= FOOTER ============= */
.site-footer { background:#000; border-top:4px solid var(--roads-orange); color:#9aa3aa;
  padding:14px 24px; display:flex; align-items:center; justify-content:space-between; gap:18px; flex-wrap:wrap;
  font-family:var(--font-mono); font-size:11px; letter-spacing:0.12em; text-transform:uppercase; }
.site-footer .wordmark { font-family:var(--font-display); font-weight:800; color:#fff; letter-spacing:0.08em; }
.site-footer .wordmark .x { color:var(--roads-orange); }

/* Brand footer (DefuserFooter.txt — guidelines p16): the VIDA Roads PO logo on the left, the
   VIDA–StateGov lockup (vertical rule · Victorian Infrastructure Delivery Authority · Victoria
   State Government mark) on the right. Reversed (white) artwork on the black footer. */
.site-footer .fb-roads { height:24px; display:block; }
.site-footer .fb-lockup { display:flex; align-items:center; gap:12px; }
.site-footer .fb-rule { width:1px; height:40px; background:rgba(255,255,255,.7); }
.site-footer .fb-vida { font-family:var(--font-display); color:#fff; font-size:9.5px; line-height:1.2;
  letter-spacing:0.1em; text-transform:uppercase; font-weight:700; }
.site-footer .fb-vida .light { font-weight:400; opacity:.85; }
.site-footer .fb-vicgov { height:44px; display:block; }

/* Build stamp lives under the user's name/email in the user menu (moved out of the footer). */
/* nowrap: the release + compile date/time stay on ONE line (the wider menu gives it room);
   colour/decoration pinned since the label is now the /releases LINK (ReleaseLadder). */
.user-dropdown-build { display:block; margin-top:2px; font-family:var(--font-mono); font-size:10px;
  letter-spacing:.08em; opacity:.65; font-variant-numeric:tabular-nums;
  white-space:nowrap; color:inherit; text-decoration:none; }
.user-dropdown-build:hover { text-decoration:underline; }

/* ============= FILTER TABS ============= */
.filter-tabs { display:flex; gap:2px; flex-wrap:wrap; margin-bottom:20px; border-bottom:2px solid rgba(0,0,0,.1); }
.filter-tab { background:transparent; border:none; border-bottom:3px solid transparent; margin-bottom:-2px; cursor:pointer;
  font-family:var(--font-display); font-weight:700; font-size:15px; text-transform:uppercase; letter-spacing:0.04em;
  color:var(--concrete); padding:10px 16px; display:inline-flex; align-items:center; gap:8px; }
.filter-tab:hover { color:var(--asphalt); }
.filter-tab.active { color:var(--asphalt); border-bottom-color:var(--roads-orange); }
.filter-tab .count { font-family:var(--font-mono); font-size:11px; background:rgba(0,0,0,.08); border-radius:999px; padding:1px 7px; }
.filter-tab.active .count { background:rgba(255,157,20,.22); color:#9a5b00; }

/* ============= PROJECTS ============= */
.proj-layout { display:grid; grid-template-columns:minmax(280px,1fr) minmax(360px,1.3fr); gap:18px; align-items:start; }
.proj-list { display:flex; flex-direction:column; gap:12px; max-height:calc(100dvh - 300px); overflow-y:auto; }
/* The project card is a clickable <div> (tap = enter the workspace). iOS Safari only fires `click`
   on the FIRST tap for elements it recognises as clickable — a plain div needs cursor:pointer, else
   it takes two taps ("select does nothing, works on double-tap"). */
.proj-card { cursor:pointer; -webkit-tap-highlight-color:rgba(255,157,20,.18); }
.proj-card-head { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
.proj-card h3 { font-size:20px; }
/* ── Shared project-card pieces (Projects page + the Home workspace tile) ──
   The work-package rows (contract name + contractor pills + the Workspace badge) and the
   card adornments are used on BOTH pages, so they live here, not in a page <style>. */
.proj-tags { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:5px; }
.proj-card-actions { display:flex; align-items:center; gap:8px; }
.proj-wps { margin-top:8px; border-top:1px solid rgba(0,0,0,.08); padding-top:6px;
    display:flex; flex-direction:column; gap:4px; }
.proj-wp { display:flex; align-items:center; gap:8px; padding:4px 6px; border-radius:6px;
    border-left:4px solid transparent; }
.proj-wp.clickable { cursor:pointer; }
.proj-wp.clickable:hover { background:rgba(255,87,0,.06); }
/* The SELECTED work package must be unmistakable: solid accent bar + tinted row. */
.proj-wp.sel { background:rgba(255,87,0,.14); border-left-color:#ff5700; }
.proj-wp.sel .proj-wp-name { color:#b3410a; }
.proj-wp-name { flex:1; min-width:0; font-size:.85rem; font-weight:600; overflow-wrap:anywhere; }
/* Contractor pills always start on their own line under the contract name. */
.proj-wp-contractors { display:flex; flex-wrap:wrap; gap:4px; margin-top:4px; }
.proj-wp-select { white-space:nowrap; }
.proj-wp-select.sel { background:#ff5700; border-color:#ff5700; color:#fff; font-weight:700; }
.badge.ws { display:inline-flex; align-items:center; gap:4px; background:rgba(255,87,0,.16); color:#b3410a; font-weight:700; }
.badge.ws .ico { color:#ff5700; }
/* team-membership marker (users icon) on the card head */
.team-ic { display:inline-flex; align-items:center; color:#0f766e; }
.team-ic .ico { width:16px; height:16px; }
.proj-meta { display:flex; gap:8px; flex-wrap:wrap; margin:10px 0 6px; }
.proj-map { position:sticky; top:84px; }
.pin { background:none; border:none; cursor:pointer; font-size:22px; line-height:1; color:var(--concrete); }
.pin.on { color:var(--roads-orange); }
@media (max-width:860px){ .proj-layout { grid-template-columns:1fr; } .proj-map { position:static; } }
/* Desktop two-column layout: the list (and the sticky map) FILL the viewport down to the
   footer — no fixed 560px cap, the list simply scrolls within the remaining height (the
   ~300px allowance covers topbar + page head + filter row + footer). */
@media (min-width:861px){
  .proj-list { max-height:calc(100dvh - 300px); }
  .proj-map .map-canvas { height:calc(100dvh - 300px); }
}

/* ============= CONFLICTS ============= */
.conflict-card { border-top:4px solid var(--services-orange); margin-bottom:20px; }
.conflict-item { border:1px solid rgba(0,0,0,.12); padding:14px; margin-top:12px; }
.conflict-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:10px; }
.conflict-field { display:grid; grid-template-columns:120px 1fr 1fr; gap:8px; align-items:stretch; margin-bottom:8px; }
.cf-name { font-family:var(--font-mono); font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--concrete); align-self:center; }
.cf-choice { display:flex; align-items:center; gap:8px; border:1px solid rgba(0,0,0,.18); padding:8px 10px; cursor:pointer; font-size:13px; }
.cf-choice.sel { border-color:var(--roads-orange); background:rgba(255,157,20,.08); }
.cf-tag { font-family:var(--font-display); font-weight:700; text-transform:uppercase; font-size:11px; letter-spacing:.04em; }
.cf-val { color:var(--slate); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.conflict-item .btn-primary { margin-top:6px; }
@media (max-width:620px){ .conflict-field { grid-template-columns:1fr; } }

/* ============= TOOLBAR ============= */
.toolbar { display:flex; align-items:center; gap:14px; margin-bottom:14px; flex-wrap:wrap; }

/* ============= WIZARD ============= */
.wizard-steps { list-style:none; display:flex; gap:4px; flex-wrap:wrap; margin-bottom:18px; }
/* Narrow screens: keep all 4 steps on ONE row — compact evenly-divided chips instead of
   letting the last step (Review) wrap onto a second row. */
@media (max-width:760px){
  .wizard-steps { flex-wrap:nowrap; gap:3px; }
  .wizard-steps li { flex:1 1 0; min-width:0; justify-content:center; padding:7px 3px;
    font-size:11px; letter-spacing:.02em; gap:5px; overflow:hidden; }   /* a step never pushes the row wider (20260913) */
  .wizard-steps { max-width:100%; min-width:0; }
  .wizard-steps .num { width:18px; height:18px; font-size:10.5px; flex:0 0 auto; }
}
.wizard-steps li { display:flex; align-items:center; gap:8px; padding:8px 14px; font-family:var(--font-display); font-weight:700;
  text-transform:uppercase; letter-spacing:0.04em; font-size:13px; color:var(--concrete); background:#fff; border:1px solid rgba(0,0,0,.1); }
.wizard-steps li.active { color:var(--asphalt); border-bottom:3px solid var(--roads-orange); }
.wizard-steps li.done { color:var(--ok); }
.wizard-steps .num { width:22px; height:22px; border-radius:50%; background:rgba(0,0,0,.07); display:inline-flex; align-items:center; justify-content:center; font-size:12px; }
.wizard-steps li.active .num { background:var(--roads-orange); color:#000; }
.wizard-nav { display:flex; align-items:center; gap:14px; margin-top:18px; }
.wizard-nav .btn-primary { margin-left:auto; }

/* minmax(0,1fr) + min-width:0 down the chain: iOS date/time inputs have a LARGE intrinsic
   minimum width they refuse to shrink below — in a bare 1fr track that floor widens the grid
   past the card and the Date / Time fields spill off the right (site-walk wizard Map step;
   AiWalkCapture carried this same guard page-locally). */
.form-grid { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:0 16px; min-width:0; }
.form-grid .span2 { grid-column:1 / -1; }
.form-grid > .field, .form-grid > label { min-width:0; }
.form-grid .field input, .form-grid .field select, .form-grid .field textarea { min-width:0; max-width:100%; }
@media (max-width:620px){ .form-grid { grid-template-columns:minmax(0,1fr); } }

.media-grid { display:flex; flex-wrap:wrap; gap:10px; }
.media-grid.pool { min-height:96px; padding:8px; background:#faf8f4; border:1px dashed rgba(0,0,0,.18); }
.media-tile { position:relative; width:92px; height:92px; border:1px solid rgba(0,0,0,.15); background:#eee; overflow:hidden; }
.media-tile.sm { width:60px; height:60px; }
.media-tile img { width:100%; height:100%; object-fit:cover; }
.media-vid { width:100%; height:100%; display:flex; align-items:center; justify-content:center; font-size:28px; background:#222; }
.media-x { position:absolute; top:2px; right:2px; width:20px; height:20px; border:none; border-radius:50%; background:rgba(0,0,0,.6);
  color:#fff; cursor:pointer; line-height:1; font-size:14px; }
.media-gps { position:absolute; top:2px; left:2px; font-size:12px; line-height:1; padding:2px 4px;
  background:rgba(0,0,0,.6); border-radius:5px; color:#fff; }

.defects-layout { display:grid; grid-template-columns:200px 1fr; gap:18px; align-items:start; }
@media (max-width:720px){ .defects-layout { grid-template-columns:1fr; } }
.sub-h { font-family:var(--font-display); text-transform:uppercase; font-size:14px; letter-spacing:.04em; margin-bottom:8px; }
.occ-card { border:1px solid rgba(0,0,0,.14); padding:14px; margin-bottom:14px; }
.occ-head { display:flex; gap:8px; align-items:center; margin-bottom:10px; }
.occ-title { flex:1; font-weight:600; }
.media-grid.drop { min-height:70px; margin-top:8px; padding:6px; background:#faf8f4; border:1px dashed rgba(0,0,0,.18); align-items:center; }
.drop-hint { color:var(--concrete); font-size:12px; }

/* ===== AI capture timeline (CaptureFeature Enhancements pt1) ===== */
.tl-panel { margin-top:16px; }
.tl-head { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
.tl-foot { display:flex; justify-content:flex-end; margin-top:10px; }   /* 20260916 — the second Add section under the last section, right-aligned like the top one */
.tl-section { border-left:3px solid rgba(124,77,255,.35); padding:6px 8px 6px 14px; margin-bottom:16px; }   /* right/top/bottom padding: the current section's INSET ring must not overlap the fields + buttons (field feedback 20260912) */
.tl-sec-head { display:flex; align-items:flex-start; gap:8px; margin-bottom:8px; }
/* 16px + appearance strip — the iOS form-control gotcha: a sub-16px INPUT makes iOS ZOOM the
   whole page on focus and the zoom PERSISTS (field case: renaming a new section on larger
   iPhones left the header rendering with the collapse button over the name), and an unstripped
   input keeps a native intrinsic width that can refuse to shrink in the flex row. */
.tl-sec-name { flex:1 1 140px; min-width:0; max-width:none; font-family:var(--font-display); font-weight:700; font-size:16px;
  -webkit-appearance:none; appearance:none;
  line-height:1.25; color:var(--asphalt); background:transparent; border:none; border-bottom:1px solid transparent; padding:1px 3px; }
.tl-sec-name:hover, .tl-sec-name:focus { border-bottom-color:rgba(124,77,255,.45); outline:none; }
.tl-sec-name[readonly] { border-bottom-color:transparent; cursor:default; }
.tl-sec-cur { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:#fff;
  background:var(--ai-violet); border-radius:999px; padding:1px 8px; }
.tl-empty { margin:2px 0 8px; }
.tl-rec { display:flex; align-items:center; gap:10px; padding:9px 12px; margin-bottom:8px; border-radius:10px;
  background:#fff; border:1px solid rgba(0,0,0,.1); }
.tl-rec.sel { border-color:var(--ai-violet); box-shadow:0 2px 10px rgba(124,77,255,.16); }
.tl-rec-ico { flex:0 0 30px; width:30px; height:30px; border-radius:8px; display:flex; align-items:center; justify-content:center;
  background:rgba(124,77,255,.12); color:var(--ai-violet); }
.tl-rec-meta { display:flex; flex-direction:column; gap:1px; min-width:0; flex:1 1 auto; }
.tl-rec-title { font-weight:700; font-size:14px; }
.tl-rec-actions { display:flex; gap:6px; flex:0 0 auto; }
/* 20260915 — the recording in flight: a live badge (red recording / amber paused) on its row. */
.tl-rec.recording { border-color:rgba(224,50,45,.55); }
.tl-rec.paused { border-color:rgba(255,157,20,.75); }
.tl-rec-badge { display:inline-block; margin-left:6px; padding:1px 8px; border-radius:999px; font-size:11px; font-weight:700; vertical-align:middle; white-space:nowrap; }
.tl-rec-badge.recording { background:#e0322d; color:#fff; animation:add-mic-pulse 1.4s ease-in-out infinite; }
.tl-rec-badge.paused { background:#ff9d14; color:#221f20; }
.tl-audio { display:block; width:100%; max-width:420px; height:38px; margin:-2px 0 10px; }
.tl-grid { margin:2px 0 6px; }
/* 20260914 — a locked section's photos open to VIEW (a small lock badge marks them). */
.media-tile .media-lock { position:absolute; top:4px; right:26px; left:auto; }
/* DesktopCamera (20260915) — the webcam capture modal on the record page. */
.cam-card { max-width:760px; width:min(96vw, 760px); }
.cam-view { text-align:center; }
.cam-view video { width:100%; max-height:60vh; background:#000; border-radius:8px; display:block; }
/* 20260915 — capture details: sections & videos card + section colour chips in the legend. */
.wm-sec { border-left:4px solid #7c4dff; border-radius:0 8px 8px 0; padding:6px 10px; margin:6px 0 10px; background:rgba(0,0,0,.02); }
.wm-sec-head { display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; margin-bottom:4px; }
.wm-vid { padding:6px 0 6px 8px; border-top:1px dashed rgba(0,0,0,.1); }
.wm-vid-row { display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; }
.wm-vid-row .btn { margin-left:auto; }
.wm-vid-counts { margin-top:2px; }
.wm-vid-tx { margin-top:4px; }
.wm-vid-tx summary { cursor:pointer; font-size:12.5px; }
.wm-vid-tx p { white-space:pre-wrap; font-size:12.5px; margin:4px 0 0; max-height:220px; overflow:auto; }
.wm-vid-head { border-left:4px solid #7c4dff; padding:2px 8px; margin:8px 0 4px; font-weight:700; font-size:13px; }
.lg-sec { display:inline-block; width:14px; height:14px; border-radius:3px; vertical-align:-2px; margin-right:4px; }
.lg-sep { display:inline-block; width:1px; height:16px; background:rgba(0,0,0,.2); margin:0 4px; vertical-align:middle; }
/* 20260915.1 — processing log: a section heading groups its steps. */
.plog-group { margin:8px 0 2px; font-weight:700; font-size:12.5px; color:var(--ai-violet, #7c4dff); }
.plog-row.in-group { padding-left:12px; }
/* 20260915 — the ORIGIN icon on every AI-capture thumbnail: a discreet corner glyph, 🎞 = a frame
   extracted from a video, 📸 = a photo taken (by the operator while recording, or on a walk).
   Same class on the record page, the review, the details map and the DLM capture page. */
/* 20260915 — THE thumbnail badge convention, the same on every capture type and screen (record,
   review, details, site walk):  TOP-LEFT = the location pin (.media-gps)  ·  BOTTOM-LEFT = the
   origin (camera = a photo taken, video = a frame extracted; .org-ico, or .media-org when it
   carries the m:ss into the video)  ·  TOP-RIGHT = remove ×, lock, tags  ·  BOTTOM-RIGHT =
   annotated. All chips share the pin's style: a semi-transparent dark rounded chip, white icon. */
.org-ico { position:absolute; left:2px; bottom:2px; font-size:12px; line-height:1; padding:2px 4px; background:rgba(0,0,0,.6);
  border-radius:5px; color:#fff; display:inline-flex; align-items:center; pointer-events:none; z-index:2; }
.org-wrap { position:relative; display:inline-block; }
.media-org { position:absolute; left:2px; bottom:2px; font-size:11px; line-height:1; padding:2px 4px; background:rgba(0,0,0,.6);
  border-radius:5px; color:#fff; display:inline-flex; align-items:center; gap:3px; pointer-events:none; z-index:2; white-space:nowrap; }
.em-viewonly { display:inline-flex; align-items:center; gap:4px; margin-left:auto; margin-right:12px; padding:2px 8px; border-radius:999px;
  font-size:11.5px; font-weight:700; color:#5a6470; background:rgba(0,0,0,.06); border:1px solid rgba(0,0,0,.12); white-space:nowrap; }
/* 20260914 — Add section STANDS OUT: a solid violet button (the AI accent) instead of a ghost. */
.btn-add-section { background:var(--ai-violet, #7c4dff); color:#fff; border:1px solid var(--ai-violet, #7c4dff); font-weight:700;
  box-shadow:0 2px 8px rgba(124,77,255,.35); }
.btn-add-section:hover { background:#6a3df2; border-color:#6a3df2; color:#fff; }
.btn-add-section[disabled] { opacity:.45; cursor:not-allowed; box-shadow:none; }
/* 20260914 — capture sections show photos THREE WIDE on a phone: a 3-column grid with fluid
   square tiles (minmax(0,1fr) shrinks to fit the narrower SELECTED section + video-group padding). */
@media (max-width:560px) {
  .tl-grid { display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:8px; }
  .tl-grid .media-tile { width:100%; height:auto; aspect-ratio:1 / 1; min-width:0; }
  .tl-grid .media-tile img, .tl-grid .media-tile .media-vid { width:100%; height:100%; object-fit:cover; }
}
@media (max-width:560px) {
  .tl-rec { flex-wrap:wrap; }
  .tl-rec-actions { width:100%; justify-content:flex-end; }
}

/* ===== CaptureFeature Enhancements pt2 — Details step, compact photo tiles, section header ===== */
/* Details step form + participant chips. */
.det-form { display:flex; flex-direction:column; gap:14px; }
.det-form textarea { width:100%; }
.chip-picker { display:flex; flex-wrap:wrap; gap:6px; }
.chip { border:1px solid rgba(0,0,0,.18); background:#fff; color:var(--asphalt); border-radius:999px;
  padding:4px 12px; font-size:13px; cursor:pointer; }
.chip.on { background:var(--ai-violet); border-color:var(--ai-violet); color:#fff; }
.chip.xs { padding:2px 9px; font-size:11px; }
.chip-add { display:flex; gap:8px; margin-top:8px; }
.chip-add input { flex:1 1 auto; min-width:0; }

/* Compact photo add — two equal tiles (pt2). */
.add-media { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px; margin-top:12px; max-width:100%; }   /* minmax(0,1fr): a bare 1fr track can't shrink below a tile's text and SPILLED the section (field feedback 20260912) */
.add-tile { position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px;
  min-height:74px; padding:12px; border:1.5px dashed rgba(124,77,255,.4); border-radius:10px; cursor:pointer;
  color:var(--ai-violet); font-weight:600; font-size:13px; background:rgba(124,77,255,.05);
  min-width:0; max-width:100%; text-align:center; overflow-wrap:anywhere; }
.add-tile:hover { background:rgba(124,77,255,.12); border-color:var(--ai-violet); }
.add-tile input[type=file] { position:absolute; inset:0; width:100%; height:100%; opacity:0; cursor:pointer; }

/* Section header (collapse, counts, current, drag target) + per-section people + photo time (pt2). */
/* Field feedback (20260912) — the CURRENT section must read as the one everything lands in: a
   thicker violet edge, a tinted panel with a violet ring, the name in violet; the others stay
   plain (slightly faded edge) so the contrast is unmistakable on a phone. */
.tl-section { box-sizing:border-box; max-width:100%; min-width:0; }
.tl-section.cur { border-left:5px solid var(--ai-violet); padding:8px 10px 8px 12px; background:rgba(124,77,255,.08);
  box-shadow:inset 0 0 0 2px rgba(124,77,255,.32); }   /* INSET ring — an outer ring spilled past the phone's edge */
/* Field feedback (20260912) — a capture video row: icon + text block + an actions group. On a
   phone the text takes the full first line(s) and the buttons drop to their own bottom row
   (they used to squeeze the name + status into a narrow left column). */
.aiv-video-item { display:flex; align-items:center; flex-wrap:wrap; gap:8px 10px; padding:8px 10px;
  border:1px dashed rgba(0,0,0,.25); border-radius:8px; margin-top:8px; min-width:0; }
.aiv-video-item.removed { opacity:.75; padding:6px 10px; margin-top:6px; border-color:rgba(0,0,0,.2); }
/* 20260914 — a VIDEO GROUP in a section: header (started · length · photos), the video row, its photos. */
.aiv-vgroup { border:1px solid rgba(124,77,255,.28); border-radius:10px; padding:8px; margin:8px 0; background:rgba(124,77,255,.035); }
.aiv-vgroup-head { display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 8px; font-size:12.5px; margin:0 2px 6px; }
.aiv-vgroup-title { font-weight:700; }
.aiv-vgroup .aiv-video-item { margin:0; }
.aiv-vgroup .media-grid.tl-grid { margin-top:8px; }
.tl-loose-h { margin:10px 2px 2px; font-weight:600; }
.aiv-video-text { flex:1 1 160px; min-width:0; }
.aiv-video-name { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.aiv-video-actions { display:flex; align-items:center; gap:6px; flex:0 0 auto; flex-wrap:wrap; }
@media (max-width:560px) {
  .aiv-video-text { flex-basis:100%; }
  .aiv-video-actions { width:100%; justify-content:flex-end; }
}
/* VideoEditing (20260912) — the per-video editor (trim + tracking), desktop and phone. */
.ved-card { max-width:760px; width:96vw; }
.ved-trim, .ved-track { margin-top:12px; padding:10px 12px; border:1px solid rgba(0,0,0,.1); border-radius:10px; background:#fff; }
.ved-trim-head { display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin-bottom:6px; }
.ved-range { display:flex; align-items:center; gap:10px; font-size:13px; margin:4px 0; }
.ved-range input[type=range] { flex:1 1 auto; min-width:0; accent-color:var(--ai-violet); }
.ved-actions { display:flex; gap:6px; flex-wrap:wrap; margin-top:8px; }
.ved-map { height:300px; }
@media (max-width:560px) { .ved-map { height:230px; } }
.tl-section.cur .tl-sec-name { color:var(--ai-violet); }
.tl-section:not(.cur):not(.locked) { border-left-color:rgba(124,77,255,.22); }
.tl-section { border-radius:0 8px 8px 0; }
/* SectionDrivenAdd (20260912) — the Upload / Record tiles sit INSIDE the current section. */
.tl-add-media { margin:10px 0 6px; }
/* 20260913 — Upload a video + Record a video share ONE row on a phone (they stacked before). */
@media (max-width:560px) { .tl-add-media { grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:8px; }
  .tl-add-media .add-tile { padding:10px 8px; min-height:68px; font-size:12.5px; text-align:center; } }
/* 20260914 — walk kinds: Record voice + Add photos + Take a photo share the section row. */
.tl-add-media.three { grid-template-columns:repeat(3, minmax(0,1fr)); }
.tl-add-media.four { grid-template-columns:repeat(4, minmax(0,1fr)); }   /* 20260915 — Pause/Resume + Stop + the two photo tiles */
@media (max-width:560px) { .tl-add-media.three { grid-template-columns:repeat(3, minmax(0,1fr)); gap:6px; }
  .tl-add-media.three .add-tile { padding:10px 4px; font-size:12px; }
  .tl-add-media.four { grid-template-columns:repeat(2, minmax(0,1fr)); gap:6px; }
  .tl-add-media.four .add-tile { padding:10px 4px; font-size:12px; } }
.add-tile.add-mic.busy { opacity:.6; cursor:default; animation:add-mic-pulse 1.4s ease-in-out infinite; }
/* 20260915 — the tile IS the stop button while a take is in flight: solid red, pulsing border. */
.add-tile.add-mic.live { background:#e0322d; color:#fff; border-color:#e0322d; cursor:pointer; animation:add-mic-pulse 1.4s ease-in-out infinite; }
.add-tile.add-mic.live:hover { background:#c9281f; border-color:#c9281f; color:#fff; }
/* An INTERRUPTED take: the tile offers Resume (amber). */
.add-tile.add-mic.paused { background:#ff9d14; color:#221f20; border-color:#ff9d14; cursor:pointer; }
.add-tile.add-mic.paused:hover { background:#e88d0f; border-color:#e88d0f; color:#221f20; }
@keyframes add-mic-pulse { 0%,100% { border-color:rgba(224,50,45,.55); } 50% { border-color:#e0322d; } }
/* The Record tile looks like a RECORD BUTTON: a red disc inside a white ring inside a red ring. */
.add-tile.add-rec { border-style:solid; border-color:rgba(224,50,45,.55); background:rgba(224,50,45,.06); color:#b3261e; }
.add-tile.add-rec:hover { background:rgba(224,50,45,.12); border-color:#e0322d; }
.rec-glyph { display:block; width:34px; height:34px; border-radius:50%; background:#e0322d;
  border:3px solid #fff; box-shadow:0 0 0 2.5px #e0322d; }
/* 20260914 — the expand/collapse control was a 22px grey glyph, easy to miss: now a 32px outlined
   round button in the section violet with a bigger caret (same height as the Select pill). */
.tl-collapse { flex:0 0 auto; width:32px; height:32px; display:inline-flex; align-items:center; justify-content:center;
  border:1.5px solid rgba(124,77,255,.45); border-radius:50%; background:#fff; cursor:pointer;
  font-size:17px; line-height:1; color:var(--ai-violet); }
.tl-collapse:hover { background:rgba(124,77,255,.10); border-color:var(--ai-violet); }
.tl-sec-counts { flex:0 0 auto; white-space:nowrap; }
/* 20260913 — Selected / Select: the section pick control, up front in the header (after the caret).
   Outlined violet = selectable; filled violet = the selected section (non-interactive). */
.tl-select { flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center; height:30px; padding:0 12px;
  border-radius:999px; font-size:12.5px; font-weight:700; line-height:1; cursor:pointer;
  border:1.5px solid var(--ai-violet); background:#fff; color:var(--ai-violet); white-space:nowrap; }
.tl-select:hover { background:rgba(124,77,255,.10); }
.tl-select.on { background:var(--ai-violet); color:#fff; cursor:default; }
.tl-people { display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; margin:2px 0 10px; line-height:1.9; }
/* DefuserRefinements20260913 — the section's people COUNT chip: amber = nobody, green = someone. */
.tl-people-btn { display:inline-flex; align-items:center; gap:5px; border-radius:999px; padding:3px 11px; font-size:12.5px;
  font-weight:700; cursor:pointer; border:1px solid transparent; line-height:1.4; }
.tl-people-btn.none { background:rgba(255,157,20,.16); color:#9a5b00; border-color:rgba(255,157,20,.5); }
.tl-people-btn.some { background:rgba(34,197,94,.16); color:#157a3a; border-color:rgba(34,197,94,.45); }
.tl-people-lbl { font-weight:500; }
/* ParticipantsBadge (20260917) — the Details step's 👥 chip + a one-line name summary */
.det-people { margin:0; flex-wrap:nowrap; }
.det-people-names { flex:1 1 120px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* 20260914.2 — the capture player's "photos taken during this video" strip. */
.vplay-photos { display:flex; gap:8px; overflow-x:auto; padding-bottom:4px; }
.vplay-photo { flex:0 0 auto; width:84px; border:1px solid rgba(0,0,0,.15); border-radius:8px; background:#fff; padding:2px; cursor:pointer; position:relative; }
.vplay-photo img { display:block; width:100%; height:60px; object-fit:cover; border-radius:6px; }
.vplay-photo .vplay-t { display:block; font-size:11px; text-align:center; padding:2px 0 0; }
/* 20260914.2 — a capture section's AI run line under its header. */
.tl-sec-run { font-size:12.5px; margin-top:2px; }
.tl-sec-run.running { color:#8a5b00; }
.tl-sec-run.done { color:#157a3a; }
.tl-sec-run.failed { color:#b3261e; }
/* 20260914 — the review's "Add a missed item" panel stands apart from the sections above it. */
.mfc-panel { margin-top:18px; border:1px dashed rgba(124,77,255,.55); background:rgba(124,77,255,.04); }
/* The review's collapsible VIDEO panel (native details). */
.rev-vid > summary { list-style:none; cursor:pointer; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.rev-vid > summary::-webkit-details-marker { display:none; }
.rev-vid[open] > summary .chev { transform:rotate(180deg); }
.media-time { position:absolute; left:0; bottom:0; right:0; padding:2px 4px; font-size:9.5px; line-height:1.1;
  background:linear-gradient(rgba(0,0,0,0), rgba(0,0,0,.55)); color:#fff; text-align:left; pointer-events:none; }

/* ===== CaptureFeature Enhancements pt3 — read-only view, section status/lock, 2-line header ===== */
.ro-banner { display:flex; align-items:center; gap:8px; background:rgba(245,166,35,.14);
  border:1px solid rgba(245,166,35,.5); color:#7a5a10; border-radius:8px; padding:8px 12px; margin-bottom:10px;
  font-size:13.5px; font-weight:600; }
.ro-banner .ico { flex:0 0 auto; }
/* Section header: name+status on line 1, counts on line 2 — one row on desktop, stacked on iPhone. */
.tl-sec-main { flex:1 1 auto; min-width:0; display:flex; align-items:baseline; flex-wrap:wrap; gap:2px 12px; }
.tl-sec-line1 { display:flex; align-items:center; gap:8px; flex:1 1 160px; min-width:0; }
.tl-sec-line2 { flex:0 0 auto; white-space:nowrap; }
.tl-sec-tools { flex:0 0 auto; display:flex; align-items:center; gap:6px; }
/* Lock/Unlock toggle — a proper button (btn-ghost small) with an icon + label; amber when locked. */
.tl-lock { display:inline-flex; align-items:center; gap:4px; }
.tl-lock.on { color:#8a6d1a; border-color:rgba(245,166,35,.6); background:rgba(245,166,35,.14); }
.tl-sec-status { display:inline-flex; align-items:center; gap:3px; flex:0 0 auto; font-size:10px; font-weight:700;
  text-transform:uppercase; letter-spacing:.04em; color:#8a6d1a; background:rgba(245,166,35,.2); border-radius:999px; padding:1px 8px; }
.tl-section.locked { border-left-color:rgba(0,0,0,.28); background:rgba(0,0,0,.02); }
.tl-section.locked .tl-sec-name { color:var(--concrete); }
.tl-rec-actions .btn.danger { color:#b3261e; border-color:rgba(179,38,30,.35); }
.tl-rec-actions .btn.danger:hover { background:rgba(179,38,30,.08); }
@media (max-width:560px) {
  /* iPhone — compact header: the name SHRINKS to share its row with a badge (never spills to its own
     line), and the actions stay on the row as slimline buttons (Lock / Delete); Select sits up front. */
  .tl-sec-head { flex-wrap:wrap; align-items:center; gap:6px; }
  /* 20260913 — row 1: caret · Select/Selected · Lock/Delete; row 2: the section name; row 3: the counts. */
  .tl-collapse { order:0; }
  .tl-select { order:1; }
  .tl-sec-tools { order:2; margin-left:auto; }
  .tl-sec-main { order:3; flex-direction:column; align-items:stretch; gap:2px; flex:1 1 100%; min-width:0; }
  .tl-sec-line1 { flex:1 1 auto; min-width:0; }
  .tl-sec-name { flex:1 1 auto; width:auto; min-width:0; max-width:100%; border-bottom-color:rgba(0,0,0,.14); }
  .tl-sec-line2 { white-space:normal; }   /* "n rec · n photos · n videos · n on walk" must wrap, not push the header wide */
  .tl-sec-head, .tl-sec-main, .tl-sec-line1 { max-width:100%; }
  .tl-sec-tools { flex:0 0 auto; gap:5px; }
  .tl-sec-tools > .btn.small { height:30px; padding:0 9px; font-size:12px; display:inline-flex;
    align-items:center; justify-content:center; }
}

/* Compact the rec-panel a touch (pt2 — it was taking too much space). */
.rec-panel { padding:12px 14px; }
.rec-panel .aiw-status { margin-bottom:8px; }

/* ============= LOGIN ============= */
.login-shell { min-height:100vh; background:linear-gradient(135deg,#001820 0%,var(--midnight) 55%,#002a3a 100%); }
.login-wrap { display:flex; align-items:center; justify-content:center; padding:48px 16px; min-height:calc(100vh - var(--hazard-h)); }
.login-card { background:#fff; width:100%; max-width:420px; padding:34px 30px; border-top:4px solid var(--roads-orange); }
.login-brand { display:flex; align-items:center; justify-content:space-between; gap:16px; margin-bottom:18px; }
/* VIDA Roads (left) + DEFUSE (right) on the auth screens — matched height, centred. */
.login-logo { height:38px; width:auto; max-width:48%; object-fit:contain; display:block; }
.login-error { background:rgba(255,87,0,.1); border:1px solid var(--services-orange); color:#9a2b00; padding:9px 12px; font-size:13px; margin-bottom:14px; }
.login-demo { margin-top:20px; padding-top:16px; border-top:1px solid rgba(0,0,0,.1); display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* ============= ERROR UI ============= */
#blazor-error-ui { display:none; position:fixed; bottom:0; width:100%; background:var(--services-orange);
  color:#000; padding:10px 16px; font-family:var(--font-mono); font-size:13px; z-index:1000; }
#blazor-error-ui .reload { text-decoration:underline; }
#blazor-error-ui .dismiss { cursor:pointer; float:right; }

/* ============= RESPONSIVE ============= */
/* Bottom mobile nav + "desktop-only" helper are hidden until the phone breakpoint. */
.mobile-nav { display:none; }
@media (max-width:980px){
  nav.primary a span { display:none; }
  nav.primary a { padding:0 14px; }
}
@media (max-width:760px){
  /* The masthead burger opens the SAME top-level nav as the bottom bar (My Projects / Workbag / Map /
     Capture) — fully redundant on phones, and it was the item pushed off the right edge (the whole
     masthead row overflowed the viewport, widening the layout so the entire page spilled right). Hide
     it on mobile; the bottom bar covers everything (Sync lives in the user dropdown). */
  .nav-burger { display:none; }
  nav.primary { position:absolute; top:var(--topbar-h); left:0; right:0; flex-direction:column; background:var(--midnight);
    border-top:1px solid var(--line); display:none; z-index:60; }
  nav.primary.open { display:flex; }
  nav.primary a { padding:14px 20px; border-right:none; border-bottom:1px solid var(--line); }
  nav.primary a span { display:inline; }
  nav.primary a.active::before { display:none; }
  nav.primary a.active { border-left:3px solid var(--roads-orange); }
  /* Tighten the masthead so the brand + utilities + user chip always fit a narrow phone without the
     row overflowing (which is what spilled the page right). The wide DEFUSER wordmark is the width
     hog, so make it SHRINK-TO-FIT: the brand lockup is the only shrinkable item (nav-aside is
     flex-shrink:0, keeping the utilities/user-chip full size), and the logo scales down proportionally
     (height:auto + max-height + max-width:100%) to whatever width is left — so the row can never
     exceed the viewport on any device. On roomy phones it stays 32px; only cramped ones scale it. */
  .nav-row { padding:0 12px; }
  .brand-lockup { border-right:none; padding-right:8px; min-width:0; flex-shrink:1; }
  .brand-logo { height:auto; max-height:32px; max-width:100%; }
  .nav-aside { gap:8px; padding-left:8px; flex-shrink:0; }
  .brand-suffix { font-size:20px; }
  .layout-main { padding:18px 14px 96px; }   /* clears the fixed bottom nav */
  .map-canvas { height:340px; }

  /* hide elements not needed on mobile (e.g. Bulk Edit) */
  .hide-mobile { display:none !important; }

  /* page head + action rows stack; buttons become comfortable full-width taps */
  .page-head { gap:14px; margin-bottom:18px; }
  .page-head h1 { font-size:30px; }
  .page-head > div:last-child { width:100%; }
  .head-actions { width:100%; }
  .head-actions .btn { flex:1 1 40%; justify-content:center; padding:13px 14px; }
  .toolbar, .filter-tabs { flex-wrap:wrap; gap:8px; }
  .btn { padding:12px 16px; }
  /* tables stay swipe-scrollable; tighten so more fits on a narrow screen */
  .data-table { font-size:13px; }
  .data-table th, .data-table td { padding:9px 10px; }

  /* ---- fixed bottom section nav (cut-down mobile UI) ---- */
  .site-footer { display:none; }   /* replaced by the bottom nav on phones */
  /* Same dark treatment as the workspace strip: bitumen with hairline amber edges, muted
     unselected items — but the selection indicator is a THICK amber line at the TOP (it's a
     bottom bar, so the indicator points up at the content). */
  .mobile-nav { display:flex; position:fixed; left:0; right:0; bottom:0; z-index:70;
    background:var(--vida-bitumen, #221f20);
    border-top:0.5px solid var(--vida-amber, #ff9d14);
    padding-bottom:env(safe-area-inset-bottom); }
  .mobile-nav a { flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:3px; padding:8px 2px 7px; min-height:56px; text-decoration:none;
    font-family:var(--font-body); font-size:10px; letter-spacing:.02em; color:#fff; }
  .mobile-nav a svg { width:22px; height:22px; color:#fff; }
  .mobile-nav a span { max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .mobile-nav a.active { color:var(--vida-amber, #ff9d14); box-shadow:inset 0 3px 0 var(--vida-amber, #ff9d14); }
  .mobile-nav a.active svg { color:var(--vida-amber, #ff9d14); }

  /* The project workspace nav as the mobile BOTTOM bar (swapped in for the general MobileNav when a
     project is selected) — DARK bitumen matching the pws-bar identity header, with an amber top
     border + amber active icons so it still reads as the workspace bar (the user-level bar stays
     midnight with the deep-orange accent). */
  /* hairline amber edges (0.5px renders as a true hairline on retina phones) */
  .mobile-nav.project-mnav { background:var(--vida-bitumen, #221f20);
    border-top:0.5px solid var(--vida-amber, #ff9d14);
    border-bottom:0.5px solid var(--vida-amber, #ff9d14); }
  .mobile-nav.project-mnav a { color:#fff; }
  .mobile-nav.project-mnav a svg { color:#fff; }
  /* selected item: amber text + icon with the thick amber underline (inset — no height change) */
  .mobile-nav.project-mnav a.active { color:var(--vida-amber, #ff9d14); box-shadow:inset 0 -3px 0 var(--vida-amber, #ff9d14); }
  .mobile-nav.project-mnav a.active svg { color:var(--vida-amber, #ff9d14); }
}

/* ===========================================================================
   Detail layouts (Project / Defect / Asset) + the slide-in Actions/Activities
   drawer + the shared ActivityLayout. Used by the *Detail.razor pages, the
   ItemActionsPanel + ActivityLayout components. Phone-first: 2-col → 1-col,
   nothing spills (DefuserChanges0104).
   =========================================================================== */

/* the (i) detail-link icon dropped into list rows / cards */
.detail-i { color:var(--concrete,#5a6470); display:inline-flex; vertical-align:-3px; margin-right:4px;
            background:none; border:none; padding:0; cursor:pointer; }
.detail-i:hover { color:var(--roads-orange,#ff9d14); }
/* record-number cells (DEF-/AST-/SAF-/ACT-…): the i + number must stay on one line */
.data-table td.nowrap { white-space:nowrap; }

/* ---- Two-part register rows (ListEnhancements.txt) — shared by Assets / Defects / Safety.
   Part 1 = ⓘ · number · badges; part 2 = secondary text. One line on desktop; on a phone the
   parts wrap onto their own rows (and part 1's badges may wrap again) so they fit the width. */
.tp-list { background:#fff; border:1px solid rgba(0,0,0,.10); border-radius:8px; overflow:hidden; }
.tp-row { display:flex; align-items:center; gap:10px; padding:10px 12px 10px 10px; cursor:pointer; }
.tp-row + .tp-row, .tp-expand + .tp-row { border-top:1px solid rgba(0,0,0,.07); }
.tp-row:hover { background:#fffbf3; }
/* opaque (tint layered over white) — a translucent background on a .swipe-content row would
   let the slide-in action block behind it show through */
.tp-row.expanded { background:linear-gradient(rgba(36,113,181,.05), rgba(36,113,181,.05)), #fff; }
.tp-main { flex:1; min-width:0; display:flex; align-items:center; flex-wrap:wrap; column-gap:16px; row-gap:5px; }
/* Defects list (2026-10-01, Simon: "the gap to defect type is also wider"): the TYPE badge now leads part 2, so its
   badge row reads at the ONE 7px gap — the other two-part lists keep the 16px badges→title gap. */
.tp-list.defects-list .tp-main { column-gap:7px; }
.tp-p1 { display:inline-flex; align-items:center; gap:7px; flex-wrap:wrap; row-gap:5px; min-width:0; }
.tp-num { font-weight:700; }
.tp-p1 .badge { white-space:nowrap; }
.tp-type { max-width:200px; overflow:hidden; text-overflow:ellipsis; }
/* Captures list part 1 (tp-cap): number + status + TYPE stay on one row — the type badge's
   TEXT truncates rather than the badge wrapping onto its own line on a phone. */
.tp-p1.tp-cap { flex-wrap:nowrap; min-width:0; }
.tp-p1.tp-cap .tp-num, .tp-p1.tp-cap .badge:not(.walk-type) { flex-shrink:0; }
.tp-p1.tp-cap .walk-type { flex-shrink:1; min-width:0; display:inline-flex; align-items:center; gap:4px; }
.walk-type .wt-txt { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.tp-p2 { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--slate,#3c434b); }
/* part-2 variant that mixes text with a badge: flex centres them on one vertical axis
   (baseline alignment left the text sitting low against the badge box) */
.tp-p2.tp-p2-flex { display:flex; align-items:center; gap:7px; }
.tp-p2-flex .tp-p2-txt { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tp-row .chev { flex:0 0 auto; color:var(--concrete,#9aa3aa); font-size:13px; }
.tp-expand { border-top:1px solid rgba(0,0,0,.07); background:rgba(0,0,0,.02); padding:6px 10px 12px; }
/* Review-page footer actions (AiWalkReview + SafetyWalkReview). The primary button's label
   varies in length ("Submit 12 safety item(s)", "Complete review"), so on a phone the buttons
   stack full-width rather than overflowing the row. */
.rev-actions { display:flex; gap:10px; margin:14px 0 8px; align-items:center; flex-wrap:wrap; }
.rev-actions .btn { min-width:0; }
.rev-savenote { display:inline-flex; align-items:center; gap:4px; }
@media (max-width:520px){
  .rev-actions .btn { flex:1 1 100%; justify-content:center; text-align:center; }
  .rev-savenote { flex:1 1 100%; }
}
/* A labelled select in a list toolbar (Group on Defects, Type on Work, Period on Insights). */
.df-group { display:inline-flex; align-items:center; gap:6px; }
.df-group select { font:inherit; font-size:16px; padding:5px 8px; border:1px solid rgba(0,0,0,.15); border-radius:16px; background:#fff; max-width:100%; }
/* Count chips (the Defects METAL bar, the plans register filters, the Overview's stage strip). */
.metal-filter { display:inline-flex; align-items:center; gap:4px; flex-wrap:wrap; }
.mf-chip { display:inline-flex; align-items:center; gap:5px; padding:3px 8px; border:1px solid rgba(0,0,0,.14);
  border-radius:16px; background:#fff; cursor:pointer; font:inherit; line-height:1; }
.mf-chip.on { border-color:var(--services-orange, #ff5700); box-shadow:inset 0 0 0 1px var(--services-orange, #ff5700); background:#fff6f1; }
.mf-count { font-size:12px; font-weight:700; color:#3c434b; }
/* Defects list structure (DefectListStructure, 2026-10-05) — the folded "Needs you" bar, collapsible groups
   with counts, and the fixed two-line row whose coloured left edge is the severity. */
.needs-you { margin:0 0 14px; border:1px solid var(--services-orange, #ff5700); border-left-width:4px; background:#fff6f1; }
.needs-you > summary { display:flex; align-items:center; gap:10px; flex-wrap:wrap; min-height:44px; padding:8px 12px; cursor:pointer; list-style:none; }
.needs-you > summary::-webkit-details-marker { display:none; }
.needs-you > summary .chev { margin-left:auto; }
.needs-you[open] > summary .chev { transform:rotate(180deg); }
.needs-you > .card { margin:0 10px 10px; }
.dg-group { border-bottom:1px solid rgba(0,0,0,.08); }
.dg-head { display:flex; align-items:center; gap:8px; width:100%; min-height:44px; padding:8px 10px; border:0; background:#f3efe9;
  font:inherit; font-weight:700; text-align:left; cursor:pointer; color:inherit; touch-action:manipulation; }
.dg-head-static { cursor:default; background:#fff6f1; }
.dg-head .chev { flex:0 0 auto; width:14px; color:var(--concrete,#9aa3aa); }
.dg-title { text-transform:uppercase; letter-spacing:.06em; font-size:13px; }
.dg-count { font-size:12px; font-weight:700; padding:1px 8px; border-radius:999px; background:var(--vida-bitumen,#221f20); color:#fff; }
.dg-split { margin-left:auto; font-weight:400; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.dg-sub { margin-left:12px; border-left:2px solid rgba(0,0,0,.08); }
.dg-subhead { background:#faf7f3; min-height:38px; }
.dg-subhead .dg-title { text-transform:none; letter-spacing:0; font-weight:600; }
.dg-subhead .dg-count { background:rgba(0,0,0,.12); color:inherit; }
.dg-more { display:block; width:100%; min-height:40px; padding:8px 12px; border:0; border-top:1px dashed rgba(0,0,0,.12); background:#fff;
  font:inherit; font-size:13px; font-weight:600; color:var(--services-orange,#ff5700); cursor:pointer; text-align:left; }
.dg-row { border-left:4px solid transparent; }
.dg-row.sev-0 { border-left-color:#b3261e; }
.dg-row.sev-1 { border-left-color:#e8730c; }
.dg-row.sev-2 { border-left-color:#d9a400; }
.dg-row.sev-3 { border-left-color:#8a949c; }
.dg-row .tp-main { display:flex; flex-direction:column; flex-wrap:nowrap; align-items:stretch; gap:3px; min-width:0; flex:1 1 auto; text-align:left; }
.dg-l1, .dg-l2 { justify-content:flex-start; }
.dg-l1 { display:flex; align-items:baseline; gap:8px; min-width:0; }
.dg-ttl { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:600; }
.dg-l2 { display:flex; align-items:center; gap:7px; min-width:0; }
.dg-meta { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--slate); }
.dg-flag { flex:0 0 auto; display:inline-flex; align-items:center; align-self:center; }
.dg-flag:empty { display:none; }
/* The defect page's Monitoring card (DefectMonitoringCard, 2026-10-05). */
.defect-monitoring { margin:12px 0; }
.dm-head { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.dm-sub { margin:12px 0 6px; font-size:13px; }
.dm-pending { list-style:none; margin:0; padding:0; display:grid; gap:4px; }
/* Work package Insights (WorkPackageInsights, 2026-10-05) — the Overview's analytics tab. One series = blue;
   the weekly chart's two series are blue (raised) + orange (closed) with a legend; values and labels stay in
   text colours, never the series colour. */
.wpi-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap:12px; align-items:start; }
.wpi-card { padding:16px; min-width:0; }
.wpi-card h3 { margin:0 0 10px; font-size:15px; }
.wpi-card h3 a { color:inherit; }
.wpi-wide { grid-column:1 / -1; }
.wpi-head { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:10px; }
.wpi-head h3 { margin:0; }
.wpi-stats { display:flex; gap:18px; flex-wrap:wrap; margin:0 0 10px; }
.wpi-stats > div { display:flex; flex-direction:column; min-width:0; }
.wpi-stats .v { font-family:var(--font-display); font-weight:800; font-size:28px; line-height:1; color:var(--asphalt); }
.wpi-stats .k { font-size:12px; color:var(--slate); }
.wpi-bad { color:#b3261e; font-weight:700; }
.wpi-legend { display:flex; align-items:center; gap:14px; flex-wrap:wrap; font-size:12px; margin-bottom:4px; }
.wpi-sw { display:inline-block; width:10px; height:10px; border-radius:2px; margin-right:4px; vertical-align:-1px; }
.wpi-sw.raised, .wpi-bar.raised { background:#2471b5; fill:#2471b5; }
.wpi-sw.closed, .wpi-bar.closed { background:#e8730c; fill:#e8730c; }
.wpi-chart svg { display:block; width:100%; height:140px; }
.wpi-axis { stroke:rgba(0,0,0,.25); stroke-width:1; vector-effect:non-scaling-stroke; }
.wpi-hit { fill:transparent; }
.wpi-chart g:hover .wpi-hit { fill:rgba(0,0,0,.05); }
.wpi-xaxis { display:flex; justify-content:space-between; margin-top:-14px; }
.wpi-table { margin-top:8px; font-size:13px; }
.wpi-table summary { cursor:pointer; color:var(--slate); min-height:32px; display:flex; align-items:center; }
.wpi-bars { list-style:none; margin:0; padding:0; display:grid; gap:7px; }
.wpi-bars li { display:grid; grid-template-columns:minmax(0, 45%) 1fr auto; align-items:center; gap:8px; font-size:13px; }
.wpi-bar-label { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:inherit; }
a.wpi-bar-label { text-decoration:underline; text-decoration-color:rgba(0,0,0,.25); }
.wpi-bar-track { height:10px; background:rgba(0,0,0,.06); border-radius:0 4px 4px 0; overflow:hidden; }
.wpi-bar-fill { display:block; height:100%; min-width:2px; background:#2471b5; border-radius:0 4px 4px 0; }
.wpi-bar-val { font-weight:700; min-width:2ch; text-align:right; }
@media (max-width:560px){ .wpi-grid { grid-template-columns:minmax(0, 1fr); } .wpi-stats .v { font-size:24px; } }
/* Captures outcomes + observations (CaptureOutcomes, 2026-10-05) — the chips under a capture row saying what it
   produced, and the observations register's rows. */
.cap-out { display:flex; align-items:center; gap:6px; flex-wrap:wrap; width:100%; }
.cap-out-chip { display:inline-flex; align-items:center; min-height:28px; padding:0 10px; border-radius:999px; font-size:12px; font-weight:600;
  text-decoration:none; background:#fff1e6; color:#8a3d00; border:1px solid rgba(232,115,12,.45); touch-action:manipulation; }
.cap-out-chip.safety { background:#e6f4f1; color:#14574a; border-color:rgba(31,107,92,.4); }
.cap-out-chip.obs { background:#eef0fb; color:#3a3f8f; border-color:rgba(58,63,143,.35); }
.obs-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.obs-row { background:#fff; border:1px solid rgba(0,0,0,.12); border-left:4px solid #3a3f8f; padding:10px 12px; }
.obs-text { font-weight:600; }
.obs-quote { margin-top:2px; font-style:italic; }
.obs-meta { display:flex; gap:5px; flex-wrap:wrap; margin-top:6px; }
.obs-meta a { color:inherit; }
/* Plan wizard — fold an option or a step to one line (DraftCollapse, 2026-10-05). */
.rp-fold { flex:0 0 auto; width:32px; height:32px; border:1px solid rgba(0,0,0,.15); border-radius:6px; background:#fff; cursor:pointer;
  font:inherit; line-height:1; touch-action:manipulation; }
.rp-fold-title { cursor:pointer; min-width:0; flex:1 1 auto; }
.rp-fold-sum { font-weight:400; color:var(--slate); }
.rp-step-head { display:flex; align-items:center; gap:8px; }
/* Plan wizard — the AI at work, and what it concluded (AiThinking, 2026-10-05). */
.rp-ai-thinking { display:flex; gap:12px; align-items:flex-start; margin:10px 0; padding:12px 14px; border:1px solid #7c4dff; border-left-width:4px;
  background:#f4f0ff; }
.rp-ai-spark { font-size:22px; line-height:1; animation:rp-ai-pulse 1.2s ease-in-out infinite; }
@keyframes rp-ai-pulse { 0%,100% { opacity:.35; transform:scale(.9); } 50% { opacity:1; transform:scale(1.15); } }
@media (prefers-reduced-motion:reduce){ .rp-ai-spark { animation:none; } }
.rp-ai-note { margin:10px 0; padding:12px 14px; border:1px solid rgba(124,77,255,.4); border-left:4px solid #7c4dff; background:#faf8ff; user-select:text; }
.rp-ai-note-head { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:6px; }
.rp-ai-note p { margin:0 0 6px; }
.rp-ai-opts { margin:0 0 6px; padding-left:18px; display:grid; gap:4px; }
.rp-ai-warn { color:#b25f00; font-weight:600; }
fieldset.rp-lock { border:0; padding:0; margin:0; min-width:0; }
fieldset.rp-lock[disabled] { opacity:.5; pointer-events:none; }
/* Plans page — the defects still needing a plan (PlansNeeded, 2026-10-05). */
.plan-needs { margin:0 0 14px; padding:14px; border-left:4px solid var(--services-orange,#ff5700); }
.plan-need-act { margin-left:auto; flex:0 0 auto; }
.plan-needs .plan-row-body:empty { display:none; }
/* Plans register (PlansRegister, 2026-10-05) — the step strip on a rectification plan row, and a monitoring
   row's overdue mark + its review history. */
.plan-steps { list-style:none; margin:4px 0 2px; padding:0; display:flex; gap:3px; }
.plan-steps li { flex:1 1 0; min-width:0; padding-top:6px; border-top:4px solid rgba(0,0,0,.12); font-size:11px; color:var(--concrete,#9aa3aa);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.plan-steps li.done { border-top-color:#1f7a55; color:#1f7a55; }
.plan-steps li.now { border-top-color:var(--services-orange,#ff5700); color:var(--asphalt); font-weight:700; }
.plan-row.plan-row-overdue { border-left:4px solid #b3261e; }
.plan-overdue { color:#b3261e; font-weight:700; }
.plan-row-actions { gap:8px; }
/* PlanRowActions (2026-10-06, Simon: "the buttons on the right for continue drafting, open plan are on their own line. for
   desktop they should fit on the row with the title and plan details") — on a wide screen the row is two columns: the
   head / steps / details stack on the left, the buttons sit in a right column centred on the row; the expanded reviews
   history spans both. A phone keeps the stacked layout. */
@media (min-width:761px){
  .plan-row { grid-template-columns:minmax(0,1fr) auto; grid-auto-flow:row; column-gap:16px; align-items:center; }
  .plan-row > * { grid-column:1; }
  .plan-row > .plan-row-actions { grid-column:2; grid-row:1 / span 4; align-self:center; justify-content:flex-end; flex-wrap:nowrap; }
  .plan-row > .plan-history { grid-column:1 / -1; }
}
.plan-history { margin-top:6px; padding-top:8px; border-top:1px dashed rgba(0,0,0,.14); }
.plan-timeline { list-style:none; margin:0; padding:0 0 0 12px; border-left:2px solid rgba(0,0,0,.12); display:grid; gap:8px; }
.plan-timeline li { font-size:.92rem; }
/* Work package Overview (WorkPackageMenu, 2026-10-05) — the Summary tab: a "needs you" strip, then one tile
   per area of work (two per row on a phone), each a link into its page. */
.wpo-tabs { margin:0 0 14px; }
.wpo-needs { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:0 0 12px; padding:10px 12px;
  background:#fff6f1; border:1px solid var(--services-orange, #ff5700); border-left-width:4px; }
.wpo-need { display:inline-flex; align-items:center; min-height:32px; padding:0 12px; border-radius:999px;
  background:var(--vida-bitumen, #221f20); color:#fff; font-size:13px; font-weight:600; text-decoration:none; }
/* DashboardColumns (2026-10-06, Simon: "make it 6 columns wide max but then 4 or 2 depending on screen width") —
   six columns on a wide screen, four on a tablet / narrow window, two on a phone; the wide tiles span two. */
.wpo-grid { display:grid; grid-template-columns:repeat(6, minmax(0, 1fr)); gap:10px; }
@media (max-width:1100px){ .wpo-grid { grid-template-columns:repeat(4, minmax(0, 1fr)); } }
.wpo-tile { display:flex; flex-direction:column; gap:4px; min-width:0; padding:14px 16px; background:#fff;
  border:1px solid rgba(0,0,0,.12); color:inherit; text-decoration:none; }
a.wpo-tile:hover, .wpo-tile-link:hover { background:#fbf8f4; }
.wpo-tile-link { display:flex; flex-direction:column; gap:4px; color:inherit; text-decoration:none; }
.wpo-tile .k { font-family:var(--font-mono); font-size:10px; letter-spacing:0.18em; text-transform:uppercase; color:var(--concrete); }
.wpo-tile .v { font-family:var(--font-display); font-weight:800; font-size:32px; line-height:1; color:var(--asphalt); }
.wpo-tile .v.wpo-go { color:var(--concrete); }
.wpo-tile .sub { font-size:13px; color:var(--slate); }
.wpo-tile .sub.wpo-warn { color:#b3261e; font-weight:600; }
.wpo-wide { grid-column:span 2; }
.wpo-stages { display:flex; gap:6px; flex-wrap:wrap; margin-top:8px; }
.wpo-stages .mf-chip { text-decoration:none; color:inherit; min-height:32px; padding:3px 10px; }
@media (max-width:640px){
  .wpo-grid { grid-template-columns:repeat(2, minmax(0, 1fr)); gap:8px; }
  .wpo-tile { padding:12px; }
  .wpo-tile .v { font-size:28px; }
  .wpo-stages { flex-wrap:nowrap; justify-content:space-between; gap:3px; }
  .wpo-stages .mf-chip { padding:3px 7px; }
}
/* Capture sticky bars (2026-10-05, Simon: "make an area sticky at the top and bottom so the user only needs
   to scroll through the details of the captures"). TOP = CaptureStickyBar under the masthead + workspace bar;
   BOTTOM = .rev-actions.rev-sticky above the phone's bottom nav. position:sticky, never fixed — a fixed bar
   sits in the LAYOUT viewport and drifts off a zoomed iOS page. */
.cap-sticky { position:sticky; top:calc(var(--topbar-h) + var(--pws-h, 0px)); z-index:30; margin:0 0 12px;
  padding:8px 12px; background:#fff; border:1px solid rgba(0,0,0,.12); border-top:0; box-shadow:0 4px 10px rgba(0,0,0,.08); }
.cap-sticky-row { display:flex; align-items:center; gap:8px; min-width:0; }
.cap-sticky-row.sub { margin-top:6px; flex-wrap:nowrap; }
.cap-sticky .cap-kind-ic { width:20px; height:20px; }
.cap-sticky-ref { font-family:var(--font-mono); font-size:14px; white-space:nowrap; }
.cap-sticky-status { background:rgba(0,0,0,.07); max-width:46vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cap-sticky-actions { margin-left:auto; display:flex; gap:6px; flex:0 0 auto; }
.cap-sticky .btn.small { min-height:32px; touch-action:manipulation; }
.cap-sticky-next { white-space:nowrap; }
/* A jumped-to card must land BELOW the sticky stack, not under it. */
.cap-sticky-phone { display:none; }
@media (max-width:760px){ .cap-sticky-phone { display:inline-flex; } }
.defect-card, #rev-settings, #wm-map-card { scroll-margin-top:calc(var(--topbar-h) + var(--pws-h, 0px) + 96px); }
.rev-actions.rev-sticky { position:sticky; bottom:0; z-index:30; margin:14px 0 0; padding:8px 12px; gap:8px;
  background:#fff; border:1px solid rgba(0,0,0,.12); box-shadow:0 -4px 10px rgba(0,0,0,.08); flex-wrap:wrap; }
.rev-actions.rev-sticky .rev-status { flex:1 1 100%; display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:13px; }
.rev-actions.rev-sticky .rev-status .ok { color:#1f6b5c; font-weight:600; }
.rev-actions.rev-sticky .rev-status .warn { color:#b25f00; font-weight:600; }
.rev-actions.rev-sticky .btn { flex:0 1 auto; white-space:nowrap; }
.rev-actions.rev-sticky .btn-primary, .rev-actions.rev-sticky .rev-main { flex:1 1 auto; justify-content:center; text-align:center; }
@media (max-width:760px){
  /* clear the fixed bottom nav (56px + the home-indicator inset) */
  .rev-actions.rev-sticky { bottom:calc(56px + env(safe-area-inset-bottom, 0px)); }
  .rev-actions.rev-sticky .btn { padding-left:12px; padding-right:12px; }
}

/* Action buttons inside an expanded row panel — PHONE only (desktop shows the same actions
   inline on the row; on a phone they're otherwise reachable only by swiping the row). */
.tp-expand-acts { display:none; }
@media (max-width:760px){
  .tp-expand-acts { display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }
}
.badge.violet { background:rgba(124,77,255,.14); color:#5a2ecc; }
/* group heading between tp-lists (e.g. Activities grouped by due date) */
.tp-group-h { display:flex; align-items:center; gap:8px; margin:18px 0 8px; font-size:13.5px; font-weight:700; }
.tp-group-h:first-child { margin-top:0; }
.tp-group-h.overdue { color:#b3261e; }
.tp-group-h .count { font-size:12px; color:var(--concrete,#5a5b5d); font-weight:600;
  background:rgba(0,0,0,.06); border-radius:999px; padding:1px 8px; }
@media (max-width:760px){
  .tp-main { flex-direction:column; align-items:stretch; }
  .tp-p1, .tp-p2 { width:100%; }   /* parts on their own rows; badges flow inline and wrap only as needed */
  /* Tighter badge row on a phone (2026-09-30, Simon: the "in triage" badge "looks to fit on the row above but
     seems to be on its own row") — 5px gaps, slimmer badge padding, no extra margin on the triage flag, so the
     number · METAL · status · severity · triage set fits one line at iPhone width. */
  .tp-p1 { gap:5px; row-gap:4px; }
  .tp-p1 .badge { padding:2px 7px; }
  .tp-p1 .tri-flag { margin-left:0; }
  .tp-p1 .mon-flag { margin-left:0; }
  .tp-p2 { white-space:normal; }
  /* Title + trailing badge flow as TEXT (not flex items) so the type badge sits right after
     the title's last word — as a flex child it dropped to its own row whenever the title was
     longer than the remaining space. The badge stays nowrap, so it wraps as one unit only
     when it truly doesn't fit. */
  .tp-p2.tp-p2-flex { display:block; }
  .tp-p2-flex .tp-p2-txt { display:inline; white-space:normal; }
  /* 2026-09-30 (Simon: "the defect type badge is slightly higher than the text it follows"): an inline-block with
     overflow:hidden (the badge's ellipsis) takes its BASELINE from its bottom edge, so as flowing text the badge
     stood on the baseline and rode high — align it to the middle of the line instead. */
  .tp-p2-flex .tp-type { vertical-align:middle; position:relative; top:-1px; }
}

/* ---- iPhone swipe actions (CapturesList.txt) — swipe a row left to reveal its actions,
   iOS-mail style (swipe.js translates .swipe-content; the buttons are Blazor-rendered).
   Desktop keeps the inline .row-actions instead (.hide-mobile) and hides the slide-in block. */
.swipe-item { position:relative; overflow:hidden; }
.swipe-item + .swipe-item, .tp-expand + .swipe-item { border-top:1px solid rgba(0,0,0,.07); }
.swipe-item .tp-row { border-top:none; }
.sw-actions { position:absolute; top:0; bottom:0; right:0; display:flex; z-index:0; }
.swipe-content { position:relative; z-index:1; background:#fff; transition:transform .18s ease; touch-action:pan-y; }
.swipe-content:hover { background:#fffbf3; }
.sw-act { display:flex; align-items:center; justify-content:center; min-width:74px; padding:0 12px;
  border:none; cursor:pointer; text-decoration:none; font-size:12.5px; font-weight:700; color:#fff;
  font-family:var(--font-body); }
.sw-act.review { background:var(--ai-violet, #7c4dff); }
.sw-act.edit   { background:var(--concrete, #5a5b5d); }
.sw-act.detail { background:#2471b5; }
.sw-act.delete { background:#b3261e; }
/* Affordance: a sliver of orange down the right edge of each swipeable row hints that
   actions slide in from the right (phone only, and only when the row HAS actions — it
   rides the content, so it slides away with the row as the actions reveal). */
.swipe-item.has-acts .swipe-content::after { content:""; position:absolute; top:0; bottom:0; right:0;
  width:3px; background:#2471b5; }   /* same blue as the Details action */
@media (min-width:761px){
  .sw-actions { display:none; }
  .swipe-item.has-acts .swipe-content::after { display:none; }   /* no swipe on desktop — no hint */
}

/* configured feature icons in the masthead utility buttons (Help / Ask) */
.util-ic { display:inline-flex; width:19px; height:19px; }
.util-ic svg { width:100%; height:100%; display:block; }
/* configured AI Capture icon in the Capture pill (fallback = the AiSpark glyph) */
/* 18px matches the desktop pill's svg sizing (the old 16px box under an 18px svg overflowed —
   and on the mobile bar it rendered the Capture icon SMALLER than the other items' 22px). */
.capture-btn-ic { display:inline-flex; width:18px; height:18px; }
.capture-btn-ic svg { width:100%; height:100%; display:block; }
/* the ≤980 nav rule hides ALL spans in nav links (labels) — the icon wrapper span and the
   Workbag count badge must survive it, or the Capture pill renders empty (and the badge
   vanishes) at mid widths / iPhone landscape */
nav.primary a .capture-btn-ic { display:inline-flex; }
nav.primary a .wb-badge { display:inline-flex; }

/* two-column detail page: main column + sticky map/side column */
.detail-layout { display:grid; grid-template-columns:1.4fr 1fr; gap:16px; align-items:start; }
.detail-main { display:flex; flex-direction:column; gap:16px; min-width:0; }
.detail-side { position:relative; padding:0; overflow:hidden; }
.detail-side .map-canvas { height:520px; }
.dl-head { display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
/* keep wide tables inside the card on small screens rather than spilling */
.detail-main .table-wrap { overflow-x:auto; }

/* Asset detail head — labelled attribute grid (AssetGuid.txt). Each attribute is its own
   labelled cell so values are individually scannable; .wide spans the row (the GUID). */
.ah-badges { display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-bottom:12px; }
.ah-ref { font-weight:700; font-size:.95rem; color:var(--ink,#221f20); background:rgba(255,157,20,.16);
          border:1px solid rgba(255,157,20,.5); border-radius:6px; padding:2px 8px; }
.ah-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(160px, 1fr)); gap:12px 18px; }
.ah-item { display:flex; flex-direction:column; gap:2px; min-width:0; }
.ah-item.wide { grid-column:1 / -1; }
.ah-k { font-size:.68rem; text-transform:uppercase; letter-spacing:.06em; color:var(--muted,#777);
        font-weight:600; }
.ah-v { font-size:.92rem; color:var(--ink,#221f20); overflow-wrap:anywhere; }
@media (max-width:480px){ .ah-grid { grid-template-columns:repeat(2, minmax(0,1fr)); } }

/* map legend (shared by the detail pages) */
.sw-legend .lg-asset { background:var(--rail-blue,#2471b5); border-radius:2px; width:14px; height:5px; }

@media (max-width:760px){
  .detail-layout { grid-template-columns:1fr; }
  .detail-side .map-canvas { height:320px; }
}

/* ---- slide-in Actions & Activities drawer ---- */
.drawer-tab { position:fixed; right:0; top:42%; z-index:1200; transform:translateY(-50%);
  display:flex; flex-direction:column; align-items:center; gap:4px; cursor:pointer;
  background:var(--bitumen,#221f20); color:#fff; border:none; border-radius:10px 0 0 10px;
  padding:12px 8px; box-shadow:-2px 2px 10px rgba(0,0,0,.25); }
.drawer-tab.is-open { right:min(420px,92vw); }
.drawer-tab-label { writing-mode:vertical-rl; transform:rotate(180deg); font-size:11px; letter-spacing:.06em; text-transform:uppercase; }
.drawer-tab-count { background:var(--roads-orange,#ff9d14); color:#221f20; font-weight:700; font-size:11px;
  border-radius:999px; min-width:18px; padding:0 5px; line-height:18px; }
.drawer-backdrop { position:fixed; inset:0; background:rgba(0,0,0,.35); z-index:1190; }
.item-drawer { position:fixed; top:0; right:0; bottom:0; width:min(420px,92vw); z-index:1200;
  background:#fff; box-shadow:-6px 0 28px rgba(0,0,0,.3); padding:16px 18px; overflow:auto;
  animation:drawer-in .25s ease-out; }
@keyframes drawer-in { from { transform:translateX(100%); } to { transform:translateX(0); } }
.drawer-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.action-list { display:flex; flex-direction:column; gap:8px; }
.action-row { display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer;
  background:rgba(255,157,20,.08); border:1px solid rgba(255,157,20,.4); border-radius:9px; padding:12px 14px;
  font:inherit; color:var(--bitumen,#221f20); }
.action-row:hover:not(:disabled) { background:rgba(255,157,20,.16); }
/* Owner-specific drawer actions wear a small chip so it's clear WHY the action is offered. */
.action-row .owner-chip { margin-left:auto; flex-shrink:0; font-size:10px; font-weight:700;
  text-transform:uppercase; letter-spacing:.06em; color:var(--services-orange,#ff5700);
  border:1px solid currentColor; border-radius:999px; padding:2px 8px; }
.action-row:disabled { opacity:.5; cursor:default; }
.action-plus { font-size:18px; font-weight:700; color:var(--roads-orange,#ff9d14); line-height:1; }
.act-group { margin-bottom:12px; }
.act-group-head { font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--concrete,#5a6470); font-weight:600; margin-bottom:6px; }
.activity-row { display:flex; align-items:center; gap:8px; width:100%; text-align:left; cursor:pointer;
  background:#fff; border:1px solid rgba(0,0,0,.12); border-radius:8px; padding:9px 11px; margin-bottom:6px; font:inherit; }
.activity-row:hover { background:rgba(0,0,0,.03); }

/* ---- shared ActivityLayout form bits (also used inline by the Work Bag modal) ---- */
.act-head { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
.act-layout .fld { display:flex; flex-direction:column; gap:4px; margin-top:10px; }
.act-layout .fld > span { font-size:12px; font-weight:600; color:#555; }
/* 16px + full-width on ALL fld controls (incl. text/date INPUTS — previously missed, so iOS
   zoomed on focus and the task form "bled off the screen"); checkboxes keep their own sizing. */
.act-layout .fld textarea, .act-layout .fld select,
.act-layout .fld input:not([type="checkbox"]) { padding:8px 10px; border:1px solid #d6d6d6; border-radius:7px; font:inherit; font-size:16px; width:100%; max-width:100%; box-sizing:border-box; }
/* iOS date inputs keep their native intrinsic width and IGNORE width:100% until the native
   appearance is stripped — otherwise the field spills off the right on an iPhone. */
.act-layout .fld input[type="date"] { -webkit-appearance:none; appearance:none; display:block; min-width:0; min-height:38px; text-align:left; background:#fff; }
/* DefectAreaWorkPackage.txt — small explanatory hint under a review field (area / design package). */
.fld-hint { display:block; margin-top:3px; font-size:12px; line-height:1.35; color:#6b7280; }
.fld-hint.warn { color:#8a5a00; }
/* Shade the matching area / design-package options in the review dropdowns (a ✓ prefix marks them
   too, for native pickers that ignore per-option colours — e.g. iOS Safari). */
option.ad-match { background-color:#e3f5ee; color:#0f766e; font-weight:600; }
.act-layout .timeline { list-style:none; margin:4px 0 0; padding:0; display:flex; flex-direction:column; gap:6px; }
.act-layout .timeline li { display:flex; gap:6px; align-items:baseline; flex-wrap:wrap; }

/* Work Bag open-task count badge on the nav item (ContractorRegisters.txt) */
.wb-badge { display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px;
  padding:0 5px; border-radius:999px; background:var(--roads-orange,#ff5700); color:#fff;
  font-size:11px; font-weight:800; line-height:1; }
/* any OPEN task past its due date → red, not amber */
.wb-badge.overdue { background:#b3261e; }
/* negative margin pulls the badge back against the nav link's flex gap so it sits tight to the label */
nav.primary a .wb-badge { margin-left:-4px; }
.mobile-nav a { position:relative; }
/* OverviewBadge — the count on the work package strip's Overview item (the strip's links need a positioning box). */
.mobile-nav.project-mnav a, nav.primary.project-top a { position:relative; }
.mobile-nav a .wb-badge { position:absolute; top:3px; left:calc(50% + 5px); min-width:16px; height:16px; font-size:10px; padding:0 4px; }
/* The digit sat high and left of centre in the strip's badge: the strip's links are an UPPERCASE display face with
   letter-spacing — the spacing trails the digit (pushing it left) and the face's metrics ride high. The badge takes the
   body face, no letter-spacing, and centres by an explicit line-height equal to its height. */
.mobile-nav.project-mnav a .wb-badge, nav.primary.project-top a .wb-badge {
  display:inline-block; box-sizing:border-box; min-width:17px; height:17px; padding:0 4px; line-height:17px; text-align:center;
  font-family:var(--font-body); font-size:11px; font-weight:700; letter-spacing:0; text-indent:0; text-transform:none;
  font-variant-numeric:tabular-nums; }
nav.primary.project-top a .wb-badge { margin-left:2px; align-self:center; }

/* ---- Lists: item-kind icon chips (same SVGs as the project nav); never wrap to a 2nd line ---- */
.kind-ico-row { display:flex; gap:8px; margin-top:6px; flex-wrap:nowrap; overflow:hidden; }
.kind-ico { display:inline-flex; align-items:center; justify-content:center; color:var(--concrete,#5a5b5d); flex:0 0 auto; }
.kind-ico svg { width:16px; height:16px; display:block; }

/* ---- Lists detail: tabbed structured views (List / Map / Members / Manage) ---- */
.list-tabpanel { margin-top:4px; }
/* grouped list view */
.lv-group { border:1px solid rgba(0,0,0,.12); border-radius:8px; margin-bottom:10px; background:#fff; overflow:hidden; }
.lv-group > .lv-row { background:rgba(0,0,0,.03); font-weight:600; }
.lv-row { display:flex; align-items:center; gap:10px; padding:10px 12px; width:100%; border:none; background:transparent; text-align:left; font:inherit; cursor:pointer; border-top:1px solid rgba(0,0,0,.07); }
.lv-group > .lv-row:first-child { border-top:none; }
.lv-row .lv-ico { flex:0 0 auto; color:var(--concrete,#5a5b5d); display:inline-flex; }
.lv-row .lv-ico svg { width:18px; height:18px; }
.lv-row .lv-main { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:1px; }
.lv-row .lv-title { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.lv-row .lv-meta { flex:0 0 auto; display:flex; align-items:center; gap:6px; }
.lv-row .chev { flex:0 0 auto; color:#9aa3aa; transition:transform .12s; }
.lv-row.open .chev { transform:rotate(90deg); }
.lv-detail { padding:8px 12px 12px 40px; border-top:1px solid rgba(0,0,0,.07); background:#fafafa; }
.lv-actrow { display:flex; gap:8px; align-items:center; padding:5px 0; flex-wrap:wrap; }
.act-count { font-family:var(--font-mono,monospace); font-size:11px; background:rgba(255,157,20,.18); color:#9a5b00; border-radius:999px; padding:1px 8px; white-space:nowrap; }
.act-count.zero { background:rgba(0,0,0,.06); color:#777; }
/* members list (read-only + manage) — keep the ✕ inside the row on phones */
.mem-row { display:flex; align-items:center; gap:8px; padding:8px 10px; border-top:1px solid rgba(0,0,0,.07); }
.mem-row:first-child { border-top:none; }
.mem-row .mem-email { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mem-row .mem-actions { flex:0 0 auto; display:flex; align-items:center; gap:8px; }
/* the two-panel item-transfer table: give the action cell right padding so the button isn't flush */
.lv-itemtable td:last-child, .lv-itemtable th:last-child { text-align:right; padding-right:12px; }
/* keep a stable min height so switching to a short tab (Members) doesn't collapse the page & jump scroll */
.list-tabpanel { min-height:65vh; }
/* List view: list + map side by side (stacks on narrow screens) */
.lv-split { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:16px; align-items:start; }
.lv-listcol { min-width:0; }
.lv-mapcol { position:sticky; top:12px; min-width:0; }
.lv-mapbox { height:70vh; min-height:360px; border-radius:8px; overflow:hidden; }
/* read-only details grid (Manage tab) */
.ro-details > div { display:flex; gap:10px; padding:5px 0; align-items:baseline; }
.ro-details .ro-k { flex:0 0 130px; color:var(--concrete,#5a5b5d); font-size:12px; font-weight:600; }
.ro-details .ro-v { flex:1 1 auto; min-width:0; }
@media (max-width:900px){
  .lv-split { grid-template-columns:1fr; }
  .lv-mapcol { position:static; }
  .lv-mapbox { height:320px; }
}
@media (max-width:760px){
  .list-subtabs { flex-wrap:wrap; }
  .lv-detail { padding-left:24px; }
  .transfer { flex-direction:column; }
  .ro-details .ro-k { flex-basis:96px; }
  /* Manage item-kind tabs: stack the icon ABOVE the label (like the bottom-nav) so they don't
     overflow to a second line on a phone. */
  .kind-tabs { display:flex; }
  .kind-tabs .filter-tab { flex:1 1 0; flex-direction:column; gap:3px; padding:8px 6px; font-size:12px; text-align:center; }
  .kind-tabs .filter-tab .kind-ico svg { width:20px; height:20px; }
}

/* ===== Contextual Map (ContextualMap.txt) — full-body map + distinct navbar button ===== */
/* Distinct, right-fixed masthead button (filled amber pill — stands out from the ghost util buttons). */
.ctxmap-btn { display:inline-flex; align-items:center; gap:7px; height:38px; padding:0 14px; align-self:center;
  border-radius:20px; background:var(--roads-orange); color:#221f20; font-family:var(--font-display);
  font-weight:800; font-size:14px; letter-spacing:.04em; text-transform:uppercase; border:1px solid var(--roads-orange);
  box-shadow:0 2px 10px rgba(255,157,20,.35); }
.ctxmap-btn:hover { background:#ffab33; color:#221f20; }
.ctxmap-btn.active { background:#221f20; color:var(--roads-orange); box-shadow:none; }
.ctxmap-btn svg { width:18px; height:18px; display:block; }
@media (max-width:600px) { .ctxmap-btn-lbl { display:none; } .ctxmap-btn { padding:0 11px; } }

/* The map button now lives INSIDE the navs (right-aligned), not the masthead aside. */
/* Desktop primary nav: keep the amber pill, floated to the far right (the `nav.primary a`
   tab rules would otherwise repaint it as a flat dark tab — re-assert the pill + right push). */
nav.primary .ctxmap-btn { margin-left:auto; align-self:center; border:1px solid var(--roads-orange);
  border-radius:20px; height:38px; padding:0 14px; gap:7px; color:#221f20; font-weight:800; font-size:14px; }
nav.primary .ctxmap-btn svg { color:#221f20; }
nav.primary .ctxmap-btn:hover { background:#ffab33; color:#221f20; }
nav.primary .ctxmap-btn.active { background:#221f20; color:var(--roads-orange); }
nav.primary .ctxmap-btn.active svg { color:var(--roads-orange); }
nav.primary .ctxmap-btn.active::before { display:none; }
/* On phones the primary nav collapses into the burger dropdown — the map lives in the bottom
   bar there, so drop the dropdown copy to avoid a stray pill + duplicate. */
@media (max-width:760px) { nav.primary .ctxmap-btn { display:none; } }

/* Mobile bottom bar: render Map as a matching bottom-bar item (icon + label), the rightmost
   cell. Strip the pill chrome; keep the amber map icon so it reads as the distinct map action. */
.mobile-nav .ctxmap-btn { background:transparent; border:none; border-radius:0; box-shadow:none;
  height:auto; padding:8px 2px 7px; gap:3px; color:#fff; font-family:var(--font-body);
  font-weight:600; font-size:10px; letter-spacing:.02em; text-transform:none; }
.mobile-nav .ctxmap-btn svg { width:22px; height:22px; color:#fff; }
.mobile-nav .ctxmap-btn-lbl { display:inline; }
.mobile-nav .ctxmap-btn.active { background:transparent; color:#fff; }

/* ===== Global search (Search.txt) — bitumen pill LEFT of the Map pill ===== */
.search-btn { display:inline-flex; align-items:center; gap:7px; height:38px; padding:0 14px; align-self:center;
  border-radius:20px; background:#221f20; color:#fff; font-family:var(--font-display);
  font-weight:800; font-size:14px; letter-spacing:.04em; text-transform:uppercase; border:1px solid #4a4647;
  box-shadow:0 2px 10px rgba(0,0,0,.35); }
.search-btn:hover { background:#3a3637; color:#fff; }
.search-btn.active { background:#fff; color:#221f20; box-shadow:none; border-color:#221f20; }
.search-btn svg { width:18px; height:18px; display:block; }
@media (max-width:600px) { .search-btn-lbl { display:none; } .search-btn { padding:0 11px; } }

/* Desktop primary nav: Search takes over the right-push (it renders FIRST in the pill group),
   so the Map pill drops its auto margin to a small gap. Re-assert the pill over the tab rules. */
nav.primary .search-btn { margin-left:auto; align-self:center; border:1px solid #4a4647;
  border-radius:20px; height:38px; padding:0 14px; gap:7px; color:#fff; font-weight:800; font-size:14px; }
nav.primary .search-btn svg { color:#fff; }
nav.primary .search-btn:hover { background:#3a3637; }
nav.primary .search-btn.active { background:#fff; color:#221f20; }
nav.primary .search-btn.active svg { color:#221f20; }
nav.primary .search-btn.active::before { display:none; }
nav.primary .ctxmap-btn { margin-left:8px; }   /* Search now carries the auto right-push */
@media (max-width:760px) { nav.primary .search-btn { display:none; } }

/* Mobile bottom bar: matching bottom-bar item between Workbag and Map. */
.mobile-nav .search-btn { background:transparent; border:none; border-radius:0; box-shadow:none;
  height:auto; padding:8px 2px 7px; gap:3px; color:#fff; font-family:var(--font-body);
  font-weight:600; font-size:10px; letter-spacing:.02em; text-transform:none; }
.mobile-nav .search-btn svg { width:22px; height:22px; color:#fff; }
.mobile-nav .search-btn-lbl { display:inline; }
.mobile-nav .search-btn.active { background:transparent; color:#fff; }

/* ===== Search page (Search.txt) — grouped, expandable result tiles ===== */
.gs-box { display:flex; gap:8px; align-items:center; margin:4px 0 10px; }
.gs-box input { flex:1; height:44px; font-size:16px; padding:0 14px; border:1px solid rgba(0,0,0,.25);
  border-radius:10px; }   /* 16px — iOS zooms sub-16px inputs */
.gs-filters { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px; }
.gs-chip { display:inline-flex; align-items:center; gap:6px; padding:6px 12px; border-radius:999px;
  border:1px solid rgba(0,0,0,.25); background:#fff; font-size:13px; font-weight:600; cursor:pointer; }
.gs-chip.on { background:#221f20; color:#fff; border-color:#221f20; }
.gs-tile { border:1px solid rgba(0,0,0,.14); border-radius:10px; margin-bottom:10px; background:#fff; overflow:hidden; }
.gs-tile-head { display:flex; align-items:center; gap:10px; padding:10px 14px; cursor:pointer; }
.gs-tile-head svg { width:20px; height:20px; flex:0 0 20px; }
.gs-tile-head .gs-count { margin-left:auto; font-weight:700; }
.gs-row { display:flex; align-items:center; gap:10px; padding:9px 14px; border-top:1px solid rgba(0,0,0,.08);
  color:inherit; text-decoration:none; }
.gs-row:hover { background:rgba(0,0,0,.04); }
.gs-row .mono { flex:0 0 auto; }
.gs-row-main { min-width:0; flex:1; }
.gs-row-title { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.gs-row-sub { font-size:12px; color:var(--ink-dim, #5a6470); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.gs-why { flex:0 0 auto; font-size:10px; font-weight:700; letter-spacing:.02em; padding:2px 8px;
  border-radius:999px; background:rgba(124,77,255,.14); color:#5b3fa8; white-space:nowrap; }
.gs-dist { flex:0 0 auto; font-size:12px; font-weight:700; color:var(--roads-orange, #ff9d14); white-space:nowrap; }

/* ===== Capture (CaptureFeature.txt) — AI-themed launcher button + hub page ===== */
/* Sync link inside the user dropdown (moved off the top nav). */
.user-dropdown-item.udi-nav { display:flex; align-items:center; gap:8px; }
/* DeviceAccess (20260916) — the user menu's Device access row: green granted, red rejected by the
   user, amber blocked by the device (no hardware / OS location services off), grey not asked yet. */
.user-dropdown-item.um-access { display:flex; align-items:center; gap:10px; cursor:default; }
.user-dropdown-item.um-access:hover { background:transparent; }
.um-access-label { font-size:12px; color:#8a939b; }
.um-access-icons { display:flex; gap:8px; margin-left:auto; }
.um-perm { display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px; border-radius:8px;
  border:1.5px solid currentColor; color:#9aa3aa; font-size:14px; line-height:1; }
.um-perm.ok { color:var(--ok); }
.um-perm.denied { color:var(--down); }
.um-perm.blocked { color:#f5a623; }
/* 20260916 — the review's per-video transcript note (reason for no transcript; red = a transcription error) */
.aiw-transcript-note { color:#8a939b; }
.aiw-transcript-note.err { color:var(--down); }
/* AudioHealth (2026-09-23) — the per-video narration-audio score on the review + the details page. */
.aiw-audio-note { color:#8a939b; }
.aiw-audio-note.clipped, .aiw-audio-note.silent, .aiw-audio-note.none { color:var(--down); }
.aiw-audio-note.quiet, .aiw-audio-note.lowrate { color:#9a4a00; }
/* the desktop camera's location line */
.cam-fix { color:#8a939b; }
.cam-fix.cam-fix-ok { color:var(--ok); }
.cam-fix.cam-fix-denied { color:var(--down); }
.cam-fix.cam-fix-unavailable, .cam-fix.cam-fix-timeout { color:#b26a00; }
.user-dropdown-item.udi-nav svg { width:16px; height:16px; flex:0 0 16px; }

/* The Capture pill — violet AI theme, sits next to the Map pill. Mirrors .ctxmap-btn shape. */
.capture-btn { display:inline-flex; align-items:center; gap:7px; height:38px; padding:0 14px; align-self:center;
  border-radius:20px; background:var(--ai-violet); color:#fff; font-family:var(--font-display);
  font-weight:800; font-size:14px; letter-spacing:.04em; text-transform:uppercase; border:1px solid var(--ai-violet);
  box-shadow:0 2px 10px rgba(124,77,255,.35); }
.capture-btn:hover { background:var(--ai-violet-2); color:#fff; }
.capture-btn.active { background:#221f20; color:var(--ai-violet-2); box-shadow:none; border-color:#221f20; }
.capture-btn svg { width:18px; height:18px; display:block; }
@media (max-width:600px) { .capture-btn-lbl { display:none; } .capture-btn { padding:0 11px; } }

/* Desktop primary nav: keep the violet pill (re-assert over the flat tab rules), sit it right of Map. */
nav.primary .capture-btn { align-self:center; margin-left:8px; border:1px solid var(--ai-violet);
  border-radius:20px; height:38px; padding:0 14px; gap:7px; color:#fff; font-weight:800; font-size:14px; }
nav.primary .capture-btn svg { color:#fff; }
nav.primary .capture-btn:hover { background:var(--ai-violet-2); }
nav.primary .capture-btn.active { background:#221f20; color:var(--ai-violet-2); }
nav.primary .capture-btn.active svg { color:var(--ai-violet-2); }
nav.primary .capture-btn.active::before { display:none; }
@media (max-width:760px) { nav.primary .capture-btn { display:none; } }

/* Mobile bottom bar: matching bottom-bar item, violet icon. */
.mobile-nav .capture-btn { background:transparent; border:none; border-radius:0; box-shadow:none;
  height:auto; padding:8px 2px 7px; gap:3px; color:#fff; font-family:var(--font-body);
  font-weight:600; font-size:10px; letter-spacing:.02em; text-transform:none; }
.mobile-nav .capture-btn svg { width:22px; height:22px; color:#fff; }
.mobile-nav .capture-btn-lbl { display:inline; }
.mobile-nav .capture-btn.active { background:transparent; color:#fff; }
/* The configured-icon wrapper matches the bar's 22px icons (its 18px desktop box otherwise
   made Capture the one smaller icon in the row). */
.mobile-nav .capture-btn .capture-btn-ic { width:22px; height:22px; }

/* All three pills sit in the bar as FULL-HEIGHT cells: the desktop pill base sets
   align-self:center, which floated them mid-bar while the regular items stretch —
   so the five icons/labels never sat on the same lines. Same stack (22px icon +
   3px gap + 10px label, centred in 56px) across all five items. */
.mobile-nav .search-btn, .mobile-nav .ctxmap-btn, .mobile-nav .capture-btn {
  align-self:stretch; min-height:56px; justify-content:center; }

/* Capture hub page — option tiles. */
.capture-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(250px, 1fr)); gap:14px; margin-bottom:26px; }
.capture-tile { display:flex; gap:14px; align-items:flex-start; padding:16px 18px; border-radius:14px; color:inherit;
  border:1px solid rgba(124,77,255,.25); background:linear-gradient(180deg, rgba(124,77,255,.07), rgba(124,77,255,.02));
  transition:border-color .15s, box-shadow .15s, transform .05s; }
.capture-tile:hover { border-color:var(--ai-violet); box-shadow:0 6px 20px rgba(124,77,255,.18); }
.capture-tile:active { transform:translateY(1px); }
.capture-tile.is-disabled { opacity:.55; pointer-events:none; }
.capture-tile .ct-ico { flex:0 0 44px; width:44px; height:44px; border-radius:12px; display:flex; align-items:center;
  justify-content:center; background:var(--ai-violet); color:#fff; }
.capture-tile .ct-ico svg { width:23px; height:23px; }
.capture-tile .ct-body { display:flex; flex-direction:column; gap:4px; min-width:0; }
.capture-tile .ct-title { display:flex; align-items:center; gap:6px; font-family:var(--font-display); font-weight:800;
  text-transform:uppercase; letter-spacing:.03em; font-size:17px; color:var(--asphalt); }
.capture-tile .ct-title .ai-spark { color:var(--ai-violet); }
.capture-tile .ct-sub { font-size:13px; color:var(--concrete); line-height:1.4; }
.capture-tile .ct-soon { align-self:flex-start; margin-top:2px; font-size:11px; font-weight:700; text-transform:uppercase;
  letter-spacing:.04em; background:rgba(0,0,0,.08); color:var(--concrete); border-radius:999px; padding:1px 9px; }

/* MinorChanges.txt — Capture hub: AI/Manual toggle, type groups, and an amber accent for MANUAL tiles. */
.cap-toggle { display:inline-flex; border:1px solid rgba(0,0,0,.16); border-radius:999px; overflow:hidden; background:#fff; }
.cap-toggle button { border:none; background:transparent; padding:7px 16px; cursor:pointer; color:var(--concrete);
  font-family:var(--font-display); font-weight:700; font-size:13px; letter-spacing:.05em; text-transform:uppercase; }
.cap-toggle button.active { background:var(--vida-bitumen, #221f20); color:#fff; }
.capture-group { margin-bottom:22px; }
.capture-group-h { font-size:14px; letter-spacing:.07em; text-transform:uppercase; color:var(--concrete); margin:0 0 10px; }
.capture-tile.manual { border-color:rgba(255,157,20,.32); background:linear-gradient(180deg, rgba(255,157,20,.09), rgba(255,157,20,.02)); }
.capture-tile.manual:hover { border-color:var(--roads-orange); box-shadow:0 6px 20px rgba(255,157,20,.18); }
.capture-tile.manual .ct-ico { background:var(--roads-orange); color:#221f20; }

/* MinorChanges.txt — spread the category groups across the available width on desktop (each a column,
   tiles stacked within it); collapses to a single column on narrow screens. */
.capture-groups { display:grid; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); gap:20px 22px; align-items:start; margin-bottom:26px; }
.capture-groups .capture-group { margin-bottom:0; }
.capture-groups .capture-grid { grid-template-columns:1fr; margin-bottom:0; }

/* MinorChanges.txt — out-of-boundary warning bar at the top of a capture page body. */
.boundary-warn { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 16px;
  margin:0 0 16px; padding:11px 16px; border-radius:10px; color:#221f20;
  background:linear-gradient(rgba(245,166,35,.16), rgba(245,166,35,.16)), #fff; border:1px solid rgba(245,166,35,.55); }
.boundary-warn .bw-msg { font-size:13px; line-height:1.4; min-width:0; }
.boundary-warn .bw-actions { display:flex; gap:8px; flex:0 0 auto; }
.boundary-warn .btn-sm { padding:5px 12px; font-size:12.5px; }

/* Walk observations (WalkObservations.txt) — narrator-requested notes on the review + capture
   details pages: tappable rows that expand to the quote / moment / location. */
.aiw-obs { padding:8px 10px; border:1px solid rgba(0,0,0,.1); border-radius:8px; margin-bottom:6px; background:#fbfaf7; }
.aiw-obs.open { border-color:var(--roads-orange,#ff5700); background:#fff; }
.aiw-obs .chev { color:var(--concrete,#9aa3aa); font-size:13px; }

/* Capture hub page — in-flight drafts list. */
.capture-inflight-h { font-size:20px; margin:6px 0 12px; }
/* Create-section header: the "Create" heading + the AI/Manual toggle on one row. */
.capture-create-head { display:flex; align-items:center; justify-content:space-between; gap:12px;
  flex-wrap:wrap; margin-top:22px; }
.capture-create-head .capture-inflight-h { margin:0; }
.capture-inflight { display:flex; flex-direction:column; gap:10px; }
/* 20260916 — collapsible In progress title bar with per-status count badges */
.capture-inflight-head { display:flex; align-items:center; gap:10px; flex-wrap:wrap; cursor:pointer; user-select:none; -webkit-user-select:none; margin:6px 0 12px; }
.capture-inflight-head .capture-inflight-h { margin:0; }
.capture-inflight-head .cd-chevron { font-size:15px; color:var(--concrete); margin-left:2px; }
.capture-inflight-counts { display:flex; gap:6px; flex-wrap:wrap; }
.capture-inflight-counts .badge { white-space:nowrap; }
.cap-draft { display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:12px 14px; background:#fff;
  border:1px solid rgba(0,0,0,.1); border-radius:10px; }
.cap-draft .cd-num { font-weight:700; }
.cap-draft .cd-type { font-family:var(--font-display); font-weight:700; text-transform:uppercase; letter-spacing:.03em; font-size:14px; }
.cap-draft .cd-meta { color:var(--concrete); }
.cap-draft .cd-actions { display:flex; gap:8px; margin-left:auto; }
.btn.small { padding:6px 10px; font-size:12px; }
.cap-draft .btn.danger { color:#b3261e; border:1px solid rgba(179,38,30,.4); background:transparent; }
.cap-draft .btn.danger:hover { background:rgba(179,38,30,.08); border-color:#b3261e; }

/* Shared modal (was page-local in SiteWalksList; promoted to global so the Capture page can reuse it). */
.modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,.55); display:flex; align-items:center; justify-content:center; z-index:1000; padding:16px; }
.modal-card { background:#fff; border-radius:10px; padding:16px 18px; width:100%; box-shadow:0 12px 40px rgba(0,0,0,.35); }
.modal-head { display:flex; align-items:center; justify-content:space-between; gap:12px; }

/* Full-body map: fixed below the masthead (hazard strip + topbar) AND the sticky Project Workspace bar
   when a workspace is active (MinorChanges.txt). --pws-h is published by ProjectWorkingBar (0 when no
   workspace), so the map's top isn't hidden behind the bar and its boundary framing + the top-right
   zoom controls + the top-left overlay stay visible. Above the mobile bottom nav. */
.ctxmap { position:fixed; left:0; right:0; top:calc(var(--hazard-h) + var(--topbar-h) + var(--pws-h, 0px)); bottom:0; z-index:20; background:#e9e6df; }
@media (max-width:760px) { .ctxmap { bottom:calc(56px + env(safe-area-inset-bottom)); } }
.ctxmap .map-wrap { height:100%; width:100%; border:0; }
.ctxmap .map-canvas { height:100%; width:100%; }

/* Coords + address overlay, top-left, small font, mostly-transparent panel. */
.ctxmap-overlay { position:absolute; top:10px; left:10px; z-index:5; max-width:min(72%, 320px);
  padding:6px 10px; border-radius:8px; background:rgba(255,255,255,.72); backdrop-filter:blur(3px);
  box-shadow:0 2px 8px rgba(0,0,0,.14); font-size:11px; line-height:1.35; color:#221f20; pointer-events:none; }
.ctxmap-title { font-weight:800; font-size:12px; letter-spacing:.02em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ctxmap-addr { color:#3f4447; overflow:hidden; text-overflow:ellipsis; }
.ctxmap-coords { font-family:var(--font-mono); color:#5a5b5d; }

/* Locator button — recentre on the user, bottom-right of the map. */
/* AssetClassificationUsageFlags.txt — the contextual map's classification toggle box: sits
   IN the top-left location overlay's flow (top-right overlapped the zoom controls). */
.ctxmap-classbox { margin-top:6px; max-width:min(52vw, 220px);
  display:flex; flex-direction:column; align-items:flex-start;
  /* the location overlay is pointer-events:none so the map drags through it — the toggle
     box must re-enable its own events or every tap falls through to the map (grab cursor) */
  pointer-events:auto; }
.ctxmap-classbox-head { border:none; border-radius:14px; padding:4px 10px; font:inherit; font-size:12px;
  background:rgba(34,31,32,.82); color:#fff; cursor:pointer; }
.ctxmap-classbox-list { margin-top:4px; background:rgba(255,255,255,.95); border-radius:10px;
  box-shadow:0 4px 16px rgba(0,0,0,.25); padding:6px 8px; max-height:38vh; overflow-y:auto; min-width:170px; }
.ctxmap-classrow { display:flex; gap:6px; align-items:center; font-size:12px; padding:2px 0; cursor:pointer; }
.ctxmap-classrow .dot { width:10px; height:10px; border-radius:50%; flex-shrink:0; }
.ctxmap-classrow .lbl { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Releases ladder (/releases — ReleaseLadder): the full release history, expandable rows. */
.rel-ladder { list-style:none; margin:10px 0 0; padding:0; display:flex; flex-direction:column; }
.rel-row { border-top:1px solid var(--line, #e5e2de); }
.rel-row:first-child { border-top:none; }
.rel-head { display:flex; align-items:baseline; gap:10px; width:100%; padding:10px 4px; border:none;
  background:none; font:inherit; text-align:left; cursor:pointer; }
.rel-head:hover { background:rgba(255,157,20,.06); }
.rel-ver { font-weight:700; min-width:56px; }
.rel-date { min-width:64px; white-space:nowrap; }
.rel-headline { flex:1; min-width:0; }
.rel-caret { margin-left:auto; }
.rel-current .rel-ver { color:var(--amber, #ff9d14); }
.rel-details { list-style:disc; margin:0 0 12px; padding:0 8px 0 30px; display:flex;
  flex-direction:column; gap:5px; }
@media (max-width: 560px) { .rel-date { display:none; } }

.ctxmap-locator { position:absolute; right:12px; bottom:12px; z-index:6; width:46px; height:46px;
  display:inline-flex; align-items:center; justify-content:center; border-radius:50%; cursor:pointer;
  background:#fff; color:#221f20; border:1px solid rgba(0,0,0,.14); box-shadow:0 3px 12px rgba(0,0,0,.22); }
.ctxmap-locator:hover { color:var(--roads-orange); border-color:var(--roads-orange); }
.ctxmap-locator svg { width:22px; height:22px; display:block; }
/* "Show my project" locator stacked above the "show my location" one (MinorChanges.txt). */
.ctxmap-locator.ctxmap-locator-proj { bottom:66px; }

/* ── Group Defect AI Walk (MultiUserSiteWalks.txt) — invites banner, lobby roster, record media ── */
.gw-banner { border:1px solid rgba(124,77,255,.28); background:rgba(124,77,255,.05);
  border-radius:12px; padding:12px 14px; margin-bottom:18px; }
.gw-joinlist { display:flex; flex-direction:column; }
.gw-invite-row { display:flex; align-items:center; gap:12px; padding:8px 0; border-top:1px solid rgba(0,0,0,.06); }
.gw-invite-row:first-of-type { border-top:0; }
.gw-inv-ico { color:var(--ai-violet,#7c4dff); flex:0 0 auto; }
.gw-inv-ico svg { width:22px; height:22px; display:block; }
.gw-inv-meta { display:flex; flex-direction:column; gap:1px; flex:1; min-width:0; }
.gw-inv-title { font-weight:600; }
.gw-invite-row .btn { margin-left:auto; flex:0 0 auto; }

.gw-head { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:10px; }
.gw-roster { display:flex; flex-direction:column; gap:6px; }
.gw-member { display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:6px 0; border-top:1px solid rgba(0,0,0,.05); }
.gw-member:first-child { border-top:0; }
.gw-dot { width:9px; height:9px; border-radius:50%; background:#9ca3af; flex:0 0 auto; }
.gw-dot.joined, .gw-dot.ready { background:#2e7d32; }
.gw-dot.invited { background:#ff9d14; }
.gw-dot.left { background:#b3261e; }
.gw-email { font-weight:600; }
.gw-owner { font-size:11px; font-weight:700; color:var(--ai-violet,#7c4dff); background:rgba(124,77,255,.12);
  border-radius:999px; padding:1px 7px; margin-left:4px; }
.gw-jstate { font-size:11.5px; font-weight:600; color:#5a6470; background:rgba(0,0,0,.05); border-radius:999px; padding:1px 8px; }
.gw-counts { margin-left:auto; }
.gw-actions { display:flex; gap:12px; align-items:center; flex-wrap:wrap; }
.gw-ok { color:#2e7d32; font-weight:600; }

.gw-invites { display:flex; flex-direction:column; gap:6px; }
.gw-invite { display:flex; align-items:center; gap:10px; padding:6px 8px; border:1px solid rgba(0,0,0,.1); border-radius:8px; }
.gw-invite.on { border-color:var(--ai-violet,#7c4dff); background:rgba(124,77,255,.05); }
.gw-inv-who { display:flex; align-items:center; gap:8px; flex:1; min-width:0; cursor:pointer; }
.gw-invite select { max-width:200px; }

.gw-media { display:flex; flex-direction:column; gap:6px; }
.gw-seg { display:flex; align-items:center; gap:10px; padding:6px 8px; border:1px solid rgba(0,0,0,.08);
  border-radius:8px; background:rgba(0,0,0,.015); }
.gw-seg .btn { margin-left:auto; }

/* "You're here" indicator (LocationFeature) — a BOLD solid-green circular chip with a white location pin,
   shown just BEFORE a project name / on a project card / on a capture row when the device is inside that
   project's boundary. Deliberately obvious. */
.here-badge { display:inline-flex; align-items:center; justify-content:center; position:relative; top:-2px;
  width:20px; height:20px; border-radius:50%; background:#0a7d34; color:#fff; flex:none;
  box-shadow:0 0 0 2px rgba(10,125,52,.22); margin-right:7px; }
.here-badge svg { width:15px; height:15px; flex:none; }
.here-badge.with-text { width:auto; height:auto; border-radius:999px; gap:5px; padding:2px 10px 2px 7px;
  font-size:12px; font-weight:700; box-shadow:none; }
.here-badge.with-text svg { width:14px; height:14px; }

/* Section header on the AI-walk review page (CaptureFeature) — groups the proposed defects by the
   section their photos were captured in. Now a NATIVE <details><summary> (field feedback — an
   @onclick h4 never fired on iPhone; the iOS non-interactive-element gotcha): the summary is the
   tappable header, the default marker is hidden (our own chevron rotates via [open]). */
.rev-section-h { display:flex; align-items:center; gap:6px; margin:20px 0 8px; padding-bottom:5px;
  border-bottom:2px solid var(--ai-violet,#7c3aed); color:#6d28d9; font-size:15px; font-weight:600;
  cursor:pointer; list-style:none; -webkit-user-select:none; user-select:none; flex-wrap:wrap; }
.rev-section-h::-webkit-details-marker, .rev-section-h::marker { display:none; content:""; }
.rev-section-h.rs-hidden { display:none; }   /* unnamed group — nothing to collapse */
.rev-sec:not([open]) > .rev-section-h .chev { transform:rotate(-90deg); }
.rev-sec:not([open]) > .rev-section-h .rev-sec-map { display:none; }
.rev-sec > .rev-section-h .chev { transition:transform .15s ease; }

/* "What will be processed" summary on the AI-walk Map step (CaptureFeature Bugs pt3) — per-section
   photo/recording counts so the user sees exactly what the AI will run over, by section. */
.proc-summary { margin-top:14px; border:1px solid rgba(0,0,0,.1); border-radius:10px; padding:10px 12px;
  background:rgba(124,58,237,.05); }
.proc-summary .ps-head { display:flex; align-items:center; gap:6px; font-weight:600; font-size:13px;
  color:#6d28d9; margin-bottom:6px; }
.proc-summary .ps-row { display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  padding:3px 0; border-top:1px solid rgba(0,0,0,.05); }
.proc-summary .ps-name { font-weight:500; overflow-wrap:anywhere; }
.proc-summary .ps-counts { color:var(--muted,#6b7280); font-size:12px; white-space:nowrap; }
.proc-summary .ps-total { margin-top:6px; padding-top:6px; border-top:1px solid rgba(0,0,0,.1);
  color:var(--muted,#6b7280); font-size:12px; }

/* "You are here" map marker (LocationFeature) — a bigger, bolder pulsing blue dot, distinct from
   record/defect pins. */
.user-loc-dot { width:22px; height:22px; border-radius:50%; background:#1f6feb; border:3px solid #fff;
  box-shadow:0 0 0 3px rgba(31,111,235,.5), 0 1px 5px rgba(0,0,0,.45); position:relative; }
.user-loc-dot::after { content:""; position:absolute; inset:-8px; border-radius:50%;
  border:2.5px solid rgba(31,111,235,.55); animation:userLocPulse 2s ease-out infinite; }
@keyframes userLocPulse { 0% { transform:scale(.45); opacity:.9; } 100% { transform:scale(1.5); opacity:0; } }

/* Rectification plan (RectificationPlans.txt — read-mostly owner view on the defect detail) */
.rect-plan .rect-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.rect-plan .rect-head h2 { margin: 0; font-size: 1.05rem; }
.rect-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; margin: 8px 0 12px; }
.rect-opt { border: 1.5px solid var(--border, #e2e2e2); border-radius: 8px; padding: 10px; }
.rect-opt.sel { border-color: var(--amber, #ff9d14); background: rgba(255, 157, 20, 0.06); }
.rect-opt-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rect-opt-meta { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.rect-signoff { display: flex; align-items: center; gap: 8px; margin: 4px 0 10px; }

/* ── PhotoAdd (ConsistentPhotos) — the solution-wide photo pipeline component. Global because the
   capture editor's classes live inline in the wizards and PhotoAdd renders on other pages. ── */
.padd { display: flex; flex-direction: column; gap: 6px; }
.padd .thumb-strip { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 4px; }
.padd .thumb { width: 72px; height: 56px; object-fit: cover; border-radius: 6px; border: 1px solid rgba(0,0,0,.12); }
.padd .thumb.ph { display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,.05); color: #999; }
.padd-tile { position: relative; display: inline-flex; }
.padd-tile .thumb { cursor: pointer; }
.padd-tile .media-flag { position: absolute; top: 3px; right: 22px; background: rgba(0,0,0,.62); color: #fff;
    border-radius: 5px; padding: 1px 4px; font-size: 10px; display: inline-flex; align-items: center; gap: 2px; }
.padd-tile .media-flag.tags { right: auto; left: 3px; }
.padd-x { position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%;
    border: none; background: rgba(0,0,0,.65); color: #fff; font-size: 13px; line-height: 1; cursor: pointer; }
.padd-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* the capture-grade editor modal (PhotoAdd's own copy of the wizard-inline classes) */
.modal-card.edit-media { max-width: 860px; width: min(94vw, 860px); }
.edit-media .em-body { display: grid; grid-template-columns: 1.2fr 1fr; gap: 14px; align-items: start; }
@media (max-width: 700px) { .edit-media .em-body { grid-template-columns: 1fr; } }
.edit-media .em-img { display: flex; flex-direction: column; gap: 8px; }
.edit-media .em-img img { max-width: 100%; max-height: 46vh; object-fit: contain; border-radius: 8px; background: #f2f2f2; }
.edit-media .tag-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 6px; }
.edit-media .tag { background: rgba(36,113,181,.12); color: #1c5582; border-radius: 999px; padding: 2px 9px; font-size: 12px; display: inline-flex; align-items: center; gap: 4px; }
.edit-media .tag button { background: transparent; border: none; padding: 0; cursor: pointer; color: inherit; font-size: 13px; }
.edit-media .tag-add { display: flex; gap: 6px; }
.edit-media .tag-add input { flex: 1; min-width: 0; padding: 6px 9px; border: 1px solid #d6d6d6; border-radius: 7px; font: inherit; font-size: 16px; }
/* iOS zooms the page when focusing a <16px control ("form bleeds off the screen") — 16px stops it.
   The file-input guard stops the iOS "Choose Files" control's intrinsic width widening the panel. */
.padd input, .padd textarea, .edit-media input, .edit-media textarea { font-size: 16px; }
.padd-actions input[type="file"] { max-width: 100%; }
.edit-media .fld { display: flex; flex-direction: column; gap: 4px; }
.edit-media .fld > span { font-size: 12px; font-weight: 600; color: #555; }
.edit-media .fld textarea { padding: 8px 10px; border: 1px solid #d6d6d6; border-radius: 7px; font: inherit; font-size: 16px; width: 100%; max-width: 100%; box-sizing: border-box; }
/* full-image lightbox (global copy — DefectDetail styles its own inline) */
.lightbox { position: fixed; inset: 0; background: rgba(0,0,0,.8); display: flex; align-items: center;
    justify-content: center; z-index: 1100; padding: 16px; }
.lightbox-inner { background: #111; padding: 14px; border-radius: 10px; max-width: 94vw; max-height: 94vh;
    display: flex; flex-direction: column; gap: 10px; align-items: center; }
/* STABLE box regardless of source resolution — the thumb-first preview (a ~240px thumbnail)
   otherwise rendered as a tiny window that expanded when the display image swapped in. */
.lightbox-inner img { width: 90vw; height: 82vh; object-fit: contain; border-radius: 6px; background: #000; }
/* CaptureItemBox.txt — when the AI's boxes overlay the photo, the img must HUG the picture
   (auto sizing, no object-fit letterbox) or the normalised boxes spill onto the blank bars.
   Trade-off: the thumb-first preview shows small until the full image swaps in. */
.lightbox-inner img.cib-hug { width: auto; height: auto; max-width: 90vw; max-height: 82vh; }
/* Consistent, OBVIOUS close: the map lightbox's top-right circular ✕, shared by every lightbox
   (replaces the easy-to-miss bottom "Close" button). Amber ring so it reads against any photo. */
.lightbox-close { position: absolute; top: 14px; right: 16px; width: 44px; height: 44px; border: 2px solid var(--defuse-orange, #ff9d14);
    border-radius: 50%; background: rgba(0,0,0,.55); color: #fff; font-size: 20px; font-weight: 700; cursor: pointer; z-index: 5; }
.lightbox-close:hover { background: rgba(0,0,0,.8); }

/* METAL stage letter pill (DefectMetalSteps.txt) — Map/Evaluate/Track/Accept/Liability shown as a
   single bold letter between the defect number and the status. Each stage gets its OWN colour. */
.metal-pill { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px;
    padding: 0 5px; border-radius: 6px; font-weight: 800; font-size: 12px; line-height: 1; letter-spacing: .02em;
    background: #5a6470; color: #fff; flex: none; }
.metal-pill.lg { min-width: 23px; height: 23px; font-size: 13px; border-radius: 7px; }
.metal-pill.m-m { background: #5a6470; }   /* Map — slate */
.metal-pill.m-e { background: #2471b5; }   /* Evaluate — blue */
.metal-pill.m-t { background: #e8730c; }   /* Track — orange */
.metal-pill.m-a { background: #1f7a55; }   /* Accept — green */
.metal-pill.m-l { background: #751853; }   /* Liability — mulberry */
.metal-pill.m-c { background: #4caf50; }   /* Closed — ✓ tick, green (a lighter shade, Simon 2026-09-25) */
.metal-pill.m-x { background: #e05a4f; }   /* Rejected — ✗ cross, red (lighter): the owner agreed with the triage dispute, not a defect */

/* Defect detail identity line: the TITLE is the heading on the LEFT (the DEF number lives in the eyebrow
   above); the METAL letter + status badges are pinned to the RIGHT. The title fills the remaining width
   and wraps internally; the badges stay together, top-right. */
.dh-idline { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 8px 14px; }
/* The title keeps at least ~55% of the row (a long badge group used to squeeze it to one letter per line);
   `overflow-wrap:anywhere` is only for a single unbreakable word — normal titles wrap at spaces. */
.dh-idline h1.dh-title { margin: 0; flex: 1 1 55%; min-width: min(100%, 14ch); font-size: 1.35rem; font-weight: 700;
    color: var(--ink, #1f2933); overflow-wrap: anywhere; }
.dh-badges { flex: 0 1 auto; display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 6px; }
/* Match the header status badge to the METAL letter pill's size (letter down a touch, status up a touch). */
.dh-badges .badge { font-size: 13px; padding: 3px 12px; }
/* Phones (TriageHeader, 2026-09-30 — Simon: "title in a compressed field… one letter per row"): the badge row
   drops UNDER the title, full width, left-aligned, and the long triage badge may wrap its text. */
@media (max-width: 640px) {
    .dh-idline h1.dh-title { font-size: 1.2rem; flex-basis: 100%; }
    .dh-badges { flex-basis: 100%; justify-content: flex-start; }
    .dh-badges .badge.tri-flag-head { white-space: normal; text-align: left; }
}
.rect-fix { border: 1px solid var(--border, #e2e2e2); border-radius: 8px; padding: 12px; margin-top: 10px; }
.rect-fix-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rect-fix-desc { margin: 6px 0; white-space: pre-wrap; }
.rect-fix-meta { display: grid; gap: 4px; font-size: 0.9rem; }
.rect-fix-meta .dd-k { display: inline-block; min-width: 92px; color: var(--ink-dim, #6b6b6b); font-weight: 600; }

/* Defect history timeline (DefectHistory.txt — online only) */
.dh-head { display:flex; align-items:center; gap:10px; }
.dh-head h2 { margin:0; font-size:1.05rem; }
.dh-list { list-style:none; margin:6px 0 0; padding:0; }
.dh-list > li { padding:8px 0; border-top:1px solid var(--border, #e2e2e2); }
.dh-list > li:first-child { border-top:none; }
.dh-line { display:flex; align-items:center; gap:8px; }
.dh-details { white-space:pre-wrap; margin-top:3px; }

/* AIV in-app tracked video recorder */
.trk-hud { display:flex; align-items:center; gap:8px; margin:8px 0; }
.rec-dot { width:10px; height:10px; border-radius:50%; background:#e53935; animation: trkpulse 1.2s infinite; }
@keyframes trkpulse { 50% { opacity:.25; } }

/* AiWalkMap — persisted compliance flags on a video capture's defects */
.wm-def-comp { border-left: 3px solid rgba(124,77,255,.55); background: rgba(124,77,255,.06); padding: 6px 8px; border-radius: 0 6px 6px 0; margin: 6px 0; display: grid; gap: 4px; }
/* Field feedback — the ⚖ compliance badge on a details-page defect header (violet when the
   defect carries ACCEPTED issues); tap shows/hides the clause-cited .wm-def-comp list. */
.wm-comp-badge { border: 1px solid rgba(124,77,255,.5); background: rgba(124,77,255,.08); color: #6a3de8;
  border-radius: 999px; padding: 1px 9px; font-size: 12px; font-weight: 700; cursor: pointer; white-space: nowrap; }
.wm-comp-badge.acc { background: #6a3de8; color: #fff; }
.wm-comp-badge { display:inline-flex; align-items:center; gap:4px; min-height:24px; }   /* ReviewIcons 2026-10-06 — the compliance glyph beside the count */
.obs-head { display:flex; align-items:flex-start; gap:8px; justify-content:space-between; }
.obs-head .obs-text { flex:1 1 auto; min-width:0; }
.obs-close { flex:0 0 auto; min-height:32px; }
.obs-row.obs-closed { border-left-color:#9aa3aa; background:#fafafa; }
.obs-row.obs-closed .obs-text { color:var(--slate); text-decoration:line-through; text-decoration-color:rgba(0,0,0,.35); }
.obs-closed-tag { color:#1a7f37; font-weight:600; }
.dup-warn .dup-msg .ico, .rev-gate-hint .ico { flex:0 0 auto; }
.wpo-steps .mf-chip { font-size:12px; }


/* Shared: a 🎞 timeframe that seeks the capture video to that moment (review + details). */
.vid-seek { font-weight:600; color:var(--brand, #ff5700); text-decoration:underline; cursor:pointer; }

/* Drone footage location + voice over (CapturesTweaks.txt) — the Record step's scan/pick card
   and the repurposed rec panel's playback element. */
.drone-geo { margin-top:12px; padding:10px 12px; border:1px solid #e2ddd4; border-radius:10px; background:#faf8f5; }
.drone-geo-frames { display:flex; gap:10px; margin:8px 0; }
.drone-geo-frames figure { margin:0; min-width:0; flex:1; }
.drone-geo-frames img { width:100%; border-radius:8px; display:block; }
.drone-geo-frames figcaption { text-align:center; margin-top:2px; }
.drone-geo-map { height:260px; border-radius:10px; overflow:hidden; margin-top:6px; }
.drone-geo-map .map-wrap, .drone-geo-map .map-canvas { height:100%; }
.drone-vo-player { display:block; width:100%; max-height:280px; border-radius:10px; background:#000; margin:8px 0; }

/* Processing log (AICapturesStatusLogs.txt) — the review's collapsible per-step panel. */
/* Native <details> accordion (the clickable-h3 toggle didn't expand on iPhone) — the summary
   dresses as the card's h3 with the platform's own disclosure marker doing the chevron's job. */
.plog-acc .plog-sum { cursor:pointer; font-family:var(--font-display); font-weight:700; font-size:17px;
  color:var(--asphalt); }
.plog { margin-top:10px; display:flex; flex-direction:column; gap:2px; }
.plog-row { display:grid; grid-template-columns:minmax(0,1fr) max-content max-content; gap:6px 14px;
            align-items:baseline; padding:5px 8px; border-radius:6px; font-size:13.5px; }
.plog-row:nth-child(odd) { background:rgba(0,0,0,.03); }
.plog-row.err { background:rgba(211,47,47,.08); }
.plog-step { overflow-wrap:anywhere; }
.plog-when, .plog-dur { font-size:12px; color:#6b665e; white-space:nowrap; }
.plog-dur { font-weight:700; }
.plog-errdetail { padding:0 8px 6px; font-size:12.5px; color:#b3261e; overflow-wrap:anywhere; }
.plog-total { border-top:1.5px solid #e2ddd4; margin-top:4px; font-weight:700; }
.plog-total .plog-dur { color:var(--vida-bitumen, #221f20); }
@media (max-width:560px) { .plog-row { grid-template-columns:minmax(0,1fr) max-content; }
  .plog-when { display:none; } }   /* phone: step + duration only — starts stay in the expanded row width */

/* Capture Item Boxes (CaptureItemBox.txt) — numbered rectangles over photos / paused video */
.cib-layer { position: absolute; inset: 0; pointer-events: none; }
.cib-box { position: absolute; border: 2px solid; border-radius: 4px; box-shadow: 0 0 0 1px rgba(0,0,0,.35); }
/* PhotoPolygons.txt — an item with a tight outline draws the POLYGON instead of the rectangle:
   the host box keeps its bbox position (pill shelf + overlap logic unchanged) but hides its own
   ring; the inner SVG stretches over the bbox (preserveAspectRatio none) and the polygon's
   stroke stays a constant screen width via non-scaling-stroke. */
.cib-box.cib-polybox { border-color: transparent; box-shadow: none; }
.cib-polysvg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.cib-polysvg polygon { fill: rgba(255,255,255,.08); stroke-width: 2.5px; vector-effect: non-scaling-stroke;
                       stroke-linejoin: round; filter: drop-shadow(0 0 1px rgba(0,0,0,.5)); }
.cib-pill { position: absolute; top: -10px; left: -2px; min-width: 20px; height: 20px; border-radius: 10px;
            color: #fff; font-size: 12px; font-weight: 700; border: none; opacity: .85;
            pointer-events: auto; cursor: pointer; padding: 0 6px; line-height: 20px; }
.cib-flash { outline: 3px solid var(--brand, #ff5700); outline-offset: 2px; border-radius: 6px; }
/* VideoPlayback.txt — the camera-position marker + the items-at-capture chip row.
   z-index lifts it above every other map marker (photo pins, defect/safety badges sit on the
   same route and buried it); the inner svg is the CAPTURE TYPE's icon, forced white. */
.playhead-dot { width: 28px; height: 28px; border-radius: 50%; background: #7c4dff;
                display: flex; align-items: center; justify-content: center;
                box-shadow: 0 0 0 3px rgba(124,77,255,.4), 0 1px 6px rgba(0,0,0,.35);
                z-index: 1000; border: 2px solid #fff; }
.playhead-dot svg { width: 15px; height: 15px; color: #fff; stroke: #fff; }
/* The FOCAL viewfinder (DroneSrtIngestion) — the projected ground point the camera is looking
   at, joined to the playhead by a dashed violet sight line. Transparent ring (the ground stays
   visible through it), sits just under the playhead in stacking. */
.focal-dot { width: 34px; height: 34px; color: #7c4dff; z-index: 999;
             display: flex; align-items: center; justify-content: center;
             filter: drop-shadow(0 0 2px rgba(255,255,255,.9)) drop-shadow(0 1px 3px rgba(0,0,0,.35)); }
.focal-dot svg { width: 34px; height: 34px; }
/* SLR-style focus reticle over the video player (DroneSrtIngestion) — AF corner brackets +
   crosshair marking the frame centre where the footage's location is perceived. Non-interactive
   (taps fall through to the player); the caption pill sits above the native controls. */
.slr-reticle { position: absolute; inset: 0; pointer-events: none; }
.slr-reticle svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.slr-reticle .ret path { stroke: #fff; stroke-width: 0.7; fill: none; stroke-linecap: round;
                         filter: drop-shadow(0 0 1px rgba(0,0,0,.85)); }
.slr-reticle .ret circle { fill: #fff; stroke: none;
                           filter: drop-shadow(0 0 1px rgba(0,0,0,.85)); }
.slr-cap { position: absolute; bottom: 48px; left: 50%; transform: translateX(-50%);
           background: rgba(34,31,32,.72); color: #fff; font-size: 11px; font-weight: 600;
           padding: 3px 11px; border-radius: 999px; white-space: nowrap; }
.vp-cur-items { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }

/* ── Renewed project layout (RenewedDefuserProjectLayout.txt) ─────────────── */
.psl-wps, .psl-group { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:10px; }
.psl-label { font-weight:600; font-size:.85em; min-width:150px; }
.psl-projname { font-weight:600; }
.psl-chip { padding:5px 12px; border:1px solid #d6d6d6; border-radius:999px; background:#fff; font:inherit;
  font-size:13px; cursor:pointer; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.psl-chip .mono { font-size:11px; opacity:.65; margin-left:4px; }
.psl-chip.sel { border-color:var(--roads-orange,#ff9d14); background:rgba(255,157,20,.12); font-weight:600; }
.psl-chip.dim { opacity:.55; }
.psl-area.nobound { border-style:dashed; }
.psl-contract-head { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.psl-contract-head h3 { margin:0; }
.psl-progpick { width:auto; padding:4px 8px; border:1px solid #d6d6d6; border-radius:7px; font:inherit; font-size:13px; }
.psl-detail h4 { margin:0 0 6px; }
.psl-area-actions { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:8px; }
.psl-map .map-view, .psl-map .mapview { min-height:340px; }

/* WP-workspace layout (WorkPackageManageTeam.txt): contract header → team + areas LEFT with
   the contract's area map RIGHT, then design packages, then contract work packages. */
.psl-cols { display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1fr); gap:14px; align-items:start; }
.psl-col-map { position:sticky; top:70px; }
.psl-sec-head { margin:0 0 6px; font-size:.95rem; }
.psl-detail-inline { margin-top:10px; padding-top:8px; border-top:1px solid rgba(0,0,0,.08); }
.psl-detail-inline h5 { margin:0 0 4px; font-size:.88rem; }
/* Area identity: the colour dot (matches the map polygon) + the boundary-defined pentagon. */
.psl-area-dot { display:inline-block; width:10px; height:10px; border-radius:50%; margin-right:5px; vertical-align:-1px; }
.psl-area-bound { margin-left:5px; font-size:.8em; opacity:.75; }
/* Project-wide area marker (🌐) + the boundary-not-set error (⚠, red so it reads as broken). */
.psl-area-wide { margin-left:5px; font-size:.8em; }
.psl-area-err  { margin-left:5px; font-size:.85em; color:#b3261e; filter:saturate(1.4); }
@media (max-width: 900px) {
    .psl-cols { grid-template-columns:1fr; }
    .psl-col-map { position:static; }
}

/* ── Area boundary editor popup ── */
.bed-overlay { position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:1000; display:flex; align-items:center; justify-content:center; padding:10px; }
/* Near-fullscreen: boundary drawing needs the map real estate — the modal takes the viewport
   (minus a slim rim) and the map stretches to fill whatever the chrome doesn't use. */
.bed-modal { background:#fff; border-radius:14px; width:min(1600px, 97vw); height:94vh; max-height:94vh; display:flex; flex-direction:column; overflow:hidden; }
.bed-head { display:flex; align-items:center; justify-content:space-between; padding:12px 14px 4px; }
.bed-head h3 { margin:0; }
.bed-toolbar { padding:0 14px 8px; }
.bed-map { flex:1; min-height:320px; }   /* stretches — the modal is viewport-height now */
.bed-actions { display:flex; gap:8px; align-items:center; flex-wrap:wrap; padding:10px 14px; border-top:1px solid rgba(0,0,0,.08); }
.bed-spacer { flex:1; }
.bed-io { padding:0 14px 12px; display:flex; flex-direction:column; gap:8px; }
.bed-io-row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.bed-io-row select { width:auto; padding:6px 8px; border:1px solid #d6d6d6; border-radius:7px; font:inherit; font-size:13px; }
.bed-io textarea { width:100%; font-family:ui-monospace, Menlo, Consolas, monospace; font-size:12px;
  border:1px solid #d6d6d6; border-radius:7px; padding:8px; }

/* editor vertex handles (created by map.js editor) */
.ed-vertex { width:14px; height:14px; border-radius:50%; background:#fff; border:3px solid var(--roads-orange,#ff9d14);
  box-shadow:0 1px 4px rgba(0,0,0,.35); cursor:grab; }
.ed-vertex.sel { background:var(--roads-orange,#ff9d14); border-color:#221f20; transform:scale(1.25); }

/* Capture-ready toast (MiscellaneousCaptures.txt) — fixed above the mobile bottom nav so it's
   visible from any page when a server-processed capture finishes. */
.capture-ready-toast {
  position:fixed; left:50%; transform:translateX(-50%); bottom:18px; z-index:1200;
  display:flex; align-items:center; gap:12px; flex-wrap:wrap; max-width:min(92vw, 520px);
  background:var(--vida-bitumen, #221f20); color:#fff; border:1px solid var(--vida-amber, #ff9d14);
  border-radius:12px; padding:10px 14px; box-shadow:0 6px 24px rgba(0,0,0,.35);
}
.capture-ready-toast .crt-msg { flex:1 1 200px; font-size:14px; }
.capture-ready-toast .crt-actions { display:inline-flex; gap:8px; }
.capture-ready-toast .btn-sm { padding:5px 12px; font-size:12.5px; }
/* The ghost button's asphalt text is invisible on the dark toast — restyle for the dark chrome. */
.capture-ready-toast .btn-ghost { color:#fff; border-color:rgba(255,255,255,.5); }
.capture-ready-toast .btn-ghost:hover { color:var(--vida-amber, #ff9d14); border-color:var(--vida-amber, #ff9d14); }
@media (max-width:760px) { .capture-ready-toast { bottom:calc(64px + env(safe-area-inset-bottom, 0px) + 10px); } }

/* Drone virtual ground map (DroneCaptureVirtualMap.txt) — the schematic card + the
   align-to-real-tiles modal. Feature kinds map to vm-* classes. The base vm-* colours below
   serve the ALIGN OVERLAY (drawn over light map tiles); the review card wears the MODERN dark
   variant (.vmap-box.modern overrides further down), whose sizes scale with the --vmk CSS var
   (viewBox dim / 1000 — the compact card auto-crops to the drawn content). */
.vmap-box { background:#f4f1ec; border:1px solid #e2ddd4; border-radius:10px; overflow:hidden; }
.vmap-box svg, .vmap-overlay svg { display:block; width:100%; height:auto; }
.vm-road { stroke:#6b6b6b; stroke-width:26; stroke-linecap:round; stroke-linejoin:round; }
.vm-path { stroke:#9a9184; stroke-width:10; stroke-dasharray:18 14; stroke-linecap:round; }
.vm-building { fill:rgba(74,74,74,.5); stroke:#4a4a4a; stroke-width:4; }
.vm-bridge { stroke:#7c5c9e; stroke-width:22; stroke-linecap:round; }
.vm-water { fill:rgba(74,144,217,.35); stroke:#4a90d9; stroke-width:4; }
.vm-rail { stroke:#333; stroke-width:6; stroke-dasharray:24 12; }
.vm-vegetation { fill:rgba(76,140,74,.3); stroke:#4c8c4a; stroke-width:3; }
.vm-other { stroke:#8a8a8a; stroke-width:8; }
polyline.vm-building, polyline.vm-water, polyline.vm-vegetation { fill:none; }
.vm-cam { stroke:#7b5cd6; stroke-width:6; stroke-dasharray:4 12; stroke-linecap:round; opacity:.9; }
.vm-def circle { fill:var(--vida-amber, #ff9d14); stroke:#221f20; stroke-width:3; }
.vm-def text { fill:#221f20; font-size:24px; font-weight:700; text-anchor:middle; dominant-baseline:central; }
.vm-label { fill:#5a554d; font-size:26px; paint-order:stroke; stroke:#f4f1ec; stroke-width:6; }
/* ── Modern compact card variant (video ∥ map on desktop, stacked on a phone) ── */
.vmap-card .vmap-head { display:flex; gap:10px; align-items:center; cursor:pointer; }
.vmap-card .vmap-head h3 { margin:0; font-size:17px; }
.vmap-chip { font-size:12px; font-weight:700; border-radius:999px; padding:2px 10px; white-space:nowrap; }
.vmap-chip.ok { background:rgba(46,125,50,.12); color:#2e7d32; }
.vmap-chip.warn { background:rgba(255,157,20,.16); color:#b26b00; }
.vmap-duo { display:grid; gap:14px; margin-top:10px; }
@media (min-width:900px) { .vmap-duo { grid-template-columns:minmax(0,1.25fr) minmax(0,1fr); align-items:start; } }
.vmap-video { min-width:0; text-align:center; }
/* The wrapper hugs the video EXACTLY (width/height auto, no object-fit letterboxing) so the
   CaptureBoxOverlay's normalised box coordinates land on the picture, not the blank bars. */
.vmap-vidwrap { position:relative; display:inline-block; max-width:100%; }
.vmap-video video { display:block; max-width:100%; max-height:420px; width:auto; height:auto; border-radius:10px; background:#000; }
/* Info summary under the player — the current capture's items, coloured like their boxes. */
.vmap-items { display:flex; flex-wrap:wrap; gap:6px 14px; margin-top:8px; text-align:left; }
.vmap-item { display:inline-flex; align-items:center; gap:6px; font-size:13px; min-width:0; }
.vmap-item .vi-dot { flex:none; width:18px; height:18px; border-radius:50%; color:#fff; font-size:11px;
  font-weight:700; display:inline-flex; align-items:center; justify-content:center; }
.vmap-item .vi-title { overflow-wrap:anywhere; }
.vmap-pane { min-width:0; }
.vmap-pane .vmap-foot { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:8px; }
.vmap-box.modern { position:relative; border:1px solid rgba(124,77,255,.35); border-radius:12px;
  background:radial-gradient(120% 90% at 20% 0%, #2c2830 0%, var(--vida-bitumen, #221f20) 55%); }
.vmap-box.modern svg { max-height:420px; }
.vmap-box.modern .vm-grid { stroke:rgba(255,255,255,.06); stroke-width:calc(2px * var(--vmk, 1)); }
.vmap-box.modern .vm-road-case { stroke:#141214; stroke-width:calc(34px * var(--vmk, 1)); stroke-linecap:round; stroke-linejoin:round; }
.vmap-box.modern .vm-road { stroke:#5c5a60; stroke-width:calc(24px * var(--vmk, 1)); }
.vmap-box.modern .vm-path { stroke:#8d857a; stroke-width:calc(9px * var(--vmk, 1)); stroke-dasharray:calc(16px * var(--vmk, 1)) calc(13px * var(--vmk, 1)); }
.vmap-box.modern .vm-building { fill:rgba(255,255,255,.07); stroke:rgba(255,255,255,.35); stroke-width:calc(4px * var(--vmk, 1)); }
.vmap-box.modern .vm-bridge { stroke:#7b6f92; stroke-width:calc(20px * var(--vmk, 1)); }
.vmap-box.modern .vm-water { fill:rgba(74,144,217,.22); stroke:#5b93d8; stroke-width:calc(4px * var(--vmk, 1)); }
.vmap-box.modern .vm-rail { stroke:#a9a4ab; stroke-width:calc(6px * var(--vmk, 1)); stroke-dasharray:calc(22px * var(--vmk, 1)) calc(12px * var(--vmk, 1)); }
.vmap-box.modern .vm-vegetation { fill:rgba(96,160,90,.18); stroke:rgba(120,180,110,.5); stroke-width:calc(3px * var(--vmk, 1)); }
.vmap-box.modern .vm-other { stroke:rgba(255,255,255,.3); stroke-width:calc(7px * var(--vmk, 1)); }
.vmap-box.modern .vm-label { fill:#c9c4bc; stroke:var(--vida-bitumen, #221f20); stroke-width:calc(6px * var(--vmk, 1)); font-size:calc(24px * var(--vmk, 1)); }
.vmap-box.modern .vm-cam { stroke:rgba(157,107,255,.4); stroke-width:calc(6px * var(--vmk, 1)); stroke-dasharray:calc(4px * var(--vmk, 1)) calc(12px * var(--vmk, 1)); }
.vmap-box.modern .vm-cam-done { stroke:var(--ai-violet, #7c4dff); stroke-width:calc(7px * var(--vmk, 1)); stroke-linecap:round; stroke-linejoin:round;
  filter:drop-shadow(0 0 calc(6px * var(--vmk, 1)) rgba(124,77,255,.6)); }
.vmap-box.modern .vm-def circle { stroke:#141214; stroke-width:calc(3px * var(--vmk, 1)); }
.vmap-box.modern .vm-def text { font-size:calc(22px * var(--vmk, 1)); }
/* Safety items on the virtual map (CapturesTweaks.txt follow-up) — muted-teal DIAMONDS,
   distinct from the amber defect dots without shouting; numbers continue the defects'
   sequence (match the box pills). */
.vmap-box .vm-safety rect, .vmap-overlay .vm-safety rect { fill:#4db6ac; stroke:#141214; stroke-width:calc(3px * var(--vmk, 1)); }
.vmap-box .vm-safety text, .vmap-overlay .vm-safety text { fill:#141214; font-size:calc(20px * var(--vmk, 1)); font-weight:700;
  text-anchor:middle; dominant-baseline:central; }
/* The review cards' item-number chip — styled like the details page's numbering (.wm-def-n):
   a 20px AI-violet circle with the white digit, inline with the title row. SAFETY items wear
   their virtual-map identity instead: a muted-teal DIAMOND with a dark digit — the same shape
   and colour as their marker on the schematic, on every capture review surface. */
.item-no { width:20px; height:20px; border-radius:50%; background:var(--ai-violet, #7c4dff); color:#fff;
  font-size:11px; font-weight:700; display:inline-flex; align-items:center; justify-content:center;
  flex:0 0 auto; align-self:center; }
.item-no.safety { width:22px; height:22px; border-radius:0; background:#4db6ac; color:#141214;
  clip-path:polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.vm-pos-cross { stroke:rgba(157,107,255,.28); stroke-width:calc(2.5px * var(--vmk, 1)); }
.vm-pos-dot { fill:var(--ai-violet-2, #9d6bff); stroke:#fff; stroke-width:calc(3px * var(--vmk, 1)); }
.vm-pos-ring { fill:none; stroke:var(--ai-violet-2, #9d6bff); stroke-width:calc(4px * var(--vmk, 1)); opacity:.8; }
.vm-pos.playing .vm-pos-ring { transform-box:fill-box; transform-origin:center; animation:vm-pulse 1.5s ease-out infinite; }
@keyframes vm-pulse { 0% { transform:scale(.55); opacity:.9; } 100% { transform:scale(1.5); opacity:0; } }
.vmap-time { position:absolute; right:8px; top:8px; background:rgba(20,18,20,.75); color:#e8e4dd;
  font-size:12px; border:1px solid rgba(124,77,255,.4); border-radius:999px; padding:2px 10px; }

.vmap-align-modal { position:fixed; inset:0; z-index:1100; background:var(--vida-bitumen, #221f20); display:flex; flex-direction:column; }
.vmap-align-head { display:flex; gap:10px; align-items:center; flex-wrap:wrap; padding:10px 14px; color:#fff; }
.vmap-align-head .muted { color:#c9c4bc; }
.vmap-align-body { position:relative; flex:1; min-height:0; }
.vmap-align-body .map-wrap { position:absolute; inset:0; height:100%; }
.vmap-align-body .map-canvas { height:100%; }
.vmap-overlay { position:absolute; left:50%; top:50%; pointer-events:none; opacity:.62;
  filter:drop-shadow(0 0 5px rgba(0,0,0,.55)); }
.vmap-align-ctl { display:flex; gap:20px; align-items:center; flex-wrap:wrap; padding:10px 14px; color:#fff; }
.vmap-align-ctl label { display:inline-flex; gap:8px; align-items:center; font-size:13.5px; }
.vmap-align-ctl input[type=range] { width:min(200px, 40vw); }

/* ── Workflow progress strip (Workflows.txt) — the defect detail's read-only step list ─────── */
.wfp-card { padding: 12px 14px; }
.wfp-head { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }
.wfp-title { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-dim, #6b7280); }
.wfp-badge { display: inline-flex; align-items: center; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 700; }
.wfp-badge.live { background: #fff1d6; color: #8a5a00; }
.wfp-badge.done { background: #dff5e1; color: #1f6b2c; }
.wfp-badge.fault { background: #fee2e2; color: #991b1b; }
.wfp-badge.test { background: #eceef1; color: #4b5563; }
.wfp-strip { display: flex; gap: 6px; flex-wrap: wrap; }
.wfp-step { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px;
  font-size: 12px; background: #eceef1; color: #4b5563; }
.wfp-dot { width: 8px; height: 8px; border-radius: 50%; background: #9aa1ab; flex: none; }
.wfp-step.done { background: #dff5e1; color: #1f6b2c; }
.wfp-step.done .wfp-dot { background: #1f6b2c; }
.wfp-step.current { background: #fff1d6; color: #8a5a00; font-weight: 700; }
.wfp-step.current .wfp-dot { background: #ff9d14; }

/* Capture-type icon beside the review/details page titles (shared CaptureKindMeta glyphs) —
   sits at the RIGHT of the title line (flex h1, icon pushed to the row's end). */
.cap-kind-h1 { display: flex; align-items: center; gap: 10px; }
.cap-kind-ic { display: inline-flex; width: 26px; height: 26px; color: var(--ai-violet, #7c4dff); flex: 0 0 auto; }
.cap-kind-ic.right { margin-left: auto; }
.cap-kind-ic svg { width: 100%; height: 100%; display: block; }

/* ── Work-package team panel (WorkPackageManageTeam.txt — Components/WpTeamPanel.razor):
   appears under a SELECTED work package on a My Projects tile. Self-contained styling so the
   panel works on any page (page-scoped team styles don't reach it). ── */
.wp-team-panel { margin: 6px 0 2px; padding: 8px 10px; border: 1px solid rgba(0,0,0,.1);
    border-radius: 8px; background: #fff; cursor: default; }
.wp-panel-error { color: #b3261e; font-size: .85rem; margin: 4px 0; }
.wp-panel-list { list-style: none; margin: 0; padding: 0; }
.wp-panel-list li { display: grid; grid-template-columns: fit-content(200px) minmax(0,1fr) auto;
    gap: 8px; align-items: center; padding: 5px 0; border-top: 1px solid rgba(0,0,0,.06); }
.wp-panel-list li:first-child { border-top: 0; }
.wp-panel-who { font-size: .85rem; font-weight: 600; overflow-wrap: anywhere; }
.wp-panel-company { display: block; font-size: .75rem; font-weight: 400; color: #777; }
.wp-panel-pills { display: flex; flex-wrap: wrap; gap: 4px; }
.wp-panel-pills .role-chip { display: inline-flex; align-items: center; gap: 3px; }
.wp-panel-pills .chip-x { background: transparent; border: none; padding: 0 0 0 1px; margin: 0;
    cursor: pointer; color: inherit; font-size: 14px; line-height: 1; opacity: .6; }
.wp-panel-remove { white-space: nowrap; }
.wp-panel-add { display: grid; grid-template-columns: minmax(0,2.6fr) minmax(0,1fr) auto;
    gap: 8px; align-items: center; margin-top: 8px; }
/* 20260917 — the type-to-filter pickers take the widest column (a "● Name — Company" label needs
   the room), fill it edge to edge (never wider — the row wraps to one column on a phone) and
   ellipsise what still doesn't fit. */
.wp-panel-add .wp-pick { min-width: 0; width: 100%; box-sizing: border-box; padding: 8px 10px; border: 1px solid #d6d6d6;
    border-radius: 7px; font-size: 16px; text-overflow: ellipsis; }   /* 16px = no iOS focus zoom */
.wp-panel-add select { padding: 8px 10px; border: 1px solid #d6d6d6; border-radius: 7px;
    font-size: 16px; min-width: 0; width: 100%; }   /* 16px = no iOS focus zoom */
.wp-team-panel .reg-ico { font-weight: 700; margin-right: 4px; cursor: help; }
.wp-team-panel .reg-ico.reg   { color: #4ebfa5; }
.wp-team-panel .reg-ico.self  { color: #2471b5; }
.wp-team-panel .reg-ico.unreg { color: var(--roads-orange, #ff9d14); }
.wp-team-panel .badge.wp-pill-cat  { background: #e3edf8; color: #1d5a96; }
.wp-team-panel .badge.wp-pill-disc { background: #e9f6f1; color: #1f6b5c; }
.wp-team-panel .wp-pill-disc-toggle { cursor: pointer; user-select: none; }
@media (max-width: 640px) {
    .wp-panel-list li { grid-template-columns: minmax(0,1fr) auto; }
    .wp-panel-list li .wp-panel-pills { grid-column: 1 / -1; }
    .wp-panel-add { grid-template-columns: 1fr; }
}

/* ── DGN drawings (DgnDrawings.txt) — register / overlay / asset picker ─────── */
.dgn-upload-row { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.dgn-upload-row select { font-size:16px; }
.dgn-map-toolbar { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-bottom:8px; }
.dgn-map-toolbar select { font-size:16px; max-width:100%; }
/* Multiple Drawings — the drawing on/off tree above the map + the reactive type search. */
.dgn-tree { display:flex; flex-direction:column; gap:4px; margin-bottom:8px; }
.dgn-tree-set { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.dgn-tree-child { opacity:.85; }
.dgn-type-search { font-size:16px; min-width:200px; padding:4px 8px; border:1px solid #d0d0d0; border-radius:8px; }
/* Type drill-down ("what are these?") + map isolate/level-filter chips. */
.dgn-bd-row > td { background:#faf8f4; padding:10px 12px; }
.dgn-bd-table { margin:0; }
.dgn-legend-chip.on { outline:2px solid var(--vida-amber, #ff9d14); border-radius:8px; }
.dgn-level-chip { background:#f3eee6; border-radius:8px; padding:2px 8px; }
.dgn-chip-x { border:none; background:none; cursor:pointer; font-size:12px; padding:0 2px; }
/* Asset elements (AssetsElements.txt) — selection action bar + grouped asset view. */
.dgn-sel-bar { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:8px 0;
    padding:8px 10px; background:#fff7ea; border:1px solid var(--vida-amber, #ff9d14); border-radius:10px; }
.dgn-sel-bar select { font-size:16px; max-width:280px; }
.dgn-asset-group { border-top:1px solid #eee7db; padding:6px 0; }
.dgn-asset-head { display:flex; justify-content:space-between; align-items:center; }
.dgn-unassigned-group { margin:6px 0; }
.psl-card-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:6px; }
.wp-struct-group { margin:4px 0 6px; }
/* the per-member "+ role…" picker in the editable team panel — sizes to its options, not the global 100% */
.wp-panel-pills .role-add { width:auto; min-width:0; font-size:12px; padding:2px 6px; border-radius:999px; border:1px dashed #9a9a9a; background:#fff; color:#2471b5; cursor:pointer; }
.wp-struct-head { font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:#5a5b5d; margin:6px 0 2px; }
.wp-team-modal .wp-team-panel { border:none; padding:0; margin:0; }
/* Drawing import wizard + element inventory (DrawingImportWizard.txt) */
.diw-steps { display:flex; gap:6px; flex-wrap:wrap; margin:0 0 12px; padding:0; list-style:none; }
.diw-steps li { display:flex; align-items:center; gap:6px; font-size:13px; padding:4px 10px; border-radius:999px; background:#f1ede4; color:#5a5b5d; }
.diw-steps li.active { background:#221f20; color:#fff; }
.diw-steps li.done { background:#e6f6ee; color:#1f6b2c; }
.diw-steps .n { display:inline-flex; width:18px; height:18px; border-radius:50%; align-items:center; justify-content:center; font-size:11px; font-weight:700; background:rgba(0,0,0,.12); }
.diw-src { display:grid; grid-template-columns:repeat(auto-fill, minmax(220px,1fr)); gap:10px; }
.diw-src button { text-align:left; padding:14px; border:1px solid #eee7db; border-radius:12px; background:#fff; cursor:pointer; }
.diw-src button.sel { border-color:var(--defuse-orange,#ff5700); box-shadow:0 0 0 2px rgba(255,87,0,.15); }
.diw-rules { display:flex; gap:8px; flex-wrap:wrap; margin:8px 0; }
.diw-rules button { padding:6px 10px; border-radius:999px; border:1px solid #cfc7ba; background:#fff; cursor:pointer; font-size:13px; }
.diw-rules button.sel { background:#221f20; color:#fff; border-color:#221f20; }
.diw-rules .muted { font-size:11px; }
.diw-actions { display:flex; gap:8px; flex-wrap:wrap; justify-content:space-between; margin-top:12px; }
.diw-split { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:12px; align-items:start; }
@media (max-width:900px) { .diw-split { grid-template-columns:1fr; } }
/* The list pane scrolls VERTICALLY inside its own box and never wider than its column — the
   map beside it stays sticky so it is always in view while the rows scroll. */
.diw-list { max-height:calc(100vh - 180px); overflow-y:auto; overflow-x:hidden; min-width:0;
    scrollbar-gutter:stable; }   /* reserve the scrollbar's width so it never eats the table */
.diw-list .table-wrap { overflow-x:hidden; border:none; }
.diw-list table.data-table { table-layout:fixed; width:100%; font-size:13px; }
.diw-list .data-table th, .diw-list .data-table td { padding:6px 8px; overflow-wrap:anywhere; white-space:normal; }
.diw-list .data-table th { white-space:normal; }
.diw-list .diw-acts { display:flex; flex-wrap:nowrap; gap:3px; white-space:nowrap; min-width:0; }
.diw-list .diw-acts .btn { padding:2px 6px; font-size:11px; flex:0 1 auto; min-width:0;
    overflow:hidden; text-overflow:ellipsis; }   /* shrink before ever spilling out of the column */
.diw-list .dgn-bd-table td, .diw-list .dgn-bd-table th { padding:4px 6px; font-size:12px; }
.diw-map { height:min(72vh, 640px); min-height:360px; position:sticky; top:12px; min-width:0;
    display:flex; flex-direction:column; }
.diw-map .map-wrap { flex:1; min-height:0; height:100%; }
.diw-map .map-canvas { height:100%; min-height:0; }   /* the base .map-canvas is a fixed 440px */
@media (max-width:900px) { .diw-map { position:static; height:420px; } .diw-list { max-height:none; } }
/* 3D BIM models page: the Element collections pane bottom-aligns with the map beside it —
   the same height formula as .diw-map, scrolling inside. */
.diw-list.bim-el-list { max-height:min(72vh, 640px); }
@media (max-width:900px) { .diw-list.bim-el-list { max-height:none; } }
.diw-swatch { display:inline-block; width:14px; height:14px; border-radius:3px; vertical-align:middle; margin-right:6px; border:1px solid rgba(0,0,0,.15); }
.inv-tree details { margin:2px 0; }
.inv-tree summary { cursor:pointer; padding:4px 6px; border-radius:8px; }
.inv-tree summary:hover { background:#f6f1e7; }
.inv-row { display:flex; align-items:center; gap:8px; padding:3px 6px 3px 26px; border-radius:8px; cursor:pointer; }
/* In-tree element list under the selected type (DrawingInventory) */
.inv-elts { margin:2px 4px 8px 34px; border-left:2px solid rgba(0,0,0,.1); padding-left:8px; max-height:320px; overflow-y:auto; }
.inv-elhead { display:flex; align-items:center; justify-content:space-between; gap:8px; padding:2px 4px; }
.inv-el { display:flex; align-items:center; gap:8px; padding:2px 6px; border-radius:6px; cursor:pointer; font-size:12px; min-width:0; }
.inv-el:hover { background:#f6f1e7; }
.inv-el .mono { white-space:nowrap; }
.inv-el .muted { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
/* Tri-state tree selection: the PARTIAL box (some children selected) */
.tri-box { display:inline-block; width:13px; height:13px; border:1.5px solid #8a8378; border-radius:3px;
  position:relative; cursor:pointer; vertical-align:-2px; background:#fff; flex-shrink:0; }
.tri-box.some { border-color:#2471b5; }
.tri-box.some::after { content:""; position:absolute; left:2px; right:2px; top:4px; height:3px;
  background:#2471b5; border-radius:1px; }
.inv-row:hover, .inv-row.sel { background:#fff3e0; }
/* Designs Register — selected document rows (multi-select scope) */
.data-table tr.dsr-sel td { background:#fff7ea; }
.data-table tr.dsr-sel td:first-child { box-shadow:inset 3px 0 0 var(--defuse-orange,#ff5700); }
.dsr-scope { padding:6px 8px; border-radius:8px; background:#fff7ea; border:1px solid rgba(255,87,0,.35); }
.data-table tr.dsr-importing td { background:#fff7ea; border-left:none; }
/* Designs Register — "Show in tree" flashes the located row */
.dsr-flash { animation: dsr-flash-pulse .8s ease-in-out 3; }
/* Elements Register — the DOCUMENT multi-select dropdown above the tree. The panel anchors
   to the FULL-WIDTH header row (its nearest positioned ancestor), never the narrow button —
   and its width is viewport-capped so the left edge always stays on screen. */
.dsr-docsel-panel { position:absolute; top:calc(100% + 4px); right:0; z-index:40;
  width:min(380px, calc(100vw - 48px));
  max-height:320px; overflow:auto; background:#fff; border:1px solid #ddd3c4; border-radius:8px;
  box-shadow:0 8px 24px rgba(34,31,32,.18); padding:8px 10px; }
.dsr-docsel-row { display:flex; gap:6px; align-items:center; padding:2px 0; cursor:pointer; white-space:nowrap; }
.dsr-docsel-row span:last-child { overflow:hidden; text-overflow:ellipsis; }
/* While the dropdown is OPEN the tree card must be tall enough for it — the card is a
   scroll container, so a short (e.g. none-selected) tree would clip the panel's bottom. */
.diw-list.dsr-docsel-hold { min-height:420px; }
/* Elements Register tree — the alignment warning flag (bubbles up every branch level). */
.dsr-warn { color:#a05a00; font-size:12px; cursor:help; margin-left:2px; }
/* Asset builder (/asset-builder) — a selected item that is currently on ANOTHER asset
   (saving moves it — the warning styling the spec asks for). */
.ab-warn { background:#fdf0e0; border-radius:6px; outline:1px solid #f0c489; }
/* WP drawing exclusions (/wp-drawing-exclusions) — the category / asset-type pickers */
.wpx-cols { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:16px; }
@media (max-width:760px) { .wpx-cols { grid-template-columns:1fr; } }
.wpx-list { max-height:420px; overflow-y:auto; border:1px solid #e8e0d2; border-radius:8px; padding:6px 8px; }
.wpx-row { display:flex; gap:8px; align-items:center; padding:3px 4px; border-radius:6px; cursor:pointer; font-size:13px; }
.wpx-row:hover { background:#f6f1e7; }
.wpx-row.on { background:#fdf0e0; }
.wpx-row .cnt { margin-left:auto; color:#8a8377; font-size:12px; }
.wpx-row span .muted { margin-left:6px; }
@keyframes dsr-flash-pulse { 0%,100% { background:transparent; } 50% { background:rgba(255,87,0,.35); } }
/* Designs Register — the import panel's indeterminate progress bar */
.dsr-prog { height:8px; border-radius:4px; background:#eee5d8; overflow:hidden; position:relative; margin:10px 0 6px; }
.dsr-prog-bar { position:absolute; top:0; bottom:0; width:35%; border-radius:4px;
  background:var(--defuse-orange,#ff5700); animation:dsr-prog-slide 1.4s ease-in-out infinite; }
@keyframes dsr-prog-slide { 0% { left:-35%; } 100% { left:100%; } }
.inv-row .cnt { margin-left:auto; font-size:12px; color:#5a5b5d; white-space:nowrap; }
.inv-colour { width:28px; height:22px; padding:0; border:1px solid #cfc7ba; border-radius:6px; background:none; cursor:pointer; }
.diw-pick { display:grid; grid-template-columns:repeat(auto-fill, minmax(200px,1fr)); gap:8px; }
/* Asset classifications (AssetClassifications.txt) */
.acl-table td, .acl-table th { padding:5px 8px; }
.acl-table input[type=text] { font-size:14px; padding:4px 6px; width:100%; min-width:0; }
.acl-group { font-weight:700; background:#f6f1e7; }
.inv-chipbar { display:flex; gap:6px; flex-wrap:wrap; margin:6px 0; }
.inv-chip { padding:3px 9px; border-radius:999px; border:1px solid #cfc7ba; background:#fff; font-size:12px; cursor:pointer; display:inline-flex; gap:6px; align-items:center; }
.inv-chip.on { background:#221f20; color:#fff; border-color:#221f20; }
.inv-map-bar { display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin:6px 0; }
/* Work package configuration page (WorkPackageConfig.txt) — tile layout */
.wpc-sec { margin:14px 0 8px; font-size:15px; }
/* Accordion groupings on the configuration page */
.wpc-acc { margin:0; }
.wpc-acc > summary.wpc-sec { cursor:pointer; list-style:none; display:flex; align-items:center; gap:7px; font-weight:600; user-select:none; }
.wpc-acc > summary.wpc-sec::-webkit-details-marker { display:none; }
.wpc-acc > summary.wpc-sec::before { content:"▸"; font-size:11px; color:#8a8378; transition:transform .15s ease; }
.wpc-acc[open] > summary.wpc-sec::before { transform:rotate(90deg); }
.wpc-acc > .wpc-grid { margin-bottom:4px; }
.wpc-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:10px; }
.wpc-tile { display:flex; flex-direction:column; gap:6px; padding:12px 14px; border:1px solid #eee7db; border-radius:12px; background:#fff; color:inherit; text-decoration:none; min-height:118px; }
a.wpc-tile:hover { border-color:var(--defuse-orange, #ff5700); }
.wpc-tile.done { border-left:4px solid #1f6b2c; }
.wpc-tile.todo { border-left:4px solid #ff9d14; }
.wpc-tile.na, .wpc-tile.info { border-left:4px solid #cfc7ba; }
.wpc-tile.on { border-left:4px solid #1f6b2c; }
.wpc-tile.off { border-left:4px solid #9a9a9a; opacity:.85; }
.wpc-title { font-weight:700; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.wpc-desc { font-size:13px; color:#5a5b5d; flex:1; }
.wpc-status { font-size:13px; font-weight:600; color:#2471b5; }
.wpc-pill { font-size:11px; font-weight:700; padding:1px 8px; border-radius:999px; background:#e6f6ee; color:#1f6b2c; }
.wpc-pill.off { background:#f1ede4; color:#5a5b5d; }
.wpc-pill.warn { background:#fdf1dc; color:#8a5b00; }
/* 20260912 — the tri-state feature mode: Configure (amber) sits between Off and Active. */
.wpc-pill.cfg { background:#fdf1dc; color:#8a5b00; }
.wpc-tile.cfg { border-left:3px solid #e8a33d; }
/* DefuserRefinements20260913 — the three mode buttons stay on ONE row (the third dropped
   under); each shares the width and never wraps its label. */
.wpc-mode { display:flex; gap:6px; flex-wrap:nowrap; }
.wpc-mode .btn { flex:1 1 0; min-width:0; padding:0 8px; height:30px; font-size:12px; white-space:nowrap;
  display:inline-flex; align-items:center; justify-content:center; }
/* The setup status panel at the top of the config page (wizard button + step chips). */
.wsw-panel { padding:10px 14px; }
.wsw-panel-head { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
.wsw-panel .wsw-chips { margin-bottom:0; }
a.wsw-chip { text-decoration:none; color:inherit; display:inline-flex; align-items:center; gap:4px; }
/* "Back to setup — step n" bar (MainLayout, from the wizard=<n> query). */
.wiz-return { padding:8px 16px 0; }
/* 20260912 — the work-package SETUP WIZARD (/wp-setup): step chips + per-step feature rows. */
.wsw-chips { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:12px; }
.wsw-chip { border:1px solid rgba(0,0,0,.18); background:#fff; border-radius:999px; padding:6px 12px;
  font-size:13px; font-weight:600; cursor:pointer; color:#221f20; }
.wsw-chip.cur { border-color:var(--services-orange,#ff9d14); box-shadow:inset 0 0 0 1px var(--services-orange,#ff9d14); }
.wsw-chip.done { background:#e6f6ee; color:#1f6b2c; border-color:rgba(31,107,44,.35); }
.wsw-feat { margin:10px 0; padding:8px 10px; border:1px solid rgba(0,0,0,.1); border-radius:8px; }
.wpc-cnt { display:inline-flex; align-items:center; gap:4px; font-size:12px; font-weight:600;
  padding:1px 8px; border-radius:999px; background:#f1ede4; color:#221f20; white-space:nowrap; flex-shrink:0; }
.wpc-switch { display:flex; align-items:center; gap:8px; cursor:pointer; font-weight:500; color:#221f20; }
.psl-config-card { display:flex; align-items:center; justify-content:space-between; gap:10px; text-decoration:none; color:inherit; }
.psl-config-card:hover { border-color:var(--defuse-orange, #ff5700); }
/* Work package setup checklist (WorkPackageSetup.txt) */
.wps-head { display:flex; align-items:center; gap:10px; }
.wps-progress { margin-left:auto; font-size:12px; font-weight:600; padding:2px 10px; border-radius:999px; background:#fff3e0; color:#8a5a00; }
.wps-progress.ready { background:#e6f6ee; color:#1f6b2c; }
.wps-toggle { padding:0 6px; }
.wps-steps { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px; }
.wps-step { display:grid; grid-template-columns:28px minmax(0,1fr) auto; gap:8px; align-items:start; padding:8px 10px; border:1px solid #eee7db; border-radius:10px; background:#fff; }
.wps-step.done { border-color:#cfe9d9; background:#f4fbf6; }
.wps-step.na, .wps-step.optional { opacity:.8; }
.wps-mark { display:inline-flex; width:24px; height:24px; border-radius:50%; align-items:center; justify-content:center; font-weight:700; background:#f1ede4; color:#5a5b5d; }
.wps-step.done .wps-mark { background:#1f6b2c; color:#fff; }
.wps-title { display:flex; flex-wrap:wrap; gap:4px; align-items:baseline; }
.wps-detail { color:#2471b5; margin-top:2px; }
.wps-actions { display:flex; gap:6px; align-items:center; flex-wrap:wrap; justify-content:flex-end; }
@media (max-width:640px) { .wps-step { grid-template-columns:28px minmax(0,1fr); } .wps-actions { grid-column:2; justify-content:flex-start; } }
/* Area grouping in the DGN register (drawings grouped by contract area) */
.dgn-area-head td { background:#f6f1e7; font-size:13px; padding:6px 10px; }
.dgn-area-sel { font-size:14px; max-width:200px; }
/* Element exclusions (ElementExclusions.txt) — ghosted rows + popup action buttons. */
.dgn-el-excluded { opacity:.45; }
.dgn-pop-acts { display:flex; gap:6px; margin-top:8px; flex-wrap:wrap; }
.dgn-pop-acts button { font-size:12px; padding:3px 8px; border-radius:8px; border:1px solid #d0d0d0; background:#fff; cursor:pointer; }
/* 20260915.1 — the design overlay picker (top-right of every map that offers designs). */
.map-design-pick { font-size:12px; max-width:min(52vw, 260px);   /* sits in the top-right stack beside the zoom (MapConsistency.txt) */
    padding:4px 8px; border-radius:14px; border:1px solid #d0d0d0; background:#fff; color:#222; }
/* Google basemap switch (GoogleMapsBasemap) — bottom-left, in the SAME slot as .map-status
   (they render mutually exclusively now; bottom:26px used to half-overlap the status pill). */
/* MapScale (2026-10-05) — the small scale bar on every map: bottom-left, sitting just ABOVE the basemap / map-status
   button that owns that corner; small type, translucent so it never hides the map. */
.maplibregl-ctrl-bottom-left .maplibregl-ctrl-scale { margin:0 0 46px 10px; padding:0 4px; font-size:10px; line-height:14px;
  color:#221f20; background:rgba(255,255,255,.75); border-color:#221f20; border-width:0 1.5px 1.5px; pointer-events:none; }
.map-basemap-btn { position:absolute; left:10px; bottom:10px; z-index:5; font-size:12px;
    padding:4px 10px; border-radius:14px; border:1px solid #d0d0d0; background:#fff;
    box-shadow:0 1px 4px rgba(0,0,0,.18); cursor:pointer; }
/* Boundary-from-drawing picker — selectable outlines (left) + preview map (right). */
.dgn-pick-modal { width:min(94vw, 900px); }
.dgn-pick-split { display:grid; grid-template-columns:minmax(0,1fr) minmax(280px, 400px); gap:14px; align-items:start; }
.dgn-pick-row { display:flex; align-items:center; justify-content:space-between; gap:8px;
    margin:4px 0 0 12px; padding:6px 10px; border:1px solid #e2ddd4; border-radius:8px; cursor:pointer; }
.dgn-pick-row.sel { border-color:var(--vida-amber, #ff9d14); background:#fff7ea; }
.dgn-pick-map .map-wrap, .dgn-pick-map .map-canvas { height:320px; }
@media (max-width: 900px) {
    .dgn-pick-split { grid-template-columns:1fr; }
}
.dgn-disc-chip { display:inline-flex; gap:5px; align-items:center; font-size:13px; cursor:pointer;
  padding:2px 8px; border:1px solid rgba(0,0,0,.12); border-radius:999px; }
.dgn-map { height:min(62vh, 640px); border-radius:8px; overflow:hidden; }
.dgn-map .map-wrap, .dgn-map .map-canvas { height:100%; }
/* The asset picker: list ∥ sticky mini-map on desktop; the map stacks on phones. */
.dgn-assets-split { display:grid; grid-template-columns: minmax(0,1fr) 340px; gap:14px; align-items:start; }
.dgn-el-list { max-height:60vh; overflow:auto; border:1px solid rgba(0,0,0,.08); border-radius:8px; }
.dgn-el-row { display:flex; justify-content:space-between; align-items:center; gap:10px;
  padding:8px 10px; border-bottom:1px solid rgba(0,0,0,.06); }
.dgn-el-row:hover { background:rgba(36,113,181,.06); }
.dgn-el-row.added { background:rgba(78,191,165,.10); }
/* Desktop-only: the mini-map stays in view while the element list scrolls. */
.dgn-mini-map { position:sticky; top:86px; }
.dgn-mini-map .map-wrap { height:300px; border-radius:8px; overflow:hidden; }
.dgn-mini-map .map-canvas { height:100%; }
@media (max-width: 900px) {
  .dgn-assets-split { grid-template-columns: 1fr; }
  .dgn-mini-map { position:static; }
}

/* DGN overlay legend — one chip per element type in its map colour. */
.dgn-legend { display:flex; gap:6px; flex-wrap:wrap; margin:0 0 8px; max-height:96px; overflow:auto; }
.dgn-legend-chip { display:inline-flex; gap:5px; align-items:center; font-size:12.5px;
  padding:2px 8px; border:1px solid rgba(0,0,0,.10); border-radius:999px; white-space:nowrap; }
.dgn-legend-dot { width:10px; height:10px; border-radius:50%; flex:0 0 10px; }

/* ── 3D BIM combined scene (3dBIMmodels.txt) — hovering an element badge highlights its
     element in the viewer (the ring mirrors the canvas-side amber emphasis); tapping it
     toggles the element on/off in the scene. ── */
.bim-scene-badge { cursor: pointer; transition: box-shadow .12s ease, opacity .12s ease; user-select: none;
    border: 1px solid rgba(0, 0, 0, .22); }   /* keeps near-white element colours visible on the card */
.bim-scene-badge:hover { box-shadow: 0 0 0 2px #ff9d14; }
.bim-scene-badge.off { opacity: .35; text-decoration: line-through; }
.bim-scene-badge.picked { box-shadow: 0 0 0 2px #221f20; }   /* the badge whose details are open */
/* The eye inside a badge shows/hides the element (the badge itself opens the details). */
.bim-scene-badge .bsb-eye { margin-left: 5px; cursor: pointer; opacity: .85; }
.bim-scene-badge .bsb-eye:hover { opacity: 1; text-shadow: 0 0 3px rgba(255, 157, 20, .9); }
.bim-scene-badge.off .bsb-eye { text-decoration: none; display: inline-block; }
/* The map's 🧊 pill — reveals the positions 3D view under the map. */
.bim-3d-btn {
    position: absolute; top: 10px; right: 10px; z-index: 5;
    padding: 6px 12px; border-radius: 999px; border: none; cursor: pointer;
    background: rgba(34, 31, 32, .82); color: #fff; font-size: 13px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}
.bim-3d-btn:hover { background: rgba(34, 31, 32, .95); }
.bim-3d-btn.on { background: #ff9d14; color: #221f20; }
/* Assembly save bar under the combined 3D view — allocate the picked elements to an assembly. */
.asm-savebar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px;
    padding-top: 8px; border-top: 1px solid rgba(0, 0, 0, .08); }

/* AssetQuickDetails — the condensed asset map popup + the reusable asset details modal. */
.ap-head { font-weight:600; font-size:12px; color:#5a5b5d; margin:0 0 4px; }
.ap-row { padding:3px 0; font-size:13px; border-top:1px solid rgba(0,0,0,.06); }
.ap-row:first-of-type { border-top:none; }
.btn-map-open { display:inline-block; margin-left:8px; padding:1px 8px; font-size:11px; border-radius:999px;
  border:1px solid #2471b5; background:#fff; color:#2471b5; cursor:pointer; }
.btn-map-open:hover { background:#2471b5; color:#fff; }
.ap-close { position:absolute; top:4px; right:6px; border:none; background:transparent; cursor:pointer;
  font-size:13px; color:#5a5b5d; }
/* Self-contained modal chrome — .bed-modal-backdrop is a DLM class with NO styles in this
   app (pages that use the name style it inline), so relying on it rendered the modal as an
   unstyled block at the page bottom. z-index clears the fixed contextual map (20) + masthead. */
/* The backdrop is the LAST-RESORT scroller: margin:auto centring keeps the modal's top edge
   reachable when it overflows (align-items:center would cut it off above the viewport,
   unreachable), so the header can never be lost whatever the device viewport does. */
.adm-backdrop { position:fixed; inset:0; background:rgba(0,20,28,.55); z-index:1300;
  display:flex; justify-content:center; padding:14px; overflow-y:auto; -webkit-overflow-scrolling:touch; }
/* Height caps use dvh (the VISIBLE viewport) with a conservative vh fallback — 92vh of the
   LAYOUT viewport overflows the visual one on phones (iOS URL bar) and pushed the header
   off the top; the header is shrink-proof so it can never be squeezed out. */
.adm-modal { background:#fff; border-radius:14px; width:min(760px, 96vw); margin:auto;
  max-height:86vh; max-height:calc(100dvh - 28px);
  display:flex; flex-direction:column; box-shadow:0 18px 60px rgba(0,0,0,.35); }
@media (max-width:600px) { .adm-backdrop { padding:0; }
  .adm-modal { width:100%; margin:auto 0 0; max-height:88vh; max-height:calc(100dvh - 10px); border-radius:14px 14px 0 0; } }
/* Sticky + opaque: if the backdrop ever ends up scrolling a too-tall modal, the header pins
   to the top of the scrollport — Close / Open full page stay visible in every case. (The
   modal deliberately has NO overflow:hidden — that would trap the sticky inside it.) */
.adm-head { display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:12px 16px 8px; border-bottom:1px solid rgba(0,0,0,.08); flex:0 0 auto; background:#fff;
  position:sticky; top:0; z-index:5; border-radius:14px 14px 0 0; }
.adm-body { padding:10px 16px 16px; overflow-y:auto; min-height:0; overscroll-behavior:contain; background:#fff; border-radius:0 0 14px 14px; }
.adm-sec { margin:8px 0; border:1px solid rgba(0,0,0,.08); border-radius:10px; padding:6px 10px; }
.adm-sec > summary { cursor:pointer; font-weight:600; font-size:14px; display:flex; align-items:center; gap:8px; }
.adm-sec > summary .cnt { font-size:12px; color:#5a5b5d; background:rgba(0,0,0,.06); border-radius:999px; padding:0 8px; }
/* The shared panel's mini map (modal + full page) — a fixed height so the sections stack. */
.adp-map { height:260px; }
.adp-map .map-wrap, .adp-map .map-canvas { height:100%; min-height:0; }
.adp-host { padding:14px 16px; }

/* UpdateHold — a new build is ready but the app is busy (unsaved edits / recording / uploads):
   a non-blocking pill; the update applies itself the moment the app is clear. */
.update-waiting { position: fixed; top: 64px; left: 50%; transform: translateX(-50%); z-index: 1290;
  background: #221f20; color: #fff; border: 1px solid var(--services-orange, #ff9d14);
  border-radius: 999px; padding: 6px 14px; font-size: 13px; box-shadow: 0 2px 10px rgba(0,0,0,.3);
  max-width: 92vw; text-align: center; }

/* ReviewParity (rel 1.0.56) — the defect detail's extended edit modal widgets. */
.oe-gpsrow { display: flex; gap: 6px; align-items: stretch; }
.oe-gpsrow input { flex: 1 1 120px; min-width: 0; }
.oe-assetbox { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 6px 8px;
  border: 1px solid rgba(0,0,0,.15); border-radius: 8px; background: #fff;
  max-width: 100%; overflow: hidden; }
/* Field feedback — the owner-edit grid's cells need min-width:0 too (grid min-width:auto
   lets a long classification force the column past an iPhone screen). */
.owner-edit > * { min-width: 0; }
.oe-assetbox button:first-of-type { margin-left: auto; }   /* Change…/× hug the right edge */
/* Field feedback — a long classification/asset label (e.g. "Traffic Management Device
   (non ITS) eg minor signs") truncates with an ellipsis instead of stretching the field
   (full text stays in the title tooltip; same treatment as the review's .asset-box-label). */
.oe-assetbox .oe-asset-label { flex: 1 1 140px; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.oe-pickmap .map-canvas { height: 340px; }

/* iPhone review feedback — descriptions grow to fit their content: the rows attribute is
   estimated from the text (works everywhere) and field-sizing upgrades it live where the
   browser supports it. Capped so a huge description scrolls instead of swallowing the page. */
.desc-flex { field-sizing: content; min-height: 4.2em; max-height: 40vh; max-height: 30dvh; overflow-y: auto; }
/* Scrollable modal card: dvh so iOS's URL bar can't clip the card past the visible viewport,
   overscroll containment so a pan reaching the card's end doesn't rubber-band the page. */
.modal-scroll { max-height: 90vh; max-height: 85dvh; overflow: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }

/* SiteVisit20260907pt1.txt — the monitoring flag beside Severity + the WP zone chips. */
.mon-flag { cursor: help; display: inline-flex; align-items: center; margin-left: 5px; padding: 1px 8px;
  border-radius: 999px; background: rgba(90,100,112,.13); border: 1px solid rgba(90,100,112,.22);
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: #5a6470; line-height: 15px; vertical-align: middle; }
.psl-zone-chip { display: inline-block; background: rgba(0,0,0,.07); border-radius: 999px;
  padding: 1px 10px; margin: 0 4px 2px 0; font-size: 12px; }
.psl-zone-chip.nb { border: 1px dashed rgba(255,157,20,.8); background: rgba(255,157,20,.08); }
.psl-zone-row { display: flex; align-items: center; gap: 6px; margin: 3px 0; flex-wrap: wrap; }
.psl-zone-add { display: flex; align-items: center; gap: 6px; margin-top: 6px; flex-wrap: wrap; }

/* Map marker stacking: governed by the !important ladder on the marker classes themselves
   (see the pin-stacking block) — photo pointers 1–2, defect/safety 4, item pills 5,
   focal 999, playhead 1000. */

/* iPhone feedback — the combined asset/classification field: full hierarchy on wide screens,
   just the asset type or name/number on phones (the path spilled off the right edge). */
.al-short { display: none; }
@media (max-width: 480px) {
  .al-full { display: none; }
  .al-short { display: inline; }
}

/* Transfer indicator (feedback): a pulsing badge OVERLAPPING the user button's top-right edge
   — arrows for upload (↑) and caching (↓). Absolutely positioned (anchored to .user-menu), it
   takes NO row space, so nothing moves when it appears or disappears. */
.user-menu { position: relative; }
.xfer-badge { position: absolute; top: -2px; right: -2px; z-index: 6; min-width: 16px; height: 16px;
  padding: 0 3px; border-radius: 999px; background: var(--services-orange, #ff9d14); color: #fff;
  font-size: 10px; font-weight: 800; line-height: 16px; text-align: center;
  animation: xfer-pulse 1.6s ease-in-out infinite; pointer-events: none; }
@keyframes xfer-pulse { 0%, 100% { transform: scale(1); opacity: .95; } 50% { transform: scale(1.08); opacity: .78; } }

/* ── MapConsistency.txt — the SAME overlay layout on every map (MapView slots) ───────────────
   top-left: legend (+ tools under it) · top-right: controls beside the zoom · bottom-left: basemap
   · bottom-right: address + coordinates (+ tools beside them). */
.map-tl { position:absolute; left:10px; top:10px; z-index:6; max-width:calc(100% - 54px); display:flex; flex-direction:column; align-items:flex-start; gap:6px; pointer-events:none; }
.map-tl > * { pointer-events:auto; }
.map-tl .map-legend { margin-top:0; max-width:100%; }
.map-tl-tools { display:flex; flex-wrap:wrap; align-items:center; gap:6px; max-width:100%; }
/* 2026-10-01 (Simon: "the overlay drop down is appearing under the show work package button … ensure it aligns to the
   left of it"): ONE row, right-anchored — the design/chainage picker first (left), the host's control after; a phone
   too narrow for both wraps the control onto the next line, still right-aligned. */
.map-tr { position:absolute; right:50px; top:10px; z-index:6; display:flex; flex-direction:row; flex-wrap:wrap; justify-content:flex-end; align-items:flex-start; gap:6px; max-width:calc(100% - 60px); }
.map-br { position:absolute; right:10px; bottom:10px; z-index:6; display:flex; align-items:flex-end; gap:8px; max-width:calc(100% - 132px); }   /* clear of the basemap button bottom-left */
.map-br-stack { display:flex; flex-direction:column; align-items:flex-end; gap:4px; min-width:0; }
.map-br .map-hint { position:static; }
.map-addr { background:rgba(255,255,255,.92); border:1px solid rgba(0,0,0,.12); border-radius:8px; padding:5px 9px; font-size:11.5px; line-height:1.3; color:#3a424d; min-width:0; max-width:100%; pointer-events:none; text-align:right; }
.map-addr-line { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.map-addr-coords { font-family:var(--font-mono); color:#5a6470; font-size:11px; }
.map-round-btn { width:38px; height:38px; display:inline-flex; align-items:center; justify-content:center; border-radius:50%; cursor:pointer;
  background:#fff; color:#221f20; border:1px solid rgba(0,0,0,.14); box-shadow:0 2px 8px rgba(0,0,0,.18); padding:0; flex:0 0 auto; }
.map-round-btn:hover { color:var(--roads-orange); border-color:var(--roads-orange); }
.map-round-btn svg { width:20px; height:20px; display:block; }
.map-tool-btn { font-size:12px; padding:4px 9px; border-radius:14px; border:1px solid #d0d0d0; background:#fff; box-shadow:0 1px 4px rgba(0,0,0,.18); cursor:pointer; white-space:nowrap; }
.map-tool-btn[disabled] { opacity:.5; cursor:not-allowed; }
.map-legend.row { gap:3px 10px; }
.map-legend.tight { flex-wrap:nowrap; gap:3px 7px; padding:3px 6px; }   /* the photo editor's three rows on ONE line on a phone */
.map-legend.tight .ml-row { gap:4px; }
.ml-tg { cursor:pointer; }
.ml-tg input { margin:0 3px 0 0; cursor:pointer; }
.ml-boundary { width:16px; height:11px; border:2px dashed #7c4dff; border-radius:2px; display:inline-block; opacity:.85; }
.ml-user { width:12px; height:12px; border-radius:50%; background:#1f6feb; border:2px solid #fff; box-shadow:0 0 0 2px rgba(31,111,235,.45); display:inline-block; }
.ml-asset { width:18px; height:0; border-top:3px solid var(--teal, #0aa); display:inline-block; }
.ml-line { width:18px; height:0; border-top:3px solid #7c4dff; display:inline-block; }
.map-tl .ctxmap-title { max-width:min(60vw, 320px); background:rgba(255,255,255,.88); padding:2px 8px; border-radius:6px; }
/* the user's own position — a location puck: blue dot + a heading cone */
.map-user-puck { position:relative; width:0; height:0; z-index:3 !important; }
.map-user-dot { position:absolute; left:-9px; top:-9px; width:18px; height:18px; border-radius:50%; background:#1f6feb; border:3px solid #fff;
  box-shadow:0 0 0 2px rgba(31,111,235,.45), 0 1px 4px rgba(0,0,0,.4); }
.map-user-cone { position:absolute; left:-24px; top:-48px; width:48px; height:48px; transform-origin:50% 100%; pointer-events:none;
  background:conic-gradient(from -28deg at 50% 100%, rgba(31,111,235,.42) 0deg, rgba(31,111,235,.42) 56deg, transparent 56deg); border-radius:50% 50% 0 0; }
/* the orientation spinner under a photo map's legend */
.hspin { display:inline-flex; align-items:center; gap:4px; background:rgba(255,255,255,.92); border:1px solid rgba(0,0,0,.12); border-radius:8px; padding:3px 6px; font-size:12px; max-width:100%; }
.hspin-btn { min-width:26px; height:24px; border-radius:6px; border:1px solid #d0d0d0; background:#fff; cursor:pointer; padding:0 4px; font-size:11px; }
.hspin-btn.wide { padding:0 8px; }
.hspin-range { width:90px; min-width:0; }
.hspin-val { min-width:54px; text-align:center; font-family:var(--font-mono); font-size:11.5px; }
.hspin-x { border:none; background:transparent; cursor:pointer; color:#6b7280; padding:0 2px; font-size:12px; }
/* a marker popup's provenance line (which section · video moment · photo) */
.mcd-src, .mci-src { display:block; font-size:11px; color:#5a6470; margin-top:2px; }
/* MapConsistency.txt — the circle sits CENTRED on the spot; the pointer's base is under the circle and
   its apex points to the bearing (rotated about the spot). */
.map-pin-wrap .map-pin { position:absolute; left:-7px; top:-7px; }
.map-pin-wrap .map-pin.manual { left:-8px; top:-8px; }
.map-pin-wrap .map-pin.orig { left:-12px; top:-12px; }
.map-pin-wrap .map-pin.glyph { left:-11px; top:-11px; }
.map-pin-dir { position:absolute; left:0; top:0; width:0; height:0; transform-origin:0 0; pointer-events:none; z-index:1; }
.map-pin-dir::before { content:""; position:absolute; left:-7px; bottom:0;
  border-left:7px solid transparent; border-right:7px solid transparent;
  border-bottom:24px solid var(--dir-colour, var(--rail-blue)); filter:drop-shadow(0 1px 2px rgba(0,0,0,.4)); }
.map-pin-dir.manual::before { border-bottom-color:var(--dir-colour, var(--services-orange)); }
/* a photo pin's popup: the caption + the photo (tap = the full image) */
.pin-pop { min-width:120px; font-size:12px; }
.pin-thumb { display:block; width:100%; max-width:216px; max-height:160px; object-fit:cover; border-radius:6px; margin-top:6px; cursor:pointer; border:1px solid rgba(0,0,0,.12); }

/* ── WorkPackageCompanies (rel 1.0.77) — Configuration › Companies ── */
.wpco-status { display:flex; align-items:center; gap:12px; flex-wrap:wrap; border-left:4px solid var(--rail-blue); }
.wpco-status.ovr { border-left-color:#d97706; }
.wpco-status-text { flex:1 1 260px; min-width:0; }
.wpco-status-text p { margin:4px 0 0; }
.wpco-table td.num, .wpco-table th.num { text-align:right; white-space:nowrap; }
.wpco-table td.wpco-tick, .wpco-table th.wpco-tick { width:28px; }
.wpco-table tr.wpco-off td { opacity:.55; }
.wpco-add { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:10px; }
.wpco-add .wp-pick { flex:1 1 260px; min-width:0; }
.wpco-actions { display:flex; flex-direction:column; align-items:flex-start; gap:8px; margin-top:12px; }
.wpco-btns { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.wpco-btns .btn { white-space:nowrap; }
@media (max-width:600px) { .wpco-btns .btn { padding:9px 12px; } }
.wpco-disc { display:flex; flex-wrap:wrap; gap:4px; min-width:160px; }
.wpco-disc .chip { font-size:11.5px; padding:2px 8px; }
.wpco-disc-cell { min-width:160px; }
.wpco-table th.wpco-ao, .wpco-table td.wpco-ao { text-align:center; white-space:nowrap; }
.wpco-table tr.wpco-ao-on td { background:rgba(31,107,92,.06); }
.wpco-ao-pick { display:inline-flex; align-items:center; gap:6px; cursor:pointer; }
.wpco-ao-lbl { display:none; font-size:12px; color:var(--concrete); white-space:nowrap; }
/* iPhone (20260917) — every column visible without a sideways scroll: each row becomes a small
   grid (tick · name · people · asset-owner tick on the first line; type, source, disciplines
   beneath) instead of a table wider than the screen. */
@media (max-width:600px) {
  .wpco-table, .wpco-table tbody { display:block; width:100%; }
  .wpco-table thead { display:none; }
  .wpco-table tr { display:grid; grid-template-columns:auto minmax(0,1fr) auto auto; column-gap:8px; row-gap:5px;
    align-items:center; padding:10px 10px; border-bottom:1px solid rgba(0,0,0,.08); }
  .wpco-table tr:last-child { border-bottom:0; }
  .wpco-table td { display:block; padding:0; border:0; min-width:0; }
  .wpco-table tr:hover td, .wpco-table tr.wpco-ao-on td { background:transparent; }
  .wpco-table tr.wpco-ao-on { background:rgba(31,107,92,.06); }
  .wpco-table td[colspan] { grid-column:1 / -1; }
  .wpco-table td.wpco-tick { grid-column:1; grid-row:1; width:auto; }
  .wpco-table td.wpco-name { grid-column:2; grid-row:1; overflow-wrap:anywhere; }
  .wpco-table td.num { grid-column:3; grid-row:1; }
  .wpco-table td.num::before { content:"👥 "; }
  .wpco-table td.wpco-ao { grid-column:4; grid-row:1; }
  .wpco-table td.wpco-ao-na { display:none; }
  .wpco-table td.wpco-type { grid-column:2 / -1; grid-row:2; }
  .wpco-table td.wpco-src { grid-column:2 / -1; grid-row:3; }
  .wpco-table td.wpco-disc-cell { grid-column:2 / -1; grid-row:4; }
  .wpco-disc, .wpco-disc-cell { min-width:0; }
  .wpco-ao-lbl { display:inline; }
}
/* the work package page's read-only Companies card (WorkPackageCompanies, 20260917) */
.psl-company-group { margin-top:4px; }
.psl-company-row { display:flex; justify-content:space-between; align-items:flex-start; gap:8px; flex-wrap:wrap; padding:4px 0; border-top:1px solid rgba(0,0,0,.06); }
.psl-company-name { min-width:0; }
.psl-company-disc { display:flex; gap:4px; flex-wrap:wrap; justify-content:flex-end; }
.badge.psl-disc-pill { background:#e9f6f1; color:#1f6b5c; }
/* 2026-09-30 — the Companies card's expandable discipline count pill (the Team card's pattern) */
.psl-company-disc .wp-pill-disc-toggle { cursor:pointer; user-select:none; }
/* iPhone (2026-09-30, Simon: "the collapse on the companies disciplines is proving difficult to tap"):
   the toggle pills are a real touch target (≥32px tall, wide padding, no 300 ms tap delay), and the
   EXPANDED group is one tappable block — a tap on any of its pills collapses it. Team card + Companies card. */
/* 2026-10-01 (Simon: the grouped "+1 role(s)" / "14 disciplines" pills "are not a consistent height with the other
   badges … the collapse badge is a lot taller"): the toggles are VISUALLY the same size as every other badge — the
   touch target is an INVISIBLE ::before halo (12px all round, ≥ ~40px tall) that belongs to the button. */
.badge.wp-pill-disc-toggle { display:inline-flex; align-items:center; position:relative; padding:2px 9px; font-size:11px; line-height:inherit; touch-action:manipulation; -webkit-tap-highlight-color:rgba(31,107,92,.18); }
.badge.wp-pill-disc-toggle::before { content:""; position:absolute; inset:-12px -8px; }
/* The toggles are <button>s (iOS's first-class tappable) wearing the badge look — reset the button chrome. */
button.badge.wp-pill-disc-toggle { border:0; font-family:inherit; font-weight:600; cursor:pointer; -webkit-appearance:none; appearance:none; }
/* The COLLAPSE pill is the one control in an expanded group — a dark fill so it stands apart from the value pills. */
.badge.wp-pill-disc-toggle.wp-pill-collapse, .wp-team-panel .badge.wp-pill-disc-toggle.wp-pill-collapse, .psl-company-disc .badge.wp-pill-disc-toggle.wp-pill-collapse { background:var(--vida-bitumen,#221f20); color:#fff; }
.wp-pill-disc-group button.badge { pointer-events:auto; }
.wp-pill-disc-group { display:inline-flex; flex-wrap:wrap; gap:4px; align-items:center; cursor:pointer; user-select:none; touch-action:manipulation; -webkit-tap-highlight-color:rgba(31,107,92,.18); padding:2px; margin:-2px; border-radius:8px; }
.wp-pill-disc-group .badge { pointer-events:none; }
/* 2026-09-30 — Design packages: a collapsed total; expanded = company › discipline › packages */
.psl-sec-toggle { display:flex; align-items:center; gap:6px; width:100%; background:none; border:0; padding:0; text-align:left; cursor:pointer; color:inherit; font:inherit; font-size:.95rem; font-weight:600; }
.psl-sec-toggle .chev { color:var(--concrete,#9aa3aa); font-size:13px; margin-left:auto; }
.psl-dp-tree { display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.psl-dp-co { border-top:1px solid rgba(0,0,0,.06); padding-top:6px; }
.psl-dp-co-head { display:flex; align-items:baseline; gap:6px; flex-wrap:wrap; margin-bottom:4px; }
.psl-dp-disc { display:grid; grid-template-columns:auto minmax(0,1fr); align-items:start; gap:6px 8px; padding:2px 0 2px 12px; }
.psl-dp-pkgs { display:flex; flex-direction:column; gap:2px; min-width:0; }
.psl-dp-pkg { font-size:.85rem; overflow-wrap:anywhere; }
.psl-dp-pkg.off { color:var(--concrete,#9aa3aa); text-decoration:line-through; }
@media (max-width:560px) { .psl-dp-disc { grid-template-columns:1fr; } }
/* CivilloChainage (2026-10-01) — the Chainage page (Configuration › Extras): import card, file rows, the
   alignments list beside the map, and the chainage label markers map.js places along the alignments. */
.chn-import { display:flex; flex-wrap:wrap; gap:8px 12px; align-items:center; }
.chn-import select { font-size:16px; padding:6px 8px; border:1px solid rgba(0,0,0,.15); border-radius:8px; }
.chn-file { display:flex; flex-wrap:wrap; gap:4px 10px; align-items:center; padding:8px 0; border-top:1px solid rgba(0,0,0,.07); cursor:pointer; }
.chn-file:first-of-type { border-top:0; }
.chn-file.sel { background:rgba(255,157,20,.08); margin:0 -8px; padding:8px; border-radius:8px; }
.chn-file .chn-name { font-weight:600; min-width:0; overflow-wrap:anywhere; }
.chn-file .chn-meta { color:var(--concrete,#5a5b5d); font-size:.85rem; }
.chn-file .chn-actions { margin-left:auto; display:flex; gap:6px; }
.chn-warn { color:#8a5a00; font-size:.85rem; margin:2px 0 0; }
.chn-align { border-top:1px solid rgba(0,0,0,.07); padding:8px 0; }
.chn-align-head { display:flex; flex-wrap:wrap; gap:6px 10px; align-items:center; cursor:pointer; }
.chn-align-head.sel { background:rgba(255,157,20,.08); margin:0 -8px; padding:4px 8px; border-radius:8px; }
.chn-swatch { width:14px; height:14px; border-radius:3px; flex:none; border:1px solid rgba(0,0,0,.15); }
.chn-align-name { font-weight:700; }
.chn-align-ch { font-variant-numeric:tabular-nums; color:var(--slate,#3c434b); }
.chn-align-body { margin-top:6px; }
.chn-kv { display:grid; grid-template-columns:auto minmax(0,1fr); gap:2px 10px; font-size:.85rem; }
.chn-kv .k { color:var(--concrete,#5a5b5d); }
.chn-table { font-size:.8rem; font-variant-numeric:tabular-nums; border-collapse:collapse; width:100%; margin-top:6px; }
.chn-table th, .chn-table td { padding:2px 6px; text-align:right; border-bottom:1px solid rgba(0,0,0,.06); white-space:nowrap; }
.chn-table th:first-child, .chn-table td:first-child { text-align:left; }
.chn-table-wrap { max-height:220px; overflow:auto; }
.chn-tap { background:#fff6f1; border:1px solid rgba(255,87,0,.3); border-radius:8px; padding:6px 10px; font-size:.9rem; margin-bottom:8px; }
.chn-list { max-height:70vh; overflow:auto; }
/* MapLibre owns the marker element's position + transform (absolute, translated, rotated) — the label only sizes to its text. */
.map-chainage-label { display:inline-block; width:max-content; font:600 11px/1 "Segoe UI",system-ui,sans-serif; color:#1b2a41; background:rgba(255,255,255,.82); border:1px solid rgba(27,42,65,.35); border-radius:3px; padding:1px 4px; white-space:nowrap; pointer-events:auto; cursor:pointer; }
.map-chainage-label.minor { font-size:9px; font-weight:500; opacity:.85; }
/* The map legend's Chainage row (MapView draws it under the host's legend when the WP has a flagged chainage file). */
.map-chainage-legend { margin-top:4px; }
.map-chainage-legend label { cursor:pointer; user-select:none; }
.map-chainage-legend input { margin:0 2px 0 0; }
.ml-line.chn { border-top:3px solid #c2185b; box-shadow:0 2px 0 -1px #fff; }
/* ChainageOnItems (2026-10-02) — the "CH 7,240.5 · 3.2 m L" / "CH 7,240–7,310 · L" chip on list rows and the From-drawing card. */
.badge.chn-chip { background:#fce4ec; color:#8e1b4a; font-variant-numeric:tabular-nums; white-space:nowrap; }
/* PointOfReference (2026-10-02) — the Point of reference input with its "Reset from location" / "From location" button beside it. */
.por-row { display:flex; gap:6px; align-items:center; min-width:0; }
.por-row input { flex:1 1 auto; min-width:0; }
.por-row .btn { flex:none; white-space:nowrap; }
.chn-from-drawing { display:flex; flex-wrap:wrap; gap:8px 12px; align-items:center; }
.chn-from-drawing select { font-size:16px; padding:6px 8px; border:1px solid rgba(0,0,0,.15); border-radius:8px; max-width:100%; }
.map-chainage-label.sel { background:#ff9d14; color:#221f20; border-color:#b25f00; }
/* rel 1.0.77 — the boundary editor's editable name (zone rename) */
.bed-name { display:flex; align-items:center; gap:8px; margin-top:4px; }
.bed-name input { font-size:16px; padding:4px 8px; border:1px solid rgba(0,0,0,.2); border-radius:6px; min-width:200px; max-width:100%; }

/* rel 1.1.0 — defect triage (DefectTriage.txt): the review-group picker, the queue rows, decisions */
.triage-chips { display:flex; flex-wrap:wrap; gap:6px; margin-top:4px; }
.triage-chip { border:1px solid rgba(0,0,0,.2); background:#fff; border-radius:999px; padding:5px 12px; font:inherit; font-size:14px; cursor:pointer; color:var(--asphalt,#221f20); }
.triage-chip.on { background:rgba(255,157,20,.18); border-color:var(--roads-orange,#ff9d14); font-weight:600; }
.triage-chip:disabled { opacity:.6; cursor:default; }
.triage-default > span:first-child { display:block; font-weight:600; margin-bottom:2px; }
.triage-row { display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:6px 0 2px; }
.triage-lbl { font-size:12px; text-transform:uppercase; letter-spacing:.04em; color:var(--concrete,#666); font-weight:700; margin-right:2px; }
.triage-proxy { margin-top:8px; padding:8px 10px; border:1px solid #ffd58a; background:#fff7e6; border-radius:8px; }
.triage-await { border-color:var(--vida-amber,#ff9d14); background:rgba(255,157,20,.07); margin-bottom:12px; }
.triage-card { margin-bottom:12px; }
.tri-flag { margin-left:0; }   /* 2026-10-01: no extra lead-in — the row gap alone spaces it like every other badge (Simon: "severity -> in triage is wider") */
.tri-tabs { margin-bottom:12px; }
.tri-row.tri-await { border-left:4px solid var(--roads-orange,#ff9d14); }
.tri-row.tri-owner { border-left:4px solid #c62828; }
.tri-turn { font-weight:700; }
.tri-roles { display:flex; flex-wrap:wrap; gap:4px; margin-top:4px; }
.tri-role { display:inline-flex; align-items:center; gap:3px; font-size:12px; border-radius:999px; padding:1px 8px; border:1px solid rgba(0,0,0,.12); background:#f4f4f4; color:#444; }
.tri-role.ok { background:#e6f4ea; border-color:#a5d6b3; color:#1b5e20; }
.tri-role.bad { background:#fdecea; border-color:#f5b3ad; color:#b71c1c; }
.tri-role.wait { background:#fff7e6; border-color:#ffd58a; color:#8a5200; }
.tri-role.off { background:#f0f0f0; border-color:rgba(0,0,0,.12); color:#888; }   /* cancelled — no longer needed (2026-09-25) */
.tri-expand .ah-grid { margin-bottom:8px; }
.tri-thumbs { display:flex; flex-wrap:wrap; gap:6px; margin:6px 0; }
.tri-thumb { width:64px; height:64px; border-radius:6px; overflow:hidden; border:1px solid rgba(0,0,0,.12); background:#eee; padding:0; cursor:pointer; display:flex; align-items:center; justify-content:center; }
.tri-thumb img { width:100%; height:100%; object-fit:cover; display:block; }
.tri-thumb-ph { font-size:22px; }
.tri-decisions { display:flex; flex-direction:column; gap:6px; margin:6px 0; }
.tri-decision { border:1px solid rgba(0,0,0,.1); border-radius:8px; padding:6px 10px; background:#fafafa; }
.tri-decision.ok { border-color:#a5d6b3; background:#f3faf5; }
.tri-decision.bad { border-color:#f5b3ad; background:#fff5f4; }
.tri-decision.off { border-color:rgba(0,0,0,.1); background:#f6f6f6; color:#666; }
.tri-decision-head { display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.tri-note { white-space:pre-wrap; font-size:14px; margin-top:4px; }
.tri-owner-banner { border:1px solid #f5b3ad; background:#fff5f4; border-radius:8px; padding:8px 10px; margin:8px 0; }
.tri-owner-open { border:1px solid rgba(0,0,0,.12); background:#fafafa; border-radius:8px; padding:8px 10px; margin:8px 0; }   /* the owner's options on a round still under review (2026-09-25) */
.tri-mine { margin-top:8px; padding-top:8px; border-top:1px dashed rgba(0,0,0,.15); }
.tri-actions { display:flex; flex-wrap:wrap; gap:8px; margin-top:8px; align-items:center; }
.tri-detail-actions { justify-content:flex-end; margin-top:4px; }
/* The triage block on an expanded Triage review row (2026-09-25): state, responses, who is still to respond, the
   owner banner and this user's actions grouped in one bordered panel, apart from the defect's details. */
/* TriagePanelFirst (2026-10-01): the triage block LEADS the expanded row — its gap sits below it, before the details. */
.tri-group { border:1px solid rgba(0,0,0,.12); border-radius:10px; padding:8px 10px; margin:0 0 10px; background:#fbfbfb; }
.tri-group-head { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:4px; }
.tri-group-head strong { font-size:12px; text-transform:uppercase; letter-spacing:.04em; color:var(--concrete,#666); }
.tri-group .tri-owner-banner { margin:8px 0 0; }
.tri-group .tri-actions { margin-top:8px; }
.tri-await-line { margin:4px 0 0; }
.tri-dispute-btn { color:#b71c1c; border-color:#f5b3ad; }
.tri-dispute-btn.btn-primary { background:#c62828; border-color:#c62828; color:#fff; }
.tri-history { margin-top:8px; }
.tri-history summary { cursor:pointer; }
.tri-round { margin:6px 0 0 6px; padding-left:8px; border-left:2px solid rgba(0,0,0,.12); }

/* ── My Activity (MyActivity.txt) — the user's own timeline, GLOBAL like every DefuseR style ── */
.mya-filters { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.mya-search { flex:1 1 220px; min-width:0; font-size:16px; padding:8px 10px; }
.mya-chips { display:flex; gap:6px; flex-wrap:wrap; }
.mya-chips .chip { border:1px solid rgba(0,0,0,.15); background:#fff; border-radius:999px; padding:4px 10px; font-size:13px; cursor:pointer; }
.mya-chips .chip.on { background:var(--vida-bitumen,#221f20); color:#fff; border-color:var(--vida-bitumen,#221f20); }
.mya-period { font-size:16px; padding:6px 8px; }
.mya-tl { position:relative; margin:8px 0 24px; padding-left:18px; border-left:2px solid rgba(0,0,0,.12); }
.mya-day { display:flex; gap:10px; align-items:baseline; margin:18px 0 6px; font-weight:600; }
.mya-day:first-child { margin-top:4px; }
.mya-group { position:relative; margin:0 0 12px; }
.mya-stamp { display:flex; gap:8px; align-items:center; margin-bottom:4px; }
.mya-dot { position:absolute; left:-25px; top:6px; width:12px; height:12px; border-radius:50%; background:var(--vida-amber,#ff9d14); border:2px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,.15); }
.mya-items { display:flex; flex-direction:column; gap:6px; }
.mya-item { display:flex; gap:10px; align-items:flex-start; background:#fff; border:1px solid rgba(0,0,0,.08); border-radius:8px; padding:8px 10px; }
.mya-kind { flex:0 0 auto; margin-top:2px; }
.mya-kind-defect { background:#e8f1fb; color:#1c4e80; }
.mya-kind-asset { background:#e6f4ef; color:#1b6b4a; }
.mya-kind-activity { background:#f3e9fb; color:#5b2d8e; }
.mya-kind-task { background:#fdf0e1; color:#8a4b00; }
.mya-kind-capture { background:#ede9fe; color:#4c1d95; }
.mya-kind-safety { background:#fdecea; color:#a32d21; }
.mya-body { flex:1 1 auto; min-width:0; }
.mya-line { display:flex; gap:8px; align-items:baseline; flex-wrap:wrap; }
.mya-title { overflow-wrap:anywhere; }
.mya-summary { margin-top:2px; overflow-wrap:anywhere; }
.mya-details pre { white-space:pre-wrap; overflow-wrap:anywhere; margin:4px 0 0; padding:6px 8px; background:rgba(0,0,0,.04); border-radius:6px; }
.mya-where { margin-top:2px; }
.mya-open { flex:0 0 auto; }
@media (max-width:560px) {
  .mya-item { flex-wrap:wrap; }
  .mya-open { width:100%; text-align:center; }
}

/* ── CapturesListSummary (2026-09-29) — the capture's title on the list row, its description + a
   sections / videos / photos summary in the expanded panel (Site Captures list + the Capture hub) ── */
.tp-title { flex:1 1 100%; min-width:0; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Desktop (2026-10-01, Simon: "the date and owner are being pushed onto a third row … It should be on the first row
   (similar to those without a title) and the title given the second row"): the full-width title takes the SECOND
   row — badges + date/owner stay together on the first, as on a row without a title. Phones keep the markup order. */
@media (min-width:761px) { .tp-main .tp-title { order:1; } }
.tp-desc { margin:4px 0 8px; white-space:pre-wrap; overflow-wrap:anywhere; }
.cap-draft { cursor:pointer; }
.cd-title { flex:1 1 100%; min-width:0; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cd-chev { flex:0 0 auto; opacity:.6; margin-left:4px; }
.cap-draft-expand { border-top:1px solid rgba(0,0,0,.07); background:rgba(0,0,0,.02); padding:6px 10px 12px; margin:0 0 6px; border-radius:0 0 8px 8px; }
.cap-draft-expand-acts { display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }
@media (min-width:761px) { .cap-draft-expand-acts { display:none; } }

/* TriageActionBadge (2026-09-29) — the list's triage badge in a DARKER shade when the triage waits on THIS user */
/* TriageHeader (2026-09-30) — the defect detail header's triage badge: tappable (scrolls to the review card), a real touch target */
.dh-badges .badge.tri-flag-head { cursor:pointer; user-select:none; touch-action:manipulation; display:inline-flex; align-items:center; min-height:28px; margin-left:0; }
.tri-flag.tri-flag-mine.amber { background:#b25f00; color:#fff; border-color:#b25f00; font-weight:700; }
.tri-flag.tri-flag-mine.red { background:#8e1b12; color:#fff; border-color:#8e1b12; font-weight:700; }

/* BatchSubmit (2026-09-29) — a proposal a batch already CREATED: locked on the review, marked with its reference */
.rev-submitted { border-color:#1c4e80 !important; background:#eef4fb !important; cursor:default !important; }
.rev-badge.rev-badge-sub { background:#1c4e80; color:#fff; }

/* RectificationPlansExtended (2026-10-02) — the extended plan panel, the proposal editor and the awaiting-you card. */
.rect-banner { border-radius: 10px; padding: 10px 12px; margin: 8px 0; font-size: 0.92rem; }
.rect-banner.returned { background: #fdecea; border: 1px solid #f3b3ac; color: #7a1f14; }
.rect-banner.escalated { background: #fff4e0; border: 1px solid #f3cf8f; color: #6a4a00; }
.rect-banner .btn { margin-top: 6px; }
.rect-meta { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 0.9rem; margin: 6px 0; }
.rect-meta .dd-k { color: var(--ink-dim, #6b6b6b); font-weight: 600; margin-right: 4px; }
.rect-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 8px; }
.rect-opt .rect-opt-body { font-size: 0.9rem; margin-top: 6px; display: grid; gap: 3px; }
.rect-opt .rect-opt-fixes { margin: 6px 0 0 16px; padding: 0; font-size: 0.88rem; }
.rect-opt .rect-opt-actions { margin-top: 8px; }
.rect-reviews { width: 100%; border-collapse: collapse; font-size: 0.9rem; margin: 6px 0; }
.rect-reviews td { padding: 6px 4px; border-top: 1px solid var(--line, #e6e3dd); vertical-align: top; }
.rect-reviews td:first-child { font-weight: 600; white-space: nowrap; }
.rect-review-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.rect-decide { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; padding: 10px; border: 1px dashed var(--line, #d8d4cc); border-radius: 10px; }
.rect-decide textarea { width: 100%; min-height: 64px; }
.rect-decide .row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* ReviewOptions (2026-10-06) — the option tick list on a plan review + the per-option role tally. */
.rect-opt-pick { display: flex; flex-direction: column; gap: 6px; }
.rect-opt-pick label { display: flex; gap: 8px; align-items: flex-start; font-size: 14px; cursor: pointer; }
.rect-opt-pick input { margin-top: 3px; flex: 0 0 auto; }
.rect-opt-roles { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.plan-opt-tally { display: flex; flex-direction: column; gap: 2px; margin: 4px 0 6px; color: var(--muted, #6b6760); }
/* OptionVerdicts (2026-10-06) — a verdict + reason per option on the review form; the panel's preferred option for the approver. */
.rect-verdict { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border: 1px solid var(--line, #d8d4cc); border-radius: 10px; background: var(--card, #fff); }
.rect-verdict-head { display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; }
.rect-verdict-pick { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.rect-verdict input[type=text] { width: 100%; font-size: 16px; }
.btn.v-sup { background: #dff5e1; color: #1f6b2c; border-color: #9fd3a8; }
.btn.v-obj { background: #fee2e2; color: #991b1b; border-color: #f1a9a9; }
.v-sup-t { color: #1f6b2c; font-weight: 700; }
.v-obj-t { color: #991b1b; font-weight: 700; }
.rect-verdict-list { display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
.plan-preferred { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 8px 10px; border-radius: 10px; background: #eef8ef; border: 1px solid #9fd3a8; margin: 6px 0; }
.rect-monitor { border: 1px solid var(--line, #e6e3dd); border-radius: 10px; padding: 10px 12px; margin: 8px 0; background: #f6fbfb; }
.rect-monitor h3 { margin: 0 0 6px; font-size: 1rem; }
.rect-monitor ul { margin: 6px 0 0; padding-left: 18px; font-size: 0.9rem; }
.rect-media { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.rect-media img { width: 72px; height: 72px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line, #e6e3dd); cursor: pointer; }
.rect-linked { margin: 4px 0; padding-left: 18px; font-size: 0.9rem; }
.rect-verify-checks { display: flex; flex-direction: column; gap: 4px; margin: 6px 0; font-size: 0.9rem; }
.rect-await-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.rect-await-list li { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.rect-await-list a { color: inherit; text-decoration: none; }
/* The proposal editor (/rectification/propose/{id}). */
.rp-page .card { margin-bottom: 12px; }
.rp-option { border: 1px solid var(--line, #e6e3dd); border-radius: 12px; padding: 12px; margin: 10px 0; background: #fff; }
.rp-option.rec { border-color: var(--brand, #ff9d14); box-shadow: 0 0 0 2px rgba(255,157,20,.15); }
.rp-option .rp-opt-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.rp-option .rp-opt-head h3 { margin: 0; font-size: 1rem; flex: 1 1 auto; }
.rp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px 12px; }
.rp-grid label, .rp-field { display: flex; flex-direction: column; gap: 3px; font-size: 0.9rem; min-width: 0; }
.rp-grid label span, .rp-field > span { color: var(--ink-dim, #6b6b6b); font-weight: 600; font-size: 0.82rem; }
.rp-grid input, .rp-grid select, .rp-grid textarea, .rp-field input, .rp-field select, .rp-field textarea { font-size: 16px; min-width: 0; width: 100%; }
.rp-wide { grid-column: 1 / -1; }
.rp-step { border-left: 3px solid var(--line, #e6e3dd); padding: 6px 10px; margin: 6px 0; }
.rp-step .rp-step-head { display: flex; gap: 8px; align-items: center; }
.rp-checks { display: flex; flex-direction: column; gap: 6px; }
.rp-checks .rp-check { display: grid; grid-template-columns: auto 1fr; gap: 6px 10px; align-items: start; }
.rp-checks .rp-check input[type=text] { font-size: 16px; width: 100%; }
.rp-links { max-height: 240px; overflow: auto; border: 1px solid var(--line, #e6e3dd); border-radius: 10px; padding: 6px 10px; }
.rp-links label { display: flex; gap: 8px; align-items: baseline; padding: 4px 0; font-size: 0.9rem; }
.rp-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 8px; }
.rp-error { color: #a4231a; font-size: 0.9rem; }

/* PlanningBadge (2026-10-02) — the "In planning" badge (darker when the planning waits on THIS user), the top planning card, the plans register. */
.plan-flag { margin-left:0; white-space:nowrap; }
.plan-flag.plan-flag-mine.amber { background:#b25f00; color:#fff; border-color:#b25f00; font-weight:700; }
.plan-flag.plan-flag-mine.red { background:#8e1b12; color:#fff; border-color:#8e1b12; font-weight:700; }
.dh-badges .badge.plan-flag { cursor:pointer; user-select:none; touch-action:manipulation; display:inline-flex; align-items:center; min-height:28px; }
.plan-panel { border-color:var(--vida-amber,#ff9d14); background:rgba(255,157,20,.06); margin-bottom:12px; }
.plan-panel.plan-panel-mine { border-left:4px solid #b25f00; }
.plan-panel-head { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-bottom:6px; }
.plan-panel-head h3 { margin:0; font-size:1rem; flex:1 1 auto; }
.plan-actions { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:8px 0 4px; }
.plan-review-row { display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
.plan-reviews { display:flex; gap:6px; flex-wrap:wrap; margin:4px 0; }
.plan-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.plan-row { border:1px solid var(--line,#e6e3dd); border-radius:12px; padding:10px 12px; background:#fff; display:grid; gap:4px; }
.plan-row.plan-row-mine { border-left:4px solid #b25f00; }
.plan-row-head { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.plan-row-head .plan-ref { color:inherit; text-decoration:none; font-size:1.02rem; }
.plan-row-body { display:flex; gap:10px; flex-wrap:wrap; align-items:baseline; font-size:0.95rem; }
.plan-row-body a { color:inherit; text-decoration:none; }
.plan-row-actions { display:flex; justify-content:flex-end; }

/* RectificationWizard (2026-10-03) — the 3-step proposal wizard's stepper + the split-done notice. */
.rp-steps { list-style:none; display:flex; gap:6px; margin:0 0 12px; padding:0; flex-wrap:wrap; }
.rp-steps li button { display:inline-flex; align-items:center; gap:6px; border:1px solid var(--line,#e6e3dd); background:#fff; border-radius:999px; padding:6px 12px; font:inherit; font-size:0.9rem; cursor:pointer; }
.rp-steps li.on button { border-color:var(--brand,#ff9d14); background:rgba(255,157,20,.12); font-weight:700; }
.rp-steps li.done button { background:#eef7ee; border-color:#bfe3bf; }
.rp-steps li button:disabled { opacity:.5; cursor:default; }
.rp-step-no { display:inline-flex; width:20px; height:20px; border-radius:50%; background:var(--ink,#221f20); color:#fff; font-size:0.75rem; align-items:center; justify-content:center; }
.rect-banner.split-done { background:#eef7ee; border:1px solid #bfe3bf; color:#1c5e1c; }

/* RectificationWizard picker — search + filters over the confirmed-in-planning defects. */
.rp-pick-tools { display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin:6px 0 8px; }
.rp-pick-tools .rp-search { flex:1 1 180px; min-width:0; font-size:16px; }
.rp-pick-tools select { font-size:16px; max-width:48%; }
.rp-pick-meta { display:inline-flex; gap:4px; flex-wrap:wrap; align-items:center; margin-left:auto; }
.rp-links label { flex-wrap:wrap; }

/* MonitoringPlans (2026-10-05) — the wizard's schedule rows + the planning card's per-plan blocks */
.rp-sched-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:4px 0; }
.rp-sched-row input[type=date] { flex:1 1 150px; min-width:0; }
.rp-sched-row select { flex:1 1 150px; min-width:0; }
.plan-block { border-top:1px solid var(--border, #e5e7eb); padding-top:8px; margin-top:8px; }
.plan-block-title { margin-bottom:4px; }
.rp-pick-off { opacity:.5; }
.rp-pathway { margin-bottom:12px; }
.rp-pathway-pick { display:flex; gap:16px; flex-wrap:wrap; align-items:center; margin:4px 0 8px; }
.rp-pathway-pick label.off { opacity:.7; }

/* FixSteps (2026-10-06) — the "return to the previous step" row on a rectify task. */
.fix-return { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-top:10px; padding:8px 10px; border:1px dashed rgba(0,0,0,.18); border-radius:8px; }
