/* The Tale of Lin & Lang — public site
   Look: Lin & Lang (gold logo, red, teal, rice-paper cream, Alegreya).
   Layout and motion: a long black cinematic page with a glowing crest and a tilted scene wall. */

@font-face { font-family: "Alegreya"; src: url("../assets/fonts/Alegreya.woff2") format("woff2"); font-weight: 400 900; font-style: normal; font-display: swap; }
@font-face { font-family: "Alegreya"; src: url("../assets/fonts/Alegreya-Italic.woff2") format("woff2"); font-weight: 400 900; font-style: italic; font-display: swap; }
@font-face { font-family: "Alegreya SC"; src: url("../assets/fonts/AlegreyaSC-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Alegreya SC"; src: url("../assets/fonts/AlegreyaSC-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Alegreya SC"; src: url("../assets/fonts/AlegreyaSC-Bold.woff2") format("woff2"); font-weight: 700; font-display: swap; }
/* picture paths used by the backgrounds below; phones (.lite, end of file) swap in smaller files */
:root {
  --img-corner-book-bl: url("../assets/img/corner-book-bl.webp");
  --img-corner-book-br: url("../assets/img/corner-book-br.webp");
  --img-corner-book-tl: url("../assets/img/corner-book-tl.webp");
  --img-corner-book-tr: url("../assets/img/corner-book-tr.webp");
  --img-ornament-red: url("../assets/img/ornament-red.webp");
  --img-wm-kite: url("../assets/img/wm-kite.webp");
  --img-wm-lang: url("../assets/img/wm-lang.webp");
  --img-wm-lao-cart: url("../assets/img/wm-lao-cart.webp");
  --img-wm-lin-lang: url("../assets/img/wm-lin-lang.webp");
  --img-wm-ornithopter: url("../assets/img/wm-ornithopter.webp");
  --img-wm-paper-crane: url("../assets/img/wm-paper-crane.webp");
  --img-wm-plum-branch: url("../assets/img/wm-plum-branch.webp");
  --img-wm-sky-lanterns: url("../assets/img/wm-sky-lanterns.webp");
  --img-wm-steam-guard: url("../assets/img/wm-steam-guard.webp");
  --img-wm-steam-tram: url("../assets/img/wm-steam-tram.webp");
  --img-wm-teahouse: url("../assets/img/wm-teahouse.webp");
  --img-wm-water-wheel: url("../assets/img/wm-water-wheel.webp");
}

:root {
  --black: #000;
  --veil: rgba(0, 0, 0, .9);
  --night: #0b0908;
  --cream: #f3e7cf;
  --cream-2: rgba(243, 231, 207, .72);
  --cream-3: rgba(243, 231, 207, .5);
  --line: rgba(243, 231, 207, .14);
  --gold: #e2b45a;
  --gold-2: #f3d58e;
  --red: #e0443a;
  --red-deep: #a51c30;
  --teal: #5fe3c8;
  --silver: #c8ccd2;
  --navy-glow: #7f9ad6;
  --jade: #4fb39c;

  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;
  --gutter: 16px;
  --section: 72px;
  --ease: cubic-bezier(.2, .7, .2, 1);
  --t: 160ms;
  --t-slow: 240ms;

  --serif: "Alegreya", "Palatino Linotype", Palatino, Georgia, serif;
  --caps: "Alegreya SC", "Alegreya", Palatino, Georgia, serif;
}
@media (min-width: 700px) { :root { --gutter: 32px; --section: 112px; } }
@media (min-width: 1600px) { :root { --gutter: 48px; } }

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; scroll-padding-top: 64px; background: var(--black); }
body {
  margin: 0; background: transparent; color: var(--cream);
  font: 400 17px/1.65 var(--serif); -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
@media (min-width: 1200px) { body { font-size: 18px; } }
@media (min-width: 2200px) { body { font-size: 21px; } }
html.js body { opacity: 0; transition: opacity 600ms var(--ease); }
html.js.is-ready body { opacity: 1; }

img, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; }
button { font: inherit; color: inherit; }
h1, h2, h3, p { margin: 0; }
ul[role="list"] { list-style: none; margin: 0; padding: 0; }
.icon { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 3px; border-radius: 2px; }

.skip { position: fixed; left: var(--s4); top: var(--s4); z-index: 100; padding: var(--s3) var(--s4); background: var(--cream); color: #000; transform: translateY(-200%); transition: transform var(--t) var(--ease); }
.skip:focus { transform: none; }

/* ---------- top bar ---------- */
.bar {
  position: fixed; inset: 0 0 auto; z-index: 50; height: 60px;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s5);
  padding: env(safe-area-inset-top) var(--gutter) 0;
  transition: background-color var(--t-slow) var(--ease);
}
.bar.is-solid { background: rgba(0, 0, 0, .86); }
.bar__home { opacity: 0; pointer-events: none; transition: opacity var(--t-slow) var(--ease); }
.bar.is-solid .bar__home { opacity: 1; pointer-events: auto; }
.bar__home img { height: 38px; width: auto; }
.bar__nav { display: none; gap: var(--s1); }
.bar__nav a, .menu a, .bar__menu {
  font: 400 14px/1 var(--caps); letter-spacing: .2em; text-transform: uppercase; text-decoration: none; color: var(--cream-2);
  transition: color var(--t) var(--ease), letter-spacing var(--t) var(--ease), text-shadow var(--t) var(--ease);
}
.bar__nav a { padding: var(--s3) var(--s3); }
.bar__nav a:hover, .bar__nav a.is-active { color: var(--gold-2); text-shadow: 0 0 12px rgba(226, 180, 90, .55); }
.bar__menu {
  display: inline-flex; align-items: center; gap: var(--s2); min-height: 48px; padding: 0 var(--s3);
  background: none; border: 0; cursor: pointer; color: var(--cream);
}
.bar__menu:hover { color: var(--gold-2); }
.bar__menu:active { transform: scale(.97); }
@media (min-width: 1080px) { .bar__nav { display: flex; } .bar .bar__menu { display: none; } }

.menu { position: fixed; inset: 0; z-index: 45; display: grid; place-items: center; background: rgba(0, 0, 0, .96); opacity: 0; transition: opacity var(--t-slow) var(--ease); }
.menu.is-open { opacity: 1; }
.menu nav { display: grid; gap: var(--s1); text-align: center; }
.menu a { font-size: 20px; color: var(--cream); padding: var(--s4) var(--s6); }
.menu a:hover, .menu a:active { color: var(--gold-2); letter-spacing: .26em; }

/* ---------- glowing words ---------- */
.glow { color: var(--gold-2); animation: glowPulse 3.2s ease-in-out infinite; white-space: nowrap; }
.glow--teal { color: var(--teal); --glow: rgba(95, 227, 200, .7); }
.glow--red { color: #ff6b5c; --glow: rgba(224, 68, 58, .75); }
@keyframes glowPulse {
  0%, 100% { text-shadow: 0 0 6px var(--glow, rgba(226, 180, 90, .55)), 0 0 18px var(--glow, rgba(226, 180, 90, .35)); }
  50% { text-shadow: 0 0 10px var(--glow, rgba(226, 180, 90, .85)), 0 0 30px var(--glow, rgba(226, 180, 90, .55)); }
}

/* ---------- banner with the crest ---------- */
.banner {
  position: relative; min-height: 100vh; min-height: 100svh;
  display: grid; place-items: center; text-align: center; overflow: hidden;
  padding: 96px var(--gutter) 112px;
  background: radial-gradient(70% 60% at 50% 45%, rgba(0, 0, 0, .25) 0%, rgba(0, 0, 0, .7) 70%, #000 100%);
}
.banner::after { content: ""; position: absolute; inset: auto 0 0; height: 34%; background: linear-gradient(180deg, transparent, var(--veil)); pointer-events: none; }
.banner__inner { position: relative; z-index: 1; display: grid; justify-items: center; gap: var(--s6); }
.crest { position: relative; width: min(64vw, 440px, 50vh * 1.13); perspective: 700px; }
.crest__logo { position: relative; z-index: 2; width: 100%; animation: crestIn 3s cubic-bezier(.19, 1, .22, 1) both; filter: drop-shadow(0 0 2px rgba(255, 90, 70, .55)) drop-shadow(0 2px 6px rgba(0, 0, 0, .8)); }
.crest__aura {
  position: absolute; z-index: 1; inset: -15.1% -13.3%;
  background: url("../assets/img/crest-aura.webp") center / 100% 100% no-repeat;
  -webkit-mask-image: url("../assets/img/shimmer-mask.png"); mask-image: url("../assets/img/shimmer-mask.png");
  -webkit-mask-size: 256px 256px; mask-size: 256px 256px;
  animation: maskDrift 5s linear infinite, auraIn 2.4s linear both;
  pointer-events: none;
}
.crest__aura--large { background-image: url("../assets/img/crest-aura-large.webp"); animation: maskDrift 12s linear infinite reverse, auraIn 3s linear both; opacity: .9; }
@keyframes crestIn { from { transform: rotateY(-90deg); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes auraIn { from { opacity: 0; } 35% { opacity: 0; } to { opacity: 1; } }
@keyframes maskDrift { to { -webkit-mask-position: 0 -256px; mask-position: 0 -256px; } }
.banner__lines {
  font: 400 clamp(15px, 2.2vw, 21px)/1.7 var(--caps); letter-spacing: .14em; text-transform: uppercase; color: var(--cream-2);
  animation: auraIn 2.6s linear both; text-wrap: balance;
}
.banner__next {
  position: absolute; z-index: 2; left: 50%; bottom: var(--s5); transform: translateX(-50%);
  display: grid; place-items: center; width: 48px; height: 48px; color: var(--cream-2);
  animation: nudge 2.4s ease-in-out infinite;
}
.banner__next:hover { color: var(--gold-2); }
@keyframes nudge { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, 6px); } }

/* ---------- sections ---------- */
.wrapper { position: relative; padding: var(--section) 0; background: var(--veil); }
.inner { position: relative; z-index: 1; width: 100%; max-width: 1240px; margin: 0 auto; padding: 0 var(--gutter); }
@media (min-width: 2000px) { .inner { max-width: 1680px; } }

.head { text-align: center; margin-bottom: var(--s7); }
.head h2 {
  font: 400 clamp(30px, 5.4vw, 56px)/1.1 var(--caps); letter-spacing: .22em; text-transform: uppercase; color: var(--cream);
  padding-left: .22em; text-shadow: 0 0 24px rgba(226, 180, 90, .18);
}
.head p { margin-top: var(--s3); font: 400 clamp(13px, 1.6vw, 16px)/1.5 var(--caps); letter-spacing: .14em; text-transform: uppercase; color: var(--cream-3); text-wrap: balance; }

/* ---------- the tale ---------- */
.tale { padding-top: 0; }
.tale__text { max-width: 760px; margin: 0 auto; display: grid; gap: var(--s4); font-size: 1.12em; line-height: 1.7; }
.tale__text p { text-wrap: pretty; }

/* feature slides */
.slides { max-width: 1100px; margin: 0 auto; }
.slides__track { position: relative; aspect-ratio: 2.39 / 1; overflow: hidden; background: #000; touch-action: pan-y; }
@media (max-width: 699px) { .slides__track { aspect-ratio: 4 / 3; } }
.slide { position: absolute; inset: 0; margin: 0; opacity: 0; transition: opacity 700ms var(--ease); }
.slide.is-current { opacity: 1; }
.slide img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.06); transition: transform 7s linear; }
.slide.is-current img { transform: scale(1); }
.slide::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, .55) 72%, rgba(0, 0, 0, .9) 100%), linear-gradient(90deg, rgba(0, 0, 0, .35), transparent 30%, transparent 70%, rgba(0, 0, 0, .35)); }
.slide figcaption { position: absolute; z-index: 1; left: 0; right: 0; bottom: 0; padding: var(--s5) var(--s5) var(--s6); text-align: center; }
.slide h3 { font: 400 clamp(20px, 3.4vw, 36px)/1.2 var(--caps); letter-spacing: .16em; text-transform: uppercase; color: var(--cream); text-shadow: 0 2px 8px rgba(0, 0, 0, .9); }
.slide p { margin-top: var(--s2); font: 400 clamp(13px, 1.6vw, 17px)/1.4 var(--caps); letter-spacing: .12em; text-transform: uppercase; color: var(--cream-2); text-shadow: 0 1px 4px rgba(0, 0, 0, .9); }
.slides__ctrl { display: flex; align-items: center; justify-content: center; gap: var(--s4); margin-top: var(--s4); }
.slides__arrow { display: grid; place-items: center; width: 48px; height: 48px; border: 0; border-radius: 50%; background: none; color: var(--cream-2); cursor: pointer; transition: color var(--t) var(--ease), background-color var(--t) var(--ease); }
.slides__arrow:hover { color: var(--gold-2); background: rgba(243, 231, 207, .06); }
.slides__arrow:active { transform: scale(.94); }
.slides__dots { display: flex; gap: var(--s2); }
.slides__dots button { width: 40px; height: 48px; padding: 0; border: 0; background: none; cursor: pointer; position: relative; }
.slides__dots button::before { content: ""; position: absolute; left: 4px; right: 4px; top: 50%; height: 2px; background: rgba(243, 231, 207, .3); transition: background-color var(--t) var(--ease), box-shadow var(--t) var(--ease); }
.slides__dots button:hover::before { background: rgba(243, 231, 207, .6); }
.slides__dots button[aria-selected="true"]::before { background: var(--gold-2); box-shadow: 0 0 10px rgba(226, 180, 90, .8); }

/* ---------- credits ---------- */
.credits { text-align: center; }
.credits .inner { display: grid; gap: var(--s7); }
.credits h3 { font: 400 clamp(13px, 1.5vw, 15px)/1.4 var(--caps); letter-spacing: .2em; text-transform: uppercase; color: var(--cream-3); margin-bottom: var(--s2); }
.credits h2 { font: 400 clamp(26px, 4.4vw, 46px)/1.2 var(--caps); letter-spacing: .14em; text-transform: uppercase; color: var(--cream); }
.credits__more { font-size: clamp(18px, 2.6vw, 26px) !important; color: var(--cream-2) !important; margin-top: var(--s2); }
.amp { font-family: var(--serif); font-style: italic; text-transform: none; color: var(--gold); letter-spacing: 0; padding: 0 .1em; }

/* ---------- main theme screen ---------- */
.screen { max-width: 1100px; margin: 0 auto; box-shadow: 0 0 0 1px rgba(226, 180, 90, .18), 0 20px 80px rgba(0, 0, 0, .8), 0 0 120px rgba(226, 180, 90, .08); }

/* YouTube facade */
.yt { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: #000; }
.yt__thumb { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--ease), filter var(--t-slow) var(--ease); filter: brightness(.85); }
.yt__play {
  position: absolute; inset: 0; margin: auto; width: 76px; height: 76px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(165, 28, 48, .9); color: var(--cream); border: 1px solid rgba(243, 213, 142, .7);
  animation: playGlow 2.6s ease-in-out infinite;
  transition: transform var(--t) var(--ease), background-color var(--t) var(--ease);
}
.yt__play .icon { width: 30px; height: 30px; margin-left: 4px; }
@keyframes playGlow { 0%, 100% { box-shadow: 0 0 0 0 rgba(224, 68, 58, .5), 0 0 24px rgba(224, 68, 58, .45); } 50% { box-shadow: 0 0 0 10px rgba(224, 68, 58, 0), 0 0 40px rgba(224, 68, 58, .7); } }
.yt:hover .yt__thumb { transform: scale(1.03); filter: brightness(1); }
.yt:hover .yt__play { transform: scale(1.07); background: rgba(196, 36, 52, .95); }
.yt__play:active { transform: scale(.95); }
.yt iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.yt.is-loading::after { content: ""; position: absolute; inset: 0; margin: auto; width: 40px; height: 40px; border: 3px solid rgba(243, 231, 207, .25); border-top-color: var(--gold-2); border-radius: 50%; animation: spin 800ms linear infinite; }
.yt.is-loading .yt__play { opacity: 0; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- characters ---------- */
.characters::before, .soundtrack::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(60% 34% at 50% 30%, rgba(165, 28, 48, .2), transparent 100%); }
.cast { display: grid; gap: var(--s6) var(--s4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 700px) { .cast { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s7) var(--s5); } }
@media (min-width: 1100px) { .cast { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.who { --tone: 226, 180, 90; }
.who[data-tone="teal"] { --tone: 95, 227, 200; }
.who[data-tone="silver"] { --tone: 200, 204, 214; }
.who[data-tone="gold"] { --tone: 226, 180, 90; }
.who[data-tone="navy"] { --tone: 127, 154, 214; }
.who[data-tone="red"] { --tone: 224, 68, 58; }
.who[data-tone="jade"] { --tone: 79, 179, 156; }
.who__btn { display: grid; justify-items: center; width: 100%; padding: 0; border: 0; background: none; cursor: pointer; text-align: center; }
.who__art { position: relative; display: block; width: 100%; aspect-ratio: 1; }
.who__art::before {
  content: ""; position: absolute; inset: 14% 8% 0; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(var(--tone), .42), rgba(var(--tone), .12) 60%, transparent 100%);
  filter: blur(6px); opacity: .75; transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
.who__art img {
  position: relative; width: 100%; height: 100%; object-fit: contain;
  -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent 100%); mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
  filter: drop-shadow(0 0 1px rgba(var(--tone), .5));
  transition: transform var(--t-slow) var(--ease), filter var(--t-slow) var(--ease);
}
.who__name { margin-top: var(--s2); font: 500 clamp(17px, 2vw, 21px)/1.2 var(--caps); letter-spacing: .12em; text-transform: uppercase; color: var(--red); transition: color var(--t) var(--ease), text-shadow var(--t) var(--ease); }
.who__role { margin-top: var(--s1); max-width: 22ch; font: 400 13px/1.45 var(--caps); letter-spacing: .1em; text-transform: uppercase; color: var(--cream-3); }
.who__btn:hover .who__art::before { opacity: 1; transform: scale(1.06); }
.who__btn:hover .who__art img { transform: translateY(-4px); filter: drop-shadow(0 0 8px rgba(var(--tone), .55)); }
.who__btn:hover .who__name { color: #ff6b5c; text-shadow: 0 0 12px rgba(224, 68, 58, .6); }
.who__btn:active .who__art img { transform: translateY(-1px); }

/* ---------- tilted scene wall ---------- */
.scenes { overflow: hidden; }
.wall { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5) var(--s4); perspective: 520px; }
@media (min-width: 900px) { .wall { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s7) var(--s5); perspective: 600px; } }
.tile { transform-style: preserve-3d; }
.tile__btn { display: block; width: 100%; padding: 0; border: 0; background: #000; cursor: pointer; aspect-ratio: 2.39 / 1; overflow: hidden; }
.tile__btn img, .tile__btn video { width: 100%; height: 100%; object-fit: cover; transition: filter var(--t-slow) var(--ease), transform 600ms var(--ease); filter: brightness(.82) saturate(.95); }
.tile__btn:hover img, .tile__btn:hover video { filter: brightness(1.05) saturate(1.05); transform: scale(1.04); }
.tile { transition: transform 600ms var(--ease); }
/* two columns: each leans toward the middle */
.tile:nth-child(odd) { transform: rotateY(9deg); transform-origin: right center; }
.tile:nth-child(even) { transform: rotateY(-9deg); transform-origin: left center; }
.tile:nth-child(odd) .tile__btn { -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, .35), #000 40%); mask-image: linear-gradient(90deg, rgba(0, 0, 0, .35), #000 40%); }
.tile:nth-child(even) .tile__btn { -webkit-mask-image: linear-gradient(270deg, rgba(0, 0, 0, .35), #000 40%); mask-image: linear-gradient(270deg, rgba(0, 0, 0, .35), #000 40%); }
@media (min-width: 900px) {
  .tile:nth-child(n) { transform: none; }
  .tile:nth-child(n) .tile__btn { -webkit-mask-image: none; mask-image: none; }
  .tile:nth-child(3n+1) { transform: rotateY(12deg); transform-origin: right center; }
  .tile:nth-child(3n) { transform: rotateY(-12deg); transform-origin: left center; }
  .tile:nth-child(3n+1) .tile__btn { -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, .3), #000 45%); mask-image: linear-gradient(90deg, rgba(0, 0, 0, .3), #000 45%); }
  .tile:nth-child(3n) .tile__btn { -webkit-mask-image: linear-gradient(270deg, rgba(0, 0, 0, .3), #000 45%); mask-image: linear-gradient(270deg, rgba(0, 0, 0, .3), #000 45%); }
}
/* a short last row sits in the middle (Pi, 26 Oct 2026): two columns -> a lone last tile centred; three columns -> a last pair
   centred and leaning in, or a lone last tile centred flat */
.tile:last-child:nth-child(odd) { grid-column: 1 / -1; justify-self: center; width: calc(50% - var(--s4) / 2); transform: none; }
.tile:last-child:nth-child(odd) .tile__btn { -webkit-mask-image: none; mask-image: none; }
@media (min-width: 900px) {
  .wall { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .tile, .tile:last-child:nth-child(odd) { grid-column: span 2; justify-self: stretch; width: auto; }
  .tile:nth-last-child(2):nth-child(3n+1) { grid-column: 2 / span 2; }
  .tile:last-child:nth-child(3n+2) { transform: rotateY(-12deg); transform-origin: left center; }
  .tile:last-child:nth-child(3n+2) .tile__btn { -webkit-mask-image: linear-gradient(270deg, rgba(0, 0, 0, .3), #000 45%); mask-image: linear-gradient(270deg, rgba(0, 0, 0, .3), #000 45%); }
  .tile:last-child:nth-child(3n+1) { grid-column: 3 / span 2; transform: none; }
  .tile:last-child:nth-child(3n+1) .tile__btn { -webkit-mask-image: none; mask-image: none; }
}
.tile:hover { transform: none !important; }

/* ---------- locations ---------- */
.places { display: grid; gap: var(--s7); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .places { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s6); } }
.place { display: grid; align-content: start; gap: var(--s3); text-align: center; }
.place img {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover; margin-bottom: var(--s3);
  -webkit-mask-image: radial-gradient(120% 100% at 50% 40%, #000 60%, transparent 100%); mask-image: radial-gradient(120% 100% at 50% 40%, #000 60%, transparent 100%);
}
.place h3 { font: 500 clamp(20px, 2.4vw, 26px)/1.2 var(--caps); letter-spacing: .14em; text-transform: uppercase; color: var(--red); }
.place p { color: var(--cream-2); max-width: 40ch; margin: 0 auto; }
.place__steel em { color: var(--gold-2); }

/* ---------- factions and infos ---------- */
.infos { display: grid; gap: var(--s7) var(--s6); grid-template-columns: minmax(0, 1fr); text-align: center; }
@media (min-width: 640px) { .infos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .infos { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 900px) { .infos--three { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.infos h3 { font: 400 15px/1.4 var(--caps); letter-spacing: .22em; text-transform: uppercase; color: var(--cream-3); margin-bottom: var(--s3); }
.faction { --tone: 226, 180, 90; display: grid; justify-items: center; align-content: start; gap: var(--s3); }
.faction[data-tone="red"] { --tone: 224, 68, 58; }
.faction[data-tone="navy"] { --tone: 127, 154, 214; }
.faction[data-tone="crane"] { --tone: 240, 90, 90; }
.faction img { width: 120px; height: 120px; object-fit: contain; margin-bottom: var(--s3); filter: drop-shadow(0 0 1px rgba(var(--tone), .9)) drop-shadow(0 0 18px rgba(var(--tone), .45)); }
.faction[data-tone="red"] img { filter: brightness(1.7) saturate(1.1) drop-shadow(0 0 16px rgba(var(--tone), .5)); }
.faction[data-tone="navy"] img { filter: brightness(3.2) saturate(.7) drop-shadow(0 0 16px rgba(var(--tone), .55)); }
.faction h3 { font: 500 22px/1.2 var(--caps); letter-spacing: .14em; color: rgb(var(--tone)); margin: 0; }
.faction p { color: var(--cream-2); max-width: 34ch; }

.infos .big { font: 400 30px/1.2 var(--caps); letter-spacing: .14em; text-transform: uppercase; color: var(--gold-2); }
.plats { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2) var(--s5); }
.plats span { display: inline-flex; align-items: center; gap: var(--s2); color: var(--cream); font-size: 18px; }
.follow { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); }
.link {
  display: inline-flex; align-items: center; gap: var(--s2); min-height: 48px; padding: 0 var(--s3);
  color: var(--cream); text-decoration: none; font-size: 18px; overflow-wrap: anywhere; border-radius: 2px;
  transition: color var(--t) var(--ease), text-shadow var(--t) var(--ease);
}
.link:hover { color: var(--gold-2); text-shadow: 0 0 10px rgba(226, 180, 90, .5); }

/* ---------- soundtrack ---------- */
.soundtrack::before { background: radial-gradient(60% 34% at 50% 70%, rgba(95, 227, 200, .08), transparent 100%); }
.ost { display: grid; gap: var(--s6) var(--s5); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 640px) { .ost { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .ost { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.track .yt__play { width: 60px; height: 60px; }
.track .yt__play .icon { width: 24px; height: 24px; }
.track h3 { margin-top: var(--s3); text-align: center; font: 400 16px/1.3 var(--caps); letter-spacing: .14em; text-transform: uppercase; color: var(--cream-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.note { margin-top: var(--s6); text-align: center; font-size: 15px; color: var(--cream-3); }

/* ---------- footer ---------- */
.foot { background: #000; padding: var(--s7) 0 calc(var(--s6) + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.foot__grid { display: grid; gap: var(--s6); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 800px) { .foot__grid { grid-template-columns: 1fr 2fr; } }
.foot h3 { font: 400 14px/1.4 var(--caps); letter-spacing: .22em; text-transform: uppercase; color: var(--cream-3); margin-bottom: var(--s3); }
.team li { color: var(--cream); font-size: 17px; line-height: 2; }
.team span { color: var(--cream-3); font-size: 14px; letter-spacing: .04em; }
.team span::before { content: " / "; }
.thanks { columns: 2; column-gap: var(--s5); }
@media (min-width: 1100px) { .thanks { columns: 3; } }
.thanks li { color: var(--cream-2); font-size: 16px; line-height: 2; }
.foot__end { display: grid; justify-items: center; gap: var(--s3); margin-top: var(--s7); }
.foot__end img { width: 160px; opacity: .85; }
.foot__end p { font-size: 13px; color: rgba(243, 231, 207, .4); }

/* ---------- detail sheet ---------- */
.icon-btn { display: inline-grid; place-items: center; width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--cream); cursor: pointer; transition: background-color var(--t) var(--ease), transform var(--t) var(--ease); }
.icon-btn:hover { background: rgba(243, 231, 207, .1); }
.icon-btn:active { transform: scale(.94); }
.icon-btn .icon { width: 22px; height: 22px; }
.sheet { width: min(100vw, 1040px); max-width: 100vw; max-height: 100dvh; padding: 0; margin: auto; border: 1px solid rgba(226, 180, 90, .25); background: #0b0908; color: var(--cream); overscroll-behavior: contain; }
.sheet::backdrop { background: rgba(0, 0, 0, .85); }
.sheet[open] { animation: sheetIn var(--t-slow) var(--ease); }
@keyframes sheetIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.sheet__inner { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); }
.sheet__close { position: absolute; top: var(--s2); right: var(--s2); z-index: 3; background: rgba(0, 0, 0, .55); }
.sheet__close:hover { background: rgba(0, 0, 0, .85); }
.sheet__art { position: relative; background: #000; }
.sheet__art img, .sheet__art video { width: 100%; height: auto; }
.sheet__text { padding: var(--s5) var(--s5) var(--s3); display: grid; gap: var(--s3); }
.sheet__text h3 { font: 500 28px/1.2 var(--caps); letter-spacing: .12em; text-transform: uppercase; color: var(--red); }
.sheet__text .detail__group { font: 400 13px/1.4 var(--caps); letter-spacing: .2em; text-transform: uppercase; color: var(--cream-3); }
.sheet__text p { color: var(--cream-2); }
.sheet__nav { display: flex; justify-content: space-between; padding: 0 var(--s3) var(--s3); }
.sheet--char .sheet__art { background: radial-gradient(closest-side, rgba(var(--tone, 226, 180, 90), .35), transparent 100%), #000; }
.sheet--char .sheet__art img { max-height: 54dvh; width: auto; margin: 0 auto; -webkit-mask-image: linear-gradient(180deg, #000 75%, transparent 100%); mask-image: linear-gradient(180deg, #000 75%, transparent 100%); }
@media (min-width: 800px) {
  .sheet--char { width: min(92vw, 880px); }
  .sheet--char .sheet__inner { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
  .sheet--char .sheet__art { grid-row: span 2; display: grid; align-items: end; padding-top: var(--s6); }
  .sheet--char .sheet__art img { max-height: none; width: 100%; }
  .sheet--char .sheet__text { padding: var(--s7) var(--s6) var(--s4); align-content: start; }
  .sheet--char .sheet__nav { align-self: end; padding: var(--s4) var(--s5); }
  .sheet--scene .sheet__text { padding: var(--s5) var(--s6) var(--s2); }
}
@media (max-width: 799px) {
  .sheet { width: 100vw; height: 100dvh; border: 0; }
  .sheet__inner { min-height: 100%; grid-template-rows: auto 1fr auto; }
  .sheet__nav { padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom)); }
}
html.has-dialog { overflow: hidden; }

/* ---------- reveal ---------- */
html.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity 600ms var(--ease), transform 600ms var(--ease); }
html.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
  html.js .reveal { opacity: 1; transform: none; }
  .tile:nth-child(n) { transform: none; }
}

/* ---------- storybook touches ---------- */
/* cloud-and-gear ornament under every section title, as under a chapter head */
.head::after { content: ""; display: block; width: min(340px, 72%); aspect-ratio: 1000 / 102; margin: var(--s4) auto 0; background: var(--img-ornament-red) center / contain no-repeat; opacity: .9; }

/* the story as a rice-paper page */
.page {
  position: relative; max-width: 820px; margin: 0 auto calc(var(--s7) * 1.5);
  padding: clamp(40px, 7vw, 72px) clamp(24px, 7vw, 80px);
  background: #e9dcc0 url("../assets/img/paper-tile.webp") center / 600px repeat;
  color: #2a1d14;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .7), 0 0 0 1px rgba(106, 0, 0, .25);
}
.page::before { content: ""; position: absolute; inset: 0; background: var(--img-wm-lin-lang) center 60% / min(70%, 420px) no-repeat; opacity: .16; mix-blend-mode: multiply; pointer-events: none; }
.page::after { content: ""; position: absolute; inset: 18px; border: 1px solid rgba(106, 0, 0, .55); pointer-events: none; }
.page__c { position: absolute; z-index: 1; width: clamp(34px, 6vw, 56px); aspect-ratio: 121 / 160; background: center / contain no-repeat; }
.page__c--tl { top: 8px; left: 8px; background-image: var(--img-corner-book-tl); }
.page__c--tr { top: 8px; right: 8px; background-image: var(--img-corner-book-tr); }
.page__c--bl { bottom: 8px; left: 8px; background-image: var(--img-corner-book-bl); }
.page__c--br { bottom: 8px; right: 8px; background-image: var(--img-corner-book-br); }
.page .tale__text { position: relative; z-index: 1; margin: 0; color: #2a1d14; text-align: left; }
.page .tale__text p:first-child::first-letter { float: left; font: 500 3.4em/0.86 var(--serif); color: #8a1010; padding: .06em .1em 0 0; }
.page .glow { animation: none; text-shadow: none; font-variant: small-caps; letter-spacing: .04em; }
.page .glow--teal { color: #1f6b5e; }
.page .glow--red { color: #8a1010; }
@media (max-width: 599px) { .page__c { width: 30px; } .page::after { inset: 12px; } }

/* framed plates: ink line, red lattice corners, the seal */
.framed { position: relative; overflow: visible; }
.framed::after {
  content: ""; position: absolute; inset: -10px; pointer-events: none; z-index: 2;
  border: 1px solid rgba(186, 38, 40, .45);
  background:
    url("../assets/img/corner-red-tl.webp") top left / 34px auto no-repeat,
    url("../assets/img/corner-red-tr.webp") top right / 34px auto no-repeat,
    url("../assets/img/corner-red-bl.webp") bottom left / 34px auto no-repeat,
    url("../assets/img/corner-red-br.webp") bottom right / 34px auto no-repeat;
}
.slides__track.framed { overflow: visible; }
.slides__track.framed .slide { overflow: hidden; }
.seal { position: absolute; z-index: 3; right: 18px; bottom: 18px; width: clamp(40px, 6vw, 64px); aspect-ratio: 1; background: url("../assets/img/seal.webp") center / contain no-repeat; opacity: .92; transform: rotate(-3deg); }
@media (max-width: 699px) { .framed::after { inset: -6px; background-size: 24px auto, 24px auto, 24px auto, 24px auto; } }

/* the scene wall follows the scroll: the eye point moves down the wall */
.wall { perspective-origin: 50% var(--eye, 50%); }

/* =====================================================================
   Storybook mode: rice-paper pages scroll over still paintings.
   One painting at a time sits behind the pages; it changes in the gaps.
   ===================================================================== */
html { background: #140d08; }


/* the cover: the first painting, the red crest */
.banner { background: radial-gradient(60% 55% at 50% 42%, rgba(10, 6, 4, .62) 0%, rgba(10, 6, 4, .35) 55%, rgba(10, 6, 4, .1) 100%); }
.banner::after { display: none; }
.banner__lines { color: #f6ead2; text-shadow: 0 1px 3px rgba(0, 0, 0, .95), 0 0 18px rgba(0, 0, 0, .8); }
.banner__next { color: #f6ead2; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .9)); }

/* gaps between pages: the painting behind shows here */
.gap { height: clamp(320px, 78vh, 900px); }
.gap--short { height: clamp(240px, 52vh, 600px); }
@media (max-width: 699px) { .gap { height: 64vh; } .gap--short { height: 44vh; } }

/* every section is a rice-paper page whose top and bottom edges dissolve */
.wrapper, .foot {
  --fade: 150px;
  --cream: #2a1d14;
  --cream-2: rgba(42, 29, 20, .88);
  --cream-3: rgba(84, 58, 38, .78);
  --line: rgba(106, 0, 0, .22);
  --gold: #8a5a12;
  --gold-2: #7a4a0c;
  --red: #8a1010;
  --teal: #1f6b5e;
  position: relative;
  color: var(--cream);
  background: #eadcbf url("../assets/img/paper-tile.webp") center top / 640px repeat;
  box-shadow: inset 0 0 140px rgba(110, 70, 30, .28);
  padding-top: calc(var(--section) + var(--fade) * .6);
  padding-bottom: calc(var(--section) + var(--fade) * .6);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 var(--fade), #000 calc(100% - var(--fade)), transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 var(--fade), #000 calc(100% - var(--fade)), transparent 100%);
}
@media (max-width: 699px) { .wrapper, .foot { --fade: 96px; } }
.foot { border-top: 0; }
/* pages that follow each other overlap, so their fades blend paper into paper */
main > section.wrapper + section.wrapper { margin-top: calc(var(--fade) * -1); }
.foot { margin-top: 0; }

/* ink, not neon, on paper */
.head h2 { text-shadow: none; color: #2a1d14; }
.head p { color: var(--cream-3); }
.wrapper .glow { animation: none; text-shadow: none; }
.page { background: none; box-shadow: none; }
.page::after { border-color: rgba(106, 0, 0, .5); }

/* slides keep light captions over the pictures */
.slide h3 { color: #f6ead2; }
.slide p { color: rgba(246, 234, 210, .85); }
.slides__dots button::before { background: rgba(42, 29, 20, .25); }
.slides__dots button:hover::before { background: rgba(42, 29, 20, .5); }
.slides__dots button[aria-selected="true"]::before { background: #8a1010; box-shadow: none; }
.slides__arrow:hover { color: #8a1010; background: rgba(106, 0, 0, .06); }

/* characters on paper: soft coloured halo, ink outline */
.who { --tone: 160, 110, 40; }
.who[data-tone="teal"] { --tone: 40, 150, 130; }
.who[data-tone="silver"] { --tone: 110, 116, 130; }
.who[data-tone="gold"] { --tone: 176, 120, 30; }
.who[data-tone="navy"] { --tone: 40, 60, 110; }
.who[data-tone="red"] { --tone: 150, 20, 24; }
.who[data-tone="jade"] { --tone: 30, 110, 92; }
.who__art::before { background: radial-gradient(closest-side, rgba(var(--tone), .28), rgba(var(--tone), .08) 60%, transparent 100%); }
.who__art img { filter: drop-shadow(0 4px 8px rgba(60, 35, 15, .18)); }
.who__btn:hover .who__art img { filter: drop-shadow(0 8px 14px rgba(60, 35, 15, .28)); }
.who__btn:hover .who__name { color: #b0161a; text-shadow: none; }
.characters::before, .soundtrack::before { display: none; }

/* factions: emblems in their own colours on paper */
.faction { --tone: 138, 16, 16; }
.faction[data-tone="navy"] { --tone: 31, 42, 68; }
.faction[data-tone="crane"] { --tone: 176, 23, 31; }
.faction img, .faction[data-tone="red"] img, .faction[data-tone="navy"] img { filter: drop-shadow(0 3px 6px rgba(60, 35, 15, .2)); }

/* links and the big words */
.link { color: #2a1d14; }
.link:hover { color: #8a1010; text-shadow: none; }
.infos .big { color: #8a1010; }
.plats span { color: #2a1d14; }
.team li { color: #2a1d14; }
.foot__end p { color: rgba(42, 29, 20, .55); }
.foot__end img { opacity: 1; }

/* the scene wall's outer tiles fade into the paper */
.tile__btn { background: transparent; }
.tile__btn img, .tile__btn video { filter: none; }
.tile__btn:hover img, .tile__btn:hover video { filter: brightness(1.04); }

/* top bar: light words over the cover, a paper strip once you scroll */
.bar__nav a, .bar__menu { color: #f6ead2; text-shadow: 0 1px 3px rgba(0, 0, 0, .9); }
.bar.is-solid { background: rgba(234, 220, 191, .96) url("../assets/img/paper-tile.webp") center / 640px; box-shadow: 0 1px 0 rgba(106, 0, 0, .25), 0 6px 18px rgba(40, 20, 10, .15); }
.bar.is-solid .bar__nav a, .bar.is-solid .bar__menu { color: #3a2818; text-shadow: none; }
.bar.is-solid .bar__nav a:hover, .bar.is-solid .bar__nav a.is-active { color: #8a1010; text-shadow: none; }
.menu { background: rgba(234, 220, 191, .98) url("../assets/img/paper-tile.webp") center / 640px; }
.menu a { color: #2a1d14; text-shadow: none; }
.menu a:hover, .menu a:active { color: #8a1010; }


/* cover: the crest and the lines sit in the sky, above Lin and Lang */
.banner { align-items: start; padding-top: calc(64px + clamp(8px, 3vh, 40px));
  background: linear-gradient(180deg, rgba(10, 6, 4, .78) 0%, rgba(10, 6, 4, .55) 30%, rgba(10, 6, 4, .18) 52%, rgba(10, 6, 4, 0) 66%); }
.banner__inner { gap: var(--s4); }
.crest { width: min(54vw, 330px, 36vh * 1.13); }
@media (max-aspect-ratio: 4/5) {
  .banner { background: linear-gradient(180deg, rgba(10, 6, 4, .82) 0%, rgba(10, 6, 4, .6) 34%, rgba(10, 6, 4, .15) 56%, rgba(10, 6, 4, 0) 70%); }
  .crest { width: min(62vw, 300px); }
}

/* cover, round 2: crest in the sky, lines low over the sand, painting set lower */
.banner { align-items: stretch;
  background:
    linear-gradient(180deg, rgba(10, 6, 4, .78) 0%, rgba(10, 6, 4, .5) 26%, rgba(10, 6, 4, 0) 46%, rgba(10, 6, 4, 0) 66%, rgba(10, 6, 4, .55) 86%, rgba(10, 6, 4, .75) 100%); }
.banner__inner { align-content: space-between; min-height: calc(100svh - 64px - 112px); }
.banner__lines { align-self: end; }
.crest { width: min(54vw, 300px, 30vh * 1.13); }
@media (max-aspect-ratio: 4/5) {
  .crest { width: min(58vw, 260px); }
  }
/* phones: an odd last tile sits centred, flat, instead of alone in one column */
@media (max-width: 899px) {
  .tile:last-child:nth-child(odd) { grid-column: 1 / -1; justify-self: center; width: 62%; transform: none; }
  .tile:last-child:nth-child(odd) .tile__btn { -webkit-mask-image: none; mask-image: none; }
}

/* =====================================================================
   Windows: each painting is seen only through its own gap (one image,
   one place). The painting is fixed, so the page slides past it.
   ===================================================================== */
.win, .gap { position: relative; z-index: 0; clip-path: inset(0); }
.win { position: absolute; inset: 0; }
.win__img { position: fixed; inset: 0; display: block; transform: scale(1.04); }
.win__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.banner .win__img img { object-position: 50% 62%; }
@media (max-aspect-ratio: 4/5) { .banner .win__img img { object-position: 20% 100%; } }
.gap .win__img::after, .banner .win::after { content: ""; position: absolute; inset: 0; background: radial-gradient(120% 90% at 50% 50%, transparent 58%, rgba(20, 10, 6, .4) 100%); }

/* the cover: no dark band at the bottom; a soft scrim only behind the words */
.banner { background: linear-gradient(180deg, rgba(10, 6, 4, .72) 0%, rgba(10, 6, 4, .45) 24%, rgba(10, 6, 4, 0) 44%); }
.banner__inner { position: relative; z-index: 1; }
.banner__lines { position: relative; padding: var(--s4) var(--s6); }
.banner__lines::before { content: ""; position: absolute; inset: -20px -40px; z-index: -1; background: radial-gradient(closest-side, rgba(10, 6, 4, .62), rgba(10, 6, 4, 0)); }

/* gaps run under the faded page edges, so paper dissolves straight into the painting */
.gap { height: calc(clamp(320px, 74vh, 860px) + var(--fade-gap) * 2); margin: calc(var(--fade-gap) * -1) 0; }
.gap--short { height: calc(clamp(240px, 50vh, 560px) + var(--fade-gap) * 2); }
:root { --fade-gap: 150px; }
@media (max-width: 699px) { :root { --fade-gap: 96px; } .gap { height: calc(60vh + var(--fade-gap) * 2); } .gap--short { height: calc(40vh + var(--fade-gap) * 2); } }
main > section, .foot { position: relative; z-index: 1; }
.banner { z-index: 0; }

/* paper pages: fade only an edge that meets a painting; page-to-page joins stay solid */
.wrapper, .foot { -webkit-mask-image: none; mask-image: none; padding-top: var(--section); padding-bottom: var(--section); }
main > section.wrapper + section.wrapper { margin-top: 0; }
.wrapper.fade-top, .foot.fade-top { padding-top: calc(var(--section) + var(--fade) * .7); }
.wrapper.fade-bottom { padding-bottom: calc(var(--section) + var(--fade) * .7); }
.fade-top { -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.25) calc(var(--fade) * .3), rgba(0,0,0,.7) calc(var(--fade) * .6), #000 var(--fade)); mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.25) calc(var(--fade) * .3), rgba(0,0,0,.7) calc(var(--fade) * .6), #000 var(--fade)); }
.fade-bottom { -webkit-mask-image: linear-gradient(0deg, transparent 0, rgba(0,0,0,.25) calc(var(--fade) * .3), rgba(0,0,0,.7) calc(var(--fade) * .6), #000 var(--fade)); mask-image: linear-gradient(0deg, transparent 0, rgba(0,0,0,.25) calc(var(--fade) * .3), rgba(0,0,0,.7) calc(var(--fade) * .6), #000 var(--fade)); }
.fade-top.fade-bottom { -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.25) calc(var(--fade) * .3), rgba(0,0,0,.7) calc(var(--fade) * .6), #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0,0,0,.7) calc(100% - var(--fade) * .6), rgba(0,0,0,.25) calc(100% - var(--fade) * .3), transparent 100%); mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.25) calc(var(--fade) * .3), rgba(0,0,0,.7) calc(var(--fade) * .6), #000 var(--fade), #000 calc(100% - var(--fade)), rgba(0,0,0,.7) calc(100% - var(--fade) * .6), rgba(0,0,0,.25) calc(100% - var(--fade) * .3), transparent 100%); }
.wrapper, .foot { --fade: var(--fade-gap); }

/* storybook page frame: one red rule, lattice corners, as in the book */
.wrapper::after, .foot::after {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  left: clamp(10px, 2.4vw, 32px); right: clamp(10px, 2.4vw, 32px);
  top: var(--frame-top, clamp(10px, 2.4vw, 32px)); bottom: var(--frame-bottom, clamp(10px, 2.4vw, 32px));
  border: 1px solid rgba(106, 0, 0, .5);
  background:
    var(--img-corner-book-tl) top -1px left -1px / clamp(30px, 4vw, 52px) auto no-repeat,
    var(--img-corner-book-tr) top -1px right -1px / clamp(30px, 4vw, 52px) auto no-repeat,
    var(--img-corner-book-bl) bottom -1px left -1px / clamp(30px, 4vw, 52px) auto no-repeat,
    var(--img-corner-book-br) bottom -1px right -1px / clamp(30px, 4vw, 52px) auto no-repeat;
}
.fade-top { --frame-top: calc(var(--fade) * .75); }
.fade-bottom { --frame-bottom: calc(var(--fade) * .75); }
/* a join between two pages shares one frame: the lower page drops its top rule */
.wrapper.joined-top::after { border-top: 0; background-image: none, none, var(--img-corner-book-bl), var(--img-corner-book-br); top: 0; }
.wrapper.joined-bottom::after { border-bottom: 0; bottom: 0; }
.wrapper.joined-bottom:not(.joined-top)::after { background-image: var(--img-corner-book-tl), var(--img-corner-book-tr), none, none; }
.wrapper.joined-top.joined-bottom::after { background-image: none; }

/* one faint ink-wash watermark per page, under the text */
.wrapper::before, .foot::before {
  content: ""; display: block !important; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--wm, none) right 6% center / min(44vw, 520px) auto no-repeat;
  opacity: .2; mix-blend-mode: multiply;
}
.wrapper:nth-of-type(even)::before { background-position: left 6% center; }
.wrapper > .inner, .foot > .inner, .foot__end { position: relative; z-index: 1; }
@media (max-width: 699px) { .wrapper::before, .foot::before { background-size: 78vw auto; background-position: center 70%; opacity: .14; } }

/* the tale page inside the first page keeps only its drop cap and text */
.page::after, .page__c { display: none; }
.page { padding: 0; margin-bottom: calc(var(--s7) * 1.5); }
.page::before { display: none; }
/* the first page slides over the bottom of the cover, so its faded top shows the cover painting */
.banner + .wrapper { margin-top: calc(var(--fade) * -1); }
/* joins between pages must not show: shade only the left and right edges, one continuous paper */
.wrapper, .foot {
  box-shadow: inset 120px 0 120px -90px rgba(110, 70, 30, .3), inset -120px 0 120px -90px rgba(110, 70, 30, .3);
  background-attachment: fixed;
}
/* watermarks, one per page (paths here resolve from this stylesheet in every browser) */
.credits { --wm: var(--img-wm-plum-branch); }
.theme { --wm: var(--img-wm-sky-lanterns); }
.characters { --wm: var(--img-wm-lao-cart); }
.scenes { --wm: var(--img-wm-kite); }
.locations { --wm: var(--img-wm-water-wheel); }
.factions { --wm: var(--img-wm-steam-guard); }
.soundtrack { --wm: var(--img-wm-paper-crane); }
#infos { --wm: var(--img-wm-teahouse); }
.foot { --wm: var(--img-wm-lang); }
.tale { --wm: var(--img-wm-lin-lang); }
/* joined pages overlap by 1px so no hairline of dark shows between them */
.wrapper.joined-top { margin-top: -1px; }
.wrapper::before, .foot::before { opacity: .3; }
@media (max-width: 699px) { .wrapper::before, .foot::before { opacity: .2; } }

/* a hidden menu must not cover the page (it caught every click) */
.menu[hidden] { display: none !important; }

/* =====================================================================
   Book page frame, to the book's own geometry (07_book_pages/border.svg):
   corner 58pt wide, rules 1.2pt on the corner's outer arms,
   each rule stopping 4pt before the next corner. In corner widths (W):
   arm centre x = .0269W, arm centre y = .092W, gap = .069W, rule = .0207W.
   ===================================================================== */
.wrapper, .foot {
  --fx: clamp(12px, 2.6vw, 40px);                 /* frame inset from the page sides */
  --cw: clamp(46px, 5.2vw, 76px);                 /* corner width */
  --ch: calc(var(--cw) * 1.324);                  /* corner height (614 x 813) */
  --gp: calc(var(--cw) * .069);                   /* gap between a rule and a corner */
  --rw: max(1.2px, calc(var(--cw) * .0207));      /* rule width */
  --ax: calc(var(--cw) * .0269 - var(--rw) / 2);  /* vertical rule offset */
  --ay: calc(var(--cw) * .092 - var(--rw) / 2);   /* horizontal rule offset */
  --frame-t: calc(var(--fx) + 8px);
  --frame-b: calc(var(--fx) + 8px);
}
.fade-top { --frame-t: calc(var(--fade) + 24px); }
.fade-bottom { --frame-b: calc(var(--fade) + 24px); }

.wrapper::after, .foot::after,
.wrapper.joined-top::after, .wrapper.joined-bottom::after,
.wrapper.joined-bottom:not(.joined-top)::after, .wrapper.joined-top.joined-bottom::after {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  left: var(--fx); right: var(--fx); top: var(--frame-t); bottom: var(--frame-b);
  border: 0;
  background:
    var(--img-corner-book-tl) left top / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-tr) right top / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-bl) left bottom / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-br) right bottom / var(--cw) var(--ch) no-repeat,
    linear-gradient(#7a0000, #7a0000) left calc(var(--cw) + var(--gp)) top var(--ay) / calc(100% - 2 * (var(--cw) + var(--gp))) var(--rw) no-repeat,
    linear-gradient(#7a0000, #7a0000) left calc(var(--cw) + var(--gp)) bottom var(--ay) / calc(100% - 2 * (var(--cw) + var(--gp))) var(--rw) no-repeat,
    linear-gradient(#7a0000, #7a0000) left var(--ax) top calc(var(--ch) + var(--gp)) / var(--rw) calc(100% - 2 * (var(--ch) + var(--gp))) no-repeat,
    linear-gradient(#7a0000, #7a0000) right var(--ax) top calc(var(--ch) + var(--gp)) / var(--rw) calc(100% - 2 * (var(--ch) + var(--gp))) no-repeat;
}
/* text stays inside the frame */
.wrapper > .inner, .foot > .inner { padding-left: max(var(--gutter), calc(var(--fx) + 24px)); padding-right: max(var(--gutter), calc(var(--fx) + 24px)); }
.wrapper:not(.fade-top) { padding-top: calc(var(--section) + var(--fx)); }
.wrapper:not(.fade-bottom) { padding-bottom: calc(var(--section) + var(--fx)); }

/* =====================================================================
   Top bar, after the Universe Wiki: deep red, brass key-fret band
   ===================================================================== */
:root {
  --bar-h: 56px; --band: 12px;
  --fretband: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='12' viewBox='0 0 16 12'%3E%3Cpath d='M0 10.5H12.5V1.5H3.5V7.5H9.5V4.5H6.5M12.5 10.5H16' fill='none' stroke='%23c9a54e' stroke-width='1.4'/%3E%3C/svg%3E");
}
html { scroll-padding-top: calc(var(--bar-h) + var(--band) + 8px); }
.bar, .bar.is-solid {
  height: calc(var(--bar-h) + var(--band) + env(safe-area-inset-top)); padding-bottom: var(--band);
  background: linear-gradient(180deg, #7a0606 0, #6a0000 70%, #5a0000 100%);
  box-shadow: 0 2px 8px rgba(52, 20, 10, .35);
}
.bar::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--band); background: #4c0000 var(--fretband) repeat-x left center / 16px 12px; border-top: 1px solid #c9a54e; border-bottom: 1px solid #c9a54e; }
.bar__home, .bar.is-solid .bar__home { opacity: 1; pointer-events: auto; display: inline-flex; align-items: center; gap: var(--s3); text-decoration: none; color: #f8ecd0; min-height: 48px; }
.bar__seal { width: 34px; height: 34px; flex: none; border-radius: 3px; padding: 2px; background: #f8ecd0 url("../assets/img/seal.webp") center / 28px no-repeat; box-shadow: 0 0 0 1px #c9a54e; }
.bar__name { font: 700 clamp(17px, 1.6vw, 22px)/1 var(--caps); letter-spacing: .01em; white-space: nowrap; text-shadow: 0 1px 0 rgba(0, 0, 0, .25); }
.bar__home:hover .bar__name { color: #fff; }
.bar__nav a, .bar.is-solid .bar__nav a { color: #f8ecd0; text-shadow: none; position: relative; }
.bar__nav a::after { content: ""; position: absolute; left: var(--s3); right: var(--s3); bottom: 4px; height: 2px; background: #e2c47a; transform: scaleX(0); transition: transform var(--t) var(--ease); }
.bar__nav a:hover, .bar.is-solid .bar__nav a:hover, .bar__nav a.is-active, .bar.is-solid .bar__nav a.is-active { color: #fff; text-shadow: none; letter-spacing: .2em; }
.bar__nav a:hover::after, .bar__nav a.is-active::after { transform: scaleX(1); }
.bar__menu, .bar.is-solid .bar__menu {
  height: 40px; min-height: 40px; padding: 0 var(--s4); border: 1.5px solid #c9a54e; border-radius: 6px;
  color: #f8ecd0; text-shadow: none; font-family: var(--caps); letter-spacing: .12em;
}
.bar__menu .icon { color: #e2c47a; }
.bar__menu:hover, .bar.is-solid .bar__menu:hover { background: rgba(248, 236, 208, .12); border-color: #e2c47a; color: #fff; }
.bar :focus-visible { outline-color: #e2c47a; }
@media (max-width: 420px) { .bar__name { font-size: 16px; } }
.menu { padding-top: calc(var(--bar-h) + var(--band)); }
.banner { padding-top: calc(var(--bar-h) + var(--band) + clamp(8px, 3vh, 40px)); }

/* =====================================================================
   Back to top: a red seal-like button, bottom right, after the cover
   ===================================================================== */
.to-top {
  position: fixed; z-index: 40; right: max(16px, env(safe-area-inset-right)); bottom: calc(16px + env(safe-area-inset-bottom));
  width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  background: linear-gradient(180deg, #7a0606, #5a0000); color: #f8ecd0; border: 1.5px solid #c9a54e;
  box-shadow: 0 4px 14px rgba(40, 15, 5, .35);
  opacity: 0; transform: translateY(12px); pointer-events: none;
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease), background-color var(--t) var(--ease);
}
.to-top.is-shown { opacity: 1; transform: none; pointer-events: auto; }
.to-top:hover { background: linear-gradient(180deg, #8a1010, #6a0000); border-color: #e2c47a; }
.to-top:active { transform: scale(.94); }
.to-top .icon { width: 22px; height: 22px; color: #e2c47a; }
@media (min-width: 700px) { .to-top { right: 24px; bottom: 24px; } }

/* =====================================================================
   Round 9
   ===================================================================== */
/* content never crosses a frame: it starts below the top corners and ends above the bottom ones */
.wrapper, .wrapper:not(.fade-top), .wrapper.fade-top { padding-top: calc(var(--frame-t) + var(--ch) + 32px); }
.wrapper, .wrapper:not(.fade-bottom), .wrapper.fade-bottom { padding-bottom: calc(var(--frame-b) + var(--ch) + 32px); }
.foot.fade-top { padding-top: calc(var(--frame-t) + var(--ch) + 24px); }
.foot { padding-bottom: calc(var(--frame-b) + var(--ch) + 16px); }
/* the tilted wall leans past its own box; give it room */
.scenes .wall { margin-bottom: clamp(24px, 4vw, 56px); }
.scenes .inner { padding-left: max(var(--gutter), calc(var(--fx) + 40px)); padding-right: max(var(--gutter), calc(var(--fx) + 40px)); }

/* cover, as on the first Lin & Lang site: full screen, a large crest centred over the art */
.banner { align-items: center; background: none; padding-bottom: calc(var(--s7) + env(safe-area-inset-bottom)); }
.banner__inner { min-height: 0; align-content: center; }
.crest { width: clamp(280px, 27vw, 560px); }
@media (max-aspect-ratio: 4/5) { .crest { width: min(66vw, 320px); } }
.banner::before { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(34% 46% at 50% 46%, rgba(255, 244, 225, .22), rgba(255, 244, 225, 0) 100%); }
.banner__next { color: #fff; }

/* factions: the people first, the mark beside the name */
.faction .faction__row { width: 100%; max-width: 440px; height: auto; object-fit: contain; margin: 0 auto var(--s3); filter: drop-shadow(0 6px 10px rgba(60, 35, 15, .18)); }
.faction h3 { display: inline-flex; align-items: center; gap: var(--s2); }
.faction h3 .faction__mark { width: 30px; height: 30px; margin: 0; object-fit: contain; filter: none; }

/* from the world */
.things { display: grid; gap: var(--s7) var(--s6); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .things { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; } }
.thing { display: grid; justify-items: center; gap: var(--s2); text-align: center; }
.thing img { width: 100%; max-width: 420px; height: clamp(160px, 18vw, 240px); object-fit: contain; margin-bottom: var(--s3); filter: drop-shadow(0 6px 10px rgba(60, 35, 15, .18)); }
.thing h3 { font: 500 clamp(19px, 2vw, 23px)/1.2 var(--caps); letter-spacing: .12em; text-transform: uppercase; color: #8a1010; }
.thing p { color: var(--cream-2); max-width: 32ch; }
.world { --wm: var(--img-wm-steam-tram); }

/* cover: the crest keeps its centred place; a cream outline and halo make it read on any part of the painting */
.crest__aura, .crest__aura--large { display: none; }
.crest::before { content: ""; position: absolute; inset: -18% -16%; z-index: 0; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255, 247, 230, .82), rgba(255, 247, 230, .5) 55%, rgba(255, 247, 230, 0) 100%); }
.crest__logo { filter: drop-shadow(0 0 1px #fff7e6) drop-shadow(0 0 1px #fff7e6) drop-shadow(0 0 6px rgba(255, 247, 230, .9)) drop-shadow(0 2px 3px rgba(60, 20, 10, .35)); }
/* contact columns: three now that the email is gone */
@media (min-width: 1100px) { #infos .infos { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* halo sits behind the logo block only; the vertical title relies on its fine cream outline */
.crest::before { inset: -14% -14% 38% -14%; background: radial-gradient(closest-side, rgba(255, 247, 230, .7), rgba(255, 247, 230, .38) 55%, rgba(255, 247, 230, 0) 100%); }
.crest__logo { filter: drop-shadow(0 0 1px #fff7e6) drop-shadow(0 0 1.5px #fff7e6) drop-shadow(0 0 4px rgba(255, 247, 230, .95)) drop-shadow(0 0 10px rgba(255, 247, 230, .55)) drop-shadow(0 2px 3px rgba(60, 20, 10, .35)); }

/* =====================================================================
   Round 12: multiply blend for sheet art, About page
   ===================================================================== */
/* sheet art keeps its white; multiply turns white into the paper, so no holes show */
.thing img, .faction .faction__row { mix-blend-mode: multiply; filter: none; }
.thing img { height: clamp(170px, 19vw, 250px); }
.things { row-gap: clamp(48px, 6vw, 72px); }
.about__text { max-width: 720px; margin: 0 auto; display: grid; gap: var(--s4); text-align: center; font-size: 1.12em; line-height: 1.75; color: var(--cream-2); }
.about { --wm: var(--img-wm-paper-crane); }
.soundtrack { --wm: var(--img-wm-plum-branch); }
.credits { --wm: var(--img-wm-kite); }
.scenes { --wm: var(--img-wm-sky-lanterns); }
.theme { --wm: var(--img-wm-teahouse); }
#infos { --wm: var(--img-wm-lao-cart); }
/* when GSAP runs, it owns the reveal motion */
html.gsap .reveal { opacity: 1; transform: none; transition: none; }
/* multiply needs the paper as its backdrop: the content layer must not isolate itself */
.wrapper > .inner, .foot > .inner { z-index: auto; }
.wrapper::before, .wrapper::after, .foot::before, .foot::after { z-index: -1; }
/* character busts on paper: multiply too, so white gaps inside a cut-out (Yu's hat, beads) take the paper colour */
.wrapper .who__art img { mix-blend-mode: multiply; }

/* =====================================================================
   Round 13
   ===================================================================== */
/* every section title is red, as in the book */
.wrapper .head h2, .foot .head h2 { color: #8a1010; }

/* factions: one large row each, emblem centred above the name, text under it */
.factions .infos, .factions .infos--three { grid-template-columns: minmax(0, 1fr) !important; gap: clamp(56px, 7vw, 96px); }
.faction { justify-items: center; text-align: center; gap: var(--s3); }
.faction .faction__row { width: 100%; max-width: 980px; margin: 0 auto var(--s4); }
.faction > .faction__mark { width: clamp(64px, 7vw, 96px); height: auto; margin: 0; object-fit: contain; filter: none; }
.faction h3 { display: block; font-size: clamp(22px, 2.6vw, 30px); margin-top: var(--s1); }
.faction p { max-width: 60ch; font-size: 1.05em; }

/* Lin and Lang stand beside the story */
.tale__duo { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; gap: var(--s4); }
.tale__who { width: clamp(140px, 30vw, 200px); height: auto; mix-blend-mode: multiply; }
.tale__who--lang { order: -1; }
.tale__duo .tale__text { order: 0; }
@media (max-width: 899px) {
  .tale__duo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tale__duo .tale__text { grid-column: 1 / -1; }
  .tale__who--lin { order: -2; justify-self: end; }
  .tale__who--lang { order: -1; justify-self: start; }
}
@media (min-width: 900px) {
  .tale__duo { grid-template-columns: minmax(160px, 1fr) minmax(0, 3fr) minmax(160px, 1fr); align-items: center; gap: var(--s6); }
  .tale__who { width: 100%; max-width: 240px; }
  .tale__who--lin { order: 0; }
  .tale__who--lang { order: 2; }
  .tale__duo .tale__text { order: 1; }
  .page { max-width: 1160px; }
}

/* the About plate */
.about__plate { max-width: 960px; margin: var(--s7) auto 0; }
.about__plate img { width: 100%; height: auto; display: block; }

/* =====================================================================
   Round 14: living paintings, more ink, creatures and robots
   ===================================================================== */
/* moving layers over the paintings (built by site.js; seen only through their window) */
.fx { position: absolute; inset: -10% 0; pointer-events: none; overflow: hidden; will-change: transform; }
.fx i { position: absolute; display: block; animation-play-state: paused; }
.is-live .fx i { animation-play-state: running; }
/* sun motes: small warm specks that rise and sway */
.fx--motes i { width: var(--s, 4px); height: var(--s, 4px); border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 238, 190, .95), rgba(255, 214, 140, .35) 45%, rgba(255, 214, 140, 0) 70%);
  animation: fxRise var(--d, 18s) cubic-bezier(.45, 0, .55, 1) var(--w, 0s) infinite; opacity: 0; }
/* sky lanterns: a warm paper glow that floats up slowly, with a slight sway */
.fx--lanterns i { width: var(--s, 10px); height: calc(var(--s, 10px) * 1.3); border-radius: 40% 40% 30% 30%;
  background: radial-gradient(60% 55% at 50% 60%, #ffe6a8, #ffb050 55%, #e2702a 100%);
  box-shadow: inset 0 calc(var(--s, 10px) * -.12) 0 rgba(120, 30, 10, .55), 0 0 calc(var(--s, 10px) * 1.8) calc(var(--s, 10px) * .45) rgba(255, 170, 70, .5);
  animation: fxLantern var(--d, 30s) cubic-bezier(.45, 0, .55, 1) var(--w, 0s) infinite; opacity: 0; }
/* mist: wide soft banks that drift across */
.fx--mist i { width: var(--s, 50vw); height: calc(var(--s, 50vw) * .28); border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 246, 232, .55), rgba(255, 246, 232, .22) 55%, rgba(255, 246, 232, 0));
  animation: fxDrift var(--d, 60s) cubic-bezier(.45, 0, .55, 1) var(--w, 0s) infinite alternate; }
/* leaves: small red leaves that fall on a swaying path */
.fx--leaves i { width: var(--s, 12px); height: calc(var(--s, 12px) * .62); border-radius: 0 85% 0 85%;
  background: linear-gradient(135deg, #c8361e, #8e1a12); opacity: 0;
  animation: fxFall var(--d, 16s) linear var(--w, 0s) infinite; }
@keyframes fxRise {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  15% { opacity: var(--o, .8); }
  50% { transform: translate3d(var(--x, 30px), -45vh, 0); }
  85% { opacity: var(--o, .8); }
  100% { transform: translate3d(calc(var(--x, 30px) * -.4), -90vh, 0); opacity: 0; }
}
@keyframes fxLantern {
  0% { transform: translate3d(0, 0, 0) rotate(-3deg); opacity: 0; }
  12% { opacity: var(--o, .9); }
  50% { transform: translate3d(var(--x, 20px), -55vh, 0) rotate(3deg); }
  88% { opacity: var(--o, .9); }
  100% { transform: translate3d(calc(var(--x, 20px) * .3), -110vh, 0) rotate(-2deg) scale(.7); opacity: 0; }
}
@keyframes fxDrift { from { transform: translate3d(-12vw, 0, 0); } to { transform: translate3d(12vw, -2vh, 0); } }
@keyframes fxFall {
  0% { transform: translate3d(0, 0, 0) rotate(0); opacity: 0; }
  8% { opacity: .9; }
  25% { transform: translate3d(var(--x, 40px), 28vh, 0) rotate(120deg); }
  50% { transform: translate3d(calc(var(--x, 40px) * -.5), 56vh, 0) rotate(220deg); }
  75% { transform: translate3d(var(--x, 40px), 84vh, 0) rotate(330deg); }
  92% { opacity: .9; }
  100% { transform: translate3d(0, 112vh, 0) rotate(420deg); opacity: 0; }
}
/* the cover painting breathes very slowly */
.banner .win__img img { animation: coverBreath 34s cubic-bezier(.45, 0, .55, 1) infinite alternate; transform-origin: 50% 60%; }
@keyframes coverBreath { from { transform: scale(1); } to { transform: scale(1.045) translate3d(-.6%, -.4%, 0); } }

/* a second, fainter ink-wash picture on the other side of a page; it drifts slower than the page */
.ink { position: absolute; z-index: -1; pointer-events: none; width: min(30vw, 360px); aspect-ratio: 1;
  background: var(--ink) center / contain no-repeat; opacity: .2; mix-blend-mode: multiply;
  transform: translate3d(0, var(--inky, 0px), 0); }
.ink--creatures { --ink: url("../assets/img/wm-creatures.webp"); left: 4%; top: 22%; }
.ink--ornithopter { --ink: var(--img-wm-ornithopter); right: 3%; top: 8%; }
.ink--rice-terraces { --ink: url("../assets/img/wm-rice-terraces.webp"); left: 3%; bottom: 14%; }
.ink--cha-cha { --ink: url("../assets/img/wm-cha-cha.webp"); right: 4%; bottom: 30%; }
.ink--city-gate { --ink: url("../assets/img/wm-city-gate.webp"); right: 3%; bottom: 8%; }
.ink--nyao { --ink: url("../assets/img/wm-nyao.webp"); left: 4%; bottom: 10%; }
.ink--boats { --ink: url("../assets/img/wm-boats.webp"); right: 4%; top: 30%; }
@media (max-width: 899px) { .ink { display: none; } }
/* the page watermark drifts too (set by site.js) */
.wrapper::before, .foot::before { transform: translate3d(0, var(--wmy, 0px), 0); }

/* section ornaments draw themselves outward from the centre */
.head::after { transition: clip-path .6s cubic-bezier(.2, .7, .2, 1); }
html.gsap .head:not(.is-drawn)::after { clip-path: inset(0 50% 0 50%); }
html.gsap .head.is-drawn::after { clip-path: inset(0 0 0 0); }

/* storybook vignettes: soft gouache spots, on the paper with multiply */
.spot { display: block; width: 100%; height: auto; mix-blend-mode: multiply; }
.tailpiece { width: clamp(180px, 22vw, 280px); margin: clamp(48px, 6vw, 80px) auto 0; }
.about__body { display: grid; gap: var(--s6); justify-items: center; }
.spot--about { width: clamp(200px, 50vw, 300px); }
@media (min-width: 900px) {
  .about__body { grid-template-columns: minmax(0, 300px) minmax(0, 620px); justify-content: center; align-items: center; gap: var(--s7); }
  .about__body .about__text { text-align: left; margin: 0; }
}

/* creatures and robots of the world: one row each, the art sits on the paper */
.kin { margin-top: clamp(72px, 9vw, 120px); text-align: center; }
.kin__title { font: 500 clamp(22px, 2.6vw, 30px)/1.2 var(--caps); letter-spacing: .14em; text-transform: uppercase; color: #8a1010; }
.kin__title::after { content: ""; display: block; width: min(220px, 60%); aspect-ratio: 1000 / 102; margin: var(--s3) auto 0; background: var(--img-ornament-red) center / contain no-repeat; opacity: .75; }
.kin__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s7) var(--s5); margin-top: var(--s7); }
@media (min-width: 700px) { .kin__row { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .kin__row { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--s6) var(--s4); } }
.kin__one { display: grid; justify-items: center; align-content: start; gap: var(--s2); }
.kin__one img { width: auto; max-width: 100%; height: clamp(110px, 11vw, 150px); object-fit: contain; mix-blend-mode: multiply; transform-origin: 50% 100%; }
.kin__one h4 { margin-top: var(--s2); font: 500 clamp(17px, 1.6vw, 20px)/1.2 var(--caps); letter-spacing: .12em; text-transform: uppercase; color: #8a1010; }
.kin__one p { margin: 0; color: var(--cream-2); font-size: .94em; line-height: 1.55; max-width: 24ch; }
.kin__one h4 { margin-bottom: 0; }
/* idle: each one breathes in its own time (overlapping action); a hover lifts it with a little overshoot */
.kin__one img { animation: kinIdle var(--idle, 4.6s) cubic-bezier(.45, 0, .55, 1) infinite; }
.kin__one:nth-child(2) img { --idle: 5.3s; animation-delay: -1.2s; }
.kin__one:nth-child(3) img { --idle: 4.1s; animation-delay: -2.4s; }
.kin__one:nth-child(4) img { --idle: 5.8s; animation-delay: -.6s; }
.kin__one:nth-child(5) img { --idle: 4.9s; animation-delay: -3.1s; }
.kin__one:nth-child(6) img { --idle: 5.5s; animation-delay: -1.8s; }
@keyframes kinIdle { 0%, 100% { transform: translate3d(0, 0, 0) scale(1, 1); } 50% { transform: translate3d(0, -4px, 0) scale(.99, 1.015); } }
@keyframes kinHop { 0% { transform: translate3d(0, 0, 0); } 35% { transform: translate3d(0, -12px, 0) rotate(-3deg) scale(1.04); } 70% { transform: translate3d(0, 1px, 0) scale(1.02, .98); } 100% { transform: translate3d(0, -6px, 0) rotate(-1.5deg) scale(1.03); } }
.kin__one:hover img { animation: kinHop .8s cubic-bezier(.34, 1.2, .64, 1) forwards; }

/* soundtrack: on hover the cover lifts, a ripple leaves the play button and the ink bars play */
.track .yt { transition: transform .45s cubic-bezier(.34, 1.3, .64, 1), box-shadow .45s ease; }
.track:hover .yt { transform: translate3d(0, -6px, 0) rotate(-.6deg); box-shadow: 0 18px 30px rgba(70, 30, 10, .28); }
.track .yt__play::after { content: ""; position: absolute; inset: -2px; border-radius: 50%; border: 2px solid rgba(255, 236, 200, .9); opacity: 0; pointer-events: none; }
.track:hover .yt__play::after { animation: ripple 1.6s cubic-bezier(.2, .6, .35, 1) infinite; }
@keyframes ripple { from { transform: scale(1); opacity: .9; } to { transform: scale(2.2); opacity: 0; } }
.eq { position: absolute; left: 12px; bottom: 10px; z-index: 2; display: flex; align-items: flex-end; gap: 3px; height: 18px; opacity: 0; transition: opacity .35s ease; pointer-events: none; }
.eq i { width: 3px; height: 100%; background: #f8ecd0; border-radius: 1px; transform-origin: 50% 100%; transform: scaleY(.25); box-shadow: 0 0 4px rgba(0, 0, 0, .5); }
.track:hover .eq, .track:focus-within .eq { opacity: 1; }
.track:hover .eq i, .track:focus-within .eq i { animation: eq var(--eq, 1.1s) cubic-bezier(.45, 0, .55, 1) var(--eqd, 0s) infinite alternate; }
.eq i:nth-child(2) { --eq: .9s; --eqd: -.3s; }
.eq i:nth-child(3) { --eq: 1.3s; --eqd: -.7s; }
.eq i:nth-child(4) { --eq: .8s; --eqd: -.2s; }
.eq i:nth-child(5) { --eq: 1.2s; --eqd: -.5s; }
@keyframes eq { from { transform: scaleY(.2); } to { transform: scaleY(1); } }
.track h3 { transition: color .3s ease, letter-spacing .4s ease; }
.track:hover h3 { color: #8a1010; letter-spacing: .14em; }
.yt.is-loading .eq, .yt:has(iframe) .eq { display: none; }

@media (prefers-reduced-motion: reduce) {
  .fx { display: none; }
  .banner .win__img img, .kin__one img, .kin__one:hover img { animation: none; }
  .head::after { transition: none; }
  .wrapper::before, .foot::before, .ink { transform: none; }
  .track:hover .yt__play::after, .track:hover .eq i { animation: none; }
  .track:hover .yt { transform: none; }
}

/* =====================================================================
   Round 15: flat faction rows, factions side by side, GSAP owns the motion
   ===================================================================== */
/* faction rows lie flat on the paper: no shadow, no filter (a filter also breaks the multiply into a box) */
.factions .faction img.faction__row,
.factions .faction[data-tone] img.faction__row { filter: none; box-shadow: none; background: none; mix-blend-mode: multiply;
  -webkit-mask-image: linear-gradient(180deg, #000 82%, transparent 100%); mask-image: linear-gradient(180deg, #000 82%, transparent 100%); }
.factions .faction[data-tone] img.faction__mark { filter: none; box-shadow: none; }
/* wide screens: the three factions side by side, emblem large and centred above the name */
@media (min-width: 1100px) {
  .factions .inner { max-width: 1600px; }
  .factions .infos, .factions .infos--three { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: var(--s7) var(--s6); align-items: start; }
  .factions .faction .faction__row { width: 100%; max-width: none; aspect-ratio: 1200 / 467; object-fit: contain; object-position: 50% 100%; margin-bottom: var(--s5); }
  .factions .faction > .faction__mark { width: auto; height: clamp(84px, 7vw, 112px); max-width: 100%; }
  .factions .faction p { max-width: 36ch; }
}
@media (min-width: 2000px) { .factions .inner { max-width: 2000px; } .factions .faction > .faction__mark { height: 128px; } }

/* GSAP owns these movements when it runs (CSS keeps them for the no-script case) */
html.gsap .banner__next { animation: none; }
html.gsap .kin__one img, html.gsap .kin__one:hover img { animation: none; }
html.gsap .who__btn:hover .who__art img, html.gsap .who__btn:active .who__art img { transform: none; }
html.gsap .who__art img { transition: filter var(--t-slow) var(--ease); }

/* =====================================================================
   Round 16: one frame per run of joined pages, the book frame on the carousel
   ===================================================================== */
/* pages that join share ONE frame: corners only at the top and the bottom of the whole run,
   the side rules run on through every join */
.wrapper.joined-top, .foot.joined-top { --frame-t: 0px; }
.wrapper.joined-bottom { --frame-b: 0px; }
.wrapper.joined-bottom:not(.joined-top)::after {
  background:
    var(--img-corner-book-tl) left top / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-tr) right top / var(--cw) var(--ch) no-repeat,
    linear-gradient(#7a0000, #7a0000) left calc(var(--cw) + var(--gp)) top var(--ay) / calc(100% - 2 * (var(--cw) + var(--gp))) var(--rw) no-repeat,
    linear-gradient(#7a0000, #7a0000) left var(--ax) bottom 0 / var(--rw) calc(100% - var(--ch) - var(--gp)) no-repeat,
    linear-gradient(#7a0000, #7a0000) right var(--ax) bottom 0 / var(--rw) calc(100% - var(--ch) - var(--gp)) no-repeat;
}
.wrapper.joined-top:not(.joined-bottom)::after, .foot.joined-top::after {
  background:
    var(--img-corner-book-bl) left bottom / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-br) right bottom / var(--cw) var(--ch) no-repeat,
    linear-gradient(#7a0000, #7a0000) left calc(var(--cw) + var(--gp)) bottom var(--ay) / calc(100% - 2 * (var(--cw) + var(--gp))) var(--rw) no-repeat,
    linear-gradient(#7a0000, #7a0000) left var(--ax) top 0 / var(--rw) calc(100% - var(--ch) - var(--gp)) no-repeat,
    linear-gradient(#7a0000, #7a0000) right var(--ax) top 0 / var(--rw) calc(100% - var(--ch) - var(--gp)) no-repeat;
}
.wrapper.joined-top.joined-bottom::after {
  background:
    linear-gradient(#7a0000, #7a0000) left var(--ax) top 0 / var(--rw) 100% no-repeat,
    linear-gradient(#7a0000, #7a0000) right var(--ax) top 0 / var(--rw) 100% no-repeat;
}
/* no corner at a join, so the words need less room there */
.wrapper.joined-top, .foot.joined-top { padding-top: clamp(32px, 4vw, 64px); }
.wrapper.joined-bottom { padding-bottom: clamp(32px, 4vw, 64px); }
.foot.joined-top { margin-top: -1px; }

/* the feature carousel wears the book frame: book corners, red rules that stop just before each corner */
.slides__track.framed::after {
  --cw: clamp(30px, 3.4vw, 50px);
  --ch: calc(var(--cw) * 1.324);
  --gp: calc(var(--cw) * .069);
  --rw: max(1.2px, calc(var(--cw) * .0207));
  --ax: calc(var(--cw) * .0269 - var(--rw) / 2);
  --ay: calc(var(--cw) * .092 - var(--rw) / 2);
  inset: calc(var(--cw) * -.42); border: 0;
  background:
    var(--img-corner-book-tl) left top / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-tr) right top / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-bl) left bottom / var(--cw) var(--ch) no-repeat,
    var(--img-corner-book-br) right bottom / var(--cw) var(--ch) no-repeat,
    linear-gradient(#7a0000, #7a0000) left calc(var(--cw) + var(--gp)) top var(--ay) / calc(100% - 2 * (var(--cw) + var(--gp))) var(--rw) no-repeat,
    linear-gradient(#7a0000, #7a0000) left calc(var(--cw) + var(--gp)) bottom var(--ay) / calc(100% - 2 * (var(--cw) + var(--gp))) var(--rw) no-repeat,
    linear-gradient(#7a0000, #7a0000) left var(--ax) top calc(var(--ch) + var(--gp)) / var(--rw) calc(100% - 2 * (var(--ch) + var(--gp))) no-repeat,
    linear-gradient(#7a0000, #7a0000) right var(--ax) top calc(var(--ch) + var(--gp)) / var(--rw) calc(100% - 2 * (var(--ch) + var(--gp))) no-repeat;
}
.slides { padding: 0 clamp(14px, 1.6vw, 22px); }

/* factions: clear space between the three columns on wide screens */
@media (min-width: 1100px) {
  .factions .infos, .factions .infos--three { column-gap: clamp(56px, 5vw, 112px); }
}

/* =====================================================================
   Round 17: art printed straight onto the paper, from the first frame.
   A transform, filter, mask, opacity or will-change on a blended picture, on its parents,
   or on a layer under it can lift it onto its own GPU layer, where multiply has nothing
   to blend with and the white shows. None of these touch blended art any more.
   ===================================================================== */
/* busts: flat on white in the file (near-white is pure white, the bottom fades to white) */
.who__art::before { display: none; }
.who__art img, .wrapper .who__art img,
.who__btn:hover .who__art img, .who__btn:active .who__art img,
html.gsap .who__btn:hover .who__art img, html.gsap .who__btn:active .who__art img {
  -webkit-mask-image: none; mask-image: none; filter: none; transform: none; transition: none; mix-blend-mode: multiply;
}
.tale__who { position: relative; mix-blend-mode: multiply; filter: none; transform: none; }
/* faction rows: the bottom fade is in the file now */
.factions .faction img.faction__row, .factions .faction[data-tone] img.faction__row { -webkit-mask-image: none; mask-image: none; }
/* every blended picture moves only by its offsets (top/left), which paint without a new layer */
.who__art img, .thing img, .faction__row, .kin__one img, .spot, .tale__who { position: relative; }
.kin__one img, .kin__one:hover img { animation: none; transform: none; }
/* watermarks drift by their offsets, not by a transform */
.wrapper::before, .foot::before { transform: none; top: var(--wmy, 0px); bottom: calc(var(--wmy, 0px) * -1); }
.ink { transform: none; margin-top: var(--inky, 0px); }

/* =====================================================================
   Round 18: no ink wash shows through the art.
   Multiply lets anything under a picture show through its light parts, so the faint
   ink-wash watermarks printed dots and lines into faces (the "dots" by Lin's head were the
   eyes of the creatures wash). A soft patch of the same fixed paper sits under each blended
   picture: it matches the page paper exactly, hides the wash, and fades out at its edges.
   The patch is a sibling under the picture, never a parent, and carries no filter or transform.
   ===================================================================== */
.who__art::before, .kin__one::before, .thing::before, .faction::before {
  content: ""; display: block; position: absolute; pointer-events: none;
  background: #eadcbf url("../assets/img/paper-tile.webp") center top / 640px repeat fixed;
  -webkit-mask-image: radial-gradient(farthest-side, #000 78%, transparent 100%);
  mask-image: radial-gradient(farthest-side, #000 78%, transparent 100%);
  border-radius: 0; filter: none; opacity: 1; transform: none; transition: none;
}
.who__art::before, .who__btn:hover .who__art::before { inset: -6% -10% -2%; opacity: 1; transform: none; }
.kin__one, .thing, .faction { position: relative; }
.kin__one::before { left: -10%; right: -10%; top: -14px; height: calc(clamp(110px, 11vw, 150px) + 28px); }
.thing::before { left: -4%; right: -4%; top: -16px; height: calc(clamp(170px, 19vw, 250px) + 32px); }
.faction::before { left: -5%; right: -5%; top: -16px; aspect-ratio: 1200 / 500; }
/* the Tale's own wash sits in the middle column, between Lin and Lang */
@media (min-width: 900px) { .wrapper.tale::before { background-position: center 42%; background-size: min(28vw, 360px) auto; } }
/* Lin and Lang beside the story sit in boxes that carry the paper patch; the boxes take the grid places */
.tale__who-box { position: relative; display: block; width: clamp(140px, 30vw, 200px); }
.tale__who-box .tale__who { display: block; width: 100%; max-width: none; height: auto; }
.tale__who-box--lang { order: -1; }
@media (max-width: 899px) {
  .tale__who-box--lin { order: -2; justify-self: end; }
  .tale__who-box--lang { order: -1; justify-self: start; }
}
@media (min-width: 900px) {
  .tale__who-box { width: 100%; max-width: 240px; }
  .tale__who-box--lin { order: 0; }
  .tale__who-box--lang { order: 2; }
}
.spotbox { position: relative; }
.spotbox--about { width: clamp(200px, 50vw, 300px); }
.spotbox--about .spot { width: 100%; }
.tailpiece { position: relative; }
.tale__who-box::before, .tailpiece::before, .spotbox::before {
  content: ""; display: block; position: absolute; pointer-events: none; inset: -8%;
  background: #eadcbf url("../assets/img/paper-tile.webp") center top / 640px repeat fixed;
  -webkit-mask-image: radial-gradient(farthest-side, #000 78%, transparent 100%);
  mask-image: radial-gradient(farthest-side, #000 78%, transparent 100%);
}
/* the character dialog shows the bust on its own piece of rice paper, printed with multiply
   (the blend happens inside the dialog's panel, so nothing can lift it off its paper) */
.sheet--char .sheet__art { background: #eadcbf url("../assets/img/paper-tile.webp") center / 520px repeat; box-shadow: inset 0 0 60px rgba(110, 70, 30, .28); }
.sheet--char .sheet__art img { mix-blend-mode: multiply; -webkit-mask-image: none; mask-image: none; }

/* =====================================================================
   Round 15: scroll-driven machines, chapter rail, lore cards, tally
   (after the scroll storytelling of The Virtual Economy, in the book's own look)
   ===================================================================== */
.machines { --wm: var(--img-wm-ornithopter); }

/* ---- a machine page: without WebGL (or with reduced motion) it is a still plate with its words ---- */
.mx { position: relative; margin: 0 auto; max-width: 1240px; padding: 0 var(--gutter); }
.mx__stage { position: relative; display: grid; gap: var(--s5); justify-items: center; text-align: center; }
.mx__poster { width: 100%; max-width: 760px; height: auto; mix-blend-mode: multiply; }
.mx__canvas, .mx__sky, .mx__dots, .mx__hint, .mx__sound, .mx__tags, .mx__lines, .mx__ring { display: none; }
.mx__caps { display: grid; gap: var(--s5); max-width: 640px; }
.mx__kicker { font: 500 13px/1.4 var(--caps); letter-spacing: .2em; text-transform: uppercase; color: #8a1010; }
.mx__cap h3 { font: 500 clamp(24px, 3vw, 36px)/1.15 var(--caps); letter-spacing: .06em; color: #2a1d14; margin: 4px 0 8px; }
.mx__cap p:last-child { color: var(--cream-2); font-size: 1.06em; }
.mx__rule { height: clamp(48px, 8vw, 96px); margin: 0 auto; max-width: 420px; position: relative;
  background: linear-gradient(#7a0000, #7a0000) center / 100% 1px no-repeat; }
.mx__rule::after { content: ""; position: absolute; left: 50%; top: 50%; width: 12px; height: 12px; margin: -6px; background: #eadcbf; border: 1.5px solid #7a0000; transform: rotate(45deg); }

/* ---- the live scene: a tall page, a stage that stays in view while the scroll drives it ---- */
.has-mx .mx:not(.is-static) { max-width: none; padding: 0; height: 430vh; }
.has-mx .mx--bell:not(.is-static) { height: 400vh; }
.has-mx .mx:not(.is-static) .mx__stage {
  position: sticky; top: calc(var(--bar-h) + var(--band));
  height: calc(100vh - var(--bar-h) - var(--band)); height: calc(100svh - var(--bar-h) - var(--band));
  margin: 0 calc(var(--fx) + 4px); display: block; text-align: left; overflow: hidden;
}
.has-mx .mx:not(.is-static) .mx__poster { display: none; }
.has-mx .mx:not(.is-static) .mx__canvas { display: block; position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 900ms var(--ease); }
.has-mx .mx.is-ready .mx__canvas { opacity: 1; }
.has-mx .mx:not(.is-static):not(.is-ready) .mx__stage::after {
  content: "Winding the machine\2026"; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font: 400 15px/1 var(--caps); letter-spacing: .18em; color: var(--cream-3); animation: mxWait 1.6s ease-in-out infinite alternate;
}
@keyframes mxWait { from { opacity: .35; } to { opacity: 1; } }

/* a watercolour sky that comes in once the ornithopter is in the air */
.has-mx .mx:not(.is-static) .mx__sky { display: block; position: absolute; inset: 0; pointer-events: none; opacity: var(--sky, 0); mix-blend-mode: multiply;
  background:
    radial-gradient(60% 46% at 62% 36%, rgba(150, 196, 212, .5), rgba(150, 196, 212, 0) 70%),
    radial-gradient(42% 34% at 30% 62%, rgba(176, 210, 216, .42), rgba(176, 210, 216, 0) 72%); }

/* captions: one at a time, each rises in on a small arc and settles */
.has-mx .mx:not(.is-static) .mx__caps { position: absolute; z-index: 2; left: clamp(20px, 5vw, 80px); top: 50%; width: min(380px, 34%); transform: translateY(-50%); display: block; max-width: none; pointer-events: none; }
.has-mx .mx:not(.is-static) .mx__cap { position: absolute; left: 0; top: 0; width: 100%; transform: translate(-14px, calc(-50% + 22px)) rotate(-.6deg); opacity: 0;
  transition: opacity 520ms var(--ease), transform 900ms cubic-bezier(.34, 1.4, .5, 1); }
.has-mx .mx:not(.is-static) .mx__cap.is-on { opacity: 1; transform: translate(0, -50%); }
.has-mx .mx:not(.is-static) .mx__cap h3 { font-size: clamp(26px, 3.2vw, 44px); }
.has-mx .mx:not(.is-static) .mx__cap p { text-shadow: 0 0 6px #eadcbf, 0 0 14px #eadcbf; }
.has-mx .mx--bell:not(.is-static) .mx__caps { left: auto; right: clamp(20px, 5vw, 80px); text-align: right; }
.has-mx .mx--bell:not(.is-static) .mx__cap { left: auto; right: 0; transform: translate(14px, calc(-50% + 22px)) rotate(.6deg); }
.has-mx .mx--bell:not(.is-static) .mx__cap.is-on { transform: translate(0, -50%); }

/* chapter dots of a scene, and the first hint to scroll */
.has-mx .mx:not(.is-static) .mx__dots { display: flex; gap: 14px; position: absolute; z-index: 2; left: 50%; bottom: 22px; transform: translateX(-50%); }
.mx__dots i { display: block; width: 8px; height: 8px; border: 1.5px solid #8a1010; transform: rotate(45deg); transition: background-color 300ms var(--ease), transform 500ms cubic-bezier(.34, 1.6, .5, 1); }
.mx__dots i.is-on { background: #8a1010; transform: rotate(45deg) scale(1.15); }
.has-mx .mx:not(.is-static) .mx__hint { display: block; position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); font: 400 13px/1 var(--caps); letter-spacing: .24em; text-transform: uppercase; color: var(--cream-3);
  opacity: clamp(0, calc(1 - var(--p, 0) * 30), 1); bottom: 48px; }
.mx__hint::after { content: ""; display: block; width: 1px; height: 26px; margin: 8px auto 0; background: linear-gradient(#8a1010, rgba(138, 16, 16, 0)); animation: mxDrip 1.8s cubic-bezier(.45, 0, .55, 1) infinite; transform-origin: top; }
@keyframes mxDrip { 0% { transform: scaleY(0); opacity: 1; } 70% { transform: scaleY(1); opacity: 1; } 100% { transform: scaleY(1); opacity: 0; } }

/* the bell: name tags with ink leader lines, a ring of ink at each strike, a sound switch */
.has-mx .mx:not(.is-static) .mx__lines { display: block; position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; overflow: visible; }
.mx__lines path { fill: none; stroke: #7a0000; stroke-width: 1.2; stroke-linecap: round; }
.has-mx .mx:not(.is-static) .mx__tags { display: block; position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.mx__tag { position: absolute; left: 0; top: 0; width: 210px; margin: -1.4em 0 0 8px; opacity: 0; transition: opacity 400ms var(--ease);
  font-size: 15px; line-height: 1.4; color: #2a1d14; text-shadow: 0 0 4px #eadcbf, 0 0 10px #eadcbf, 0 0 18px #eadcbf; }
.mx__tag b { display: block; font: 500 16px/1.3 var(--caps); letter-spacing: .12em; text-transform: uppercase; color: #8a1010; }
.mx__tag.is-left { margin-left: -218px; text-align: right; }
.mx__tag.is-on { opacity: 1; }
.has-mx .mx:not(.is-static) .mx__ring { display: block; position: absolute; z-index: 1; width: 12px; height: 12px; margin: -6px 0 0 -6px; pointer-events: none; }
.mx__ring::before, .mx__ring::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid rgba(138, 16, 16, .55); opacity: 0; }
.mx__ring.is-on::before { animation: mxRing 1.8s cubic-bezier(.15, .7, .3, 1) forwards; }
.mx__ring.is-on::after { animation: mxRing 2.2s cubic-bezier(.15, .7, .3, 1) .16s forwards; }
@keyframes mxRing { 0% { transform: scale(1); opacity: .8; border-width: 3px; } 100% { transform: scale(42); opacity: 0; border-width: .2px; } }
.has-mx .mx:not(.is-static) .mx__sound { display: inline-flex; position: absolute; z-index: 4; left: 18px; bottom: 18px; align-items: center; gap: 8px; min-height: 40px; padding: 0 14px;
  border: 1.5px solid #8a1010; border-radius: 6px; background: rgba(234, 220, 191, .85); color: #8a1010; cursor: pointer;
  font: 500 13px/1 var(--caps); letter-spacing: .14em; text-transform: uppercase; }
.mx__sound::before { content: ""; width: 14px; height: 14px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 9h4l5-4v14l-5-4H4z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 9h4l5-4v14l-5-4H4z'/%3E%3C/svg%3E") center / contain no-repeat; }
.mx__sound[aria-pressed="true"] { background: #8a1010; color: #f8ecd0; }
.mx__sound:hover { border-color: #b8860b; }

/* phones: the words sit under the machine, centred */
@media (max-width: 799px) {
  .has-mx .mx:not(.is-static) { height: 360vh; }
  .has-mx .mx--bell:not(.is-static) { height: 340vh; }
  .has-mx .mx:not(.is-static) .mx__stage { margin: 0 6px; }
  .has-mx .mx:not(.is-static) .mx__caps, .has-mx .mx--bell:not(.is-static) .mx__caps { left: 16px; right: 16px; width: auto; top: auto; bottom: 64px; transform: none; text-align: center; }
  .has-mx .mx:not(.is-static) .mx__cap, .has-mx .mx--bell:not(.is-static) .mx__cap { left: 0; right: 0; top: auto; bottom: 0; transform: translateY(18px); }
  .has-mx .mx:not(.is-static) .mx__cap.is-on, .has-mx .mx--bell:not(.is-static) .mx__cap.is-on { transform: none; }
  .has-mx .mx:not(.is-static) .mx__cap h3 { font-size: 24px; }
  .mx__tag { width: 150px; font-size: 13px; margin-left: 6px; }
  .mx__tag b { font-size: 13px; }
  .mx__tag.is-left { margin-left: -156px; }
  .has-mx .mx:not(.is-static) .mx__sound { bottom: auto; top: 12px; left: auto; right: 12px; }
  .has-mx .mx:not(.is-static) .mx__dots, .has-mx .mx:not(.is-static) .mx__hint { display: none; }
}

/* ---- tally: what is made so far, counted from the page ---- */
ul.tally { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s6) var(--s5); max-width: 880px; margin: var(--s7) auto 0; text-align: center; }
@media (min-width: 800px) { .tally { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.tally li { display: grid; gap: 2px; justify-items: center; position: relative; }
@media (min-width: 800px) { .tally li + li::before { content: ""; position: absolute; left: calc(var(--s5) / -2); top: 18%; bottom: 18%; width: 1px; background: rgba(122, 0, 0, .35); } }
.tally__n { font: 500 clamp(46px, 6vw, 80px)/1 var(--serif); color: #8a1010; font-variant-numeric: lining-nums tabular-nums; }
.tally__n.is-done { animation: tallySet 700ms cubic-bezier(.34, 1.8, .5, 1); }
@keyframes tallySet { 0% { transform: scale(1); } 40% { transform: scale(1.08, .94); } 100% { transform: scale(1); } }
.tally__l { font: 400 13px/1.4 var(--caps); letter-spacing: .16em; text-transform: uppercase; color: var(--cream-3); }

/* ---- lore words and their cards ---- */
.lore-word { cursor: help; text-decoration: underline dotted 1px; text-underline-offset: 4px; border-radius: 2px; }
.lore-word:hover { text-decoration-style: solid; }
.lore { position: fixed; z-index: 60; left: 0; top: 0; width: min(330px, calc(100vw - 24px)); display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 12px; align-items: center;
  padding: 12px 14px; color: #2a1d14; font-size: 15px; line-height: 1.45;
  background: #efe2c6 url("../assets/img/paper-tile.webp") center / 420px repeat;
  border: 1px solid rgba(122, 0, 0, .45); border-radius: 3px; box-shadow: 0 10px 28px rgba(40, 20, 8, .35), inset 0 0 30px rgba(110, 70, 30, .2);
  opacity: 0; transform: translateY(8px) scale(.97); transform-origin: var(--arrow, 50%) 100%; transition: opacity 200ms var(--ease), transform 420ms cubic-bezier(.34, 1.5, .5, 1); }
.lore[hidden] { display: none; }
.lore.is-below { transform-origin: var(--arrow, 50%) 0; transform: translateY(-8px) scale(.97); }
.lore.is-open { opacity: 1; transform: none; }
.lore img { width: 84px; height: 84px; object-fit: contain; mix-blend-mode: multiply; }
.lore img.is-wide { grid-column: 1 / -1; width: 100%; height: 92px; object-fit: cover; mix-blend-mode: normal; }
.lore:has(img.is-wide) { grid-template-columns: minmax(0, 1fr); }
.lore b { display: block; font: 500 15px/1.3 var(--caps); letter-spacing: .12em; text-transform: uppercase; color: #8a1010; margin-bottom: 2px; }
.lore p { margin: 0; }
.lore::after { content: ""; position: absolute; left: calc(var(--arrow, 50%) - 6px); bottom: -7px; width: 12px; height: 12px; background: #efe2c6; border-right: 1px solid rgba(122, 0, 0, .45); border-bottom: 1px solid rgba(122, 0, 0, .45); transform: rotate(45deg); }
.lore.is-below::after { bottom: auto; top: -7px; transform: rotate(-135deg); }

/* ---- chapter rail (wide screens) and reading line (phones and tablets) ---- */
.rail { display: none; }
@media (min-width: 1360px) {
  .rail { display: block; position: fixed; z-index: 40; right: 14px; top: 50%; height: min(58vh, 540px); width: 16px; transform: translate(8px, -50%); opacity: 0; pointer-events: none;
    transition: opacity 400ms var(--ease), transform 600ms cubic-bezier(.34, 1.3, .5, 1); }
  .rail.is-shown { opacity: 1; transform: translate(0, -50%); pointer-events: auto; }
  .has-dialog .rail { opacity: 0; pointer-events: none; }
}
.rail__rod { position: absolute; left: 7px; top: 0; bottom: 0; width: 2px; background: rgba(201, 165, 78, .45); box-shadow: 0 0 0 1px rgba(60, 20, 10, .25); }
.rail__rod::before, .rail__rod::after { content: ""; position: absolute; left: -4px; width: 10px; height: 6px; border-radius: 3px; background: linear-gradient(#e2c47a, #9a7426); box-shadow: 0 1px 2px rgba(40, 15, 5, .4); }
.rail__rod::before { top: -6px; }
.rail__rod::after { bottom: -6px; }
.rail__ink { position: absolute; inset: 0; background: #8a1010; transform-origin: 50% 0; transform: scaleY(0); }
.rail__stop { position: absolute; left: 0; top: calc(var(--at, 0) * 100%); width: 16px; height: 16px; margin-top: -8px; display: grid; place-items: center; text-decoration: none; }
.rail__stop::before { content: ""; width: 8px; height: 8px; background: #f3e7cf; border: 1.5px solid #8a1010; transform: rotate(45deg); box-shadow: 0 0 0 2px rgba(40, 15, 5, .2);
  transition: background-color 300ms var(--ease), transform 500ms cubic-bezier(.34, 1.6, .5, 1); }
.rail__stop.is-past::before { background: #8a1010; }
.rail__stop.is-current::before { background: #e2c47a; border-color: #6a0000; transform: rotate(45deg) scale(1.45); }
.rail__name { position: absolute; right: 24px; top: 50%; white-space: nowrap; padding: 5px 10px; border: 1px solid #c9a54e; border-radius: 3px;
  background: linear-gradient(180deg, #7a0606, #5a0000); color: #f8ecd0; font: 500 12px/1 var(--caps); letter-spacing: .16em; text-transform: uppercase;
  opacity: 0; transform: translate(8px, -50%); pointer-events: none; transition: opacity 260ms var(--ease), transform 420ms cubic-bezier(.34, 1.4, .5, 1); }
.rail__stop.is-flash .rail__name, .rail__stop:hover .rail__name, .rail__stop:focus-visible .rail__name { opacity: 1; transform: translate(0, -50%); }
.readline { position: fixed; z-index: 49; left: 0; right: 0; top: calc(var(--bar-h) + var(--band) + env(safe-area-inset-top)); height: 2px; background: linear-gradient(90deg, #c9a54e, #e2c47a);
  transform-origin: 0 50%; transform: scaleX(0); opacity: 0; transition: opacity 300ms var(--ease); pointer-events: none; }
.readline.is-shown { opacity: 1; }
@media (min-width: 1360px) { .readline { display: none; } }
@media (prefers-reduced-motion: reduce) { .mx__cap, .mx__tag, .lore, .rail, .rail__name { transition: none !important; } .mx__hint::after, .tally__n.is-done { animation: none; } }

/* Pi, 20 Oct 2026: the cloud-and-gear bars take the exact title red (the picture is used as a mask) */
.head::after, .kin__title::after {
  background: #8a1010; opacity: 1;
  -webkit-mask: var(--img-ornament-red) center / contain no-repeat;
  mask: var(--img-ornament-red) center / contain no-repeat;
}
/* Pi, 20 Oct 2026: lore words show clearly that they can be hovered */
.lore-word { text-decoration: underline 1.5px dotted; text-underline-offset: 4px; border-radius: 3px;
  transition: background-color 180ms var(--ease), box-shadow 180ms var(--ease); }
.lore-word:hover, .lore-word:focus-visible { text-decoration-style: solid;
  background: color-mix(in srgb, currentColor 16%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 16%, transparent); outline: none; }
.page .glow--teal.lore-word { color: #16705f; }

/* credits: the role words, the ampersands and the footer headings in red (Pi, 26 Oct 2026) */
.credits h3, .credits .amp, .foot h3 { color: #8a1010; }

/* =====================================================================
   Phones and touch tablets (Pi, 26 Oct 2026): the same page with less work in each frame.
   The page head sets .lite for a narrow screen or a touch-only screen; the desktop never gets it.
   ===================================================================== */
/* fixed backgrounds repaint the whole screen on each scroll step: the paper scrolls with the page */
.lite .wrapper, .lite .foot,
.lite .who__art::before, .lite .kin__one::before, .lite .thing::before, .lite .faction::before,
.lite .tale__who-box::before, .lite .tailpiece::before, .lite .spotbox::before { background-attachment: scroll; }
/* the paintings scroll inside their windows (no fixed layers, no slow zoom, no drifting motes) */
.lite .win__img { position: absolute; transform: none; }
.lite .banner .win__img img { animation: none; }
.lite .fx { display: none; }
/* the scene wall lies flat: no 3D tilt and no edge masks */
.lite .wall { perspective: none; }
.lite .tile, .lite .tile:nth-child(n) { transform: none; transform-style: flat; transition: none; }
.lite .wall .tile:nth-child(n):last-child { transform: none; }
.lite .tile .tile__btn, .lite .wall .tile:nth-child(n):last-child .tile__btn { -webkit-mask-image: none; mask-image: none; }
/* the ink-wash watermarks load only when their page comes near */
.lite .wrapper:not(.is-near)::before, .lite .foot:not(.is-near)::before { background-image: none; }

/* the Machines subtitle: "scroll to bring them to life" only where the 3D scene runs (.has-mx); phones and
   reduced-motion users see the still poster, so they get a plain line (Pi, 26 Oct 2026) */
.mx-still { display: none; }
html:not(.has-mx) .mx-live { display: none; }
html:not(.has-mx) .mx-still { display: inline; }

/* phones: smaller files for the corners, the cloud-and-gear bars and the ink-wash watermarks */
.lite {
  --img-corner-book-bl: url("../assets/img/corner-book-bl-110.webp");
  --img-corner-book-br: url("../assets/img/corner-book-br-110.webp");
  --img-corner-book-tl: url("../assets/img/corner-book-tl-110.webp");
  --img-corner-book-tr: url("../assets/img/corner-book-tr-110.webp");
  --img-ornament-red: url("../assets/img/ornament-red-680.webp");
  --img-wm-kite: url("../assets/img/wm-kite-347.webp");
  --img-wm-lang: url("../assets/img/wm-lang-347.webp");
  --img-wm-lao-cart: url("../assets/img/wm-lao-cart-347.webp");
  --img-wm-lin-lang: url("../assets/img/wm-lin-lang-480.webp");
  --img-wm-ornithopter: url("../assets/img/wm-ornithopter-347.webp");
  --img-wm-paper-crane: url("../assets/img/wm-paper-crane-347.webp");
  --img-wm-plum-branch: url("../assets/img/wm-plum-branch-347.webp");
  --img-wm-sky-lanterns: url("../assets/img/wm-sky-lanterns-347.webp");
  --img-wm-steam-guard: url("../assets/img/wm-steam-guard-347.webp");
  --img-wm-steam-tram: url("../assets/img/wm-steam-tram-347.webp");
  --img-wm-teahouse: url("../assets/img/wm-teahouse-347.webp");
  --img-wm-water-wheel: url("../assets/img/wm-water-wheel-347.webp");
}

/* phones: no motion at all. Every part shows at once in its final, still state. */
.lite { scroll-behavior: auto; }
.lite *, .lite *::before, .lite *::after { animation: none !important; transition: none !important; }
html.js.lite body { opacity: 1; }
.lite .reveal { opacity: 1; transform: none; }
.lite .yt:hover .yt__thumb, .lite .yt:hover .yt__play, .lite .track:hover .yt,
.lite .who__btn:hover .who__art img, .lite .tile__btn:hover img, .lite .tile__btn:hover video { transform: none; }
