/* GoJumps - sitewide stylesheet
   Direction (2026-10-03, owner-approved A1 mockup): Apple product-page
   restraint in an outdoor-lifestyle world. Morning sky, real lawn, one
   crisp grotesk, generous space. Color comes from the inflatables
   themselves; the four chapter colors are accents only (dots, rules),
   never full-bleed fields. Mobile-first, one stylesheet, no frameworks. */

/* ---------------------------------------------------------------- fonts */
@font-face {
  font-family: 'DM Sans Display';
  src: url('fonts/dm-sans-display-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('fonts/dm-sans-text-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('fonts/dm-sans-text-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------- tokens */
:root {
  /* surfaces */
  --color-paper: #F6F4EF;      /* page background */
  --color-paper-2: #EEEBE4;    /* alternate band, duo panels */
  --color-surface: #FFFFFF;    /* cards; matches Amazon's white product shots */
  --color-sky: #E1EFFC;        /* hero sky, top */
  --color-haze: #F3F4F0;       /* hero sky at the horizon */
  --color-night: #172219;      /* footer */

  /* text. Ratios on --color-paper: ink 16.2, ink-2 7.3, ink-3 5.4 */
  --color-ink: #151915;
  --color-ink-2: #4B524B;
  --color-ink-3: #5F665F;
  --color-on-dark: #F6F4EF;    /* 14.9 on night */
  --color-on-dark-2: #C3CAC0;  /* 9.8 on night */
  --color-hairline: rgba(21, 25, 21, 0.12);
  --color-hairline-dark: rgba(246, 244, 239, 0.16);

  /* brand green. lawn = in-content links (5.7 on paper);
     lawn-deep = link hover and primary-button hover (8.5 on paper,
     9.3 under white text). Hovers always DARKEN. */
  --color-lawn: #3E6B3A;
  --color-lawn-deep: #2C4F29;

  /* chapter accents: non-text only (dots, rules). Labels stay ink. */
  --chapter-slides: #D2603F;
  --chapter-water: #4E93C4;
  --chapter-toddler: #E0B040;
  --chapter-bigkids: #5C9A60;

  /* type */
  --font-display: 'DM Sans Display', 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-text: 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fs-hero: clamp(2.75rem, 1rem + 4.2vw, 5.5rem);
  --fs-h2: clamp(2.25rem, 1.1rem + 3.4vw, 4.5rem);
  --fs-h3: clamp(1.5rem, 1.15rem + 1vw, 2.125rem);
  --fs-lead: clamp(1.0625rem, 0.98rem + 0.4vw, 1.3125rem);
  --fs-body: 1.0625rem;
  --fs-small: 0.9375rem;
  --fs-label: 0.8125rem;
  --track-display: -0.035em;

  /* space and shape */
  --container: 1240px;
  --gutter: clamp(20px, 4vw, 48px);
  --space-section: clamp(96px, 12vw, 176px);
  --header-h: 64px;
  /* how far the homepage category cards ride up over the hero lawn; the
     hero's handoff line sits just above this */
  --picks-overlap: clamp(48px, 7vw, 104px);
  --radius-lg: 28px;
  --radius-md: 20px;
  --radius-sm: 14px;
  --shadow-card: 0 1px 2px rgba(21, 25, 21, 0.06), 0 14px 36px -16px rgba(21, 25, 21, 0.22);
  --shadow-card-hover: 0 2px 4px rgba(21, 25, 21, 0.06), 0 24px 48px -18px rgba(21, 25, 21, 0.28);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html, body { overflow-x: hidden; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}
body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-text);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, p, ul, ol, figure, blockquote { margin: 0; }
ul[role="list"], .plain-list { list-style: none; padding: 0; }
img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; }
button { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
/* component display rules (.btn is inline-flex) must never unhide [hidden] */
[hidden] { display: none !important; }

/* Running prose gets real paragraph spacing. Scoped to direct children so
   it can never outspecify a tuned component. */
.prose > * + * { margin-top: 1em; }

/* In-content links are ALWAYS visibly links. Explicit container list (never
   a bare `a` rule, which would underline whole cards); buttons excluded. */
.prose a:not(.btn),
.chapter__body p a:not(.btn),
.method__item p a:not(.btn),
.page-meta a,
.site-footer p a:not(.btn) {
  color: var(--color-lawn);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color 0.2s var(--ease-out);
}
.prose a:not(.btn):hover,
.chapter__body p a:not(.btn):hover,
.method__item p a:not(.btn):hover,
.page-meta a:hover { color: var(--color-lawn-deep); }
.site-footer p a:not(.btn) { color: var(--color-on-dark); }

/* ------------------------------------------------------- accessibility */
.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 100;
  padding: 12px 18px;
  border-radius: 999px;
  background: var(--color-ink);
  color: #FFFFFF;
  font-weight: 500;
  transition: top 0.2s var(--ease-out);
}
.skip-link:focus { top: 12px; }

:focus-visible {
  outline: 3px solid var(--color-lawn);
  outline-offset: 3px;
  border-radius: 6px;
}
.on-dark :focus-visible { outline-color: var(--color-on-dark); }

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ----------------------------------------------------------- layout */
.container {
  width: 100%;
  max-width: calc(var(--container) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section { padding-block: var(--space-section); }
/* consecutive plain sections share one gap instead of stacking two */
.section + .section { padding-top: 0; }

/* ---------------------------------------------------------- type */
.display-1,
.display-2,
.display-3 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: var(--track-display);
  text-wrap: balance;
}
.display-1 { font-size: var(--fs-hero); line-height: 1.02; letter-spacing: -0.04em; }
.display-2 { font-size: var(--fs-h2); line-height: 1.04; }
.display-3 { font-size: var(--fs-h3); line-height: 1.12; letter-spacing: -0.025em; }
.lead {
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--color-ink-2);
  text-wrap: pretty;
}

/* Eyebrow: a chapter-color dot plus an ink label. The dot never carries
   meaning on its own; the label always names the chapter. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-2);
}
.eyebrow::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--dot, var(--color-lawn));
  flex: none;
}
.eyebrow--pill {
  padding: 7px 14px 7px 12px;
  border-radius: 999px;
  background: rgba(15, 22, 15, 0.55);
  border: 1px solid rgba(246, 244, 239, 0.18);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  color: var(--color-on-dark);
}
[data-chapter="slides"] { --dot: var(--chapter-slides); }
[data-chapter="water"] { --dot: var(--chapter-water); }
[data-chapter="toddler"] { --dot: var(--chapter-toddler); }
[data-chapter="bigkids"] { --dot: var(--chapter-bigkids); }

/* -------------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 50px;
  padding: 13px 26px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-family: var(--font-text);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.25;
  text-align: center;
  white-space: normal;
  cursor: pointer;
  transition: background-color 0.25s var(--ease-out), color 0.25s var(--ease-out),
              border-color 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}
.btn:active { transform: scale(0.98); }

/* ink pill, white label 17.8:1; hover fills lawn-deep, label stays white 9.3:1 */
.btn--primary { background: var(--color-ink); color: #FFFFFF; }
.btn--primary:hover,
.btn--primary:focus-visible { background: var(--color-lawn-deep); color: #FFFFFF; }

/* white pill for dark photography, ink label 17.8:1; hover paper-2, 13.9:1 */
.btn--light { background: #FFFFFF; color: var(--color-ink); }
.btn--light:hover,
.btn--light:focus-visible { background: #E7E3DA; color: var(--color-ink); }

/* frosted light pill for text that may land on sky OR lawn (the hero's
   secondary CTA: on wide, short screens the horizon rises behind it).
   Ink label on the frosted pill measures about 11.5:1 even over the
   darkest grass; hover goes solid and darker, like .btn--light. */
.btn--glass {
  background: rgba(246, 244, 239, 0.78);
  border-color: rgba(21, 25, 21, 0.1);
  color: var(--color-ink);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  backdrop-filter: blur(10px) saturate(1.3);
}
.btn--glass svg { width: 16px; height: 16px; flex: none; transition: transform 0.3s var(--ease-out); }
.btn--glass:hover,
.btn--glass:focus-visible { background: #E7E3DA; border-color: #E7E3DA; color: var(--color-ink); }
.btn--glass:hover svg,
.btn--glass:focus-visible svg { transform: translateX(3px); }

/* outline on dark photography */
.btn--outline-light {
  background: rgba(15, 22, 15, 0.2);
  border-color: rgba(246, 244, 239, 0.7);
  color: var(--color-on-dark);
}
.btn--outline-light:hover,
.btn--outline-light:focus-visible { background: var(--color-on-dark); border-color: var(--color-on-dark); color: var(--color-ink); }

/* outline on light surfaces (the consent banner's Decline): ink label on
   white 17.8:1; hover fills paper-2 and the border goes ink, 14.9:1 */
.btn--quiet {
  background: transparent;
  border-color: rgba(21, 25, 21, 0.3);
  color: var(--color-ink);
}
.btn--quiet:hover,
.btn--quiet:focus-visible { background: var(--color-paper-2); border-color: var(--color-ink); color: var(--color-ink); }

/* text link with arrow: ink at rest, darkens to lawn-deep with underline */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  color: var(--color-ink);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.22em;
  transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
}
.link-arrow svg { width: 16px; height: 16px; flex: none; transition: transform 0.3s var(--ease-out); }
.link-arrow:hover,
.link-arrow:focus-visible { color: var(--color-lawn-deep); text-decoration-color: currentColor; }
.link-arrow:hover svg,
.link-arrow:focus-visible svg { transform: translateX(3px); }
.on-dark .link-arrow { color: var(--color-on-dark); }
.on-dark .link-arrow:hover,
.on-dark .link-arrow:focus-visible { color: #FFFFFF; }

/* --------------------------------------------------------- header */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  height: var(--header-h);
  border-bottom: 1px solid var(--color-hairline);
  transition: background-color 0.3s var(--ease-out), border-color 0.3s var(--ease-out);
}
.site-header.is-scrolled {
  background: rgba(246, 244, 239, 0.82);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  backdrop-filter: blur(16px) saturate(1.4);
}
.header-inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.site-logo {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.375rem;
  letter-spacing: -0.03em;
  color: var(--color-ink);
}
.nav-desktop { display: none; }
.nav-desktop ul { display: flex; gap: clamp(20px, 2.6vw, 36px); }
.nav-desktop a {
  position: relative;
  display: inline-block;
  padding-block: 6px;
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--color-ink);
}
/* hover adds a lawn rule under the label; the label itself never lightens */
.nav-desktop a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--color-lawn);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease-out);
}
.nav-desktop a:hover::after,
.nav-desktop a:focus-visible::after,
.nav-desktop a[aria-current="page"]::after { transform: scaleX(1); }

.hamburger {
  position: relative;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.hamburger span {
  position: absolute;
  left: 11px;
  right: 11px;
  height: 2px;
  border-radius: 2px;
  background: var(--color-ink);
  transition: transform 0.35s var(--ease-out), opacity 0.2s;
}
.hamburger span:nth-child(1) { top: 15px; }
.hamburger span:nth-child(2) { top: 21px; }
.hamburger span:nth-child(3) { top: 27px; }
.hamburger.is-active span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.hamburger.is-active span:nth-child(2) { opacity: 0; }
.hamburger.is-active span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.nav-mobile-overlay {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  padding: calc(var(--header-h) + 24px) var(--gutter) 48px;
  background: rgba(246, 244, 239, 0.97);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--ease-out), visibility 0.3s;
}
.nav-mobile-overlay.is-open { opacity: 1; visibility: visible; }
.nav-mobile-overlay a {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 9vw, 2.75rem);
  letter-spacing: var(--track-display);
  line-height: 1.25;
  color: var(--color-ink);
}

@media (min-width: 900px) {
  .nav-desktop { display: block; }
  .hamburger, .nav-mobile-overlay { display: none; }
}

/* ----------------------------------------------- hero: The Inflate
   One pinned section. Frame 0 (deflated) shows on load; scrolling scrubs
   to the inflated frame and swaps the headline for the handoff line.
   DEFAULT STATE, with no JS or with reduced motion: the inflated still and
   the main headline, no scroll hint. The head's gate class flips it to the
   start state only when home-anim.js is going to run. */
main { display: block; }
.inflate {
  /* Where the frames anchor inside the media box (0 = left/top, 1 =
     right/bottom). The stills read these through object-position and
     home-anim.js reads them for the canvas, so both crop identically. */
  --inflate-anchor-x: 0.5;
  --inflate-anchor-y: 1;
  position: relative;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
  background: linear-gradient(180deg, var(--color-sky) 0%, #EAF2F7 40%, var(--color-haze) 62%);
}
/* Ultra-wide screens scale the 16:9 frames by width and crop height; anchor
   at 0.66 so the turrets survive and a strip of lawn is cropped instead.
   (Briefly 0.45 on 2026-10-04 while the handoff line sat at the top; the
   line now sits on the lawn, so the lawn below the castle matters more.) */
@media (min-aspect-ratio: 2/1) {
  .inflate { --inflate-anchor-y: 0.66; }
}
/* Phones see about 40% of the frame's width; the inflated house sits a
   touch left of center (its slide is on the left). */
@media (max-width: 699px) {
  .inflate { --inflate-anchor-x: 0.45; }
}
.inflate__media {
  position: absolute;
  inset: auto 0 0 0;
  height: 64%;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 22%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 22%);
}
.inflate__frame,
.inflate__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: calc(var(--inflate-anchor-x) * 100%) calc(var(--inflate-anchor-y) * 100%);
}
.inflate__frame--start { opacity: 0; }
.inflate__frame--end { opacity: 1; }
.inflate__canvas { display: none; }

.inflate__copy {
  position: relative;
  z-index: 2;
  padding-top: calc(var(--header-h) + clamp(28px, 7vh, 112px));
  text-align: center;
}
.inflate__copy .lead { max-width: 44ch; margin: 18px auto 0; }
.inflate__ctas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px 28px;
  margin-top: 28px;
}
/* Bottom scrim behind the handoff line (the line itself lives in
   .yard-picks, below). Visible by default so the white line reads in the
   no-JS / reduced-motion state; the head's gate hides it and home-anim.js
   fades it in as the line rises. */
.inflate__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top, rgba(15, 22, 15, 0.6) 0%, rgba(15, 22, 15, 0.32) 24%, rgba(15, 22, 15, 0) 46%);
}
.inflate__hint {
  display: none;
  position: absolute;
  left: 50%;
  bottom: 18px;
  z-index: 2;
  transform: translateX(-50%);
  flex-direction: column;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-label);
  font-weight: 500;
  color: #FFFFFF;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 0 18px rgba(0, 0, 0, 0.25);
}
.inflate__hint::after {
  content: '';
  width: 1px;
  height: 36px;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0));
}

@media (min-width: 700px) {
  .inflate__media {
    inset: 0;
    height: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* ----------------------------------------------- yard picks (handoff)
   Overlaps the bottom of the hero lawn, the way the A2 mockup's cards sat
   on the grass. The section background only starts below the overlap. */
.yard-picks {
  --overlap: var(--picks-overlap);
  position: relative;
  z-index: 3;
  margin-top: calc(-1 * var(--overlap));
  padding-bottom: var(--space-section);
  background: linear-gradient(to bottom, transparent var(--overlap), var(--color-paper) var(--overlap));
}
.yard-picks > .container { position: relative; }
/* The handoff line: white, on the hero lawn, pinned to the top of the
   card row (absolute, bottom: 100%), so it scrolls up WITH the cards
   whatever its height (one line on desktop, two on phones). Owner,
   2026-10-04: it should feel attached to the cards, not to the castle. */
.yard-picks__title {
  position: absolute;
  inset: auto 0 100% 0;
  padding: 0 var(--gutter) clamp(18px, 3.5vh, 40px);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.75rem, 1rem + 2.6vw, 3.5rem);
  line-height: 1.06;
  letter-spacing: var(--track-display);
  text-align: center;
  text-wrap: balance;
  color: #FFFFFF;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.32), 0 0 30px rgba(0, 0, 0, 0.28);
}
.pick-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 20px);
}
.pick-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 10px 10px 18px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
}
.pick-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}
.pick-card__name {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 14px 6px 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1rem, 0.9rem + 0.45vw, 1.1875rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
}
.pick-card__name::before {
  content: '';
  width: 9px;
  height: 9px;
  margin-top: 0.42em;
  border-radius: 50%;
  background: var(--dot);
  flex: none;
}
.pick-card__name svg {
  width: 16px;
  height: 16px;
  margin: 0.2em 0 0 auto;
  flex: none;
  transition: transform 0.3s var(--ease-out);
}
.pick-card__blurb {
  margin: 6px 6px 0 23px;
  font-size: var(--fs-small);
  line-height: 1.45;
  color: var(--color-ink-3);
}
.pick-card:hover,
.pick-card:focus-visible { transform: translateY(-4px); box-shadow: var(--shadow-card-hover); }
.pick-card:hover .pick-card__name svg,
.pick-card:focus-visible .pick-card__name svg { transform: translateX(3px); }
.pick-card:focus-visible { outline-offset: 4px; border-radius: var(--radius-md); }

@media (max-width: 599px) {
  .pick-card__blurb { display: none; }
}
@media (min-width: 1024px) {
  .pick-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .pick-card { padding: 12px 12px 22px; }
}

/* ----------------------------------------------------- chapters */
.chapter__body { min-width: 0; }
.chapter__body .eyebrow { margin-bottom: 22px; }
.chapter__body > p:not(.eyebrow) { margin-top: 20px; max-width: 42ch; }
.chapter__body .btn,
.chapter__body .link-arrow { margin-top: 30px; }

/* Chapter, full bleed: text bottom-left over the photo */
.chapter--full {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(560px, 92svh, 980px);
  overflow: hidden;
  color: var(--color-on-dark);
  background: #2B3A2A;
}
.chapter--full .chapter__media {
  position: absolute;
  inset: 0;
}
.chapter--full .chapter__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 60% 50%;
}
.chapter--full .chapter__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(15, 22, 15, 0.68) 0%, rgba(15, 22, 15, 0.4) 34%, rgba(15, 22, 15, 0) 64%),
    linear-gradient(to right, rgba(15, 22, 15, 0.4) 0%, rgba(15, 22, 15, 0) 55%);
}
.chapter--full .container {
  position: relative;
  padding-block: clamp(48px, 8vw, 112px);
}
.chapter--full .display-2 {
  max-width: 13ch;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 30px rgba(0, 0, 0, 0.2);
}
.chapter--full .chapter__body > p:not(.eyebrow) {
  color: var(--color-on-dark);
  font-size: var(--fs-lead);
  line-height: 1.5;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/* Chapter, split: photo bleeds off the left edge, text in the right third */
.chapter--split { padding-block: var(--space-section); }
.split {
  display: grid;
  gap: 40px;
  align-items: center;
}
.split__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.split__body { padding-inline: var(--gutter); }
.type-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin-top: 40px;
}
.type-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding: 10px 8px 16px;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  font-size: var(--fs-small);
  font-weight: 500;
  text-align: center;
  line-height: 1.25;
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
}
.type-card img { width: 100%; aspect-ratio: 4 / 3; object-fit: contain; }
.type-card:hover,
.type-card:focus-visible { transform: translateY(-3px); box-shadow: var(--shadow-card-hover); }

/* Halves and a 540px cap (owner 2026-10-16: the photo read too large once
   real art replaced the placeholder; at 1440 it was 714x738, taller than
   the 4:3 photo itself). Now about 684x540 at 1440. */
@media (min-width: 900px) {
  .split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(40px, 5vw, 88px);
  }
  .split__media img {
    aspect-ratio: auto;
    height: clamp(380px, 38vw, 540px);
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  }
  /* right padding lines the text up with the container's right edge */
  .split__body {
    padding-left: 0;
    padding-right: max(var(--gutter), calc((100vw - var(--container)) / 2));
  }
}

/* Chapter, duo: two panels side by side. Sits right under the split
   chapter, whose bottom padding already makes the gap. Content capped at
   820px and centred so each panel matches a "Three to start with" card
   (about 398px; owner 2026-10-16: at full width they were 608px, far
   larger). The duo is also a .container, so the cap adds its gutters. */
.chapter--duo { padding-bottom: 0; }
.duo {
  display: grid;
  gap: clamp(16px, 2vw, 24px);
  max-width: calc(820px + 2 * var(--gutter));
}
.duo-panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--color-paper-2);
}
.duo-panel__media { overflow: hidden; }
.duo-panel__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 0.9s var(--ease-out);
}
.duo-panel:hover .duo-panel__media img { transform: scale(1.03); }
.duo-panel .chapter__body { padding: clamp(28px, 3.4vw, 48px); }
.duo-panel .chapter__body > p:not(.eyebrow) { color: var(--color-ink-2); }
.duo-panel .display-3 { max-width: 18ch; }
@media (min-width: 800px) {
  .duo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ------------------------------------------------ section headers */
.section-head { max-width: 860px; margin-bottom: clamp(40px, 5vw, 64px); }
.section-head .lead { margin-top: 18px; max-width: 52ch; }

/* --------------------------------------------- checks (bento grid)
   4 columns x 2 rows at 1024px+: yard 2x2, anchor 2x1, fabric 1x1,
   blower 1x1 = 8 cells, all filled. 2 columns below that: yard and
   anchor span both, fabric and blower share the last row. */
.checks-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-auto-flow: dense;
  gap: clamp(14px, 1.6vw, 20px);
}
.check {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: clamp(26px, 3vw, 40px);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
}
.check p { margin-top: 12px; color: var(--color-ink-2); max-width: 44ch; }
.check .link-arrow { margin-top: auto; padding-top: 24px; }
/* the card's one link stretches over the whole card */
.check .link-arrow::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-lg);
}
/* only a card that links somewhere lifts; text-only checks stay still */
.check:has(.link-arrow):hover { transform: translateY(-3px); box-shadow: var(--shadow-card-hover); }
/* keyboard focus rings the whole card; the link keeps its own outline too */
.check:has(.link-arrow:focus-visible) { box-shadow: 0 0 0 3px var(--color-lawn); }
.check__figure { margin: 28px 0 8px; }
.check__figure svg { width: 100%; height: auto; }
.yard-label text {
  font-family: var(--font-text);
  font-size: 15px;
  font-weight: 500;
  fill: var(--color-ink-2);
}

@media (min-width: 640px) {
  .checks-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .check--yard, .check--anchor { grid-column: span 2; }
}
@media (min-width: 1024px) {
  .checks-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .check--yard { grid-column: span 2; grid-row: span 2; }
  .check--anchor { grid-column: span 2; }
  .check--fabric, .check--blower { grid-column: span 1; }
}

/* -------------------------------------------------------- statement */
.statement { text-align: center; }
.statement__text {
  max-width: 24ch;
  margin-inline: auto;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 1rem + 3.4vw, 4.25rem);
  line-height: 1.08;
  letter-spacing: var(--track-display);
  text-wrap: balance;
}
/* Both sentences end in full ink (owner, 2026-10-17: the muted second
   sentence read as a brighten that never finished). The calculator from
   the rent or buy page sits under it as a centred card, its own text
   left-aligned. Each sentence starts its own line, so on phones the two
   don't run together now that they share a colour (direct children only:
   home-anim.js wraps each word in a span.w). */
.statement__text > span { display: block; }
.statement .calc {
  max-width: 640px;
  margin: clamp(40px, 5vw, 64px) auto 0;
  text-align: left;
}
.statement .link-arrow { margin-top: 36px; }

/* ---------------------------------------------------------- method */
.method-grid {
  display: grid;
  gap: 36px;
}
.method__item {
  padding-top: 22px;
  border-top: 1px solid var(--color-hairline);
}
.method__item h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.3125rem;
  letter-spacing: -0.02em;
  line-height: 1.25;
}
.method__item p { margin-top: 10px; color: var(--color-ink-2); }
@media (min-width: 800px) {
  .method-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(28px, 4vw, 56px); }
}

/* --------------------------------------------------------- closing */
.closing {
  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(520px, 78svh, 860px);
  overflow: hidden;
  text-align: center;
  color: var(--color-on-dark);
  background: #3A3A2E;
}
.closing__media { position: absolute; inset: 0; }
.closing__media img { width: 100%; height: 100%; object-fit: cover; }
.closing__scrim {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 55%, rgba(15, 22, 15, 0.55) 0%, rgba(15, 22, 15, 0.25) 70%);
}
.closing .container { position: relative; padding-block: 96px; }
.closing .display-2 { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 30px rgba(0, 0, 0, 0.2); }
.closing p:not(.closing__ctas) {
  max-width: 40ch;
  margin: 18px auto 0;
  font-size: var(--fs-lead);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.closing__ctas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  margin-top: 34px;
}

/* ---------------------------------------------------------- footer */
.site-footer {
  padding-block: clamp(64px, 8vw, 104px) 40px;
  background: var(--color-night);
  color: var(--color-on-dark-2);
  font-size: var(--fs-small);
}
.footer-grid {
  display: grid;
  gap: 40px;
}
.footer-brand .site-logo { color: var(--color-on-dark); }
.footer-brand p { margin-top: 14px; max-width: 36ch; line-height: 1.6; }
.footer-column h2 {
  font-family: var(--font-text);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--color-on-dark);
}
.footer-column ul { margin-top: 14px; display: grid; gap: 10px; }
.footer-column a {
  color: var(--color-on-dark-2);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.2em;
  transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
}
.footer-column a:hover,
.footer-column a:focus-visible { color: var(--color-on-dark); text-decoration-color: currentColor; }
.footer-bottom {
  display: grid;
  gap: 10px;
  margin-top: clamp(48px, 6vw, 72px);
  padding-top: 24px;
  border-top: 1px solid var(--color-hairline-dark);
  font-size: var(--fs-label);
  line-height: 1.6;
}
/* brand column first, then one column per link group, however many there
   are (the Guides column is out until the guides launch) */
@media (min-width: 800px) {
  .footer-grid { grid-template-columns: 1.6fr; grid-auto-columns: 1fr; grid-auto-flow: column; gap: 32px; }
  .footer-bottom { grid-template-columns: auto 1fr; gap: 32px; }
  .footer-affiliate-disclosure { text-align: right; }
}

/* =================================================================
   INNER PAGES (Phase 2, 2026-10-03). Same restraint as the homepage:
   paper ground, one rounded media panel per page, white cards that sit
   beside Amazon's own white product shots. Everything below is shared by
   every listing page; nothing is page-specific.
   ================================================================= */

/* Scroll reveal (main.js adds .is-visible; 2 s safety net; the noscript
   override in every head shows everything). */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
.reveal.is-visible { opacity: 1; transform: none; }

/* Breadcrumbs: nav.breadcrumbs > div.container > ol (canonical shape). The
   fixed header sits over the top, so this row carries the offset. */
.breadcrumbs { padding-top: calc(var(--header-h) + 18px); }
.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-label);
  color: var(--color-ink-3);
}
.breadcrumbs li { display: inline-flex; align-items: center; gap: 6px; }
.breadcrumbs li + li::before { content: '/'; color: var(--color-ink-3); opacity: 0.6; }
.breadcrumbs a {
  color: var(--color-ink-2);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.2em;
  transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
}
.breadcrumbs a:hover,
.breadcrumbs a:focus-visible { color: var(--color-ink); text-decoration-color: currentColor; }
.breadcrumbs [aria-current="page"] { color: var(--color-ink); font-weight: 500; }

/* Page hero: a rounded video panel inside the container, copy bottom-left.
   Layers back to front: the frame's dark lawn color (permanent fallback),
   the wrapper's poster background (autoplay refused), the video, the scrim,
   the copy. Per-page clip, poster and phone crop live inline on the
   wrapper (video-hero.md); one rule here serves every page. */
.page-hero { padding-top: 14px; }
.page-hero__frame {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(440px, 60svh, 600px);
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: #2B3A2A;
  color: var(--color-on-dark);
}
.hero-video {
  position: absolute;
  inset: 0;
  background-color: #2B3A2A;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: var(--hero-focus, 50% center);
}
.hero-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--hero-focus, 50% center);
}
/* no system play glyph if autoplay is refused; the poster shows instead */
.hero-video video::-webkit-media-controls-start-playback-button { display: none !important; }
.hero-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(15, 22, 15, 0.66) 0%, rgba(15, 22, 15, 0.4) 36%, rgba(15, 22, 15, 0) 66%),
    linear-gradient(to right, rgba(15, 22, 15, 0.5) 0%, rgba(15, 22, 15, 0) 58%);
}
.page-hero__copy {
  position: relative;
  max-width: 900px;
  padding: clamp(26px, 4.4vw, 60px);
}
.page-hero__copy .eyebrow { margin-bottom: 20px; }
.page-hero__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.375rem, 1rem + 3.9vw, 4.75rem);
  line-height: 1.03;
  letter-spacing: -0.04em;
  text-wrap: balance;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.28), 0 0 30px rgba(0, 0, 0, 0.22);
}
/* Phones see about half the 16:9 frame; each page sets the window from its
   own clip's frames (subjects sit in the right two-thirds by brief). */
@media (max-width: 1024px) {
  .hero-video,
  .hero-video video { --hero-focus: var(--hero-focus-mobile, 72% center); }
}
@media (max-width: 599px) {
  .page-hero .container { padding-inline: 12px; }
  .page-hero__frame { min-height: 460px; border-radius: var(--radius-md); }
}

/* Intro: byline, lead and the editorial paragraphs on the left, the
   to-scale yard plan on the right at 1024px+ (it illustrates the intro's
   own example and doubles as the legend for every card's drawing). On
   phones the plan follows the text and the affiliate note follows the
   plan, so the note still sits right above the first picks. */
.page-intro { padding-block: clamp(36px, 5vw, 64px) 0; }
.page-intro__grid { display: grid; gap: 28px; }
.page-intro__text { min-width: 0; max-width: 860px; }
.page-intro__grid .affiliate-note { margin-top: 0; }
.plan-figure {
  max-width: 440px;
  padding: clamp(14px, 1.8vw, 22px);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}
.plan-figure svg { width: 100%; height: auto; }
.plan-figure figcaption {
  margin-top: 12px;
  font-size: var(--fs-label);
  line-height: 1.5;
  color: var(--color-ink-3);
}
.plan__lawn { fill: #E3ECD6; }
.plan__clear { fill: rgba(78, 147, 196, 0.08); stroke: var(--chapter-water); stroke-width: 1.6; stroke-dasharray: 6 5; }
.plan__unit { fill: #F6DCD2; stroke: var(--chapter-slides); stroke-width: 1.8; }
.plan__dim { fill: none; stroke: var(--color-ink-3); stroke-width: 1; }
.plan__label { font-family: var(--font-text); font-size: 13px; font-weight: 500; fill: var(--color-ink-2); }
.plan__label--unit { font-size: 15px; fill: var(--color-ink); }
@media (min-width: 1024px) {
  .page-intro__grid {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
    grid-template-areas: "text plan" "note plan";
    column-gap: clamp(40px, 5vw, 80px);
    row-gap: 26px;
    align-items: start;
  }
  .page-intro__text { grid-area: text; }
  .plan-figure { grid-area: plan; }
  .page-intro__grid .affiliate-note { grid-area: note; }
}
.page-meta {
  font-size: var(--fs-small);
  color: var(--color-ink-3);
}
.page-intro .lead { margin-top: 18px; color: var(--color-ink); }
.page-intro .prose { margin-top: 18px; color: var(--color-ink-2); }

/* Affiliate note fixture: between the intro and the first product grid on
   every page that carries affiliate links. Verbatim by design. */
.affiliate-note {
  margin-top: 26px;
  padding-top: 16px;
  border-top: 1px solid var(--color-hairline);
  font-size: var(--fs-label);
  line-height: 1.55;
  color: var(--color-ink-3);
}

/* Section jumps: one tile per pick section (replaced 12 per-product
   pills, 2026-10-03: too busy once the page had sections). Each tile
   carries its lead pick's footprint at the shared card scale, so the
   three sizes compare at a glance. Stacked rows on phones. */
.section-jumps { padding-block: clamp(36px, 5vw, 56px) 0; }
.section-jumps__label {
  margin-bottom: 12px;
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--color-ink-3);
}
.section-jumps ol {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.section-jumps a {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) 16px;
  align-items: center;
  gap: 14px;
  min-height: 72px;
  padding: 10px 18px 10px 10px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  transition: transform 0.4s var(--ease-out), box-shadow 0.4s var(--ease-out);
}
.section-jumps .footprint { width: 56px; height: 56px; }
.section-jumps__name {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--color-ink);
}
.section-jumps__meta {
  display: block;
  margin-top: 3px;
  font-size: var(--fs-label);
  line-height: 1.4;
  color: var(--color-ink-3);
}
.section-jumps__arrow { width: 16px; height: 16px; transform: rotate(90deg); transition: transform 0.3s var(--ease-out); }
.section-jumps a:hover,
.section-jumps a:focus-visible { transform: translateY(-2px); box-shadow: var(--shadow-card-hover); }
.section-jumps a:hover .section-jumps__arrow,
.section-jumps a:focus-visible .section-jumps__arrow { transform: rotate(90deg) translateX(3px); }
@media (min-width: 800px) {
  .section-jumps ol { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(12px, 1.6vw, 20px); }
}

/* Product cards: curated catalog entries. One CTA per card; the photo
   links to the same place but is hidden from keyboards and screen
   readers, so the labelled button stays the canonical link. */
.products { padding-block: clamp(32px, 4vw, 48px) var(--space-section); }
.product-grid {
  display: grid;
  gap: clamp(14px, 1.8vw, 24px);
}
.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 12px 12px 18px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  scroll-margin-top: calc(var(--header-h) + 20px);
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
}
.product-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-card-hover); }
.product-card:target { box-shadow: 0 0 0 3px var(--color-lawn), var(--shadow-card-hover); }
.product-card__for {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 6px 6px 12px;
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-2);
}
.product-card__for::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--dot, var(--color-lawn));
  flex: none;
}
/* the image anchor MUST be block (an inline <a> has no height of its own).
   No height: 100% here: this anchor is a flex child of a stretched grid
   card, so 100% resolves against the card and pads the photo unevenly. */
.product-card__media {
  display: block;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}
.product-card__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  transition: transform 0.9s var(--ease-out);
}
.product-card:hover .product-card__media img { transform: scale(1.03); }
.product-card__name {
  margin: 16px 6px 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.4375rem);
  line-height: 1.18;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.product-card__fit {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 14px;
  align-items: center;
  margin: 16px 6px 0;
  padding: 14px 0;
  border-block: 1px solid var(--color-hairline);
}
.footprint { width: 84px; height: 84px; }
.footprint__yard { fill: #E3ECD6; }
.footprint__clear { fill: rgba(78, 147, 196, 0.08); stroke: var(--chapter-water); stroke-width: 1.4; stroke-dasharray: 4 3; }
.footprint__unit { fill: #F6DCD2; stroke: var(--chapter-slides); stroke-width: 1.6; }
.product-card__specs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 14px;
  margin: 0;
}
.product-card__specs dt {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-3);
}
.product-card__specs dd {
  margin: 2px 0 0;
  font-size: var(--fs-small);
  font-weight: 500;
  line-height: 1.3;
  color: var(--color-ink);
}
/* "Listing disagrees" and "Listing unclear" read quieter than a number */
.product-card__specs dd.is-unclear { font-weight: 400; color: var(--color-ink-3); }
.product-card__blurb {
  margin: 14px 6px 20px;
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--color-ink-2);
}
/* margin-top: auto pins every CTA to its card's bottom edge, so buttons
   line up across a row whatever the blurb length */
.product-card__cta {
  margin: auto 6px 0;
  align-self: stretch;
}
.product-card__cta svg { width: 15px; height: 15px; flex: none; }
@media (min-width: 640px) {
  .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1080px) {
  .product-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Pick sections: each opens with a lead card (the lifestyle photo)
   followed by three standard cards (white photos). Every layout fills:
   1 column on phones; a 2 x 2 at tablet widths, where the lead is just a
   card; at 3 columns the lead takes the whole first row and the three
   standard cards fill the second. */
.pick-section { scroll-margin-top: calc(var(--header-h) + 24px); }
.pick-section + .pick-section { margin-top: clamp(64px, 8vw, 120px); }
.pick-section__head { max-width: 860px; margin-bottom: clamp(24px, 3vw, 36px); }
.pick-section__head p { margin-top: 12px; color: var(--color-ink-2); max-width: 60ch; }
.product-card--lead .product-card__media img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.product-card--lead .product-card__body { display: flex; flex-direction: column; min-width: 0; }
.product-card--lead .product-card__for { margin-top: 18px; }
@media (min-width: 1080px) {
  .product-card--lead {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
    gap: clamp(24px, 3vw, 44px);
    align-items: stretch;
    padding: 14px clamp(18px, 2.4vw, 32px) 14px 14px;
  }
  .product-card--lead .product-card__media { height: 100%; }
  .product-card--lead .product-card__media img { height: 100%; min-height: 100%; }
  .product-card--lead .product-card__body { padding-block: clamp(14px, 2vw, 26px); }
  .product-card--lead .product-card__for { margin-top: 0; }
  .product-card--lead .product-card__name { font-size: clamp(1.625rem, 1.1rem + 1vw, 2.125rem); }
  .product-card--lead .product-card__blurb { font-size: var(--fs-body); }
  .product-card--lead .product-card__cta { align-self: flex-start; padding-inline: 34px; }
}

/* Buying guide: two paragraphs side by side at 820px+ so the text never
   hugs the left edge of a wide container. It is a tinted band, so the
   section after it needs its own top padding back. */
.buying-guide { background: var(--color-paper-2); }
/* Band joins (owner review 2026-10-17): a full section padding on each
   side of the colour edge left about 352px of empty paper at 2000 wide on
   the five guides, About and Yard Fit. Now the block before the band ends
   shorter, the band pads its own content moderately, and the block after
   it starts shorter: about 240px content to content at 2000, 120 at 390,
   against 176 / 96 for a plain join. Browsers without :has() keep the old
   full padding before the band, nothing worse. */
.buying-guide,
.section + .buying-guide { padding-block: clamp(64px, 8vw, 128px); }
.buying-guide + .section { padding-top: clamp(56px, 7vw, 112px); }
.section:has(+ .buying-guide),
.products:has(+ .buying-guide) { padding-bottom: clamp(56px, 7vw, 112px); }
.guide-grid {
  display: grid;
  gap: clamp(28px, 4vw, 56px);
}
.guide-grid h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.3125rem;
  letter-spacing: -0.02em;
  line-height: 1.25;
  padding-top: 20px;
  border-top: 1px solid var(--color-hairline);
}
.guide-grid .prose { margin-top: 12px; color: var(--color-ink-2); }
@media (min-width: 820px) {
  .guide-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Homepage picks: three standard product cards between the category
   cards and the first chapter */
.home-picks { padding-top: 0; }
.home-picks .section-head .affiliate-note { margin-top: 22px; max-width: 60ch; }
.home-picks__all { margin-top: clamp(28px, 3vw, 40px); }

/* Related pages reuse the homepage pick cards */
.related .section-head { margin-bottom: clamp(28px, 4vw, 44px); }
.related__all { margin-top: clamp(24px, 3vw, 36px); }

/* -------------------------------------------- doc pages (2026-10-16)
   about.html and privacy.html. No product links, so no affiliate note.
   About opens with a still photo in the page-hero panel; privacy opens
   with a quiet text header, a summary card, then long-form sections in a
   760px column with a sticky contents list beside it at 1024px+. */
/* --hero-focus-desktop (inline, optional) moves the crop above 1024px only;
   an inline --hero-focus would also beat the phone rule below. */
.page-hero__still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--hero-focus, var(--hero-focus-desktop, 50% center));
}
@media (max-width: 1024px) {
  .page-hero__still { --hero-focus: var(--hero-focus-mobile, 72% center); }
}

/* About: four ways a pick earns its place, white cards two by two */
.earn-grid {
  display: grid;
  gap: clamp(14px, 1.6vw, 20px);
}
.earn-card {
  min-width: 0;
  padding: clamp(26px, 3vw, 40px);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.earn-card__num {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-3);
}
.earn-card h3 { margin-top: 14px; }
.earn-card p { margin-top: 12px; color: var(--color-ink-2); max-width: 52ch; }
@media (min-width: 760px) {
  .earn-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.about-old .prose { max-width: 760px; color: var(--color-ink-2); }

/* Privacy: header, summary card, sections */
.doc-head { padding-top: clamp(28px, 4vw, 56px); }
.doc-head .container > .eyebrow { margin-bottom: 18px; }
.doc-head__title {
  max-width: 15ch;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.5rem, 1.1rem + 4vw, 5rem);
  line-height: 1.02;
  letter-spacing: -0.04em;
  text-wrap: balance;
}
.doc-head .lead { margin-top: 22px; max-width: 54ch; }
.doc-head .page-meta { margin-top: 18px; }

.doc-summary {
  margin-top: clamp(36px, 5vw, 56px);
  padding: clamp(24px, 3vw, 40px);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}
.doc-summary__list {
  display: grid;
  gap: 22px;
  margin-top: 22px;
}
.doc-summary__list li {
  min-width: 0;
  padding-top: 16px;
  border-top: 1px solid var(--color-hairline);
}
.doc-summary__list h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.1875rem;
  line-height: 1.25;
  letter-spacing: -0.02em;
}
.doc-summary__list p {
  margin-top: 6px;
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--color-ink-2);
}
@media (min-width: 640px) {
  .doc-summary__list { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 28px; }
}
@media (min-width: 1100px) {
  .doc-summary__list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.doc { padding-block: clamp(56px, 7vw, 96px) var(--space-section); }
.doc__grid { display: grid; gap: 40px; }
.doc__toc { display: none; }
.doc__toc-label {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-3);
}
.doc__toc ol {
  display: grid;
  gap: 10px;
  margin-top: 14px;
  padding: 0;
  list-style: none;
  font-size: var(--fs-small);
}
.doc__toc a {
  color: var(--color-ink-2);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.2em;
  transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
}
.doc__toc a:hover,
.doc__toc a:focus-visible { color: var(--color-ink); text-decoration-color: currentColor; }
/* Not sticky: `html, body { overflow-x: hidden }` makes body a scroll box
   of its own, so position: sticky never engages under it. The list sits
   at the top of its column. */
@media (min-width: 1024px) {
  .doc__grid {
    grid-template-columns: 200px minmax(0, 760px);
    column-gap: clamp(48px, 6vw, 104px);
  }
  .doc__toc { display: block; align-self: start; }
}
.doc-section { min-width: 0; scroll-margin-top: calc(var(--header-h) + 24px); }
.doc-section + .doc-section {
  margin-top: clamp(44px, 5vw, 64px);
  padding-top: clamp(44px, 5vw, 64px);
  border-top: 1px solid var(--color-hairline);
}
.doc-section .prose { margin-top: 18px; color: var(--color-ink-2); }

/* privacy.html's Analytics on/off panel; main.js fills it and unhides it */
.consent-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  margin-top: 24px;
  padding: 18px 18px 18px 24px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}
.consent-panel p { font-weight: 500; color: var(--color-ink); }

/* Analytics consent banner (main.js; only devices on a European time zone
   with no stored choice and no privacy signal see it). A bottom card,
   never modal, under the mobile menu (45) and the header (50). */
.consent {
  position: fixed;
  left: 50%;
  bottom: clamp(12px, 2.4vw, 24px);
  z-index: 40;
  display: grid;
  gap: 14px;
  width: min(660px, calc(100vw - 24px));
  padding: 18px 20px 20px;
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: 0 2px 4px rgba(21, 25, 21, 0.08), 0 24px 56px -18px rgba(21, 25, 21, 0.42);
  transform: translateX(-50%);
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--color-ink-2);
}
.consent__text a {
  color: var(--color-lawn);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color 0.2s var(--ease-out);
}
.consent__text a:hover { color: var(--color-lawn-deep); }
.consent__actions { display: flex; gap: 10px; }
.consent__actions .btn { flex: 1 1 0; min-height: 44px; padding: 10px 22px; }
@media (min-width: 640px) {
  .consent {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 22px;
    padding: 18px 18px 18px 24px;
  }
  .consent__actions .btn { flex: none; min-width: 108px; }
}
.prose ul { padding-left: 1.2em; }
.prose li + li { margin-top: 0.5em; }
.prose li::marker { color: var(--color-lawn); }
.prose strong { font-weight: 500; color: var(--color-ink); }
.prose code {
  padding: 0.1em 0.4em;
  border-radius: 6px;
  background: var(--color-paper-2);
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.88em;
  color: var(--color-ink);
  white-space: nowrap;
}

/* ------------------------------------------------------ 404 (2026-10-16)
   Ported from the approved coming-soon 404 (_coming-soon/404.html): the
   headline stacked over open sky, and frame 1 of the inflate (the deflated
   heap) rising out of that sky below it. The bands were tuned 2026-10-06 so
   the heap clears the fade at every width; keep them together. */
.lost-hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, var(--color-sky) 0%, #E4EFFA 100%);
}
.lost-hero__copy {
  position: relative;
  z-index: 2;
  padding-top: calc(var(--header-h) + clamp(16px, 4.5vh, 56px));
  text-align: center;
}
.lost-hero__copy .lead { max-width: 46ch; margin: 18px auto 0; }
.lost-hero__copy .btn { margin-top: 28px; }
.lost-hero__media {
  position: relative;
  z-index: 1;
  /* pulls the band's faded sky up under the lead so the turret tips land
     about 60-70px below it at every width */
  margin-top: calc(60px - 24vw);
  aspect-ratio: 6 / 5;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 18%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 18%);
}
.lost-hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 46% 50%; }
@media (min-width: 700px) {
  .lost-hero__media { aspect-ratio: 2 / 1; margin-top: calc(70px - 13.5vw); }
  .lost-hero__media img { object-position: 50% 50%; }
}
@media (min-width: 1100px) {
  .lost-hero__media { aspect-ratio: 2.4 / 1; margin-top: calc(70px - 9.9vw); }
  .lost-hero__media img { object-position: 50% 46%; }
}

/* -------------------------------------------- Yard Fit (2026-10-17)
   bounce-house-size.html, written by _tools/gen_size.py and run by
   yard-fit.js. The controls sit on the paper and the plan is the white
   card beside them (1024px+); below them, one white row per unit, three
   across at 1080px+. With no JS the form stays hidden and the rows read
   as a size chart, smallest first. */
.fit { padding-top: clamp(48px, 6vw, 88px); }
.fit-panel { display: grid; gap: clamp(28px, 4vw, 40px); }
.fit-panel__controls { min-width: 0; max-width: 620px; }
.fit-form { display: grid; gap: 26px; margin-top: 26px; }
.fit-form fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.fit-form legend {
  margin-bottom: 10px;
  padding: 0;
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-3);
}
.fit-form__sides { display: flex; align-items: flex-end; gap: 12px; }
.fit-field { display: grid; flex: 1 1 0; gap: 6px; min-width: 0; }
.fit-field span { font-size: var(--fs-small); font-weight: 500; color: var(--color-ink-2); }
.fit-field input {
  width: 100%;
  height: 58px;
  padding: 0 18px;
  border: 1px solid rgba(21, 25, 21, 0.22);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--color-ink);
  -moz-appearance: textfield;
  appearance: textfield;
  transition: border-color 0.2s var(--ease-out);
}
.fit-field input::-webkit-inner-spin-button,
.fit-field input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.fit-field input::placeholder { color: rgba(21, 25, 21, 0.28); }
.fit-field input:hover { border-color: var(--color-ink-3); }
.fit-field input:focus-visible { outline: 3px solid var(--color-lawn); outline-offset: 2px; border-color: var(--color-lawn); }
.fit-form__by { padding-bottom: 15px; font-size: 1.25rem; color: var(--color-ink-3); }

/* type chips: real radios under the pills, so arrow keys work. Unchecked
   white with ink 17.8, hover paper-2 14.9; checked ink with white 17.8,
   hover lawn-deep 9.3. Every hover darkens. */
.fit-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.fit-chips label { position: relative; display: inline-flex; }
.fit-chips input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.fit-chips span {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 8px 16px;
  border: 1px solid rgba(21, 25, 21, 0.18);
  border-radius: 999px;
  background: var(--color-surface);
  font-size: var(--fs-small);
  font-weight: 500;
  line-height: 1.2;
  color: var(--color-ink);
  transition: background-color 0.2s var(--ease-out), border-color 0.2s var(--ease-out), color 0.2s var(--ease-out);
}
.fit-chips label:hover span { background: var(--color-paper-2); border-color: var(--color-ink-3); }
.fit-chips input:checked + span { background: var(--color-ink); border-color: var(--color-ink); color: #FFFFFF; }
.fit-chips label:hover input:checked + span { background: var(--color-lawn-deep); border-color: var(--color-lawn-deep); }
.fit-chips input:focus-visible + span { outline: 3px solid var(--color-lawn); outline-offset: 2px; }

.fit-status {
  margin-top: 22px;
  font-size: var(--fs-small);
  font-weight: 500;
  line-height: 1.5;
  color: var(--color-ink-2);
}
.fit-plan { width: 100%; }
.plan__mine { stroke: var(--color-ink-3); stroke-width: 1.2; }
.plan__clear--over { fill: rgba(210, 96, 63, 0.08); stroke: var(--chapter-slides); }
@media (min-width: 1024px) {
  .fit-panel {
    grid-template-columns: minmax(0, 1fr) minmax(340px, 460px);
    column-gap: clamp(40px, 5vw, 80px);
    align-items: start;
  }
  /* .plan-figure takes grid-area: plan inside the guides' intro grid; this
     grid has no such area, so put the figure back in the flow */
  .fit-plan { grid-area: auto; max-width: none; }
}

.fit-results { margin-top: clamp(48px, 6vw, 80px); }
.fit-results__title {
  margin-bottom: 18px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.3125rem;
  line-height: 1.25;
  letter-spacing: -0.02em;
}
.fit-results__title--over { margin-top: clamp(40px, 5vw, 56px); }
.fit-list {
  display: grid;
  gap: clamp(10px, 1.2vw, 14px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.fit-row {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  column-gap: 16px;
  row-gap: 10px;
  align-items: start;
  min-width: 0;
  padding: 14px 18px 16px 14px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}
.fit-row .footprint { grid-row: span 2; width: 64px; height: 64px; }
.fit-row__body { min-width: 0; }
.fit-row__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.25;
  letter-spacing: -0.02em;
}
.fit-row__name a {
  color: var(--color-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(21, 25, 21, 0.28);
  text-underline-offset: 0.2em;
  transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
}
.fit-row__name a:hover,
.fit-row__name a:focus-visible { color: var(--color-lawn-deep); text-decoration-color: currentColor; }
.fit-row__meta { margin-top: 4px; font-size: var(--fs-label); line-height: 1.45; color: var(--color-ink-3); }
/* the verdict: words carry it; the dot only repeats it */
.fit-row__fit {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 8px;
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: 1.4;
  color: var(--color-ink);
}
.fit-row__fit::before {
  content: '';
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-lawn);
  transform: translateY(-1px);
}
.fit-row__fit.is-over::before { background: var(--chapter-slides); }
/* pinned to the row's bottom edge, so links line up across a grid row */
.fit-row__buy {
  grid-column: 2;
  justify-self: start;
  align-self: end;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--color-ink);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.2em;
  transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
}
.fit-row__buy svg { width: 13px; height: 13px; flex: none; }
.fit-row__buy:hover,
.fit-row__buy:focus-visible { color: var(--color-lawn-deep); text-decoration-color: currentColor; }
/* too big: the row steps back onto the paper; ink-3 on paper-2 is 5.0 */
.fit-row.is-over { background: var(--color-paper-2); box-shadow: none; }
/* the glyph once a lawn is entered: the reader's lawn in green with an ink
   edge, the clear zone dashed (coral where it runs past the lawn) */
.footprint__bg { fill: var(--color-paper-2); }
.fit-row.is-over .footprint__bg { fill: var(--color-surface); }
.footprint__mine { fill: #E3ECD6; stroke: var(--color-ink-3); stroke-width: 1; }
.footprint__clear.is-over { fill: rgba(210, 96, 63, 0.1); stroke: var(--chapter-slides); }
@media (min-width: 700px) {
  .fit-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1080px) {
  .fit-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Size chart: a white table card at 760px+; below that each row stacks
   into its own block, labels from data-label */
.size-chart .section-head .lead { max-width: 60ch; }
.table-scroll {
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}
.size-table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); line-height: 1.5; }
.size-table th,
.size-table td { padding: 16px 20px; text-align: left; vertical-align: top; }
.size-table thead th {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-3);
  border-bottom: 1px solid var(--color-hairline);
}
.size-table tbody th {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  color: var(--color-ink);
  white-space: nowrap;
}
.size-table td { color: var(--color-ink-2); }
.size-table tbody tr + tr > * { border-top: 1px solid var(--color-hairline); }
.size-table td a {
  color: var(--color-lawn);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color 0.2s var(--ease-out);
}
.size-table td a:hover { color: var(--color-lawn-deep); }
@media (max-width: 759px) {
  .size-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .size-table,
  .size-table tbody,
  .size-table tr,
  .size-table th,
  .size-table td { display: block; }
  .size-table tbody tr { padding: 20px 20px 18px; }
  .size-table tbody tr + tr > * { border-top: 0; }
  .size-table tbody tr + tr { border-top: 1px solid var(--color-hairline); }
  .size-table tbody th { padding: 0 0 6px; font-size: 1.25rem; }
  .size-table td { padding: 6px 0 0; }
  .size-table td::before {
    content: attr(data-label) ': ';
    font-weight: 500;
    color: var(--color-ink);
  }
}
@media (min-width: 760px) {
  .size-table td:nth-child(3),
  .size-table td:nth-child(4) { white-space: nowrap; }
}

/* ----------------------------------- guide articles (2026-10-17)
   bounce-house-safety.html and bounce-house-blower.html, written by
   _tools/gen_guides.py. They reuse the about page's still hero, the privacy
   page's doc layout (.doc, .doc__toc, .doc-section) and the guides' product
   cards; the pieces below are the only new ones. */

/* "Read this first": a white card with a coral rule, never a full colour
   field. Label ink, body ink-2 (7.3 on white). */
.notice {
  margin-top: 28px;
  padding: clamp(20px, 2.6vw, 28px) clamp(20px, 2.8vw, 32px);
  border-left: 4px solid var(--chapter-slides);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}
.notice__label {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink);
}
.notice p + p { margin-top: 8px; font-size: var(--fs-small); line-height: 1.6; color: var(--color-ink-2); }

.doc-section h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.1875rem;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--color-ink);
}
.doc-section .prose > h3 { margin-top: 1.7em; }
.doc-section .prose + .table-scroll,
.doc-section .table-scroll + .prose { margin-top: 24px; }
.doc-note { font-size: var(--fs-small); color: var(--color-ink-3); }

/* tables inside the 760px column: one rule set with the size chart */
.table-scroll--doc { border-radius: var(--radius-md); }
.data-table tbody th { font-size: 1rem; white-space: normal; }
@media (min-width: 760px) {
  .data-table th,
  .data-table td { padding: 13px 18px; }
}
@media (max-width: 759px) {
  .data-table tbody tr { padding: 16px 18px 14px; }
  .data-table td { padding-top: 3px; }
}
.data-table tbody th a {
  color: var(--color-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(21, 25, 21, 0.28);
  text-underline-offset: 0.2em;
  transition: color 0.2s var(--ease-out), text-decoration-color 0.2s var(--ease-out);
}
.data-table tbody th a:hover,
.data-table tbody th a:focus-visible { color: var(--color-lawn-deep); text-decoration-color: currentColor; }
@media (min-width: 760px) {
  .data-table td:nth-child(3) { white-space: normal; }
  .data-table td:nth-child(2) { white-space: nowrap; }
}

/* the two-minute check: numbered white rows */
.checklist {
  display: grid;
  gap: 10px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: check;
}
.checklist li {
  position: relative;
  padding: 16px 20px 16px 62px;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  color: var(--color-ink-2);
  counter-increment: check;
}
.checklist li::before {
  content: counter(check);
  position: absolute;
  left: 20px;
  top: 15px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.3;
  color: var(--color-lawn);
}
.checklist strong { font-weight: 500; color: var(--color-ink); }
.checklist a {
  color: var(--color-lawn);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.checklist a:hover { color: var(--color-lawn-deep); }

/* Block rhythm (2026-10-17): .doc is not a .section, so ".section +
   .section" never collapsed its joins and two full paddings stacked (352px
   at 2000 wide against the site's 176). One gap per join: the block above
   keeps its bottom padding and the block below drops its top. Measured with
   the scratchpad gaps.py script on all four guides. */
.doc + .section,
.section + .doc { padding-top: 0; }

/* gear and replacement cards: product cards with no footprint drawing.
   After the doc they need no top padding (the rule above); straight after
   the intro (the verdict pair) they take the same gap Yard Fit's tool does */
.gear { padding-top: 0; }
.page-intro + .gear { padding-top: clamp(48px, 6vw, 88px); }
.gear .pick-section__head { margin-bottom: clamp(28px, 3.4vw, 44px); }
.product-card__fit--plain { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1080px) {
  .product-grid--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* keep reading: two text cards that lift and darken their title */
.next-grid { display: grid; gap: clamp(14px, 1.6vw, 20px); }
.next-card {
  display: grid;
  gap: 8px;
  padding: clamp(24px, 3vw, 36px);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  transition: transform 0.4s var(--ease-out), box-shadow 0.4s var(--ease-out);
}
.next-card__eyebrow {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-3);
}
.next-card__title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1.12;
  letter-spacing: -0.025em;
  color: var(--color-ink);
  transition: color 0.2s var(--ease-out);
}
.next-card__title svg { width: 20px; height: 20px; flex: none; transition: transform 0.3s var(--ease-out); }
.next-card__blurb { font-size: var(--fs-small); color: var(--color-ink-2); }
.next-card:hover,
.next-card:focus-visible { transform: translateY(-4px); box-shadow: var(--shadow-card-hover); }
.next-card:hover .next-card__title,
.next-card:focus-visible .next-card__title { color: var(--color-lawn-deep); }
.next-card:hover .next-card__title svg,
.next-card:focus-visible .next-card__title svg { transform: translateX(3px); }
@media (min-width: 760px) {
  .next-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Rent or buy calculator (rent-or-buy.js). A white panel inside the doc
   column: four inputs two by two, the answer underneath. Hidden with no
   JS; the noscript line gives the formula instead. */
.calc {
  margin-top: 24px;
  padding: clamp(20px, 3vw, 32px);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}
.calc-form { display: grid; gap: 16px; }
.calc-field { display: grid; gap: 6px; min-width: 0; }
.calc-field span { font-size: var(--fs-small); font-weight: 500; color: var(--color-ink-2); }
.calc-field__box { position: relative; display: block; }
.calc-field__box[data-prefix]::before {
  content: attr(data-prefix);
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-ink-3);
  pointer-events: none;
}
.calc-field input {
  width: 100%;
  height: 54px;
  padding: 0 16px;
  border: 1px solid rgba(21, 25, 21, 0.22);
  border-radius: var(--radius-sm);
  background: var(--color-paper);
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--color-ink);
  -moz-appearance: textfield;
  appearance: textfield;
  transition: border-color 0.2s var(--ease-out);
}
.calc-field__box[data-prefix] input { padding-left: 34px; }
.calc-field input::-webkit-inner-spin-button,
.calc-field input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.calc-field input::placeholder { color: rgba(21, 25, 21, 0.28); }
.calc-field input:hover { border-color: var(--color-ink-3); }
.calc-field input:focus-visible { outline: 3px solid var(--color-lawn); outline-offset: 2px; border-color: var(--color-lawn); }
@media (min-width: 560px) {
  .calc-form { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 18px; }
}
.calc-out {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--color-hairline);
}
.calc-out__lead {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.25rem, 1.05rem + 0.6vw, 1.5rem);
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--color-ink);
}
.calc-out__lead strong { font-weight: 600; color: var(--color-lawn-deep); }
.calc-out__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 18px;
  margin: 18px 0 0;
}
.calc-out__grid dt { font-size: 0.75rem; font-weight: 500; letter-spacing: 0.02em; color: var(--color-ink-3); }
.calc-out__grid dd { margin: 2px 0 0; font-size: var(--fs-body); font-weight: 500; color: var(--color-ink); }
.calc-out__verdict,
.calc-out__note { margin-top: 16px; font-size: var(--fs-small); line-height: 1.55; color: var(--color-ink-2); }

/* ------------------------------------------------ guides hub (2026-10-17)
   guides.html: each guide is a card with its own hero still, inset like
   the pick cards. A wide lead card opens each section (photo left on the
   planning row, right on the buying row), then four cards: 1 column on
   phones, 2 x 2 from 640px, four across from 1100px. The buying row's
   four are the homepage pick cards, so only the planning row uses
   .hub-grid. */
.hub-grid { display: grid; gap: clamp(14px, 1.6vw, 20px); }
.hub-lead { margin-bottom: clamp(14px, 1.6vw, 20px); }
.guide-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 10px 10px 22px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
}
.guide-card img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-sm);
}
.guide-card__body { display: grid; gap: 8px; margin: 18px 8px 0; }
.guide-card__eyebrow {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-ink-3);
}
.guide-card__title {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.1875rem, 1rem + 0.5vw, 1.4375rem);
  line-height: 1.18;
  letter-spacing: -0.02em;
  color: var(--color-ink);
  transition: color 0.2s var(--ease-out);
}
.guide-card__title svg {
  width: 18px;
  height: 18px;
  margin: 0.15em 0 0 auto;
  flex: none;
  transition: transform 0.3s var(--ease-out);
}
.guide-card__blurb { font-size: var(--fs-small); line-height: 1.5; color: var(--color-ink-2); }
.guide-card:hover,
.guide-card:focus-visible { transform: translateY(-4px); box-shadow: var(--shadow-card-hover); }
.guide-card:hover .guide-card__title,
.guide-card:focus-visible .guide-card__title { color: var(--color-lawn-deep); }
.guide-card:hover .guide-card__title svg,
.guide-card:focus-visible .guide-card__title svg { transform: translateX(3px); }
.guide-card:focus-visible { outline-offset: 4px; }
@media (min-width: 640px) {
  .hub-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 900px) {
  .guide-card--lead {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: clamp(24px, 3vw, 48px);
    align-items: center;
    padding: 12px clamp(24px, 3vw, 44px) 12px 12px;
  }
  .guide-card--flip {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    padding: 12px 12px 12px clamp(24px, 3vw, 44px);
  }
  .guide-card--flip img { order: 2; }
  .guide-card--lead .guide-card__body { margin: 0; gap: 12px; }
  .guide-card--lead .guide-card__title { font-size: var(--fs-h3); line-height: 1.12; letter-spacing: -0.025em; }
  .guide-card--lead .guide-card__title svg { width: 22px; height: 22px; margin-top: 0.2em; }
  .guide-card--lead .guide-card__blurb { font-size: var(--fs-body); max-width: 40ch; }
}
@media (min-width: 1100px) {
  .hub-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ------------------------------------------------- reduced motion
   No scroll animation of any kind: the head gate never adds gsap-anim,
   so the hero renders its inflated still, and CSS transitions collapse.
   Inner-page video heroes keep their poster as a still. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero-video video { display: none; }
  .reveal { opacity: 1; transform: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
