/* ==========================================================================
   LockYourBike website v2 — design system
   Governed by projects/website-v2/design-decisions.md
   Mobile-first: every rule is written for 375px, then widened with min-width
   media queries. Fluid values below interpolate between a 375px and a
   1440px viewport — the two ends of "phone the team votes on" to
   "desk monitor the MD forwards the link to."
   ========================================================================== */

/* ---- 0. Fonts — self-hosted, no external requests ----
   Fraunces (Google Fonts, OFL licence) and Switzer (Fontshare, free
   commercial licence) are both free to self-host. Self-hosting instead of
   linking fonts.googleapis.com/api.fontshare.com removes a third-party
   DNS lookup + connection from the critical path, which matters against
   the LCP < 1.5s bar in design-decisions §11 — a render-blocking @font-face
   is cheaper than a render-blocking cross-origin stylesheet fetch. */

@font-face {
  font-family: 'Fraunces';
  src: url('../fonts/fraunces-variable.woff2') format('woff2');
  font-weight: 400 600; /* variable file covers the whole range design-decisions §5 asks for (400–600) in one download */
  font-style: normal;
  font-display: swap; /* show the fallback serif instantly rather than an invisible hero H1 */
  font-optical-sizing: auto; /* Fraunces' optical-size axis; lets large hero text and small UI text pull different glyph shapes from the same file */
}

@font-face {
  font-family: 'Switzer';
  src: url('../fonts/switzer-light.woff2') format('woff2');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Switzer';
  src: url('../fonts/switzer-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Switzer';
  src: url('../fonts/switzer-medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ---- 1. Colour tokens (design-decisions §4) ----
   Drawn from the Suffolk coast at dusk, not the old couples-era parchment
   palette. Cooler and deeper on purpose: reads landscape and confidence,
   not romance. */
:root {
  --chalk:   #F7F5F0; /* page background. Off-white with no yellow cast — parchment read was banned outright (design-decisions §3, §11) */
  --estuary: #1C2B33; /* primary dark: headlines, footer. A deep blue-slate, not brown-black, so it never drifts toward "olde-worlde" */
  --deben:   #4A6B7C; /* secondary: eyebrows, links, quiet UI. Sits between chalk and estuary so quiet UI never competes with the one accent colour */
  --reed:    #7E8B70; /* sparing use only: success states, nature accents. A second colour would dilute Ember as THE accent, so this stays rare on purpose */
  --ember:   #A85B2A; /* THE single accent: every CTA, the wax seal, hover states, nowhere else. One accent colour is the whole discipline the quiet-luxury register depends on */
  --dusk:    #12202B; /* dark section background, one shade below Estuary. Used for "the evening" and "the story" sections — the page gets darker where the story gets closer (design-decisions §4) */

  /* Same tokens as RGB triplets, for places that need an alpha channel
     (overlays, hover tints) without hand-picking a new colour */
  --chalk-rgb:   247, 245, 240;
  --estuary-rgb: 28, 43, 51;
  --dusk-rgb:    18, 32, 43;

  --content-max: 1200px; /* the content grid width design-decisions §6 sets for full-bleed photography to break against */
  --measure: 68ch;       /* line-length cap — long-form copy stops being readable past this on wide screens */
}

/* ---- 2. Fluid type scale (design-decisions §5) ----
   clamp(min, preferred, max) per step. Preferred values interpolate
   between a 375px and a 1440px viewport so type grows continuously
   instead of jumping at breakpoints. Only display/heading sizes are
   fluid — body copy and UI labels are fixed. Reading text shouldn't
   change size with viewport width; only the type that has to command a
   full-bleed photo does. */
:root {
  --step-hero:    clamp(2.5rem,  1.44rem + 4.5vw,  5.5rem);   /* 40px → 88px, the H1. Range fixed by design-decisions §5 */
  --step-h2:      clamp(1.75rem, 1.4rem + 1.5vw,   2.75rem);  /* 28px → 44px, section headings ("The shape", "The evening") */
  --step-sub:     clamp(1.25rem, 1.07rem + 0.75vw, 1.75rem);  /* 20px → 28px, the hero subhead / section standfirsts */
  --step-h3:      clamp(1.375rem, 1.2rem + 0.75vw, 1.875rem); /* 22px → 30px, card and sub-section titles */
  --step-lead:    clamp(1.125rem, 1.04rem + 0.4vw, 1.375rem); /* 18px → 22px, intro paragraphs under a heading */

  --step-body:    1.0625rem; /* 17px fixed — design-decisions §5 states body size explicitly; a reading paragraph doesn't need to scale with the viewport, only wrap narrower */
  --step-small:   0.875rem;  /* 14px fixed — captions, trust-strip labels, footer links */
  --step-eyebrow: 0.8125rem; /* 13px fixed — the wide-tracked uppercase label; a UI label keeps a constant size the way a badge would */
}

/* ---- 3. Spacing scale ----
   Fixed steps for anything inside a component (gaps that should feel
   identical on a phone and a monitor); fluid steps only for the macro
   rhythm between sections, where more screen really should mean more air. */
:root {
  --space-3xs: 0.25rem; /* 4px  — icon-to-label gaps */
  --space-2xs: 0.5rem;  /* 8px  — tight inline spacing */
  --space-xs:  0.75rem; /* 12px — eyebrow-to-heading gaps */
  --space-sm:  1rem;    /* 16px — base paragraph spacing */
  --space-md:  1.5rem;  /* 24px — component internal padding */
  --space-lg:  2rem;    /* 32px — gaps between related components in a section */
  --space-xl:  3rem;    /* 48px — gaps between distinct blocks within one section */

  --space-2xl: clamp(3rem, 6vw, 5rem);  /* 48px → 80px — a section's own top/bottom padding, so wide layouts don't feel cramped against the 1200px content grid */
  --space-3xl: clamp(4rem, 10vw, 8rem); /* 64px → 128px — the gap between whole homepage sections; the light/dusk contrast in §4 needs room to read as a deliberate shift, not a cramped stack */
}

/* ---- 4. Reset & base ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; }

body {
  background: var(--chalk);
  color: var(--estuary);
  font-family: 'Switzer', -apple-system, 'Helvetica Neue', sans-serif; /* system sans fallback renders instantly while Switzer loads */
  font-size: var(--step-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: var(--deben); }
p { max-width: var(--measure); }

/* One focus style everywhere, so the WCAG AA bar (design-decisions §11)
   holds without every interactive element needing its own :focus rule. */
a:focus-visible,
button:focus-visible,
.btn:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 3px;
}

/* Skip link: off-screen until focused, so keyboard users can jump the header. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--estuary);
  color: var(--chalk);
  padding: 0.6em 1em;
  border-radius: 2px;
  text-decoration: none;
}
.skip-link:focus { left: var(--space-md); top: var(--space-md); }

/* Scroll-reveal utility (design-decisions §9: fade up 12px, once).
   Gated twice over: only when JS has run (.js) AND the user has not asked
   for reduced motion. If either is false, .reveal content shows normally,
   so nothing is ever hidden behind an animation that never fires. */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 600ms ease, transform 600ms ease;
  }
  .js .reveal.is-visible {
    opacity: 1;
    transform: none;
  }
}

/* ---- 5. Shared components ---- */

/* Eyebrow: wide-tracked uppercase sans (design-decisions §5, "kept device").
   Fixed size on purpose — see --step-eyebrow above. */
.eyebrow {
  font-family: 'Switzer', -apple-system, 'Helvetica Neue', sans-serif;
  font-size: var(--step-eyebrow);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.btn {
  display: inline-block;
  font-family: 'Switzer', -apple-system, 'Helvetica Neue', sans-serif;
  font-size: 1rem;
  font-weight: 500;
  text-decoration: none;
  padding: 0.9em 1.8em;
  border-radius: 2px; /* barely-there radius — a sharp corner reads confident, a rounded one reads soft-agency (the Penguins anti-pattern) */
  transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}

/* Primary CTA: Ember, one per viewport max (design-decisions §6).
   There is deliberately no secondary "loud" button style — the whole
   site only ever has one shade of urgency on screen at a time. */
.btn--primary {
  background: var(--ember);
  color: var(--chalk);
}
.btn--primary:hover { background: #935024; } /* ~15% darker Ember, hover should read as depth not a colour change */

/* Ghost: for the CTA that sits over a photo (the header). A faint dark
   backplate + a stronger border so it stays legible over the bright top of
   the hero photo, where a border-only button disappeared. */
.btn--ghost {
  color: var(--chalk);
  background: rgba(var(--dusk-rgb), 0.22);
  border: 1px solid rgba(var(--chalk-rgb), 0.55);
  padding: 0.55em 1.2em;
}
.btn--ghost:hover {
  background: rgba(var(--dusk-rgb), 0.38);
  border-color: var(--chalk);
}

/* Quiet text CTA: the "See the full weekend" / "Request a proposal" link
   style — present everywhere a section deliberately has no primary CTA
   (design-decisions §6, one CTA per viewport). */
.btn--text {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-family: 'Switzer', -apple-system, 'Helvetica Neue', sans-serif;
  font-weight: 500;
  color: var(--deben);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.btn--text:hover { border-bottom-color: currentColor; }

/* ---- 6. Header ---- */
.site-header {
  position: absolute; /* sits over the hero photo */
  inset: 0 0 auto 0;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-md) var(--space-md);
  max-width: var(--content-max);
  margin-inline: auto;
}

.wordmark {
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 500;
  font-size: 1rem;
  letter-spacing: 0.22em;
  color: var(--chalk);
  text-decoration: none;
}

/* Header CTA is hidden on mobile: it duplicated the hero's Ember CTA in the
   first viewport. It returns at 768px where there's nav context for it. */
.site-header .btn--ghost { display: none; }

/* ---- 7. Hero (page-specific, built on the system above) ---- */
.hero {
  position: relative;
  min-height: 100svh; /* full-bleed on phones — the vote happens here */
  display: flex;
  align-items: flex-end;
  color: var(--chalk);
}

.hero__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--dusk); /* fill behind the photo while it decodes, so the hero is never a white flash */
}

.hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* full-bleed; the 16:9 photo is cropped to whatever the viewport is, tightest on a portrait phone */
  /* Keep the five riders in frame on a tall phone crop. The group sits
     centre of the frame, so hold horizontal centre; lift the focal point
     up to 42% so the bottom scrim + headline land over grass, not over the
     riders or the glow. */
  object-position: 50% 42%;
}

/* Two scrims in one layer (both must paint over the <img>, so both live in
   ::after, not ::before which would sit behind the photo).
   1) A short top wash so the wordmark + header CTA hold contrast over the
      bright sky. 2) A taller bottom wash covering the whole text band, so the
      eyebrow and headline no longer float on the riders' silhouettes.
   The middle stays clear to keep the golden light (WCAG AA, design-decisions §11). */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to bottom,
      rgba(var(--dusk-rgb), 0.55) 0%,
      rgba(var(--dusk-rgb), 0) 22%
    ),
    linear-gradient(
      to top,
      rgba(var(--dusk-rgb), 0.9) 0%,
      rgba(var(--dusk-rgb), 0.7) 30%,
      rgba(var(--dusk-rgb), 0.32) 55%,
      rgba(var(--dusk-rgb), 0) 78%
    );
}

.hero__content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding: 0 var(--space-md) clamp(3rem, 10svh, 6rem);
}

.hero .eyebrow {
  color: var(--chalk); /* full opacity — the label was the lowest-contrast text on the page */
  letter-spacing: 0.16em; /* a touch tighter than the base eyebrow so the label holds one line at 375px */
  margin-bottom: var(--space-md);
}
/* "Now live" stays Chalk: Ember is a warm hue and the photo is warm, so the
   accent had no stable dark ground and read muddy. The separator carries it. */
.eyebrow__news { color: var(--chalk); }

.hero h1 {
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-size: var(--step-hero);
  font-weight: 450;
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-wrap: balance; /* never let the browser dismember the headline at the box edge */
  margin-bottom: var(--space-md); /* opened from 16px — the stack was a cramped four-size ladder */
}

.hero__sub {
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-sub);
  font-weight: 400;
  line-height: 1.3;
  text-wrap: balance; /* split the three-beat line evenly instead of orphaning "that reveals itself" */
  margin-bottom: var(--space-lg); /* real breathing room before the CTA (mobile) / descriptor (desktop) */
}

/* Descriptor is cut on mobile: at 375px the subhead already carries the
   promise, and dropping a level turns a four-size ladder into three. It
   returns at 768px where there's room for it to earn its place. */
.hero__desc {
  display: none;
  color: rgba(var(--chalk-rgb), 0.82);
  font-weight: 300;
  margin-bottom: var(--space-lg);
}

/* Mobile: the primary CTA commits to a full-width block (thumb target, no
   ragged right edge). Capped so it stays a button, not a banner. It goes
   back to inline auto-width on wider screens. */
.hero .btn--primary {
  display: block;
  width: 100%;
  max-width: 22rem;
  text-align: center;
}

/* ---- 8. Wider screens ---- */
@media (min-width: 768px) {
  .site-header { padding: var(--space-lg) var(--space-xl); }
  .site-header .btn--ghost { display: inline-block; }
  .hero__content { padding-inline: var(--space-xl); }
  .hero__sub { max-width: 26ch; margin-bottom: var(--space-md); }
  .hero__desc { display: block; max-width: 44ch; }
  .hero .btn--primary { display: inline-block; width: auto; }
}

/* ---- 9. Designed 404 (design-decisions §8) ---- */
.notfound {
  min-height: 100svh;
  display: grid;
  place-items: center;
  background: var(--dusk);
  color: var(--chalk);
  text-align: center;
  padding: var(--space-2xl) var(--space-md);
}
.notfound__inner { max-width: 34rem; }
.notfound__route { display: block; width: 128px; height: auto; margin: 0 auto var(--space-lg); }
.notfound .eyebrow {
  color: rgba(var(--chalk-rgb), 0.75); /* chalk-based, not deben: deben fails AA on the dusk ground */
  margin-bottom: var(--space-md);
}
.notfound__title {
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-size: var(--step-h2);
  font-weight: 450;
  line-height: 1.1;
  text-wrap: balance;
  margin-bottom: var(--space-md);
}
.notfound__text {
  color: rgba(var(--chalk-rgb), 0.82);
  margin: 0 auto var(--space-xl);
  max-width: 34ch;
}

/* ==========================================================================
   10. Homepage sections 2–6 (design-decisions §7)
   Built on the system above. Mobile-first; each section is a full-width band
   with an inner .container that respects the 1200px content grid. Light bands
   carry information and reassurance; two "dusk" bands (the evening, and the
   final call) carry the reward register — the page gets darker where the
   story gets closer (design-decisions §4).
   ========================================================================== */

/* Section shell: the vertical rhythm between whole sections (design-decisions
   §6, --space-3xl). One class for every band; a modifier flips it to dusk. */
.section { padding-block: var(--space-3xl); }
.section--dusk {
  background: var(--dusk);
  color: var(--chalk);
}

/* Inner width limiter — full-bleed backgrounds, contained text. */
.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--space-md);
}
@media (min-width: 768px) {
  .container { padding-inline: var(--space-xl); }
}

/* Section head: eyebrow + H2 + optional standfirst, shared by every band. */
.section-head { margin-bottom: var(--space-xl); }
.section-head .eyebrow { color: var(--deben); margin-bottom: var(--space-sm); }
.section--dusk .section-head .eyebrow { color: rgba(var(--chalk-rgb), 0.7); } /* deben fails AA on dusk; chalk-based instead (matches the 404) */

h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-size: var(--step-h2);
  font-weight: 450;
  line-height: 1.08;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* Standfirst under an H2 — the one-line intro (--step-lead). */
.standfirst {
  font-size: var(--step-lead);
  margin-top: var(--space-md);
  color: inherit;
}
.section:not(.section--dusk) .standfirst { color: #3a4a52; } /* estuary lightened ~15% so the standfirst sits under the H2, not level with it */

/* ---- Section 2: The shape — three stops on the route line ----
   The route line is THE narrative device (design-decisions §3). Here it is
   literal: a single thin dashed line running down the left, stitching the
   three days together, with an ink-drawn node at each stop. No parchment,
   no map illustration — the line alone carries the map-and-mystery idea. */
.route { list-style: none; padding: 0; margin: 0; }
.route__stop {
  position: relative;
  padding-left: var(--space-xl);
  padding-bottom: var(--space-2xl);
}
.route__stop:last-child { padding-bottom: 0; }

/* The dashed line itself: a 2px dashed left border on every stop, so it draws
   continuously from the first node to the last with no extra element. */
.route__stop::before {
  content: "";
  position: absolute;
  left: 5px; /* centres the 2px line under the 12px node */
  top: 0.4rem;
  bottom: 0;
  border-left: 2px dashed var(--deben);
}
.route__stop:last-child::before { bottom: auto; height: 0.4rem; } /* line stops at the last node, doesn't dangle */

/* The node: a small filled ink dot in Ember, the one accent (design-decisions §4). */
.route__stop::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0.25rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--ember);
}

.route__day {
  display: block;
  font-family: 'Switzer', -apple-system, sans-serif;
  font-size: var(--step-eyebrow);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--deben);
  margin-bottom: var(--space-2xs);
}
.route__lead {
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-h3);
  font-weight: 450;
  line-height: 1.15;
  margin-bottom: var(--space-2xs);
}
.route__note { color: #3a4a52; margin: 0; }

/* ---- Section 3: You don't need to be a cyclist ----
   The objection-killer (design-decisions §7.3), written for the nervous guest.
   Flowing paragraphs, then one highlighted closing line. */
.prose > * + * { margin-top: var(--space-md); }
.prose p { color: #26343b; } /* near-estuary body; full estuary is for headings */
.pull {
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-sub);
  font-weight: 400;
  line-height: 1.3;
  color: var(--estuary);
  text-wrap: balance;
  margin-top: var(--space-xl);
  padding-top: var(--space-lg);
  border-top: 2px dashed var(--deben); /* the route-line motif, reused as a quiet rule */
}
.section--dusk .pull { color: var(--chalk); border-top-color: rgba(var(--chalk-rgb), 0.4); }
.section--dusk .prose p { color: rgba(var(--chalk-rgb), 0.85); }

/* ---- Section 5: Included + price + founder moment ----
   The all-inclusive list, one number, then a small founder note. */
.included__list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-xl);
  display: grid;
  gap: var(--space-md);
}
.included__list li {
  position: relative;
  padding-left: var(--space-lg);
  max-width: var(--measure);
}
/* Each item marked with a short dash — the ink-line motif at bullet scale. */
.included__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.75em;
  width: 14px;
  height: 2px;
  background: var(--ember);
}

/* The price line: stated plainly, no tiers, no asterisks (design-decisions §6). */
.price-line {
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-h3);
  font-weight: 450;
  line-height: 1.25;
  color: var(--estuary);
  padding: var(--space-lg) 0;
  border-block: 2px dashed var(--deben);
  max-width: none;
}

/* Founder moment: small photo + one-line note (design-decisions §7.5). Built to
   read intentional with or without the portrait — the NZ shot is a to-source
   slot (image-brief), so the note stands on its own until it lands. */
.founder {
  display: flex;
  flex-direction: column; /* photo over quote on phones */
  gap: var(--space-lg);
  align-items: flex-start;
  margin-top: var(--space-2xl);
}
.founder__photo {
  flex: 0 0 auto;
  width: 100%;
  max-width: 260px;
  height: auto;
  border-radius: 2px; /* the site's barely-there radius, not a face-disc — the scene is the point */
  background: var(--dusk); /* the ground shown while the portrait decodes */
}
.founder__note {
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-lead);
  font-style: italic;
  line-height: 1.4;
  color: var(--estuary);
  margin: 0;
}
.founder__attr {
  display: block;
  font-family: 'Switzer', -apple-system, sans-serif;
  font-style: normal;
  font-size: var(--step-small);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--deben);
  margin-top: var(--space-sm);
}

/* ---- Section 6: Final CTA + booking form + trust + footer ---- */
.cta-final { text-align: left; }
.cta-final .standfirst { max-width: 46ch; }

/* Phone, offered as the call-first alternative to the form. */
.cta-phone {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2xs);
  margin-top: var(--space-lg);
  font-family: 'Fraunces', Georgia, serif;
  font-size: var(--step-h3);
  color: var(--chalk);
  text-decoration: none;
}
.cta-phone span { font-family: 'Switzer', sans-serif; font-size: var(--step-small); letter-spacing: 0.14em; text-transform: uppercase; color: rgba(var(--chalk-rgb), 0.7); }
.cta-phone:hover { color: var(--ember); }

/* Booking form (feeds the Airtable waitlist API, design-decisions §6).
   Short qualification fields only — the sell happens on the call. */
.booking {
  margin-top: var(--space-2xl);
  max-width: 34rem;
}
.field { margin-bottom: var(--space-md); }
.field label {
  display: block;
  font-size: var(--step-small);
  font-weight: 500;
  letter-spacing: 0.02em;
  margin-bottom: var(--space-2xs);
  color: rgba(var(--chalk-rgb), 0.85);
}
.field input,
.field textarea {
  width: 100%;
  font-family: 'Switzer', -apple-system, sans-serif;
  font-size: 1rem;
  color: var(--chalk);
  background: rgba(var(--chalk-rgb), 0.06);
  border: 1px solid rgba(var(--chalk-rgb), 0.28);
  border-radius: 2px;
  padding: 0.8em 0.9em;
}
.field input::placeholder,
.field textarea::placeholder { color: rgba(var(--chalk-rgb), 0.4); }
.field input:focus,
.field textarea:focus {
  outline: 2px solid var(--ember);
  outline-offset: 1px;
  border-color: transparent;
}
.field textarea { min-height: 6rem; resize: vertical; }

/* The honeypot: a real field named "Company" that humans never see or reach
   (the API drops any submission that fills it). Hidden from layout, tab order
   and screen readers alike — not display:none, which some bots skip. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.booking .btn--primary { width: 100%; max-width: 22rem; text-align: center; }
@media (min-width: 768px) { .booking .btn--primary { width: auto; } }

/* Submit feedback line, populated by js/form.js. Never relies on colour alone. */
.form-msg { margin-top: var(--space-md); font-size: var(--step-small); min-height: 1.4em; }
.form-msg--ok { color: var(--reed); }
.form-msg--err { color: #E0A24A; } /* a warm amber that clears AA on dusk; ember-family without being the CTA colour */

.form-secondary {
  margin-top: var(--space-lg);
  font-size: var(--step-small);
  color: rgba(var(--chalk-rgb), 0.7);
}
.form-secondary a { color: var(--chalk); border-bottom: 1px solid rgba(var(--chalk-rgb), 0.4); text-decoration: none; }
.form-secondary a:hover { border-bottom-color: var(--chalk); }

/* Trust strip: substance cues stated once, plainly (design-decisions §6).
   Route-line dashes separate the claims instead of bullets. */
.trust {
  margin-top: var(--space-3xl);
  padding-top: var(--space-lg);
  border-top: 1px solid rgba(var(--chalk-rgb), 0.18);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  font-size: var(--step-small);
  color: rgba(var(--chalk-rgb), 0.75);
}
.trust li { list-style: none; position: relative; }
.trust li + li { padding-left: var(--space-md); }
.trust li + li::before { content: "·"; position: absolute; left: 0; color: var(--deben); }
.trust ul { display: contents; }

/* Footer: discreet, dusk-toned, the quiet links (design-decisions §7.6). */
.site-footer {
  background: var(--estuary);
  color: rgba(var(--chalk-rgb), 0.7);
  padding-block: var(--space-2xl);
  font-size: var(--step-small);
}
.site-footer .container { display: flex; flex-wrap: wrap; gap: var(--space-md) var(--space-xl); justify-content: space-between; align-items: baseline; }
.site-footer a { color: rgba(var(--chalk-rgb), 0.85); text-decoration: none; }
.site-footer a:hover { color: var(--chalk); text-decoration: underline; }
.site-footer__links { display: flex; flex-wrap: wrap; gap: var(--space-md); }
.site-footer__mark { font-family: 'Fraunces', Georgia, serif; letter-spacing: 0.18em; color: rgba(var(--chalk-rgb), 0.85); }

/* ---- Section 2/5 desktop: the route and the list get room to breathe ---- */
@media (min-width: 768px) {
  .founder { flex-direction: row; align-items: center; gap: var(--space-xl); }
  .founder__photo { width: 300px; max-width: 300px; }
  .included__list { grid-template-columns: 1fr 1fr; gap: var(--space-md) var(--space-xl); }
  .included__list li:nth-child(1),
  .included__list li:nth-child(2) { } /* keep natural flow; two columns from the first row */
}
