/* ===========================================================================
   Afloata landing - night page.
   Colours are the shipped app tokens (frontend/apps/mobile/src/theme/
   _afloata.scss). Do not invent new hues here.
   ======================================================================== */

:root {
  --night: #06101d;
  --night-900: #081523;
  --night-850: #0b1828;
  --night-800: #0f1f33;
  --night-750: #13253c;
  --edge: #1c3047;
  --edge-strong: #27415d;
  --ink-1: #f4f7fb;
  --ink-2: #a4b3c3;
  --ink-3: #7d90a5;
  --cyan: #21c4c3;
  --cyan-hi: #2fd3d2;
  --cyan-soft: rgba(33, 196, 195, 0.12);
  --warm: #f5a623;
  --warm-hi: #ffc56f;
  --ok: #45c77a;
  --bad: #ff5a4f;
  --day-bg: #f3f6f8;
  --day-surface: #ffffff;
  --day-ink: #102238;
  --day-ink-2: #52677b;
  --day-teal: #0d91a0;
  --day-warm: #f06a2a;
  --header-h: 72px;
  /* site.css tokens the landing re-points at the app palette */
  --cyan-legacy: #35c4dc;
}
.voyage-page {
  background: var(--night);
  color: var(--ink-1);
  overflow-x: hidden;
}
.voyage-page main {
  isolation: isolate;
}
.voyage-page section[id] {
  scroll-margin-top: calc(var(--header-h) + 16px);
}
.voyage-page :focus-visible {
  outline: 3px solid var(--cyan-hi);
  outline-offset: 2px;
}
.voyage-kicker {
  font:
    500 11px/1.3 "IBM Plex Mono",
    monospace;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cyan-hi);
  margin: 0;
}

/* --- Persistent header ---------------------------------------------------- */

.voyage-page .site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 90;
  background: rgba(6, 16, 29, 0.74);
  backdrop-filter: blur(14px) saturate(1.25);
  -webkit-backdrop-filter: blur(14px) saturate(1.25);
  border-bottom: 1px solid rgba(28, 48, 71, 0.9);
  box-shadow: 0 10px 30px rgba(2, 7, 14, 0.35);
}
.voyage-header .wrap.bar {
  /* Full-bleed bar padded exactly like .hero-copy-stack, so on wide screens the
     logo sits on the same vertical line as the copy below it. */
  max-width: none;
  padding-inline: clamp(24px, 5vw, 88px);
  height: var(--header-h);
  gap: clamp(14px, 2vw, 30px);
}
.voyage-header .brand img {
  width: 123px;
  height: 36px;
}
@media (max-width: 720px) {
  .voyage-header .brand img {
    width: 96px;
    height: 28px;
  }
}
.voyage-header .site-nav a {
  color: var(--ink-2);
  font-size: 0.93rem;
}
.voyage-header .site-nav a:hover {
  color: var(--ink-1);
}
.voyage-header .lang-dd summary {
  color: var(--ink-3);
}
.voyage-header .lang-dd summary:hover,
.voyage-header .lang-dd[open] summary {
  color: var(--ink-1);
  background: rgba(255, 255, 255, 0.08);
}
.voyage-header .lang-panel {
  background: var(--night-800);
  border: 1px solid var(--edge-strong);
  box-shadow: 0 18px 40px rgba(2, 7, 14, 0.6);
}
.voyage-header .lang-opt {
  color: var(--ink-1);
}
.voyage-header a.lang-opt:hover {
  background: rgba(255, 255, 255, 0.07);
}
.voyage-header .lang-opt[aria-current] {
  color: var(--cyan-hi);
  background: var(--cyan-soft);
  font-weight: 600;
}
.voyage-header .header-cta {
  background: var(--warm);
  color: #06101d;
  padding: 9px 17px;
  font-size: 0.88rem;
  font-weight: 700;
}
.voyage-header .header-cta:hover {
  background: var(--warm-hi);
}
.scroll-rail {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: rgba(33, 196, 195, 0.14);
  overflow: hidden;
}
.scroll-rail span {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--cyan) 0%, var(--cyan-hi) 55%, var(--warm) 100%);
}

/* --- Hero ------------------------------------------------------------------ */

.voyage-hero {
  position: relative;
  /* site.css gives every <section> 96px of block padding; here it would shrink
     the hero stage and, in the voyage, the sticky containing block. */
  padding: 0;
  height: 100svh;
  min-height: 700px;
  /* Flat, because the Safari MP4 fallback is flattened onto exactly #06101d.
     Any gradient behind the video would draw its rectangle. */
  background: var(--night);
}
.hero-stage {
  --video-w: min(58vw, 1050px);
  --video-h: calc(var(--video-w) * 0.5625);
  height: 100%;
  position: relative;
  isolation: isolate;
}
.hero-video {
  position: absolute;
  z-index: 1;
  width: var(--video-w);
  height: auto;
  aspect-ratio: 16/9;
  object-fit: contain;
  left: 65%;
  top: 51%;
  transform: translate(-50%, -50%);
  /* The render's water runs to the bottom edge of the 16:9 frame, which otherwise
     ends in a hard horizontal line against the page. The hull bottom sits near 84%
     of the frame, so the feather starts just under it and reaches zero at the edge.
     Also hides the Safari MP4's opaque bottom corners. */
  -webkit-mask-image: linear-gradient(180deg, #000 82%, rgba(0, 0, 0, 0.55) 92%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 82%, rgba(0, 0, 0, 0.55) 92%, transparent 100%);
}
/* Atmosphere layers sit above the video so the flattened MP4 never shows an
   edge; they are soft enough to read as haze over the rig. */
.hero-glow,
.hero-stage::before,
.hero-stage::after {
  content: "";
  position: absolute;
  z-index: 3;
  inset: 0;
  pointer-events: none;
}
.hero-glow {
  background: radial-gradient(circle 34vw at 79% 9%, rgba(163, 205, 222, 0.17), transparent 64%);
}
.hero-stage::before {
  background: radial-gradient(ellipse 46% 34% at 65% 46%, rgba(33, 196, 195, 0.09), transparent 68%);
  animation: hero-atmosphere-breathe 11s ease-in-out infinite alternate;
}
.hero-stage::after {
  inset: 26% -6% 42%;
  opacity: 0.5;
  background:
    radial-gradient(ellipse 46% 16% at 72% 22%, rgba(122, 158, 178, 0.09), transparent 70%),
    radial-gradient(ellipse 38% 12% at 44% 66%, rgba(122, 158, 178, 0.07), transparent 72%);
  animation: hero-wave-drift 16s ease-in-out infinite alternate;
}
@keyframes hero-atmosphere-breathe {
  to {
    opacity: 0.72;
    transform: scale(1.05);
  }
}
@keyframes hero-wave-drift {
  to {
    transform: translate3d(2.5%, -0.6%, 0);
  }
}

/* Hero copy ----------------------------------------------------------------- */

.hero-copy-stack {
  position: absolute;
  z-index: 6;
  top: 16%;
  left: clamp(24px, 5vw, 88px);
  width: clamp(320px, 30vw, 460px);
}
.hero-copy {
  position: relative;
  width: 100%;
}
.hero-copy h1 {
  font-size: clamp(34px, 3.5vw, 58px);
  line-height: 0.96;
  letter-spacing: -0.045em;
  margin: 14px 0 18px;
  text-wrap: balance;
}
.hero-sub {
  font-size: clamp(14px, 1.05vw, 17px);
  line-height: 1.6;
  color: var(--ink-2);
  margin: 0;
}
.hero-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
}
.hero-badges li {
  font:
    500 10px/1 "IBM Plex Mono",
    monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cyan-hi);
  border: 1px solid rgba(33, 196, 195, 0.32);
  background: var(--cyan-soft);
  border-radius: 999px;
  padding: 7px 11px;
}
.hero-badges li:nth-child(2) {
  color: var(--warm-hi);
  border-color: rgba(245, 166, 35, 0.36);
  background: rgba(245, 166, 35, 0.11);
}
.mobile-engine {
  display: none;
}
/* Pure-CSS entrance. No JS involved, so the headline is on screen even if
   voyage.js never loads. Total delay stays under 0.2s. */
.hero-copy > * {
  animation: rise-in 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.hero-copy > *:nth-child(2) {
  animation-delay: 0.05s;
}
.hero-copy > *:nth-child(3) {
  animation-delay: 0.1s;
}
.hero-copy > *:nth-child(4) {
  animation-delay: 0.15s;
}
@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Fleet waitlist - the only email capture on the page, final section only ---- */

.waitlist {
  margin-top: 36px;
  max-width: 460px;
  padding-top: 26px;
  border-top: 1px solid rgba(39, 65, 93, 0.7);
}
.fleet-kicker {
  margin: 0;
  font:
    500 11px/1.3 "IBM Plex Mono",
    monospace;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--warm-hi);
}
.fleet-lede {
  margin: 8px 0 14px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 46ch;
}
.waitlist-row {
  display: grid;
  gap: 9px;
}
.waitlist label {
  font:
    500 10px/1 "IBM Plex Mono",
    monospace;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.waitlist input {
  font: inherit;
  font-size: 16px;
  width: 100%;
  color: var(--ink-1);
  background: rgba(15, 31, 51, 0.86);
  border: 1px solid var(--edge-strong);
  border-radius: 10px;
  padding: 12px 14px;
}
.waitlist input::placeholder {
  color: #5c7085;
}
.waitlist input:focus-visible {
  border-color: var(--cyan-hi);
  outline: 3px solid rgba(47, 211, 210, 0.35);
  outline-offset: 0;
}
.waitlist button {
  font: inherit;
  font-weight: 700;
  font-size: 16px;
  color: #06101d;
  background: var(--warm);
  border: none;
  border-radius: 10px;
  padding: 13px 18px;
  cursor: pointer;
  transition: background 0.15s ease;
}
.waitlist button:hover {
  background: var(--warm-hi);
}
.waitlist button:disabled {
  opacity: 0.62;
  cursor: default;
}
.waitlist-status {
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-2);
  min-height: 1px;
}
.waitlist-status:empty {
  display: none;
}
.waitlist.is-ok .waitlist-status {
  color: var(--ok);
}
.waitlist.is-error .waitlist-status {
  color: var(--bad);
}
.waitlist-note {
  margin: 9px 0 0;
  font:
    10px/1.5 "IBM Plex Mono",
    monospace;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.waitlist-nojs {
  margin: 9px 0 0;
  font-size: 12px;
  color: var(--warm-hi);
}
.js .waitlist-nojs {
  display: none;
}

/* Store badges - only in the final section, never on the first screen ------- */

.store-row {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin-top: 22px;
}
.store-lead {
  margin: 0;
  font:
    10px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.store-badge {
  border: 1px solid var(--edge-strong);
  border-radius: 8px;
  padding: 5px 11px;
  background: rgba(8, 21, 35, 0.6);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
}
.store-badge small {
  display: block;
  font-size: 8px;
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Hotspots and leader lines -------------------------------------------------- */

.hero-leaders {
  position: absolute;
  z-index: 4;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.hero-leaders path {
  fill: none;
  stroke: var(--cyan-hi);
  stroke-width: 1.1;
  opacity: 0.7;
}
.hero-leaders circle {
  fill: #9ff0ee;
}
.hero-hotspots {
  position: absolute;
  z-index: 5;
  inset: 0;
  pointer-events: none;
}
.hotspot {
  position: absolute;
  width: 172px;
  padding: 11px 13px;
  border: 1px solid rgba(33, 196, 195, 0.3);
  background: rgba(8, 21, 35, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-radius: 4px;
  transition:
    border-color 0.45s ease,
    box-shadow 0.45s ease;
}
/* voyage.js adds .is-live while the fitting this badge names is both facing the
   camera and close to the badge, so the four take turns as the camera orbits
   instead of all sitting at full strength. */
.hotspot.is-live {
  border-color: rgba(47, 211, 210, 0.75);
  box-shadow:
    0 0 0 1px rgba(47, 211, 210, 0.18),
    0 6px 26px rgba(33, 196, 195, 0.22);
}
.hotspot small {
  display: block;
  color: var(--cyan-hi);
  font:
    10px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.hotspot strong {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  color: var(--ink-1);
}
/* One fixed lane per card, ordered by the y of the anchor it points at
   (rigging 0.477 < engine 0.730 < winch 0.768 < anodes 0.801 of frame
   height), so no two leader lines can cross. */
.hs-rigging {
  top: 19%;
  right: 2.5%;
}
.hs-engine {
  top: 39%;
  right: 2.5%;
}
.hs-winch {
  top: 57%;
  right: 2.5%;
}
.hs-anodes {
  top: 75%;
  right: 2.5%;
}

/* --- Voyage ----------------------------------------------------------------- */

.voyage-journey {
  position: relative;
  z-index: 2;
  padding: 0;
  height: 360vh;
  background: linear-gradient(180deg, var(--night) 0%, #071628 55%, var(--day-bg) 100%);
  isolation: isolate;
  /* The tail now lifts while the sky is still mid-sunrise, so its bottom edge is
     amber against the white day panel - a hard line without this. Feather the last
     150px of the section into transparency; during the sticky phase that strip is
     below the viewport, so the mask only ever shows during the lift. */
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 150px), transparent 100%);
  mask-image: linear-gradient(180deg, #000 calc(100% - 150px), transparent 100%);
}
.journey-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: var(--night);
}
.chart-frame {
  position: absolute;
  z-index: 0;
  inset: 0;
  overflow: hidden;
}
/* The chart layer carries the water gradient rather than the stage, so the
   engraved instruments have an opaque backdrop to `screen` against inside this
   transformed (and therefore isolated) group. */
.chart-pan {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 240vh;
  background: linear-gradient(180deg, #06101d 0%, #08192c 22%, #071628 55%, #050f1a 100%);
  will-change: transform;
}
.journey-chart {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.journey-chart path {
  fill: none;
  stroke: #9fd8df;
}
.grid-minor {
  stroke-width: 1px;
  stroke-opacity: 0.085;
}
.grid-major {
  stroke-width: 1.3px;
  stroke-opacity: 0.16;
}
.grid-tick {
  stroke-width: 1px;
  stroke-opacity: 0.14;
}
.chart-label text {
  fill: #a8d7dc;
  fill-opacity: 0.34;
  font:
    11px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.05em;
}
.chart-islands path {
  fill: rgba(140, 196, 204, 0.1);
  stroke-opacity: 0.26;
  stroke-width: 1.3px;
}
.chart-shallows path {
  fill: url(#shallows);
  stroke-opacity: 0.13;
  stroke-width: 1px;
}
.journey-chart pattern path {
  fill: none;
  stroke-opacity: 0.17;
  stroke-width: 1px;
}
.chart-isobaths path {
  stroke-opacity: 0.155;
  stroke-width: 1.1px;
}
.chart-marks text {
  fill: #a8d7dc;
  fill-opacity: 0.2;
  font:
    11px "IBM Plex Mono",
    monospace;
}
.chart-instrument {
  position: absolute;
  z-index: 0;
  pointer-events: none;
}
/* Instrument placement: the top of the chart is the emptiest stretch, so the
   big wind rose fills it; nothing sits on the left mid-band where the beat
   captions travel, so copy never lands on top of an engraving. */
.chart-compass {
  top: 71%;
  right: 9%;
  width: clamp(190px, 21vw, 360px);
  height: auto;
  opacity: 0.5;
}
.chart-wind {
  top: 21%;
  left: 5%;
  width: clamp(300px, 30vw, 520px);
  height: auto;
  opacity: 0.3;
  mix-blend-mode: screen;
}
.chart-anchor {
  top: 3%;
  right: 5%;
  width: clamp(140px, 14vw, 240px);
  height: auto;
  opacity: 0.34;
  mix-blend-mode: screen;
}
.journey-route {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
}
.route-todo {
  fill: none;
  stroke: #8fd4e2;
  stroke-opacity: 0.22;
  stroke-width: 1.6px;
  stroke-dasharray: 9 10;
}
.route-glow {
  fill: none;
  stroke: var(--cyan);
  stroke-opacity: 0.22;
  stroke-width: 8px;
  stroke-linecap: round;
}
.route-done {
  fill: none;
  stroke: #96f4f1;
  stroke-opacity: 0.95;
  stroke-width: 2.5px;
  stroke-linecap: round;
}
.route-pins {
  position: absolute;
  z-index: 2;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}
.route-pin {
  position: absolute;
  display: flex;
  align-items: center;
  transform: translate(-13px, -50%);
  opacity: 0.34;
  transition: opacity 0.4s ease;
}
.route-pin[data-side="l"] {
  flex-direction: row-reverse;
  transform: translate(calc(-100% + 13px), -50%);
}
/* no-JS fallback positions, close to where JS lands each pin on the route */
.route-pin[data-pin="0"] {
  left: 39%;
  top: 16.5%;
}
.route-pin[data-pin="1"] {
  left: 60%;
  top: 34.5%;
}
.route-pin[data-pin="2"] {
  left: 39%;
  top: 54%;
}
.route-pin[data-pin="3"] {
  left: 60%;
  top: 73%;
}
.route-pin b {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font:
    600 10px "IBM Plex Mono",
    monospace;
  color: #06101d;
  background: #96f4f1;
  box-shadow: 0 0 0 4px rgba(33, 196, 195, 0.16);
}
.route-pin span {
  position: relative;
  margin-left: 15px;
  padding: 5px 10px;
  border: 1px solid var(--edge-strong);
  border-radius: 6px;
  background: rgba(8, 21, 35, 0.9);
  font:
    500 11px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.06em;
  color: var(--ink-2);
  white-space: nowrap;
}
.route-pin span::before {
  content: "";
  position: absolute;
  left: -15px;
  top: 50%;
  width: 15px;
  height: 1px;
  background: var(--edge-strong);
}
.route-pin[data-side="l"] span {
  margin-left: 0;
  margin-right: 15px;
}
.route-pin[data-side="l"] span::before {
  left: auto;
  right: -15px;
}
.route-pin.is-on {
  opacity: 1;
}
.route-pin.is-on b {
  background: var(--cyan-hi);
  box-shadow:
    0 0 0 5px rgba(47, 211, 210, 0.22),
    0 0 18px rgba(47, 211, 210, 0.5);
}
.route-pin.is-on span {
  color: var(--ink-1);
  border-color: var(--cyan);
}
.journey-boat {
  position: absolute;
  z-index: 1;
  /* no-JS fallback position: the start of the route, 300/1000 by 300/2600 */
  left: 39.5%;
  top: 11.5%;
  width: 42px;
  height: 95px;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 0 11px rgba(47, 211, 210, 0.45));
  will-change: transform;
}
.journey-boat svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.boat-hull {
  fill: #e9f4f8;
  stroke: #06101d;
  stroke-width: 1.2;
  stroke-linejoin: round;
}
.boat-deck {
  fill: #bed4e1;
  stroke: #06101d;
  stroke-width: 0.7;
}
.boat-coachroof {
  fill: #f4fafc;
  stroke: #06101d;
  stroke-width: 0.8;
}
.boat-cockpit {
  fill: #17304a;
  stroke: #06101d;
  stroke-width: 0.7;
}
.boat-mast {
  fill: #06101d;
}
.boat-rail {
  fill: none;
  stroke: #7f99ab;
  stroke-width: 0.9;
  stroke-linecap: round;
}
.boat-wake {
  fill: none;
  stroke: #8ff3f0;
  stroke-opacity: 0.4;
  stroke-width: 1.4;
  stroke-linecap: round;
}
.boat-wash {
  fill: url(#boat-wash);
  stroke: none;
}

/* Fixed furniture inside the sticky stage ------------------------------------ */

.journey-head {
  position: absolute;
  z-index: 3;
  top: calc(var(--header-h) + 4vh);
  left: 6vw;
  width: min(560px, 40vw);
}
.journey-head h2,
.screen-marquee h2,
.voyage-faq h2,
.pricing-band h2 {
  font-size: clamp(32px, 4.4vw, 66px);
  line-height: 0.97;
  letter-spacing: -0.045em;
  margin: 0.28em 0 0;
  text-wrap: balance;
}
.journey-rail {
  position: absolute;
  z-index: 3;
  left: 2vw;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.journey-rail li {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid var(--edge-strong);
  background: rgba(13, 37, 60, 0.9);
  transition:
    background 0.35s ease,
    box-shadow 0.35s ease,
    transform 0.35s ease;
}
.journey-rail li.is-on {
  background: var(--cyan-hi);
  border-color: var(--cyan-hi);
  transform: scale(1.35);
  box-shadow: 0 0 12px rgba(47, 211, 210, 0.6);
}

/* Beats ---------------------------------------------------------------------- */

.beat-media {
  position: absolute;
  z-index: 2;
  right: 5vw;
  top: calc(var(--header-h) + 4vh);
  width: min(34vw, 600px);
  aspect-ratio: 3/2;
}
.beat-fig {
  position: absolute;
  z-index: 2;
  inset: 0;
  margin: 0;
  overflow: hidden;
  border: 1px solid rgba(39, 65, 93, 0.9);
  border-radius: 4px;
  box-shadow: 0 26px 70px rgba(2, 7, 14, 0.55);
  opacity: 0;
  transform: scale(1.03);
  will-change: opacity, transform;
}
.beat-fig img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* The toasts hang right under the photo and share its left edge, so the pair
   reads as one column instead of a card drifting in the chart. */
.beat-toasts {
  position: absolute;
  z-index: 3;
  left: calc(95vw - min(34vw, 600px));
  top: calc(var(--header-h) + 4vh + min(34vw, 600px) * 2 / 3 + 22px);
  width: 272px;
  height: 150px;
}
.journey-toast {
  position: absolute;
  z-index: 2;
  left: 0;
  top: 0;
  width: 272px;
  padding: 16px 18px;
  border: 1px solid rgba(33, 196, 195, 0.3);
  border-radius: 16px;
  background: rgba(11, 24, 40, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 22px 50px rgba(2, 7, 14, 0.6);
  display: flex;
  flex-direction: column;
  gap: 4px;
  opacity: 0;
  will-change: opacity, transform;
}
.journey-toast small {
  font:
    10px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cyan-hi);
}
.journey-toast strong {
  font-size: 20px;
  color: var(--ink-1);
}
.journey-toast span {
  font-size: 13px;
  color: var(--ink-2);
}
.journey-toast [data-check] {
  padding-left: 21px;
  position: relative;
  color: var(--ink-3);
  transition: color 0.25s ease;
}
.journey-toast [data-check]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 3px;
  width: 13px;
  height: 13px;
  border: 1px solid var(--edge-strong);
  border-radius: 4px;
  transition:
    background 0.2s ease,
    border-color 0.2s ease;
}
.journey-toast [data-check].is-checked {
  color: var(--ok);
}
.journey-toast [data-check].is-checked::before {
  background: var(--ok);
  border-color: var(--ok);
}
.beat-caps {
  position: absolute;
  z-index: 3;
  left: 6vw;
  top: 45vh;
  width: min(470px, 36vw);
  height: 42vh;
}
.beat-cap {
  position: absolute;
  z-index: 2;
  left: 0;
  top: 0;
  width: 100%;
  opacity: 0;
  will-change: opacity, transform;
  /* The captions travel over chart furniture (rose, grid, soundings); a quiet
     card keeps them readable no matter what is underneath. */
  box-sizing: border-box;
  padding: 18px 20px;
  border: 1px solid rgba(39, 65, 93, 0.6);
  border-radius: 14px;
  background: rgba(8, 20, 34, 0.78);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 18px 44px rgba(2, 7, 14, 0.35);
}
.beat-cap p {
  margin: 0;
  font:
    11px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cyan-hi);
}
.beat-cap h3 {
  font-size: clamp(21px, 2.2vw, 34px);
  line-height: 1.1;
  letter-spacing: -0.03em;
  margin: 11px 0 10px;
}
.beat-cap span {
  display: block;
  color: var(--ink-2);
  font-size: 14.5px;
  line-height: 1.55;
}
/* Without JS the first beat still reads as a finished composition instead of
   an empty 300vh section. voyage.js takes over with inline opacity. */
.beat-fig[data-beat="0"],
.journey-toast[data-beat="0"],
.beat-cap[data-beat="0"] {
  opacity: 1;
  transform: none;
}

/* Dawn: night -> indigo -> amber -> daylight, no hard edge anywhere ---------- */

.dawn {
  position: absolute;
  z-index: 6;
  inset: 0;
  pointer-events: none;
}
.dawn span {
  position: absolute;
  display: block;
  inset: 0;
  opacity: 0;
}
.dawn span.dawn-stars {
  inset: 0 0 auto 0;
  height: 48%;
  opacity: 0.4;
  mix-blend-mode: screen;
  background-image:
    radial-gradient(1.4px 1.4px at 51% 12%, #dbeaf5, transparent),
    radial-gradient(1.2px 1.2px at 58% 31%, #cfe1ef, transparent),
    radial-gradient(1.6px 1.6px at 64% 8%, #eaf4fb, transparent),
    radial-gradient(1.1px 1.1px at 70% 24%, #c6d9e8, transparent),
    radial-gradient(1.5px 1.5px at 76% 15%, #dbeaf5, transparent),
    radial-gradient(1.2px 1.2px at 83% 35%, #cfe1ef, transparent),
    radial-gradient(1.3px 1.3px at 89% 19%, #eaf4fb, transparent),
    radial-gradient(1.1px 1.1px at 95% 29%, #c6d9e8, transparent),
    radial-gradient(1.4px 1.4px at 47% 42%, #dbeaf5, transparent),
    radial-gradient(1.2px 1.2px at 55% 55%, #cfe1ef, transparent),
    radial-gradient(1.5px 1.5px at 68% 48%, #eaf4fb, transparent),
    radial-gradient(1.1px 1.1px at 80% 62%, #c6d9e8, transparent),
    radial-gradient(1.3px 1.3px at 91% 52%, #dbeaf5, transparent),
    radial-gradient(1.2px 1.2px at 33% 22%, #cfe1ef, transparent),
    radial-gradient(1.4px 1.4px at 26% 47%, #eaf4fb, transparent),
    radial-gradient(1.1px 1.1px at 14% 33%, #c6d9e8, transparent),
    radial-gradient(1.5px 1.5px at 8% 58%, #dbeaf5, transparent),
    radial-gradient(1.2px 1.2px at 40% 66%, #cfe1ef, transparent);
}
.dawn-indigo {
  background: linear-gradient(180deg, #16215a 0%, #222c68 28%, #2a3060 58%, #1a2340 100%);
}
.dawn-amber {
  background: linear-gradient(180deg, #3c3d78 0%, #8a5a70 30%, #dd854a 58%, #f5a623 78%, #b56430 100%);
}
/* The sun itself. Lengthening the dawn so it could actually be seen turned it into
   a viewport of empty gradient; it needed a subject. voyage.js drives --dawn-rise
   from 0 to 1 across the sunrise and the disc climbs out of the horizon with it.
   Inherits the amber layer's opacity, so it fades in and out with that layer. */
.dawn-amber::before {
  content: "";
  position: absolute;
  /* Up AND sideways - a real sunrise arcs. Both offsets ride the same --dawn-rise,
     so the disc leaves the horizon low on the left of its track and tops out higher
     and to the right, and the tail's own upward slide steepens the arc's end. */
  left: calc(57% + var(--dawn-rise, 0) * 12%);
  bottom: calc(6% + var(--dawn-rise, 0) * 34%);
  width: clamp(150px, 15vw, 260px);
  aspect-ratio: 1;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(
    circle,
    #fff6dd 0%,
    #ffd98d 34%,
    rgba(245, 166, 35, 0.62) 56%,
    rgba(245, 166, 35, 0.16) 70%,
    rgba(245, 166, 35, 0) 78%
  );
}
.dawn-day {
  background: linear-gradient(180deg, #c8dfec 0%, #e2edf3 30%, var(--day-bg) 58%, var(--day-bg) 100%);
}
/* One line of copy carries the sunrise so the dawn is never a blank screen,
   and it hands the reader over to the day panel. */
.dawn-line {
  position: absolute;
  z-index: 7;
  left: 6vw;
  top: 46vh;
  width: min(620px, 46vw);
  margin: 0;
  opacity: 0;
  font-family: var(--font-display, "Archivo", sans-serif);
  font-size: clamp(24px, 2.6vw, 40px);
  line-height: 1.08;
  letter-spacing: -0.035em;
  color: var(--day-ink);
  pointer-events: none;
}
.dawn-line b {
  display: block;
  font:
    11px "IBM Plex Mono",
    monospace;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* Same dark ink as the headline below it: amber-on-amber vanished against the
     sunrise, and the ink stays readable on the white the scroll ends on. */
  color: var(--day-ink);
  opacity: 0.72;
  margin-bottom: 12px;
}

/* --- Day panel --------------------------------------------------------------- */

/* Exactly margin + lift, no hold. The first 100vh is eaten by the negative margin
   that slides this panel under the journey's tail; the second is the curtain lift,
   and the photo and copy resolve DURING it (voyage.js masks them below the moving
   edge, so nothing gets sliced). Any height beyond 200vh just parks the finished
   panel on screen and reads as dead scrolling before the next section. */
.day-wrap {
  height: 200vh;
  margin-top: -100vh;
  position: relative;
  z-index: 1;
}
.day-reveal {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  box-sizing: border-box;
  background: var(--day-bg);
  color: var(--day-ink);
  padding: 0;
}
/* Daylight wash: the top of the day panel is the same colour the dawn ends
   on, so the curtain edge has nothing to draw against. */
.day-reveal::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0 0 auto 0;
  height: 74vh;
  pointer-events: none;
  opacity: var(--day-wash, 1);
  background: linear-gradient(
    180deg,
    #f3f6f8 0%,
    rgba(243, 246, 248, 0.96) 18%,
    rgba(243, 246, 248, 0.74) 44%,
    rgba(243, 246, 248, 0.32) 72%,
    rgba(243, 246, 248, 0) 100%
  );
}
/* --day-edge is where the journey's tail currently ends, in viewport pixels; voyage.js
   writes it during the curtain lift and it reaches 0 once the tail is gone. Everything
   above it is still covered by that tail, so the panel's content is masked out there
   and feathered over the 170px below it. Without the feather the tail's hard bottom
   edge cuts straight across the headline as it slides up. Falls back to 0px, which is
   a fully visible panel - the no-JS and reduced-motion state. */
.day-grid {
  position: relative;
  width: 100%;
  max-width: none;
  height: 100vh;
  margin: 0;
  -webkit-mask-image: linear-gradient(180deg, transparent calc(var(--day-edge, 0px) - 170px), #000 var(--day-edge, 0px));
  mask-image: linear-gradient(180deg, transparent calc(var(--day-edge, 0px) - 170px), #000 var(--day-edge, 0px));
}
.day-photo {
  position: absolute;
  z-index: 0;
  inset: 0;
  height: 100%;
  overflow: hidden;
}
.day-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.day-device {
  position: absolute;
  z-index: 2;
  top: 12vh;
  right: clamp(34px, 7vw, 120px);
  width: clamp(190px, 17vw, 270px);
  padding: 12px;
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: 34px;
  background: rgba(255, 255, 255, 0.97);
  box-shadow: 0 30px 70px rgba(16, 34, 56, 0.26);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  perspective: 1000px;
}
.day-device img {
  width: 100%;
  border-radius: 28px;
  transform: rotateX(4deg) rotateY(-8deg);
  box-shadow:
    25px 35px 70px rgba(16, 34, 56, 0.3),
    0 2px 0 #fff;
}
.day-device:after {
  content: "";
  display: block;
  height: 35px;
  background: radial-gradient(ellipse, rgba(16, 34, 56, 0.25), transparent 70%);
  transform: translateY(16px);
}
.day-copy {
  position: absolute;
  z-index: 2;
  top: 12vh;
  left: clamp(28px, 6vw, 110px);
  width: min(500px, 40vw);
  padding: clamp(22px, 2.5vw, 38px);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.97);
  box-shadow: 0 28px 70px rgba(16, 34, 56, 0.24);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.day-copy h2 {
  font-size: clamp(30px, 3.4vw, 52px);
  line-height: 0.98;
  letter-spacing: -0.045em;
  margin: 8px 0 6px;
}
.day-copy .voyage-kicker {
  color: var(--day-teal);
}
.day-copy ul {
  padding: 0;
  margin: 8px 0 0;
  list-style: none;
}
.day-copy li {
  padding: 12px 0;
  border-top: 1px solid #d8e2e8;
  font-size: 14px;
  color: var(--day-ink-2);
}
.day-copy b {
  display: block;
  font:
    11px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--day-teal);
  margin-bottom: 5px;
}

/* --- Screens marquee ---------------------------------------------------------- */

.screen-marquee {
  position: relative;
  z-index: 2;
  padding: 14vh 0;
  background: linear-gradient(180deg, #071628, var(--night));
  overflow: hidden;
}
.screen-marquee > .wrap,
.voyage-faq > .wrap,
.pricing-band > .wrap {
  max-width: 1180px;
}
.marquee-window {
  margin-top: 60px;
  overflow: hidden;
  padding: 50px 0;
}
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 45s linear infinite;
}
.marquee-window:hover .marquee-track,
.marquee-window:focus .marquee-track,
.marquee-window:focus-within .marquee-track {
  animation-play-state: paused;
}
.marquee-set {
  display: flex;
  align-items: center;
  gap: 28px;
  padding-right: 28px;
}
.marquee-set figure {
  margin: 0;
  flex: none;
  overflow: hidden;
  border-radius: 22px;
  background: var(--night-800);
  box-shadow: 0 25px 50px rgba(2, 7, 14, 0.55);
}
.scene-card {
  width: 390px;
  height: 280px;
}
.scene-card.square {
  width: 310px;
  height: 310px;
  transform: translateY(-35px);
}
.scene-card.low {
  transform: translateY(35px);
}
.scene-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.screen-card {
  width: 240px;
  height: 330px;
  border: 8px solid var(--night-750);
  position: relative;
}
/* object-fit, not translateY. The old scheme slid a full-width image up inside a
   240x330 window: at this card size the image renders 519px tall, so any offset past
   -36.4% ran the window off the bottom of the picture and showed bare card. crop-check
   was set to -42% and did exactly that. object-position cannot overflow by construction,
   and the percentages below are measured - each is the window position that puts the
   most non-empty rows of that screenshot on screen. Re-measure if the shots change. */
.screen-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
}
.crop-check img {
  object-position: center 0%;
}
.crop-equip img {
  object-position: center 63%;
}
.crop-boat img {
  object-position: center 41%;
}
.crop-journal img {
  object-position: center 55%;
}
.crop-boats img {
  object-position: center 0%;
}
.crop-reminders img {
  object-position: center 37%;
}
.tilt-a {
  transform: translateY(25px) rotate3d(1, 1, 0, -5deg);
}
.tilt-b {
  transform: translateY(-15px) rotate3d(1, -1, 0, 6deg);
}
.tilt-c {
  transform: translateY(35px) rotate3d(-1, 1, 0, 5deg);
}
@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

/* --- Pricing ------------------------------------------------------------------ */

.pricing-band {
  position: relative;
  z-index: 2;
  padding: 12vh 0;
  background: var(--night);
  border-top: 1px solid var(--edge);
}
.price-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px;
  margin-top: 46px;
}
.price-card {
  padding: 30px 28px;
  border: 1px solid var(--edge);
  border-radius: 16px;
  background: var(--night-800);
}
.price-card.is-now {
  border-color: rgba(245, 166, 35, 0.45);
  background: linear-gradient(180deg, rgba(245, 166, 35, 0.08), rgba(15, 31, 51, 0.9) 42%);
}
.price-tag {
  margin: 0;
  font:
    600 11px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cyan-hi);
}
.price-card.is-now .price-tag {
  color: var(--warm);
}
.price-card h3 {
  font-size: clamp(21px, 2vw, 28px);
  letter-spacing: -0.03em;
  margin: 10px 0 12px;
}
.price-card > p {
  color: var(--ink-2);
  font-size: 15px;
  margin: 0;
}
.price-card ul {
  list-style: none;
  padding: 0;
  margin: 20px 0 0;
}
.price-card li {
  padding: 10px 0 10px 24px;
  border-top: 1px solid var(--edge);
  font-size: 14px;
  color: var(--ink-2);
  position: relative;
}
.price-card li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 18px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--cyan);
  opacity: 0.75;
}
.price-card.is-now li::before {
  background: var(--warm);
}
.price-card.is-later {
  opacity: 0.9;
}
.price-foot {
  margin: 26px 0 0;
  font:
    11px "IBM Plex Mono",
    monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* --- FAQ ----------------------------------------------------------------------- */

.voyage-faq {
  position: relative;
  z-index: 2;
  padding: 12vh 0;
  background: var(--night);
}
.voyage-faq .faq-list {
  max-width: none;
  margin-top: 40px;
}
.faq-list details {
  border-top: 1px solid var(--edge);
  border-bottom: none;
  padding: 4px 0;
}
.faq-list summary {
  cursor: pointer;
  font-size: 19px;
  font-weight: 600;
  padding: 20px 4px;
  color: var(--ink-1);
}
.faq-list summary::after {
  color: var(--cyan-hi);
}
.faq-list .answer {
  color: var(--ink-2);
  max-width: 78ch;
  padding: 0 4px 22px;
}
.faq-list .answer a {
  color: var(--cyan-hi);
}

/* --- Final CTA ------------------------------------------------------------------ */

.final-cta {
  position: relative;
  z-index: 2;
  min-height: 92vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: 10vh 0;
}
.final-cta > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.4;
}
/* The ripple canvas repaints the same photo (same 40%-over-night dimming), so
   it is invisible until the water moves. It sits UNDER the :after wash on
   purpose - paint order is img, canvas, then the section's :after. */
.cta-ripple {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.final-cta:after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(6, 16, 29, 0.95) 0%, rgba(6, 16, 29, 0.72) 48%, rgba(6, 16, 29, 0.45) 100%);
}
.final-cta > .wrap {
  position: relative;
  z-index: 2;
  width: 100%;
}
.final-cta h2 {
  font-size: clamp(44px, 7vw, 104px);
  letter-spacing: -0.055em;
  line-height: 0.92;
  margin: 0.18em 0 0.22em;
}
.final-lede {
  max-width: 46ch;
  color: var(--ink-2);
  margin: 0;
}
.ships-log {
  position: absolute;
  z-index: 3;
  right: 4vw;
  bottom: 6vh;
  width: min(360px, 42vw);
  border: 1px solid var(--edge-strong);
  background: rgba(6, 16, 29, 0.92);
  box-shadow: 0 20px 60px rgba(2, 7, 14, 0.6);
  font:
    11px/1.8 "IBM Plex Mono",
    monospace;
  color: var(--ink-2);
}
.log-title {
  padding: 7px 10px;
  border-bottom: 1px solid var(--edge-strong);
  display: flex;
  justify-content: space-between;
  color: var(--cyan-hi);
}
.ships-log p {
  padding: 12px 15px;
  margin: 0;
}
.cursor {
  animation: blink 1s steps(1) infinite;
}
@keyframes blink {
  50% {
    opacity: 0;
  }
}

/* --- Responsive ------------------------------------------------------------------ */

@media (max-width: 1250px) {
  /* Narrow the caption column and the photo so the route band that voyage.js
     lays out (0.38 - 0.50 of the stage width below 1250px) stays clear. */
  .beat-media {
    width: min(42vw, 460px);
  }
  .beat-toasts {
    left: calc(95vw - min(42vw, 460px));
    top: calc(var(--header-h) + 4vh + min(42vw, 460px) * 2 / 3 + 22px);
  }
  .beat-caps {
    width: min(30vw, 330px);
  }
  .journey-head {
    width: min(440px, 34vw);
  }
}
@media (max-width: 1100px) {
  .price-grid {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 900px) {
  .voyage-header .wrap.bar {
    /* .hero-copy-stack pins itself to 24px below 900px - keep the logo on it */
    padding-inline: 24px;
  }
  .voyage-hero {
    min-height: 760px;
  }
  .hero-stage {
    --video-w: 58vw;
  }
  .hero-video {
    left: 68%;
  }
  .hero-copy-stack {
    top: 13%;
    left: 24px;
    width: min(34vw, 330px);
  }
  .hero-copy h1 {
    font-size: 34px;
  }
  .hotspot {
    width: 138px;
    padding: 9px;
  }
  .hotspot strong {
    font-size: 11px;
  }
  .journey-toast,
  .beat-toasts {
    width: 232px;
  }
  .ships-log {
    width: 46vw;
  }
}
@media (max-width: 760px) {
  .voyage-header .wrap.bar {
    height: 60px;
  }
  .voyage-page {
    --header-h: 60px;
  }
  .voyage-hero {
    height: auto;
    min-height: 100svh;
  }
  .hero-stage {
    --video-w: 112vw;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
    overflow: hidden;
    min-height: 100svh;
    padding: 88px 22px 30px;
    box-sizing: border-box;
  }
  .hero-copy-stack,
  .hero-copy {
    display: contents;
  }
  .hero-copy > * {
    position: relative;
    z-index: 6;
    width: min(100%, 520px);
  }
  .hero-copy .voyage-kicker {
    order: 1;
  }
  .hero-copy h1 {
    order: 2;
    margin: 12px 0 14px;
  }
  .hero-sub {
    order: 3;
  }
  .hero-badges {
    order: 4;
  }
  .mobile-engine {
    order: 5;
    display: block;
    width: min(220px, 62vw);
    margin-top: 14px;
    padding: 10px 12px;
    border: 1px solid rgba(33, 196, 195, 0.32);
    background: rgba(8, 21, 35, 0.78);
    border-radius: 4px;
  }
  .mobile-engine small {
    display: block;
    color: var(--cyan-hi);
    font:
      10px "IBM Plex Mono",
      monospace;
    text-transform: uppercase;
  }
  .mobile-engine strong {
    display: block;
    margin-top: 4px;
    font-size: 12px;
  }
  .hero-video {
    order: 7;
    position: relative;
    z-index: 1;
    top: auto;
    left: 50%;
    width: var(--video-w);
    margin: 10px 0 0;
    transform: translateX(-50%);
  }
  .hero-glow,
  .hero-stage::before,
  .hero-stage::after {
    display: none;
  }
  .hs-engine,
  .hs-anodes,
  .hs-winch {
    display: none;
  }
  .hero-leaders {
    display: block;
  }
  .hero-leaders g[data-line="anodes"],
  .hero-leaders g[data-line="winch"],
  .hero-leaders g[data-line="engine"] {
    display: none;
  }
  .hs-rigging {
    top: auto;
    right: 14px;
    bottom: 26%;
    width: 134px;
  }
  .journey-head {
    top: calc(var(--header-h) + 12px);
    left: 20px;
    right: 20px;
    width: auto;
  }
  .journey-head h2 {
    font-size: 25px;
  }
  .journey-rail {
    left: auto;
    right: 8px;
  }
  /* keep the numbered pins on the route but drop the chips: there is no room
     for them beside a full-width photo and caption */
  .route-pin span {
    display: none;
  }
  .beat-media {
    top: 23vh;
    left: 20px;
    right: 20px;
    width: auto;
  }
  .beat-toasts {
    left: 20px;
    right: 20px;
    bottom: auto;
    top: 51vh;
    width: auto;
    height: 130px;
  }
  .journey-toast {
    left: 0;
    right: auto;
    width: min(100%, 300px);
    padding: 12px 14px;
  }
  .journey-toast strong {
    font-size: 17px;
  }
  .beat-caps {
    left: 20px;
    right: 20px;
    top: 68vh;
    width: auto;
    height: 26vh;
  }
  .beat-cap h3 {
    font-size: 19px;
    margin: 8px 0 6px;
  }
  .beat-cap span {
    font-size: 13px;
  }
  .chart-compass,
  .chart-wind,
  .chart-anchor {
    display: none;
  }
  .final-cta {
    padding: 12vh 0 6vh;
  }
}
@media (max-width: 600px) {
  .hero-copy h1 {
    font-size: 31px;
  }
  .hero-sub {
    font-size: 13.5px;
  }
  .store-badge {
    padding: 4px 9px;
  }
  .hotspot {
    width: 118px;
  }
  .hotspot strong {
    font-size: 10px;
  }
  .hs-rigging {
    top: auto;
    bottom: 25%;
  }
  .day-reveal {
    padding: 0;
  }
  .day-grid {
    display: block;
    height: 100vh;
    min-height: 0;
  }
  .day-photo {
    height: 100%;
  }
  /* 86px turned the screenshot into an illegible smudge - at that size it reads as a
     blur, not as an app, which is the one thing this section has to show. The copy card
     above ends around 55% of the panel, so there is room for a phone about twice that
     wide without crowding it. */
  .day-device {
    top: auto;
    right: 14px;
    bottom: 16px;
    width: min(168px, 46vw);
    padding: 7px;
    border-radius: 22px;
  }
  .day-device img {
    border-radius: 16px;
  }
  .day-copy {
    top: calc(var(--header-h) + 10px);
    left: 18px;
    width: calc(100% - 36px);
    box-sizing: border-box;
    padding: 14px 16px;
  }
  .day-copy h2 {
    font-size: clamp(24px, 8vw, 34px);
    margin: 6px 0 8px;
  }
  .day-copy li {
    padding: 8px 0;
    font-size: 11.5px;
    line-height: 1.35;
  }
  .ships-log {
    position: relative;
    right: auto;
    bottom: auto;
    margin: 40px 20px 0;
    width: auto;
  }
  .final-cta {
    display: block;
  }
  .scene-card {
    width: 300px;
    height: 220px;
  }
  .screen-card {
    width: 190px;
    height: 270px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero-stage::before,
  .hero-stage::after {
    animation: none;
  }
  .hero-copy > * {
    animation: none;
    opacity: 1;
    transform: none;
  }
  .marquee-track {
    animation: none;
    transform: none;
  }
  .cursor {
    animation: none;
  }
  .route-todo {
    stroke-dasharray: none;
  }
  .beat-fig,
  .journey-toast,
  .beat-cap {
    transition: none;
  }
  .journey-boat {
    filter: none;
  }
}
