/**
 * db-blocks.css — styling for the shared result blocks.
 *
 * WHY A SEPARATE SHEET. db-system.css is pinned with a hand-bumped `?v=` on 57
 * pages, so adding rules there means touching all 57 in one commit or leaving
 * returning readers on a stale sheet. This file is included only by the pages
 * that use public/js/db-blocks.js, so it carries its own version and nobody
 * else pays for it.
 *
 * These rules were previously inline in three page files and duplicated between
 * them: the tick lane existed twice (procurement.html `.prm-lane` and
 * government.html `.gov-lane`) with different class names for the same visual
 * idea, and the staged chain existed twice again. One definition each, here.
 *
 * Everything is token-driven, so the blocks follow the theme with no JavaScript.
 */

/* ── Block chrome ─────────────────────────────────────────────────────────── */

.dbb { min-width: 0; }
.dbb-note {
  margin: var(--db-space-md) 0 0;
  font-size: var(--db-text-xs);
  color: var(--db-muted);
  max-width: var(--db-read-measure);
}
.dbb-svg { width: 100%; max-width: 100%; display: block; }

/* An SVG carrying a viewBox and a height attribute has an intrinsic width, so
   inside a grid or flex item it can ratchet its track wider on every redraw and
   never shrink back. Every block host gets both guards. */
.dbb-host { min-width: 0; }
.dbb-host > * { min-width: 0; }

/* ── eventLane / laneTimeline ─────────────────────────────────────────────── */

.dbb-lanes {
  display: grid; gap: 1px;
  background: var(--db-border);
  border: var(--db-rule) solid var(--db-border);
  border-radius: var(--db-radius-sm);
  overflow: hidden;
}
.dbb-lane {
  background: var(--db-card);
  display: grid; grid-template-columns: 170px minmax(0, 1fr) 52px;
  gap: var(--db-space-md); align-items: center;
  padding: 9px var(--db-space-md);
}
.dbb-lane.is-empty { background: var(--db-surface-sunken); }
.dbb-lane-label {
  font-size: var(--db-text-2xs); font-weight: var(--db-weight-label);
  letter-spacing: var(--db-tracking-wider);
  text-transform: uppercase; color: var(--db-muted);
}
.dbb-lane-track { position: relative; display: block; height: 18px; }
.dbb-lane-empty { font-size: var(--db-text-xs); color: var(--db-muted); font-style: italic; }
.dbb-lane-n {
  font-family: var(--db-font-num); font-variant-numeric: tabular-nums;
  font-size: var(--db-text-xs); color: var(--db-muted); text-align: right;
}
.dbb-tick {
  position: absolute; top: 3px; width: 3px; height: 12px;
  /* Centred on its own position, so a tick at 0% or 100% sits ON the edge of the
     track rather than half outside it where it cannot be clicked. */
  transform: translateX(-50%);
  border: 0; padding: 0; cursor: pointer; border-radius: 1px; opacity: .8;
  background: currentColor;
  transition: opacity var(--db-motion-fast) var(--db-ease),
              height var(--db-motion-fast) var(--db-ease);
}
.dbb-tick:hover, .dbb-tick:focus-visible { opacity: 1; height: 18px; top: 0; outline: none; }
/* An inferred or unverified item is hollow, never merely a different colour, so
   the distinction survives greyscale.

   An OUTLINE, not a hatch: a tick is three pixels wide, and a repeating gradient
   at that width renders as either solid or nothing. The block passes a colour
   via the "color" property and adds this class; it must never set "background"
   inline, because that shorthand resets background-image and silently defeats
   the distinction — which is exactly how this was first written, and the hollow
   ticks rendered as nothing at all. */
.dbb-tick.is-hollow {
  background: transparent;
  box-shadow: inset 0 0 0 1px currentColor;
}
.dbb-axis {
  display: flex; justify-content: space-between; margin-top: 6px;
  font-family: var(--db-font-num); font-size: var(--db-text-2xs); color: var(--db-muted);
  font-variant-numeric: tabular-nums;
}

/* ── scatter (the opportunity matrix) ─────────────────────────────────────── */

.dbb-dot { cursor: pointer; transition: r var(--db-motion-fast) var(--db-ease); }
.dbb-dot:focus-visible { outline: none; }
/* Unmatched points are drawn, not hidden: hollow, so the eye skips them but the
   count is still honest. */
.dbb-dot.is-unmatched { fill: none; stroke-dasharray: 2 2; }
.dbb-axis-line { stroke: var(--db-chart-axis); stroke-width: 1; }
.dbb-axis-label {
  font-size: var(--db-text-2xs); font-weight: var(--db-weight-label); letter-spacing: var(--db-tracking-wide);
  text-transform: uppercase; fill: var(--db-muted);
}
.dbb-tick-label { font-family: var(--db-font-num); font-size: var(--db-text-2xs); fill: var(--db-muted); font-variant-numeric: tabular-nums; }
.dbb-band { fill: var(--db-surface-sunken); }
.dbb-band-label { font-size: var(--db-text-2xs); fill: var(--db-muted); }

/* ── stagedChain ──────────────────────────────────────────────────────────── */

.dbb-stage-box { fill: var(--db-card); stroke: var(--db-border-strong); stroke-width: 1; }
.dbb-stage-name {
  font-size: var(--db-text-xs); font-weight: var(--db-weight-label); letter-spacing: var(--db-tracking-wide);
  text-transform: uppercase; fill: var(--db-muted);
}
.dbb-stage-count {
  font-family: var(--db-font-num); font-size: var(--db-text-md); font-weight: var(--db-weight-label); fill: var(--db-navy);
  font-variant-numeric: tabular-nums;
}
html.dark-mode .dbb-stage-count { fill: var(--db-char); }
.dbb-link { cursor: pointer; }
.dbb-link:focus { outline: none; }
.dbb-break {
  margin-top: var(--db-space-md); padding: 10px var(--db-space-md);
  border: var(--db-rule) dashed var(--db-level-elevated);
  border-left: var(--db-edge-width) dashed var(--db-level-elevated);
  border-radius: var(--db-radius-sm); background: var(--db-level-elevated-bg);
  font-size: var(--db-text-sm); color: var(--db-char);
}
.dbb-break + .dbb-break { margin-top: var(--db-space-sm); }
.dbb-break b { font-family: var(--db-font-num); font-weight: var(--db-weight-label); font-variant-numeric: tabular-nums; }

/* ── bipartite ────────────────────────────────────────────────────────────── */

.dbb-edge { fill: none; stroke: var(--db-chart-1); stroke-opacity: .34; stroke-width: 1; }
.dbb-edge.is-inferred { stroke-dasharray: 3 3; stroke-opacity: .55; }
.dbb-edge.is-hot { stroke: var(--db-chart-emphasis); stroke-opacity: .95; stroke-width: 1.8; }
.dbb-node { cursor: pointer; }
.dbb-node-label { font-size: var(--db-text-2xs); fill: var(--db-muted); }
.dbb-node-label.is-hot { fill: var(--db-red-ink); font-weight: var(--db-weight-title); }

/* ── hierarchy ────────────────────────────────────────────────────────────── */

.dbb-tree { list-style: none; margin: 0; padding: 0; }
.dbb-tree ul {
  list-style: none; margin: 0; padding: 0 0 0 20px;
  border-left: var(--db-rule) solid var(--db-border);
}
.dbb-branch { border-top: var(--db-rule) solid var(--db-border); }
.dbb-tree > .dbb-branch:first-child { border-top: 0; }
.dbb-row {
  display: grid; grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: var(--db-space-sm); align-items: baseline; width: 100%;
  padding: 9px 6px; border: 0; background: none; font: inherit;
  color: var(--db-char); text-align: left; cursor: pointer;
}
.dbb-row:hover { background: var(--db-surface-rail); }
.dbb-row:focus-visible { outline: 2px solid var(--db-red-ink); outline-offset: -2px; }
.dbb-row.is-selected { background: var(--db-surface-rail); box-shadow: inset 3px 0 0 var(--db-red); }
.dbb-twist {
  font-family: var(--db-font-num); font-size: var(--db-text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--db-muted); line-height: 1.5; user-select: none;
}
.dbb-twist.is-leaf { color: var(--db-border-strong); }
/* The chevron collapses; the row selects. One click doing both closes the branch
   the reader just opened. */
.dbb-twist[data-twist] {
  cursor: pointer; padding: 2px 4px; margin: -2px -4px;
  border-radius: var(--db-radius-xs);
}
.dbb-twist[data-twist]:hover { background: var(--db-border); color: var(--db-char); }
.dbb-name { font-size: var(--db-text-sm); font-weight: var(--db-weight-title); color: var(--db-navy); }
html.dark-mode .dbb-name { color: var(--db-char); }
.dbb-abbr {
  font-family: var(--db-font-num); font-size: var(--db-text-2xs); font-weight: var(--db-weight-label);
  font-variant-numeric: tabular-nums;
  color: var(--db-muted); margin-left: 6px;
}
.dbb-kind {
  display: block; font-size: var(--db-text-2xs); font-weight: var(--db-weight-label);
  letter-spacing: var(--db-tracking-wide); text-transform: uppercase;
  color: var(--db-muted); margin-top: 2px;
}
.dbb-what {
  display: block; font-size: var(--db-text-xs); color: var(--db-muted);
  margin-top: 3px; max-width: 74ch;
}
.dbb-counts { display: flex; gap: var(--db-space-sm); align-items: baseline; white-space: nowrap; }
.dbb-count {
  font-family: var(--db-font-num); font-variant-numeric: tabular-nums;
  font-size: var(--db-text-2xs); color: var(--db-muted);
}
.dbb-count b { color: var(--db-char); font-weight: var(--db-weight-label); }

/* ── recordList ───────────────────────────────────────────────────────────── */

.dbb-records { width: 100%; border-collapse: collapse; font-size: var(--db-text-sm); }
.dbb-records th {
  text-align: left; font-size: var(--db-text-2xs); font-weight: var(--db-weight-label);
  letter-spacing: var(--db-tracking-wide); text-transform: uppercase;
  color: var(--db-muted); padding: 0 var(--db-space-md) 8px 0;
  border-bottom: var(--db-rule-strong) solid var(--db-border-strong);
}
.dbb-records td {
  padding: 9px var(--db-space-md) 9px 0;
  border-bottom: var(--db-rule) solid var(--db-border);
  vertical-align: top; color: var(--db-char);
}
.dbb-record-row { cursor: pointer; }
.dbb-record-row:hover { background: var(--db-surface-rail); }
.dbb-record-row:focus-visible { outline: 2px solid var(--db-red-ink); outline-offset: -2px; }
.dbb-mono {
  font-family: var(--db-font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--db-text-xs); white-space: nowrap; color: var(--db-muted);
}
.dbb-records-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── Shared marks ─────────────────────────────────────────────────────────── */

.dbb-tag {
  display: inline-block; padding: 2px 7px 2px 5px;
  border: var(--db-rule) solid var(--db-border);
  border-left: var(--db-edge-width) solid var(--db-level-moderate);
  border-radius: var(--db-radius-xs); background: var(--db-level-moderate-bg);
  font-size: var(--db-text-2xs); font-weight: var(--db-weight-label); letter-spacing: var(--db-tracking-wide);
  text-transform: uppercase; white-space: nowrap;
}
.dbb-tag[data-hollow="1"] {
  border-left-style: dashed; border-left-color: var(--db-level-elevated);
  background: var(--db-level-elevated-bg);
}

@media (max-width: 760px) {
  .dbb-lane { grid-template-columns: minmax(0, 1fr) 52px; }
  .dbb-lane-track { grid-column: 1 / -1; }
  .dbb-row { grid-template-columns: 20px minmax(0, 1fr); }
  .dbb-counts { grid-column: 2; }
}
@media (max-width: 640px) {
  .dbb-row, .dbb-record-row { min-height: 44px; }
}


/* ══════════════════════════════════════════════════════════════════════════
   SHARED CONTROLS — pairs with public/js/db-controls.js

   db-system.css §17 has carried .db-maptoolbar / .db-maprail / .db-maplegend
   since the design-system refactor with nothing using them. These are the
   pieces that were missing to make them usable, plus the Leaflet overrides
   without which a Leaflet map ignores all of it.

   Why here and not in db-system.css: that sheet is pinned with a hand-bumped
   ?v= on 59 pages, so adding to it means touching all 59 in one commit or
   leaving returning readers on a stale copy. Same reasoning as this file's
   own header.
   ══════════════════════════════════════════════════════════════════════════ */

/* The rail sits inside a positioned box. Without this it escapes to the
   nearest positioned ancestor, which on a map page is usually the page. */
.db-map-host { position: relative; min-width: 0; }

.db-maprail-btn svg { width: 16px; height: 16px; display: block; }
.db-maprail-btn:focus-visible {
  outline: 2px solid var(--db-border-focus);
  outline-offset: -2px;
}

/* db-system.css §17 sets this border to a literal rgba(11,31,51,.18), which is
   navy-on-white and stays navy on the dark page ground. The token flips. */
.db-maplegend-swatch { border-color: var(--db-border-strong); }

/* ── Fullscreen fallback ───────────────────────────────────────────────────
   iOS Safari does not implement the Fullscreen API on arbitrary elements, so
   fullscreenControl() falls back to this class. Fixed rather than absolute:
   it must escape any ancestor with overflow or a transform, which a chart
   host frequently has. */
.is-expanded {
  position: fixed !important;
  inset: 0 !important;
  z-index: 1000;
  width: auto !important;
  height: auto !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  background: var(--db-card);
}
/* The real Fullscreen API paints its own backdrop black by default, which
   would sit behind a transparent chart. */
.db-map-host:fullscreen,
.db-chart-frame:fullscreen { background: var(--db-card); }

/* ── Timestamp ─────────────────────────────────────────────────────────────
   SOURCE / METADATA tier: extra-small, muted, mono because it is machine
   data. One rule, replacing six hand-written formats. */
.db-stamp {
  font-family: var(--db-font-num);
  font-size: var(--db-text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--db-muted);
  white-space: nowrap;
}
.db-stamp[hidden] { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   LEAFLET CONTROL OVERRIDES

   There is not one .leaflet-control rule anywhere else in this codebase, so
   until now every Leaflet map shipped the stock chrome: a white box with a
   4px radius and a 0 1px 5px rgba(0,0,0,.65) drop shadow — the floating
   rounded control this design system exists to remove — and it did not
   respond to dark mode, because Leaflet hardcodes #fff.

   The zoom control itself is replaced by .db-maprail (create the map with
   zoomControl:false and call mountLeafletControls). These rules cover
   attribution, popups and the scale, which Leaflet still owns.
   ══════════════════════════════════════════════════════════════════════════ */

.leaflet-container { background: var(--db-surface-sunken); font-family: var(--db-font); }

.leaflet-control-attribution {
  background: var(--db-card) !important;
  color: var(--db-muted) !important;
  font-family: var(--db-font);
  font-size: var(--db-text-2xs);
  border-top: var(--db-rule) solid var(--db-border);
  border-left: var(--db-rule) solid var(--db-border);
  border-radius: 0;
  box-shadow: none;
  padding: 2px 6px;
}
.leaflet-control-attribution a { color: var(--db-muted) !important; }
.leaflet-control-attribution a:hover { color: var(--db-red-ink) !important; }

/* Any Leaflet control still in play loses the pill and the drop shadow. */
.leaflet-bar,
.leaflet-control-zoom,
.leaflet-control-layers {
  border: var(--db-rule) solid var(--db-border) !important;
  border-radius: var(--db-radius-xs) !important;
  box-shadow: none !important;
  background: var(--db-card);
}
.leaflet-bar a,
.leaflet-control-zoom a {
  background: var(--db-card);
  color: var(--db-muted);
  border-bottom: var(--db-rule) solid var(--db-border);
  border-radius: 0 !important;
}
.leaflet-bar a:hover,
.leaflet-control-zoom a:hover { background: var(--db-surface-sunken); color: var(--db-navy); }

/* Leaflet's popup is a white rounded bubble with a tip and a 24px shadow.
   Squared, hairlined and tokenised, it reads as the same family as
   .db-readout without having to replace Leaflet's positioning logic. */
.leaflet-popup-content-wrapper {
  background: var(--db-card);
  color: var(--db-char);
  border: var(--db-rule) solid var(--db-border-strong);
  border-top: var(--db-rule-strong) solid var(--db-red);
  border-radius: var(--db-radius-xs);
  box-shadow: var(--db-shadow-dropdown);
}
.leaflet-popup-content { margin: 10px 12px; font-size: var(--db-text-xs); line-height: var(--db-leading-snug); }
.leaflet-popup-tip { background: var(--db-card); box-shadow: none; }
.leaflet-popup-close-button { color: var(--db-muted) !important; }

.leaflet-tooltip {
  background: var(--db-card);
  color: var(--db-char);
  border: var(--db-rule) solid var(--db-border-strong);
  border-radius: var(--db-radius-xs);
  box-shadow: var(--db-shadow-sm);
  font-family: var(--db-font);
  font-size: var(--db-text-xs);
}
.leaflet-tooltip-top:before { border-top-color: var(--db-border-strong); }
.leaflet-tooltip-bottom:before { border-bottom-color: var(--db-border-strong); }
.leaflet-tooltip-left:before { border-left-color: var(--db-border-strong); }
.leaflet-tooltip-right:before { border-right-color: var(--db-border-strong); }

/* ── Reduced motion ────────────────────────────────────────────────────────
   tokens.css neuters the --db-motion-* tokens globally, which covers anything
   built on them. These two are the transitions in this file that are not. */
@media (prefers-reduced-motion: reduce) {
  .db-maprail-btn { transition: none; }
  .dbb-tick { transition: none; }
}
