@font-face {
  font-family: "Gotham";
  src: url("fonts/Gotham-Light.woff2") format("woff2");
  font-weight: 300;
  font-display: swap;
}

@font-face {
  font-family: "Gotham";
  src: url("fonts/Gotham-Medium.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}

:root {
  --accent: #A7E6D7;
  --bg-media: #04070C;
  --bg-fleet: #040A12;
  --bg-monaco: #080C11;
  --bg-panel: #03060B;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

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

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

body {
  font-family: "Gotham", "Helvetica Neue", Arial, sans-serif;
  font-weight: 300;
  color: #FFFFFF;
  background: var(--bg-media);
  -webkit-font-smoothing: antialiased;
}

/* Every section sticks at the top of the viewport and is covered by the
   next one sliding over it — the curtain reveal. Layout space is kept,
   so scroll length and trigger positions are unaffected. */
/* No overflow: hidden here — it would break the sticky frames inside
   tall sections (an overflow ancestor becomes their sticky scrollport). */
.section {
  position: sticky;
  top: 0;
  height: 100svh;
  background: var(--bg-media);
}

/* Section 2 is 180svh: its 100svh frame stays on screen for an extra
   ~80vh of scroll, pinning the statement over its own video. */
.opening {
  height: 180svh;
}

/* Sticky inside its own section, so a tall section's frame keeps its
   full dwell even near the end of the page, where the section itself
   runs out of room to stick. */
.frame {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100svh;
  overflow: hidden;
}

.media {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.scrim {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.desktop-br {
  display: none;
}

/* Brand wordmark — fixed top-centre, visible over the hero only.
   Not a link, never intercepts input; GSAP fades it with hero scroll
   progress (opacity only, so it runs under reduced motion too). */
.brand {
  position: fixed;
  top: calc(28px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  width: 150px;
  opacity: 0.92;
  pointer-events: none;
  z-index: 90;
}

/* 01 HERO */

.scrim-hero {
  background: linear-gradient(180deg, rgba(4, 7, 12, 0.42) 0%, rgba(4, 7, 12, 0.10) 45%, rgba(4, 7, 12, 0.55) 88%, rgba(4, 7, 12, 0.30) 100%);
}

.hero-statement-wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 76%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 36px;
  pointer-events: none;
}

.hero-statement {
  font-weight: 300;
  font-size: 36px;
  line-height: 1.3;
  letter-spacing: 0.015em;
  text-align: center;
  text-wrap: pretty;
  opacity: 0;
  animation: heroIn 480ms var(--ease) 1.2s forwards;
}

@keyframes heroIn {
  to { opacity: 1; }
}

.scroll-cue {
  position: absolute;
  bottom: 36px;
  left: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  pointer-events: none;
  transition: opacity 480ms var(--ease);
}

/* The cue guides the first scroll only. Once the guest has left the
   hero it fades out for good, so the fixed CTAs never sit on top of
   it when scrolling back up. */
.scroll-cue.is-done {
  opacity: 0;
}

.scroll-cue-line {
  width: 1px;
  height: 44px;
  background: rgba(255, 255, 255, 0.7);
  transform-origin: top;
  animation: cuePulse 4s ease-in-out infinite;
}

@keyframes cuePulse {
  0%, 100% { transform: scaleY(0.4); opacity: 0.4; }
  50% { transform: scaleY(1); opacity: 0.9; }
}

.scroll-cue-label {
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  padding-left: 0.4em;
}

/* 02 OPENING — centred lockup pinned over its own video, using the
   same structure and type as the experience panels. */

.scrim-opening {
  background: linear-gradient(180deg, rgba(4, 7, 12, 0.5) 0%, rgba(4, 7, 12, 0.4) 45%, rgba(4, 7, 12, 0.55) 100%);
}

.lockup-wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 36px;
  text-align: center;
  pointer-events: none;
}

/* 03–06 THE EXPERIENCES — two beats each: the black text panel is the
   arriving face of the section, then it slides away (scrubbed to
   scroll) revealing the video playing clean beneath. 260svh = arrival
   + text dwell + panel departure + video dwell. */

.experience {
  height: 260svh;
}

.experience-monaco .frame {
  background: var(--bg-monaco);
}

/* The panel is the section's opening face: it covers the video from
   the start (z-index keeps it above the later video element) and GSAP
   slides it away upward to reveal the footage. */
.panel {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--bg-panel);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 36px;
  text-align: center;
}

.lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  pointer-events: none;
}

/* The repeating mint signature: a hairline at its full final width in
   CSS, opening outwards from the centre on transform alone, then the
   headline and subheadline fade and rise. Initial state lives here;
   .is-visible (added once by an IntersectionObserver when the panel is
   in view, never on load) plays the sequence. */
.lockup-rule {
  width: 48px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 500ms var(--ease);
}

.lockup-eyebrow {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  padding-left: 0.4em;
}

.lockup-eyebrow,
.lockup-headline,
.lockup-sub {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 700ms var(--ease), transform 700ms var(--ease);
}

/* After the 500ms hairline draw, eyebrow, headline and subheadline
   each start 120ms after the previous one begins. */
.lockup-eyebrow {
  transition-delay: 500ms;
}

.lockup-headline {
  transition-delay: 620ms;
}

.lockup-sub {
  transition-delay: 740ms;
}

/* On the experience panels the guest should catch the build mid-play:
   the observer fires only once the black screen is 90% on, and the
   sequence runs compressed — rule 300ms, then eyebrow, headline and
   subheadline starting 100ms apart, each 450ms. */
.experience .lockup-rule {
  transition-duration: 300ms;
}

.experience .lockup-eyebrow,
.experience .lockup-headline,
.experience .lockup-sub {
  transition-duration: 450ms;
}

.experience .lockup-eyebrow {
  transition-delay: 250ms;
}

.experience .lockup-headline {
  transition-delay: 350ms;
}

.experience .lockup-sub {
  transition-delay: 450ms;
}

.lockup.is-visible .lockup-rule {
  transform: scaleX(1);
}

.lockup.is-visible .lockup-eyebrow,
.lockup.is-visible .lockup-headline,
.lockup.is-visible .lockup-sub {
  opacity: 1;
  transform: translateY(0);
}

.lockup-headline {
  font-weight: 300;
  font-size: 36px;
  line-height: 1.3;
  letter-spacing: 0.015em;
  color: #FFFFFF;
  text-wrap: pretty;
}

.lockup-sub {
  font-weight: 300;
  font-size: 18px;
  line-height: 1.7;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.75);
  max-width: 280px;
}

.experience-celebration .lockup-sub {
  max-width: 290px;
}

/* 07 THE CHARTER EXPERIENCE + CTA */

.fleet {
  background: var(--bg-fleet);
  display: flex;
  flex-direction: column;
  padding: 32px 36px 24px;
}

.eyebrow {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--accent);
  text-align: center;
}

.lines {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lines-above {
  margin-top: 22px;
}

.lines-below {
  margin-top: 12px;
}

.stat-line {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.stat-line:nth-child(1) {
  align-items: flex-start;
  text-align: left;
}

.stat-line:nth-child(2) {
  align-items: center;
  text-align: center;
}

.stat-line:nth-child(3) {
  align-items: flex-end;
  text-align: right;
}

.stat-label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: #FFFFFF;
  line-height: 2;
}

.stat-rule {
  width: 1px;
  background: var(--accent);
  opacity: 0.6;
  height: 24px;
}

/* Rules always face the hull: above-hull lines draw upward from their
   bottom end, below-hull lines downward from their top end. */
.stat-line.above .stat-rule {
  transform-origin: bottom;
}

.stat-line.below .stat-rule {
  transform-origin: top;
}

.hull-stage {
  margin: 16px -24px 0;
  perspective: 1200px;
}

.hull-rotor {
  transform-style: preserve-3d;
}

.hull {
  width: 100%;
  display: block;
}

.cta-wrap {
  margin-top: auto;
  display: flex;
  justify-content: center;
  padding-top: 16px;
}

/* Button and secondary link travel together; the group is what goes
   fixed. pointer-events stay on the links themselves so the gap
   between them never blocks the page. */
.cta-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  pointer-events: none;
}

.cta-group a {
  pointer-events: auto;
}

/* Explicit row width (the flow content width) so the buttons keep
   exactly the same size when the group leaves the flow and goes
   fixed with width: max-content. */
.cta-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: calc(100vw - 72px);
}

.cta-secondary {
  font-size: 12px;
  font-weight: 300;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  text-decoration: none;
  text-underline-offset: 3px;
}

.cta-secondary:hover,
.cta-secondary:focus-visible {
  text-decoration: underline;
}

/* Solid buttons: opaque in both states so that once fixed they mask
   rather than tangle with any text scrolling behind them. */
.cta {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #FFFFFF;
  color: var(--bg-fleet);
  background: #FFFFFF;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-align: center;
  padding: 13px 8px;
  text-decoration: none;
  transition: background-color 480ms var(--ease), color 480ms var(--ease), transform 200ms var(--ease);
}

.cta:hover,
.cta:focus-visible {
  background: var(--bg-fleet);
  color: #FFFFFF;
}

.cta:active {
  transform: scale(0.97);
}

/* After its entrance the CTA group becomes fixed at the bottom centre
   of the viewport for the rest of the session, at the same offset it
   holds in the fleet section so the swap is position-matched. Centring
   via left/right + margin auto keeps transform free for the press
   scale, and the hit areas stay on the links themselves. */
.cta-fixed {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  margin: 0 auto;
  width: max-content;
  z-index: 100;
}

/* Desktop adaptation — 1440 design */

@media (min-width: 900px) {
  .desktop-br {
    display: inline;
  }

  .mobile-br {
    display: none;
  }

  .brand {
    top: calc(36px + env(safe-area-inset-top, 0px));
    width: 180px;
  }

  /* 01 HERO */
  .scrim-hero {
    background: linear-gradient(180deg, rgba(4, 7, 12, 0.38) 0%, rgba(4, 7, 12, 0.08) 45%, rgba(4, 7, 12, 0.5) 90%, rgba(4, 7, 12, 0.28) 100%);
  }

  .hero-statement {
    font-size: 64px;
    line-height: 1.25;
    letter-spacing: 0.02em;
  }

  .scroll-cue {
    bottom: 44px;
    gap: 14px;
  }

  .scroll-cue-line {
    height: 52px;
  }

  /* 02 OPENING */
  .lockup-wrap {
    padding: 0 96px;
  }

  .lockup-rule {
    width: 64px;
  }

  /* 03–06 THE EXPERIENCES */
  .panel {
    padding: 0 96px;
  }

  .lockup {
    gap: 28px;
  }

  .lockup-headline {
    font-size: 64px;
    line-height: 1.25;
    letter-spacing: 0.02em;
  }

  .lockup-sub {
    font-size: 18px;
    line-height: 1.8;
    max-width: none;
  }

  .experience-celebration .lockup-sub {
    max-width: 640px;
  }

  /* 07 THE CHARTER EXPERIENCE + CTA */
  .fleet {
    display: block;
    padding: 0;
  }

  /* Vertical offsets are proportions of the 900px artboard so the
     layout compresses on shorter viewports instead of colliding with
     the bottom-anchored CTA. */
  .eyebrow {
    position: absolute;
    top: 9.8%;
    left: 0;
    width: 100%;
    font-size: 11px;
    text-align: center;
  }

  .lines {
    position: absolute;
    left: calc(50% - 600px);
    width: 1200px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 96px;
  }

  .lines-above {
    top: 18.7%;
    margin-top: 0;
  }

  .lines-below {
    /* 72% of the artboard, but always leaving 240px beneath for the
       labels, clearance and the bottom-anchored CTA on short windows. */
    top: min(72%, calc(100% - 240px));
    margin-top: 0;
  }

  .stat-line {
    gap: 14px;
  }

  .lines-above .stat-line {
    justify-content: flex-end;
  }

  .stat-label {
    font-size: 12px;
    letter-spacing: 0.32em;
    line-height: 2.1;
  }

  .stat-line:nth-child(3) .stat-label {
    white-space: nowrap;
  }

  .stat-rule {
    height: 44px;
  }

  .hull-stage {
    position: absolute;
    top: 33.6%;
    left: calc(50% - 440px);
    width: 880px;
    margin: 0;
  }

  .hull {
    stroke-width: 0.9;
  }

  .hull path[stroke-width="1.4"] {
    stroke-width: 1.1;
  }

  .hull path[stroke-width="1"] {
    stroke-width: 0.8;
  }

  /* The group anchor sits one link-row lower than the button's design
     offset, keeping the button itself at the artboard position with
     the secondary link tucked beneath. */
  .cta-wrap {
    position: absolute;
    bottom: max(16px, calc(clamp(24px, 7.1%, 64px) - 30px));
    left: 0;
    width: 100%;
    margin-top: 0;
    padding-top: 0;
  }

  .cta-row {
    flex-direction: row;
    width: auto;
    gap: 16px;
  }

  .cta {
    flex: none;
    font-size: 11px;
    letter-spacing: 0.28em;
    min-width: 220px;
    padding: 16px 28px;
    white-space: nowrap;
  }

  /* Matches the desktop flow offset of the group. */
  .cta-fixed {
    bottom: calc(max(16px, calc(clamp(24px, 7.1svh, 64px) - 30px)) + env(safe-area-inset-bottom, 0px));
  }
}

/* Reduced motion — a calm mode, not a static one: videos and all
   scroll-paced behaviour continue (remote desktops force the reduce
   flag on), while decorative motion stills: no cue pulse, no draw
   animations, text fades without moving. html.no-motion (GSAP failed
   to load) stacks the experience beats statically instead, so the
   panel text is never unreachable. */

@media (prefers-reduced-motion: reduce) {
  .hero-statement {
    animation: none;
    opacity: 1;
  }

  .scroll-cue-line {
    animation: none;
  }

  .cta {
    transition: none;
  }

  /* Text entrances under reduced motion: every mint rule appears at
     full width with no draw, and the text fades only, no movement. */
  .lockup-rule {
    transform: none;
    transition: none;
  }

  .lockup-eyebrow,
  .lockup-headline,
  .lockup-sub {
    transform: none;
    transition: opacity 700ms var(--ease);
  }
}

html.no-motion .experience,
html.no-motion .experience .frame {
  position: static;
  height: auto;
  overflow: visible;
}

html.no-motion .experience .media {
  position: relative;
  display: block;
  height: 100svh;
}

html.no-motion .panel {
  position: relative;
  transform: none;
  height: 100svh;
}

html.no-motion .lockup-rule {
  transform: none;
  transition: none;
}

html.no-motion .lockup-eyebrow,
html.no-motion .lockup-headline,
html.no-motion .lockup-sub {
  opacity: 1;
  transform: none;
  transition: none;
}
