/* ============================================================
   Skies of Fight — style.css
   Mango 9 Sep 26: one page. The sky is the title card; below the
   horizon the page falls into night and holds the chapters. The
   palette is lifted straight off the logo — sky blue for the world,
   hot orange for anything the visitor is meant to click.
   ============================================================ */

:root {
  /* --- sky --- */
  --sky-high:   #1663AE;
  --sky-mid:    #4E9BDA;
  --sky-low:    #9FCDEC;
  --sky-haze:   #DCEAF4;
  --sea-high:   #7FB2D6;
  --sea-low:    #4B84B4;

  /* --- night, everything below the horizon ---
     Mango 10 Sep 26: the chapters ride on a gradient that follows the
     four wave screenshots, one tone per picture, top to bottom: day
     sea, sunset, the shmup's deep blue, then night. Each tone is a
     darkened cut of the picture that sits on it, so the picture reads
     as a wash of colour on its own hue.
     --wave-alpha is how much of the picture shows through. */
  --wave-1:     #2D363D;
  --wave-2:     #7C3712;
  --wave-3:     #0B2C7A;
  --wave-4:     #000000;
  --wave-5:     #23103C;
  --wave-alpha: 0.24;
  --night:      #000000;
  --night-text: rgba(255, 255, 255, 0.78);
  --night-rule: rgba(255, 255, 255, 0.13);

  /* --- the loud one --- */
  --flame:      #F07216;
  --flame-hot:  #FF9227;
  --flame-deep: #C4520A;

  /* How deep the sea band is, measured up from the bottom of the hero.
     The horizon is wherever this band starts, and the hero pads its
     content clear of it, so the horizon can never cut through a line of
     text at any window size. Raise this to bring the horizon up. */
  --sea-h: clamp(76px, 14vh, 158px);
  --hero-pad-y: clamp(56px, 9vh, 96px);

  /* One typeface does the whole page, the way the arcade cabinets did
     it: weight and size carry the hierarchy, not a second family. */
  --font: "Sora", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* One place to retune the whole site's rhythm. */
  --gutter: clamp(20px, 5vw, 64px);
  --section-y: clamp(64px, 10vw, 128px);
  --measure: 62ch;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--night);
  color: var(--night-text);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3 {
  font-family: var(--font);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0;
}

p { margin: 0; }
p + p { margin-top: 1.05em; }

a { color: var(--flame-deep); }

/* Reachable by screen readers, invisible to everyone else. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The one word that gets to be loud. */
.flame { color: var(--flame-hot); }


/* ============================================================
   BUTTONS
   ============================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: #fff;
  background: linear-gradient(180deg, var(--flame-hot), var(--flame));
  border: 0;
  border-radius: 3px;
  /* A hard darker lip instead of a soft shadow: the button reads as a
     physical cabinet key, and pressing it actually travels downward. */
  box-shadow: 0 4px 0 var(--flame-deep), 0 6px 18px rgba(11, 30, 49, 0.28);
  transition: transform 0.09s ease, box-shadow 0.09s ease, filter 0.15s ease;
}
.btn:hover { filter: brightness(1.07); }
.btn:active {
  transform: translateY(3px);
  box-shadow: 0 1px 0 var(--flame-deep), 0 2px 8px rgba(11, 30, 49, 0.28);
}
.btn:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

.btn-big { padding: 16px 32px; font-size: clamp(18px, 2.3vw, 23px); }


/* ============================================================
   THE SKY
   Stacked CSS layers, no hero image to download.
   ============================================================ */

.sky { position: absolute; inset: 0; }

.sky-gradient {
  position: absolute; inset: 0;
  background: linear-gradient(
    180deg,
    var(--sky-high)  0%,
    var(--sky-mid)   calc((100% - var(--sea-h)) * 0.50),
    var(--sky-low)   calc((100% - var(--sea-h)) * 0.87),
    var(--sky-haze)  calc(100% - var(--sea-h))
  );
}

/* A soft sun bloom sitting just above the horizon. */
.sky-glow {
  position: absolute;
  left: 50%; top: calc(100% - var(--sea-h));
  width: 150vmax; height: 70vmax;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    ellipse at center,
    rgba(255, 246, 226, 0.55) 0%,
    rgba(255, 236, 200, 0.20) 32%,
    rgba(255, 236, 200, 0) 62%
  );
}

/* --- cloud bands ---------------------------------------------
   Each band is one wide tile of soft ellipses, scrolled sideways
   by animating background-position. The tile repeats, so the loop
   is seamless with no JS and no image files.
   ------------------------------------------------------------- */
.cloud-band {
  position: absolute;
  left: -10%; right: -10%;
  background-repeat: repeat-x;
  will-change: background-position;
}

.cloud-far {
  top: 8%; height: 26%;
  opacity: 0.5;
  background-image:
    radial-gradient(70px 14px at 120px 60%, rgba(255,255,255,0.85), rgba(255,255,255,0) 70%),
    radial-gradient(110px 18px at 420px 40%, rgba(255,255,255,0.7),  rgba(255,255,255,0) 70%),
    radial-gradient(80px 13px at 760px 72%, rgba(255,255,255,0.8),  rgba(255,255,255,0) 70%),
    radial-gradient(130px 20px at 1080px 30%, rgba(255,255,255,0.6), rgba(255,255,255,0) 70%);
  background-size: 1300px 100%;
  animation: drift-left 130s linear infinite;
}

.cloud-mid {
  top: 26%; height: 30%;
  opacity: 0.6;
  background-image:
    radial-gradient(150px 26px at 200px 50%, rgba(255,255,255,0.9),  rgba(255,255,255,0) 72%),
    radial-gradient(210px 34px at 640px 30%, rgba(255,255,255,0.75), rgba(255,255,255,0) 72%),
    radial-gradient(170px 28px at 1050px 66%, rgba(255,255,255,0.85), rgba(255,255,255,0) 72%);
  background-size: 1450px 100%;
  animation: drift-left 78s linear infinite;
}

.cloud-near {
  bottom: var(--sea-h); height: 20%;
  opacity: 0.42;
  background-image:
    radial-gradient(260px 40px at 260px 40%, rgba(255,255,255,0.85), rgba(255,255,255,0) 72%),
    radial-gradient(320px 52px at 900px 62%, rgba(255,255,255,0.7),  rgba(255,255,255,0) 72%);
  background-size: 1600px 100%;
  animation: drift-left 42s linear infinite;
}

@keyframes drift-left {
  from { background-position-x: 0; }
  to   { background-position-x: -1600px; }
}

/* --- sea ------------------------------------------------------ */
.sea {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: var(--sea-h);
  background: linear-gradient(180deg, var(--sea-high) 0%, var(--sea-low) 100%);
  overflow: hidden;
}
/* A hairline of glare exactly where sky meets water. */
.sea::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: 2px;
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.85) 35%,
    rgba(255,255,255,0.95) 50%,
    rgba(255,255,255,0.85) 65%,
    rgba(255,255,255,0) 100%);
}
.sea-shimmer {
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(
    180deg,
    rgba(255,255,255,0.16) 0px,
    rgba(255,255,255,0.16) 1px,
    rgba(255,255,255,0) 1px,
    rgba(255,255,255,0) 7px
  );
  animation: shimmer 9s ease-in-out infinite;
}
@keyframes shimmer {
  0%, 100% { opacity: 0.55; transform: translateY(0); }
  50%      { opacity: 0.9;  transform: translateY(2px); }
}

.sky-vignette {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 45%,
    rgba(0,0,0,0) 45%, rgba(4, 24, 44, 0.36) 100%);
}


/* ============================================================
   THE TITLE SECTION
   ============================================================ */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: var(--hero-pad-y) var(--gutter)
           calc(var(--hero-pad-y) + var(--sea-h));
  text-align: center;
}

.hero-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 1000px;
}

.hero-logo {
  display: block;
  width: min(94vw, 1040px);
  height: auto;
  filter: drop-shadow(0 10px 26px rgba(4, 22, 42, 0.45));

  /* The banner is a photo of a sky sitting on top of a live sky, so its
     edges would otherwise read as a rectangle pasted on. Two gradients
     intersected feather all four sides: the vertical stops are pulled in
     tight because the wordmark itself occupies 14%-85% of the image and
     must not be touched. If a browser ignores masks the image simply
     shows in full, which is merely less pretty. */
  --edge-x: linear-gradient(90deg,
    transparent 0%, #000 11%, #000 89%, transparent 100%);
  --edge-y: linear-gradient(180deg,
    transparent 0%, #000 9%, #000 88%, transparent 100%);
  -webkit-mask-image: var(--edge-x), var(--edge-y);
  -webkit-mask-composite: source-in;
  mask-image: var(--edge-x), var(--edge-y);
  mask-composite: intersect;
}

/* --- the writing on the sky -----------------------------------
   Type on the sky, nothing else. A box around it would compete
   with the one real button on the page. The measure is short so
   the lines stay easy to read against a moving background.
   --------------------------------------------------------------- */
.hero-intro {
  margin-top: clamp(18px, 3.5vh, 40px);
  max-width: 54ch;
  color: #fff;
  font-size: clamp(17px, 2vw, 21px);
  font-weight: 500;
  line-height: 1.5;
  text-shadow: 0 2px 14px rgba(4, 22, 42, 0.72), 0 1px 3px rgba(4, 22, 42, 0.55);
}

.hero-cta { margin-top: clamp(22px, 4vh, 40px); }

/* --- the scroll cue -------------------------------------------
   A chevron drawn from two borders on a rotated square, so there
   is no glyph and no image to load. Orange because it has to hold
   against both the pale haze and the darker water underneath it.
   --------------------------------------------------------------- */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: calc(var(--sea-h) + 24px);
  z-index: 2;
  transform: translateX(-50%);
  padding: 12px;
  animation: cue-bob 2.4s ease-in-out infinite;
}
.scroll-cue-mark {
  display: block;
  width: 18px; height: 18px;
  border-right: 3px solid var(--flame);
  border-bottom: 3px solid var(--flame);
  transform: rotate(45deg);
  filter: drop-shadow(0 1px 2px rgba(255, 255, 255, 0.7));
}
.scroll-cue:focus-visible { outline: 3px solid var(--flame); outline-offset: 2px; }

@keyframes cue-bob {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 7px); }
}


/* ============================================================
   IMAGE SLOTS
   Mango 9 Sep 26: a picture is shown whole, at whatever shape it
   happens to be. Only the empty placeholder needs a made-up shape,
   because it has no picture to measure.
   ============================================================ */

.shot {
  display: block;
  width: 100%;
  border-radius: 5px;
  box-shadow: 0 8px 24px rgba(11, 30, 49, 0.18);
}

/* The image sets its own height from its own proportions. */
img.shot { height: auto; }

/* The placeholder borrows a 16:9 box so it holds the right space. */
div.shot {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 9;
  background: linear-gradient(160deg, var(--sky-low), var(--sea-low));
}
.shot span {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  border: 2px dashed rgba(255, 255, 255, 0.5);
  border-radius: 3px;
  padding: 9px 16px;
  text-align: center;
}


/* ============================================================
   THE CHAPTERS
   The band spans the window so the night gradient reaches both
   edges; the reading column is the inner div.
   ============================================================ */

.chapters {
  position: relative;
  padding: var(--section-y) var(--gutter);
  /* Five pictures, five stops, each at the centre of its fifth. The
     fair stops for N pictures are (i + 0.5) / N, so a sixth would be
     8.3 / 25 / 41.7 / 58.3 / 75 / 91.7%. */
  background: linear-gradient(180deg,
    var(--wave-1) 10%,
    var(--wave-2) 30%,
    var(--wave-3) 50%,
    var(--wave-4) 70%,
    var(--wave-5) 90%);
}
.chapters-inner {
  position: relative;
  z-index: 1;            /* the reading column sits above the pictures */
  max-width: 1180px;
  margin: 0 auto;
}

/* --- the wave stage ------------------------------------------
   Mango 10 Sep 26. .chapters-bg is a layer the exact size of the
   band. Inside it the stage is position: sticky, so it rides along
   pinned to the viewport for as long as the band is on screen, then
   lets go when the band's bottom edge arrives. The pictures stack
   inside the stage; main.js sets --wave-mix (0..1) on each one to
   crossfade, and --wave-drift for a slow parallax slide.

   The stage is scaled up a touch so the drift never shows an edge.
   ------------------------------------------------------------- */
.chapters-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.wave-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.wave {
  --wave-mix: 0;
  --wave-drift: 0px;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: calc(var(--wave-alpha) * var(--wave-mix));
  transform: scale(1.12) translateY(var(--wave-drift));
  will-change: opacity, transform;
}
/* The first picture shows before the script runs, so the band is
   never bare while the page is still loading. */
.no-js .wave:first-child { --wave-mix: 1; }

.chapter {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 4.5vw, 64px);
  align-items: center;
}
.chapter + .chapter {
  margin-top: var(--section-y);
  padding-top: var(--section-y);
  border-top: 1px solid var(--night-rule);
}

/* Every other chapter puts its art on the left. Ordering the grid
   items rather than reordering the markup keeps the reading order
   intact for screen readers. */
.chapter-flip .chapter-text { order: 2; }
.chapter-flip .chapter-art  { order: 1; }

.chapter-text h2 {
  font-size: clamp(27px, 3.6vw, 40px);
  margin-bottom: 16px;
  color: #fff;
}
.chapter-text p { color: var(--night-text); max-width: var(--measure); }

.chapter-art { display: grid; gap: clamp(12px, 1.6vw, 18px); }


/* ============================================================
   THE STUDIO CARD
   Mango 11 Sep 26: the logo with a row of link buttons under it.
   Five separate images in a flex row rather than one picture with
   an image map: each button gets its own hover, focus ring and alt
   text, and the row wraps on a narrow screen instead of shrinking.
   ============================================================ */

.links-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(20px, 3vw, 36px);
}

.links-logo {
  display: block;
  width: min(100%, 440px);
  height: auto;
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.45));
}

.links-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(12px, 2vw, 22px);
}

/* --links-size is the one number that sizes every button. The source
   images are different pixel sizes; the img fills the anchor so they
   all land at the same width regardless. */
.links-btn {
  --links-size: clamp(52px, 7vw, 84px);
  display: block;
  width: var(--links-size);
  height: var(--links-size);
  border-radius: 22%;
  transition: transform 0.15s ease, filter 0.15s ease;
}
.links-btn img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.links-btn:hover { transform: translateY(-4px); filter: brightness(1.12); }
.links-btn:focus-visible { outline: 3px solid var(--flame-hot); outline-offset: 4px; }


/* ============================================================
   FOOTER
   ============================================================ */

.site-footer {
  padding: 44px var(--gutter) 56px;
  background: var(--night);
  color: rgba(255, 255, 255, 0.62);
  text-align: center;
}
.footer-title {
  font-family: var(--font);
  font-weight: 700;
  font-size: 18px;
  color: #fff;
  margin-bottom: 8px;
}
.footer-meta { font-size: 15px; }
.footer-meta + .footer-meta { margin-top: 6px; }
.site-footer a { color: var(--flame-hot); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }


/* ============================================================
   SCROLL REVEAL
   .reveal is the resting state; main.js adds .in when the element
   scrolls into view. The .no-js rule is the safety net: if the
   script never runs, nothing stays invisible.
   ============================================================ */

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.reveal.in { opacity: 1; transform: none; }
.no-js .reveal { opacity: 1; transform: none; }


/* ============================================================
   MOTION PREFERENCES
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .cloud-band, .sea-shimmer { animation: none; }
  .scroll-cue { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .btn, .links-btn { transition: none; }
  /* The crossfade moves at scroll pace so it stays; only the drift goes. */
  .wave { transform: scale(1.12); }
}


/* ============================================================
   NARROW SCREENS
   ============================================================ */

@media (max-width: 820px) {
  .chapter { grid-template-columns: minmax(0, 1fr); }
  /* On one column the art always follows its text, flip or not. */
  .chapter-flip .chapter-text { order: 0; }
  .chapter-flip .chapter-art  { order: 0; }
  .chapter-art { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .hero-logo { width: 100vw; max-width: none; }
  .chapter-art { grid-template-columns: minmax(0, 1fr); }
  /* The cue costs vertical room the small screen does not have. */
  .scroll-cue { display: none; }
}
