/* =====================================================================
   WATERLINE — site styles
   The palette is lifted verbatim from the game's :root block (index.html)
   so the site and the app are tinted from one source, not two.
   Mobile-first. Everything that animates is transform/opacity only.
   ===================================================================== */

:root {
  --ink:        #0b1017;
  --paper:      #212d43;
  --paper-deep: #121926;
  --vessel:     #233546;
  --vessel-lit: #2b4356;
  --water:      #2fb4c8;
  --water-lit:  #6fd4e0;
  --foam:       #e9e7cd;
  --wood:       #dab77e;
  --wood-dark:  #ac8551;
  --gold:       #e3a33c;
  --gold-lit:   #ffdf9d;
  --cream:      #f4ecc9;
  --muted:      #8a9ab4;

  /* the accent light of the moment — retinted per district, exactly the way
     applySection() retints the game's HUD when the player changes district. */
  --accent:     #6fd4e0;
  --accent-dim: rgba(111, 212, 224, .16);

  --ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;

  --gutter: clamp(20px, 5.5vw, 64px);
  --measure: 34ch;
  --frame-shadow: 5px 6px 0 var(--ink);
}

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

html {
  background: var(--ink);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  font: 400 clamp(1rem, 0.96rem + 0.35vw, 1.1rem)/1.62 var(--ui);
  color: var(--cream);
  background:
    radial-gradient(120% 60% at 22% 3%,  rgba(140,170,224,.055), rgba(0,0,0,0) 58%),
    radial-gradient(120% 55% at 78% 99%, rgba(5,9,18,.34),        rgba(0,0,0,0) 60%),
    var(--paper);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: var(--water-lit); text-decoration-color: rgba(111,212,224,.4); text-underline-offset: 3px; }
a:hover { color: var(--gold-lit); text-decoration-color: rgba(255,223,157,.6); }
:focus-visible { outline: 2px solid var(--gold-lit); outline-offset: 3px; border-radius: 3px; }

/* ---------------------------------------------------------------- layers */

/* the water. Fixed behind everything, painted by flood.js. */
#flood {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
}

/* a paper grain + vignette over the water, under the type. Keeps the flat
   canvas fill from reading as a coloured <div>. */
#grain {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(140% 100% at 50% 50%, rgba(0,0,0,0) 42%, rgba(6,10,18,.55) 100%);
  mix-blend-mode: multiply;
}

.page { position: relative; z-index: 2; }

/* the same water, painted a second time in FRONT of the page: a thin cast
   over whatever the flood has already swallowed, and the waterline itself
   crossing the art. This is the layer that makes it read as flooding. */
#flood-fore {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: 3; pointer-events: none;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: var(--gold); color: var(--ink); padding: 10px 16px;
  font-weight: 700; border-radius: 0 0 8px 0; text-decoration: none;
}
.skip:focus { left: 0; }

/* ------------------------------------------------------------------- nav */

#nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  display: flex; align-items: center; gap: 14px;
  padding: 12px var(--gutter);
  background: linear-gradient(rgba(11,16,23,.82), rgba(11,16,23,0));
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0; transform: translateY(-8px);
  transition: opacity .45s ease, transform .45s ease;
}
#nav.on { opacity: 1; transform: none; }
#nav .mark {
  display: flex; align-items: center; gap: 9px;
  font-weight: 800; font-size: .84rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--cream); text-decoration: none;
}
#nav .mark img { width: 18px; height: 18px; }
#nav nav { margin-left: auto; display: flex; gap: clamp(12px, 3vw, 28px); }
#nav nav a {
  font-size: .78rem; letter-spacing: .08em; color: var(--muted);
  text-decoration: none; white-space: nowrap;
}
#nav nav a:hover { color: var(--gold-lit); }
@media (max-width: 560px) { #nav nav a.opt { display: none; } }

/* --------------------------------------------------------------- shared */

.wrap { width: 100%; max-width: 1120px; margin-inline: auto; padding-inline: var(--gutter); }

.kicker {
  font-size: .7rem; font-weight: 700; letter-spacing: .34em;
  text-transform: uppercase; color: var(--muted); margin: 0;
}

h1, h2, h3 { font-weight: 800; letter-spacing: -.02em; line-height: 1.06; margin: 0; }

.h-section { font-size: clamp(1.85rem, 1.1rem + 3.6vw, 3.1rem); }

.lede { color: rgba(244,236,201,.78); }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

/* the game's card: 2px ink border, hard offset shadow, no soft blur. */
.frame {
  position: relative;
  border: 2px solid var(--ink);
  border-radius: 12px;
  box-shadow: var(--frame-shadow);
  overflow: hidden;
  background: var(--paper-deep);
}
.frame::after { /* the accent light of the district, laid over the art */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0) 55%, rgba(11,16,23,.42));
  mix-blend-mode: multiply;
}
.frame img { width: 100%; height: 100%; object-fit: cover; }

/* ------------------------------------------------------------------ hero */

#hero {
  position: relative;
  min-height: 100vh;   /* fallback for browsers without svh */
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(96px, 16vh, 150px) 0 clamp(72px, 12vh, 110px);
  overflow: hidden;
}
#hero .hero-bg {
  position: absolute; inset: 0; z-index: -1;
  overflow: hidden;
  /* the rooftops stop short of the bottom of the frame so the first
     waterline can sit low on the viewport, behind the words. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 62%, rgba(0,0,0,.35) 86%, rgba(0,0,0,0) 99%);
          mask-image: linear-gradient(180deg, #000 0%, #000 62%, rgba(0,0,0,.35) 86%, rgba(0,0,0,0) 99%);
}
#hero .hero-bg img {
  width: 100%; height: 118%;
  object-fit: cover; object-position: 50% 22%;
  opacity: .92;
  will-change: transform;
}
#hero .hero-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(11,16,23,.62) 0%, rgba(11,16,23,.16) 44%, rgba(18,25,38,.60) 100%);
}

.hero-inner { max-width: 44rem; }
.hero-mark {
  width: clamp(230px, 62vw, 420px);
  margin: 14px 0 clamp(18px, 4vw, 26px);
  filter: drop-shadow(0 8px 22px rgba(4,8,14,.7));
}
.hero-tagline {
  font-size: clamp(2.1rem, 1rem + 5.6vw, 4.1rem);
  line-height: 1.02;
  text-wrap: balance;
  text-shadow: 0 3px 26px rgba(4,8,14,.75);
}
.hero-invite {
  margin-top: clamp(16px, 3vw, 22px);
  max-width: 32rem;
  color: rgba(244,236,201,.84);
  font-size: clamp(1rem, .95rem + .5vw, 1.2rem);
}
.hero-status {
  margin-top: clamp(22px, 4vw, 30px);
  max-width: 30rem;
  font-size: .88rem; line-height: 1.55; color: var(--muted);
  padding-left: 14px; border-left: 2px solid rgba(111,212,224,.3);
}
.hero-cta {
  display: inline-flex; align-items: center; gap: 10px;
  margin-top: clamp(22px, 4vw, 28px);
  padding: 13px 22px;
  font: 700 .92rem/1 var(--ui); letter-spacing: .04em;
  color: var(--ink); background: var(--gold);
  border: 2px solid var(--ink); border-radius: 10px;
  box-shadow: 4px 5px 0 var(--ink);
  text-decoration: none;
  transition: transform .16s ease, box-shadow .16s ease, background-color .16s ease;
}
.hero-cta:hover { background: var(--gold-lit); color: var(--ink); transform: translate(1px, 2px); box-shadow: 3px 3px 0 var(--ink); }
.hero-cta:active { transform: translate(4px, 5px); box-shadow: 0 0 0 var(--ink); }
.hero-cta .drip { width: 9px; height: 9px; border-radius: 0 50% 50% 50%; background: var(--ink); transform: rotate(45deg); opacity: .82; }

.scroll-cue {
  position: absolute; left: 50%; bottom: calc(clamp(46px, 7vh, 74px) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  font-size: .64rem; letter-spacing: .3em; text-transform: uppercase; color: var(--muted);
}
.scroll-cue .rail {
  width: 1px; height: 40px;
  background: linear-gradient(var(--water-lit), rgba(111,212,224,0));
  position: relative; overflow: hidden;
}
.scroll-cue .rail::after {
  content: ""; position: absolute; left: -1.5px; top: 0;
  width: 4px; height: 4px; border-radius: 50%; background: var(--water-lit);
  animation: drip 2.6s ease-in infinite;
}
@keyframes drip {
  0%   { transform: translateY(-6px); opacity: 0; }
  22%  { opacity: 1; }
  100% { transform: translateY(40px); opacity: 0; }
}

/* ----------------------------------------------------------- story beats */

#story { position: relative; }

.beat-stage {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex; align-items: center;
  padding: clamp(70px, 12vh, 110px) 0;
}
.beat-stage .wrap { position: relative; width: 100%; }

.beat { display: grid; gap: clamp(22px, 4vw, 44px); align-items: center; }

/* The four beats hold still while the reader scrolls past them. The track
   reserves the scroll distance in CSS, so the document is its full height
   from the very first layout — lazy images below stay lazy, nothing jumps
   when the script arrives, and there is no pin-spacer to maintain. */
html.js-motion .beat-track { height: 460vh; height: 460svh; position: relative; }
html.js-motion .beat-track .beat-stage {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  min-height: 100vh; min-height: 100svh;
  padding: 0;
}

/* stacked cross-fade — only when JS + motion are actually driving it */
html.js-motion .beat-stage .beats {
  position: relative;
  min-height: min(74vh, 660px);
  min-height: min(74svh, 660px);
}
html.js-motion .beat {
  position: absolute; inset: 0;
  align-content: center;
  opacity: 0;
  will-change: transform, opacity;
}
/* no JS motion: the four beats simply stack down the page */
html:not(.js-motion) .beats { display: flex; flex-direction: column; gap: clamp(52px, 9vh, 96px); }
html:not(.js-motion) .beat-stage { min-height: 0; padding: clamp(46px, 8vh, 80px) 0; }

.beat-art { width: 100%; aspect-ratio: 2 / 3; max-width: min(60vw, 262px); margin-inline: auto; }
.beat-copy { max-width: 30rem; }
.beat-no {
  font: 800 .72rem/1 var(--ui); letter-spacing: .3em; color: var(--accent);
  display: flex; align-items: center; gap: 12px; margin-bottom: 14px;
}
.beat-no::after { content: ""; height: 1px; flex: 1; background: linear-gradient(90deg, var(--accent-dim), rgba(0,0,0,0)); }
.beat-copy p {
  font-size: clamp(1.12rem, .98rem + 1.1vw, 1.6rem);
  line-height: 1.45; letter-spacing: -.01em;
  color: var(--cream);
  text-wrap: pretty;
}

@media (min-width: 800px) {
  .beat { grid-template-columns: 352px minmax(0, 30rem); gap: 60px; justify-content: center; }
  .beat-art { max-width: 352px; margin-inline: 0; }
  html.js-motion .beats { min-height: min(78vh, 660px); min-height: min(78svh, 660px); }
}

/* --------------------------------------------------------------- journey */

#journey { position: relative; padding: clamp(80px, 14vh, 150px) 0 clamp(40px, 8vh, 80px); }

.journey-head { max-width: 40rem; margin-bottom: clamp(46px, 8vh, 90px); }
.journey-head .h-section { margin: 12px 0 16px; }
.journey-head .lede { font-size: clamp(1.02rem, .95rem + .6vw, 1.25rem); max-width: 30rem; }

.districts { display: flex; flex-direction: column; gap: clamp(64px, 12vh, 140px); }

.district { display: grid; gap: clamp(20px, 4vw, 40px); align-items: center; }

/* `width: 100%` matters: it gives the frame a definite width, so aspect-ratio
   can reserve the height before the lazy painting has arrived. Without it the
   frame would size to the loaded image, the whole journey would measure short
   at first layout, and every scroll trigger below it would start in the wrong
   place (as well as shifting the page as each image landed). */
.district-art { position: relative; width: 100%; }
.district-art .frame {
  aspect-ratio: 2 / 3;
  width: 100%; max-width: min(72vw, 320px);
  margin-inline: auto;
}
.district-art .frame img { will-change: transform; }
.district-art .glow {
  position: absolute; inset: -8%;
  background: radial-gradient(60% 50% at 50% 62%, var(--accent-dim), rgba(0,0,0,0) 70%);
  pointer-events: none; z-index: -1;
}
.district-anchor {
  position: absolute; right: -14px; bottom: -22px;
  width: clamp(84px, 22vw, 116px); aspect-ratio: 2 / 3;
  border: 2px solid var(--ink); border-radius: 10px;
  box-shadow: 4px 5px 0 var(--ink);
  overflow: hidden; background: var(--paper-deep);
}
.district-anchor img { width: 100%; height: 100%; object-fit: cover; }

.district-meta { max-width: 32rem; }
.district-no {
  font: 800 .72rem/1 var(--ui); letter-spacing: .28em; color: var(--accent);
  display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px;
}
.district-no .levels { color: var(--muted); letter-spacing: .1em; font-weight: 600; }
.district-name {
  font-size: clamp(1.5rem, 1.15rem + 1.7vw, 2.3rem);
  margin-bottom: 14px;
}
.district-meta p { color: rgba(244,236,201,.8); text-wrap: pretty; }

@media (min-width: 860px) {
  .district { grid-template-columns: 1fr 1fr; gap: 64px; }
  .district-art .frame { max-width: 330px; margin-inline: auto 0; }
  .district-meta { margin-right: auto; }
  .district:nth-child(even) .district-art { order: 2; }
  .district:nth-child(even) .district-art .frame { margin-inline: 0 auto; }
  .district:nth-child(even) .district-anchor { right: auto; left: -18px; }
  .district:nth-child(even) .district-meta { order: 1; margin-inline: auto 0; }
}

/* the settle — where the flood finds its level, and the gold line appears */
#settle {
  position: relative;
  height: clamp(220px, 40vh, 420px);
}

/* ---------------------------------------------------------- how it plays */

#how-it-plays { position: relative; padding: clamp(60px, 10vh, 110px) 0 clamp(70px, 12vh, 120px); }
#how-it-plays .h-section { margin: 12px 0 clamp(34px, 6vh, 60px); }

.principles { display: grid; gap: clamp(26px, 4vw, 34px); margin-bottom: clamp(48px, 8vh, 84px); }
.principle {
  border-top: 1px solid rgba(138,154,180,.22);
  padding-top: 22px;
  display: grid; gap: 16px;
  /* the columns stretch to the tallest of the three; without this the spare
     height is shared out between the rows and the headings stop lining up */
  align-content: start;
}
.principle .dia { width: 72px; height: 46px; flex: none; }
.principle h3 { font-size: clamp(1.15rem, 1.05rem + .6vw, 1.4rem); margin-bottom: 8px; color: var(--cream); }
.principle p { color: rgba(244,236,201,.74); font-size: .98rem; max-width: 32rem; }

@media (min-width: 720px) {
  .principles { grid-template-columns: repeat(3, 1fr); gap: 34px; }
}

.pledges {
  border: 2px solid var(--ink);
  border-radius: 12px;
  box-shadow: var(--frame-shadow);
  background: rgba(18,25,38,.72);
  padding: clamp(20px, 4vw, 30px);
  max-width: 44rem;
}
.pledges ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.pledges li {
  display: flex; gap: 12px; align-items: baseline;
  color: var(--cream); font-size: .99rem; line-height: 1.5;
}
.pledges li::before {
  content: ""; flex: none;
  width: 8px; height: 8px; border-radius: 0 50% 50% 50%;
  background: var(--water-lit); transform: rotate(45deg) translateY(1px);
}
.pledges li:last-child { color: rgba(244,236,201,.78); }

/* --------------------------------------------------------------- support */

#support { position: relative; padding: clamp(60px, 10vh, 110px) 0 clamp(70px, 12vh, 120px); }
#support .h-section { margin: 12px 0 24px; }
.support-body { max-width: 34rem; color: rgba(244,236,201,.8); }
.support-mail {
  display: inline-block; margin: 6px 0 20px;
  font-size: clamp(1.05rem, .98rem + .7vw, 1.3rem); font-weight: 700;
  color: var(--gold-lit); text-decoration: none;
  border-bottom: 2px solid rgba(227,163,60,.45); padding-bottom: 3px;
}
.support-mail:hover { border-bottom-color: var(--gold-lit); }

/* ---------------------------------------------------------------- footer */

footer.site {
  position: relative;
  border-top: 1px solid rgba(138,154,180,.16);
  padding: clamp(30px, 5vh, 46px) 0 clamp(34px, 6vh, 54px);
  font-size: .84rem; color: var(--muted);
}
footer.site .wrap { display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center; }
footer.site .sig { font-style: italic; opacity: .8; }
footer.site .spacer { flex: 1; min-width: 0; }
footer.site a { color: var(--muted); text-decoration: none; border-bottom: 1px solid rgba(138,154,180,.3); }
footer.site a:hover { color: var(--gold-lit); border-bottom-color: var(--gold-lit); }

/* --------------------------------------------------------- privacy page */

.doc { padding: clamp(110px, 18vh, 180px) 0 clamp(70px, 12vh, 120px); }
.doc-inner { max-width: 40rem; }
.doc h1 { font-size: clamp(2.2rem, 1.4rem + 3.4vw, 3.4rem); margin-bottom: 12px; }
.doc .eff { color: var(--muted); font-size: .88rem; margin-bottom: clamp(28px, 5vh, 44px); }
.doc h2 {
  font-size: clamp(1.1rem, 1rem + .6vw, 1.32rem);
  margin: clamp(32px, 5vh, 46px) 0 12px;
  color: var(--water-lit); letter-spacing: -.01em;
}
.doc p { color: rgba(244,236,201,.82); }
.doc .back { display: inline-block; margin-top: clamp(38px, 6vh, 56px); font-weight: 600; }
.doc-rule { height: 1px; background: linear-gradient(90deg, rgba(111,212,224,.4), rgba(111,212,224,0)); margin-top: 26px; }

/* ------------------------------------------------- reveal (JS-driven) */

html.js-motion .rise { opacity: 0; }

/* =====================================================================
   REDUCED MOTION — no scrub, no pin, no stacking. Everything static and
   readable, in document order.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.js-motion .beat,
  html.js-motion .beat-stage .beats { position: static; opacity: 1; }
  html.js-motion .rise { opacity: 1; }

  .beat-stage { min-height: 0; padding: clamp(46px, 8vh, 80px) 0; }
  .beat-stage .beats { display: flex; flex-direction: column; gap: clamp(52px, 9vh, 96px); }
  #hero { min-height: auto; padding-block: clamp(120px, 20vh, 190px) clamp(70px, 12vh, 110px); }
  .scroll-cue { display: none; }
  .scroll-cue .rail::after { animation: none; }
  #settle { height: clamp(80px, 12vh, 140px); }
}
