/* ==========================================================================
   pages.css — page-specific styles + shared utilities.
   Last in the cascade (tokens → base → layout → components → pages).
   Page-scoped blocks get a body class (e.g. .page-styleguide).
   ========================================================================== */

/* --- Shared utilities -------------------------------------------------- */
.eyebrow { font-size: var(--t-small); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--water); }
.lede { font-size: 1.1875rem; color: var(--ink-muted); }
.grid { display: grid; gap: var(--s6); }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--4 { grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid--2 { grid-template-columns: repeat(2, 1fr); } .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
}
.stack > * + * { margin-top: var(--s4); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }
.text-center { text-align: center; }

/* Section head — eyebrow + heading + optional lede */
.section-head { max-width: 680px; margin-bottom: var(--s12); }
.section-head > * + * { margin-top: var(--s3); }
.section-head--center { margin-inline: auto; text-align: center; }

/* --- Section surfaces (water-forward, desert accents) -----------------
   Pale water tints are the dominant section background; white gives the
   media/personal sections a neutral rest; sand is the desert accent.
   Deep teal (hero + CTA band) bookends the page. Cards stay --paper so
   they lift off the tinted surfaces. */
.section--water {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--shallow) 26%, var(--paper)) 0%,
    color-mix(in srgb, var(--shallow) 12%, var(--paper)) 100%);
}
.section--water-soft { background: color-mix(in srgb, var(--shallow) 12%, var(--paper)); }
.section--paper { background: var(--paper); }
.section--sand  { background: var(--sand); }

/* ==========================================================================
   Home (/index.html) — sections in §5.1 order. Scoped to .page-home.
   ========================================================================== */

/* 2 · Hero — full-bleed desert-water photo with a deep-teal scrim.
   Content sits low-left over the darkened water; the brand water-line
   (added right after the section) lets the hero rest on flowing water. */
.hero {
  position: relative;
  isolation: isolate;                 /* keep the scrim's z-index local */
  display: flex;
  align-items: center;                /* vertically centered — not dropped low */
  min-height: clamp(520px, 76vh, 720px);
  padding-block: var(--s16);
  overflow: hidden;
  background: var(--deep);            /* fallback + edges before the photo paints */
}
.hero__bg { position: absolute; inset: 0; z-index: -2; }
.hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 62% 50%; }
/* Deep-water scrim: darker at the text (left + bottom), clearing toward the
   mountains (top-right) so the turquoise water still reads. */
.hero__scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    /* Top edge — deep water so the navbar's wave dips into teal, not the
       bright top of the photo (kills the image bleed under the wave). */
    linear-gradient(180deg,
      color-mix(in srgb, var(--deep) 72%, transparent) 0%,
      color-mix(in srgb, var(--deep) 22%, transparent) 12%,
      transparent 24%),
    linear-gradient(95deg,
      color-mix(in srgb, var(--deep) 90%, transparent) 0%,
      color-mix(in srgb, var(--deep) 72%, transparent) 45%,
      color-mix(in srgb, var(--deep) 34%, transparent) 78%,
      color-mix(in srgb, var(--deep) 8%, transparent) 100%),
    linear-gradient(0deg,
      color-mix(in srgb, var(--deep) 82%, transparent) 0%,
      color-mix(in srgb, var(--deep) 20%, transparent) 38%,
      transparent 60%);
}
.hero__inner {
  position: relative; max-width: 640px;
  text-shadow: 0 1px 12px color-mix(in srgb, var(--deep) 45%, transparent);
}
.hero .eyebrow { color: var(--shallow); }
.hero__title {
  font-size: var(--t-hero);
  color: var(--on-deep);
  letter-spacing: -.02em;
  max-width: 15ch;
  margin-top: var(--s3);
}
.hero__sub {
  font-size: 1.1875rem;
  color: color-mix(in srgb, var(--on-deep) 88%, transparent);
  max-width: 46ch;
  margin-top: var(--s4);
}
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s6); }
/* Credential chips — real, substantiable claims only */
.hero__trust {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s6);
  list-style: none; padding: 0; margin-top: var(--s6);
  color: var(--on-deep);
}
.hero__trust li {
  display: inline-flex; align-items: center; gap: var(--s2);
  margin: 0; max-width: none;
  font-size: var(--t-small); font-weight: 600;
}
.hero__trust svg { width: 18px; height: 18px; color: var(--shallow); flex: 0 0 auto; }
.hero__areas { font-size: var(--t-small); color: color-mix(in srgb, var(--on-deep) 78%, transparent); margin-top: var(--s4); }
.hero__areas a { color: var(--shallow); font-weight: 600; }
.hero__areas a:hover { color: var(--on-deep); }
@media (min-width: 768px) {
  .hero__title { max-width: 14ch; }
}

/* --- Fixed-hero reveal (home only) ------------------------------------
   The hero pins to the viewport; .after-hero (all content below it) scrolls
   up over it and under the sticky navbar. .hero-spacer reserves one viewport
   of scroll so the page height accounts for the pinned hero. hero-reveal.js
   fades .hero__inner (text + CTAs, NOT the photo) as content covers it.
   Scoped to .page-home so service/about heroes are unaffected. */
.page-home .hero {
  position: fixed;
  inset: 0 0 auto 0;         /* top:0; left/right:0 */
  height: 100dvh;
  min-height: 0;             /* override the base clamp */
  z-index: 0;                /* sits behind .after-hero (z-1), under header (z-100) */
}
.page-home .hero-spacer { height: 100dvh; }
.page-home .after-hero {
  position: relative;
  z-index: 1;                /* scrolls OVER the pinned hero */
  background: var(--sand);   /* opaque base so nothing shows through gaps/waterlines */
}
/* The footer lives outside .after-hero — lift it into the same layer so it
   scrolls over the pinned hero too (otherwise the photo shows through below
   the last section). */
.page-home .site-footer { position: relative; z-index: 1; }
/* hero__inner fades via JS; keep the transition smooth if JS steps are coarse,
   and make sure the photo layers never inherit the fade. */
.page-home .hero__inner { will-change: opacity; }
/* No-JS / reduced-motion safety net: if the reveal script can't run, fall back
   to the normal in-flow hero so content is never trapped behind a fixed layer. */
@media (prefers-reduced-motion: reduce) {
  .page-home .hero { position: relative; height: auto; min-height: clamp(520px, 76vh, 720px); }
  .page-home .hero-spacer { display: none; }
  .page-home .hero__inner { opacity: 1 !important; }
}

/* 3 · Trust strip */
.trust-strip {
  border-block: 1px solid var(--line);
  background: var(--paper);
}
.trust-strip__row {
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s6);
  align-items: center; justify-content: center;
  padding-block: var(--s4); text-align: center;
}
.trust-strip__item { display: inline-flex; align-items: center; gap: var(--s2); color: var(--deep); font-weight: 600; }
.trust-strip__item svg { width: 18px; height: 18px; color: var(--water); flex: 0 0 auto; }
.trust-strip__sep { color: var(--line); }
@media (max-width: 640px) { .trust-strip__sep { display: none; } }

/* 5 · Before / after — give it room; it's the emotional center */
.proof { background: var(--paper); }
.proof__frame { max-width: 860px; margin-inline: auto; }
/* Two equipment before/after sliders side by side (repairs page); stacks on mobile */
.ba-grid { align-items: start; margin-top: var(--s8); }
.ba-figure { margin: 0; }
.ba-figure figcaption { margin-top: var(--s3); text-align: center; font-size: var(--t-small); color: var(--ink-muted); }
/* Two before/after sliders side by side (green-to-clean) — equal size, stack on mobile */
.proof__pair { display: grid; gap: var(--s4); max-width: 1040px; margin-inline: auto; }
@media (min-width: 760px) { .proof__pair { grid-template-columns: 1fr 1fr; } }

/* 7 · How it works — three numbered steps (a real sequence) */
.how { counter-reset: step; }
.how__grid { display: grid; gap: var(--s8); grid-template-columns: 1fr; }
@media (min-width: 768px) { .how__grid { grid-template-columns: repeat(3, 1fr); } }
.how__step { position: relative; padding-top: calc(48px + var(--s4)); }
.how__step::before {
  counter-increment: step; content: counter(step);
  position: absolute; top: 0; left: 0;
  display: grid; place-items: center; width: 48px; height: 48px;
  font-family: var(--font-display); font-weight: 600; font-size: 1.5rem;
  color: var(--water); background: color-mix(in srgb, var(--shallow) 40%, transparent);
  border-radius: var(--radius-pill);
}
.how__step h3 { margin-bottom: var(--s2); }

/* 8b · Founder / "Meet the owner" — a paper panel that reads as its own block
   regardless of the neighbouring section's background. */
.founder__panel {
  display: grid; gap: var(--s8); align-items: center;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: var(--s8);
}
@media (min-width: 860px) {
  .founder__panel { grid-template-columns: .82fr 1.18fr; gap: var(--s12); padding: var(--s12); }
}
.founder__photo { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); aspect-ratio: 3 / 4; max-width: 360px; }
.founder__photo img { width: 100%; height: 100%; object-fit: cover; }
.founder__body > * + * { margin-top: var(--s4); }
.founder__sig { font-family: var(--font-display); font-weight: 600; color: var(--deep); font-size: var(--t-h3); }
.founder__sig span { display: block; font-family: var(--font-body); font-size: var(--t-small); font-weight: 400; color: var(--ink-muted); }

/* 9 · Service areas — plain statement (no per-city pages; intent routes to /quote/) */
.areas__chips { display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: center; }
.areas__line {
  max-width: 52ch; margin: var(--s6) auto 0; text-align: center;
  font-size: var(--t-h3); line-height: var(--lh-body); color: var(--ink);
}
.areas__line strong { color: var(--deep); font-weight: 600; }
.areas__cta { max-width: none; text-align: center; margin-top: var(--s3); }
.areas__cta a { color: var(--water); font-weight: 600; }
.areas__cta a:hover { color: var(--deep); }

/* Home "Where we work" — tappable city tiles (each routes to the /quote/ ZIP checker) */
.area-cards {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: stretch;
  gap: var(--s4); max-width: 920px; margin: var(--s8) auto 0;
  list-style: none; padding: 0;
}
.area-cards > li { display: flex; }   /* let each card fill the row's shared height */
.area-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s3);
  width: 152px; padding: var(--s5) var(--s3);
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  text-decoration: none; text-align: center;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.area-card:hover, .area-card:focus-visible {
  transform: translateY(-4px); box-shadow: var(--shadow-md);
  border-color: var(--water); text-decoration: none;
}
.area-card__pin {
  display: grid; place-items: center; width: 46px; height: 46px;
  border-radius: var(--radius-pill); background: var(--shallow); color: var(--deep);
  transition: background .18s ease, color .18s ease;
}
.area-card__pin svg { width: 22px; height: 22px; }
.area-card:hover .area-card__pin, .area-card:focus-visible .area-card__pin {
  background: var(--water); color: #fff;
}
.area-card__name { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; color: var(--deep); }
.areas__nearby { text-align: center; margin: var(--s5) auto 0; font-size: var(--t-small); color: var(--ink-muted); }
.areas__actions { display: flex; justify-content: center; margin-top: var(--s6); }
@media (prefers-reduced-motion: reduce) { .area-card, .area-card__pin { transition: none; } }

/* Expandable full ZIP list (client wanted the served ZIPs visible, not just the wizard check) */
.areas__zips { max-width: 62ch; margin: var(--s6) auto 0; text-align: center; }
.areas__zips > summary {
  cursor: pointer; display: inline-flex; align-items: center; gap: var(--s2);
  font-weight: 600; color: var(--water); list-style: none;
}
.areas__zips > summary::-webkit-details-marker { display: none; }
.areas__zips > summary::after { content: "\25BE"; font-size: .8em; transition: transform .2s ease; }
.areas__zips[open] > summary::after { transform: rotate(180deg); }
.areas__zips > summary:hover { color: var(--deep); }
.areas__zips-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--s4) var(--s6); margin-top: var(--s5); text-align: left;
}
.areas__zips-grid h3 {
  font-size: var(--t-small); text-transform: uppercase; letter-spacing: .04em;
  color: var(--deep); margin-bottom: var(--s1);
}
.areas__zips-grid p { font-size: var(--t-small); color: var(--ink-muted); line-height: var(--lh-body); max-width: none; }
.areas__zips-note { font-size: var(--t-small); color: var(--ink-muted); margin-top: var(--s5); text-align: center; max-width: none; }
@media (prefers-reduced-motion: reduce) { .areas__zips > summary::after { transition: none; } }

/* Home plans preview — two levels (Essential + Complete); keep the pair from stretching too wide */
.plans-preview { max-width: 760px; margin-inline: auto; }

/* ==========================================================================
   Gallery (/gallery/). Masonry via CSS columns so mixed portrait/landscape
   photos pack tightly without cropping. Scoped to .page-gallery.
   ========================================================================== */
.gallery-group + .gallery-group { margin-top: var(--s12); }
.gallery-grid { columns: 3 260px; column-gap: var(--s4); margin-top: var(--s6); }
@media (max-width: 560px) { .gallery-grid { column-gap: var(--s3); } }
.gallery__item {
  display: block; margin: 0 0 var(--s4); break-inside: avoid;
  border-radius: var(--radius-md); overflow: hidden; background: var(--sand);
  box-shadow: var(--shadow-sm); cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur) var(--ease);
}
.gallery__item img { display: block; width: 100%; height: auto; }
.gallery__item:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.gallery__item:focus-visible { outline: 3px solid var(--water); outline-offset: 2px; }

/* 11 · Final CTA band */
.cta-band { background: var(--deep); color: var(--on-deep); text-align: center; }
.cta-band h2 { color: var(--on-deep); }
.cta-band p { color: color-mix(in srgb, var(--on-deep) 82%, transparent); margin-inline: auto; }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: center; margin-top: var(--s8); }

/* ==========================================================================
   Service pages (/services/… + hub). Scoped to .page-service.
   Reuses .card / .service-card / .area-chip / .faq-accordion / .btn.
   ========================================================================== */
/* breadcrumb clearance now lives in the base .breadcrumbs rule (components.css) */
.svc-hero { padding-block: var(--s6) var(--s12); overflow: clip; }
.svc-hero__grid { display: grid; gap: var(--s8); align-items: center; }
@media (min-width: 900px) {
  /* Image column gets the larger share (client request). minmax(0,…) keeps the
     illustration from forcing the track wider than its fraction. */
  .svc-hero__grid { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); gap: var(--s12); }
}
/* Services-hub hero illustration — client-provided PNG with the outer white
   removed so it blends into the sand hero. */
.svc-hero__art { display: grid; place-items: center; }
.svc-hero__art img { display: block; width: 100%; height: auto; }
@media (min-width: 900px) {
  /* Let the illustration spill past the container toward the page edge (clipped
     by .svc-hero) so it reads as immersive rather than cut off at a hard box
     edge. Anchored left so it only bleeds right and never overlaps the copy. */
  .svc-hero__art { place-items: center start; }
  .svc-hero__art img { width: 132%; max-width: none; }
}
@media (max-width: 899px) {
  .svc-hero__art { padding-block: var(--s2); }
  .svc-hero__art img { max-width: 560px; }
}

/* "What's included" checklist */
.checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s3); }
/* Inline flow, not flex: a flex li turns each child — including bare text nodes —
   into a separate column, so "<strong>Label</strong> — detail" breaks into two. */
.checklist li { position: relative; padding-left: calc(1ch + var(--s3)); max-width: none; margin: 0; }
.checklist li::before { content: "✓"; position: absolute; left: 0; top: 0; color: var(--success); font-weight: 700; }
@media (min-width: 640px) { .checklist--2 { grid-template-columns: 1fr 1fr; gap: var(--s3) var(--s8); } }

/* Cost callout — water accent (NOT amber; amber is CTA-only) */
.cost-callout {
  border-left: 4px solid var(--water);
  background: var(--paper);
  border-radius: var(--radius-md);
  padding: var(--s6);
  box-shadow: var(--shadow-sm);
}
.cost-callout h3 { margin-bottom: var(--s2); }

.svc-prose > * + * { margin-top: var(--s4); }

/* Two-up content (e.g. includes + cost/why) */
.svc-split { display: grid; gap: var(--s8); }
@media (min-width: 900px) { .svc-split { grid-template-columns: 1.2fr .8fr; gap: var(--s12); align-items: start; } }

/* ==========================================================================
   About page (/about/). Scoped to .page-about. Reuses cards/badges/checklist.
   ========================================================================== */
.about-hero__grid { display: grid; gap: var(--s8); align-items: center; }
@media (min-width: 900px) { .about-hero__grid { grid-template-columns: 1fr .8fr; gap: var(--s12); } }
.about-portrait { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); aspect-ratio: 3 / 4; max-width: 420px; }
.about-portrait img { width: 100%; height: 100%; object-fit: cover; }

.prose { max-width: 68ch; }
.prose > * + * { margin-top: var(--s4); }
.prose h2 { margin-top: var(--s12); }

/* About "Our Story" — text + a sticky owner photo so the wide section reads
   balanced instead of a lone left column. */
.about-story__grid { display: grid; gap: var(--s8); }
.about-story__grid .prose { max-width: none; }   /* fill the text column */
.about-story__media {
  border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md);
  aspect-ratio: 3 / 4;
}
.about-story__media img { width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 900px) {
  /* image left, text right (alternates against the hero photo on the right) */
  .about-story__grid { grid-template-columns: .9fr 1.35fr; gap: var(--s16); align-items: start; }
  .about-story__media { position: sticky; top: 96px; }   /* pinned beside the scrolling text, clears the sticky header */
}

/* About "Our promise" — centered statement that separates the two photo sections */
.about-mission { text-align: center; }
.about-mission__statement {
  font-family: var(--font-display); font-weight: 500;
  font-size: var(--t-h2); line-height: 1.3; color: var(--deep);
  margin-top: var(--s4); max-width: none; text-wrap: balance;
}

.pullquote {
  font-family: var(--font-display); font-weight: 500;
  font-size: var(--t-h3); line-height: 1.35; color: var(--deep);
  border-left: 4px solid var(--shallow); padding-left: var(--s6);
  margin-block: var(--s8); max-width: none;
}

/* ==========================================================================
   Plans (/plans/) — service-level tiers + comparison table (§5.3)
   Client publishes "request a quote": no prices anywhere on this page.
   ========================================================================== */
.plan-card__tagline { color: var(--ink-muted); font-size: var(--t-small); margin-top: calc(var(--s2) * -1); }

/* Honest "why no prices" note under the cards — a centered callout */
.plans-pricing-note {
  display: flex; gap: var(--s3); align-items: center; justify-content: center;
  max-width: 64ch; margin: var(--s16) auto 0;
  padding: var(--s6) var(--s8);
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  text-align: center;
}
.plans-pricing-note svg { color: var(--water); flex-shrink: 0; }
.plans-pricing-note p { margin: 0; color: var(--ink); text-wrap: balance; }
@media (max-width: 560px) {
  .plans-pricing-note { flex-direction: column; gap: var(--s2); padding: var(--s5) var(--s6); }
}

/* Comparison table */
.compare-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.compare {
  width: 100%; border-collapse: collapse; min-width: 640px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
}
.compare th, .compare td {
  padding: var(--s4) var(--s5); text-align: center;
  border-bottom: 1px solid var(--line); vertical-align: middle;
}
.compare thead th { background: var(--deep); color: #fff; font-family: var(--font-display); font-weight: 600; }
.compare tbody th[scope="row"], .compare tfoot td:first-child { text-align: left; font-weight: 500; color: var(--deep); }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }
.compare__yes { color: var(--success); font-weight: 700; font-size: 1.1em; }
.compare__no { color: var(--shallow); }
/* The featured-column tint only means anything while this is a real table. Once
   it stacks into cards (≤640px) there is no column to highlight, so scope the
   tint here rather than repainting it and then unpainting it per-section below. */
@media (min-width: 641px) {
  .compare__featured { background: color-mix(in srgb, var(--sun) 8%, transparent); }
  .compare thead .compare__featured { background: var(--sun); color: #fff; }
  .compare tfoot td { padding-top: var(--s5); background: var(--sand); }
  .compare tfoot .compare__featured { background: color-mix(in srgb, var(--sun) 12%, var(--sand)); }
}

/* Stack the table into cards on narrow screens */
@media (max-width: 640px) {
  .compare { min-width: 0; border: 0; background: transparent; }
  .compare thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .compare tbody tr {
    /* One equal column per plan (Essential + Complete). The row title spans the
       full width above them, so there's no label column here — and `auto` tracks
       would size to each plan name, spacing the checkmarks unevenly. */
    display: grid; grid-template-columns: repeat(2, 1fr);
    gap: var(--s2); align-items: start;
    background: var(--paper); border: 1px solid var(--line);
    border-radius: var(--radius-md); margin-bottom: var(--s3); padding: var(--s2) var(--s3);
  }
  .compare tbody th[scope="row"] { grid-column: 1 / -1; text-align: left; border: 0; padding: var(--s2) var(--s1) var(--s1); }
  .compare tbody td { border: 0; padding: var(--s1); font-size: var(--t-small); }
  .compare tbody td::before { content: attr(data-label) ": "; color: var(--ink-muted); font-size: var(--t-micro); display: block; }
  .compare tfoot tr { display: grid; grid-template-columns: 1fr; gap: var(--s5); }
  .compare tfoot td:first-child { display: none; }
  /* border: 0 clears the `.compare th, .compare td` hairline, which would
     otherwise float under each stacked button as an unexplained divider. */
  .compare tfoot td { padding: 0; border: 0; }
  /* Stacked, every button reads "Get a quote" — name the plan each one is for
     (thead is hidden on mobile, so nothing else identifies them). */
  .compare tfoot td::before {
    content: attr(data-label); display: block; text-align: left;
    color: var(--ink-muted); font-size: var(--t-micro); font-weight: 600;
    text-transform: uppercase; letter-spacing: .06em; margin-bottom: var(--s2);
  }
}

/* ==========================================================================
   Contact (/contact/) — form + direct-contact details (§5.7)
   ========================================================================== */
.contact__grid { display: grid; gap: var(--s8); grid-template-columns: 1.4fr 1fr; align-items: start; }
@media (max-width: 860px) { .contact__grid { grid-template-columns: 1fr; } }
/* Grid items default to min-width:auto, so a long unbreakable token (the email
   address) would widen the track past the viewport. */
.contact__grid > * { min-width: 0; }

.contact__form-card { padding: var(--s8); }
.contact__form-intro { color: var(--ink-muted); margin-bottom: var(--s6); }
.contact__form-row { display: grid; gap: var(--s4); grid-template-columns: 1fr 1fr; }
@media (max-width: 480px) { .contact__form-row { grid-template-columns: 1fr; } }
.req { color: var(--danger); }

/* Preferred-contact radios */
.contact__prefs { border: 0; padding: 0; margin: 0 0 var(--s6); }
.contact__radios { display: flex; flex-wrap: wrap; gap: var(--s4); margin-top: var(--s2); }
.contact__radio { display: inline-flex; align-items: center; gap: var(--s2); font-weight: 400; color: var(--ink); }
.contact__radio input { width: auto; accent-color: var(--water); }

/* Submit status message */
.contact__status {
  margin-bottom: var(--s4); padding: var(--s3) var(--s4);
  border-radius: var(--radius-md); font-size: var(--t-small); font-weight: 500;
}
.contact__status[data-kind="error"]   { background: color-mix(in srgb, var(--danger) 10%, transparent); color: var(--danger); }
.contact__status[data-kind="success"] { background: color-mix(in srgb, var(--success) 12%, transparent); color: var(--success); }
.contact__status[data-kind="notice"]  { background: var(--shallow); color: var(--deep); }

/* Details aside */
.contact__aside { display: flex; flex-direction: column; gap: var(--s6); position: sticky; top: calc(var(--s16, 96px)); }
@media (max-width: 860px) { .contact__aside { position: static; } }
.contact__card, .contact__promise { padding: var(--s6); }
.contact__card-title { font-size: var(--t-h3); margin-bottom: var(--s5); }
.contact__list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--s5); }
.contact__list li { margin: 0; }  /* cancel base.css `li + li` — the list spaces itself with gap */
.contact__item { display: flex; gap: var(--s4); align-items: flex-start; }
.contact__icon {
  flex-shrink: 0; width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--water) 12%, transparent); color: var(--water);
}
.contact__icon svg { width: 20px; height: 20px; }
.contact__label { display: block; font-size: var(--t-small); color: var(--ink-muted); }
.contact__value { display: block; font-weight: 600; color: var(--deep); overflow-wrap: anywhere; }
a.contact__value:hover { color: var(--water); }
.contact__promise { background: var(--shallow); }
.contact__promise-text { color: var(--deep); margin-block: var(--s2) var(--s5); }

/* ==========================================================================
   Quote wizard (/quote/) — progressive-enhancement multi-step form (§6)
   No-JS baseline: all fieldsets stack into one long form. With JS the form
   gets .is-enhanced and shows one step at a time.
   ========================================================================== */
.quote-form { max-width: 760px; margin-inline: auto; padding: var(--s12); }
@media (max-width: 640px) { .quote-form { padding: var(--s8) var(--s6); } }
@media (max-width: 420px) { .quote-form { padding: var(--s6) var(--s5); } }

/* --- Progress stepper (JS-only) — connected horizontal steps ---------- */
.quote-form .step-indicator { display: none; }
.quote-form.is-enhanced .step-indicator {
  display: flex; justify-content: space-between; align-items: flex-start; position: relative;
  /* nowrap is load-bearing: the rail below is absolutely positioned on one row,
     and 6 dots don't fit a 320px screen. Overrides the base component's wrap. */
  flex-wrap: nowrap;
  margin: 0 0 var(--s12); padding: 0 0 calc(var(--s6) + 1.3em);
  border-bottom: 1px solid var(--line);
}
/* One continuous track spanning the FULL content width (first dot centre → last
   dot centre, and the end dots sit at the content edges), with a coloured
   progress fill driven by --wizard-progress (0–1, set in JS). */
.quote-form.is-enhanced .step-indicator::before,
.quote-form.is-enhanced .step-indicator::after {
  content: ""; position: absolute; top: 17px; height: 2px; z-index: 0; left: 18px;
}
.quote-form.is-enhanced .step-indicator::before { right: 18px; background: var(--line); }
.quote-form.is-enhanced .step-indicator::after {
  width: calc((100% - 36px) * var(--wizard-progress, 0)); background: var(--water);
  transition: width var(--dur) var(--ease);
}
/* Each step is just the 36px dot; the label is absolutely centred beneath it so
   variable label widths can't push the dots off their even spacing. */
.quote-form.is-enhanced .step-indicator li {
  flex: 0 0 36px; position: relative; color: var(--ink-muted);
}
/* The dot+label are a button so any completed step is a jump target. */
.quote-form.is-enhanced .step-indicator__btn {
  position: relative; display: block; width: 36px; height: 36px;
  padding: 0; border: 0; background: none; color: inherit; font: inherit;
  cursor: pointer; overflow: visible; border-radius: var(--radius-pill);
}
.quote-form.is-enhanced .step-indicator__btn:hover .step-indicator__dot { border-color: var(--water); }
.quote-form.is-enhanced .step-indicator__dot {
  position: relative; z-index: 1; width: 36px; height: 36px; font-size: var(--t-small);
  transition: border-color var(--dur) var(--ease);
}
.quote-form.is-enhanced .step-indicator__label {
  position: absolute; top: calc(100% + var(--s3)); left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: var(--t-micro); line-height: 1.2; color: inherit;
}
.quote-form.is-enhanced .step-indicator [aria-current="step"] .step-indicator__label { color: var(--deep); font-weight: 700; }
@media (max-width: 600px) {
  .quote-form.is-enhanced .step-indicator li:not([aria-current="step"]) .step-indicator__label { display: none; }
}

/* --- Steps ----------------------------------------------------------- */
.wizard-step { border: 0; padding: 0; margin: 0; min-inline-size: 0; }
.quote-form.is-enhanced .wizard-step:not(.is-active) { display: none; }
.quote-form.is-enhanced .wizard-step.is-active { min-height: 300px; }
/* No-JS long form: clearly divide each section */
.quote-form:not(.is-enhanced) .wizard-step + .wizard-step {
  margin-top: var(--s12); padding-top: var(--s12); border-top: 1px solid var(--line);
}
.wizard-step__title { font-size: var(--t-h2); color: var(--deep); margin-bottom: var(--s3); }
.wizard-step__title:focus { outline: none; }
.wizard-step__hint { color: var(--ink-muted); margin: 0 0 var(--s8); }
.wizard-step__title + .choice-grid { margin-top: var(--s6); }
.wizard-group__label { font-weight: 600; color: var(--deep); font-size: var(--t-body); margin: var(--s8) 0 var(--s4); }
.wizard-step__title + .wizard-group__label { margin-top: var(--s6); }

/* --- Choice cards (radio/checkbox) ----------------------------------- */
.choice-grid { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.choice-grid--tight { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.choice-grid--stack { grid-template-columns: 1fr; }
.choice-grid.is-invalid { outline: 2px solid var(--danger); outline-offset: 6px; border-radius: var(--radius-lg); }

/* Each option is a "water tile": icon chip + label + an animated check badge. */
.choice {
  position: relative;
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s5); padding-right: calc(var(--s5) + 26px);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--paper); cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}

/* Native input hidden only once JS enhances the wizard; without JS it stays a
   real, visible control so the plain form still works. Never display:none. */
.quote-form.is-enhanced .choice input {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.choice input { accent-color: var(--water); flex-shrink: 0; }

/* Icon chip — inverts to solid water when selected */
.choice__icon {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 44px; height: 44px; border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--shallow) 32%, var(--paper)); color: var(--water);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.choice__icon svg { width: 23px; height: 23px; display: block; }

.choice__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.choice__title { font-weight: 600; color: var(--deep); line-height: 1.3; }
.choice__desc { font-size: var(--t-small); color: var(--ink-muted); line-height: 1.45; }

.choice:hover { border-color: var(--shallow); box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.choice:hover .choice__icon { background: color-mix(in srgb, var(--shallow) 55%, var(--paper)); }
.choice:focus-within { border-color: var(--water); box-shadow: 0 0 0 3px color-mix(in srgb, var(--water) 22%, transparent); }

.choice:has(:checked) {
  border-color: var(--water);
  background: linear-gradient(180deg, color-mix(in srgb, var(--shallow) 26%, var(--paper)) 0%, var(--paper) 78%);
  box-shadow: var(--shadow-md); transform: translateY(-1px);
}
.choice:has(:checked) .choice__icon { background: var(--water); color: var(--paper); }
.choice:focus-within:has(:checked) { box-shadow: var(--shadow-md), 0 0 0 3px color-mix(in srgb, var(--water) 22%, transparent); }

/* Short options (pool type / size / features / frequency): icon-forward, centered */
.choice-grid--tight .choice {
  flex-direction: column; align-items: center; text-align: center;
  gap: var(--s3); padding: var(--s6) var(--s4);
}
.choice-grid--tight .choice__text { align-items: center; }

/* Animated selection badge (JS injects .choice__indicator into each .choice) */
.choice__indicator { position: absolute; top: var(--s3); right: var(--s3); width: 22px; height: 22px; line-height: 0; pointer-events: none; }
.choice__indicator svg { width: 100%; height: 100%; overflow: visible; }
.choice__indicator-ring { fill: none; stroke: var(--line); stroke-width: 1.5; transition: stroke var(--dur) var(--ease); }
.choice:hover .choice__indicator-ring { stroke: var(--shallow); }
.choice:focus-within .choice__indicator-ring { stroke: var(--water); }
.choice__indicator-badge { transform-origin: 12px 12px; transform: scale(0); opacity: 0; }
.choice__indicator-fill { fill: var(--water); }
.choice__indicator-check {
  fill: none; stroke: var(--paper); stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 20; stroke-dashoffset: 20;
}
.choice:has(:checked) .choice__indicator-ring { opacity: 0; }
.choice:has(:checked) .choice__indicator-badge { animation: indicator-pop var(--dur) var(--ease) forwards; }
.choice:has(:checked) .choice__indicator-check { animation: indicator-draw 180ms var(--ease) 90ms forwards; }
@keyframes indicator-pop { 0% { transform: scale(0); opacity: 0; } 60% { transform: scale(1.12); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes indicator-draw { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  .choice, .choice__icon, .choice__indicator-ring { transition: none; }
  .choice:hover, .choice:has(:checked) { transform: none; }
  .choice__indicator-badge, .choice__indicator-check { animation: none !important; }
  .choice:has(:checked) .choice__indicator-badge { transform: scale(1); opacity: 1; }
  .choice:has(:checked) .choice__indicator-check { stroke-dashoffset: 0; }
}

/* --- Navigation + submit --------------------------------------------- */
.wizard-nav { display: flex; gap: var(--s4); margin-top: var(--s12); }
.quote-form.is-enhanced .wizard-nav { border-top: 1px solid var(--line); padding-top: var(--s8); }
.wizard-nav [data-wizard-next] { margin-left: auto; }
.quote-form.is-enhanced .quote-form__submit { margin-top: var(--s6); }

/* Step-level error + soft notices */
.wizard-step__error { display: none; color: var(--danger); font-weight: 500; font-size: var(--t-small); margin-top: var(--s4); }
.wizard-step__error:not([hidden]) { display: block; }
.wizard-notice { margin-top: var(--s4); padding: var(--s3) var(--s4); border-radius: var(--radius-md); font-size: var(--t-small); font-weight: 500; }
.wizard-notice[data-kind="success"] { background: color-mix(in srgb, var(--success) 12%, transparent); color: var(--success); }
.wizard-notice[data-kind="notice"]  { background: var(--shallow); color: var(--deep); }
.wizard-notice[data-kind="error"]    { background: color-mix(in srgb, var(--danger) 10%, transparent); color: var(--danger); }
.wizard-notice a { color: inherit; }

/* Results recap on the final step */
.quote-summary {
  background: color-mix(in srgb, var(--shallow) 25%, var(--paper));
  border: 1px solid var(--shallow); border-radius: var(--radius-md);
  padding: var(--s5); margin-block: var(--s6);
}
.quote-summary__title { font-size: var(--t-h3); margin-bottom: var(--s3); }
.quote-summary__list { display: grid; gap: var(--s2); margin: 0 0 var(--s4); }
.quote-summary__list > div { display: flex; gap: var(--s3); justify-content: space-between; font-size: var(--t-small); border-bottom: 1px dashed var(--line); padding-bottom: var(--s2); }
.quote-summary__list dt { color: var(--ink-muted); }
.quote-summary__list dd { margin: 0; font-weight: 600; color: var(--deep); text-align: right; }
.quote-summary__estimate { margin: 0; color: var(--ink); }

/* Enter-animation for step advance (killed under reduced-motion, §4.5) */
@media (prefers-reduced-motion: no-preference) {
  .wizard-step--in { animation: wizard-step-in var(--dur) var(--ease); }
  @keyframes wizard-step-in {
    from { opacity: 0; transform: translateX(12px); }
    to   { opacity: 1; transform: translateX(0); }
  }
}

/* Confirmation panel */
.quote-confirm { max-width: 600px; margin-inline: auto; text-align: center; padding: var(--s12) var(--s8); }
.quote-confirm__icon { color: var(--success); display: inline-flex; margin-bottom: var(--s4); }
.quote-confirm[data-kind="error"] .quote-confirm__icon { color: var(--danger); }
.quote-confirm[data-kind="notice"] .quote-confirm__icon { color: var(--water); }
.quote-confirm__title:focus { outline: none; }
.quote-confirm__body { color: var(--ink); max-width: 46ch; margin: var(--s3) auto var(--s6); }
.quote-confirm__body a { color: var(--water); font-weight: 600; }

/* ==========================================================================
   Styleguide (/styleguide.html) — the Phase 0 review gate.
   Renders every token and component. Not shipped to production nav.
   ========================================================================== */
.page-styleguide .sg-section { padding-block: var(--s12); border-top: 1px solid var(--line); }
.page-styleguide .sg-section:first-of-type { border-top: 0; }
.page-styleguide h2 { margin-bottom: var(--s6); }

/* Swatch grid */
.sg-swatches { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.sg-swatch { border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; background: var(--paper); }
.sg-swatch__chip { height: 72px; }
.sg-swatch__meta { padding: var(--s3); font-size: var(--t-small); }
.sg-swatch__name { font-weight: 600; color: var(--deep); }
.sg-swatch__val { color: var(--ink-muted); font-family: ui-monospace, monospace; font-size: var(--t-micro); }

/* Type specimens */
.sg-type > * { margin-bottom: var(--s4); }
.sg-type .label { display: block; font-size: var(--t-micro); color: var(--ink-muted); font-family: ui-monospace, monospace; }

/* Spacing scale */
.sg-space { display: flex; flex-direction: column; gap: var(--s3); }
.sg-space__row { display: flex; align-items: center; gap: var(--s4); font-size: var(--t-small); }
.sg-space__bar { height: 16px; background: var(--water); border-radius: var(--radius-sm); }

/* Elevation demo */
.sg-elev { display: grid; gap: var(--s6); grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.sg-elev__card { background: var(--paper); border-radius: var(--radius-lg); padding: var(--s6); text-align: center; font-size: var(--t-small); }

/* Component demo scaffolding */
.sg-demo { display: grid; gap: var(--s6); }
.sg-demo--row { grid-auto-flow: column; grid-auto-columns: max-content; align-items: center; overflow-x: auto; }

/* ==========================================================================
   Blog — "Coming soon" holding page (/blog/). An underwater scene: a deep-water
   gradient, seamless drifting wave surfaces (same one-tile-drift technique as
   the signature water-line, so motion never seams), and bubbles rising through.
   Scoped to .page-blog. Static under prefers-reduced-motion.
   ========================================================================== */
.page-blog { background: var(--deep); }
.blog-scene {
  position: relative; overflow: hidden;
  min-height: calc(100svh - 64px);
  display: grid; place-items: center;
  padding: var(--s16) var(--s5);
  background: linear-gradient(180deg, #0B3D4F 0%, #0F5163 46%, #146277 100%);
  color: var(--on-deep); text-align: center;
}
.blog-scene__inner { position: relative; z-index: 3; max-width: 46ch; }
.blog-scene__inner .eyebrow { color: var(--shallow); }
.blog-scene__inner h1 { color: var(--on-deep); margin-top: var(--s3); }
.blog-scene__lede { color: color-mix(in srgb, var(--on-deep) 82%, transparent); margin-top: var(--s4); font-size: 1.1875rem; line-height: var(--lh-body); }
.blog-scene__actions { display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: center; margin-top: var(--s8); }

/* Drifting wave surfaces — filled 240px sine tile, one-tile drift = seamless. */
.blog-wave { position: absolute; left: 0; right: 0; height: 120px; z-index: 1; pointer-events: none;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='240'%20height='120'%20viewBox='0%200%20240%20120'%3E%3Cpath%20fill='white'%20d='M0%2024%20Q60%200%20120%2024%20T240%2024%20L240%20120%20L0%20120%20Z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='240'%20height='120'%20viewBox='0%200%20240%20120'%3E%3Cpath%20fill='white'%20d='M0%2024%20Q60%200%20120%2024%20T240%2024%20L240%20120%20L0%20120%20Z'/%3E%3C/svg%3E");
  -webkit-mask-repeat: repeat-x; mask-repeat: repeat-x; -webkit-mask-size: 240px 100%; mask-size: 240px 100%; }
.blog-wave--1 { top: 30%; background: color-mix(in srgb, var(--shallow) 22%, transparent); }
.blog-wave--2 { top: 46%; background: color-mix(in srgb, var(--shallow) 16%, transparent); }
.blog-wave--3 { top: 62%; background: color-mix(in srgb, var(--water) 30%, transparent); }

/* Bubbles rising through the water. Fade in/out hides the loop reset. */
.blog-bubbles { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.blog-bubble { position: absolute; bottom: -40px; border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, rgba(255,255,255,.55), rgba(168,216,220,.10) 60%, transparent 70%);
  box-shadow: inset 0 0 4px rgba(255,255,255,.3); opacity: 0; }

@media (prefers-reduced-motion: no-preference) {
  .blog-wave--1 { animation: blog-drift 18s linear infinite; }
  .blog-wave--2 { animation: blog-drift 26s linear infinite reverse; }
  .blog-wave--3 { animation: blog-drift 34s linear infinite; }
  .blog-bubble { animation: blog-rise var(--dur, 12s) ease-in infinite; animation-delay: var(--delay, 0s); }
}
/* one full tile-width of travel = seamless loop */
@keyframes blog-drift { from { -webkit-mask-position: 0 0; mask-position: 0 0; } to { -webkit-mask-position: -240px 0; mask-position: -240px 0; } }
@keyframes blog-rise {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  10%  { opacity: .8; }
  90%  { opacity: .5; }
  100% { transform: translateY(-104svh) translateX(var(--sway, 20px)); opacity: 0; }
}

/* ==========================================================================
   Reviews carousel (home). Progressive enhancement: with no JS the reviews
   render as a readable centered stack; reviews.js adds .is-enhanced to turn
   the track into a one-at-a-time slider with arrows + dots.
   ========================================================================== */
.reviews-carousel { margin-top: var(--s8); }
.reviews-carousel__track { list-style: none; margin: 0; padding: 0; }
/* override the global readability cap (p, li { max-width: var(--measure) }) so a
   slide can fill its full-width column; the card sets its own reading width. */
.reviews-carousel__slide { max-width: none; }
.reviews-carousel__slide + .reviews-carousel__slide { margin-top: var(--s4); }

.review-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s5);
  max-width: 720px; margin-inline: auto;
  padding: var(--s8); text-align: center;
  background: var(--paper); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.review-card__quote { font-family: var(--font-display); font-size: var(--t-h3); font-weight: 500; color: var(--deep); line-height: 1.4; max-width: 54ch; }
.review-card__cite { font-style: normal; font-size: var(--t-small); color: var(--ink-muted); }
.review-card__cite strong { color: var(--ink); font-weight: 600; }

/* Enhanced: horizontal slider. Slides size to their own content and the
   viewport animates to the active slide's height (reviews.js sets it) — forcing
   every slide to the tallest one left a short review with ~250px of dead space
   on a phone, where the longest quote wraps to 3x the lines. */
.reviews-carousel.is-enhanced .reviews-carousel__viewport { overflow: hidden; }
.reviews-carousel.is-enhanced .reviews-carousel__track { display: grid; grid-auto-flow: column; grid-auto-columns: 100%; align-items: start; justify-items: stretch; }
.reviews-carousel.is-enhanced .reviews-carousel__slide { width: 100%; min-width: 0; margin: 0; padding-inline: var(--s2); display: flex; }
.reviews-carousel.is-enhanced .review-card { width: 100%; }
@media (prefers-reduced-motion: no-preference) {
  .reviews-carousel.is-enhanced .reviews-carousel__track { transition: transform var(--dur) var(--ease); }
  /* armed by reviews.js once a height is on the element, so no animation from 0 */
  .reviews-carousel.is-enhanced[data-rc-ready] .reviews-carousel__viewport { transition: height var(--dur) var(--ease); }
}
@media (prefers-reduced-motion: reduce) {
  /* No transition to smooth a height change, so keep the slides equal-height —
     the arrangement that never jumps. reviews.js leaves the height unset here. */
  .reviews-carousel.is-enhanced .reviews-carousel__track { align-items: stretch; }
}

.reviews-carousel__controls { display: flex; align-items: center; justify-content: center; gap: var(--s4); margin-top: var(--s6); }
.reviews-carousel__arrow {
  display: grid; place-items: center; width: 44px; height: 44px; flex: 0 0 auto;
  border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--paper); color: var(--deep);
  cursor: pointer; transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.reviews-carousel__arrow:hover { border-color: var(--water); background: var(--sand); }
.reviews-carousel__arrow:focus-visible { outline: 3px solid var(--water); outline-offset: 2px; }
.reviews-carousel__dots { display: flex; gap: var(--s1); }
.reviews-carousel__dot { display: grid; place-items: center; width: 40px; height: 44px; padding: 0; border: none; background: none; cursor: pointer; }
.reviews-carousel__dot::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--shallow); transition: background var(--dur) var(--ease), transform var(--dur) var(--ease); }
.reviews-carousel__dot:hover::before { background: var(--water); }
.reviews-carousel__dot[aria-current="true"]::before { background: var(--water); transform: scale(1.35); }
.reviews-carousel__dot:focus-visible { outline: 2px solid var(--water); outline-offset: 2px; border-radius: var(--radius-md); }
.reviews-source { max-width: none; margin-top: var(--s6); text-align: center; font-size: var(--t-small); color: var(--ink-muted); }
.reviews-source a { color: var(--water); font-weight: 600; }
.reviews-source a:hover { color: var(--deep); }

/* ==========================================================================
   Legal pages (/terms/, and future /privacy/). Readable long-form prose.
   Scoped to .legal. Reuses the narrow container.
   ========================================================================== */
.legal { max-width: 72ch; margin-inline: auto; }
.legal > * + * { margin-top: var(--s4); }
.legal h2 { margin-top: var(--s12); font-size: var(--t-h3); color: var(--deep); }
.legal h3 { margin-top: var(--s6); font-size: 1.05rem; color: var(--deep); }
.legal p, .legal li { max-width: none; color: var(--ink); line-height: var(--lh-body); }
.legal ul { padding-left: var(--s6); list-style: disc; }
.legal li + li { margin-top: var(--s2); }
.legal a { color: var(--water); font-weight: 500; }
.legal a:hover { color: var(--deep); }
.legal__meta { color: var(--ink-muted); font-size: var(--t-small); }
.legal__sms { border-left: 4px solid var(--water); background: var(--paper); border-radius: var(--radius-md); padding: var(--s6); box-shadow: var(--shadow-sm); }
.legal__sms > * + * { margin-top: var(--s3); }
