 .button { display: inline-flex; justify-content: center; align-items: center; min-height: 40px; padding: 8px 15px; border: 1px solid var(--line); border-radius: 7px; background: white; color: var(--ink); cursor: pointer; font-weight: 600; font-size: .85rem; gap: 6px; }
.button:hover { background: #edf3f6; border-color: #9fb2c1; } .button.primary { background: var(--navy); border-color: var(--navy); color: white; }
.button.primary:hover { background: var(--navy-soft); } .button.danger { color: var(--danger); border-color: #e9bdc1; background: #fff5f5; }
.button.text { border-color: transparent; background: transparent; color: var(--accent-strong); padding-left: 4px; padding-right: 4px; }
button:disabled { cursor: not-allowed; opacity: .55; } .button:disabled:hover { border-color: var(--line); }
.panel { background: var(--surface); padding: 26px; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); min-width: 0; }
.page-header { display: flex; justify-content: space-between; align-items: center; gap: 20px; padding: 4px 0; }
.page-header p:last-child { margin-bottom: 0; max-width: 70ch; }
.page-heading { display: flex; align-items: center; gap: 8px; min-width: 0; }
.page-heading h1 { margin: 0; font-size: 1.4rem; line-height: 1.25; }
/* The page description, one hover or focus away instead of a permanent
   paragraph. A real button so it is reachable by keyboard, not a div. */
.page-hint { width: 20px; min-height: 20px; padding: 0; border-radius: 50%; border: 1px solid var(--line);
  background: #fff; color: var(--muted); font-size: .72rem; font-weight: 700; font-style: italic;
  line-height: 1; cursor: help; flex-shrink: 0; }
.page-hint:hover,.page-hint:focus-visible { color: var(--accent); border-color: var(--accent); }
.form { display: grid; gap: 17px; } .form-field { display: grid; gap: 7px; font-size: .87rem; font-weight: 600; }
.form-field small { font-weight: 400; } input:not([type=checkbox]):not([type=range]),select { width: 100%; min-height: 42px; border: 1px solid #b6c5d1; background: #fff; border-radius: 7px; padding: 9px 11px; color: var(--ink); min-width: 0; }
input[type=checkbox] { width: 17px; height: 17px; accent-color: var(--accent); flex-shrink: 0; }
.select-field { display: grid; gap: 4px; } .field-label { font-size: .68rem; font-weight: 700; text-transform: uppercase; color: var(--muted); letter-spacing: .06em; }
.form-error { color: var(--danger); margin: 0; font-size: .86rem; } .form-error:empty { display: none; }
.badge { display: inline-flex; padding: 3px 9px; font-size: .74rem; font-weight: 650; border-radius: 5px; border: 1px solid #ccd7df; background: #eef2f5; color: #405566; }
.badge.positive { background: #e9f6f0; color: #216047; border-color: #bedfd0; } .badge.danger { background: #fff0f1; color: #95232d; border-color: #edc6ca; }
.badge.warning { background: #fdf3e0; color: #8a5a05; border-color: #f0d9a6; }
/* The five semantic tones of docs/architecture/status-taxonomy-design.md
   Section 22, plus the unknown one. `attention` means a person must act
   and is deliberately the same red as `danger` -- they were one tone
   before the split and the split is about meaning, not about hue.
   `closed` is terminal-but-not-good and must NOT read as an error: a
   demolished building or a retired asset is a settled fact, not a fault.
   `unknown` is a display GAP and is the only tone that looks wrong on
   purpose -- dashed, so it cannot be mistaken for a state somebody chose. */
.badge.progress { background: #eef4fb; color: #1f4b7a; border-color: #c3d8ee; }
.badge.attention { background: #fff0f1; color: #95232d; border-color: #edc6ca; }
.badge.closed { background: #f2f0f4; color: #58516a; border-color: #d6d1de; }
.badge.unknown { background: #fbf6ea; color: #6b5320; border-style: dashed; border-color: #cbb188; }
/* The saved filter groups (Open / Needs Action / Completed / Exceptions).
   A pressed one is shown by fill AND by aria-pressed -- a toggle whose
   only state is a shade of grey is not a toggle to a screen reader. */
.filter-groups { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 8px 0 2px; }
.filter-group { border: 1px solid #ccd7df; background: #fff; color: #405566; border-radius: 999px; padding: 4px 12px; font-size: .78rem; font-weight: 650; cursor: pointer; }
.filter-group:hover { border-color: #9fb3c2; }
.filter-group.is-active { background: var(--navy); border-color: var(--navy); color: #fff; }
/* A cell that carries a status plus its reason, without the reason
   competing for attention with the badge beside it. */
.cell-stack { display: grid; gap: 2px; }
.cell-note { font-size: .74rem; color: var(--muted); }
/* Family headings in the column chooser. The list stays in the user's own
   column order; a heading appears wherever the family changes. */
.column-group { margin: 14px 0 2px; font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
/* The operational counts for exactly the rows on screen. Needs action is
   the one that is somebody's job today, so it is the one that is louder;
   everything else is a number, not an alarm. */
.summary-bar { display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: baseline; padding: 10px 16px; border: 1px solid var(--line); border-radius: 9px; background: #f7fafb; font-size: .82rem; color: #405566; }
.summary-count { white-space: nowrap; }
.table-toolbar-summary { flex: 1 1 280px; min-width: 0; display: flex; justify-content: flex-start; }
.summary-bar.is-inline { padding: 0; border: 0; background: none; gap: 4px 14px; }
.summary-bar.is-inline[hidden] { display: none; }
.summary-count.is-attention { color: #95232d; font-weight: 700; }
.summary-count.is-unknown { color: #6b5320; font-style: italic; }
.notice { padding: 14px 18px; border: 1px solid var(--notice-line); background: var(--notice-bg); color: var(--notice-ink); border-radius: 8px; font-size: .86rem; }
.notice.warning { border-color: #f0d9a6; background: #fdf3e0; color: #6b4703; }
.notice.danger { border-color: #edc6ca; background: #fff0f1; color: #7a1c24; }
/* Blocking upload rejections (Import) and non-blocking per-row staging
   warnings share this compact list shape -- a badge naming the severity
   plus the message, one per line, never a plain comma/space-joined string
   that loses which issue belongs to which severity. */
.issue-list { display: grid; gap: 7px; margin: 0; padding: 0; list-style: none; font-size: .84rem; }
.issue-list li { display: flex; gap: 8px; align-items: baseline; }
.issue-list .badge { flex-shrink: 0; }
.state { text-align: center; padding: 46px 24px; color: var(--muted); } .state h3 { color: var(--ink); } .state p { max-width: 62ch; margin: 0 auto 12px; }
.error { color: var(--danger); } .skeleton { padding: 30px; color: var(--muted); } .skeleton-line { height: 16px; margin-top: 20px; border-radius: 4px; background: linear-gradient(90deg,#edf2f5,#dce7ed,#edf2f5); background-size: 200%; animation: shimmer 1.5s infinite; }
@keyframes shimmer { to { background-position: -200%; } } @media (prefers-reduced-motion: reduce) { .skeleton-line { animation: none; } }
.modal,.drawer { border: 1px solid var(--line); box-shadow: 0 12px 70px #102a4333; color: var(--ink); padding: 0; overflow: hidden; width: min(560px,calc(100vw - 24px)); max-height: calc(100dvh - 24px); border-radius: 14px; }
dialog::backdrop { background: var(--backdrop); } .drawer { margin: 0 0 0 auto; height: 100dvh; max-height: 100dvh; width: min(580px,100vw); border-radius: 0; border-right: 0; }
.modal[open],.drawer[open] { display: flex; flex-direction: column; }
.overlay-body { min-height: 0; overflow: auto; padding: 24px 26px; overscroll-behavior: contain; }
.overlay-header { flex-shrink: 0; padding: 20px 26px; border-bottom: 1px solid var(--line); background: var(--surface); display: flex; justify-content: space-between; align-items: center; gap: 16px; } .overlay-header h2 { margin: 0; }
.detail-list { display: grid; grid-template-columns: minmax(110px,1fr) 2fr; gap: 12px; margin: 0; font-size: .9rem; } dt { color: var(--muted); } dd { margin: 0; overflow-wrap: anywhere; }
.action-group { border-top: 1px solid var(--line); padding-top: 18px; } summary { cursor: pointer; font-weight: 600; } .action-group[open] summary { margin-bottom: 16px; }
#notifications { position: fixed; bottom: 22px; right: 22px; max-width: min(440px,calc(100vw - 44px)); display: grid; gap: 8px; z-index: 30; }
/* As a popover (see Toast): undo the UA's centred, bordered popover box. */
#notifications[popover] { inset: auto 22px 22px auto; margin: 0; padding: 0; border: 0; background: transparent; overflow: visible; color: inherit; }
#notifications[popover]:not(:popover-open) { display: none; }
.toast { display: flex; gap: 16px; align-items: center; background: white; padding: 16px; border: 1px solid var(--line); border-left: 4px solid var(--accent); border-radius: 9px; box-shadow: 0 6px 32px #102a431c; }
.toast.danger { border-left-color: var(--danger); }
.table-panel { padding: 0; overflow: hidden; } .table-toolbar,.filter-bar,.pagination,.export-actions { padding: 10px 22px; display: flex; align-items: center; flex-wrap: wrap; gap: 12px; border-bottom: 1px solid var(--line); }
.table-toolbar { justify-content: space-between; } .table-toolbar h2 { margin: 0; font-size: 1rem; }
.table-toolbar-title { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.table-count { font-size: .8rem; white-space: nowrap; }
/* The toolbar IS the page heading on a single-table page: one row instead
   of a title, then a near-identical card title 70px below it. */
.table-toolbar.is-page-heading { padding: 14px 22px; background: #fcfdfe; }
.table-toolbar.is-page-heading h1 { font-size: 1.25rem; margin: 0; }
.table-toolbar.is-page-heading .table-count { font-size: .82rem; }

/* Controls are not form fields.
   `input,select { width: 100% }` above is written for FORMS, and it was
   reaching every select in the app: a toolbar select stretched to its
   container, the flex row wrapped, and "Columns / Saved views / Save view"
   stacked into three lines of chrome. Scoped back here rather than
   narrowing the global rule, which 18 pages' forms depend on. */
.table-toolbar select,.table-toolbar input,
.filter-builder select,.filter-builder input,
.export-actions select,.pagination select {
  width: auto; min-width: 9rem; min-height: 36px; padding: 6px 10px;
}
.filter-builder .filter-control-value input,.filter-builder .search-field input { min-width: 16rem; }
.table-toolbar .select-field,.filter-builder .select-field { display: flex; align-items: center; gap: 6px; }
.table-toolbar .button,.filter-builder .button { min-height: 36px; padding: 6px 12px; }

/* The Category/Condition/Value captions are already aria-hidden -- they are
   decoration, and the selects carry their own accessible names. Stacking
   them cost ~20px of every grid page for words the control itself says. */
.filter-builder .filter-control { display: flex; align-items: center; gap: 6px; }
.filter-builder .filter-control-label { display: none; }
.filter-lead { font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); flex-shrink: 0; }

/* A row is a row, not a form. The first cell's link is a <button>, and the
   global 42px control height was making every data row 57px tall -- a
   third of the table's height spent on one clickable word. */
.data-table td .button { min-height: 0; padding: 0; line-height: 1.35; text-align: left; }
.filter-add { width: 34px; min-height: 34px; padding: 0; }
.pagination,.export-actions { padding: 10px 22px; } .filter-bar { background: #fcfdfe; } .search-field { flex: 1; min-width: 180px; } .filter-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.filter-chips:empty { display: none; } .chip { border: 1px solid var(--accent-line); color: var(--accent-ink); background: var(--accent-soft); border-radius: 20px; padding: 4px 10px; font: inherit; font-size: .76rem; cursor: pointer; }
.table-scroll { overflow: auto; max-height: 65vh; } table { width: 100%; border-collapse: collapse; font-size: .86rem; table-layout: auto; }
th,td { text-align: left; padding: 8px 14px; border-bottom: 1px solid var(--line); min-width: 7rem; overflow-wrap: normal; word-break: normal; } th { background: #f6f9fb; position: sticky; top: 0; z-index: 1; font-size: .78rem; color: var(--muted); }
th.selection-column,td.selection-column { width: 44px; min-width: 44px; max-width: 44px; } tbody tr:hover { background: var(--row-hover); } .sort-button { background: none; border: 0; color: inherit; font: inherit; font-weight: 650; padding: 0; text-align: left; cursor: pointer; }
input.header-filter { min-height: 28px!important; padding: 4px!important; margin-top: 7px; } .pagination { justify-content: flex-end; border-top: 1px solid var(--line); border-bottom: 0; font-size: .82rem; } .pagination > span:first-child { margin-right: auto; }
.pagination select { min-height: 34px; } .export-actions { justify-content: flex-end; border-top: 1px solid var(--line); border-bottom: 0; } .export-actions .select-field { max-width: 180px; }
.bulk-bar { background: var(--accent-soft); padding: 12px 22px; display: flex; align-items: center; gap: 16px; } .column-setting { border-bottom: 1px solid var(--line); padding: 12px 0; display: grid; gap: 10px; } .column-setting label { display: flex; gap: 10px; align-items: center; }
.checkbox-label { display: flex; align-items: flex-start; gap: 10px; font-size: .88rem; }

/* Plain read-only tables used in drawers and admin lists (asset history,
   staging-row preview, contractor alias lists) -- distinct from the
   DataTable's own richer table styling above, which assumes its toolbar/
   filter-bar/pagination chrome around it. */
.simple-table { margin-top: 8px; display: block; max-width: 100%; overflow: auto; }
.simple-table th:first-child,.simple-table td:first-child { min-width: 12rem; }
/* A checklist's first column is its tick box, not a name: no 12rem. */
.simple-table.group-rows th:first-child,.simple-table.group-rows td:first-child { min-width: 0; width: 2.5rem; }
.simple-table.group-rows td { white-space: nowrap; }
.simple-table th, .simple-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); font-size: .86rem; }
.simple-table th { color: var(--muted); font-weight: 600; }
.data-table th,.data-table td { min-width: 0; }
.data-table .selection-column { min-width: 44px; }
.stack > * { min-width: 0; }
.overlay-header .button { flex-shrink: 0; }
.overlay-footer { flex-shrink: 0; padding: 16px 26px; border-top: 1px solid var(--line); background: var(--surface); }
.overlay-body { min-width: 0; }
.drawer { max-width: 100vw; }
body:has(dialog[open]) { overflow: hidden; }
.overlay-body h3,.overlay-body h4 { margin: 0; }
.overlay-body .badge { justify-self: start; }
.form-section { display: grid; gap: 14px; min-width: 0; }
.section-divider { border-top: 1px solid var(--line); padding-top: 24px; }
.notice p { margin: 6px 0 0; }
.editor-form textarea { width: 100%; resize: vertical; min-height: 80px; border: 1px solid #b6c5d1; border-radius: 7px; padding: 10px; font: inherit; color: var(--ink); }
.permission-groups { display: grid; gap: 8px; }
.permission-group { border: 1px solid var(--line); border-radius: 7px; }
.permission-group summary { padding: 12px; }
.permission-group summary .badge { float: right; margin-left: 10px; }
.permission-options { display: grid; gap: 14px; border-top: 1px solid var(--line); padding: 14px; }
.permission-choice small { display: block; margin-top: 3px; font-weight: 400; }
.permission-choice[hidden],.permission-group[hidden] { display: none; }
.selection-summary { margin: 0; font-weight: 600; }
.editor-form .form-error { overflow-wrap: anywhere; }
@media (max-width: 620px) { .overlay-header,.overlay-footer { padding: 14px 16px; } .overlay-body { padding: 18px 16px; } }

/* Field progress (MVP-7). A ratio ("3 / 5") plus a bar reads as progress
   at a glance; a bare number does not. The bar is decorative -- the
   accessible value is the ratio text beside it and the aria-label on the
   track, never colour alone. */
.progress-track {
  width: 100%;
  height: 6px;
  border-radius: 3px;
  background: var(--surface-sunken, #e7edf3);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: var(--accent, #087f83);
}
.stack-tight { display: grid; gap: 4px; }
.plain-list { margin: 0; padding-left: 18px; }
.detail-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 16px;
  margin: 0 0 16px;
}
.detail-grid dt { font-weight: 600; }
.detail-grid dd { margin: 0; }

/* Filter panel (every DataTable grid): Category / Condition / Value / +,
   then the Applied filters box with the AND / OR switch and removable
   chips. Outlined controls with the label sitting on the border, so the
   row reads as one sentence. See components/filter-bar.js. */
.filter-panel { padding: 10px 22px; display: grid; gap: 10px; border-bottom: 1px solid var(--line); background: #fcfdfe; }
.filter-panel[hidden], .bulk-bar[hidden] { display: none; }
.filter-builder { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.filter-builder .filter-control-value { flex: 1; min-width: 16rem; }
.filter-builder > .button.text { grid-column: 1 / -1; justify-self: start; }
.filter-control { position: relative; display: grid; min-width: 0; }
.filter-control-label { position: absolute; top: -8px; left: 9px; z-index: 2; padding: 0 5px; background: #fcfdfe; color: var(--muted); font-size: .7rem; font-weight: 600; line-height: 1; pointer-events: none; }
.filter-control:focus-within > .filter-control-label { color: var(--accent); }
.filter-control select:focus, .filter-control input:focus { border-color: var(--accent); outline: 2px solid var(--focus); outline-offset: 0; }
.filter-value-slot { min-width: 0; }
.filter-range { display: flex; gap: 8px; align-items: center; } .filter-range input { flex: 1; }
.filter-add { width: 42px; height: 42px; border-radius: 50%; border: 1.5px solid var(--accent); background: white; color: var(--accent); font-size: 1.45rem; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0 0 2px; }
.filter-add:hover { background: var(--accent); color: white; }
.value-picker { position: relative; min-width: 0; }
.value-picker-box { position: relative; }
.value-picker-box input { padding-right: 36px; }
.value-picker-toggle { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); border: 0; background: none; color: var(--muted); width: 30px; height: 30px; cursor: pointer; font-size: .9rem; }
.value-picker-list { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20; margin: 0; padding: 6px 0; list-style: none; max-height: 290px; overflow: auto; background: white; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 10px 34px #102a4324; }
.value-picker-option { display: flex; align-items: center; gap: 10px; padding: 9px 14px; font-size: .86rem; cursor: pointer; }
.value-picker-option:hover, .value-picker-option.active { background: #f0f5f8; }
.value-picker-check { width: 16px; color: var(--accent); font-weight: 700; flex-shrink: 0; }
.value-picker-label { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.value-picker-count { color: var(--muted); font-size: .76rem; }
.value-picker-status { padding: 8px 14px; color: var(--muted); font-size: .78rem; }
.value-picker-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.value-picker-tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 9px; border-radius: 12px; background: var(--accent-soft); border: 1px solid #badbd9; color: #285b60; font-size: .76rem; }
.value-picker-tag-remove { border: 0; background: none; color: inherit; cursor: pointer; font-size: .9rem; line-height: 1; padding: 0 3px; }
.applied-filters { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-height: 56px; padding: 16px 12px 11px; border: 1px solid var(--line); border-radius: 8px; }
.applied-filters-legend { position: absolute; top: -8px; left: 9px; padding: 0 5px; background: #fcfdfe; color: var(--muted); font-size: .7rem; font-weight: 600; line-height: 1; }
.applied-filters-always { font-size: .76rem; }
.applied-filters-clear { margin-left: auto; min-height: 30px; font-size: .8rem; }
.match-toggle { display: inline-flex; border: 1px solid #b6c5d1; border-radius: 6px; overflow: hidden; margin-right: 4px; }
.match-toggle button { border: 0; background: white; color: var(--muted); padding: 6px 14px; font-weight: 750; font-size: .74rem; letter-spacing: .06em; cursor: pointer; }
.match-toggle button + button { border-left: 1px solid #b6c5d1; }
.match-toggle button[aria-pressed="true"] { background: var(--accent); color: white; }
.filter-chip { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; padding: 4px 5px 4px 12px; border-radius: 16px; background: #eef2f5; border: 1px solid #d6e0e7; font-size: .8rem; color: var(--ink); }
.filter-chip-text { overflow-wrap: anywhere; } .filter-chip-text strong { font-weight: 700; }
.filter-chip-remove { flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%; border: 0; background: #5b6f80; color: white; font-size: .85rem; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0 0 1px; }
.filter-chip-remove:hover { background: var(--danger); }
@media (max-width: 950px) { .filter-builder { grid-template-columns: 1fr 1fr auto; } .filter-builder > .filter-control:nth-child(2) { grid-column: 2 / 4; } .filter-value-slot { grid-column: 1 / 3; } }
@media (max-width: 620px) { .filter-panel { padding: 18px 14px 14px; } .filter-builder { grid-template-columns: 1fr; } .filter-builder > .filter-control:nth-child(2), .filter-value-slot { grid-column: auto; } .filter-builder .filter-add { width: 100%; border-radius: 7px; } .applied-filters-clear { margin-left: 0; } }

/* Field evidence panel: building GPS, field times, location photos. */
.evidence-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.evidence-card { margin: 0; display: flex; flex-direction: column; gap: 6px; }
.evidence-card figcaption { display: flex; flex-direction: column; gap: 2px; font-size: .82rem; }
.evidence-thumb { aspect-ratio: 4 / 3; border: 1px solid var(--border, #d8dee4); border-radius: 8px; overflow: hidden; display: flex; align-items: center; justify-content: center; background: var(--surface-muted, #f3f5f7); }
.evidence-thumb a, .evidence-thumb img { display: block; width: 100%; height: 100%; }
.evidence-thumb img { object-fit: cover; }
button.evidence-thumb { padding: 0; cursor: zoom-in; width: 100%; font: inherit; }
.image-viewer { display: flex; flex-direction: column; gap: 12px; }
.image-viewer img { display: block; max-width: 100%; max-height: 70vh; margin: 0 auto; object-fit: contain; cursor: zoom-in; }


/* ADR-008 field review workspace */
.review-workspace { display: grid; grid-template-columns: minmax(220px, 270px) minmax(280px, 340px) minmax(0, 1fr); gap: 14px; align-items: start; }
.review-workspace.queue-collapsed { grid-template-columns: 46px minmax(280px, 340px) minmax(0, 1fr); }
.queue-title { display: flex; align-items: center; gap: 6px; }
.queue-title h1 { margin: 0; font-size: 1.25rem; letter-spacing: -.02em; }
.queue-toggle { margin-left: auto; font: inherit; font-size: 1.1rem; line-height: 1; font-weight: 700; color: var(--accent-strong); background: var(--background); border: 1px solid var(--line); border-radius: 8px; width: 30px; height: 30px; cursor: pointer; }
.queue-toggle:hover { border-color: var(--accent); }
.queue-collapsed .review-queue { padding: 10px 6px; }
.queue-collapsed .review-queue > :not(.queue-title), .queue-collapsed .queue-title > :not(.queue-toggle) { display: none; }
.queue-collapsed .queue-title { justify-content: center; }
.queue-collapsed .queue-toggle { margin: 0; }
.review-pane { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 14px; display: grid; gap: 12px; min-width: 0; align-content: start; }
.review-queue, .review-building { position: sticky; top: 12px; max-height: calc(100vh - 110px); overflow: auto; }
.review-queue-controls { display: grid; gap: 8px; }
.review-queue-controls input, .review-queue-controls select { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.review-queue-list { display: grid; gap: 8px; }
.queue-item { text-align: left; display: grid; gap: 5px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); cursor: pointer; font: inherit; color: inherit; }
.queue-item:hover { border-color: #9fb6c8; }
.queue-item.selected { border-color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); background: var(--accent-soft); }
.queue-item-title { display: flex; justify-content: space-between; gap: 8px; align-items: center; }
.review-queue-footer { display: flex; justify-content: space-between; align-items: center; }
.meter-bar { display: flex; height: 7px; border-radius: 4px; overflow: hidden; background: #e6ecf1; }
.meter-bar-part.accepted { background: #2f8f68; } .meter-bar-part.awaiting { background: #5b8fc7; }
.meter-bar-part.returned { background: #c0392b; } .meter-bar-part.rejected { background: #7d6b91; }
.flag-pills { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.flag-pill { font-size: .72rem; font-weight: 700; padding: 1px 6px; border-radius: 10px; border: 1px solid transparent; }
.flag-pill.blocking { background: #fff0f1; color: #95232d; border-color: #edc6ca; }
.flag-pill.warning { background: #fdf3e0; color: #8a5a05; border-color: #f0d9a6; }
.flag-pill.info { background: #eef4fb; color: #1f4b7a; border-color: #c3d8ee; }
.review-building-head h2, .review-packet-head h2 { margin: 0; }
.review-building-head, .review-packet-head { display: grid; gap: 6px; }
.detail-list.compact { grid-template-columns: max-content 1fr; gap: 4px 12px; font-size: .84rem; }
.review-section summary { cursor: pointer; font-weight: 650; }
.flag-list { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 6px; }
.flag { display: grid; grid-template-columns: 74px 1fr; gap: 8px; padding: 7px 9px; border-radius: 8px; border-left: 4px solid; font-size: .86rem; }
.flag.blocking { background: #fff6f6; border-color: #c0392b; } .flag.warning { background: #fffaf0; border-color: #d99a1e; } .flag.info { background: #f4f8fc; border-color: #6d9ccf; }
.flag-severity { font-size: .7rem; font-weight: 750; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding-top: 2px; }
.link-button { background: none; border: 0; padding: 0; color: var(--accent-strong); cursor: pointer; font: inherit; text-decoration: underline; text-underline-offset: 3px; }
.review-clean { color: #216047; margin: 6px 0 0; }
.cross-section { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-start; }
.cross-section .tower, .cross-section .outdoor { display: grid; gap: 6px; min-width: 200px; flex: 1; }
.cross-section h3 { margin: 0; font-size: .82rem; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.building-stack { display: grid; gap: 3px; padding: 6px; border: 2px solid #b8c7d4; border-radius: 10px 10px 4px 4px; background: #f7fafc; }
.outdoor-stack { border-style: dashed; border-radius: 10px; }
.floor-bar { display: grid; grid-template-columns: minmax(70px, auto) 1fr auto; gap: 8px; align-items: center; padding: 8px 10px; border-radius: 6px; border: 1px solid transparent; cursor: pointer; font: inherit; text-align: left; color: var(--ink); }
.floor-bar-label { font-weight: 700; } .floor-bar-meta { font-size: .78rem; color: var(--muted); }
.floor-bar.selected { outline: 3px solid var(--accent); outline-offset: 1px; }
.state-not_reviewed { background: #eef2f5; } .state-in_review { background: #e5eef8; } .state-needs_re_review { background: #fdf0d9; }
.state-partially_returned { background: #fbe3e5; } .state-approved { background: #e2f3ea; }
.state-no_meters, .state-no_water_meters, .state-does_not_exist { background: repeating-linear-gradient(45deg, #f4f6f8, #f4f6f8 6px, #eceff2 6px, #eceff2 12px); color: var(--muted); }
.ground-line { border-top: 3px solid #8b6d4b; margin: 4px -6px; font-size: .66rem; color: #8b6d4b; text-transform: uppercase; letter-spacing: .12em; padding-left: 8px; }
.review-legend { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.legend-swatch { padding: 1px 7px; border-radius: 4px; }
.review-phase-note { padding: 8px 12px; border-radius: 8px; background: #f4f8fc; border: 1px solid #c3d8ee; font-size: .85rem; color: #1f4b7a; }
.location-card { border: 1px solid var(--line); border-radius: 10px; padding: 12px; display: grid; gap: 10px; border-left-width: 5px; scroll-margin-top: 12px; transition: box-shadow .3s; background: var(--surface); }
.location-card.state-approved { border-left-color: #2f8f68; background: var(--surface); }
.location-card.state-partially_returned { border-left-color: #c0392b; background: var(--surface); }
.location-card.state-in_review { border-left-color: #5b8fc7; background: var(--surface); }
.location-card.state-needs_re_review { border-left-color: #d99a1e; background: var(--surface); }
.location-card.state-not_reviewed, .location-card.state-no_meters { background: var(--surface); }
.location-card.highlight { box-shadow: 0 0 0 3px var(--accent); }
.location-card-head { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.location-card-head h3 { margin: 0; }
.review-photo-strip { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
.review-photo { margin: 0; width: 120px; flex: 0 0 120px; display: grid; gap: 4px; font-size: .74rem; }
.review-photo figcaption { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; color: var(--muted); }
.review-thumb { aspect-ratio: 4 / 3; }
.review-photo.missing .review-thumb { border: 2px dashed #d98a8f; color: #95232d; background: #fff6f6; font-size: .74rem; }
.review-meters td, .review-meters th { font-size: .84rem; white-space: nowrap; padding-top: 4px; padding-bottom: 4px; }
.review-meters td .cell-note { white-space: normal; }
.image-viewer-head { display: flex; justify-content: space-between; gap: 12px; }
@media (max-width: 1000px) {
  .review-workspace { grid-template-columns: minmax(220px, 300px) minmax(0, 1fr); }
  .review-workspace:not(.queue-collapsed) .review-packet { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
  .review-workspace { grid-template-columns: 1fr; }
  .review-queue, .review-building { position: static; max-height: none; }
}

/* Field review: coverage view */
.review-view-controls { display: grid; gap: 8px; }
.segmented { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; justify-self: start; }
.segmented .chip { border: 0; border-radius: 0; }
.chip-row { display: flex; gap: 6px; flex-wrap: wrap; }
.chip { font: inherit; font-size: .8rem; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); cursor: pointer; }
.chip.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); font-weight: 650; }
.coverage-alert { padding: 8px 10px; border-radius: 8px; background: #fff0f1; border: 1px solid #edc6ca; color: #7d1d26; font-size: .84rem; display: grid; gap: 4px; }
.coverage-alert.ok { background: #e9f6f0; border-color: #bedfd0; color: #1d553f; }
.floor-bar.coverage { grid-template-columns: 70px minmax(0, 1fr) minmax(70px, auto); background: var(--surface); border-color: var(--line); }
.coverage-rows { display: grid; gap: 3px; min-width: 0; }
.coverage-row { display: flex; gap: 3px; height: 12px; align-items: stretch; min-width: 0; }
.coverage-row.big { height: 24px; }
.coverage-tech { flex: 0 0 58px; font-size: .64rem; color: var(--muted); line-height: 12px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.coverage-seg { flex: 1 1 0; min-width: 6px; border-radius: 3px; font-size: .7rem; font-weight: 650; display: flex; align-items: center; justify-content: center; overflow: hidden; white-space: nowrap; }
.coverage-dot { display: inline-block; width: 10px; height: 10px; border-radius: 3px; vertical-align: -1px; }
.coverage-chip { font-size: .76rem; font-weight: 650; padding: 2px 8px; border-radius: 6px; }
.tone-best { background: #2f7d32; color: #fff; } .tone-good { background: #9ccc65; color: #1b3a06; }
.tone-marginal { background: #f0a92b; color: #3d2500; } .tone-gap { background: #d64541; color: #fff; }
.tone-unknown, .tone-not-measured { background: #d5dbe0; color: #3b4a56; }
.tone-not-surveyed { background: repeating-linear-gradient(45deg, #e3e7eb, #e3e7eb 4px, #f3f5f7 4px, #f3f5f7 8px); color: #56636e; }
.tone-empty { background: transparent; color: var(--muted); font-weight: 400; justify-content: flex-start; }
.cross-section.coverage-mode .tower, .cross-section.coverage-mode .outdoor { min-width: 260px; }
.has-hint { cursor: help; border-bottom: 1px dotted var(--muted); }

/* Field review: numbers as tiles, and the radio survey panel */
.stat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 8px; }
.stat-tile { display: grid; gap: 1px; padding: 8px 10px; border-radius: 10px; background: var(--background); border: 1px solid var(--line); }
.stat-tile .stat-value { font-size: 1.25rem; font-weight: 750; line-height: 1.1; letter-spacing: -.02em; }
.stat-tile .stat-label { font-size: .7rem; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; font-weight: 650; }
.stat-tile .stat-note { font-size: .7rem; color: var(--muted); }
.stat-tile.positive { background: #eef8f3; border-color: #cfe7db; } .stat-tile.positive .stat-value { color: #216047; }
.stat-tile.progress { background: #f0f5fb; border-color: #cfdef0; } .stat-tile.progress .stat-value { color: #1f4b7a; }
.stat-tile.attention { background: #fff3f4; border-color: #f0cfd2; } .stat-tile.attention .stat-value { color: #95232d; }
.stat-tile.warning { background: #fdf6e8; border-color: #f0dfb8; } .stat-tile.warning .stat-value { color: #8a5a05; }
.queue-item { transition: border-color .15s, box-shadow .15s, transform .15s; }
.queue-item:hover { box-shadow: 0 4px 14px #102a4312; transform: translateY(-1px); }
.location-card { box-shadow: 0 1px 2px #102a430a; transition: box-shadow .2s; }
.location-card:hover { box-shadow: 0 6px 20px #102a4314; }
.location-card-head h3 { font-size: 1.05rem; }
.rf-badge-button { cursor: pointer; font: inherit; font-size: .74rem; font-weight: 650; gap: 2px; align-items: center; transition: filter .15s, box-shadow .15s; }
.rf-badge-button:hover { filter: brightness(.97); box-shadow: 0 2px 8px #102a4318; }
.rf-badge-more { font-weight: 800; }
.coverage-chip.clickable { border: 0; font: inherit; font-size: .76rem; font-weight: 650; cursor: pointer; }
.coverage-chip.clickable:hover { filter: brightness(.95); }
.radio-dialog { width: min(1040px, calc(100vw - 24px)); }
.radio-panel { display: grid; gap: 18px; }
.radio-captures { display: grid; gap: 14px; }
.radio-captures.two { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.radio-capture { display: grid; gap: 10px; padding: 16px; border: 1px solid var(--line); border-radius: 12px; border-top: 5px solid #d5dbe0; background: linear-gradient(180deg, var(--background), var(--surface) 60%); }
.tone-edge-best { border-top-color: #2f7d32; } .tone-edge-good { border-top-color: #9ccc65; } .tone-edge-marginal { border-top-color: #f0a92b; } .tone-edge-gap { border-top-color: #d64541; }
.radio-capture-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.radio-capture-scope { font-size: .72rem; font-weight: 750; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.radio-headline { display: flex; align-items: baseline; gap: 8px; }
.radio-rsrp { font-size: 2.6rem; font-weight: 800; letter-spacing: -.04em; line-height: 1; }
.radio-unit { color: var(--muted); font-weight: 650; font-size: .85rem; }
.signal-track { display: block; height: 8px; border-radius: 99px; background: #e6eaee; overflow: hidden; }
.signal-track.small { height: 6px; width: 90px; flex: 0 0 90px; }
.signal-fill { display: block; height: 100%; border-radius: 99px; }
.radio-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin: 0; }
.radio-stats > div { padding: 8px; border-radius: 8px; background: var(--surface); border: 1px solid var(--line); min-width: 0; }
.radio-stats dt { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 650; }
.radio-stats dd { font-weight: 700; font-size: .92rem; overflow-wrap: anywhere; }
.radio-meta { display: flex; flex-wrap: wrap; gap: 6px; }
.radio-meta-item { font-size: .78rem; padding: 3px 9px; border-radius: 99px; background: var(--surface); border: 1px solid var(--line); }
.radio-table-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.radio-table-holder { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; }
.radio-readings { margin: 0; }
.radio-readings th, .radio-readings td { font-size: .84rem; white-space: nowrap; padding: 7px 10px; }
.radio-readings tbody tr:nth-child(even) td { background: #fafbfc; }
.radio-readings tr.representative td { background: var(--accent-soft); font-weight: 650; }
.radio-rsrp-cell { display: flex; align-items: center; gap: 8px; }
.radio-table-switches { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.radio-tech-tabs .chip { font-weight: 650; }
.radio-tech-summary { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; font-size: .86rem; }
.radio-readings .radio-cell-col { color: var(--muted); font-variant-numeric: tabular-nums; }
.radio-empty { margin: 0; padding: 18px; color: var(--muted); text-align: center; }
@media (max-width: 620px) { .radio-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .radio-rsrp { font-size: 2.1rem; } }

/* Field review: floor summaries, floor coverage, coverage report */
.floor-summary { grid-template-columns: minmax(70px, auto) 1fr auto; row-gap: 5px; }
.floor-mini-coverage { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; min-width: 0; }
.mini-strip { display: flex; gap: 2px; flex: 1; height: 7px; min-width: 0; }
.mini-seg { flex: 1 1 0; min-width: 4px; border-radius: 2px; }
.mini-worst { font-size: .7rem; color: var(--muted); white-space: nowrap; }
.floor-list-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.review-building .stat-tiles { grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: 6px; }
.review-building .stat-tile { padding: 6px 8px; } .review-building .stat-tile .stat-value { font-size: 1.1rem; }
.building-details-head { margin: 6px 0 0; padding-top: 10px; border-top: 1px solid var(--line); font-size: .82rem; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.floor-list-head h3 { margin: 0; font-size: .82rem; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.building-coverage-line { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: .8rem; }
.floor-coverage { display: grid; gap: 8px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: linear-gradient(180deg, var(--background), var(--surface)); }
.floor-coverage-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.floor-coverage-head h3 { margin: 0; font-size: .95rem; }
.coverage-matrix-holder { overflow-x: auto; }
.coverage-matrix { margin: 0; }
.coverage-matrix th, .coverage-matrix td { font-size: .8rem; white-space: nowrap; padding: 5px 8px; }
.coverage-matrix tr.clickable { cursor: pointer; }
.coverage-matrix tr.clickable:hover td { background: var(--accent-soft); }
.coverage-report { display: grid; gap: 14px; }
.coverage-report-bar { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.coverage-report .coverage-row { height: 20px; gap: 4px; }
.coverage-report .coverage-row.big { height: 28px; }
.coverage-report .coverage-tech { flex-basis: 64px; line-height: 20px; font-size: .7rem; }
.coverage-report .coverage-seg { justify-content: flex-start; padding: 0 8px; font-size: .72rem; font-weight: 600; }
.coverage-report .coverage-row.big .coverage-seg { justify-content: center; font-size: .82rem; }
.coverage-seg .seg-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.coverage-report .floor-bar.coverage { grid-template-columns: 90px minmax(0, 1fr) minmax(110px, auto); padding: 10px 12px; }
.coverage-report .floor-bar-meta { font-size: .78rem; }
.coverage-report-subhead { margin: 4px 0 0; font-size: .95rem; }

/* Field review: decisions */
.decision-bar { position: sticky; top: 0; z-index: 3; display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: #f7fafc; }
.decision-bar-count { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.review-meters .select-col { width: 28px; padding-right: 0; }
.review-meters tr.selected-row td { background: var(--accent-soft); }
.checked-badge { margin-left: 4px; }
.decision-dialog .field { display: grid; gap: 4px; }
.decision-dialog select, .decision-dialog textarea { width: 100%; padding: 8px; border: 1px solid var(--line); border-radius: 8px; font: inherit; }
.decision-flags { padding: 8px 10px; border-radius: 8px; display: grid; gap: 6px; }
.decision-flags.blocking { background: #fff6f6; border: 1px solid #edc6ca; } .decision-flags.warning { background: #fffaf0; border: 1px solid #f0d9a6; }
.checkbox-line { display: flex; gap: 8px; align-items: center; font-weight: 600; }
.form-error { color: var(--danger); margin: 0; min-height: 1em; }

/* Settings: appearance and project configuration */
.setting-row { display: flex; flex-wrap: wrap; gap: 12px 24px; justify-content: space-between; align-items: flex-start;
  padding: 14px 0; border-bottom: 1px solid var(--line); }
.setting-row:last-child { border-bottom: 0; }
.setting-row > div:first-child { flex: 1 1 320px; max-width: 60ch; }
.setting-value { display: grid; gap: 6px; justify-items: end; text-align: right; }
.setting-current { font-weight: 600; max-width: 46ch; overflow-wrap: anywhere; }
.setting-key { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .72rem; }
.settings-group { border-top: 1px solid var(--line); padding: 6px 0; }
.settings-group > summary { cursor: pointer; font-weight: 650; padding: 10px 0; }
.settings-head { justify-content: flex-start; }
.setting-dialog { min-width: min(720px, 80vw); }
.setting-fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.setting-fieldset > legend { padding: 0 6px; font-weight: 650; }
.count-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 8px 18px; }
.count-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.count-row input, .count-row select { width: 8.5rem; }
.reason-row { display: flex; gap: 8px; align-items: center; }
.reason-row input:first-child { width: 12rem; }
.reason-row input:nth-child(2) { flex: 1; }
.coverage-class-row { display: grid; gap: 6px; padding: 8px 0; border-bottom: 1px dashed var(--line); }
.setting-json { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .76rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.setting-json-editor { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .8rem; width: 100%; }
.setting-history li { padding: 8px 0; border-bottom: 1px solid var(--line); }

/* Field review Phase B part 2: sign-off, claims, outcomes */
.signoff-line { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.claim-banner { margin-top: 8px; padding: 8px 12px; border-radius: 8px; background: var(--accent-soft); color: var(--ink); font-size: .88rem; }
.claim-marker { color: var(--muted); }
.outcome-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 4px 6px; border-radius: 6px; }
.outcome-list li.selected-row { background: var(--accent-soft); }


/* THE PROJECT MAP.

   The map IS the page: it fills from under the top bar to the bottom of
   the window, and every control floats over it. A control panel above the
   map pushed the one thing people opened the page to look at below the
   fold -- on a map, the content is the whole surface.

   The negative margin cancels .main-content's padding so the map reaches
   the edges; the height leaves room for the top bar and the workspace
   footer, which are the only other things on screen. */
.map-page { position: relative; margin: -32px; height: calc(100dvh - 150px); min-height: 460px; overflow: hidden; background: #dfe6ec; }
.map-canvas { position: absolute; inset: 0; height: 100%; }
.map-canvas .leaflet-container { font: inherit; }

/* One card, top left, holding what a reader changes. Glass over the map
   rather than a panel beside it: it covers a corner of Abu Dhabi, not a
   third of the screen. */
/* THE TRANSPARENCY RULE: every card over the map is glass at rest -- the
   streets show through it, softened -- and turns solid the moment a
   pointer or keyboard reaches for it. The map is the content; the cards
   only get to be opaque while somebody is actually using them. */
.map-controls-float, .map-status-float, .map-legend {
  background: rgba(255, 255, 255, .72); backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid rgba(255, 255, 255, .7); box-shadow: 0 8px 28px rgba(16, 42, 67, .16);
  transition: background .18s ease, box-shadow .18s ease; }
.map-controls-float:hover, .map-controls-float:focus-within,
.map-status-float:hover,
.map-legend:hover, .map-legend:focus-within { background: rgba(255, 255, 255, .96); box-shadow: 0 10px 32px rgba(16, 42, 67, .22); }
.map-controls-float { position: absolute; z-index: 500; top: 14px; left: 14px; width: 236px; display: grid; gap: 6px;
  padding: 10px 12px; border-radius: 14px; }
.map-card-body { display: grid; gap: 6px; }
.map-controls-float.collapsed { width: auto; }
.map-controls-float.collapsed .map-card-body { display: none; }

/* A card's own header is the button that folds it. */
.map-card-head { display: inline-flex; align-items: center; gap: 6px; padding: 2px 0; border: 0; background: none; font: inherit; color: var(--ink); cursor: pointer; }
.map-card-head strong { font-size: .76rem; text-transform: uppercase; letter-spacing: .08em; }
.map-chevron { display: inline-block; font-size: .8rem; color: var(--muted); transition: transform .18s ease; }
.collapsed .map-chevron { transform: rotate(-90deg); }
.map-fade input[type=range] { width: 118px; accent-color: var(--accent); }
.map-select > span { white-space: nowrap; }
.map-controls-title { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--muted); }
.map-controls-title .button.text { padding: 0; font-size: .78rem; }
.map-controls-divider { height: 1px; background: var(--line); margin: 3px 0; }
.map-toggle { display: flex; align-items: center; gap: 8px; font-size: .85rem; padding: 6px 8px; border-radius: 8px; border: 1px solid transparent; cursor: pointer; }
.map-toggle:hover { background: var(--accent-soft); }
.map-toggle input { accent-color: var(--accent); }
.map-toggle-count { margin-left: auto; font-size: .76rem; color: var(--muted); font-variant-numeric: tabular-nums; }
/* A coloured edge on each switch, so the legend and the switch agree. */
.map-toggle.tone-taqa { box-shadow: inset 3px 0 0 #5b6b7d; }
.map-toggle.tone-track { box-shadow: inset 3px 0 0 #1f77b4; }
.map-toggle.tone-surveyed { box-shadow: inset 3px 0 0 var(--accent); }
.map-select { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: .82rem; color: var(--muted); padding: 2px 8px; }
.map-select select { font: inherit; font-size: .82rem; color: var(--ink); border: 1px solid var(--line); border-radius: 7px; padding: 3px 6px; background: var(--surface); }

/* What is on screen, top right, in one line. */
.map-status-float { position: absolute; z-index: 500; top: 14px; right: 14px; max-width: 320px; display: grid; gap: 2px;
  padding: 10px 14px; border-radius: 14px; }
.map-status-title { font-weight: 700; font-size: .92rem; }
.map-status-float .cell-note { margin: 0; }

/* The legend sits out of the way, bottom left, above Leaflet's own
   attribution. */
.map-legend { position: absolute; z-index: 500; left: 14px; bottom: 30px; display: grid; gap: 5px; font-size: .76rem; color: var(--ink);
  padding: 8px 12px; border-radius: 14px; }
.map-legend.collapsed { padding: 6px 12px; }
.map-legend-row { display: flex; flex-wrap: wrap; gap: 5px 12px; align-items: center; }
.map-legend-class { display: inline-flex; align-items: center; gap: 5px; }
.map-key { display: inline-block; width: 11px; height: 11px; border-radius: 50%; background: #fff; border: 2px solid #5b6b7d; }
.map-key.track { background: #1f77b4; border-color: #1f77b4; }
.map-key.line { width: 16px; height: 0; border: 0; border-top: 2px dashed #c0392b; border-radius: 0; }
.map-legend[data-tiles="unreachable"]::after { content: 'No basemap: this network cannot reach the tile server. The data layers are unaffected.'; color: #8a5a05; max-width: 260px; }

.map-page .leaflet-bottom.leaflet-right .leaflet-control-zoom { margin: 0 14px 30px 0; border: 1px solid rgba(255, 255, 255, .7);
  border-radius: 12px; overflow: hidden; box-shadow: 0 8px 28px rgba(16, 42, 67, .16); }
.map-page .leaflet-control-zoom a { background: rgba(255, 255, 255, .82); backdrop-filter: blur(10px); color: var(--ink); }
.map-page .leaflet-control-zoom a:hover { background: #fff; }
.map-page .leaflet-control-attribution { background: rgba(255, 255, 255, .6); border-radius: 6px 0 0 0; }

/* A building's own panel, over the map from the right. It takes the
   corner the summary was using, so the two never stack on each other. */
.map-page.panel-open .map-status-float { display: none; }
.map-panel { display: none; }
.map-panel.open { display: grid; gap: 12px; position: absolute; z-index: 600; top: 14px; right: 14px; bottom: 14px; width: min(390px, calc(100% - 28px));
  padding: 16px; border-radius: 12px; border: 1px solid var(--line); background: rgba(255, 255, 255, .97); backdrop-filter: blur(8px);
  box-shadow: 0 10px 34px rgba(16, 42, 67, .24); overflow: auto; align-content: start; }
.map-panel-head { display: flex; justify-content: space-between; gap: 8px; align-items: flex-start; }
.map-panel-head h2 { margin: 0; font-size: 1.05rem; }

/* The headline a building opens with: its coverage, in the colour the pin
   was drawn in, so the map and the panel cannot disagree. */
.map-coverage-hero { display: grid; gap: 2px; padding: 12px 14px; border-radius: 10px; color: #fff; background: var(--hero, #6b7a8c); }
.map-coverage-hero .cell-note { color: rgba(255, 255, 255, .85); }
.map-coverage-label { font-size: 1.15rem; font-weight: 700; }
.map-stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.map-stat { display: grid; gap: 1px; padding: 8px 6px; text-align: center; border: 1px solid var(--line); border-radius: 8px; }
.map-stat-value { font-size: 1.1rem; font-weight: 700; }
.map-flagged { color: #95232d; font-weight: 650; }
.map-rooms { display: grid; gap: 8px; padding-left: 0; list-style: none; }
.map-rooms > li { padding: 8px 10px; border: 1px solid var(--line); border-radius: 9px; }
.map-room-head { display: flex; justify-content: space-between; gap: 8px; align-items: center; }

@media (max-width: 1200px) { .map-page { margin: -24px; height: calc(100dvh - 134px); } }
@media (max-width: 760px) {
  .map-controls-float { width: calc(100% - 28px); }
  .map-status-float { display: none; }
  /* A sheet from the bottom, because a column beside the map is most of a
     phone. */
  .map-panel.open { top: auto; left: 14px; right: 14px; bottom: 14px; width: auto; max-height: 62%; }
  .map-legend { display: none; }
}
@media (max-width: 620px) { .map-page { margin: -22px -16px; height: calc(100dvh - 120px); } }
