:root {
  --font-sans: "Poppins", ui-sans-serif, system-ui, sans-serif;
  /* Dark is the look. The artwork is `dark_backround.svg`. */
  --bg: #050726;
  --ink: #fff;
  --muted: rgba(255, 255, 255, 0.78);
  --cyan: #00b8f0;
  --blue: #006dff;
  --pink: #ff1680;
  --yellow: #ffd31a;
  --orange: #ff7a18;
  --green: #19c36b;
  --panel: rgba(0, 0, 0, 0.42);
  --line: rgba(255, 255, 255, 0.22);
  /* Gap between the headline block and the phone. This is the ONE knob for the
     hero spacing now: lower it to bring them closer, raise it to spread them.
     The topbar and footer are separate regions and never move with it. */
  --hero-gap: clamp(2rem, 4vw, 5rem);
}

* {
  box-sizing: border-box;
}

html,
body {
  min-height: 100%;
  margin: 0;
}

html {
  background: var(--bg);
}

body {
  font-family: var(--font-sans);
  color: var(--ink);
  background: var(--bg);
}

button,
input,
textarea {
  font-family: inherit;
}

a {
  color: inherit;
  text-decoration: none;
}

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

.page {
  position: relative;
  height: 100svh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(circle at 63% 34%, rgba(0, 109, 255, 0.2), transparent 26rem),
    radial-gradient(circle at 82% 58%, rgba(255, 22, 128, 0.18), transparent 28rem),
    linear-gradient(110deg, #05060b 0%, #030411 48%, #02030a 100%);
}

.page::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -3;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px),
    linear-gradient(0deg, rgba(255, 255, 255, 0.022) 1px, transparent 1px);
  background-size: 58px 58px;
  mask-image: radial-gradient(circle at 55% 48%, black, transparent 82%);
}

.page::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.74), rgba(0, 0, 0, 0.18) 44%, rgba(0, 0, 0, 0.35)),
    radial-gradient(circle at center, transparent 45%, rgba(0, 0, 0, 0.62) 100%);
}

.bg-layer {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
}

.beam,
.spark {
  position: absolute;
  display: block;
}

.beam {
  width: 0.75rem;
  height: 60rem;
  border-radius: 999px;
  transform: rotate(41deg);
  opacity: 0.9;
  filter: drop-shadow(0 0 22px currentColor);
}

.beam--blue {
  left: 50%;
  top: -8rem;
  color: var(--blue);
  background: linear-gradient(180deg, transparent, #1b31ff 18%, var(--cyan) 50%, transparent 82%);
}

.beam--pink {
  right: 4%;
  top: -10rem;
  color: var(--pink);
  background: linear-gradient(180deg, transparent, var(--pink) 20%, #ff44b0 50%, transparent 84%);
}

.beam--orange {
  right: 1%;
  top: 22rem;
  width: 1rem;
  color: var(--orange);
  background: linear-gradient(180deg, transparent, var(--yellow) 15%, #ff4c10 65%, transparent);
}

.beam--thin-blue,
.beam--thin-pink {
  width: 1px;
  height: 48rem;
  opacity: 0.74;
  background: currentColor;
}

.beam--thin-blue {
  left: 45%;
  top: -9rem;
  color: #0a82ff;
}

.beam--thin-pink {
  right: 8%;
  top: -18rem;
  color: #ff1b64;
}

.spark {
  width: 3px;
  height: 3px;
  border-radius: 999px;
  background: var(--pink);
  box-shadow: 0 0 16px currentColor;
}

.spark--one {
  left: 47%;
  top: 16%;
}

.spark--two {
  right: 10%;
  top: 14%;
}

.spark--three {
  left: 43%;
  top: 56%;
  background: var(--cyan);
}

.hero {
  position: relative;
  z-index: 2;
  flex: 1;
  width: min(100%, 112rem);
  min-height: 0;
  margin: 0 auto;
  padding: clamp(0.6rem, 1.4vw, 1.6rem) clamp(1.25rem, 4vw, 4.5rem) clamp(1rem, 2vw, 2.2rem);
  display: grid;
  /* Text and phone are sized to their content and centered as ONE block, so
     the whitespace sits evenly on both outer sides instead of pooling in the
     middle or leaving the phone stranded. --hero-gap is the space between the
     two: lower it to bring the phone closer to the copy. */
  grid-template-columns: auto auto;
  justify-content: center;
  gap: var(--hero-gap);
  align-items: center;
}

.hero__content {
  position: relative;
  z-index: 4;
  max-width: 64rem;
}

.topbar {
  position: relative;
  z-index: 5;
  width: min(100%, 112rem);
  margin: 0 auto;
  padding: clamp(1rem, 2.2vw, 1.9rem) clamp(1.25rem, 4vw, 4.5rem) 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1.4rem;
}

.topbar::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: calc(100% + 2.6rem);
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(2, 3, 10, 0.82) 0%, rgba(2, 3, 10, 0.42) 52%, transparent 100%);
}

.topbar .brand {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.12rem;
  margin-bottom: 0;
}

.topbar .brand__logo {
  width: clamp(6rem, 8vw, 9rem);
}

.topbar .brand__name {
  font-size: clamp(0.6rem, 0.78vw, 0.76rem);
  font-weight: 700;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
}

.topbar__actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.topbar__actions .btn {
  width: auto;
  min-height: 2.5rem;
  padding: 0.45rem 0.85rem;
  font-size: 0.72rem;
  white-space: nowrap;
}

.topbar__actions .btn .icon {
  width: 17px;
  height: 17px;
}

.brand {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.18rem;
  margin-bottom: clamp(1rem, 2.2vw, 1.8rem);
}

.brand__logo {
  display: block;
  width: clamp(8.6rem, 13vw, 13.5rem);
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 0 18px rgba(0, 184, 240, 0.12));
}

.brand__name {
  display: block;
  color: #fff;
  font-size: clamp(1.25rem, 1.95vw, 2rem);
  line-height: 1;
  font-weight: 700;
}

.headline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.title {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  /* .headline aligns its items to flex-start, which makes this title size to its
     longest UNWRAPPED line and overflow narrow screens. Force full container
     width so the lines wrap instead of running off-screen. */
  width: 100%;
  max-width: 100%;
  min-width: 0;
  color: #fff;
  font-size: clamp(1.25rem, 2.5vw, 2rem);
  line-height: 1.35;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding-bottom: 0.08em;
}

.title > span {
  display: block;
  padding-bottom: 0.05em;
}

/* No accent colour at all: the whole headline is one solid white, same as
   the rest of the line. The span carries no colour anymore. */
.title__gradient {
  color: inherit;
  -webkit-text-fill-color: currentColor;
  background: none;
}

.title__dot {
  color: inherit;
}

.title-rule {
  width: min(24rem, 78vw);
  height: 3px;
  margin: clamp(0.7rem, 1.3vw, 1rem) 0 clamp(0.7rem, 1.3vw, 1rem);
  background: linear-gradient(90deg, var(--cyan), var(--pink), var(--orange), var(--yellow), transparent);
  box-shadow: 0 0 18px rgba(255, 22, 128, 0.3);
}

.subtitle {
  max-width: 37rem;
  margin: 0;
  color: rgba(255, 255, 255, 0.72);
  font-size: clamp(0.92rem, 1.05vw, 1.08rem);
  line-height: 1.4;
  font-weight: 400;
}

.subtitle span {
  color: var(--pink);
}

.conversion {
  width: min(100%, 35rem);
  margin-top: clamp(0.7rem, 1.3vw, 1.1rem);
}

.actions {
  display: grid;
  gap: 0.7rem;
  align-content: end;
}

.btn {
  min-height: 3.1rem;
  border: 1px solid transparent;
  border-radius: 0.45rem;
  padding: 0.62rem 0.9rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  color: #fff;
  background: rgba(255, 255, 255, 0.035);
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform 180ms ease, box-shadow 180ms ease, background 180ms ease, border-color 180ms ease;
}

.actions .btn {
  width: 100%;
}

.btn:hover,
.subscribe__btn:hover,
.social:hover {
  transform: translateY(-2px);
}

.btn:active,
.subscribe__btn:active,
.social:active {
  transform: translateY(0);
}

.btn:focus-visible,
.subscribe__btn:focus-visible,
.input:focus-visible,
.modal__close:focus-visible,
.social:focus-visible {
  outline: 3px solid var(--yellow);
  outline-offset: 4px;
}

.btn--primary,
.subscribe__btn,
.modal__submit {
  background: linear-gradient(100deg, var(--blue), var(--pink) 53%, var(--orange) 82%, var(--yellow));
  border-color: rgba(255, 255, 255, 0.14);
  box-shadow: 0 14px 34px rgba(255, 22, 128, 0.28), 0 0 0 1px rgba(255, 255, 255, 0.08) inset;
}

.btn--outline {
  border-color: rgba(255, 255, 255, 0.24);
  backdrop-filter: blur(14px);
}

.btn--outline:hover {
  border-color: rgba(0, 184, 240, 0.86);
  box-shadow: 0 0 22px rgba(0, 184, 240, 0.18);
}

.btn--download {
  margin-top: 0.2rem;
  background: rgba(25, 195, 107, 0.16);
  border-color: rgba(25, 195, 107, 0.75);
  color: #fff;
}

.btn.is-downloading,
.modal__submit.is-loading,
.subscribe__btn.is-loading {
  cursor: progress;
  pointer-events: none;
}

.btn.is-downloading::before,
.modal__submit.is-loading::before,
.subscribe__btn.is-loading::before {
  content: "";
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: spin 700ms linear infinite;
}

.icon,
.waitlist__bell,
.subscribe__icon,
.privacy-note svg {
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.waitlist {
  width: 100%;
  margin-top: 0;
}

.waitlist__title {
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--yellow);
}

.waitlist__bell {
  width: 1.75rem;
  height: 1.75rem;
}

.waitlist h2,
.follow h2 {
  margin: 0;
  color: #fff;
  font-size: clamp(0.88rem, 1.15vw, 1.08rem);
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

.waitlist__copy {
  margin: 0.45rem 0 0.7rem;
  color: var(--muted);
  font-size: clamp(0.9rem, 1.05vw, 1rem);
}

.subscribe__row {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) auto;
  gap: 0.7rem;
  align-items: stretch;
}

.subscribe__field {
  min-height: 2.8rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.42);
  border-radius: 0.45rem;
  background: rgba(0, 0, 0, 0.36);
  box-shadow: 0 0 28px rgba(255, 255, 255, 0.04) inset;
}

.subscribe__icon {
  width: 1.15rem;
  height: 1.15rem;
  color: #fff;
  flex: 0 0 auto;
}

.input {
  width: 100%;
  min-width: 0;
  border: 0;
  background: transparent;
  color: #fff;
  outline: none;
  font-size: clamp(0.9rem, 1vw, 1rem);
}

.input::placeholder {
  color: rgba(255, 255, 255, 0.55);
}

.subscribe__btn {
  min-width: 10rem;
  border: 0;
  border-radius: 0.45rem;
  padding: 0 1.1rem;
  background: linear-gradient(180deg, #ffe264, var(--yellow));
  color: #10131f;
  box-shadow: 0 12px 30px rgba(255, 200, 20, 0.3), 0 0 0 1px rgba(0, 0, 0, 0.08) inset;
  font-size: 0.82rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  cursor: pointer;
}

.privacy-note {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  margin: 0.6rem 0 0;
  color: rgba(255, 255, 255, 0.64);
  font-size: 0.95rem;
}

.privacy-note svg {
  width: 0.95rem;
  height: 0.95rem;
  color: rgba(255, 255, 255, 0.8);
}

.honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.follow {
  width: min(100%, 43rem);
  margin-top: clamp(1.05rem, 2vw, 1.6rem);
}

.socials {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem 0.7rem;
  margin-top: 0.8rem;
}

.social {
  min-height: 2.45rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: #fff;
  transition: transform 180ms ease, opacity 180ms ease;
}

.social::after {
  content: "";
  width: 1px;
  height: 1.35rem;
  margin-left: 0.45rem;
  background: rgba(255, 255, 255, 0.26);
}

.social:last-child::after {
  display: none;
}

.social__icon {
  width: 2.35rem;
  height: 2.35rem;
  padding: 0.52rem;
  border: 1px solid currentColor;
  border-radius: 999px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.social:nth-child(1) .social__icon,
.social:nth-child(4) .social__icon {
  color: var(--cyan);
}

.social:nth-child(2) .social__icon {
  color: var(--pink);
}

.social:nth-child(3) .social__icon,
.social:nth-child(5) .social__icon {
  color: var(--orange);
}

.social__icon path {
  fill: currentColor;
  stroke: none;
}

.social__label {
  color: rgba(255, 255, 255, 0.92);
  font-size: 0.74rem;
}

/* Phone device frame holding the character screen (desktop / landscape). */
.hero__visual {
  /* In-flow grid item (column 2), not pinned to the edge. position:relative is
     kept so the notch/side-button pseudo-elements still anchor to the phone. */
  position: relative;
  align-self: center;
  z-index: 2;
  width: clamp(15rem, 19vw, 20rem);
  aspect-ratio: 9 / 18.5;
  max-height: calc(100svh - 13rem);
  padding: 0.5rem;
  border-radius: 2.7rem;
  background: linear-gradient(155deg, #1a1a22, #050506 62%);
  box-shadow: 0 36px 90px rgba(0, 0, 0, 0.62), 0 0 0 1.5px rgba(255, 255, 255, 0.07), 0 0 60px rgba(0, 109, 255, 0.12);
  pointer-events: none;
}

.hero__visual::before {
  content: "";
  position: absolute;
  z-index: 3;
  top: 1.15rem;
  left: 50%;
  transform: translateX(-50%);
  width: 34%;
  height: 1.4rem;
  border-radius: 1rem;
  background: #050506;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}

.hero__visual::after {
  content: "";
  position: absolute;
  right: -0.26rem;
  top: 33%;
  width: 0.26rem;
  height: 4.6rem;
  border-radius: 0 0.3rem 0.3rem 0;
  background: linear-gradient(90deg, #21212b, #0a0a0e);
}

.character-stage {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 2.25rem;
  overflow: hidden;
  background: #05060b;
}

/* Fade the lower part of the character into the phone's black so it can float anywhere. */
.character-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(180deg, transparent 40%, rgba(5, 6, 11, 0.5) 68%, #05060b 100%);
}

.character-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center top;
  opacity: 0;
  transform: scale(1.05);
  filter: saturate(1.08) contrast(1.05);
  transition: opacity 760ms cubic-bezier(0.22, 1, 0.36, 1), transform 1100ms cubic-bezier(0.22, 1, 0.36, 1);
}

.character-image.is-active {
  opacity: 1;
  transform: scale(1);
}

.character-image.is-exiting {
  opacity: 0;
  transform: scale(1.08);
}

.footer {
  position: relative;
  width: min(calc(100% - 2.5rem), 103rem);
  margin: 0 auto 0.7rem;
  z-index: 4;
  padding-top: 0.7rem;
  border-top: 1px solid;
  border-image: linear-gradient(90deg, var(--cyan), var(--pink), var(--orange), var(--yellow)) 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem 1.5rem;
  color: rgba(255, 255, 255, 0.58);
  font-size: 0.9rem;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
}

.footer::before {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 100vw;
  top: -2.6rem;
  bottom: -0.7rem;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, rgba(2, 3, 10, 0.72) 46%, #02030a 100%);
}

.footer__copy {
  margin: 0;
  font-size: 0.8rem;
  white-space: nowrap;
}

.footer .follow {
  width: auto;
  margin-top: 0;
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.footer .follow__title {
  font-size: clamp(0.68rem, 0.9vw, 0.8rem);
  letter-spacing: 0.16em;
  white-space: nowrap;
}

.footer .socials {
  margin-top: 0;
  flex-wrap: nowrap;
  gap: 0.4rem;
}

.footer .social::after,
.footer .social__label {
  display: none;
}

.footer .social__icon {
  width: 2rem;
  height: 2rem;
  padding: 0.46rem;
}

.messages {
  width: min(100%, 42rem);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.message {
  margin: 0;
  padding: 0.85rem 1rem;
  border-radius: 0.45rem;
  font-size: 0.92rem;
  line-height: 1.45;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.06);
}

.message--success {
  border-color: rgba(25, 195, 107, 0.8);
  background: rgba(25, 195, 107, 0.16);
}

.message--warning {
  border-color: rgba(255, 211, 26, 0.8);
  background: rgba(255, 211, 26, 0.16);
}

.message--error {
  border-color: rgba(255, 122, 24, 0.7);
  background: rgba(255, 122, 24, 0.18);
}

.reveal {
  opacity: 0;
  transform: translateY(18px);
  animation: fadeUp 700ms ease forwards;
  animation-delay: var(--delay, 0s);
}

@keyframes fadeUp {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes characterArrive {
  0% {
    clip-path: inset(0 42% 0 0);
  }
  58% {
    clip-path: inset(0 0 0 0);
  }
  100% {
    clip-path: inset(0 0 0 0);
  }
}

.modal {
  position: fixed;
  inset: 0;
  display: none;
  z-index: 50;
}

.modal.is-open {
  display: block;
}

.modal__backdrop {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 18% 20%, rgba(255, 22, 128, 0.2), transparent 34rem),
    radial-gradient(circle at 82% 20%, rgba(0, 184, 240, 0.2), transparent 32rem),
    rgba(0, 0, 0, 0.84);
  backdrop-filter: blur(14px);
  opacity: 0;
  transition: opacity 200ms ease;
}

.modal__panel {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(calc(100% - 2rem), 34rem);
  max-height: calc(100vh - 2rem);
  padding: 2rem;
  overflow-x: hidden;
  overflow-y: auto;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 1rem;
  background:
    linear-gradient(135deg, rgba(255, 22, 128, 0.18), transparent 32%),
    linear-gradient(225deg, rgba(0, 184, 240, 0.18), transparent 34%),
    linear-gradient(180deg, #08091b, #02030a);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.72);
  opacity: 0;
  transform: translate(-50%, calc(-50% + 20px)) scale(0.96);
  transition: opacity 200ms ease, transform 200ms ease;
}

.modal__content {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 1.7rem;
}

.modal__close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.45rem;
  height: 2.45rem;
  border-radius: 999px;
  border: 0;
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.icon--muted {
  color: rgba(255, 255, 255, 0.72);
}

.modal__header {
  padding-right: 2.8rem;
}

.modal__title {
  margin: 0;
  color: #fff;
  font-size: clamp(1.8rem, 4vw, 2.35rem);
  font-weight: 800;
  line-height: 1.05;
  text-transform: uppercase;
}

.modal__subtitle {
  margin: 0.7rem 0 0;
  color: var(--muted);
  line-height: 1.6;
}

.modal__form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.label {
  font-size: 0.875rem;
  font-weight: 800;
  color: rgba(255, 255, 255, 0.8);
}

.field__input {
  width: 100%;
  padding: 1rem 1.125rem;
  border-radius: 0.5rem;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #fff;
  outline: none;
}

.field__input::placeholder {
  color: rgba(255, 255, 255, 0.36);
}

.field__input:focus {
  border-color: var(--cyan);
  box-shadow: 0 0 0 4px rgba(0, 184, 240, 0.14);
}

.choice-group {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0;
  margin: 0;
  border: 0;
}

.choice {
  position: relative;
  display: grid;
  grid-template-columns: 1.125rem 1fr;
  gap: 0.75rem;
  align-items: start;
  padding: 0.875rem 1rem;
  border-radius: 0.5rem;
  color: rgba(255, 255, 255, 0.84);
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.14);
  cursor: pointer;
}

.choice__input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.choice__mark {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.1rem;
  border-radius: 999px;
  border: 2px solid rgba(255, 255, 255, 0.5);
}

.choice__text {
  line-height: 1.4;
  font-size: 0.9375rem;
}

.choice:has(.choice__input:checked) {
  border-color: var(--cyan);
  background: rgba(0, 184, 240, 0.12);
  box-shadow: 0 0 0 4px rgba(0, 184, 240, 0.1);
}

.choice:has(.choice__input:checked) .choice__mark {
  border-color: var(--cyan);
  background: var(--cyan);
  box-shadow: inset 0 0 0 4px #05060b;
}

.choice:has(.choice__input:focus-visible) {
  outline: 3px solid var(--yellow);
  outline-offset: 3px;
}

.modal__submit {
  width: 100%;
  min-height: 3.35rem;
  margin-top: 0.65rem;
  border: 0;
  border-radius: 0.45rem;
  color: #fff;
  cursor: pointer;
  font-weight: 800;
  text-transform: uppercase;
}

.modal.is-open .modal__backdrop {
  opacity: 1;
}

.modal.is-open .modal__panel {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

@media (min-width: 2000px) {
  /* Keep the layout from stretching so wide that a gap opens between text and phone. */
  .topbar,
  .hero {
    width: min(100%, 128rem);
  }

  .hero {
    gap: clamp(2rem, 2.5vw, 3.5rem);
  }

  .hero__content {
    max-width: 76rem;
  }

  .conversion {
    width: min(100%, 40rem);
  }

  .subtitle {
    max-width: 48rem;
  }

  .hero__visual {
    width: clamp(24rem, 18vw, 30rem);
  }

  .footer {
    width: min(calc(100% - 2.5rem), 121rem);
  }
}

/* Stacked hero: character on top, copy underneath. Used for every portrait
   tablet/phone AND any screen under 1000px wide, because two columns get too
   cramped below that (headline shatters, phone shrinks). Wide landscape screens
   (>=1001px, e.g. Nest Hub 1024x600) keep the 2-col hero below. */
@media (max-width: 1180px) and (orientation: portrait), (max-width: 1000px) {
  .page {
    height: auto;
    min-height: 100svh;
    overflow: visible;
    overflow-x: clip;
  }

  .hero {
    /* minmax(0, 1fr), not 1fr: a plain 1fr track floors at the phone image's
       intrinsic width and blows the column wider than the screen, so the
       headline lays out off-screen and gets clipped. The 0 minimum lets the
       track shrink to the viewport and the text wrap. */
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    padding-bottom: clamp(2rem, 5vw, 4rem);
  }

  /* Character sits on top, content underneath it (per waitlist feedback). */
  .hero__content {
    max-width: 100%;
    min-width: 0;
    order: 2;
  }

  .hero__visual {
    display: block;
    order: 1;
    position: relative;
    right: auto;
    top: auto;
    bottom: auto;
    transform: none;
    aspect-ratio: auto;
    max-height: none;
    align-self: stretch;
    justify-self: stretch;
    width: 100%;
    /* Also floor the phone track at 0, or its image's intrinsic width blows the
       shared single-column track wider than the screen and clips the headline. */
    min-width: 0;
    max-width: 100%;
    height: clamp(13rem, 46vw, 30rem);
    margin: 0 0 -3rem;
    padding: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  .hero__visual::before,
  .hero__visual::after {
    display: none;
  }

  /* Fade the image itself to TRANSPARENT (mask, not a colour overlay) so it melts
     into whatever the page background is. A colour fade always leaves a seam. */
  .character-stage {
    border-radius: 0;
    /* Solid backing: the character PNGs are cut-outs, so a transparent stage lets
       the page's beams show straight through them. */
    background: #05060b;
    /* Two masks intersected: fade top+bottom AND both sides, so the backing
       rectangle has no hard edge on any side at any screen size. */
    -webkit-mask-image:
      linear-gradient(180deg, transparent 0%, #000 7%, #000 60%, rgba(0, 0, 0, 0.4) 82%, transparent 100%),
      linear-gradient(90deg, transparent 0%, #000 9%, #000 91%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(180deg, transparent 0%, #000 7%, #000 60%, rgba(0, 0, 0, 0.4) 82%, transparent 100%),
      linear-gradient(90deg, transparent 0%, #000 9%, #000 91%, transparent 100%);
    mask-composite: intersect;
  }

  .character-stage::after {
    display: none;
  }

  .character-image {
    object-position: center 18%;
  }
}

/* Landscape tablets / short-wide screens (e.g. Nest Hub 1024x600): keep the
   2-col hero + character, but let the columns flex so nothing overflows at
   ~1024px. Only from 1001px up; anything narrower stacks (query above). */
@media (min-width: 1001px) and (max-width: 1180px) and (orientation: landscape) {
  .hero {
    /* Flexible columns (not auto/centered like the wide desktop) so the copy
       wraps instead of overflowing at ~1024px. The text gets the larger share
       so the headline does not shatter into a tall stack; the phone column is
       kept snug. justify-content is reset to stretch because the fr tracks fill
       the row themselves. */
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    justify-content: stretch;
    gap: clamp(1.25rem, 3vw, 2.5rem);
    padding-left: clamp(1.1rem, 3vw, 2.4rem);
    padding-right: clamp(1.1rem, 3vw, 2.4rem);
  }

  .hero__content {
    max-width: 100%;
  }

  .hero__visual {
    width: clamp(10rem, 21vw, 14rem);
    max-height: calc(100svh - 7rem);
    /* Centre the phone in its column so it is not jammed against the wrapping
       text on the left. */
    justify-self: center;
  }
}

@media (max-width: 760px) {
  .page {
    min-height: 100svh;
  }

  .topbar {
    display: contents;
  }

  .topbar::before {
    display: none;
  }

  .brand {
    order: 1;
    margin: 1.4rem 1.05rem 0;
  }

  .topbar__actions {
    order: 3;
    width: auto;
    flex-direction: column;
    gap: 0.55rem;
    padding: 0 1.05rem;
    margin: 0.2rem 0 1.6rem;
  }

  .topbar__actions .btn {
    width: 100%;
    min-height: 3rem;
    font-size: 0.78rem;
    padding: 0.62rem 0.9rem;
  }

  .hero {
    order: 2;
    padding: 1.4rem 1.05rem 1.5rem;
  }

  .conversion {
    grid-template-columns: 1fr;
    width: 100%;
  }

  .brand {
    margin-bottom: 1.6rem;
  }

  .brand__logo {
    width: min(12.5rem, 62vw);
  }

  .brand__name {
    font-size: 1.35rem;
  }

  .title {
    font-size: clamp(1.2rem, 5vw, 1.7rem);
    letter-spacing: 0.03em;
    overflow-wrap: break-word;
    word-break: break-word;
  }

  .title > span {
    overflow-wrap: anywhere;
  }

  .subtitle {
    font-size: 0.98rem;
  }

  .actions,
  .subscribe__row {
    grid-template-columns: 1fr;
    width: 100%;
  }

  .actions .btn,
  .subscribe__btn {
    width: 100%;
  }

  .subscribe__btn {
    min-height: 3.3rem;
    font-size: 0.95rem;
    margin-top: 0.25rem;
  }

  .socials {
    gap: 0.65rem;
  }

  .follow {
    width: 100%;
    margin-top: 1.35rem;
  }

  .follow .socials {
    justify-content: flex-start;
    width: 100%;
    max-width: 100%;
    margin: 0.8rem 0 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    backdrop-filter: none;
  }

  .social::after,
  .social__label {
    display: none;
  }

  .footer {
    order: 4;
    width: calc(100% - 2rem);
    margin: 0 auto 1rem;
    font-size: 0.8rem;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.55rem;
  }
}

@media (max-width: 520px) {
  .hero {
    padding-bottom: 1.25rem;
  }

  .waitlist h2,
  .follow h2 {
    letter-spacing: 0.2em;
  }

  .modal__panel {
    padding: 1.35rem;
    border-radius: 0.85rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }

  .character-image.is-active {
    animation: none !important;
  }
}



/* Native [hidden] loses to any display rule, so restate it for the wizard. */
.wizard[hidden],
.wizard__step[hidden],
.wizard__error[hidden],
[data-wizard-submit][hidden],
[data-wizard-next][hidden] {
  display: none !important;
}
 
/* --- Collapsed state ------------------------------------------------------ */
 
.waitlist__cta {
  width: fit-content;
  min-height: 2.9rem;
  padding: 0 1.35rem;
}
 
/* When the wizard is open the headline block steps aside so the questions own
   the hero. The rule is scoped to .hero__content so the topbar/footer are
   untouched. */
.hero__content.is-waitlist-open .headline {
  display: none;
}
 
.hero__content.is-waitlist-open .waitlist__copy {
  display: none;
}
 
/* --- Wizard shell --------------------------------------------------------- */
 
.wizard {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  margin-top: 0.9rem;
  animation: fadeUp 420ms ease both;
}
 
.wizard__progress {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
 
.wizard__track {
  height: 3px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
 
.wizard__fill {
  display: block;
  height: 100%;
  width: 25%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--cyan), var(--pink), var(--orange), var(--yellow));
  transition: width 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
 
.wizard__count {
  margin: 0;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}
 
/* --- A single question ---------------------------------------------------- */
 
.wizard__step {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
  /* Re-runs every time a step is un-hidden, so moving between questions fades
     and lifts the new one in. Needs its own keyframe with an explicit start,
     since the shared fadeUp has no from-state and would animate to nothing. */
  animation: wizardStepIn 300ms ease both;
}
@keyframes wizardStepIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
 
.wizard__question {
  padding: 0;
  color: #fff;
  font-size: clamp(1.02rem, 1.35vw, 1.22rem);
  font-weight: 700;
  line-height: 1.35;
}
 
.field__select-wrap {
  position: relative;
}
 
.field__select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.75rem;
  cursor: pointer;
}
 
.field__select option {
  color: #fff;
  background: #08091b;
}
 
.field__select:invalid {
  color: rgba(255, 255, 255, 0.42);
}
 
.field__select-arrow {
  position: absolute;
  right: 1rem;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  fill: none;
  stroke: rgba(255, 255, 255, 0.7);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
 
.wizard__error {
  margin: 0;
  padding: 0.7rem 0.9rem;
  border: 1px solid rgba(255, 122, 24, 0.7);
  border-radius: 0.45rem;
  background: rgba(255, 122, 24, 0.18);
  color: #fff;
  font-size: 0.88rem;
  line-height: 1.4;
}
 
/* --- Navigation ----------------------------------------------------------- */
 
.wizard__nav {
  display: flex;
  align-items: stretch;
  gap: 0.6rem;
}
 
.wizard__back {
  min-height: 3.1rem;
  padding: 0 1.15rem;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: 0.45rem;
  background: rgba(255, 255, 255, 0.035);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 180ms ease, background 180ms ease;
}
 
.wizard__back:hover {
  border-color: rgba(0, 184, 240, 0.86);
}
 
.wizard__back:focus-visible,
.wizard__next:focus-visible,
.waitlist__cta:focus-visible,
.field__select:focus-visible,
.wizard__summary-edit:focus-visible {
  outline: 3px solid var(--yellow);
  outline-offset: 4px;
}
 
.wizard__next {
  flex: 1;
  min-height: 3.1rem;
}
 
/* --- Answers so far, listed under the current question -------------------- */
 
.wizard__summary {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
 
.wizard__summary:empty {
  display: none;
}
 
.wizard__summary-item {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-left: 2px solid rgba(25, 195, 107, 0.75);
  border-radius: 0.4rem;
  background: rgba(255, 255, 255, 0.045);
  font-size: 0.85rem;
}
 
.wizard__summary-key {
  flex: 0 0 auto;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
 
.wizard__summary-value {
  flex: 1;
  min-width: 0;
  color: rgba(255, 255, 255, 0.92);
  overflow-wrap: anywhere;
}
 
.wizard__summary-edit {
  flex: 0 0 auto;
  border: 0;
  padding: 0.1rem 0.2rem;
  background: transparent;
  color: var(--cyan);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}
 
.wizard__summary-edit:hover {
  color: var(--yellow);
}
 
/* --- Small screens -------------------------------------------------------- */
 
@media (max-width: 760px) {
  .wizard__nav {
    flex-wrap: wrap;
  }
 
  .wizard__back {
    flex: 1 1 100%;
    order: 2;
  }
 
  .wizard__next {
    flex: 1 1 100%;
    order: 1;
    min-height: 3.3rem;
  }
}
 
@media (prefers-reduced-motion: reduce) {
  .wizard,
  .wizard__step {
    animation: none !important;
  }
 
  .wizard__fill {
    transition: none !important;
  }
}
 







/* Waitlist expanded state (form open).
   The CTA sets [hidden] in JS, but its display rule was overriding it, so it
   kept showing. These make the collapsed bits actually disappear once the
   wizard is open, and drop the "Question X of 4" counter entirely. */
.waitlist__cta[hidden] { display: none; }
.hero__content.is-waitlist-open .waitlist__title { display: none; }

/* ══ Waitlist wizard redesign ════════════════════════
   Cleaner, on-brand form: a real question above each field, softer inputs,
   and Yes/No as two solid choice buttons instead of radio rows.
   ═══════════════════════════════════════════════════ */
.wizard {
  gap: 1rem;
}
.wizard__q {
  margin: 0 0 0.9rem;
  font-size: clamp(1rem, 1.4vw, 1.15rem);
  font-weight: 600;
  line-height: 1.45;
  color: #fff;
}

/* Inputs: quieter border, clear focus. */
.field__input {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
  transition: border-color 0.16s ease, background 0.16s ease;
}
.field__input::placeholder { color: rgba(255, 255, 255, 0.42); }
/* One clean focus: a single yellow border plus a soft glow, not the old
   1px border + 3px offset outline double ring. */
.field__input:focus,
.field__input:focus-visible {
  outline: none;
  border-color: var(--yellow);
  background: rgba(255, 255, 255, 0.07);
  box-shadow: 0 0 0 3px rgba(255, 211, 26, 0.14);
}

/* Yes / No as two buttons side by side. */
.choice-group--inline {
  flex-direction: row;
  gap: 0.6rem;
}
.choice-group--inline .choice {
  display: flex;
  justify-content: center;
  align-items: center;
  flex: 1;
  padding: 0.85rem 1rem;
  text-align: center;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.14);
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.choice-group--inline .choice:hover { border-color: rgba(255, 255, 255, 0.3); }
.choice-group--inline .choice__text {
  font-size: 0.95rem;
  font-weight: 700;
  color: inherit;
}
.choice-group--inline .choice:has(.choice__input:checked) {
  border-color: var(--yellow);
  background: rgba(255, 211, 26, 0.14);
  color: #fff;
}

/* The product testing question wraps to several lines, and a wrapped paragraph
   carries extra leading under its last line. With the step gap and the question
   margin stacking on top of that, the Yes/No buttons drifted well away from the
   question. Scoped to this step only, so the name and email steps keep the
   spacing they already have. */
.wizard__step:has(.choice-group--inline) {
  gap: 0.3rem;
}
.wizard__step:has(.choice-group--inline) .wizard__q {
  margin-bottom: 0;
  line-height: 1.35;
}

/* The hero's text column is an auto grid track, so it grows to the widest
   UNWRAPPED line inside it. The product testing question is long enough to
   stretch that track to its 64rem cap, which left a wide empty strip between
   the answers and the phone even though the text itself wrapped much earlier.
   Capping the question keeps the track the same width as the form. */
.wizard__q {
  max-width: 35rem;
}

/* ============================================================
   LIGHT THEME (default)
   ============================================================
   The site was built dark: `--bg` was near-black and roughly fifty rules paint
   white text or white hairlines directly rather than through a token. Flipping
   the tokens alone would have left all of those white on a light page.

   Rather than rewrite those rules in place, this block re-states the ones that
   sit on the page canvas. The modal keeps its own dark panel and is deliberately
   left alone: a dark sheet over a light page is intentional, and it owns about
   thirty of those white rules.

   Delete this block and restore the four tokens at the top to go back to dark.
   ============================================================ */

/* The ash artwork carries its own diagonal ribbons, so it replaces the hand
   built .beam elements rather than sitting behind them. */
html {
  background: var(--bg) url("../images/bg-light.svg") center / cover no-repeat fixed;
}
body {
  background: transparent;
}
.bg-layer {
  display: none;
}

/* The faint grid was white-on-black. Same idea, inverted. */
.page::before {
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.035) 1px, transparent 1px),
    linear-gradient(0deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px);
}

/* Type on the canvas */
.title,
.brand__name,
.topbar .brand__name,
.waitlist h2,
.follow h2 {
  color: var(--ink);
}
.subtitle,
.privacy-note,
.social__label,
.footer {
  color: var(--muted);
}

/* Controls. The outlined buttons were a white hairline on black; on a light
   canvas they need an ink edge or they disappear. */
.btn {
  color: var(--ink);
  background: rgba(0, 0, 0, 0.04);
}
.btn--outline {
  border-color: rgba(0, 0, 0, 0.22);
}
.btn--download {
  color: #0f5c33;
  background: rgba(25, 195, 107, 0.14);
  border-color: rgba(25, 195, 107, 0.55);
}
.btn--primary,
.subscribe__btn {
  /* Brand yellow with dark ink, as in the design. */
  color: #12141a;
}

/* The email field was a dark well with a white hairline. */
.subscribe__field {
  border-color: rgba(0, 0, 0, 0.22);
  background: rgba(255, 255, 255, 0.75);
  box-shadow: none;
}
.input {
  color: var(--ink);
}
.input::placeholder {
  color: rgba(18, 20, 26, 0.45);
}
.subscribe__icon,
.privacy-note svg,
.icon--muted {
  color: var(--muted);
}

/* Inline status messages sat on a dark page. */
.message {
  color: var(--ink);
  background: rgba(0, 0, 0, 0.05);
}

/* Social row divider */
.social::after {
  background: rgba(0, 0, 0, 0.16);
}

/* `.page` painted its own full-screen dark gradient and `.page::after` laid a
   dark vignette over everything. Both sat above the html background, so the ash
   artwork was completely hidden until these were cleared. The topbar had a dark
   scrim for the same reason. */
.page {
  background: transparent;
}
.page::after {
  background:
    linear-gradient(90deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0.05) 44%, transparent),
    radial-gradient(circle at center, transparent 55%, rgba(255, 255, 255, 0.25) 100%);
}
.topbar::before {
  background: linear-gradient(180deg, rgba(242, 243, 245, 0.9) 0%, rgba(242, 243, 245, 0.45) 52%, transparent 100%);
}

/* Fade above the footer was black. The phone and the modal keep their own dark
   surfaces on purpose, so they are not touched. */
.footer::before {
  background: linear-gradient(180deg, transparent 0%, rgba(242, 243, 245, 0.72) 46%, #f2f3f5 100%);
}

/* ============================================================
   HERO, laid out to the design
   ============================================================ */

/* Copy left, figures right, the pair centred as one block. */
.hero {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: clamp(1rem, 3vw, 3rem);
}

/* ── headline ─────────────────────────────────────────────── */
/* The old rule shouted the whole headline in caps with wide tracking. In the
   design only "SOON" is uppercase; the two lines are sentence case. */
.title {
  color: var(--ink);
  text-transform: none;
  letter-spacing: -0.01em;
  gap: 0.35rem;
}
.title__lead {
  font-size: clamp(0.95rem, 1.15vw, 1.25rem);
  font-weight: 400;
  color: var(--muted);
}
.title__main {
  font-size: clamp(1.5rem, 3.2vw, 2.9rem);
  font-weight: 700;
  line-height: 1.15;
}
/* Blue through magenta to gold, left to right across the word. */
.title__gradient {
  text-transform: uppercase;
  font-weight: 800;
  background: linear-gradient(90deg, #1755ed 0%, #7b2ff7 26%, #ff1680 55%, #ff7a18 82%, #ffd31a 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.title__dot {
  color: var(--ink);
  -webkit-text-fill-color: var(--ink);
}

/* ── join the waiting list ────────────────────────────────── */
.waitlist__title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: clamp(1rem, 2vw, 1.6rem);
}
.waitlist__title h2 {
  margin: 0;
  color: var(--ink);
  font-size: clamp(0.85rem, 1.05vw, 1.05rem);
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* Gold bell, filled, as in the design. */
.waitlist__bell {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  fill: var(--yellow);
  stroke: var(--yellow);
  stroke-width: 1.5;
}
.waitlist__copy {
  margin: 0.5rem 0 0;
  color: var(--muted);
  font-size: clamp(0.9rem, 1.05vw, 1.05rem);
}

/* ── the three actions ────────────────────────────────────── */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.65rem;
  margin-top: clamp(0.9rem, 1.8vw, 1.4rem);
}
.hero__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 2.9rem;
  padding: 0.6rem 1.15rem;
  border: 2px solid transparent;
  border-radius: 0.3rem;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform 0.16s ease, filter 0.16s ease;
}
.hero__btn:hover {
  transform: translateY(-1px);
  filter: brightness(1.04);
}
.hero__btn .icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Solid gold, dark label. The one primary action. */
.hero__btn--subscribe {
  background: var(--yellow);
  border-color: var(--yellow);
  color: #12141a;
}
.hero__btn--subscribe .icon {
  stroke-width: 2.4;
}
/* White with a blue edge. */
.hero__btn--report {
  background: #fff;
  border-color: var(--blue);
  color: #12141a;
}
/* White with a red edge, and a filled play head. */
.hero__btn--podcast {
  background: #fff;
  border-color: #e01e37;
  color: #12141a;
}
.hero__btn--podcast .icon path {
  fill: currentColor;
  stroke: none;
}

/* ── the two figures ──────────────────────────────────────── */
/* They stand on the bottom edge of the hero and overlap slightly, the man in
   front. Cropped by the hero rather than scaled down, as in the design. */
.hero__figures {
  position: relative;
  align-self: end;
  justify-self: end;
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 100%;
  min-height: 0;
  pointer-events: none;
}
.hero__figure {
  display: block;
  width: auto;
  max-width: none;
  height: min(78vh, 46rem);
  object-fit: contain;
  object-position: bottom;
  filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.35));
}
.hero__figure--man {
  position: relative;
  z-index: 2;
  margin-right: -6%;
}
.hero__figure--woman {
  position: relative;
  z-index: 1;
}

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
  }
  .hero__figures {
    justify-self: center;
    order: 2;
  }
  .hero__figure {
    height: min(42vh, 24rem);
  }
  .hero__actions {
    width: 100%;
  }
  .hero__btn {
    flex: 1 1 auto;
  }
}

/* ============================================================
   TYPE, to the design's measurements
   ============================================================
   Sizes were given in points. At 96dpi 1pt = 4/3px, so:
     10.45pt = 13.933px = 0.8708rem
     18.2pt  = 24.267px = 1.5167rem
     10.2pt  = 13.6px   = 0.85rem

   Poppins everywhere, including form controls, which inherit from the browser
   rather than the page unless told otherwise.

   The design size is the ceiling. Below roughly 900px the headline steps down
   so it does not run off a phone, which is what the old clamp was protecting
   against. Everything else holds its stated size. */
body,
button,
input,
textarea,
select,
option {
  font-family: var(--font-sans);
}

.title__lead {
  font-size: 0.8708rem;   /* 10.45pt */
  font-weight: 400;
}
.title__main {
  font-size: 1.5167rem;   /* 18.2pt */
  font-weight: 600;
  line-height: 1.25;
}
.waitlist__title h2 {
  font-size: 0.85rem;     /* 10.2pt */
  font-weight: 600;
}
.waitlist__copy {
  font-size: 0.8708rem;   /* matches the lead line */
  font-weight: 400;
}
.hero__btn {
  font-size: 0.72rem;
  font-weight: 600;
}

@media (max-width: 900px) {
  .title__main {
    font-size: clamp(1.15rem, 4.6vw, 1.5167rem);
  }
}

/* ============================================================
   BACKGROUND, layered to match the design
   ============================================================
   The artwork is three files, not one. `ash_background.svg` is only the pale
   base: four rects and a single polygon, which is why on its own the page looked
   almost blank. The colour lives in `background.svg`, thirteen polygons in blue,
   red, orange and yellow, with `blur_background.svg` as the faded set.

   Stacked back to front: base, soft ribbons anchored left, vivid ribbons
   anchored right. The middle stays clear, which is where the copy sits. */
html {
  background:
    url("../images/bg-ribbons.svg") right center / auto 100% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left center / auto 108% no-repeat fixed,
    url("../images/bg-light.svg") center center / cover no-repeat fixed,
    var(--bg);
}

/* ============================================================
   HERO CORRECTIONS against the design
   ============================================================ */

/* The headline sits on one line in the design. The base .title rule still
   carried a clamp that overrode the point size, so it is pinned here. */
.title .title__main {
  font-size: 1.5167rem;   /* 18.2pt */
  line-height: 1.3;
  letter-spacing: -0.005em;
}
.title .title__lead {
  font-size: 0.8708rem;   /* 10.45pt */
  line-height: 1.5;
}

/* All three actions stay on one row, as in the design. */
.hero__actions {
  flex-wrap: nowrap;
}
.hero__btn {
  min-height: 2.5rem;
  padding: 0.5rem 0.95rem;
  white-space: nowrap;
}

/* The figures stand clean against the artwork. The drop shadow was reading as a
   dark box behind them because the page clips at the fold. */
.hero__figure {
  filter: none;
}

/* Give the copy room and stop it stretching across the whole column. */
.hero__content {
  max-width: 34rem;
}

@media (max-width: 760px) {
  .hero__actions {
    flex-wrap: wrap;
  }
}

/* ============================================================
   DARK, and the pattern moved to the top left
   ============================================================
   Supersedes the light block above. Most of that block points at --ink and
   --muted, so it followed the tokens back to dark on its own. Only the rules
   that hardcoded light values are restated here.

   The soft pattern used to sit at left centre, which put it under the figures.
   It is anchored past the top left corner instead, so it bleeds off both edges
   and only the lower right of the shape is on screen. */
html {
  background:
    url("../images/bg-ribbons.svg") right center / auto 100% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

/* Vignette and grid go back to light-on-dark. */
.page::before {
  background:
    linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px),
    linear-gradient(0deg, rgba(255, 255, 255, 0.022) 1px, transparent 1px);
}
.page::after {
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.45), transparent 46%),
    radial-gradient(circle at center, transparent 55%, rgba(0, 0, 0, 0.35) 100%);
}
.footer::before {
  background: linear-gradient(180deg, transparent 0%, rgba(5, 7, 38, 0.7) 46%, #050726 100%);
}

/* Controls that had light-only values. The two outlined hero buttons stay white
   with coloured edges, which is how the dark design shows them. */
.btn {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.035);
}
.btn--outline {
  border-color: rgba(255, 255, 255, 0.24);
}
.btn--download {
  color: #fff;
  background: rgba(25, 195, 107, 0.16);
  border-color: rgba(25, 195, 107, 0.75);
}
.subscribe__field {
  border-color: rgba(255, 255, 255, 0.42);
  background: rgba(0, 0, 0, 0.36);
}
.input::placeholder {
  color: rgba(255, 255, 255, 0.5);
}
.message {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
}
.social::after {
  background: rgba(255, 255, 255, 0.18);
}

/* ============================================================
   FIGURE SIZE AND SPACING
   ============================================================
   They were sized off viewport height, so on a short window the heads clipped
   against the top edge. Sized off viewport width instead, with a height cap so
   they still fit on a short screen, and pushed together so the pair reads as
   one group rather than two separate cut-outs. */
.hero__figure {
  height: min(28vw, 60vh);
  width: auto;
}
/* Negative margin pulls the woman in behind the man's shoulder. */
.hero__figure--man {
  margin-right: -13%;
}

/* Bottom aligned, so shrinking them drops the heads away from the top edge
   rather than leaving them floating. */
.hero__figures {
  align-items: flex-end;
  align-self: end;
  padding-bottom: 0;
}

@media (max-width: 900px) {
  .hero__figure {
    height: min(46vw, 34vh);
  }
  .hero__figure--man {
    margin-right: -12%;
  }
}

/* ============================================================
   PASS AGAINST THE DESIGN
   ============================================================ */

/* The headline reads light in the design, not bold. Only SOON carries weight. */
.title .title__main {
  font-weight: 400;
}
.title .title__gradient {
  font-weight: 700;
}

/* The lead line sits a touch larger than the 10.45pt it was set to. */
.title .title__lead {
  font-size: 0.95rem;
}

/* The headline and the waiting-list line were too far apart. */
.waitlist__title {
  margin-top: 0.55rem;
}
.waitlist__copy {
  margin-top: 0.35rem;
}
.hero__actions {
  margin-top: 0.9rem;
}
.hero__btn {
  font-size: 0.7rem;
}

/* ── figures ──────────────────────────────────────────────────
   Bigger, and pushed together far enough that they meet at the hoodies rather
   than leaving a gap at the shoulders.

   The pair also runs past the bottom of the hero and behind the footer, which
   sits on a higher layer, so the cut-off edge of the artwork is never visible.
   `.page` clips whatever is left. */
.hero__figure {
  height: min(36vw, 86vh);
}
.hero__figure--man {
  margin-right: -21%;
}
.hero__figures {
  margin-bottom: clamp(-5rem, -7vh, -2.5rem);
  overflow: visible;
}

/* ── ribbon artwork ───────────────────────────────────────────
   Scaled past the viewport so it runs off the top and the bottom instead of
   sitting inside the frame, and anchored right as in the design. */
html {
  background:
    url("../images/bg-ribbons.svg") right -4% center / auto 132% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

@media (max-width: 900px) {
  .hero__figure {
    height: min(52vw, 40vh);
  }
  .hero__figure--man {
    margin-right: -18%;
  }
  .hero__figures {
    margin-bottom: -1.5rem;
  }
}

/* ============================================================
   SECOND PASS AGAINST THE DESIGN
   ============================================================ */

/* Footer hidden, not removed. The markup, the social links and the copyright
   are all still in the page; only the display is off, so bringing it back is
   one line. The figures now run past the bottom of the window and `.page`
   clips them, so their lower edge is never visible. */
.footer {
  display: none;
}

/* ── the container ────────────────────────────────────────────
   Narrower than the full window, centred, so there is real margin on the left
   before the copy and on the right after the woman. */
.hero {
  width: min(100%, 96rem);
  padding-left: clamp(1.5rem, 5vw, 5rem);
  padding-right: clamp(1.5rem, 5vw, 5rem);
  align-items: center;
}

/* ── figures ──────────────────────────────────────────────────
   They were laid out from the left of their column with no justification, so
   the pair overflowed off the RIGHT edge of the screen and the woman was cut.
   Aligned to the end instead: any overflow now runs left, behind the copy,
   and the right hand margin is kept. */
.hero__figures {
  justify-content: flex-end;
  margin-bottom: clamp(-9rem, -12vh, -4rem);
}

/* Closer still, so the hoodies meet rather than leaving a gap between the
   man's shoulder and the woman's arm. */
.hero__figure--man {
  margin-right: -29%;
}

/* ── ribbon artwork ───────────────────────────────────────────
   At `auto 132%` the artwork was about 90% of the window wide, because the file
   is half again as wide as it is tall. That is why it was running across the
   copy. Sized by width instead and pinned right, so it covers the figures and
   leaves the text column clear, while still bleeding off the top and bottom. */
html {
  background:
    url("../images/bg-ribbons.svg") right center / 60% 140% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

/* ── buttons, smaller again ───────────────────────────────── */
.hero__btn {
  min-height: 2.2rem;
  padding: 0.42rem 0.8rem;
  font-size: 0.64rem;
  gap: 0.4rem;
}
.hero__btn .icon {
  width: 15px;
  height: 15px;
}
.hero__actions {
  gap: 0.5rem;
}

@media (max-width: 900px) {
  .hero {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
  .hero__figures {
    justify-content: center;
    margin-bottom: -2rem;
  }
  .hero__figure--man {
    margin-right: -24%;
  }
  html {
    background:
      url("../images/bg-ribbons.svg") right center / 92% 120% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   RIBBONS ANCHORED TOP RIGHT
   ============================================================
   It was pinned to `right center` at 140% tall, so a fifth of the artwork was
   cut off above the window and the top right corner sat empty. Anchored to the
   top right instead, mirroring the soft pattern in the top left corner, and
   scaled up so it runs the full height and past the bottom edge. */
html {
  background:
    url("../images/bg-ribbons.svg") right top / 66% 116% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

@media (max-width: 900px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right top / 96% 100% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   RIBBONS: OVERFLOW THE TOP RIGHT CORNER
   ============================================================
   The left pattern is pushed past its corner with negative offsets, so part of
   it is hidden off screen. The right one was sitting neatly inside the corner
   instead, which is why it read as small and boxed in.

   Same treatment now, mirrored. `right -20vw` puts its right edge twenty
   viewport widths' worth past the right side and `top -14vh` lifts it above the
   top, so the top right of the artwork is cut off by the window. What is left
   on screen is the lower left of the pattern, which runs down past the bottom
   edge, and its inner edge lands clear of the headline. */
html {
  background:
    url("../images/bg-ribbons.svg") right -20vw top -14vh / 62% 140% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

@media (max-width: 900px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -18vw top -8vh / 96% 118% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   RIBBONS: STOP HIDING THE DENSE HALF
   ============================================================
   Measured the file rather than guessing again. The ink fills the whole
   697x471 viewBox, but it is not evenly spread: the busiest shapes sit in the
   upper right, roughly x 391-697 of 697.

   The previous `right -20vw` pushed that entire cluster off the side of the
   window, so what stayed on screen was the sparser left half of the artwork.
   That is why the top right corner looked empty no matter how much the size
   went up.

   Pulled almost flush to the right edge now, so the dense corner is on screen,
   and lifted so it runs off the top. */
html {
  background:
    url("../images/bg-ribbons.svg") right -2vw top -12vh / 62% 138% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

@media (max-width: 900px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -2vw top -8vh / 92% 120% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* Back to the previous placement, with the top offset increased so it rides up
   off the top edge the same way the left pattern does. Left uses top -22%; the
   right now matches it. */
html {
  background:
    url("../images/bg-ribbons.svg") right -20vw top -22% / 62% 140% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

@media (max-width: 900px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -18vw top -22% / 96% 118% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* Percentage offsets resolve against (container - image). The artwork is taller
   than the window, so that figure is negative and `top: -22%` pushed it DOWN
   rather than up. That is the opposite of the left pattern, where the artwork
   is shorter than the window and the same -22% lifts it.

   Fixed lengths behave the same way whatever the size, so the vertical offset
   is in vh. -24vh lifts it clear off the top. */
html {
  background:
    url("../images/bg-ribbons.svg") right -20vw top -24vh / 62% 140% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

@media (max-width: 900px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -18vw top -12vh / 96% 118% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   SCALE UP
   ============================================================
   Same placement and character as now, just bigger. Width goes 62% -> 80% and
   height 140% -> 170%, with the right offset opened to -22vw so the inner edge
   still lands clear of the headline at about 42% across. */
html {
  background:
    url("../images/bg-ribbons.svg") right -22vw top -30vh / 80% 170% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

/* Figures fill more of the vertical space, closing the gap above the heads and
   below. Sized off viewport WIDTH, so they hold their proportion of the layout
   at every desktop size rather than shrinking on a short window. The height cap
   is deliberately loose: their lower half is hidden below the fold anyway, so
   overshooting costs nothing. */
.hero__figure {
  height: min(42vw, 112vh);
}

@media (max-width: 900px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -18vw top -12vh / 110% 130% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
  .hero__figure {
    height: min(58vw, 46vh);
  }
}

/* Figures back to the size they were before. Scaling them was my mistake:
   "scale" meant the pattern behind them, not the people. */
.hero__figure {
  height: min(36vw, 86vh);
}

/* Pattern up and a little bigger. `top` goes -30vh -> -44vh so more of it rides
   off the top edge, and the size goes 80%/170% -> 86%/184%. The right offset
   opens to -28vw at the same time so the inner edge still lands at about 42%
   across, which is where it sits now and reads correctly against the headline. */
html {
  background:
    url("../images/bg-ribbons.svg") right -28vw top -44vh / 86% 184% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

@media (max-width: 900px) {
  .hero__figure {
    height: min(52vw, 40vh);
  }
  html {
    background:
      url("../images/bg-ribbons.svg") right -20vw top -18vh / 118% 140% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* Same scale, lifted further. Only the top offset changes: -44vh -> -62vh, so
   more of the upper part of the artwork sits above the window. Size and the
   right offset are untouched, so the inner edge stays where it is. */
html {
  background:
    url("../images/bg-ribbons.svg") right -28vw top -62vh / 86% 184% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

/* A little further up, and pulled back in from the right so less of it is lost
   off that edge: top -62vh -> -70vh, right -28vw -> -24vw. Size unchanged. */
html {
  background:
    url("../images/bg-ribbons.svg") right -24vw top -70vh / 86% 184% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

/* Down a touch from the top, and eased back in from the right:
   top -70vh -> -64vh, right -24vw -> -27vw. Size unchanged. */
html {
  background:
    url("../images/bg-ribbons.svg") right -27vw top -64vh / 86% 184% no-repeat fixed,
    url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
    url("../images/bg-dark.svg") center center / cover no-repeat fixed,
    var(--bg);
}

/* ============================================================
   RESPONSIVE
   ============================================================
   The type was set in fixed rem and the figures in raw vw. That pair only
   agreed at one window size. On a 2400px screen the copy stayed tiny while the
   figures grew past 850px and ran over it; on a 1200px screen the layout emptied
   out. Both now scale from the same viewport width, with floors and ceilings.

   The point sizes from the design hold at 1920: 18.2pt is 24.27px, which is
   1.264vw of 1920. That is the middle value of the headline clamp, so the design
   is matched exactly at its own width and scales either side of it. */

.title .title__lead {
  font-size: clamp(0.86rem, 0.73vw, 1.3rem);
}
.title .title__main {
  font-size: clamp(1.2rem, 1.264vw, 2.3rem);
}
.waitlist__title h2 {
  font-size: clamp(0.78rem, 0.708vw, 1.15rem);
}
.waitlist__copy {
  font-size: clamp(0.82rem, 0.7vw, 1.2rem);
}
.hero__btn {
  font-size: clamp(0.62rem, 0.55vw, 0.92rem);
  min-height: clamp(2.2rem, 2.4vw, 3.1rem);
  padding: 0.5rem clamp(0.8rem, 1vw, 1.5rem);
}
.hero__btn .icon {
  width: clamp(14px, 1vw, 20px);
  height: clamp(14px, 1vw, 20px);
}
.waitlist__bell {
  width: clamp(18px, 1.15vw, 28px);
  height: clamp(18px, 1.15vw, 28px);
}

/* Capped in rem as well as vw, so on a very wide screen they stop growing and
   stop crossing the copy. */
.hero__figure {
  height: min(36vw, 86vh, 44rem);
}

/* ── tablet and small laptop ─────────────────────────────── */
@media (max-width: 1180px) {
  .hero {
    gap: 1.5rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
  }
  .hero__figure {
    height: min(42vw, 70vh);
  }
  .hero__figures {
    margin-bottom: clamp(-4rem, -6vh, -1.5rem);
  }
}

/* ── mobile: stacked, figures on top ─────────────────────────
   Structure taken from the phone mockup: art first, then the headline, the
   waiting-list line, and the actions stacked full width. No logo and no extra
   strapline, per the brief. */
@media (max-width: 900px) {
  .page {
    height: auto;
    min-height: 100svh;
    overflow-x: hidden;
  }
  .hero {
    grid-template-columns: 1fr;
    justify-content: stretch;
    align-content: start;
    gap: 0;
    padding: 1.25rem 1.35rem 2.5rem;
  }

  /* Art above the copy. */
  .hero__figures {
    order: -1;
    justify-content: center;
    align-self: center;
    margin-bottom: 1.5rem;
    overflow: hidden;
    border-radius: 14px;
  }
  .hero__figure {
    height: min(64vw, 40vh);
  }
  .hero__figure--man {
    margin-right: -16%;
  }

  .hero__content {
    max-width: none;
  }
  .title .title__lead {
    font-size: 0.85rem;
  }
  .title .title__main {
    font-size: clamp(1.35rem, 6.4vw, 2rem);
    line-height: 1.2;
  }
  .waitlist__title h2 {
    font-size: 0.8rem;
  }
  .waitlist__copy {
    font-size: 0.85rem;
  }

  /* Actions stack and fill the width, as in the mockup. */
  .hero__actions {
    flex-direction: column;
    align-items: stretch;
    gap: 0.55rem;
    margin-top: 1.1rem;
  }
  .hero__btn {
    width: 100%;
    min-height: 2.9rem;
    font-size: 0.72rem;
  }
}

@media (max-width: 520px) {
  .hero__figure {
    height: min(72vw, 36vh);
  }
}

/* ============================================================
   ROOT-CAUSE FIX: FIGURES SIZED BY THEIR COLUMN, NOT BY HEIGHT
   ============================================================
   Every earlier attempt set `.hero__figure { height: <vw|vh> }` and left width
   to `auto`. Nothing then constrained how wide the PAIR became, so at desktop
   sizes it measured ~1070px inside a ~680px column and the excess spilled left
   across the copy, because the group is justified to the end.

   Sized as a share of the column instead. The two widths plus the negative
   overlap add up to exactly 100%, so the pair can never be wider than the space
   it has, at any window size. Height follows from the aspect ratio.

     man   65.6%  +  woman 53.4%  -  overlap 19%  =  100%

   The column ratio 1 : 1.38 is set so the resulting height lands at roughly the
   660px that was approved on a 1920 screen. */
.hero {
  width: min(100%, 120rem);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.38fr);
}

.hero__figures {
  width: 100%;
  min-width: 0;
  justify-content: flex-end;
  align-items: flex-end;
  overflow: visible;
}

.hero__figure {
  height: auto;
  max-width: none;
  flex: 0 0 auto;
}
.hero__figure--man {
  width: 65.6%;
  margin-right: -19%;
}
.hero__figure--woman {
  width: 53.4%;
  margin-right: 0;
}

@media (max-width: 1180px) {
  .hero {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  }
  .hero__figure {
    height: auto;
  }
}

@media (max-width: 900px) {
  .hero__figures {
    justify-content: center;
    width: min(100%, 26rem);
    margin-inline: auto;
  }
  .hero__figure--man {
    width: 62%;
    margin-right: -16%;
  }
  .hero__figure--woman {
    width: 54%;
  }
  .hero__figure {
    height: auto;
  }
}

/* ============================================================
   FIGURES: CONSTANT HEIGHT, ANCHORED, NEVER RESIZED BY WIDTH
   ============================================================
   While they were a grid item their size had to be negotiated against the copy,
   so narrowing the window shrank them. Taken out of the flow entirely: they are
   now pinned to the bottom right of the hero and sized purely off viewport
   HEIGHT, so they hold exactly the same proportion of the screen at 1200px wide
   or 2560px wide.

   `.page` already has overflow:hidden, so as the window narrows the pair simply
   crops against the right edge instead of scaling down. The copy sits on a
   higher layer and keeps its own width, so it is never pushed.

   The overlap is in vh too, not a percentage, so it tracks the height and the
   hoodies stay joined at every size. 19% of the man's width works out at
   0.193 x height, hence -14.3vh against a 74vh figure. */
.hero {
  display: flex;
  align-items: center;
  position: relative;
}

.hero__content {
  position: relative;
  z-index: 4;
  max-width: min(42rem, 54%);
}

.hero__figures {
  position: absolute;
  right: clamp(0.5rem, 3vw, 4rem);
  bottom: -5vh;
  left: auto;
  top: auto;
  z-index: 1;
  width: auto;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  margin: 0;
  pointer-events: none;
}

.hero__figure {
  height: 74vh;
  width: auto;
  max-width: none;
  flex: 0 0 auto;
}
.hero__figure--man {
  width: auto;
  margin-right: -14.3vh;
}
.hero__figure--woman {
  width: auto;
  margin-right: 0;
}

@media (max-width: 1180px) {
  .hero__figure {
    height: 68vh;
  }
  .hero__figure--man {
    margin-right: -13.1vh;
  }
  .hero__content {
    max-width: min(34rem, 58%);
  }
}

/* Below this the layout stacks, so they go back into the flow. */
@media (max-width: 900px) {
  .hero {
    display: grid;
  }
  .hero__figures {
    position: static;
    order: -1;
    width: min(100%, 26rem);
    margin: 0 auto 1.5rem;
    justify-content: center;
  }
  .hero__figure {
    height: auto;
    width: 62%;
  }
  .hero__figure--man {
    width: 62%;
    margin-right: -16%;
  }
  .hero__figure--woman {
    width: 54%;
  }
  .hero__content {
    max-width: none;
  }
}

/* ============================================================
   FIGURES: ANCHOR THE LEFT EDGE, NOT THE RIGHT
   ============================================================
   Pinning `right` meant the pair grew LEFTWARD as it got wider relative to the
   window, so on a 1743px screen it reached 214px into the copy and the headline
   landed on the man's face.

   Pinned by `left` instead, at a point past where the copy ends. The pair keeps
   its constant height, and any width it cannot fit now runs off the RIGHT edge
   and is cropped by `.page`. The copy is never touched at any width.

   Height raised 74vh -> 84vh as well: at 74 the heads started 31% down the
   screen and left a dead band across the top. */
.hero__figures {
  left: 47%;
  right: auto;
  bottom: -6vh;
}

.hero__figure {
  height: 84vh;
}
.hero__figure--man {
  margin-right: -16.2vh;   /* same 19% of the man's width, tracked in vh */
}

@media (max-width: 1180px) {
  .hero__figures {
    left: 44%;
  }
  .hero__figure {
    height: 78vh;
  }
  .hero__figure--man {
    margin-right: -15vh;
  }
}

/* The copy width and the figures' left edge are now on the same axis, so the
   gap between them cannot close at any width. Copy takes at most 40vw and the
   figures begin at 46vw, leaving 6vw of clear space between them always. */
.hero__content {
  max-width: min(42rem, 40vw);
}
.hero__figures {
  left: 46%;
}

@media (max-width: 1180px) {
  .hero__content {
    max-width: min(34rem, 40vw);
  }
  .hero__figures {
    left: 46%;
  }
}

@media (max-width: 900px) {
  .hero__content {
    max-width: none;
  }
}

/* The original .hero rule (line ~205) still carried `justify-content: center`
   from when the hero was a two-column grid holding the copy and a phone. Once
   the figures were pulled out of the flow, the copy became the only flex child,
   so that declaration CENTRED it: it started 536px in instead of at the left
   padding, and ran 406px into the figures.

   Every measurement I took assumed it was left aligned. This is the one
   declaration that made all of them wrong. */
.hero {
  justify-content: flex-start;
  align-items: center;
  gap: 0;
}

/* ============================================================
   BACK TO THE APPROVED COMPOSITION
   ============================================================
   Anchoring by `left: 46%` pushed the pair right and cropped the woman against
   the window edge. The composition that was approved has her fully visible with
   a margin from the right, so the anchor goes back to `right`.

   Height back to 70vh from 84vh, which is what put the heads about a quarter of
   the way down rather than near the top. */
.hero__figures {
  right: clamp(1rem, 3vw, 4rem);
  left: auto;
  bottom: -4vh;
}

.hero__figure {
  height: 70vh;
}
.hero__figure--man {
  margin-right: -13.5vh;
}

@media (max-width: 1180px) {
  .hero__figures {
    right: clamp(0.5rem, 2vw, 2rem);
    left: auto;
  }
  .hero__figure {
    height: 64vh;
  }
  .hero__figure--man {
    margin-right: -12.3vh;
  }
}

/* ============================================================
   STACKED LAYOUT FROM 1700px DOWN
   ============================================================
   The side-by-side hero needs roughly 1900px to seat the figures beside the
   copy without the two meeting. Below that it was always going to be a
   compromise, and squarish windows around 1600 were the worst of it.

   So it stops compromising and switches instead: below 1700 the page takes the
   stacked shape from the phone mockup, art in a framed box on top and the copy
   underneath. That treatment then carries all the way down to a phone, with
   only the box size and the button stacking changing.

   Above 1700 the approved side-by-side composition is untouched. */
@media (max-width: 1700px) {
  .page {
    height: auto;
    min-height: 100svh;
    overflow-x: hidden;
  }

  .hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0;
    padding: clamp(1.5rem, 4vh, 3rem) clamp(1.5rem, 5vw, 4rem) clamp(2rem, 5vh, 3.5rem);
    width: min(100%, 60rem);
  }

  /* The art sits in a framed box, as in the mockup, rather than floating cut
     out on the page. Bottom aligned inside it so the figures stand on the
     lower edge and the crop reads as deliberate. */
  .hero__figures {
    position: static;
    order: -1;
    width: min(100%, 34rem);
    aspect-ratio: 16 / 10;
    margin: 0 auto clamp(1.25rem, 3vh, 2rem);
    border-radius: 16px;
    overflow: hidden;
    background:
      linear-gradient(160deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.02) 60%),
      rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    inset: auto;
  }

  .hero__figure {
    height: 96%;
    width: auto;
    max-width: none;
  }
  .hero__figure--man {
    margin-right: -9%;
  }
  .hero__figure--woman {
    margin-right: 0;
  }

  .hero__content {
    max-width: min(34rem, 100%);
    width: 100%;
    text-align: left;
  }

  .title .title__lead {
    font-size: 0.9rem;
  }
  .title .title__main {
    font-size: clamp(1.35rem, 2.6vw, 1.9rem);
    line-height: 1.25;
  }
  .waitlist__title h2 {
    font-size: 0.82rem;
  }
  .waitlist__copy {
    font-size: 0.88rem;
  }

  .hero__actions {
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-top: 1.1rem;
  }
  .hero__btn {
    min-height: 2.7rem;
    font-size: 0.7rem;
  }
}

/* Phone: box gets wider relative to the screen, actions stack full width. */
@media (max-width: 640px) {
  .hero {
    padding: 1.25rem 1.25rem 2rem;
  }
  .hero__figures {
    width: 100%;
    aspect-ratio: 4 / 3;
    border-radius: 14px;
  }
  .hero__content {
    max-width: none;
  }
  .title .title__main {
    font-size: clamp(1.3rem, 6.6vw, 1.75rem);
  }
  .hero__actions {
    flex-direction: column;
    align-items: stretch;
  }
  .hero__btn {
    width: 100%;
    min-height: 2.9rem;
    font-size: 0.74rem;
  }
}

/* ============================================================
   SIDE-BY-SIDE HOLDS DOWN TO 800px
   ============================================================
   The stacked layout was starting at 1700, which meant a normal laptop got the
   phone treatment. It now holds the desktop composition all the way down to
   800px and only stacks below that.

   To make that possible the figures scale with viewport WIDTH below the point
   where there is no longer room beside the copy. That is the trade: the layout
   stays consistent across every desktop and tablet size, and the price is that
   the pair gets smaller as the window narrows rather than colliding with the
   copy or cropping the woman off the edge.

     copy   at most 36vw
     figure height  min(70vh, 33vw)   -> pair width 1.649 x that
     the two never meet at any width from 800 to 2560. */
@media (min-width: 801px) {
  .page {
    height: 100svh;
    overflow: hidden;
  }
  .hero {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    width: min(100%, 120rem);
    padding: clamp(0.6rem, 1.4vw, 1.6rem) clamp(1.5rem, 5vw, 5rem) clamp(1rem, 2vw, 2.2rem);
  }
  .hero__content {
    max-width: min(42rem, 36vw);
    width: auto;
  }
  .hero__figures {
    position: absolute;
    right: clamp(0.75rem, 3vw, 4rem);
    left: auto;
    bottom: -4vh;
    order: 0;
    width: auto;
    aspect-ratio: auto;
    background: none;
    border-radius: 0;
    overflow: visible;
    margin: 0;
  }
  .hero__figure {
    height: min(70vh, 33vw);
    width: auto;
  }
  .hero__figure--man {
    margin-right: -19.3%;
  }
}

/* ── stacked, 800px and below ─────────────────────────────── */
@media (max-width: 800px) {
  /* Breathing room either side of the framed art, it was hard against the
     window edge. */
  .hero {
    padding-left: clamp(1.25rem, 6vw, 2.5rem);
    padding-right: clamp(1.25rem, 6vw, 2.5rem);
  }
  .hero__figures {
    width: 100%;
    max-width: 30rem;
  }

  /* No top-left pattern here, and the right one runs the full height of the
     screen, as in the phone mockup. */
  html {
    background:
      url("../images/bg-ribbons.svg") right -10vw top 0 / auto 100% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   FINAL SIZING RULE
   ============================================================
   One rule, stated once, so it stops moving around:

     - The pair is pinned to the bottom right corner. That corner never moves.
     - Above roughly 1950px there is room for full size, so it stays FIXED
       at 70vh no matter how the window changes.
     - Below that it scales gently with width, so the layout holds its shape
       all the way to 800px instead of breaking.
     - It never crops and it never touches the copy.

   The copy is capped on the same axis so the gap between them can never close. */
@media (min-width: 801px) {
  .hero__figure {
    height: min(70vh, 34vw);
  }
  .hero__content {
    max-width: min(38rem, 32vw);
  }
  .hero__figures {
    right: clamp(0.75rem, 3vw, 4rem);
    bottom: -4vh;
    left: auto;
  }
}

/* ============================================================
   MORE ROOM FOR THE FIGURES
   ============================================================
   On a short or narrow window the width cap was doing all the limiting and the
   pair ended up small, leaving a dead band above their heads.

   The copy gives up some width so the art can take it: copy 32vw -> 28vw, and
   the figure cap 34vw -> 38vw with the height ceiling raised to 78vh. Roughly
   12% more figure at every size, and the clearance still holds. */
@media (min-width: 801px) {
  .hero__figure {
    height: min(78vh, 38vw);
  }
  .hero__content {
    max-width: min(38rem, 28vw);
  }
}

/* The top-left blue pattern comes off below 1100px. At those widths it sits
   directly behind the copy and muddies it, and the mockup does not have it. */
@media (max-width: 1100px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -20vw top -30vh / 86% 150% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

@media (max-width: 800px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -10vw top 0 / auto 100% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   STEPPED SIZE BANDS, 1400px DOWN TO 800px
   ============================================================
   Smooth scaling made the pair keep shrinking all the way to the stack point.
   Instead the size steps UP at each band, so it holds a decent presence the
   whole way down.

   Two things give it the room, per band:
     1. The copy takes a smaller share (28vw -> 19vw). Short lines wrap fine.
     2. The two figures stand CLOSER (19% overlap -> 58%). The pair is 1.65x its
        height when they are apart and only 1.23x when tucked together, so this
        is where most of the room comes from.

   Result: about 480px of figure at 950px wide, against 394px on plain scaling.
   Roughly a third bigger, and it holds instead of collapsing. */

@media (max-width: 1400px) and (min-width: 1201px) {
  .hero__figure   { height: min(80vh, 42vw); }
  .hero__content  { max-width: min(38rem, 26vw); }
  .hero__figure--man { margin-right: -30%; }
}

@media (max-width: 1200px) and (min-width: 1051px) {
  .hero__figure   { height: min(80vh, 46vw); }
  .hero__content  { max-width: min(38rem, 24vw); }
  .hero__figure--man { margin-right: -40%; }
}

@media (max-width: 1050px) and (min-width: 951px) {
  .hero__figure   { height: min(80vh, 50vw); }
  .hero__content  { max-width: min(38rem, 22vw); }
  .hero__figure--man { margin-right: -48%; }
}

@media (max-width: 950px) and (min-width: 861px) {
  .hero__figure   { height: min(80vh, 55vw); }
  .hero__content  { max-width: min(38rem, 20vw); }
  .hero__figure--man { margin-right: -55%; }
}

@media (max-width: 860px) and (min-width: 801px) {
  .hero__figure   { height: min(80vh, 57vw); }
  .hero__content  { max-width: min(38rem, 19vw); }
  .hero__figure--man { margin-right: -58%; }
}

/* ============================================================
   SIMPLE AND FINAL
   ============================================================
   The stepped bands changed the overlap between the two figures per breakpoint,
   pushing it as far as 58%. That is what made the woman slide behind the man as
   the window narrowed. Wrong idea, removed.

   The overlap is now ONE value at every size. The pair always looks the same,
   only its size changes.

   And the side-by-side stops at 1100 rather than being forced down to 800.
   Below that there is genuinely not enough width for a person beside a
   paragraph, which is why every attempt at that range looked broken. It hands
   over to the stacked boxed layout instead, which already works. */

@media (min-width: 1101px) {
  .hero__figure {
    height: min(74vh, 36vw);
  }
  /* Never changes. The pair keeps its shape at every width. */
  .hero__figure--man {
    margin-right: -19%;
  }
  .hero__content {
    max-width: min(38rem, 30vw);
  }
  .hero__figures {
    right: clamp(0.75rem, 3vw, 4rem);
    bottom: -4vh;
    left: auto;
  }
}

/* Everything below 1100 uses the stacked layout with the framed art on top. */
@media (max-width: 1100px) {
  .page {
    height: auto;
    min-height: 100svh;
    overflow-x: hidden;
    overflow-y: auto;
  }
  .hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0;
    width: min(100%, 46rem);
    padding: clamp(1.5rem, 4vh, 3rem) clamp(1.5rem, 6vw, 3rem) clamp(2rem, 5vh, 3.5rem);
  }
  .hero__figures {
    position: static;
    order: -1;
    width: min(100%, 32rem);
    max-width: 32rem;
    aspect-ratio: 16 / 10;
    margin: 0 auto clamp(1.25rem, 3vh, 2rem);
    border-radius: 16px;
    overflow: hidden;
    background:
      linear-gradient(160deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.02) 60%),
      rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    inset: auto;
  }
  .hero__figure {
    height: 96%;
    width: auto;
  }
  .hero__figure--man {
    margin-right: -9%;
  }
  .hero__content {
    max-width: 32rem;
    width: 100%;
  }
  .title .title__main {
    font-size: clamp(1.35rem, 3.4vw, 1.9rem);
  }
  .hero__actions {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.6rem;
  }
  .hero__btn {
    width: auto;
    min-height: 2.7rem;
  }
}

@media (max-width: 640px) {
  .hero__figures {
    aspect-ratio: 4 / 3;
  }
  .hero__actions {
    flex-direction: column;
    align-items: stretch;
  }
  .hero__btn {
    width: 100%;
    min-height: 2.9rem;
  }
}

/* ============================================================
   BLUE PATTERN BACK ON THE NARROW VIEWS
   ============================================================ */
@media (max-width: 1100px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -14vw top -12vh / 92% 130% no-repeat fixed,
      url("../images/bg-ribbons-soft.svg") left -18% top -20% / auto 86% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}
@media (max-width: 800px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -8vw top 0 / auto 100% no-repeat fixed,
      url("../images/bg-ribbons-soft.svg") left -22% top -14% / auto 62% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   WAITLIST WIZARD AS A CENTRED OVERLAY
   ============================================================
   The questions used to open inline in the hero, so the artwork and the other
   two buttons stayed behind them and competed for attention.

   The script already flips `hidden` on the form, so `:not([hidden])` is enough
   of a hook and no JavaScript changes are needed. When it opens the form
   becomes a centred panel and its ::before lays a blurred sheet over the whole
   page, hiding the figures, the pattern and the actions.

   The panel is capped in height and scrolls internally, so it behaves on a
   short laptop and on a phone as well as on a desktop. */
#waitlistForm:not([hidden]) {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 300;
  display: grid;
  gap: 0.9rem;
  width: min(92vw, 34rem);
  max-height: min(88vh, 44rem);
  overflow-y: auto;
  padding: clamp(1.25rem, 3vw, 2rem);
  border-radius: 16px;
  background: linear-gradient(180deg, #101334, #0a0c22);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.6);
  scrollbar-width: thin;
}

/* The blurred sheet. Sits inside the panel's stacking context, behind its own
   background but above everything else on the page. */
#waitlistForm:not([hidden])::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(3, 5, 24, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

/* Inside the panel the question is the only thing that matters. */
#waitlistForm:not([hidden]) .wizard__q {
  font-size: clamp(1rem, 1.6vw, 1.3rem);
  font-weight: 700;
  line-height: 1.35;
  color: var(--ink);
  margin: 0 0 0.75rem;
}
#waitlistForm:not([hidden]) .wizard__count {
  font-size: 0.72rem;
  color: var(--muted);
}
#waitlistForm:not([hidden]) .field__input,
#waitlistForm:not([hidden]) .field__select {
  width: 100%;
  min-height: 3rem;
  font-size: 0.95rem;
}
#waitlistForm:not([hidden]) .wizard__nav {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.5rem;
}
#waitlistForm:not([hidden]) .wizard__next {
  flex: 1;
  min-height: 3rem;
}

@media (max-width: 520px) {
  #waitlistForm:not([hidden]) {
    width: calc(100vw - 2rem);
    max-height: 90vh;
  }
  #waitlistForm:not([hidden]) .wizard__nav {
    flex-direction: column-reverse;
    align-items: stretch;
  }
}

/* ============================================================
   THE REASON THE OVERLAY WAS NOT CENTRED
   ============================================================
   `.conversion` carries `.reveal`, which animates `transform: translateY()`
   with `fill-mode: forwards`. The end state is translateY(0), but that is still
   a transform, and a transformed ancestor becomes the containing block for any
   `position: fixed` descendant.

   So the panel and its backdrop were being positioned inside that small div
   rather than against the viewport: bottom of the screen, blur covering only
   its own box, figures and buttons still showing.

   Clearing the transform while the wizard is open puts the viewport back as the
   containing block. Opacity is pinned at the same time because dropping the
   animation would otherwise return the element to its `opacity: 0` start. */
.conversion:has(#waitlistForm:not([hidden])) {
  animation: none;
  transform: none;
  opacity: 1;
}

/* Belt and braces for the same trap on the wrappers between. */
.hero__content:has(#waitlistForm:not([hidden])),
.waitlist:has(#waitlistForm:not([hidden])) {
  transform: none;
  filter: none;
}

/* The sheet fades and the panel rises into place, rather than appearing. */
@keyframes wizardSheetIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes wizardPanelIn {
  from { opacity: 0; transform: translate(-50%, -46%) scale(0.97); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

#waitlistForm:not([hidden]) {
  animation: wizardPanelIn 260ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
#waitlistForm:not([hidden])::before {
  animation: wizardSheetIn 220ms ease both;
}

@media (prefers-reduced-motion: reduce) {
  #waitlistForm:not([hidden]),
  #waitlistForm:not([hidden])::before {
    animation: none;
  }
}

/* ============================================================
   THE SHEET, FIXED PROPERLY
   ============================================================
   I centred the panel with `transform: translate(-50%,-50%)` and animated that
   transform. That made the PANEL a containing block for its own `::before`, so
   the backdrop's `inset: 0` filled the panel instead of the screen and sat
   hidden behind the panel's background. The figures and the two buttons were
   never covered by anything.

   Centred with `inset: 0; margin: auto` instead, which needs no transform. The
   entrance animation is opacity only for the same reason. */
#waitlistForm:not([hidden]) {
  position: fixed;
  inset: 0;
  margin: auto;
  top: auto;
  left: auto;
  transform: none;
  width: min(92vw, 34rem);
  height: fit-content;
  max-height: min(88vh, 44rem);
  z-index: 300;
  animation: wizardPanelIn 240ms ease both;
}

/* Now that nothing above it is transformed, this really does fill the viewport. */
#waitlistForm:not([hidden])::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(3, 5, 24, 0.78);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  animation: wizardSheetIn 220ms ease both;
}

@keyframes wizardPanelIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (max-width: 520px) {
  #waitlistForm:not([hidden]) {
    width: calc(100vw - 2rem);
    max-height: 90vh;
  }
}

/* ============================================================
   HIDE THE PAGE BEHIND THE WIZARD
   ============================================================
   Covering things with a blur was the wrong answer. When the wizard opens the
   figures, the three buttons and the headline are actually hidden, so only the
   question is on screen.

   `.hero__actions` and the form are siblings inside `.waitlist`, so hiding the
   actions never touches the form. They fade rather than snap. */
.page:has(#waitlistForm:not([hidden])) .hero__figures,
.page:has(#waitlistForm:not([hidden])) .hero__actions,
.page:has(#waitlistForm:not([hidden])) .headline,
.page:has(#waitlistForm:not([hidden])) .waitlist__title,
.page:has(#waitlistForm:not([hidden])) .waitlist__copy,
.page:has(#waitlistForm:not([hidden])) .messages {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.hero__figures,
.hero__actions,
.headline,
.waitlist__title,
.waitlist__copy {
  transition: opacity 200ms ease, visibility 200ms ease;
}

/* ============================================================
   PANEL: CENTRED, NO CARD, EVEN BUTTONS
   ============================================================
   1. `inset: 0` sets all four offsets, then I overrode top and left to `auto`,
      which left only right and bottom at 0 and pinned the panel to the bottom
      right corner. All four stay at 0 so `margin: auto` can centre it.
   2. The card background, shadow and radius come off. The question sits
      directly on the blurred sheet.
   3. Continue matches Cancel instead of stretching, and the two sit apart. */
#waitlistForm:not([hidden]) {
  inset: 0;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  background: none;
  box-shadow: none;
  border-radius: 0;
  padding: 0;
  width: min(92vw, 34rem);
  height: fit-content;
}

#waitlistForm:not([hidden]) .wizard__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.25rem;
}
#waitlistForm:not([hidden]) .wizard__next,
#waitlistForm:not([hidden]) .wizard__back {
  flex: 0 0 auto;
  width: auto;
  min-width: 9.5rem;
  min-height: 2.9rem;
  padding: 0.7rem 1.4rem;
  justify-content: center;
}

@media (max-width: 520px) {
  #waitlistForm:not([hidden]) {
    width: calc(100vw - 2.5rem);
  }
  #waitlistForm:not([hidden]) .wizard__nav {
    gap: 0.75rem;
  }
  #waitlistForm:not([hidden]) .wizard__next,
  #waitlistForm:not([hidden]) .wizard__back {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* ============================================================
   WIZARD BUTTONS MATCH THE HERO BUTTONS
   ============================================================
   Same shape language as Subscribe / Download Report / Watch Podcast: 2px edge,
   0.3rem corner, uppercase at weight 800, and the same hover lift. Continue
   takes the gold primary treatment, Cancel is the quiet outlined version. */
#waitlistForm:not([hidden]) .wizard__next,
#waitlistForm:not([hidden]) .wizard__back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 2px solid transparent;
  border-radius: 0.3rem;
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: none;
  transition: transform 0.16s ease, filter 0.16s ease;
}
#waitlistForm:not([hidden]) .wizard__next:hover,
#waitlistForm:not([hidden]) .wizard__back:hover {
  transform: translateY(-1px);
  filter: brightness(1.05);
}

/* Primary, same as Subscribe for updates. */
#waitlistForm:not([hidden]) .wizard__next {
  background: var(--yellow);
  border-color: var(--yellow);
  color: #12141a;
}
#waitlistForm:not([hidden]) .wizard__next .icon {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  stroke-width: 2.4;
  fill: none;
}

/* Quiet secondary. */
#waitlistForm:not([hidden]) .wizard__back {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.35);
  color: var(--ink);
}
#waitlistForm:not([hidden]) .wizard__back:hover {
  border-color: rgba(255, 255, 255, 0.6);
}

/* The input picks up the same corner and edge treatment. */
#waitlistForm:not([hidden]) .field__input,
#waitlistForm:not([hidden]) .field__select {
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 0.3rem;
  background: rgba(255, 255, 255, 0.04);
}
#waitlistForm:not([hidden]) .field__input:focus,
#waitlistForm:not([hidden]) .field__select:focus {
  border-color: var(--yellow);
  outline: none;
}

/* ============================================================
   MOBILE WIZARD FIXES
   ============================================================
   1. An earlier rule of mine set the nav to `column-reverse` below 520px, which
      is what stacked Continue under Cancel. Forced back to a row.
   2. The panel had `overflow-y: auto`, so on a short screen it grew a scrollbar
      and that is the line running down the side. The panel sizes to its content
      instead; the page scrolls if it ever needs to.
   3. The progress track is pinned to the panel width so it cannot run past it. */
@media (max-width: 640px) {
  #waitlistForm:not([hidden]) .wizard__nav {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
  }
  #waitlistForm:not([hidden]) .wizard__next,
  #waitlistForm:not([hidden]) .wizard__back {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    padding: 0.7rem 0.9rem;
    font-size: 0.68rem;
  }
}

#waitlistForm:not([hidden]) {
  overflow: visible;
  max-height: none;
  scrollbar-width: auto;
}
#waitlistForm:not([hidden]) .wizard__progress,
#waitlistForm:not([hidden]) .wizard__track {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}
#waitlistForm:not([hidden]) .wizard__step {
  min-width: 0;
}

/* Mobile background: the blue pattern only. The vivid right-hand ribbons are
   dropped below 800px, they were too loud behind the stacked content. */
@media (max-width: 800px) {
  html {
    background:
      url("../images/bg-ribbons-soft.svg") left -12% top -8% / auto 108% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* Desktop pattern pulled back on screen. At `right -27vw` some 518px of the
   artwork sat past the right edge, and the part still visible fell entirely
   behind the two figures, so the top right corner read as empty. Brought in to
   -6vw so the dense corner lands above and beside them, and the inner edge
   still clears the copy. */
@media (min-width: 1101px) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -6vw top -30vh / 70% 150% no-repeat fixed,
      url("../images/bg-ribbons-soft.svg") left -14% top -22% / auto 92% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}

/* ============================================================
   BIG MONITORS AND SQUARE MONITORS
   ============================================================
   Two faults with one cause. The pair is sized against the WINDOW
   (min(74vh, 36vw)) but it is pinned inside `.hero`, and `.hero`
   stops growing at 120rem. Past that width the window keeps handing
   the figures more size while the box holding them stays 1920px, so
   the only direction left to grow is left, into the copy. On a
   3440x1440 monitor that is a 420px collision with the headline.

   The mirror of it on a squarish window: 36vw becomes the smaller
   term, so at 1691x1327 the pair is only 609px tall inside a 1327px
   window. It fills 46% of the height and leaves a dead band above
   their heads.

   Numbers everything below is derived from:
     hero-man.png    1206 x 1187
     hero-woman.png  1057 x 1280
     sized by height, overlapping 19%, so the pair is always
     1.49 x the figure height wide.

   Fix, stated once:

   1. The pair is pinned to the right edge of the SCREEN instead of
      the right edge of `.hero`. The gutter either side of `.hero` is
      (100vw - 120rem) / 2, so subtracting it puts the pair back on
      the window edge where the design has it. Below 120rem that
      gutter is zero and the value is exactly what it was before, so
      nothing moves on a normal display.

      That alone removes the collision, because the pair now travels
      right as the monitor widens instead of growing left into the
      copy. A ceiling of 60rem stops it running away on a 5K panel.

   2. Squarer than 1.45:1 there is genuinely not enough width for a
      person standing beside a paragraph at any useful size. So the
      copy moves to the top of the screen and the figures take the
      HEIGHT instead of the width. Nothing is beside anything, so the
      pair is free to be big, and it stays stuck to the bottom edge
      where `.page` crops it. */

@media (min-width: 1101px) {
  .hero__figure {
    height: min(74vh, 36vw, 60rem);
  }
  .hero__figures {
    right: calc(clamp(0.75rem, 3vw, 4rem) - (100vw - min(100vw, 120rem)) / 2);
  }
}

/* Square and tall windows: copy on top, the pair along the bottom.
   44% of 120rem is 52.8rem, the same cap logic as above. */
@media (min-width: 1101px) and (max-aspect-ratio: 29 / 20) {
  .hero {
    align-items: flex-start;
    padding-top: clamp(1.5rem, 5vh, 5rem);
  }
  /* Wide enough to carry the enlarged button row, which is about
     1000px at this size. */
  .hero__content {
    max-width: min(70rem, 82vw);
  }

  /* The supporting copy scales with the headline instead of staying at
     the small sizes from the 1700px block, where it read as a caption
     under a poster. Each one is written at the specificity of the rule
     it has to beat: `.title .title__lead` is (0,2,0) and
     `.waitlist__title h2` is (0,1,1). */
  .title .title__lead {
    font-size: clamp(1.25rem, 2.1vw, 2.4rem);
  }
  .waitlist__title {
    margin-top: 1rem;
  }
  .waitlist__title h2 {
    font-size: clamp(1.05rem, 1.75vw, 2rem);
  }
  .waitlist__copy {
    font-size: clamp(1.1rem, 1.85vw, 2.1rem);
  }
  .waitlist__bell {
    width: clamp(30px, 2.6vw, 44px);
    height: clamp(30px, 2.6vw, 44px);
  }
  .hero__actions {
    gap: 0.9rem;
    margin-top: 1.5rem;
  }
  .hero__btn {
    font-size: clamp(0.9rem, 1.35vw, 1.5rem);
    min-height: 3.8rem;
    padding: 0.95rem clamp(1.4rem, 1.9vw, 2.6rem);
  }
  /* The headline carries the whole left side on a square screen, so it
     scales up and breaks over three lines. Only the headline block is
     narrowed, not `.hero__content`, because the three buttons below it
     are wider than the text column and must stay on one row.

     Written as `.title .title__main` to match the specificity of the
     rule inside `@media (max-width: 1700px)`, which every square
     screen also matches. A bare `.title__main` loses to it on
     specificity no matter how late it appears. */
  .title .title__main {
    font-size: clamp(2.9rem, 5.6vw, 5.4rem);
    line-height: 1.1;
  }
  /* 44rem, not 38rem. At 38rem "coming SOON." is 632px and does not
     fit, so it drops to a fourth line and SOON sits alone. This holds
     the three lines the design breaks to: Something / amazing is /
     coming SOON. "amazing is coming" is 830px so line two still
     breaks where it should. */
  .headline {
    max-width: min(44rem, 50vw);
  }
  /* The three actions need 558px on one row and `.conversion` is
     35rem, so they were wrapping with 2px to spare and the second
     row ate into the clearance above the figures. The wizard is a
     fixed, centred overlay at its own width, so this only moves the
     button row. */
  .conversion {
    width: min(100%, 70rem);
  }
  /* 50vh is the real limit here: the copy block is taller now that
     everything in it scaled up, so the pair gives back the difference
     or it meets the buttons.

     The width term is 62vw, not 41vw. In THIS layout the copy sits
     ABOVE the pair, not beside it, so the only horizontal limit is the
     window itself. The pair is 1.49x the figure height wide, and with
     the 3vw right offset that works out at 0.65vw before it touches
     the left edge. 62vw leaves 50px of margin at the worst case.

     41vw was left over from when the copy stood beside them, and on a
     portrait window it was the smaller term, so it bound instead of
     50vh and starved them: 456px inside a 1318px window, 35% of the
     height, which is the long gap under the buttons.

     This changes nothing on the wider square sizes. At 1280x1024,
     1569x1205 and 1691x1327 the 50vh term is already the smaller one,
     so the cap is never reached and those renders are untouched. */
  .hero__figure {
    height: min(50vh, 62vw, 52.8rem);
  }

  /* Nudge the pair right so it reads centred.
     Measured at 1158x1327 the pair sat 24px from the left and 151px
     from the right. That is not the layout, it is the artwork:
     hero-woman.png carries about 21% dead dark area on her right where
     the braids fade out, while hero-man.png runs edge to edge. The pair
     is right anchored, so every bit of that dead space piles up on one
     side.

     The correction is half the dead area, which is 0.075 of the figure
     height, so it tracks the pair at every size instead of being a
     fixed number tuned to one window. The gutter term is carried over
     from the wide rule so this still works if a 4:3 window is wider
     than 120rem. */
  .hero__figures {
    right: calc(
      clamp(0.75rem, 3vw, 4rem)
      - (100vw - min(100vw, 120rem)) / 2
      - 0.075 * min(50vh, 62vw, 52.8rem)
    );
  }
}

/* ============================================================
   TALL RECTANGULAR WINDOWS, 1.45 TO 1.75
   ============================================================
   Between square and 16:9 the pair is sized by WIDTH (36vw is smaller
   than 74vh below 2.05:1), so making the window taller does not make
   them any bigger. They just sit lower and open a dead band above
   their heads.

     1615 x 817   figures 581 tall,  71% of the window, correct
     1676 x 1107  figures 603 tall,  54% of the window, too low

   Growing them alone does not fix it. The copy stands beside them, so
   the pair only gets whatever is left:

     window - right gutter - left padding - copy - clearance

   At 1676 that caps the figures at 672, an 11% gain. Not enough.

   So the copy gives up width as well, 30vw down to 24vw, and the pair
   takes it: 36vw up to 42vw. At 1676 the figures go 603 -> 704, which
   is 64% of the window instead of 54%. The headline still breaks over
   two lines at that width.

   Checked at every width in the band, narrowest clearance is 28px at
   1280 and it only grows from there.

   The band stops at 1.6, which is where the switch was asked for. On a
   1105 tall window that lands at 1768px wide. 16:10 is exactly 1.6 so
   1440x900 is still inside it. 16:9 is 1.778, so 1920x1080 and
   2560x1440 stay out and keep exactly the layout they have now. */
@media (min-width: 1101px) and (min-aspect-ratio: 1451 / 1000) and (max-aspect-ratio: 8 / 5) {
  .hero__figure {
    height: min(74vh, 42vw, 60rem);
  }
  .hero__content {
    max-width: min(30rem, 24vw);
  }
}

/* 1.6 to 1.75, the step down.
   Without this, dragging past 1.6 drops the pair from 42vw straight to
   36vw in one go, a 13% snap in size that is very visible while
   resizing. This lands halfway at 39vw so the drag reads as two small
   steps instead of one jump, and the copy gives back proportionally,
   24vw -> 27vw -> 30vw.

   Above 1.75 nothing is overridden and the original rules resume, by
   which point the pair is already 63% of the window height and climbing
   on its own, so there is nothing left to correct. */
@media (min-width: 1101px) and (min-aspect-ratio: 1601 / 1000) and (max-aspect-ratio: 7 / 4) {
  .hero__figure {
    height: min(74vh, 39vw, 60rem);
  }
  .hero__content {
    max-width: min(30rem, 27vw);
  }
}

/* Square windows only: the ribbons pull apart toward the two edges so
   the middle opens up behind the copy and the pair, and both sides run
   off the screen instead of sitting fully inside it.

   Offsets are in vw, not %. A percentage background-position resolves
   against (container - image), which goes NEGATIVE when the image is
   larger than the container, and the offset then travels the wrong
   way. That is what sent the artwork down the screen last time a
   negative percentage was used here. `right -18vw` is unambiguous:
   18vw past the right edge, cropped by the window. */
@media (min-width: 1101px) and (max-aspect-ratio: 29 / 20) {
  html {
    background:
      url("../images/bg-ribbons.svg") right -18vw top -26vh / 82% 150% no-repeat fixed,
      url("../images/bg-ribbons-soft.svg") left -18vw top -18vh / auto 104% no-repeat fixed,
      url("../images/bg-dark.svg") center center / cover no-repeat fixed,
      var(--bg);
  }
}
