/* ==========================================================================
   Coastal Bend Health Exchange
   Every size is in rem so OS text-size settings actually scale the page.
   Nothing renders below 16px. Body floor is 18px.
   ========================================================================== */

/* --- self-hosted fonts ----------------------------------------------------
   No third-party font requests. Both files are the `latin` subset, whose
   unicode-range covers U+0000-00FF, so every Spanish accent (á é í ó ú ñ ¿ ¡)
   is already present for the Phase 2 translation.

   Atkinson Hyperlegible ships 700 only: it is used exclusively for headings,
   the wordmark, the step numerals, and the footer name, all at 700.
   Inter is a variable file covering the whole 100-900 range, so the single
   download serves body 400, buttons/nav 600, and labels 700.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Atkinson Hyperlegible";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/atkinson-hyperlegible-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Palette — contrast verified against WCAG AA.
     navy on off-white 16.4:1 · white on teal 6.4:1 · grey on off-white 8.8:1 */
  --navy: #002046;
  --navy-container: #1b365d;
  --teal: #006a6a;
  --teal-dark: #004f4f;
  --teal-tint: #e6f2f2;
  --amber-bg: #ffdfa0;
  --amber-text: #261a00;
  --surface: #f8f9fa;
  --white: #ffffff;
  --surface-low: #f2f4f6;
  --outline: #74777f;
  --outline-variant: #c4c6cf;
  --on-surface: #191c1d;
  --on-surface-variant: #44474e;
  --error: #ba1a1a;

  /* Fallback order is a layout decision, not a taste one. Measured against the
     h1 string at 33px/700: Atkinson 849px, Arial 856px (99.2% match), Verdana
     1004px (18% wider). Verdana used to sit first here, and in the frame before
     the webfont applied it pushed the h1 from 3 lines to 4 and dropped the hero
     CTAs below the fold on a 375px screen. Arial holds the same line count. */
  --font-head: "Atkinson Hyperlegible", Arial, "Helvetica Neue", system-ui, sans-serif;
  --font-body: Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Type scale. The rem terms keep user font-size settings effective;
     the vw term only adds fluidity between breakpoints. */
  --size-h1: clamp(2rem, 1.55rem + 2.2vw, 2.5rem);
  --size-h2: clamp(1.625rem, 1.4rem + 1.1vw, 2rem);
  --size-h3: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
  --size-body: 1.125rem;   /* 18px — the floor for prose */
  --size-small: 1rem;      /* 16px — absolute minimum anywhere on the site */
  --size-btn: 1.125rem;
  --size-nav: 1.0625rem;   /* 17px */

  --tap: 3.5rem;           /* 56px — exceeds the 44pt Apple HIG minimum */
  --wrap: 75rem;
  --gutter: 1.25rem;
  --radius: 0.5rem;
  --radius-lg: 0.875rem;

  /* Fallback used before js/main.js measures the real bar. In rem so it still
     grows when the user scales text up and JS is unavailable. Includes the
     safe-area inset because the bar's own padding does too — js/main.js later
     replaces this with the measured height, which also already includes it. */
  --action-bar-h: calc(6rem + env(safe-area-inset-bottom, 0px));

  --shadow-sm: 0 1px 2px rgba(0, 32, 70, 0.06), 0 2px 8px rgba(0, 32, 70, 0.05);
  --shadow-md: 0 2px 6px rgba(0, 32, 70, 0.08), 0 8px 24px rgba(0, 32, 70, 0.08);

  color-scheme: light;
}

/* --- reset ---------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--surface);
  color: var(--on-surface);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* The inset is NOT added here: --action-bar-h already accounts for it, whether
   it came from the fallback above or from the measured height set by
   js/main.js. Adding it again double-counts and leaves a dead gap at the
   bottom of every page on notched iPhones. */
body.has-action-bar {
  padding-bottom: var(--action-bar-h);
}

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

h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 700;
  color: var(--navy);
  margin: 0 0 0.5em;
  text-wrap: balance;
}

h1 { font-size: var(--size-h1); line-height: 1.2; letter-spacing: -0.01em; }
h2 { font-size: var(--size-h2); line-height: 1.3; }
h3 { font-size: var(--size-h3); line-height: 1.4; }

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 1rem; padding-left: 1.25rem; }
li { margin-bottom: 0.5rem; }

.icon { width: 1.5rem; height: 1.5rem; flex: none; }

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

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: clamp(2.5rem, 6vw, 4.5rem); }
.section--tint { background: var(--white); }
.section--low { background: var(--surface-low); }

/* Prose never runs long enough to lose your place on the return sweep. */
.prose { max-width: 65ch; }
.lede {
  font-size: clamp(1.1875rem, 1.1rem + 0.4vw, 1.375rem);
  line-height: 1.55;
  color: var(--on-surface-variant);
  max-width: 60ch;
}

/* --- accessibility -------------------------------------------------------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--navy);
  color: var(--white);
  padding: 1rem 1.5rem;
  font-weight: 600;
  border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus {
  left: 0;
}

:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 3px;
  border-radius: 2px;
}

.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) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- header + nav --------------------------------------------------------- */
/* Navigation is still persistent and identical on every page, but it now lives
   in a drawer behind a button.
   The original build refused a hamburger on purpose: an unlabeled icon fails
   low-vision users, and this audience contains them. That objection is real and
   is mitigated, not dismissed — the trigger carries the visible word "Menu",
   the rows are 48px, and the full link list is still in the footer of every
   page as a no-JS-proof fallback. */

.site-header {
  background: var(--white);
  border-bottom: 1px solid var(--outline-variant);
}

.site-header__inner {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.625rem;
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 2.75rem;      /* was 42px tall, one under the 44 minimum */
  text-decoration: none;
  color: var(--navy);
}

.logo__mark { width: 2.5rem; height: 2.5rem; flex: none; }

.logo__word { display: flex; flex-direction: column; line-height: 1.05; }

.logo__word-top {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: -0.01em;
}

/* 1rem, not 0.9375 — the 16px floor applies to the wordmark too. */
.logo__word-bottom {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--teal);
}

/* --- nav toggle ----------------------------------------------------------- */

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 2.75rem;          /* 44px */
  min-width: 2.75rem;
  padding: 0.5rem 0.75rem;
  background: var(--white);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  color: var(--navy);
  font-family: var(--font-body);
  font-size: var(--size-nav);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  flex: none;
}

.nav-toggle:hover { color: var(--teal); border-color: var(--teal); }
.nav-toggle__bars { width: 1.5rem; height: 1.5rem; flex: none; }

/* --- nav drawer ----------------------------------------------------------- */
/* visibility, not display, is what takes the closed drawer out of the tab order
   and the accessibility tree.
   The `visibility 0s linear <delay>` pattern is load-bearing, not styling.
   Transitioning visibility over the same 0.24s as the slide leaves it computing
   as `hidden` for the whole animation, and focus() on anything inside a hidden
   subtree is silently discarded — the drawer opened with focus stranded on the
   page behind it. So: flip to visible instantly on open (0s, no delay), and
   delay the flip to hidden until the slide-out has finished. */

.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(0, 32, 70, 0.5);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.24s ease, visibility 0s linear 0.24s;
}

.drawer-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.24s ease, visibility 0s linear 0s;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 90;                  /* above the action bar, which is 60 */
  width: min(20rem, 84vw);
  display: flex;
  flex-direction: column;
  padding-block: 0.75rem calc(1rem + env(safe-area-inset-bottom, 0px));
  background: var(--white);
  border-left: 1px solid var(--outline-variant);
  box-shadow: -8px 0 28px rgba(0, 32, 70, 0.18);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform 0.24s ease, visibility 0s linear 0.24s;
}

.drawer.is-open {
  transform: none;
  visibility: visible;
  transition: transform 0.24s ease, visibility 0s linear 0s;
}

/* Holds the page still behind the open drawer. */
body.drawer-open { overflow: hidden; }

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 0.75rem 0.75rem 1.25rem;
  border-bottom: 1px solid var(--outline-variant);
}

.drawer__title {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.125rem;
  color: var(--navy);
}

.drawer__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;               /* 44px */
  height: 2.75rem;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--radius);
  color: var(--navy);
  cursor: pointer;
  flex: none;
}

.drawer__close:hover { background: var(--surface-low); color: var(--teal); }

.drawer__list {
  list-style: none;
  margin: 0;
  padding: 0.5rem 0;
}

.drawer__item { margin: 0; }

.drawer__link {
  display: flex;
  align-items: center;
  min-height: 3rem;             /* 48px rows */
  padding: 0.5rem 1.25rem;
  font-size: var(--size-nav);
  font-weight: 600;
  color: var(--navy);
  text-decoration: none;
  border-left: 4px solid transparent;
}

.drawer__link:hover { background: var(--surface-low); color: var(--teal); }

.drawer__link--active {
  color: var(--teal);
  background: var(--teal-tint);
  border-left-color: var(--teal);
}

.drawer__divider {
  margin: 0 1.25rem;
  border: 0;
  border-top: 1px solid var(--outline-variant);
}

/* Secondary pages read quieter, but never below the 16px floor and never on
   colour alone — the divider above them is what carries the grouping. */
.drawer__list--secondary .drawer__link { color: var(--on-surface-variant); }
.drawer__list--secondary .drawer__link--active { color: var(--teal); }

@media (prefers-reduced-motion: reduce) {
  .drawer,
  .drawer-backdrop { transition: none; }
}

/* No scripting: the drawer can never open, so it stops pretending to be one.
   It renders as a plain stacked list under the header and the button that
   would do nothing is removed. */
.no-js .nav-toggle,
.no-js .drawer-backdrop,
.no-js .drawer__head { display: none; }

.no-js .drawer {
  position: static;
  width: auto;
  transform: none;
  visibility: visible;
  box-shadow: none;
  border-left: 0;
  border-bottom: 1px solid var(--outline-variant);
  padding-block: 0.25rem 0.5rem;
}

/* --- links + buttons ------------------------------------------------------ */

.link { color: var(--teal-dark); text-decoration: underline; text-underline-offset: 2px; }
.link:hover { color: var(--navy); }

/* A link that stands alone as the route to another page is a control, not
   prose, so it gets a real 44px target. Inline links inside a sentence keep
   .link and stay inline (WCAG 2.5.8 exempts those). */
.link-cta {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-block: 0.375rem;
  color: var(--teal-dark);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.link-cta:hover { color: var(--navy); }

.section__more { margin-top: 1.5rem; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: var(--tap);
  padding: 0.75rem 1.5rem;
  font-family: var(--font-body);
  font-size: var(--size-btn);
  font-weight: 600;
  line-height: 1.2;
  border-radius: var(--radius);
  border: 2px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, box-shadow 0.15s ease, transform 0.05s ease;
}

.btn--primary {
  background: var(--teal);
  color: var(--white);
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover { background: var(--teal-dark); }
.btn--primary:active { transform: translateY(1px); box-shadow: none; }

.btn--secondary {
  background: var(--white);
  color: var(--navy);
  border-color: var(--navy);
}
.btn--secondary:hover { background: var(--surface-low); }

.btn--block { width: 100%; }

.btn-row {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

@media (min-width: 32rem) {
  .btn-row { flex-direction: row; flex-wrap: wrap; }
  .btn-row .btn { flex: 1 1 14rem; }
}

/* --- action bar ----------------------------------------------------------- */
/* Action is contextual and changes on every page, so it never becomes
   furniture people tune out. Visually unlike the nav on purpose. */

.action-bar {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 60;
  background: var(--teal);
  padding: 0.75rem var(--gutter);
  /* Without this the iPhone home indicator sits on top of the Call button. */
  padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -4px 20px rgba(0, 32, 70, 0.2);
}

.action-bar__inner {
  display: flex;
  gap: 0.75rem;
  max-width: 40rem;
  margin-inline: auto;
}

.action-btn {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: var(--tap);
  padding: 0.625rem 1rem;
  font-size: var(--size-btn);   /* 18px — not the 10px the concept shipped */
  font-weight: 700;
  line-height: 1.2;
  border-radius: var(--radius);
  text-decoration: none;
  text-align: center;
}

.action-btn--primary {
  background: var(--white);
  color: var(--teal-dark);
}
.action-btn--primary:active { background: #e9f0f0; }

.action-btn--secondary {
  background: transparent;
  color: var(--white);
  border: 2px solid rgba(255, 255, 255, 0.75);
}
.action-btn--secondary:active { background: rgba(255, 255, 255, 0.12); }

.action-bar :focus-visible { outline-color: var(--white); }

/* --- hero ----------------------------------------------------------------- */

.hero {
  background: linear-gradient(168deg, var(--white) 0%, var(--teal-tint) 100%);
  border-bottom: 1px solid var(--outline-variant);
  padding-block: clamp(1.25rem, 6vw, 4rem);
}

/* Hero rhythm is tighter than the rest of the page on purpose: on a 375x667
   iPhone SE these margins decide whether the Call and Text buttons land above
   the fold. Desktop still gets air from the clamp above. */
.hero h1 { margin-bottom: 0.5rem; }
.hero .lede { margin-bottom: 0.75rem; }
.hero .btn-row { margin-top: 1.25rem; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--amber-bg);      /* amber is a background, never a text color */
  color: var(--amber-text);
  padding: 0.5rem 1rem;
  border-radius: 999px;
  font-size: var(--size-small);
  font-weight: 700;
  margin-bottom: 0.75rem;
}

.badge .icon { width: 1.125rem; height: 1.125rem; }

.hero h1 { max-width: 18ch; }

.hero__regions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.25rem;
  padding: 0;
  list-style: none;
}

/* Compact on purpose: these are a coverage signal, not a tap target. Four
   long chips cost four stacked rows at 375px and pushed the hero CTAs under
   the fold on an iPhone SE. */
.hero__regions li {
  margin: 0;
  background: var(--white);
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  padding: 0.3125rem 0.6875rem;
  font-size: var(--size-small);
  font-weight: 600;
  line-height: 1.35;
  color: var(--navy);
}

/* The demoted text option, wherever a Call / Get an Offer pair appears.
   Texting is no longer a primary button, but it is still the lowest-effort
   thing this audience can do, so it stays one tap away as a real 44px target
   rather than vanishing into the FAQ. */
.alt-action { margin-top: 0.25rem; }

.hero__note {
  margin-top: 1rem;
  font-size: var(--size-small);
  color: var(--on-surface-variant);
}

/* --- cards ---------------------------------------------------------------- */

/* min(100%, …) is load-bearing. A bare minmax(15rem, 1fr) keeps growing when
   the user scales text up, so at 135% the column minimum exceeds the viewport
   and the whole page scrolls sideways. Clamping the minimum to the container
   width lets the column collapse instead. */
.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.grid--mid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }

/* A two-column band whose photo has been stripped collapses to a single column.
   Left alone, the surviving text stretches the full 75rem wrap — 150-odd
   characters a line, which is an unreadable measure. This only bites while the
   grid has exactly one child, so restoring the photo restores the two-column
   layout with no CSS change needed. */
.grid > :only-child { max-width: 65ch; }
.grid--wide { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid--gap-lg { gap: 2.5rem; }
.grid--center { align-items: center; }
.grid--start { align-items: start; }

.card {
  background: var(--white);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
}

.card h3 { margin-bottom: 0.375rem; }
.card p { color: var(--on-surface-variant); }

.card__icon {
  width: 2.75rem;
  height: 2.75rem;
  color: var(--teal);
  margin-bottom: 0.875rem;
}

/* --- steps ---------------------------------------------------------------- */

.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.5rem; }

.steps li { margin: 0; display: flex; gap: 1rem; align-items: flex-start; }

.step__num {
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 999px;
  background: var(--navy-container);
  color: var(--white);          /* 12.1:1 — the concept's #87a0cd was 4.58:1 */
  display: grid;
  place-items: center;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.25rem;
}

.step__body h3 { margin-bottom: 0.25rem; }
.step__body p { color: var(--on-surface-variant); margin-bottom: 0; }

/* --- region split --------------------------------------------------------- */

.region-card {
  background: var(--white);
  border: 1px solid var(--outline-variant);
  border-left: 6px solid var(--teal);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
}

.region-card--mail { border-left-color: var(--navy-container); }

.region-card__kicker {
  display: inline-block;
  font-size: var(--size-small);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teal-dark);
  margin-bottom: 0.5rem;
}

.region-card--mail .region-card__kicker { color: var(--navy-container); }

.region-card ul { margin-bottom: 0; }
.region-card li { color: var(--on-surface-variant); }

/* --- about aside --------------------------------------------------------- */

.about-aside { display: grid; gap: 1.5rem; }

/* Until the client sends an owner photo, this column holds only the contact
   card, which would otherwise sit at the top of a very tall empty column.
   Sticking it keeps it beside the reader the whole way down. Two-column widths
   only — below this the grid is a single column and the card just flows. */
@media (min-width: 48rem) {
  .about-aside { position: sticky; top: 1.5rem; align-self: start; }
}

/* --- callout -------------------------------------------------------------- */

.callout {
  background: var(--amber-bg);
  color: var(--amber-text);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
}

.callout h3 { color: var(--amber-text); }
.callout p:last-child { margin-bottom: 0; }

.callout--plain {
  background: var(--white);
  color: var(--on-surface);
  border: 1px solid var(--outline-variant);
}
.callout--plain h3 { color: var(--navy); }

/* --- bridge band ---------------------------------------------------------- */
/* A wide cinematic crop of the source, not the whole 750x425 frame.
   The frame is capped at 750px — the image's natural width — because stretching
   it across a 1200px page is a 1.6x upscale and the softness shows immediately
   on a retina screen. Below that cap it runs edge to edge, which is the case
   that actually matters: on a phone the band is full-bleed. */

.bridge-band { background: var(--surface-low); }

.bridge-band__frame {
  position: relative;
  max-width: 750px;          /* natural width of the source. Never exceed it. */
  margin-inline: auto;
}

/* An explicit height, not aspect-ratio, is what makes this zero-CLS: the box is
   fully determined by CSS before a single byte of the image arrives. object-fit
   crops rather than distorts, and because the frame never exceeds 750px the
   crop never scales the source above 1:1. */
.bridge-band__img {
  display: block;
  width: 100%;
  height: clamp(15rem, 46vw, 17.5rem);   /* 240px … 280px */
  object-fit: cover;
  object-position: center 60%;
}

/* A scrim, not a solid bar: the kicker has to stay legible over open sky
   without covering the photo it sits on. */
.bridge-band__kicker {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  margin: 0;
  padding: 2.5rem var(--gutter) 0.75rem;
  font-size: var(--size-small);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--white);
  background: linear-gradient(to top, rgba(0, 32, 70, 0.78), rgba(0, 32, 70, 0));
  pointer-events: none;
}

/* --- photo placeholders --------------------------------------------------- */
/* Deliberate frames, not gray boxes. Swap to a real image by replacing the
   figure contents with <img src="assets/…" alt="…">. */

.photo-slot {
  position: relative;
  aspect-ratio: 4 / 3;
  border: 2px dashed var(--outline-variant);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(135deg, rgba(0, 106, 106, 0.06), rgba(0, 32, 70, 0.05));
  display: grid;
  place-items: center;
  text-align: center;
  padding: 1.5rem;
  overflow: hidden;
}

.photo-slot__mark {
  width: 3.5rem;
  height: 3.5rem;
  color: var(--teal);
  opacity: 0.35;
  margin-inline: auto;
  margin-bottom: 0.75rem;
}

.photo-slot__label {
  font-size: var(--size-small);
  font-weight: 600;
  color: var(--on-surface-variant);
  margin: 0;
  max-width: 24ch;
}

figure { margin: 0; }

figcaption {
  font-size: var(--size-small);
  color: var(--on-surface-variant);
  margin-top: 0.5rem;
}

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

.faq { display: grid; gap: 2rem; max-width: 65ch; }
.faq h3 { margin-bottom: 0.5rem; }
.faq p { color: var(--on-surface-variant); }

/* --- form ----------------------------------------------------------------- */

.form-card {
  background: var(--white);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-lg);
  padding: clamp(1.25rem, 4vw, 2.25rem);
  box-shadow: var(--shadow-md);
  max-width: 40rem;
}

.field { margin-bottom: 1.25rem; }

/* Labels are persistent, never placeholder-only — you never lose context of
   what you are typing. */
.field label {
  display: block;
  font-size: var(--size-small);
  font-weight: 700;
  color: var(--navy);
  margin-bottom: 0.375rem;
}

.field__hint {
  font-size: var(--size-small);
  color: var(--on-surface-variant);
  margin: 0 0 0.375rem;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: var(--tap);
  padding: 0.75rem 0.875rem;
  font-family: var(--font-body);
  font-size: var(--size-body);   /* 18px — under 16px iOS Safari auto-zooms */
  color: var(--on-surface);
  background: var(--white);
  border: 2px solid var(--outline);
  border-radius: var(--radius);
}

.field textarea { min-height: 7rem; resize: vertical; }

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--teal);
  outline: 3px solid rgba(0, 106, 106, 0.35);
  outline-offset: 0;
}

.field--error input,
.field--error select,
.field--error textarea { border-color: var(--error); }

/* Errors carry text and an icon, never color alone. */
.field__error {
  display: none;
  align-items: center;
  gap: 0.375rem;
  color: var(--error);
  font-size: var(--size-small);
  font-weight: 600;
  margin-top: 0.375rem;
}

.field--error .field__error { display: flex; }
.field__error .icon { width: 1.125rem; height: 1.125rem; }

/* Honeypot: display:none keeps it out of the layout, the tab order, and the
   accessibility tree, while leaving it in the DOM where a bot will find it. */
.honeypot { display: none; }

.consent {
  font-size: var(--size-small);   /* TCPA language must be legible: 16px floor */
  line-height: 1.5;
  color: var(--on-surface-variant);
  margin: 1.25rem 0;
}

.form-status {
  display: none;
  margin-top: 1.25rem;
  padding: 1rem 1.25rem;
  border-radius: var(--radius);
  background: var(--teal-tint);
  border: 1px solid var(--teal);
  color: var(--navy);
  font-weight: 600;
}
.form-status.is-visible { display: block; }

/* A failed submit must not render in the same reassuring teal as a successful
   one. Lead lost + "thanks, we got it" is the worst outcome this form has. */
.form-status--error {
  background: #fff5f5;
  border-color: var(--error);
  color: var(--error);
}

.contact-direct {
  display: grid;
  gap: 0.75rem;
  margin-bottom: 2rem;
}

@media (min-width: 32rem) {
  .contact-direct { grid-template-columns: 1fr 1fr; }
}

/* --- price list ----------------------------------------------------------- */

.price-note {
  background: var(--teal-tint);
  border-left: 4px solid var(--teal);
  border-radius: var(--radius);
  padding: 1rem 1.125rem;
  margin-bottom: 2.25rem;
  max-width: 65ch;
}

.price-note__updated {
  margin: 0.5rem 0 0;
  font-size: var(--size-small);
  color: var(--on-surface-variant);
}

.product-group + .product-group { margin-top: 2.75rem; }

.product-group__title {
  margin-bottom: 0.25rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--outline-variant);
}

.product-group__blurb {
  color: var(--on-surface-variant);
  margin-bottom: 1.25rem;
  max-width: 60ch;
}

.product-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.875rem;
}

/* Photo beside the text, not above it. A stacked card would put 16 products
   over roughly 3,000px of scroll on a 375px screen; this halves that and keeps
   the product name at a size this audience can actually read. */
.product {
  margin: 0;
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  gap: 1rem;
  align-items: center;
  background: var(--white);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-lg);
  padding: 0.75rem;
  box-shadow: var(--shadow-sm);
}

.product__photo {
  width: 6rem;
  height: 6rem;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--surface-low);
}

.product__name {
  font-size: 1.0625rem;
  line-height: 1.3;
  margin: 0 0 0.125rem;
}

.product__qty {
  font-size: var(--size-small);
  color: var(--on-surface-variant);
  margin: 0 0 0.375rem;
}

.product__price {
  font-family: var(--font-head);
  font-size: 1.375rem;
  line-height: 1.2;
  color: var(--navy);
  margin: 0;
}

/* "Call for price" is not a price and must not be dressed as one. It drops to
   the body face at label size, so the day real figures land they outweigh it
   on the page instead of competing with it. */
.product__price--call {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--size-small);
  color: var(--teal-dark);
}

@media (min-width: 40rem) {
  .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 64rem) {
  .product-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- footer --------------------------------------------------------------- */

.site-footer {
  background: var(--navy);
  color: #dfe4ea;
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  padding-top: clamp(2rem, 5vw, 3rem);
  font-size: var(--size-small);
}

.site-footer a { color: #cfe3e3; }
.site-footer a:hover { color: var(--white); }

.site-footer__inner {
  display: grid;
  gap: 2rem;
  padding-bottom: 2rem;
}

@media (min-width: 48rem) {
  .site-footer__inner { grid-template-columns: 2fr 1fr 1fr; }
}

.site-footer__mark { width: 2.25rem; height: 2.25rem; color: #8fb8b8; margin-bottom: 0.625rem; }

.site-footer__name {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--white);
  margin-bottom: 0.375rem;
}

.site-footer__where { color: #b9c3ce; max-width: 40ch; }

.site-footer__heading {
  font-weight: 700;
  color: var(--white);
  margin-bottom: 0.625rem;
}

.site-footer__note { color: #b9c3ce; }

.site-footer__nav ul { list-style: none; margin: 0; padding: 0; }
.site-footer__nav li { margin-bottom: 0.5rem; }

.site-footer__legal {
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  padding-block: 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  align-items: center;
  color: #b9c3ce;
}

.site-footer__legal p { margin: 0; }
.site-footer__legal ul { list-style: none; margin: 0; padding: 0; display: flex; gap: 1.5rem; }
.site-footer__legal li { margin: 0; }

.site-footer__disclaimer {
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  padding-block: 1.25rem 2rem;
  color: #a9b4c0;
}

.site-footer__disclaimer p { max-width: 80ch; margin: 0; }

/* Footer links are real tap targets too. min-width matters: "FAQ" was 31px. */
.site-footer a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  min-width: 2.75rem;
}
.site-footer__disclaimer a,
.site-footer__where a { min-height: 0; line-height: inherit; }
