:root {
  color-scheme: dark;
  font-family:
    Inter,
    ui-sans-serif,
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
  background: #111315;
  color: #ffffff;
  --background: #111315;
  --elevated: #171a1f;
  --surface: #1d2128;
  --surface-alt: #252a33;
  --border: #303641;
  --primary: #6d5ef5;
  --primary-bright: #7c4dff;
  --primary-soft: #9b8cff;
  --text-secondary: #b8bdc7;
  --text-tertiary: #7e8592;
  --success: #38d996;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  min-width: 320px;
  margin: 0;
  overflow-x: hidden;
  background:
    radial-gradient(circle at 76% 26%, rgba(109, 94, 245, 0.2), transparent 31rem),
    radial-gradient(circle at 8% 5%, rgba(124, 77, 255, 0.08), transparent 25rem), var(--background);
}

body::before {
  position: fixed;
  z-index: -1;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.018) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.018) 1px, transparent 1px);
  background-size: 52px 52px;
  mask-image: linear-gradient(to bottom, black, transparent 72%);
  content: "";
  pointer-events: none;
}

a {
  color: inherit;
}

button,
input {
  font: inherit;
}

.site-header,
.hero,
.live-map,
.product-loop,
footer {
  width: min(1240px, calc(100% - 40px));
  margin-inline: auto;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 82px;
  padding-top: env(safe-area-inset-top);
}

.brand {
  display: inline-flex;
  gap: 10px;
  align-items: center;
  color: #fff;
  font-size: 1.08rem;
  font-weight: 750;
  letter-spacing: -0.03em;
  text-decoration: none;
}

/* The mark is the approved artwork itself, served as-is. Its plate is 0.797 of
   the file's canvas — the rest is transparent margin and its drop shadow — so the
   box is sized up to make the plate read at the intended size. No border-radius:
   the artwork carries its own rounded plate. */
.brand-wordmark {
  display: inline-flex;
  align-items: center;
}

.brand-mark {
  display: block;
  width: 38px;
  height: 38px;
  margin: -4px 0;
}

.brand-wordmark svg {
  display: block;
  width: auto;
  height: 15px;
}

.footer-brand .brand-mark {
  width: 32px;
  height: 32px;
  margin: -3px 0;
}

.footer-brand .brand-wordmark svg {
  height: 13px;
}

.contact-link {
  color: var(--text-secondary);
  font-size: 0.88rem;
  font-weight: 700;
  text-decoration: none;
  transition: color 160ms ease;
}

.contact-link:hover,
.contact-link:focus-visible {
  color: #fff;
}

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(340px, 0.8fr);
  gap: clamp(48px, 7vw, 112px);
  align-items: center;
  min-height: calc(100svh - 82px);
  padding: 54px 0 86px;
}

.hero-copy {
  max-width: 760px;
}

.eyebrow {
  display: flex;
  gap: 9px;
  align-items: center;
  margin: 0 0 24px;
  color: var(--primary-soft);
  font-size: 0.78rem;
  font-weight: 750;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.eyebrow span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 15px rgba(56, 217, 150, 0.75);
}

h1 {
  margin: 0;
  font-size: clamp(3.2rem, 6.4vw, 6.6rem);
  font-weight: 820;
  letter-spacing: -0.075em;
  line-height: 0.92;
  text-wrap: balance;
}

h1 span {
  display: block;
}

.accent-line {
  color: var(--primary-soft);
}

.hero-description {
  max-width: 620px;
  margin: 28px 0 30px;
  color: var(--text-secondary);
  font-size: clamp(1.04rem, 1.8vw, 1.28rem);
  line-height: 1.55;
}

.waitlist-card {
  max-width: 690px;
}

.waitlist-form {
  position: relative;
  display: flex;
  gap: 8px;
  padding: 7px;
  border: 1px solid var(--border);
  border-radius: 17px;
  background: rgba(29, 33, 40, 0.92);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.25);
}

.waitlist-form:focus-within {
  border-color: rgba(155, 140, 255, 0.65);
  box-shadow:
    0 0 0 3px rgba(109, 94, 245, 0.12),
    0 24px 70px rgba(0, 0, 0, 0.25);
}

.waitlist-form input[type="email"] {
  min-width: 0;
  flex: 1;
  padding: 0 17px;
  border: 0;
  outline: 0;
  background: transparent;
  color: #fff;
  font-size: 1rem;
}

.waitlist-form input::placeholder {
  color: var(--text-tertiary);
}

.waitlist-form button {
  display: inline-flex;
  min-height: 56px;
  padding: 0 18px 0 22px;
  gap: 10px;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--primary), var(--primary-bright));
  box-shadow: 0 10px 28px rgba(109, 94, 245, 0.34);
  color: #fff;
  cursor: pointer;
  font-weight: 750;
  white-space: nowrap;
}

.waitlist-form button img {
  object-fit: contain;
}

.waitlist-form button:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

.waitlist-form button:disabled {
  cursor: wait;
  filter: saturate(0.5);
  opacity: 0.72;
  transform: none;
}

.form-trap {
  position: absolute;
  overflow: hidden;
  width: 1px;
  height: 1px;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.form-status {
  min-height: 22px;
  margin: 9px 4px 0;
  color: var(--text-secondary);
  font-size: 0.85rem;
}

.form-status.is-success {
  color: var(--success);
}

.form-status.is-error {
  color: #ff6b7a;
}

/* The waitlist count and the founding reward share one horizontal row on desktop
   and stack inside this same area below the desktop breakpoint. */
.hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 18px;
  align-items: center;
  margin-top: 18px;
}

.waitlist-proof {
  display: flex;
  gap: 12px;
  align-items: center;
  color: var(--text-secondary);
  font-size: 0.9rem;
  white-space: nowrap;
}

.waitlist-proof p {
  margin: 0;
}

.waitlist-proof strong {
  color: #fff;
}

.crew-faces span {
  display: grid;
  place-items: center;
  border: 2px solid var(--background);
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--primary-soft);
  font-weight: 750;
}

/* Plain text, deliberately in the same voice as the waitlist count beside it. The
   card this used to sit in — tinted panel, border, radius — competed with the
   waitlist form for attention and read as a second CTA. */
.founding-reward {
  /* Deliberately not a flex container. As flex, the mark, the bold clause and the
     trailing sentence became three independent items that spread apart and wrapped
     separately once the row got narrow. It is one sentence, so it flows as text. */
  margin: 0;
  color: var(--text-secondary);
  font-size: 0.9rem;
  line-height: 1.45;
}

.founding-reward .reward-mark {
  margin-right: 6px;
}

.founding-reward strong {
  color: #fff;
}

.reward-mark {
  color: var(--primary-soft);
  font-size: 1.2rem;
}

/* The Crew on a map. Everything here is CSS plus one inline SVG: the streets and
   the route are decorative, and the marker list carries the meaning. Markers are
   positioned in per cent so the panel can be any width without re-tuning. */
.live-map {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
  padding: 24px 0 96px;
}

.live-map-copy h2 {
  margin: 0 0 14px;
  font-size: clamp(1.8rem, 3.2vw, 2.9rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 1.04;
}

.live-map-copy p {
  max-width: 44ch;
  margin: 0;
  color: var(--text-secondary);
  font-size: clamp(0.98rem, 1.4vw, 1.12rem);
  line-height: 1.55;
}

.map-frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--border);
  border-radius: 22px;
  background:
    radial-gradient(circle at 30% 18%, rgba(109, 94, 245, 0.14), transparent 62%), var(--elevated);
  box-shadow: 0 26px 70px rgba(0, 0, 0, 0.4);
}

.map-grid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.map-chip {
  position: absolute;
  z-index: 2;
  top: 14px;
  left: 14px;
  display: inline-flex;
  gap: 7px;
  align-items: center;
  padding: 6px 11px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(17, 19, 21, 0.86);
  color: var(--text-secondary);
  font-size: 0.68rem;
  font-weight: 700;
}

.map-chip i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
}

.map-markers {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.map-marker {
  position: absolute;
  display: grid;
  justify-items: center;
  /* Centred horizontally on its route point, and shifted up by half the avatar so
     the circle sits ON the point rather than hanging below it. */
  transform: translate(-50%, -19px);
}

.map-marker > img,
.map-you {
  display: grid;
  width: 38px;
  height: 38px;
  place-items: center;
  border: 2px solid var(--primary-soft);
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
  object-fit: cover;
}

.map-you svg {
  width: 22px;
  height: 22px;
  color: var(--primary-soft);
}

/* The category badge is what makes each marker read as a different person doing a
   different thing, rather than four identical pins. */
.map-badge {
  display: grid;
  width: 22px;
  height: 22px;
  margin-top: -11px;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--background);
}

.map-badge img {
  width: 13px;
  height: 13px;
  object-fit: contain;
}

.map-marker b {
  margin-top: 5px;
  padding: 2px 7px;
  border-radius: 6px;
  background: rgba(17, 19, 21, 0.8);
  color: var(--text-secondary);
  font-size: 0.62rem;
  font-weight: 700;
  white-space: nowrap;
}

.map-marker.is-one {
  top: 79%;
  left: 13.1%;
}

.map-marker.is-two {
  top: 46%;
  left: 36.9%;
}

.map-marker.is-three {
  top: 60%;
  left: 65%;
}

.map-marker.is-four {
  top: 22%;
  left: 86.3%;
}

.phone-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 650px;
  isolation: isolate;
}

.phone-stage::before {
  position: absolute;
  z-index: -3;
  width: 440px;
  height: 440px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(109, 94, 245, 0.32), transparent 67%);
  content: "";
  filter: blur(8px);
}

.ambient-orbit {
  position: absolute;
  z-index: -2;
  border: 1px solid rgba(155, 140, 255, 0.13);
  border-radius: 50%;
}

.orbit-one {
  width: 500px;
  height: 500px;
}

.orbit-two {
  width: 580px;
  height: 580px;
}

.phone-shell {
  position: relative;
  width: min(360px, 88vw);
  padding: 10px;
  border: 1px solid #454b57;
  border-radius: 46px;
  background: #090a0d;
  box-shadow:
    0 38px 100px rgba(0, 0, 0, 0.56),
    0 0 48px rgba(109, 94, 245, 0.11);
  /* Static, deliberately.
     A rotation rasterises the layer once and resamples it, and an animated
     translate is just as bad: it composites the element and repositions it on
     fractional pixels every frame, which is what made every label in here soft.
     Animating `top` in whole-pixel steps kept the text sharp but read as lag
     rather than a bounce, so the phone does not move at all. */
}

.phone-speaker {
  position: absolute;
  z-index: 3;
  top: 19px;
  left: 50%;
  width: 86px;
  height: 24px;
  border-radius: 999px;
  background: #090a0d;
  transform: translateX(-50%);
}

/* Column layout so the tab bar can sit on the bottom edge like it does in the
   app. Without it the screen's min-height left dead space *below* the nav. */
.phone-screen {
  display: flex;
  overflow: hidden;
  flex-direction: column;
  min-height: 676px;
  padding: 17px 15px 13px;
  border-radius: 37px;
  background:
    radial-gradient(circle at 50% 0, rgba(109, 94, 245, 0.12), transparent 230px), #111315;
}

.phone-status {
  display: flex;
  justify-content: space-between;
  padding: 0 9px 10px;
  color: #d5d7dc;
  font-size: 0.67rem;
  font-weight: 650;
}

.night-heading,
.preview-section-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.night-heading p,
.night-heading h2,
.preview-section-heading h3,
.night-summary span,
.night-summary strong,
.vault-preview strong,
.vault-preview span {
  margin: 0;
}

.night-heading p {
  color: var(--text-tertiary);
  font-size: 0.72rem;
}

.night-heading h2 {
  margin-top: 2px;
  font-size: 1.35rem;
  letter-spacing: -0.04em;
}

.live-chip {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 6px 9px;
  border-radius: 999px;
  background: rgba(56, 217, 150, 0.1);
  color: var(--success);
  font-size: 0.66rem;
  font-weight: 700;
}

.live-chip i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.night-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 8px 0 0;
  padding: 9px;
  border: 1px solid rgba(155, 140, 255, 0.16);
  border-radius: 15px;
  background: linear-gradient(135deg, rgba(109, 94, 245, 0.15), rgba(29, 33, 40, 0.88));
}

.night-summary > div:first-child {
  display: grid;
  gap: 3px;
}

.night-summary span {
  color: var(--text-tertiary);
  font-size: 0.66rem;
}

.night-summary strong {
  font-size: 1.12rem;
  letter-spacing: 0.03em;
}

.crew-faces {
  display: flex;
  justify-content: flex-end;
}

.crew-faces span {
  width: 28px;
  height: 28px;
  margin-left: -6px;
  border-color: #1b1c2a;
  font-size: 0.59rem;
}

/* Real faces rather than initials. `object-fit: cover` plus the radius clips the
   source images' square corners, so no extra masking is needed. */
.crew-faces img {
  width: 28px;
  height: 28px;
  margin-left: -6px;
  border: 2px solid #1b1c2a;
  border-radius: 50%;
  object-fit: cover;
}

.crew-faces img:first-child {
  margin-left: 0;
}

.quick-log-preview {
  /* Deliberately tight. The mockup gained a chat preview and an activity feed, and
     the phone surface must not grow to fit them, so Quick Log gives up the room. */
  margin-top: 14px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 17px;
  background: rgba(29, 33, 40, 0.84);
}

.preview-section-heading {
  margin-bottom: 10px;
}

.preview-section-heading h3 {
  margin: 0;
  font-size: 0.74rem;
}

.preview-section-heading span {
  color: var(--text-tertiary);
  font-size: 0.61rem;
}

.quick-log-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}

.quick-log-grid button {
  display: grid;
  min-width: 0;
  min-height: 30px;
  padding: 2px 2px;
  place-items: center;
  border: 0;
  border-radius: 10px;
  background: var(--surface-alt);
  color: #d8dae0;
  pointer-events: none;
}

.quick-log-grid img {
  width: 19px;
  height: 19px;
  object-fit: contain;
}

/* Still deliberately below the app's own `shot ? 24 : 30` ratio: a shot glass is
   the smallest real object in the set and reads oversized at parity. */
.quick-log-grid img.is-shot {
  width: 14px;
  height: 14px;
}

.quick-log-grid span {
  overflow: hidden;
  max-width: 100%;
  font-size: 0.45rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vault-preview {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: center;
  margin-top: 14px;
  padding: 11px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}

.vault-icon {
  display: grid;
  width: 33px;
  height: 33px;
  place-items: center;
  border-radius: 10px;
  background: rgba(109, 94, 245, 0.13);
  /* The inlined vector strokes with `currentColor`, so this is what tints it.
     Inlining is why that works at all: `currentColor` does not inherit into an
     SVG referenced with `<img src>`. */
  color: var(--primary-soft);
}

.vault-icon svg {
  display: block;
  width: 19px;
  height: 19px;
}

.vault-preview > div:nth-child(2) {
  display: grid;
  gap: 2px;
}

.vault-preview strong {
  font-size: 0.72rem;
}

.vault-preview span {
  color: var(--text-tertiary);
  font-size: 0.57rem;
}

.vault-preview .vault-count {
  display: grid;
  width: 26px;
  height: 26px;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--primary-soft);
  font-weight: 750;
}

.phone-nav {
  display: flex;
  align-items: flex-end;
  justify-content: space-around;
  height: 61px;
  /* Pushed to the bottom of the column rather than following the content. */
  margin: auto -15px -13px;
  padding: 10px 18px 9px;
  border-top: 1px solid var(--border);
  background: var(--elevated);
  color: var(--text-tertiary);
  font-size: 1rem;
}

/* The app draws its tab icons at 26 on a 390px-wide screen. The mockup phone is
   360px, so 24 keeps the same optical weight; 18 read as a different, tinier app. */
/* Crew chat preview. The feature is BLOCKED in the product (CURRENT_STATE.md);
   this is an intent preview on the marketing page, not a shipped screen. */
.chat-preview,
.activity-preview {
  margin-top: 14px;
  padding: 6px 10px 7px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}

.chat-rows,
.activity-rows {
  display: grid;
  gap: 6px;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}

/* The activity feed is deliberately clipped and faded out rather than shortened.
   Three rows exist in the markup; only the first two and a hint of the third are
   visible, which reads as "there is more, scroll" and leaves the Vault its room.
   The phone surface is fixed, so this is where the overflow is absorbed. */
.activity-rows {
  max-height: 34px;
  overflow: hidden;
  mask-image: linear-gradient(to bottom, #000 42%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 42%, transparent 100%);
}

.chat-row {
  display: flex;
  gap: 7px;
  align-items: center;
}

.chat-row img {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  object-fit: cover;
}

.chat-row p {
  overflow: hidden;
  margin: 0;
  padding: 5px 9px;
  border-radius: 10px 10px 10px 3px;
  background: var(--surface-alt);
  color: #d8dae0;
  font-size: 0.58rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-row p b {
  margin-right: 4px;
  color: var(--primary-soft);
}

/* Your own message reads as outgoing: mirrored corner, purple tint, right aligned. */
.chat-row.is-you {
  justify-content: flex-end;
}

.chat-row.is-you p {
  border-radius: 10px 10px 3px;
  background: rgba(109, 94, 245, 0.22);
  color: #fff;
}

.chat-row.is-you p b {
  color: #cfc6ff;
}

.activity-rows li {
  display: grid;
  grid-template-columns: 16px 1fr auto;
  gap: 7px;
  align-items: center;
}

.activity-rows img {
  width: 16px;
  height: 16px;
  object-fit: contain;
}

.activity-rows span {
  overflow: hidden;
  color: var(--text-secondary);
  font-size: 0.58rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.activity-rows span b {
  color: #fff;
}

.activity-rows i {
  color: var(--text-tertiary);
  font-size: 0.53rem;
  font-style: normal;
}

.phone-nav svg {
  display: block;
  width: 24px;
  height: 24px;
}

.camera-action {
  display: grid;
  width: 48px;
  height: 48px;
  margin-top: -24px;
  place-items: center;
  border: 5px solid #111315;
  border-radius: 50%;
  background: var(--primary);
  /* White only inside the central purple action button, per DESIGN_SYSTEM §8. */
  color: white;
}

.camera-action svg {
  width: 26px;
  height: 26px;
}

.product-loop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 110px;
  padding: 27px 30px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: rgba(29, 33, 40, 0.7);
}

.product-loop p {
  margin: 0;
  color: var(--primary-soft);
  font-size: 0.76rem;
  font-weight: 750;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.product-loop div {
  display: flex;
  gap: 16px;
  align-items: center;
  color: var(--text-secondary);
  font-size: 0.9rem;
  font-weight: 650;
}

.product-loop i {
  color: var(--primary-soft);
  font-style: normal;
}

footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 110px;
  padding: 26px 0 calc(26px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border);
  color: var(--text-tertiary);
  font-size: 0.82rem;
}

footer > div {
  display: flex;
  gap: 20px;
}

footer a {
  color: var(--text-secondary);
  text-decoration: none;
}

footer a:hover {
  color: #fff;
}

.footer-brand {
  color: #fff;
  font-size: 0.94rem;
}

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

/* Desktop only. The copy column is widened and the gap tightened so the subtitle
   holds one line; below this breakpoint it wraps responsively, which is fine. */
@media (min-width: 901px) {
  .hero {
    grid-template-columns: minmax(0, 1.32fr) minmax(320px, 0.68fr);
    gap: clamp(40px, 4.6vw, 84px);
  }

  .hero-copy {
    max-width: 880px;
  }

  .hero-description {
    max-width: none;
    font-size: clamp(1rem, 1.34vw, 1.16rem);
    white-space: nowrap;
  }

  .hero-meta {
    flex-wrap: nowrap;
  }
}

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 48px;
    min-height: 0;
    padding-top: 50px;
  }

  .hero-copy {
    max-width: 720px;
  }

  .phone-stage {
    min-height: 710px;
  }

  .product-loop {
    align-items: flex-start;
    flex-direction: column;
    gap: 18px;
  }

  .live-map {
    /* minmax(0, 1fr), not 1fr: a bare 1fr keeps an `auto` minimum, and the panel's
       aspect-ratio plus min-height below wants a width wider than the screen, which
       an auto minimum happily grants — that overflowed the page at 320px. */
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
    padding-bottom: 64px;
  }
}

@media (max-width: 620px) {
  .map-marker > img,
  .map-you {
    width: 30px;
    height: 30px;
  }

  .map-badge {
    width: 18px;
    height: 18px;
    margin-top: -9px;
  }

  .map-badge img {
    width: 11px;
    height: 11px;
  }

  .map-marker b {
    font-size: 0.55rem;
  }

  .map-marker {
    transform: translate(-50%, -15px);
  }

  /* Taller panel on narrow screens. At 16/10 a 292px-wide panel is only 182px
     high, and the lowest marker's label fell outside it and was clipped by
     `overflow: hidden`. The route stretches with the box (preserveAspectRatio
     is none) and the markers are positioned in per cent, so alignment holds. */
  /* A floor, not just a ratio. Markers are positioned in per cent, so a taller
     panel moves them down too and the clearance below the lowest label barely
     improves; only an absolute height does. Below ~286px of panel height that
     label starts colliding with the bottom edge. */
  .map-frame {
    /* Width pinned so aspect-ratio cannot derive it from min-height. */
    width: 100%;
    aspect-ratio: 6 / 5;
    min-height: 300px;
  }

  .site-header,
  .hero,
  .product-loop,
  footer {
    width: min(100% - 28px, 1240px);
  }

  .site-header {
    min-height: 70px;
  }

  .brand {
    font-size: 1rem;
  }

  .brand img {
    width: 32px;
    height: 32px;
  }

  .hero {
    padding: 34px 0 64px;
  }

  .eyebrow {
    margin-bottom: 18px;
    font-size: 0.63rem;
  }

  /* Sized so the longest line, "won't remember.", never wraps: the deliberate
     three-line break is the point of the headline, and a fourth line breaks it. */
  h1 {
    font-size: clamp(2.35rem, 11.2vw, 3.1rem);
    line-height: 0.94;
  }

  .hero-description {
    margin: 23px 0 25px;
    font-size: 1.03rem;
  }

  .waitlist-form {
    display: grid;
    gap: 8px;
    padding: 7px;
  }

  .waitlist-form input[type="email"] {
    min-height: 55px;
    padding: 0 15px;
    font-size: 16px;
  }

  .waitlist-form button {
    width: 100%;
    min-height: 57px;
  }

  /* Stacked inside the same metadata area, still with no horizontal scroll. */
  .hero-meta {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
    margin-top: 14px;
  }

  .waitlist-proof {
    white-space: normal;
  }

  .phone-stage {
    min-height: 690px;
  }

  .phone-stage::before {
    width: 100%;
    height: auto;
    aspect-ratio: 1;
  }

  .phone-shell {
    width: min(350px, 100%);
  }

  /* Without these the decorative rings keep their 500/580px desktop size and push
     the page sideways at 390 and 320. */
  .orbit-one {
    width: min(390px, 100%);
    height: auto;
    aspect-ratio: 1;
  }

  .orbit-two {
    width: min(470px, 100%);
    height: auto;
    aspect-ratio: 1;
  }

  /* One row less of the fade, so the narrower screen — where the copy wraps more —
     still fits the same 676px surface. */
  .activity-rows {
    max-height: 26px;
  }
}

@media (max-width: 370px) {
  h1 {
    font-size: 2.15rem;
  }

  .contact-link {
    font-size: 0.56rem;
  }

  /* No `scale()` here either. The shell is already `min(360px, 88vw)`, so it fits
     without it, and scaling resampled the whole mockup into softness. */
  .phone-stage {
    min-height: 660px;
  }
}

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

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Privacy notice */
.privacy-main {
  width: min(760px, calc(100% - 36px));
  margin: 0 auto;
  padding: 72px 0 110px;
}

.privacy-main h1 {
  margin-bottom: 24px;
  font-size: clamp(2.8rem, 8vw, 5rem);
}

.privacy-main h2 {
  margin: 38px 0 12px;
  font-size: 1.25rem;
}

.privacy-main p,
.privacy-main li {
  color: var(--text-secondary);
  line-height: 1.7;
}

.privacy-main a {
  color: var(--primary-soft);
}

.privacy-main .notice-date {
  color: var(--text-tertiary);
  font-size: 0.86rem;
}
