@font-face { font-family: 'Inter'; src: url(../fonts/Inter-Bold.woff2) format('woff2'); font-weight: 700; font-display: swap; }
:root { --ink03:#020c14; --ink06:#03131c; --ink12:#04161f; --ink24:#08222e; --mute:#2e7384; --soft:#6cb2bb; --text:#a8dbdb;
        --lemon:#f8ee6c; --coral:#ff5a3c; --label:#3f8c9c; color-scheme: dark; }
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; height: 100dvh; background: var(--ink03); color: var(--text); font-family: Inter, system-ui, sans-serif; overflow: hidden; }
.neon { position: relative; height: 0; margin: 0 auto; }
.glyph { position: absolute; }
.neon { width: calc(var(--w) * var(--s)); }
.glyph img { position: absolute; inset: 0; width: 100%; height: 100%; }
.glyph .glow { mix-blend-mode: plus-lighter; opacity: 0; animation: strike 1.1s var(--d) both, breathe 4s calc(var(--d) + 1.1s) infinite; }
.glyph .tube { opacity: 0; animation: strike 1.1s var(--d) both; }
.glyph.flicker .glow, .glyph.flicker .tube { animation: strike 1.1s var(--d) both, flick 3.4s calc(var(--d) + 2s) infinite; }
.glyph.flicker.f2 .glow, .glyph.flicker.f2 .tube { animation: strike 1.1s var(--d) both, flick 4.9s calc(var(--d) + 3.2s) infinite; }
/* the sign's ignition: off, on, a stutter, steady */
@keyframes strike { 0% {opacity:0} 4.5% {opacity:0} 5% {opacity:1} 9.5% {opacity:1} 10% {opacity:.15} 12.5% {opacity:.15} 13% {opacity:1} 100% {opacity:1} }
@keyframes breathe { 0%,100% {opacity:1} 50% {opacity:.86} }
@keyframes flick { 0%,88% {opacity:1} 89% {opacity:.15} 90.5% {opacity:1} 92% {opacity:.25} 93% {opacity:1} 100% {opacity:1} }
.thief { position: absolute; }
.thief img { width: 100%; display: block; }
.thief .lid { position: absolute; background: #000; opacity: 0; animation: blink 5s 3s infinite; }
@keyframes blink { 0%,94% {opacity:0} 95%,97% {opacity:1} 98%,100% {opacity:0} }
.label { font-weight: 700; letter-spacing: .18em; text-transform: uppercase; font-size: clamp(11px, .55vw + 8px, 14px); line-height: 1.7; color: var(--label); }
@media (prefers-reduced-motion: reduce) { .glyph .glow, .glyph .tube, .glyph.flicker .glow, .glyph.flicker .tube, .glyph.flicker.f2 .glow, .glyph.flicker.f2 .tube { animation: none; opacity: 1; } .thief .lid { animation: none; } }

/* Scene, intro pull-back, thief, footer. Sizing is pure CSS (no JS, no layout shift). */
:root {
  --vh: 1vh;
  /* S = min(1.4, vw*0.8/327, vh/640) px per pt */
  --S: min(1.4px, calc(100vw * .8 / 327), calc(calc(100 * var(--vh)) / 640));
  /* thief + the intro's eye target, all derived from the viewport */
  --tw: clamp(40px, 4.5vw, 70px);
  --th: calc(var(--tw) * 400 / 310);
  --ex: calc(16vw + var(--tw) * .785);
  --ey: calc(calc(87 * var(--vh)) - 1px - var(--th) * .645);
  --dx: calc(50vw - var(--ex));
  --dy: calc(calc(50 * var(--vh)) - var(--ey));
}
.world { position: absolute; inset: 0; transform-origin: var(--ex) var(--ey);
  animation: pull 2.8s .8s cubic-bezier(.65,0,.35,1) both; }
@keyframes pull { from { transform: translate(var(--dx), var(--dy)) scale(2.4); } to { transform: none; } }
.stage { position: absolute; left: 0; right: 0; top: 0; bottom: calc(13 * var(--vh)); display: flex; flex-direction: column; align-items: center; justify-content: center; }
.w1, .w2 { --s: var(--S); }
.w3 { --s: calc(var(--S) * .42); }
.gap1 { height: calc(var(--S) * 104); }
.gap2 { height: calc(var(--S) * 92); }
.roof { position: absolute; left: 0; right: 0; bottom: calc(13 * var(--vh)); height: 2px; background: var(--ink24); }
.ground { position: absolute; left: 0; right: 0; bottom: 0; height: calc(13 * var(--vh)); background: var(--ink06); }
.thief { width: var(--tw); bottom: calc(calc(13 * var(--vh)) + 1px); left: 16vw; }
.thief img { height: auto; aspect-ratio: 310 / 400; }
.thief .lid { left: 71%; top: 32%; width: 15%; height: 7%; }
.eyeglow { position: absolute; left: 78.5%; top: 35.5%; width: 0; height: 0; }
.eyeglow::before { content: ''; position: absolute; left: -3em; top: -3em; width: 6em; height: 6em; border-radius: 50%;
  background: radial-gradient(circle, rgba(248,238,108,.35), rgba(248,238,108,0) 60%); mix-blend-mode: plus-lighter;
  font-size: calc(var(--tw) / 10); animation: eyepulse 2.4s ease-in-out infinite; }
@keyframes eyepulse { 50% { opacity: .6; } }
footer { position: absolute; bottom: calc(4.5 * var(--vh)); width: 100%; text-align: center; padding: 0 16px; opacity: 0; animation: fade .4s 3.4s forwards; }
footer b { color: var(--lemon); font-weight: 700; }
@keyframes fade { to { opacity: 1; } }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
/* plus-lighter needs Safari 16.4+ / Chrome 100+; fall back to screen */
@supports not (mix-blend-mode: plus-lighter) {
  .glyph .glow, .eyeglow::before { mix-blend-mode: screen; }
}

/* the thief strolls the roof after the intro: right, turn (mirror, lamp off/on), left, off screen, back in from either side */
.thief.walk { animation: walk 60s 4s ease-in-out infinite; }
/* two leg frames swap while walking; the hi-res standing sprite is used for the intro */
.thief .step { position: absolute; left: 0; top: 0; opacity: 0; }
.thief .wf { position: absolute; inset: 0; }
.thief.walk .wf { animation: wf 60s 4s steps(1, end) infinite; }
.thief.walk .s0 { animation: s0 60s 4s steps(1, end) infinite; }
/* legs only swap while walking; during the 4 stops (turns) he stands on frame 1 */
@keyframes wf { 0% { opacity: 1; } 14% { opacity: 0; } 16% { opacity: 1; } 58% { opacity: 0; } 60% { opacity: 1; } 66% { opacity: 0; } 68% { opacity: 1; } 98% { opacity: 0; } 100% { opacity: 1; } }
@keyframes s0 { 0% { opacity: 0; } 14% { opacity: 1; } 16% { opacity: 0; } 58% { opacity: 1; } 60% { opacity: 0; } 66% { opacity: 1; } 68% { opacity: 0; } 98% { opacity: 1; } 100% { opacity: 0; } }
.thief.walk .base { animation: hide 0s 4s forwards; }
.thief.walk .s1 { animation: step1 .42s 4s steps(1, end) infinite; }
.thief.walk .s2 { animation: step2 .42s 4s steps(1, end) infinite; }
@keyframes hide { to { opacity: 0; } }
@keyframes step1 { 0% { opacity: 1; } 50% { opacity: 0; } }
@keyframes step2 { 0% { opacity: 0; } 50% { opacity: 1; } }
@keyframes walk {
  0%      { transform: translateX(0) scaleX(1); }
  14%     { transform: translateX(28vw) scaleX(1); }
  14.99%  { transform: translateX(28vw) scaleX(1); }
  15%     { transform: translateX(28vw) scaleX(-1); }
  16%     { transform: translateX(28vw) scaleX(-1); }
  34%     { transform: translateX(calc(-16vw - 110%)) scaleX(-1); }
  40%     { transform: translateX(calc(-16vw - 110%)) scaleX(-1); }
  40.01%  { transform: translateX(calc(-16vw - 110%)) scaleX(1); }
  58%     { transform: translateX(50vw) scaleX(1); }
  58.99%  { transform: translateX(50vw) scaleX(1); }
  59%     { transform: translateX(50vw) scaleX(-1); }
  60%     { transform: translateX(50vw) scaleX(-1); }
  66%     { transform: translateX(20vw) scaleX(-1); }
  66.99%  { transform: translateX(20vw) scaleX(-1); }
  67%     { transform: translateX(20vw) scaleX(1); }
  68%     { transform: translateX(20vw) scaleX(1); }
  80%     { transform: translateX(calc(84vw + 110%)) scaleX(1); }
  86%     { transform: translateX(calc(84vw + 110%)) scaleX(1); }
  86.01%  { transform: translateX(calc(84vw + 110%)) scaleX(-1); }
  98%     { transform: translateX(0) scaleX(-1); }
  98.99%  { transform: translateX(0) scaleX(-1); }
  99%     { transform: translateX(0) scaleX(1); }
  100%    { transform: translateX(0) scaleX(1); }
}
@media (prefers-reduced-motion: reduce) { .thief.walk, .thief.walk .base, .thief.walk .wf, .thief.walk .s0, .thief.walk .s1, .thief.walk .s2 { animation: none; } .thief.walk .wf { opacity: 0; } .world { animation: none; } footer { animation: none; opacity: 1; } }

@supports (height: 100dvh) { :root { --vh: 1dvh; } }

/* depth: soft haze behind the sign, light spilling on the roof, vignette */
.haze { position: absolute; inset: -6%; pointer-events: none;
  background: radial-gradient(55% 42% at 50% 38%, rgba(255,90,60,.07), transparent 70%),
              radial-gradient(34% 26% at 50% 50%, rgba(248,238,108,.05), transparent 70%);
  opacity: 0; animation: hazein 2.4s 1.6s ease-out forwards; translate: calc(var(--px, 0) * -3px) calc(var(--py, 0) * -2px); }
@keyframes hazein { to { opacity: 1; } }
.ground { background: linear-gradient(180deg, var(--ink06), #020d15); }
.ground::before { content: ''; position: absolute; left: 20%; right: 20%; top: 0; height: 70%;
  background: radial-gradient(ellipse 50% 100% at 50% 0, rgba(255,90,60,.06), rgba(248,238,108,.025) 45%, transparent 75%);
  opacity: 0; animation: hazein 2.4s 2.2s ease-out forwards; }
body::after { content: ''; position: fixed; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 45%, transparent 55%, rgba(0,0,0,.4)); }

/* parallax (js/parallax.js sets --px/--py in -1..1; far things move less) */
.stage { translate: calc(var(--px, 0) * -6px) calc(var(--py, 0) * -3px); }
.thief { translate: calc(var(--px, 0) * 12px) calc(var(--py, 0) * 2px); }

/* footer: a touch larger, balanced wrap, soft entrance */
footer { text-wrap: balance; animation: fade .9s 3.4s cubic-bezier(.2,.7,.2,1) forwards; }
@keyframes fade { from { opacity: 0; transform: translateY(8px); filter: blur(3px); } to { opacity: 1; transform: none; filter: none; } }
a:focus-visible { outline: 2px solid var(--lemon); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { footer { animation: none; opacity: 1; } .haze, .ground::before { animation: none; opacity: 1; } .stage, .thief, .haze { translate: none; } }

/* footer wrap: one line if it fits; otherwise the lemon part always gets its own line */
.label { display: flex; flex-wrap: wrap; justify-content: center; column-gap: .7em; }
.label .lead { text-wrap: balance; }
.label b { white-space: nowrap; }

/* flashlight beam: a flat, pale cone of light with hard edges (no drawn lamp); switched off while he mirrors */
.beam { position: absolute; left: calc(97% + 5px); top: 50%; width: calc(var(--tw) * 5.8); height: calc(var(--tw) * 4.2); pointer-events: none;
  transform: translateY(-50%); transform-origin: 0 50%; opacity: 0; animation: beamin .9s 3.6s ease-out forwards; }
.beam .cone { position: absolute; inset: 0;
  clip-path: polygon(0 47%, 100% 0, 100% 100%, 0 53%);
  -webkit-mask-image: linear-gradient(90deg, #000 72%, transparent); mask-image: linear-gradient(90deg, #000 72%, transparent);
  background: linear-gradient(90deg, rgba(196,236,240,.26), rgba(196,236,240,.17) 55%, rgba(196,236,240,.09));
  animation: lamp 60s 4s linear infinite; }
@keyframes beamin { to { opacity: 1; } }
/* off just before each mirror turn (at 15, 59, 67, 99 %), back on after */
@keyframes lamp {
  0%, 14%      { opacity: 1; } 14.5%, 15.5% { opacity: 0; } 16%, 58%    { opacity: 1; }
  58.5%, 59.5% { opacity: 0; } 60%, 66%     { opacity: 1; } 66.5%, 67.5% { opacity: 0; }
  68%, 98%     { opacity: 1; } 98.5%, 99.5% { opacity: 0; } 100%        { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .beam { animation: none; opacity: 1; } .beam .cone { animation: none; opacity: 1; } }

/* generated from tools/layout.json */
.w1{--w:306.17}
.w1 .g0{left:calc(-56.2*var(--s));width:calc(178*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:1.5s}
.w1 .g1{left:calc(13.45*var(--s));width:calc(185*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:1.66s}
.w1 .g2{left:calc(90.12*var(--s));width:calc(140.67*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:1.68s}
.w1 .g3{left:calc(122.27*var(--s));width:calc(175.67*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:1.77s}
.w1 .g4{left:calc(189.48*var(--s));width:calc(173*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:1.93s}
.w2{--w:278.72}
.w2 .g0{left:calc(-56.2*var(--s));width:calc(171*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:1.95s}
.w2 .g1{left:calc(6.37*var(--s));width:calc(187*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.11s}
.w2 .g2{left:calc(85*var(--s));width:calc(177.33*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.13s}
.w2 .g3{left:calc(154.01*var(--s));width:calc(181*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.22s}
.w3{--w:779.19}
.w3 .g0{left:calc(-56.2*var(--s));width:calc(185.33*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.7s}
.w3 .g1{left:calc(20.77*var(--s));width:calc(187*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.82s}
.w3 .g2{left:calc(99.4*var(--s));width:calc(205*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.8s}
.w3 .g3{left:calc(195.9*var(--s));width:calc(140.67*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.85s}
.w3 .g4{left:calc(228.05*var(--s));width:calc(186.33*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.97s}
.w3 .g5{left:calc(305.9*var(--s));width:calc(186.33*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:2.95s}
.w3 .g6{left:calc(419.37*var(--s));width:calc(181*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:3s}
.w3 .g7{left:calc(491.9*var(--s));width:calc(187*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:3.12s}
.w3 .g8{left:calc(570.53*var(--s));width:calc(187*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:3.1s}
.w3 .g9{left:calc(649.16*var(--s));width:calc(186.33*var(--s));height:calc(237.33*var(--s));top:calc(-118.665*var(--s));--d:3.15s}
