/* ============================================================
   med.co.uk · med.uk — private-offering landing
   Staging: flat black, single dark identity. No theme switch — the
   generative background and light palette were tried and set aside;
   this is the plain, permanent look.
   ============================================================ */

:root {
  --ink: #000000;                              /* flat black ground */
  --paper: #f8f7f4;                            /* primary text, near-white */
  --paper-dim: #ddd8ce;                        /* secondary text */
  --paper-faint: rgba(248, 247, 244, 0.88);    /* annotations, eyebrow */
  --paper-press: #e7e3da;                      /* CTA hover surface */
  --accent: #b3985f;                           /* muted gold, single accent */
  --hairline: rgba(248, 247, 244, 0.12);
  --hairline-strong: rgba(248, 247, 244, 0.34); /* hero divider */
  --display: "Inter Tight", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --measure: 34rem;
  --topbar-space: 4.0625rem;   /* the header capsule's footprint: 10px frame inset + 55px capsule */
  --fast: 120ms ease-out;
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);  /* the whole motion system */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  /* One landing pad for every anchor jump, clearing the fixed header capsule.
     Supersedes the per-element scroll-margin that used to be hand-tuned in the
     showcase section. */
  scroll-padding-top: 5rem;
  -webkit-text-size-adjust: 100%;
  color-scheme: dark;
}

/* Vendored Lenis smooth scroll. The .lenis class exists only while an instance
   is live; Lenis writes the real scroll position every frame, and per the
   scroll-behavior spec each of those writes would otherwise be re-animated by
   the browser's own smoothing, so it stands down here. scroll-padding-top above
   stays in force: Lenis reads it for its own anchor landings. Without JS the
   class never appears and the smooth declaration above still covers anchors. */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }

body {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 400;
  letter-spacing: 0.01em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

main, .topbar, .footer { position: relative; z-index: 2; }

::selection { background: var(--accent); color: var(--ink); }

/* Film grain: a static breath of texture over the flat black, so the page
   reads as material rather than void. Inline SVG noise, matching the favicon
   precedent (no image file), fixed, non-interactive, far below legibility. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.07;
}

/* ---------- Top bar ---------- */

/* A floating glass capsule, after Apple's product headers: the fixed element
   is a transparent inset frame, and the capsule inside it carries the glass.
   Same construction at every size, wide-inset on phones and centred on a max
   width at desktop. */
.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 10;
  padding: 10px;
  padding-left: max(10px, env(safe-area-inset-left));
  padding-right: max(10px, env(safe-area-inset-right));
  pointer-events: none;   /* the frame is inert; the capsule takes the clicks */
}

.topbar-inner {
  pointer-events: auto;
  /* Aligns the capsule's edges with the showcase panel, the widest block on
     the page, so the header sits in the same column as the content. */
  max-width: 1180px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.5rem 0.5rem 1.35rem;
  /* The thanks page carries no CTA pill, so without this its capsule would
     sit shorter than the main page's. Same header, same height. */
  min-height: 3.4375rem;
  border-radius: 999px;
  /* The glass the showcase controls already established, one step denser. */
  background: rgba(22, 21, 18, 0.72);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  backdrop-filter: blur(20px) saturate(1.3);
  border: 1px solid rgba(248, 247, 244, 0.06);
}

/* Alone in the capsule (the confirmation page), the marque centres rather than
   sitting off to one side. The padding equalises too: the capsule's larger left
   inset exists to balance the CTA pill on the right, and would otherwise throw a
   centred marque off true. Engines without :has() keep today's left alignment. */
.topbar-inner:has(> :only-child) {
  justify-content: center;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

/* Reveal on scroll. Scoped under .js, which main.js adds only when it will
   actually run, so without JavaScript (and under reduced motion, which returns
   before the class is added) the header is simply always present. */
.js .topbar-inner {
  transform: translateY(-130%);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.55s var(--ease-out-expo), opacity 0.3s ease-out;
}

.js .topbar.shown .topbar-inner {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}

/* While a showcase card is open the capsule steps back out of the way, the same
   move it makes over the hero, so a tall graphic and its card can share a phone
   screen. The showcase controller owns .m-cardopen and drops it the moment the
   card closes or the panel scrolls out of view. main.js keeps toggling .shown
   underneath, so this has to outrank the rule above: (0,5,1) against (0,4,0).
   Scoped under .js like the rest, which leaves no-JS, reduced-motion and the
   thanks page (no controller) with a permanently visible header. */
html.js.m-cardopen .topbar.shown .topbar-inner {
  transform: translateY(-130%);
  opacity: 0;
  pointer-events: none;
}

.marque {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: 0.02em;
  color: var(--paper);
  text-decoration: none;
}

/* A filled pill, the hero CTA one step down. The white draw-in sweep this
   replaced could not survive the change: a white line beneath a white pill is
   invisible. The hover cue is the same paper-press shift the hero button uses. */
.topbar-cta {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
  padding: 0.5rem 1.15rem;
  background: var(--paper);
  border-radius: 999px;
  transition: background-color var(--fast);
}

.topbar-cta:hover,
.topbar-cta:focus-visible { background: var(--paper-press); }

/* ---------- Hero ---------- */

.hero {
  min-height: 100vh;   /* fallback for browsers without dvh/lvh support */
  min-height: 100lvh;  /* large viewport: always >= the visible area in every
                          mobile browser-chrome state, so on first paint the
                          hero fully covers the screen and "The asset" never
                          peeks in before the visitor scrolls past it */
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  /* Optical centre: the block sits a touch above true middle, which is where
     the eye expects "centred" to be. The old 5.5/3.5 split was clearance for a
     fixed bar that no longer sits here, and it pushed the content 32px low.
     The two paddings must always SUM to the same 9rem: the content box, and so
     the overflow behaviour, then never changes — landscape phones have zero
     slack, so any loss of available height would clip them. The clamp ceiling
     keeps padding-top positive above ~1600px tall, where an uncapped
     4.5rem - 4.5vh would compute negative and be dropped entirely. */
  --hero-pad: 4.5rem;
  --hero-lift: clamp(1rem, 4.5vh, 2.5rem);
  padding: calc(var(--hero-pad) - var(--hero-lift)) clamp(1.25rem, 5vw, 3.5rem)
           calc(var(--hero-pad) + var(--hero-lift));
  position: relative;
}

/* The confirmation page never loads main.js, so its capsule is permanently
   visible: its hero centres in the space below the capsule, not the viewport. */
.hero-confirm { padding-top: calc(var(--hero-pad) - var(--hero-lift) + var(--topbar-space)); }

.kicker {
  font-size: 0.71875rem;   /* 11.5px */
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--paper-faint);
  margin-bottom: 1.75rem;
}

/* Engraved, single ink — no gradients, no accents on the names.
   The three letters carry the mark; the suffix steps back a weight. */
.hero-wordmark {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.8rem, 8.5vw, 6.75rem);
  line-height: 1.05;
  letter-spacing: -0.035em;
  color: var(--paper);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.9rem, 2.2vw, 1.4rem);
}

.hero-wordmark .tld {
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--paper-dim);
}

.hero-wordmark .divider {
  display: block;
  width: clamp(2.5rem, 6vw, 4rem);
  height: 1px;
  background: var(--hairline-strong);
}

/* Confirmation page: the same mark, one step down, so "Thank you."
   never competes with the hero it follows */
.hero-wordmark-sm { font-size: clamp(2.6rem, 8vw, 6rem); }

.hero-return { margin-top: 2.75rem; }

.hero-line {
  margin-top: 2rem;
  max-width: var(--measure);
  font-size: clamp(1.05rem, 1.5vw, 1.1875rem);
  color: var(--paper-dim);
}

.hero .cta { margin-top: 2rem; }

.hero-note {
  margin-top: 1.1rem;
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
  color: var(--paper-dim);
}

/* ---------- CTA ---------- */

.cta {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  padding: 0.95rem 2.4rem;
  background: var(--paper);
  border: 1px solid var(--paper);
  border-radius: 2px;
  cursor: pointer;
  transition: background-color var(--fast), border-color var(--fast);
}

.cta:hover,
.cta:focus-visible {
  background: var(--paper-press);
  border-color: var(--paper-press);
}

.cta:active { transform: translateY(1px); }

/* ---------- Label morph (after unseen.co) ----------
   On hover the label's characters roll up and out while the same text rolls in
   from below in the display italic, staggered left to right. Two stacked
   aria-hidden layers inside an overflow mask; the accessible name lives on the
   element's aria-label. Transform-only, timed with per-character delays. */

.flip {
  display: inline-grid;
  align-items: center;
  overflow: hidden;
  line-height: 1.3;
}

.flip-a,
.flip-b {
  grid-area: 1 / 1;
  display: flex;
  justify-content: center;
  white-space: pre;
}

.flip i {
  display: inline-block;
  font-style: normal;
  transition: transform 0.55s cubic-bezier(0.77, 0, 0.175, 1);
}

.flip-b {
  font-family: var(--display);
  font-style: italic;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.01em;
  /* Topbar morph target: a shade over the label size so the italic holds the
     line without outgrowing it. */
  font-size: 1.05em;
}

/* Inside the boxed buttons the italic runs a shade over the caps label,
   tuned to this exact figure by owner preference. */
.cta .flip-b { font-size: 1.19em; }

.flip-b i {
  font-style: italic;
  transform: translateY(125%);
}

.cta-flip:hover .flip-a i,
.cta-flip:focus-visible .flip-a i { transform: translateY(-125%); }

.cta-flip:hover .flip-b i,
.cta-flip:focus-visible .flip-b i { transform: translateY(0); }

.flip i:nth-child(2)  { transition-delay: 0.018s; }
.flip i:nth-child(3)  { transition-delay: 0.036s; }
.flip i:nth-child(4)  { transition-delay: 0.054s; }
.flip i:nth-child(5)  { transition-delay: 0.072s; }
.flip i:nth-child(6)  { transition-delay: 0.09s; }
.flip i:nth-child(7)  { transition-delay: 0.108s; }
.flip i:nth-child(8)  { transition-delay: 0.126s; }
.flip i:nth-child(9)  { transition-delay: 0.144s; }
.flip i:nth-child(10) { transition-delay: 0.162s; }
.flip i:nth-child(11) { transition-delay: 0.18s; }
.flip i:nth-child(12) { transition-delay: 0.198s; }
.flip i:nth-child(13) { transition-delay: 0.216s; }
.flip i:nth-child(14) { transition-delay: 0.234s; }
.flip i:nth-child(15) { transition-delay: 0.252s; }

.cta:focus-visible,
.topbar-cta:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ---------- Sections ---------- */

/* One quiet hairline between sections. A gold segment was tried on top
   of its left end and read as a half-drawn line rather than a detail. */

/* The vertical rhythm is deliberately generous. Each section holds one
   idea and is given enough room that it arrives on its own screenful
   rather than competing with the next, which is what actually slows a
   skim-reader down. Tightening this is what makes the page skimmable. */
.section {
  max-width: 52rem;
  margin: 0 auto;
  /* Generous by design (the pacing decision), but the ceiling is trimmed:
     8rem read as dead air rather than rhythm, on the owner's review. */
  padding: clamp(4.25rem, 10vh, 6.5rem) clamp(1.25rem, 5vw, 3.5rem);
  border-top: 1px solid var(--hairline);
  text-align: center;
}

/* Section titles: clean sans label, confident weight — a product
   section heading, not a serif clause heading */
.section .kicker {
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--paper);
  margin-bottom: 1.75rem;
}

/* Sideways sections: a sticky label pinned left while its copy scrolls
   past on the right — Vercel/Stripe's two-column feature-section pattern.
   Pure CSS grid + position: sticky, no JS. */
.section-asset,
.section-questions,
.section-whynow,
.section-terms {
  max-width: 64rem;
  text-align: left;
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr;
  column-gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.section-asset > .kicker,
.section-questions > .kicker,
.section-whynow > .kicker,
.section-terms > .kicker {
  grid-column: 1;
  position: sticky;
  top: 6rem;
  margin-bottom: 0;
}

.section-asset > .statements,
.section-questions > .questions,
.section-whynow > .terms-copy,
.section-whynow > .whynow-lead,
.section-terms > .terms-copy {
  grid-column: 2;
}

/* Why-now's label spans two content rows (the quiet line, then the lead) */
.section-whynow > .kicker { grid-row: 1 / -1; }

/* Why it matters: a 3-up feature grid instead of a stacked list */
.section-why {
  max-width: 72rem;
  text-align: left;
}

.statements {
  display: flex;
  flex-direction: column;
  gap: 3.25rem;
  align-items: flex-start;
}

.statement {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(1.15rem, 1.8vw, 1.4rem);
  line-height: 1.6;
  max-width: 42rem;
}

.statement em { font-style: normal; color: var(--accent); }

/* Numbered feature grid — side by side on desktop, stacked below 48rem */

.points {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: clamp(2rem, 4vw, 3rem);
  row-gap: 3.5rem;
  align-items: start;
}

.point {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

.point-num {
  font-family: var(--sans);
  font-style: normal;
  font-weight: 600;
  font-size: 0.875rem;
  letter-spacing: 0.04em;
  color: var(--accent);
}

.point h2 {
  font-family: var(--sans);
  font-weight: 600;
  font-size: clamp(1.3rem, 2vw, 1.5rem);
  letter-spacing: -0.01em;
}

.point p { color: var(--paper-dim); max-width: var(--measure); }

/* Points of detail — the section a director reads when the link has
   been forwarded to them. Reuses the sticky-label grid above. */

.questions {
  display: flex;
  flex-direction: column;
  gap: 2.9rem;
  max-width: 42rem;
}

/* Was clamp(1.05rem, 1.5vw, 1.2rem), which renders 16.8px on a phone against 17px
   body copy: the heading was smaller than the answer beneath it, separated only by
   weight. A forwarded link has to survive a board skim, so the question has to read
   as the question. */
.qa h2 {
  font-family: var(--sans);
  font-weight: 600;
  font-size: clamp(1.25rem, 1.9vw, 1.45rem);
  letter-spacing: -0.01em;
  line-height: 1.35;
  margin-bottom: 0.7rem;
}

.qa p { color: var(--paper-dim); }

/* Why now · Terms */

.terms-copy {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  line-height: 1.6;
  max-width: 36rem;
}

.section-whynow .terms-copy { color: var(--paper-dim); }

.whynow-lead {
  font-family: var(--sans);
  font-weight: 600;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.3;
  max-width: 36rem;
  margin-top: 1.25rem;
  color: var(--paper);
}

/* ---------- Enquiry ---------- */

/* The form title anchors the bottom half of the page: the one place
   besides the hero and the marque where the display face is used. */
.section-enquiry .kicker {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.02em;
  font-size: clamp(1.6rem, 2.6vw, 1.9rem);
  margin-bottom: 1.25rem;
}

.enquiry-line {
  color: var(--paper-dim);
  max-width: var(--measure);
  margin: 0 auto 2.5rem;
}

.enquiry-form {
  max-width: 36rem;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
  text-align: left;
}

.hp-field { position: absolute; left: -9999px; height: 1px; width: 1px; overflow: hidden; }

.field { display: flex; flex-direction: column; gap: 0.55rem; position: relative; }

/* The conversion moment gets the craft: a gold line sweeps under the active
   field. Replaces both the instant border flip and the boxy focus outline as
   the visible focus indicator (2px, full field width). */
.field::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2.5px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  /* Slow enough that the travel itself reads; the old instant flip made the
     focus state look identical to a static border. */
  transition: transform 480ms cubic-bezier(0.25, 0.1, 0.25, 1);
}

.field:focus-within::after { transform: scaleX(1); }

/* Email and phone sit on one line where there is room for them */
.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 1.75rem;
  row-gap: 1.75rem;
}

.field label {
  font-size: 0.71875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-dim);
  transition: color 150ms ease-out;
}

.field-opt {
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--paper-dim);
  opacity: 0.65;
}

.field input,
.field textarea {
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 400;
  color: var(--paper);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--hairline);
  padding: 0.55rem 0;
  border-radius: 0;
  transition: border-color 150ms ease-out;
}

.field input:focus-visible,
.field textarea:focus-visible { outline: none; }

.field:focus-within label { color: var(--paper); }

/* Keep browser autofill from painting fields light */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus,
.field textarea:-webkit-autofill {
  -webkit-text-fill-color: var(--paper);
  -webkit-box-shadow: 0 0 0 1000px var(--ink) inset;
  caret-color: var(--paper);
  transition: background-color 600000s ease-out, border-color 150ms ease-out;
}

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

.cta-submit { align-self: center; margin-top: 0.5rem; }

.call-link { margin-top: 2rem; }

.cta-ghost {
  background: transparent;
  border-color: var(--hairline);
  color: var(--paper);
}

.cta-ghost:hover,
.cta-ghost:focus-visible {
  background: transparent;
  border-color: var(--paper);
}

/* ---------- Footer ---------- */

.footer {
  border-top: 1px solid var(--hairline);
  padding: 2.25rem clamp(1.25rem, 5vw, 3.5rem);
  text-align: center;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  color: var(--paper-dim);
}

.footer p + p { margin-top: 0.5rem; }

/* The closing note: the marque once more, oversized and nearly silent,
   bookending the page with the monument it opened on. */
.footer-marque {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(3.75rem, 13vw, 8.75rem);
  line-height: 1;
  letter-spacing: -0.035em;
  color: rgba(248, 247, 244, 0.07);
  margin-bottom: 1.5rem;
  user-select: none;
}

/* ---------- Motion ---------- */

/* Every hidden state below is scoped under .js, which main.js adds to
   <html> only once it has confirmed it will actually run. With
   JavaScript off, none of these selectors match and the page is simply
   the finished layout: nothing is ever hidden behind an animation. */

/* 1 · Body content rises and fades as it enters. Unhurried on purpose:
   the settle time is long enough that a reader arriving at a section
   watches it resolve, which buys a beat of attention before they move
   on. Long enough to notice, short enough never to be waited on. */
.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 820ms var(--ease-out-expo), transform 820ms var(--ease-out-expo);
  will-change: opacity, transform;
}

.js .reveal.in { opacity: 1; transform: none; }

/* Siblings arrive in sequence rather than as one block, so a three-up
   grid is read left to right instead of taken in at a glance. */
.js .points > .point:nth-child(2) { transition-delay: 150ms; }
.js .points > .point:nth-child(3) { transition-delay: 300ms; }
.js .statements > .statement:nth-child(2) { transition-delay: 150ms; }
.js .statements > .statement:nth-child(3) { transition-delay: 300ms; }
.js .questions > .qa:nth-child(2) { transition-delay: 120ms; }
.js .questions > .qa:nth-child(3) { transition-delay: 240ms; }
.js .questions > .qa:nth-child(4) { transition-delay: 360ms; }

/* 2 · Headings wipe up from behind their own edge. The host clips, the
   inner span travels: pure transform, no clip-path. The padding pair
   widens the clipping box past the glyphs so descenders never shear. */
.js .masked {
  overflow: hidden;
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
}

.js .reveal .wipe,
.js .reveal.masked .wipe {
  display: block;
  transform: translateY(115%);
  transition: transform 940ms var(--ease-out-expo);
}

.js .reveal.in .wipe { transform: none; }

/* 3 · Scroll-linked reveal, where the browser supports it.
   Everything above is time-based: the observer trips and the transition
   then plays on its own clock, whatever the reader does next. These
   bind the same movement to scroll position instead, so copy resolves
   as the page moves and settles back if the reader scrolls up. That
   coupling to the hand is the effect itself.
   Ignored by browsers without support, which keep the reveal above,
   and skipped entirely under reduced motion. Runs off the main thread,
   costs no JavaScript. */

@keyframes rise-in {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}

@keyframes wipe-in {
  from { transform: translateY(115%); }
  to { transform: none; }
}

@supports (animation-timeline: view()) {
  /* Ranged over `cover` rather than `entry`. The entry phase of a short
     element is only as long as the element is tall, so the fade was
     over in a couple of hundred pixels. Cover spans the viewport too,
     which is what stretches the resolve across a real length of scroll
     and gives it the unhurried feel. Copy is fully present by roughly
     the middle of the screen. */
  .js .reveal {
    animation: rise-in linear both;
    animation-timeline: view();
    animation-range: cover 2% cover 42%;
    transition: none;
  }

  .js .reveal .wipe,
  .js .reveal.masked .wipe {
    animation: wipe-in linear both;
    animation-timeline: view();
    animation-range: cover 2% cover 36%;
    transition: none;
  }

  /* transition-delay means nothing on a scroll timeline, so siblings
     are sequenced by finishing further down the range instead */
  .js .points > .point:nth-child(2),
  .js .statements > .statement:nth-child(2),
  .js .questions > .qa:nth-child(2) { animation-range: cover 2% cover 50%; }

  .js .points > .point:nth-child(3),
  .js .statements > .statement:nth-child(3),
  .js .questions > .qa:nth-child(3) { animation-range: cover 2% cover 58%; }

  .js .questions > .qa:nth-child(4) { animation-range: cover 2% cover 66%; }
}

/* Reduced motion: belt and braces. main.js returns before adding .js at
   all, so these selectors should never match; they are here in case the
   preference changes after load. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; animation: none; }
  .js .reveal .wipe { transform: none; transition: none; animation: none; }
  .cta { transition: none; }
  .flip i { transition: none; }
  .field::after { transition: none; }
  .topbar-cta { transition: none; }
}

/* ---------- Landscape phones ---------- */

/* Wide but very short: the hero's vw-scaled wordmark would overflow a 375px
   tall screen, so type and spacing follow height here instead. */
@media (orientation: landscape) and (max-height: 480px) {
  /* Retuning the two variables is enough: the base rule's padding recomputes
     from them. Holds this block's 7rem total, so the zero-slack fit here is
     preserved exactly. */
  .hero {
    --hero-pad: 3.5rem;
    --hero-lift: clamp(0.75rem, 4.5vh, 1.25rem);
  }
  /* No room here for the full optical treatment on top of the capsule's
     footprint: the confirmation page's content would drop below the fold on a
     393px-tall screen. Clear the capsule and no more. */
  .hero-confirm {
    padding-top: calc(var(--topbar-space) + 0.5rem);
    padding-bottom: 1.5rem;
  }
  .hero-wordmark { font-size: clamp(2.4rem, 13vh, 4.25rem); }
  .hero-line { margin-top: 1.25rem; }
  .hero .cta { margin-top: 1.25rem; }
  .hero-note { margin-top: 0.8rem; }
  .footer-marque { font-size: clamp(3rem, 24vh, 6rem); }
}

/* ---------- Sideways-section collapse ---------- */

/* Sits after the base rules so it wins the cascade at narrow widths:
   sticky label + grid become a plain single-column stack, no JS involved.
   Landscape phones (wide but short) fall through width-only breakpoints into
   the desktop layout, hence the height clause on every mobile block. */
@media (max-width: 48rem), (orientation: landscape) and (max-height: 480px) {
  .section-asset,
  .section-questions,
  .section-whynow,
  .section-terms {
    grid-template-columns: 1fr;
  }
  .section-asset > .kicker,
  .section-questions > .kicker,
  .section-whynow > .kicker,
  .section-terms > .kicker {
    position: static;
    grid-column: 1;
    grid-row: auto;
    margin-bottom: 2rem;
  }
  .section-asset > .statements,
  .section-questions > .questions,
  .section-whynow > .terms-copy,
  .section-whynow > .whynow-lead,
  .section-terms > .terms-copy {
    grid-column: 1;
  }
  .points { grid-template-columns: 1fr; }
}

/* ---------- Small screens ---------- */

@media (max-width: 40rem), (orientation: landscape) and (max-height: 480px) {
  /* Phones need less: sections span multiple screens regardless, so the
     screenful pacing argument doesn't apply and padding is pure scroll cost. */
  .section { padding-top: 3.25rem; padding-bottom: 3.25rem; }
  .statements { gap: 2.6rem; }
  .points { gap: 3rem; }
  .questions { gap: 2.4rem; }

  /* Vertical stacking puts headings hard against their own body copy;
     add the breathing room that side-by-side layout gave them for free.
     (Private enquiry keeps its own spacing, untouched by this pass.) */
  .section-asset .kicker,
  .section-why .kicker,
  .section-questions .kicker,
  .section-whynow .kicker,
  .section-terms .kicker {
    margin-bottom: 2.25rem;
  }
  .point { gap: 0.65rem; }
  .point h2 { margin-bottom: 0.2rem; }

  /* One field per line once the pair no longer fits comfortably */
  .field-row { grid-template-columns: 1fr; }
}
