/* The Wedding Method — application survey skin.
   Tokens copied from tenants/weddingmethod/customer.config.json in nexus so
   this page and the admin app stay visibly the same product. Values are
   inlined on purpose: no build step, no Tailwind, nothing to install.

   The composition is a frame, not a card: a full-height left rail carrying the
   brand, the ad's promise and the progress, and a stage holding one question at
   editorial size. The first cut of this page put a small card in the middle of
   an empty black screen with 14px type — every brand colour was correct and it
   still read like an admin panel, because nothing had any scale.

   Deliberate deviation from the plan: the ad's landing page fills its whole nav
   bar with orange, and a solid orange band above a dark page is exactly what
   made the first cut look cheap. The orange is spent instead on the bloom, the
   selected answer, the counter and the primary button — louder where it counts,
   quieter where it was only decoration. */

:root {
  --c-background: #0a0a0a;
  --c-surface: #14110f;
  --c-text: #f3f3f3;
  --c-text-muted: #9a948f;
  --c-primary: #e44209;
  --c-primary-dark: #b53507;
  --c-primary-light: #f0662e;
  --c-border: #211d1a;
  --c-on-primary: #f3f3f3;
  --c-success: #37c26b;
  --c-danger: #d64550;

  --font-body: 'Jost', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --rail: 23rem;
  --gutter: 1.5rem;
}

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

html {
  -webkit-text-size-adjust: 100%;
  /* The whole page is sized in rem, so the base is the one lever that scales
     type and the space around it together. 17px, because Jost runs small for
     its point size. */
  font-size: 106.25%;
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--c-background);
  color: var(--c-text);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

[hidden] {
  display: none !important;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── The ground ────────────────────────────────────────────────────────
   Everything filmic about the page, in one fixed layer behind the content.
   Pointer-events off throughout: none of it is interactive. */
.ground {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* A single warm bloom behind the rail, as if one practical light were just
   off-frame. Kept small and dim, and kept off the answers: the first version
   was 60vw at 26% and hazed the whole viewport brown, which cost more contrast
   on the question than the atmosphere was worth. */
.ground__bloom {
  position: absolute;
  top: -22vh;
  left: -14vw;
  width: 34vw;
  min-width: 20rem;
  height: 58vh;
  background: radial-gradient(
    circle at 40% 40%,
    color-mix(in srgb, var(--c-primary) 17%, transparent),
    transparent 60%
  );
  filter: blur(40px);
}

/* Deepens the bottom of the frame so the page has a direction of light rather
   than one flat field of near-black. */
.ground__falloff {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 35%, rgb(0 0 0 / 0.55) 100%);
}

/* Grain, at the opacity where it reads as film stock rather than as dirt. */
.ground__grain {
  position: absolute;
  inset: -50%;
  opacity: 0.035;
  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.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Viewfinder corner marks — the framing motif from the app's splash SVG, held
   still. Inset far enough not to fight the content on a phone. */
.ground__mark {
  position: absolute;
  width: 1.25rem;
  height: 1.25rem;
  border: 0 solid color-mix(in srgb, var(--c-primary) 55%, transparent);
}

.ground__mark--tl {
  top: 0.875rem;
  left: 0.875rem;
  border-top-width: 1px;
  border-left-width: 1px;
}

.ground__mark--tr {
  top: 0.875rem;
  right: 0.875rem;
  border-top-width: 1px;
  border-right-width: 1px;
}

.ground__mark--bl {
  bottom: 0.875rem;
  left: 0.875rem;
  border-bottom-width: 1px;
  border-left-width: 1px;
}

.ground__mark--br {
  bottom: 0.875rem;
  right: 0.875rem;
  border-bottom-width: 1px;
  border-right-width: 1px;
}

/* ── Shell ─────────────────────────────────────────────────────────── */
.shell {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

/* ── Rail ──────────────────────────────────────────────────────────────
   A header on phones, a full-height column on desktop. On phones the order is
   brand → progress → promise, so the applicant sees where they are before they
   read anything; `order` does that without moving the DOM. */
.rail {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 1.75rem var(--gutter) 0;
}

.rail__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  order: 0;
}

.rail__pitch {
  order: 2;
}

.rail__foot {
  order: 1;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-width: 0;
  color: var(--c-text);
  text-decoration: none;
}

.brand__logo {
  width: 1.75rem;
  height: 1.75rem;
  flex-shrink: 0;
  object-fit: contain;
}

/* Stands in for the logo's mass so the wordmark is never left floating. */
.brand__tick {
  width: 0.5rem;
  height: 0.5rem;
  flex-shrink: 0;
  background-color: var(--c-primary);
}

.brand__word {
  overflow: hidden;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lang-toggle {
  flex-shrink: 0;
  padding: 0.375rem 0.6875rem;
  border: 1px solid var(--c-border);
  border-radius: 0.375rem;
  background-color: transparent;
  color: var(--c-text-muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.lang-toggle:hover {
  border-color: color-mix(in srgb, var(--c-primary) 60%, transparent);
  color: var(--c-text);
}

.eyebrow {
  margin: 0;
  color: var(--c-primary-light);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* The ad's promise. Big enough to be the reason the page exists. */
.pitch {
  margin: 0.75rem 0 0;
  font-size: clamp(1.4375rem, 4.8vw, 1.875rem);
  font-weight: 300;
  line-height: 1.22;
  letter-spacing: -0.015em;
  color: var(--c-text);
  text-wrap: pretty;
}

/* ── Counter and progress ────────────────────────────────────────────── */
.counter {
  display: flex;
  align-items: baseline;
  gap: 0.25rem;
  margin: 0 0 0.625rem;
  font-family: var(--font-mono);
  line-height: 1;
}

.counter__now {
  color: var(--c-primary);
  font-size: 2rem;
  font-weight: 500;
  letter-spacing: -0.02em;
}

.counter__total {
  color: color-mix(in srgb, var(--c-text-muted) 70%, transparent);
  font-size: 0.9375rem;
}

/* Seven ticks, not a loading bar: the applicant can see it is seven questions
   before answering the first one. */
.progress {
  display: flex;
  gap: 0.25rem;
}

.progress__tick {
  flex: 1;
  height: 2px;
  background-color: var(--c-border);
  transition: background-color 0.3s var(--ease-out);
}

.progress__tick[data-done] {
  background-color: color-mix(in srgb, var(--c-primary) 45%, transparent);
}

.progress__tick[data-current] {
  background-color: var(--c-primary);
  box-shadow: 0 0 8px color-mix(in srgb, var(--c-primary) 60%, transparent);
}

.notice {
  margin: 1rem 0 0;
  padding: 0.5rem 0.75rem;
  border-left: 2px solid color-mix(in srgb, var(--c-primary) 60%, transparent);
  background-color: color-mix(in srgb, var(--c-primary) 8%, transparent);
  color: var(--c-primary-light);
  font-size: 0.8125rem;
  line-height: 1.45;
}

.notice--danger {
  border-left-color: var(--c-danger);
  background-color: color-mix(in srgb, var(--c-danger) 8%, transparent);
  color: var(--c-danger);
}

/* ── Stage ─────────────────────────────────────────────────────────────
   Holds one question, vertically centred so a two-line question and a
   six-option one both sit in the same optical place. */
.stage {
  display: flex;
  flex: 1;
  min-width: 0;
  padding: 2rem var(--gutter) 7.5rem;
}

.form {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 40rem;
}

/* Toggling [hidden] restarts this, so every step arrives the same way with no
   JS involved.

   No `both` fill-mode, deliberately. A filling animation keeps applying its
   keyframes forever, and those keyframes set `transform`, which makes the step
   a permanent stacking context — which trapped the country picker's popover
   inside it, so the fixed action bar (z-index 30) painted over an open panel
   (z-index 50). Without the fill the animation stops applying once it ends and
   the step stops being a stacking context, so the panel sits above the bar
   where it belongs. */
.step {
  animation: step-in 0.34s var(--ease-out);
}

@keyframes step-in {
  from {
    opacity: 0;
    transform: translateY(0.625rem);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.q {
  margin: 0 0 1.75rem;
  font-size: clamp(1.625rem, 6.4vw, 2.375rem);
  font-weight: 300;
  line-height: 1.18;
  letter-spacing: -0.02em;
  color: var(--c-text);
  text-wrap: pretty;
}

/* Steps 5 and 6 are paragraphs quoted from the ad, not headlines — at display
   size they would fill the screen and read as shouting. */
.q--sm {
  font-size: clamp(1.25rem, 3.9vw, 1.5rem);
  font-weight: 400;
  line-height: 1.42;
  letter-spacing: -0.005em;
  color: color-mix(in srgb, var(--c-text) 88%, var(--c-text-muted));
}

.hint {
  margin: 0.75rem 0 0;
  color: color-mix(in srgb, var(--c-text-muted) 85%, transparent);
  font-size: 0.875rem;
}

.grid {
  display: grid;
  gap: 1.5rem;
}

.field--wide {
  grid-column: 1 / -1;
}

.field__label {
  display: block;
  margin-bottom: 0.375rem;
  color: var(--c-text-muted);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.field__req {
  margin-left: 0.25rem;
  color: var(--c-danger);
  transition: color 0.2s ease;
}

.field[data-satisfied] .field__req {
  color: color-mix(in srgb, var(--c-success) 80%, transparent);
}

.field__error {
  display: block;
  margin-top: 0.5rem;
  color: var(--c-danger);
  font-size: 0.875rem;
}

.field__error:empty {
  display: none;
}

/* ── Choices ───────────────────────────────────────────────────────────
   The radio groups and the acknowledgement checkbox. Buttons rather than
   native inputs — see createChoices() in form.js for why.

   The mono key chip is the selected-state indicator and doubles as the
   keyboard shortcut it names: pressing A–D picks that answer. */
.choices {
  display: grid;
  gap: 0.625rem;
}

.choice {
  display: flex;
  align-items: center;
  gap: 0.9375rem;
  width: 100%;
  padding: 1rem 1.125rem;
  border: 1px solid var(--c-border);
  border-radius: 0.75rem;
  background-color: color-mix(in srgb, var(--c-surface) 70%, transparent);
  color: var(--c-text);
  font-family: inherit;
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.18s ease, background-color 0.18s ease,
    transform 0.18s var(--ease-out);
}

.choice--multiline {
  align-items: flex-start;
}

.choice:hover {
  border-color: color-mix(in srgb, var(--c-primary) 50%, transparent);
  background-color: color-mix(in srgb, var(--c-surface) 100%, transparent);
  transform: translateX(3px);
}

.choice:focus-visible {
  outline: none;
  border-color: var(--c-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-primary) 22%, transparent);
}

.choice[aria-checked='true'] {
  border-color: var(--c-primary);
  background-color: color-mix(in srgb, var(--c-primary) 10%, var(--c-surface));
}

.choice__key {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 1.875rem;
  height: 1.875rem;
  border: 1px solid var(--c-border);
  border-radius: 0.375rem;
  color: var(--c-text-muted);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.choice--multiline .choice__key {
  margin-top: 0.0625rem;
}

.choice:hover .choice__key {
  border-color: color-mix(in srgb, var(--c-primary) 50%, transparent);
  color: var(--c-text);
}

.choice[aria-checked='true'] .choice__key {
  border-color: var(--c-primary);
  background-color: var(--c-primary);
  color: var(--c-on-primary);
}

/* The acknowledgement is a checkbox, so it gets a mark rather than a key. */
.choice__mark {
  position: relative;
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.125rem;
  border: 1px solid color-mix(in srgb, var(--c-text-muted) 65%, transparent);
  border-radius: 0.3125rem;
  transition: border-color 0.18s ease, background-color 0.18s ease;
}

.choice[aria-checked='true'] .choice__mark {
  border-color: var(--c-primary);
  background-color: var(--c-primary);
}

.choice[aria-checked='true'] .choice__mark::after {
  content: '';
  position: absolute;
  top: 0.1875rem;
  left: 0.3125rem;
  width: 0.3125rem;
  height: 0.5625rem;
  border: solid var(--c-on-primary);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}

.choice__label {
  min-width: 0;
}

/* ── Controls ──────────────────────────────────────────────────────────
   One question per screen earns a real answer line rather than a boxed input:
   an underline at display size reads as "write here", a 14px box reads as a
   settings panel. */
.control {
  width: 100%;
  border: 1px solid var(--c-border);
  border-radius: 0.5rem;
  padding: 0.625rem 0.8125rem;
  background-color: var(--c-background);
  color: var(--c-text);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 400;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.control::placeholder {
  color: color-mix(in srgb, var(--c-text-muted) 55%, transparent);
}

.control--line {
  border: 0;
  border-bottom: 1px solid var(--c-border);
  border-radius: 0;
  padding: 0.5rem 0.125rem;
  background-color: transparent;
  font-size: 1.375rem;
  transition: border-color 0.2s ease;
}

.control--mono {
  font-family: var(--font-mono);
  font-size: 1.125rem;
  letter-spacing: 0.01em;
}

.control--line:hover {
  border-bottom-color: color-mix(in srgb, var(--c-primary) 45%, transparent);
}

.control--line:focus {
  outline: none;
  border-bottom-color: var(--c-primary);
  box-shadow: none;
}

.control:focus:not(.control--line) {
  outline: none;
  border-color: color-mix(in srgb, var(--c-primary) 60%, transparent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-primary) 20%, transparent);
}

/* A required field still unanswered — a tinted edge, not a message. Focus
   keeps its own colour: being in the field is not the moment to be told it is
   empty. */
.field:not([data-satisfied]) .control--line {
  border-bottom-color: color-mix(in srgb, var(--c-danger) 32%, transparent);
}

.field:not([data-satisfied]) .control--line:focus,
.field:not([data-satisfied]) .phone:focus-within {
  border-bottom-color: var(--c-primary);
}

/* ── Phone ─────────────────────────────────────────────────────────────
   The country trigger and the number share one underline, so the pair reads as
   a single field. */
.phone {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border-bottom: 1px solid var(--c-border);
  transition: border-color 0.2s ease;
}

.phone:hover {
  border-bottom-color: color-mix(in srgb, var(--c-primary) 45%, transparent);
}

.field:not([data-satisfied]) .phone {
  border-bottom-color: color-mix(in srgb, var(--c-danger) 32%, transparent);
}

.phone__country {
  flex-shrink: 0;
}

.phone__number {
  flex: 1;
  min-width: 0;
  border: 0;
  border-radius: 0;
  padding: 0.5rem 0.125rem;
  background-color: transparent;
}

.phone__number:focus {
  outline: none;
  box-shadow: none;
}

/* ── Country select ────────────────────────────────────────────────────
   A button plus a panel, not a native <select>: the answer lives in a hidden
   input, so what Zoho receives is unchanged. Copied from the Eternus form. */
.select {
  position: relative;
}

.select__trigger {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 0.5rem 0.5rem 0.125rem;
  border: 0;
  background: none;
  color: var(--c-text);
  font-family: var(--font-mono);
  font-size: 1.125rem;
  cursor: pointer;
}

.select__trigger:focus-visible {
  outline: none;
  color: var(--c-primary-light);
}

.select__value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.select__value[data-placeholder] {
  color: color-mix(in srgb, var(--c-text-muted) 60%, transparent);
}

.select__chevron {
  width: 0.75rem;
  height: 0.75rem;
  flex-shrink: 0;
  background-color: var(--c-text-muted);
  transition: transform 0.2s ease;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
    center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
    center / contain no-repeat;
}

.select__trigger[aria-expanded='true'] .select__chevron {
  transform: rotate(180deg);
}

.panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  border: 1px solid var(--c-border);
  border-radius: 0.75rem;
  background-color: color-mix(in srgb, var(--c-surface) 97%, transparent);
  box-shadow: 0 20px 45px rgb(0 0 0 / 0.6);
  backdrop-filter: blur(16px);
  transform-origin: top left;
  animation: scale-in 0.18s ease-out both;
}

/* Flipped up when the field sits too close to the bottom of the viewport. */
.panel--up {
  top: auto;
  bottom: calc(100% + 6px);
  transform-origin: bottom left;
}

@keyframes scale-in {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* While a popover is open its step is lifted above the fixed action bar.

   This is not belt-and-braces, it is the actual fix. The panel lives inside
   .step, and .step is a stacking context for as long as its entry animation is
   applying a transform — so the panel's z-index:50 is confined inside .step and
   cannot beat the bar's z-index:30 no matter how high it goes. Dropping the
   `both` fill-mode above stops that context from lasting forever, but it still
   exists during the 0.34s animation, which is reachable: tab straight into the
   country picker as a step opens. Lifting the step itself is timing-independent.

   Only while open, because the bar must stay above ordinary step content that
   scrolls under it on a phone. */
.step[data-panel-open] {
  position: relative;
  z-index: 40;
}

.select__panel {
  min-width: 100%;
  /* form.js asks for a 300px minimum so country names are not truncated; on a
     narrow phone that is wider than the screen, and the panel is anchored to
     the trigger's left edge, so it would run off the right. This caps it to the
     viewport minus the gutters and wins over the inline min-width. */
  max-width: calc(100vw - 2 * var(--gutter));
  padding: 0.25rem 0;
}

.select__search {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 0.5rem;
  border-bottom: 1px solid var(--c-border);
  background-color: color-mix(in srgb, var(--c-surface) 97%, transparent);
  backdrop-filter: blur(16px);
}

.select__search .control {
  font-size: 0.9375rem;
  padding-top: 0.4375rem;
  padding-bottom: 0.4375rem;
}

.select__list {
  max-height: 15rem;
  overflow-y: auto;
  margin: 0;
  padding: 0;
  list-style: none;
}

.select__option {
  padding: 0.5rem 0.75rem;
  color: var(--c-text);
  font-size: 0.9375rem;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.select__option[data-active] {
  background-color: color-mix(in srgb, var(--c-primary) 14%, transparent);
}

.select__option[aria-selected='true'] {
  color: var(--c-primary-light);
  font-weight: 500;
}

.select__empty {
  padding: 0.5rem 0.75rem;
  color: var(--c-text-muted);
  font-size: 0.9375rem;
}

/* Honeypot — in the DOM, never on screen. */
.hp {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Actions ───────────────────────────────────────────────────────────
   A fixed bar on phones — the thumb is at the bottom of the screen, not
   wherever the answers happen to end. */
.actions {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.875rem var(--gutter) calc(0.875rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--c-border);
  background-color: color-mix(in srgb, var(--c-background) 86%, transparent);
  backdrop-filter: blur(12px);
}

.actions__go {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  margin-left: auto;
}

/* Names the shortcut the keyboard already supports; hidden where there is no
   keyboard to name it for. */
.actions__hint {
  display: none;
  color: color-mix(in srgb, var(--c-text-muted) 75%, transparent);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.btn {
  padding: 0.8125rem 1.5rem;
  border: 1px solid transparent;
  border-radius: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease,
    transform 0.15s ease;
}

.btn--ghost {
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  background-color: transparent;
  color: var(--c-text-muted);
}

.btn--ghost:hover {
  color: var(--c-text);
}

/* Filled orange takes #F3F3F3, never pure white. */
.btn--primary {
  position: relative;
  overflow: hidden;
  background-color: var(--c-primary);
  color: var(--c-on-primary);
  box-shadow: 0 1px 0 rgb(255 255 255 / 0.14) inset,
    0 6px 20px -6px color-mix(in srgb, var(--c-primary) 70%, transparent);
}

.btn--primary:hover:not(:disabled) {
  background-color: var(--c-primary-light);
}

.btn--primary:active:not(:disabled) {
  transform: scale(0.98);
  background-color: var(--c-primary-dark);
}

/* A light sweeps across the button once on hover-enter. */
.btn--primary::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 35%;
  background: linear-gradient(100deg, transparent, rgb(255 255 255 / 0.28), transparent);
  transform: translateX(-250%) skewX(-18deg);
  pointer-events: none;
}

.btn--primary:hover:not(:disabled)::before {
  animation: btn-shine 0.75s var(--ease-out);
}

@keyframes btn-shine {
  to {
    transform: translateX(400%) skewX(-18deg);
  }
}

.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-primary) 35%, transparent);
}

.btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* ── Thank-you ─────────────────────────────────────────────────────── */
.thanks {
  max-width: 34rem;
}

.thanks__title {
  margin: 0.75rem 0 0;
  font-size: clamp(2rem, 7.2vw, 3rem);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.025em;
}

.thanks__body {
  margin: 1.125rem 0 0;
  color: color-mix(in srgb, var(--c-text-muted) 88%, var(--c-text));
  font-size: 1.125rem;
  line-height: 1.6;
  text-wrap: pretty;
}

/* ── Desktop ───────────────────────────────────────────────────────────
   The rail becomes a column and the question is centred beside it. */
@media (min-width: 64rem) {
  :root {
    --gutter: 3.5rem;
  }

  .shell {
    flex-direction: row;
    align-items: stretch;
  }

  .rail {
    position: sticky;
    top: 0;
    flex-shrink: 0;
    width: var(--rail);
    height: 100vh;
    height: 100dvh;
    padding: 3rem 2.5rem 3rem var(--gutter);
    border-right: 1px solid var(--c-border);
  }

  /* On a column there is room to keep the ad's promise in view the whole way
     through, so the phone-only reordering is undone. */
  .rail__pitch {
    order: 1;
    margin-top: 2.5rem;
  }

  .rail__foot {
    order: 2;
    margin-top: auto;
  }

  .rail__pitch[hidden] {
    display: block !important;
  }

  /* Centred on both axes in whatever space the rail leaves — without the
     horizontal centring the question hugged the rail and left a third of the
     screen empty on the right. */
  .stage {
    align-items: center;
    justify-content: center;
    padding: 4rem var(--gutter);
  }

  .actions {
    position: static;
    padding: 0;
    margin-top: 2.75rem;
    border-top: 0;
    background: none;
    backdrop-filter: none;
  }

  .actions__hint {
    display: block;
  }

  .grid {
    grid-template-columns: 1fr 1fr;
    gap: 1.75rem 2rem;
  }

  .q {
    margin-bottom: 2.25rem;
  }
}

@media (min-width: 80rem) {
  :root {
    --rail: 26rem;
  }

  .pitch {
    font-size: 2.125rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .step,
  .panel {
    animation: none;
  }

  .choice,
  .choice:hover,
  .btn,
  .btn--primary:active:not(:disabled) {
    transform: none;
    transition: none;
  }

  .btn--primary:hover:not(:disabled)::before {
    animation: none;
  }
}
