/* G-66 / G-75 product chrome. Uses only --sc-* from sc-kit.css. Declares no tokens. */

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--sc-canvas);
  color: var(--sc-ink);
  font-family: var(--sc-font-ui);
  font-size: 14px;
  line-height: 20px;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
a { color: var(--sc-accent); }
:focus-visible {
  outline: 2px solid var(--sc-focus);
  outline-offset: 2px;
  border-radius: 3px;
}
/* G-95, and the rule that is deliberately NOT here.
   The first draft of this card added iframe:focus with the same outline, on the
   reading that Tab lands on each mount frame and paints nothing. Measured, that
   rule can never match: with document.activeElement === #map-site, the frame
   itself reports matches(":focus") false and matches(":focus-visible") false,
   because focus has crossed into the mounted document and the element carrying
   :focus lives there. A rule that cannot fire is decorative, and shipping one
   would have read as a fix in the diff and changed no pixel. The indicator for
   a control inside a mount is painted by the mounted product, which answers for
   its own conformance; scripts/a11y-scan.mjs reports each crossing by name
   rather than scoring it clean. */

/* ---------- the hidden attribute ---------- */

/* The kit gives .pill, .prov, .state, .metric and a dozen others an explicit
   display, and an author declaration of equal or greater weight beats the
   user-agent [hidden] rule. So el.hidden = true was inert on exactly the
   components most likely to be shown conditionally, and it shipped: an amber
   Partial pill rendered beside the words "No meeting packet has been read".
   Two components had already bought their way out one selector at a time
   (.stage and .stage-esc each carried a private [hidden] patch, both deleted
   with this rule). A third would have followed, then a fourth.

   Why this form. An attribute selector and a class both score one, so [hidden]
   and .pill tie and source order decides the winner; doubling the attribute to
   raise the score beats one class but ties .lens.on and loses to any future
   rule carrying three. Every specificity answer is a bet on where the next
   component rule lands in this file, and that bet is the thing this card is
   here to retire. An important author declaration is the only form that wins
   over every normal author declaration whatever its specificity and wherever
   it sits, and over a normal inline style as well, so this rule holds without
   knowing anything about the rest of the stylesheet.

   The :not() leaves hidden="until-found" alone, because the user-agent sheet
   gives that value content-visibility rather than display: none. The rule
   restores the platform default at a weight components cannot accidentally
   override; it does not invent a stronger one. No markup here uses that value
   today, and this keeps the day it does from being a surprise.

   Guarded by src/hidden-rule.test.mjs, which also fails if a per-component
   [hidden] patch reappears. */
[hidden]:not([hidden="until-found" i]) { display: none !important; }

/* ---------- type ---------- */

.t-label {
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
}
.t-caption { font: 400 12px/16px var(--sc-font-ui); color: var(--sc-ink-3); }
.t-data {
  font: 400 13px/18px var(--sc-font-data);
  font-variant-numeric: tabular-nums;
  color: var(--sc-ink);
}

/* ---------- controls ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border-radius: var(--sc-r-control);
  border: 1px solid var(--sc-line);
  background: var(--sc-surface);
  color: var(--sc-ink);
  font: 500 14px/20px var(--sc-font-ui);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { background: var(--sc-surface-2); border-color: var(--sc-line-strong); }
.btn-primary { background: var(--sc-accent); border-color: var(--sc-accent); color: var(--sc-on-accent); }
.btn-primary:hover { background: var(--sc-accent-hi); border-color: var(--sc-accent-hi); color: var(--sc-on-accent); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--sc-ink-2); }
.btn-ghost:hover { background: var(--sc-surface-3); color: var(--sc-ink); border-color: transparent; }
.btn-sm { height: 26px; padding: 0 9px; font-size: 12px; }
.btn[disabled], .btn[aria-disabled="true"] {
  color: var(--sc-ink-3);
  background: var(--sc-surface-2);
  border-color: var(--sc-line-faint);
  cursor: not-allowed;
}
.inp {
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r-control);
  background: var(--sc-surface);
  color: var(--sc-ink);
  font: 400 14px/30px var(--sc-font-ui);
  width: 100%;
}
.inp::placeholder { color: var(--sc-ink-3); }
.inp:disabled {
  background: var(--sc-surface-2);
  border-color: var(--sc-line-faint);
  color: var(--sc-ink-3);
  cursor: not-allowed;
}
.searchwrap { position: relative; display: flex; align-items: center; gap: var(--sc-2); flex: 1; min-width: 0; }
/* The Not built badge sits inside the field, so the field reserves its width
   rather than letting the placeholder run under it. */
.searchwrap .inp { padding-left: 30px; padding-right: 100px; }
.searchwrap > svg { position: absolute; left: 9px; color: var(--sc-ink-3); pointer-events: none; }
.searchwrap .badge-off {
  position: absolute;
  right: 8px;
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
  border: 1px solid var(--sc-line);
  border-radius: 3px;
  padding: 1px 5px;
  background: var(--sc-surface-2);
  pointer-events: none;
}

/* ---------- pills, provenance ---------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--sc-r-full);
  font: 500 12px/16px var(--sc-font-ui);
  border: 1px solid transparent;
  white-space: nowrap;
}
.p-ok { color: var(--sc-ok); background: var(--sc-ok-wash); }
.p-info { color: var(--sc-info); background: var(--sc-info-wash); }
.p-warn { color: var(--sc-warn); background: var(--sc-warn-wash); }
.p-crit { color: var(--sc-crit); background: var(--sc-crit-wash); }
.p-restricted { color: var(--sc-restricted); background: var(--sc-restricted-wash); }
.p-quiet { color: var(--sc-quiet); background: var(--sc-quiet-wash); }

.prov {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 20px;
  padding: 0 7px;
  border-radius: var(--sc-r-control);
  border: 1px solid var(--sc-line);
  background: var(--sc-surface-2);
  font: 400 13px/18px var(--sc-font-data);
  font-variant-numeric: tabular-nums;
  color: var(--sc-ink-3);
  white-space: nowrap;
}
.prov b { color: var(--sc-ink-2); font-weight: 500; }
.prov .sep { color: var(--sc-line-strong); }
a.prov { text-decoration: none; }
a.prov:hover { border-color: var(--sc-line-strong); background: var(--sc-surface-3); }

/* ---------- panels ---------- */

.panel {
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r);
  background: var(--sc-surface);
  overflow: hidden;
}
.panel-head {
  display: flex;
  align-items: center;
  gap: var(--sc-2);
  min-height: 42px;
  padding: var(--sc-2) var(--sc-4);
  border-bottom: 1px solid var(--sc-line-faint);
  background: var(--sc-surface);
  flex-wrap: wrap;
}
.panel-head .t { font: 620 15px/22px var(--sc-font-ui); letter-spacing: -0.008em; color: var(--sc-ink); }
.panel-head .sub { font: 400 12px/16px var(--sc-font-ui); color: var(--sc-ink-3); }
.panel-head .grow, .grow { flex: 1; }
.panel-body { padding: var(--sc-4); }
.panel-body.flush { padding: 0; }
.panel-body > p { margin: 0 0 var(--sc-2); color: var(--sc-ink-2); max-width: 68ch; }
.panel-body > p:last-child { margin-bottom: 0; }

/* ---------- tabs ---------- */

.tabs {
  display: flex;
  gap: var(--sc-5);
  border-bottom: 1px solid var(--sc-line);
  padding: 0 var(--sc-5);
  overflow-x: auto;
  background: var(--sc-surface);
  flex: none;
}
.tabs a, .tabs button {
  appearance: none;
  background: none;
  border: 0;
  cursor: pointer;
  font: 500 14px/20px var(--sc-font-ui);
  color: var(--sc-ink-3);
  padding: 12px 0 11px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  text-decoration: none;
  white-space: nowrap;
}
.tabs a:hover, .tabs button:hover { color: var(--sc-ink); }
.tabs a[aria-selected="true"], .tabs button[aria-selected="true"] {
  color: var(--sc-ink);
  border-bottom-color: var(--sc-accent);
}

/* ---------- tables, registers ---------- */

.dt { width: 100%; border-collapse: collapse; font-size: 14px; background: var(--sc-surface); }
.dt thead th {
  text-align: left;
  background: var(--sc-surface-2);
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
  padding: 0 var(--sc-4);
  height: 34px;
  border-bottom: 1px solid var(--sc-line);
}
.dt tbody td {
  padding: 0 var(--sc-4);
  height: var(--sc-row);
  border-bottom: 1px solid var(--sc-line-faint);
  color: var(--sc-ink-2);
  vertical-align: middle;
}
.dt .id { font-family: var(--sc-font-data); font-size: 13px; color: var(--sc-ink); font-variant-numeric: tabular-nums; }
.dt .subj { color: var(--sc-ink); }

.srcreg {
  display: grid;
  grid-template-columns: 3px minmax(0, 1fr) auto;
  gap: var(--sc-3);
  align-items: center;
  padding: 11px var(--sc-4);
  border-bottom: 1px solid var(--sc-line-faint);
}
.srcreg:last-child { border-bottom: 0; }
.srcreg .rail { align-self: stretch; background: var(--sc-line); border-radius: var(--sc-r-full); }
.srcreg.ok .rail { background: var(--sc-ok); }
.srcreg.partial .rail { background: var(--sc-warn); }
.srcreg[data-disposition="Mounted"] .rail { background: var(--sc-restricted); }
.srcreg[data-disposition="Island"] .rail { background: var(--sc-warn); }
.srcreg .nm { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.srcreg .nm b { font: 600 14px/20px var(--sc-font-ui); color: var(--sc-ink); }
.srcreg .nm span { font: 400 12px/16px var(--sc-font-ui); color: var(--sc-ink-3); }

.reg-group {
  display: flex;
  align-items: center;
  gap: var(--sc-2);
  padding: var(--sc-2) var(--sc-4);
  background: var(--sc-surface-2);
  border-bottom: 1px solid var(--sc-line-faint);
  border-top: 1px solid var(--sc-line-faint);
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
  position: sticky;
  top: 0;
  z-index: 1;
}
.reg-group:first-child { border-top: 0; }

/* ---------- honest-empty state ---------- */

.state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sc-3);
  padding: var(--sc-8) var(--sc-6);
  max-width: 62ch;
}
.state .st-k {
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
}
/* G-95. The state headline is an h2, and h5 is deliberately NOT in this
   selector any more. Every one of these sits directly under the page h1, so an
   h5 skipped three levels and misrepresented the document outline - 1.3.1 Info
   and Relationships, and 2.4.6 Headings and Labels in a conformance report.
   Leaving h5 styled here would have made a re-introduced skip look correct on
   the screen while the gate went red, which is the quietest way for a fix to
   rot. */
.state h2 { font: 620 15px/22px var(--sc-font-ui); letter-spacing: -0.008em; margin: 0; color: var(--sc-ink); }
.state p { font: 400 14px/20px var(--sc-font-ui); color: var(--sc-ink-2); margin: 0; max-width: none; }
/* A basis line reads the same wherever it appears, inside an empty state or
   under a panel paragraph. Scoping it to .state left the loose ones unstyled. */
.basis {
  display: block;
  font: 400 13px/18px var(--sc-font-data);
  color: var(--sc-ink-3);
  border-left: 2px solid var(--sc-line);
  padding-left: var(--sc-3);
  margin-top: var(--sc-3);
}
.state .basis { margin-top: var(--sc-1); }
.state.compact { padding: var(--sc-6) var(--sc-5); }

/* ---------- metric strip ---------- */

.metrics {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sc-3);
  flex: none;
}
.metric {
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r);
  background: var(--sc-surface);
  padding: var(--sc-3) var(--sc-4) var(--sc-4);
  display: flex;
  flex-direction: column;
  gap: var(--sc-1);
  min-width: 0;
}
/* G-120. On Overview, each tile is a filtered entry point rather than a
   static figure, and IS its own <a href>. A first draft kept .metric a plain
   div and covered it with a full-bleed absolutely-positioned sibling anchor;
   the CI a11y gate correctly failed that (color-contrast: axe cannot SETTLE
   a background for text with an overlapping positioned box on top of it,
   "bgOverlap" - and a positioned box paints above in-flow inline content
   regardless of DOM order, so ordering the overlay last did not help). The
   anchor is the card itself instead, so there is no overlap to resolve.
   Every other lens's .metric stays a plain div; this reset is scoped to the
   anchor form only. */
a.metric { text-decoration: none; }
a.metric:hover { border-color: var(--sc-line-strong); }
/* At the 12px floor a key like MEETINGS THIS WEEK no longer fits one narrow
   column, and an ellipsis would drop the label rather than the decoration. The
   four metrics are grid items and stretch together, so wrapping costs nothing. */
.metric .k {
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
}
.metric .v {
  font: 400 26px/32px var(--sc-font-data);
  font-variant-numeric: tabular-nums;
  color: var(--sc-ink-3);
  letter-spacing: -0.01em;
}
.metric.has-value .v { color: var(--sc-ink); }
/* A metric with no source states that in words. It never shows a zero, because
   a zero here would be a claim the city has not made. */
.metric .v.word { font: 620 15px/32px var(--sc-font-ui); letter-spacing: -0.008em; }
.metric .n { font: 400 12px/16px var(--sc-font-ui); color: var(--sc-ink-3); }

/* ---------- across-departments grid (G-120) ---------- */

.deptsection { display: flex; flex-direction: column; gap: var(--sc-3); }
.deptsection-head { display: flex; align-items: baseline; gap: var(--sc-2); }
.deptsection-head h2 { font: 620 15px/22px var(--sc-font-ui); letter-spacing: -0.008em; margin: 0; color: var(--sc-ink); }
.deptgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sc-3); }
.deptcard {
  display: grid;
  grid-template-columns: 3px minmax(0, 1fr);
  gap: var(--sc-3);
  padding: var(--sc-3) var(--sc-4);
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r);
  background: var(--sc-surface);
  min-width: 0;
}
.deptcard .rail { background: var(--sc-line); border-radius: var(--sc-r-full); }
.deptcard .nm { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.deptcard .nm b { font: 600 14px/20px var(--sc-font-ui); color: var(--sc-ink); }
.deptcard .nm .basis { margin-top: 0; }

/* ---------- attention row (tier 1: filtered entry points, primary) ---------- */
/* Reuses .metrics/.metric's card look at six columns instead of four. G-123:
   acceptance is the click, not the number, so every tile is a real link --
   the SAME a.metric anchor-is-the-card shape G-120 already established and
   hardened on Overview (a.metric { text-decoration: none } above), after its
   own first draft (a full-bleed overlay anchor) failed CI's a11y gate on
   color-contrast (bgOverlap: a positioned box paints over in-flow text
   regardless of DOM order, so axe cannot resolve a background for it). No
   second link-styling rule is added here; the tile is the anchor itself. */
.metrics.attn { grid-template-columns: repeat(6, minmax(0, 1fr)); }

/* ---------- tab strip inline counts (tier 2) ---------- */
.tabs .n {
  font: 400 12px/16px var(--sc-font-data);
  font-variant-numeric: tabular-nums;
  color: var(--sc-ink-3);
}

/* ---------- tab metric strip (tier 3: compact, secondary, no cards) ---------- */
.metricbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  border: 1px solid var(--sc-line-faint);
  border-radius: var(--sc-r);
  background: var(--sc-surface-2);
  padding: var(--sc-1) 0;
  flex: none;
}
.metricbar-item {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 6px var(--sc-4);
  border-left: 1px solid var(--sc-line-faint);
}
.metricbar-item:first-child { border-left: 0; }
.metricbar-item .v {
  font: 400 17px/22px var(--sc-font-data);
  font-variant-numeric: tabular-nums;
  color: var(--sc-ink);
}
.metricbar-item .v.word { font: 620 13px/22px var(--sc-font-ui); color: var(--sc-ink-3); }
.metricbar-item .k { font: 400 12px/16px var(--sc-font-ui); color: var(--sc-ink-3); }

/* ---------- ONE load component (inspector / manager / officer load) ---------- */
.loadstrip-head { display: flex; align-items: center; gap: var(--sc-2); padding: var(--sc-2) var(--sc-3); }
.loadstrip-head .t { font: 600 13px/18px var(--sc-font-ui); color: var(--sc-ink); }
.loadstrip-head .n { font: 400 12px/16px var(--sc-font-data); color: var(--sc-ink-3); }
.loadstrip-body { display: flex; gap: var(--sc-2); padding: 0 var(--sc-3) var(--sc-3); flex-wrap: wrap; }
.loadcard {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 120px;
  padding: var(--sc-2) var(--sc-3);
  border: 1px solid var(--sc-line-faint);
  border-radius: var(--sc-r-control);
  background: var(--sc-surface-2);
}
.loadcard .who { font: 600 13px/18px var(--sc-font-ui); color: var(--sc-ink); }
.loadcard .row { display: flex; align-items: center; gap: 6px; }
.loadcard .n { font: 400 13px/18px var(--sc-font-data); font-variant-numeric: tabular-nums; color: var(--sc-ink-2); }
.loadcard .bar { flex: 1; height: 3px; border-radius: 2px; background: var(--sc-line); }
.loadcard .bar > i { display: block; height: 3px; border-radius: 2px; background: var(--sc-accent); }
.loadcard .bar > i.hot { background: var(--sc-crit); }

/* ---------- view mode segmented control (List / Map / Performance) ---------- */
.seg { display: flex; gap: 2px; padding: 2px; background: var(--sc-surface-2); border: 1px solid var(--sc-line); border-radius: var(--sc-r-control); flex: none; }
.seg button {
  appearance: none;
  border: 0;
  cursor: pointer;
  font: 500 12px/16px var(--sc-font-ui);
  padding: 3px 10px;
  border-radius: 3px;
  color: var(--sc-ink-3);
  background: transparent;
}
.seg button[aria-selected="true"] { color: var(--sc-ink); background: var(--sc-surface); }

/* ---------- filter bar ---------- */
.filterbar { display: flex; align-items: center; gap: var(--sc-2); flex-wrap: wrap; padding: var(--sc-2) var(--sc-3); border-bottom: 1px solid var(--sc-line-faint); flex: none; }
.filterbar input[type="search"] {
  flex: 1;
  min-width: 200px;
  height: 28px;
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r-control);
  background: var(--sc-surface-2);
  padding: 0 var(--sc-3);
  font: 400 13px/18px var(--sc-font-ui);
  color: var(--sc-ink);
}
.filterbar select {
  height: 28px;
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r-control);
  background: var(--sc-surface);
  padding: 0 var(--sc-2);
  font: 400 13px/18px var(--sc-font-ui);
  color: var(--sc-ink-2);
}
.filterbar .n { font: 400 12px/16px var(--sc-font-data); color: var(--sc-ink-3); }
.filterbar .reset { font: 400 12px/16px var(--sc-font-ui); color: var(--sc-accent); background: none; border: 0; cursor: pointer; padding: 0; }

/* ---------- pagination, at the foot of every table ---------- */
.pager { display: flex; align-items: center; padding: var(--sc-2) var(--sc-4); border-top: 1px solid var(--sc-line-faint); flex: none; }
.pager button {
  appearance: none;
  background: none;
  border: 0;
  cursor: pointer;
  font: 400 12px/16px var(--sc-font-ui);
  color: var(--sc-accent);
  padding: 0;
}
.pager button:disabled { color: var(--sc-ink-3); cursor: default; }
.pager .pos { flex: 1; text-align: center; font: 400 12px/16px var(--sc-font-data); color: var(--sc-ink-3); }

/* ---------- region and mount anchor ---------- */

.region {
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r);
  overflow: hidden;
  background: var(--sc-surface);
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
}
.region-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  column-gap: var(--sc-2);
  row-gap: var(--sc-1);
  min-height: 38px;
  padding: var(--sc-1) var(--sc-2) var(--sc-1) var(--sc-3);
  border-bottom: 1px solid var(--sc-line-faint);
  flex: none;
}
.region-bar .t {
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
}
.region-canvas {
  position: relative;
  background: var(--sc-map-ground);
  flex: 1;
  min-height: 0;
}
.region-canvas.doc { background: var(--sc-doc-ground); }
/* Placeholder sits under the stage. It is what a reader sees if the mount
   never arrives, so it states that rather than showing an empty rectangle. */
.mount-note {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sc-1);
  text-align: center;
  padding: var(--sc-5);
  color: var(--sc-ink-3);
  font: 400 14px/20px var(--sc-font-ui);
}
.region-foot {
  border-top: 1px solid var(--sc-line-faint);
  padding: var(--sc-2) var(--sc-3);
  background: var(--sc-surface);
  display: flex;
  align-items: center;
  gap: var(--sc-3);
  flex-wrap: wrap;
  flex: none;
}

/* ---------- app frame ---------- */

.shell {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--sc-canvas);
  overflow: hidden;
}
.cp-recede {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  transform-origin: 50% 50%;
}
.shell-top {
  display: flex;
  align-items: center;
  gap: var(--sc-3);
  height: var(--sc-topbar);
  padding: 0 var(--sc-4);
  background: var(--sc-surface);
  border-bottom: 1px solid var(--sc-line);
  z-index: 6;
  box-shadow: var(--sc-e1);
  flex: none;
}
.seal {
  width: 24px;
  height: 24px;
  border-radius: 3px;
  border: 1px solid var(--sc-line-strong);
  display: grid;
  place-items: center;
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.06em;
  color: var(--sc-ink-2);
  background: var(--sc-surface-3);
  flex: none;
}
.brandcity { font: 600 14px/20px var(--sc-font-ui); color: var(--sc-ink); white-space: nowrap; }
.brandcity span { font-weight: 400; color: var(--sc-ink-3); }
.env {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--sc-r-control);
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px dashed var(--sc-line-strong);
  color: var(--sc-ink-3);
  white-space: nowrap;
  flex: none;
}
.env.demo { border-color: var(--sc-warn); color: var(--sc-warn); background: var(--sc-warn-wash); }
.menu-btn { display: none; }
.shell-top .grow { flex: 1; min-width: 0; }
.shell-top .searchwrap { max-width: 420px; }

/* ---------- top-bar menus (G-90 shell function parity) ----------

   Four new class names, and they are the smallest set that a dropdown needs:
   an anchor that a panel can be positioned against, the panel itself, a group
   inside it, and a row. Everything else composes classes this file already
   defines - .panel for the frame, .panel-head for the header, .basis for the
   reason line, .btn for the controls, .pill for the session state.

   NO TOKEN IS ADDED OR OVERRIDDEN. Every value below is an existing var(--sc-*)
   or a layout number. web/sc-kit.css stays byte-identical across the three
   repos that vendor it; a new colour or type step is a product-line decision
   and not this card's to make.

   The type floor holds: 13px on a row, 12px on a caption, which are the steps
   already used by .t-caption and .prov. */

.topmenu { position: relative; flex: none; }
.pop {
  position: absolute;
  top: calc(100% + var(--sc-2));
  right: 0;
  z-index: 12;
  width: 320px;
  max-width: calc(100vw - var(--sc-6));
  box-shadow: var(--sc-e3);
  /* The account menu can outgrow a short viewport once every group states its
     basis, so the panel scrolls rather than running off the bottom of the
     screen with the sign-in row unreachable. */
  max-height: calc(100vh - var(--sc-topbar) - var(--sc-6));
  overflow-y: auto;
}
/* .panel sets overflow:hidden for its rounded corners, and .pop needs to scroll.
   Stated here rather than in .panel, so no other panel in the product changes. */
.panel.pop { overflow-y: auto; }
.pop-group {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sc-1);
  padding: var(--sc-2) var(--sc-3) var(--sc-3);
  border-bottom: 1px solid var(--sc-line-faint);
}
.pop-group:last-child { border-bottom: 0; }
.pop-group > .basis { margin-top: var(--sc-2); }
.pop-group > .actionbar { margin-top: var(--sc-2); }
.pop-group > textarea.inp {
  height: auto;
  padding: var(--sc-2) 10px;
  line-height: 18px;
  resize: vertical;
}
.pop-item {
  display: flex;
  align-items: center;
  gap: var(--sc-2);
  width: 100%;
  min-height: var(--sc-row-compact);
  padding: 0 var(--sc-2);
  border: 1px solid transparent;
  border-radius: var(--sc-r-control);
  background: transparent;
  color: var(--sc-ink);
  font: 400 13px/18px var(--sc-font-ui);
  text-align: left;
  cursor: pointer;
}
.pop-item:hover { background: var(--sc-surface-3); }
/* An unavailable entry reads as unavailable rather than merely unresponsive.
   Its reason is the .basis line its group carries, filled from the server. */
.pop-item[disabled] {
  color: var(--sc-ink-3);
  cursor: not-allowed;
  background: transparent;
}
.pop-item[disabled]:hover { background: transparent; }

.shell-body {
  display: grid;
  grid-template-columns: var(--sc-nav) minmax(0, 1fr);
  flex: 1;
  min-height: 0;
}
.shell-nav {
  border-right: 1px solid var(--sc-line);
  background: var(--sc-surface);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.navgroup { padding: var(--sc-3) var(--sc-2) 0; }
.navgroup:first-child { padding-top: var(--sc-4); }
.navgroup > .gl {
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
  padding: 0 10px var(--sc-2);
}
/* Label at the body step and badge at the 12px floor no longer always fit one
   248px row. The row keeps auto height and the badge drops under the label,
   right-aligned, rather than the badge going under the floor or a state word
   being dropped. The markup is unchanged. */
.navitem {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  column-gap: 9px;
  row-gap: 2px;
  min-height: 32px;
  padding: 6px 10px;
  margin-bottom: 1px;
  border-radius: var(--sc-r-control);
  font: 500 14px/20px var(--sc-font-ui);
  color: var(--sc-ink-2);
  text-decoration: none;
  cursor: pointer;
  position: relative;
}
.navitem:hover { background: var(--sc-surface-3); color: var(--sc-ink); }
.navitem.on { background: var(--sc-accent-wash); color: var(--sc-accent); }
.navitem.on::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  border-radius: var(--sc-r-full);
  background: var(--sc-accent);
}
.navitem .badge {
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
  border: 1px solid var(--sc-line);
  border-radius: 3px;
  padding: 0 5px;
  flex: none;
  margin-left: auto;
}
.navitem.roster { color: var(--sc-ink-3); }
.navitem.roster:hover { color: var(--sc-ink-2); }
.navitem.unbuilt { color: var(--sc-ink-3); cursor: default; }
.navitem.unbuilt:hover { background: transparent; color: var(--sc-ink-3); }
.nav-foot {
  margin-top: auto;
  border-top: 1px solid var(--sc-line-faint);
  padding: var(--sc-3);
  position: sticky;
  bottom: 0;
  background: var(--sc-surface);
}
/* The sidebar is 248px and the source line is derived, so it can grow. Let it
   wrap onto two lines rather than run off the edge of the nav. */
.nav-foot .prov {
  display: flex;
  height: auto;
  min-height: 20px;
  padding: 5px 7px;
  white-space: normal;
  flex-wrap: wrap;
  row-gap: 2px;
  line-height: 18px;
}

.shell-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: var(--sc-canvas);
}
.pagehead {
  padding: var(--sc-3) var(--sc-5) var(--sc-4);
  border-bottom: 1px solid var(--sc-line);
  background: var(--sc-surface);
  display: flex;
  flex-direction: column;
  gap: var(--sc-2);
  flex: none;
}
.crumb { display: flex; align-items: center; gap: 7px; font: 400 12px/16px var(--sc-font-ui); color: var(--sc-ink-3); flex-wrap: wrap; }
.crumb b { font-weight: 500; color: var(--sc-ink-2); }
.pagehead .titlerow { display: flex; align-items: center; gap: var(--sc-3); flex-wrap: wrap; }
.pagehead h1 { font: 620 19px/26px var(--sc-font-ui); letter-spacing: -0.015em; margin: 0; color: var(--sc-ink); }
.pagehead .fill { flex: 1; }
.pagehead .lede { font: 400 14px/20px var(--sc-font-ui); color: var(--sc-ink-3); margin: 0; max-width: 68ch; }

/* The work surface: fills the frame, columns scroll independently. */
.shell-regions {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--sc-rail);
  gap: var(--sc-4);
  padding: var(--sc-4) var(--sc-5);
  align-items: stretch;
}
.shell-regions.solo { grid-template-columns: minmax(0, 1fr); }
.colstack {
  display: flex;
  flex-direction: column;
  gap: var(--sc-4);
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: var(--sc-1);
}
/* Panels keep their content height and the column scrolls. Without this they
   shrink to fit the column and .panel overflow clips the copy mid-sentence. */
.colstack > * { flex: none; }
/* The rail holds the map. On a short viewport the rail scrolls rather than
   crushing the map back into a postage stamp; the stage tracks the anchor. */
.colstack.rail > .region { flex: 1; min-height: 260px; }
.colstack.rail > .panel { flex: none; }

/* ---------- map dock: three states (G-128) ----------
   Dock (default, no [data-map-mode] override needed): the map region takes
   the remaining rail height (flex:1 above) and any panels beneath it stack
   full-width, because .colstack is already flex-column -- this is the
   Overview pattern this generalizes to Development services. Expand/Full
   are set on .shell-regions by web/app.js from the map's own in-iframe
   Dock/Expand/Full pill (property-map.js's setDockMode(), postMessage'd up
   as "state", never map-engine data) and reflow two things: the lens's own
   primary content shrinks to a quiet 250px strip (Expand) or is hidden
   entirely (Full), and the rail's own trailing panels -- wrapped in
   .mapdock-row, a lens supplies zero, one or two of them -- move from
   stacked-beneath (Dock) to a side-by-side row (Expand/Full) beneath the
   now-larger map. mapdock-row is display:contents in Dock so its children
   join .colstack.rail's own flex-column directly, needing no extra rule
   there beyond the existing .colstack.rail > .panel above -- but contents
   does not change DOM-selector matching, so mapdock-row > .mapdock-detail/
   .mapdock-records get their own flex:none for that case explicitly. */
.shell-regions[data-map-mode="expand"] {
  grid-template-columns: 250px minmax(0, 1fr);
}
.shell-regions[data-map-mode="full"] {
  grid-template-columns: 0 minmax(0, 1fr);
}
.shell-regions[data-map-mode="expand"] > .colstack:not(.rail) {
  opacity: 0.55;
  pointer-events: none;
  overflow: hidden;
}
.shell-regions[data-map-mode="full"] > .colstack:not(.rail) {
  display: none;
}
.mapdock-row {
  display: contents;
}
.mapdock-row > .mapdock-detail,
.mapdock-row > .mapdock-records {
  flex: none;
}
.shell-regions[data-map-mode="expand"] .mapdock-row,
.shell-regions[data-map-mode="full"] .mapdock-row {
  display: flex;
  flex-direction: row;
  flex: none;
  gap: var(--sc-3);
  height: 320px;
}
.shell-regions[data-map-mode="expand"] .mapdock-row > .mapdock-records,
.shell-regions[data-map-mode="full"] .mapdock-row > .mapdock-records {
  flex: 2 1 0;
  min-width: 0;
}
.shell-regions[data-map-mode="expand"] .mapdock-row > .mapdock-detail {
  flex: 1 1 0;
  min-width: 0;
}
.shell-regions[data-map-mode="full"] .mapdock-row > .mapdock-detail {
  flex: none;
  width: 320px;
}

/* The property-detail attribute rows (zoning/flood/buildable area). Composes
   existing tokens only, same shape family as .metricbar-item's label+value
   but a fuller row: a label, a value, and a provenance caption -- .basis
   already carries that caption role elsewhere, reused here rather than
   invented twice. */
.pdl-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px var(--sc-3);
  border-bottom: 1px solid var(--sc-line-faint);
}
.pdl-row:last-child { border-bottom: none; }
.pdl-row .k {
  font: 500 12px/16px var(--sc-font-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
}
.pdl-row .v { font: 400 14px/20px var(--sc-font-ui); color: var(--sc-ink); }
.pdl-row .basis { margin-top: var(--sc-1); }

.lens { display: none; }
.lens.on { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.ds-tab, .assets-tab { display: none; }
.ds-tab.on, .assets-tab.on { display: flex; flex-direction: column; flex: 1; min-height: 0; }

/* ---------- first paint ---------- */

/* G-89. The four rules above decide visibility from a class that app.js moves,
   and app.js is a module, so that class cannot arrive until the whole document
   has parsed. Every deep link therefore painted the one surface carrying
   class="on" in the static markup - Overview - and then switched. On a
   not-built surface the operator watched a populated screen collapse into an
   honest-empty one, which reads as a broken deploy.

   CSS cannot read a query string, and this repo has no build step. So the
   inline classless script in the <head> of web/index.html resolves the query
   before the parser reaches the body and stamps three attributes on the root,
   and the rules below key visibility off those. The switch is gone because the
   first paint is already correct, not because it happens sooner.

   THE GATE IS PRESENCE, NOT VALUE. With scripting off nothing is stamped, none
   of the three hide rules below matches, and .lens.on above governs exactly as
   it did before. That is what keeps the scripting-disabled behaviour identical
   rather than merely similar.

   SPECIFICITY, COMPUTED RATHER THAN ASSUMED, because "it should win" is not a
   measurement and both rules are live at once:
     html[data-surface] .lens                          (0,2,1)
     .lens.on                                          (0,2,0)  <- loses
     html[data-surface="lens-finance"] #lens-finance   (1,1,1)  <- wins both
   One id outranks any number of classes and attributes, so the show rule beats
   the hide rule, and the hide rule beats the static class without depending on
   source order. No !important is used or needed: src/hidden-rule.test.mjs
   check 4 forbids a second display-!important rule in this file, and the one
   that exists - the bare [hidden] rule - stays the only thing that outranks
   all of this, which is correct, since hidden means hidden.

   THE SHOW LISTS ARE ENUMERATIONS because CSS cannot compare two attribute
   values. Fifteen surfaces, six Development-services tabs, three Assets tabs.
   Nothing keeps an enumeration in step with a section list except a test, so
   src/first-paint.test.mjs asserts each list below equals both the panel ids
   in web/index.html and the id lists exported by src/staff-review.mjs. A
   sixteenth surface added without its selector fails the suite rather than
   shipping a screen that paints blank. */

html[data-surface] .lens { display: none; }
html[data-surface="lens-city-manager"] #lens-city-manager,
html[data-surface="lens-development-services"] #lens-development-services,
html[data-surface="lens-finance"] #lens-finance,
html[data-surface="lens-citizen"] #lens-citizen,
html[data-surface="lens-public-works"] #lens-public-works,
html[data-surface="lens-parks"] #lens-parks,
html[data-surface="lens-police"] #lens-police,
html[data-surface="lens-fire-ems"] #lens-fire-ems,
html[data-surface="lens-fleet"] #lens-fleet,
html[data-surface="work-review"] #work-review,
html[data-surface="work-files"] #work-files,
html[data-surface="work-records"] #work-records,
html[data-surface="work-assets"] #work-assets,
html[data-surface="work-connections"] #work-connections,
html[data-surface="work-people"] #work-people {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* The same defect one altitude down: #tab-pipeline and #atab-inventory also
   carry class="on" in the static markup, so ?tab=review painted the Pipeline
   table and then swapped it out. Same mechanism, same script, same shape. */
html[data-tab] .ds-tab { display: none; }
html[data-tab="pipeline"] #tab-pipeline,
html[data-tab="inspections"] #tab-inspections,
html[data-tab="work-orders"] #tab-work-orders,
html[data-tab="code-enforcement"] #tab-code-enforcement,
html[data-tab="licenses"] #tab-licenses,
html[data-tab="plan-review"] #tab-plan-review,
html[data-tab="flood-study"] #tab-flood-study {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

html[data-atab] .assets-tab { display: none; }
html[data-atab="inventory"] #atab-inventory,
html[data-atab="map"] #atab-map,
html[data-atab="fixture"] #atab-fixture {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* ---------- citizen, scoped light ---------- */

.cz {
  max-width: 760px;
  width: 100%;
  margin: 0 auto;
  padding: var(--sc-8) var(--sc-5) var(--sc-9);
  display: flex;
  flex-direction: column;
  gap: var(--sc-5);
}
.cz-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: var(--sc-canvas);
}
.cz h1 { font: 650 26px/32px var(--sc-font-ui); letter-spacing: -0.022em; margin: 0; color: var(--sc-ink); }
.cz p { font-size: 15px; line-height: 23px; margin: var(--sc-2) 0 0; max-width: none; color: var(--sc-ink-2); }
.cz .btn, .cz .inp { height: 44px; font-size: 15px; }
.cz .panel-body > p { font-size: 15px; line-height: 23px; }
.citizen-lookup { display: flex; gap: var(--sc-3); flex-wrap: wrap; align-items: center; }
.citizen-lookup .searchwrap { min-width: 240px; }

/* ---------- Compass ---------- */

.cp-source {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  /* The label is body-em and the scope is the data step, so the stack is 38px
     and the control can no longer be pinned to 32px inside the 52px bar. */
  height: auto;
  min-height: 32px;
  padding: 2px 10px;
  border-radius: var(--sc-r-control);
  border: 1px solid var(--sc-line);
  background: var(--sc-surface-2);
  color: var(--sc-ink-2);
  cursor: pointer;
  font: inherit;
  flex: none;
}
.cp-source:hover { border-color: var(--sc-line-strong); background: var(--sc-surface-3); }
.cp-source .cp-src-l { display: flex; flex-direction: column; align-items: flex-start; line-height: 1; }
.cp-source .cp-src-l b { font: 600 14px/20px var(--sc-font-ui); color: var(--sc-ink); }
.cp-source .cp-src-l em { font: 400 13px/18px var(--sc-font-data); font-style: normal; color: var(--sc-ink-3); }
.cp-scrim { position: fixed; inset: 0; background: var(--sc-canvas); opacity: 0.34; z-index: 8; }
.cp-sheet {
  position: fixed;
  z-index: 9;
  background: var(--sc-surface);
  border: 1px solid var(--sc-line);
  box-shadow: var(--sc-e3);
  overflow: hidden;
  transform-origin: 0 0;
  width: 400px;
  max-width: 100vw;
}
.cp-inner { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.cp-head {
  display: flex;
  align-items: center;
  gap: var(--sc-2);
  padding: 0 var(--sc-3);
  height: 40px;
  border-bottom: 1px solid var(--sc-line-faint);
  flex: none;
}
.cp-grab { width: 26px; height: 4px; border-radius: var(--sc-r-full); background: var(--sc-line-strong); flex: none; }
.cp-scope {
  display: flex;
  align-items: center;
  gap: var(--sc-2);
  padding: var(--sc-2) var(--sc-3);
  border-bottom: 1px solid var(--sc-line-faint);
  flex-wrap: wrap;
  flex: none;
}
.cp-thread { flex: 1; overflow: auto; padding: var(--sc-4) var(--sc-3); display: flex; flex-direction: column; gap: var(--sc-3); }
.cp-turn { font: 400 14px/20px var(--sc-font-ui); color: var(--sc-ink-2); margin: 0; }
.cp-note { font: 400 12px/16px var(--sc-font-ui); color: var(--sc-ink-3); margin: 0; }

/* ---------- mount stages ----------
   One persistent iframe per product, positioned over the anchor that is
   currently visible. The stage lives outside .cp-recede so it is never inside a
   transformed ancestor, which is what lets it use position: fixed while the
   shell recedes, and what lets it grow without the iframe being reparented or
   reloaded. */

.stage {
  position: fixed;
  z-index: 5;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  overflow: hidden;
  background: var(--sc-map-ground);
  border-radius: var(--sc-r);
  transform-origin: 0 0;
  will-change: transform;
}
.stage.doc { background: var(--sc-doc-ground); }
.stage > iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: transparent;
}
.stage.is-presented, .stage.is-max {
  z-index: 10;
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r-lg);
  box-shadow: var(--sc-e3);
}
.stage-scrim { position: fixed; inset: 0; background: var(--sc-canvas); opacity: 0.34; z-index: 9; }
.stage-esc {
  position: fixed;
  z-index: 11;
  top: var(--sc-3);
  right: var(--sc-3);
  display: flex;
  align-items: center;
  gap: var(--sc-2);
}
.stage-esc .prov { background: var(--sc-surface); }
.mount-note b { display: block; color: var(--sc-ink-2); }
.mount-note { max-width: 46ch; margin: 0 auto; }

/* ---------- assets ---------- */

.kv {
  display: grid;
  grid-template-columns: minmax(120px, auto) minmax(0, 1fr);
  gap: var(--sc-2) var(--sc-4);
  align-items: baseline;
}
.kv dt { font: 500 12px/16px var(--sc-font-data); letter-spacing: 0.06em; text-transform: uppercase; color: var(--sc-ink-3); margin: 0; }
.kv dd { margin: 0; font: 400 14px/20px var(--sc-font-ui); color: var(--sc-ink-2); }

.actionbar { display: flex; align-items: center; gap: var(--sc-2); flex-wrap: wrap; }

/* ---------- roster and not-built views ---------- */

.roster-note {
  display: flex;
  flex-direction: column;
  gap: var(--sc-2);
  padding: var(--sc-4);
  border-top: 1px solid var(--sc-line-faint);
}
.roster-note .t-label { color: var(--sc-ink-3); }
.roster-list { display: flex; flex-wrap: wrap; gap: var(--sc-2); }
.roster-list .prov { background: var(--sc-surface); }

/* ---------- code citation, evidence chip, applicability matrix, finding row ----------

   G-88 item 2. Four families ported from the design system's own style block
   (30b_smartcity_design_system.html lines 236-253 and 316-344) into this file's
   formatting. Nothing below was designed. Every rule is the spec's, re-laid-out
   one declaration per line, and every colour is a var(--sc-*) that already
   ships. Zero tokens are declared here; sc-kit.css is untouched.

   G1, the type floor holds. The spec sets .cite em at 11px, and .cite.model
   .corpus, .mxgroup .lic and .basisline below the floor. All four ship at 12px.
   The product had already made this call once, shipping .prov at 13px where the
   spec says 11px. The consequence is named and accepted: the spec's own
   specimens no longer match what ships, and the spec is the looser document.
   The port principle was to change only the size number, so every line-height,
   weight, tracking and geometry below is exactly what the spec drew.

   The evidence chip label is the ONE exception and it is taken. The type law
   grants it in one sentence, quoted here because a carve-out whose reason lives
   only in a review thread does not survive:

     12px is the floor and nothing renders below it, with one named exception:
     the evidence chip label may set at 10px, because the chip has to read as a
     citation mark rather than a button and SmartSite sets it near 9.5px. The
     exception is the chip label only. The body of BRIEF and FULL, and every
     other string in the system, stays at the 12px floor. Nothing else inherits
     this.

   So .atomchip and .atomchip .did set 10px and nothing else in this file does.
   The gate at src/type-conformance.test.mjs had hardcoded the floor as absolute
   and justified it in its own error string with the words 'the evidence chip,
   which does not exist in this product'. That was true when it was written and
   this card falsified it, so the gate was amended to carry the exception by
   name rather than left to assert something untrue. .basisline is NOT covered:
   the exception is the chip label only, so the basis line stays at 12px even
   though the spec draws it at 11px.

   G2, the design system governs the CSS wherever it and the platform IA
   document disagree. Five divergences, each marked DIV-n at the rule.

   Markup contract for .atomchip comes from the platform IA section 6.3, because
   the design system carries no atomchip specimen: the openable form is a
   button with aria-expanded, and the unverified .web form is a plain span. */

.cite {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 2px 7px;
  border-radius: var(--sc-r-control);
  border: 1px solid var(--sc-line);
  background: var(--sc-surface-2);
  font: 500 12px/16px var(--sc-font-data);
  color: var(--sc-ink);
  text-decoration: none;
  white-space: nowrap;
}
/* G1: the spec sets 11px here. */
.cite em { font-style: normal; font-weight: 400; font-size: 12px; color: var(--sc-ink-3); }
.cite:hover { border-color: var(--sc-accent); color: var(--sc-accent); }

/* The licensed form. Full canonical corpus title above the section identifier,
   two lines inside one chip, and no slot for body copy anywhere in this family.
   That absence is the enforcement mechanism, not a styling choice: licensed
   model-code text cannot leak into a screenshot or an export through a
   component that does not exist. */
.cite.model { flex-direction: column; align-items: flex-start; gap: 1px; padding: 3px 8px; }
/* G1: the spec sets 10px here. DIV-2: the IA document drops the tracking. */
.cite.model .corpus {
  font: 400 12px/13px var(--sc-font-data);
  letter-spacing: 0.01em;
  color: var(--sc-ink-3);
}
.cite.model .sect { font: 500 12px/16px var(--sc-font-data); color: var(--sc-ink); }
/* DIV-3: absent from the IA document, so the licensed form would lose its hover
   affordance there. Kept. */
.cite.model:hover .sect { color: var(--sc-accent); }

/* The evidence chip. Wears the reserved atom accent, which marks a thing you
   can open and read the record of. Not chrome, not emphasis, not a link colour.
   .dead is an unservable record; .web is an unverified source and drops the
   accent entirely for a neutral, differently-shaped chip, so the reservation
   holds structurally rather than by convention. */
/* 10px is the type law's one named exception, carved into the gate by name.
   At 14px line the chip stays 20px tall, the same height as .pill and .prov. */
.atomchip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 7px;
  border-radius: var(--sc-r-control);
  border: 1px solid color-mix(in srgb, var(--sc-atom) 45%, transparent);
  background: var(--sc-atom-wash);
  font: 500 10px/14px var(--sc-font-ui);
  color: var(--sc-atom);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  vertical-align: 2px;
}
/* The record identifier is part of the chip label, so the same exception covers
   it. These two selectors are the entire exception; the gate names both. */
.atomchip .did { font: 400 10px/14px var(--sc-font-data); opacity: 0.75; }
.atomchip:hover { border-color: var(--sc-atom); }
/* DIV-4: the IA document states cursor: pointer, which this rule already
   inherits from .atomchip, so the two agree in effect. */
.atomchip.dead {
  color: var(--sc-quiet);
  background: var(--sc-quiet-wash);
  border-color: color-mix(in srgb, var(--sc-quiet) 40%, transparent);
  border-style: dashed;
}
/* DIV-5: the IA document sets cursor: default here and this one is a real
   disagreement, not a restatement. Its own specimen is a non-interactive span.
   Resolved to the design system per G2, so the chip inherits cursor: pointer.
   Named in the close. */
.atomchip.web {
  color: var(--sc-ink-3);
  background: var(--sc-surface-2);
  border-color: var(--sc-line);
  border-radius: var(--sc-r-full);
}

/* The applicability matrix, inverted. Pass is the quietest row on the page:
   grey text, no fill, no rail. Fail takes the critical rail and wash, Uncertain
   the warn rail and wash, and Unchecked a diagonal hatch, the plat-drawing
   convention for nobody has been here yet, because unreviewed is more dangerous
   than failed and must never read as clean. Rows group under a corpus header
   that prints the full canonical title once, which is how the matrix stays
   dense without ever printing an abbreviation alone. */
.mx {
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r);
  background: var(--sc-surface);
  overflow: hidden;
}
.mxgroup {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px var(--sc-3);
  background: var(--sc-surface-2);
  border-bottom: 1px solid var(--sc-line);
  flex-wrap: wrap;
}
.mxgroup .c { font: 500 12px/16px var(--sc-font-data); color: var(--sc-ink); }
/* G1: the spec sets 10px here. */
.mxgroup .lic {
  font: 500 12px/1 var(--sc-font-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sc-ink-3);
  border: 1px solid var(--sc-line);
  border-radius: 3px;
  padding: 3px 6px;
}
/* DIV-1: the IA document narrows the section-identifier column to 108px. Kept
   at 132px, which is also the column the raised type needs. */
.mxrow {
  display: grid;
  grid-template-columns: 3px 132px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sc-3);
  border-bottom: 1px solid var(--sc-line-faint);
  padding-right: var(--sc-3);
  min-height: 42px;
}
.mxrow:last-child { border-bottom: 0; }
.mxrow > .rail { align-self: stretch; background: transparent; min-height: 42px; }
.mxrow .sec { font: 500 12px/1 var(--sc-font-data); color: var(--sc-ink-2); padding-left: var(--sc-3); }
.mxrow .txt { font: 400 13px/18px var(--sc-font-ui); color: var(--sc-ink-2); padding: 8px 0; }
/* Pass declares no background and no rail colour. Adding a green wash here is
   the one edit that reverses the ruling this component exists to express. */
.mx-pass .sec { color: var(--sc-ink-3); }
.mx-pass .txt { color: var(--sc-ink-3); }
.mx-fail { background: var(--sc-crit-wash); }
.mx-fail > .rail { background: var(--sc-crit); }
.mx-fail .txt { color: var(--sc-ink); }
.mx-unc { background: var(--sc-warn-wash); }
.mx-unc > .rail { background: var(--sc-warn); }
.mx-unc .txt { color: var(--sc-ink); }
.mx-unchecked {
  background: repeating-linear-gradient(135deg, transparent 0 6px, var(--sc-quiet-wash) 6px 13px);
}
.mx-unchecked > .rail { background: var(--sc-line-strong); }
.mx-unchecked .txt { color: var(--sc-ink); }

/* The finding row, the unit of a comment letter. Composes .cite and .prov in
   its .fmeta slot and carries its basis line underneath, so a confidence value
   cannot render without the state, source count and timestamp that earn it. */
.finding {
  display: grid;
  grid-template-columns: 3px auto minmax(0, 1fr) auto;
  gap: var(--sc-3);
  /* The spec writes the grid-relative start keyword here. flex-start behaves
     identically on a grid container and keeps the G-75 mount guard, which
     greps this whole file for that literal string, able to fire. */
  align-items: flex-start;
  border: 1px solid var(--sc-line);
  border-radius: var(--sc-r);
  background: var(--sc-surface);
  padding-right: var(--sc-3);
  overflow: hidden;
}
.finding > .rail { align-self: stretch; background: var(--sc-warn); }
.finding.crit > .rail { background: var(--sc-crit); }
.finding .fid {
  font: 500 12px/18px var(--sc-font-data);
  color: var(--sc-ink-3);
  padding: 13px 0 13px var(--sc-3);
  white-space: nowrap;
}
.finding .fbody { padding: 12px 0; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.finding .ftitle { font: 600 13px/19px var(--sc-font-ui); color: var(--sc-ink); }
.finding .fmeta { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.finding .fact { padding: 11px 0; display: flex; gap: 6px; align-items: center; }

/* G1: the spec sets 11px here. Not covered by the chip-label exception, which is
   the chip label only, so it goes to the floor. */
.basisline {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font: 400 12px/16px var(--sc-font-data);
  color: var(--sc-ink-3);
}
.basisline .conf { display: inline-flex; align-items: center; gap: 6px; color: var(--sc-ink-2); }
.meter { display: inline-flex; gap: 2px; }
.meter i { width: 11px; height: 4px; border-radius: 1px; background: var(--sc-line-strong); }
.meter i.f { background: var(--sc-accent); }

/* ---------- responsive ---------- */

@media (max-width: 1180px) {
  .shell-regions { grid-template-columns: minmax(0, 1fr) 320px; }
  /* Below this width four metric columns are about 75px each. On main that
     ellipsised every key to four characters; two columns keep the label. */
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .deptgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .metrics.attn { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .menu-btn { display: inline-flex; }
  .shell-body { grid-template-columns: 1fr; }
  .shell-nav {
    display: none;
    position: fixed;
    inset: var(--sc-topbar) 0 0 0;
    z-index: 7;
  }
  .shell-nav.open { display: flex; }
  .shell-regions {
    grid-template-columns: 1fr;
    grid-auto-rows: min-content;
    overflow-y: auto;
    padding: var(--sc-3);
    gap: var(--sc-3);
  }
  .colstack, .colstack.rail { overflow: visible; min-height: 0; }
  .colstack.rail > .region { min-height: 320px; }
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .deptgrid { grid-template-columns: minmax(0, 1fr); }
  .metrics.attn { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .filterbar input[type="search"] { min-width: 100%; }
  .cp-sheet { width: 100vw; }
  .shell-top .searchwrap { display: none; }
  /* The top bar gained three controls at G-90. On a phone the theme toggle
     keeps its icon and drops its word, which is the only one of the three that
     carries a text label at all. The control itself does not hide: losing a
     capability on a narrow screen is the thing this card was opened about. */
  #theme-toggle-label { display: none; }
  .pagehead { padding: var(--sc-3) var(--sc-4); }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0ms !important; transition-duration: 0ms !important; }
}
