/* ============================================================================
   LCB — Wada structural system
   ----------------------------------------------------------------------------
   Loaded AFTER each page's inline <style>, so these rules win at equal
   specificity and act as the shared visual contract.

   Source: Nonarkara/palette — Sanzo Wada's 348 recorded colour combinations.
   We take *structure* and *value*, not all 159 colours.

     --paper    #f7f5ef  dominant field      (the exhibition's own white)
     --ink      #111314  Wada Black          counter-field, 17.1:1 with paper
     --plate    #12354e  Dark Tyrian Blue    structural depth, 11.7:1 with paper
     --wada-hi  #fdbf68  Cream Yellow        rare signal only

   Relationship follows the exhibition's two-colour plate rule: paper carries
   ~62% of the surface, ink the decisive ~38% concentrated in the hub bezel,
   panel rules and active states. Route-family colours are a CLOSED signal
   system (green open / red closed / orange restricted / blue port / yellow
   warning) and are deliberately left untouched — never recolour a status to
   suit a mood.

   Measured against --paper #f7f5ef:
     --ink-3  #767168  4.61:1  (previous #a9a59a was 2.34:1 — an AA failure
                                carrying every structural micro-label)
     --ink-2  #706b62  5.03:1
   ========================================================================== */

/* Palette lives in css/tokens.css so every page shares one copy.
   Load tokens.css BEFORE this file. */

/* The hub bezel moved to css/bezel.css so every page shares it.
   See the note there for why it could not stay map-only. */

/* ============================================================================
   HUB STATUS COUNTS — the one piece of hub furniture that is NOT shared.
   Only map.html carries route counts, so these stay here rather than in
   css/bezel.css.

   Regression guard. These rules were lost during the bezel extraction and the
   numerals silently fell back to map.html's own `.hub-stat .v` (16px / weight
   600) and `.l` (--ink-3) against the ink bezel — 3.93:1 green, 3.68:1 purple,
   3.68:1 labels. Two independent instruments caught it: an element-level
   alpha-composited probe, and scripts/audit-tokens.cjs, which drops from 3:1 to
   4.5:1 once text stops qualifying as large-bold.

   The numerals keep their EXACT route colours. Green/amber/purple/orange are a
   CLOSED status signal and must read identically here and on the map, so they
   are sized to stay large-bold (>=18.66px at weight 700), where AA is 3:1:
   green #00853F 3.93:1, purple #B933AD 3.68:1, amber 6.38:1, orange 6.27:1.
   Do NOT shrink these numerals below 18.66px without recolouring them.
   ========================================================================== */

.hub .hub-stats { gap: 0 !important; border-left: 1px solid #3a3833; padding-left: 14px; }
.hub .hub-stat {
  background: transparent !important;
  border: 0 !important;
  border-right: 1px solid #3a3833 !important;
  padding: 2px 12px 2px 10px !important;
  min-width: 0 !important;
}
.hub .hub-stat:last-child { border-right: 0 !important; }
.hub .hub-stat .v {
  font-size: 21px !important;
  line-height: 1 !important;
  font-weight: 700 !important;
}
.hub .hub-stat .l { color: #a9a496 !important; font-size: 9px !important; letter-spacing: 0.1em; }

/* ============================================================================
   1. PANEL PLATES — hierarchy floor.
   Section headers were 8.5px gray on a hairline: invisible. Now they carry a
   hard 2px ink rule, a solid geometry square, and a 10.5px ink label.
   ========================================================================== */

.panel-h {
  font-size: 10.5px !important;
  letter-spacing: 0.14em !important;
  font-weight: 700 !important;
  color: var(--ink) !important;
  padding-bottom: 5px !important;
  margin-bottom: 8px !important;
  border-bottom: 2px solid var(--ink) !important;
}
.panel-h > span:first-child {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
/* Geometry as grammar: a filled square marks every section, the way the
   exhibition marks a division. It is redundant with the label, never alone. */
.panel-h > span:first-child::before {
  content: "";
  width: 9px; height: 9px;
  background: var(--plate);
  flex: none;
}
.panel-h .code {
  background: var(--ink) !important;
  color: var(--paper) !important;
  font-size: 8.5px !important;
  letter-spacing: 0.12em !important;
  font-weight: 700 !important;
  padding: 2px 6px !important;
  border-radius: 0 !important;
}
.panel-collapse {
  background: var(--ink) !important;
  color: var(--paper) !important;
  border-color: var(--ink) !important;
  border-radius: 0 !important;
  min-width: 24px; min-height: 24px;
}
.panel-collapse:hover { background: var(--plate) !important; border-color: var(--plate) !important; }

/* The aside itself is a paper field, not a white void. */
.aside { background: var(--paper) !important; }
.aside--right { border-left-color: var(--line-2) !important; }
.aside::-webkit-scrollbar-thumb { background: var(--line-2) !important; }

/* ============================================================================
   2. LAYER ROWS — grouped so 19 rows stop reading as a wall.
   Group plates are inserted in the markup; order is preserved.
   ========================================================================== */

.layer-row {
  padding: 5px 0 !important;
  border-top: 1px solid var(--line) !important;
  align-items: center;
}
/* Give the row a hard left rule on hover so the clickable area is obvious. */
.layer-row:hover { background: color-mix(in srgb, var(--plate) 5%, transparent); }
.layer-row .label-text { font-size: 12px !important; color: var(--ink) !important; font-weight: 600 !important; }
.layer-row .sub { color: var(--ink-2) !important; font-size: 10px !important; }
.layer-row .meta .n { font-size: 12.5px !important; }
.layer-row .meta .lab {
  color: var(--ink-2) !important;
  font-size: 8px !important;
  letter-spacing: 0.12em !important;
  font-weight: 700 !important;
}

/* Group header — a solid plate between runs of rows. */
.layer-group {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 10px 0 2px;
  padding: 3px 7px;
  background: var(--plate);
  color: var(--paper);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.layer-group::before {
  content: "";
  width: 6px; height: 6px;
  background: var(--wada-hi);
  flex: none;
}
.layer-group:first-child { margin-top: 0; }

/* ============================================================================
   3. OPS PANEL — colour-blocked status edges.
   The card carries its verdict on a solid edge, so the right rail can be
   scanned without reading a single number. Text label always accompanies it.
   ========================================================================== */

.ops-grid { gap: 8px !important; }
.ops-card {
  border: 1px solid var(--line-2) !important;
  border-left: 4px solid var(--line-2) !important;
  border-radius: 0 !important;
  background: var(--panel) !important;
  padding: 8px 10px 9px !important;
}
.ops-card-h { color: var(--ink-2) !important; font-size: 8.5px !important; letter-spacing: 0.14em !important; }
.ops-metric { color: var(--ink) !important; }
.ops-row { border-top-color: var(--line) !important; }
.ops-k { color: var(--ink-2) !important; }
.ops-chip {
  border-radius: 0 !important;
  border-color: var(--line-2) !important;
  background: var(--paper) !important;
  color: var(--ink-2) !important;
  /* WCAG 2.5.8 AA — these were 19px */
  min-height: 24px;
  display: inline-flex; align-items: center;
}
.ops-chip-btn:hover { border-color: var(--ink) !important; color: var(--ink) !important; }
.ops-chip-hot  { background: #fbeae8 !important; border-color: var(--neg) !important; color: var(--neg) !important; }
.ops-chip-warm { background: #fdf3e0 !important; border-color: #b6930c !important; color: #6f5a06 !important; }

.ops-card.good     { border-left-color: var(--accent) !important; }
.ops-card.moderate { border-left-color: #b6930c !important; }
.ops-card.sensitive,
.ops-card.unhealthy     { border-left-color: var(--neg) !important; }
.ops-card--flood.good     { border-color: var(--line-2) !important; border-left-color: var(--accent) !important; }
.ops-card--flood.moderate { border-color: #b6930c !important; border-left-color: #b6930c !important; }
.ops-card--flood.sensitive,
.ops-card--flood.unhealthy { border-color: var(--neg) !important; border-left-color: var(--neg) !important; }
.ops-card--air.good     { border-color: var(--line-2) !important; border-left-color: var(--accent) !important; }
.ops-card--air.moderate { border-color: #b6930c !important; border-left-color: #b6930c !important; }
.ops-card--air.sensitive,
.ops-card--air.unhealthy { border-color: var(--neg) !important; border-left-color: var(--neg) !important; }

/* ============================================================================
   4. 3D MODE MARKER
   #c9ff38 acid lime sat outside the palette and read as a debug flag. Mode
   identity now uses the structural plate + Cream Yellow, which still shouts
   but belongs to the system.
   ========================================================================== */

.map3d-bar-title {
  background: var(--ink) !important;
  border-color: var(--ink) !important;
  color: var(--paper) !important;
  border-radius: 0 !important;
}
.map3d-bar-title .pill {
  background: var(--wada-hi) !important;
  color: var(--ink) !important;
  border-radius: 0 !important;
}
.map3d-chip {
  background: var(--ink) !important;
  color: var(--paper) !important;
  border-color: var(--ink) !important;
  border-radius: 0 !important;
  min-height: 26px;
  display: inline-flex; align-items: center;
}
.map3d-chip:hover { background: var(--plate) !important; color: var(--paper) !important; }
.map3d-chip--exit { background: var(--wada-hi) !important; color: var(--ink) !important; }
.map3d-chip--exit:hover { background: var(--paper) !important; color: var(--ink) !important; }

/* ============================================================================
  5. LEGIBILITY FLOOR — microtype that used to sit at 2.3:1
   ========================================================================== */

/* Top strip vs Leaflet zoom control — they shared the map's top-left origin,
   so the first alert chip rendered *behind* the +/- buttons. Inset the strip
   past the control instead of moving either. */
@media (min-width: 721px) {
  .map-topstrip { left: 52px !important; }
}
@media (max-width: 720px) {
  .map-topstrip { left: 46px !important; }
}

/* The top band belongs to ONE stack: alerts + route time controls. Three other
   absolutely-positioned map chips were sharing it and rendering on top —
   #situationMapChip sat directly over the Leaflet zoom control and #mapOverlay
   over the last truck-class chip. Moved to a deliberate bottom stack so the
   primary instrument reads first and nothing overlaps anything.

   bottom: 44  .btn-3d                (left)
   bottom: 92  .situationMapChip      (left)   .mapOverlay (right)
   bottom: 140 .activeRoutesChip      (right, only when routes are restricted) */
#situationMapChip  { top: auto !important; bottom: 92px !important; left: 12px !important; right: auto !important; }
.map-overlay-top   { top: auto !important; bottom: 92px !important; right: 12px !important; }
.active-routes-chip{ top: auto !important; bottom: 140px !important; right: 12px !important; }

.leaflet-control-attribution,
.leaflet-control-attribution a {
  color: var(--ink-3) !important;
  /* Leaflet ships this link at 11px tall. It is a legal attribution and should
     still be reachable — pad the hit area without changing the type size. */
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  padding: 0 4px;
}
.road-label {
  background: color-mix(in srgb, var(--paper) 88%, transparent) !important;
  color: var(--ink) !important;
  border: 1px solid var(--line-2) !important;
  font-size: 9.5px !important;
}
.leaflet-control-zoom a {
  background: var(--paper) !important;
  color: var(--ink) !important;
  border-color: var(--line-2) !important;
  border-radius: 0 !important;
}
.leaflet-control-zoom a:hover { background: var(--ink) !important; color: var(--paper) !important; }
.leaflet-bar { border: 1px solid var(--line-2) !important; box-shadow: none !important; }

/* Focus: a hard warm ring, visible on ink, paper and map alike. */
:where(.hub, .panel, .rtc, .map-topstrip, .ops-card) :focus-visible {
  outline: 2px solid var(--wada-hi) !important;
  outline-offset: 2px !important;
}
body :focus-visible { outline: 2px solid var(--plate); outline-offset: 2px; }

/* ============================================================================
   7. MOBILE MAP CHROME
   At 375px the bezel wrapped to ~265px: the eyebrow code broke over three
   lines and the title over four, pushing the map down to ~150px. On a phone
   the map is the point, so the chrome yields: the eyebrow and the publication
   stamp are provenance, not operation, and drop out; the status counts keep
   their own strip because they are the answer to "can I drive this road?".
   ========================================================================== */

@media (max-width: 880px) {
  /* Bezel basics (padding, the eyebrow/stamp drop-out) now live in
     css/bezel.css and apply to every page. What remains here is map-only:
     reordering the map's own hub children into three compact rows. */
  .hub {
    flex-wrap: wrap !important;
    gap: 6px 8px !important;
    padding: 7px 10px !important;
  }
  /* Flatten .hub-left so its children become flex items of .hub and can be
     ordered into three compact rows instead of wrapping by accident. */
  .hub-left    { display: contents; }

  .disc--lg    { order: 1; width: 32px; height: 32px; font-size: 12px; }
  .hub-left > div:nth-child(2) { order: 2; flex: 1 1 0; min-width: 0; }
  .sidebar-toggle { order: 3; flex: none; }
  .hub-stats   { order: 4; flex: 1 1 100% !important; }
  /* The nav used to be hidden here and replaced by a SECOND copy of it
     (.hub-link Data|Dashboard) — so the map page showed Dashboard twice on
     desktop, in two languages, in two groups. There is now ONE nav element,
     and it carries the same group on every screen. */
  .nav-links   { order: 5; flex: 1 1 auto; margin-left: 0 !important; display: flex !important; }
  .hub-actions { order: 6; flex: 0 0 auto; justify-content: flex-end; }

  /* One line, never three. The full title stays on desktop and in <title>. */
  .hub-title {
    font-size: 13px !important;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Status counts keep their own compact full-width strip — this is the answer
     to "can I drive this road right now?" */
  .hub-stats {
    border-left: 0 !important;
    border-top: 1px solid #3a3833;
    padding: 5px 0 0 !important;
    gap: 0 !important;
    display: flex !important;
    align-items: baseline;
  }
  .hub-stat { flex: 1 1 0; }
  .hub-stat:first-child { padding-left: 0 !important; }

  /* The numerals and labels deliberately do NOT get a smaller mobile size.
     These overrides existed once and never ran: the base rules above are
     `.hub .hub-stat .v` / `.l` (0,3,0) with !important, so a bare
     `.hub-stat .v { font-size: 16px !important }` (0,2,0) could never win.
     Shipping a 16px numeral is exactly the regression the audit caught — it
     stops qualifying as large-bold and drops green/purple below 4.5:1 on ink.
     Flex and the first-child padding are kept because those were never
     shadowed; the rest is removed rather than left as dead code. */

  .hub-actions { gap: 6px !important; }
  .nav-links a { font-size: 10px !important; min-height: 26px; padding: 4px 8px !important; }
  .bio-trigger strong { font-size: 10px !important; }
  .bio-trigger span   { display: none !important; }
  .bio-trigger img    { width: 22px; height: 22px; }
  .bio-trigger        { padding: 2px 7px 2px 2px !important; }

  /* Bottom stack. #situationMapChip and .map-overlay-top are hidden here on
     purpose: both restate facts the alert bar immediately above already
     carries in full ("5 police checkpoints active", "N restricted now"), and
     on a 375px screen they overlapped each other and the 3D button.
     .active-routes-chip is kept — it is the only place naming the routes
     currently restricted — and parked at the map's bottom edge. */
  #situationMapChip   { display: none !important; }
  .map-overlay-top    { display: none !important; }
  .btn-3d             { bottom: 44px !important; left: 12px !important; font-size: 11px !important; padding: 7px 10px !important; }
  /* The collapsed layer sheet owns the bottom 52px of the screen, and the
     Leaflet bottom-right controls (the rain-radar clock) sat UNDER it —
     46% of the pause button was covered and unclickable. Lift them clear of
     the sheet, the same way the 3D button and the routes chip already are. */
  .leaflet-bottom.leaflet-right { margin-bottom: 58px; }
  .active-routes-chip { top: auto !important; bottom: 12px !important; left: 12px !important; right: 12px !important;
                        padding: 6px 9px !important; font-size: 10px !important; }
}

/* ============================================================================
  8. MOTION / PREFERENCE SAFETY
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
/* prefers-contrast branch lives in css/tokens.css */
