/* Demetra primitive component styles. Token-driven. */

/* Buttons */
.dm-btn {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  padding: 6px 14px;
  border-radius: var(--radius-sm);
  border: var(--border-thin);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.dm-btn:hover            { background: var(--bg-soft); }
.dm-btn[disabled]        { opacity: 0.5; cursor: not-allowed; }
.dm-btn--primary         { background: var(--navy); color: #fff; border-color: var(--navy); }
.dm-btn--primary:hover   { background: var(--navy-deep); }
.dm-btn--secondary       { background: var(--bg-soft); }
.dm-btn--tertiary        { background: transparent; border-color: transparent; }
.dm-btn--destructive     { background: var(--error); color: #fff; border-color: var(--error); }

/* Sidebar buttons (LayerPanel).
   Lighthouse 2026-04-30 flagged these as failing target-size (< 24×24 CSS
   px) — they shipped with browser-default styling (Arial, gray bg, ~21 px
   tall). The rule below matches the dm-btn token family and brings the
   button to ≥ 28 px hit area. Phase 2 D2 dropped the .dm-criteria__add /
   .dm-criteria__run / .dm-criteria__reset / .dm-criteria__actions /
   .crit-val--disabled rules — the old form-row CriteriaBuilder DOM they
   targeted was replaced by the sentence-style cards (see
   .demetra-criteria-builder rules below). */
.dm-layers__add {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  min-height: 28px;
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  border: var(--border-thin);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.dm-layers__add:hover { background: var(--bg-soft); }

.dm-layers__domain-head {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  min-height: 28px;
  padding: 4px 8px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: transparent;
  border: 0;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.dm-layers__domain-head:hover { background: var(--bg-soft); }

/* Phase 3.1 (closes B1): per-layer error state.
   When a layer fetch fails (e.g. zones.json.gz 404 from R2), the reducer
   sets state.layers.errors[layerId] and the LayerPanel renders the row
   with .dm-layer-toggle--errored + a .dm-layer-error-dot. The dot is
   accessible (role=img + aria-label carrying the message); the row also
   carries title= for tooltip. WCAG 2.2 AA: not colour-only — italic name +
   ● glyph + tooltip provide three redundant signals. */
.dm-layer-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px 8px;
  font-size: var(--fs-base);
}
.dm-layer-error-dot {
  color: var(--coral);
  margin-left: 4px;
  cursor: help;
  font-size: var(--fs-md);
  line-height: 1;
}
.dm-layer-toggle--errored .dm-layer-name {
  font-style: italic;
  color: var(--muted);
}

/* Phase 3.4 (closes B5): per-layer load spinner. Rendered next to the layer
 * row while LAYER_LOADING is active and the matching LAYER_LOADED has not yet
 * dispatched. The teal top-color matches our existing .dm-loading__spinner
 * pattern; we keep this one smaller (10×10) so it sits inline beside the
 * checkbox label without disturbing the row height. Kept token-driven so a
 * theme tweak to --teal / --muted updates everything. */
.layer-spinner {
  display: inline-block;
  width: 10px;
  height: 10px;
  border: 2px solid var(--muted, #888);
  border-top-color: var(--teal, #2a9d8f);
  border-radius: 50%;
  animation: layer-spin 0.8s linear infinite;
  margin-left: 4px;
  vertical-align: middle;
}
@keyframes layer-spin { to { transform: rotate(360deg); } }

/* Form controls */
.dm-input, .dm-select {
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  padding: 6px 10px;
  border: var(--border-medium);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--ink);
}
.dm-input:focus, .dm-select:focus { border-color: var(--teal); }
.dm-input--cmdk        { width: 100%; padding: var(--space-2) var(--space-3); font-size: var(--fs-md); }

/* Phase 4.3 (closes QA findings C7 + C14): parcel-search input + styled
 * inline error for ParcelSearch.js. Width:100% lets the input fill the
 * sidebar column so the placeholder is never truncated by the gutter,
 * even at the 280px collapsed-section default. The error <p> sits below
 * the input in coral so a "Parcel not found" lookup result is visible
 * instead of unstyled black text. role="alert" is on the element. */
.dm-search                      { display: flex; flex-direction: column; gap: 4px; }
.dm-search__input               { width: 100%; }
.dm-search__error,
.parcel-search__error,
.dm-search-v2__error            {
  color: var(--coral, #e07a5f);
  font-size: var(--fs-sm);
  margin: 4px 0 0 0;
  line-height: 1.3;
}

/* Parcel search v2 — cascading composite search + Google Maps URL paste.
 * Replaces the bare parcel-ID typing input. Vertical layout (one field per
 * row) so it fits the 280 px sidebar without horizontal scroll. Focus +
 * disabled states inherit from .dm-input / .dm-select. */
.dm-search-v2                   { display: flex; flex-direction: column; gap: 6px; }
.dm-search-v2__row,
.dm-search-v2__form,
.dm-search-v2__paste,
.dm-search-v2__advanced { display: flex; flex-direction: column; gap: 4px; }
.dm-search-v2__label {
  font-size: var(--fs-xs); color: var(--muted, #5b6473);
  margin-bottom: 2px;
  font-weight: 500;
}
.dm-search-v2__field            { display: flex; flex-direction: column; gap: 2px; }
.dm-search-v2__paste-row        { display: flex; gap: 4px; align-items: stretch; }
.dm-search-v2__paste-row .dm-input { flex: 1; min-width: 0; }
.dm-search-v2__go               { min-width: 48px; flex: 0 0 auto; }
.dm-search-v2__hint {
  font-size: 11px; color: var(--muted, #5b6473);
  margin: 2px 0 0 0; line-height: 1.3;
}
.dm-search-v2__divider {
  font-size: var(--fs-xs); color: var(--muted, #5b6473);
  text-transform: uppercase; letter-spacing: 0.04em;
  margin: 4px 0 2px 0; padding-top: 8px;
  border-top: 1px solid var(--border-thin-color, #e5e7eb);
  text-align: center;
}
.dm-search-v2__submit { margin-top: 6px; min-height: 32px; }
/* Use --teal-deep (not --teal) for text-on-surface use: --teal #2a9d8f only
 * yields 3.10:1 on --bg-soft #f6f7f9, failing WCAG 2.2 AA (needs >= 4.5:1
 * for normal text). --teal-deep #1f7a70 yields 4.81:1 on the same surface. */
.dm-search-v2__advanced-toggle {
  background: transparent; border: 0; padding: 6px 0; margin-top: 4px;
  font-size: var(--fs-xs); color: var(--teal-deep, #1f7a70);
  text-align: left; cursor: pointer; min-height: 28px;
}
.dm-search-v2__advanced-toggle:hover { text-decoration: underline; }
.dm-search-v2__advanced { gap: 4px; }
.dm-search-v2__advanced .dm-input { width: 100%; }

/* SearchableSelect — combo input with substring filter dropdown. Compact
 * form factor (no clear button overlap with input padding); options scroll
 * inside .dm-ss__dropdown which is positioned absolutely so it doesn't
 * push other fields down. */
.dm-ss                          { position: relative; }
.dm-ss__input {
  width: 100%; padding: 6px 24px 6px 8px;
  border: var(--border-thin); border-radius: var(--radius-sm);
  background: var(--bg, #fff); color: var(--ink, #15171c);
  font-size: var(--fs-sm, 13px); min-height: 32px;
  font-family: var(--font-sans);
}
.dm-ss__input:focus { outline: 2px solid var(--teal, #2a9d8f); outline-offset: 1px; border-color: var(--teal, #2a9d8f); }
.dm-ss--disabled .dm-ss__input,
.dm-ss__input[disabled] { background: var(--bg-soft, #f3f4f6); cursor: not-allowed; opacity: 0.7; }
.dm-ss__clear {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: transparent; border: 0; cursor: pointer; padding: 0 4px;
  font-size: 16px; color: var(--muted, #5b6473);
}
.dm-ss__clear:hover { color: var(--ink, #15171c); }
.dm-ss__dropdown {
  position: absolute; top: calc(100% + 2px); left: 0; right: 0;
  z-index: 30;
  max-height: 240px; overflow-y: auto;
  background: var(--bg, #fff);
  border: var(--border-thin); border-radius: var(--radius-sm);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  font-size: var(--fs-sm, 13px);
}
.dm-ss__option {
  padding: 6px 8px; cursor: pointer; min-height: 30px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dm-ss__option:hover               { background: var(--bg-soft, #f3f4f6); }
.dm-ss__option--selected           { background: var(--bg-soft, #f3f4f6); font-weight: 600; }
.dm-ss__more,
.dm-ss__nomatch {
  padding: 6px 8px; font-size: var(--fs-xs, 12px);
  color: var(--muted, #5b6473); font-style: italic;
}
.dm-checkbox           { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--fs-base); }
.dm-toggle             {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: none; border: none; cursor: pointer; font-size: var(--fs-base);
}
.dm-toggle__thumb {
  width: 28px; height: 16px; border-radius: 8px; background: #d1d5db; position: relative;
  transition: background var(--dur-fast) var(--ease-out);
}
/* benign: decorative-only — empty content, draws toggle switch thumb dot */
.dm-toggle__thumb::after {
  content: ""; position: absolute; left: 2px; top: 2px;
  width: 12px; height: 12px; border-radius: 50%; background: #fff;
  transition: transform var(--dur-fast) var(--ease-out);
}
.dm-toggle--on .dm-toggle__thumb         { background: var(--teal); }
.dm-toggle--on .dm-toggle__thumb::after  { transform: translateX(12px); }

/* KPI card */
.dm-kpi {
  background: var(--bg-soft);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  text-align: center;
}
.dm-kpi__num   { font-size: var(--fs-xl); font-weight: 700; color: var(--navy); line-height: 1.1; }
.dm-kpi__label { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-top: var(--space-1); }
.dm-kpi--gradient {
  background: linear-gradient(135deg, var(--navy) 0%, var(--teal) 100%);
  color: #fff;
}
.dm-kpi--gradient .dm-kpi__num   { color: #fff; }
.dm-kpi--gradient .dm-kpi__label { color: rgba(255,255,255,0.85); }

/* Clickable KPI card — Stats tab tiles that map to a find criterion.
   Phase 2.9 (closes QA finding C10). Looks identical to .dm-kpi by default,
   adds hover + focus affordances so users discover the actionable filter. */
button.dm-kpi--clickable {
  display: block;
  width: 100%;
  border: var(--border-thin);
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
button.dm-kpi--clickable:hover {
  background: #eef0f4;
  border-color: var(--teal);
}
button.dm-kpi--clickable:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

/* Stats tab grid — 2-up tiles inside the right drawer (≥320px wide).
   Phase 2.9: extended from 4 → 6 tiles (added blockers + constraints).
   The drawer is narrow so we cap at 2 columns; tiles wrap. */
.dm-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-2);
  padding: var(--space-3) 0;
}

/* Methodology badge */
.dm-method-badge        { display: inline-block; position: relative; margin-left: var(--space-2); }
.dm-method-badge__btn   {
  background: none; border: none; cursor: pointer;
  color: var(--muted); font-size: var(--fs-sm);
}
.dm-method-badge__pop {
  position: absolute; right: 0; top: 100%;
  background: var(--bg); border: var(--border-thin);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-md);
  padding: var(--space-2) var(--space-3); width: 280px; z-index: 40;
  font-size: var(--fs-sm);
}

/* Empty / Loading / Error */
.dm-empty, .dm-loading {
  text-align: center; padding: var(--space-6) var(--space-4); color: var(--muted);
}
.dm-empty__title  { color: var(--ink); margin: 0 0 var(--space-1); font-size: var(--fs-md); }
.dm-empty__body   { font-size: var(--fs-base); }
.dm-empty__icon   { font-size: var(--fs-2xl); margin-bottom: var(--space-2); }

/* Visually-hidden helper for screen-reader-only content (e.g. landmark
 * h1 that the design doesn't show but axe-core demands). Keeps element
 * focusable/announceable but takes 1×1px out of the visual flow. */
.dm-sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap;
  border: 0;
}

.dm-loading__spinner {
  display: inline-block; width: 20px; height: 20px;
  border: 2px solid #e5e7eb; border-top-color: var(--teal);
  border-radius: 50%; animation: dm-spin var(--dur-slow) linear infinite;
}
@keyframes dm-spin { to { transform: rotate(360deg); } }

.dm-error-boundary {
  border: 1px solid var(--error); border-radius: var(--radius-sm);
  padding: var(--space-3); background: rgba(201,76,76,0.05);
}

/* Inspector parcel-meta block — always rendered, shows parcel ID +
   district + village + area + coordinates even when no pre-computed
   assessment exists. */
.dm-inspector__meta { padding: var(--space-3) var(--space-3) 0; border-bottom: var(--border-thin); margin-bottom: var(--space-3); }
.dm-inspector__id { font-size: var(--fs-md); font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; margin: 0 0 var(--space-2); color: var(--ink); word-break: break-all; }
.dm-inspector__metalist { display: grid; grid-template-columns: max-content 1fr; gap: 4px var(--space-3); margin: 0 0 var(--space-3); font-size: var(--fs-sm); }
.dm-inspector__metalist dt { color: var(--muted); font-weight: 500; }
.dm-inspector__metalist dd { color: var(--ink); margin: 0; }
.dm-inspector__metalist a { color: var(--teal); text-decoration: underline; text-underline-offset: 2px; }
.dm-inspector__no-assess { font-size: var(--fs-sm); color: var(--muted); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); background: var(--bg-soft, #f6f7f9); margin: 0 var(--space-3) var(--space-3); line-height: 1.4; }

/* Full-report drawer error state (timeout / API failure) */
.dm-report-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-4);
  text-align: center;
}
.dm-report-error__msg {
  color: var(--coral);
  font-size: var(--fs-md);
  margin: 0;
  max-width: 56ch;
}
.dm-report-error__retry {
  /* Inherits .dm-btn baseline; this rule only positions it */
  min-width: 96px;
}

/* Phase 5 polish A (closes C13): Results-list pagination polish.
   Brings the Prev/Next/CSV buttons up to a 32×32 hit area (Lighthouse
   target-size) and styles the new jump-to-page input introduced in
   ResultsList.js. .dm-pager hosts all three controls. */
.dm-pager {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  flex-wrap: wrap;
}
.dm-pager button {
  min-height: 32px;
  min-width: 32px;
  padding: 0 var(--space-2);
  font-size: var(--fs-md);
  border: var(--border-thin);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
}
.dm-pager button:hover { background: var(--bg-soft); }
.dm-pager button:disabled { opacity: 0.5; cursor: not-allowed; }
.dm-pager__jump {
  width: 60px;
  padding: var(--space-1);
  font-size: var(--fs-sm);
  border: var(--border-thin);
  border-radius: var(--radius-sm);
}

/* Phase 5 polish B (closes C15): sub-score progress bars in ParcelInspector.
   Each row is a 3-column grid: dimension label · filled track · signed value.
   Track is var(--bg-soft) with a teal fill for positive scores, coral for
   negative — keeps direction visible at a glance even though the engine
   can return values in [-100, +100]. Width is set inline as a percentage
   of |value| so a +90 fills 90%, a -25 fills 25% in coral. The bar is
   labelled role="progressbar" with aria-valuenow for screen-reader parity
   with the visual representation. */
.subscore-bar {
  display: grid;
  grid-template-columns: 100px 1fr 44px;
  gap: var(--space-2);
  align-items: center;
  padding: 4px 0;
}
.subscore-bar__label {
  font-size: var(--fs-sm);
  color: var(--ink);
}
.subscore-bar__track {
  height: 8px;
  background: var(--bg-soft);
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  overflow: hidden;
}
.subscore-bar__fill {
  height: 100%;
  background: var(--teal);
  border-radius: 4px;
  transition: width var(--dur-base) var(--ease-out);
}
.subscore-bar__fill--neg {
  background: var(--coral);
}
.subscore-bar__value {
  font-size: var(--fs-sm);
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Phase 5 polish B (closes C11): Map view tab content. Replaces the old
   single-line hint with a labelled count + colour-coded score legend +
   disabled heatmap toggle (stub — backend not yet wired). The legend dots
   align with the marker colours used in MapCanvas so users can map the
   visual encoding back to a numeric score range. */
.map-view-tab {
  padding: var(--space-3);
}
.map-view-tab__count {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--fs-base);
  color: var(--ink);
}
.map-view-tab__h {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
}
.score-legend {
  list-style: none;
  padding: 0;
  margin: var(--space-2) 0;
}
.score-legend li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 2px 0;
  font-size: var(--fs-sm);
  color: var(--ink);
}
.score-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.score-dot--90  { background: #1a8c5e; }   /* dark teal-green — top tier */
.score-dot--70  { background: #4ab59a; }   /* mid teal — strong */
.score-dot--50  { background: #c9a84c; }   /* gold — viable */
.score-dot--low { background: #999;    }   /* grey — below threshold */
.heatmap-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  color: var(--muted);
  font-size: var(--fs-sm);
  cursor: not-allowed;
}
.heatmap-toggle input[type="checkbox"] { cursor: not-allowed; }
.map-view-tab__pending {
  color: var(--muted);
  font-style: italic;
}

/* Phase 2 Task B1 — layer panel v2 (8 categories, sub-sub-headers, ⓘ button).
   Replaces the 5-DOMAINS .dm-layers__* skin. The new skin keeps font-size at
   11px to match the dense desktop sidebar and uses .has-active / .no-active
   on the cat header so users can scan which categories carry active layers
   at a glance (design system §6: don't rely on colour alone — tooltip + count
   provide redundant signals). */
.demetra-layer-panel { font-size: 11px; }
/* Phase 2 Stream F (ADR 0025) — canvas labels master toggle. Sits at the
   top of the LayerPanel as a single switch independent of category state. */
.demetra-layer-panel__labels-toggle {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; background: #fff;
  border-bottom: 1px solid var(--border, #f0f3f7);
  font-size: 11px; cursor: pointer;
  user-select: none;
}
.demetra-layer-panel__labels-toggle input[type="checkbox"] {
  cursor: pointer; accent-color: var(--accent, #2563eb);
}
.demetra-layer-panel__labels-toggle span { color: var(--charcoal, #1f2937); font-weight: 500; }
.demetra-layer-panel .cat { border-bottom: 1px solid var(--border, #eef0f3); }
.demetra-layer-panel .cat-head {
  width: 100%;
  padding: 8px 12px; background: #fff;
  display: flex; justify-content: space-between; align-items: center;
  border: none; border-bottom: 1px solid var(--border, #f0f3f7);
  font-size: 11px; cursor: pointer; text-align: left;
}
.demetra-layer-panel .cat-head:hover { background: var(--surface-hover, #f3f5f9); }
.demetra-layer-panel .cat-head:focus-visible { outline: 2px solid var(--focus, #2563eb); outline-offset: -2px; }
.demetra-layer-panel .cat-head.has-active { background: #ecf0fe; color: #2563eb; font-weight: 600; }
/* --muted (#4b5563) yields 7.56:1 on white, well above WCAG 2.2 AA 4.5:1.
 * Previous hardcoded #94a3b8 was 2.56:1 (failing). */
.demetra-layer-panel .cat-head.no-active { color: var(--muted, #4b5563); }
.demetra-layer-panel .cat-head .count { font-size: 10px; }
.demetra-layer-panel .subhead {
  padding: 6px 12px 3px;
  font-size: 9px; color: var(--text-muted, #6b7280);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.demetra-layer-panel .layer-row {
  display: flex; align-items: center;
  padding: 3px 12px; cursor: pointer;
}
.demetra-layer-panel .layer-row:hover { background: #f3f5f9; }
.demetra-layer-panel .layer-row.active { font-weight: 500; }
.demetra-layer-panel .layer-row input[type=checkbox] { margin-right: 8px; flex-shrink: 0; }
.demetra-layer-panel .layer-row .label { flex: 1; font-size: 11px; cursor: pointer; }
.demetra-layer-panel .layer-row .info-icon {
  background: transparent; border: none; cursor: pointer;
  font-size: 11px; color: #94a3b8; padding: 0 4px;
}
.demetra-layer-panel .layer-row .info-icon:hover { color: var(--accent, #4a6cf7); }
.demetra-layer-panel .layer-row .info-icon:focus-visible { outline: 2px solid var(--focus, #2563eb); outline-offset: 1px; border-radius: 2px; }

/* Phase 2 Stream A.5 — entitlement badges on paid layers. The row also
   carries [data-disabled='true'] when the user can't currently access the
   layer (anonymous or free tier on a paid layer), which dims the row and
   blocks the checkbox via the inline `disabled` attribute. ADR 0028. */
.demetra-layer-panel .layer-row .layer-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 0 6px;
  font-size: 10px;
  font-weight: 500;
  line-height: 16px;
  border-radius: 4px;
  flex-shrink: 0;
  vertical-align: middle;
}
.demetra-layer-panel .layer-row .layer-badge--paywall {
  background: #fef3c7;
  color: #92400e;
}
/* UX sweep item 18 — the "Sign in" badge gates a dataset behind an
 * account. Style it as a link (accent colour + underline) so it reads
 * as an action, not just a flat grey chip. The verbose `title`
 * (set in LayerPanel.js) explains what unlocks the layer. */
.demetra-layer-panel .layer-row .layer-badge--sign-in {
  background: transparent;
  padding: 0;
  color: var(--accent-deep, #3046b8);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.demetra-layer-panel .layer-row.gated,
.demetra-layer-panel .layer-row[data-disabled='true'] {
  opacity: 0.6;
  cursor: not-allowed;
}
.demetra-layer-panel .layer-row.gated .label,
.demetra-layer-panel .layer-row[data-disabled='true'] .label {
  cursor: not-allowed;
}

/* Phase 2 Stream H — per-layer quality dots. Rendered by LayerPanel next to
   layer rows that are 'watch' or 'below' in the quality index. 'ok' layers
   get no dot (don't clutter the panel). WCAG 2.2 AA: colour + role="img"
   + aria-label provide both visual and non-visual signal. ADR 0027. */
.demetra-layer-panel .layer-row .quality-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-left: 6px;
  vertical-align: middle;
  flex-shrink: 0;
}
.demetra-layer-panel .layer-row .quality-dot--watch {
  background: var(--color-amber-500, #f59e0b);
}
.demetra-layer-panel .layer-row .quality-dot--below {
  background: var(--color-rose-500, #f43f5e);
}

/* Toast — Track C4 introduces a queue host (.dm-toast-container) so multiple
   toasts stack vertically. Each .dm-toast lives inside the container at
   normal flow (no longer position:fixed itself). Container sits bottom-right
   and toasts stack upward (newest below, gap between rows). */
.dm-toast-container {
  position: fixed; bottom: var(--space-5); right: var(--space-5);
  display: flex; flex-direction: column-reverse; gap: var(--space-2);
  z-index: 60;
  pointer-events: none;  /* container doesn't catch clicks; toasts do */
}
.dm-toast {
  background: var(--charcoal); color: #fff;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
  pointer-events: auto;
}
.dm-toast--ok    { background: var(--ok); }
.dm-toast--warn  { background: var(--warn); }
.dm-toast--error { background: var(--error); }
.dm-toast--info  { background: var(--info); }

/* Phase 2 Task B3 — LayerInterpretationModal.
   Opens when LayerPanel's ⓘ button (B1) fires onOpenCard(layerId). Overlay
   covers the whole viewport at z-index 9999 so it sits above the map +
   right rail; click-on-overlay closes via stopPropagation on the modal
   body. ✕ button uses DemetraIcon (one icon set per pillar). :focus-visible
   honours design-system §6 (keyboard a11y, no colour-only encoding). */
.demetra-modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.4); z-index: 9999;
  display: flex; align-items: center; justify-content: center;
}
.demetra-modal {
  background: #fff; border-radius: 8px;
  width: 640px; max-width: 90vw; max-height: 80vh;
  overflow-y: auto; padding: 24px; position: relative;
  box-shadow: 0 10px 32px rgba(0,0,0,0.2);
}
.demetra-modal .modal-close {
  position: absolute; top: 12px; right: 12px;
  width: 28px; height: 28px;
  background: transparent;
  border: 1px solid var(--border, #c8c8d0);
  border-radius: 4px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted, #5b6370);
}
.demetra-modal .modal-close:hover { background: #fee2e2; color: #b91c1c; border-color: #b91c1c; }
.demetra-modal .modal-close:focus-visible { outline: 2px solid var(--focus, #2563eb); outline-offset: 2px; }
.demetra-modal .modal-loading { padding: 32px; text-align: center; color: var(--text-muted, #6b7280); }
.demetra-modal .modal-prov { font-size: 11px; color: var(--text-muted, #6b7280); margin: 8px 0 16px; }
.demetra-modal .modal-md h3 { margin-top: 16px; font-size: 13px; font-weight: 600; color: var(--ink, #2b3245); }
.demetra-modal .modal-md p { margin: 8px 0; font-size: 12px; line-height: 1.6; color: var(--ink, #2b2b2b); }
.demetra-modal .modal-md a { color: var(--accent, #4a6cf7); }
.demetra-modal .modal-empty h3 { color: var(--text-muted, #5b6370); }
.demetra-modal .modal-empty code { font-family: var(--mono, monospace); font-size: 11px; }

/* Phase 2 — keyboard-shortcuts modal */
.demetra-modal.shortcuts-modal { width: 480px; }
.shortcuts-modal .shortcuts-table { width: 100%; font-size: 12px; border-collapse: collapse; margin-top: 8px; }
.shortcuts-modal .shortcuts-table td { padding: 6px 8px; border-bottom: 1px solid var(--border, #eef0f3); }
.shortcuts-modal .shortcuts-table .key-cell { width: 80px; text-align: center; }
.shortcuts-modal .shortcuts-table kbd {
  display: inline-block; padding: 2px 8px;
  background: var(--surface-2, #f3f5f9); border: 1px solid var(--border, #d0d3da);
  border-radius: 3px; font-family: var(--mono, monospace);
  font-size: 11px; font-weight: 600;
}

/* Phase 2 Task D2 — sentence-style CriteriaBuilder. Replaces the
   per-row form (.dm-criteria, .crit-row, .crit-key, .crit-op, .crit-val,
   .crit-x) with a chip strip + compact criterion cards. */
.demetra-criteria-builder { display: flex; flex-direction: column; gap: 8px; }
.demetra-criteria-builder .templates {
  display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 4px;
}
.demetra-criteria-builder .template {
  font-size: 12px; padding: 4px 10px;
  background: var(--surface-2, #f3f5f9);
  border: 1px solid var(--border, #d0d3da);
  border-radius: 999px;
  color: var(--ink, #2b3245);
  cursor: pointer;
  transition: background 120ms ease-out, border-color 120ms ease-out;
}
.demetra-criteria-builder .template:hover { background: var(--surface-1, #e9ecf2); }
.demetra-criteria-builder .template.active {
  background: var(--accent, #4a6cf7);
  border-color: var(--accent, #4a6cf7);
  color: #fff;
}
.demetra-criteria-builder .crit-card {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px;
  border: 1px solid var(--border, #d0d3da);
  border-radius: 4px;
  background: var(--surface-1, #fff);
  font-size: 12px;
}
.demetra-criteria-builder .crit-card.must         { border-left: 3px solid var(--success, #2e7d32); }
.demetra-criteria-builder .crit-card.must-not     { border-left: 3px solid var(--error, #c62828); }
.demetra-criteria-builder .crit-card .pol {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; cursor: pointer;
  font-size: 14px; line-height: 1;
}
.demetra-criteria-builder .crit-card.must .pol     { color: var(--success, #2e7d32); }
.demetra-criteria-builder .crit-card.must-not .pol { color: var(--error, #c62828); }
.demetra-criteria-builder .crit-card .sentence { flex: 1; }
.demetra-criteria-builder .crit-card .x {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; cursor: pointer;
  color: var(--text-muted, #5b6370);
  font-size: 16px; line-height: 1;
}
.demetra-criteria-builder .crit-card .x:hover { color: var(--ink, #2b3245); }
.demetra-criteria-builder .add-crit {
  align-self: flex-start;
  background: transparent;
  border: 1px dashed var(--border, #d0d3da);
  border-radius: 4px;
  padding: 4px 10px;
  font-size: 12px;
  color: var(--text-muted, #5b6370);
  cursor: pointer;
}
.demetra-criteria-builder .add-crit:hover {
  border-color: var(--accent, #4a6cf7);
  color: var(--accent, #4a6cf7);
}
.demetra-criteria-builder .find-actions {
  display: flex; gap: 6px; margin-top: 4px;
}
.demetra-criteria-builder .btn {
  font-size: 12px; padding: 6px 12px;
  background: var(--surface-2, #f3f5f9);
  border: 1px solid var(--border, #d0d3da);
  border-radius: 4px;
  color: var(--ink, #2b3245);
  cursor: pointer;
}
.demetra-criteria-builder .btn:hover { background: var(--surface-1, #e9ecf2); }
.demetra-criteria-builder .btn-primary {
  background: var(--accent, #4a6cf7);
  border-color: var(--accent, #4a6cf7);
  color: #fff;
}
.demetra-criteria-builder .btn-primary:hover {
  background: var(--accent-hover, #3955d2);
  border-color: var(--accent-hover, #3955d2);
}
/* UX sweep item 9 — a disabled "Run search" must read as clearly
 * disabled. `opacity: 0.5` on the blue primary background left a pale
 * lavender that was hard to tell apart from the enabled state. Use an
 * explicit grey fill + grey text instead so the affordance is obvious. */
.demetra-criteria-builder .btn:disabled {
  opacity: 0.5; cursor: not-allowed;
}
.demetra-criteria-builder .btn-primary:disabled,
.demetra-criteria-builder .btn-primary:disabled:hover {
  opacity: 1;
  cursor: not-allowed;
  background: var(--surface-1, #e9ecf2);
  border-color: var(--border, #d0d3da);
  color: var(--text-muted, #5b6370);
}
/* WCAG 2.2 AA focus ring (Olympus design system §6) */
.demetra-criteria-builder .template:focus-visible,
.demetra-criteria-builder .pol:focus-visible,
.demetra-criteria-builder .x:focus-visible,
.demetra-criteria-builder .add-crit:focus-visible,
.demetra-criteria-builder .btn:focus-visible {
  outline: 2px solid var(--focus, #2563eb);
  outline-offset: 1px;
}

/* UX sweep item 8 — inline custom-criterion builder popover.
 * Opened by the "Custom…" template chip. Field / operator / value
 * controls + Apply / Cancel. Sits directly under the chip strip. */
.demetra-criteria-builder .custom-builder {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px;
  background: var(--surface-2, #f3f5f9);
  border: 1px solid var(--border, #d0d3da);
  border-radius: 6px;
}
.demetra-criteria-builder .custom-builder__row {
  display: flex;
  gap: 6px;
}
.demetra-criteria-builder .custom-builder__pol {
  font-size: 12px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--border, #d0d3da);
  background: #fff;
  cursor: pointer;
}
.demetra-criteria-builder .custom-builder__pol.must {
  color: var(--success, #2e7d32);
  border-color: var(--success, #2e7d32);
}
.demetra-criteria-builder .custom-builder__pol.must-not {
  color: var(--error, #c62828);
  border-color: var(--error, #c62828);
}
.demetra-criteria-builder .custom-builder__label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted, #5b6370);
  margin-top: 4px;
}
.demetra-criteria-builder .custom-builder__select,
.demetra-criteria-builder .custom-builder__input {
  font-size: 12px;
  padding: 5px 8px;
  border: 1px solid var(--border, #c8c8d0);
  border-radius: 4px;
  background: #fff;
  color: var(--ink, #2b3245);
}
.demetra-criteria-builder .custom-builder__actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.demetra-criteria-builder .custom-builder__pol:focus-visible,
.demetra-criteria-builder .custom-builder__select:focus-visible,
.demetra-criteria-builder .custom-builder__input:focus-visible {
  outline: 2px solid var(--focus, #2563eb);
  outline-offset: 1px;
}

/* Phase 2 Task D3 — save prompt */
.demetra-criteria-builder .save-prompt {
  display: flex; gap: 6px; align-items: center;
  padding: 8px; margin-top: 6px;
  background: var(--surface-2, #f3f5f9);
  border: 1px solid var(--border, #d0d3da);
  border-radius: 4px;
}
.demetra-criteria-builder .save-prompt input {
  flex: 1; padding: 4px 8px; border: 1px solid var(--border, #c8c8d0);
  border-radius: 3px; font-size: 11px;
}
.demetra-criteria-builder .save-prompt input:focus-visible {
  outline: 2px solid var(--focus, #2563eb); outline-offset: 1px;
}

/* Phase 2 Task D3 — saved searches list */
.demetra-criteria-builder .saved-searches { margin-top: 6px; font-size: 11px; }
.demetra-criteria-builder .saved-link {
  background: transparent; border: none;
  color: var(--accent, #4a6cf7);
  cursor: pointer; padding: 2px 4px; font-size: 11px;
}
.demetra-criteria-builder .saved-link:focus-visible {
  outline: 2px solid var(--focus, #2563eb); outline-offset: 1px;
}
.demetra-criteria-builder .saved-list {
  list-style: none; padding: 4px 0; margin: 4px 0 0;
  border: 1px solid var(--border, #d0d3da);
  border-radius: 4px; background: #fff;
}
.demetra-criteria-builder .saved-list li {
  display: flex; align-items: center;
  padding: 3px 8px;
}
.demetra-criteria-builder .saved-list li:hover { background: var(--surface-2, #f3f5f9); }
.demetra-criteria-builder .saved-item {
  flex: 1; background: transparent; border: none;
  cursor: pointer; padding: 0; text-align: left;
  font-size: 11px; color: var(--ink, #2b2b2b);
}
.demetra-criteria-builder .saved-delete {
  background: transparent; border: none;
  color: var(--text-muted, #94a3b8);
  cursor: pointer; font-size: 14px; padding: 0 4px;
}
.demetra-criteria-builder .saved-delete:hover { color: var(--error, #b91c1c); }
.demetra-criteria-builder .saved-item:focus-visible,
.demetra-criteria-builder .saved-delete:focus-visible {
  outline: 2px solid var(--focus, #2563eb); outline-offset: 1px;
}

/* Phase 2 D5 — viewport-filter toggle bar at top of the ResultsList.
   Sticky so the user can flip the filter even when scrolled deep into a
   long result set. Pinned to z-index 2 so it sits above the result rows
   but stays under any overlays (popups, modals). */
.dm-results .viewport-filter-bar {
  position: sticky; top: 0; z-index: 2;
  padding: 6px 8px; background: var(--surface-2, #f3f5f9);
  border-bottom: 1px solid var(--border, #d0d3da);
  font-size: 11px; color: var(--text-muted, #6b7280);
}
.dm-results .viewport-filter-bar .vf-toggle {
  background: transparent; border: 1px solid transparent;
  color: var(--accent, #4a6cf7); cursor: pointer;
  padding: 2px 6px; border-radius: 3px;
  font-size: 11px; font-weight: 500;
}
.dm-results .viewport-filter-bar .vf-toggle:hover { background: rgba(255,255,255,0.5); }
.dm-results .viewport-filter-bar .vf-toggle:focus-visible { outline: 2px solid var(--focus, #2563eb); outline-offset: 1px; }

/* Phase 2 E1 — inspector header v6.
   Sticky 10-fact summary card + 4-button action row, rendered at the top
   of the parcel inspector drawer. Uses design-token vars with hex
   fallbacks so the component still reads sensibly if the token sheet is
   missing. Compare and Add-to-project buttons are gated behind Phase 3
   (rendered disabled). No emoji on labels — design system mandates one
   icon set per pillar. */
.demetra-insp-head {
  background: linear-gradient(135deg, var(--surface-2, #f3f5f9) 0%, #e9ecf3 100%);
  padding: 14px 16px;
  border-bottom: 1px solid var(--border, #d0d3da);
  position: sticky; top: 0; z-index: 5;
}
.demetra-insp-head .label {
  font-size: 9px; color: var(--text-muted, #6b7280);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.demetra-insp-head .pid {
  font-weight: 600; font-size: 14px;
  font-family: var(--mono, monospace);
  color: var(--ink, #2b3245); margin: 4px 0;
}
.demetra-insp-head .municipality {
  font-size: 10px; color: var(--text-muted, #5b6370);
  margin: 4px 0 10px;
}
.demetra-insp-head .facts-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
}
.demetra-insp-head .fact {
  background: #fff; border: 1px solid var(--border, #e3e3e8);
  border-radius: 4px; padding: 4px 7px;
}
.demetra-insp-head .fact .lbl {
  font-size: 7.5px; color: var(--text-muted, #6b7280);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.demetra-insp-head .fact .val {
  font-weight: 600; font-size: 11px;
  font-family: var(--mono, monospace); color: var(--ink, #2b3245);
}
.demetra-insp-head .fact.alert {
  border-color: #fca5a5; background: #fff5f5;
}
.demetra-insp-head .fact.alert .val { color: var(--error, #b91c1c); }
.demetra-insp-head .actions {
  display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap;
}
.demetra-insp-head .actions button {
  padding: 3px 8px; border-radius: 3px;
  border: 1px solid var(--border, #c8c8d0); background: #fff;
  font-size: 10px; cursor: pointer;
}
.demetra-insp-head .actions button:hover:not([disabled]) {
  background: var(--surface-2, #f3f5f9);
}
.demetra-insp-head .actions button:focus-visible {
  outline: 2px solid var(--focus, #2563eb); outline-offset: 1px;
}
.demetra-insp-head .actions button[disabled] {
  color: var(--text-muted, #94a3b8); cursor: not-allowed;
}

/* ----------------------------------------------------------------------- */
/* Phase 2 — Task E2: inspector accordion + embedded patterns              */
/* (sheet chip · PHGA grid · geological-suitability quote)                  */
/* ----------------------------------------------------------------------- */
.demetra-insp-accordion .accordion {
  border-bottom: 1px solid var(--border, #eef0f3);
}
.demetra-insp-accordion .acc-head {
  width: 100%;
  padding: 10px 14px;
  background: var(--bg-soft, #fafbfc);
  display: flex; justify-content: space-between; align-items: center;
  border: none; border-bottom: 1px solid var(--border, #eef0f3);
  font-weight: 600; font-size: 12px; color: var(--ink, #2b3245);
  cursor: pointer; text-align: left;
}
.demetra-insp-accordion .acc-head:hover {
  background: var(--surface-2, #f3f5f9);
}
.demetra-insp-accordion .acc-head:focus-visible {
  outline: 2px solid var(--focus, #2563eb);
  outline-offset: -2px;
}
/* Badge fg darkened from #d97706 (2.61:1 on #ffe4cc — fails WCAG AA) to
   #8a4500 (5.87:1 — passes AA with margin). The 9px font sits well below
   the 18px / 14px-bold "large text" threshold, so the 4.5:1 normal-text
   target applies. The pale-orange surface stays unchanged so the warm
   "tag" vibe is preserved. */
.demetra-insp-accordion .acc-head .badge {
  background: #ffe4cc; color: #8a4500;
  padding: 1px 7px; border-radius: 9px;
  font-size: 9px; font-weight: 600;
}
.demetra-insp-accordion .acc-body {
  padding: 8px 14px 14px;
  background: var(--bg, #fff);
  font-size: 11px;
}
.demetra-insp-accordion .field-row {
  display: flex; justify-content: space-between;
  padding: 5px 0;
  border-bottom: 1px solid var(--surface-2, #f3f5f9);
}
.demetra-insp-accordion .field-row:last-child { border-bottom: none; }
.demetra-insp-accordion .field-row .l {
  color: var(--text-muted, #5b6370); font-size: 10.5px;
}
.demetra-insp-accordion .field-row .v {
  font-weight: 500; font-family: var(--font-mono, monospace);
  font-size: 10.5px; color: var(--ink, #2b3245);
}
.demetra-insp-accordion .field-row .v.alert {
  color: var(--error, #b91c1c);
}

/* Sheet-PDF chip (Cadastre section) */
.demetra-insp-accordion .chip-action {
  display: inline-flex; align-items: center; gap: 5px;
  background: #d1fae5; color: #047857;
  padding: 2px 8px; border-radius: 11px;
  font-size: 9.5px; font-weight: 600;
  text-decoration: none; border: 1px solid #6ee7b7;
}
.demetra-insp-accordion .chip-action:hover { background: #a7f3d0; }
.demetra-insp-accordion .chip-action:focus-visible {
  outline: 2px solid var(--focus, #2563eb);
  outline-offset: 2px;
}

/* PHGA grid (Hazards section) */
.demetra-insp-accordion .phga-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 4px; margin: 6px 0;
}
.demetra-insp-accordion .phga-cell {
  background: #fef3c7; border: 1px solid #fcd34d;
  border-radius: 3px; padding: 4px 5px; text-align: center;
}
.demetra-insp-accordion .phga-cell .pl {
  font-size: 8px; color: #92400e; text-transform: uppercase;
}
.demetra-insp-accordion .phga-cell .pv {
  font-weight: 700; font-size: 11px; color: #92400e;
  font-family: var(--font-mono, monospace);
}

/* Geological-suitability quote (Hazards section) */
.demetra-insp-accordion .suggestion-quote {
  background: #f0f9ff; border-left: 3px solid #0ea5e9;
  padding: 6px 10px; margin: 6px 0;
  font-size: 10.5px; color: #075985;
  font-style: italic; line-height: 1.5;
}

/* ---------- LiveDataRow (Phase 2 Task E3) ----------
 *
 * Used inside the inspector accordion's Network section. One row per
 * upstream live source (air quality, EAC RES capacity, WDD reservoirs).
 *
 * Brand-orange theme is intentional and called out in the spec — these
 * three accent colours are not in the design-token palette today, so
 * they're inlined. If we ever need a fourth "live" surface, promote them
 * to tokens (see knowledge/design/OLYMPUS_DESIGN_SYSTEM.md §12).
 */
.live-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "meta val"
    "foot foot";
  gap: 2px 8px;
  padding: 6px 8px;
  margin: 4px 0;
  border-radius: var(--radius-sm, 3px);
  background: var(--bg-soft, #f6f7f9);
  border-left: 3px solid var(--muted, #4b5563);
  font-size: var(--fs-sm, 12px);
  line-height: var(--lh-base, 1.45);
}
.live-row .live-meta {
  grid-area: meta;
  color: var(--muted, #4b5563);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: var(--fs-xs, 11px);
}
.live-row .live-val {
  grid-area: val;
  font-weight: 600;
  color: var(--ink, #15171c);
  text-align: right;
}
.live-row .live-val-text {
  font-family: var(--font-mono, ui-monospace, monospace);
}
.live-row .live-val-placeholder {
  color: var(--muted, #4b5563);
  font-weight: 400;
}
.live-row .live-foot {
  grid-area: foot;
  color: var(--muted, #4b5563);
  font-size: var(--fs-xs, 11px);
}

/* Status accents — left border + subtle background tint per state. */
.live-row.fresh {
  border-left-color: #d97706;          /* brand orange */
  background: #fff7ed;                 /* very light orange tint */
}
.live-row.stale {
  border-left-color: #c2410c;          /* deeper orange */
  background: #ffedd5;                 /* warmer tint */
}
.live-row.stale .live-foot-stale {
  color: #92400e;                      /* readable on the warmer tint */
  font-weight: 600;
}
.live-row.error {
  border-left-color: var(--error, #c94c4c);
  background: #fef2f2;
}
.live-row.error .live-foot-error {
  color: #991b1b;
  font-weight: 600;
}
.live-row.error .live-foot-error code {
  background: rgba(220, 38, 38, 0.08);
  padding: 0 4px;
  border-radius: 2px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 10px;
}
.live-row.loading .live-foot {
  font-style: italic;
}

/* Future-proof focus-visible: the row itself is non-interactive today,
 * but if a child becomes clickable (e.g. an "open source page" affordance)
 * it inherits a sane outline rather than the UA default. */
.live-row a:focus-visible,
.live-row button:focus-visible {
  outline: 2px solid var(--focus, #2563eb);
  outline-offset: 2px;
}

/* Phase 2 — export menu */
.export-menu {
  position: absolute;
  background: #fff; border: 1px solid var(--border, #c8c8d0);
  border-radius: 6px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  padding: 4px; min-width: 220px; font-size: 11px; z-index: 100;
}
.export-menu button {
  display: block; width: 100%; text-align: left;
  background: transparent; border: none; padding: 6px 10px;
  cursor: pointer; border-radius: 3px; color: inherit;
  font-size: inherit; font-family: inherit;
}
.export-menu button:hover:not([disabled]) { background: var(--surface-2, #f3f5f9); }
.export-menu button:focus-visible { outline: 2px solid var(--focus, #2563eb); outline-offset: -1px; }
.export-menu button[disabled] { color: var(--text-muted, #94a3b8); cursor: not-allowed; }
.export-menu .placeholder-tag { color: var(--text-muted, #94a3b8); font-size: 10px; }

/* Phase 3a.1 — Severity badge (per ADR 0006) */
.severity-badge {
  display: inline-block;
  padding: 1px 6px;
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-radius: 3px;
  border: 1px solid transparent;
  vertical-align: middle;
  line-height: 1.4;
}
.severity-info {
  background: #f3f4f6;
  color: #374151;
  border-color: #e5e7eb;
}
.severity-advisory {
  background: #fffbeb;
  color: #92400e;
  border-color: #fbbf24;
}
.severity-constraint {
  background: #fff7ed;
  color: #9a3412;
  border-color: #f97316;
}
.severity-blocker {
  background: #fef2f2;
  color: #991b1b;
  border-color: #dc2626;
}

/* Phase 3a.1 — Source citation chip + popover */
.source-citation { position: relative; display: inline-block; }
.source-citation-chip {
  background: transparent;
  border: none;
  font-size: 11px;
  color: var(--text-muted, #5b6370);
  cursor: pointer;
  padding: 0 2px;
  vertical-align: middle;
}
.source-citation-chip:hover { color: var(--accent, #4a6cf7); }
.source-citation-chip:focus-visible { outline: 2px solid var(--focus, #2563eb); outline-offset: 1px; }
.source-citation-popover {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 50;
  min-width: 240px;
  max-width: 320px;
  padding: 8px 10px;
  background: var(--surface, #ffffff);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  font-size: 11px;
}
.source-citation-source { font-weight: 500; margin-bottom: 4px; }
.source-citation-version { color: var(--text-muted, #5b6370); font-size: 10px; margin-bottom: 6px; }
.source-citation-rec { font-style: italic; margin-bottom: 6px; padding-top: 4px; border-top: 1px solid var(--border, #e5e7eb); }
.source-citation-see-also { font-size: 10px; padding-top: 4px; border-top: 1px solid var(--border, #e5e7eb); }
.see-also-label { color: var(--text-muted, #5b6370); margin-bottom: 2px; }
.see-also-chip {
  display: inline-block;
  padding: 1px 4px;
  margin: 2px 4px 2px 0;
  background: var(--surface-2, #f5f5f0);
  border-radius: 2px;
  font-family: var(--mono, monospace);
}

/* Phase 3a.1 — Fact-row interpretation triplet */
.fact-interp { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; font-size: 11px; }

/* Phase 3a.1 — Section header severity rollup badge alignment */
.acc-head .severity-badge { margin-left: auto; margin-right: 12px; }
.fact-interp .interp-text { color: var(--text, #1a1f2e); }

/* -- Phase 3b T5.1-T5.4 — Compare canvas ----------------------------- */
.compare-canvas {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 12px;
  font-size: 12px;
}
.compare-toggle-bar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 4px 0;
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.compare-show-all-label {
  font-size: 11px;
  color: var(--text-muted, #5b6370);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.compare-show-all-input { cursor: pointer; }
.compare-empty-state {
  padding: 32px 12px;
  text-align: center;
  color: var(--text-muted, #5b6370);
  font-size: 12px;
}
.compare-empty-state p { margin: 4px 0; }
.compare-header-row,
.compare-row {
  display: grid;
  grid-template-columns: 160px repeat(auto-fit, minmax(80px, 1fr));
  align-items: stretch;
  gap: 0;
}
.compare-header-row {
  position: sticky;
  top: 0;
  background: var(--surface, #ffffff);
  z-index: 1;
  padding: 4px 0;
  border-bottom: 2px solid var(--border, #e5e7eb);
}
.compare-header-label,
.compare-row-label {
  padding: 6px 8px;
  font-weight: 500;
  border-right: 1px solid var(--border, #e5e7eb);
}
.compare-row-label {
  cursor: pointer;
  user-select: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.compare-row[aria-disabled="true"] .compare-row-label {
  cursor: not-allowed;
  color: var(--text-muted, #5b6370);
}
.compare-sort-indicator {
  font-size: 10px;
  margin-left: 6px;
}
.compare-row {
  border-top: 1px solid var(--border-soft, #f1f1ee);
}
.compare-row--sort-active .compare-row-label {
  background: var(--surface-2, #f5f5f0);
}
.compare-row--flat .compare-row-label {
  font-style: italic;
  color: var(--text-muted, #5b6370);
}
.compare-cell {
  padding: 6px 8px;
  border-left: 3px solid transparent;
  border-right: 1px solid var(--border-soft, #f1f1ee);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.compare-cell.best-cell { border-left-color: var(--success, #16a34a); }
.compare-cell.worst-cell { border-left-color: var(--danger, #dc2626); }

.compare-parcel-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 4px 8px;
  background: var(--surface-2, #f5f5f0);
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 12px;
  font-family: var(--mono, monospace);
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.compare-parcel-pill .pill-remove {
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 2px;
  color: var(--text-muted, #5b6370);
}
.compare-parcel-pill .pill-remove:hover { color: var(--danger, #dc2626); }

.compare-group-heading {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted, #5b6370);
  padding: 8px 8px 4px;
  margin: 8px 0 0;
  border-bottom: 1px solid var(--border, #e5e7eb);
}

/* -- Phase 3b T5.5 — CompareSelectionPicker -------------------------- */
.compare-selection-picker {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.compare-picker-form {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 8px;
}
.compare-picker-input {
  flex: 1;
  font-family: var(--mono, monospace);
  font-size: 12px;
  padding: 4px 6px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 3px;
}
.compare-picker-submit {
  padding: 4px 10px;
  background: var(--accent, #1f3760);
  color: #ffffff;
  border: 1px solid var(--accent, #1f3760);
  border-radius: 3px;
  cursor: pointer;
  font-size: 12px;
}
.compare-picker-submit:disabled {
  background: var(--surface-2, #f5f5f0);
  color: var(--text-muted, #5b6370);
  border-color: var(--border, #e5e7eb);
  cursor: not-allowed;
}
.picker-cap-hint {
  margin: 4px 0 8px;
  padding: 4px 6px;
  background: var(--warn-soft, #fef3c7);
  color: var(--warn-text, #92400e);
  font-size: 11px;
  border-radius: 3px;
}
.picker-section-heading {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted, #5b6370);
  margin: 6px 0 4px;
}
.picker-recent-row,
.picker-find-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.picker-recent-pill,
.picker-find-result {
  border: 1px solid var(--border, #e5e7eb);
  background: var(--surface, #ffffff);
  padding: 3px 8px;
  font-family: var(--mono, monospace);
  font-size: 11px;
  cursor: pointer;
  border-radius: 12px;
}
.picker-recent-pill:disabled,
.picker-find-result:disabled {
  background: var(--surface-2, #f5f5f0);
  color: var(--text-muted, #5b6370);
  cursor: not-allowed;
}

/* -- Phase 3b T5.6 — CompareSavedSelections ------------------------- */
.compare-saved-selections {
  padding: 8px 12px;
  border-top: 1px solid var(--border, #e5e7eb);
  margin-top: 8px;
}
.saved-section-heading {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted, #5b6370);
  margin: 0 0 6px;
}
.saved-save-button {
  width: 100%;
  padding: 6px;
  background: var(--surface-2, #f5f5f0);
  border: 1px dashed var(--border, #e5e7eb);
  border-radius: 3px;
  cursor: pointer;
  font-size: 12px;
}
.saved-save-button:disabled {
  cursor: not-allowed;
  color: var(--text-muted, #5b6370);
}
.saved-save-form,
.saved-rename-form {
  display: flex;
  gap: 4px;
  align-items: center;
  margin-bottom: 8px;
}
.saved-name-input,
.saved-rename-input {
  flex: 1;
  padding: 4px 6px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 3px;
  font-size: 12px;
}
.saved-confirm-button,
.saved-cancel-button {
  padding: 4px 8px;
  font-size: 11px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 3px;
  cursor: pointer;
}
.saved-confirm-button {
  background: var(--accent, #1f3760);
  color: #ffffff;
  border-color: var(--accent, #1f3760);
}
.saved-empty {
  margin: 6px 0;
  color: var(--text-muted, #5b6370);
  font-size: 11px;
  font-style: italic;
}
.saved-selection-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
}
.saved-selection-row {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  border-top: 1px solid var(--border-soft, #f1f1ee);
}
.saved-row-name {
  font-size: 12px;
  cursor: text;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.saved-row-count {
  font-size: 10px;
  color: var(--text-muted, #5b6370);
}
.saved-load-button,
.saved-delete-button {
  padding: 2px 6px;
  font-size: 11px;
  border: 1px solid var(--border, #e5e7eb);
  background: var(--surface, #ffffff);
  border-radius: 3px;
  cursor: pointer;
}
.saved-delete-button { color: var(--danger, #dc2626); }

/* ---------------------------------------------------------------------------
 * Stream E (cross-pillar Apollo facade plan) — Recent Sales Nearby section.
 *
 * Body component for the inspector accordion's "Recent Sales Nearby"
 * section. Four states: loading, error, empty, table. CSS classes are
 * applied by src/js/components/drawer/sections/RecentSalesSection.js;
 * see the file header for the state machine.
 *
 * Sits inside .demetra-insp-accordion .acc-body so it inherits the
 * standard accordion-body padding. No new colours introduced — we reuse
 * the existing CSS-variable palette (--text-muted, --danger, --bg-soft,
 * --border) so design-system tokens propagate.
 * --------------------------------------------------------------------------*/
.recent-sales-loading,
.recent-sales-error,
.recent-sales-empty {
  padding: 8px 4px;
  font-size: var(--fs-sm, 12px);
  color: var(--text-muted, #5b6370);
  line-height: var(--lh-base, 1.45);
}
.recent-sales-error {
  color: var(--danger, #c94c4c);
}
.recent-sales-empty {
  font-style: italic;
}
.recent-sales-table {
  width: 100%;
  font-size: var(--fs-sm, 12px);
  border-collapse: collapse;
  margin: 4px 0;
}
.recent-sales-table th,
.recent-sales-table td {
  text-align: left;
  padding: 4px 6px;
  border-bottom: 1px solid var(--border, #e5e7eb);
}
.recent-sales-table thead th {
  background: var(--bg-soft, #f6f7f9);
  font-weight: 600;
  color: var(--text-muted, #5b6370);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: var(--fs-xs, 11px);
}
.recent-sales-table tbody td {
  font-variant-numeric: tabular-nums;
}
/* Right-align numeric columns (Dist. + €/m²) for easy column scanning. */
.recent-sales-table tbody td:nth-child(1),
.recent-sales-table tbody td:nth-child(4) {
  text-align: right;
}
.recent-sales-table tbody td:last-child {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--fs-xs, 11px);
  color: var(--text-muted, #5b6370);
}
