/* ============================================================
   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;
  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; }
.user-dropdown { position:absolute; right:0; top:calc(100% + 8px); min-width:180px; 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; }
.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; }
/* 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.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) */
/* 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 sizes + stacking when defect / photo / walk-start overlap:
   photo (exif, smallest, in front) ‹ defect ‹ walk-start (manual, largest, behind).
   z-index is !important to beat MapLibre's per-marker inline z-index (lat-based). */
.map-pin { width:16px; height:16px; border-radius:50% 50% 50% 0; background:var(--rail-blue); transform:rotate(-45deg);
  border:2px solid #fff; box-shadow:0 1px 4px rgba(0,0,0,.4); cursor:pointer; z-index:6 !important; }
.map-pin.manual { background:var(--services-orange); width:24px; height:24px; z-index:2 !important; }

/* Directional photo pin — points in the compass bearing the photo was taken at.
   MapLibre owns the transform of the element it positions, so the rotatable
   pin lives on a CHILD (.map-pin-arrow) of a neutral wrapper (.map-pin-wrap)
   that MapLibre positions (anchor:center → wrapper centre = the geo point). */
.map-pin-wrap { position:absolute; width:0; height:0; z-index:6 !important; cursor:pointer; }
/* 0×0 box pinned at the geo point; transform-origin at that point so the inline
   rotate(bearing) pivots about the location. The ::before triangle is the
   pointer (apex north at 0°), its base on the point; ::after is the hub dot. */
.map-pin-arrow { position:absolute; left:0; top:0; width:0; height:0; transform-origin:0 0; }
.map-pin-arrow::before { content:""; position:absolute; left:-8px; bottom:0;
  border-left:8px solid transparent; border-right:8px solid transparent;
  border-bottom:26px solid var(--rail-blue);
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.45)); }
.map-pin-arrow::after { content:""; position:absolute; left:-6px; top:-6px;
  width:12px; height:12px; border-radius:50%; background:#fff;
  box-shadow:0 0 0 3px var(--rail-blue), 0 1px 3px rgba(0,0,0,.4); }
.map-pin-arrow.manual::before { border-bottom-color:var(--services-orange); }
.map-pin-arrow.manual::after  { box-shadow:0 0 0 3px var(--services-orange), 0 1px 3px rgba(0,0,0,.4); }
/* hover-highlight: pulse the hub (transform is taken by the bearing rotation). */
.map-pin-arrow.hl { z-index:10 !important; }
.map-pin-arrow.hl::after { animation:pin-pulse 1.1s ease-out infinite; }
/* 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; }
.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). */
.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; }

/* ============= 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; }
  .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-section { border-left:3px solid rgba(124,77,255,.35); padding:4px 0 4px 14px; margin-bottom:16px; }
.tl-sec-head { display:flex; align-items:flex-start; gap:8px; margin-bottom:8px; }
.tl-sec-name { flex:1 1 140px; min-width:0; max-width:none; font-family:var(--font-display); font-weight:700; font-size:15px;
  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; }
.tl-audio { display:block; width:100%; max-width:420px; height:38px; margin:-2px 0 10px; }
.tl-grid { margin:2px 0 6px; }
@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:1fr 1fr; gap:10px; margin-top:12px; }
.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); }
.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). */
.tl-section.cur { border-left-color:var(--ai-violet); background:rgba(124,77,255,.04); }
.tl-section { border-radius:0 8px 8px 0; }
.tl-collapse { flex:0 0 auto; width:22px; height:22px; border:none; background:transparent; cursor:pointer;
  font-size:13px; color:var(--concrete); }
.tl-sec-counts { flex:0 0 auto; white-space:nowrap; }
.tl-setcur { flex:0 0 auto; }
.tl-people { display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; margin:2px 0 10px; line-height:1.9; }
.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); }
/* "Current" indicator — sits in the action row, sized like the buttons (uses .btn small) but filled
   violet and non-interactive, so it reads uniformly instead of floating next to the name. */
.tl-cur-chip { background:var(--ai-violet); border-color:var(--ai-violet); color:#fff; font-weight:700;
  cursor:default; display:inline-flex; align-items:center; justify-content:center; }
.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 / Set current / Delete). */
  .tl-sec-head { flex-wrap:wrap; align-items:center; gap:6px; }
  .tl-sec-main { flex-direction:column; align-items:stretch; gap:2px; flex:1 1 120px; 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; border-bottom-color:rgba(0,0,0,.14); }
  .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; }
.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%; }
}

/* 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 */
  .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; }
}

/* ---- 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; }
.mobile-nav a .wb-badge { position:absolute; top:3px; left:calc(50% + 5px); min-width:16px; height:16px; font-size:10px; padding:0 4px; }

/* ---- 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-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; }
.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; }
.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. */
.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. */
.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; }

/* "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: #157a3a; }   /* Closed — ✓ tick, green */

/* 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; align-items: flex-start; justify-content: space-between; gap: 8px 14px; }
.dh-idline h1.dh-title { margin: 0; flex: 1 1 auto; min-width: 0; font-size: 1.35rem; font-weight: 700;
    color: var(--ink, #1f2933); overflow-wrap: anywhere; }
.dh-badges { flex: none; 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; }
@media (max-width: 640px) { .dh-idline h1.dh-title { font-size: 1.2rem; } }
.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; }

/* 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. */
.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,1.6fr) minmax(0,1fr) auto;
    gap: 8px; align-items: center; margin-top: 8px; }
.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; } }
.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; }
.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; }
.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; }
/* Google basemap switch (GoogleMapsBasemap) — bottom-left, clear of the nav control. */
.map-basemap-btn { position:absolute; left:10px; bottom:26px; 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; }
