/* =============================================================================
   style.css — component & layout styles.
   Loads AFTER tokens.css. Uses ONLY semantic tokens (--color-*, --space-*,
   --radius-*, --shadow-*, --text-*) — never raw palette primitives or hex.
   ========================================================================== */

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--color-primary); }

img { max-width: 100%; display: block; }

h1, h2, h3 { line-height: var(--leading-tight); letter-spacing: -0.01em; font-weight: var(--weight-bold); }

/* Accessible focus ring for keyboard users on every interactive element. */
:focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Skip link for keyboard/screen-reader users. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  z-index: 100;
}
.skip-link:focus { left: var(--space-3); top: var(--space-3); }

/* --- Layout container ---------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--maxw-content);
  margin-inline: auto;
  padding-inline: var(--space-gutter);
}

/* --- Header / nav -------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--color-surface) 90%, transparent);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--color-border);
  transition: background var(--motion-base) var(--ease-in-out),
              border-color var(--motion-base) var(--ease-in-out),
              box-shadow var(--motion-base) var(--ease-in-out);
}
.site-header .container {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 64px;
  gap: var(--space-3);
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-text);
  text-decoration: none;
}
.brand-logo {
  display: flex;
  align-items: center;
  height: 44px;
  flex: 0 0 auto;
}
.brand-logo-img { display: block; }
.brand-logo-img img { width: auto; height: 44px; display: block; }
/* The dark mark reads on the solid cream header; the reverse mark is reserved
   for the transparent state over the dark hero (swapped in below). */
.brand-logo-light { display: none; }
.brand-name {
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  line-height: 1.08;
  letter-spacing: -0.01em;
}
/* Legacy text badge (kept for compatibility / no-image fallback). */
.brand-mark {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  font-weight: var(--weight-black);
}

/* --- Sticky header scroll states (docs/07 §6) ---------------------------- */
/* On the home page the header starts transparent and fixed over the full-bleed
   hero, then solidifies once the hero is scrolled past (toggled by header.js).
   On every other page the header is the solid sticky bar above.
   The transparent appearance is gated under html.js: without JS (so without the
   scroll-solidify behaviour) the header stays the solid sticky bar, keeping the
   nav legible below the hero. */
.js .site-header.is-transparent {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
  box-shadow: none;
}
.js .site-header.is-transparent .brand-name {
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
.js .site-header.is-transparent .nav-toggle {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.55);
}
.js .site-header.is-transparent .nav-toggle-bar { background: #fff; }
/* Over the dark hero show the reverse (light) mark; once solidified (scrolled or
   menu open) the default dark mark applies again via the base rule. */
.js .site-header.is-transparent:not(.is-scrolled):not(:has(.nav-links.is-open)) .brand-logo-dark { display: none; }
.js .site-header.is-transparent:not(.is-scrolled):not(:has(.nav-links.is-open)) .brand-logo-light { display: block; }
/* Gold focus ring reads clearly (≥3:1) against the dark hero. */
.js .site-header.is-transparent :focus-visible { outline-color: var(--color-accent); }

/* Solidified: scrolled past the hero, OR the mobile menu is open. */
.js .site-header.is-transparent.is-scrolled,
.js .site-header.is-transparent:has(.nav-links.is-open) {
  background: color-mix(in srgb, var(--color-surface) 92%, transparent);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom-color: var(--color-border);
  box-shadow: var(--shadow-sm);
}
.js .site-header.is-transparent.is-scrolled .brand-name,
.js .site-header.is-transparent:has(.nav-links.is-open) .brand-name {
  color: var(--color-text);
  text-shadow: none;
}
.js .site-header.is-transparent.is-scrolled .nav-toggle,
.js .site-header.is-transparent:has(.nav-links.is-open) .nav-toggle {
  background: var(--color-bg);
  border-color: var(--color-border);
}
.js .site-header.is-transparent.is-scrolled .nav-toggle-bar,
.js .site-header.is-transparent:has(.nav-links.is-open) .nav-toggle-bar {
  background: var(--color-text);
}

/* Inline nav links (desktop) ride white over the hero, then go dark on scroll.
   Scoped to ≥768px so the mobile dropdown panel always keeps dark links. */
@media (min-width: 768px) {
  .js .site-header.is-transparent .nav-link,
  .js .site-header.is-transparent .nav-link:hover {
    color: #fff;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  }
  .js .site-header.is-transparent.is-scrolled .nav-link,
  .js .site-header.is-transparent:has(.nav-links.is-open) .nav-link {
    color: var(--color-text);
    text-shadow: none;
  }
  .js .site-header.is-transparent.is-scrolled .nav-link:hover,
  .js .site-header.is-transparent:has(.nav-links.is-open) .nav-link:hover {
    color: var(--color-primary);
  }
}

/* --- Mobile-first nav + hamburger ---------------------------------------- */
/* No-JS fallback: the toggle stays hidden and the nav shows inline (wrapping).
   When JS is present (html.js), the toggle appears on small screens and the
   nav collapses into a dropdown panel until opened. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.js .nav-toggle { display: inline-flex; }
.nav-toggle-box { position: relative; width: 22px; height: 16px; display: inline-block; }
.nav-toggle-bar {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-text);
  border-radius: 2px;
  transition: transform var(--transition-base), opacity var(--transition-base);
}
.nav-toggle-bar:nth-child(1) { top: 0; }
.nav-toggle-bar:nth-child(2) { top: 7px; }
.nav-toggle-bar:nth-child(3) { top: 14px; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav-links {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}
/* JS: collapse into a dropdown panel under the header on small screens. */
.js .nav-links {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-2);
  padding: var(--space-4);
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-md);
}
.js .nav-links.is-open { display: flex; }
.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  color: var(--color-text);
  font-weight: var(--weight-medium);
  text-decoration: none;
  border-radius: var(--radius-sm);
}
.nav-link:hover { color: var(--color-primary); }

/* --- Button component ---------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px; /* comfortable mobile tap target */
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-pill);
  font-weight: var(--weight-medium);
  font-size: var(--text-base);
  line-height: 1.2;
  text-decoration: none;
  text-align: center;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--transition-fast),
              background var(--transition-base),
              box-shadow var(--transition-base),
              border-color var(--transition-base);
}
.btn-block { display: flex; width: 100%; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--color-primary); color: var(--color-primary-contrast); }
.btn-primary:hover { background: var(--color-primary-hover); box-shadow: var(--shadow-md); }
.btn-secondary {
  background: transparent;
  color: var(--color-primary);
  border-color: var(--color-border);
}
.btn-secondary:hover { border-color: var(--color-primary); }
.btn-accent { background: var(--color-accent); color: var(--color-accent-contrast); }
.btn-accent:hover { background: var(--color-accent-hover); box-shadow: var(--shadow-md); }
.btn-lg { padding: var(--space-4) var(--space-6); font-size: var(--text-lg); }
.btn[aria-disabled="true"] { opacity: 0.6; cursor: not-allowed; }

/* Desktop-only hover lift (touch devices skip it to avoid stuck-hover states). */
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover,
  .btn-accent:hover { transform: translateY(-2px); }
}

/* --- Hero component ------------------------------------------------------ */
.hero {
  background: linear-gradient(160deg, var(--color-surface) 0%, var(--color-surface-2) 100%);
  border-bottom: 1px solid var(--color-border);
}
.hero-inner { padding: var(--space-7) 0; text-align: center; }
.eyebrow {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  /* Coffee (primary) meets AA on the light cream/white backgrounds.
     Over the dark hero the eyebrow gets a translucent chip (see hero rules). */
  color: var(--color-primary);
  margin-bottom: var(--space-4);
}
.hero h1 { font-size: var(--text-4xl); margin: 0 0 var(--space-4); }
.lede {
  font-size: var(--text-xl);
  color: var(--color-text-muted);
  max-width: var(--maxw-narrow);
  margin: 0 auto var(--space-6);
}
.cta-row { display: flex; gap: var(--space-3); justify-content: center; flex-wrap: wrap; }

/* --- Full-bleed home hero (docs/06 §4 · docs/07 §5) ---------------------- */
.hero--home {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 86vh;
  padding: var(--space-9) 0 var(--space-8);
  overflow: hidden;
  border-bottom: 0;
  background: var(--green-900);     /* fallback colour behind the photo */
  isolation: isolate;
}
@supports (height: 100svh) { .hero--home { min-height: 86svh; } }

.hero-media { position: absolute; inset: 0; z-index: -2; }
.hero-img { width: 100%; height: 100%; object-fit: cover; object-position: center; }

/* Rotating hero: every .hero-slide stacks in the media box and crossfades via
   opacity (driven by hero.js toggling .is-active). The active slide is opaque,
   the rest wait at zero. A lone slide / the single-image fallback is simply
   always active, so it paints solid immediately (good for LCP). */
.hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--motion-slower) var(--ease-in-out);
}
.hero-slide.is-active { opacity: 1; }

/* Gentle Ken-Burns breathing zoom on the visible slide — compositor-only
   transform, off for reduced-motion (and the kenburns token collapses to 1ms
   there too). */
@media (prefers-reduced-motion: no-preference) {
  .hero-slide.is-active {
    will-change: transform;
    animation: hero-kenburns var(--motion-kenburns) var(--ease-in-out) infinite alternate;
  }
}
@keyframes hero-kenburns {
  from { transform: scale(1.001); }
  to   { transform: scale(1.07); }
}

/* Reduced motion: no crossfade and no zoom — just present the first slide. */
@media (prefers-reduced-motion: reduce) {
  .hero-slide { transition: none; }
  .hero-slide:not(.is-active) { display: none; }
}

/* Dark gradient overlay — darker at the top (header legibility) and bottom
   (CTA/headline legibility) so white text meets AA over the photo. */
.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
      rgba(23, 22, 20, 0.62) 0%,
      rgba(23, 22, 20, 0.42) 42%,
      rgba(23, 22, 20, 0.52) 72%,
      rgba(23, 22, 20, 0.82) 100%);
}

.hero--home .hero-inner { width: 100%; padding: 0; text-align: center; color: #fff; }
/* The eyebrow rides over rotating photos, so give it a translucent chip to hold
   contrast on any frame (keeps the light text legible regardless of the image). */
.hero--home .eyebrow {
  color: var(--color-on-feature);
  background: rgba(23, 22, 20, 0.55);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
}
@supports (backdrop-filter: blur(4px)) {
  .hero--home .eyebrow { backdrop-filter: blur(4px); }
}
.hero--home .hero-title {
  font-size: var(--text-4xl);
  font-weight: var(--weight-display);
  letter-spacing: -0.02em;
  margin: 0 0 var(--space-5);
  color: #fff;
  text-wrap: balance;
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.32);
}
.hero--home .hero-title .line { display: block; }
.hero--home .hero-lede {
  font-size: var(--text-xl);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.94);
  max-width: 46rem;
  margin: 0 auto var(--space-6);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.hero--home .hero-note {
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.88);
  max-width: 40rem;
  margin: var(--space-6) auto 0;
}

/* Hero CTAs ride over the photo, so lift them off it: bigger, bolder, with a
   clear drop shadow. The primary is a solid near-white chip (coffee text) for
   maximum contrast on any frame; the secondary is a glassy, strongly-bordered
   fill so it never reads as a faint ghost. Scoped to the home hero so the
   site-wide buttons are untouched; hover colour overrides sit outside the
   hover query so a stray tap can't flash the default coffee fill. */
.hero--home .cta-row .btn {
  padding: var(--space-4) var(--space-7);
  font-size: var(--text-lg);
  font-weight: var(--weight-black);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}
.hero--home .cta-row .btn:focus-visible { outline-color: #fff; }
.hero--home .btn-primary {
  background: #fff;
  color: var(--color-primary);
  border-color: #fff;
}
.hero--home .btn-primary:hover {
  background: #f3ede4;
  color: var(--color-primary-hover);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}
.hero--home .btn-accent {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.82);
}
.hero--home .btn-accent:hover {
  background: rgba(255, 255, 255, 0.28);
  border-color: #fff;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}
@supports (backdrop-filter: blur(6px)) {
  .hero--home .btn-accent { backdrop-filter: blur(6px); }
}

/* Anchor targets clear the fixed/sticky header on in-page jumps. */
[id] { scroll-margin-top: calc(64px + var(--space-4)); }

/* =============================================================================
   Scroll reveal (docs/07 §3) — declarative [data-reveal] variants.
   The hidden/pre-reveal state is scoped under .js, so with JS disabled the
   content shows normally. If reveal.js fails to load, the inline <head> safety
   net adds .no-reveal to force everything visible. reveal.js adds .is-revealed
   when an element scrolls into view (reveal-once).
   ========================================================================== */
.js [data-reveal] {
  opacity: 0;
  transition: opacity var(--motion-base) var(--ease-out),
              transform var(--motion-base) var(--ease-out);
}
.js [data-reveal].is-revealed { opacity: 1; transform: none; }

.js [data-reveal="fade-up"]  { transform: translateY(var(--reveal-distance)); }
.js [data-reveal="scale-in"] { transform: scale(var(--reveal-scale)); }

.js [data-reveal="image-reveal"] { opacity: 1; } /* the clip wipe does the reveal */
/* Clip the inner media, NOT the observed [data-reveal] figure. A figure clipped
   with inset(... 100% ...) collapses to zero area, so IntersectionObserver
   reports ratio 0 and never fires — the image then stays permanently clipped
   (loaded but invisible). Keeping the figure unclipped lets the observer reveal
   it like any other variant; the wipe runs on the image instead. */
.js [data-reveal="image-reveal"] > img {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--motion-slow) var(--ease-out);
}
.js [data-reveal="image-reveal"].is-revealed > img { clip-path: inset(0 0 0 0); }

/* Staggered group: parent visible, its direct children cascade in. */
.js [data-reveal="fade-up-stagger"] { opacity: 1; transform: none; transition: none; }
.js [data-reveal="fade-up-stagger"] > * {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition: opacity var(--motion-base) var(--ease-out),
              transform var(--motion-base) var(--ease-out);
}
.js [data-reveal="fade-up-stagger"].is-revealed > * { opacity: 1; transform: none; }

/* Heading reveal: lines (or words) cascade in; parent visible. */
.js [data-reveal="heading-lines"],
.js [data-reveal="heading-words"] { opacity: 1; transform: none; transition: none; }
.js [data-reveal="heading-lines"] .line,
.js [data-reveal="heading-words"] .word {
  opacity: 0;
  transform: translateY(var(--reveal-distance-sm));
  transition: opacity var(--motion-slow) var(--ease-out),
              transform var(--motion-slow) var(--ease-out);
}
.js [data-reveal="heading-lines"] .line { display: block; }
.js [data-reveal="heading-words"] .word { display: inline-block; }
.js [data-reveal="heading-lines"].is-revealed .line,
.js [data-reveal="heading-words"].is-revealed .word { opacity: 1; transform: none; }

/* Safety net — force everything visible if the engine never claimed the page. */
.no-reveal [data-reveal],
.no-reveal [data-reveal] > *,
.no-reveal [data-reveal] .line,
.no-reveal [data-reveal] .word {
  opacity: 1 !important;
  transform: none !important;
  clip-path: none !important;
}

/* --- Section component --------------------------------------------------- */
.section { padding: var(--space-section) 0; }
.section-alt { background: var(--color-surface); }
.section h2 { font-size: var(--text-3xl); margin: 0 0 var(--space-2); }
.section .sub { color: var(--color-text-muted); max-width: var(--maxw-narrow); margin-bottom: var(--space-6); }
.section-center { text-align: center; }
.section-center .sub { margin-inline: auto; }

/* --- Card component ------------------------------------------------------ */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-5);
}
.card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  box-shadow: var(--shadow-md);
}
.card h3 { margin: 0 0 var(--space-2); font-size: var(--text-xl); }
.card p { margin: 0; color: var(--color-text-muted); }

/* --- CTA block component ------------------------------------------------- */
.cta-block {
  text-align: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-5);
}
.cta-block h2 { font-size: var(--text-2xl); margin: 0 0 var(--space-2); }
.cta-block p { color: var(--color-text-muted); max-width: var(--maxw-narrow); margin: 0 auto var(--space-5); }

/* --- Placeholder marker (for unknown content) ---------------------------- */
.placeholder {
  display: inline-block;
  background: var(--color-placeholder-bg);
  border: 1px dashed var(--color-placeholder-border);
  color: var(--color-placeholder-text);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.45em;
  font-size: 0.85em;
  font-weight: var(--weight-medium);
}

/* --- Form-field component ------------------------------------------------ */
.form-wrap {
  max-width: var(--maxw-narrow);
  margin-inline: auto;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  box-shadow: var(--shadow-lg);
}
.field { margin-bottom: var(--space-5); }
.field label { display: block; font-weight: var(--weight-medium); margin-bottom: var(--space-2); }
.field .req { color: var(--color-error-text); }
/* Boxed fields: a white fill over the cream form card + a clear border so inputs
   read as obvious, tappable boxes (not faint underlines). */
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.7rem 0.9rem;
  font-size: var(--text-base);
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}
.field input::placeholder,
.field textarea::placeholder { color: var(--color-text-muted); }
.field input:focus,
.field select:focus,
.field textarea:focus,
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 28%, transparent);
}
.field textarea { min-height: 120px; resize: vertical; }
.hint { font-size: var(--text-sm); color: var(--color-text-muted); margin-top: var(--space-1); }

/* Honeypot field — visually hidden but present for bots. */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* --- Alert / notice component -------------------------------------------- */
.alert {
  border-radius: var(--radius-sm);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
  border: 1px solid transparent;
}
.alert-success { background: var(--color-success-bg); border-color: var(--color-success-border); color: var(--color-success-text); }
.alert-error { background: var(--color-error-bg); border-color: var(--color-error-border); color: var(--color-error-text); }
.alert ul { margin: var(--space-2) 0 0; padding-left: var(--space-5); }

/* --- Footer -------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
  padding: var(--space-7) 0;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}
.site-footer a { color: var(--color-primary); }
.footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  align-items: center;
}

/* --- Utilities ----------------------------------------------------------- */
.text-center { text-align: center; }
.mt-5 { margin-top: var(--space-5); }
.stack > * + * { margin-top: var(--space-4); }
.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;
}

/* =============================================================================
   Admin (dashboard + login) — uses semantic tokens only.
   ========================================================================== */
.admin-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-6);
}
.admin-bar-id { color: var(--color-text-muted); font-size: var(--text-sm); }
.admin-bar-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.admin-title { font-size: var(--text-3xl); margin: 0 0 var(--space-5); }

.admin-search {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
/* The field wraps the icon + input so the magnifier sits inside the control. */
.admin-search-field {
  display: flex;
  align-items: center;
  flex: 1 1 260px;
  min-width: 0;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}
.admin-search-field:focus-within {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.admin-search-icon { flex: 0 0 auto; color: var(--color-text-muted); }
.admin-search-field:focus-within .admin-search-icon { color: var(--color-primary); }
.admin-search input[type="search"] {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  font-size: var(--text-base);
  font-family: inherit;
  color: var(--color-text);
  background: transparent;
  border: 0;
}
.admin-search input[type="search"]::placeholder { color: var(--color-text-muted); }
.admin-search input[type="search"]:focus { outline: none; }

/* Status filter chips — preserve the active search across links (url_with). */
.admin-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
}
.admin-filter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  text-decoration: none;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  transition: border-color var(--transition-base), background var(--transition-base), color var(--transition-base);
}
.admin-filter:hover { border-color: var(--color-primary); }
.admin-filter.is-active {
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  border-color: var(--color-primary);
}
.admin-filter-count {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  padding: 0.05em 0.55em;
  border-radius: var(--radius-pill);
  background: var(--color-surface-2);
  color: var(--color-text-muted);
}
.admin-filter.is-active .admin-filter-count {
  background: color-mix(in srgb, var(--color-primary-contrast) 22%, transparent);
  color: var(--color-primary-contrast);
}

.admin-count { color: var(--color-text-muted); margin: 0 0 var(--space-4); }
.muted { color: var(--color-text-muted); }

/* Inline status editor (one small form per row). */
.btn-sm { min-height: 36px; padding: var(--space-2) var(--space-4); font-size: var(--text-sm); }
.status-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.status-select {
  padding: var(--space-2) var(--space-3);
  font-family: inherit;
  font-size: var(--text-sm);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  min-height: 36px;
}
.status-select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

/* Responsive table: stacked "cards" on mobile (base), real table at >=768px. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.admin-table { width: 100%; border-collapse: collapse; }
.admin-table thead { /* visually hidden on mobile */
  position: absolute;
  width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); border: 0;
}
.admin-table tr {
  display: block;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-2) var(--space-4);
  margin-bottom: var(--space-4);
}
.admin-table td {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  text-align: right;
  word-break: break-word;
}
.admin-table td:last-child { border-bottom: 0; }
.admin-table td::before {
  content: attr(data-label);
  flex: 0 0 auto;
  font-weight: var(--weight-medium);
  color: var(--color-text-muted);
  text-align: left;
}

.pill {
  display: inline-block;
  padding: 0.15em 0.6em;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
}
.pill-new { background: var(--color-success-bg); color: var(--color-success-text); border-color: var(--color-success-border); }
.pill-contacted { background: var(--color-placeholder-bg); color: var(--color-placeholder-text); border-color: var(--color-placeholder-border); }
.pill-archived { background: var(--color-surface-2); color: var(--color-text-muted); border-color: var(--color-border); }

.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--space-4); margin-top: var(--space-6); }
.pager-status { color: var(--color-text-muted); font-size: var(--text-sm); }

.form-wrap-narrow { max-width: 420px; }
.footer-staff-link { opacity: 0.85; }

/* =============================================================================
   PHASE 2 — distinct home sections (visual rhythm + hierarchy).
   Every band is built from semantic tokens; no hard-coded hex in components.
   ========================================================================== */

/* --- Section variants: alternate backgrounds give the page rhythm -------- */
.section--surface { background: var(--color-surface); }
.section--green {
  background: linear-gradient(155deg, var(--color-feature) 0%, var(--color-feature-2) 100%);
  color: var(--color-on-feature);
}
.section--clay {
  background: linear-gradient(155deg, var(--color-feature-warm) 0%, var(--color-feature-warm-2) 100%);
  color: var(--color-on-feature-warm);
}
.section--green h2,
.section--clay h2 { color: #fff; }
.section--green .sub,
.section--clay .sub { color: rgba(255, 255, 255, 0.88); }
.section--green .eyebrow { color: var(--color-on-feature); } /* crisp light eyebrow on the coffee band */
.section--clay .eyebrow { color: #fff; }
.section--warm { background: var(--color-warm-surface); border-block: 1px solid var(--color-warm-border); }
.section--cool { background: var(--color-cool-surface); }
.section-narrow .container { max-width: var(--maxw-narrow); }

/* --- Impact stats band (count-up) — the deep-green anchor ----------------- */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6) var(--space-4);
  margin-top: var(--space-6);
}
.stat { text-align: center; }
.stat-value {
  display: block;
  font-size: var(--text-4xl);
  font-weight: var(--weight-display);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--color-accent);              /* gold pops on deep green */
  font-variant-numeric: tabular-nums;
}
.stat-label {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.85);
}

/* --- Ministries array — icon-led card grid ------------------------------- */
.ministry-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-5);
  margin-top: var(--space-6);
}
.ministry-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: transform var(--motion-fast) var(--ease-out),
              box-shadow var(--motion-fast) var(--ease-out);
}
.ministry-icon {
  display: inline-grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: var(--radius-md);
  background: var(--color-cool-surface);
  color: var(--color-primary);
  margin-bottom: var(--space-4);
}
.ministry-icon .icon { width: 28px; height: 28px; }
.ministry-name { margin: 0 0 var(--space-3); font-size: var(--text-xl); }
.ministry-stat {
  display: inline-block;
  margin-bottom: var(--space-3);
  padding: 0.2em 0.7em;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-primary);
  background: var(--color-cool-surface);
  border-radius: var(--radius-pill);
}
.ministry-blurb { margin: 0; color: var(--color-text-muted); }

/* --- Spotlight rows — asymmetric image/text, alternating ----------------- */
.spotlight { display: grid; gap: var(--space-8); margin-top: var(--space-6); }
.spotlight-row { display: grid; gap: var(--space-5); }
.spotlight-media {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
.spotlight-img {
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.spotlight-body { align-self: center; }
.spotlight-title { font-size: var(--text-2xl); margin: var(--space-2) 0 var(--space-3); }
.spotlight-text { color: var(--color-text-muted); }
.spotlight-text p { margin: 0 0 var(--space-4); }
.spotlight-link { margin: 0; }

/* "Read more" arrow link (also used elsewhere) */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-semibold);
  color: var(--color-primary);
  text-decoration: none;
}
.link-arrow .icon { width: 18px; height: 18px; transition: transform var(--motion-fast) var(--ease-out); }
.link-arrow:hover { color: var(--color-primary-hover); }

/* --- Stories / testimonials --------------------------------------------- */
.story-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-6);
  margin-top: var(--space-6);
}
.story-card {
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform var(--motion-fast) var(--ease-out),
              box-shadow var(--motion-fast) var(--ease-out);
}
.story-media { position: relative; margin: 0; aspect-ratio: 3 / 2; overflow: hidden; }
.story-img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--motion-base) var(--ease-out); }
.story-tag {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  padding: 0.25em 0.7em;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-tag-text);
  background: var(--color-tag-bg);
  border-radius: var(--radius-pill);
}
.story-tag--inline { position: static; display: inline-block; margin-bottom: var(--space-1); }
.story-body { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-5); }
.story-card--noimg { border-top: 4px solid var(--color-warm); }
.story-name { margin: 0; font-size: var(--text-xl); }
.story-summary { margin: 0; color: var(--color-text-muted); }
.story-quote {
  margin: 0;
  padding-left: var(--space-4);
  border-left: 3px solid var(--color-accent);
  font-style: italic;
}
.story-quote p { margin: 0; }
.story-quote cite {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  font-style: normal;
  color: var(--color-text-muted);
}

/* --- Donation amount picker (docs/09) ------------------------------------ */
.donate-card {
  max-width: 720px;
  margin: var(--space-6) auto 0;
  padding: var(--space-7) var(--space-5);
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  text-align: center;
}
.amount-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: var(--space-3);
}
.amount-form { margin: 0; display: flex; }
.amount-chip {
  flex: 1;
  width: 100%;
  min-height: 52px;
  padding: var(--space-3);
  font-family: inherit;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--color-primary);
  background: var(--color-surface);
  border: 2px solid var(--color-primary);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: transform var(--transition-base),
              color var(--transition-base),
              border-color var(--transition-base),
              box-shadow var(--transition-base),
              background var(--transition-base);
}
.amount-chip:hover {
  color: var(--color-primary-contrast);
  background: var(--color-primary);
  border-color: var(--color-primary);
  box-shadow: var(--shadow-md);
}
.amount-chip:focus-visible {
  outline: none;
  color: var(--color-primary-contrast);
  background: var(--color-primary);
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.amount-chip:active { transform: translateY(1px); }
.amount-custom { margin-top: var(--space-5); text-align: left; }
.amount-custom-label { display: block; font-weight: var(--weight-medium); margin-bottom: var(--space-2); }
.custom-row { display: flex; align-items: stretch; gap: var(--space-2); }
.custom-prefix {
  display: inline-grid;
  place-items: center;
  padding-inline: var(--space-3);
  font-weight: var(--weight-bold);
  color: var(--color-primary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.custom-input {
  flex: 1;
  min-width: 0;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-base);
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.custom-input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
/* Donate submit reads as the primary action (scoped so site-wide .btn-accent
   stays taupe). */
.donate-picker .btn-accent {
  background: var(--color-primary);
  color: var(--color-primary-contrast);
}
.donate-picker .btn-accent:hover {
  background: var(--color-primary-hover);
  box-shadow: var(--shadow-md);
}
.donate-fineprint { margin: var(--space-3) 0 0; font-size: var(--text-sm); color: var(--color-text-muted); }

/* --- The globe moment (docs/07 §8) --------------------------------------- */
.globe-figure { margin: var(--space-7) auto 0; max-width: 420px; }
.globe-stage {
  position: relative;
  width: 100%;
  max-width: 380px;
  margin-inline: auto;
  aspect-ratio: 1 / 1;
}
.globe-fallback,
.globe-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.globe-fallback svg { width: 100%; height: 100%; display: block; }
.globe-stage.is-live .globe-fallback { display: none; }
.globe-canvas { display: block; touch-action: pan-y; cursor: grab; }
.globe-canvas:active { cursor: grabbing; }
.globe-caption {
  margin: var(--space-5) auto 0;
  max-width: 32rem;
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.85);
}

/* Desktop-only hover affordances (touch devices skip stuck-hover states). */
@media (hover: hover) and (pointer: fine) {
  .ministry-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
  .story-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
  .story-card:hover .story-img { transform: scale(1.04); }
  .link-arrow:hover .icon { transform: translateX(3px); }
  .amount-chip:hover { transform: translateY(-2px); }
}

/* =============================================================================
   Larger-screen enhancements (mobile-first: base = small, min-width scales up)
   ========================================================================== */
@media (min-width: 768px) {
  .hero-inner { padding: var(--space-9) 0 var(--space-8); }

  /* Home hero: a wider, more confident lede measure on desktop (mobile stays
     as-is — the narrow 46rem cap below only loosens at this breakpoint). */
  .hero--home .hero-lede { max-width: 54rem; }

  /* Headline reads as a bold, near-full-width statement on desktop. The shared
     .container 1080px cap was the limiter, so widen the hero column and step the
     title up; the lede/note keep their own narrow measures so they don't sprawl. */
  .hero--home .hero-inner { max-width: 1240px; }
  .hero--home .hero-title { font-size: clamp(3rem, 6.4vw, 4.6rem); }

  /* Impact stats: a clean single row. */
  .stats-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }

  /* Spotlight rows: asymmetric two-column; alternate which side the image is. */
  .spotlight-row {
    grid-template-columns: 1.1fr 0.9fr;
    gap: var(--space-7);
    align-items: center;
  }
  .spotlight-row.is-flipped .spotlight-media { order: 2; }
  .spotlight-img { max-height: 460px; }

  /* Nav: inline horizontal, no hamburger. */
  .nav-toggle,
  .js .nav-toggle { display: none; }
  .nav-links,
  .js .nav-links {
    display: flex;
    position: static;
    flex-direction: row;
    align-items: center;
    gap: var(--space-2);
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
  }

  /* Applicants: revert stacked cards to a real table. */
  .admin-table {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
  }
  .admin-table thead {
    position: static;
    width: auto; height: auto; margin: 0;
    clip: auto; overflow: visible;
  }
  .admin-table thead th {
    text-align: left;
    background: var(--color-surface);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
  }
  .admin-table tr {
    display: table-row;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    margin: 0;
  }
  .admin-table tbody tr + tr td { border-top: 1px solid var(--color-border); }
  .admin-table td {
    display: table-cell;
    text-align: left;
    border-bottom: 0;
    padding: var(--space-3) var(--space-4);
    vertical-align: top;
  }
  .admin-table td::before { content: none; }
}

/* Wide desktops: push the headline further so it spans most of the column. The
   widened hero column lets the lines breathe; the lede/note stay capped above. */
@media (min-width: 1200px) {
  .hero--home .hero-inner { max-width: 1440px; }
  .hero--home .hero-title { font-size: clamp(4.4rem, 7vw, 6.4rem); }
}

@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto; transition: none !important; }
}

/* =============================================================================
   HONDURAS MAP — homepage "Where your help goes" band
   (views/components/honduras-map.php). Self-hosted inline SVG, no JS. It sits on
   the deep-coffee section--green band, so the land is a light earthy tone and the
   labels carry a halo (paint-order: stroke) to stay legible over land + band.
   ========================================================================== */
.hmap {
  width: 100%;
  max-width: 560px;
  margin: var(--space-6) auto 0;
}
.hmap-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible; /* fanned labels sit slightly outside the outline */
}

/* Land — light greige outline so the country reads on the dark band. */
.hmap-land {
  fill: var(--accent-300);
  stroke: var(--accent-100);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

/* Gentle highlight of the Comayagua working area, behind the pins. */
.hmap-focus {
  fill: var(--color-accent);
  opacity: 0.22;
}

/* Thin connector from each pin out to its label. */
.hmap-leader {
  stroke: var(--color-on-feature);
  stroke-width: 1.25;
  opacity: 0.5;
}

/* Pins — coffee dot with a light ring so it pops on the land. */
.hmap-pin-dot {
  fill: var(--color-primary);
  stroke: var(--white);
  stroke-width: 1.5;
}
.hmap-pin-pulse {
  fill: none;
  stroke: var(--color-primary);
  stroke-width: 2;
  transform-box: fill-box;
  transform-origin: center;
  animation: hmap-pulse 2.6s var(--ease-out) infinite;
}
@keyframes hmap-pulse {
  0%   { transform: scale(1);   opacity: 0.65; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* Labels — light text with a dark halo for legibility over land or band. */
.hmap-label {
  fill: var(--color-on-feature);
  stroke: var(--color-feature);
  stroke-width: 4;
  paint-order: stroke;
  stroke-linejoin: round;
  font-family: var(--font-sans);
  font-size: 27px;
  font-weight: var(--weight-semibold);
}

/* Pin pulse is the only motion here; honor reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  .hmap-pin-pulse { animation: none; opacity: 0; }
}

/* =============================================================================
   Signup page — faded background photo with the interest form on a tan card.
   Scoped to .signup-page (set on the signup <section> via the section `class`
   prop) so NOTHING else on the site is affected.
   ========================================================================== */
.signup-page {
  /* A light cream tint layered OVER the photo in the SAME element so the image
     reads softly/faded (a gentle backdrop, never a loud focal point). No
     background-attachment: fixed (janky on mobile); no repeat. */
  background-image:
    linear-gradient(rgba(245, 241, 236, 0.66), rgba(245, 241, 236, 0.66)),
    url("/assets/img/hero/IMG_9702.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  /* Fill most of the viewport on short pages so the photo always shows and the
     form sits front-and-center; flex centers the card vertically. */
  min-height: 80vh;
  display: flex;
  align-items: center;
}
.signup-page .container { width: 100%; }

/* The form card: a warm TAN fill that pops off the faded photo, with a clear
   shadow and the existing rounded corners. White boxed inputs keep good
   contrast on the tan, so the input rules are left untouched. */
.signup-page .form-wrap {
  background: var(--color-surface-2);
  border-color: var(--color-warm-border);
  box-shadow: var(--shadow-lg);
}
