/* ============================================================================
   Civic Voice — signed-out landing (platform chrome)
   Hand-rolled CSS. Every colour, spacing, radius, motion, and type-size value
   resolves to a --civic-* design token (see @civicvoice/tokens) — no Tailwind. The
   only literals are values the token set does not cover: component dimensions (bar
   and input heights, content max-widths), the WCAG 44px target-size floor and the
   3px/2px focus ring, border widths, em-based letter-spacing, and the 2px optical
   alignment nudge on icon-beside-text rows.
   Mobile-first: base styles target ~375px; min-width queries expand up.

   AAA discipline baked in:
   - Body text pairs clear 7:1 (validated with a checker — see the build notes).
   - Interactive targets are ≥44×44 (SC 2.5.5).
   - Focus ring: 3px interactive.focus, 2px offset, never removed (SC 2.4.7/2.4.13).
   - prefers-reduced-motion disables non-essential transitions.
   ============================================================================ */

/* ---- Reset-ish base ---- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  font-family: var(--civic-font-family-body);
  font-size: var(--civic-font-size-lg); /* 17px — public app base */
  line-height: var(--civic-font-line-height-normal); /* 1.5 — AAA floor */
  color: var(--civic-text-primary);
  background: var(--civic-background-tint);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
img,
svg {
  max-width: 100%;
}
a {
  color: var(--civic-interactive-primary);
}
/* The UA's `[hidden] { display: none }` is a user-agent-origin rule, so ANY author
   `display` declaration outranks it in the cascade — `.btn { display: inline-flex }`
   would leave a `hidden` button fully visible. Restate it in the author origin so the
   attribute means what it says everywhere (the directory's "Load more" depends on it). */
[hidden] {
  display: none !important;
}

/* ---- Accessibility utilities ---- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--civic-space-2);
  top: calc(-1 * var(--civic-space-16));
  z-index: 100;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--civic-space-2) var(--civic-space-4);
  background: var(--civic-surface-raised);
  color: var(--civic-interactive-primary);
  border: 1px solid var(--civic-border-strong);
  border-radius: var(--civic-radius-sm);
  font-weight: var(--civic-font-weight-semibold);
  text-decoration: none;
  transition: top var(--civic-motion-duration-fast) var(--civic-motion-easing-out);
}
.skip-link:focus-visible {
  top: var(--civic-space-2);
}

/* ---- Focus ring — global, never removed ---- */
:focus-visible {
  outline: 3px solid var(--civic-interactive-focus);
  outline-offset: 2px;
}
/* Summary carries its own focus target; keep the ring tight to the button box. */
summary:focus-visible {
  outline-offset: 2px;
}

/* ============================================================================
   Platform top bar
   ============================================================================ */
.site-header {
  background: var(--civic-background-default);
  border-bottom: 1px solid var(--civic-border-subtle);
  position: sticky;
  top: 0;
  z-index: 30;
}
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--civic-space-3);
  min-height: 56px;
  padding: var(--civic-space-2) var(--civic-space-5);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--civic-space-2);
  text-decoration: none;
  color: var(--civic-text-primary);
  min-height: 44px;
}
/* The Rotunda platform mark — mono ink on the light platform chrome. Brand-owned,
   never tenant-tinted. Sizing comes from the inline SVG's width/height attrs. */
.brand-mark {
  flex-shrink: 0;
  color: var(--civic-brand-mark);
}
.brand-wordmark {
  font-family: var(--civic-font-family-display);
  font-weight: var(--civic-font-weight-medium);
  font-size: var(--civic-font-size-lg);
  letter-spacing: 0.005em; /* brand wordmark spec (Source Serif 4, 500) */
  color: var(--civic-text-primary);
}

/* Inline nav (wide) vs compact nav (mobile) */
.topbar-inline {
  display: none;
  align-items: center;
  gap: var(--civic-space-1);
}
.topbar-compact {
  display: inline-flex;
  align-items: center;
  gap: var(--civic-space-1);
}

.topbar-link {
  display: inline-flex;
  align-items: center;
  gap: var(--civic-space-2);
  min-height: 44px;
  padding: 0 var(--civic-space-3);
  border-radius: var(--civic-radius-sm);
  color: var(--civic-text-primary);
  text-decoration: none;
  font-size: var(--civic-font-size-sm);
  font-weight: var(--civic-font-weight-medium);
  transition: background var(--civic-motion-duration-fast) var(--civic-motion-easing-out);
}
.topbar-link:hover {
  background: var(--civic-background-sunken);
}
.topbar-link.is-current {
  font-weight: var(--civic-font-weight-semibold);
}
.topbar-link.is-current::after {
  content: "";
  width: var(--civic-space-1);
  height: var(--civic-space-1);
  border-radius: var(--civic-radius-pill);
  background: var(--civic-text-primary);
  margin-left: var(--civic-space-1);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: var(--civic-space-2);
  border: none;
  background: transparent;
  border-radius: var(--civic-radius-sm);
  color: var(--civic-text-primary);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--civic-motion-duration-fast) var(--civic-motion-easing-out);
}
.icon-btn:hover {
  background: var(--civic-background-sunken);
}

/* ---- Disclosure menus: one grammar, three anchors ---- */
/* The mobile menu, the language selector, and the feature-nav dropdowns are all native
   <details> disclosures, so they share the trigger reset (no marker, pointer cursor) and
   the sheet's surface treatment. enhance.js layers Escape / outside-click dismissal on
   all three; with JS off they still open and close from their own summary. Only the
   anchor edge and the sheet's width differ — those stay per-menu below. */
.topbar-menu,
.lang-menu,
.nav-menu {
  position: relative;
}
.topbar-menu > summary,
.lang-menu > summary,
.nav-menu > summary {
  list-style: none;
  cursor: pointer;
}
.topbar-menu > summary::-webkit-details-marker,
.lang-menu > summary::-webkit-details-marker,
.nav-menu > summary::-webkit-details-marker {
  display: none;
}

/* Mobile disclosure menu (works without JS) */
/* The sheet is absolutely positioned inside a sticky header, so anything past the
   viewport bottom can never be scrolled to — cap it and scroll inside instead. The
   organisations nav pushes this well past a short phone's height. */
.topbar-menu-sheet {
  position: absolute;
  right: 0;
  top: calc(100% + var(--civic-space-2));
  z-index: 40;
  width: min(78vw, 320px);
  max-height: min(70vh, 540px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--civic-space-2);
  padding: var(--civic-space-3);
  background: var(--civic-surface-raised);
  border: 1px solid var(--civic-border-subtle);
  border-radius: var(--civic-radius-md);
  box-shadow: var(--civic-shadow-lg);
}
.topbar-menu-link {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--civic-space-3);
  border-radius: var(--civic-radius-sm);
  color: var(--civic-text-primary);
  text-decoration: none;
  font-size: var(--civic-font-size-md);
  font-weight: var(--civic-font-weight-medium);
}
.topbar-menu-link:hover {
  background: var(--civic-background-sunken);
}

/* ---- Dropdown sheets: language selector + feature-nav (organisations header) ---- */
/* Same sheet, two anchors. The language sheet hangs off the trigger's RIGHT edge (it
   sits at the end of both bars, so a left anchor would run off-screen); the feature-nav
   sheet hangs off the LEFT edge, because nav items are left-aligned. Both cap their
   height and scroll internally — the header is sticky, so anything past the viewport
   bottom is otherwise unreachable. */
.lang-menu-sheet,
.nav-menu-sheet {
  position: absolute;
  z-index: 40;
  width: max-content;
  min-width: 200px;
  max-width: min(80vw, 280px);
  max-height: min(70vh, 540px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--civic-space-1);
  padding: var(--civic-space-2);
  background: var(--civic-surface-raised);
  border: 1px solid var(--civic-border-subtle);
  border-radius: var(--civic-radius-md);
  box-shadow: var(--civic-shadow-lg);
}
.lang-menu-sheet {
  right: 0;
  top: calc(100% + var(--civic-space-2));
}
/* Flush under the trigger (no gap) so the pointer crosses no dead-zone on the way in —
   enhance.js opens these on hover for pointer users. */
.nav-menu-sheet {
  left: 0;
  top: 100%;
}

.lang-option,
.nav-option {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 44px;
  padding: 0 var(--civic-space-3);
  border: none;
  border-radius: var(--civic-radius-sm);
  background: transparent;
  color: var(--civic-text-primary);
  text-align: left;
  text-decoration: none;
  font-family: var(--civic-font-family-body);
  font-size: var(--civic-font-size-md);
  font-weight: var(--civic-font-weight-medium);
  white-space: nowrap;
  cursor: pointer;
}
.lang-option:hover,
.nav-option:hover {
  background: var(--civic-background-sunken);
}
/* Current option — info-tint surface + info-text ink (AAA: info-700 on info-50). */
.lang-option[aria-current="true"],
.nav-option.is-current {
  background: var(--civic-feedback-info-tint);
  color: var(--civic-feedback-info-text);
  font-weight: var(--civic-font-weight-semibold);
}

/* The caret sits after a feature-nav label; rotate it when the dropdown is open. */
.nav-caret {
  margin-left: var(--civic-space-1);
  transition: transform var(--civic-motion-duration-fast) var(--civic-motion-easing-out);
}
.nav-menu[open] > summary .nav-caret {
  transform: rotate(180deg);
}

/* Mobile menu sheet: a category label + its indented child links (no nested menus).
   The group is a real role="group" wrapper, so it carries its own flex layout. */
.topbar-menu-group-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--civic-space-2);
}
.topbar-menu-group {
  margin: 0;
  padding: 0 var(--civic-space-3);
  font-size: var(--civic-font-size-sm);
  font-weight: var(--civic-font-weight-semibold);
  color: var(--civic-text-secondary);
}
.topbar-menu-sub {
  padding-left: var(--civic-space-5);
  font-size: var(--civic-font-size-sm);
}

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--civic-space-2);
  min-height: 44px;
  padding: 0 var(--civic-space-4);
  border-radius: var(--civic-radius-sm);
  font-family: var(--civic-font-family-body);
  font-size: var(--civic-font-size-sm);
  font-weight: var(--civic-font-weight-semibold);
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  transition:
    background var(--civic-motion-duration-fast) var(--civic-motion-easing-out),
    border-color var(--civic-motion-duration-fast) var(--civic-motion-easing-out);
}
.btn-block {
  width: 100%;
}
.btn-primary {
  background: var(--civic-interactive-primary);
  color: var(--civic-text-on-inverse);
  border-color: var(--civic-interactive-primary);
}
.btn-primary:hover {
  background: var(--civic-interactive-primary-hover);
  border-color: var(--civic-interactive-primary-hover);
}
.btn-ghost {
  background: transparent;
  color: var(--civic-text-primary);
  border-color: var(--civic-border-strong);
}
.btn-ghost:hover {
  background: var(--civic-background-sunken);
}
.btn-ai {
  background: var(--civic-ai-touched-text);
  color: var(--civic-text-on-inverse);
  border-color: var(--civic-ai-touched-text);
  font-size: var(--civic-font-size-md);
}
.btn-ai:hover {
  background: var(--civic-interactive-primary);
  border-color: var(--civic-interactive-primary);
}

/* ============================================================================
   Page layout
   ============================================================================ */
.site-main {
  display: block;
}
.wrap {
  width: 100%;
  max-width: 780px;
  margin: 0 auto;
  padding: 0 var(--civic-space-5);
}
.landing {
  padding-top: var(--civic-space-6);
  padding-bottom: var(--civic-space-10);
}
.section {
  margin-bottom: var(--civic-space-8);
}

/* Stub-page back link — a standalone nav target, sized to the 44px floor (SC 2.5.5). */
.stub-back {
  display: inline-flex;
  align-items: center;
  gap: var(--civic-space-2);
  min-height: 44px;
  margin-top: var(--civic-space-4);
  color: var(--civic-interactive-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---- Hero ---- */
.hero {
  margin-bottom: var(--civic-space-6);
}
.hero-title {
  font-family: var(--civic-font-family-display);
  font-weight: var(--civic-font-weight-medium);
  font-size: var(--civic-font-size-3xl);
  line-height: var(--civic-font-line-height-tight);
  color: var(--civic-text-primary);
  margin: 0 0 var(--civic-space-3);
}
.hero-sub {
  font-size: var(--civic-font-size-lg);
  color: var(--civic-text-secondary);
  line-height: var(--civic-font-line-height-normal);
  margin: 0;
}

/* Responsive copy swap (mobile string is the base) */
.copy-wide {
  display: none;
}
.copy-mobile {
  display: inline;
}

/* ---- Primary search ---- */
.search {
  margin-bottom: var(--civic-space-2);
}
.search-field {
  position: relative;
  display: block;
}
.search-icon {
  position: absolute;
  left: var(--civic-space-4);
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  color: var(--civic-text-muted);
  pointer-events: none;
}
.search-input {
  width: 100%;
  min-height: 52px;
  padding: var(--civic-space-3) var(--civic-space-4) var(--civic-space-3) var(--civic-space-12);
  font-family: var(--civic-font-family-body);
  font-size: var(--civic-font-size-lg);
  color: var(--civic-text-primary);
  background: var(--civic-surface-raised);
  border: 2px solid var(--civic-border-strong);
  border-radius: var(--civic-radius-md);
  box-shadow: var(--civic-shadow-sm);
}
.search-input::placeholder {
  color: var(--civic-text-muted);
}
.search-input:hover {
  border-color: var(--civic-text-secondary);
}
.search-helper {
  margin: var(--civic-space-2) 0 0;
  font-size: var(--civic-font-size-sm);
  color: var(--civic-text-muted);
}

/* ============================================================================
   Location panel — AI-touched tone
   ============================================================================ */
.loc-panel {
  background: var(--civic-ai-touched-tint);
  border: 1px solid var(--civic-ai-touched-border);
  border-radius: var(--civic-radius-md);
  overflow: hidden;
  color: var(--civic-ai-touched-text);
}
.loc-row {
  display: flex;
  align-items: flex-start;
  gap: var(--civic-space-3);
  padding: var(--civic-space-4);
}
.loc-icon {
  display: inline-flex;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--civic-ai-touched-text);
}
.loc-body {
  flex: 1;
  min-width: 0;
}
.loc-text {
  margin: 0;
  font-size: var(--civic-font-size-sm);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-ai-touched-text);
}
.loc-text strong {
  font-weight: var(--civic-font-weight-semibold);
}
.loc-link {
  color: var(--civic-ai-touched-text);
  font-weight: var(--civic-font-weight-semibold);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}
.loc-divider {
  height: 1px;
  margin: 0 var(--civic-space-4);
  background: var(--civic-ai-touched-border);
}
.loc-prompt {
  margin: 0 0 var(--civic-space-2);
  font-size: var(--civic-font-size-sm);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-ai-touched-text);
}
.loc-prompt strong {
  font-weight: var(--civic-font-weight-semibold);
}
.loc-address-row {
  display: flex;
  flex-direction: column;
  gap: var(--civic-space-2);
  margin-bottom: var(--civic-space-2);
}
.loc-input {
  width: 100%;
  min-height: 44px;
  padding: var(--civic-space-2) var(--civic-space-3);
  font-family: var(--civic-font-family-body);
  font-size: var(--civic-font-size-md);
  color: var(--civic-text-primary);
  background: var(--civic-surface-raised);
  border: 1px solid var(--civic-ai-touched-border);
  border-radius: var(--civic-radius-sm);
}
.loc-input::placeholder {
  color: var(--civic-text-muted);
}
.loc-privacy {
  margin: 0;
  font-size: var(--civic-font-size-xs);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-ai-touched-text);
}
.loc-privacy a {
  color: var(--civic-ai-touched-text);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}

/* ============================================================================
   Browse by type
   ============================================================================ */
.section-label {
  margin: 0 0 var(--civic-space-3);
  font-size: var(--civic-font-size-xs);
  font-weight: var(--civic-font-weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--civic-text-muted);
}
.browse-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--civic-space-2);
}
/* Shared link-card surface. The homepage Browse-by-type cards and the directory rows on
   /browse/<type>/ are the same component with different internal layout, so the surface,
   border, radius and hover live here once — a restyle can't move one and leave the other. */
.browse-card,
.tenant-row {
  background: var(--civic-surface-raised);
  border: 1px solid var(--civic-border-subtle);
  border-radius: var(--civic-radius-md);
  text-decoration: none;
  transition:
    background var(--civic-motion-duration-normal) var(--civic-motion-easing-out),
    border-color var(--civic-motion-duration-normal) var(--civic-motion-easing-out);
}
.browse-card:hover,
.tenant-row:hover {
  background: var(--civic-background-tint);
  border-color: var(--civic-border-strong);
}
.browse-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--civic-space-3);
  /* Fill the grid cell. The <li> grid items already stretch to the tallest card in
     their row; height:100% passes that height down to the card itself, so a card whose
     title wraps to two lines ("State & federal government", "Non-profits & other
     organisations") no longer leaves its row-mates short. */
  height: 100%;
  /* A comfortable floor for the two-line card. The no-reflow guarantee is NOT this number:
     it lives on `.browse-count` below, which keeps its line box whether or not a count ever
     arrives. Reserving on the card instead only worked for a one-line title — a title that
     wraps ("State & federal government", "Non-profits & other organisations") already
     exceeds any fixed floor, so those cards jumped the moment the numbers landed, which is
     the exact thing the reservation exists to prevent. */
  min-height: 76px;
  padding: var(--civic-space-3) var(--civic-space-4);
}
.browse-title {
  display: block;
  margin: 0;
  font-size: var(--civic-font-size-md);
  font-weight: var(--civic-font-weight-medium);
  color: var(--civic-text-primary);
}
/* The count line always occupies its box, empty or not — that is what makes the number
   arriving a text change rather than a layout change, at any title length and at every
   breakpoint. directory.js writes the text and nothing else (see fillCount); it never
   toggles visibility, so there is no state where the card's height depends on whether
   /api/tenant answered. The gap between the two lines belongs here rather than to the
   title's margin-bottom, so the reserved line owns its own spacing. */
.browse-count {
  display: block;
  margin: var(--civic-space-1) 0 0;
  min-height: calc(var(--civic-font-size-sm) * var(--civic-font-line-height-normal));
  font-size: var(--civic-font-size-sm);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-text-muted);
}
.browse-chevron {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--civic-text-muted);
}

/* ============================================================================
   Tenant directory — Browse-by-type listing pages (/browse/<type>/)
   Rendered live, client-side, from /api/tenant (see client/directory.js). Fully
   token-driven, AAA: rows are ≥44px link targets, status text pairs clear 7:1,
   the "Load more" button reuses the 44px-floor .btn, motion honours reduce.
   ============================================================================ */
.directory-page {
  padding-top: var(--civic-space-5);
}
.crumb {
  margin: 0 0 var(--civic-space-2);
}
.crumb-link {
  display: inline-flex;
  align-items: center;
  gap: var(--civic-space-2);
  min-height: 44px;
  color: var(--civic-interactive-primary);
  text-decoration: none;
  font-size: var(--civic-font-size-sm);
  font-weight: var(--civic-font-weight-medium);
}
.crumb-link:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}
.directory-head {
  margin-bottom: var(--civic-space-6);
}

.directory {
  display: flex;
  flex-direction: column;
}
.tenant-list {
  list-style: none;
  margin: 0 0 var(--civic-space-4);
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--civic-space-2);
}
/* Surface, border and hover come from the shared .browse-card/.tenant-row rule above. */
.tenant-row {
  display: flex;
  flex-direction: column;
  gap: var(--civic-space-1);
  min-height: 44px;
  padding: var(--civic-space-4);
  /* Fill the grid cell, exactly as .browse-card does: summaries wrap to different line
     counts, and without this a card sits at its own content height inside an <li> the
     grid has already stretched, leaving its row-mates visibly short. */
  height: 100%;
}
.tenant-name {
  font-size: var(--civic-font-size-md);
  font-weight: var(--civic-font-weight-semibold);
  color: var(--civic-text-primary);
}
.tenant-meta {
  font-size: var(--civic-font-size-sm);
  color: var(--civic-text-muted);
}
.tenant-summary {
  font-size: var(--civic-font-size-sm);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-text-secondary);
}
.directory-status {
  margin: 0 0 var(--civic-space-3);
  font-size: var(--civic-font-size-sm);
  color: var(--civic-text-muted);
}
/* Error state: strongest ink + weight so the message reads clearly (7:1). */
.directory-status.is-error {
  color: var(--civic-text-primary);
  font-weight: var(--civic-font-weight-semibold);
}
/* While a page is in flight the button is aria-disabled rather than `disabled`, so it keeps
   keyboard focus (see client/directory.js). Match the pointer affordance to that state. */
.load-more[aria-disabled="true"] {
  cursor: default;
}
.directory-noscript {
  margin: 0;
  font-size: var(--civic-font-size-sm);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-text-secondary);
}
.directory-noscript a {
  color: var(--civic-interactive-primary);
  text-underline-offset: 2px;
}

/* ============================================================================
   Discover invitation — AI-touched tone
   ============================================================================ */
.invite {
  background: var(--civic-ai-touched-tint);
  border: 1px solid var(--civic-ai-touched-border);
  border-radius: var(--civic-radius-md);
  padding: var(--civic-space-4);
  display: grid;
  gap: var(--civic-space-3);
}
.invite-title {
  margin: 0 0 var(--civic-space-1);
  font-family: var(--civic-font-family-display);
  font-weight: var(--civic-font-weight-medium);
  font-size: var(--civic-font-size-lg);
  color: var(--civic-ai-touched-text);
}
.invite-body {
  margin: 0;
  font-size: var(--civic-font-size-sm);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-ai-touched-text);
}
.invite-cta {
  justify-self: stretch;
}

/* ============================================================================
   Sign-in row
   ============================================================================ */
.signin-row {
  background: var(--civic-surface-sunken);
  border: 1px solid var(--civic-border-subtle);
  border-radius: var(--civic-radius-md);
  padding: var(--civic-space-4);
  display: grid;
  gap: var(--civic-space-3);
}
.signin-title {
  margin: 0 0 var(--civic-space-1);
  font-size: var(--civic-font-size-md);
  font-weight: var(--civic-font-weight-semibold);
  color: var(--civic-text-primary);
}
.signin-body {
  margin: 0;
  font-size: var(--civic-font-size-sm);
  line-height: var(--civic-font-line-height-normal);
  color: var(--civic-text-secondary);
}
.signin-cta {
  justify-self: stretch;
}

/* ============================================================================
   About + trust stats
   ============================================================================ */
.about {
  background: var(--civic-surface-raised);
  border: 1px solid var(--civic-border-subtle);
  border-radius: var(--civic-radius-md);
  padding: var(--civic-space-5);
}
.about-heading {
  margin: 0 0 var(--civic-space-3);
  font-family: var(--civic-font-family-display);
  font-weight: var(--civic-font-weight-medium);
  font-size: var(--civic-font-size-xl);
  color: var(--civic-text-primary);
}
.about p {
  margin: 0 0 var(--civic-space-3);
  font-size: var(--civic-font-size-md);
  line-height: var(--civic-font-line-height-relaxed);
  color: var(--civic-text-secondary);
  max-width: 68ch;
}
.about p:last-of-type {
  margin-bottom: 0;
}

.trust {
  margin: var(--civic-space-5) 0 0;
  padding: var(--civic-space-4);
  background: var(--civic-background-tint);
  border-radius: var(--civic-radius-md);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--civic-space-4) var(--civic-space-3);
}
.trust-stat {
  text-align: left;
  margin: 0;
}
.trust dt,
.trust dd {
  margin: 0;
}
.browse-text {
  min-width: 0;
}
.trust-value {
  font-family: var(--civic-font-family-display);
  font-weight: var(--civic-font-weight-semibold);
  font-size: var(--civic-font-size-2xl);
  color: var(--civic-text-primary);
  line-height: var(--civic-font-line-height-tight);
}
.trust-label {
  margin: var(--civic-space-1) 0 0;
  font-size: var(--civic-font-size-xs);
  color: var(--civic-text-muted);
  line-height: var(--civic-font-line-height-normal);
}

/* ============================================================================
   Footer
   ============================================================================ */
.site-footer {
  background: var(--civic-surface-sunken);
  border-top: 1px solid var(--civic-border-subtle);
}
.footer-inner {
  max-width: 780px;
  margin: 0 auto;
  padding: var(--civic-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--civic-space-3);
  align-items: flex-start;
}
.footer-copy {
  font-size: var(--civic-font-size-sm);
  color: var(--civic-text-muted);
}
.footer-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--civic-space-1) var(--civic-space-3);
}
.footer-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--civic-space-2);
  font-size: var(--civic-font-size-sm);
  color: var(--civic-text-secondary);
  text-decoration: none;
}
.footer-nav a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============================================================================
   Breakpoints — mobile-first expansion
   ============================================================================ */
/* The organisations header carries a fuller feature nav, so it stays in the compact
   (disclosure-menu) layout longer than the member-facing header. Measured on the rendered
   page (Inter loaded): brand 125 + inline nav 797 + padding 64 + gap 12 = 998px to lay the
   row out on one line, so the lg token clears it with ~26px to spare. Below the fitting
   width the labels wrap to two lines *inside* the 44px pill, so min-height hides the break
   from any height check while it still looks broken on screen — which is why this wants a
   measured number, not a guessed one (the previous 960 was hand-tuned and 130px short).
   26px does not fit another nav item (the cheapest here costs ~95px) and will not survive
   translation, so re-measure before adding or lengthening one; the durable fix is
   collapsing on measured overflow (README).
   Higher specificity than the 640px rules below, so it wins where both match; at lg and
   above only those apply and the org nav goes inline too. */
@media (min-width: 640px) and (max-width: 1023.98px) {
  .topbar.is-org .topbar-inline {
    display: none;
  }
  .topbar.is-org .topbar-compact {
    display: inline-flex;
  }
}
@media (min-width: 640px) {
  .topbar {
    min-height: 64px;
    padding: var(--civic-space-3) var(--civic-space-8);
  }
  .topbar-inline {
    display: inline-flex;
  }
  .topbar-compact {
    display: none;
  }

  .copy-wide {
    display: inline;
  }
  .copy-mobile {
    display: none;
  }

  .landing {
    padding-top: var(--civic-space-10);
  }
  .section {
    margin-bottom: var(--civic-space-12);
  }
  .wrap {
    padding: 0 var(--civic-space-10);
  }

  /* Hero + search centre on wider screens */
  .hero {
    text-align: center;
    margin-bottom: var(--civic-space-8);
  }
  .hero-title {
    font-size: var(--civic-font-size-4xl);
    max-width: 20ch;
    margin-left: auto;
    margin-right: auto;
  }
  .hero-sub {
    max-width: 60ch;
    margin-left: auto;
    margin-right: auto;
  }

  .search {
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
  }
  .search-helper {
    text-align: center;
  }

  .loc-panel {
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
  }
  /* Address input + button sit side by side; privacy wraps below */
  .loc-address-row {
    flex-direction: row;
    align-items: stretch;
  }
  .loc-address-row .btn {
    flex-shrink: 0;
  }

  .section-label {
    text-align: center;
  }
  .browse-list {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--civic-space-3);
  }
  .browse-card {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--civic-space-1);
    min-height: 96px;
    padding: var(--civic-space-5);
  }
  .browse-chevron {
    display: none;
  }

  .directory-head {
    text-align: center;
  }
  .tenant-list {
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--civic-space-3);
    /* Every card the same height, not just every card within a row. In a grid whose own
       height is indefinite, `1fr` rows all resolve to the tallest row's content, so a
       two-line summary in the first row lifts the rest with it instead of leaving a
       ragged grid. Multi-column only — down one column it would just pad every card. */
    grid-auto-rows: 1fr;
  }
  /* Two lines, then an ellipsis — scoped to the same breakpoint as `grid-auto-rows: 1fr`,
     because the clamp exists only to bound it: without a cap one long summary would set the
     height of every card on the page, and "Load more" keeps adding chances for one. Below
     this breakpoint the list is a single column with no shared row height, so there is
     nothing to bound and clamping would only hide text that fits perfectly well. */
  .tenant-summary {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
  }
  /* Button hugs its label and centres, rather than stretching the full row. */
  .load-more {
    align-self: center;
    min-width: 220px;
  }

  /* Text left, CTA right */
  .invite {
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--civic-space-4);
    padding: var(--civic-space-5) var(--civic-space-6);
  }
  .invite-cta {
    justify-self: end;
  }
  .signin-row {
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--civic-space-4);
    padding: var(--civic-space-5) var(--civic-space-6);
  }
  .signin-cta {
    justify-self: end;
  }

  .about {
    padding: var(--civic-space-6) var(--civic-space-8);
  }
  .about-heading {
    font-size: var(--civic-font-size-2xl);
  }
  .trust-stat {
    text-align: center;
  }

  .footer-inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: var(--civic-space-6) var(--civic-space-8);
  }
}

@media (min-width: 1024px) {
  .hero-title {
    font-size: var(--civic-font-size-5xl);
  }
  /* Four fixed trust stats sit in one row on wide desktop, matching the
     wireframe. Narrower viewports keep the auto-fit(minmax(150px,1fr)) wrap. */
  .trust {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* ============================================================================
   Reduced motion — disable non-essential transitions (keep focus ring + reveal)
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
