/* ==========================================================================
   The front door. A committed dark design — deliberately single-theme, because it is a
   room rather than a tool: you arrive from an Instagram bio, look, and decide.
   The desk (app.css) stays light and theme-aware.

   The glow is treated as an actual light source, not an ambient blob: it emanates from
   the mark and from the button, the two things that are meant to be lit. A radially
   symmetric blur floating behind a hero implies illumination from nowhere.
   ========================================================================== */

:root {
  color-scheme: dark;

  --bg:        oklch(0.1450 0.0060 265);
  --bg-2:      oklch(0.1750 0.0075 265);
  --surface:   oklch(0.2050 0.0080 265);
  --surface-2: oklch(0.2400 0.0090 265);

  --ink:       oklch(0.9750 0.0030 265);
  --ink-2:     oklch(0.7550 0.0090 265);
  --ink-3:     oklch(0.5900 0.0100 265);

  --hair:      oklch(0.2950 0.0090 265);
  --hair-2:    oklch(0.3700 0.0110 265);

  /* One accent. Champagne rather than a shiny gold gradient — metal reads expensive,
     a gradient reads like a template. */
  --gold:      oklch(0.8450 0.0950 88);
  --gold-2:    oklch(0.9100 0.0700 92);
  --gold-ink:  oklch(0.1700 0.0400 70);
  --gold-dim:  oklch(0.6200 0.0700 88);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  /* A high-contrast Didone, used ONLY for the mark. Everything else stays on the system
     face — the serif is the brand, not the interface. */
  --serif: "Playfair Display", "Didot", "Bodoni MT", Georgia, "Times New Roman", serif;

  /* Front-door registers are wider than the desk's: this is a room, not a table. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 20px;
  --s5: 32px; --s6: 48px;
  --s7: 80px; --s8: 120px; --s9: 180px;

  --r-card: 16px;
  --r-ctl: 12px;

  --spring-smooth: linear(0.0000, 0.0174, 0.0610, 0.1209, 0.1897, 0.2623, 0.3351, 0.4057, 0.4724, 0.5344, 0.5912, 0.6427, 0.6889, 0.7300, 0.7664, 0.7985, 0.8266, 0.8512, 0.8725, 0.8909, 0.9069, 0.9206, 0.9325, 0.9426, 0.9513, 0.9587, 0.9650, 0.9704, 0.9750, 0.9789, 0.9822, 0.9850, 0.9873, 0.9894, 0.9910, 0.9925, 0.9937, 0.9947, 0.9955, 0.9963, 0.9969, 0.9974, 0.9978, 0.9982, 0.9985, 0.9987, 0.9989, 0.9991, 0.9992, 0.9994, 0.9995, 0.9996, 0.9996, 0.9997, 0.9997, 0.9998, 0.9998, 0.9999, 0.9999, 0.9999, 1.0000);
  --spring-smooth-ms: 760ms;
  --spring-snap: linear(0.0000, 0.0174, 0.0610, 0.1209, 0.1897, 0.2623, 0.3351, 0.4057, 0.4724, 0.5344, 0.5912, 0.6427, 0.6889, 0.7300, 0.7664, 0.7985, 0.8266, 0.8512, 0.8725, 0.8909, 0.9069, 0.9206, 0.9325, 0.9426, 0.9513, 0.9587, 0.9650, 0.9704, 0.9750, 0.9789, 0.9822, 0.9850, 0.9873, 0.9894, 0.9910, 0.9925, 0.9937, 0.9947, 0.9955, 0.9963, 0.9969, 0.9974, 0.9978, 0.9982, 0.9985, 0.9987, 0.9989, 0.9991, 0.9992, 0.9994, 0.9995, 0.9996, 0.9996, 0.9997, 0.9997, 0.9998, 0.9998, 0.9999, 0.9999, 0.9999, 1.0000);
  --spring-snap-ms: 532ms;
  --spring-bounce: linear(0.0000, 0.0320, 0.1106, 0.2145, 0.3286, 0.4425, 0.5495, 0.6456, 0.7290, 0.7991, 0.8564, 0.9021, 0.9375, 0.9641, 0.9835, 0.9970, 1.0059, 1.0113, 1.0141, 1.0151, 1.0149, 1.0138, 1.0123, 1.0106, 1.0088, 1.0072, 1.0057, 1.0044, 1.0033, 1.0024, 1.0016, 1.0011, 1.0006, 1.0003, 1.0001, 0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000);
  --spring-bounce-ms: 1040ms;
  --spring-drawer: linear(0.0000, 0.0320, 0.1106, 0.2145, 0.3286, 0.4425, 0.5495, 0.6456, 0.7290, 0.7991, 0.8564, 0.9021, 0.9375, 0.9641, 0.9835, 0.9970, 1.0059, 1.0113, 1.0141, 1.0151, 1.0149, 1.0138, 1.0123, 1.0106, 1.0088, 1.0072, 1.0057, 1.0044, 1.0033, 1.0024, 1.0016, 1.0011, 1.0006, 1.0003, 1.0001, 0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000);
  --spring-drawer-ms: 780ms;
}

/* ==========================================================================
   The application stepper.

   One question at a time, on a track that follows your finger 1:1, hands its release
   velocity to a spring, projects momentum to decide which question you land on, and
   rubber-bands at both ends. It is interruptible: grab it mid-flight and it comes with you.

   Without JavaScript the same markup is an ordinary stacked form that posts to /apply.
   ========================================================================== */

.apply { padding: var(--s8) 0 var(--s9); }
.apply__head { text-align: center; margin-bottom: var(--s6); }
.apply__head .lede { margin: var(--s4) auto 0; }

.quiz {
  background: var(--bg-2);
  border: 1px solid var(--hair);
  border-radius: var(--r-card);
  overflow: hidden;
}

/* Progress: a rail that fills. Not a percentage label — the fill IS the number. */
.quiz__rail { height: 2px; background: var(--hair); }
.quiz__fill {
  height: 100%; width: 100%;
  transform: scaleX(0); transform-origin: left center;
  background: linear-gradient(90deg, var(--gold-dim), var(--gold));
  /* scaleX rather than width — the compositor handles transform, width forces layout. */
  transition: transform var(--spring-smooth-ms) var(--spring-smooth);
  will-change: transform;
}

.quiz__meta {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s4) var(--s5) 0;
}

.quiz__viewport {
  overflow: hidden;
  touch-action: pan-y;
  /* The card breathes to the question you are on, rather than every question sitting in a
     box sized for the longest one.

     This is the one place height is animated. `contain: layout paint` walls the
     recalculation inside this element so it cannot invalidate the rest of the page, and
     the alternative — a card sized to the longest question — left short questions sitting
     in a mostly empty box. A deliberate exception, not an oversight. */
  contain: layout paint;
  /* deliberate-ignore layout-animation — contained to this element; see the note above. */
  transition: height var(--spring-smooth-ms) var(--spring-smooth);
}
.quiz__track {
  display: flex;
  align-items: flex-start;     /* each question keeps its own height */
  will-change: transform;
}
.quiz__slide {
  flex: 0 0 100%;
  min-width: 0;
  padding: var(--s5);
  display: grid; gap: var(--s4); align-content: start;
  /* Questions you are not on are dimmed rather than hidden, so the edge of the next one
     is visible while dragging — the motion tells you what it is doing. */
  opacity: 0.28;
  transition: opacity 260ms ease-out;
}
.quiz__slide[data-current="true"] { opacity: 1; }

.q label { display: block; font-size: clamp(1.25rem, 3.4vw, 1.625rem); line-height: 1.2;
  letter-spacing: -0.018em; font-weight: 600; color: var(--ink); }
.q .hint { display: block; margin-top: calc(var(--s3) * -1 + 2px);
  color: var(--ink-3); font-size: 0.9375rem; }

.q input[type="text"], .q input[type="tel"], .q input[type="number"], .q textarea {
  font: inherit; font-size: 17px;            /* under 16px iOS zooms on focus */
  width: 100%;                               /* spacing comes from the grid gap, not a margin */
  background: transparent; color: var(--ink);
  border: 0; border-bottom: 1px solid var(--hair-2);
  border-radius: 0; padding: var(--s3) 0;
  transition: border-color 200ms ease-out;
}
.q input:focus, .q textarea:focus { outline: none; border-bottom-color: var(--gold); }
/* A one-pixel underline is enough of a hint for a pointer, but a keyboard needs a real
   indicator — so :focus-visible puts the ring back rather than leaving `outline: none` to
   remove the browser's own affordance and replace it with almost nothing. */
.q input:focus-visible, .q textarea:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 5px;
  border-radius: 2px;
}
.q textarea { min-height: 92px; resize: none; line-height: 1.5; }
.q input::placeholder, .q textarea::placeholder { color: var(--ink-3); }

/* Choices are buttons, not a select — one tap, and they can be answered without a keyboard. */
.choices { display: grid; gap: var(--s2); }
.choice {
  font: inherit; text-align: left; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  min-height: 52px; padding: 0 var(--s4);
  border: 1px solid var(--hair-2); border-radius: var(--r-ctl);
  background: transparent; color: var(--ink);
  transition: transform var(--spring-snap-ms) var(--spring-snap),
              background-color 160ms ease-out, border-color 160ms ease-out;
}
.choice:hover { background: var(--surface); }
.choice:active { transform: scale(0.98); transition: transform 90ms ease-out; }
.choice[aria-pressed="true"] { border-color: var(--gold); color: var(--gold); }
.choice[aria-pressed="true"]::after { content: "✓"; font-weight: 700; }

.quiz__foot {
  display: flex; align-items: center; gap: var(--s3);
  padding: 0 var(--s5) var(--s5);
}
.quiz__err { color: oklch(0.78 0.13 27); font-size: 0.875rem; min-height: 1.2em; }

.quiz__done { padding: var(--s7) var(--s5); text-align: center; display: none; }
.quiz[data-done="true"] .quiz__done { display: block; }
.quiz[data-done="true"] .quiz__viewport,
.quiz[data-done="true"] .quiz__foot,
.quiz[data-done="true"] .quiz__meta { display: none; }

/* No JavaScript: an ordinary stacked form. Nothing here is gated on script. */
.no-js .quiz__viewport { overflow: visible; }
.no-js .quiz__track { display: block; transform: none !important; }
.no-js .quiz__slide { opacity: 1; }
.no-js .quiz__rail, .no-js .quiz__meta { display: none; }

*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* `clip` rather than `hidden`: it stops sideways scrolling without turning the element
     into a scroll container, so position:sticky and scroll-into-view keep working. The
     hero glow is deliberately wider than the viewport and must not create a scrollbar. */
  overflow-x: clip;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

/* --- type: tracking and leading move with size, never one value ------------ */
h1, h2, h3 { margin: 0; text-wrap: balance; font-optical-sizing: auto; }
h1 {
  font-size: clamp(2.5rem, 7.2vw, 4.75rem);
  line-height: 1.02;
  letter-spacing: -0.032em;
  font-weight: 600;
}
h2 {
  font-size: clamp(1.875rem, 4.2vw, 2.875rem);
  line-height: 1.08;
  letter-spacing: -0.024em;
  font-weight: 600;
}
h3 { font-size: 1.125rem; line-height: 1.3; letter-spacing: -0.011em; font-weight: 600; }
p  { margin: 0; }
.lede { font-size: clamp(1.0625rem, 1.9vw, 1.1875rem); line-height: 1.55;
        letter-spacing: -0.004em; color: var(--ink-2); max-width: 54ch; }
.small { font-size: 0.875rem; letter-spacing: 0.003em; color: var(--ink-3); line-height: 1.5; }
.caps  { font-size: 0.6875rem; letter-spacing: 0.16em; text-transform: uppercase;
         color: var(--ink-3); font-weight: 600; }
.tnum { font-variant-numeric: tabular-nums; }

::selection { background: color-mix(in oklab, var(--gold) 30%, transparent); color: var(--ink); }
:root { caret-color: var(--gold); }
::-webkit-scrollbar { width: 11px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--hair-2); border-radius: 999px;
  border: 3px solid var(--bg); }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: var(--r-ctl); }

/* --- layout --------------------------------------------------------------- */
/* deliberate-ignore round-stat — 100% is a layout constraint, not a displayed figure. */
.wrap { width: min(1060px, 100%); margin: 0 auto; padding: 0 var(--s4); }
/* deliberate-ignore round-stat — as above. */
.narrow { width: min(720px, 100%); margin: 0 auto; }
section { position: relative; }
.rule { height: 1px; background: linear-gradient(90deg,
  transparent, var(--hair) 18%, var(--hair) 82%, transparent); border: 0; margin: 0; }

/* --- the light source ------------------------------------------------------
   Anchored to the mark and bleeding past its container, so it reads as light coming
   off the thing rather than a blurred circle parked behind the text. */
.hero { padding: var(--s8) 0 var(--s7); text-align: center; isolation: isolate; }
.hero::before {
  content: "";
  position: absolute;
  left: 50%; top: -8%;
  width: min(1100px, 145vw); aspect-ratio: 1;
  /* The light comes up before anything else does, then holds. Depth on scroll is applied
     as a second translate through --glow-y, set from a rAF scroll handler. */
  transform: translateX(-50%) translateY(var(--glow-y, 0px)) scale(var(--glow-s, 0.82));
  opacity: var(--glow-o, 0);
  transition: opacity 1100ms ease-out, transform 1400ms var(--spring-smooth);
  will-change: transform, opacity;
  background: radial-gradient(circle closest-side,
    color-mix(in oklab, var(--gold) 13%, transparent) 0%,
    color-mix(in oklab, var(--gold) 5%, transparent) 38%,
    transparent 68%);
  pointer-events: none;
  z-index: -1;
}

/* --- the mark ------------------------------------------------------------- */
.mark { display: inline-block; margin-bottom: var(--s7); }
.mark__badge {
  width: 42px; height: 42px; border-radius: 11px;
  display: grid; place-items: center;
  background: linear-gradient(160deg, var(--gold-2), var(--gold));
  color: var(--gold-ink); font-weight: 700; font-size: 15px; letter-spacing: -0.02em;
  /* The badge is a lit object, so it may cast light. Everything else casts none. */
  box-shadow: 0 0 28px color-mix(in oklab, var(--gold) 34%, transparent);
}
.mark__name { text-align: left; line-height: 1.15; }
.mark__name b { display: block; font-weight: 650; font-size: 1.0625rem; letter-spacing: -0.012em; }
.mark__name span { display: block; font-size: 0.625rem; letter-spacing: 0.19em;
  text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin-top: 2px; }

.hero h1 { margin: 0 auto; max-width: 15ch; }
.hero h1 em { font-style: normal; color: var(--gold); }
.hero .lede { margin: var(--s5) auto 0; }
.hero__meta { margin-top: var(--s5); }
.hero__meta span { color: var(--ink-3); font-size: 0.8125rem; letter-spacing: 0.02em; }

/* --- buttons -------------------------------------------------------------- */
.btn {
  font: inherit; font-weight: 600; letter-spacing: -0.005em;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 52px; padding: 0 var(--s5);
  border-radius: var(--r-ctl); border: 1px solid var(--hair-2);
  background: var(--surface); color: var(--ink);
  cursor: pointer; text-decoration: none;
  /* Spring on the release; the press itself stays linear or it feels mushy. */
  transition: transform var(--spring-snap-ms, 520ms) var(--spring-snap, ease-out),
              background-color 160ms ease-out, border-color 160ms ease-out,
              box-shadow 220ms ease-out;
}
.btn:active:not(:disabled) { transform: scale(0.965); transition: transform 90ms ease-out; }
.btn:hover:not(:disabled) { background: var(--surface-2); }

.btn--gold {
  background: linear-gradient(160deg, var(--gold-2), var(--gold));
  color: var(--gold-ink); border-color: transparent;
  box-shadow: 0 0 0 color-mix(in oklab, var(--gold) 0%, transparent);
}
/* The button is a light source when you reach for it — the glow is the affordance. */
.btn--gold:hover { box-shadow: 0 0 34px color-mix(in oklab, var(--gold) 40%, transparent); }
.btn--gold:active { box-shadow: 0 0 18px color-mix(in oklab, var(--gold) 30%, transparent); }
.btn--ghost { background: transparent; }

/* --- sections ------------------------------------------------------------- */
.band { padding: var(--s8) 0; }
.band--tight { padding: var(--s7) 0; }
.band__head { max-width: 34ch; margin-bottom: var(--s6); }
.band__head .caps { display: block; margin-bottom: var(--s3); }
.band__head p { margin-top: var(--s4); }

.cards { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); }
/* Four cards in a three-up grid leaves an orphan on the second row. */
@media (min-width: 760px) { .cards--2up { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.card {
  background: var(--bg-2);
  border: 1px solid var(--hair);
  border-radius: var(--r-card);
  padding: var(--s5);
  display: grid; gap: var(--s3); align-content: start;
}
.card p { color: var(--ink-2); font-size: 0.9375rem; }

/* The path is a genuine sequence, so it is numbered. Nothing else on the page is. */
.steps { display: grid; gap: 0; }
.step { display: grid; grid-template-columns: auto 1fr; gap: var(--s4);
        padding: var(--s5) 0; border-top: 1px solid var(--hair); align-items: start; }
.step:first-child { border-top: 0; }
.step__n { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid var(--hair-2); color: var(--gold); font-size: 0.75rem; font-weight: 700;
  font-variant-numeric: tabular-nums; }
.step p { color: var(--ink-2); margin-top: var(--s2); font-size: 0.9375rem; }

.qa { display: grid; gap: 0; }
.qa__item { border-top: 1px solid var(--hair); padding: var(--s5) 0; }
.qa__item:first-child { border-top: 0; }
.qa__item h3 { color: var(--ink); }
.qa__item p { color: var(--ink-2); margin-top: var(--s3); max-width: 62ch; font-size: 0.9375rem; }

footer { padding: var(--s7) 0 var(--s7); border-top: 1px solid var(--hair); }
footer p { color: var(--ink-3); font-size: 0.8125rem; max-width: 68ch; }
footer p + p { margin-top: var(--s3); }


/* Hidden from sight, present for a form post and for screen readers, and — unlike
   left:-9999px — it occupies no space and cannot widen the page. */
.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}


/* ==========================================================================
   Hero choreography.

   One sequence, on arrival, once. Each element travels a slightly different distance so
   the group reads as depth rather than as a block sliding up together — the mark is
   nearest and moves least, the fine print is furthest and moves most.
   ========================================================================== */
.js-motion .hero [data-enter] {
  opacity: 0;
  transform: translate3d(0, var(--rise, 20px), 0) scale(var(--from-scale, 1));
  will-change: opacity, transform;
}
.js-motion .hero [data-enter].is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity 620ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform var(--spring-smooth-ms) var(--spring-smooth);
  transition-delay: var(--enter-delay, 0ms);
  will-change: auto;
}
.hero .mark        { --rise: 12px; --from-scale: 0.94; }
.hero h1           { --rise: 26px; }
.hero .lede        { --rise: 32px; }
.hero .hero__cta   { --rise: 36px; }
.hero .hero__meta  { --rise: 40px; }

/* The hero recedes as you leave it rather than simply scrolling away — parallax with a
   purpose, driven by --hero-p (0 at rest, 1 when the hero is a screen behind you). */
.hero__inner {
  transform: translate3d(0, calc(var(--hero-p, 0) * -34px), 0);
  opacity: calc(1 - var(--hero-p, 0) * 0.55);
  will-change: transform, opacity;
}

/* A quiet cue that there is more, which removes itself the moment you act on it. */
.scrollcue {
  display: grid; justify-items: center; gap: 6px;
  margin-top: var(--s7);
  color: var(--ink-3);
  opacity: calc(1 - var(--hero-p, 0) * 3);
  transition: opacity 300ms ease-out;
  pointer-events: none;
}
.scrollcue i {
  display: block; width: 1px; height: 26px;
  background: linear-gradient(180deg, transparent, var(--hair-2));
  animation: cue 2.4s ease-in-out infinite;
}
@keyframes cue {
  0%, 100% { transform: scaleY(0.45); transform-origin: top; opacity: 0.5; }
  50%      { transform: scaleY(1);    transform-origin: top; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .hero::before { opacity: 1 !important; transform: translateX(-50%) !important;
                  transition: none !important; }
  .js-motion .hero [data-enter] { transform: none !important; }
  .js-motion .hero [data-enter].is-in { transform: none !important;
    transition: opacity 220ms ease-out !important; transition-delay: 0ms !important; }
  .hero__inner { transform: none !important; opacity: 1 !important; }
  .scrollcue i { animation: none; }
}


/* ==========================================================================
   The mark.

   Built from live type rather than an image: it stays crisp at any size, recolours for the
   light desk, and weighs a fraction of a PNG. One word — WESTBERRY.
   ========================================================================== */
.logo {
  display: inline-grid;
  justify-items: center;
  gap: 0;
  font-family: var(--serif);
  line-height: 1;
  --logo: 1;                     /* scale knob: everything below is in em of this */
  font-size: calc(var(--logo) * 1rem);
}

/* --- monogram: gold W, white B, a hairline cutting between them -----------
   Proportions measured off the supplied mark: the B starts at 52% of the lockup width and
   11% down, and the diagonal runs from 86%/-5% to roughly 37%/98% — a 36 degree lean. */
.logo__mono {
  position: relative;
  display: block;
  height: 2.85em;
  width: 4.2em;
  margin-bottom: 0.5em;
}
.logo__mono span {
  position: absolute;
  font-weight: 500;
  line-height: 1;
  /* deliberate-ignore tracking-crushed — the overlap IS the monogram; these two glyphs
     are a mark, not running text. */
  letter-spacing: -0.05em;
}
.logo__w { left: 0; top: 0; font-size: 3.5em; color: var(--gold); z-index: 1; }
/* The B sits above the rule, so the diagonal reads as passing behind it. */
.logo__b { left: 52%; top: 11%; font-size: 3.1em; color: var(--ink); z-index: 3; }
.logo__cut {
  position: absolute;
  left: 86%; top: -5%;
  width: 1.6px; height: 127%;
  background: var(--gold);
  transform: rotate(36deg);
  transform-origin: top center;
  z-index: 2;
}

/* --- wordmark ------------------------------------------------------------- */
.logo__word {
  font-size: 1.32em;
  font-weight: 500;
  letter-spacing: 0.30em;
  /* Tracked caps always need the last letter's trailing space removed, or the whole
     wordmark sits off-centre by half a letter. */
  text-indent: 0.30em;
  color: var(--ink);
  white-space: nowrap;
}

.logo__rule {
  width: 3.4em; height: 1px;
  background: var(--gold);
  margin: 0.62em 0 0.58em;
  opacity: 0.85;
}

.logo__sub {
  font-size: 0.66em;
  font-weight: 500;
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  color: var(--gold);
  white-space: nowrap;
}

/* A compact lockup for tight places — monogram beside the name, no sub-line. */
.logo--inline {
  grid-auto-flow: column;
  align-items: center;
  justify-items: start;
  gap: 0.55em;
}
.logo--inline .logo__mono { height: 1.55em; width: 2.3em; margin: 0; }
.logo--inline .logo__w { font-size: 1.9em; }
.logo--inline .logo__b { font-size: 1.68em; left: 52%; top: 11%; }
.logo--inline .logo__cut { width: 1.2px; }
.logo--inline .logo__word { font-size: 0.95em; letter-spacing: 0.2em; text-indent: 0.2em; }
.logo--inline .logo__rule, .logo--inline .logo__sub { display: none; }

@media (max-width: 480px) { .logo { --logo: 0.86; } }


/* On a phone a text link is still something a finger has to hit. Width-keyed, because
   `pointer: coarse` does not apply under emulation and misses touchscreen laptops. */
@media (max-width: 760px) {
  /* Every text link on a public page, not just the ones inside .doc — the thanks page uses
     a different wrapper and was missed by a narrower selector. */
  footer a, .doc a, .wrap p a, .done a, .small a {
    display: inline-flex; align-items: center; min-height: 44px;
  }
}


/* ==========================================================================
   Apple pass — the groups the page was not yet hitting.
   ========================================================================== */

/* §12 MATERIALS. A translucent bar that content scrolls UNDER, rather than an opaque strip
   that eats a band of the screen. It materialises — blur and scale together — instead of
   fading, so it reads as a surface arriving rather than an element appearing. It also keeps
   the one action on the page permanently within reach. */
.topbar {
  position: fixed; inset: 0 0 auto 0; z-index: 40;
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s3) var(--s4);
  background: color-mix(in oklab, var(--bg) 62%, transparent);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  /* A bright top edge is light catching the material. */
  border-bottom: 1px solid color-mix(in oklab, var(--hair) 70%, transparent);
  opacity: 0; transform: translate3d(0, -100%, 0) scale(0.98);
  transition:
    opacity 260ms ease-out,
    transform var(--spring-drawer-ms) var(--spring-drawer),
    backdrop-filter 300ms ease-out;
  pointer-events: none;
}
.topbar[data-on="true"] { opacity: 1; transform: none; pointer-events: auto; }
.topbar .logo { --logo: 0.78; }
.topbar__cta { margin-left: auto; min-height: 40px; padding: 0 var(--s4); font-size: 0.9375rem; }
@media (prefers-reduced-motion: reduce) {
  .topbar { transform: none !important; transition: opacity 160ms ease-out !important; }
}
@media (prefers-reduced-transparency: reduce) {
  .topbar { background: var(--bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* §11 + §7. Sections MATERIALISE rather than slide: a touch of scale and blur alongside the
   travel, so the arrival reads as depth. Both are compositor properties. */
.js-motion [data-reveal] { transform: translate3d(0, 24px, 0) scale(0.985); filter: blur(6px); }
.js-motion [data-reveal].is-in {
  transform: none; filter: blur(0);
  transition:
    opacity 500ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform var(--spring-smooth-ms) var(--spring-smooth),
    filter 420ms ease-out;
  transition-delay: var(--enter-delay, 0ms);
}
@media (prefers-reduced-motion: reduce) {
  .js-motion [data-reveal] { filter: none !important; transform: none !important; }
  .js-motion [data-reveal].is-in { filter: none !important; }
}

/* §8 HINT IN THE DIRECTION OF THE GESTURE. A sliver of the next question stays on screen, so
   the track visibly has somewhere to go. Without it the card looks like a static panel and
   nobody discovers the swipe. */
.quiz__slide { flex: 0 0 calc(100% - 30px); }
