/* ==========================================================================
   NS27 · Arctic Express — landing page
   Global styles. Component styling lives inline in index.html, exactly as
   authored in the Claude Design source, so the two stay easy to diff.
   ========================================================================== */

* { box-sizing: border-box; }
html, body { margin: 0; background: #000; }
html { scroll-behavior: auto; }
body { overflow-x: hidden; }

/* The page carries its own scroll rail on the right edge, so the native bar
   sits redundant beside it. Only the drawn handle goes: wheel, trackpad,
   touch, arrow keys, space bar, Page Up and Down and Home and End all still
   scroll normally. Delete this block to bring the native bar back. */
html {
  scrollbar-width: none;      /* Firefox */
  -ms-overflow-style: none;   /* legacy Edge */
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {     /* Chrome, Safari, current Edge */
  width: 0;
  height: 0;
  display: none;
}
img, video { display: block; }
::selection { background: rgba(226, 232, 237, 0.22); }

@keyframes grainShift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-2%, 1.5%); }
  50%  { transform: translate(1.5%, -2%); }
  75%  { transform: translate(-1%, -1%); }
  100% { transform: translate(2%, 2%); }
}

@keyframes cuePulse {
  0%, 100% { opacity: 0.25; }
  50%      { opacity: 0.9; }
}

/* --------------------------------------------------------------------------
   Hero film fallback
   The scroll-scrubbed film is the hero. If assets/arctic-train.mp4 is absent
   or unplayable, this arctic-night wash takes its place so the frame, the
   scrim and all five text beats still read as designed.
   -------------------------------------------------------------------------- */
[data-hero-fallback] {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 1400ms cubic-bezier(0.22, 1, 0.36, 1);
  background: linear-gradient(180deg, #050a10 0%, #080e15 48%, #020406 100%);
}
[data-hero-fallback].is-on { opacity: 1; }
[data-hero-fallback]::before,
[data-hero-fallback]::after {
  content: "";
  position: absolute;
  inset: -22%;
  pointer-events: none;
}
[data-hero-fallback]::before {
  background:
    radial-gradient(45% 30% at 30% 34%, rgba(96, 142, 166, 0.34), rgba(0, 0, 0, 0) 70%),
    radial-gradient(40% 26% at 72% 25%, rgba(64, 98, 128, 0.30), rgba(0, 0, 0, 0) 70%);
  animation: auroraA 26s ease-in-out infinite alternate;
}
[data-hero-fallback]::after {
  background: radial-gradient(60% 40% at 50% 88%, rgba(226, 232, 237, 0.12), rgba(0, 0, 0, 0) 72%);
  animation: auroraB 34s ease-in-out infinite alternate;
}
@keyframes auroraA {
  0%   { transform: translate3d(-4%, 2%, 0) scale(1.05); }
  100% { transform: translate3d(5%, -3%, 0) scale(1.18); }
}
@keyframes auroraB {
  0%   { transform: translate3d(3%, 3%, 0) scale(1.10); }
  100% { transform: translate3d(-4%, -2%, 0) scale(1.02); }
}

/* --------------------------------------------------------------------------
   Partner logos
   The ledger is monochrome, so the marks sit back a little and come up to full
   on hover, the same move the names they replaced made. Each logo carries its
   own --h because a stacked crest and a wide wordmark cannot share a height
   and still read at the same weight.
   -------------------------------------------------------------------------- */
.partner { display: inline-flex; align-items: center; cursor: default; }
.partner-logo {
  display: block;
  height: var(--h, 24px);
  width: auto;
  object-fit: contain;
  opacity: 0.82;
  transition: opacity 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
.partner:hover .partner-logo { opacity: 1; }
/* The ecosystem tier sat at 0.55 as text. Logo strokes are thinner than type,
   so the same number reads fainter and needs a little back. */
.partner-quiet .partner-logo { opacity: 0.62; }

/* --------------------------------------------------------------------------
   Image slots
   Every slot ships with the path its photograph belongs at. A slot with no
   file behind it collapses out of the layout entirely rather than leaving an
   empty frame on the page, and main.js clears data-media-empty the moment the
   image loads, so the designed two-column composition returns on its own.
   -------------------------------------------------------------------------- */
.slot {
  position: relative;
  display: block;
  margin: 0;
  overflow: hidden;
  background: #04060a;
}
.slot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
.slot.is-filled img { opacity: 1; }

/* No file, no frame. */
[data-media-empty] { display: none !important; }

/* A Journey stop whose photograph is missing keeps the two-column row and
   holds the side its copy was designed to sit on, so the four stops go on
   alternating down the rail rather than all stacking to the left. */
[data-stop][data-solo] [data-stop-copy] { grid-column: 1; }
[data-stop][data-solo] [data-copy-right] { grid-column: 2; }

/* --------------------------------------------------------------------------
   Responsive: tablet
   -------------------------------------------------------------------------- */
@media (max-width: 820px) {
  /* In Good Company: stack the tier label above its members */
  [data-tier-row] {
    grid-template-columns: 1fr !important;
    gap: 18px !important;
  }
  /* The Offer: stack heading above description */
  [data-offer-row] {
    grid-template-columns: 1fr !important;
    gap: 22px !important;
    padding-left: 20px !important;
    padding-right: 20px !important;
  }
}

/* --------------------------------------------------------------------------
   Responsive: phone
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* Roomier vertical rhythm, tighter sides on every section */
  [data-screen-label] { padding-left: 20px !important; padding-right: 20px !important; }

  /* Nav: the wordmark, the co-host mark and a full-size CTA will not share a
     390px bar. Drop the co-host mark here, it still carries the preloader and
     the footer, and tighten the button. */
  [data-nav] { padding: 16px 20px !important; }
  [data-nav-cohost] { display: none !important; }
  [data-nav-wordmark] { font-size: 18px !important; letter-spacing: 0.18em !important; text-indent: 0.18em !important; }
  [data-nav-cta] { padding: 9px 14px !important; font-size: 10px !important; letter-spacing: 0.1em !important; }

  /* The scroll rail is a pointer affordance and it collides with the nav on a
     narrow screen. */
  [data-scroll-rail] { display: none !important; }

  /* See the note in drawConstellation: without the gauge to hang from, the
     strands stop reading as strands. */
  [data-ref="constellation"] { display: none !important; }

  /* Hero: bigger film frame so it isn't a stamp on a tall phone screen.
     :not([data-full]) keeps the full-bleed cut at the end of the hero intact. */
  [data-hero-card]:not([data-full]) { width: 88vw !important; }

  /* The Facts: drop the survey gauge and become a plain 2-up list */
  [data-facts-grid] {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 44px 16px !important;
    min-height: 0 !important;
  }
  [data-facts-wrap] { min-height: 0 !important; }
  [data-fact-stack] { position: static !important; transform: none !important; }
  [data-fact-block] { padding-top: 0 !important; padding-bottom: 0 !important; }
  [data-reveal="stem"],
  [data-gauge-line],
  [data-gauge-ticks],
  [data-gauge-dot] { display: none !important; }

  /* The Journey: single column, photograph first then copy */
  [data-stop] { grid-template-columns: 1fr !important; gap: 28px !important; }
  [data-stop-media] { order: -1 !important; }
  /* One column here, so the alternating side above has to be unwound or the
     copy would ask for a column that does not exist. */
  [data-stop-copy] { order: 0 !important; grid-column: 1 !important; }

  /* In Good Company: the marks come down a step so a row of them still fits */
  .partner-logo { height: calc(var(--h, 24px) * 0.82); }

  /* The Builders: three long lines plus a two-line heading is a lot for a
     narrow screen, so the rhythm tightens to keep the pinned scene on one
     viewport. */
  [data-screen-label="The Forty"] h2 { margin-bottom: 40px !important; }
  [data-screen-label="The Forty"] p { margin-top: 34px !important; }
  [data-forty-row] { padding-top: 18px !important; padding-bottom: 18px !important; }
}

/* --------------------------------------------------------------------------
   Short viewports
   The Builders and The Turn pin a full viewport and hold their copy inside it.
   That assumes the viewport is tall enough. On a small phone, and on any phone
   held sideways, it is not, and the copy was being cut off at both ends. Below
   this height both scenes release the pin and read as ordinary sections.
   The staged reveal is driven by scroll progress through the pin, so it goes
   with it. The steps are shown outright instead of being left at zero.
   -------------------------------------------------------------------------- */
@media (max-height: 700px) {
  [data-screen-label="The Forty"],
  [data-screen-label="The Turn"] { height: auto !important; }

  [data-screen-label="The Forty"] > div,
  [data-screen-label="The Turn"] > div {
    position: static !important;
    height: auto !important;
    padding-top: 96px !important;
    padding-bottom: 96px !important;
  }

  [data-forty-step] { opacity: 1 !important; transform: none !important; }
  [data-turn-word] { opacity: 1 !important; transform: none !important; }
  [data-turn-underline] { transform: scaleX(1) !important; }
}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-grain],
  [data-hero-fallback]::before,
  [data-hero-fallback]::after,
  [data-cue] span { animation: none !important; }
}
