/* The official site: the key art's dusk on top, the night that falls after it all the way down - one night, not bands:
   main.ts lays its colours along the page (.backdrop) by where each part is, so the page darkens as it goes down without
   a seam; soft lights drift in it (.night), the 3D world's sea showing through round the world.  No pure black anywhere:
   every dark is a blue.  The lamps' amber is the only warm light.  Things come in as they are reached (data-reveal),
   gently, and stay; nothing moves for a reader who asks for less motion.
   site round 2: blue and black in gradients, with taste; round 3: motion, the parts flowing into each other, the
   top's shade from top to bottom, fewer small words. */
:root {
  color-scheme: dark;
  /* the night along the page, top to bottom (main.ts: .backdrop) */
  --c-dusk: #1a1a49;         /* under the key art: its violet dusk going blue */
  --c-trailer: #141842;
  --c-world-top: #151330;    /* the 3D world's own night at its top edge */
  --c-world-foot: #0c1331;   /* and its deep sea at its foot */
  --c-classes: #0f163b;
  --c-features: #0d1436;
  --c-closing: #0a1029;
  --c-foot: #070a1c;
  --c-end: #05070f;
  --night-rgb: 10, 13, 40;   /* the shade, the glass (main.ts reads it for the key art's shade) */
  --glow: 74, 104, 232;      /* the blue light inside the night */
  --violet: 128, 92, 214;
  --sea: 46, 168, 196;       /* the world's sea */
  /* the light */
  --moon: #eef0fb;           /* headings */
  --text: #b9c1de;           /* body */
  --dim: #8a93b9;            /* the least */
  --line: rgba(198, 210, 255, 0.11);
  --line2: rgba(198, 210, 255, 0.22);
  --amber: #ffc56a;
  --amber-hi: #ffdc9c;
  --amber-lo: #f2ad4e;
  --amber-rgb: 255, 190, 90;
  --on-amber: #121a45;
  /* one spacing scale: multiples of 8 */
  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 32px; --s5: 48px; --s6: 64px; --s7: 96px; --s8: 128px; --s9: 160px;
  --gutter: 16px;
  --sec: var(--s7);
  --wrap: min(1312px, calc(100% - 2 * var(--gutter)));
  --r: 4px;
  --ease: cubic-bezier(0.2, 0.75, 0.15, 1);
  /* how far the page scrolls while the hero holds the screen, the camera rising (main.ts); none without the script or
     for a reader who asks for less motion */
  --ascent: 0px;
  /* type */
  /* type (site round 5, the user's): Josefin Sans for what is shown - headings, the bar, buttons, dates and figures -
     and Source Han Sans for what is read, the running text in both languages (its Latin is Source Sans: Josefin's small
     lower case tires a paragraph); the Chinese headings in LXGW WenKai, as the art's lettering is.  The pages'
     @font-face: latin-zh is Josefin for the Latin inside Chinese, a little larger to stand beside it, its punctuation
     left to the Chinese face; sans is two files by script, so a page loads only the half it shows */
  --head: latin-zh, wenkai, "LXGW WenKai", "Kaiti SC", STKaiti, serif;
  --ui: latin-zh, sans, "Source Han Sans SC", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  --body: sans, "Source Han Sans SC", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  --track-head: 0.06em;
  --track-body: 0.025em;
  --lh: 1.85;
}
.lang-en {
  --head: latin, "Josefin Sans", "Futura", "Century Gothic", sans-serif;
  --ui: var(--head);
  --body: sans, "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
  --track-head: -0.012em;
  --track-body: 0;
  --lh: 1.65;
}
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) { :root { --ascent: 85svh; } }
@media (min-width: 640px) { :root { --gutter: 32px; } }
@media (min-width: 768px) { :root { --sec: var(--s8); } }
@media (min-width: 1024px) { :root { --gutter: 48px; } }
@media (min-width: 1200px) { :root { --sec: var(--s9); } }
@media (min-width: 1440px) { :root { --gutter: 64px; } }

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { background: var(--c-end); scroll-behavior: smooth; scroll-padding-top: var(--s7); -webkit-text-size-adjust: 100%; }
body {
  position: relative; margin: 0; min-height: 100vh; overflow-x: hidden; color: var(--text);
  font: 17px/var(--lh) var(--body); letter-spacing: var(--track-body); -webkit-font-smoothing: antialiased;
}
main { position: relative; overflow-x: clip; }
.lang-zh { line-break: strict; }
/* short Chinese lines break only between phrases (after a comma or a stop), never inside one */
.lang-zh :is(h2, h3, .tagline, .meta span, .classes p, summary, .road li > span) { word-break: keep-all; overflow-wrap: anywhere; }
/* a section's lede too where its lines are long; on a phone (about 20 characters a line) that would leave it ragged, so
   there it breaks anywhere and sits square */
@media (min-width: 721px) { .lang-zh .head .lede { word-break: keep-all; overflow-wrap: anywhere; } }
@media (max-width: 720px) { .lang-zh .head .lede { text-align: justify; text-wrap: wrap; } }
.nb { white-space: nowrap; }
/* Latin inside Chinese (main.ts .lt): Josefin's own tracking, not the Chinese headings' wide one */
.lang-zh .lt { letter-spacing: 0.02em; }
/* on a phone (about 20 characters a line, set square) a name or a number kept whole would stretch the line before it:
   there they break as a Chinese book's would */
@media (max-width: 720px) { .nb.word { white-space: normal; } }
/* display Chinese with its punctuation at half width (WenKai's halt), so a comma is a pause, not a hole */
.lang-zh :is(h2, h3, .tagline, summary, .road time) { font-feature-settings: "halt"; }
p { margin: 0; text-wrap: pretty; }
h1, h2, h3 { margin: 0; font-family: var(--head); font-weight: 400; color: var(--moon); letter-spacing: var(--track-head); text-wrap: balance; }
/* Josefin: light where it is big, regular as it gets smaller */
:is(header, .btn, .meta, footer .links, footer .copy) { font-family: var(--ui); }
.lang-en :is(h2, .tagline) { font-weight: 300; letter-spacing: -0.01em; }
.lang-en h3 { font-weight: 400; }
.lang-en :is(summary, .road time) { font-weight: 400; }
a { color: var(--amber); text-underline-offset: 0.2em; }
img.px { image-rendering: pixelated; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.wrap { width: var(--wrap); margin-inline: auto; }
:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; border-radius: 2px; }

/* ---------- the night behind it all ---------- */
/* its colours down the page, laid by main.ts at each part's place (a fallback for a page without the script) */
.backdrop { position: absolute; z-index: -2; left: 0; right: 0; top: 0; height: 100%; pointer-events: none;
            background: linear-gradient(180deg, var(--c-dusk) 0, var(--c-trailer) 18%, var(--c-classes) 45%, var(--c-closing) 80%, var(--c-foot) 96%, var(--c-end)); }
/* soft lights drifting in it, held to the screen; the sea's teal coming up round the world (--sea-on, main.ts) */
.night { position: fixed; z-index: -1; inset: 0; pointer-events: none; overflow: hidden; }
.night .glow { position: absolute; border-radius: 50%; opacity: 0; transition: opacity 1.2s var(--ease); }
.page-home .night .glow { opacity: var(--on, 1); }
.night .a { width: 90vmax; height: 70vmax; left: -30vmax; top: -10vmax;
            background: radial-gradient(closest-side, rgba(var(--glow), 0.16), rgba(var(--glow), 0)); animation: drift-a 48s ease-in-out infinite alternate; }
.night .b { width: 80vmax; height: 60vmax; right: -30vmax; bottom: -20vmax;
            background: radial-gradient(closest-side, rgba(var(--violet), 0.12), rgba(var(--violet), 0)); animation: drift-b 60s ease-in-out infinite alternate; }
.night .sea { width: 110vmax; height: 50vmax; left: calc(50% - 55vmax); top: 30%; --on: var(--sea-on, 0);
              background: radial-gradient(closest-side, rgba(var(--sea), 0.16), rgba(var(--sea), 0)); }
/* the lamps going on up behind the page (main.ts) */
.night .field { position: absolute; inset: 0; width: 100%; height: 100%; }
@keyframes drift-a { to { transform: translate3d(18vmax, 14vmax, 0); } }
@keyframes drift-b { to { transform: translate3d(-16vmax, -12vmax, 0); } }
/* a fine grain over the night, so its long gradients never band */
.night::after { content: ""; position: absolute; inset: 0; opacity: 0.045; mix-blend-mode: soft-light;
                background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

/* ---------- the bar on top ---------- */
header {
  position: fixed; z-index: 10; inset: 0 0 auto; height: var(--s7); display: flex; align-items: center; gap: var(--s4);
  padding: 0 max(var(--gutter), env(safe-area-inset-right)) 0 max(var(--gutter), env(safe-area-inset-left));
  transition: height 0.4s var(--ease), background-color 0.4s, border-color 0.4s, transform 0.5s var(--ease);
  border-bottom: 1px solid transparent;
}
header.solid { height: 72px; background: rgba(var(--night-rgb), 0.72); border-color: var(--line);
               -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3); }
/* reading down the bar steps aside; a move back up brings it back */
header.away { transform: translateY(-100%); }
header .mark { display: flex; opacity: 0; transform: translateY(-6px); pointer-events: none; transition: opacity 0.4s, transform 0.5s var(--ease); }
header.solid .mark { opacity: 1; transform: none; pointer-events: auto; }
header nav { display: flex; gap: var(--s4); margin-left: auto; }
header nav a, header .switch { position: relative; color: var(--moon); opacity: 0.78; text-decoration: none; font-size: 15px; letter-spacing: 0.12em;
                               transition: opacity 0.25s; }
.lang-en header nav a { font-size: 14px; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; }
header nav a:hover, header .switch:hover, header nav a.on { opacity: 1; }
/* where the reader is: a lamp's glint under it */
header nav a::after { content: ""; position: absolute; left: 50%; bottom: -10px; width: 4px; height: 4px; margin-left: -2px; background: var(--amber);
                      box-shadow: 0 0 8px 1px rgba(var(--amber-rgb), 0.8); transform: scale(0); transition: transform 0.35s var(--ease); }
header nav a.on::after { transform: scale(1); }
header .switch { padding: 6px 14px; border: 1px solid var(--line2); border-radius: var(--r); font-size: 14px; letter-spacing: 0.06em; }
@media (max-width: 720px) { header nav { display: none; } header .switch { margin-left: auto; } header { height: 72px; } }
@media (min-width: 2200px) { header nav { gap: var(--s5); } header nav a { font-size: 17px; } .lang-en header nav a { font-size: 15px; } header .switch { font-size: 16px; } }

/* ---------- the key art: drawn on the canvas in its planes at a whole number of screen pixels a game pixel (main.ts),
   its lamps alive; the night from the top down, the words in it.  The hero holds the screen (.pin) for --ascent of
   scrolling while the camera rises with the lamps into the night ---------- */
#hero { --pin: max(100svh, 600px); position: relative; height: calc(var(--pin) + var(--ascent)); }
@media (max-aspect-ratio: 1 / 1) { #hero { --pin: max(100svh, 744px); } }
#hero .pin { position: sticky; top: 0; height: var(--pin); overflow: hidden; background: var(--c-dusk); }
#hero .stage { position: absolute; inset: 0; }
#hero canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; image-rendering: pixelated; }
/* the ground going into the night under it */
#hero .pin::after {
  content: ""; position: absolute; inset: auto 0 0; height: 20%; pointer-events: none;
  background: linear-gradient(180deg, rgba(26, 26, 73, 0) 0%, rgba(26, 26, 73, 0.3) 30%, rgba(26, 26, 73, 0.75) 62%, var(--c-dusk) 94%);
}
.keyart-fallback { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; }
.hero-words {
  position: absolute; z-index: 1; left: var(--gutter); right: var(--gutter); top: var(--words-y, 34vh); text-align: center;
  text-shadow: 0 1px 2px rgba(var(--night-rgb), 0.5), 0 0 28px rgba(var(--night-rgb), 0.5);
}
.tagline { font-family: var(--head); color: var(--moon); font-size: clamp(30px, 1.5vw + 21px, 52px); line-height: 1.25; letter-spacing: 0.1em; }
.lang-en .tagline { font-size: clamp(34px, 1.8vw + 23px, 60px); line-height: 1.08; }
.meta { margin-top: var(--s2); font-size: clamp(15px, 0.2vw + 13px, 18px); line-height: 1.6; letter-spacing: 0.06em; color: var(--moon); opacity: 0.8;
        font-variant-numeric: tabular-nums; }
.lang-en .meta { letter-spacing: 0.01em; }
.meta > span + span::before { content: ""; display: inline-block; vertical-align: 0.28em; width: 3px; height: 3px; margin: 0 0.9em 0 0.5em;
                            background: currentColor; opacity: 0.6; }
@media (max-width: 720px) { .meta > span { display: block; } .meta > span + span::before { display: none; } }
.cta { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); margin-top: var(--s5); }
@media (max-width: 720px) { .cta { margin-top: var(--s4); } .cta .btn { width: min(100%, 320px); } }
@media (min-width: 2200px) {
  .tagline { font-size: 68px; }
  .lang-en .tagline { font-size: 78px; }
  .meta { font-size: 21px; margin-top: var(--s3); }
  :root { --g: 4px; }
  .cta .btn { font-size: 18px; }
}
/* the opening (main.ts draws the picture's: the lamp lit, the lamps after it, the logo); then the words, one after
   another, from when the picture begins (.opened) */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  .hero-words > * { opacity: 0; }
  #hero.opened .hero-words > * { animation: come 1.3s var(--ease) both; }
  #hero.opened .hero-words > :nth-child(1) { animation-delay: 1.5s; }
  #hero.opened .hero-words > :nth-child(2) { animation-delay: 1.7s; }
  #hero.opened .hero-words > :nth-child(3) { animation-delay: 1.9s; }
}
@keyframes dawn { from { opacity: 0; } }
@keyframes up { from { opacity: 0; transform: translateY(18px); } }
@keyframes come { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* ---------- buttons: the game's own (src/ui/kit/widgets.ts buttonPlate; site round 5, the user: as Dark Veil's menu is its
   game's), drawn in its pixels at the page's game pixel (--g, the key art's: 3 CSS pixels on a desk, 2 on a phone) -
   an edge with its corners cut two pixels deep, inside it a face lit from above (its upper half lighter), a lit top row,
   a shaded bottom row; held, it sinks a pixel.  The lit one amber, the others the game's plum (src/ui/kit/tokens.ts) ---------- */
:root { --g: 3px; }
@media (max-width: 720px) { :root { --g: 2px; } }
.btn {
  --edge: #1c1119; --light: #9d8cab; --face0: #6b5a78; --face1: #4a3a55; --shade: #3b2a44; --ink: #fff1dc;
  position: relative; isolation: isolate; display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  min-height: calc(var(--g) * 18); padding: 0 calc(var(--g) * 10) var(--g);
  font: 500 16px/1 var(--ui); letter-spacing: 0.06em; color: var(--ink); text-decoration: none; text-shadow: none; white-space: nowrap;
  border: 0; background: none; cursor: pointer;
}
.lang-en .btn { font-weight: 600; letter-spacing: 0.04em; }
.btn::before, .btn::after { content: ""; position: absolute; z-index: -1; pointer-events: none; }
.btn::before { inset: 0; background: var(--edge);
  clip-path: polygon(calc(var(--g) * 2) 0, calc(100% - var(--g) * 2) 0, calc(100% - var(--g) * 2) var(--g), calc(100% - var(--g)) var(--g),
                     calc(100% - var(--g)) calc(var(--g) * 2), 100% calc(var(--g) * 2), 100% calc(100% - var(--g) * 2), calc(100% - var(--g)) calc(100% - var(--g) * 2),
                     calc(100% - var(--g)) calc(100% - var(--g)), calc(100% - var(--g) * 2) calc(100% - var(--g)), calc(100% - var(--g) * 2) 100%,
                     calc(var(--g) * 2) 100%, calc(var(--g) * 2) calc(100% - var(--g)), var(--g) calc(100% - var(--g)), var(--g) calc(100% - var(--g) * 2),
                     0 calc(100% - var(--g) * 2), 0 calc(var(--g) * 2), var(--g) calc(var(--g) * 2), var(--g) var(--g), calc(var(--g) * 2) var(--g)); }
.btn::after { inset: var(--g);
  background: linear-gradient(180deg, var(--light) 0 var(--g), var(--face0) var(--g) 50%, var(--face1) 50% calc(100% - var(--g)), var(--shade) calc(100% - var(--g)));
  clip-path: polygon(var(--g) 0, calc(100% - var(--g)) 0, calc(100% - var(--g)) var(--g), 100% var(--g), 100% calc(100% - var(--g)),
                     calc(100% - var(--g)) calc(100% - var(--g)), calc(100% - var(--g)) 100%, var(--g) 100%, var(--g) calc(100% - var(--g)),
                     0 calc(100% - var(--g)), 0 var(--g), var(--g) var(--g)); }
.btn:hover, .btn:focus-visible { --light: #cbbdd6; --face0: #7d6c8a; --face1: #6b5a78; --shade: #4a3a55; --ink: #fff8ec; }
.btn:active { --edge: #120a14; --face0: #4a3a55; --face1: #4a3a55; --light: var(--face0); padding-top: var(--g); padding-bottom: 0; }
/* the one lit button: the wishlist's once the store page is public (and it comes first), the trailer's till then - the
   game's primary, amber, a lamp's warmth round it */
.btn.lit { --edge: #8f2a14; --light: #fff2c4; --face0: #ffd675; --face1: #ffb84a; --shade: #c4521c; --ink: #3b1408;
           filter: drop-shadow(0 10px 28px rgba(var(--amber-rgb), 0.38)); }
.btn.lit:hover, .btn.lit:focus-visible { --light: #fffbe6; --face0: #ffe39a; --face1: #ffd675; --shade: #f08a32; --ink: #3b1408;
                                         filter: drop-shadow(0 12px 34px rgba(var(--amber-rgb), 0.55)); }
.btn.lit:active { --edge: #5c1d0c; --face0: #ffb84a; --face1: #ffb84a; --light: #ffb84a; --shade: #c4521c; }
.btn:focus-visible { outline: none; }
.btn:focus-visible::before { background: var(--moon); }
.btn .tri { width: 0; height: 0; border-style: solid; border-width: calc(var(--g) * 2) 0 calc(var(--g) * 2) calc(var(--g) * 3);
            border-color: transparent transparent transparent currentColor; }
.btn.ghost .tri { border-left-color: #ffd675; }
/* (till the store page is public, the page shows no wishlist button at all: main.ts takes it out) */
#wishlist[data-href=""] { display: none; }

/* ---------- things come in as they are reached (main.ts adds .in), staggered by --i ---------- */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  [data-reveal] { opacity: 0; transform: translate3d(0, 28px, 0); filter: blur(5px);
                  transition: opacity 1s var(--ease), transform 1.2s var(--ease), filter 1s var(--ease);
                  transition-delay: calc(var(--i, 0) * 120ms); }
  [data-reveal="rise"] { transform: translate3d(0, 56px, 0); filter: none; }
  [data-reveal="fade"] { transform: none; filter: none; transition-duration: 1.6s; }
  [data-reveal].in { opacity: 1; transform: none; filter: none; }
  /* a heading rising out of its own line */
  [data-reveal="line"] { opacity: 1; transform: none; filter: none; }
  [data-reveal="line"] .ln-in { transform: translate3d(0, 108%, 0); transition: transform 1.3s var(--ease); }
  [data-reveal="line"].in .ln-in { transform: none; }
}
.ln-mask { display: block; overflow: hidden; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.ln-in { display: block; }

/* ---------- the sections: no bands - each sits in the one night ---------- */
section { position: relative; }
#world, #classes, #features, .closing { padding-top: var(--sec); }
h2 { font-size: clamp(32px, 1.6vw + 24px, 48px); line-height: 1.3; }
.lang-en h2 { font-size: clamp(38px, 2vw + 26px, 60px); line-height: 1.05; }
.head { display: grid; gap: var(--s3); margin-bottom: var(--s6); }
.head .lede { max-width: 34em; font-size: 18px; line-height: 1.8; letter-spacing: 0.04em; color: var(--text); }
/* English ledes larger and light: the page's voice */
.lang-en .head .lede { max-width: 30em; font: 300 22px/1.55 var(--head); letter-spacing: 0; }
@media (min-width: 1024px) {
  .head { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: var(--s5); align-items: start; }
  .head .lede { padding-top: 0.5em; }
  .lang-en .head .lede { padding-top: 0.55em; }
}

/* the trailer: rising into the night the camera rose into, over the held hero, its frame opening as it comes (--o,
   main.ts), the screen's blue light spilling round it */
#trailer { z-index: 2; margin-top: calc(-0.5 * var(--ascent) - min(7vh, 72px)); }
#trailer::before { content: ""; position: absolute; inset: -20% 0; pointer-events: none; opacity: var(--o, 1);
                   background: radial-gradient(closest-side, rgba(var(--glow), 0.2), rgba(var(--glow), 0)) 50% 50% / 100% 70% no-repeat; }
.video { position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--r); background: var(--c-world-foot);
         clip-path: inset(calc((1 - var(--o, 1)) * 9%) calc((1 - var(--o, 1)) * 13%) round var(--r)); }
.video::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px var(--line); pointer-events: none; }
.video .play { opacity: clamp(0, calc(var(--o, 1) * 3 - 2), 1); }
.video video { width: 100%; height: 100%; display: block; }
.video .play { position: absolute; inset: 0; border: 0; padding: 0; background: transparent; cursor: pointer; }
.video .play::before { content: ""; position: absolute; inset: 0; background: radial-gradient(closest-side, rgba(var(--night-rgb), 0.32), transparent); }
/* the play mark: a lamp-lit square, breathing */
.video .play i { position: absolute; left: 50%; top: 50%; width: 80px; height: 80px; margin: -40px 0 0 -40px; border-radius: var(--r);
                 background: linear-gradient(180deg, var(--amber-hi), var(--amber) 60%, var(--amber-lo));
                 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 0 0 8px rgba(var(--night-rgb), 0.35), 0 0 0 9px rgba(255, 214, 150, 0.4),
                             0 0 64px rgba(var(--amber-rgb), 0.55);
                 transition: transform 0.35s var(--ease); }
.video .play i::after { content: ""; position: absolute; left: 32px; top: 26px; border-style: solid; border-width: 14px 0 14px 22px;
                        border-color: transparent transparent transparent var(--on-amber); }
.video .play i::before { content: ""; position: absolute; inset: -9px; border-radius: 6px; border: 1px solid rgba(255, 214, 150, 0.5); opacity: 0; }
@media (prefers-reduced-motion: no-preference) { .video .play i::before { animation: ring 2.8s var(--ease) infinite; } }
@keyframes ring { 0% { opacity: 0.7; transform: scale(1); } 100% { opacity: 0; transform: scale(1.6); } }
.video .play:hover i { transform: scale(1.06); }
/* the site's own controls (main.ts), the same on every system: one row on a shade at the foot - play, the time, the
   bar (an amber line drawn to where it is, a lamp's square at its head), sound, full screen; gone while it plays and
   the pointer rests, back on a move */
.vc { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: var(--s1);
      padding: var(--s5) var(--s2) var(--s1); color: var(--moon);
      background: linear-gradient(180deg, rgba(var(--night-rgb), 0), rgba(var(--night-rgb), 0.55) 45%, rgba(var(--night-rgb), 0.85));
      transition: opacity 0.45s var(--ease), transform 0.45s var(--ease); }
.vc[hidden] { display: none; }
.video.idle .vc { opacity: 0; transform: translateY(8px); pointer-events: none; }
.video.idle { cursor: none; }
.vc button { flex: none; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: var(--r);
             color: inherit; background: transparent; cursor: pointer; transition: color 0.2s, background-color 0.2s; }
.vc button:hover { color: var(--amber); background: rgba(238, 240, 251, 0.06); }
.vc svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.vc .i-play, .vc .i-pause, .vc .i-speaker { fill: currentColor; stroke: none; }
.vc-play .i-pause, .video.playing .vc-play .i-play { display: none; }
.video.playing .vc-play .i-pause { display: inline; }
.vc-mute .i-x, .video.muted .vc-mute .i-waves { display: none; }
.video.muted .vc-mute .i-x { display: inline; }
.vc-full .i-exit, .video.full .vc-full .i-full { display: none; }
.video.full .vc-full .i-exit { display: inline; }
/* the time in Josefin, each figure in a cell of its own so the time does not shake as it counts */
.vc-time { flex: none; display: flex; gap: 0.35em; margin: 0 var(--s1); font: 400 14px/1 var(--ui); letter-spacing: 0.04em; color: var(--moon); }
.vc-time .of, .vc-time .dur { color: var(--dim); }
.vc-time i { display: inline-block; width: 0.62em; text-align: center; font-style: normal; }
.vc-bar { position: relative; flex: 1; height: 24px; cursor: pointer; touch-action: none; --t: 0; --buf: 0; }
.vc-bar::before, .vc-bar .buf, .vc-bar .fill { content: ""; position: absolute; left: 0; top: 50%; height: 3px; margin-top: -1.5px; border-radius: 2px;
                                               transition: height 0.2s var(--ease), margin 0.2s var(--ease); }
.vc-bar::before { right: 0; background: rgba(238, 240, 251, 0.16); }
.vc-bar .buf { width: calc(var(--buf) * 100%); background: rgba(238, 240, 251, 0.22); }
.vc-bar .fill { width: calc(var(--t) * 100%); background: linear-gradient(90deg, var(--amber-lo), var(--amber-hi)); box-shadow: 0 0 10px rgba(var(--amber-rgb), 0.45); }
.vc-bar .head { position: absolute; top: 50%; left: calc(var(--t) * 100%); width: 10px; height: 10px; margin: -5px 0 0 -5px; background: var(--amber-hi);
                box-shadow: 0 0 0 3px rgba(var(--amber-rgb), 0.2), 0 0 12px 2px rgba(var(--amber-rgb), 0.7); transform: scale(0.6);
                transition: transform 0.2s var(--ease); }
.vc-bar:is(:hover, :focus-visible, .seeking) :is(.buf, .fill), .vc-bar:is(:hover, :focus-visible, .seeking)::before { height: 5px; margin-top: -2.5px; }
.vc-bar:is(:hover, :focus-visible, .seeking) .head { transform: scale(1); }
.vc-bar:focus-visible { outline: none; }
.vc-bar:focus-visible .head { box-shadow: 0 0 0 3px var(--amber), 0 0 12px 2px rgba(var(--amber-rgb), 0.7); }
/* full screen: the frame the screen's, the picture whole in it */
.video.full { border-radius: 0; clip-path: none; background: #05070f; }
.video.full video { object-fit: contain; }
.video.full .vc { padding: var(--s6) var(--s4) var(--s3); }
@media (max-width: 640px) { .vc { gap: 2px; padding: var(--s4) var(--s1) 2px; } .vc-time { font-size: 12px; margin: 0 4px; } }
@media (max-width: 640px) {
  #trailer .wrap { width: 100%; }
  .video { border-radius: 0; }
  .video .play i { width: 64px; height: 64px; margin: -32px 0 0 -32px; }
  .video .play i::after { left: 25px; top: 20px; border-width: 12px 0 12px 19px; }
}

/* the world you can turn: edge to edge, its night fading into the page's at both edges */
.world { position: relative; width: 100%; height: min(56.25vw, 86vh); height: min(56.25vw, 86svh); min-height: 420px;
         background: var(--c-world-top) url("../media/world.jpg") center / cover;
         -webkit-mask-image: linear-gradient(180deg, transparent 0, #fff 16%, #fff 88%, transparent 100%);
         mask-image: linear-gradient(180deg, transparent 0, #fff 16%, #fff 88%, transparent 100%); }
.world iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
@media (max-width: 640px) { .world { height: auto; min-height: 0; aspect-ratio: 4 / 5; } }

/* the three classes */
.classes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4); }
.classes figure { margin: 0; }
.shot { position: relative; border-radius: var(--r); overflow: hidden; box-shadow: 0 0 0 1px var(--line), 0 32px 64px -32px rgba(2, 4, 16, 0.8);
        transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease); }
.shot img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; cursor: zoom-in; }
@media (hover: hover) {
  .classes figure:hover .shot { transform: translateY(-6px);
                                box-shadow: 0 0 0 1px var(--line2), 0 40px 80px -32px rgba(2, 4, 16, 0.9), 0 0 48px -8px rgba(var(--glow), 0.35); }
}
.classes figcaption { padding-top: var(--s3); }
.classes h3 { font-size: 28px; line-height: 1.3; letter-spacing: 0.12em; }
.lang-en .classes h3 { font-size: 30px; letter-spacing: -0.01em; line-height: 1.15; }
.classes p { margin-top: var(--s1); }
.classes .ln { display: block; }
/* a tablet: three across would wrap each line in two; a row each, the picture beside its words */
@media (min-width: 721px) and (max-width: 1199px) {
  .classes { grid-template-columns: 1fr; gap: var(--s4); }
  .classes figure { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: var(--s5); align-items: center; }
  .classes figcaption { padding-top: 0; }
}
@media (max-width: 720px) { .classes { grid-template-columns: 1fr; gap: var(--s6); } }

/* the four features.  A phone and a tablet: each its picture and its words, one after another.  A desk: one picture held
   in the middle of the screen while the four texts go by beside it, the picture turning to each as it comes (main.ts
   marks the one in front .on); 640 wide, so the 1280 shot's game pixels stay whole */
#features { padding-bottom: var(--s6); }
.story .media { display: none; }
.steps article + article { margin-top: var(--s7); }
.steps .shot { margin-bottom: var(--s4); }
#features h3 { font-size: clamp(28px, 0.8vw + 20px, 34px); line-height: 1.35; }
.lang-en #features h3 { font-size: clamp(30px, 1vw + 20px, 40px); line-height: 1.1; }
/* each feature (site round 5: the user found them a block of text each): its number, outlined, lit when it is the one
   in front; its title; its first sentence a lead in the light of the headings; the rest quieter; then an element of
   its own - the lamps a row that lights one after another, the party and the free play their figures, the world its day
   going from dusk to noon to night */
#features .no { display: block; margin: 0 0 var(--s2) -0.04em; font: 200 clamp(72px, 3vw + 48px, 112px)/0.8 var(--ui); letter-spacing: -0.03em;
                color: transparent; -webkit-text-stroke: 1px rgba(var(--amber-rgb), 0.6); transition: -webkit-text-stroke-color 0.7s var(--ease); }
#features .text p { max-width: 34em; }
#features .text p.lead { margin-top: var(--s3); font-size: 19px; line-height: 1.8; color: var(--moon); }
.lang-en #features .text p.lead { font-size: 20px; line-height: 1.55; }
#features .text p.rest { margin-top: var(--s2); font-size: 15px; line-height: 1.95; color: var(--text); opacity: 0.8; }
.lang-en #features .text p.rest { font-size: 16px; line-height: 1.7; }
#features .text p.rest:empty { display: none; }
/* (justified Chinese is wrapped plainly: "pretty" would pull characters down and stretch the line above the last) */
.lang-zh :is(#features .text p, .qa .a p) { text-align: justify; text-wrap: wrap; }
/* the figures: large and light in Josefin, amber, what each counts beneath in the body's face */
.facts { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s3) var(--s6); margin: var(--s5) 0 0; padding: var(--s4) 0 0;
         border-top: 1px solid var(--line); }
.facts li { display: grid; align-content: start; gap: 12px; min-width: 5.5em; }
.facts b { font: 300 clamp(44px, 1.6vw + 28px, 56px)/0.85 var(--ui); letter-spacing: -0.02em; color: var(--amber-hi);
           text-shadow: 0 0 28px rgba(var(--amber-rgb), 0.35); }
.facts span { max-width: 9em; font-size: 14px; line-height: 1.5; letter-spacing: 0.04em; color: var(--dim); }
@media (max-width: 720px) { .facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s2); } .facts li { min-width: 0; }
                            .facts b { font-size: 40px; } .facts span { font-size: 13px; } }
/* the world's day: the sky's colours from its dusk to its noon to its night, a lamp going along it */
.times { margin-top: var(--s5); max-width: 30em; }
.times .sky { position: relative; height: 6px; border-radius: 3px;
              background: linear-gradient(90deg, #e0857a, #f3a77c 14%, #fbc38e 28%, #ffe6b5 46%, #b9c8ef 60%, #5a64ad 76%, #1d2154); }
.times .sky i { position: absolute; top: 50%; left: 0; width: 10px; height: 10px; margin: -5px 0 0 -5px; background: var(--amber-hi);
                box-shadow: 0 0 0 3px rgba(var(--amber-rgb), 0.2), 0 0 14px 3px rgba(var(--amber-rgb), 0.7); }
@media (prefers-reduced-motion: no-preference) { .times .sky i { animation: day 9s ease-in-out infinite alternate; } }
@keyframes day { to { left: 100%; } }
.times p { display: flex; justify-content: space-between; margin-top: var(--s2); font: 400 14px/1 var(--ui); letter-spacing: 0.12em; color: var(--dim); }
.times + .facts { margin-top: var(--s4); }
/* the lamps: each a point the game's drift lamp hangs from (main.ts sets its pixels from the key art's sheet) */
.lamprow { display: flex; align-items: center; gap: 72px; height: 56px; margin-top: var(--s5); padding-left: 24px; }
.lamprow > i { position: relative; flex: none; width: 0; height: 0; }
.lamprow .g, .lamprow .b { position: absolute; background-image: url("../media/keyart-planes.webp"); background-repeat: no-repeat; image-rendering: pixelated; }
.lamprow .g { mix-blend-mode: plus-lighter; }
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  [data-reveal="lamps"] { opacity: 1; transform: none; filter: none; }
  .lamprow .g { opacity: 0; transition: opacity 0.9s var(--ease) calc(var(--n) * 0.24s + 0.3s); }
  .lamprow .b { filter: grayscale(0.85) brightness(0.4); transition: filter 0.6s var(--ease) calc(var(--n) * 0.24s + 0.3s); }
  .lamprow.in .g { opacity: calc(0.4 + var(--n) * 0.15); }     /* (the more lamps lit, the brighter: as the game's lamps feed one another) */
  .lamprow.in .b { filter: none; }
  .lamprow.in > i { animation: bob 3.4s ease-in-out infinite; animation-delay: calc(var(--n) * -0.7s); }
}
@keyframes bob { 50% { transform: translateY(-5px); } }
@media (min-width: 1200px) {
  .story { display: grid; grid-template-columns: 640px minmax(0, 1fr); column-gap: var(--s7); }
  .story .media { display: block; position: sticky; top: calc(50vh - 180px); grid-column: 1; grid-row: 1; align-self: start;
                  height: 360px; border-radius: var(--r); box-shadow: 0 0 0 1px var(--line), 0 48px 110px -44px rgba(2, 4, 16, 0.95); }
  .story .media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: var(--r);
                      opacity: 0; transform: translate3d(0, 16px, 0); transition: opacity 0.9s var(--ease), transform 1.1s var(--ease); }
  .story .media img.on { opacity: 1; transform: none; }
  /* (the picture dissolving into the next, main.ts; over the pictures, which are there without it) */
  .story .media .dissolve { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: var(--r); }
  .story .steps { grid-column: 2; grid-row: 1; }
  .steps article { min-height: 76vh; display: flex; align-items: center; }
  .steps article:first-child { min-height: 64vh; align-items: flex-start; padding-top: calc(32vh - 180px + 24px); }
  .steps article:last-child { min-height: 64vh; align-items: flex-end; padding-bottom: calc(32vh - 180px + 24px); }
  .steps article + article { margin-top: 0; }
  .steps .shot { display: none; }
  .steps .text { opacity: 0.22; transition: opacity 0.7s var(--ease); }
  .steps article.on .text { opacity: 1; }
  .steps article.on .no { -webkit-text-stroke-color: rgba(var(--amber-rgb), 0.95); }
  #features h3 { cursor: default; }
}

/* the road and the questions, side by side on a desk */
.closing { padding-bottom: var(--s4); }
.closing .wrap { position: relative; display: grid; gap: var(--sec); }
.closing h2 { margin-bottom: var(--s5); }
@media (min-width: 1200px) { .closing .wrap { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: var(--s5); align-items: start; } }
/* the road: its line drawn as it is read (--p, main.ts), each date lit as the line reaches it, the last one a lamp */
.road { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4); position: relative; --p: 1; }
.road::before, .road::after { content: ""; position: absolute; left: 3px; top: 0.75em; bottom: 3em; width: 1px; }
.road::before { background: var(--line2); }
.road::after { background: linear-gradient(180deg, rgba(238, 240, 251, 0.7), rgba(var(--amber-rgb), 0.9)); transform-origin: top; transform: scaleY(var(--p)); }
.road li { position: relative; padding-left: var(--s5); transition: opacity 0.6s var(--ease); }
.road li::before { content: ""; position: absolute; z-index: 1; left: 0; top: 0.55em; width: 7px; height: 7px; background: var(--c-closing);
                   box-shadow: inset 0 0 0 1px var(--dim); transition: background-color 0.5s, box-shadow 0.5s; }
.road li.lit::before { box-shadow: inset 0 0 0 1px var(--moon), 0 0 10px rgba(238, 240, 251, 0.35); }
.road li.now.lit::before { background: var(--amber); box-shadow: 0 0 0 3px rgba(var(--amber-rgb), 0.18), 0 0 16px 3px rgba(var(--amber-rgb), 0.8); }
.road li.now::after { content: ""; position: absolute; left: -77px; top: calc(0.55em - 77px); width: 160px; height: 160px; pointer-events: none; opacity: 0;
                      background: radial-gradient(closest-side, rgba(var(--amber-rgb), 0.2), rgba(var(--amber-rgb), 0)); transition: opacity 1s; }
.road li.now.lit::after { opacity: 1; }
@media (prefers-reduced-motion: no-preference) { .road li.now.lit::after { animation: breathe 3.6s ease-in-out infinite; } }
@keyframes breathe { 50% { transform: scale(1.15); opacity: 0.7; } }
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) { .road li:not(.lit) { opacity: 0.45; } }
.road time { display: block; font-family: var(--head); font-size: clamp(19px, 0.6vw + 14px, 22px); line-height: 1.4; letter-spacing: 0.04em;
             color: var(--moon); white-space: nowrap; font-variant-numeric: tabular-nums; }
.lang-en .road time { font-size: clamp(20px, 0.8vw + 13px, 24px); letter-spacing: -0.005em; line-height: 1.25; }
.road li.now time { color: var(--amber); }
.road li > span { display: block; margin-top: var(--s1); font-size: 15px; line-height: 1.7; color: var(--text); text-wrap: balance; }
/* a tablet, the questions under it: the road runs across */
@media (min-width: 900px) and (max-width: 1199px) {
  .road { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .road::before, .road::after { left: 0; right: 0; top: 3px; bottom: auto; width: auto; height: 1px; }
  .road::after { background: linear-gradient(90deg, rgba(238, 240, 251, 0.7), rgba(var(--amber-rgb), 0.9)); transform-origin: left; transform: scaleX(var(--p)); }
  .road li { padding: var(--s4) var(--s2) 0 0; }
  .road li::before { top: 0; }
  .road li.now::after { top: -77px; }
}
/* the lamp going down the road (main.ts: placed at the line's end, its pixels the key art's sheet's) */
.lamp-head { position: absolute; z-index: 2; left: 0; top: 0; pointer-events: none; }
.lamp-head i { position: absolute; background-image: url("../media/keyart-planes.webp"); background-repeat: no-repeat; image-rendering: pixelated; }
.lamp-head .g { mix-blend-mode: plus-lighter; }
@media (min-width: 900px) and (max-width: 1199px) { .lamp-head { display: none; } }
/* the questions: each opening smoothly (main.ts) */
.qa details { border-top: 1px solid var(--line); }
.qa details:last-child { border-bottom: 1px solid var(--line); }
.qa summary { position: relative; cursor: pointer; list-style: none; padding: var(--s3) var(--s6) var(--s3) 0; font-family: var(--head);
              font-size: 21px; line-height: 1.45; letter-spacing: 0.04em; color: var(--moon); transition: color 0.25s; }
.lang-en .qa summary { font-size: 22px; letter-spacing: -0.005em; line-height: 1.3; }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::before, .qa summary::after { content: ""; position: absolute; right: 4px; top: 50%; width: 14px; height: 1.5px; margin-top: -1px;
                                          background: var(--moon); opacity: 0.7; transition: transform 0.4s var(--ease), opacity 0.4s; }
.qa summary::after { transform: rotate(90deg); }
.qa details[open] summary::after { transform: rotate(0deg); opacity: 0; }
.qa summary:hover { color: #fff8e8; }
.qa summary:hover::before, .qa summary:hover::after { opacity: 1; }
.qa .a { overflow: hidden; }
.qa .a p { padding-bottom: var(--s4); max-width: 36em; }
.lang-en .qa .a p { max-width: 38em; }

/* ---------- the foot of the page: the darkest of the night, and the last lamp in it ---------- */
footer { position: relative; padding: var(--sec) 0 calc(var(--s6) + env(safe-area-inset-bottom)); text-align: center; }
footer img.px { filter: drop-shadow(0 0 22px rgba(var(--amber-rgb), 0.3)); }
footer .wrap { display: flex; flex-direction: column; align-items: center; }
footer .links { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s1) var(--s4); margin-top: var(--s5); font-size: 15px; letter-spacing: 0.06em; }
footer .links:empty { display: none; }
/* (a phone: the five accounts of a region on one row, none left alone on a second) */
@media (max-width: 480px) { footer .links { gap: var(--s1) var(--s2); font-size: 14px; letter-spacing: 0.04em; } }
footer .links a { color: var(--text); text-decoration: none; transition: color 0.25s; }
footer .links a:hover { color: var(--moon); text-decoration: underline; text-decoration-color: var(--amber); }
footer .copy { margin-top: var(--s4); font-size: 13px; letter-spacing: 0.08em; color: var(--dim); }

/* ---------- a screenshot made bigger ---------- */
#zoom { position: fixed; z-index: 20; inset: 0; display: flex; align-items: center; justify-content: center; padding: var(--s2);
        background: rgba(6, 9, 26, 0.94); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); cursor: zoom-out; }
@media (prefers-reduced-motion: no-preference) { #zoom:not([hidden]) { animation: dawn 0.35s var(--ease); } #zoom:not([hidden]) img { animation: up 0.5s var(--ease); } }
#zoom img { max-width: 100%; max-height: 100%; border-radius: var(--r); box-shadow: 0 0 0 1px var(--line); }
#zoom button { position: absolute; right: var(--s2); top: var(--s2); width: 48px; height: 48px; border-radius: var(--r); cursor: pointer;
               background: rgba(var(--night-rgb), 0.8); border: 1px solid var(--line2); }
#zoom button::before, #zoom button::after { content: ""; position: absolute; left: 16px; top: 23px; width: 16px; height: 1.5px; background: var(--moon);
                                            transform: rotate(45deg); }
#zoom button::after { transform: rotate(-45deg); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
}
