/* expeal.com — starter styles.
   Structural scaffold styles. All design tokens flow from the vendored
   framework layer (/assets/css/fgl/tokens.css, with expeal.css as the
   override surface — @fgl/vituno adoption, Story 1.12.1); the local aliases
   below just re-point the scaffold's existing selectors at those tokens. */

:root {
  --color-bg: var(--surface-primary);
  --color-text: var(--ink-body);
  --color-muted: var(--ink-muted);
  --color-accent: var(--accent-info);
  --color-border: var(--border-subtle);
  --max-width: 64rem;
  --space: 1rem;
  /* --font, type scale, and --measure come from the framework token layer
     (/assets/css/fgl/tokens.css; expeal.css overrides — Story 1.12.1). */
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-text);
  background: var(--color-bg);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

a {
  color: var(--color-accent);
  /* The one baseline motion in the scaffold: a color-only hover transition.
     Permitted on EVERY surface — §8.3 forbids hover animation on disclosure
     surfaces "beyond color change", so color is the exception that's always OK.
     Uses --dur-hover so the reduced-motion rule (bottom of file) collapses it. */
  transition: color var(--dur-hover) var(--ease-out);
}

main {
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding: calc(var(--space) * 2) var(--space);
}

/* Skip link, .prose, sr-only, and the global reduced-motion kill-switch now
   ship in the framework's base.css (@fgl/vituno adoption, Story 1.12.1). */

/* Header / nav */
.site-header {
  border-bottom: 1px solid var(--color-border);
}
.site-header__inner {
  max-width: var(--max-width);
  margin-inline: auto;
  padding: var(--space);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space);
}
.site-header__brand {
  font-weight: 700;
  font-size: 1.25rem;
  text-decoration: none;
  color: var(--color-text);
}
.site-nav__list {
  display: flex;
  gap: var(--space);
  margin: 0;
  padding: 0;
}
.site-nav__list a {
  text-decoration: none;
}

/* Hero (home) */
.hero {
  position: relative;
  isolation: isolate; /* contain the ::before's z-index so it can't slip under other layers */
  text-align: center;
  padding-block: clamp(3rem, 12vw, 8rem);
}
/* Hero imagery reconciliation (§7.3 / gap G7 / Story 1.2.5).
   Per the imagery sourcing decision (2026-06-23): the life-after photo library
   is DEFERRED to launch; the build ships minimal imagery. hero.jpg's heavy fade
   — flagged by G7 as conflicting with §7.3 "no heavy filters" — is reconciled by
   treating the photo as an INTENTIONAL low-opacity background wash rather than a
   featured photo. At ~10% over the warm page surface it reads as faint texture,
   so the heavy fade becomes a deliberate choice and body/heading contrast is
   unaffected (the solid token pairs the contrast gate checks still govern text). */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("/assets/images/hero.jpg") center / cover no-repeat;
  opacity: 0.1;
  pointer-events: none;
}
.hero__title {
  font-size: var(--fs-display-1);
  line-height: var(--lh-display-1);
  font-weight: var(--fw-bold);
  margin: 0 0 0.5rem;
}
.hero__tagline {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--color-muted);
  margin: 0;
}

/* Footer */
.site-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--color-border);
  color: var(--color-muted);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
}
.site-footer__inner {
  max-width: var(--max-width);
  margin-inline: auto;
  padding: var(--space);
}

/* ── State-route stub scaffold (Story 1.3.3; Epic 1.4 replaces the layout) ────
   Moved here from inline style= attributes on _stub-state-page.njk so shipped
   pages honor the CSP's style-src 'self' (Story 2.9.2). Deliberately loud —
   the banner exists to be impossible to mistake for a real page. */
.scaffold { border: 2px dashed #b00; padding: 1rem; margin: 1rem; }
.scaffold__warning { font-weight: bold; color: #b00; }
/* components.css — SITE-SPECIFIC chrome styling. Since the @fgl/vituno
   adoption (Story 1.12.1) the census-promoted component rules — buttons, the
   topnav shell, hamburger/mobile-menu, the footer shell, and the shared focus
   ring (now the framework's zero-specificity :where() rule covering every
   interactive element) — live in the vendored /assets/css/fgl/ payload. Only
   rules the framework deliberately does NOT ship stay here (KB
   fgl-frontend-pattern: the switcher, the footer's site-authored bands). */

/* Sign-in link — site-specific nav element (not part of the framework topnav
   shell); accent-colored, unlike the framework's ink-body nav links. */
.topnav__signin { color: var(--accent-info); text-decoration: none; font-weight: var(--fw-semibold); }

/* State switcher (COMPONENT-SPEC "StateSwitcher") — the one shadowed chrome element */
.switcher { position: relative; }
/* min-height 48px (Story 2.3.8): the repo's own ≥48px buttons/inputs commitment —
   COMPONENT-SPEC's stray "Trigger: 40px" resolved toward its global rule. */
.switcher__trigger { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 48px; padding-inline: var(--space-3); border: 1px solid var(--border-subtle); border-radius: 8px; cursor: pointer; list-style: none; }
.switcher__trigger::-webkit-details-marker { display: none; }
.switcher__panel { position: absolute; z-index: 20; margin-top: var(--space-2); min-width: 280px; background: var(--surface-elevated); border: 1px solid var(--border-subtle); border-radius: 8px; box-shadow: var(--shadow-2); padding: var(--space-3); }
.switcher__heading { font-size: var(--fs-caption); font-weight: 700; color: var(--ink-muted); text-transform: uppercase; }
.switcher__row { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2); border-radius: 6px; text-decoration: none; color: var(--ink-body); min-height: 44px; }
.switcher__row:hover { background: var(--surface-primary); }
.switcher__row.is-current { font-weight: 700; color: var(--brand-primary); }
.switcher__filter-label { display: block; font-size: var(--fs-caption); font-weight: 700; margin-block-end: var(--space-1); }
.switcher__filter input { width: 100%; min-height: 48px; padding-inline: var(--space-3); border: 1px solid var(--border-strong); border-radius: 8px; }
/* Calm no-results row (COMPONENT-SPEC EmptyState register: not an error — no red). */
.switcher__empty { padding: var(--space-2); background: var(--surface-primary); border-radius: 6px; }
.switcher__list { max-height: 320px; overflow: auto; }
.switcher__directory { display: inline-block; margin-top: var(--space-2); color: var(--accent-info); font-weight: 700; text-decoration: none; }
/* Story 2.3.10 (WCAG 1.4.10 reflow): below the nav-collapse breakpoint the open panel
   pins to the viewport with side gutters — a 320px screen (or a zoomed-in viewport,
   which shrinks into the same range) must never horizontal-scroll to reach the state
   list or its type-to-filter. 47.999rem pairs with the framework's md constant
   (48rem — the fgl nav.css teardown query). Regression
   coverage: Story 2.3.11's zoom/reflow pass (Sprint 2) re-measures this. */
@media (max-width: 47.999rem) {
  .switcher__panel { position: fixed; left: var(--space-3); right: var(--space-3); min-width: 0; }
  /* The nav ROW must fit too (surfaced once the panel stopped masking it): the
     trigger is the row's one shrinkable element — ellipsize its label rather than
     push the hamburger past the viewport edge. */
  .topnav__switcher { min-width: 0; flex: 1 1 auto; }
  .switcher__trigger { max-width: 100%; }
  .switcher__current { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* Footer — the site-authored bands (COMPONENT-SPEC "SiteFooter"; the framework
   ships only the shell + link grid, KB fgl-frontend-pattern). */
.footer__crisis { background: var(--brand-primary); color: #fff; padding-block: var(--space-5); }
.footer__crisis-lead { font-weight: 700; font-size: var(--fs-body-lg); }
/* 988 is a real tel: link (Story 2.3.4): inherit keeps it white on the purple band
   (the verified white/brand-primary contrast pair); focus outline in currentColor so
   the indicator is visible against the purple, not the accent blue. box-shadow:none
   opts OUT of the framework's global :where() focus ring here — the ring's accent
   blue is unverified against the purple band (the Story 2.3.6 extension decision,
   preserved through the adoption). */
.footer__988 { color: inherit; text-decoration: underline; }
.footer__988:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; box-shadow: none; }
.footer__anti { background: var(--surface-primary); border-block: 1px solid var(--border-subtle); padding-block: var(--space-4); color: var(--ink-muted); }

/* Motion: dropdown 200ms on the full surface only; none on disclosure or reduced-motion */
@media (prefers-reduced-motion: no-preference) {
  .topnav:not(.topnav--minimal) .switcher__panel { transition: opacity var(--dur-panel, 200ms) var(--ease-out); }
}