/* RiskyEats — civic newspaper aesthetic
 * ================================================================
 * Designed mobile-first for a 55+ audience. WCAG 2.2 AAA contrast
 * minimums (7:1 normal text, 4.5:1 large text). All interactive
 * surfaces are at least 48×48 CSS px (Material Design recommended
 * minimum, exceeds Apple's 44 px floor).
 *
 * Typography:
 *   Body    — Atkinson Hyperlegible (Braille Institute, designed for
 *             low-vision readability; characters disambiguated at small
 *             sizes and through poor contrast).
 *   Display — Bricolage Grotesque (modern variable grotesque; clean
 *             geometric forms with editorial authority — no art-deco
 *             flourish or 1970s revival nostalgia).
 *
 * Color:
 *   White paper, black ink, deep red accent — the classic broadsheet.
 *   All combinations exceed WCAG AAA on the white background.
 *
 * Layout:
 *   Single-column mobile, 2-up at 640px, 3-up at 1024px. Content
 *   max-width caps at 65ch for body text and 1240px for grids.
 *
 * Motion:
 *   Minimal. Honors `prefers-reduced-motion`. Focus indicators are
 *   always visible (keyboard users never lose their place).
 * ================================================================ */

/* ---- Custom properties ---------------------------------------- */
:root {
  /* Paper + ink — white paper, black ink, the classic broadsheet. */
  --paper:        #FFFFFF;
  --paper-2:      #F6F6F6;
  --paper-3:      #ECECEC;
  --rule:         #D6D6D6;
  --rule-strong:  #6E6E6E;

  /* All measured contrast ratios are computed against --paper #FFFFFF. */
  --ink:          #111111;            /* 18.9:1 — AAA */
  --ink-2:        #2B2B2B;            /* 13.6:1 — AAA */
  --ink-muted:    #555555;            /*  7.5:1 — AAA */

  /* Editorial accents — measured + verified against #FFFFFF for AAA-large
     and AA-normal. The red is deep enough to read as serious news red,
     not a marketing crimson. */
  --orange:       #9A3412;            /*  9.1:1 — AAA-normal — Near Miss orange (white text) */
  --red:          #A11515;            /*  7.7:1 — AAA-normal (was #B91C1C 6.5:1, fails AAA for body text) */
  --red-deep:     #6B0F0F;            /* 11.4:1 — AAA-normal — MAROON / chronic */
  --red-bg:       #FBE8E8;
  --amber:        #6E3A00;            /*  8.6:1 — AAA */
  --amber-bg:     #FAEFDC;
  --yellow:       #8A6300;            /*  7.0:1 — AAA-large, AA-normal — Near Miss caution color */
  --yellow-bg:    #FEF3C7;
  --green:        #1F5D2D;            /*  7.6:1 — AAA */
  --green-bg:     #E2F0DE;
  --navy:         #1A3D6D;            /* 10.9:1 — AAA */
  --navy-bg:      #E2EAF4;
  /* Black/death color for closure-signal + ghost-license dimensions.
     Reuses --ink for the stripe; pairs with --paper-3 for a barely-tinted
     bg that doesn't shout against the body wash. */
  --death:        #111111;            /* same as --ink — strongest possible */
  --death-bg:     #ECECEC;            /* paper-3 — light grey, dignified */

  /* Type scale — 1.250 modular, anchored at 18px */
  --text-xs:      0.875rem;
  --text-sm:      1rem;
  --text-base:    1.125rem;            /* 18px body */
  --text-md:      1.40625rem;
  --text-lg:      1.7578125rem;
  --text-xl:      2.197265625rem;
  --text-2xl:     2.74658rem;
  --text-3xl:     3.43323rem;

  /* Spacing (8-point) */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;

  /* Containers — single-column, mobile-first AT EVERY BREAKPOINT.
     Even on a 4K monitor the content sits in a centered ~680px column
     so the layout reads identically to a phone. Reading line-length
     caps at 65ch for prose; the grid container caps at 680px so cards,
     stats, and dimensions never go multi-column. */
  --measure-prose: 65ch;
  /* Main content widens with the viewport (was 680px hard cap which
     left huge empty side margins on desktop). Prose paragraphs stay
     65ch via the separate `p, li, dd { max-width: var(--measure-prose) }`
     rule for readability; the surrounding shell scales out. */
  --measure-grid:  min(1280px, 100% - 2 * var(--s-4));

  /* Touch */
  --tap: 48px;

  /* Type families */
  --font-body:    "Atkinson Hyperlegible", "Verdana", "Tahoma", system-ui, sans-serif;
  --font-display: "Bricolage Grotesque", "Helvetica Neue", "Arial", system-ui, sans-serif;

  /* Focus ring (WCAG 2.4.7) */
  --focus-ring: 0 0 0 3px var(--paper), 0 0 0 6px var(--navy);
}

/* No dark-scheme override — RiskyEats is always served as a white-paper
   broadsheet with black body and red accent. The masthead / wordmark
   carry the chrome; OS-level dark mode does not invert the layout.
   (color-scheme: only light keeps native form widgets light, too.) */
:root { color-scheme: light; }

/* ---- Reset + base --------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg, video, canvas { max-width: 100%; height: auto; display: block; }

a {
  color: var(--navy);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.2em;
}
a:hover { color: var(--ink); }
a:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: 2px; }

button {
  font: inherit;
  color: inherit;
  background: transparent;
  border: 0;
  cursor: pointer;
}
button:focus-visible { outline: none; box-shadow: var(--focus-ring); }

p, li, dd { max-width: var(--measure-prose); }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 580;
  font-variation-settings: "opsz" 32;
  line-height: 1.15;
  letter-spacing: -0.005em;
  margin: 0 0 var(--s-4);
  color: var(--ink);
  text-wrap: balance;
}
h1 { font-size: var(--text-2xl); }
@media (min-width: 1024px) { h1 { font-size: var(--text-3xl); } }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-md); }

/* ---- Utility -------------------------------------------------- */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: var(--s-2);
  left: var(--s-2);
  background: var(--ink);
  color: var(--paper);
  padding: var(--s-3) var(--s-4);
  border-radius: 4px;
  font-weight: 700;
  z-index: 1000;
  transform: translateY(-200%);
  transition: transform 120ms ease-out;
}
.skip-link:focus { transform: translateY(0); }

/* ---- Stale banner --------------------------------------------- */
.stale-banner {
  background: var(--amber-bg);
  color: var(--ink);
  border-block: 2px solid var(--amber);
  padding: var(--s-3) var(--s-4);
  text-align: center;
  font-size: var(--text-sm);
}
.stale-banner strong { color: var(--amber); margin-right: var(--s-2); text-transform: uppercase; letter-spacing: 0.05em; }

/* ---- Masthead ------------------------------------------------- */
.masthead {
  padding: var(--s-3) var(--s-4) 0;
  transition: opacity 140ms ease, max-height 140ms ease, padding 140ms ease;
}
@media (min-width: 1024px) {
  .masthead { padding: var(--s-2) var(--s-4) 0; }
}
.masthead__inner {
  max-width: var(--measure-grid);
  margin: 0 auto;
  text-align: center;
}
.masthead__rule {
  height: 3px;
  background: var(--red);
  border: 0;
  margin: var(--s-2) 0;
}
.masthead__rule--top    { background: var(--red); height: 4px; }
.masthead__rule--bottom {
  height: 1px;
  background: var(--rule-strong);
  margin-top: var(--s-2);
}
.wordmark {
  display: inline-block;
  text-decoration: none;
  color: var(--red);
  padding: var(--s-2);
  border-radius: 4px;
}
.wordmark:hover { color: var(--red); }
.wordmark__title {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.4rem, 8vw + 0.25rem, 4rem);
  font-variation-settings: "opsz" 64, "wdth" 90;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--red);
}
.wordmark__sub {
  display: block;
  font-family: var(--font-body);
  font-style: italic;
  font-weight: 400;
  font-size: var(--text-md);
  color: var(--ink-muted);
  margin-top: var(--s-1);
  letter-spacing: 0.02em;
}
.masthead__folio {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-muted);
  margin: var(--s-2) 0 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-2);
}

/* ---- Lede ------------------------------------------------------ */
/* Tight on mobile, even tighter (and headline-only) on desktop. The
   wordmark + folio in the masthead already cover the "what is this"
   role; the lede doesn't need to take a full viewport on a laptop. */
.lede {
  padding: var(--s-4) var(--s-4) var(--s-5);
  background: var(--paper);
}
.lede__inner {
  max-width: 56ch;
  margin: 0 auto;
  text-align: center;
}
.lede__headline {
  font-family: var(--font-display);
  font-weight: 700;
  font-variation-settings: "opsz" 64;
  font-size: clamp(1.4rem, 3vw + 0.5rem, 2rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: var(--s-2);
  color: var(--ink);
}
.lede__summary {
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--ink-muted);
  margin: 0 auto;
}
@media (min-width: 1024px) {
  .wordmark__title { font-size: clamp(2rem, 3vw + 0.5rem, 2.7rem); }
  .wordmark__sub { font-size: var(--text-sm); }
}
/* (Dead .masthead.is-compact + .lede rules removed 2026-05-02 —
   the surfaces these target were deleted from the DOM long ago.) */

/* ---- Metro picker -------------------------------------------- */
.metro-picker {
  background: var(--paper-2);
  border-block: 1px solid var(--rule);
  padding: var(--s-2) var(--s-4);
  position: sticky; top: 0; z-index: 50;
  backdrop-filter: blur(6px);
  transition: padding 140ms ease, background 140ms ease, box-shadow 140ms ease;
}
@supports not (backdrop-filter: blur(6px)) {
  .metro-picker { background: var(--paper-2); }
}
.metro-picker__inner {
  max-width: var(--measure-grid);
  margin: 0 auto;
}
/* Mobile: stack brand + dropdown + share vertically inside the bar
   with tight spacing. The bar is still sticky and ~120px tall on
   phones (brand row + dropdown row + share row). */
.metro-picker__inner {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  align-items: stretch;
}
@media (min-width: 1024px) {
  /* Desktop: single row — brand | dropdown | freshness | share.
     Override the body 680px reading-width: the nav bar fits brand +
     label + dropdown + "DBPR data through YYYY-MM-DD · twice-daily" +
     share/follow icons (~860px of content). At 680px the children
     overlap into each other (the dropdown lands on top of the heading
     and the freshness slug). 1100px gives enough room for all four
     columns at any desktop width without overflowing 4K monitors. */
  .metro-picker { padding: var(--s-1) var(--s-4); }
  .metro-picker__inner {
    max-width: min(1240px, 100% - 2 * var(--s-4));
    display: grid;
    /* brand | metro-picker | find-a-resto | freshness | signup+social
       v1.0.34: added find-a-resto column right of the metro picker
       per Rachel. Bumped max-width 1100→1240 to absorb ~140px of new
       column without crowding the other masthead cells. */
    grid-template-columns: auto auto auto minmax(0, 1fr) auto auto;
    gap: var(--s-3);
    align-items: center;
  }
}
/* The .metro-picker__brand rule lives further down, alongside the
   brand-name + brand-tagline children (v1.0.21 brand block). Keeping
   font-variation-settings off the parent anchor — Atkinson Hyperlegible
   doesn't support opsz/wdth axes and inheriting them onto the tagline
   child caused render artifacts in the sticky header. */
.metro-picker__brand:hover .metro-picker__brand-name { color: var(--red-deep); }
.metro-picker__heading {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-muted);
  margin: 0 0 var(--s-2);
  text-align: center;
}
@media (min-width: 1024px) {
  .metro-picker__heading {
    margin: 0;
    text-align: left;
    white-space: nowrap;
  }
}
/* Chip wall is hidden — the dropdown in the sticky bar is the primary
   metro picker on every breakpoint. The chip wall stays in the DOM
   for hash-routing keyboard nav but never shows. */
.metro-picker__chips { display: none; }

.metro-chip {
  min-height: var(--tap);
  padding: var(--s-2) var(--s-4);
  background: var(--paper);
  border: 2px solid var(--rule);
  border-radius: 999px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--ink);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.1;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
@media (min-width: 1024px) {
  /* Single-line city pills on desktop — the anchor city sub-label
     gets dropped to halve the chip height. */
  .metro-chip {
    min-height: 30px;
    padding: var(--s-1) var(--s-3);
    font-size: var(--text-xs);
    border-width: 1px;
    white-space: nowrap;
  }
  .metro-chip__sub { display: none; }
}
.metro-chip__name { display: block; }
.metro-chip__sub {
  display: block;
  font-weight: 400;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  margin-top: 2px;
}
.metro-chip:hover { border-color: var(--ink); }
.metro-chip[data-active="true"] {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.metro-chip[data-active="true"] .metro-chip__sub { color: var(--paper-3); }

/* Masthead control chrome is consolidated in the unified masthead
   block near the end of the file. */

/* (Dead .metro-picker.is-compact rules removed 2026-05-02 — the
   IntersectionObserver that toggled this class observed .masthead /
   .lede surfaces that no longer exist in the DOM, so the class was
   never set. Per Codex MED.) */

/* ---- Metro panel --------------------------------------------- */
.metro-panel {
  padding: var(--s-5) var(--s-4);
  outline: none;
}
.metro-panel:focus-visible { box-shadow: none; }

.loading,
.empty {
  text-align: center;
  padding: var(--s-7) var(--s-4);
  color: var(--ink-muted);
  font-style: italic;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14;
  font-size: var(--text-md);
}
.empty--error { color: var(--red); }

/* ---- Metro briefing layout ----------------------------------- */
.metro-briefing {
  max-width: var(--measure-grid);
  margin: 0 auto;
  display: grid;
  gap: var(--s-5);
}
.metro-briefing__head { text-align: center; }
.metro-briefing__kicker {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--red);
  margin: 0 0 var(--s-2);
}
.metro-briefing__headline {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96;
  font-weight: 700;
  font-size: clamp(1.6rem, 3vw + 0.8rem, 2.4rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0;
}
.metro-briefing__location {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: "opsz" 14;
  color: var(--ink-2);
  margin-top: var(--s-2);
  font-size: var(--text-base);
}

/* ---- Stat band ------------------------------------------------ */
.stat-band {
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: var(--s-5) var(--s-4);
}
.stat-band__heading {
  /* Visible now — carries the metro label so readers don't mistake
     these counts for statewide totals. */
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink);
  margin: 0 0 var(--s-3);
  text-align: center;
}
.stat-band__metro {
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--red-deep);
  text-transform: none;
}

/* Stat grid — 2 columns on every breakpoint, compressed. Each tile
   stays a horizontal-flex row (small label left, big numeral right). */
.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-1);
}

.stat-tile {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: var(--s-1) var(--s-2);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-2);
  min-height: 36px;
}
.stat-tile__label {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin: 0;
  line-height: 1.2;
  flex: 1;
  min-width: 0;
}
.stat-tile__value {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 64;
  font-weight: 700;
  font-size: var(--text-md);
  line-height: 1;
  margin: 0;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  flex: 0 0 auto;
}

/* Stat-tile color stripes — aligned with the jump-nav HEALTH/LICENSE
   grouping. HEALTH (inspection / sanitation) = red; LICENSE
   (administrative / regulatory) = navy; positive subsets (clean
   plates, new licenses) = green. Reader scanning the stat band
   should clump the same way they scan the jump nav. */
/* HEALTH group — red border */
/* 5-bucket UX color scheme: red (UEO) / yellow (Near Miss) /
   red-deep (chronic) / green (clean) / blue (admin) / black (death). */
.stat-tile--under-emergency-order { border-left: 6px solid #dc2626; }
.stat-tile--recent-failures      { border-left: 6px solid #F97316; }
.stat-tile--worst-offenders      { border-left: 6px solid #8B1818; }
.stat-tile--bad-actors           { border-left: 6px solid #8B1818; }
.stat-tile--most-improved        { border-left: 6px solid #16a34a; }
/* LICENSE group — navy border */
.stat-tile--permanent-closures   { border-left: 6px solid #991B1B; }
.stat-tile--delinquent           { border-left: 6px solid #EA580C; }
.stat-tile--lost-licenses        { border-left: 6px solid #1A3D6D; }
/* Positive signals (good news) — green border, regardless of group */
.stat-tile--openings             { border-left: 6px solid #06b6d4; }
.stat-tile--new-licenses         { border-left: 6px solid #06b6d4; }
/* clean_plates accent declared once with the dimension below — green */

.stat-help {
  margin: var(--s-5) auto 0;
  font-size: var(--text-sm);
  color: var(--ink-2);
  max-width: 65ch;
  line-height: 1.55;
  text-align: left;
}

/* ---- Briefing prose ------------------------------------------ */
.briefing {
  max-width: var(--measure-prose);
  margin: 0 auto;
}
.briefing__prose p { margin: 0 0 var(--s-4); }
.briefing__paragraph {
  /* Lede + briefing prose paragraphs match the per-dim narrative
     size (text-base / 18px font-body) per operator 2026-05-02:
     "intro narration font size is very big. reduce to the same size
     as sections". Was previously oversized on font-display at text-md.
     Body font is more readable for the 55+ audience anyway. */
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--ink);
  max-width: 75ch;
}
/* Drop cap on the lede paragraph. Only applied when the paragraph
   isn't first-letter punctuation/quote (CSS ::first-letter would
   otherwise enlarge the quote glyph instead of the actual letter,
   producing a typographic glitch). The `data-leading-letter` flag is
   set in JS only when the first character is a letter (Unicode L).
   Suppressed when the briefing renders a persona avatar — the
   avatar IS the drop-cap. */
.briefing__paragraph--first[data-leading-letter="true"]::first-letter {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96;
  font-weight: 700;
  font-size: 2.6em;
  line-height: 0.9;
  float: left;
  padding: 0.05em var(--s-3) 0 0;
  color: var(--red);
}
.briefing__prose[data-has-avatar="true"]
  .briefing__paragraph--first[data-leading-letter="true"]::first-letter {
  font-size: inherit;
  font-family: inherit;
  font-weight: inherit;
  float: none;
  padding: 0;
  color: inherit;
}

/* Persona avatar acting as a portrait drop-cap on the briefing prose.
   Floats left so the lede prose flows around it, exactly as a drop
   cap would. Sized for visibility (matches the ~4em CSS drop-cap
   block height). Square crop with sharp edge — no rounded corners,
   keeps the newspaper register. */
.briefing__avatar {
  float: left;
  width: 5.5em;
  height: 5.5em;
  margin: 0.2em var(--s-3) var(--s-1) 0;
  object-fit: cover;
  object-position: center top;
  border: 2px solid var(--ink);
  background: var(--paper-2);
  shape-outside: margin-box;
}
@media (max-width: 480px) {
  .briefing__avatar {
    width: 4.5em;
    height: 4.5em;
    margin-right: var(--s-2);
  }
}
.briefing__byline {
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-align: right;
  margin-top: var(--s-4);
}

/* Briefing dimension sections — each paragraph wrapped in a themed box
   so closure / ownership / chronic / clean-plates / etc. read as
   visually distinct blocks instead of a continuous prose stream. The
   left border + kicker label echo the matching dimension panel below
   for at-a-glance grouping. Click the kicker to jump to the section. */
.briefing-section {
  border-left: 4px solid var(--rule);
  padding: var(--s-2) 0 var(--s-2) var(--s-3);
  margin-bottom: var(--s-3);
}
.briefing-section:last-child { margin-bottom: 0; }
.briefing-section__kicker {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-muted);
  text-decoration: none;
  margin-bottom: var(--s-1);
  padding: 1px 0;
  border-bottom: 1px dotted transparent;
}
.briefing-section__kicker:hover,
.briefing-section__kicker:focus-visible {
  color: var(--ink);
  border-bottom-color: currentColor;
}
.briefing-section__kicker:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}
.briefing-section .briefing__paragraph { margin: 0; }
/* Per-dimension theme — five-bucket UX color scheme:
     RED    = Red Alert (UEO)             — DBPR-shut-down severity
     RED-D  = chronic (worst, bad-actors) — repeating offenders
     YELLOW = Near Miss (recent_failures) — cited but not closed
     GREEN  = Clean Plates                — winners
     BLUE   = Administrative (lost / new / license-activity)
     BLACK  = Closed / Ghost (permanent_closures, delinquent)
     NEUTRAL = statewide context, velocity (frame, not signal) */

/* Operator 2026-05-04 — single canonical palette per dim. Sections
   are paper-white with a single solid-color band on the LEFT and the
   kicker text in the same dim hex. No tinted backgrounds (operator:
   "worst of worst is pink" — the tinted fill was reading as the dim
   color, washing out the band). The dim color shows up ONLY on the
   border-left band + kicker text + dim icon. Hex values match
   config/dimensions.json. */
.briefing-section--statewide-context {
  border-left-color: #64748b;
  background: var(--paper);
}
.briefing-section--statewide-context .briefing-section__kicker { color: #64748b; }

.briefing-section--under-emergency-order { border-left-color: #dc2626; background: var(--paper); }
.briefing-section--under-emergency-order .briefing-section__kicker { color: #dc2626; }

.briefing-section--recent-failures { border-left-color: #F97316; background: var(--paper); }
.briefing-section--recent-failures .briefing-section__kicker { color: #F97316; }

.briefing-section--clean-plates { border-left-color: #16a34a; background: var(--paper); }
.briefing-section--clean-plates .briefing-section__kicker { color: #16a34a; }

.briefing-section--worst-offenders,
.briefing-section--bad-actors {
  border-left-color: #8B1818;
  background: var(--paper);
}
.briefing-section--worst-offenders .briefing-section__kicker,
.briefing-section--bad-actors .briefing-section__kicker { color: #8B1818; }

/* Operator 2026-05-04 (rev 2): WORSTS = SUNBURST ORANGE — distinct
   from chronic-bad-actors red, distinct from the standard near-miss
   orange (#F97316), and bright enough to read as the cross-flag
   "extreme" tier. */
.briefing-section--worsts {
  border-left-color: #ff5722;
  background: var(--paper);
}
.briefing-section--worsts .briefing-section__kicker { color: #ff5722; }

.briefing-section--most-improved { border-left-color: #16a34a; background: var(--paper); }
.briefing-section--most-improved .briefing-section__kicker { color: #16a34a; }

.briefing-section--permanent-closures,
.briefing-section--closures {
  border-left-color: #991B1B;
  background: var(--paper);
}
.briefing-section--permanent-closures .briefing-section__kicker,
.briefing-section--closures .briefing-section__kicker { color: #991B1B; }

.briefing-section--delinquent,
.briefing-section--distressed {
  border-left-color: #EA580C;
  background: var(--paper);
}
.briefing-section--delinquent .briefing-section__kicker,
.briefing-section--distressed .briefing-section__kicker { color: #EA580C; }

.briefing-section--ghost-licenses { border-left-color: #64748b; background: var(--paper); }
.briefing-section--ghost-licenses .briefing-section__kicker { color: #64748b; }

.briefing-section--lost-licenses { border-left-color: #1A3D6D; background: var(--paper); }
.briefing-section--lost-licenses .briefing-section__kicker { color: #1A3D6D; }

.briefing-section--openings,
.briefing-section--new-licenses {
  border-left-color: #06b6d4;
  background: var(--paper);
}
.briefing-section--openings .briefing-section__kicker,
.briefing-section--new-licenses .briefing-section__kicker { color: #06b6d4; }

.briefing-section--license-activity { border-left-color: #1A3D6D; background: var(--paper); }
.briefing-section--license-activity .briefing-section__kicker { color: #1A3D6D; }

.briefing-section--chain-activity { border-left-color: #9333ea; background: var(--paper); }
.briefing-section--chain-activity .briefing-section__kicker { color: #9333ea; }

.briefing-section--velocity {
  border-left-color: var(--ink-muted);
  background: var(--paper);
}
.briefing-section--velocity .briefing-section__kicker { color: var(--ink-2); }
/* In-briefing inline links (briefing-mention pills inherit their own
   colors elsewhere; this catches plain anchors like the kicker plus
   any future inline citations in prose). */
.briefing-section a:not(.briefing-section__kicker):not(.briefing-mention) {
  color: var(--navy);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

/* ---- Dimensions ---------------------------------------------- */
/* Single-column stack at every breakpoint. Each dimension section is a
   sequential block — sequential reading is the design language. */
.dimensions {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}
.dimension { display: flex; flex-direction: column; gap: var(--s-4); }
.dimension__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  border-bottom: 2px solid var(--ink);
  padding-bottom: var(--s-2);
}
.dimension__heading { margin: 0; font-size: var(--text-md); }
.dimension__count {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* Expand/collapse cue — gives <summary> a clear "click to expand"
   affordance with chevron. The default disclosure triangle is hidden
   in our CSS reset; this is the visible substitute. The state cue
   ("Show N records" / "Hide N records") swaps via the [open]
   attribute on the parent <details>. */
.dimension__expand {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 6px 10px;
  white-space: nowrap;
  transition: background 120ms, border-color 120ms;
  margin-left: auto;
}
.dimension > summary.dimension__head:hover .dimension__expand,
.dimension > summary.dimension__head:focus-visible .dimension__expand {
  background: var(--paper);
  border-color: var(--ink);
}
.dimension__expand-cue { display: inline-block; }
.dimension__expand-cue--open { display: none; }
.dimension[open] .dimension__expand-cue--closed { display: none; }
.dimension[open] .dimension__expand-cue--open { display: inline-block; }
.dimension__expand-chevron {
  transition: transform 200ms ease;
  flex-shrink: 0;
}
.dimension[open] .dimension__expand-chevron {
  transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
  .dimension__expand-chevron { transition: none; }
}
/* Hide the default browser disclosure triangle on the summary so our
   chevron is the canonical affordance. */
.dimension > summary.dimension__head { list-style: none; cursor: pointer; }
.dimension > summary.dimension__head::-webkit-details-marker { display: none; }
/* The legacy .dimension__count pill stays visible as a secondary
   cue; expand button is the primary affordance. Hide the count when
   the expand button is present (avoids two redundant indicators). */
.dimension__head .dimension__expand + .dimension__count,
.dimension__head .dimension__count + .dimension__expand { /* preserve order tolerance */ }
.dimension__head:has(.dimension__expand) .dimension__count { display: none; }

/* Section heading borders use the same 5-bucket color scheme. */
/* Canonical per-dim palette from config/dimensions.json — operator
   2026-05-04: "JUMP BUTTON COLORS = DIMENSION BAR COLORS = DIMENSION
   COLORS IN BLOGS". Same hex codes everywhere. */
.dimension--under-emergency-order .dimension__head { border-bottom-color: #dc2626; }
.dimension--recent-failures       .dimension__head { border-bottom-color: #F97316; }
.dimension--worst-offenders       .dimension__head { border-bottom-color: #8B1818; }
.dimension--bad-actors            .dimension__head { border-bottom-color: #8B1818; }
.dimension--worsts                .dimension__head { border-bottom-color: #ff5722; }
.dimension--most-improved         .dimension__head { border-bottom-color: #16a34a; }
.dimension--clean-plates          .dimension__head { border-bottom-color: #16a34a; }
.dimension--permanent-closures    .dimension__head { border-bottom-color: #991B1B; }
.dimension--closures              .dimension__head { border-bottom-color: #991B1B; }
.dimension--delinquent            .dimension__head { border-bottom-color: #EA580C; }
.dimension--distressed            .dimension__head { border-bottom-color: #EA580C; }
.dimension--ghost-licenses        .dimension__head { border-bottom-color: #64748b; }
.dimension--lost-licenses         .dimension__head { border-bottom-color: #1A3D6D; }
.dimension--openings              .dimension__head { border-bottom-color: #06b6d4; }
.dimension--new-licenses          .dimension__head { border-bottom-color: #06b6d4; }
.dimension--chain-activity        .dimension__head { border-bottom-color: #9333ea; }

/* Per-section explainer that appears beneath the section heading when the
   accordion is open. Sized for 55+ readability — body-text sized, full
   ink contrast, roman (not italic), generous line-height, capped measure
   so lines stay under ~75ch. */
.dimension__intro {
  margin: var(--s-2) 0 var(--s-3);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--ink);
  font-style: normal;
  border-left: 3px solid var(--rule);
  padding: var(--s-2) var(--s-3);
  background: var(--paper-2);
  max-width: 75ch;
}
.dimension__intro ol,
.dimension__intro ul {
  margin: var(--s-2) 0 0;
  padding-left: var(--s-4);
}
.dimension__intro li {
  margin-bottom: var(--s-1);
  line-height: 1.55;
}
.dimension__intro li:last-child { margin-bottom: 0; }
.dimension__intro p { margin: 0 0 var(--s-2); }
.dimension__intro p:last-child { margin-bottom: 0; }

/* Cross-panel notes that go below the dimensions block — small,
   secondary, talks about overlap + dedup rules. */
.dimensions__notes {
  margin: var(--s-4) 0 0;
  padding: var(--s-3) var(--s-4);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 6px;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--ink-muted);
}

/* Same per-signal accent on stat tiles */
.stat-tile--clean-plates       { border-left: 6px solid #16a34a; }

/* ---- Card stack ---------------------------------------------- */
.card-stack { display: grid; gap: var(--s-4); }
.more-cards { margin-top: var(--s-4); }
.more-cards__summary {
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--navy);
  padding: var(--s-3) var(--s-4);
  border: 2px solid var(--navy);
  border-radius: 6px;
  background: var(--navy-bg);
  list-style: none;
  text-align: center;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: center;
}
.more-cards__summary::-webkit-details-marker { display: none; }
.more-cards__summary:hover { background: var(--navy); color: var(--paper); }
.more-cards__summary:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.more-cards[open] .more-cards__summary { margin-bottom: var(--s-4); }
.more-cards__list { display: grid; gap: var(--s-4); }
.more-cards__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  width: 100%;
  margin-top: var(--s-4);
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--navy);
  padding: var(--s-3) var(--s-4);
  border: 2px solid var(--navy);
  border-radius: 6px;
  background: var(--navy-bg);
  min-height: var(--tap);
}
.more-cards__btn:hover { background: var(--navy); color: var(--paper); }
.more-cards__btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.more-cards__remaining {
  font-weight: 400;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}
.more-cards__btn:hover .more-cards__remaining { color: var(--paper-3); }

/* ---- Restaurant card -----------------------------------------
   Two-column grid: main content on the left, meta rail on the right.
   The meta rail (.card__meta) carries the section chip + severity
   score so the otherwise-wasted right side reads as a per-card
   classification panel. On narrow viewports the rail sits at the top
   of the card (full width). */
.card {
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: var(--s-3);
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "body meta";
  column-gap: var(--s-3);
  row-gap: var(--s-2);
  position: relative;
}
.card > .card__meta { grid-area: meta; }
/* Everything else flows into the main "body" column. We don't want
   to relabel every existing element; the > selector + grid-area
   defaults all unmarked children to a generic span. Use grid-auto-
   placement so non-meta children stack in the body column. */
.card > :not(.card__meta) { grid-column: 1 / 2; }
@media (max-width: 540px) {
  /* Operator 2026-05-05: drop the explicit grid for narrow viewports
     so the meta rail (.card__meta) floats top-right and the
     restaurant name (.card__head h4) wraps to its left on the SAME
     line — saves the vertical scroll where the section chip + letter
     grade used to stack above the name. */
  .card {
    display: block;
  }
  .card__meta {
    float: right;
    flex-direction: row !important;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end !important;
    gap: var(--s-2) !important;
    margin: 0 0 var(--s-1) var(--s-2);
    min-width: 0;
  }
  .card__head { clear: none; }
}
.card__meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-start;
  gap: var(--s-2);
  min-width: 80px;
  margin: 0;
}

/* Section chip — small pill in the right rail labeling which
   dimension this card belongs to ("Near Miss", "Chronic", etc.).
   Color-keyed by dim group: health (red family), license (navy),
   clean-plates (green). */
.card__section {
  display: inline-flex;
  align-items: center;
  padding: 3px var(--s-2);
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  background: var(--ink);
  color: var(--paper);
}
.card__section--under-emergency-order { background: #dc2626; color: var(--paper); }
.card__section--recent-failures       { background: #F97316; color: var(--paper); }
.card__section--worst-offenders       { background: #8B1818; color: var(--paper); }
.card__section--bad-actors            { background: #8B1818; color: var(--paper); }
.card__section--most-improved         { background: #16a34a; color: var(--paper); }
.card__section--clean-plates          { background: #16a34a; color: var(--paper); }
.card__section--permanent-closures    { background: #991B1B; color: var(--paper); border: 1px solid #991B1B; }
.card__section--delinquent            { background: #EA580C; color: var(--paper); border: 1px solid #EA580C; }
.card__section--lost-licenses         { background: #1A3D6D; color: var(--paper); }
.card__section--openings              { background: #06b6d4; color: var(--paper); }
.card__section--new-licenses          { background: #06b6d4; color: var(--paper); }

/* Inspection letter grade chip — A/B/C/F derived from the inspection
   that EARNED the dimension entry (see inspectionLetterGrade in
   index.html.j2). Larger, bolder, color-banded by severity. Sits in
   the right-rail meta column directly under the section chip. */
.card__letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  height: 38px;
  padding: 0 8px;
  border-radius: 4px;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96;
  font-weight: 800;
  font-size: 1.4rem;
  line-height: 1;
  border: 2px solid currentColor;
  background: var(--paper);
  font-variant-numeric: normal;
  letter-spacing: 0;
}
.card__letter--low      { color: var(--green); }
.card__letter--moderate { color: var(--amber); }
.card__letter--high     { color: var(--red); }
.card__letter--critical {
  color: var(--paper);
  background: var(--red-deep);
  border-color: var(--red-deep);
}

/* Bottom-row actions — closure-history expander, all-violations
   expander, and the report-issue link sit on one line at desktop
   widths so the card foot reads tight. Wraps to multi-row on
   narrow viewports. Per operator 2026-05-02. */
.card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
  margin-top: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
}
.card__actions > * { margin: 0; }
.card__actions .card__details {
  flex: 0 0 auto;
}
.card__actions .card__report {
  flex: 0 1 auto;
  margin-left: auto;        /* push to the right end of the row */
}
.card__actions .card__report-link {
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.card__actions .card__report-link:hover { color: var(--red); }

/* =================================================================
   Per-card share buttons — Operator 2026-05-05: requires credit
   when readers share our data. Direct intents to FB/X/LinkedIn/
   Reddit/Email + clipboard copy. Sized small to fit card actions
   row without crowding "Report issue" link.
   ================================================================= */
.card__share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-1, 4px);
  flex: 0 1 auto;
  margin-left: auto;
  font-size: var(--text-sm);
  order: 99;
}
.card__share-label {
  margin-right: var(--s-1, 4px);
  color: var(--ink-muted);
  font-size: var(--text-xs, .72rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.card__share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  color: #fff;
  text-decoration: none;
  font-weight: 900;
  font-size: .82rem;
  line-height: 1;
  border-radius: 4px;
  border: 0;
  cursor: pointer;
}
.card__share-btn:hover { opacity: .85; }
.card__share-btn--fb { background: #1877f2; }
.card__share-btn--tw { background: #000; }
.card__share-btn--li { background: #0a66c2; }
.card__share-btn--rd { background: #ff4500; }
.card__share-btn--em { background: #4b5563; }
.card__share-btn--cp { background: #6b7280; }
@media (max-width: 540px) {
  .card__share {
    width: 100%;
    margin-left: 0;
    margin-top: var(--s-1, 4px);
    padding-top: var(--s-1, 4px);
    border-top: 1px dashed var(--rule);
  }
}

/* =================================================================
   Worst Today hero rail — 3-card "what's risky right now" strip
   above the dimensions block. Pulled from the highest-urgency dims
   (Red Alert → Near Miss → Chronic Offenders), one tile each, no
   duplicates. Tapping a tile jumps to that card's anchor.
   ================================================================= */
.hero-rail {
  margin: 0 0 var(--s-5);
  padding: var(--s-3) 0 var(--s-4);
  border-block: 2px solid var(--ink);
}
.hero-rail__head {
  margin: 0 0 var(--s-3);
}
.hero-rail__title {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96;
  font-weight: 700;
  font-size: var(--text-md);
  margin: 0;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.hero-rail__sub {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink-muted);
  margin: var(--s-1) 0 0;
}
.hero-rail__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--s-3);
}
.hero-rail__tile {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto auto auto;
  grid-template-areas:
    "kicker letter"
    "name   letter"
    "city   letter"
    "score  score";
  gap: 2px var(--s-2);
  padding: var(--s-3);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 6px solid var(--ink);
  border-radius: 6px;
  text-decoration: none;
  color: var(--ink);
  transition: box-shadow 120ms ease, transform 120ms ease;
}
.hero-rail__tile:hover,
.hero-rail__tile:focus-visible {
  box-shadow: 0 4px 12px rgba(17, 17, 17, 0.12);
  transform: translateY(-1px);
}
.hero-rail__tile--low      { border-left-color: var(--green); }
.hero-rail__tile--moderate { border-left-color: var(--amber); }
.hero-rail__tile--high     { border-left-color: var(--red); }
.hero-rail__tile--critical { border-left-color: var(--red-deep); }
.hero-rail__kicker {
  grid-area: kicker;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
}
.hero-rail__letter {
  grid-area: letter;
  align-self: center;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 96;
  font-weight: 800;
  font-size: 2.4rem;
  line-height: 1;
  border: 2px solid currentColor;
  border-radius: 6px;
  padding: 4px 10px;
  min-width: 48px;
  text-align: center;
}
.hero-rail__tile--low      .hero-rail__letter { color: var(--green); }
.hero-rail__tile--moderate .hero-rail__letter { color: var(--amber); }
.hero-rail__tile--high     .hero-rail__letter { color: var(--red); }
.hero-rail__tile--critical .hero-rail__letter {
  color: var(--paper);
  background: var(--red-deep);
  border-color: var(--red-deep);
}
.hero-rail__name {
  grid-area: name;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 32;
  font-weight: 700;
  font-size: var(--text-md);
  line-height: 1.15;
  color: var(--ink);
  text-transform: uppercase;
}
.hero-rail__city {
  grid-area: city;
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--text-sm);
  color: var(--ink-2);
}
.hero-rail__score {
  grid-area: score;
  margin-top: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
/* Neutral card spine. Severity is now communicated by the dedicated
   log-scaled severity bar, not by competing card-border colors. */
.card[data-risk-band] {
  border-left: 4px solid var(--rule);
}

.card__head { display: flex; flex-direction: column; gap: var(--s-1); }
.card__name {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 32;
  font-weight: 600;
  font-size: var(--text-md);
  margin: 0;
  line-height: 1.2;
  color: var(--ink);
}
.card__location {
  font-size: var(--text-sm);
  color: var(--ink-2);
  margin: 0;
  font-style: italic;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 14;
}
.card__stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  margin: 0;
}
.card__stat { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.card__stat dt {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
}
.card__stat dd {
  margin: 0;
  font-size: var(--text-base);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.risk-band {
  display: inline-block;
  padding: 2px var(--s-2);
  border-radius: 4px;
  font-weight: 700;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1px solid currentColor;
}
.risk-band--low      { color: var(--green); background: var(--green-bg); }
.risk-band--moderate { color: var(--amber); background: var(--amber-bg); }
.risk-band--high     { color: var(--red);   background: var(--red-bg); }
.risk-band--critical { color: var(--paper); background: var(--red); border-color: var(--red); }

.risk-score {
  margin-left: var(--s-2);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.card-trend {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: var(--s-2);
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  vertical-align: middle;
}
.card-trend--up {
  color: var(--red-deep);
  background: var(--red-bg);
}
.card-trend--down {
  color: var(--green);
  background: var(--green-bg);
}
.card-trend--flat {
  color: var(--ink-2);
  background: var(--paper-2);
}
.card-trend__arrow {
  font-size: 0.9em;
  line-height: 1;
}
.card-trend__spark {
  display: inline-flex;
  align-items: end;
  gap: 1px;
  height: 14px;
}
.card-trend__bar {
  display: block;
  width: 2px;
  min-height: 2px;
  background: currentColor;
  opacity: 0.72;
}
.card-trend__label {
  font-variant-numeric: tabular-nums;
}

.card__counts {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.card__counts strong { font-weight: 700; }
.card__disposition {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-2);
}

/* One severity visualization per inspection-rooted card. The marker uses
   log10(score+1)/log10(500), so bottom-end differences remain visible
   while long-tail emergency scores still have room to move. */
.card__severity {
  margin: var(--s-2) 0 var(--s-1);
}
.severity-bar-link {
  display: block;
  width: min(100%, 26rem);
  color: inherit;
  text-decoration: none;
}
.severity-bar {
  --severity-color: #2e7d32;
  width: 100%;
}
.severity-bar--clean { --severity-color: #2e7d32; }
.severity-bar--routine { --severity-color: #fbc02d; }
.severity-bar--heavy { --severity-color: #f57c00; }
.severity-bar--severe { --severity-color: #d32f2f; }
.severity-bar--emergency { --severity-color: #4a148c; }
.severity-bar__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-2);
  margin-bottom: 16px;
  font-family: var(--font-body);
}
.severity-bar__title {
  color: var(--ink-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.severity-bar__tier {
  color: var(--severity-color);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.severity-bar__track {
  position: relative;
  height: 14px;
  border: 1px solid rgba(23, 23, 23, 0.35);
  border-radius: 999px;
  background:
    linear-gradient(
      90deg,
      #2e7d32 0%,
      #2e7d32 38.6%,
      #fbc02d 38.6%,
      #fbc02d 55.3%,
      #f57c00 55.3%,
      #f57c00 66.2%,
      #d32f2f 66.2%,
      #d32f2f 74.3%,
      #4a148c 74.3%,
      #4a148c 100%
    );
  box-shadow: inset 0 0 0 1px rgba(255, 253, 249, 0.42);
}
.severity-bar__marker {
  position: absolute;
  top: 50%;
  width: 16px;
  height: 16px;
  border: 3px solid var(--severity-color);
  border-radius: 50%;
  background: var(--paper);
  box-shadow: 0 1px 4px rgba(23, 23, 23, 0.3);
  transform: translate(-50%, -50%);
}
.severity-bar__score {
  position: absolute;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.4rem;
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 4px;
  background: var(--paper);
  color: var(--severity-color);
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.severity-bar__marker--left .severity-bar__score {
  left: 0;
  transform: none;
}
.severity-bar__marker--right .severity-bar__score {
  right: 0;
  left: auto;
  transform: none;
}
.severity-bar__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 8px;
  margin-top: 5px;
  color: var(--ink-muted);
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.25;
  text-transform: uppercase;
}
.severity-bar-link:hover .severity-bar__track,
.severity-bar-link:focus-visible .severity-bar__track {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.card__details {
  margin-top: var(--s-2);
  border-top: 1px solid var(--rule);
  padding-top: var(--s-3);
}
.card__more {
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 700;
  color: var(--navy);
  font-size: var(--text-sm);
  list-style: none;
  padding: var(--s-2) 0;
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
}
.card__more::-webkit-details-marker { display: none; }
.card__more::after { content: " ▾"; }
.card__details[open] .card__more::after { content: " ▴"; }
.card__more:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: 4px; padding: var(--s-2); }

.card__details h5 {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  margin: var(--s-3) 0 var(--s-2);
}
.card__details p { margin: 0 0 var(--s-2); font-size: var(--text-sm); color: var(--ink); }

/* History list — recent inspections (worst-offenders) or closure events
   (bad-actors). Renders as a vertical timeline with the date in tabular
   nums on the left and the disposition/violation summary on the right. */
.card__details--supporting {
  margin-top: var(--s-3);
}
.history {
  list-style: none;
  margin: var(--s-2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.history__item {
  display: grid;
  grid-template-columns: minmax(7em, auto) 1fr;
  gap: var(--s-3);
  font-size: var(--text-sm);
  padding: var(--s-2) var(--s-3);
  border-left: 3px solid var(--rule);
  background: var(--paper-2);
  border-radius: 0 4px 4px 0;
}
.history__item:nth-child(1) {
  border-left-color: var(--red);
}
.history__item--eor {
  border-left-color: var(--red-deep);
}
.history__link {
  display: contents;
  color: inherit;
  text-decoration: none;
}
.history__link:hover .history__what {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.history__date {
  font-family: var(--font-body);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink);
}
.history__what {
  color: var(--ink-2);
}
.history__counts {
  display: block;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  margin-top: 2px;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.history__summary {
  color: var(--ink-2);
  font-size: var(--text-sm);
}
.card__trend-signal {
  font-weight: 700;
}
.card__trend-signal--recovering {
  color: var(--green);
}

.violations { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.violation {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  align-items: start;
}
.violation__priority {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 2px var(--s-2);
  border-radius: 4px;
  align-self: start;
  text-align: center;
  min-width: 3.5em;
  border: 1px solid currentColor;
  text-decoration: none;
  cursor: help;
}
a.violation__priority:hover,
a.violation__priority:focus {
  text-decoration: underline;
  outline-offset: 2px;
}
.violation__priority--hp  { color: var(--red);    background: var(--red-bg); }
.violation__priority--int { color: var(--amber);  background: var(--amber-bg); }
.violation__priority--bas { color: var(--ink-2);  background: var(--paper-3); }
.violation__label { font-weight: 700; font-size: var(--text-sm); color: var(--ink); }
.violation__code {
  font-family: var(--font-body);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: var(--text-xs);
  color: var(--navy);
  text-decoration: none;
  padding: 1px 4px;
  border-radius: 3px;
  background: var(--navy-bg);
  margin-right: var(--s-1);
}
.violation__code:hover { color: var(--paper); background: var(--navy); }
.violation__count {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  color: var(--ink-muted);
}
.violation__snippet {
  grid-column: 2;
  margin: var(--s-1) 0 0;
  font-size: var(--text-sm);
  color: var(--ink-2);
}
.violation--none { font-style: italic; color: var(--ink-muted); grid-template-columns: 1fr; }

/* ---- Footer --------------------------------------------------- */
.site-footer {
  background: var(--paper-2);
  border-top: 4px solid var(--ink);
  padding: var(--s-5) var(--s-4) var(--s-6);
  margin-top: var(--s-6);
}
.site-footer__inner {
  max-width: var(--measure-grid);
  margin: 0 auto;
  display: grid;
  gap: var(--s-5);
}
.freshness {
  font-size: var(--text-sm);
  color: var(--ink-2);
  margin: 0;
  text-align: center;
}
.freshness strong {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--text-xs);
  display: inline-block;
  margin-right: var(--s-2);
  color: var(--ink-muted);
}
.legal-block { margin: 0; }
.legal-block dt {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  margin-top: var(--s-4);
  margin-bottom: var(--s-2);
}
.legal-block dd { margin: 0; font-size: var(--text-sm); color: var(--ink-2); line-height: 1.55; }
.researcher-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  justify-content: center;
  font-size: var(--text-sm);
}
.researcher-links a {
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--s-2);
}
.copyright {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  margin: 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule);
}

/* ---- Data providers showcase ---------------------------------- */
/* Showcase-quality attribution to Foursquare (cuisine + rich data)
   and Google Places (closure verification). Uses each brand's
   official mark + colors. The block is prominent enough that anyone
   from those teams browsing the site sees clean third-party
   attribution; matches developer-attribution guidelines from both
   vendors. */
.data-providers {
  margin: var(--s-5) auto var(--s-4);
  padding: var(--s-4);
  max-width: var(--measure-grid);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 6px;
  text-align: center;
}
.data-providers__heading {
  margin: 0 0 var(--s-3);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-muted);
}
.data-providers__list {
  list-style: none;
  margin: 0 0 var(--s-3);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-3);
}
.data-providers__item { margin: 0; }
.data-providers__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 6px;
  text-decoration: none;
  color: var(--ink);
  font-size: var(--text-sm);
  transition: border-color 120ms ease, transform 120ms ease;
}
.data-providers__link:hover {
  transform: translateY(-1px);
}
.data-providers__link--foursquare:hover { border-color: #F94877; }
.data-providers__link--overture:hover   { border-color: #0B5394; }
.data-providers__link--google:hover     { border-color: #4285F4; }
.data-providers__link--dbpr:hover       { border-color: #0066CC; }
.data-providers__link--sunbiz:hover     { border-color: #C0392B; }
/* DBPR + Sunbiz "wordmark" treatment — text-based logo placeholders
   styled to read as agency-issued without infringing the actual mark.
   DBPR's official logo is lowercase blue "dbpr" with a sun icon in
   the "p"; this approximation uses brand blue + lowercase + bold. */
.data-providers__wordmark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  padding: 2px 8px;
  border-radius: 4px;
  font-weight: 800;
  font-size: var(--text-sm);
  letter-spacing: -0.02em;
  flex-shrink: 0;
}
.data-providers__wordmark--dbpr {
  background: #0066CC;
  color: white;
  text-transform: lowercase;
}
.data-providers__wordmark--sunbiz {
  background: #C0392B;
  color: white;
  text-transform: none;
  font-style: italic;
}
.data-providers__brand {
  font-weight: 700;
}
.data-providers__role {
  font-size: var(--text-xs);
  color: var(--ink-muted);
}
.data-providers__source {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  font-style: italic;
}
@media (min-width: 1024px) {
  .data-providers {
    max-width: min(720px, 100% - 2 * var(--s-4));
  }
}

/* ---- Share + follow widgets (ShareThis) ----------------------- */
/* AddToAny injects icon buttons into the .a2a_kit host. The follow row
   is a small icon set we render ourselves — three operator-curated
   accounts (Facebook group, IG, Bluesky). Both groups live inside the
   sticky .metro-picker so they stay visible while the reader scrolls. */

.metro-picker__share .a2a_button_facebook,
.metro-picker__share .a2a_button_x,
.metro-picker__share .a2a_button_bluesky,
.metro-picker__share .a2a_button_linkedin,
.metro-picker__share .a2a_button_reddit,
.metro-picker__share .a2a_button_email,
.metro-picker__share .a2a_dd {
  vertical-align: middle;
}

.metro-picker__follow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
}
.follow-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  color: var(--ink-2);
  text-decoration: none;
  transition: color 120ms ease, background 120ms ease;
}
.follow-link:hover { background: var(--paper-2); }
.follow-link--facebook:hover  { color: #1877F2; }
.follow-link--instagram:hover { color: #E1306C; }
.follow-link--bluesky:hover   { color: #1185FE; }
.follow-link:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.metro-picker__social {
  /* Hidden in the picker bar at all breakpoints — the share+follow
     strip lives in the footer where it has full-width room. Adding
     the jump-nav second row in 2026-04 made the picker too tall on
     mobile when social was also visible (~250px sticky header on a
     phone screen). Footer is the right home; the picker stays lean. */
  display: none;
}
@media (min-width: 1024px) {
  /* Desktop: same — social-in-picker stays hidden. */
  .metro-picker__social { display: none; }
  /* Picker bar drops to 3 columns on desktop now that social is gone:
     brand | dropdown | freshness. Keep it visually balanced. */
  .metro-picker__inner {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }
}

/* Footer share + follow strip — visible at all breakpoints. On
   narrow viewports the HEADER social block remains primary and this
   footer strip is a duplicate fallback the reader scrolls past. On
   wide viewports the header social is hidden (above) and this strip
   is the only share surface. AddToAny is fine with two .a2a_kit
   instances; the script binds both. */
.site-footer__share {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--rule);
}
.site-footer__share-row {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.site-footer__share-label {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}
.metro-picker__social-group {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
/* Inline label sits directly in front of each ShareThis button group:
   "share" [icons] "follow" [icons]. Visible at every breakpoint. */
.metro-picker__social-label {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: lowercase;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin-right: var(--s-1);
  white-space: nowrap;
}
.metro-picker__social-label + .a2a_kit,
.metro-picker__social-label + .metro-picker__follow {
  margin-right: var(--s-3);
}

/* ---- Print ---------------------------------------------------- */
@media print {
  :root { --paper: #fff; --ink: #000; }
  .skip-link, .metro-picker, .more-cards__summary, .card__more,
  .researcher-links, .metro-picker__social { display: none !important; }
  body { background: #fff; color: #000; }
  a { text-decoration: underline; color: #000; }
  .card { break-inside: avoid; }
  .metro-panel { padding: 0; }
}

/* ---- High-contrast preference -------------------------------- */
@media (prefers-contrast: more) {
  :root {
    --rule: #5A544A;
    --rule-strong: #1A1A1A;
    --ink-muted: #38332C;
  }
  .metro-chip { border-width: 3px; }
  .stat-tile { border-width: 2px; }
}

/* ---- Card v1.0.13 additions ---------------------------------- */
.card__address {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-2);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.card__chain {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  font-style: italic;
}
.card__chain strong { color: var(--ink); font-style: normal; }

/* Cuisine kicker — single emoji + short label sourced from
   riskyeats.render.cuisine_classify. Sits between the business name
   and the location, italicized in the body font so it reads as
   editorial annotation rather than a UI tag. The emoji carries the
   visual weight; the label is muted text. */
.card__cuisine {
  margin: 2px 0 4px;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  line-height: 1.2;
  letter-spacing: 0.005em;
}
.card__cuisine-emoji {
  font-style: normal;
  margin-right: 2px;
  font-size: 1.05em;
}
/* Generic restaurant tags get muted further so they don't scream
   "we don't know what this is" — just a quiet 🍴. */
.card__cuisine--generic { opacity: 0.7; }

/* Brand chain line — from Overture's brand.wikidata. Sits below the
   inspection metric, sibling-class to .card__chain (existing
   multi-location operator detection) but with its own visual key so
   we can tell which signal fired which line in code review. */
.card__brand {
  margin: 0 0 4px;
  font-size: var(--text-xs);
  color: var(--ink-muted);
  font-style: italic;
}
.card__brand-name { color: var(--ink); font-style: italic; font-weight: 600; }
.card__brand-link {
  color: var(--ink);
  font-style: italic;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px dotted var(--ink-muted);
}
.card__brand-link:hover,
.card__brand-link:focus-visible {
  color: var(--navy);
  border-bottom-style: solid;
  border-bottom-color: var(--navy);
}
/* Franchisee link — operator entity, links to Sunbiz. Rendered in
   the same chain badge so a reader can see "who runs this place"
   one click away from the corporate record. */
.card__franchisee-link,
.card__franchisee-name {
  color: var(--ink);
  font-style: italic;
  font-weight: 600;
  text-decoration: none;
}
.card__franchisee-link {
  border-bottom: 1px dotted var(--ink-muted);
}
.card__franchisee-link:hover,
.card__franchisee-link:focus-visible {
  color: var(--navy);
  border-bottom-style: solid;
  border-bottom-color: var(--navy);
}
/* Per-kind chain badge tints — subtle, only differ in the
   indicator stripe so a reader scanning the column can tell
   national-corp from franchisee-of-national from regional-only.
   National = navy (corporate); franchise = amber (mixed); regional
   = green (independent operator scaling up). */
.card__brand--national   { border-left: 2px solid var(--navy); padding-left: 6px; }
.card__brand--franchise  { border-left: 2px solid var(--amber, #B85C00); padding-left: 6px; }
.card__brand--regional   { border-left: 2px solid var(--green, #1B873F); padding-left: 6px; }

/* Verify-details collapsible — phone / website / socials + provenance
   footer. Tinted neutral so it visually reads as ancillary verification
   surface, not a primary card data row. Mirrors the fb / news details
   pattern (same summary cursor, expand chevron treatment). */
.card__details--verify summary {
  color: var(--ink-2);
  font-weight: 600;
}
.card__verify-body {
  padding: 8px 10px;
  background: var(--paper-2);
  border-radius: 4px;
  margin-top: 4px;
}
.card__verify-row {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
}
.card__verify-link {
  color: var(--navy);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px dotted currentColor;
  font-size: var(--text-sm);
}
.card__verify-link:hover,
.card__verify-link:focus-visible { border-bottom-style: solid; }
.card__verify-meta {
  margin: 6px 0 0;
  font-size: 11px;
  color: var(--ink-muted);
  font-style: italic;
}
.card__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1);
  margin: 0;
}
.card__link {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 2px var(--s-2);
  font-size: var(--text-xs);
  font-weight: 700;
  border: 1px solid var(--navy);
  background: var(--navy-bg);
  color: var(--navy);
  border-radius: 4px;
  text-decoration: none;
}
.card__link:hover { background: var(--navy); color: var(--paper); }
.card__pest {
  display: inline-block;
  margin-left: var(--s-2);
  padding: 1px 6px;
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: #58348B;
  color: var(--paper);
  border-radius: 3px;
}
.card__sunbiz {
  font-size: var(--text-xs);
  color: var(--red);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
/* FSQ-OS-Places "marked closed on YYYY-MM-DD" tag rendered inline on
   permanent-closures cards. Editorial value: gives reader the date FSQ
   noticed the closure, often weeks-to-months ahead of DBPR's admin
   action. Pink to match the FSQ source-pill color (#F94877 family). */
.card__fsq-closed {
  font-size: var(--text-xs);
  color: #B82F58;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
/* Tighten internal-card vertical rhythm globally — cards had too much
   whitespace between blocks per operator feedback. */
.card__stats { margin: 0; gap: var(--s-1); }
.card__stat dt { font-size: var(--text-xs); margin: 0; }
.card__stat dd { margin: 0; }
.card__counts { margin: 0; font-size: var(--text-xs); }
.card__disposition { margin: 0; font-size: var(--text-sm); }

/* ---- Privacy-policy button ---------------------------------- */
/* Operator wants the footer privacy disclosure to read as a button,
   not a hyperlink-styled <summary>. Style the disclosure summary
   with our standard button chrome (navy outline + bg-tint). */
.share-block__privacy summary {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--navy);
  background: var(--navy-bg);
  border: 1px solid var(--navy);
  border-radius: 4px;
  list-style: none;
}
.share-block__privacy summary::-webkit-details-marker { display: none; }
.share-block__privacy summary::after { content: " ▾"; margin-left: var(--s-1); }
.share-block__privacy[open] summary { background: var(--navy); color: var(--paper); }
.share-block__privacy[open] summary::after { content: " ▴"; }
.share-block__privacy[open] > div { margin-top: var(--s-3); }
.share-block__privacy-body {
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--ink);
  max-width: 65ch;
}
.share-block__privacy-body p { margin: 0 0 var(--s-2); }
.share-block__privacy-body p:last-child { margin-bottom: 0; }
.share-block__privacy-body a { color: var(--navy); text-decoration: underline; }

/* ---- Card kind color coding (left-stripe + small badge) ----- */
/* Each dimension gets a colored left-stripe so a reader can scan a
   long stack and see at-a-glance what kind of card they're looking at. */
/* Card stripe colors per 5-bucket UX scheme. */
.card--under-emergency-order { border-left: 6px solid #dc2626; }
.card--recent-failures      { border-left: 6px solid #F97316; }
.card--worst-offenders      { border-left: 6px solid #8B1818; }
.card--bad-actors           { border-left: 6px solid #8B1818; }
.card--most-improved        { border-left: 6px solid #16a34a; }
.card--clean-plates         { border-left: 6px solid #16a34a; }
.card--permanent-closures   { border-left: 6px solid #991B1B; }
.card--delinquent           { border-left: 6px solid #EA580C; }
.card--lost-licenses        { border-left: 6px solid #1A3D6D; }
.card--openings             { border-left: 6px solid #06b6d4; }
.card--new-licenses         { border-left: 6px solid #06b6d4; }

.card__kind-badge {
  display: inline-block;
  padding: 2px var(--s-2);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-radius: 3px;
  align-self: flex-start;
}
/* Kind-badge fills follow the same 5-bucket scheme. */
.card--under-emergency-order .card__kind-badge { background: #dc2626; color: var(--paper); }
.card--recent-failures      .card__kind-badge { background: #F97316; color: var(--paper); }
.card--worst-offenders      .card__kind-badge { background: #8B1818; color: var(--paper); }
.card--bad-actors           .card__kind-badge { background: #8B1818; color: var(--paper); }
.card--most-improved        .card__kind-badge { background: #16a34a; color: var(--paper); }
.card--clean-plates         .card__kind-badge { background: #16a34a; color: var(--paper); }
.card--permanent-closures   .card__kind-badge { background: #991B1B; color: var(--paper); }
.card--delinquent           .card__kind-badge { background: #EA580C; color: var(--paper); }
.card--lost-licenses        .card__kind-badge { background: #1A3D6D; color: var(--paper); }
.card--openings             .card__kind-badge { background: #06b6d4; color: var(--paper); }
.card--new-licenses         .card__kind-badge { background: #06b6d4; color: var(--paper); }

/* ---- Metro-picker freshness slug ---------------------------- */
/* Renders right of the metro dropdown — small data-currency line.
   Hidden on narrow viewports (the bar can't fit it). */
.metro-picker__freshness {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--ink-muted);
  display: none;
  align-items: center;
  gap: var(--s-1);
  white-space: nowrap;
}
@media (min-width: 768px) {
  .metro-picker__freshness { display: inline-flex; }
}
.metro-picker__freshness-label {
  text-transform: lowercase;
  letter-spacing: 0.02em;
}
.metro-picker__freshness-date {
  font-weight: 700;
  color: var(--ink);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.metro-picker__freshness-edition { color: var(--ink-muted); }

/* ---- ShareThis: suppress widget-internal labels ----------- */
/* The platform-api injects its own "Follow us:" / "Share" copy.
   Our inline <span class="metro-picker__social-label"> already does
   that. Hide every ShareThis-internal label class so we don't end
   up with duplicated copy. */
.sharethis-inline-share-buttons .st-label,
.sharethis-inline-share-buttons .st-share-label,
.sharethis-inline-follow-buttons .st-label,
.sharethis-inline-follow-buttons .st-follow-label,
.st-follow-label,
.st-share-counts {
  display: none !important;
}

/* ---- Dimension accordion --------------------------------- */
/* Wrapper that holds the always-visible narrative kicker + the
   collapsed <details> for one dimension. Stack vertically. */
.dimension-block {
  display: flex;
  flex-direction: column;
  gap: 0;
  border-top: 1px solid var(--rule);
  /* Sticky header has 2 rows on desktop (~5rem) + jump-nav (~3rem)
     + toolbar (~3rem) = ~11rem. On mobile the masthead column-stacks
     6 controls (~16rem), so the upper clamp goes to 18rem to clear
     all sticky chrome. */
  scroll-margin-top: clamp(11rem, 28vh, 22rem);
}
.dimension-block:first-child { border-top: 0; }

/* Search filter sets data-search-empty on dim-blocks (and the
   featured-closures section) when zero of their cards match the
   current query. Hidden during search-mode; cleared on filter clear.
   Sections WITH matches keep their summary heading visible so the
   reader can see which dimension each match belongs to. */
.dimension-block[data-search-empty="true"],
.featured-closures[data-search-empty="true"] {
  display: none;
}
/* When the search-mode is on (any non-empty filter active), tighten
   the dim chrome: hide the long-form narrative + explainer prose so
   the matching cards are the dominant content. The dim's summary
   heading stays visible — that's the "what section am I in" anchor
   the operator wants preserved. */
.metro-panel[data-search-mode="on"] .dimension__narrative,
.metro-panel[data-search-mode="on"] .dimension__intro,
.metro-panel[data-search-mode="on"] .dimension__head .dimension__count,
.metro-panel[data-search-mode="on"] .featured-closures__head .featured-closures__count {
  display: none;
}
/* Tighten heading padding while in search mode so the section labels
   read as compact rules between match groups, not as full panels. */
.metro-panel[data-search-mode="on"] .dimension__head,
.metro-panel[data-search-mode="on"] .featured-closures__head {
  padding-top: var(--s-2);
  padding-bottom: var(--s-2);
}
/* The persona's per-dim distributed narrative — always visible above
   the collapsed dimension <details>. Reads first; the summary headline
   under it is the affordance to drill into the cards.
   Two-column layout: icon column (left) + prose+blog-link column. */
.dimension__narrative {
  margin: 0;
  padding: var(--s-3) var(--s-3) var(--s-2);
  background: var(--paper);
  border-left: 4px solid var(--rule);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  align-items: start;
}
.dimension__narrative-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--paper-2);
  color: var(--ink);
  flex-shrink: 0;
  border: 2px solid currentColor;
}
.dimension__narrative-icon svg {
  display: block;
  width: 24px;
  height: 24px;
}
/* Per-dim icon color tracks the narrative's left-border color. */
/* Operator 2026-05-04: narrative-icon colors must match the canonical
   per-dim palette (config/dimensions.json). Same hex on the pill, the
   section border, the dim icon, AND this narrative-prose ring. */
.dimension-block[data-dim="under-emergency-order"] .dimension__narrative-icon { color: #dc2626; }
.dimension-block[data-dim="recent-failures"]       .dimension__narrative-icon { color: #F97316; }
.dimension-block[data-dim="worst-offenders"]       .dimension__narrative-icon { color: #8B1818; }
.dimension-block[data-dim="bad-actors"]            .dimension__narrative-icon { color: #8B1818; }
.dimension-block[data-dim="worsts"]                .dimension__narrative-icon { color: #ff5722; }
.dimension-block[data-dim="most-improved"]         .dimension__narrative-icon { color: #16a34a; }
.dimension-block[data-dim="clean-plates"]          .dimension__narrative-icon { color: #16a34a; }
.dimension-block[data-dim="permanent-closures"]    .dimension__narrative-icon { color: #991B1B; }
.dimension-block[data-dim="closures"]              .dimension__narrative-icon { color: #991B1B; }
.dimension-block[data-dim="delinquent"]            .dimension__narrative-icon { color: #EA580C; }
.dimension-block[data-dim="distressed"]            .dimension__narrative-icon { color: #EA580C; }
.dimension-block[data-dim="ghost-licenses"]        .dimension__narrative-icon { color: #64748b; }
.dimension-block[data-dim="lost-licenses"]         .dimension__narrative-icon { color: #1A3D6D; }
.dimension-block[data-dim="openings"]              .dimension__narrative-icon { color: #06b6d4; }
.dimension-block[data-dim="new-licenses"]          .dimension__narrative-icon { color: #06b6d4; }
.dimension-block[data-dim="chain-activity"]        .dimension__narrative-icon { color: #9333ea; }
/* Featured Closure Signals re-uses the same icon container so the
   page reads consistently across the always-expanded panel + the
   collapsed dim panels. */
.featured-closures .dimension__narrative-icon { color: var(--ink); }
.dimension__narrative-body {
  min-width: 0;
}
.dimension__narrative-prose {
  margin: 0 0 var(--s-1);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--ink);
  max-width: 75ch;
}
.dimension__narrative-blog-link {
  display: inline-block;
  margin-top: var(--s-1);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.dimension__narrative-blog-link:hover,
.dimension__narrative-blog-link:focus-visible {
  color: var(--red-deep);
  text-decoration-thickness: 2px;
}
/* Per-dim left-border colors echo the section group (health/license)
   so the narrative reads as part of the same color band as the data
   panel below it. */
.dimension-block[data-dim="under-emergency-order"] .dimension__narrative { border-left-color: #dc2626; }
.dimension-block[data-dim="recent-failures"]       .dimension__narrative { border-left-color: #F97316; }
.dimension-block[data-dim="worst-offenders"]       .dimension__narrative,
.dimension-block[data-dim="bad-actors"]            .dimension__narrative { border-left-color: #8B1818; }
.dimension-block[data-dim="worsts"]                .dimension__narrative { border-left-color: #ff5722; }
.dimension-block[data-dim="most-improved"]         .dimension__narrative,
.dimension-block[data-dim="clean-plates"]          .dimension__narrative { border-left-color: #16a34a; }
.dimension-block[data-dim="permanent-closures"]    .dimension__narrative,
.dimension-block[data-dim="closures"]              .dimension__narrative { border-left-color: #991B1B; }
.dimension-block[data-dim="delinquent"]            .dimension__narrative,
.dimension-block[data-dim="distressed"]            .dimension__narrative { border-left-color: #EA580C; }
.dimension-block[data-dim="ghost-licenses"]        .dimension__narrative { border-left-color: #64748b; }
.dimension-block[data-dim="lost-licenses"]         .dimension__narrative { border-left-color: #1A3D6D; }
.dimension-block[data-dim="openings"]              .dimension__narrative,
.dimension-block[data-dim="new-licenses"]          .dimension__narrative { border-left-color: #06b6d4; }
.dimension-block[data-dim="chain-activity"]        .dimension__narrative { border-left-color: #9333ea; }

/* Each .dimension is a <details> that defaults to closed (except
   red alert + permanent closures). Summary row shows the section
   name + record count, click to expand. */
.dimension {
  border-block: 1px solid var(--rule);
  margin: 0;
  padding: 0;
  /* Account for the sticky masthead+jump-nav strip so a jump-link
     click lands the section heading BELOW the sticky header, not
     hidden under it. Same offset as .card (6rem) — keeps the visual
     anchor consistent across jump types. */
  scroll-margin-top: 6rem;
}
/* Featured Closure Signals panel uses .dimension class so it inherits
   the scroll-margin above. Belt-and-suspenders: re-apply on the
   featured-closures alias in case .featured-closures CSS specificity
   ever overrides .dimension. */
.featured-closures { scroll-margin-top: 6rem; }
.dimension + .dimension { border-top: 0; }
.dimension > summary.dimension__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  cursor: pointer;
  padding: var(--s-3) var(--s-3);
  margin: 0;
  list-style: none;
  background: var(--paper);
  font-family: var(--font-display);
  font-weight: 700;
  min-height: var(--tap);
  transition: background 120ms ease;
}
.dimension > summary.dimension__head:hover { background: var(--paper-2); }
.dimension > summary.dimension__head::-webkit-details-marker { display: none; }
.dimension > summary.dimension__head::after {
  content: "▾";
  color: var(--ink-muted);
  font-family: var(--font-body);
  font-size: var(--text-md);
  transition: transform 140ms ease;
}
.dimension[open] > summary.dimension__head::after { transform: rotate(180deg); }
.dimension__heading {
  margin: 0;
  font-size: var(--text-md);
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--ink);
  flex: 1;
}
.dimension__icon {
  display: inline-block;
  vertical-align: -4px;
  width: 22px;
  height: 22px;
  margin-right: var(--s-2);
  /* Inherit color from the dimension's accent set on .dimension--<slug>. */
  color: currentColor;
}
.dimension__heading-text {
  /* Inline span — keeps prior heading wrap/balance intact. */
}
/* Per-dim icon color — matches the pill, dim bar, and blog kicker so
   every surface reads from the same hex per dim. Operator 2026-05-04. */
.dimension--under-emergency-order .dimension__icon { color: #dc2626; }
.dimension--bad-actors .dimension__icon,
.dimension--worst-offenders .dimension__icon { color: #8B1818; }
.dimension--worsts .dimension__icon { color: #ff5722; }
.dimension--permanent-closures .dimension__icon,
.dimension--closures .dimension__icon { color: #991B1B; }
.dimension--delinquent .dimension__icon,
.dimension--distressed .dimension__icon { color: #EA580C; }
.dimension--recent-failures .dimension__icon { color: #F97316; }
.dimension--most-improved .dimension__icon,
.dimension--clean-plates .dimension__icon { color: #16a34a; }
.dimension--openings .dimension__icon,
.dimension--new-licenses .dimension__icon { color: #06b6d4; }
.dimension--ghost-licenses .dimension__icon { color: #64748b; }
.dimension--lost-licenses .dimension__icon { color: #1A3D6D; }
.dimension--chain-activity .dimension__icon { color: #9333ea; }
.dimension__count {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  white-space: nowrap;
}
.dimension > .card-stack,
.dimension > .more-cards__btn,
.dimension > .empty {
  margin: var(--s-3);
}

/* Color the accordion summary stripe per-dimension to match the
   card-kind color coding so the stripe carries through even when
   the section is collapsed. */
.dimension--under-emergency-order > summary.dimension__head { border-left: 6px solid #dc2626; padding-left: var(--s-3); }
.dimension--permanent-closures   > summary.dimension__head { border-left: 6px solid #991B1B; padding-left: var(--s-3); }
.dimension--closures             > summary.dimension__head { border-left: 6px solid #991B1B; padding-left: var(--s-3); }
.dimension--recent-failures      > summary.dimension__head { border-left: 6px solid #F97316; padding-left: var(--s-3); }
.dimension--worst-offenders      > summary.dimension__head { border-left: 6px solid #8B1818; padding-left: var(--s-3); }
.dimension--bad-actors           > summary.dimension__head { border-left: 6px solid #8B1818; padding-left: var(--s-3); }
.dimension--worsts               > summary.dimension__head { border-left: 6px solid #ff5722; padding-left: var(--s-3); }
.dimension--most-improved        > summary.dimension__head { border-left: 6px solid #16a34a; padding-left: var(--s-3); }
.dimension--clean-plates         > summary.dimension__head { border-left: 6px solid #16a34a; padding-left: var(--s-3); }
.dimension--delinquent           > summary.dimension__head { border-left: 6px solid #EA580C; padding-left: var(--s-3); }
.dimension--distressed           > summary.dimension__head { border-left: 6px solid #EA580C; padding-left: var(--s-3); }
.dimension--ghost-licenses       > summary.dimension__head { border-left: 6px solid #64748b; padding-left: var(--s-3); }
.dimension--lost-licenses        > summary.dimension__head { border-left: 6px solid #1A3D6D; padding-left: var(--s-3); }
.dimension--openings             > summary.dimension__head { border-left: 6px solid #06b6d4; padding-left: var(--s-3); }
.dimension--new-licenses         > summary.dimension__head { border-left: 6px solid #06b6d4; padding-left: var(--s-3); }
.dimension--chain-activity       > summary.dimension__head { border-left: 6px solid #9333ea; padding-left: var(--s-3); }

/* ---- Jump-nav container (second row INSIDE metro-picker) ---------
   The jump-nav-container is now a sibling row inside the sticky
   metro-picker <nav>, NOT a separate sticky container. The parent
   metro-picker handles sticky positioning at top:0; we just add a
   thin separator border above the jump row so it reads visually
   distinct from the brand/dropdown row above it. */
.jump-nav-container {
  margin-top: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
  position: relative;
}
/* Mobile: right-edge fade so readers see the strip is horizontally
   scrollable. Hidden once the strip is scrolled to its end via the
   data-scroll-end attribute that the JS scrollspy toggles. */
@media (max-width: 1023px) {
  .jump-nav-container::after {
    content: "";
    position: absolute;
    top: var(--s-2);
    right: 0;
    bottom: 0;
    width: 28px;
    pointer-events: none;
    background: linear-gradient(to right, transparent, var(--paper-2));
    transition: opacity 140ms ease;
  }
  .jump-nav-container[data-scroll-end="true"]::after { opacity: 0; }
}
.jump-nav {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  gap: var(--s-1);
  margin: 0 auto;
  max-width: var(--measure-grid);
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--s-2);
}
@media (min-width: 1024px) {
  .jump-nav {
    flex-wrap: wrap;
    overflow-x: visible;
    max-width: min(1100px, 100% - 2 * var(--s-4));
    scroll-snap-type: none;
  }
}
/* (Compact-mode jump-nav rule removed 2026-05-02 — is-compact class
   was never set after the masthead/lede observer surfaces went away.) */
.jump-nav__link {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s-1);
  padding: 4px var(--s-2);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-decoration: none;
  color: var(--navy);
  background: var(--navy-bg);
  border: 1px solid var(--navy);
  border-radius: 4px;
  white-space: nowrap;
  scroll-snap-align: start;
}
.jump-nav__link:hover { background: var(--navy); color: var(--paper); }
/* Mobile: WCAG-compliant 36px tap target (was ~22px). Center-align the
   label vertically once we have real height. */
@media (max-width: 1023px) {
  .jump-nav__link {
    padding: 8px var(--s-2);
    min-height: 36px;
    align-items: center;
  }
}
/* Active pill — set by the scrollspy when its dimension is in view.
   Inverts the pill colors so the reader can see at-a-glance which
   section they're reading. Stays subordinate to :hover so power-users
   browsing the nav still see hover feedback. */
.jump-nav__link[aria-current="location"] {
  background: var(--navy);
  color: var(--paper);
}
.jump-nav__link[data-group="health"][aria-current="location"] {
  background: var(--red-deep);
  color: var(--paper);
  border-color: var(--red-deep);
}
.jump-nav__link[data-group="license"][aria-current="location"] {
  background: var(--navy);
  color: var(--paper);
  border-color: var(--navy);
}
.jump-nav__count {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  opacity: 0.8;
}
/* Operator 2026-05-04: replaced coarse `data-group` palette with the
   canonical per-`data-dim` palette below (line ~2680+ — codered/
   badactors/distressed/defunct/etc.). Keeping fallback rules here for
   anchors that don't have `data-dim` (e.g. the legacy distress chip-
   row's `data-group="license"` pills above the briefing). Subtle
   default — the per-dim selectors take over wherever data-dim is set.
   Don't add new colors here; add them at the per-dim block. */
.jump-nav__link[data-group="health"]:not([data-dim]),
.jump-nav__link[data-group="license"]:not([data-dim]) {
  color: var(--ink);
  background: var(--paper);
  border-color: var(--rule);
}
.jump-nav__link[data-group="health"]:not([data-dim]):hover,
.jump-nav__link[data-group="license"]:not([data-dim]):hover {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
/* Operator 2026-05-04: FRI = Florida Restaurant Index analytics —
   purple `#7c3aed` (violet-600). Distinct from chain-activity's
   #9333ea purple-600 by being slightly more violet, less magenta. */
.jump-nav__link[data-group="fri"],
.jump-nav__link--fri {
  color: var(--paper);
  background: #7c3aed;
  border-color: #7c3aed;
  font-weight: 800;
  box-shadow: 0 0 0 1px rgba(124, 58, 237, 0.25);
}
.jump-nav__link[data-group="fri"]:hover,
.jump-nav__link--fri:hover {
  background: #5b21b6;
  color: var(--paper);
  border-color: #5b21b6;
}
.jump-nav__link--fri .jump-nav__count {
  font-weight: 800;
  opacity: 1;
}

/* ─────────────────────────────────────────────────────────────────
 * Operator 2026-05-04 canonical palette — config/dimensions.json.
 * Single source of truth; every pill, kicker, section border, and
 * dim-icon uses ONE of these hex values per dim slug. Don't pick
 * adjacent shades; if a hover variant is needed, darken via filter
 * not a different color.
 *
 *   codered     #dc2626   under-emergency-order      (active emergency)
 *   badactors   #8B1818   bad-actors / worst-offenders
 *                         (chronic offenders — repeat violations)
 *   worsts      #ff5722   worsts                       (cross-flag outlier)
 *   distressed  #EA580C   delinquent                  (trouble brewing)
 *   defunct     #991B1B   closures / permanent-closures (closed)
 *   conditiongreen #16a34a most-improved / clean-plates (positive)
 *   newopenings #06b6d4   openings / new-licenses     (issuance)
 *   hotspots    #9333ea   chain-activity              (chain rollup)
 *   slate       #64748b   ghost-licenses              (admin grey-zone)
 *   navy        #1A3D6D   lost-licenses               (administrative)
 *   nearmiss    #F97316   recent-failures             (cited but open)
 * ─────────────────────────────────────────────────────────────────*/

/* CODE RED #dc2626 — active enforcement */
.jump-nav__link[data-dim="under-emergency-order"] {
  color: var(--paper);
  background: #dc2626;
  border-color: #dc2626;
}
/* BAD ACTORS #8B1818 — chronic / repeat offenders */
.jump-nav__link[data-dim="bad-actors"],
.jump-nav__link[data-dim="worst-offenders"] {
  color: var(--paper);
  background: #8B1818;
  border-color: #8B1818;
}

/* WORSTS #ff5722 — sunburst orange (cross-flag, multi-dim concentration).
   Operator 2026-05-04: distinct from bad-actors red so the cross-flag
   tier reads at a glance as the "extreme" outlier. */
.jump-nav__link[data-dim="worsts"],
.jump-nav__link[data-group="worsts"] {
  color: var(--paper);
  background: #ff5722;
  border-color: #ff5722;
}

/* DEFUNCT #991B1B — closed / permanent */
.jump-nav__link[data-dim="permanent-closures"],
.jump-nav__link[data-dim="closures"] {
  color: var(--paper);
  background: #991B1B;
  border-color: #991B1B;
}

/* DISTRESSED #EA580C — admin lapse trouble brewing */
.jump-nav__link[data-dim="delinquent"],
.jump-nav__link[data-dim="distressed"] {
  color: var(--paper);
  background: #EA580C;
  border-color: #EA580C;
}

/* NEAR MISS #F97316 — cited but still operating */
.jump-nav__link[data-dim="recent-failures"] {
  color: var(--paper);
  background: #F97316;
  border-color: #F97316;
}

/* CONDITION GREEN #16a34a — positive */
.jump-nav__link[data-dim="most-improved"],
.jump-nav__link[data-dim="clean-plates"] {
  color: var(--paper);
  background: #16a34a;
  border-color: #16a34a;
}

/* NEW OPENINGS #06b6d4 — issuance */
.jump-nav__link[data-dim="openings"],
.jump-nav__link[data-dim="new-licenses"] {
  color: var(--paper);
  background: #06b6d4;
  border-color: #06b6d4;
}

/* SLATE #64748b — ghost / admin grey-zone */
.jump-nav__link[data-dim="ghost-licenses"] {
  color: var(--paper);
  background: #64748b;
  border-color: #64748b;
}

/* NAVY #1A3D6D — administrative ownership */
.jump-nav__link[data-dim="lost-licenses"] {
  color: var(--paper);
  background: #1A3D6D;
  border-color: #1A3D6D;
}

/* HOTSPOTS #9333ea — chain rollup */
.jump-nav__link[data-group="chain"],
.jump-nav__link[data-dim="chain-activity"] {
  color: var(--paper);
  background: #9333ea;
  border-color: #9333ea;
}

/* Operator 2026-05-04 (rev 3) — pill hover. Earlier `filter: brightness(0.82)`
   was clipping the contained text on some browsers (pills appeared to
   "disappear" on hover). Switched to a 2px ink ring via box-shadow +
   slight saturate boost; preserves dim-color, never affects layout, no
   stacking-context side-effects. */
.jump-nav__link[data-dim]:hover,
.jump-nav__link[data-group="worsts"]:hover,
.jump-nav__link[data-group="chain"]:hover,
.jump-nav__link--fri:hover {
  box-shadow: 0 0 0 2px var(--ink);
}
/* Spacer between health and license groups: the rule below targets
   any license-pill immediately preceded by a health-pill, which is
   only true at the group boundary. */
.jump-nav__link[data-group="health"] + .jump-nav__link[data-group="license"] {
  margin-left: var(--s-3);
}

/* ---- ShareThis: aggressive label suppression -------------- */
/* The first pass missed ShareThis's actual class names (their JS
   injects a label without our hide-list classes). Wildcard match
   any class containing "label" / "text" / "header" anywhere inside
   either widget container. The icon buttons use class names like
   `st-btn` / `st-btns` which do NOT match label/text/header, so the
   icons stay visible. */
.sharethis-inline-share-buttons [class*="label" i],
.sharethis-inline-share-buttons [class*="text" i],
.sharethis-inline-share-buttons [class*="header" i],
.sharethis-inline-share-buttons [class*="title" i],
.sharethis-inline-follow-buttons [class*="label" i],
.sharethis-inline-follow-buttons [class*="text" i],
.sharethis-inline-follow-buttons [class*="header" i],
.sharethis-inline-follow-buttons [class*="title" i] {
  display: none !important;
}

/* ---- Briefing mentions: color-coded per dimension ---- */
/* When the briefing names a restaurant, wrap the name in a colored
   underline + bold so the reader can scan and see what kind of
   trouble each named place is in (red = closure / near miss,
   navy = bad actor, amber = lost license, green = clean / new). */
.briefing-mention {
  font-weight: 700;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.15em;
}
.briefing-mention--under-emergency-order { color: #dc2626; text-decoration-color: #dc2626; }
.briefing-mention--permanent-closures   { color: #991B1B; text-decoration-color: #991B1B; }
.briefing-mention--closures             { color: #991B1B; text-decoration-color: #991B1B; }
.briefing-mention--recent-failures      { color: #F97316; text-decoration-color: #F97316; }
.briefing-mention--worst-offenders      { color: #8B1818; text-decoration-color: #8B1818; }
.briefing-mention--bad-actors           { color: #8B1818; text-decoration-color: #8B1818; }
.briefing-mention--worsts               { color: #ff5722; text-decoration-color: #ff5722; }
.briefing-mention--most-improved        { color: #16a34a; text-decoration-color: #16a34a; }
.briefing-mention--clean-plates         { color: #16a34a; text-decoration-color: #16a34a; }
.briefing-mention--delinquent           { color: #EA580C; text-decoration-color: #EA580C; }
.briefing-mention--distressed           { color: #EA580C; text-decoration-color: #EA580C; }
.briefing-mention--ghost-licenses       { color: #64748b; text-decoration-color: #64748b; }
.briefing-mention--lost-licenses        { color: #1A3D6D; text-decoration-color: #1A3D6D; }
.briefing-mention--openings             { color: #06b6d4; text-decoration-color: #06b6d4; }
.briefing-mention--new-licenses         { color: #06b6d4; text-decoration-color: #06b6d4; }
.briefing-mention--chain-activity       { color: #9333ea; text-decoration-color: #9333ea; }

/* Source-attribution icons after a mention. Used to mark closures
   confirmed by Google Places (multicolor G) or flagged by Foursquare
   (pink check square). The icon sits inline after the name with a
   small left margin and slight baseline lift for vertical alignment.
   The two extra modifier classes (--google-confirmed and
   --fsq-confirmed) lift the visual weight: thicker underline, bolder
   color treatment, so the reader's eye lands on confirmed cases first.
   Google = strong confirmation tier (external customer-facing
   attestation). FSQ = secondary signal. DBPR and Sunbiz signals are
   preserved on the underlying card data for historical / post-mortem
   reference but don't add prose emphasis. */
.briefing-mention__source-icon {
  display: inline-block;
  vertical-align: -1px;
  margin-left: 3px;
  flex-shrink: 0;
}
.briefing-mention__check {
  display: inline-block;
  margin-right: 3px;
  color: #1B873F;
  font-weight: 800;
}
.briefing-mention--google-confirmed {
  text-decoration-thickness: 3px;
  text-decoration-color: #4285F4;
  background: rgba(66, 133, 244, 0.07);
  padding: 0 3px;
  border-radius: 2px;
}
.briefing-mention--fsq-confirmed {
  text-decoration-thickness: 3px;
  text-decoration-color: #F94877;
}
.briefing-mention--fb-confirmed {
  text-decoration-thickness: 3px;
  text-decoration-color: #1877F2;
  background: rgba(24, 119, 242, 0.06);
  padding: 0 3px;
  border-radius: 2px;
}

/* Sunbiz / corporate operator line — visible on every card so
   readers see the legal-entity owner. Status badge color-codes
   active vs dissolved. */
.card__sunbiz-line {
  margin: 4px 0 6px;
  font-size: 13px;
  color: var(--ink-mute, #555);
}
.card__sunbiz-label {
  font-weight: 600;
  color: var(--ink, #1a1a1a);
}
.card__sunbiz-status {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-left: 4px;
  background: #e9f3e9;
  color: #1B873F;
}
.card__sunbiz-status--inactive,
.card__sunbiz-status--dissolved,
.card__sunbiz-status--admin-dissolved-for-annual-report,
.card__sunbiz-status--admin-dissolution-for-annual-report,
.card__sunbiz-status--admin-dissolved {
  background: rgba(220, 38, 38, 0.1);
  color: #b30000;
}

/* Multi-source confirmation badge row. Each source (FB, Google, Sunbiz,
   DBPR, LLM, FSQ) gets its own pill so a reader sees instantly which
   independent sources corroborate the card. */
.card__sources-row {
  margin: 4px 0 6px;
  font-size: 11px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}
.card__source-badge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: white;
}
/* Sunbiz pill becomes a link when corp data is present. Keep the pill
   visually identical to its non-link siblings, but indicate interactivity
   on hover/focus and ensure focus is visible for keyboard users. */
.card__source-badge-link {
  display: inline-block;
  text-decoration: none;
}
.card__source-badge-link:hover .card__source-badge,
.card__source-badge-link:focus-visible .card__source-badge {
  filter: brightness(1.12);
}
.card__source-badge-link:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: 3px;
}
/* Inline Sunbiz authority link (operator line + body stat rows).
   Renders as a single anchor wrapping name + ↗ icon (single tab stop).
   Underline-on-hover keeps the editorial tone in dense card bodies. */
.sunbiz-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted currentColor;
}
.sunbiz-link:hover,
.sunbiz-link:focus-visible {
  border-bottom-style: solid;
  color: var(--navy);
}
.sunbiz-link:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
  border-radius: 2px;
}
.sunbiz-link__icon {
  display: inline-block;
  margin-left: 0.2em;
  font-size: 0.85em;
  opacity: 0.7;
  vertical-align: baseline;
}
.card__confidence-label {
  font-size: 11px;
  font-weight: 600;
  color: #555;
  margin-left: 4px;
}

/* Confidence label on FB-announced cards. Single-source = signal-only
   amber/grey; multi-source = corroborated solid badge. */
.card__confidence {
  display: inline-block;
  margin: 4px 0;
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.card__confidence--signal-only {
  background: #fff5e6;
  color: #b85c00;
  border: 1px dashed #b85c00;
}
.card__confidence--corroborated {
  background: rgba(24, 119, 242, 0.1);
  color: #1877F2;
  border: 1px solid #1877F2;
}
.card__sources {
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0;
  text-transform: lowercase;
  margin-left: 4px;
}

/* FB-announced extras block on social-signal cards. */
.card__details--fb summary {
  color: #1877F2;
  font-weight: 600;
}
.card__fb-body {
  padding: 8px 10px;
  background: rgba(24, 119, 242, 0.04);
  border-radius: 4px;
  margin-top: 4px;
}
.card__fb-link {
  color: #1877F2;
  font-weight: 600;
  text-decoration: underline;
}
.card__fb-meta {
  font-size: 12px;
  color: #666;
  margin: 6px 0 0;
}

/* News-source extras block on closure-signal cards. Mirrors fb-extras
   pattern but tinted teal to match the news pill color (#0E7C66). */
.card__details--news summary {
  color: #0E7C66;
  font-weight: 600;
}
.card__news-body {
  padding: 8px 10px;
  background: rgba(14, 124, 102, 0.05);
  border-radius: 4px;
  margin-top: 4px;
}
.card__news-headline {
  font-style: italic;
  color: var(--ink, #1a1a1a);
  margin: 0 0 6px;
}
.card__news-link {
  color: #0E7C66;
  font-weight: 600;
  text-decoration: underline;
}
.card__news-meta {
  font-size: 12px;
  color: #666;
  margin: 6px 0 0;
}
.card__ocr-block {
  margin-top: 6px;
  font-size: 12px;
}
.card__ocr {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 11px;
  background: #fff;
  padding: 6px 8px;
  border: 1px solid #ddd;
  border-radius: 3px;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 180px;
  overflow: auto;
  margin: 4px 0 0;
}

/* ---- Brand block: name + tagline ---------------------- */
/* Small italic tagline beneath the wordmark so a first-time visitor
   knows what the site is without scrolling. Tagline hides under
   600px (the bar can't fit it on phones). */
.metro-picker__brand {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  line-height: 1;
  text-decoration: none;
  color: var(--red);
  white-space: nowrap;
}
.metro-picker__brand-name {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 800;
  font-variation-settings: "opsz" 64, "wdth" 90;
  line-height: 1;
  color: var(--red);
}
.metro-picker__brand-tagline {
  display: none;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-style: italic;
  font-weight: 400;
  color: var(--ink-muted);
  letter-spacing: 0;
  margin-top: 2px;
}
@media (min-width: 600px) {
  .metro-picker__brand-tagline { display: block; }
}

/* ---- Featured Closure Watch module ----------------------------- */
/* Promoted out of the dimension accordion list per GRAEAE UX consult
   2026-04-29. Sits directly under the briefing prose, above the jump
   nav. Always expanded; the most journalistically valuable surface
   on the page. Visual treatment is editorial-card (heavy border, red
   accent, contained card-stack) — distinct from the other panel
   accordions so it reads as the lead story not just another section. */
.featured-closures {
  margin: var(--s-5) 0 var(--s-5);
  padding: var(--s-4) var(--s-4) var(--s-3);
  border-left: 6px solid #991B1B;
  background: linear-gradient(90deg, rgba(153, 27, 27, 0.04), transparent 60%);
  border-radius: 6px;
}
.featured-closures__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-bottom: var(--s-2);
  padding-bottom: var(--s-2);
  border-bottom: 2px solid #991B1B;
}
.featured-closures__badge {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--paper);
  background: #991B1B;
  padding: var(--s-1) var(--s-2);
  border-radius: 3px;
}
.featured-closures__heading {
  margin: 0;
  font-size: var(--text-lg);
  font-family: var(--font-display);
  color: var(--ink);
  flex: 1;
}
.featured-closures__count {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.card__stat--temp-closed dd small {
  display: block;
  margin-top: 2px;
  color: var(--ink-muted);
  font-style: italic;
}

/* ---- Closure Score badge ----------------------------------- */
/* Prominent X/4 score on every Closure Signals card. Tier 1-4 get
   progressively heavier color treatment to scan-rank the stack at
   a glance. See section intro for tier semantics. */
.card__stat--closure-score dd {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}
.closure-score {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.4rem;
  line-height: 1;
  padding: var(--s-1) var(--s-2);
  border-radius: 4px;
  font-variant-numeric: tabular-nums;
}
.closure-score__total {
  font-size: 0.7em;
  font-weight: 600;
  opacity: 0.6;
  margin-left: 1px;
}
.closure-score--tier-1 { background: rgba(245, 158, 11, 0.12); color: var(--amber-deep, #92400e); }
.closure-score--tier-2 { background: rgba(220, 38, 38, 0.10); color: var(--red); }
.closure-score--tier-3 { background: rgba(220, 38, 38, 0.18); color: var(--red-deep); }
.closure-score--tier-4 {
  background: var(--red-deep);
  color: var(--paper);
}

/* ---- External-verifier badge row --------------------------- */
/* Shown inside Closure Signals cards when one or more of Google/
   Yelp/Foursquare has weighed in on the place's status. Compact row
   of provider logos, each linking out to the matched listing. */
.card__stat--verdict {
  border-top: 1px dashed var(--rule);
  padding-top: var(--s-2);
  margin-top: var(--s-2);
}
.provider-logos {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-left: var(--s-2);
  vertical-align: middle;
}
.provider-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  text-decoration: none;
  transition: transform 120ms ease, background 120ms ease;
}
.provider-logo:hover { background: var(--paper-2); transform: scale(1.1); }
.provider-logo:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.verdict-reason {
  display: block;
  margin-top: var(--s-1);
  font-style: italic;
  color: var(--ink-muted);
}

/* Promote tier-4 (externally-confirmed) cards visually — heavier left
   stripe + tinted bg so the eye finds them first in the closure-signals
   stack. Falls back to existing card-stripe color for other tiers. */
.card--permanent-closures.card--tier-4 {
  border-left-width: 8px;
  border-left-color: #991B1B;
  background: linear-gradient(90deg, rgba(153, 27, 27, 0.04), transparent 60%);
}

/* ---- Delinquent dimension styling -------------------------- */
.card--delinquent          { border-left: 6px solid #EA580C; }
.dimension--delinquent > summary.dimension__head { border-left: 6px solid #EA580C; padding-left: var(--s-3); }
.briefing-mention--delinquent { color: #EA580C; text-decoration-color: #EA580C; }

/* ---- Report mapping issue (per-card) ---- */
/* Small bottom-of-card link readers can use to flag a suspected
   mismatch (card shows violations for license X but the user knows
   the actual restaurant is a different license). mailto with
   license_id + business_name pre-filled so audit is fast. */
.card__report {
  margin: 0.6rem 0 0 0;
  padding: 0.3rem 0 0 0;
  border-top: 1px dashed var(--paper-3);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  text-align: right;
}
.card__report-link {
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px dotted var(--paper-3);
  padding-bottom: 1px;
}
.card__report-link:hover,
.card__report-link:focus-visible {
  color: var(--red);
  border-bottom-color: var(--red);
  outline: none;
}

/* ---- Sparkline + trend chip (bad_actors / worst_offenders) ---- */
/* Server-rendered SVG sparkline shows quarterly event density over
   ~11 years; the trend chip alongside is a single-glance verdict on
   whether the restaurant is worsening, stable, or recovering based on
   recent-540d vs prior-540d event ratio. Goal: reader can scan the
   card without reading the full closure-history list, but can expand
   to receipts via the <details> below. */
.card__sparkline {
  margin: 0.5rem 0 0 0;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.card__sparkline-label {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-2);
  white-space: nowrap;
}
.sparkline {
  display: block;
  flex: 0 0 auto;
}
.trend-chip {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.trend-chip--worsening   { background: var(--red-bg);   color: var(--red-deep); }
.trend-chip--worsening::before { content: "↑"; font-weight: 800; }
.trend-chip--stable      { background: #FEF3C7;          color: #8A6300; }
.trend-chip--stable::before    { content: "→"; }
.trend-chip--recovering  { background: #DCFCE7;          color: #14532D; }
.trend-chip--recovering::before { content: "↓"; }
.trend-chip--no_signal   { background: var(--paper-3);   color: var(--ink-muted); }
.trend-chip--no_signal::before { content: "·"; }

/* ---- Closure / inspection history collapse details ---- */
.card__history-details {
  margin: 0.4rem 0 0 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
}
.card__history-details summary {
  cursor: pointer;
  color: var(--navy);
  font-weight: 600;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.card__history-details summary::before {
  content: "▸";
  display: inline-block;
  transition: transform 0.12s ease;
}
.card__history-details[open] summary::before {
  transform: rotate(90deg);
}
.card__history-details ul {
  list-style: none;
  padding: 0.4rem 0 0 1rem;
  margin: 0;
  border-left: 2px solid var(--paper-3);
  margin-left: 0.4rem;
}
.card__history-details li {
  margin: 0.2rem 0;
  color: var(--ink-2);
  display: flex;
  gap: 0.5rem;
}
.card__history-details li time {
  font-weight: 600;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  flex: 0 0 auto;
}

/* ---- Briefing paragraph color sectioning ------------------- */
/* Each paragraph in the briefing prose carries a left border tinted
   to match the dimension that the paragraph's first restaurant mention
   belongs to. JS adds .briefing__paragraph--<kind> when it can determine
   which dimension the paragraph is about. */
.briefing__paragraph[data-kind] {
  border-left: 4px solid var(--rule);
  padding-left: var(--s-3);
  margin-left: 0;
}
.briefing__paragraph[data-kind="under-emergency-order"] { border-left-color: #dc2626; }
.briefing__paragraph[data-kind="recent-failures"]       { border-left-color: #F97316; }
.briefing__paragraph[data-kind="worst-offenders"],
.briefing__paragraph[data-kind="bad-actors"]            { border-left-color: #8B1818; }
.briefing__paragraph[data-kind="worsts"]                { border-left-color: #ff5722; }
.briefing__paragraph[data-kind="permanent-closures"],
.briefing__paragraph[data-kind="closures"]              { border-left-color: #991B1B; }
.briefing__paragraph[data-kind="delinquent"],
.briefing__paragraph[data-kind="distressed"]            { border-left-color: #EA580C; }
.briefing__paragraph[data-kind="most-improved"],
.briefing__paragraph[data-kind="clean-plates"]          { border-left-color: #16a34a; }
.briefing__paragraph[data-kind="openings"],
.briefing__paragraph[data-kind="new-licenses"]          { border-left-color: #06b6d4; }
.briefing__paragraph[data-kind="ghost-licenses"]        { border-left-color: #64748b; }
.briefing__paragraph[data-kind="lost-licenses"]         { border-left-color: #1A3D6D; }
.briefing__paragraph[data-kind="chain-activity"]        { border-left-color: #9333ea; }

.signup__submit-loading { display: none; }
.signup__form[data-state="loading"] .signup__submit-label { visibility: hidden; }
.signup__form[data-state="loading"] .signup__submit-loading {
  display: inline;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.signup__form[data-state="loading"] .signup__submit { pointer-events: none; }
.signup__form[data-state="ok"] .metro-picker__signup-status      { color: var(--green); }
.signup__form[data-state="error"] .metro-picker__signup-status   { color: var(--red); }

/* ----------------------------------------------------------------------
   Per-metro restaurant search (native <datalist> autocomplete).
   Sits between the brand bar and the jump-nav pills, inside the
   sticky header so it follows the reader. JS rebuilds the form +
   datalist on every metro switch from that metro's loaded JSON.
   Aesthetic matches the signup module (light card chrome, red
   submit) so the two compact masthead modules read as a pair.
   ---------------------------------------------------------------------- */
.metro-search-container {
  margin-top: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--rule);
}
.metro-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-1);
  margin: 0 auto;
  max-width: var(--measure-grid);
}
.metro-search__label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.metro-search__submit {
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.4rem 0.9rem;
  background: var(--red);
  color: var(--paper);
  border: 1px solid var(--red);
  border-radius: 3px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.metro-search__submit:hover,
.metro-search__submit:focus-visible {
  background: var(--red-deep);
  border-color: var(--red-deep);
  outline: none;
}
.metro-search__status {
  flex: 1 0 100%;
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.78rem;
  color: var(--ink-muted);
  min-height: 1em;
}
.metro-search__status:empty { display: none; }
.metro-picker__contrib-link {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--red-deep, var(--red));
  text-decoration: underline;
  text-underline-offset: 0.2em;
  align-self: center;
  white-space: nowrap;
}
.metro-picker__contrib-link:hover { color: var(--ink); }
/* (Removed: .metro-search__hint — operator 2026-05-02: extra text block not needed; placeholder broadened to 'Name, city, or address…' instead.) */

/* (Compact-mode tightening removed 2026-05-02 — was targeting
   .metro-search-container which never existed in the template
   (real class is .metro-picker__search-wrap). Codex MED LOW finding.) */
@media (max-width: 1023px) {
  .metro-search__label-text {
    font-size: 0.72rem;
  }
}

/* Search-hit highlight — short pulse on the landed card so the
   reader's eye finds it even when the section was already partly
   in view. CSS-only; the class is removed after 1800ms by JS. */
.card--search-hit {
  animation: card-search-hit 1.6s ease-out 1;
  scroll-margin-top: 6rem;
}
@keyframes card-search-hit {
  0%   { box-shadow: 0 0 0 0 rgba(185, 28, 28, 0.55); }
  30%  { box-shadow: 0 0 0 6px rgba(185, 28, 28, 0.18); }
  100% { box-shadow: 0 0 0 0 rgba(185, 28, 28, 0); }
}
/* Always give cards scroll-margin so deep-link jumps don't land
   under the sticky header. Independent of search; benefits any
   #card-* link (briefing-mention rewrite, social shares, etc.). */
.card[id^="card-"] { scroll-margin-top: 6rem; }

/* ---- Announced-closure tier (2026-05-01) -------------------- */
/* Cards in the announced-closure tier carry a moderate-tone badge
   ("Closing YYYY-MM-DD") + a small footer line clarifying the venue
   is still open today. Visually warmer than the critical
   confirmed-closed treatment so readers do not conflate "soon" with
   "already happened". Reuses .risk-band--moderate (amber) which
   matches the temp-closed pattern. */
.card__stat--announced-closure dd small {
  display: block;
  margin-top: 2px;
  color: var(--ink-muted);
  font-style: italic;
}
.card__stat--announced-closure dt {
  /* Slightly stronger emphasis than the default card__stat dt so the
     "Announced closing" row reads as the editorial lead. */
  color: var(--ink);
}

/* ====================================================================
   Phase 0 UX consolidation (2026-05-02) — InspectFL-cherry-pick + 55+
   broadsheet UX principles + space-density tightening.

   Goals (operator directives):
   - Stop wasting so much space
   - Present data immediately (no drilling, no preamble)
   - 55+ readability (18px body min, AAA contrast, ≥44px tap targets)
   - Anti-drill-down: dimension panels open by default
   - Steal what works from InspectFL.org: per-card severity stripe, A-F grade
   - Civic-newspaper aesthetic preserved (deep red, not peach)
   ==================================================================== */

/* ---- Hide the AddToAny "+" share-menu trigger -------------------- */
/* The default "+" icon isn't recognizable as a share affordance.
   We ship explicit per-platform buttons (FB, X, Bluesky, LinkedIn,
   Reddit, Email) — the dropdown is redundant. */
.a2a_dd { display: none !important; }

/* Masthead tightening, blog CTA, and signup chrome are consolidated in
   the unified masthead block near the end of the file. */

/* ---- Anti-drill-down: dimension panels open by default ----------
   InspectFL hides everything behind clicks. We don't. Every panel's
   <details> renders open; users see the data on landing, no click
   required. The summary still toggles open/close for the user who
   wants to collapse, but the default state is OPEN. */
.dimension[open] { display: flex; }
.dimension > summary.dimension__head {
  cursor: pointer;
}
/* Ensure all dimension panels actually open on render. The template
   sets `open` on the first dim by default; for the rest, JS in the
   template will add the `open` attribute on first metro load. */

/* ---- Compact dimension panels -----------------------------------
   Reduce vertical waste between panels + within each panel. */
.dimensions { gap: var(--s-4); }
.dimension { gap: var(--s-3); }
.dimension > summary.dimension__head {
  padding: var(--s-2) 0;
}
.dimension__head {
  padding-bottom: var(--s-1);
}
/* Compact-mode tweak retained for vertical rhythm. Font-size now
   inherits from the canonical rule above (base size for 55+ legibility). */


/* ---- Compact stat-band ------------------------------------------
   Was rendering as a fairly tall table. Tighten + reduce padding so
   it occupies less vertical space above the briefing. */
.stat-band {
  padding: var(--s-2);
}
.stat-band__heading {
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  margin: 0 0 var(--s-1);
}

/* ---- Tighter cards (same data, less padding) -------------------- */
.card {
  padding: var(--s-2) var(--s-3);
  gap: var(--s-1);
}
.card__head { gap: 1px; }
.card__location { font-size: 0.85rem; }
.card__stats { gap: var(--s-3); }
.card__stat dt { font-size: 0.7rem; }
.card__stat dd { font-size: 0.95rem; }
.card__counts, .card__disposition { font-size: 0.85rem; }

/* ---- Default-open <details> behavior for dimension panels --------
   Cleanly visible disclosure caret that doesn't compete with the
   colored severity stripes inside. Smaller than default, ink color. */
.dimension > summary::-webkit-details-marker { display: none; }
.dimension > summary { list-style: none; }
.dimension > summary::after {
  content: "▾";
  font-size: 0.85em;
  color: var(--ink-muted);
  margin-left: var(--s-2);
  display: inline-block;
  transition: transform 120ms ease;
}
.dimension[open] > summary::after { transform: rotate(180deg); }

/* ---- Wider above-the-fold cap on prose / wide-screen reflow ----
   The briefing prose stays 65ch for readability, but the surrounding
   container can fill 1280px on wide screens. Cards inside dimensions
   already use a grid that scales to multiple columns above 1024px. */
@media (min-width: 1280px) {
  .card-stack { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Cap at 3 columns on widescreen per operator 2026-05-03.
   The previous 4-col at 1680px+ made each card narrow enough that
   'All violations' expansions wrapped awkwardly and the CHRONIC
   badge truncated. */

/* Cards keep a neutral spine; section identity lives in the section chip
   and dimension heading, while inspection severity lives in the bar. */
.card--under-emergency-order,
.card--recent-failures,
.card--worst-offenders,
.card--bad-actors,
.card--most-improved,
.card--clean-plates,
.card--permanent-closures,
.card--delinquent,
.card--lost-licenses,
.card--openings,
.card--new-licenses {
  border-left-width: 4px;
  border-left-color: var(--rule);
}

/* =================================================================
   Unified masthead controls — 2026-05-02
   One canonical source for the sticky masthead layout and the four
   bottom-row pills: metro, restaurant search, blog, and subscribe.
   Native select/search controls stay native; no custom SVG data-URI
   carets or native-control reset hacks.
   ================================================================= */
:root {
  --pill-h:        38px;
  --pill-h-sm:     32px;
  --pill-radius:   999px;
  --pill-radius-soft: 4px;
  --pill-pad-x:    14px;
  --pill-pad-y:    6px;
  --pill-gap:      6px;
}

.metro-picker { padding-block: var(--s-1) !important; }
.metro-picker__inner {
  display: flex !important;
  flex-direction: column;
  align-items: stretch;
  gap: var(--pill-gap);
}

.metro-picker__brand {
  order: 1;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  min-height: var(--pill-h);
  margin: 0;
  text-decoration: none;
  color: var(--red);
  white-space: nowrap;
}
.metro-picker__brand-name {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 32;
  font-weight: 800;
  font-size: clamp(1.35rem, 4vw, 1.8rem);
  letter-spacing: 0;
  line-height: 1;
  color: var(--red);
}
.metro-picker__brand-tagline {
  display: none;
  font-size: 0.78rem;
}
.metro-picker__freshness {
  order: 2;
  display: inline-flex;
  margin: 0;
  font-size: 0.78rem;
  gap: 0.25rem;
}

.metro-picker__select-wrap,
.metro-picker__search-wrap,
.metro-picker__signup,
.metro-picker__blog-cta {
  min-width: 0;
}
.metro-picker__select-wrap { order: 3; }
.metro-picker__search-wrap { order: 4; display: block; }
.metro-picker__blog-cta    { order: 5; }
.metro-picker__signup      { order: 6; display: block; }
.metro-picker__social-stub { display: none !important; }

.metro-picker__select-wrap,
.metro-picker__search-wrap .metro-search,
.metro-picker__blog-cta,
.metro-picker__signup-form {
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  min-height: var(--pill-h);
  border: 1px solid var(--rule);
  border-radius: var(--pill-radius);
  display: inline-flex;
  align-items: center;
  gap: var(--pill-gap);
  margin: 0;
  padding: 0 var(--pill-pad-x);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1;
  white-space: nowrap;
}
/* All four masthead pills share the same rose background per
   operator 2026-05-02: "use same rose background for all ux pills
   in the header". Visual unity > role differentiation here — the
   metro/resto pickers + blog/subscribe CTAs all read as one palette. */
/* Operator 2026-05-04: pick-a-metro / find-a-resto / blog cta /
   subscribe form — red background with white text, not the pink
   tint they had before. Inputs inside need their text + placeholder
   colors flipped to white-ish too. */
.metro-picker__select-wrap,
.metro-picker__search-wrap .metro-search,
.metro-picker__blog-cta,
.metro-picker__signup-form {
  background: #dc2626;
  border-color: #dc2626;
  color: var(--paper);
}
.metro-picker__select-label,
.metro-picker__search-wrap .metro-search__label,
.metro-picker__blog-cta,
.metro-picker__signup-pitch,
.metro-picker__signup-kicker,
.metro-picker__signup-tag {
  color: var(--paper) !important;
}
/* Operator 2026-05-04: metro selection text + find-a-resto typed-in
   query + subscribe email all read in YELLOW on the red picker
   background. #FFEA00 = ~6.5:1 contrast on #dc2626 (AAA normal-text)
   and pops against the red far better than the previous white. */
.metro-picker__select,
.metro-picker__search-wrap .metro-search__input,
.metro-picker__signup-input {
  color: #FFEA00;
  font-weight: 700;
  caret-color: #FFEA00;
}
.metro-picker__search-wrap .metro-search__input::placeholder,
.metro-picker__signup-input::placeholder {
  color: rgba(255, 234, 0, 0.78);
}
.metro-picker__select option {
  color: var(--ink);  /* native dropdown options stay paper-on-ink */
  background: var(--paper);
}

.metro-picker__select-label,
.metro-picker__search-wrap .metro-search__label {
  flex: 0 0 auto;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  white-space: nowrap;
  line-height: 1;
}
.metro-picker__search-wrap .metro-search {
  flex-wrap: nowrap;
}
.metro-picker__select,
.metro-picker__search-wrap .metro-search__input {
  box-sizing: border-box;
  flex: 1 1 auto;
  min-width: 0;
  height: calc(var(--pill-h) - 10px);
  padding: 0 4px;
  border: 0;
  border-radius: var(--pill-radius);
  background: transparent;
  /* Operator 2026-05-04: yellow on red picker — was overriding the
     yellow rule above with `var(--ink)` (black). Strip native chrome
     with appearance:none so macOS Safari respects the color too. */
  color: #FFEA00;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: normal;
  outline: none;
}
/* Custom dropdown chevron now that we stripped native appearance. */
.metro-picker__select {
  background-image:
    linear-gradient(45deg, transparent 50%, #FFEA00 50%),
    linear-gradient(-45deg, transparent 50%, #FFEA00 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 22px;
}
.metro-picker__select {
  cursor: pointer;
}
.metro-picker__search-wrap .metro-search__input {
  cursor: text;
}
/* Operator 2026-05-04: belt-and-suspenders bold on find-a-resto.
   Some browsers render <input> with their own font-weight default that
   was beating the cascade above on certain devices. Force it. */
.metro-search__input,
.metro-picker__search-wrap .metro-search__input,
.metro-search__input::placeholder,
.metro-picker__search-wrap .metro-search__input::placeholder {
  font-weight: 700 !important;
}
.metro-picker__search-wrap .metro-search__input::-webkit-search-decoration,
.metro-picker__search-wrap .metro-search__input::-webkit-search-cancel-button,
.metro-picker__search-wrap .metro-search__input::-webkit-search-results-button,
.metro-picker__search-wrap .metro-search__input::-webkit-search-results-decoration {
  display: none;
}
.metro-picker__select-wrap:focus-within,
.metro-picker__search-wrap .metro-search:focus-within,
.metro-picker__signup-form:focus-within,
.metro-picker__blog-cta:focus-visible {
  border-color: var(--ink);
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--ink);
  outline: none;
}
.metro-picker__search-wrap .metro-search__status,
.metro-picker__signup-status {
  display: none;
}
.metro-picker__search-wrap .metro-search__status:not(:empty),
.metro-picker__signup-status:not(:empty) {
  display: block;
  flex-basis: 100%;
  margin: var(--s-1) 0 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-muted);
  white-space: normal;
}

.metro-picker__blog-cta {
  text-decoration: none;
  justify-content: flex-start;
  transition: background 120ms ease, color 120ms ease;
}
.metro-picker__blog-cta:hover,
.metro-picker__blog-cta:focus-visible {
  background: var(--red);
  color: var(--paper);
}
.metro-picker__blog-cta-avatar {
  width: 24px !important;
  height: 24px !important;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
  background: var(--paper-3);
}
.metro-picker__blog-cta-label {
  display: inline-flex;
  flex-direction: column;
  line-height: 1;
  gap: 1px;
}
.metro-picker__blog-cta-kicker {
  font-size: 0.7em;
  color: var(--red);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.metro-picker__blog-cta:hover .metro-picker__blog-cta-kicker,
.metro-picker__blog-cta:focus-visible .metro-picker__blog-cta-kicker {
  color: var(--paper);
}
.metro-picker__blog-cta-name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.95em;
}

.metro-picker__signup-pitch,
.metro-picker__signup-kicker,
.metro-picker__signup-tag {
  display: none !important;
}
.metro-picker__signup-form {
  padding: 0 4px 0 var(--pill-pad-x);
}
.metro-picker__signup-input {
  flex: 1 1 12rem;
  min-width: 0;
  height: calc(var(--pill-h) - 12px);
  padding: 0 10px;
  border: 0;
  border-radius: var(--pill-radius);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  outline: none;
}
.metro-picker__signup-input::placeholder { color: var(--ink-muted); }
.metro-picker__signup-submit {
  flex: 0 0 auto;
  height: calc(var(--pill-h) - 12px);
  padding: 0 14px;
  border: 1px solid var(--paper);
  border-radius: var(--pill-radius);
  /* Submit button sits ON the red signup-form bg now — invert: paper
     bg with red text reads as the canonical submit affordance. */
  background: var(--paper);
  color: #dc2626;
  font-family: var(--font-body);
  font-weight: 800;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
}
.metro-picker__signup-submit:hover,
.metro-picker__signup-submit:focus-visible {
  background: #fee2e2;
  color: #991B1B;
  outline: none;
}

@media (min-width: 600px) {
  .metro-picker__brand-tagline { display: block; }
}
@media (min-width: 1024px) {
  /* Desktop masthead. Per Stuart Skolnik feedback 2026-05-03: 4 pills
     in one row squeezed the Find-a-Resto input too narrow for typing.
     Now 2 pills per row at 1024-1440px (metro+search on row 1,
     blog+signup on row 2), then 4-up at >=1440px where there\u0027s
     genuine horizontal headroom. */
  .metro-picker__inner {
    max-width: min(1240px, 100% - 2 * var(--s-4));
    display: grid !important;
    grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "brand freshness freshness"
      "brand metro     search"
      "brand signup    signup";
    justify-content: start;
    align-items: center;
    column-gap: var(--pill-gap);
    row-gap: var(--pill-gap);
  }
  .metro-picker__brand       { grid-area: brand; align-self: stretch; display: flex; align-items: center; }
  .metro-picker__freshness   { grid-area: freshness; justify-self: start; }
  .metro-picker__select-wrap { grid-area: metro; }
  .metro-picker__search-wrap { grid-area: search; }
  .metro-picker__blog-cta    { grid-area: blog; }
  .metro-picker__signup      { grid-area: signup; }
  .metro-picker__select-wrap,
  .metro-picker__search-wrap .metro-search,
  .metro-picker__blog-cta,
  .metro-picker__signup-form {
    width: 100% !important;
    min-width: 0;
  }
  .metro-picker__select,
  .metro-picker__search-wrap .metro-search__input,
  .metro-picker__signup-input {
    width: auto;
    flex: 1 1 auto;
    min-width: 0;
  }
}
@media (min-width: 1440px) {
  /* Wide desktop — go back to 4 pills in a single row. At 1440px+
     each pill has room to breathe even with the Find-a-Resto label
     occupying ~110px. */
  .metro-picker__inner {
    grid-template-columns: auto minmax(0, 1.4fr) minmax(360px, 2fr) auto;
    grid-template-areas:
      "brand freshness freshness freshness"
      "brand metro     search    signup";
  }
}

/* Social share + follow — top-of-masthead pill row, always visible */
.metro-picker__social,
.metro-picker__social--top {
  display: inline-flex !important;
  align-items: center;
  gap: var(--pill-gap);
  flex-wrap: wrap;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  height: auto;
}
.metro-picker__social .metro-picker__social-label { display: none; }
.metro-picker__social .a2a_kit { display: inline-flex; gap: 4px; }
.metro-picker__social .a2a_kit > a {
  width: var(--pill-h);
  height: var(--pill-h);
  border: 1px solid var(--rule);
  border-radius: var(--pill-radius);
  background: var(--paper);
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
}
.metro-picker__social .a2a_kit > a:hover { background: var(--paper-2); border-color: var(--ink); }
.metro-picker__social .a2a_kit > a img,
.metro-picker__social .a2a_kit > a svg {
  width: 18px !important;
  height: 18px !important;
  display: block;
}
.metro-picker__social .metro-picker__follow {
  display: inline-flex;
  gap: 4px;
}
.metro-picker__social .follow-link {
  width: var(--pill-h);
  height: var(--pill-h);
  border: 1px solid var(--rule);
  border-radius: var(--pill-radius);
  background: var(--paper);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
}
.metro-picker__social .follow-link:hover { background: var(--ink); color: var(--paper); }

/* (Legacy compact-mode social-visibility override removed 2026-05-02 —
   social block now lives in .riskyeats-toolbar between the jump-nav
   and the metro panel, not in the masthead. Codex MED.) */

/* Jump nav — pill row, same metrics as masthead */
.jump-nav__link {
  height: var(--pill-h);
  padding: 0 var(--pill-pad-x);
  border-radius: var(--pill-radius);
  font-size: var(--text-sm);
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: var(--pill-gap);
  white-space: nowrap;
}

/* Stat-band — pills */
.stat-tile {
  height: var(--pill-h);
  padding: 0 var(--pill-pad-x);
  border-radius: var(--pill-radius);
  display: inline-flex;
  align-items: center;
  gap: var(--pill-gap);
  min-height: 0;
  border-left-width: 1px !important;
}
.stat-tile__label {
  font-size: var(--text-sm);
  line-height: 1;
}
.stat-tile__value {
  font-size: 1.1em;
  line-height: 1;
}
.stat-band {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;       /* center stat tiles when the row wraps — operator 2026-05-02 */
  gap: var(--pill-gap);
  padding: var(--s-2) 0 !important;
  background: transparent !important;
  border: 0 !important;
}
.stat-band__heading,
.stat-band__metro { display: none; }

/* =================================================================
   SLIM FOOTER — 2026-05-02
   Compact one-line strips replacing the stacked legal/data-providers
   blocks. Single "details" handles full legal text on demand.
   ================================================================= */
.site-footer {
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--rule);
  background: var(--paper-2);
}
.site-footer__inner {
  max-width: var(--measure-grid);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  align-items: center;
  text-align: center;
}
.footer-freshness {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--ink-muted);
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
}
.footer-links a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.footer-links a:hover { color: var(--red); }
.footer-links span[aria-hidden] { color: var(--ink-muted); }

.footer-legal {
  width: 100%;
  max-width: 75ch;
  margin: 0;
}
.footer-legal > summary {
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  text-align: center;
  list-style: none;
}
.footer-legal > summary::-webkit-details-marker { display: none; }
.footer-legal > summary::after { content: " ▾"; }
.footer-legal[open] > summary::after { content: " ▴"; }
.footer-legal__body {
  padding-top: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: 1.55;
  color: var(--ink);
  text-align: left;
}
.footer-legal__body p { margin: 0 0 var(--s-2); }
.footer-legal__body p:last-child { margin: 0; }

.data-providers-strip {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--ink-muted);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  align-items: center;
}
.data-providers-strip__label {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.data-providers-strip a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.data-providers-strip a:hover { color: var(--red); }

.copyright {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

/* =================================================================
   GLOBAL TYPOGRAPHY PASS — 2026-05-02
   Operator: "lets see if we can improve global typography"
   Target audience is 55+; favor body font (Atkinson Hyperlegible)
   for prose, display font (Bricolage Grotesque) only for the bigger
   headings + numerals. Every paragraph at 18px body / 1.6 line-height.
   Heading hierarchy: h1 28px, h2 22.5px, h3 18px-bold, h4 16px-bold.
   ================================================================= */

/* Body prose anywhere on the page — paragraphs and list items inherit
   the 55+-friendly 18px / 1.6 / Atkinson family unless something
   inside a card or header overrides. */
body, p, li, dd {
  font-family: var(--font-body);
}
.metro-panel p,
.metro-panel li,
.metro-panel dd,
.dimension__narrative-prose,
.dimension__intro p,
.briefing__paragraph,
.post-section__voice,
.post-lede {
  font-size: var(--text-base);
  line-height: 1.6;
}

/* Heading hierarchy — display font, weighted, balanced text-wrap */
.dimension__heading {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 32;
  font-weight: 700;
  font-size: var(--text-md);
  line-height: 1.2;
  letter-spacing: -0.005em;
  text-wrap: balance;
}
.metro-briefing > h2,
.briefing > h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-md);
  line-height: 1.2;
}

/* Card name — body font at 18px so the 55+ reader doesn't squint.
   Was previously text-md display which read as too-big for a card
   that's already constrained on horizontal real estate. */
.card__name {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 32;
  font-weight: 700;
  font-size: var(--text-base);
  line-height: 1.25;
  letter-spacing: -0.005em;
}

/* Card secondary text — bump from text-xs to text-sm for readability.
   xs (14px) was too small for the 55+ baseline. */
.card__location,
.card__counts,
.card__disposition,
.card__report-link {
  font-size: var(--text-sm);
  line-height: 1.5;
}

/* Stat tile + jump-nav labels — keep at text-sm; was inconsistent
   between text-xs and text-sm depending on which historical block
   set them. */
.stat-tile__label,
.stat-tile__value {
  font-size: var(--text-sm);
}
.jump-nav__link .jump-nav__label {
  font-size: var(--text-sm);
  font-weight: 700;
}
.jump-nav__link .jump-nav__count {
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  margin-left: 4px;
  opacity: 0.85;
}

/* Footer + masthead small text — unify at text-xs (14px) so all
   incidental labels read as one register. */
.footer-freshness,
.footer-links,
.data-providers-strip,
.metro-picker__freshness {
  font-size: var(--text-xs);
}

/* =================================================================
   WCAG typography pass — 2026-05-02
   ================================================================= */

/* Global focus-visible default. Any interactive element that doesn't
   ship its own focus style gets a clear ink outline. WCAG 2.4.7
   requires a visible focus indicator on every keyboard-reachable
   element; this is the safety net. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Touch pointers (phones, tablets) — bump pill min-height to AAA's
   44px target. The masthead controls, jump-nav, and toolbar all
   inherit through the existing `var(--pill-h)`. */
/* (Coarse-pointer global --pill-h bump removed — was forcing every
   pill on the page to 44px and stretching the masthead pills into
   tall ovals on widescreen + mobile. We hit 44px tap targets via
   per-element min-height where needed, not via a global var bump.) */
/* Card-body text bumps — these pieces of prose were sitting at
   text-xs (~14px) which fails the operator's 16px-minimum-for-body
   rule for the 55+ audience. Lift them to text-sm where readability
   matters; truly incidental labels (kicker tags, status timestamps)
   stay at xs. */
.card__location {
  font-size: var(--text-sm);
}
.card__counts {
  font-size: var(--text-sm);
  line-height: 1.55;
}
.card__disposition {
  font-size: var(--text-sm);
}

/* Body prose line-height — bump from any 1.4 hits to ≥1.55 so the
   55+ audience reads dense paragraphs without losing place. */
.card__counts,
.dimension__intro p,
.footer-legal__body p {
  line-height: 1.55;
}

/* (Legacy .metro-picker__social--hidden hide-rule removed 2026-05-02 —
   the placeholder div now uses the [hidden] HTML attribute, which
   does the same thing without a CSS selector. Codex MED.) */

/* =================================================================
   Fixed social toolbar — sits BETWEEN jump nav and metro panel.
   Single horizontal pill row, always visible, no compact-mode hide.
   ================================================================= */
.riskyeats-toolbar {
  max-width: var(--measure-grid);
  margin: 0 auto;
  padding: var(--s-2) var(--s-4);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--pill-gap);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.riskyeats-toolbar__label {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
}
.riskyeats-toolbar__divider { color: var(--ink-muted); }
.riskyeats-toolbar .a2a_kit { display: inline-flex; gap: 4px; }
.riskyeats-toolbar .a2a_kit > a {
  width: var(--pill-h);
  height: var(--pill-h);
  border: 1px solid var(--rule);
  border-radius: var(--pill-radius);
  background: var(--paper);
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
}
.riskyeats-toolbar .a2a_kit > a:hover { background: var(--ink); border-color: var(--ink); }
.riskyeats-toolbar .a2a_kit > a img,
.riskyeats-toolbar .a2a_kit > a svg {
  width: 18px !important;
  height: 18px !important;
  display: block;
}
.riskyeats-toolbar__follow {
  display: inline-flex;
  gap: 4px;
}
.riskyeats-toolbar__follow .follow-link {
  width: var(--pill-h);
  height: var(--pill-h);
  border: 1px solid var(--rule);
  border-radius: var(--pill-radius);
  background: var(--paper);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
}
.riskyeats-toolbar__follow .follow-link:hover { background: var(--ink); color: var(--paper); }
/* CACHE-BUST 20260502T190737 */

/* ---- Dimension expander head — 5-bucket severity palette ----------
   Operator 2026-05-02 (rev 2): cleaner functional grouping.
     RED      = UEO active enforcement
     ORANGE   = Near Miss (cited but operating)
     MAROON   = Chronic pattern
     GREEN    = Positive (clean / new license)
     NAVY     = License admin (lost license)
     CHARCOAL = Closed / off-cadence
*/
.dimension-block > .dimension > summary.dimension__head {
  padding: var(--s-2) var(--s-3);
  border-radius: 4px;
  border-bottom: 0;
  margin: 0 0 var(--s-3);
  cursor: pointer;
  background: #2B2B2B;
  color: var(--paper);
  transition: filter 120ms ease;
}
.dimension-block > .dimension > summary.dimension__head:hover {
  filter: brightness(1.08);
}
.dimension-block > .dimension > summary.dimension__head,
.dimension-block > .dimension > summary.dimension__head *,
.dimension-block > .dimension > summary.dimension__head .dimension__heading,
.dimension-block > .dimension > summary.dimension__head .dimension__count,
.dimension-block > .dimension > summary.dimension__head .dimension__expand,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-cue,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-cue--open,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-cue--closed,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-chevron {
  color: inherit !important;
}
/* Yellow/orange variants need dark text for AAA contrast on the
   warmer backgrounds. Recent-failures uses ORANGE which still passes
   on white text but the chronic-pattern + UEO RED + deep MAROON
   need lighter weight for the small "Show N records" cue so it
   reads at glance. */
.dimension-block > .dimension > summary.dimension__head .dimension__count,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-cue {
  opacity: 0.92;
}
.dimension-block[data-dim="under-emergency-order"] > .dimension > summary.dimension__head {
  background: #dc2626;
}
.dimension-block[data-dim="recent-failures"] > .dimension > summary.dimension__head {
  background: #F97316;
  color: var(--paper);
}
.dimension-block[data-dim="worst-offenders"] > .dimension > summary.dimension__head,
.dimension-block[data-dim="bad-actors"] > .dimension > summary.dimension__head {
  background: #8B1818;
}
.dimension-block[data-dim="worsts"] > .dimension > summary.dimension__head {
  background: #ff5722;
}
.dimension-block[data-dim="most-improved"] > .dimension > summary.dimension__head,
.dimension-block[data-dim="clean-plates"] > .dimension > summary.dimension__head {
  background: #16a34a;
}
.dimension-block[data-dim="permanent-closures"] > .dimension > summary.dimension__head,
.dimension-block[data-dim="closures"] > .dimension > summary.dimension__head {
  background: #991B1B;
}
.dimension-block[data-dim="delinquent"] > .dimension > summary.dimension__head,
.dimension-block[data-dim="distressed"] > .dimension > summary.dimension__head {
  background: #EA580C;
}
.dimension-block[data-dim="ghost-licenses"] > .dimension > summary.dimension__head {
  background: #64748b;
}
.dimension-block[data-dim="lost-licenses"] > .dimension > summary.dimension__head {
  background: #1A3D6D;
}
.dimension-block[data-dim="openings"] > .dimension > summary.dimension__head,
.dimension-block[data-dim="new-licenses"] > .dimension > summary.dimension__head {
  background: #06b6d4;
}
.dimension-block[data-dim="chain-activity"] > .dimension > summary.dimension__head {
  background: #9333ea;
}

/* ---- Jump-nav pills — match section bar colors (5-bucket rev2) ---
   Same palette as dimension__head. Solid color rest state, brightness
   bump on hover, outline on aria-current="location" (scrollspy).
*/
.jump-nav__link[data-dim="under-emergency-order"] {
  color: var(--paper); background: #dc2626; border-color: #dc2626;
}
.jump-nav__link[data-dim="recent-failures"] {
  color: var(--paper) !important; background: #F97316; border-color: #F97316;
}
.jump-nav__link[data-dim="worst-offenders"],
.jump-nav__link[data-dim="bad-actors"] {
  color: var(--paper); background: #8B1818; border-color: #8B1818;
}
.jump-nav__link[data-dim="most-improved"],
.jump-nav__link[data-dim="clean-plates"] {
  color: var(--paper); background: #16a34a; border-color: #16a34a;
}
.jump-nav__link[data-dim="lost-licenses"] {
  color: var(--paper); background: #1A3D6D; border-color: #1A3D6D;
}
.jump-nav__link[data-dim="openings"],
.jump-nav__link[data-dim="new-licenses"] {
  color: var(--paper); background: #06b6d4; border-color: #06b6d4;
}
.jump-nav__link[data-dim="ghost-licenses"] {
  color: var(--paper); background: #64748b; border-color: #64748b;
}
.jump-nav__link[data-dim="chain-activity"] {
  color: var(--paper); background: #9333ea; border-color: #9333ea;
}
.jump-nav__link[data-dim="worsts"] {
  color: var(--paper); background: #ff5722; border-color: #ff5722;
}
.jump-nav__link[data-dim="delinquent"],
.jump-nav__link[data-dim="distressed"] {
  color: var(--paper); background: #EA580C; border-color: #EA580C;
}
.jump-nav__link[data-dim="permanent-closures"],
.jump-nav__link[data-dim="closures"] {
  color: var(--paper); background: #991B1B; border-color: #991B1B;
}
/* Operator 2026-05-04: removed duplicate hover rule (was
   `filter: brightness(1.12)`). Pill hover lives once at line ~2783
   with `box-shadow: 0 0 0 2px var(--ink)` — filters were causing
   pills to "disappear" on hover in some stacking contexts. */
.jump-nav__link[data-dim][aria-current="location"] {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}
.jump-nav__link[data-dim] .jump-nav__count {
  color: inherit;
  opacity: 0.85;
}

/* ---- Stat band — mobile-safe stacked list -------------------------
   Operator 2026-05-02 (eve): the pill-row layout corrupts on mobile
   because each pill has its own width + the row-wrap happens mid-tile
   when label + 5-digit number can't fit a 50%-screen track. On
   ≤640px screens drop the pill chrome entirely and render as a clean
   2-column key/value list — body font, tabular numerals, no overflow
   risk. Desktop keeps the pill-row look unchanged.
*/
@media (max-width: 640px) {
  .stat-band {
    display: block !important;
    padding: var(--s-2) var(--s-3) !important;
    background: var(--paper-2) !important;
    border: 1px solid var(--rule) !important;
    border-radius: 6px !important;
  }
  .stat-band__heading,
  .stat-band__metro { display: block !important; }
  .stat-band__heading {
    font-family: var(--font-body);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-muted);
    text-align: center;
    margin: 0 0 var(--s-2);
  }
  .stat-grid,
  .stat-band > .stat-tile,
  .stat-band {
    /* Be explicit: any descendant tile becomes a row regardless of
       which intermediate wrapper class the renderer ships. */
  }
  .stat-grid {
    display: flex !important;
    flex-direction: column !important;
    gap: 0 !important;
  }
  .stat-tile {
    display: flex !important;
    flex-direction: row !important;
    align-items: baseline !important;
    justify-content: space-between !important;
    width: 100% !important;
    min-height: 0 !important;
    height: auto !important;
    padding: 6px var(--s-2) !important;
    border: 0 !important;
    border-bottom: 1px solid var(--rule) !important;
    border-left: 4px solid var(--accent, var(--ink-muted)) !important;
    border-radius: 0 !important;
    background: transparent !important;
    gap: var(--s-2) !important;
  }
  .stat-tile:last-child {
    border-bottom: 0 !important;
  }
  .stat-tile__label {
    font-family: var(--font-body) !important;
    font-size: 0.78rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.04em !important;
    color: var(--ink) !important;
    line-height: 1.3 !important;
    flex: 1 1 auto !important;
    min-width: 0 !important;
    text-align: left !important;
  }
  .stat-tile__value {
    font-family: var(--font-body) !important;
    font-variation-settings: normal !important;
    font-weight: 800 !important;
    font-size: 0.95rem !important;
    line-height: 1.2 !important;
    color: var(--ink) !important;
    font-variant-numeric: tabular-nums !important;
    white-space: nowrap !important;
    flex: 0 0 auto !important;
  }
  /* Per-dim accent left border on mobile (matches the bucket palette). */
  .stat-tile--under-emergency-order { border-left-color: #dc2626 !important; }
  .stat-tile--recent-failures       { border-left-color: #F97316 !important; }
  .stat-tile--worst-offenders,
  .stat-tile--bad-actors            { border-left-color: #8B1818 !important; }
  .stat-tile--most-improved,
  .stat-tile--clean-plates          { border-left-color: #16a34a !important; }
  .stat-tile--openings,
  .stat-tile--new-licenses          { border-left-color: #06b6d4 !important; }
  .stat-tile--lost-licenses         { border-left-color: #1A3D6D !important; }
  .stat-tile--permanent-closures    { border-left-color: #991B1B !important; }
  .stat-tile--delinquent            { border-left-color: #EA580C !important; }
}

/* ---- Font-size selector (upper-left, dynamic) -----------------------
   Three sizes scale every text-* CSS variable. Selector is fixed-pos
   upper-left so it's always reachable without disrupting masthead.
   Stored in localStorage as riskyeats:fz.
*/
.fz-selector {
  position: fixed;
  top: var(--s-2);
  right: var(--s-2);
  z-index: 200;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background: var(--paper);
  border: 1px solid var(--ink);
  border-radius: 999px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
  font-family: var(--font-body);
}
.fz-selector__label {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-right: 4px;
}
.fz-selector__btn {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 2px 8px;
  font-family: var(--font-body);
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  min-width: 28px;
  line-height: 1;
}
.fz-selector__btn:hover {
  background: var(--paper-2);
  border-color: var(--rule);
}
.fz-selector__btn:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.fz-selector__btn--active {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.fz-selector__btn[data-fz="sm"] { font-size: 0.78rem; }
.fz-selector__btn[data-fz="md"] { font-size: 0.92rem; }
.fz-selector__btn[data-fz="lg"] { font-size: 1.05rem; }

@media (max-width: 540px) {
  .fz-selector {
    /* Tighter on phones; the label hides to save room. */
    padding: 2px 6px;
  }
  .fz-selector__label { display: none; }
}

/* Three text-size scales — applied at the :root level so every
   var(--text-*) downstream rescales proportionally. The default
   (.fz--md) matches the prior baseline so existing pages render
   identically until the user picks small or large. */
html.fz--sm {
  --text-xs:   0.7rem;
  --text-sm:   0.8rem;
  --text-base: 0.875rem;
  --text-md:   1.05rem;
  --text-lg:   1.3rem;
  --text-xl:   1.6rem;
}
html.fz--md {
  /* default — keep current values */
}
html.fz--lg {
  --text-xs:   1.05rem;
  --text-sm:   1.2rem;
  --text-base: 1.45rem;
  --text-md:   1.8rem;
  --text-lg:   2.25rem;
  --text-xl:   2.85rem;
}
html.fz--lg body { line-height: 1.7; }
html.fz--lg .post-headline { font-size: clamp(1.6rem, 2vw + 0.8rem, 2.2rem) !important; }

/* ---- AAA contrast sweep — colored dim elements (eve 2026-05-02) -----
   Force readable foreground on every text element that lives inside a
   colored dimension surface, regardless of cascade specificity.
   Operator complaint: "you fixed contrast on pills but not on the
   colored dimension bars next to the expanders". This block uses
   !important to win over earlier rules and applies to:
     - summary.dimension__head colored bar (RED/ORANGE/MAROON/GREEN/NAVY/CHARCOAL)
     - .briefing-section--* tinted background panels
     - .dimension__narrative (per-dim narrative box)
     - all child text + svg + the count/cue/chevron
*/
.dimension-block > .dimension > summary.dimension__head,
.dimension-block > .dimension > summary.dimension__head h1,
.dimension-block > .dimension > summary.dimension__head h2,
.dimension-block > .dimension > summary.dimension__head h3,
.dimension-block > .dimension > summary.dimension__head h4,
.dimension-block > .dimension > summary.dimension__head p,
.dimension-block > .dimension > summary.dimension__head span,
.dimension-block > .dimension > summary.dimension__head a,
.dimension-block > .dimension > summary.dimension__head svg {
  color: var(--paper) !important;
  fill: currentColor !important;
}
.dimension-block > .dimension > summary.dimension__head .dimension__count,
.dimension-block > .dimension > summary.dimension__head .dimension__expand,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-cue,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-cue--open,
.dimension-block > .dimension > summary.dimension__head .dimension__expand-cue--closed {
  color: var(--paper) !important;
  opacity: 1 !important;
}
.dimension-block > .dimension > summary.dimension__head .dimension__expand-chevron {
  stroke: var(--paper) !important;
  color: var(--paper) !important;
}

/* Dim narrative panel — tinted background with colored border. Force
   the prose + blog-link to use --ink (dark) for AAA on the tints. */
.dimension-block .dimension__narrative {
  color: var(--ink);
}
.dimension-block .dimension__narrative-prose {
  color: var(--ink) !important;
  font-size: var(--text-base);
  line-height: 1.65;
}
.dimension-block .dimension__narrative-blog-link {
  color: var(--navy) !important;
  font-weight: 700;
}
.dimension-block .dimension__narrative-blog-link:hover {
  color: var(--ink) !important;
}

/* briefing-section colored panels — kicker color tuned for AAA on
   the matching tinted background. Existing color variables are AAA
   on white, but the kicker sits on var(--*-bg) (very light tint of
   same hue) which has slightly lower contrast. Use the deeper
   variant for kicker text. */
/* Operator 2026-05-04 canonical palette — these used to override the
   earlier per-dim rules with old `var(--*)` values; now they use the
   exact same hex codes as the pills + dim heads + blog so pills,
   dim band, kickers, mentions, narrative-icon all read as one color
   per dim. */
.briefing-section--under-emergency-order .briefing-section__kicker { color: #dc2626 !important; }
.briefing-section--recent-failures .briefing-section__kicker        { color: #F97316 !important; }
.briefing-section--worst-offenders .briefing-section__kicker,
.briefing-section--bad-actors .briefing-section__kicker             { color: #8B1818 !important; }
.briefing-section--worsts .briefing-section__kicker                 { color: #ff5722 !important; }
.briefing-section--permanent-closures .briefing-section__kicker,
.briefing-section--closures .briefing-section__kicker               { color: #991B1B !important; }
.briefing-section--delinquent .briefing-section__kicker,
.briefing-section--distressed .briefing-section__kicker             { color: #EA580C !important; }
.briefing-section--most-improved .briefing-section__kicker,
.briefing-section--clean-plates .briefing-section__kicker           { color: #16a34a !important; }
.briefing-section--openings .briefing-section__kicker,
.briefing-section--new-licenses .briefing-section__kicker           { color: #06b6d4 !important; }
.briefing-section--ghost-licenses .briefing-section__kicker         { color: #64748b !important; }
.briefing-section--lost-licenses .briefing-section__kicker          { color: #1A3D6D !important; }
.briefing-section--chain-activity .briefing-section__kicker         { color: #9333ea !important; }

/* ---- Briefing mentions — section-color consistency -------------------
   Operator 2026-05-02: alternating mention colors must have a clear
   purpose. Each mention's color now matches the SECTION it appears
   in (not the mention's own kind), so within a single dim-narrative
   paragraph all mentions share one color = "this is where these
   restaurants live on the page". Confirmation tier still shows via
   icon (Google G / Foursquare / Facebook) and underline weight.
*/
/* Operator 2026-05-04 canonical palette for briefing-mentions —
   per-dim hex codes from config/dimensions.json. */
.briefing-section--under-emergency-order .briefing-mention,
.briefing-section--under-emergency-order .briefing-mention[data-kind] {
  color: #dc2626 !important;
  border-bottom-color: #dc2626 !important;
}
.briefing-section--recent-failures .briefing-mention,
.briefing-section--recent-failures .briefing-mention[data-kind] {
  color: #F97316 !important;
  border-bottom-color: #F97316 !important;
}
.briefing-section--worst-offenders .briefing-mention,
.briefing-section--worst-offenders .briefing-mention[data-kind],
.briefing-section--bad-actors .briefing-mention,
.briefing-section--bad-actors .briefing-mention[data-kind] {
  color: #8B1818 !important;
  border-bottom-color: #8B1818 !important;
}
.briefing-section--worsts .briefing-mention,
.briefing-section--worsts .briefing-mention[data-kind] {
  color: #ff5722 !important;
  border-bottom-color: #ff5722 !important;
}
.briefing-section--permanent-closures .briefing-mention,
.briefing-section--permanent-closures .briefing-mention[data-kind],
.briefing-section--closures .briefing-mention,
.briefing-section--closures .briefing-mention[data-kind] {
  color: #991B1B !important;
  border-bottom-color: #991B1B !important;
}
.briefing-section--delinquent .briefing-mention,
.briefing-section--delinquent .briefing-mention[data-kind],
.briefing-section--distressed .briefing-mention,
.briefing-section--distressed .briefing-mention[data-kind] {
  color: #EA580C !important;
  border-bottom-color: #EA580C !important;
}
.briefing-section--most-improved .briefing-mention,
.briefing-section--most-improved .briefing-mention[data-kind],
.briefing-section--clean-plates .briefing-mention,
.briefing-section--clean-plates .briefing-mention[data-kind] {
  color: #16a34a !important;
  border-bottom-color: #16a34a !important;
}
.briefing-section--openings .briefing-mention,
.briefing-section--openings .briefing-mention[data-kind],
.briefing-section--new-licenses .briefing-mention,
.briefing-section--new-licenses .briefing-mention[data-kind] {
  color: #06b6d4 !important;
  border-bottom-color: #06b6d4 !important;
}
.briefing-section--ghost-licenses .briefing-mention,
.briefing-section--ghost-licenses .briefing-mention[data-kind] {
  color: #64748b !important;
  border-bottom-color: #64748b !important;
}
.briefing-section--lost-licenses .briefing-mention,
.briefing-section--lost-licenses .briefing-mention[data-kind] {
  color: #1A3D6D !important;
  border-bottom-color: #1A3D6D !important;
}
.briefing-section--chain-activity .briefing-mention,
.briefing-section--chain-activity .briefing-mention[data-kind] {
  color: #9333ea !important;
  border-bottom-color: #9333ea !important;
}

/* The same applies to the dimension narrative panels at the top of
   each dim block (briefing prose lives in two places: the per-section
   briefing-section--* boxes AND the dim narratives directly under
   each colored summary bar). Same purpose: color = which section. */
/* Operator 2026-05-04 canonical palette for narrative-block mentions */
.dimension-block[data-dim="under-emergency-order"] .briefing-mention {
  color: #dc2626 !important; border-bottom-color: #dc2626 !important;
}
.dimension-block[data-dim="recent-failures"] .briefing-mention {
  color: #F97316 !important; border-bottom-color: #F97316 !important;
}
.dimension-block[data-dim="worst-offenders"] .briefing-mention,
.dimension-block[data-dim="bad-actors"] .briefing-mention {
  color: #8B1818 !important; border-bottom-color: #8B1818 !important;
}
.dimension-block[data-dim="worsts"] .briefing-mention {
  color: #ff5722 !important; border-bottom-color: #ff5722 !important;
}
.dimension-block[data-dim="permanent-closures"] .briefing-mention,
.dimension-block[data-dim="closures"] .briefing-mention {
  color: #991B1B !important; border-bottom-color: #991B1B !important;
}
.dimension-block[data-dim="delinquent"] .briefing-mention,
.dimension-block[data-dim="distressed"] .briefing-mention {
  color: #EA580C !important; border-bottom-color: #EA580C !important;
}
.dimension-block[data-dim="most-improved"] .briefing-mention,
.dimension-block[data-dim="clean-plates"] .briefing-mention {
  color: #16a34a !important; border-bottom-color: #16a34a !important;
}
.dimension-block[data-dim="openings"] .briefing-mention,
.dimension-block[data-dim="new-licenses"] .briefing-mention {
  color: #06b6d4 !important; border-bottom-color: #06b6d4 !important;
}
.dimension-block[data-dim="ghost-licenses"] .briefing-mention {
  color: #64748b !important; border-bottom-color: #64748b !important;
}
.dimension-block[data-dim="lost-licenses"] .briefing-mention {
  color: #1A3D6D !important; border-bottom-color: #1A3D6D !important;
}
.dimension-block[data-dim="chain-activity"] .briefing-mention {
  color: #9333ea !important; border-bottom-color: #9333ea !important;
}

/* ---- Briefing-mention single-color enforcement ---------------------
   The wrapMentions output is <a class="briefing-mention"><strong
   class="mention">NAME</strong>...</a>. Both elements have their
   own color rules and end up rendering the strong text in --ink while
   the anchor underline is the section color — visually a TWO-color
   restaurant name. Force the inner strong / mention text to inherit
   the anchor color so each mention reads as ONE consistent color.
*/
.briefing-mention,
.briefing-mention .mention,
.briefing-mention strong,
.briefing-mention strong.mention {
  color: inherit !important;
}
.briefing-mention .briefing-mention__check,
.briefing-mention .briefing-mention__source-icon {
  color: inherit !important;
  fill: currentColor;
}

/* ---- Dimension expander redesign (eve 2026-05-02) ---------------
   The "Show N records" button must read as a clear button on the
   colored bar — undo the white-text inheritance ONLY for this
   specific control, give it paper bg + ink text + crisp border.
   Heading allowed to wrap to 2 lines max on mobile.
*/
.dimension-block > .dimension > summary.dimension__head .dimension__expand {
  background: var(--paper) !important;
  color: var(--ink) !important;
  border: 1px solid var(--paper) !important;
  border-radius: 999px !important;
  padding: 4px 12px !important;
  font-size: var(--text-xs) !important;
  font-weight: 700 !important;
  letter-spacing: 0.02em !important;
  flex: 0 0 auto;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(0,0,0,0.18);
}
.dimension-block > .dimension > summary.dimension__head:hover .dimension__expand {
  background: var(--paper-2) !important;
  border-color: var(--paper-2) !important;
}
.dimension-block > .dimension > summary.dimension__head .dimension__expand .dimension__expand-cue,
.dimension-block > .dimension > summary.dimension__head .dimension__expand .dimension__expand-cue--open,
.dimension-block > .dimension > summary.dimension__head .dimension__expand .dimension__expand-cue--closed {
  color: var(--ink) !important;
  opacity: 1 !important;
}
.dimension-block > .dimension > summary.dimension__head .dimension__expand .dimension__expand-chevron {
  stroke: var(--ink) !important;
  color: var(--ink) !important;
}

/* Tighter bar overall. */
.dimension-block > .dimension > summary.dimension__head {
  padding: 8px 12px;
  margin: 0 0 var(--s-3);
  gap: var(--s-2);
  align-items: center;
}
.dimension-block > .dimension > summary.dimension__head .dimension__heading {
  font-size: var(--text-base);
  line-height: 1.25;
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
}

/* Mobile: cap heading to 2 lines so verbose subtitles don't bloat
   the bar (e.g. "Near miss — high violations, NOT closed"). */
@media (max-width: 640px) {
  .dimension-block > .dimension > summary.dimension__head {
    min-height: 44px;
    padding: 6px 10px;
    align-items: center;
  }
  .dimension-block > .dimension > summary.dimension__head .dimension__heading {
    font-size: var(--text-sm);
    line-height: 1.2;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .dimension-block > .dimension > summary.dimension__head .dimension__expand {
    min-height: 32px;
    padding: 5px 10px !important;
    font-size: 0.72rem !important;
  }
}

/* Final UX/a11y pass: all phone-reachable controls meet the 44px
   target floor, while search empty-state copy has a visible panel. */
@supports (height: 100dvh) {
  body { min-height: 100dvh; }
}

.metro-search__empty-panel[hidden] { display: none !important; }

@media (max-width: 640px), (pointer: coarse) {
  /* Tap-target floor — min-height only. min-width on the jump-nav
     pills was making them render as 44x44 circles (with their 999px
     border-radius). Pills already grow horizontally to fit their
     label; let them. */
  .fz-selector__btn,
  .riskyeats-toolbar .a2a_kit > a,
  .riskyeats-toolbar__follow .follow-link,
  .footer-legal > summary {
    min-width: 44px;
    min-height: 44px;
  }
  .metro-chip,
  .jump-nav__link,
  .card__link,
  .sunbiz-link,
  .more-cards__btn {
    min-height: 44px;
  }
  .fz-selector__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: 10px;
  }
  .card__actions {
    gap: 8px;
  }
  .card__link,
  .sunbiz-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .contrib-banner:hover,
  .card--search-hit,
  .provider-logo:hover {
    transform: none !important;
  }
}

/* ---- Card whitespace tightening (eve 2026-05-02) ---------------------
   Operator: 'fix card whitespace'. Cards were s-3 padding + s-2 row-gap
   = ~28px vertical breathing room around each child. Drop to s-2 / s-1
   so the same content reads tighter. Touched: .card padding+gap,
   .card__head gap, .card__stats gap, .card__violations margin,
   .card__actions margin, .card__location margin.
*/
.card {
  padding: var(--s-2) var(--s-3) !important;
  row-gap: var(--s-1) !important;
  column-gap: var(--s-2) !important;
}
.card__head {
  gap: 1px !important;
  margin: 0 !important;
}
.card__name {
  margin: 0 !important;
  line-height: 1.2 !important;
}
.card__location {
  margin: 0 !important;
  line-height: 1.3 !important;
}
.card__violations,
.card__violations-row {
  margin: 2px 0 !important;
}
.card__stats {
  margin: 0 !important;
  gap: var(--s-2) !important;
  padding: 0 !important;
}
.card__stat {
  margin: 0 !important;
  padding: 0 !important;
}
.card__stat dt {
  margin: 0 !important;
  line-height: 1.1 !important;
}
.card__stat dd {
  margin: 0 !important;
  line-height: 1.1 !important;
}
.card__actions {
  margin: var(--s-1) 0 0 !important;
  padding: 0 !important;
  gap: var(--s-2) !important;
}
.card__counts,
.card__disposition {
  margin: 0 !important;
  line-height: 1.3 !important;
}
.card__meta {
  gap: var(--s-1) !important;
  margin: 0 !important;
}
@media (max-width: 540px) {
  .card {
    padding: var(--s-2) !important;
    row-gap: 4px !important;
  }
}

/* ---- Pill height clamp — masthead can't stretch beyond pill-h --------
   Codex's a11y pass introduced unexpected vertical stretching on the
   four masthead pills (homepage screenshot showed them as 300px-tall
   ovals on widescreen). Cap height at 44px max so they always read
   as compact pill rows. */
.metro-picker__select-wrap,
.metro-picker__search-wrap .metro-search,
.metro-picker__blog-cta,
.metro-picker__signup-form {
  max-height: 44px !important;
  height: var(--pill-h, 38px) !important;
  align-items: center !important;
}

/* (Old single-row scoreboard removed; replaced with 2x5 modular grid below.) */

/* ---- Stat-band — GRAEAE 2x5 modular grid (eve 2026-05-03) -------
   Print-newspaper aesthetic: consistent card heights, bold uppercase
   labels above subdued numeric values, 6px colored left border per
   bucket, subtle tinted backgrounds. 9 stats in 2 rows × 5 cols
   (one slot for the metro heading) on wide desktop; 3 cols on
   tablet; stacked list on mobile.
*/

/* Tablet — 3-col grid */
@media (min-width: 641px) and (max-width: 1023px) {
  .stat-band {
    display: block !important;
    padding: var(--s-3) var(--s-4) !important;
    background: var(--paper-2) !important;
    border: 1px solid var(--rule) !important;
    border-radius: 6px !important;
    max-width: var(--measure-grid) !important;
    margin: 0 auto !important;
    text-align: center !important;
  }
  .stat-band .stat-grid {
    display: grid !important;
    grid-template-columns: repeat(3, 1fr) !important;
    gap: var(--s-2) !important;
    margin: 0 auto !important;
  }
  .stat-band__heading,
  .stat-band__metro { display: block !important; grid-column: 1 / -1; }
  .stat-band__heading {
    font-size: 0.78rem;
    font-family: var(--font-body);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--ink-muted);
    text-align: center;
    margin: 0 0 var(--s-2);
  }
  .stat-band__metro {
    color: var(--red-deep);
    font-weight: 700;
  }
}

/* Wide desktop — 2x5 modular grid (operator + GRAEAE 2026-05-03) */
@media (min-width: 1024px) {
  .stat-band {
    display: block !important;
    padding: var(--s-3) var(--s-4) !important;
    background: var(--paper-2) !important;
    border: 1px solid var(--rule) !important;
    border-radius: 6px !important;
    max-width: var(--measure-grid) !important;
    margin: 0 auto !important;
    text-align: center !important;
  }
  .stat-band .stat-grid {
    display: grid !important;
    grid-template-columns: repeat(5, 1fr) !important;
    grid-auto-rows: minmax(64px, auto) !important;
    gap: var(--s-2) !important;
    align-items: stretch !important;
    margin: 0 auto !important;
  }
  .stat-band__heading {
    display: block !important;
    text-align: center;
    font-family: var(--font-body);
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--ink-muted);
    text-align: center;
    margin: 0 0 var(--s-2);
  }
  .stat-band__metro {
    display: inline !important;
    color: var(--red-deep);
    font-weight: 800;
  }
}

/* Stat tile shared geometry (tablet + desktop) */
@media (min-width: 641px) {
  .stat-tile {
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
    align-items: flex-start !important;
    gap: 4px !important;
    height: auto !important;
    min-height: 64px !important;
    padding: 8px 10px 8px 14px !important;
    border: 1px solid var(--rule) !important;
    border-left: 6px solid var(--accent, var(--ink-muted)) !important;
    border-radius: 4px !important;
    background: var(--paper) !important;
    margin: 0 !important;
  }
  .stat-tile__label {
    font-family: var(--font-body) !important;
    font-size: 0.72rem !important;
    font-weight: 700 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.06em !important;
    color: var(--ink-muted) !important;
    line-height: 1.2 !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    max-width: 100%;
  }
  .stat-tile__value {
    font-family: var(--font-display) !important;
    font-variation-settings: "opsz" 48 !important;
    font-size: 1.6rem !important;
    font-weight: 700 !important;
    line-height: 1.05 !important;
    color: var(--ink) !important;
    font-variant-numeric: tabular-nums !important;
  }
  /* Bucket palette per stat */
  .stat-tile--under-emergency-order {
    border-left-color: #dc2626 !important;
    background: rgba(161, 21, 21, 0.04) !important;
  }
  .stat-tile--recent-failures {
    border-left-color: #F97316 !important;
    background: rgba(154, 52, 18, 0.05) !important;
  }
  .stat-tile--worst-offenders,
  .stat-tile--bad-actors {
    border-left-color: #8B1818 !important;
    background: rgba(107, 15, 15, 0.04) !important;
  }
  .stat-tile--clean-plates,
  .stat-tile--most-improved {
    border-left-color: #16a34a !important;
    background: rgba(31, 93, 45, 0.05) !important;
  }
  .stat-tile--openings,
  .stat-tile--new-licenses {
    border-left-color: #06b6d4 !important;
    background: rgba(6, 182, 212, 0.05) !important;
  }
  .stat-tile--lost-licenses {
    border-left-color: #1A3D6D !important;
    background: rgba(26, 61, 109, 0.05) !important;
  }
  .stat-tile--permanent-closures {
    border-left-color: #991B1B !important;
    background: rgba(153, 27, 27, 0.04) !important;
  }
  .stat-tile--delinquent {
    border-left-color: #EA580C !important;
    background: rgba(234, 88, 12, 0.04) !important;
  }
}

/* ---- Today on the Blog feature (homepage) ----------------------------
   Prominent hero strip below stat-band, above briefing prose.
   Operator 2026-05-03: blog needed to feel more important on main page.
*/
.todays-blog {
  max-width: var(--measure-grid);
  margin: var(--s-5) auto var(--s-5);
  padding: var(--s-4);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 8px;
  border-top: 6px solid var(--red);
}
.todays-blog__head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-3);
  flex-wrap: wrap;
}
.todays-blog__avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 3px solid var(--paper);
  box-shadow: 0 0 0 1px var(--rule);
  object-fit: cover;
  object-position: center top;
  flex-shrink: 0;
}
.todays-blog__head-text {
  flex: 1 1 200px;
  min-width: 0;
}
.todays-blog__kicker {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin: 0 0 var(--s-1);
}
.todays-blog__title {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 48;
  font-weight: 700;
  font-size: var(--text-md);
  line-height: 1.2;
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}
.todays-blog__thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s-3);
  margin: var(--s-3) 0;
}
.todays-blog__thumb {
  display: block;
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  border: 1px solid var(--rule);
  background: var(--paper-3, #ECECEC);
  transition: transform 120ms ease;
}
.todays-blog__thumb:hover {
  transform: translateY(-2px);
}
.todays-blog__thumb img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
.todays-blog__thumb-label {
  display: block;
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  color: #FFFFFF;
  background: linear-gradient(180deg, transparent, rgba(0,0,0,0.65));
  text-shadow: 0 1px 4px rgba(0,0,0,0.7);
}
/* Mobile single-hero — hidden on desktop / iPad, shown only on
   narrow viewports (operator 2026-05-03: mobile = too much scroll
   with 3 thumbnails, collapse to 1 selected-metro hero). */
.todays-blog__hero--mobile {
  display: none;
}
.todays-blog__hero {
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  border: 1px solid var(--rule);
  background: var(--paper-3, #ECECEC);
  transition: transform 120ms ease;
}
.todays-blog__hero:hover {
  transform: translateY(-2px);
}
.todays-blog__hero img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
.todays-blog__hero-label {
  display: block;
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  color: #FFFFFF;
  background: linear-gradient(180deg, transparent, rgba(0,0,0,0.65));
  text-shadow: 0 1px 4px rgba(0,0,0,0.7);
}
.todays-blog__cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  align-items: center;
  justify-content: space-between;
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--rule);
}
.todays-blog__cta {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--paper);
  background: var(--red);
  border: 1px solid var(--red);
  border-radius: 999px;
  padding: 8px 18px;
  text-decoration: none;
}
.todays-blog__cta:hover {
  background: var(--red-deep);
  border-color: var(--red-deep);
}
.todays-blog__contrib {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--navy);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.todays-blog__contrib:hover {
  color: var(--ink);
}
@media (max-width: 768px) {
  /* Hide the 3-thumbnail grid on mobile, show the single selected-
     metro hero in its place. Operator 2026-05-03: mobile scroll budget
     does not allow 3 hero images stacked. */
  .todays-blog__thumbs {
    display: none;
  }
  .todays-blog__hero--mobile {
    display: block;
    margin: var(--s-3) 0;
  }
  .todays-blog {
    padding: var(--s-3);
    margin: var(--s-3) auto;
  }
  .todays-blog__title {
    font-size: var(--text-base);
  }
  .todays-blog__hero-label,
  .todays-blog__thumb-label {
    font-size: var(--text-xs);
  }
  .todays-blog__cta-row {
    flex-direction: column;
    align-items: stretch;
  }
  .todays-blog__cta {
    text-align: center;
  }
}

/* ---- Find-a-Resto: explicit clear + match chips (2026-05-03) -------
   Per Stuart Skolnik beta feedback: HTML5 input[type=search] X is
   missing on iOS/older mobiles, and a 1-match result was invisible
   without auto-scroll. Add explicit Clear button + a chip list of
   matches that the reader can click without scrolling.
*/
.metro-search__clear {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 64px;
  height: 32px;
  margin-left: 0;
  padding: 0 12px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
}
.metro-search__clear:hover,
.metro-search__clear:focus-visible {
  background: var(--paper-2);
  outline: none;
  border-color: var(--ink);
}
.metro-search__matches {
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1);
  margin-top: var(--s-1);
}
.metro-search__matches[hidden] {
  display: none;
}
.metro-search__match-chip {
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.36rem 0.72rem;
  background: var(--paper-2);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 999px;
  cursor: pointer;
  text-align: left;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background 120ms ease, border-color 120ms ease;
}
.metro-search__match-chip:hover,
.metro-search__match-chip:focus-visible {
  background: var(--red);
  color: var(--paper);
  border-color: var(--red);
  outline: none;
}
@media (max-width: 640px) {
  .metro-search__match-chip {
    font-size: 0.78rem;
    padding: 0.32rem 0.64rem;
  }
}

/* ---- More-cards row: 'Show next 10' + 'Show all' (2026-05-03) -----
   Per Stuart Skolnik beta feedback: chunked 'Show next 10' is
   annoying when reading large stat categories. Default stays chunked
   to protect mobile DOM, but 'Show all' is the opt-in escape hatch.
*/
.more-cards__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-2);
  align-items: center;
}
.more-cards__btn--all {
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--rule);
}
.more-cards__btn--all:hover,
.more-cards__btn--all:focus-visible {
  background: var(--paper-2);
  border-color: var(--ink);
  color: var(--ink);
  outline: none;
}
@media (max-width: 640px) {
  .more-cards__row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--s-1);
  }
  .more-cards__row .more-cards__btn {
    width: 100%;
    text-align: center;
  }
}

/* ---- Device tier transparency (2026-05-03) ----------------------
   Per Stuart Skolnik feedback + operator: when the user hits the
   'Show next 10' restriction, surface WHY — what tier did we detect.
   Tiny calm pill near the search; per-row caption alongside the
   Show-next/Show-all buttons.
*/
.device-tier-badge {
  flex: 1 0 100%;
  display: inline-flex;
  align-items: center;
  gap: 0.32rem;
  margin-top: var(--s-1);
  padding: 0.18rem 0.55rem;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-muted, #6B6B6B);
  background: var(--paper-2, #F4F1E8);
  border: 1px solid var(--rule);
  border-radius: 999px;
  width: fit-content;
  cursor: help;
  user-select: none;
}
.device-tier-badge::before {
  content: "Device:";
  margin-right: 0.18rem;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.66rem;
  letter-spacing: 0.05em;
  color: var(--ink);
}
.device-tier-badge--ram-2g {
  border-color: rgba(180, 60, 40, 0.45);
  background: rgba(255, 200, 100, 0.22);
}
.device-tier-badge--ram-4g {
  border-color: rgba(150, 100, 40, 0.40);
  background: rgba(255, 220, 130, 0.18);
}
.device-tier-badge--ram-6g {
  border-color: rgba(0, 0, 0, 0.10);
  background: rgba(220, 220, 220, 0.20);
}
.device-tier-badge--ram-8g {
  border-color: rgba(43, 132, 65, 0.45);
  background: rgba(43, 132, 65, 0.10);
}
.device-tier-badge--desktop {
  border-color: rgba(43, 87, 132, 0.45);
  background: rgba(43, 87, 132, 0.10);
}
/* Legacy tier names retained for any cached HTML still in flight. */
.device-tier-badge--low,
.device-tier-badge--mid,
.device-tier-badge--high {
  border-color: rgba(0, 0, 0, 0.10);
  background: rgba(220, 220, 220, 0.20);
}
.more-cards__caption {
  font-family: var(--font-body);
  font-size: 0.72rem;
  color: var(--ink-muted, #6B6B6B);
  align-self: center;
  margin-left: var(--s-1);
}
@media (max-width: 640px) {
  .device-tier-badge {
    font-size: 0.68rem;
    padding: 0.16rem 0.5rem;
  }
  .more-cards__caption {
    flex: 1 0 100%;
    text-align: center;
    margin-left: 0;
    margin-top: 0.32rem;
  }
}

/* ---- Find-a-Resto status text wrap (Laura @ Amazon, 2026-05-03) ---
   Long status strings ('Showing N matches. First X below — click to
   jump...') were clipping mid-sentence on narrower viewports. Force
   wrap behaviour so the entire status reads inside its box.
*/
.metro-search__status,
.metro-search__matches {
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.metro-search__status {
  line-height: 1.45;
  padding: 0.2rem 0.1rem;
}

/* ---- Masthead auto-hide on scroll (2026-05-03) ------------------
   Operator: 'header eats a ton of space; during scroll, we auto
   hide.' Classic news-app pattern. JS in index.html toggles the
   --hidden class based on scroll direction. Within first 100px
   we keep it pinned for orientation.
*/
.metro-picker {
  transition: transform 220ms ease;
  will-change: transform;
}
.metro-picker--hidden {
  transform: translateY(-105%);
}
@media (prefers-reduced-motion: reduce) {
  .metro-picker { transition: none; }
}

/* ---- Condensed footer (2026-05-03) ----------------------------
   Operator: 'too big'. Data sources moved to disclosure.html;
   footer is now a single line.
*/
.footer-compact {
  font-family: var(--font-body);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--ink-muted, #6B6B6B);
  text-align: center;
  margin: 0;
  padding: var(--s-2) var(--s-3);
}
.footer-compact a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  margin: 0 0.1rem;
}
.footer-compact a:hover { color: var(--red); }
.footer-meta {
  font-size: 0.75rem;
  opacity: 0.75;
}

/* ---- Card overflow containment + violation wrap (2026-05-03) ----
   Stuart Skolnik PC screenshot: clicking 'All violations' on a card
   in a 4-column desktop layout caused violation snippets to bleed
   across into the next card column. Plus the CHRONIC badge in the
   top-right was getting clipped to 'CHRO' on narrow cards.
*/
.card {
  overflow: hidden; /* contain children to card boundary */
  min-width: 0;
}
.card__details,
.card__details[open] {
  max-width: 100%;
  overflow: hidden;
}
.violations {
  max-width: 100%;
  overflow: hidden;
}
.violation {
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
  min-width: 0;
}
.violation__label,
.violation__snippet {
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
  min-width: 0;
  white-space: normal;
}
.violation__snippet {
  hyphens: auto;
}
.violation__code {
  flex-shrink: 0;
}
/* Card kind-badge — abbreviate on narrow cards rather than truncate.
   The ::after replacement is dropped via media query so wide layouts
   show the full label. */
.card__kind-badge {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
@media (max-width: 1023px) {
  /* Mobile / 1-col stacks have plenty of horizontal room — full label. */
  .card__kind-badge { max-width: none; }
}
@media (min-width: 1024px) {
  /* On the 3-col / 4-col desktop card stack, force the badge to a
     compact size so it never truncates to a fragment. */
  .card-stack .card__kind-badge {
    font-size: 10px;
    padding: 1px 6px;
    letter-spacing: 0.02em;
  }
}

/* ---- Card stack alignment fix (2026-05-03 PC screenshot) ----
   Stuart's PC view: when one card has 'All violations' expanded the
   sibling cards stretched to equal height leaving huge whitespace.
   Align children to the top instead.

   Also loosen the previous overflow-wrap: anywhere which was breaking
   mid-word ('Single-service / articles' looked broken). break-word
   only splits when a single token won't fit, never inside a normal
   word.
*/
.card-stack {
  align-items: start;
}
.violation,
.violation__label,
.violation__snippet {
  overflow-wrap: break-word;
  word-break: normal;
  hyphens: manual;
}

/* ==== Codex desktop UX recommendations (2026-05-03) ============ */

/* HIGH #2 — search status / matches break out of the fixed-height
   pill on desktop. Render them as positioned children that flow
   below the search pill rather than inside it. */
@media (min-width: 1024px) {
  .metro-picker__search-wrap .metro-search {
    position: relative;
  }
  .metro-search__status,
  .metro-search__matches {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% + 2px);
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.4rem 0.7rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    z-index: 50;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--ink);
  }
  .metro-search__status:empty {
    display: none;
  }
  .metro-search__matches[hidden] {
    display: none;
  }
}

/* HIGH #3 — when 'All violations' (or any card details) is open,
   let it span the full card width so violations don't get squeezed
   into the narrow body column on a 3-col desktop grid. */
.card__details[open] {
  grid-column: 1 / -1;
  margin-top: var(--s-2);
}

/* HIGH #4 — desktop masthead too tall. Move share/follow strip into
   footer (HTML moved separately). On the masthead, hide it. */
@media (min-width: 1024px) {
  .metro-picker__social--top,
  .metro-picker__social {
    display: none !important;
  }
}

/* MED #6 — jump-nav: widen max-width on desktop + single-row
   horizontally scrollable for the narrow-desktop case. */
@media (min-width: 1024px) {
  .jump-nav {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    max-width: min(1400px, 100% - 2 * var(--s-4)) !important;
    scrollbar-width: thin;
  }
}

/* MED #8 — signup status renders below the form pill on desktop,
   matching the search status pattern. */
@media (min-width: 1024px) {
  .metro-picker__signup-form {
    position: relative;
  }
  .metro-picker__signup-status:not(:empty) {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% + 2px);
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.4rem 0.7rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    z-index: 50;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--ink);
  }
}

/* MED #10 — text-size pill (.fz-selector) tightened on desktop so
   it's a smaller cluster, less competing-with-masthead. */
@media (min-width: 1024px) {
  .fz-selector {
    transform: scale(0.85);
    transform-origin: top right;
  }
}

/* LOW #11 — 'Tap' vs 'Click' wording per pointer type. Replaces the
   visible 'Tap' text inside .worst-today__sub on devices with a fine
   pointer (mouse/trackpad). */
@media (pointer: fine) {
  .worst-today__sub .pointer-tap {
    display: none;
  }
  .worst-today__sub .pointer-click {
    display: inline;
  }
}
@media (pointer: coarse), (pointer: none) {
  .worst-today__sub .pointer-click {
    display: none;
  }
  .worst-today__sub .pointer-tap {
    display: inline;
  }
}

/* LOW #12 — footer bumped slightly larger + higher contrast for a
   public-records site that wants its credit + freshness readable. */
.footer-compact {
  font-size: 0.9rem;
  color: var(--ink);
}
.footer-meta {
  font-size: 0.82rem;
  opacity: 0.85;
}
.footer-compact a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---- Persona attribution UI (operator 2026-05-03) ----------------- */
/* Per-dim narrative voice avatar — small portrait of the correspondent
   who voiced THAT paragraph. Important for keys-pair (Florida Keys)
   where Clancy and Gracie alternate by dim; cosmetic but reinforcing
   for single-persona metros. */
.dimension__narrative {
  position: relative;
}
.dimension__narrative-voice {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid var(--ink);
  object-fit: cover;
  /* Operator 2026-05-03: float so prose wraps around the avatar
     instead of stacking with vertical whitespace. Side margins +
     small bottom margin keep clean wrap. */
  float: left;
  margin: 0 10px 4px 0;
  shape-outside: circle(50%);
  background: #fff;
}
.dimension__narrative-body::after {
  content: "";
  display: block;
  clear: both;
}
[data-voice="inspector-clancy"] .dimension__narrative-voice {
  border-color: #0d9488;
}
[data-voice="mama-gracie"] .dimension__narrative-voice {
  border-color: #9d174d;
}

/* Today-on-the-Blog dual-portrait pair (keys-pair correspondents). */
.todays-blog__avatar-pair {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  gap: 8px;
}
.todays-blog__avatar-pair .todays-blog__avatar {
  border: 3px solid var(--ink);
  border-radius: 50%;
  background: #fff;
  width: 64px;
  height: 64px;
  object-fit: cover;
  position: static;  /* override any earlier absolute positioning */
}
@media (max-width: 480px) {
  .todays-blog__avatar-pair .todays-blog__avatar {
    width: 52px;
    height: 52px;
  }
}

/* ---- Delinquent / Expired status badges (operator 2026-05-03) ----
   Cards in the new "delinquent" dim carry a status_class field
   ("delinquent" or "expired"); the badge color signals which
   formal DBPR flag the license has. Amber for grace-period (45),
   red for terminal expiration (46). */
.status-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-right: 6px;
  vertical-align: middle;
}
.status-badge--delinquent {
  background: rgba(217, 119, 6, 0.18);
  color: #B45309;
  border: 1px solid rgba(217, 119, 6, 0.35);
}
.status-badge--expired {
  background: rgba(185, 28, 28, 0.18);
  color: #B91C1C;
  border: 1px solid rgba(185, 28, 28, 0.40);
}

/* ---- UX audit fixes (operator 2026-05-03, GRAEAE + Codex) ---- */
/* Codex measured cue text at 11.5px on mobile — bump to 14px so it's
   discoverable below the persona-prose narrative. Drop the redundant
   chevron at this size: the text "View N cards" + open/close summary
   marker is enough affordance. */
@media (max-width: 768px) {
  .dimension__expand-cue {
    font-size: 14px !important;
    font-weight: 700 !important;
  }
  .dimension__expand-chevron {
    display: none !important;
  }
}
.dimension__expand-cue {
  font-weight: 600;
}

/* ==== Combo-badge matrix + card grid (operator 2026-05-03) ============
   Bad Actors merged dim and Chain Activity dim use pre-rendered combo
   SVGs keyed by signature (e.g. bad-actors-HCR.svg). Cards reference
   ``card.combo_badge_url`` which the template renders as <img>. */
.combo-badge {
  display: inline-block;
  vertical-align: middle;
  height: 42px;
  width: auto;
  max-width: 132px;
}
.combo-badge--block {
  display: block;
  margin: var(--s-2) 0;
}

/* Card-side badge grid (Bad Actors). 3 fixed slots + 1 flex slot for
   sparkline so cards align across the dim regardless of how many
   badges each carries. Empty slots render as nothing — no flow. */
.card-badges {
  display: grid;
  grid-template-columns: var(--badge-w, 92px) 1fr;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-2) 0;
}
.card-badges__pill {
  /* the combo-badge slot */
}
.card-badges__sparkline {
  /* the sparkline slot */
  min-width: 0;
  overflow: hidden;
}
@media (max-width: 480px) {
  .card-badges {
    grid-template-columns: 1fr;
  }
}

/* Chain Activity card group treatment. Brand summary card uses a
   distinct chrome (chain group) to read as cross-cutting. */
.dimension--chain {
  background: var(--paper);
  border-left: 3px solid #9333ea;
  padding-left: var(--s-3);
}
.chain-licensee {
  margin-top: var(--s-3);
  padding-left: var(--s-3);
  border-left: 1px dashed var(--rule);
}
.chain-licensee__head {
  font-weight: 600;
  font-size: 0.95em;
  color: var(--ink);
}
.chain-locations {
  margin: var(--s-2) 0 0 var(--s-4);
  font-size: 0.9em;
  color: var(--ink-muted);
}

/* ==== V3 polish (operator 2026-05-03) =================================
   GRAEAE consult recommendations:
   (1) License-track chrome — wrap the 5 license-event dims (Lapsed,
       Confirmed-closed, Off-the-radar, Owner-changed, New-licenses)
       in a shared --navy left-border frame so the administrative band
       reads as a single editorial group, distinct from the health/
       inspection band.
   (2) Paper tiers 3→2 — drop the middle --paper-2 stripe so the
       homepage doesn't fragment into 3 visual layers. Keep --paper
       (white) as the body and --paper-3 (light gray) only for major
       section heads.
   (3) Combo-badge sizing — clamp combo-badge width inside cards so
       the matrix SVG sits at a readable scale without overflowing.  */

/* (1) license-track chrome */
.dimension-block .dimension--group-license {
  border-left: 3px solid #1A3D6D;
  background: var(--paper);
}
.dimension-block .dimension--group-license .dimension__head {
  border-bottom-color: #1A3D6D;
}

/* Health band gets a complementary subtle red-tinted left rule */
.dimension-block .dimension--group-health {
  border-left: 3px solid var(--rule);
}

/* Chain band — distinct so the cross-cutting dim reads as its own thing */
.dimension-block .dimension--group-chain {
  border-left: 3px solid #9333ea;
  background: var(--paper);
}

/* (2) paper tiers 3→2 — collapse --paper-2 mid-tier to --paper.
       This keeps backwards compat for any explicit --paper-2 reference
       (just makes it identical to --paper) without removing the var. */
:root {
  --paper-2: var(--paper);
}

/* (3) combo-badge sizing in cards */
.card__combo-badge {
  margin: var(--s-2) 0;
}
.card__combo-badge .combo-badge {
  height: 36px;
  width: auto;
  display: block;
}
@media (max-width: 480px) {
  .card__combo-badge .combo-badge {
    height: 32px;
  }
}

/* Worsts lifetime severity sparkline + narrative summary
   (operator 2026-05-04). Tells the reader WHY each card is
   worst-of-worst — the badge shows the combo, the spark shows
   the 11-year arc, the caption names the inflection. */
.worsts-spark {
  margin: var(--s-2) 0 var(--s-3);
  padding: var(--s-1) var(--s-2);
  background: rgba(255, 87, 34, 0.04);   /* faint sunburst tint */
  border-left: 3px solid #ff5722;
  border-radius: 2px;
}
.worsts-spark__svg {
  display: block;
  width: 100%;
  max-width: 264px;
  height: 36px;
  margin: 0 0 4px;
}
.worsts-spark__summary {
  margin: 0;
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
}
.worsts-spark__summary--chronic    { color: #8B1818; }
.worsts-spark__summary--climbing   { color: #dc2626; }
.worsts-spark__summary--collapsing { color: #ff5722; }
.worsts-spark__summary--persistent { color: #991B1B; }
.worsts-spark__caption {
  margin: 2px 0 0;
  font-size: 0.66rem;
  font-style: italic;
  color: var(--ink-muted);
  letter-spacing: 0.02em;
}
/* Operator 2026-05-05: time markers on the lifetime sparkline so readers
   know the timescale. Year ticks under the line + start/end labels. */
.worsts-spark__chart-wrap {
  position: relative;
  width: 100%;
  max-width: 264px;
  margin: 0 0 4px;
}
.worsts-spark__year-axis {
  position: relative;
  width: 100%;
  height: 12px;
  margin-top: 1px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9px;
  font-weight: 700;
  color: var(--ink-muted, #6b7280);
}
.worsts-spark__year-tick {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
  line-height: 1;
}
.worsts-spark__endpoints {
  display: flex;
  justify-content: space-between;
  margin-top: 2px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.66rem;
  font-weight: 800;
  color: var(--ink, #111);
}
.worsts-spark__endpoint--start { text-align: left; }
.worsts-spark__endpoint--end { text-align: right; }

/* ==== Chain-activity card detail (operator 2026-05-03) ============
   Per-licensee block inside chain-activity cards. Each licensee shows
   its location count + summary flags + scrollable list of locations
   with per-location signal pills (corp_dissolved, lapsed, viols, etc.). */

.card__details--licensees {
  margin-top: var(--s-3);
}
.card__details--licensees > summary {
  font-weight: 600;
  cursor: pointer;
}
.chain-licensee {
  margin: var(--s-3) 0 var(--s-2) 0;
  padding: var(--s-2) var(--s-3);
  border-left: 3px solid var(--rule);
  background: var(--paper);
}
.chain-licensee__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: baseline;
  margin-bottom: var(--s-2);
  font-size: 0.95em;
}
.chain-licensee__head strong { color: var(--ink); }
.chain-licensee__count {
  color: var(--ink-muted);
  font-size: 0.85em;
}
.chain-licensee__flags {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.chain-locations {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.chain-locations__row {
  font-size: 0.85em;
  padding: 2px 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}
.chain-loc__name { font-weight: 500; }
.chain-loc__city { color: var(--ink-muted); }
.chain-locations__more {
  font-size: 0.85em;
  color: var(--ink-muted);
  padding: 2px 0;
}

/* Per-location signal flag pills */
.loc-flag {
  display: inline-block;
  font-size: 0.75em;
  padding: 1px 7px;
  border-radius: 3px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}
.loc-flag--red    { background: var(--red-bg); color: var(--red); }
.loc-flag--deep   { background: var(--red-bg); color: var(--red-deep); }
.loc-flag--orange { background: var(--amber-bg); color: var(--orange); }
.loc-flag--green  { background: var(--green-bg); color: var(--green); }
.loc-flag--grey   { background: var(--paper-3); color: var(--ink-muted); }

/* ==== Worsts dim chrome (operator 2026-05-03) =========================
   Cross-dim concentration tier — gets distinct visual treatment so
   readers see at a glance that this is the high-water-mark dim, not
   one of the standard 9. Sunburst-orange left rule on paper. */
.dimension-block .dimension--group-worsts {
  border-left: 4px solid #ff5722;
  background: var(--paper);
  box-shadow: 0 1px 0 var(--rule);
}
.dimension-block .dimension--group-worsts .dimension__head {
  border-bottom: 2px solid #ff5722;
}
.dimension-block .dimension--group-worsts .dimension__heading::before {
  content: "⚠  ";
  color: #ff5722;
  font-weight: 900;
}
.dimension-block .dimension--group-worsts .jump-nav__link[data-group="worsts"],
.jump-nav__link[data-group="worsts"] {
  background: #ff5722;
  color: var(--paper);
  font-weight: 700;
  border: 1px solid #ff5722;
}

/* Worsts card — flag-detail row + tier badge below combo-badge */
.card .worsts-flag-detail {
  font-size: 0.8em;
  color: #ff5722;
  font-weight: 600;
  margin-top: var(--s-1);
  letter-spacing: 0.01em;
}
.card .worsts-tier {
  display: inline-block;
  padding: 2px 8px;
  background: #ff5722;
  color: var(--paper);
  font-size: 0.72em;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 3px;
  margin-right: var(--s-2);
  vertical-align: middle;
}
.card .worsts-tier--worst-3 { background: #ff5722; }
.card .worsts-tier--acute { background: #dc2626; }
.card .worsts-tier--admin-bad { background: #EA580C; }
.card .worsts-tier--gone-quiet { background: #1A3D6D; }
.card .worsts-tier--admin-acute { background: #fbbf24; }

/* ==== Distressed Licenses sub-badges + EOR callback-overdue (operator 2026-05-04) === */

/* Distress sub-badges: shown on the Distressed Licenses cards. Each
   card carries 1-5 of these depending on which signals fired. */
.card .distress-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: var(--s-2);
}
.card .distress-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 0.72em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.card .distress-badge--dbpr_delinquent { background: rgba(234, 88, 12, 0.10); color: #EA580C; border: 1px solid #EA580C; }
.card .distress-badge--dbpr_expired    { background: var(--red-bg); color: var(--red); border: 1px solid var(--red); }
.card .distress-badge--sunbiz_iflal    { background: var(--yellow-bg); color: var(--yellow); border: 1px solid var(--yellow); }
.card .distress-badge--near_expiry     { background: var(--orange) and ; background: var(--amber-bg); color: var(--orange); border: 1px solid var(--orange); }
.card .distress-badge--annual_gap      { background: var(--paper-3); color: var(--ink-muted); border: 1px solid var(--rule); }

/* Unified Closures severity/source badges. */
.card .closure-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: var(--s-2);
}

/* Unified Openings source/confidence badges. */
.card .opening-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: var(--s-2);
}

/* EOR callback-overdue indicator on EOR cards. When DBPR's regulatory
   followup is past 14d (warning) or 30d (severe), surface inline. */
.card .callback-overdue {
  display: inline-block;
  margin-left: var(--s-2);
  padding: 1px 8px;
  border-radius: 3px;
  font-size: 0.78em;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  vertical-align: middle;
}
.card .callback-overdue--warning { background: var(--amber-bg); color: var(--orange); border: 1px solid var(--orange); }
.card .callback-overdue--severe  { background: var(--red-deep); color: var(--paper); border: 1px solid var(--red-deep); }

/* ==== Dimension card name + link text colors (operator 2026-05-04) ====
   Scoped to the dimension wrappers only: restaurant names and in-card link
   CTAs pick up the section color without changing addresses, cities, chips,
   badge labels, or link text-decoration.

   Contrast audit against --paper #FFFFFF:
   - Canonical colors below 4.5:1 use darker same-family text variants here:
     #ff5722 -> #c2410c, #EA580C -> #c2410c, #F97316 -> #c2410c,
     #16a34a -> #15803d, #06b6d4 -> #0e7490.
   - #fbbf24 audits at 1.67:1 on white, but it is a badge background, not a
     restaurant-name or link-CTA text color, so it is intentionally untouched. */

/* under-emergency-order: canonical #dc2626, 4.83:1 on white. */
.dimension-block[data-dim="under-emergency-order"] .card__name,
.dimension-block[data-dim="under-emergency-order"] .card__name a,
.dimension--under-emergency-order .card__name,
.dimension--under-emergency-order .card__name a {
  color: #dc2626;
}
.dimension-block[data-dim="under-emergency-order"] .card__link,
.dimension-block[data-dim="under-emergency-order"] .card__source-badge-link,
.dimension-block[data-dim="under-emergency-order"] .card__verify-link,
.dimension-block[data-dim="under-emergency-order"] .card__fb-link,
.dimension-block[data-dim="under-emergency-order"] .card__news-link,
.dimension-block[data-dim="under-emergency-order"] .sunbiz-link,
.dimension-block[data-dim="under-emergency-order"] .card-link,
.dimension--under-emergency-order .card__link,
.dimension--under-emergency-order .card__source-badge-link,
.dimension--under-emergency-order .card__verify-link,
.dimension--under-emergency-order .card__fb-link,
.dimension--under-emergency-order .card__news-link,
.dimension--under-emergency-order .sunbiz-link,
.dimension--under-emergency-order .card-link {
  color: #dc2626;
}

/* bad-actors: canonical #8B1818, 9.37:1 on white. */
.dimension-block[data-dim="bad-actors"] .card__name,
.dimension-block[data-dim="bad-actors"] .card__name a,
.dimension--bad-actors .card__name,
.dimension--bad-actors .card__name a {
  color: #8B1818;
}
.dimension-block[data-dim="bad-actors"] .card__link,
.dimension-block[data-dim="bad-actors"] .card__source-badge-link,
.dimension-block[data-dim="bad-actors"] .card__verify-link,
.dimension-block[data-dim="bad-actors"] .card__fb-link,
.dimension-block[data-dim="bad-actors"] .card__news-link,
.dimension-block[data-dim="bad-actors"] .sunbiz-link,
.dimension-block[data-dim="bad-actors"] .card-link,
.dimension--bad-actors .card__link,
.dimension--bad-actors .card__source-badge-link,
.dimension--bad-actors .card__verify-link,
.dimension--bad-actors .card__fb-link,
.dimension--bad-actors .card__news-link,
.dimension--bad-actors .sunbiz-link,
.dimension--bad-actors .card-link {
  color: #8B1818;
}

/* worst-offenders: canonical #8B1818, 9.37:1 on white. */
.dimension-block[data-dim="worst-offenders"] .card__name,
.dimension-block[data-dim="worst-offenders"] .card__name a,
.dimension--worst-offenders .card__name,
.dimension--worst-offenders .card__name a {
  color: #8B1818;
}
.dimension-block[data-dim="worst-offenders"] .card__link,
.dimension-block[data-dim="worst-offenders"] .card__source-badge-link,
.dimension-block[data-dim="worst-offenders"] .card__verify-link,
.dimension-block[data-dim="worst-offenders"] .card__fb-link,
.dimension-block[data-dim="worst-offenders"] .card__news-link,
.dimension-block[data-dim="worst-offenders"] .sunbiz-link,
.dimension-block[data-dim="worst-offenders"] .card-link,
.dimension--worst-offenders .card__link,
.dimension--worst-offenders .card__source-badge-link,
.dimension--worst-offenders .card__verify-link,
.dimension--worst-offenders .card__fb-link,
.dimension--worst-offenders .card__news-link,
.dimension--worst-offenders .sunbiz-link,
.dimension--worst-offenders .card-link {
  color: #8B1818;
}

/* worsts: canonical #ff5722 is 3.16:1 on white, so text uses #c2410c. */
.dimension-block[data-dim="worsts"] .card__name,
.dimension-block[data-dim="worsts"] .card__name a,
.dimension--worsts .card__name,
.dimension--worsts .card__name a,
.dimension-block .dimension--group-worsts .card__name,
.dimension-block .dimension--group-worsts .card__name a {
  color: #c2410c;
}
.dimension-block[data-dim="worsts"] .card__link,
.dimension-block[data-dim="worsts"] .card__source-badge-link,
.dimension-block[data-dim="worsts"] .card__verify-link,
.dimension-block[data-dim="worsts"] .card__fb-link,
.dimension-block[data-dim="worsts"] .card__news-link,
.dimension-block[data-dim="worsts"] .sunbiz-link,
.dimension-block[data-dim="worsts"] .card-link,
.dimension--worsts .card__link,
.dimension--worsts .card__source-badge-link,
.dimension--worsts .card__verify-link,
.dimension--worsts .card__fb-link,
.dimension--worsts .card__news-link,
.dimension--worsts .sunbiz-link,
.dimension--worsts .card-link,
.dimension-block .dimension--group-worsts .card__link,
.dimension-block .dimension--group-worsts .card__source-badge-link,
.dimension-block .dimension--group-worsts .card__verify-link,
.dimension-block .dimension--group-worsts .card__fb-link,
.dimension-block .dimension--group-worsts .card__news-link,
.dimension-block .dimension--group-worsts .sunbiz-link,
.dimension-block .dimension--group-worsts .card-link {
  color: #c2410c;
}

/* permanent-closures: canonical #991B1B, 8.31:1 on white and 7.76:1 on tier-4 tint. */
.dimension-block[data-dim="permanent-closures"] .card__name,
.dimension-block[data-dim="permanent-closures"] .card__name a,
.dimension--permanent-closures .card__name,
.dimension--permanent-closures .card__name a {
  color: #991B1B;
}
.dimension-block[data-dim="permanent-closures"] .card__link,
.dimension-block[data-dim="permanent-closures"] .card__source-badge-link,
.dimension-block[data-dim="permanent-closures"] .card__verify-link,
.dimension-block[data-dim="permanent-closures"] .card__fb-link,
.dimension-block[data-dim="permanent-closures"] .card__news-link,
.dimension-block[data-dim="permanent-closures"] .sunbiz-link,
.dimension-block[data-dim="permanent-closures"] .card-link,
.dimension--permanent-closures .card__link,
.dimension--permanent-closures .card__source-badge-link,
.dimension--permanent-closures .card__verify-link,
.dimension--permanent-closures .card__fb-link,
.dimension--permanent-closures .card__news-link,
.dimension--permanent-closures .sunbiz-link,
.dimension--permanent-closures .card-link {
  color: #991B1B;
}

/* closures: canonical #991B1B, 8.31:1 on white. */
.dimension-block[data-dim="closures"] .card__name,
.dimension-block[data-dim="closures"] .card__name a,
.dimension--closures .card__name,
.dimension--closures .card__name a {
  color: #991B1B;
}
.dimension-block[data-dim="closures"] .card__link,
.dimension-block[data-dim="closures"] .card__source-badge-link,
.dimension-block[data-dim="closures"] .card__verify-link,
.dimension-block[data-dim="closures"] .card__fb-link,
.dimension-block[data-dim="closures"] .card__news-link,
.dimension-block[data-dim="closures"] .sunbiz-link,
.dimension-block[data-dim="closures"] .card-link,
.dimension--closures .card__link,
.dimension--closures .card__source-badge-link,
.dimension--closures .card__verify-link,
.dimension--closures .card__fb-link,
.dimension--closures .card__news-link,
.dimension--closures .sunbiz-link,
.dimension--closures .card-link {
  color: #991B1B;
}

/* delinquent: canonical #EA580C is 3.56:1 on white, so text uses #c2410c. */
.dimension-block[data-dim="delinquent"] .card__name,
.dimension-block[data-dim="delinquent"] .card__name a,
.dimension--delinquent .card__name,
.dimension--delinquent .card__name a {
  color: #c2410c;
}
.dimension-block[data-dim="delinquent"] .card__link,
.dimension-block[data-dim="delinquent"] .card__source-badge-link,
.dimension-block[data-dim="delinquent"] .card__verify-link,
.dimension-block[data-dim="delinquent"] .card__fb-link,
.dimension-block[data-dim="delinquent"] .card__news-link,
.dimension-block[data-dim="delinquent"] .sunbiz-link,
.dimension-block[data-dim="delinquent"] .card-link,
.dimension--delinquent .card__link,
.dimension--delinquent .card__source-badge-link,
.dimension--delinquent .card__verify-link,
.dimension--delinquent .card__fb-link,
.dimension--delinquent .card__news-link,
.dimension--delinquent .sunbiz-link,
.dimension--delinquent .card-link {
  color: #c2410c;
}

/* distressed: canonical #EA580C is 3.56:1 on white, so text uses #c2410c. */
.dimension-block[data-dim="distressed"] .card__name,
.dimension-block[data-dim="distressed"] .card__name a,
.dimension--distressed .card__name,
.dimension--distressed .card__name a {
  color: #c2410c;
}
.dimension-block[data-dim="distressed"] .card__link,
.dimension-block[data-dim="distressed"] .card__source-badge-link,
.dimension-block[data-dim="distressed"] .card__verify-link,
.dimension-block[data-dim="distressed"] .card__fb-link,
.dimension-block[data-dim="distressed"] .card__news-link,
.dimension-block[data-dim="distressed"] .sunbiz-link,
.dimension-block[data-dim="distressed"] .card-link,
.dimension--distressed .card__link,
.dimension--distressed .card__source-badge-link,
.dimension--distressed .card__verify-link,
.dimension--distressed .card__fb-link,
.dimension--distressed .card__news-link,
.dimension--distressed .sunbiz-link,
.dimension--distressed .card-link {
  color: #c2410c;
}

/* recent-failures: canonical #F97316 is 2.80:1 on white, so text uses #c2410c. */
.dimension-block[data-dim="recent-failures"] .card__name,
.dimension-block[data-dim="recent-failures"] .card__name a,
.dimension--recent-failures .card__name,
.dimension--recent-failures .card__name a {
  color: #c2410c;
}
.dimension-block[data-dim="recent-failures"] .card__link,
.dimension-block[data-dim="recent-failures"] .card__source-badge-link,
.dimension-block[data-dim="recent-failures"] .card__verify-link,
.dimension-block[data-dim="recent-failures"] .card__fb-link,
.dimension-block[data-dim="recent-failures"] .card__news-link,
.dimension-block[data-dim="recent-failures"] .sunbiz-link,
.dimension-block[data-dim="recent-failures"] .card-link,
.dimension--recent-failures .card__link,
.dimension--recent-failures .card__source-badge-link,
.dimension--recent-failures .card__verify-link,
.dimension--recent-failures .card__fb-link,
.dimension--recent-failures .card__news-link,
.dimension--recent-failures .sunbiz-link,
.dimension--recent-failures .card-link {
  color: #c2410c;
}

/* most-improved: canonical #16a34a is 3.30:1 on white, so text uses #15803d. */
.dimension-block[data-dim="most-improved"] .card__name,
.dimension-block[data-dim="most-improved"] .card__name a,
.dimension--most-improved .card__name,
.dimension--most-improved .card__name a {
  color: #15803d;
}
.dimension-block[data-dim="most-improved"] .card__link,
.dimension-block[data-dim="most-improved"] .card__source-badge-link,
.dimension-block[data-dim="most-improved"] .card__verify-link,
.dimension-block[data-dim="most-improved"] .card__fb-link,
.dimension-block[data-dim="most-improved"] .card__news-link,
.dimension-block[data-dim="most-improved"] .sunbiz-link,
.dimension-block[data-dim="most-improved"] .card-link,
.dimension--most-improved .card__link,
.dimension--most-improved .card__source-badge-link,
.dimension--most-improved .card__verify-link,
.dimension--most-improved .card__fb-link,
.dimension--most-improved .card__news-link,
.dimension--most-improved .sunbiz-link,
.dimension--most-improved .card-link {
  color: #15803d;
}

/* clean-plates: canonical #16a34a is 3.30:1 on white, so text uses #15803d. */
.dimension-block[data-dim="clean-plates"] .card__name,
.dimension-block[data-dim="clean-plates"] .card__name a,
.dimension--clean-plates .card__name,
.dimension--clean-plates .card__name a {
  color: #15803d;
}
.dimension-block[data-dim="clean-plates"] .card__link,
.dimension-block[data-dim="clean-plates"] .card__source-badge-link,
.dimension-block[data-dim="clean-plates"] .card__verify-link,
.dimension-block[data-dim="clean-plates"] .card__fb-link,
.dimension-block[data-dim="clean-plates"] .card__news-link,
.dimension-block[data-dim="clean-plates"] .sunbiz-link,
.dimension-block[data-dim="clean-plates"] .card-link,
.dimension--clean-plates .card__link,
.dimension--clean-plates .card__source-badge-link,
.dimension--clean-plates .card__verify-link,
.dimension--clean-plates .card__fb-link,
.dimension--clean-plates .card__news-link,
.dimension--clean-plates .sunbiz-link,
.dimension--clean-plates .card-link {
  color: #15803d;
}

/* openings: canonical #06b6d4 is 2.43:1 on white, so text uses #0e7490. */
.dimension-block[data-dim="openings"] .card__name,
.dimension-block[data-dim="openings"] .card__name a,
.dimension--openings .card__name,
.dimension--openings .card__name a {
  color: #0e7490;
}
.dimension-block[data-dim="openings"] .card__link,
.dimension-block[data-dim="openings"] .card__source-badge-link,
.dimension-block[data-dim="openings"] .card__verify-link,
.dimension-block[data-dim="openings"] .card__fb-link,
.dimension-block[data-dim="openings"] .card__news-link,
.dimension-block[data-dim="openings"] .sunbiz-link,
.dimension-block[data-dim="openings"] .card-link,
.dimension--openings .card__link,
.dimension--openings .card__source-badge-link,
.dimension--openings .card__verify-link,
.dimension--openings .card__fb-link,
.dimension--openings .card__news-link,
.dimension--openings .sunbiz-link,
.dimension--openings .card-link {
  color: #0e7490;
}

/* new-licenses: canonical #06b6d4 is 2.43:1 on white, so text uses #0e7490. */
.dimension-block[data-dim="new-licenses"] .card__name,
.dimension-block[data-dim="new-licenses"] .card__name a,
.dimension--new-licenses .card__name,
.dimension--new-licenses .card__name a {
  color: #0e7490;
}
.dimension-block[data-dim="new-licenses"] .card__link,
.dimension-block[data-dim="new-licenses"] .card__source-badge-link,
.dimension-block[data-dim="new-licenses"] .card__verify-link,
.dimension-block[data-dim="new-licenses"] .card__fb-link,
.dimension-block[data-dim="new-licenses"] .card__news-link,
.dimension-block[data-dim="new-licenses"] .sunbiz-link,
.dimension-block[data-dim="new-licenses"] .card-link,
.dimension--new-licenses .card__link,
.dimension--new-licenses .card__source-badge-link,
.dimension--new-licenses .card__verify-link,
.dimension--new-licenses .card__fb-link,
.dimension--new-licenses .card__news-link,
.dimension--new-licenses .sunbiz-link,
.dimension--new-licenses .card-link {
  color: #0e7490;
}

/* ghost-licenses: canonical #64748b, 4.76:1 on white. */
.dimension-block[data-dim="ghost-licenses"] .card__name,
.dimension-block[data-dim="ghost-licenses"] .card__name a,
.dimension--ghost-licenses .card__name,
.dimension--ghost-licenses .card__name a {
  color: #64748b;
}
.dimension-block[data-dim="ghost-licenses"] .card__link,
.dimension-block[data-dim="ghost-licenses"] .card__source-badge-link,
.dimension-block[data-dim="ghost-licenses"] .card__verify-link,
.dimension-block[data-dim="ghost-licenses"] .card__fb-link,
.dimension-block[data-dim="ghost-licenses"] .card__news-link,
.dimension-block[data-dim="ghost-licenses"] .sunbiz-link,
.dimension-block[data-dim="ghost-licenses"] .card-link,
.dimension--ghost-licenses .card__link,
.dimension--ghost-licenses .card__source-badge-link,
.dimension--ghost-licenses .card__verify-link,
.dimension--ghost-licenses .card__fb-link,
.dimension--ghost-licenses .card__news-link,
.dimension--ghost-licenses .sunbiz-link,
.dimension--ghost-licenses .card-link {
  color: #64748b;
}

/* lost-licenses: canonical #1A3D6D, 10.87:1 on white. */
.dimension-block[data-dim="lost-licenses"] .card__name,
.dimension-block[data-dim="lost-licenses"] .card__name a,
.dimension--lost-licenses .card__name,
.dimension--lost-licenses .card__name a {
  color: #1A3D6D;
}
.dimension-block[data-dim="lost-licenses"] .card__link,
.dimension-block[data-dim="lost-licenses"] .card__source-badge-link,
.dimension-block[data-dim="lost-licenses"] .card__verify-link,
.dimension-block[data-dim="lost-licenses"] .card__fb-link,
.dimension-block[data-dim="lost-licenses"] .card__news-link,
.dimension-block[data-dim="lost-licenses"] .sunbiz-link,
.dimension-block[data-dim="lost-licenses"] .card-link,
.dimension--lost-licenses .card__link,
.dimension--lost-licenses .card__source-badge-link,
.dimension--lost-licenses .card__verify-link,
.dimension--lost-licenses .card__fb-link,
.dimension--lost-licenses .card__news-link,
.dimension--lost-licenses .sunbiz-link,
.dimension--lost-licenses .card-link {
  color: #1A3D6D;
}

/* chain-activity: canonical #9333ea, 5.38:1 on white. */
.dimension-block[data-dim="chain-activity"] .card__name,
.dimension-block[data-dim="chain-activity"] .card__name a,
.dimension--chain-activity .card__name,
.dimension--chain-activity .card__name a {
  color: #9333ea;
}
.dimension-block[data-dim="chain-activity"] .card__link,
.dimension-block[data-dim="chain-activity"] .card__source-badge-link,
.dimension-block[data-dim="chain-activity"] .card__verify-link,
.dimension-block[data-dim="chain-activity"] .card__fb-link,
.dimension-block[data-dim="chain-activity"] .card__news-link,
.dimension-block[data-dim="chain-activity"] .sunbiz-link,
.dimension-block[data-dim="chain-activity"] .card-link,
.dimension--chain-activity .card__link,
.dimension--chain-activity .card__source-badge-link,
.dimension--chain-activity .card__verify-link,
.dimension--chain-activity .card__fb-link,
.dimension--chain-activity .card__news-link,
.dimension--chain-activity .sunbiz-link,
.dimension--chain-activity .card-link {
  color: #9333ea;
}

/* Keep the existing filled-pill hover contrast for tray links. */
.dimension-block[data-dim] .card__link:hover,
.dimension-block .dimension .card__link:hover {
  color: var(--paper);
}

.dim__new-badge {
  display: inline-flex;
  align-items: center;
  margin-left: 0.45em;
  padding: 0.08rem 0.34rem;
  border: 1px solid rgba(17, 24, 39, 0.18);
  border-radius: 3px;
  background: #fff7ed;
  color: #9a3412;
  font-family: var(--font-sans);
  font-size: 0.62rem;
  font-weight: 800;
  line-height: 1.25;
  text-transform: uppercase;
  vertical-align: middle;
}

.dim__since-last-visit-caption {
  display: block;
  margin-top: 0.18rem;
  color: var(--ink-muted);
  font-family: var(--font-sans);
  font-size: 0.76rem;
  font-weight: 600;
  line-height: 1.3;
  text-transform: none;
}

.dim__since-last-visit-caption[hidden] {
  display: none;
}

.tse-insights {
  margin: 0 0 0.9rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid rgba(14, 124, 102, 0.28);
  border-left: 4px solid #0e7c66;
  border-radius: 6px;
  background: #f0fdfa;
  color: var(--ink);
}

.tse-insights--metro {
  margin: 1rem 0 1.25rem;
}

.tse-insights__kicker {
  display: block;
  color: #0f766e;
  font-family: var(--font-sans);
  font-size: 0.74rem;
  font-weight: 800;
  line-height: 1.2;
  text-transform: uppercase;
}

.tse-insights__list {
  display: grid;
  gap: 0.35rem;
  margin: 0.45rem 0 0;
  padding-left: 1rem;
}

.tse-insights__item {
  margin: 0;
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1.35;
}
