/* =====================================================================
   Waitlist — the one-question-at-a-time signup flow at /waitlist
   ---------------------------------------------------------------------
   Page-scoped on purpose. site.css is the shared compositions layer that
   all 16 pages download; this file is ~400 lines of machinery only this
   page uses (screen states, the flow's keyframes, option cards), so it
   loads alongside site.css rather than inside it.

   The page still takes the header, container, and button/chip/input
   components from the shared layers — only the flow itself lives here.

   Structure: scaffold · header · progress · screens+motion ·
   question · options · fields · actions · errors · confirmation ·
   responsive · reduced-motion.
   ===================================================================== */

.waitlist-page {
  /* The bar is 80px here rather than the site's 64px: it carries the logo
     at full size, with no nav pill to keep it short. site.css reads this
     variable for the fixed header's own height, so setting it here keeps
     the two in step. */
  --site-header-h: 80px;
  --waitlist-col: 640px;
  /* The bar plus the header — what the question has to clear at top and
     bottom to stay centred on the viewport without colliding with either. */
  --waitlist-chrome: calc(var(--site-header-h) + 3px);

  position: relative;
  min-height: 100svh;
  background: var(--srve-color-bg-subtle);
}

/* The question centres on the viewport, not on the space under the chrome.
   The bar and the header are taken out of the flow (below) so they cost no
   height, and the padding here is symmetric — top and bottom both clear the
   header — so reserving that room doesn't shift the centre back off again. */
.waitlist {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: var(--waitlist-chrome) var(--site-gutter);
  box-sizing: border-box;
}

/* The form and the confirmation are siblings, and only ever one of them has
   any height. Left as separate grid rows they centre as a *pair*, which sat
   the confirmation below the middle of the viewport by half the form's
   remaining height. Stacking both in the one cell centres whichever is
   showing, on its own. */
.waitlist > * {
  grid-area: 1 / 1;
  width: min(var(--waitlist-col), 100%);
}

/* ------ Header ------------------------------------------------------ */
/* Two departures from site.css, which fixes the bar over the page and frosts
   it with a page-coloured layer on ::before:
   - it sits in the normal flow here, so it scrolls away with everything else.
     A bar that follows you down a form is chrome this flow doesn't need, and
     nothing passes behind it once it scrolls as one piece with the content.
   - the glass comes off, so the bar is genuinely transparent rather than
     merely page-coloured.
   The toggle is left alone, so it matches the rest of the site. */
/* Absolute, not fixed: it still scrolls away with the page, but it costs the
   flow no height, which is what lets .waitlist centre on the viewport. */
.waitlist-page .site-header {
  position: absolute;
  top: 3px; /* below the progress bar */
  left: 0;
  right: 0;
}
.waitlist-page .site-header::before {
  display: none;
}
.waitlist-page .site-header__inner {
  justify-content: space-between;
}

/* Inlined rather than <img> so the mark can follow the theme directly. Both
   parts — the wordmark and the bowl beneath it — take the text token rather
   than a literal black: same #111827 as the source SVG in light mode, but it
   flips with the page instead of vanishing into a dark background. */
.waitlist-logo {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
.waitlist-logo svg {
  display: block;
  height: 30px;
  width: auto;
}
.waitlist-logo__mark,
.waitlist-logo__bowl {
  fill: var(--srve-color-text-primary);
}

/* ------ Progress ---------------------------------------------------- */
/* Along the very top edge of the page, above the header — the first thing
   the eye meets, and out of the flow so it costs the centring nothing. */
.waitlist__progress {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 51; /* over the header, which site.css puts at 50 */
  height: 3px;
  background: var(--srve-color-neutral-100);
}
.waitlist__progress-bar {
  height: 100%;
  width: 0;
  background: var(--srve-color-brand-primary);
  transition: width var(--srve-duration-base) var(--srve-ease-standard);
}

/* The spoken counterpart to the bar. Visually hidden, announced politely
   on each advance. */
.waitlist__progress-text {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ------ Screens ----------------------------------------------------- */
/* Without JS every screen stays visible and the whole thing degrades to
   one long, ordinary form — which still posts, because the last screen
   holds a real submit button. The .js class is set pre-paint in <head>,
   so nothing flashes before hiding. */
.waitlist__form,
.waitlist-screen__inner {
  width: min(var(--waitlist-col), 100%);
}

.js .waitlist-screen { display: none; }
.js .waitlist-screen.is-active { display: block; }

.js .waitlist-screen--done { display: none; }
.js .waitlist-screen--done.is-active { display: block; }

/* No-JS: hide the per-screen chrome that only means something in a flow. */
html:not(.js) [data-advance],
html:not(.js) [data-skip],
html:not(.js) [data-link-add],
html:not(.js) [data-link-remove],
html:not(.js) .waitlist-intro__meta,
html:not(.js) .waitlist__progress,
html:not(.js) [data-back],
html:not(.js) .waitlist-screen--done {
  display: none;
}
html:not(.js) .waitlist-screen { margin-bottom: var(--srve-space-7); }

/* Entrance. Children rise in sequence via --i; the cap keeps the last
   item in a long list from lagging behind the reader. */
@keyframes waitlist-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes waitlist-rise-far {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
@keyframes waitlist-leave {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-8px); }
}

.waitlist-screen.is-active .waitlist-screen__title,
.waitlist-screen.is-active .waitlist-screen__help,
.waitlist-screen.is-active .waitlist-screen__body,
.waitlist-screen.is-active .waitlist-screen__actions {
  animation: waitlist-rise 240ms var(--srve-ease-standard) both;
  animation-delay: calc(min(var(--i, 0) * 35ms, 420ms));
}
.waitlist-screen.is-active .waitlist-screen__title  { --i: 0; }
.waitlist-screen.is-active .waitlist-screen__help   { --i: 1; }
.waitlist-screen.is-active .waitlist-screen__body   { --i: 2; }
.waitlist-screen.is-active .waitlist-screen__actions{ --i: 3; }

/* Option rows arrive one by one — they read as a list, and a list wants
   sequence rather than a single block fading up. */
.waitlist-screen.is-active .waitlist-option {
  animation: waitlist-rise-far 320ms var(--srve-ease-standard) both;
  animation-delay: calc(min(var(--i, 0) * 110ms, 880ms) + 120ms);
}
/* Ten of them in two columns, so the same 110ms step would run on well past
   the reader. Tighter, and capped sooner. */
.waitlist-screen.is-active .waitlist-options--split .waitlist-option {
  animation-delay: calc(min(var(--i, 0) * 45ms, 400ms) + 120ms);
}

.waitlist-screen.is-leaving {
  animation: waitlist-leave 160ms var(--srve-ease-standard) both;
}
/* Going back reverses the direction of travel. */
.waitlist-screen.is-active[data-dir="back"] .waitlist-screen__title,
.waitlist-screen.is-active[data-dir="back"] .waitlist-screen__body {
  animation-name: waitlist-rise;
}

/* ------ Question ---------------------------------------------------- */
/* The UI family, not the display face: these are questions being asked,
   not headlines being announced. Weight 800 and the tight display
   leading keep them from going soft at this size. */
.waitlist-screen__title {
  margin: 0;
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-heading-lg);
  font-weight: var(--srve-font-weight-semibold);
  line-height: var(--srve-line-height-display);
  letter-spacing: var(--srve-tracking-display);
  color: var(--srve-color-text-primary);
}
.waitlist-screen__title:focus { outline: none; }

.waitlist-screen__help {
  margin: var(--srve-space-5) 0 0;
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-body-lg);
  line-height: var(--srve-line-height-relaxed);
  color: var(--srve-color-text-secondary);
}

/* Positioned and lifted so the location dropdown can hang over the buttons
   below it. The entrance animation leaves an identity transform on both this
   and .waitlist-screen__actions, and any transform other than `none` makes an
   element a stacking context — which would otherwise trap the dropdown's
   z-index in here and let the later-painted actions row cover it. */
.waitlist-screen__body {
  position: relative;
  z-index: 1;
  margin-top: var(--srve-space-6);
}

/* ------ Option cards (single choice) -------------------------------- */
.waitlist-options {
  display: flex;
  flex-direction: column;
  gap: var(--srve-space-3);
}

/* Ten options in one column would run past the fold, and as loose pills they
   read as tags rather than as things to pick. Two columns of the same row
   the single-choice screens use: one control for choosing, whether you may
   pick one or several. The grid also fixes each cell's width, so ticking a
   box can never reflow the ones around it. */
.waitlist-options--split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--srve-space-3);
}

/* The real radio sits inside the label, visually hidden — so arrow keys,
   Space, and the accessibility tree all work without being rebuilt. */
.waitlist-option {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  background: var(--srve-color-bg-surface);
  border: 1px solid var(--srve-color-border);
  border-radius: var(--srve-radius-md);
  cursor: pointer;
  transition:
    border-color var(--srve-duration-fast) var(--srve-ease-standard),
    background-color var(--srve-duration-fast) var(--srve-ease-standard),
    transform var(--srve-duration-fast) var(--srve-ease-standard);
}
.waitlist-option input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}
.waitlist-option:hover {
  border-color: var(--srve-color-neutral-300);
  transform: translateY(-1px);
}
.waitlist-option:has(input:checked) {
  background: var(--srve-color-brand-primary-tint);
  border-color: var(--srve-color-brand-primary);
}
.waitlist-option:has(input:focus-visible) {
  border-color: var(--srve-color-brand-primary);
  box-shadow: 0 0 0 3px var(--srve-color-brand-primary-tint);
}

.waitlist-option__label {
  flex: 1;
  font-size: var(--srve-font-size-body-lg);
  font-weight: var(--srve-font-weight-medium);
  color: var(--srve-color-text-primary);
}
.waitlist-option:has(input:checked) .waitlist-option__label {
  font-weight: var(--srve-font-weight-semibold);
}

.waitlist-option__check {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--srve-color-brand-primary);
  opacity: 0;
}
.waitlist-option:has(input:checked) .waitlist-option__check { opacity: 1; }

/* The free-text field belongs to the Other chip, so it waits for it. Hidden
   until that box is ticked, then revealed by :has() — no JS, and it cannot
   fall out of step with the checkbox the way a toggled class could. */
.waitlist-other {
  display: none;
  margin-top: var(--srve-space-5);
  padding-top: var(--srve-space-5);
  border-top: 1px solid var(--srve-color-neutral-100);
}
.waitlist-screen__body:has(#services-is-other:checked) .waitlist-other {
  display: block;
  animation: waitlist-rise 240ms var(--srve-ease-standard) both;
}
/* No :has() (older Safari/Firefox): show the field rather than stranding the
   Other chip with nowhere to type. */
@supports not selector(:has(*)) {
  .waitlist-other { display: block; }
}
.waitlist-other__label {
  display: block;
  margin-bottom: var(--srve-space-3);
  font-size: var(--srve-font-size-body-sm);
  font-weight: var(--srve-font-weight-medium);
  color: var(--srve-color-text-secondary);
}

/* ------ Fields ------------------------------------------------------ */
/* The component-library input at the scale this format needs. */
.waitlist-input {
  width: 100%;
  box-sizing: border-box;
  background-color: var(--srve-color-neutral-50);
  border: 1px solid var(--srve-color-border);
  border-radius: var(--srve-radius-md);
  padding: 18px 20px;
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-heading-sm);
  color: var(--srve-color-text-primary);
  transition:
    border-color var(--srve-duration-fast) var(--srve-ease-standard),
    box-shadow var(--srve-duration-fast) var(--srve-ease-standard);
}
.waitlist-input::placeholder { color: var(--srve-color-neutral-300); }
.waitlist-input:focus-visible,
.waitlist-input:focus {
  outline: none;
  border-color: var(--srve-color-brand-primary);
  box-shadow: 0 0 0 3px var(--srve-color-brand-primary-tint);
}
textarea.waitlist-input {
  min-height: 132px;
  resize: vertical;
  font-size: var(--srve-font-size-body-lg);
  line-height: var(--srve-line-height-normal);
}
.waitlist-input[aria-invalid="true"] {
  border-color: var(--srve-color-error);
  box-shadow: none;
}

.waitlist-other__row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.waitlist-other__row .waitlist-input {
  flex: 1;
  padding: 12px 16px;
  font-size: var(--srve-font-size-body-md);
}

/* ------ Phone ------------------------------------------------------- */
/* Country picker and number read as one control: they share a row, and the
   select is sized to its own content so the number keeps the rest. */
.waitlist-phone {
  display: flex;
  align-items: stretch;
  gap: var(--srve-space-2);
}
/* A native <select> can only ever display the selected option's own text, so
   it cannot show "🇺🇸 +1" closed and "🇺🇸 +1 United States" open. waitlist.js
   replaces it with the button and listbox below, and the real <select> stays
   in the DOM holding the value — so the field still works, and still submits,
   with no JavaScript at all. */
.waitlist-phone__country {
  flex: 0 0 auto;
  width: 10rem;
  padding-right: var(--srve-space-6);
  font-size: var(--srve-font-size-body-md);
  cursor: pointer;
  appearance: none;
  /* background-COLOR, not the shorthand — the shorthand would wipe the SVG. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--srve-space-3) center;
  background-size: 12px;
  text-overflow: ellipsis;
}
:root[data-theme="dark"] .waitlist-phone__country {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%239aa5a0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E");
}
.waitlist-phone__number { flex: 1; min-width: 0; }

/* Once the custom picker is in, the select is the value and nothing else:
   out of sight and out of the tab order, since the button now stands for it. */
.waitlist-phone--custom .waitlist-phone__country {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.waitlist-phone__picker {
  position: relative;
  flex: 0 0 auto;
}

/* Sized to its contents — flag and dial code only — so the number keeps
   everything else. */
.waitlist-phone__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--srve-space-2);
  height: 100%;
  padding: 18px var(--srve-space-3) 18px 20px;
  background-color: var(--srve-color-neutral-50);
  border: 1px solid var(--srve-color-border);
  border-radius: var(--srve-radius-md);
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-heading-sm);
  color: var(--srve-color-text-primary);
  cursor: pointer;
  white-space: nowrap;
  transition:
    border-color var(--srve-duration-fast) var(--srve-ease-standard),
    box-shadow var(--srve-duration-fast) var(--srve-ease-standard);
}
.waitlist-phone__trigger:hover { border-color: var(--srve-color-neutral-300); }
.waitlist-phone__trigger:focus-visible {
  outline: none;
  border-color: var(--srve-color-brand-primary);
  box-shadow: 0 0 0 3px var(--srve-color-brand-primary-tint);
}
.waitlist-phone__trigger svg {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  color: var(--srve-color-text-secondary);
}
.waitlist-phone__flag { font-size: var(--srve-font-size-body-lg); line-height: 1; }
.waitlist-phone__dial { font-size: var(--srve-font-size-body-md); }

/* Same panel as the location suggestions, sized for a long list. */
.waitlist-phone__list {
  min-width: 17rem;
  max-height: 300px;
}
.waitlist-phone__list .waitlist-combo__option {
  display: flex;
  align-items: center;
  gap: var(--srve-space-3);
  font-size: var(--srve-font-size-body-sm);
}
.waitlist-phone__list .waitlist-combo__option span:first-child { font-size: var(--srve-font-size-body-lg); }
.waitlist-phone__list .waitlist-combo__option .is-dial {
  margin-left: auto;
  color: var(--srve-color-text-secondary);
  font-variant-numeric: tabular-nums;
}
.waitlist-phone__list .waitlist-combo__option[aria-selected="true"] .is-dial { color: inherit; }

/* ------ Location combobox ------------------------------------------- */
/* The suggestion list is drawn here rather than taken from a provider's
   widget, so it inherits the field's own border, radius and focus ring
   instead of arriving with someone else's. */
.waitlist-combo { position: relative; }

.waitlist-combo__list {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 20;
  margin: 0;
  padding: var(--srve-space-1);
  list-style: none;
  max-height: 264px;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--srve-color-bg-surface);
  border: 1px solid var(--srve-color-border);
  border-radius: var(--srve-radius-md);
  box-shadow: var(--srve-shadow-md);
}
.waitlist-combo__list[hidden] { display: none; }

.waitlist-combo__option {
  padding: 11px 14px;
  border-radius: var(--srve-radius-sm);
  font-size: var(--srve-font-size-body-md);
  color: var(--srve-color-text-primary);
  cursor: pointer;
}
/* One highlight for both the pointer and the arrow keys, so the list never
   shows two different "current" rows at once. */
.waitlist-combo__option:hover,
.waitlist-combo__option[aria-selected="true"] {
  background: var(--srve-color-brand-primary-tint);
  color: var(--srve-color-brand-text);
}
.waitlist-combo__option mark {
  background: none;
  color: inherit;
  font-weight: var(--srve-font-weight-bold);
}

/* ------ Links (repeatable) ------------------------------------------ */
.waitlist-links {
  display: flex;
  flex-direction: column;
  gap: var(--srve-space-3);
}
.waitlist-links__row {
  display: flex;
  align-items: center;
  gap: var(--srve-space-2);
}
.waitlist-links__row .waitlist-input {
  flex: 1;
  padding: 14px 18px;
  font-size: var(--srve-font-size-body-md);
}
/* The first row's placeholder cycles through example links. It crosses over
   at zero opacity so the text never appears to mutate mid-word; waitlist.js
   swaps the string at the bottom of the fade. */
.waitlist-links__row .waitlist-input::placeholder {
  opacity: 1;
  transition: opacity var(--srve-duration-base) var(--srve-ease-standard);
}
.waitlist-links__row .waitlist-input.is-swapping::placeholder { opacity: 0; }
.waitlist-links__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--srve-radius-md);
  color: var(--srve-color-text-secondary);
  cursor: pointer;
}
.waitlist-links__remove:hover {
  background: var(--srve-color-neutral-100);
  color: var(--srve-color-text-primary);
}
.waitlist-links__remove:focus-visible {
  outline: 2px solid var(--srve-color-brand-text);
  outline-offset: 2px;
}
.waitlist-links__remove svg { width: 16px; height: 16px; }
.waitlist-links__remove[hidden] { display: none; }

.waitlist-links__add {
  display: inline-flex;
  align-items: center;
  gap: var(--srve-space-2);
  margin-top: var(--srve-space-3);
  padding: var(--srve-space-2) 0;
  background: none;
  border: 0;
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-body-sm);
  font-weight: var(--srve-font-weight-semibold);
  color: var(--srve-color-brand-text);
  cursor: pointer;
}
.waitlist-links__add:hover { text-decoration: underline; }
.waitlist-links__add:focus-visible {
  outline: 2px solid var(--srve-color-brand-text);
  outline-offset: 2px;
}
.waitlist-links__add svg { width: 15px; height: 15px; }

/* ------ Actions ----------------------------------------------------- */
/* Back on the left, Continue on the right — the direction of travel matches
   the direction they point. */
.waitlist-screen__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--srve-space-4);
  margin-top: var(--srve-space-6);
}

.waitlist-back {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: none;
  border: 0;
  padding: var(--srve-space-2);
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-body-sm);
  font-weight: var(--srve-font-weight-medium);
  color: var(--srve-color-text-secondary);
  cursor: pointer;
}
.waitlist-back:hover { color: var(--srve-color-text-primary); }
.waitlist-back:focus-visible {
  outline: 2px solid var(--srve-color-brand-text);
  outline-offset: 2px;
}
.waitlist-back svg { width: 15px; height: 15px; }

.waitlist-cta svg { width: 17px; height: 17px; }

/* ------ Errors ------------------------------------------------------ */
.waitlist-screen__error {
  margin: var(--srve-space-3) 0 0;
  font-size: var(--srve-font-size-body-sm);
  font-weight: var(--srve-font-weight-medium);
  color: var(--srve-color-error);
}
.waitlist-screen__error[hidden] { display: none; }

/* ------ Honeypot ---------------------------------------------------- */
/* Off-screen rather than display:none — some bots skip what is hidden. */
.waitlist__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ------ Confirmation ------------------------------------------------ */
.waitlist-done {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* ------ Success check ------------------------------------------------
   Transitions.dev — "Success check" (transitions.dev/detail.html?t=success-check).
   Vendored rather than rewritten, so it stays recognisable against the
   original; the variables below are its own knobs. Four things run together
   on the wrapper — fade, rotate in from 80°, unblur, and a bob up from 40px —
   while the tick draws itself along its own length just behind them.

   One adaptation: the snippet's stroke-dasharray of 20 is a placeholder for
   your path's real length. Ours is the 56×56 CheckCircle, whose tick measures
   28.28 units, so the dash is 29 — long enough that no dash repeats, and the
   round caps hide the fractional overshoot. */
.t-success-check {
  --check-opacity-dur: 500ms;
  --check-rotate-dur: 500ms;
  --check-rotate-from: 80deg;
  --check-bob-dur: 500ms;
  --check-y-amount: 40px;
  --check-blur-dur: 500ms;
  --check-blur-from: 10px;
  --check-path-dur: 500ms;
  --check-path-delay: 80ms;
  --check-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --check-ease-opacity: cubic-bezier(0.22, 1, 0.36, 1);
  --check-ease-rotate: cubic-bezier(0.22, 1, 0.36, 1);
  --check-ease-bob: cubic-bezier(0.34, 1.35, 0.64, 1);
  --check-ease-path: cubic-bezier(0.22, 1, 0.36, 1);

  display: inline-block;
  transform-origin: center;
  opacity: 0;
  will-change: transform, opacity, filter;
}
.t-success-check svg { display: block; overflow: visible; }
.t-success-check svg path {
  stroke-dasharray: 29;
  stroke-dashoffset: 29;
}

.t-success-check[data-state="in"] {
  animation:
    t-check-fade   var(--check-opacity-dur) var(--check-ease-opacity) forwards,
    t-check-rotate var(--check-rotate-dur)  var(--check-ease-rotate)  forwards,
    t-check-blur   var(--check-blur-dur)    var(--check-ease-out)     forwards,
    t-check-bob    var(--check-bob-dur)     var(--check-ease-bob)     forwards;
}
.t-success-check[data-state="in"] svg path {
  animation: t-check-draw var(--check-path-dur) var(--check-ease-path) var(--check-path-delay, 0ms) forwards;
}

@keyframes t-check-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes t-check-rotate {
  from { transform: rotate(var(--check-rotate-from)); }
  to   { transform: rotate(0deg); }
}
@keyframes t-check-blur {
  from { filter: blur(var(--check-blur-from)); }
  to   { filter: blur(0); }
}
@keyframes t-check-bob {
  from { translate: 0 var(--check-y-amount); }
  to   { translate: 0 0; }
}
@keyframes t-check-draw { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  .t-success-check { animation: none !important; opacity: 1; }
  .t-success-check svg path { animation: none !important; stroke-dashoffset: 0 !important; }
}

/* The words come up under the mark once it has landed. Holding them back is
   what makes the screen read as cause and effect rather than as one block
   appearing all at once. */
.waitlist-screen--done.is-active .waitlist-done__title,
.waitlist-screen--done.is-active .waitlist-done__sub,
.waitlist-screen--done.is-active .waitlist-done__actions {
  animation: waitlist-rise-far 340ms var(--srve-ease-standard) both;
}
.waitlist-screen--done.is-active .waitlist-done__title   { animation-delay: 300ms; }
.waitlist-screen--done.is-active .waitlist-done__sub     { animation-delay: 390ms; }
.waitlist-screen--done.is-active .waitlist-done__actions { animation-delay: 480ms; }
.waitlist-done__icon {
  width: 60px;
  height: 60px;
  color: var(--srve-color-brand-primary);
}
.waitlist-done__title {
  margin: var(--srve-space-5) 0 0;
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-heading-lg);
  font-weight: var(--srve-font-weight-bold);
  line-height: var(--srve-line-height-display);
  letter-spacing: var(--srve-tracking-display);
  color: var(--srve-color-text-primary);
}
.waitlist-done__title:focus { outline: none; }
.waitlist-done__sub {
  margin: var(--srve-space-5) 0 0;
  max-width: 520px;
  font-size: var(--srve-font-size-body-lg);
  line-height: var(--srve-line-height-relaxed);
  color: var(--srve-color-text-secondary);
}
.waitlist-done__actions {
  display: flex;
  align-items: center;
  gap: var(--srve-space-3);
  margin-top: var(--srve-space-6);
}

/* ------ Intro ------------------------------------------------------- */
.waitlist-intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.waitlist-intro__title {
  margin: 0;
  font-family: var(--srve-font-family-ui);
  font-size: var(--srve-font-size-display-lg);
  font-weight: var(--srve-font-weight-bold);
  line-height: var(--srve-line-height-display);
  letter-spacing: var(--srve-tracking-display);
  color: var(--srve-color-text-primary);
}
.waitlist-intro__sub {
  margin: var(--srve-space-5) 0 0;
  max-width: 560px;
  font-size: var(--srve-font-size-body-lg);
  line-height: var(--srve-line-height-relaxed);
  color: var(--srve-color-text-secondary);
}
.waitlist-intro__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: var(--srve-space-6);
}
.waitlist-intro__meta {
  margin-top: var(--srve-space-5);
  font-size: var(--srve-font-size-body-sm);
  color: var(--srve-color-text-secondary);
}

/* ------ Responsive -------------------------------------------------- */
@media (max-width: 640px) {
  .waitlist-page {
    --site-header-h: 68px;
    --waitlist-chrome: calc(68px + 3px);
  }

  /* Two columns of these would be two very narrow columns. One list, and
     the screen scrolls — which it already does at this height. */
  .waitlist-options--split { grid-template-columns: 1fr; }

  /* Narrow screens give the number the room instead: the picker keeps the
     flag and the code, and drops the name entirely. */
  .waitlist-phone__country {
    width: 6.5rem;
    padding-right: var(--srve-space-5);
  }

  .waitlist-logo svg { height: 24px; }

  .waitlist-screen__title { font-size: var(--srve-font-size-heading-md); }
  .waitlist-screen__help,
  .waitlist-intro__sub,
  .waitlist-done__sub { font-size: var(--srve-font-size-body-md); }
  .waitlist-intro__title { font-size: var(--srve-font-size-heading-lg); }
  .waitlist-done__title { font-size: var(--srve-font-size-heading-md); }

  .waitlist-input { font-size: var(--srve-font-size-body-lg); }

  /* Back stays a quiet text button on the left; Continue takes the rest
     of the row, which is where a thumb expects it. */
  .waitlist-screen__actions { gap: var(--srve-space-3); }
  .waitlist-screen__actions .waitlist-cta { flex: 1; justify-content: center; }

  .waitlist-intro__actions { align-self: stretch; }
  .waitlist-intro__actions .waitlist-cta { justify-content: center; }

  .waitlist-links__row .waitlist-input { font-size: var(--srve-font-size-body-md); }

  .waitlist-done__actions { flex-direction: column; align-self: stretch; }
  .waitlist-done__actions .srve-button { justify-content: center; }

}

/* ------ Reduced motion ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .waitlist-screen.is-active .waitlist-screen__title,
  .waitlist-screen.is-active .waitlist-screen__help,
  .waitlist-screen.is-active .waitlist-screen__body,
  .waitlist-screen.is-active .waitlist-screen__actions,
  .waitlist-screen.is-active .waitlist-option,
  .waitlist-screen--done.is-active .waitlist-done__title,
  .waitlist-screen--done.is-active .waitlist-done__sub,
  .waitlist-screen--done.is-active .waitlist-done__actions,
  .waitlist-screen.is-leaving {
    animation: none;
  }
  .waitlist__progress-bar,
  .waitlist-option,
  .waitlist-input { transition: none; }
  .waitlist-option:hover { transform: none; }
}
