/* ───────── MOTION LAYER — "cinematic noir 5K" ─────────
   Loaded after style.css on the published site. Switch it off with  motion: false  in js/config.js
   (or build with --classic). Everything is progressive: without JavaScript the classic look stays. */

/* ── 5K: scale the whole page up on very large screens (everything is vector, so it stays razor sharp) ── */
html.mo { --z: 1; }   /* --z = the zoom factor; viewport units (vh/vw) must be divided by it */
@media (min-width: 1800px) { html.mo { zoom: 1.2; --z: 1.2; } }
@media (min-width: 2400px) { html.mo { zoom: 1.55; --z: 1.55; } }
@media (min-width: 3200px) { html.mo { zoom: 2.1; --z: 2.1; } }
@media (min-width: 4400px) { html.mo { zoom: 2.9; --z: 2.9; } }
html.mo body { min-height: calc(100vh / var(--z)); }

html.mo { scroll-behavior: smooth; }
html.mo body { overflow-x: clip; }

/* ── page transitions (browsers that support view transitions) ── */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: .28s ease both mo-page-out; }
::view-transition-new(root) { animation: .5s ease both mo-page-in; }
@keyframes mo-page-out { to { opacity: 0; filter: blur(10px); transform: scale(.985); } }
@keyframes mo-page-in { from { opacity: 0; filter: blur(10px); transform: scale(1.012); } }

/* ── living film grain + slow vignette breathing ── */
html.mo body::after { animation: mo-grain .9s steps(6) infinite; opacity: .085; }
@keyframes mo-grain {
  0% { transform: translate(0, 0); } 17% { transform: translate(-2%, 1%); } 33% { transform: translate(1%, -2%); }
  50% { transform: translate(-1%, 2%); } 67% { transform: translate(2%, 1%); } 83% { transform: translate(-1%, -1%); } 100% { transform: translate(0, 0); }
}
html.mo body::before { background: radial-gradient(720px circle at var(--mx) var(--my), rgba(216, 162, 74, 0.11), transparent 62%); }

/* ── reading progress ── */
.mo-progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 80; transform-origin: 0 50%; transform: scaleX(var(--p, 0)); background: linear-gradient(90deg, #8a5f1f, var(--accent), #f6d58b); box-shadow: 0 0 12px rgba(216, 162, 74, .7); pointer-events: none; }

/* ── glass header that hides on scroll down ── */
html.mo .site-hdr { position: sticky; top: 0; z-index: 70; background: rgba(11, 9, 8, .62); backdrop-filter: blur(16px) saturate(1.2); -webkit-backdrop-filter: blur(16px) saturate(1.2); transition: transform .45s cubic-bezier(.2, .8, .2, 1); }
html.mo .site-hdr.mo-hide { transform: translateY(-101%); }
html.mo .brand svg { transition: transform 1.2s cubic-bezier(.2, .8, .2, 1); }
html.mo .brand:hover svg { transform: rotate(360deg) scale(1.06); }
html.mo nav.main a { position: relative; border-bottom: 0; }
html.mo nav.main a::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px; background: var(--accent); transform: scaleX(0); transform-origin: 0 50%; transition: transform .45s cubic-bezier(.2, .8, .2, 1); }
html.mo nav.main a:hover::after, html.mo nav.main a[aria-current="page"]::after { transform: scaleX(1); }

/* ── custom cursor ring (added next to the normal cursor, never replaces it) ── */
.mo-ring, .mo-dot { position: fixed; top: 0; left: 0; z-index: 90; pointer-events: none; border-radius: 50%; opacity: 0; transition: opacity .3s, width .35s cubic-bezier(.2, .8, .2, 1), height .35s cubic-bezier(.2, .8, .2, 1), background .3s, border-color .3s; }
.mo-ring { width: 38px; height: 38px; margin: -19px 0 0 -19px; border: 1px solid rgba(216, 162, 74, .7); }
.mo-dot { width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; background: var(--accent); }
.mo-ring.on, .mo-dot.on { opacity: 1; }
.mo-ring.hot { width: 74px; height: 74px; margin: -37px 0 0 -37px; background: rgba(216, 162, 74, .1); border-color: var(--accent); }
@media (pointer: coarse) { .mo-ring, .mo-dot { display: none; } }

/* ── reveal on scroll (content is visible by default; only hidden once the script has marked it) ── */
html.mo .mo-rev { opacity: 0; transform: translateY(46px) scale(.975); filter: blur(7px); }
html.mo .mo-rev.mo-in { opacity: 1; transform: none; filter: none; transition: opacity .9s cubic-bezier(.2, .8, .2, 1) var(--d, 0s), transform 1s cubic-bezier(.2, .8, .2, 1) var(--d, 0s), filter .9s ease var(--d, 0s); }

/* score bars fill in, seals count up */
html.mo .bar .fill { transform-origin: 0 50%; transform: scaleX(0); }
html.mo .bar.mo-in .fill, html.mo .mo-done .bar .fill { transform: scaleX(1); transition: transform 1.4s cubic-bezier(.2, .8, .2, 1) .25s; }
html.mo .seal { font-variant-numeric: tabular-nums lining-nums; }

/* ── cards: cursor spotlight + gentle 3D tilt ── */
html.mo .card, html.mo .featured, html.mo .topcat, html.mo .ticket { position: relative; transform-style: preserve-3d; }
html.mo .card::after, html.mo .featured::after, html.mo .topcat::after, html.mo .ticket::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .35s;
  background: radial-gradient(460px circle at var(--sx, 50%) var(--sy, 50%), rgba(216, 162, 74, .16), transparent 62%);
}
html.mo .card:hover::after, html.mo .featured:hover::after, html.mo .topcat:hover::after, html.mo .ticket:hover::after { opacity: 1; }
html.mo .card, html.mo .featured { transition: transform .5s cubic-bezier(.2, .8, .2, 1), border-color .3s, box-shadow .5s; }
html.mo .card:hover, html.mo .featured:hover { box-shadow: 0 30px 80px -30px rgba(216, 162, 74, .28); }
html.mo .card .art, html.mo .featured .art { transition: transform 1.2s cubic-bezier(.2, .8, .2, 1); }
html.mo .card:hover .art, html.mo .featured:hover .art { transform: scale(1.06); }
html.mo .card .art, html.mo .featured .art { overflow: hidden; }

/* ── hero ── */
html.mo .hero { position: relative; min-height: calc(100svh / var(--z) - 70px); display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 3vh 0 6vh; }
html.mo .hero .mask { width: min(52vw, 440px); height: min(52vw, 440px); margin: 0 auto 2.2vh; color: var(--accent); filter: drop-shadow(0 0 48px rgba(216, 162, 74, .28)); }
html.mo .hero .mask svg { width: 100%; height: 100%; overflow: visible; }
.mo-spin { transform-origin: 100px 100px; animation: mo-spin 70s linear infinite; }
.mo-spin-rev { transform-origin: 100px 100px; animation: mo-spin 110s linear infinite reverse; }
@keyframes mo-spin { to { transform: rotate(360deg); } }
.mo-key { animation: mo-breathe 5s ease-in-out infinite; transform-origin: 100px 104px; }
@keyframes mo-breathe { 50% { transform: scale(1.04); } }

html.mo .hero.wrap { max-width: min(1440px, 100%); }
html.mo .hero h1 { font-size: clamp(50px, 9.4vw, 168px); line-height: .92; letter-spacing: -.02em; perspective: 900px; }
html.mo .hero h1 .w { display: inline-block; white-space: nowrap; }
html.mo .hero h1 .ch { display: inline-block; opacity: 0; transform: translateY(.55em) rotateX(-75deg); filter: blur(12px); animation: mo-ch 1.15s cubic-bezier(.2, .9, .2, 1) forwards; animation-delay: calc(var(--i) * 52ms + .35s); transform-origin: 50% 100%; }
@keyframes mo-ch { to { opacity: 1; transform: none; filter: none; } }
html.mo .hero h1 em { animation: mo-glow 5s ease-in-out 2s infinite; }
@keyframes mo-glow { 50% { text-shadow: 0 0 60px rgba(216, 162, 74, .55); } }
html.mo .hero .eyebrow, html.mo .hero .lede { opacity: 0; animation: mo-fade 1.2s ease forwards; }
html.mo .hero .eyebrow { animation-delay: .15s; }
html.mo .hero .lede { animation-delay: 1.6s; max-width: 760px; }
@keyframes mo-fade { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.mo-embers { position: absolute; top: 0; bottom: 0; left: 50%; width: calc(100vw / var(--z)); transform: translateX(-50%); pointer-events: none; z-index: -1; }
.mo-scroll { position: absolute; bottom: 2.4vh; left: 50%; width: 1px; height: 54px; background: linear-gradient(var(--accent), transparent); transform-origin: 0 0; animation: mo-cue 2.4s ease-in-out infinite; }
@keyframes mo-cue { 0% { transform: scaleY(0); opacity: 1; } 55% { transform: scaleY(1); opacity: 1; } 100% { transform: scaleY(1); opacity: 0; } }

/* ── marquee of latest scores ── */
.mo-marquee { position: relative; overflow: hidden; margin: 0 0 70px; padding: 20px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.mo-marquee .track { display: flex; width: max-content; gap: 0; animation: mo-marq 70s linear infinite; }
.mo-marquee:hover .track { animation-play-state: paused; }
.mo-marquee a { display: inline-flex; align-items: baseline; gap: 14px; padding: 0 34px; text-decoration: none; white-space: nowrap; font-family: var(--display); font-style: italic; font-weight: 500; font-size: clamp(28px, 3.4vw, 54px); color: var(--ink); transition: color .3s; }
.mo-marquee a b { font-family: var(--mono); font-style: normal; font-weight: 500; font-size: .42em; letter-spacing: .1em; color: var(--accent); }
.mo-marquee a:hover { color: var(--accent); }
.mo-marquee a::after { content: "✦"; color: var(--dim); font-style: normal; font-size: .5em; margin-left: 34px; }
@keyframes mo-marq { to { transform: translateX(-50%); } }

/* ── review page extras ── */
html.mo .post-cover { overflow: hidden; }
html.mo .post-cover img { transform: translate3d(0, var(--py, 0px), 0) scale(1.14); will-change: transform; }
html.mo .post-head h1 { letter-spacing: -.02em; }
html.mo .section-head h2, html.mo .pagehead h1 { background: linear-gradient(100deg, var(--ink) 20%, #f6d58b 50%, var(--ink) 80%); background-size: 220% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; animation: mo-sheen 9s linear infinite; }
@keyframes mo-sheen { to { background-position: -220% 0; } }
html.mo .stamp { transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
html.mo .stamp:hover { transform: rotate(-1deg) scale(1.08); }

/* ── respect "reduce motion" ── */
html.mo-reduce *, html.mo-reduce *::before, html.mo-reduce *::after { animation: none !important; transition: none !important; }
html.mo-reduce .mo-rev, html.mo-reduce .hero h1 .ch, html.mo-reduce .hero .eyebrow, html.mo-reduce .hero .lede { opacity: 1 !important; transform: none !important; filter: none !important; }
html.mo-reduce .bar .fill { transform: none !important; }
html.mo-reduce .mo-marquee .track { animation: none !important; }
html.mo-reduce .mo-embers, html.mo-reduce .mo-ring, html.mo-reduce .mo-dot, html.mo-reduce .mo-scroll { display: none; }
@media (max-width: 700px) {
  html.mo .hero { min-height: calc(100svh / var(--z) - 120px); }
  html.mo .hero .mask { width: min(64vw, 300px); height: min(64vw, 300px); }
  .mo-marquee a { padding: 0 22px; }
}

html.mo .lightbox img { max-width: calc(96vw / var(--z)); max-height: calc(94vh / var(--z)); }

/* ───────── aerial intro (js/intro.js) ───────── */
html.mo-intro-pending { background: #0a0807; }
html.mo-intro-pending body > *:not(.mo-intro) { visibility: hidden; }
/* the loading mark is drawn by CSS from the very first paint, then handed over when the map is ready */
html.mo-intro-pending::after { content: ""; position: fixed; left: 50%; top: 50%; width: 84px; height: 84px; margin: -66px 0 0 -42px; z-index: 310; pointer-events: none; animation: mo-pulse 2.2s ease-in-out infinite;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200' fill='none' stroke='%23d8a24a' stroke-linejoin='round' stroke-linecap='round'%3E%3Ccircle cx='100' cy='100' r='92' stroke-width='7'/%3E%3Cg transform='translate(100 104) scale(1.45) translate(-100 -104)'%3E%3Cpath d='M55 100C70 82 88 80 100 90C112 80 130 82 145 100C130 105 70 105 55 100Z' fill='%23d8a24a' fill-opacity='.22' stroke-width='5'/%3E%3Cpath d='M55 100C70 106 130 106 145 100C136 122 116 128 100 128C84 128 64 122 55 100Z' stroke-width='5'/%3E%3Ccircle cx='100' cy='104' r='5.5' fill='%23d8a24a' stroke='none'/%3E%3Cpath d='M97.5 108l-3.5 12h12l-3.5-12Z' fill='%23d8a24a' stroke='none'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat; }
html.mo-intro-ready::after { display: none; }
@keyframes mo-pulse { 50% { transform: scale(1.12); opacity: .65; } }
/* nothing on the hidden page may animate while the map is loading / flying (keeps the flight smooth) */
html.mo-intro-pending .hero *, html.mo-intro-pending .mo-marquee .track, html.mo-intro-pending .mo-spin, html.mo-intro-pending .mo-key { animation-play-state: paused !important; }
html.mo-intro-pending body::after { animation: none; }

.mo-intro { position: fixed; inset: 0; z-index: 300; background: #0a0807; overflow: hidden; zoom: calc(1 / var(--z, 1)); }
.mo-intro.bg { z-index: 1; background: transparent; pointer-events: none; }
#mo-map { position: absolute; inset: 0; opacity: 0; transition: opacity 1.6s ease, filter 2.4s ease; }
.mo-intro.ready #mo-map { opacity: 1; }
.mo-intro.bg #mo-map { filter: brightness(.86) saturate(.95); }
/* golden hour: warm dusk haze where the far ground fades out, dark foot for the captions, soft dark corners */
.mo-vig { position: absolute; inset: 0; pointer-events: none; transition: background 2s ease; background: linear-gradient(#2c1708 0%, rgba(150, 78, 26, .42) 12%, rgba(150, 78, 26, 0) 36%), linear-gradient(0deg, rgba(10, 8, 7, .78) 0%, rgba(10, 8, 7, 0) 32%), radial-gradient(ellipse at 50% 55%, transparent 46%, rgba(20, 11, 5, .72) 100%); }
/* behind the landing page: darker centre so the text stays readable, the city shows around the edges */
.mo-intro.bg .mo-vig { background: linear-gradient(rgba(10, 8, 7, .55), rgba(10, 8, 7, .1) 30%, rgba(10, 8, 7, .55)), radial-gradient(ellipse at 50% 46%, rgba(10, 8, 7, .72) 0%, rgba(10, 8, 7, .34) 54%, rgba(10, 8, 7, .04) 100%); }
.mo-intro.bg .mo-skip, .mo-intro.bg .mo-cap, .mo-intro.bg .mo-load { display: none; }
.mo-load { position: absolute; left: 0; right: 0; top: 50%; margin-top: 38px; display: flex; justify-content: center; color: var(--accent); font-family: var(--mono); font-size: 12px; letter-spacing: .22em; text-transform: uppercase; pointer-events: none; transition: opacity .6s; }
.mo-intro.ready .mo-load { opacity: 0; }
.mo-cap { position: absolute; left: 6vw; bottom: 9vh; right: 6vw; color: var(--ink); pointer-events: none; opacity: 0; text-shadow: 0 2px 30px rgba(0, 0, 0, .9); }
.mo-cap.in { animation: mo-cap var(--d, 2.5s) ease both; }
@keyframes mo-cap { 0% { opacity: 0; transform: translateY(20px); filter: blur(10px); } 16% { opacity: 1; transform: none; filter: none; } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-12px); } }
.mo-cap small { display: block; font-family: var(--mono); font-size: 12px; letter-spacing: .26em; text-transform: uppercase; color: var(--accent); min-height: 1em; }
.mo-cap strong { display: block; font-family: var(--display); font-style: italic; font-weight: 500; font-size: clamp(44px, 8vw, 128px); line-height: 1; }
.mo-cap em { display: block; font-family: var(--mono); font-style: normal; font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); margin-top: 10px; min-height: 1em; }
.mo-skip { position: absolute; top: 22px; right: 22px; z-index: 3; background: rgba(10, 8, 7, .55); color: var(--ink); border: 1px solid rgba(236, 229, 216, .3); font-family: var(--mono); font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase; padding: 10px 16px; border-radius: 40px; cursor: pointer; transition: background .25s, color .25s; }
.mo-skip:hover { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.mo-attr { position: absolute; right: 12px; bottom: 8px; font: 10.5px var(--mono); letter-spacing: .04em; color: rgba(236, 229, 216, .4); pointer-events: none; }
/* the page fades in over the living map (no cut) */
html.mo-intro-reveal .site-hdr, html.mo-intro-reveal main, html.mo-intro-reveal .site-ftr { animation: mo-reveal 1.6s ease both; }
@keyframes mo-reveal { from { opacity: 0; } to { opacity: 1; } }
.mo-replay { margin-top: 28px; background: transparent; border: 1px solid rgba(216, 162, 74, .45); color: var(--accent); font-family: var(--mono); font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase; padding: 10px 18px; border-radius: 40px; cursor: pointer; opacity: 0; animation: mo-fade 1s ease 2.4s forwards; transition: background .25s, color .25s; }
.mo-replay:hover { background: var(--accent); color: var(--accent-ink); }
html.mo-reduce .mo-replay { display: none; }
@media (max-width: 700px) { .mo-cap { bottom: 12vh; } .mo-skip { top: 14px; right: 14px; } }
/* big screens: the page is scaled with CSS zoom; the WebGL map must not be (clicks/drag would be offset and the canvas blurry),
   so the map box is counter-zoomed and its pins, popups and buttons are scaled back up by hand */
html.mo #map { --mh: 560px; zoom: calc(1 / var(--z, 1)); height: calc(var(--mh) * var(--z, 1)); }
@media (max-width: 900px) { html.mo #map { --mh: 420px; } }
html.mo #map .gpop .maplibregl-popup-content { zoom: var(--z, 1); }
html.mo #map .maplibregl-ctrl-top-right, html.mo #map .maplibregl-ctrl-bottom-right { zoom: var(--z, 1); }