/* ============================
   HOUSTON CHRISTIAN HOMESCHOOLS — design tokens + components
   Canonical: 03-projects/2026-08-houston-christian-homeschools/blueprint.md §2
              + design/design-spec.md (approved 2026-08-22)
   Fonts load from Google Fonts (see Layout.tsx <link>) — Newsreader (headings)
   + Plus Jakarta Sans (body/UI).
   ============================ */

:root {
  font-size: 112.5%; /* 18px effective base at browser default 16px; still respects user zoom */

  --ink: #123F3A;
  --ink-2: #1E5A52;
  --paper: #FBF8F3;
  --surface: #FFFFFF;
  --panel: #F3EEE5;
  --text: #1E1E1C;
  --muted: #5B5B56;
  --line: #E6DFD2;
  --clay: #C2512E;
  --clay-dark: #A6431F;
  --gold: #E0A52B;
  --gold-soft: #FBEFD4;
  --sky: #DCE8F2;
  --sage: #A8B89F;
  --rose: #F2D7D0;

  --font-heading: "Newsreader", Georgia, "Times New Roman", serif;
  --font-body: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --radius-card: 12px;
  --radius-pill: 999px;
  --radius-input: 8px;
  --shadow-card: 0 4px 16px rgba(18, 63, 58, 0.09);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: hidden; } /* QA B1: horizontal-overflow guard */

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  font-weight: 400;
}

h1, h2, h3, h4 { font-family: var(--font-heading); font-weight: 600; color: var(--ink); margin: 0 0 0.5em; }
h1 { font-size: 2.5rem; line-height: 1.15; }
h2 { font-size: 1.75rem; line-height: 1.2; }
h3 { font-size: 1.375rem; line-height: 1.3; }
h4 { font-size: 1.1rem; }

@media (max-width: 640px) {
  html { font-size: 106.25%; } /* 17px effective base on mobile */
  h1 { font-size: 2rem; }
}

p { margin: 0 0 1em; max-width: 70ch; }
a { color: var(--clay-dark); }
a.plain { color: inherit; text-decoration: none; }
/* Body-copy links need more than color alone to read as links (WCAG 1.4.1) —
   nav/card/button links stay underline-free by design (icon/position/weight
   already distinguish them), but inline prose links get an underline. */
p a, .lead a, article a, .faq-answer a, li a {
  text-decoration: underline;
  text-underline-offset: 2px;
}
img, svg { max-width: 100%; }

a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, summary:focus-visible {
  outline: 3px solid var(--ink-2);
  outline-offset: 2px;
}

.wrap { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
.wrap-narrow { max-width: 760px; margin: 0 auto; padding: 0 24px; }

/* ===== THE PAGE GUTTER, AND WHY IT IS WRITTEN TWICE =====================
   This has now shipped broken three times (QA B4, research/32), always the
   same way and never as a typo. `.wrap` sets the 24px gutter with a
   `padding` shorthand. Any LATER rule of equal specificity that also uses
   the `padding` shorthand on an element carrying `.wrap` resets all four
   sides, so the gutter silently becomes 0 and the page renders flush to
   both screen edges at 390. `.home-hero { padding: 18px 0 8px }` did exactly
   that to the fix that was written for the previous occurrence, forty lines
   further down the same file.

   Three things stop the fourth occurrence, in order of how load-bearing
   they are:

   1. The doubled class below. `.wrap.wrap` is specificity (0,2,0), so no
      single-class `padding` shorthand can reach it, whatever the source
      order. It sets only the inline axis, so a co-occurring class is still
      free to own the block axis, which is all any of them ever wanted.
   2. Every rule in this file that pairs with `.wrap` now uses
      `padding-block`, not the shorthand. Belt as well as braces, and it
      makes the intent readable at the call site.
   3. scripts/test-security.mjs greps this stylesheet AND the templates for
      the pattern and fails the build check, so the next occurrence is loud
      instead of shipping to a founder's phone.

   An inline `style="padding: ..."` on a `.wrap` element still beats all of
   this, which is how the /search side of B4 happened. That is what check 3
   covers.
   ======================================================================= */
.wrap.wrap, .wrap-narrow.wrap-narrow { padding-inline: 24px; }

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--surface); padding: 12px 16px; z-index: 200;
}
.skip-link:focus { left: 0; }

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

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

/* ---------- Header / mega-menu ---------- */

.site-header { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 50; }
.header-inner { display: flex; align-items: center; justify-content: space-between; min-height: 68px; gap: 20px; }
.logo { font-family: var(--font-heading); font-weight: 600; font-size: 1.2rem; color: var(--ink); text-decoration: none; display: flex; align-items: center; gap: 8px; }
.logo .mark { width: 30px; height: 30px; border-radius: 8px; background: var(--gold); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; font-family: var(--font-heading); font-weight: 700; font-size: 0.9rem; flex: none; }

.main-nav { display: none; }
@media (min-width: 1024px) { .main-nav { display: block; } }
.main-nav > ul { list-style: none; display: flex; gap: 8px; margin: 0; padding: 0; align-items: center; }
.main-nav > ul > li { position: relative; }
.nav-link { color: var(--ink); text-decoration: none; font-weight: 500; padding: 10px 12px; border-radius: var(--radius-input); display: inline-block; }
.nav-link:hover, .nav-link:focus-visible { background: var(--panel); }

.has-mega { position: static; }
.mega-panel {
  display: none; position: absolute; left: 0; right: 0; top: 100%;
  background: var(--surface); border-bottom: 1px solid var(--line); box-shadow: var(--shadow-card);
  padding: 28px 0;
}
.has-mega:hover .mega-panel, .has-mega:focus-within .mega-panel { display: block; }
.mega-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; }
.mega-col h4 { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin-bottom: 12px; }
.mega-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px 20px; }
.mega-list a { color: var(--text); text-decoration: none; display: flex; justify-content: space-between; padding: 6px 8px; border-radius: 6px; }
.mega-list a:hover { background: var(--panel); }
.mega-count { color: var(--muted); font-size: 0.8em; }
.cluster-block { margin-bottom: 14px; }
.cluster-block .cluster-name { font-weight: 600; font-size: 0.92rem; color: var(--ink); }
.cluster-block .area-links { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.cluster-block .area-links a { font-size: 0.85rem; color: var(--muted); text-decoration: none; }
.cluster-block .area-links a:hover { color: var(--clay-dark); }

.header-actions { display: flex; align-items: center; gap: 10px; }
/* QA B1: "List your program" / "Sign in" collapse into the hamburger panel
   below the same 1024px breakpoint the mega-nav already collapses at — they
   were never hidden, so header-actions overflowed the viewport on every
   page at mobile widths, pushing the hamburger off-screen and (via the
   resulting horizontal scroll) breaking the fixed mobile-sticky-bar too.
   Both links still render in .mobile-nav (see Layout.tsx) so nothing is lost. */
@media (max-width: 1023px) { .header-actions > a { display: none; } }
.hamburger { display: inline-flex; background: none; border: none; padding: 8px; cursor: pointer; color: var(--ink); }
@media (min-width: 1024px) { .hamburger { display: none; } }

.mobile-nav { display: none; background: var(--surface); border-top: 1px solid var(--line); padding: 12px 24px 24px; }
.mobile-nav.open { display: block; }
.mobile-nav details { border-bottom: 1px solid var(--line); padding: 10px 0; }
.mobile-nav summary { cursor: pointer; font-weight: 600; }
.mobile-nav .mega-list { grid-template-columns: 1fr; margin-top: 8px; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: var(--radius-input); padding: 12px 22px; font-weight: 600; font-size: 1rem;
  text-decoration: none; min-height: 44px; line-height: 1; border: 2px solid transparent; cursor: pointer;
  font-family: var(--font-body); transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.btn-primary { background: var(--clay); color: #fff; }
.btn-primary:hover { background: var(--clay-dark); }
.btn-outline { background: transparent; border-color: var(--ink); color: var(--ink); }
.btn-outline:hover { background: var(--panel); }
.btn-ghost { background: transparent; color: var(--ink); }
.btn-ghost:hover { background: var(--panel); }
.btn-sm { min-height: 36px; padding: 8px 16px; font-size: 0.9rem; }
.btn[disabled], .btn.disabled { opacity: 0.4; cursor: not-allowed; }
.btn-block { width: 100%; }

/* ---------- Chips / Tags / Badges ---------- */

.tag {
  display: inline-flex; align-items: center; gap: 5px; padding: 6px 14px; border-radius: var(--radius-pill);
  font-size: 0.875rem; font-weight: 500; background: var(--panel); color: var(--ink); border: 1px solid var(--line);
  max-width: 100%;
}
/* QA B1 follow-up: found while re-verifying the mobile-overflow fix — some
   required-copy chips (faith precision, "Support Groups & Communities"
   before its short_name) are long enough on their own to overflow a 390px
   viewport when `white-space: nowrap` forces one unbroken line. Wrapping to
   a second line inside the pill is the safe fix; unlike header nav links
   this text has nowhere else to go (it's the chip's whole content). */
@media (max-width: 480px) {
  .tag { white-space: normal; }
}
.tag-sky { background: var(--sky); border-color: transparent; }
.tag-gold { background: var(--gold); color: var(--ink); border-color: transparent; font-weight: 700; }
.tag-sage { background: var(--sage); border-color: transparent; color: var(--ink); }
.tag-rose { background: var(--rose); border-color: transparent; }

.chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: var(--radius-pill);
  font-size: 0.9rem; font-weight: 500; background: var(--surface); border: 1px solid var(--line); color: var(--ink);
  text-decoration: none; cursor: pointer; min-height: 40px;
}
.chip:hover { border-color: var(--ink-2); }
.chip-active { background: var(--ink); color: #fff; border-color: var(--ink); }
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; }
.chip-remove { background: none; border: none; color: inherit; font-size: 1em; cursor: pointer; padding: 0 0 0 4px; }

.badge-verified { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: var(--ink-2); font-size: 0.85rem; }

/* ---------- Cards ---------- */

.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card);
  padding: 18px; transition: box-shadow 150ms ease; display: block;
}
.card:hover, .card:focus-within { box-shadow: var(--shadow-card); }
.card-featured { background: var(--gold-soft); border: 2px solid var(--gold); overflow: hidden; padding: 0; }
.card-featured .featured-topbar { height: 6px; background: var(--gold); }
.card-featured .card-body { padding: 16px 18px 18px; }

/* QA N1 — BLOCKER regression (research/15): S4's fixed 150px .thumb inside
   a 260px-floor auto-fill grid left as little as 64-141px for the card
   body at every multi-column width from 768px up (every type hub, area
   hub, area×type page, and the Nearby module) — one word per line, names
   clipping mid-word. `container-type: inline-size` lets the card react to
   its OWN rendered width (which depends on how many columns the grid
   picked, not on the viewport alone) rather than guessing one viewport
   breakpoint that would be wrong for some page's column count. Below
   380px of actual card width, the thumbnail moves above the text instead
   of beside it — the body then gets the full card width, at every grid
   density, on every page that uses this component. */
.program-card { display: flex; flex-direction: column; gap: 10px; text-decoration: none; color: inherit; height: 100%; container-type: inline-size; }
/* QA S4: 150x110 thumbnail beside the text (design-spec §7's scannability
   finding), not a full-width empty band above it — at card widths wide
   enough for that layout to have room; see the container query below. */
.program-card-inner { display: flex; gap: 14px; align-items: flex-start; }
.program-card-body { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
.program-card .thumb {
  width: 150px; height: 110px; flex: none; border-radius: 8px; background: var(--panel);
  display: flex; align-items: center; justify-content: center; color: var(--muted); overflow: hidden;
}
.program-card .thumb img { width: 100%; height: 100%; object-fit: cover; }
/* Scoped to viewport >=421px: at <=420px the existing rule below already
   shrinks the thumb to 96x80 side-by-side, which research/15 confirmed
   already reads fine at every single-column mobile width it measured
   (327-537px cards, 179-335px body) — this only needs to catch the
   multi-column desktop/tablet cases (768-1920px) that were actually
   broken, not re-litigate a width range that already works. */
@media (min-width: 421px) {
  @container (max-width: 379px) {
    .program-card-inner { flex-direction: column; }
    .program-card .thumb { width: 100%; height: 140px; }
  }
}
@media (max-width: 420px) {
  .program-card .thumb { width: 96px; height: 80px; }
}
.program-card h3 { font-size: 1.05rem; margin: 0; }
.program-card .meta-line { color: var(--muted); font-size: 0.9rem; }
.program-card .schedule-stamp { color: var(--ink-2); font-weight: 600; font-size: 0.88rem; }
.program-card .review-quote { font-size: 0.88rem; color: var(--text); font-style: italic; border-left: 2px solid var(--line); padding-left: 10px; }
.program-card .card-actions { display: flex; gap: 8px; margin-top: auto; flex-wrap: wrap; }
.card-ring { box-shadow: 0 0 0 3px var(--ink-2), var(--shadow-card); }

/* QA N1: raised the column floor from 260px to 300px so auto-fill picks
   fewer, wider columns at a given container width (fewer 4-up grids
   squeezing every card down to the old floor). The container query above
   is what actually guarantees a readable body at whatever width auto-fill
   lands on, though — this floor change alone was not the fix. */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }

/* ---------- Filter rail / quick chips ---------- */

.filter-rail { background: var(--panel); border-radius: var(--radius-card); padding: 18px; }
.filter-rail details { border-bottom: 1px solid var(--line); padding: 12px 0; }
.filter-rail details:last-of-type { border-bottom: none; }
.filter-rail summary { cursor: pointer; font-weight: 600; display: flex; justify-content: space-between; align-items: center; list-style: none; }
.filter-rail summary::-webkit-details-marker { display: none; }
.filter-rail .opt-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.filter-rail label { display: flex; align-items: center; gap: 8px; font-size: 0.92rem; }
.filter-clear { font-size: 0.85rem; color: var(--muted); text-decoration: underline; background: none; border: none; cursor: pointer; padding: 0; }

.quick-filters { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0; }

/* QA S2: quick-filter row — 4 <details> dropdowns, not a 14-chip dump. */
.qf-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0; }
.qf-details { position: relative; }
.qf-details summary { list-style: none; }
.qf-details summary::-webkit-details-marker { display: none; }
.qf-details[open] summary { border-color: var(--ink-2); }
.qf-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 25; min-width: 220px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: 12px; display: flex; flex-direction: column; gap: 8px;
}

.disclosure-line { color: var(--muted); font-size: 0.9rem; padding: 10px 0; }

/* ---------- Results layout ---------- */

.results-layout { display: grid; grid-template-columns: 260px 1fr; gap: 24px; align-items: start; }
@media (min-width: 1024px) { .results-layout.with-map { grid-template-columns: 260px 1fr 420px; } }
@media (max-width: 1023px) { .results-layout { grid-template-columns: 1fr; } .filter-rail-col { order: 3; } }

/* QA B1 follow-up: /tefa reused .results-layout but overrode its columns
   via an *inline* style ("1fr 260px") to get a content+TOC-rail pair
   instead of the 3-up search layout — inline styles beat the media query
   above at any width, so the 260px rail never collapsed and the page
   overflowed to 592px on a 390px viewport. A dedicated class fixes this
   properly (desktop-only 2-column, real mobile collapse) instead of
   another inline style that would just re-trigger the same bug. */
.tefa-layout { grid-template-columns: 1fr 260px; }
@media (max-width: 1023px) { .tefa-layout { grid-template-columns: 1fr; } }
.map-col { position: sticky; top: 84px; height: calc(100vh - 100px); border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--line); }
@media (max-width: 1023px) { .map-col { display: none; } }
#leaflet-map { width: 100%; height: 100%; background: var(--panel); margin-bottom: 14px; }
/* Lighthouse target-size: Leaflet's own bottom-left attribution control has
   no built-in clearance from whatever sits right below the map (listing
   "Get directions" link, area-hub content) — the margin above gives real
   space; program.tsx also adds explicit spacing on its own link for the
   same reason. */

.mobile-sticky-bar {
  display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 60;
  background: var(--surface); border-top: 1px solid var(--line); padding: 10px 16px;
  justify-content: space-around; box-shadow: 0 -4px 16px rgba(18,63,58,.08);
}
@media (max-width: 1023px) { .mobile-sticky-bar { display: flex; } }
.mobile-sticky-bar button, .mobile-sticky-bar a {
  background: none; border: none; color: var(--ink); font-weight: 600; font-size: 0.9rem;
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 6px 10px; min-height: 44px;
}

/* ---------- Pagination ---------- */

.pagination { display: flex; gap: 8px; align-items: center; justify-content: center; margin: 32px 0; flex-wrap: wrap; }
.pagination a, .pagination span {
  min-width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  text-decoration: none; color: var(--text); font-weight: 600; padding: 0 8px;
}
.pagination .current { background: var(--ink); color: #fff; }
.pagination a:hover { background: var(--panel); }

/* ---------- Forms ---------- */

.field { margin-bottom: 16px; }
.field label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 5px; }
.field input, .field select, .field textarea {
  width: 100%; font-family: inherit; font-size: 1rem; border: 1px solid var(--line);
  border-radius: var(--radius-input); padding: 12px; background: var(--surface); color: var(--text); min-height: 44px;
}

/* QA P7: bare <select>s outside a .field (results sort, hero area picker)
   rendered as an unstyled native control next to fully-branded buttons, and
   clipped at the mobile viewport edge with no width constraint. */
select {
  font-family: inherit; font-size: 1rem; border: 1px solid var(--line);
  border-radius: var(--radius-input); padding: 8px 12px; background: var(--surface);
  color: var(--text); min-height: 40px; max-width: 100%;
}
.field textarea { min-height: 100px; }
.field .hint { font-size: 0.8rem; color: var(--muted); margin-top: 4px; }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: var(--clay); background: var(--rose); }
.checkbox-field { display: flex; align-items: flex-start; gap: 8px; font-size: 0.9rem; }
.checkbox-field input { width: auto; min-height: auto; }
.honeypot-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.toast { padding: 12px 18px; border-radius: 8px; font-size: 0.9rem; display: inline-flex; align-items: center; gap: 10px; }
.toast-success { background: var(--ink); color: #fff; }
.toast-error { background: var(--rose); color: var(--text); }

/* ---------- Sticky inquiry rail (listing) ---------- */

.listing-layout { display: grid; grid-template-columns: 1fr 360px; gap: 32px; align-items: start; }
@media (max-width: 900px) { .listing-layout { grid-template-columns: 1fr; } }
.inquiry-rail { position: sticky; top: 84px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 20px; }
@media (max-width: 900px) { .inquiry-rail { position: static; } }

/* ---------- Newsletter bar / claim banner ---------- */

.newsletter-bar {
  background: var(--gold-soft); border-radius: 10px; padding: 20px 24px; display: flex; justify-content: space-between;
  align-items: center; gap: 16px; flex-wrap: wrap;
}
.newsletter-bar form { display: flex; gap: 8px; flex-wrap: wrap; }
.newsletter-bar input { min-width: 220px; }

.claim-banner {
  background: var(--panel); border-radius: 10px; padding: 18px 20px; display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.claim-banner .grow { flex: 1; min-width: 220px; }
.claim-banner .remove-link { font-size: 0.85rem; color: var(--muted); }

/* ---------- Stat bar / facts grid / breadcrumb ---------- */

.stat-bar { display: flex; gap: 28px; flex-wrap: wrap; padding: 18px 0; font-weight: 600; color: var(--ink); }
.stat-bar .stat-num { font-family: var(--font-heading); font-size: 1.4rem; }
.stat-bar .stat-label { display: block; font-weight: 400; font-size: 0.85rem; color: var(--muted); }

.breadcrumb { font-size: 0.85rem; color: var(--muted); margin-bottom: 16px; }
.breadcrumb a { color: var(--muted); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }

.facts-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.facts-grid .fact-tile { background: var(--panel); border-radius: 10px; padding: 14px 16px; }
.facts-grid .fact-tile .fact-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.facts-grid .fact-tile .fact-value { font-weight: 600; margin-top: 4px; }

.tefa-popover-wrap { position: relative; display: inline-block; }
.tefa-popover-btn { background: none; border: none; color: var(--ink-2); cursor: pointer; padding: 0; display: inline-flex; }
.tefa-popover {
  display: none; position: absolute; bottom: 130%; left: 0; z-index: 30; width: 300px;
  background: var(--ink); color: var(--paper); padding: 14px 16px; border-radius: 10px; font-size: 0.85rem;
  box-shadow: var(--shadow-card);
}
.tefa-popover-wrap:hover .tefa-popover, .tefa-popover-wrap:focus-within .tefa-popover { display: block; }

/* ---------- FAQ accordion ---------- */

.faq-list details { border-bottom: 1px solid var(--line); padding: 14px 0; }
.faq-list summary { cursor: pointer; font-weight: 600; list-style: none; display: flex; justify-content: space-between; gap: 12px; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list .faq-answer { margin-top: 10px; color: var(--text); }

/* ---------- Reviews ---------- */

.review { border-bottom: 1px solid var(--line); padding: 16px 0; }
.review .review-head { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.review .stars { color: var(--gold); font-weight: 700; }
.review .role { font-size: 0.85rem; color: var(--muted); }
.vendor-response { margin-top: 10px; margin-left: 18px; padding: 10px 14px; background: var(--panel); border-radius: 8px; font-size: 0.9rem; }

/* ---------- Hero / home ---------- */

.hero { padding-block: 56px 40px; }
.hero .lead { font-size: 1.125rem; color: var(--muted); max-width: 60ch; }
.hero-search { display: flex; gap: 10px; flex-wrap: wrap; margin: 24px 0; }
.hero-search input[type="search"] { flex: 1; min-width: 240px; }
.hero-search select { min-width: 200px; }
/* QA (WP5 polish): the search field above was relying on nothing but the
   global input:focus-visible outline — no border/radius/background/height
   of its own, so at mobile widths it rendered as a bare native <input>
   sitting above the (already-styled, see the `select` rule above) area
   picker, and the row's own min-widths (240px + 200px) don't fit a 390px
   viewport, so it wrapped in a way that read as broken rather than
   intentional. Gives the field the same tokens every other input/select
   already uses, then turns the row into one coherent stacked control group
   below the same 640px breakpoint the rest of the page uses. */
.hero-search input[type="search"] {
  border: 1px solid var(--line); border-radius: var(--radius-input);
  background: var(--surface); color: var(--text); padding: 12px; min-height: 44px;
}
@media (max-width: 640px) {
  .hero-search { flex-direction: column; align-items: stretch; }
  .hero-search input[type="search"], .hero-search select, .hero-search button { width: 100%; min-width: 0; }
}

.tile-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 20px; }
@media (max-width: 900px) { .tile-grid { grid-template-columns: repeat(2, 1fr); } }
.type-tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card);
  padding: 16px; text-decoration: none; color: var(--ink); display: flex; flex-direction: column; gap: 8px;
}
.type-tile:hover { box-shadow: var(--shadow-card); }
.type-tile .tile-count { color: var(--muted); font-size: 0.85rem; }

.section { padding-block: 48px; }
.section-panel { background: var(--panel); }
.section-title-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 20px; flex-wrap: wrap; gap: 8px; }

.cluster-grid { display: grid; gap: 24px; }
.cluster-row h3 { margin-bottom: 8px; }
.cluster-row .area-chip-row { display: flex; flex-wrap: wrap; gap: 8px; }

.finder-block, .toc-rail { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 20px; }
.toc-rail h3 { font-size: 1.1rem; } /* QA P8: promoted from h4 to fix heading-order; kept the original visual size */

table.data-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
table.data-table th, table.data-table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
table.data-table th { color: var(--muted); font-weight: 600; font-size: 0.85rem; text-transform: uppercase; letter-spacing: .02em; }
.table-scroll { overflow-x: auto; }

.tefa-tier-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 800px) { .tefa-tier-row { grid-template-columns: 1fr; } }
.tefa-tier-card { border-radius: var(--radius-card); border: 1px solid var(--line); padding: 18px; border-top: 6px solid var(--line); background: var(--surface); }
.tefa-tier-card.tier-sky { border-top-color: var(--sky); }
.tefa-tier-card.tier-gold { border-top-color: var(--gold); }
.tefa-tier-card.tier-clay { border-top-color: var(--clay); }

/* ---------- Footer ---------- */

.site-footer { background: var(--ink); color: var(--paper); padding: 48px 0 24px; margin-top: 48px; }
.site-footer a { color: var(--paper); opacity: 0.85; text-decoration: none; }
.site-footer a:hover { opacity: 1; text-decoration: underline; }
.footer-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 32px; }
@media (max-width: 800px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
.footer-grid h4, .footer-col-heading { color: var(--paper); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.7; margin-bottom: 12px; font-family: var(--font-body); }
.footer-grid ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 0.92rem; }
.footer-tagline { max-width: 60ch; color: var(--paper); opacity: 0.9; }
.footer-legal-line { font-size: 0.85rem; opacity: 0.75; margin-top: 8px; }
/* Inline prose links in the footer need real contrast + underline, not the
   nav-list treatment (WCAG 1.4.1 — Lighthouse link-in-text-block). */
.footer-legal-line a { color: var(--paper); opacity: 1; text-decoration: underline; }
.footer-bottom { font-size: 0.875rem; opacity: 0.7; border-top: 1px solid rgba(251, 248, 243, 0.15); padding-top: 16px; margin-top: 32px; }

/* ---------- Misc ---------- */

.coming-soon { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 20px 24px; color: var(--ink-2); max-width: 60ch; }
.empty-state { background: var(--panel); border-radius: var(--radius-card); padding: 28px; text-align: center; }
.badge-preview-box { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 20px; display: inline-flex; align-items: center; gap: 10px; }
.error-page { padding-block: 64px; text-align: center; }
.icon { flex: none; }
.sr-price-toggle { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-pill); overflow: hidden; }
.sr-price-toggle button { border: none; background: var(--surface); padding: 10px 18px; cursor: pointer; font-weight: 600; }
.sr-price-toggle button.active { background: var(--ink); color: #fff; }

/* ---------- Vendor dashboard / admin (WP2) ---------- */

.dashboard-layout { display: grid; grid-template-columns: 200px 1fr; gap: 32px; align-items: start; margin-top: 16px; }
@media (max-width: 768px) { .dashboard-layout { grid-template-columns: 1fr; } }
.dashboard-nav { display: flex; flex-direction: column; gap: 4px; background: var(--panel); border-radius: var(--radius-card); padding: 16px; position: sticky; top: 16px; }
.dashboard-nav a { padding: 8px 10px; border-radius: 8px; color: var(--ink); text-decoration: none; font-weight: 500; font-size: 0.92rem; }
.dashboard-nav a:hover { background: var(--surface); }
.dashboard-nav a.active { background: var(--ink); color: #fff; }
.dashboard-content { min-width: 0; }

.stat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 12px; margin: 16px 0; }
.stat-tile { background: var(--panel); border-radius: var(--radius-card); padding: 14px; text-align: center; }
.stat-tile .stat-num { display: block; font-family: var(--font-heading); font-size: 1.6rem; color: var(--ink); }
.stat-tile .stat-label { font-size: 0.8rem; color: var(--muted); }

.completeness-bar { background: var(--panel); border-radius: 999px; height: 10px; overflow: hidden; margin: 8px 0 12px; }
.completeness-bar > div { background: var(--sage); height: 100%; }
.checklist { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.checklist li { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 0.9rem; }
.checklist li.done { color: var(--ink); }
.checklist li.done .icon { color: var(--sage); }

.leads-table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 0.9rem; }
.leads-table th, .leads-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.leads-table th { color: var(--muted); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.02em; }
/* QA N2 (research/15): a data table wider than its viewport should scroll
   within its own box, not push the page's whole layout viewport wider than
   the device (the /sponsor status column was going fully off-screen at
   390px with no way to reach it). */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll .leads-table { min-width: 480px; }

.remove-link { font-size: 0.85rem; color: var(--muted); margin-left: auto; text-decoration: underline; }

/* ============================================================================
   HOMEPAGE — "The Map of Houston" blend (founder ruling 2026-09-06, "go map")
   Design ported from the Astro prototypes in _repos/coops-homepage-directions
   (Direction 2 atlas + dock + cluster cards, Direction 3 type wall, Direction
   5 faith pills + spec card, Direction 1 tag cloud). Rationale:
   research/24-homepage-directions-review.md. Tokens only — no new colors, no
   new fonts, nothing from the prototypes' own palettes.

   Two rules every block below obeys, because they are the two things the
   review measured Direction 2 failing at on a phone:
     - No page-level horizontal overflow at 390 / 768 / 1280. Every grid track
       is minmax(0,…) or minmax(min(Npx,100%),…); every nowrap row lives in
       its own overflow-x container.
     - The map is labelled and the readout never sits on top of it.
   ============================================================================ */

/* `.wrap` supplies the 24px page gutter, but `.section`/`.hero`/`.home-hero`
   all set `padding` as a shorthand, which zeroes the inline padding of any
   element carrying both classes — the old homepage rendered flush to both
   edges at 390 because of it. `.home-sec` restores the gutter on the
   homepage's own combined-class sections without touching `.section` for
   every other page (they nest a plain `.wrap` inside and are unaffected). */
.home-sec { padding-inline: 24px; }

/* ---------- 1. Search dock ---------- */
.home-dock-band { background: linear-gradient(180deg, var(--gold-soft), var(--paper) 78%); padding: 20px 0 4px; }
.home-dock {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px 18px 18px 6px;
  padding: 10px 12px;
  box-shadow: var(--shadow-card);
}
.home-dock-field { display: flex; flex-direction: column; gap: 2px; padding: 2px 6px; min-width: 0; }
.home-dock-label { font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.home-dock-field:focus-within .home-dock-label { color: var(--ink); }
.home-dock input, .home-dock select {
  border: 0; background: transparent; font: inherit; font-size: 1rem; color: var(--text);
  padding: 4px 0; width: 100%; min-width: 0; min-height: 32px;
}
.home-dock input:focus, .home-dock select:focus { outline: 2px solid var(--ink-2); outline-offset: 2px; border-radius: 4px; }
.home-dock-split { display: none; width: 1px; background: var(--line); margin: 6px 0; }
.home-dock-go { border-radius: 14px 14px 14px 4px; gap: 8px; }
.home-dock-note {
  display: flex; flex-wrap: wrap; gap: 4px 18px;
  margin: 10px 2px 0; font-size: 0.85rem; color: var(--muted); max-width: none;
}
@media (min-width: 720px) {
  .home-dock { grid-template-columns: minmax(0, 1fr) auto minmax(0, 15rem) auto; align-items: center; gap: 0; }
  .home-dock-split { display: block; }
  .home-dock-field { padding-inline: 14px; }
}

/* ---------- 2. Hero + atlas ---------- */
.home-hero { padding-block: 18px 8px; }
.home-eyebrow {
  display: flex; align-items: center; gap: 6px; margin: 0 0 10px;
  font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--clay-dark);
}
.home-hero h1 { margin-bottom: 6px; letter-spacing: -0.02em; }
.home-hero h1 em { font-style: italic; color: var(--clay-dark); }
.home-hero-sub { margin-bottom: 22px; }
.home-h2-sm { font-size: 1.35rem; margin-bottom: 10px; }
.section-tight { padding-block: 20px 28px; }

.atlas { position: relative; }
.atlas-frame {
  position: relative;
  background: linear-gradient(160deg, var(--surface), var(--gold-soft));
  border: 1px solid var(--line);
  border-radius: 20px 20px 20px 6px;
  padding: 8px 8px 2px;
  min-width: 0;
}
.atlas-corner { position: absolute; width: 24px; height: 24px; border: 2px solid var(--clay); opacity: 0.6; }
.atlas-corner-tl { top: 10px; left: 10px; border-right: 0; border-bottom: 0; border-radius: 6px 0 0 0; }
.atlas-corner-br { bottom: 10px; right: 10px; border-left: 0; border-top: 0; border-radius: 0 0 6px 0; }
.atlas-svg { display: block; width: 100%; height: auto; }
.atlas-water { fill: var(--sky); opacity: 0.85; }
.atlas-grat line { stroke: var(--muted); stroke-width: 0.6; opacity: 0.16; }
.atlas-roads * { fill: none; stroke: var(--clay); stroke-width: 1.1; opacity: 0.22; stroke-dasharray: 5 6; }
.atlas-roads circle { stroke-dasharray: none; opacity: 0.2; stroke-width: 1.3; }

.atlas-region { cursor: pointer; }
.atlas-shape { fill: #FCF4E6; stroke: var(--ink); stroke-width: 1.4; stroke-linejoin: round; transition: fill 200ms ease, stroke-width 200ms ease; }
.atlas-halo { fill: none; stroke: none; stroke-linejoin: round; }
.atlas-labels, .atlas-label { pointer-events: none; }
/* Leader line for the two central clusters whose real outline is too small to
   hold their own name (Inner Loop, Memorial), the way a paper map does it. */
.atlas-leader line { stroke: var(--ink); stroke-width: 1; opacity: 0.42; }
.atlas-leader circle { fill: var(--ink); opacity: 0.55; }
/* Labels are painted with a paper-coloured outline behind the glyphs, so a
   name that overhangs its own coastline is still readable over water or a
   neighbouring shape. */
.atlas-name, .atlas-count {
  paint-order: stroke fill; stroke: var(--paper); stroke-width: 3.5; stroke-linejoin: round;
}
.atlas-name { text-anchor: middle; font-family: var(--font-heading); font-size: 18px; font-weight: 600; fill: var(--ink); letter-spacing: -0.01em; }
.atlas-name-narrow { display: none; }
.atlas-count { text-anchor: middle; font-family: var(--font-body); font-size: 14px; font-weight: 700; fill: var(--clay-dark); stroke-width: 3; }
.atlas-region:hover .atlas-shape { fill: var(--gold-soft); stroke-width: 2.4; }
/* Visible keyboard focus: SVG ignores `outline` inconsistently across
   engines, so the ring is a second copy of the same polygon painted behind
   the shape and revealed only on focus-visible. The selected-state fill is
   declared *after* it, because focusing a polygon also selects it and the
   gold selected fill has to win over the hover/focus tint. */
.atlas-region:focus-visible { outline: none; }
.atlas-region:focus-visible .atlas-halo { stroke: var(--clay-dark); stroke-width: 8; stroke-dasharray: 7 5; }
.atlas-region:focus-visible .atlas-shape { fill: var(--gold-soft); stroke-width: 2.4; }
.atlas-region.is-active .atlas-shape { fill: var(--gold); stroke-width: 2.6; }
.atlas-region.is-active .atlas-count { fill: var(--ink); }
.atlas-label-g.is-active .atlas-count { fill: var(--ink); }
.atlas-compass-ring { fill: none; stroke: var(--ink); stroke-width: 1; opacity: 0.32; }
.atlas-needle-a { fill: var(--ink); opacity: 0.45; }
.atlas-needle-b { fill: var(--clay); }
.atlas-compass-n { text-anchor: middle; font-family: var(--font-heading); font-size: 13px; font-weight: 700; fill: var(--ink); }
.atlas-scale line { stroke: var(--muted); stroke-width: 1.2; opacity: 0.6; }
.atlas-scale text { font-family: var(--font-body); font-size: 12px; fill: var(--muted); letter-spacing: 0.1em; }
.atlas-hint {
  margin: 2px 0 8px; text-align: center; font-size: 0.72rem;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted); max-width: none;
}

.atlas-readout {
  display: block;
  margin-top: 14px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 16px 16px 16px 5px;
  padding: 16px 18px 18px;
  min-width: 0;
}
.atlas-readout[hidden] { display: none; }
.atlas-readout-tag { display: inline-block; font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold); }
.atlas-readout-name { margin: 6px 0 2px; color: var(--paper); font-size: 1.5rem; letter-spacing: -0.02em; }
.atlas-readout-count { margin: 0 0 8px; font-size: 0.88rem; color: rgba(251, 248, 243, 0.78); max-width: none; }
.atlas-readout-count b { color: var(--gold); font-size: 1.1rem; }
.atlas-readout-blurb { margin: 0 0 12px; font-size: 0.9rem; line-height: 1.5; color: rgba(251, 248, 243, 0.92); max-width: none; }
.atlas-readout-areas { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.atlas-area-chip {
  font-size: 0.8rem; padding: 4px 10px; border-radius: var(--radius-pill);
  text-decoration: none; color: var(--paper);
  background: rgba(251, 248, 243, 0.12); border: 1px solid rgba(251, 248, 243, 0.3);
}
.atlas-area-chip:hover, .atlas-area-chip:focus-visible { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.atlas-readout-go {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--gold); color: var(--ink); text-decoration: none;
  font-weight: 700; font-size: 0.92rem; padding: 10px 18px; border-radius: var(--radius-pill);
  min-height: 44px; box-sizing: border-box;
}
.atlas-readout-go:hover { background: #F0B948; }

@media (max-width: 767px) {
  /* Real polygons run 20-45px wide at phone scale, too tight for a full
     cluster name, so a short recognisable place name replaces it rather than
     the label being hidden outright (the prototype's mobile failure). */
  .atlas-name-wide { display: none; }
  .atlas-name-narrow { display: block; font-size: 21px; }
  .atlas-count { font-size: 15px; transform: translateY(4px); }
}
@media (min-width: 1024px) {
  /* Readout sits beside the map, never over it — a flex sibling, not an
     overlay. The frame is capped so the whole hero (headline, sub, atlas,
     readout) still clears an 844px-tall desktop fold. The real-geography
     viewBox is slightly taller than it is wide, so the cap is tighter than
     the 700px the old landscape box used. */
  .home-hero { padding-top: 12px; }
  .atlas { display: flex; align-items: center; justify-content: center; gap: 24px; }
  .atlas-frame { flex: 1 1 auto; min-width: 0; max-width: 545px; }
  .atlas-readouts { flex: 0 1 21rem; width: 21rem; min-width: 0; }
  .atlas-readout { margin-top: 0; }
}

/* ---------- 3. Faith pills ---------- */
.faith-row { display: flex; flex-wrap: wrap; gap: 8px; }
.faith-pill {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 9px 15px; border-radius: var(--radius-pill);
  background: var(--surface); border: 1px solid var(--clay);
  color: var(--ink); text-decoration: none; font-weight: 600; font-size: 0.92rem;
  min-height: 44px; box-sizing: border-box; align-content: center;
}
.faith-pill:hover, .faith-pill:focus-visible { background: var(--gold-soft); border-color: var(--clay-dark); }
.faith-pill-count { font-size: 0.82rem; font-weight: 700; color: var(--clay-dark); }
.faith-pill-all { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.faith-pill-all .faith-pill-count { color: var(--gold); }
.faith-pill-all:hover, .faith-pill-all:focus-visible { background: var(--ink-2); border-color: var(--ink-2); }
.faith-note { margin: 12px 0 0; font-size: 0.86rem; color: var(--muted); }

/* ---------- 4. Cluster cards ---------- */
.cluster-card-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr); }
.cluster-card-cell { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.cluster-card {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px 16px 16px 5px; padding: 14px 16px;
  text-decoration: none; color: inherit;
}
.cluster-card:hover, .cluster-card:focus-visible { box-shadow: var(--shadow-card); border-color: var(--ink-2); }
.cluster-thumb {
  display: grid; place-items: center; width: 54px; height: 54px; flex: none;
  border-radius: 12px 12px 12px 4px; background: var(--gold-soft); border: 1px solid var(--line); color: var(--ink);
}
.cluster-thumb svg { width: 76%; height: 76%; }
/* Real outlines carry far more detail than the old stylised cells, so the
   thumbnail stroke is thinner: at 2px it filled in the coastline. */
.cluster-thumb path { fill: var(--gold); stroke: var(--ink); stroke-width: 1.25; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.cluster-card-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cluster-card-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.cluster-card-name { font-family: var(--font-heading); font-weight: 600; font-size: 1.1rem; color: var(--ink); }
.cluster-card-count { font-weight: 700; font-size: 1.25rem; color: var(--clay-dark); line-height: 1; }
.cluster-card-blurb { font-size: 0.86rem; line-height: 1.45; color: var(--muted); }
.cluster-card-chips { display: flex; flex-wrap: wrap; gap: 6px; padding-left: 2px; }
.chip-sm { font-size: 0.8rem; padding: 5px 11px; }
@media (min-width: 640px) { .cluster-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .cluster-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; } }

/* ---------- 5. Type wall ---------- */
.type-wall { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(min(270px, 100%), 1fr)); }
.type-tile {
  display: flex; flex-direction: column; min-width: 0;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px 14px 14px 4px; padding: 16px 16px 14px;
}
.type-tile:hover, .type-tile:focus-within { box-shadow: var(--shadow-card); border-color: var(--ink-2); }
.type-tile-main { display: flex; flex-direction: column; gap: 6px; text-decoration: none; color: inherit; min-width: 0; }
.type-tile-icon { color: var(--clay-dark); display: block; }
.type-tile-name { font-family: var(--font-heading); font-weight: 600; font-size: 1.08rem; color: var(--ink); line-height: 1.25; }
.type-tile-blurb { font-size: 0.85rem; line-height: 1.45; color: var(--muted); }
.type-tile-count { font-size: 0.85rem; color: var(--muted); margin-top: 2px; }
.type-tile-count b { font-size: 1.15rem; color: var(--clay-dark); margin-right: 4px; }
.type-tile-count em { font-style: normal; font-weight: 600; color: var(--ink-2); }
.type-tile-empty { background: var(--panel); border-style: dashed; }
.type-tile-jump { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.type-tile-jump-label { width: 100%; font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }

/* ---------- 6. Spec card ---------- */
.spec-layout { display: grid; gap: 24px; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 900px) { .spec-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; } }
.spec-card { margin: 0; background: var(--surface); border: 1px solid var(--line); border-top: 6px solid var(--gold); border-radius: 14px; padding: 6px 18px 10px; }
.spec-card > div { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.spec-card > div:last-child { border-bottom: none; }
.spec-card dt { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted); }
.spec-card dd { margin: 0; font-weight: 600; color: var(--ink); }

/* ---------- 7. Popular searches, funding, leaders ---------- */
.tag-cloud { display: flex; flex-wrap: wrap; gap: 10px; }
.tag-cloud-item {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: var(--radius-pill);
  background: var(--surface); border: 1px dashed var(--line);
  color: var(--ink); text-decoration: none; font-size: 0.92rem;
  min-height: 44px; box-sizing: border-box;
}
.tag-cloud-item:hover, .tag-cloud-item:focus-visible { border-style: solid; border-color: var(--clay); background: var(--gold-soft); }
.tag-cloud-item .icon { color: var(--clay-dark); flex: none; }
.funding-layout { display: grid; gap: 28px; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 900px) { .funding-layout { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 48px; } }
.plain-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.leaders-block { max-width: 44rem; }

@media (prefers-reduced-motion: reduce) {
  .atlas-shape, .cluster-card, .type-tile, .faith-pill, .tag-cloud-item, .atlas-readout-go { transition: none !important; }
}


/* ---------- QA fix round, 2026-09-07 (research/33-qa-fixes.md) ---------- */

/* P5: /search set its h1 size with an inline style, on the same element
   family that caused B4. Structural styling belongs here. */
.search-h1 { font-size: 1.6rem; }

/* B5: the honest coverage line under the hero sub-headline. */
.home-hero-note { margin: 0 0 20px; max-width: 62ch; }

/* B3: every popular search now carries the count it returns, so the module
   is self-evidencing rather than a promise. */
.tag-cloud-count {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 0.8rem;
  color: var(--ink-2); background: var(--paper); border-radius: var(--radius-pill);
  padding: 1px 8px; margin-left: 2px;
}

/* S4/B2: an area with no listings stays visible on a cluster hub (the
   geography is honest) but stops being a clickable dead end. */
.card-muted { opacity: 0.72; }
.card-muted h3 { font-weight: 600; }

/* S1: the mobile menu's first row is the way into search. */
.mobile-nav-search { margin: 0 0 12px; }
.mobile-nav-search .btn { width: 100%; justify-content: center; }
.nav-link-search { display: inline-flex; align-items: center; gap: 6px; }

/* S9: 44px minimum on the two hero-dock fields and the atlas area chips.
   Lighthouse's tap-targets audit does not run on these pages, so this will
   never show up in a score; it is still the first thing a thumb meets. */
.home-dock input, .home-dock select { min-height: 44px; }
.atlas-area-chip { min-height: 44px; display: inline-flex; align-items: center; }

/* S5: /houston grouped its area chips by cluster, but the gap above a
   heading (54px) and the gap below it (36-73px) were indistinguishable, so
   on a scan the chips read as belonging to the previous cluster. Pure
   proximity: tight to its own chips, generous to the group above. */
.metro-cluster-group { margin-block-start: 48px; }
.metro-cluster-group:first-of-type { margin-block-start: 24px; }
.metro-cluster-group .section-title-row { margin-bottom: 12px; }

/* S8: 611 identical grey placeholder rectangles were the biggest single
   visual cost on the site. The thumb keeps its shape (the grid depends on
   it) but is tinted by program type, so a card grid reads by category at a
   glance instead of as a wall of missing images. */
.thumb[data-type] { background: var(--panel); color: var(--ink-2); }
.thumb[data-type="co-ops"] { background: #EAF2EC; color: #1F5B44; }
.thumb[data-type="hybrid-schools"] { background: #EDEEF8; color: #38407A; }
.thumb[data-type="microschools"] { background: #F5EEF7; color: #6A3D72; }
.thumb[data-type="christian-schools"] { background: #F4EEE4; color: #7A5A22; }
.thumb[data-type="private-school-a-la-carte"] { background: #F1EEE7; color: #6B5B36; }
.thumb[data-type="preschool"] { background: #FBEFEA; color: #8A4224; }
.thumb[data-type="tutors"] { background: #E9F1F8; color: #23567F; }
.thumb[data-type="enrichment"] { background: #F8F0E3; color: #8A5B18; }
.thumb[data-type="sports"] { background: #E8F3EF; color: #1E6053; }
.thumb[data-type="online"] { background: #E9EEF6; color: #2F4C7A; }
.thumb[data-type="curriculum"] { background: #F3F1E9; color: #5F6135; }
.thumb[data-type="support-groups"] { background: #F7EDF1; color: #7A3350; }
.thumb[data-type="field-trips"] { background: #EAF3F5; color: #22606B; }
.thumb[data-type="special-needs"] { background: #EFF0F7; color: #414678; }
.thumb[data-type="stem"] { background: #E7F1F4; color: #1F5E70; }
.thumb[data-type="therapies"] { background: #F0F2F6; color: #47506E; }

/* S4: a zero-count area chip is plain text, not a link into an empty page. */
.chip-muted { opacity: 0.55; cursor: default; }
