@charset "UTF-8";

:root {
  color-scheme: dark;
  --black: #080808;
  --white: #f4f4f2;
  --muted: #8e8e8e;
  --surface: #141414;
  --line: #292929;
  --ease: cubic-bezier(.22, .72, .22, 1);
  --mono: ui-monospace, 'SFMono-Regular', Consolas, monospace;
  --arrival: 1;
  font-family: 'DM Sans', Arial, sans-serif;
  font-synthesis: none;
  background: var(--black);
  scroll-behavior: smooth;
}
* { box-sizing: border-box; }
body { margin: 0; color: var(--white); background: var(--black); -webkit-font-smoothing: antialiased; }
button, input { font: inherit; }
button, a { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
button { border: 0; color: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
svg, img { display: block; }
button:disabled { cursor: wait; }
[hidden] { display: none !important; }
::selection { color: #080808; background: #ededed; }
:focus-visible { outline: 2px solid #f3f3f3; outline-offset: 7px; }
em { font: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
[data-icon] { display: inline-flex; align-items: center; justify-content: center; flex: none; }
[data-icon] svg { width: 19px; height: 19px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.skip-link { position: fixed; top: 20px; left: 20px; z-index: 100; padding: 14px 20px; border-radius: 6px; background: #fff; color: #080808; transform: translateY(-160%); }
.skip-link:focus { transform: none; }
.js { --arrival: 0; }
.js:not(.is-ready) :is(.site-chrome, .scene, .nerd-position, .ambient-stage, .voice-wire) { visibility: hidden; }
.js.is-ready { scrollbar-width: none; }
.js.is-ready::-webkit-scrollbar { display: none; }

/* The page starts with actual black. No full-screen coloured wash. */
.site-chrome { position: fixed; z-index: 30; inset: 0 0 auto; height: 100px; padding: 0 4.3vw; display: flex; align-items: center; justify-content: space-between; pointer-events: none; opacity: var(--arrival); }
.site-chrome a, .site-chrome button { pointer-events: auto; }
.small-wordmark { font-size: 22px; font-weight: 650; letter-spacing: -1.2px; display: inline-flex; align-items: start; }
.small-wordmark > span { font: 8px var(--mono); margin: 4px 0 0 5px; color: #9a9a9a; }
.site-chrome nav { display: flex; align-items: center; gap: 22px; }
.index-trigger { background: transparent; display: inline-flex; align-items: center; gap: 13px; font-size: 11px; padding: 11px 0; }
.index-trigger [data-icon] { margin-left: 7px; }
.index-trigger svg { width: 16px; height: 16px; }
.index-trigger:hover, .quiet-link:hover { color: #aaa; }
.motion-toggle { padding: 10px; width: 36px; height: 36px; border-radius: 50%; background: #171717; display: grid; place-items: center; }
.motion-toggle:hover { background: #2b2b2b; }
.motion-bars { display: flex; height: 13px; gap: 3px; align-items: center; }
.motion-bars i { width: 1px; background: #c0c0c0; height: 7px; }
.motion-bars i:nth-child(2) { height: 13px; }
.motion-bars i:nth-child(3) { height: 10px; }
.motion-toggle[aria-pressed="true"] .motion-bars i { height: 2px; }

/* A single procedural light and a single travelling character. */
.ambient-stage { position: fixed; inset: 0; pointer-events: none; z-index: 1; }
.portal { position: absolute; left: 50%; top: 39%; width: min(670px, 69vw); aspect-ratio: 1; transform: translate(-50%, -50%); opacity: 0; }
.portal canvas { width: 100%; height: 100%; display: block; opacity: 0; }
.portal.has-webgl canvas, .portal.has-canvas canvas { opacity: 1; }
.portal.has-webgl .portal-fallback, .portal.has-canvas .portal-fallback { display: none; }
.portal-fallback { position: absolute; inset: 20%; background: #f4f4f0; border-radius: 41% 59% 63% 37% / 44% 43% 57% 56%; filter: blur(13px); box-shadow: -4px 3px 10px #fda4aa55, 5px -3px 11px #99d4eb55, 0 0 37px #ffffff36; }
.voice-wire { position: fixed; z-index: 11; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.voice-wire { color: #d6d6d0; }
.voice-wire path { stroke: currentColor; stroke-width: 1.2; fill: none; stroke-linecap: round; stroke-linejoin: round; }
/* His voice travelling down the cable: short bright pulses while he talks. */
.voice-wire #voice-pulse { stroke: #fff; stroke-width: 2.4; stroke-dasharray: 2 26; opacity: 0; filter: drop-shadow(0 0 3px #fff); transition: opacity 220ms; }
.voice-wire circle { fill: #f2f2ec; filter: drop-shadow(0 0 4px #fff8); }

/* Lines DaNerd says appear word by word, in time with his mouth. */
.has-voice .say-word { display: inline-block; opacity: 0; }
.has-voice.is-said .say-word { opacity: 1; }
.has-voice.is-saying .say-word { animation: say-in 340ms cubic-bezier(.2, .8, .2, 1) var(--say-at, 0ms) both; }
@keyframes say-in {
  from { opacity: 0; transform: translateY(.35em) scale(.96); filter: blur(5px); }
  to { opacity: 1; transform: none; filter: none; }
}
.nerd-position { position: fixed; left: 0; top: 0; width: 240px; height: 190px; z-index: 12; will-change: transform; transform-origin: 50% 50%; color: #0a0a0a; opacity: 0; }
.nerd { width: 100%; height: 100%; display: block; padding: 0; background: transparent; transform-origin: center; color: inherit; }
.nerd svg { width: 100%; height: 100%; overflow: visible; transform-origin: 50% 90%; animation: nerd-breathe 3.8s ease-in-out infinite; }
/* Alive even when still: he breathes, hops when he's happy, fixes his glasses. */
@keyframes nerd-breathe { 50% { transform: scale(1.018, .985); } }
.nerd.is-poked { animation: nerd-poke 460ms cubic-bezier(.3, .7, .3, 1); }
[data-temper="enojado"] .nerd.is-poked { animation: nerd-huff 420ms ease-out; }
@keyframes nerd-poke {
  0% { transform: none; }
  20% { transform: translateY(5px) scale(1.07, .9); }
  50% { transform: translateY(-16px) scale(.96, 1.05) rotate(3deg); }
  78% { transform: translateY(0) scale(1.04, .96); }
  100% { transform: none; }
}
@keyframes nerd-huff {
  0%, 100% { transform: none; }
  15% { transform: translateY(3px) scale(1.06, .92); }
  35% { transform: translateX(-5px) rotate(-3deg); }
  55% { transform: translateX(5px) rotate(3deg); }
  75% { transform: translateX(-2px); }
}
.nerd.is-hopping { animation: nerd-hop 720ms cubic-bezier(.3, .7, .3, 1); }
@keyframes nerd-hop {
  0% { transform: none; }
  18% { transform: translateY(6px) scale(1.08, .9); }
  45% { transform: translateY(-34px) scale(.94, 1.07) rotate(-4deg); }
  70% { transform: translateY(0) scale(1.06, .93); }
  85% { transform: translateY(-5px) scale(.99, 1.01); }
  100% { transform: none; }
}
#nerd-adjust { transform-box: view-box; }

/* ── Moods ─────────────────────────────────────────────────────────────
   Whatever only switches on and off lives here, keyed on the data-* set by
   personality.js and face.js. Shapes that morph are drawn in face.js. */
.nerd-body { display: block; width: 100%; height: 100%; }
[data-temper="feliz"] .nerd-body { animation: mood-bounce .9s ease-in-out infinite alternate; }
[data-temper="enojado"] .nerd-body { animation: mood-seethe 2.6s linear infinite; }
[data-temper="nervioso"] .nerd-body { animation: mood-tremble .14s steps(2) infinite; }
[data-temper="indiferente"] .nerd-body { transform: translateY(6px) rotate(-4deg); transition: transform 500ms var(--ease); }
[data-temper="presumido"] .nerd-body { animation: mood-sway 3.2s ease-in-out infinite alternate; }
[data-temper="sospechoso"] .nerd-body { animation: mood-lean 5s ease-in-out infinite; }
[data-temper="dramatico"] .nerd-body { animation: mood-sigh 4.6s ease-in-out infinite; }
@keyframes mood-bounce { from { transform: translateY(0); } to { transform: translateY(-7px) rotate(1.5deg); } }
@keyframes mood-seethe { 0%, 78%, 100% { transform: none; } 80% { transform: translate(-2px, 1px); } 83% { transform: translate(2px, -1px); } 86% { transform: translate(-2px, 0); } 89% { transform: translate(1px, 1px); } }
@keyframes mood-tremble { 0% { transform: translate(.8px, -.5px); } 100% { transform: translate(-.8px, .6px); } }
@keyframes mood-sway { from { transform: rotate(-4deg); } to { transform: rotate(4deg) translateY(-2px); } }
@keyframes mood-lean { 0%, 100% { transform: translateX(-5px) rotate(-6deg); } 50% { transform: translateX(5px) rotate(5deg); } }
@keyframes mood-sigh { 0%, 100% { transform: none; } 45% { transform: translateY(7px) rotate(2deg) scale(1.02, .97); } }

.nerd-extra { opacity: 0; transition: opacity 250ms; pointer-events: none; transform-box: fill-box; }
.nerd-steam path { fill: none; stroke: currentColor; stroke-width: 4; stroke-linecap: round; transform-box: fill-box; transform-origin: 50% 100%; }
[data-temper="enojado"] .nerd-steam { opacity: 1; }
[data-temper="enojado"] .nerd-steam path { animation: steam-rise 1.3s ease-out infinite; }
[data-temper="enojado"] .nerd-steam path + path { animation-delay: .6s; }
@keyframes steam-rise { 0% { opacity: 0; transform: translateY(8px) scale(.7); } 30% { opacity: .9; } 100% { opacity: 0; transform: translateY(-22px) scale(1.15); } }
.nerd-vein path { fill: none; stroke: #ff5a4f; stroke-width: 4.5; stroke-linecap: round; }
.nerd-vein { transform-origin: 50% 50%; }
[data-temper="enojado"] .nerd-vein { opacity: 1; animation: vein-pulse .8s ease-in-out infinite alternate; }
@keyframes vein-pulse { from { transform: scale(.85); } to { transform: scale(1.12); } }
.nerd-sparkles path { fill: currentColor; transform-box: fill-box; transform-origin: center; }
[data-temper="feliz"] .nerd-sparkles, [data-temper="presumido"] .nerd-sparkles { opacity: 1; }
[data-temper="feliz"] .nerd-sparkles path, [data-temper="presumido"] .nerd-sparkles path { animation: sparkle 1.8s ease-in-out infinite; }
.nerd-sparkles path:nth-child(2) { animation-delay: .6s !important; }
.nerd-sparkles path:nth-child(3) { animation-delay: 1.2s !important; }
@keyframes sparkle { 0%, 100% { transform: scale(0) rotate(0); } 40% { transform: scale(1) rotate(45deg); } 70% { transform: scale(.2) rotate(90deg); } }
.nerd-tear { fill: #9fc3ff; transform-origin: 50% 0; }
[data-temper="dramatico"] .nerd-tear { opacity: 1; animation: tear-fall 3.4s ease-in infinite; }
@keyframes tear-fall { 0%, 30% { transform: translateY(0) scale(0); opacity: 0; } 40% { transform: translateY(0) scale(1); opacity: .95; } 90% { transform: translateY(42px) scale(.8, 1.1); opacity: .9; } 100% { transform: translateY(50px); opacity: 0; } }
.nerd-question { font: 700 36px 'DM Sans', Arial, sans-serif; fill: currentColor; transform-origin: 50% 100%; }
[data-temper="sospechoso"] .nerd-question { opacity: 1; animation: question-bob 2.2s ease-in-out infinite; }
@keyframes question-bob { 0%, 100% { transform: rotate(-8deg); } 50% { transform: translateY(-5px) rotate(10deg); } }

/* Props that depend on the hour (and on luck): a nightcap, a coffee. */
.nerd-cap { transform-origin: 50% 100%; transform: translateY(-40px); transition: opacity 250ms, transform 520ms cubic-bezier(.3, 1.5, .5, 1); }
.cap-body { fill: #2f3d8a; stroke: currentColor; stroke-width: 4; stroke-linejoin: round; }
.cap-dots { stroke: #f4f1c9; stroke-width: 6; stroke-linecap: round; }
.cap-brim, .cap-pom { fill: #f2f2ee; stroke: currentColor; stroke-width: 4; }
[data-prop="cap"] .nerd-cap { opacity: 1; transform: none; }
.nerd-mug { transform-origin: 50% 50%; transform: translateX(30px); transition: opacity 250ms, transform 420ms var(--ease); }
.mug-body { fill: #c8643b; stroke: currentColor; stroke-width: 4; }
.mug-handle, .mug-coffee { fill: none; stroke: currentColor; stroke-width: 4; stroke-linecap: round; }
.mug-steam { fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; opacity: .7; animation: steam-rise 1.6s ease-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
[data-prop="coffee"] .nerd-mug { opacity: 1; transform: none; animation: mug-float 2.8s ease-in-out infinite alternate; }
[data-prop="coffee"] .nerd-mug.is-sipping { animation: mug-sip 1.5s cubic-bezier(.4, 0, .3, 1); }
@keyframes mug-float { to { transform: translateY(-5px) rotate(3deg); } }
@keyframes mug-sip { 0%, 100% { transform: none; } 30%, 62% { transform: translate(-76px, 8px) rotate(-32deg); } }

/* In Marble Cake Family's kitchen he always cooks with the hat on. */
.nerd-chef { transform-origin: 50% 100%; transform: translateY(-46px) rotate(-8deg); transition: opacity 250ms, transform 560ms cubic-bezier(.3, 1.5, .5, 1); }
.chef-puff, .chef-band { fill: #f7f6f0; stroke: currentColor; stroke-width: 4; stroke-linejoin: round; }
.chef-fold { fill: none; stroke: #c9c7bd; stroke-width: 3.5; stroke-linecap: round; }
[data-scene="proyecto-marble-cake"] .nerd-chef { opacity: 1; transform: rotate(-4deg); }
[data-scene="proyecto-marble-cake"] [data-prop="cap"] .nerd-cap { opacity: 0; }

/* Rocket Launcher: his face becomes the cockpit and he rides the scroll home. */
.rocket-body { fill: #121212; stroke: currentColor; stroke-width: 5; stroke-linejoin: round; }
.rocket-nose, .rocket-fin { fill: #ff5a4f; stroke: currentColor; stroke-width: 5; stroke-linejoin: round; }
.rocket-rivets { stroke: currentColor; stroke-width: 7; stroke-linecap: round; opacity: .6; }
.flame-outer { fill: #ff9f43; }
.flame-inner { fill: #ffe066; }
.rocket-flame { transform-box: fill-box; transform-origin: 50% 0; }
[data-rocket] .nerd-rocket { opacity: 1; }
[data-rocket] .rocket-flame { animation: rocket-flame 110ms steps(2) infinite alternate; }
[data-rocket] .nerd-body { animation: rocket-rumble 90ms linear infinite alternate; }
[data-rocket] .nerd-extra:not(.nerd-rocket), [data-rocket] .nerd-shades, [data-rocket] .nerd-reaction { opacity: 0 !important; }
@keyframes rocket-flame { from { transform: scale(.85, .8); } to { transform: scale(1.08, 1.15); } }
@keyframes rocket-rumble { from { transform: translate(-1px, 0); } to { transform: translate(1px, 1px); } }

/* Eyes: hearts, crosses, tiny scared pupils or spirals, and the shades. */
.nerd-heart { fill: #ff5c7a; opacity: 0; transform-box: fill-box; transform-origin: center; }
.nerd-cross { fill: none; stroke: currentColor; stroke-width: 6; stroke-linecap: round; opacity: 0; }
.pupil { transition: opacity 120ms; }
[data-eyes="hearts"] .pupil, [data-eyes="x"] .pupil, [data-eyes="spiral"] .pupil { opacity: 0; }
[data-eyes="hearts"] .nerd-heart { opacity: 1; animation: heart-beat .5s ease-in-out infinite alternate; }
@keyframes heart-beat { from { transform: scale(.9); } to { transform: scale(1.15); } }
[data-eyes="x"] .nerd-cross { opacity: 1; }
[data-eyes="spiral"] .nerd-dizzy { opacity: 1; }
[data-sweat="true"] .nerd-sweat { opacity: .8; animation: sweat-drip 1.1s ease-in-out infinite alternate; }
@keyframes sweat-drip { to { transform: translateY(4px); } }
.nerd-shades { transform: translateY(-120px); opacity: 0; transition: transform 520ms cubic-bezier(.3, 1.5, .5, 1), opacity 200ms; }
.nerd-shades rect { fill: #0b0b0b; stroke: currentColor; stroke-width: 3; }
.shade-glint { fill: none; stroke: #fff; stroke-width: 4; stroke-linecap: round; opacity: .85; }
[data-shades="true"] .nerd-shades { transform: none; opacity: 1; }
.nerd-stars { opacity: 0; transition: opacity 200ms; }
.bonk-star { fill: #ffe066; stroke: #0b0b0b; stroke-width: 1.5; }
[data-stars="true"] .nerd-stars { opacity: 1; }

/* A change of temperament is a change of channel. */
.nerd-position.is-switching { animation: nerd-channel 340ms steps(1) both; }
@keyframes nerd-channel {
  0% { filter: drop-shadow(-6px 0 #ff2d55) drop-shadow(6px 0 #22e1ff); clip-path: inset(0 0 55% 0); }
  20% { filter: drop-shadow(5px 0 #ff2d55) drop-shadow(-5px 0 #22e1ff) brightness(1.6); clip-path: inset(40% 0 0 0); }
  40% { filter: drop-shadow(-3px 0 #ff2d55) drop-shadow(3px 0 #22e1ff); clip-path: inset(10% 0 30% 0); }
  60% { filter: none; clip-path: inset(0); opacity: .3; }
  75% { opacity: 1; filter: drop-shadow(-2px 0 #ff2d55) drop-shadow(2px 0 #22e1ff); }
  100% { filter: none; clip-path: none; opacity: 1; }
}
.nerd.is-bonked { animation: nerd-bonk 620ms cubic-bezier(.3, .7, .3, 1); }
@keyframes nerd-bonk {
  0% { transform: none; }
  12% { transform: translateY(18px) scale(1.28, .62); }
  40% { transform: translateY(-6px) scale(.9, 1.12) rotate(6deg); }
  65% { transform: scale(1.05, .95) rotate(-3deg); }
  100% { transform: none; }
}
.is-calm .nerd-body, .is-calm .nerd-extra, .is-calm .nerd-heart, .is-calm .nerd-sweat { animation: none !important; }

/* The mallet: drawn like DaNerd, and inverted over whatever is behind it. */
.mallet { position: fixed; left: 0; top: 0; z-index: 40; width: 130px; height: 158px; color: #fff; mix-blend-mode: difference; transform-origin: 65px 149px; pointer-events: none; opacity: 0; visibility: hidden; }
.mallet.is-visible { opacity: 1; visibility: visible; pointer-events: auto; cursor: grab; }
.mallet.is-held { pointer-events: none; }
.mallet svg { width: 100%; height: 100%; overflow: visible; }
.mallet rect { fill: #000; stroke: currentColor; stroke-width: 7; }
.mallet path { fill: none; stroke: currentColor; stroke-width: 5; stroke-linecap: round; }
.mallet-hint { position: absolute; left: 110px; top: -14px; white-space: nowrap; font: 11px/1 'Silkscreen', var(--mono); color: #fff; opacity: 0; transition: opacity 300ms; }
.mallet.show-hint .mallet-hint { opacity: 1; }
.mallet.is-poof { animation: mallet-poof 600ms ease-in forwards; }
@keyframes mallet-poof { to { opacity: 0; filter: blur(6px); scale: .2; } }
html.has-hammer, html.has-hammer * { cursor: none !important; }

/* ── The locked door: a tiny pixel error at the bottom of the screen ── */
.gate-error { position: fixed; z-index: 70; left: 50%; bottom: 26px; transform: translateX(-50%); pointer-events: none; font-family: 'Silkscreen', var(--mono); image-rendering: pixelated; }
.gate-window { min-width: min(430px, 88vw); background: #0d0d0d; color: #f4f4f2; box-shadow: 0 -4px 0 -1px #f4f4f2, 0 4px 0 -1px #f4f4f2, -4px 0 0 -1px #f4f4f2, 4px 0 0 -1px #f4f4f2, 0 0 0 1px #0d0d0d, 8px 8px 0 #000; animation: gate-in 260ms steps(4) both; }
.gate-title { display: flex; align-items: center; gap: 10px; padding: 6px 10px; background: #e2433b; color: #fff; font-size: 11px; letter-spacing: .06em; }
.gate-code { opacity: .75; }
.gate-close { margin-left: auto; width: 16px; height: 16px; display: grid; place-items: center; background: #0d0d0d; color: #fff; font-size: 12px; line-height: 1; }
.gate-body { display: flex; align-items: center; gap: 14px; padding: 14px 16px 16px; background: repeating-linear-gradient(0deg, #ffffff06 0 2px, transparent 2px 4px); }
.gate-icon { width: 44px; flex: none; fill: #ffd23f; }
.gate-icon .bang { fill: #0d0d0d; }
.gate-body p { margin: 0; display: grid; gap: 6px; font-size: 13px; line-height: 1.3; }
.gate-body strong { font-weight: 700; font-size: 14px; color: #ffd23f; }
.gate-body span { color: #cfcfca; font-size: 12px; }
.gate-cursor { display: inline-block; width: 9px; height: 13px; background: #f4f4f2; animation: gate-blink .8s steps(1) infinite; }
@keyframes gate-blink { 50% { opacity: 0; } }
@keyframes gate-in { from { transform: translateY(30px); opacity: 0; } to { transform: none; opacity: 1; } }
.gate-error.is-shaking .gate-window { animation: gate-in 260ms steps(4) both, gate-shake 380ms steps(6) 120ms; }
@keyframes gate-shake { 0%, 100% { translate: 0; } 20% { translate: -8px 0; } 40% { translate: 7px 0; } 60% { translate: -5px 0; } 80% { translate: 3px 0; } }
.project-stage.is-denied { animation: stage-denied 420ms cubic-bezier(.3, .7, .3, 1); }
@keyframes stage-denied { 0%, 100% { translate: 0; } 15% { translate: -14px 0; } 35% { translate: 11px 0; } 55% { translate: -7px 0; } 75% { translate: 4px 0; } }
.is-nagging .hardware-power .power-label { opacity: 1; }
.is-nagging .hardware-power::before { animation-duration: 500ms !important; }

/* Sound on/off, in the same family as the motion toggle. */
.sound-toggle svg { width: 17px; height: 17px; fill: none; stroke: #c0c0c0; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.sound-toggle .mute { display: none; }
.sound-toggle[aria-pressed="true"] .waves { display: none; }
.sound-toggle[aria-pressed="true"] .mute { display: inline; }
#nerd-adjust.is-adjusting { animation: glasses-adjust 900ms cubic-bezier(.3, .7, .3, 1); }
@keyframes glasses-adjust {
  0% { transform: none; }
  30% { transform: translateY(9px) rotate(-3deg); }
  55% { transform: translateY(-4px) rotate(1deg); }
  75% { transform: translateY(1px); }
  100% { transform: none; }
}
.is-calm .nerd svg, .is-calm .nerd, .is-calm #nerd-adjust { animation: none !important; }
.glasses-frame { fill: none; stroke: currentColor; stroke-width: 14; }
.glasses-bridge { stroke: currentColor; stroke-width: 14; }
.pupil { fill: currentColor; }
.nerd-mouth { stroke: currentColor; fill: none; stroke-width: 12; stroke-linecap: butt; }
.happy-marks { opacity: 0; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; }
.nerd-brows { stroke: currentColor; stroke-width: 5; stroke-linecap: round; fill: none; opacity: 0; }
.nerd-sweat { fill: none; stroke: currentColor; stroke-width: 3; opacity: 0; transition: opacity 200ms; }
.nerd-dizzy { stroke: currentColor; stroke-width: 3.5; fill: none; opacity: 0; }
.nerd-dizzy .orbit-star { stroke-width: 2; }
.nerd-reaction { position: absolute; top: 103%; left: 50%; transform-origin: 50% 0; font: 12px/1.4 'DM Sans', Arial, sans-serif; letter-spacing: -.1px; white-space: nowrap; background: #202020; color: #eeeeea; padding: 10px 14px; border-radius: 0 14px 14px; box-shadow: 0 5px 18px #0005; pointer-events: none; }

/* Spacer sections preserve normal scroll, anchors and browser history. */
.chapter { position: relative; height: 112svh; }
.chapter-intro { height: 82svh; }
.chapter-pitch { height: 104svh; }
.chapter-context { height: 125svh; }
.chapter-outro { height: 100svh; }
.chapter-project { height: 96svh; }
.scene { position: fixed; inset: 0; z-index: 5; display: flex; align-items: center; padding: 100px 7vw; pointer-events: none; }
.js .scene { visibility: hidden; opacity: 0; will-change: transform, opacity; }
.scene.is-active a, .scene.is-active button { pointer-events: auto; }
.scene-intro { padding: 0; display: block; text-align: center; }
.hero-type { position: absolute; top: 61%; left: 0; width: 100%; }
.hero-type h1 { margin: 0; font-size: clamp(72px, 8.1vw, 132px); font-weight: 550; line-height: .98; letter-spacing: -.077em; }
.scroll-invitation { position: absolute; left: 50%; bottom: 8%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 12px; font-size: clamp(14px, 1.15vw, 18px); white-space: nowrap; color: #9d9d9d; }
.scroll-invitation svg { width: 18px; height: 18px; }
/* "Sigue scrolleando": floats up when the visitor stops halfway (nudge.js). */
.keep-scrolling { position: fixed; left: 50%; bottom: 28px; z-index: 26; display: flex; align-items: center; gap: 8px; padding: 9px 16px; border: 1px solid #2c2c2c; border-radius: 999px; background: #121212e6; color: #d8d8d4; font-size: 13px; pointer-events: none; opacity: 0; transform: translate(-50%, 12px); transition: opacity .35s, transform .35s; }
.keep-scrolling.is-visible { opacity: 1; transform: translate(-50%, 0); animation: keep-scrolling-float 2.4s ease-in-out .35s infinite; }
.keep-scrolling svg { width: 15px; height: 15px; }
@keyframes keep-scrolling-float { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, -6px); } }
.is-calm .keep-scrolling.is-visible { animation: none; }
.scroll-line { display: block; height: 28px; width: 1px; background: linear-gradient(transparent, #6b6b6b); margin-top: 4px; }
.scene-speech { display: block; }
/* The welcome act: DaNerd types, deletes and retypes his pitch (pitch.js). */
.pitch-speech { position: absolute; left: 36%; top: 27%; width: 56%; max-width: 900px; }
.pitch-speech h2 { min-height: 3.4em; font-size: clamp(38px, 4.5vw, 72px); line-height: 1.12; font-weight: 450; letter-spacing: -.055em; margin: 0; }
.pitch-caret { display: inline-block; width: .07em; height: .95em; margin-left: .06em; vertical-align: -.1em; background: currentColor; opacity: 0; }
.pitch-speech.is-playing .pitch-caret { opacity: 1; animation: caret-blink 900ms steps(1) infinite; }
@keyframes caret-blink { 50% { opacity: .15; } }
.pitch-note { opacity: 0; transform: translateY(8px); transition: opacity 500ms 200ms, transform 500ms 200ms var(--ease); }
.pitch-speech.is-done .pitch-note, html:not(.js) .pitch-note { opacity: 1; transform: none; }
.context-speech { position: absolute; left: 10%; top: 23%; width: 56%; max-width: 800px; }
.context-speech h1 { font-size: clamp(36px, 4.05vw, 61px); line-height: 1.15; font-weight: 450; letter-spacing: -.05em; margin: 0 0 26px; }
.context-speech p { font-size: clamp(16px, 1.2vw, 19px); line-height: 1.8; color: #b7b7b2; max-width: 670px; margin: 16px 0; }
.context-speech .quiet-link { margin-top: 9px; }
.aside-note { color: #838383; font-size: 14px; margin: 27px 0 0; line-height: 1.7; }
.quiet-link { display: inline-flex; align-items: center; gap: 23px; background: transparent; padding: 12px 0; margin-top: 26px; font-size: 12px; transition: color 200ms; }
.quiet-link svg { width: 17px; height: 17px; }

/* The project is real. DaNerd supplies the words beside it. */
.project-scene { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .35fr); gap: 3.5vw; padding: 10vh 7vw 8vh 5vw; align-items: center; }
.project-scene.side-left { grid-template-columns: minmax(0, .35fr) minmax(0, 1fr); padding: 10vh 5vw 8vh 7vw; }
.project-stage { --title-size: clamp(32px, 3.3vw, 49px); --title-gap: 25px; min-width: 0; position: relative; }
/* The title now lives with DaNerd's words; this keeps the room it used to take,
   so every hand-tuned pose stays exactly where it was placed. */
.project-stage::before { content: ''; display: block; height: calc(var(--title-size) * 1.08 + var(--title-gap)); }
.side-left .project-stage { grid-column: 2; grid-row: 1; }
.project-art { display: block; width: 100%; padding: 0; border: 0; background: #171717; border-radius: 7px; position: relative; overflow: hidden; isolation: isolate; text-align: left; }
.project-art > img { display: block; width: 100%; aspect-ratio: 1.65; object-fit: cover; object-position: top; height: auto; filter: saturate(.68) brightness(.88); transform: scale(1.004); transition: transform 650ms var(--ease), filter 500ms; }
.project-art:hover > img, .project-art:focus-visible > img { filter: saturate(1) brightness(1); transform: scale(1.025); }
.art-overlay { position: absolute; inset: 0; background: linear-gradient(transparent 64%, #0006); pointer-events: none; }
.art-open { position: absolute; right: 20px; bottom: 18px; display: flex; align-items: center; gap: 24px; padding: 12px 17px; border-radius: 25px; background: #f0f0ee; color: #111; font-size: 11px; box-shadow: 0 3px 20px #0003; transition: transform 250ms var(--ease); }
.project-art:hover .art-open { transform: translateY(-3px); }
.art-open svg { width: 15px; height: 15px; }
/* A fixed height keeps the words still when they change (asking for help,
   then describing the project): the block no longer re-centres and jumps. */
.project-speech { position: relative; z-index: 2; align-self: center; justify-self: end; width: min(100%, 290px); height: calc(13vh + 16rem); margin-right: -2.5vw; padding-top: 13vh; min-width: 0; }
/* Pushed toward the outer edge, away from the shells. */
.side-left .project-speech { justify-self: start; margin-right: 0; margin-left: -2.5vw; }
/* Shells can spill under the words; a soft pool of page black keeps them legible. */
.project-speech::before { content: ''; position: absolute; z-index: -1; inset: 9vh -4vw -4vh; background: radial-gradient(closest-side, #080808f2 58%, #08080000); pointer-events: none; }
.project-speech h2 { font-size: clamp(30px, 2.9vw, 44px); line-height: 1.08; font-weight: 450; letter-spacing: -.05em; margin: 0 0 18px; }
.side-left .project-speech { grid-column: 1; grid-row: 1; }
.project-speech p { font-size: 14px; line-height: 1.85; color: #ababaa; margin: 0; max-width: 370px; }
.chuckle { white-space: nowrap; color: #e6e6e1; font: 13px var(--mono); }
.chuckle-face { display: inline-block; animation: chuckle-shake 1.6s ease-in-out infinite; }
.chuckle-je { display: inline-block; font: 10px 'Silkscreen', var(--mono); color: #ffd23f; animation: chuckle-je 1.6s ease-in-out infinite; }
.chuckle-je + .chuckle-je { animation-delay: .18s; }
@keyframes chuckle-shake { 0%, 40%, 100% { transform: none; } 10%, 30% { transform: translateY(-1px) rotate(-4deg); } 20% { transform: translateY(1px) rotate(4deg); } }
@keyframes chuckle-je { 0%, 45%, 100% { transform: none; opacity: .55; } 12% { transform: translateY(-6px); opacity: 1; } 26% { transform: translateY(-2px); opacity: .9; } }
.is-calm .chuckle-face, .is-calm .chuckle-je { animation: none; }

.scene-outro { display: block; text-align: center; }
.outro-speech { position: absolute; top: 45%; left: 10%; width: 80%; }
.outro-speech h2 { font-weight: 450; font-size: clamp(46px, 5.6vw, 85px); line-height: 1.1; letter-spacing: -.055em; margin: 0; }
.outro-actions { display: flex; justify-content: center; gap: 35px; }
.site-footer { position: absolute; left: 0; right: 0; bottom: 4vh; text-align: center; color: #8d8d8d; }
.footer-socials { display: flex; justify-content: center; gap: 22px; margin-bottom: 15px; }
.footer-socials svg { width: 21px; height: 21px; }
.footer-socials a { display: flex; transition: color .2s; }
.footer-socials a:hover { color: #f3f3f3; }
.site-footer p { margin: 0; font-size: 11px; line-height: 1.5; }

.scroll-rail { position: fixed; right: 14px; top: 120px; bottom: 30px; width: 38px; z-index: 25; pointer-events: none; opacity: var(--arrival); }
#scroll-progress { position: absolute; top: calc(var(--scroll-progress, 0) * (100% - 45px)); width: 38px; height: 45px; pointer-events: auto; display: flex; justify-content: center; align-items: center; background: #191919cc; backdrop-filter: blur(8px); border-radius: 22px; gap: 1px; font: 11px var(--mono); color: #bebebe; font-variant-numeric: tabular-nums; cursor: grab; touch-action: none; user-select: none; }
#scroll-progress small { font-size: 7px; color: #747474; }
#scroll-progress.is-dragging { cursor: grabbing; background: #ededed; color: #080808; }

/* The index becomes available after reaching the end of the journey. */
dialog { color: var(--white); }
.project-index { position: fixed; inset: 16px 16px 16px auto; margin: 0; width: min(570px, calc(100vw - 32px)); height: calc(100dvh - 32px); max-height: none; max-width: none; padding: 28px 35px; border: 0; border-radius: 12px; background: #171717; box-shadow: -30px 0 100px #0007; }
.project-index { scrollbar-width: none; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; }
.project-index::-webkit-scrollbar, .project-index *::-webkit-scrollbar { display: none; width: 0; height: 0; }
.project-index * { scrollbar-width: none; }
.project-index[open] { animation: drawer-in 400ms var(--ease); }
.project-index::backdrop { background: #080808b3; backdrop-filter: blur(15px); }
.index-head { display: flex; align-items: center; justify-content: end; }
.index-head button { background: #252525; }
.project-index h2 { font-size: 56px; font-weight: 450; line-height: 1; letter-spacing: -3px; margin: 26px 0; }
#index-links a { display: grid; grid-template-columns: 51px 1fr 20px; align-items: center; gap: 14px; padding: 15px 0; border-bottom: 1px solid #313131; }
#index-links a:hover img { filter: grayscale(0); }
#index-links a:hover [data-icon] { transform: translate(3px, -3px); }
#index-links img { width: 51px; height: 37px; object-fit: cover; filter: grayscale(1); border-radius: 3px; transition: filter 200ms; }
#index-links strong { display: block; font-size: 14px; font-weight: 450; }
#index-links small { display: block; color: #878787; font-size: 9px; margin-top: 3px; }
#index-links [data-icon] { color: #8b8b8b; transition: transform 200ms; }
#index-links svg { width: 15px; height: 15px; }
.index-restart { display: flex; justify-content: space-between; font-size: 11px; color: #aaa; margin-top: 24px; }
.index-restart svg { width: 15px; height: 15px; }
.icon-button { display: inline-flex; align-items: center; justify-content: center; width: 35px; height: 35px; border-radius: 8px; background: transparent; flex: none; transition: background 160ms; }
.icon-button:hover { background: #333; }
.project-dialog { width: 100vw; max-width: none; height: 100dvh; max-height: none; margin: 0; padding: 0; border: 0; background: #0d0d0d; color: #eee; overflow: hidden; }
.project-dialog[open] { display: block; animation: viewer-in 300ms var(--ease); }
.project-dialog::backdrop { background: #080808dd; backdrop-filter: blur(15px); }
/* The dive (viewer.js): the camera flies into the screen with the viewer
   still invisible; it then fades in as the screen's picture, which settles
   into the stage and fades once the demo has loaded underneath. */
.project-dialog.is-diving { animation: none; }
.project-dialog.is-veiled, .project-dialog.is-veiled::backdrop { opacity: 0; }
.viewer-cover { position: absolute; z-index: 5; inset: 0; background: #0a0a0a center / cover no-repeat; pointer-events: none; transition: inset 420ms var(--ease), opacity 380ms, filter 380ms; }
.viewer-cover.is-waiting { filter: brightness(.42) saturate(.7); }
.viewer-cover.is-gone { opacity: 0; }
.project-dialog.is-diving .viewer-loading { visibility: hidden; }
.project-dialog.has-cover .viewer-loading { z-index: 6; background: transparent; }
body:has(dialog[open]) { overflow: hidden; }
body:has(dialog[open]) .scroll-rail { visibility: hidden; }
/* No frame: the demo fills the window and the controls float over it, in a
   small dock in the bottom-left corner, where the demos leave room. */
.viewer-header { position: absolute; z-index: 8; left: 16px; bottom: 16px; display: flex; align-items: center; gap: 14px; height: 50px; padding: 0 7px 0 16px; border-radius: 16px; background: #0f0f0fdb; backdrop-filter: blur(14px); box-shadow: 0 10px 34px #0008, inset 0 0 0 1px #ffffff14; white-space: nowrap; }
.viewer-identity { display: flex; gap: 12px; align-items: center; }
.viewer-nerd { font: 18px var(--mono); color: #b0b0b0; }
.viewer-identity h2 { font-size: 13px; font-weight: 550; letter-spacing: -.3px; margin: 0; }
.viewer-identity p { font: 9px var(--mono); color: #929292; margin: 3px 0 0; }
.viewer-controls { display: flex; align-items: center; gap: 5px; }
.viewer-external { display: flex; align-items: center; gap: 12px; padding: 10px 12px; font-size: 10px; background: #262626; border-radius: 7px; margin: 0 7px; }
.viewer-external:hover { background: #444; }
.viewer-external svg { width: 14px; height: 14px; }
.close-button { background: #e8e8e8; color: #080808; }
.close-button:hover { background: #aaa; }
.viewer-description { position: absolute; z-index: 8; left: 16px; bottom: 78px; width: min(560px, calc(100vw - 32px)); padding: 15px 20px; font-size: 12px; line-height: 1.7; border-radius: 14px; background: #161616f0; backdrop-filter: blur(14px); color: #c4c4c4; box-shadow: 0 10px 34px #0008; }
.viewer-stage { position: absolute; inset: 0; background: #fff; }
.frame-mount { width: 100%; height: 100%; }
.frame-mount iframe { display: block; width: 100%; height: 100%; border: 0; background: #fff; }
.viewer-external-stage { height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; padding: 20px; background: #080808; }
.viewer-external-stage img { max-width: 100%; max-height: calc(100% - 65px); object-fit: contain; border-radius: 8px; }
.viewer-external-stage a { flex: none; border-radius: 30px; background: #ededeb; color: #101010; padding: 13px 23px; font-size: 13px; }
.viewer-loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; background: #161616; z-index: 2; pointer-events: none; }
.viewer-loading p { font-size: 14px; margin: 19px 0 8px; }
.viewer-loading small { color: #8b8b8b; font-size: 10px; }
.loading-orbit { width: 28px; height: 28px; border: 2px solid #3b3b3b; border-top-color: #bbb; border-radius: 50%; animation: orbit 800ms linear infinite; }
.viewer-footer { display: contents; }
/* The hint shows for a few seconds above the dock, then gets out of the way. */
.viewer-footer p:empty { display: none; }
.viewer-footer p { position: absolute; z-index: 8; left: 16px; bottom: 76px; max-width: min(520px, calc(100vw - 32px)); padding: 8px 13px; border-radius: 10px; background: #0f0f0fd0; backdrop-filter: blur(12px); font-size: 11px; color: #c9c9c4; margin: 0; line-height: 1.45; pointer-events: none; animation: hint-out 7s var(--ease) forwards; }
@keyframes hint-out { 0% { opacity: 0; translate: 0 6px; } 6%, 80% { opacity: 1; translate: 0; } 100% { opacity: 0; translate: 0 6px; visibility: hidden; } }
.viewer-description:not([hidden]) ~ .viewer-footer p { display: none; }
/* Keep the dock narrow so it stays clear of the demos' own bottom bars: after
   a few seconds it tucks down to name + close, and opens again on hover. */

.viewer-identity p { display: none; }
.viewer-header .viewer-external { font-size: 0; gap: 0; padding: 10px; margin: 0 2px; }
.viewer-divider { width: 1px; height: 22px; margin: 0 3px; background: #ffffff1f; }
.viewer-fallback { position: absolute; z-index: 8; bottom: 80px; left: 50%; transform: translateX(-50%); width: min(580px, 90%); padding: 15px 38px 15px 18px; font-size: 11px; line-height: 1.65; border-radius: 9px; background: #252525; color: #eee; box-shadow: 0 5px 30px #0005; }
.viewer-fallback a { display: block; text-decoration: underline; font-weight: 550; }
.viewer-fallback button { position: absolute; right: 10px; top: 8px; background: none; font-size: 20px; }
.toast { position: fixed; bottom: 24px; left: 50%; transform: translate(-50%, 15px); opacity: 0; pointer-events: none; z-index: 50; padding: 13px 20px; border-radius: 9px; background: #eee; color: #080808; font-size: 12px; transition: opacity 160ms, transform 160ms; }
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }
@keyframes viewer-in { from { opacity: 0; transform: translateY(15px) scale(.99); } to { opacity: 1; transform: none; } }
@keyframes drawer-in { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }
@keyframes orbit { to { transform: rotate(360deg); } }

/* A document remains available when JavaScript cannot start. */
html:not(.js) .chapter { height: auto; min-height: 80vh; }
html:not(.js) .scene { position: relative; min-height: 80vh; pointer-events: auto; }
html:not(.js) .scene-intro { min-height: 90vh; }
html:not(.js) .hero-type { top: 35%; }
html:not(.js) :is(.ambient-stage, .voice-wire, .nerd-position, .motion-toggle, .index-trigger) { display: none; }
html:not(.js) :is(.pitch-speech, .context-speech) { position: relative; left: auto; top: auto; width: 100%; padding: 40px 0; }
html:not(.js) .scene-speech { display: flex; }
.no-script { position: relative; z-index: 20; margin: 40px 8vw; font-size: 15px; line-height: 2; color: #aaa; }
.no-script a { color: #eee; text-decoration: underline; }

@media (min-width: 1700px) {
  .project-scene, .project-scene.side-left { padding-inline: max(5vw, calc((100vw - 1680px) / 2)); gap: 65px; }
}
@media (max-width: 1100px) {
  .site-chrome { height: 85px; }
  .project-scene { gap: 3vw; padding: 11vh 6vw 9vh 4vw; grid-template-columns: minmax(0, 1fr) minmax(0, .4fr); }
  .project-scene.side-left { padding: 11vh 4vw 9vh 6vw; grid-template-columns: minmax(0, .4fr) minmax(0, 1fr); }
  .project-stage { --title-size: 40px; }
  .project-speech h2 { font-size: 36px; }
  .project-speech p { font-size: 13px; }
  .pitch-speech { left: 35%; width: 60%; }
  .scroll-rail { right: 8px; width: 32px; }
  #scroll-progress { width: 32px; }
}
@media (max-height: 760px) and (min-width: 761px) {
  .portal { width: min(570px, 63vw); }
  .hero-type { top: 59%; }
  .hero-type h1 { font-size: min(8vw, 96px); }
  .scroll-invitation { bottom: 7%; gap: 6px; }
  .scroll-line { height: 14px; }
  .project-scene, .project-scene.side-left { padding-top: 11vh; padding-bottom: 9vh; }
  .project-stage { max-width: 730px; }
  .project-art > img { max-height: 47vh; object-fit: cover; }
  .project-stage { --title-size: 40px; --title-gap: 17px; }
  .project-index h2 { font-size: 40px; margin: 18px 0; }
  #index-links a { padding: 10px 0; }
  .project-index { padding-block: 21px; }
}
@media (max-width: 760px) {
  .site-chrome { padding-inline: 24px; height: 78px; }
  .small-wordmark { font-size: 21px; }
  .site-chrome nav { gap: 13px; }
  .index-trigger { font-size: 10px; }
  .index-trigger [data-icon] { display: none; }
  .portal { width: 110vw; max-width: 560px; }
  .hero-type { top: 57%; }
  .hero-type h1 { font-size: 20vw; }
  .scroll-invitation { bottom: 11%; }
  .pitch-speech { left: 10%; top: 44%; width: 82%; }
  .pitch-speech h2 { font-size: clamp(28px, 7.2vw, 48px); }
  .context-speech { left: 9%; top: 38%; width: 79%; }
  .context-speech h1 { font-size: 30px; margin-bottom: 18px; }
  .context-speech p { font-size: 13px; line-height: 1.7; margin: 13px 0; }
  .aside-note { font-size: 12px; margin-top: 20px; }
  .project-scene, .project-scene.side-left { display: flex; flex-direction: column; align-items: stretch; justify-content: center; padding: 115px 48px 85px 26px; gap: 25px; }
  .project-stage { --title-size: 36px; --title-gap: 17px; }
  .project-speech h2 { font-size: 30px; margin-bottom: 10px; }
  .project-art > img { aspect-ratio: 1.6; max-height: 32vh; object-fit: cover; }
  .art-open { padding: 9px 12px; right: 12px; bottom: 11px; font-size: 9px; gap: 13px; }
  .project-speech, .side-left .project-speech { width: auto; height: auto; margin: 0; padding-top: 0; padding-right: 24%; align-self: stretch; }
  .project-speech p { font-size: 10px; line-height: 1.8; max-width: none; }
  .outro-speech { top: 46%; }
  .outro-speech h2 { font-size: 43px; }
  .scroll-rail { top: 95px; right: 6px; bottom: 26px; }
  .project-index { padding: 22px; }
  .project-index h2 { font-size: 45px; margin-block: 24px; }
  #index-links a { grid-template-columns: 43px 1fr 18px; gap: 10px; padding: 12px 0; }
  #index-links img { width: 43px; height: 34px; }
  #index-links strong { font-size: 12px; }
  .viewer-header { left: 10px; right: 10px; bottom: 10px; transform: none; padding: 0 6px 0 12px; justify-content: space-between; }
  .viewer-nerd { display: none; }
  .viewer-identity h2 { font-size: 12px; }
  .viewer-controls { gap: 0; }
  .viewer-external { font-size: 0; padding: 10px; gap: 0; margin-inline: 2px 4px; }
  .viewer-controls .icon-button { width: 32px; height: 32px; }
  .viewer-footer p { font-size: 10px; left: 10px; bottom: 68px; }
  .viewer-description { left: 10px; bottom: 68px; padding: 12px; font-size: 11px; }
}
@media (prefers-reduced-motion: reduce) {
  :root { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
.is-calm { scroll-behavior: auto; }
.is-calm *, .is-calm *::before, .is-calm *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }

/* ── Trophies: the header button, the pop-up and the case ─────────────── */
.lang-toggle { position: relative; }
.lang-toggle svg { width: 17px; height: 17px; fill: none; stroke: #c0c0c0; stroke-width: 1.5; overflow: visible; }
.lang-toggle:hover svg { stroke: #fff; }
.lang-code { position: absolute; right: -7px; bottom: -5px; padding: 2px 3px 1px; background: #e9e9e4; color: #111; font: 700 8px/1 'Silkscreen', var(--mono); letter-spacing: .5px; }
.globe-meridian { transform-box: fill-box; transform-origin: center; }
.lang-toggle.is-spinning svg { animation: globe-tilt 760ms cubic-bezier(.3, 1.4, .5, 1); }
.lang-toggle.is-spinning .globe-meridian { animation: globe-spin 760ms ease-in-out; }
@keyframes globe-tilt { 0% { transform: none; } 30% { transform: rotate(-22deg) scale(1.12); } 100% { transform: none; } }
@keyframes globe-spin { 0%, 50%, 100% { transform: scaleX(1); } 25%, 75% { transform: scaleX(0); } }
.is-calm .lang-toggle svg, .is-calm .globe-meridian { animation: none !important; }
.trophy-toggle { position: relative; }
.trophy-toggle svg { width: 16px; height: 15px; fill: #c0c0c0; }
.trophy-toggle:hover svg { fill: #ffd23f; }
.trophy-badge { position: absolute; top: -4px; right: -6px; min-width: 17px; height: 17px; padding: 0 4px; display: grid; place-items: center; background: #ffd23f; color: #111; font: 700 9px/1 'Silkscreen', var(--mono); }
.trophy-toggle.is-bumped { animation: trophy-bump 600ms cubic-bezier(.3, 1.6, .5, 1); }
@keyframes trophy-bump { 30% { transform: scale(1.35) rotate(-10deg); } 60% { transform: scale(.92) rotate(6deg); } }
.trophy-tray { position: fixed; z-index: 80; left: 22px; bottom: 22px; display: grid; gap: 10px; pointer-events: none; }
.trophy-toast { display: flex; align-items: center; gap: 12px; min-width: 280px; max-width: min(360px, 86vw); padding: 10px 14px 10px 10px; background: #111; color: #f4f4f2; font-family: 'Silkscreen', var(--mono); box-shadow: 0 -3px 0 #ffd23f, 0 3px 0 #ffd23f, -3px 0 0 #ffd23f, 3px 0 0 #ffd23f, 6px 6px 0 #000; animation: toast-in 380ms steps(5) both; }
.trophy-toast.is-leaving { animation: toast-out 360ms steps(4) both; }
.trophy-toast-icon { width: 40px; height: 40px; display: grid; place-items: center; flex: none; background: #2a2412; }
.trophy-toast-icon svg, .trophy-row-icon svg { width: 26px; fill: #ffd23f; }
.trophy-toast-icon .shine, .trophy-row-icon .shine { fill: #fff6c8; }
.trophy-toast small { display: block; font-size: 9px; color: #ffd23f; letter-spacing: .08em; }
.trophy-toast strong { display: block; font-size: 13px; margin: 3px 0 2px; }
.trophy-toast em { display: block; font-style: normal; font-size: 10px; color: #bdbdb7; line-height: 1.35; }
@keyframes toast-in { from { transform: translateX(-120%); } to { transform: none; } }
@keyframes toast-out { to { transform: translateX(-130%); opacity: 0; } }
.trophy-case { width: min(720px, 92vw); max-height: 86vh; padding: 0; border: 0; background: #0f0f0f; color: #f4f4f2; font-family: 'Silkscreen', var(--mono); box-shadow: 0 -4px 0 #ffd23f, 0 4px 0 #ffd23f, -4px 0 0 #ffd23f, 4px 0 0 #ffd23f, 10px 10px 0 #000; overflow: auto; scrollbar-width: thin; }
.trophy-case::backdrop { background: #080808cc; backdrop-filter: blur(6px); }
.trophy-head { position: sticky; top: 0; display: flex; align-items: center; gap: 14px; padding: 14px 18px; background: #ffd23f; color: #111; }
.trophy-head h2 { margin: 0; font-size: 18px; font-weight: 700; }
.trophy-head span { font-size: 13px; }
.trophy-close { margin-left: auto; width: 30px; height: 30px; background: #111; color: #ffd23f; font: 700 18px/1 'Silkscreen', var(--mono); }
.trophy-stats { margin: 16px 18px 4px; font-size: 11px; color: #bdbdb7; }
.trophy-list { list-style: none; margin: 0; padding: 12px 18px 22px; display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.trophy-list li { display: flex; gap: 12px; align-items: center; padding: 10px; background: #171717; }
.trophy-list li.is-locked { opacity: .55; }
.trophy-list li.is-locked svg { fill: #6c6c68; }
.trophy-list li.is-locked .hole { fill: #171717; }
.trophy-row-icon { width: 38px; height: 38px; display: grid; place-items: center; flex: none; background: #0c0c0c; }
.trophy-list strong { display: block; font-size: 12px; }
.trophy-list em { display: block; font-style: normal; font-size: 10px; color: #a9a9a4; line-height: 1.4; margin-top: 3px; }

/* ── Hidden things in the project scenes ─────────────────────────────── */
.secret { position: absolute; z-index: 3; left: calc(var(--x) - 22px); top: calc(var(--y) - 22px); width: 44px; height: 44px; padding: 0; background: transparent; color: #e9e9e3; opacity: .8; cursor: pointer; transition: opacity 200ms, transform 200ms var(--ease); animation: secret-wiggle 7s var(--wiggle-delay, 0s) infinite; }
.secret.is-behind { z-index: 0; }
.secret svg { width: 100%; height: 100%; overflow: visible; }
.secret:hover, .secret:focus-visible { opacity: 1; transform: scale(1.15) rotate(-6deg); }
.secret.is-found { animation: secret-found 900ms cubic-bezier(.5, 0, .6, 1) forwards; z-index: 50; pointer-events: none; }
@keyframes secret-wiggle { 0%, 90%, 100% { rotate: 0deg; } 92% { rotate: -14deg; } 94% { rotate: 11deg; } 96% { rotate: -6deg; } }
@keyframes secret-found {
  0% { transform: none; opacity: 1; }
  25% { transform: translateY(-30px) scale(1.6) rotate(20deg); opacity: 1; }
  100% { transform: translate(var(--fly-x), var(--fly-y)) scale(.25) rotate(360deg); opacity: .2; }
}
.hardware-power.is-poked .power-face { transform: scale(.9); filter: brightness(.8); }

/* ── 8-bit mode ───────────────────────────────────────────────────────── */
.is-retro body, .is-retro button, .is-retro .nerd-reaction { font-family: 'Silkscreen', var(--mono); }
.is-retro :is(h1, h2, h3) { letter-spacing: -.05em; word-spacing: -.12em; }
.is-retro #nerd-face, .is-retro .mallet svg { filter: url(#retro-pixels); }
.is-retro .hardware-shell, .is-retro .portal canvas { filter: url(#retro-pixels-big); }
.is-retro .crt-picture img { filter: saturate(1.4) contrast(1.15); image-rendering: pixelated; }
.is-retro .nerd-reaction { border-radius: 0; box-shadow: 0 -3px 0 #f4f4f2, 0 3px 0 #f4f4f2, -3px 0 0 #f4f4f2, 3px 0 0 #f4f4f2; }
.is-retro body::after { content: ''; position: fixed; inset: 0; z-index: 95; pointer-events: none; background: repeating-linear-gradient(0deg, #0000002e 0 2px, transparent 2px 4px), radial-gradient(ellipse at center, transparent 60%, #00000066); }
.retro-badge { position: fixed; z-index: 96; left: 50%; top: 22px; transform: translateX(-50%); padding: 8px 14px; background: #22e1a3; color: #0b0b0b; font: 700 11px/1 'Silkscreen', var(--mono); box-shadow: 4px 4px 0 #000; animation: badge-in 300ms steps(4) both; pointer-events: none; }
@keyframes badge-in { from { transform: translate(-50%, -40px); } to { transform: translateX(-50%); } }

/* ── The viewer dock, in DaNerd's own colours ─────────────────────────────
   Close sits first and never moves; the mark next to it is the handle, and
   hovering the dock slides the rest of the tools out to its right. */
.viewer-header { gap: 0; padding: 6px; height: auto; background: #f4f4ec; color: #242820; box-shadow: 0 12px 34px #0007, inset 0 0 0 1px #24282014; border-radius: 16px; }
.viewer-header .icon-button { color: #242820; width: 38px; height: 38px; border-radius: 11px; }
.viewer-header .icon-button:hover, .viewer-header .viewer-external:hover { background: #2428201a; }
.viewer-header .close-button { background: #242820; color: #f4f4ec; }
.viewer-header .close-button:hover { background: #3a3f33; }
.viewer-identity { gap: 9px; padding: 0 10px 0 12px; }
.viewer-mark { width: 34px; height: 26px; fill: #242820; flex: none; transition: transform 300ms cubic-bezier(.3, 1.6, .5, 1); }
.viewer-header:hover .viewer-mark { transform: rotate(-6deg) scale(1.06); }
.viewer-identity h2 { color: #242820; }
.viewer-header .viewer-external { background: transparent; color: #242820; }
.viewer-divider { background: #24282026; }
.viewer-identity > div, .viewer-controls { display: flex; align-items: center; overflow: hidden; max-width: 460px; opacity: 1; transition: max-width 420ms var(--ease), opacity 260ms; }
.viewer-header.is-tucked:not(:hover, :has(:focus-visible)) :is(.viewer-identity > div, .viewer-controls) { max-width: 0; opacity: 0; }
.viewer-header.is-tucked:not(:hover, :has(:focus-visible)) .viewer-identity { padding-right: 6px; }
.viewer-identity { transition: padding 420ms var(--ease); }