/* ============================================================
   wavflow — marketing site
   ============================================================

   Design rules this file follows, and why:

   · No decorative gradients. Depth comes from translucency,
     shadow weight and a warm neutral ground, the way material
     does. Colour is flat and confident.
   · Tracking is size-specific. Large display type gets negative
     tracking (letters read too far apart as they grow); body sits
     near zero; small caps get positive tracking.
   · Leading tracks size inversely — tight on display, generous on
     body.
   · Spacing is in rem so the whole layout scales with the reader's
     text-size setting instead of breaking.
   · Only `transform` and `opacity` are animated. Everything else
     would cost a paint.
   · Motion respects prefers-reduced-motion, -transparency and
     -contrast independently. Reduced motion means gentler, not
     absent.

   Palette is lifted from the product's own design system so the
   site and the app are unmistakably the same thing.
   ============================================================ */

/* ---------- Tokens ---------- */

:root {
  /* Ground + surfaces */
  --paper:        #FAF7F2;
  --paper-deep:   #F4F0E9;
  --surface:      #FFFFFF;
  --sunken:       #F1ECE4;

  /* Ink */
  --ink:          #1F1D1A;
  --ink-2:        #6B6660;
  --ink-3:        #9A938B;
  --hairline:     #E7E0D6;

  /* Accent — the product's teal */
  --accent:       #2F6F6B;
  --accent-press: #245854;
  --accent-tint:  #E4EFEE;
  --accent-ink:   #1E4B48;
  --on-accent:    #FFFFFF;

  /* Consensus ramp, used by the availability grid */
  --heat-0: #F1ECE4;
  --heat-1: #DCE9E7;
  --heat-2: #BCD8D4;
  --heat-3: #8FC0BA;
  --heat-4: #59A29B;
  --heat-5: #2F6F6B;

  /* Radii — a step rounder than default, always continuous-ish */
  --r-sm: 0.75rem;
  --r-md: 1.125rem;
  --r-lg: 1.5rem;
  --r-xl: 2rem;
  --r-2xl: 2.5rem;
  --r-pill: 999px;

  /* Elevation. Warm-tinted, never grey-blue. Larger surfaces read
     thicker, so they get more blur and more offset. */
  --e1: 0 1px 2px rgba(31,29,26,.04), 0 2px 8px rgba(31,29,26,.04);
  --e2: 0 2px 6px rgba(31,29,26,.05), 0 10px 26px rgba(31,29,26,.06);
  --e3: 0 6px 16px rgba(31,29,26,.06), 0 28px 60px rgba(31,29,26,.10);
  --e4: 0 10px 30px rgba(31,29,26,.08), 0 44px 100px rgba(31,29,26,.14);

  /* Motion. These curves approximate a critically damped spring —
     they settle without overshoot. The bounce curve is reserved for
     moments that follow a gesture. */
  --ease-out:    cubic-bezier(.22,.61,.36,1);
  --ease-settle: cubic-bezier(.16,.84,.32,1);
  --ease-bounce: cubic-bezier(.34,1.36,.5,1);
  --t-fast: 140ms;
  --t-base: 260ms;
  --t-slow: 620ms;

  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --shell: 76rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:       #141310;
    --paper-deep:  #100F0D;
    --surface:     #1E1C18;
    --sunken:      #211F1A;
    --ink:         #F5F1EA;
    --ink-2:       #A9A29A;
    --ink-3:       #7A736B;
    --hairline:    #332F29;
    --accent:      #4E9A94;
    --accent-press:#3E837D;
    --accent-tint: #1B302F;
    --accent-ink:  #9CCBC6;
    --on-accent:   #0E1F1E;

    --heat-0: #211F1A;
    --heat-1: #22322F;
    --heat-2: #2A4744;
    --heat-3: #356059;
    --heat-4: #427C76;
    --heat-5: #4E9A94;

    --e1: 0 1px 2px rgba(0,0,0,.30), 0 2px 8px rgba(0,0,0,.24);
    --e2: 0 2px 6px rgba(0,0,0,.34), 0 10px 26px rgba(0,0,0,.30);
    --e3: 0 6px 16px rgba(0,0,0,.38), 0 28px 60px rgba(0,0,0,.40);
    --e4: 0 10px 30px rgba(0,0,0,.42), 0 44px 100px rgba(0,0,0,.50);
  }
}

/* ---------- Reset ---------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The pinned walkthrough owns its own scroll maths, so anchors
     need a little breathing room under the floating bar. */
  scroll-padding-top: 6rem;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 1rem/1.65 -apple-system, BlinkMacSystemFont, "SF Pro Text",
        system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-optical-sizing: auto;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* `clip`, not `hidden`. `overflow-x: hidden` turns the body into a
     scroll container, which silently breaks every `position: sticky`
     descendant — including the pinned device in the walkthrough.
     `clip` contains overflow without creating that container. */
  overflow-x: clip;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

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

.skip {
  position: fixed; top: 0.75rem; left: 0.75rem; z-index: 200;
  padding: 0.625rem 1rem; border-radius: var(--r-pill);
  background: var(--accent); color: var(--on-accent);
  font-size: 0.875rem; font-weight: 600;
  transform: translateY(-150%);
  transition: transform var(--t-base) var(--ease-out);
}
.skip:focus { transform: translateY(0); }

/* ---------- Type scale ----------
   Every step pairs a size with its own tracking and leading.
   A single letter-spacing value across the scale is wrong
   somewhere by definition. */

.display-xl {
  font-size: clamp(2.75rem, 7.4vw, 5.75rem);
  line-height: 0.98;
  letter-spacing: -0.036em;
  font-weight: 600;
}
.display-l {
  font-size: clamp(2rem, 4.6vw, 3.35rem);
  line-height: 1.06;
  letter-spacing: -0.028em;
  font-weight: 600;
}
.display-m {
  font-size: clamp(1.5rem, 2.7vw, 2.15rem);
  line-height: 1.14;
  letter-spacing: -0.021em;
  font-weight: 600;
}

.lede {
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
  line-height: 1.6;
  letter-spacing: -0.004em;
  color: var(--ink-2);
  max-width: 34em;
}
.lede--center { margin-inline: auto; text-align: center; }

.eyebrow, .overline {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.15em;   /* small text wants positive tracking */
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}

.microcopy {
  font-size: 0.8125rem;
  line-height: 1.55;
  letter-spacing: 0.004em;
  color: var(--ink-3);
}

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

/* ---------- Layout ---------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.shell--narrow { max-width: 48rem; }

/* ---------- Nav ----------
   A real material: content scrolls under it, it blurs what's
   behind, and the top edge is a bright hairline where light
   catches the surface. */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  padding: 0.75rem var(--gutter);
  transition: transform var(--t-base) var(--ease-out);
  will-change: transform;
}

.nav__inner {
  max-width: var(--shell);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 0.5rem 0.5rem 1rem;
  border-radius: var(--r-pill);

  /* Starts invisible; materialises once content is behind it. */
  background: transparent;
  border: 1px solid transparent;
  box-shadow: none;
  backdrop-filter: blur(0px) saturate(100%);
  -webkit-backdrop-filter: blur(0px) saturate(100%);
  transition:
    background var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out),
    backdrop-filter var(--t-base) var(--ease-out);
}

.nav.is-stuck .nav__inner {
  background: color-mix(in srgb, var(--paper) 72%, transparent);
  border-color: color-mix(in srgb, var(--hairline) 70%, transparent);
  box-shadow: var(--e2);
  backdrop-filter: blur(22px) saturate(180%);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--accent);
  font-weight: 600;
  letter-spacing: -0.02em;
  font-size: 1.0625rem;
}
.brand__mark {
  width: 1.75rem; height: 1.75rem; flex: none;
  display: block; position: relative;
  border-radius: 0.5rem;
  overflow: hidden;
  box-shadow: var(--e1);
}
.brand__img { width: 100%; height: 100%; object-fit: cover; }
/* The icon ships in two appearances. Show the one built for the theme
   the reader is actually in rather than tinting a single asset. */
.brand__img--dark { display: none; }
@media (prefers-color-scheme: dark) {
  .brand__img--light { display: none; }
  .brand__img--dark { display: block; }
}
.brand--foot .brand__mark { width: 2rem; height: 2rem; border-radius: 0.625rem; }
.brand__word { color: var(--ink); }

.nav__links {
  display: flex;
  gap: 1.75rem;
  margin-left: auto;
  font-size: 0.9375rem;
  color: var(--ink-2);
}
.nav__links a { transition: color var(--t-fast) var(--ease-out); }
.nav__links a:hover { color: var(--ink); }

@media (max-width: 47.99rem) {
  .nav__links { display: none; }
  .btn--sm { margin-left: auto; }
}

/* ---------- Buttons ----------
   Press feedback fires on pointer-down and tracks 1:1, rather than
   waiting for release. 100ms is below the threshold where a tap
   starts to feel reported rather than felt. */

.btn {
  --btn-scale: 1;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font: inherit;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  white-space: nowrap;
  transform: scale(var(--btn-scale)) translate3d(var(--mx, 0px), var(--my, 0px), 0);
  transition: transform 110ms var(--ease-out),
              background 160ms var(--ease-out),
              border-color 160ms var(--ease-out);
  will-change: transform;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.btn.is-pressed { --btn-scale: 0.965; }

.btn--sm { padding: 0.5625rem 1.0625rem; font-size: 0.875rem; min-height: 2.5rem; }
.btn--lg { padding: 0.9375rem 1.5rem; font-size: 1rem; min-height: 3.25rem; }
.btn--wide { width: min(22rem, 100%); }

.btn--primary { background: var(--accent); color: var(--on-accent); box-shadow: var(--e1); }
.btn--primary:hover { background: var(--accent-press); }

.btn--quiet {
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  color: var(--ink);
  border-color: var(--hairline);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.btn--quiet:hover { background: var(--surface); }

.btn__arrow {
  width: 1rem; height: 1rem; flex: none;
  transition: transform var(--t-base) var(--ease-settle);
}
.btn:hover .btn__arrow { transform: translateX(3px); }

/* ---------- Reveal ----------
   Content lifts into place once. `--d` staggers siblings without
   needing a class per index. */

.reveal {
  opacity: 0;
  transform: translate3d(0, 1.25rem, 0);
  transition:
    opacity var(--t-slow) var(--ease-settle) var(--d, 0ms),
    transform var(--t-slow) var(--ease-settle) var(--d, 0ms);
  will-change: transform, opacity;
}
.reveal.is-in { opacity: 1; transform: none; }

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

.hero {
  position: relative;
  padding: clamp(8rem, 16vh, 11rem) 0 clamp(4rem, 9vh, 7rem);
  overflow: clip;
}

.hero .shell {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.hero__title { margin: 1.25rem 0 0; }
.hero__title .line { display: block; }

.hero .lede { margin-top: 1.5rem; }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.25rem;
}
.hero .microcopy { margin-top: 1.25rem; }

.hero__stage { position: relative; display: grid; place-items: center; }


@media (max-width: 61.99rem) {
  /* Single column: the headline leads. Putting the device first
     looked balanced in a mockup but pushed every word below the
     fold on a phone — the one thing a hero cannot do. */
  .hero { padding-top: clamp(6.5rem, 13vh, 8.5rem); }
  .hero .shell { grid-template-columns: 1fr; }
  .hero__stage { margin-top: 2.5rem; }
  .device--hero { width: min(15.5rem, 62vw); }
}

@media (max-width: 29.99rem) {
  .device--hero { width: min(13.5rem, 60vw); }
  .hero__actions .btn { width: 100%; }
}

/* ---------- Device ----------
   A physical object: real bezel thickness, a screen inset, and a
   soft contact shadow underneath rather than a glow behind. */

.device {
  position: relative;
  width: min(19rem, 78vw);
  aspect-ratio: 9 / 19.2;
  transform: perspective(1400px)
             rotateX(var(--rx, 0deg))
             rotateY(var(--ry, 0deg))
             translate3d(0, var(--ty, 0px), 0)
             scale(var(--ds, 1));
  transform-style: preserve-3d;
  will-change: transform;
}

.device__frame {
  position: absolute;
  inset: 0;
  border-radius: var(--r-2xl);
  background: var(--surface);
  border: 1px solid var(--hairline);
  box-shadow: var(--e4);
  padding: 0.5rem;
}

.device__screen {
  position: relative;
  height: 100%;
  border-radius: 2.05rem;
  background: var(--paper);
  overflow: hidden;
  isolation: isolate;
}

/* Contact shadow. Sits under the device, not behind it. */
.device__glow {
  position: absolute;
  left: 8%; right: 8%; bottom: -1.75rem;
  height: 2.5rem;
  background: rgba(31,29,26,.16);
  filter: blur(28px);
  border-radius: 50%;
  z-index: -1;
}
@media (prefers-color-scheme: dark) {
  .device__glow { background: rgba(0,0,0,.6); }
}

/* ---------- App surface inside the device ---------- */

.app { padding: 0.875rem 0.875rem 1rem; height: 100%; }

/* Scenes lay out as a column so the explanatory note settles against
   the bottom edge and the slack lands in the middle, where it reads
   as breathing room rather than as a half-finished screen. */
.scene {
  padding: 0.875rem 0.875rem 1rem;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.app__status {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 0.6875rem; font-weight: 600; color: var(--ink-2);
  padding: 0.125rem 0.375rem 0.75rem;
  letter-spacing: 0;
}
.app__dots {
  width: 2.25rem; height: 0.5rem; border-radius: var(--r-pill);
  background: var(--sunken);
}

.app__title {
  font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.02em;
  text-align: center; padding-bottom: 0.875rem;
}

.pcard {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  box-shadow: var(--e1);
  padding: 0.9375rem;
  text-align: center;
  margin-bottom: 0.75rem;
}
.pcard__state {
  font-size: 0.5625rem; font-weight: 600; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-3);
}
.pcard__state--go { color: var(--accent); }
.pcard__name {
  font-size: 0.9375rem; font-weight: 600; letter-spacing: -0.016em;
  margin: 0.375rem 0 0.1875rem;
}
.pcard__sub { font-size: 0.6875rem; color: var(--ink-2); line-height: 1.4; }
.pcard__stats {
  display: flex; align-items: center;
  background: var(--sunken);
  border-radius: var(--r-md);
  padding: 0.625rem 0;
  margin-top: 0.75rem;
}
.pcard__stats > div { flex: 1; display: grid; gap: 0.0625rem; }
.pcard__stats b { font-size: 0.8125rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.pcard__stats span { font-size: 0.5rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.pcard__stats i { width: 1px; height: 1.5rem; background: var(--hairline); }
.pcard--locked { border-color: color-mix(in srgb, var(--accent) 30%, transparent); }

/* ---------- Statement ---------- */

.statement { padding: clamp(5rem, 12vh, 9rem) 0; text-align: center; }

.statement__text { margin-bottom: 1.75rem; }

/* Per-word reveal. Each word rises independently — the sentence
   assembles rather than fading in as a block. */
.statement__text .w {
  display: inline-block;
  opacity: 0.12;
  transform: translate3d(0, 0.35em, 0);
  transition: opacity 520ms var(--ease-settle), transform 520ms var(--ease-settle);
  transition-delay: calc(var(--i) * 26ms);
  will-change: transform, opacity;
}
.statement__text.is-in .w { opacity: 1; transform: none; }

/* ---------- Walkthrough ---------- */

.walk { position: relative; padding: 0 0 clamp(4rem, 10vh, 8rem); }

.walk__shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
}

/* The classic pin: a viewport-tall sticky box with its contents
   centred. Using `top: 0` + full height (rather than a percentage
   top plus a translate) means the device is centred the whole way
   through the section, including at the entry and exit edges. */
.walk__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 1.75rem;
}

.device--walk { width: min(18.5rem, 72vw); }

.rail { display: flex; gap: 0.4375rem; }
.rail i {
  width: 0.375rem; height: 0.375rem; border-radius: var(--r-pill);
  background: var(--hairline);
  transition: width var(--t-base) var(--ease-settle),
              background var(--t-base) var(--ease-out);
}
.rail i.is-on { width: 1.375rem; background: var(--accent); }

.walk__track { display: grid; }

.panel {
  min-height: 78vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.875rem;
  padding: 2rem 0;
  opacity: 0.34;
  transform: translate3d(0, 0, 0);
  transition: opacity var(--t-slow) var(--ease-settle);
  will-change: opacity;
}
.panel.is-active { opacity: 1; }
.panel p:not(.overline) { color: var(--ink-2); max-width: 32em; }

/* Scenes cross-fade in place. Only the active one is interactive. */
.scene {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translate3d(0, 0.75rem, 0) scale(0.985);
  transition: opacity 420ms var(--ease-settle), transform 420ms var(--ease-settle);
  pointer-events: none;
  will-change: transform, opacity;
}
.scene.is-on { opacity: 1; transform: none; pointer-events: auto; }

.scene__head { padding: 0 0.375rem 1rem; }
.scene__head h4 {
  font-size: 1.0625rem; letter-spacing: -0.022em; line-height: 1.2;
  margin-top: 0.3125rem;
}

.scene__note {
  margin-top: auto;
  background: var(--accent-tint);
  color: var(--accent-ink);
  border-radius: var(--r-md);
  padding: 0.625rem 0.75rem;
  font-size: 0.6875rem;
  line-height: 1.45;
}
.scene__note b { font-weight: 600; }

.field {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  padding: 0.8125rem 0.875rem;
  font-size: 0.8125rem;
  box-shadow: var(--e1);
}
.field--active { border-color: var(--accent); }

.chips { display: flex; flex-wrap: wrap; gap: 0.375rem; margin: 0.75rem 0 1rem; }
.chip {
  font-size: 0.6875rem;
  padding: 0.375rem 0.625rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--hairline);
  color: var(--ink-2);
}
.chip--on {
  background: var(--accent-tint);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent-ink);
  font-weight: 600;
}

/* Swipe deck — the product's card stack, in miniature */
.deck { position: relative; flex: 1 1 auto; min-height: 15rem; max-height: 21rem; margin: 0.25rem 0 1rem; }

.swipe {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  box-shadow: var(--e2);
  overflow: hidden;
  transform-origin: 50% 100%;
  transition: transform 560ms var(--ease-settle), opacity 400ms var(--ease-out);
  will-change: transform, opacity;
}
.swipe[data-swipe="2"] { transform: translate3d(0, 1.125rem, 0) scale(0.9); opacity: .55; }
.swipe[data-swipe="1"] { transform: translate3d(0, 0.5625rem, 0) scale(0.95); opacity: .85; }
.swipe[data-swipe="0"] { transform: none; }
.swipe.is-gone {
  transform: translate3d(120%, -1.5rem, 0) rotate(14deg);
  opacity: 0;
}

.swipe__art { flex: 1 1 auto; min-height: 7rem; background: var(--accent-tint); position: relative; }
.swipe__art::after {
  content: "";
  position: absolute; inset: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 2.75rem;
  opacity: .5;
}
.match__art { overflow: hidden; }
/* Flat, geometric category marks. No photography, no gradient. */
[data-art="dinner"]::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M6 3v8a2 2 0 0 0 4 0V3M8 11v10M18 3c-1.5 2-2 4-2 6s.5 3 2 3v9'/%3E%3C/svg%3E");
}
[data-art="bowl"]::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.5'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Ccircle cx='9.5' cy='9' r='1.1' fill='%232F6F6B'/%3E%3Ccircle cx='14' cy='8.5' r='1.1' fill='%232F6F6B'/%3E%3Ccircle cx='12' cy='13' r='1.1' fill='%232F6F6B'/%3E%3C/svg%3E");
}
[data-art="cafe"]::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M4 9h13v5a5 5 0 0 1-5 5H9a5 5 0 0 1-5-5V9ZM17 10h1.5a2.5 2.5 0 0 1 0 5H17M7 3v2.5M11 3v2.5'/%3E%3C/svg%3E");
}

.swipe__meta {
  padding: 0.625rem 0.75rem;
  display: grid;
  gap: 0.125rem;
  flex: none;
  transition: opacity 260ms var(--ease-out);
}
/* Only the top card carries its title. The cards behind are scaled
   and offset, so their text would otherwise stack up against the
   front card's and read as a smudge. */
.swipe:not([data-swipe="0"]) .swipe__meta { opacity: 0; }
.swipe__meta b { font-size: 0.8125rem; letter-spacing: -0.014em; }
.swipe__meta span { font-size: 0.625rem; color: var(--ink-2); }

.swipe__stamp {
  position: absolute; top: 0.75rem; left: 0.75rem;
  font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border-radius: var(--r-sm);
  border: 2px solid currentColor;
  opacity: 0;
  transform: rotate(-8deg) scale(0.86);
  transition: opacity 200ms var(--ease-out), transform 260ms var(--ease-bounce);
}
.swipe__stamp--yes { color: var(--accent); }
.swipe__stamp--maybe { color: #C08A3E; }
.swipe.is-stamped .swipe__stamp { opacity: 1; transform: rotate(-8deg) scale(1); }

/* Availability grid */
.grid { display: grid; gap: 0.5rem; margin: 0.25rem 0 1rem; }
.grid__row { display: flex; align-items: center; gap: 0.375rem; }
.grid__row span {
  width: 1.75rem; font-size: 0.625rem; color: var(--ink-2); font-weight: 600;
}
.grid__row i {
  flex: 1; height: 2.4rem; border-radius: 0.5rem;
  background: var(--heat-0);
  transform: scale(0.82);
  opacity: 0;
  transition: background 420ms var(--ease-out),
              transform 420ms var(--ease-bounce),
              opacity 300ms var(--ease-out);
  transition-delay: calc(var(--gd, 0) * 34ms);
}
.scene.is-on .grid__row i { opacity: 1; transform: none; }
.grid__row i[data-h="1"] { background: var(--heat-1); }
.grid__row i[data-h="2"] { background: var(--heat-2); }
.grid__row i[data-h="3"] { background: var(--heat-3); }
.grid__row i[data-h="4"] { background: var(--heat-4); }
.grid__row i[data-h="5"] { background: var(--heat-5); }

/* Match result */
.match {
  display: flex; align-items: center; gap: 0.625rem;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: var(--r-lg);
  padding: 0.75rem;
  box-shadow: var(--e2);
}
.match__art {
  width: 3rem; height: 3rem; flex: none;
  border-radius: var(--r-md);
  background: var(--accent-tint) center / 1.5rem no-repeat;
  position: relative;
}
.match__art::after {
  content: "";
  position: absolute; inset: 0;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 1.75rem;
  opacity: .55;
}
.match__body { display: grid; gap: 0.1875rem; }
.match__body b { font-size: 0.8125rem; letter-spacing: -0.016em; line-height: 1.25; }
.match__body span { font-size: 0.625rem; color: var(--ink-2); line-height: 1.35; }

.why { margin-top: 1rem; margin-bottom: 1rem; display: grid; gap: 0.75rem; }
.why li {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.8125rem; color: var(--ink-2);
}
.why i {
  width: 1rem; height: 1rem; flex: none; border-radius: var(--r-pill);
  background: var(--accent-tint);
  position: relative;
}
.why i::after {
  content: ""; position: absolute; inset: 0;
  background: center / 0.625rem no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5 9.5 18 20 6.5'/%3E%3C/svg%3E");
}

/* Locked-in reward */
.locked { display: grid; place-items: center; text-align: center; flex: 1 1 auto; align-content: center; gap: 0.5rem; }
.locked__seal {
  width: 4rem; height: 4rem; border-radius: var(--r-pill);
  background: var(--accent-tint);
  color: var(--accent);
  display: grid; place-items: center;
  margin-bottom: 0.5rem;
  transform: scale(0.6);
  opacity: 0;
  transition: transform 520ms var(--ease-bounce), opacity 300ms var(--ease-out);
}
.locked__seal svg { width: 1.75rem; height: 1.75rem; }
.scene.is-on .locked__seal { transform: none; opacity: 1; }
.locked h4 { font-size: 1.25rem; letter-spacing: -0.024em; }
.locked p { font-size: 0.8125rem; color: var(--ink-2); line-height: 1.5; }
.locked__row { display: flex; align-items: center; gap: -0.25rem; margin-top: 0.625rem; }
.av {
  width: 1.5rem; height: 1.5rem; border-radius: var(--r-pill);
  background: var(--accent-tint); color: var(--accent-ink);
  display: grid; place-items: center;
  font-size: 0.625rem; font-weight: 600;
  border: 2px solid var(--paper);
  margin-right: -0.375rem;
}
.locked__row em { font-size: 0.6875rem; color: var(--ink-3); margin-left: 0.75rem; }

@media (max-width: 61.99rem) {
  .walk__shell { grid-template-columns: 1fr; }
  .walk__sticky {
    position: sticky;
    top: 4.75rem;
    height: auto;
    align-content: start;
    padding: 1rem 0 1.25rem;
    /* Frosted so panels scrolling underneath stay legible */
    background: color-mix(in srgb, var(--paper) 86%, transparent);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    z-index: 5;
    border-radius: var(--r-xl);
  }
  .device--walk { width: min(17rem, 74vw); }
  .panel { min-height: 60vh; }
}

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

.craft { padding: clamp(4rem, 10vh, 7rem) 0; }

.sechead { max-width: 40rem; margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.sechead h2 { margin-top: 0.875rem; }

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: clamp(0.875rem, 1.6vw, 1.25rem);
}

.card {
  --lift: 0px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  padding: clamp(1.5rem, 2.4vw, 1.875rem);
  box-shadow: var(--e1);
  transform: translate3d(0, var(--lift), 0);
  transition: transform 420ms var(--ease-settle),
              box-shadow 420ms var(--ease-out),
              opacity var(--t-slow) var(--ease-settle) var(--d, 0ms);
  will-change: transform;
}
.card:hover { --lift: -4px; box-shadow: var(--e3); }
.card h3 { font-size: 1.0625rem; letter-spacing: -0.02em; margin: 1.125rem 0 0.5rem; }
.card p { font-size: 0.9375rem; color: var(--ink-2); }

.card__icon {
  width: 2.75rem; height: 2.75rem;
  border-radius: var(--r-md);
  background: var(--accent-tint) center / 1.375rem no-repeat;
}
.card__icon[data-icon="pin"]    { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s7-5.6 7-11a7 7 0 1 0-14 0c0 5.4 7 11 7 11Z'/%3E%3Ccircle cx='12' cy='10' r='2.6'/%3E%3C/svg%3E"); }
.card__icon[data-icon="scale"]  { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v16M5 8h14M4 8l-2.4 5.5a3 3 0 0 0 4.8 0Zm16 0-2.4 5.5a3 3 0 0 0 4.8 0Z'/%3E%3C/svg%3E"); }
.card__icon[data-icon="lock"]   { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='10' width='16' height='10' rx='2.6'/%3E%3Cpath d='M8 10V7.5a4 4 0 0 1 8 0V10'/%3E%3C/svg%3E"); }
.card__icon[data-icon="wallet"] { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='6' width='18' height='13' rx='3'/%3E%3Cpath d='M3 10h18M16.5 14.5h1.5'/%3E%3C/svg%3E"); }
.card__icon[data-icon="chat"]   { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 12.5c0 3.6-3.6 6.5-8 6.5a9.7 9.7 0 0 1-2.6-.35L5 20.5l1.2-3.2A6.4 6.4 0 0 1 4 12.5C4 8.9 7.6 6 12 6s8 2.9 8 6.5Z'/%3E%3C/svg%3E"); }
.card__icon[data-icon="spark"]  { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232F6F6B' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.5 13.9 9 19.5 11l-5.6 2L12 18.5 10.1 13 4.5 11 10.1 9Z'/%3E%3C/svg%3E"); }

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

.cta { padding: clamp(3rem, 8vh, 6rem) 0 clamp(4rem, 10vh, 7rem); }

.cta__panel {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-2xl);
  box-shadow: var(--e3);
  padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 5vw, 3.5rem);
  text-align: center;
  display: grid;
  justify-items: center;
  gap: 1.25rem;
}
.cta__panel h2 { margin-top: 0.25rem; }
.cta__panel .lede { margin-bottom: 0.5rem; }

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

.faq { padding: 0 0 clamp(4rem, 10vh, 7rem); }
.faq h2 { margin-bottom: 2rem; }

.acc { display: grid; gap: 0.625rem; }

.acc__item {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: box-shadow var(--t-base) var(--ease-out),
              opacity var(--t-slow) var(--ease-settle) var(--d, 0ms),
              transform var(--t-slow) var(--ease-settle) var(--d, 0ms);
}
.acc__item[open] { box-shadow: var(--e2); }

.acc__item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.125rem 1.375rem;
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: -0.012em;
  min-height: 3.25rem;
  -webkit-tap-highlight-color: transparent;
}
.acc__item summary::-webkit-details-marker { display: none; }

.acc__item summary i {
  position: relative;
  width: 1rem; height: 1rem; flex: none;
}
.acc__item summary i::before,
.acc__item summary i::after {
  content: "";
  position: absolute; inset: 50% 0 auto 0;
  height: 1.5px; border-radius: 2px;
  background: var(--accent);
  transition: transform var(--t-base) var(--ease-settle);
}
.acc__item summary i::after { transform: rotate(90deg); }
.acc__item[open] summary i::after { transform: rotate(0deg); }

.acc__body { padding: 0 1.375rem 1.25rem; }
.acc__body p { color: var(--ink-2); font-size: 0.9375rem; max-width: 46em; }

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

.foot {
  border-top: 1px solid var(--hairline);
  padding: clamp(2.5rem, 6vh, 4rem) 0;
}
.foot__inner { display: grid; justify-items: center; gap: 0.75rem; text-align: center; }
.brand--foot { font-size: 1.125rem; }
.foot__line { color: var(--ink-2); font-size: 0.9375rem; }
.foot__legal { color: var(--ink-3); font-size: 0.8125rem; }

/* ============================================================
   Accessibility preferences. Three independent signals, handled
   independently — reduced motion is not reduced transparency.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  /* Gentler, not absent: opacity still carries meaning, movement
     and overshoot go away. */
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 180ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { transform: none; }
  .reveal.is-in { transform: none; }
  .statement__text .w { transform: none; }
  .device { transform: none !important; }
  .scene { transform: none; }
  .scene.is-on { transform: none; }
  .swipe, .swipe.is-gone { transition: opacity 180ms linear; }
  .card:hover { --lift: 0px; }
  .grid__row i { transform: none; }
}

@media (prefers-reduced-transparency: reduce) {
  /* Frostier means solid. Drop the blur entirely rather than
     leaving a half-translucent surface that reads as neither. */
  .nav.is-stuck .nav__inner,
  .btn--quiet,
  .walk__sticky {
    background: var(--surface) !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}

@media (prefers-contrast: more) {
  :root { --ink-2: #4A453F; --ink-3: #5E574F; --hairline: #B9AFA1; }
  .card, .acc__item, .cta__panel, .field, .pcard, .swipe {
    border-width: 1.5px;
    border-color: var(--ink-3);
  }
  .btn--quiet { border-color: var(--ink); }
}

/* Print — nobody will, but a broken print sheet reads as careless */
@media print {
  .nav, .rail, .device__glow { display: none; }
  body { background: #fff; color: #000; }
  .reveal { opacity: 1; transform: none; }
}

/* ============================================================
   Custom cursor
   ============================================================
   Two layers, following the direct-manipulation rule: the dot sits
   exactly under the pointer with no lag, and the ring trails it on a
   spring. Only the trailing element is allowed to lag — the thing
   representing the pointer itself must be 1:1 or it feels broken.

   The native cursor is only hidden once JS has confirmed it can drive
   these, so a script failure leaves a usable pointer rather than an
   invisible one. Coarse pointers never see it at all.
   ============================================================ */

.cursor, .cursor-ring {
  position: fixed;
  top: 0; left: 0;
  pointer-events: none;
  z-index: 300;
  opacity: 0;
  will-change: transform;
  /* Only opacity and size transition; position is driven per-frame. */
  transition: opacity 200ms var(--ease-out);
}

.cursor {
  width: 7px; height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: var(--accent);
}

.cursor-ring {
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, transparent);
  transition: opacity 200ms var(--ease-out),
              width 260ms var(--ease-settle),
              height 260ms var(--ease-settle),
              margin 260ms var(--ease-settle),
              border-color 260ms var(--ease-out),
              background 260ms var(--ease-out);
}

/* Live only once JS has taken over *and* the pointer has actually
   moved. Showing them earlier parks a stray dot and ring in the
   top-left corner, and hides the native cursor before there is
   anything to replace it with. */
html.cursor-live .cursor,
html.cursor-live .cursor-ring { opacity: 1; }
html.cursor-live.cursor-out .cursor,
html.cursor-live.cursor-out .cursor-ring { opacity: 0; }

html.cursor-live,
html.cursor-live a,
html.cursor-live button,
html.cursor-live summary,
html.cursor-live .btn { cursor: none; }

/* Over something interactive the ring opens up and softly fills —
   the hint that the thing under it is grabbable. */
html.cursor-live.cursor-hot .cursor-ring {
  width: 58px; height: 58px;
  margin: -29px 0 0 -29px;
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
html.cursor-live.cursor-hot .cursor { opacity: 0; }

/* Press: the ring tightens toward the point of contact. */
html.cursor-live.cursor-down .cursor-ring {
  width: 26px; height: 26px;
  margin: -13px 0 0 -13px;
}

/* Text fields keep the system caret — a dot over an input is worse
   than no custom cursor at all. */
html.cursor-live input,
html.cursor-live textarea { cursor: auto; }

@media (hover: none), (pointer: coarse) {
  .cursor, .cursor-ring { display: none !important; }
  html.cursor-live, html.cursor-live a, html.cursor-live button,
  html.cursor-live summary, html.cursor-live .btn { cursor: auto; }
}

@media (prefers-reduced-motion: reduce) {
  /* Keep the cursor, drop the trailing lag and the size springs. */
  .cursor-ring { transition: opacity 200ms linear; }
}

/* ============================================================
   Walkthrough caption (mobile)
   ============================================================
   On a phone the pinned device fills most of the screen, so copy
   scrolling underneath it just gets covered. Instead the step's
   words wrap the device: eyebrow and title above it, the
   description below. The scrolling panels stay in the document as
   the scroll track and as the accessible copy, but go visually
   silent so nothing is ever hidden behind the phone.
   ============================================================ */

.walk__cap { display: none; }

@media (max-width: 61.99rem) {
  .walk__cap {
    display: block;
    text-align: center;
    max-width: 30rem;
    padding-inline: 0.5rem;
    transition: opacity 300ms var(--ease-settle), transform 300ms var(--ease-settle);
  }
  .walk__cap.is-swapping { opacity: 0; transform: translate3d(0, 0.5rem, 0); }

  .walk__cap--top { display: grid; gap: 0.4375rem; }
  .walk__cap-title {
    font-size: clamp(1.375rem, 6vw, 1.875rem);
    line-height: 1.15;
    letter-spacing: -0.022em;
  }
  .walk__cap--body {
    font-size: clamp(0.9375rem, 3.6vw, 1.0625rem);
    line-height: 1.55;
    color: var(--ink-2);
  }

  /* The panels become pure scroll track. Kept in the a11y tree —
     opacity, not display or visibility — so the copy is still
     announced in document order. */
  .panel {
    opacity: 0 !important;
    min-height: 78vh;
    padding: 0;
    pointer-events: none;
  }

  /* Nothing scrolls behind the pin any more, so it no longer needs to
     be frosted — a solid-feeling surface here would be a lie about
     what's underneath. */
  .walk__sticky {
    position: sticky;
    top: 0;
    height: 100svh;
    align-content: center;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    padding: 0;
    gap: clamp(0.75rem, 2.5vh, 1.25rem);
    border-radius: 0;
  }

  /* Sized so title + phone + body + rail all fit one screen. */
  .device--walk { width: min(13.5rem, 52vw); }
  .rail { margin-top: 0.25rem; }
}

/* Very short phones: drop the body copy rather than squeezing the
   device to the point the UI inside it stops being readable. */
@media (max-width: 61.99rem) and (max-height: 43.75rem) {
  .walk__cap--body { display: none; }
  .device--walk { width: min(12rem, 46vw); }
}
