/* =========================================================================
   THE LAST PIXEL ON THE INTERNET
   A non-interactive, stop-motion-inspired animated short.

   Design notes:
   - The whole film lives on a fixed 960x540 logical canvas (.viewport).
     JS scales it to fit any screen so every coordinate in film.js is exact.
   - "Stop motion" is achieved with steps() timing functions, tiny jittery
     keyframes, and squash/stretch — never smooth easing on the character.
   - Scenes are just classes on #backdrop. film.js swaps them and moves the
     pixel; CSS owns all the look.
   ========================================================================= */

:root {
  --stage-w: 960px;
  --stage-h: 540px;
  --px: 15px;               /* logical size of the hero pixel */
  --scale: 1;               /* set by JS to fit the screen */

  --ink: #101014;
  --paper: #f4f1e8;
  --hero: #ff5d3b;          /* the pixel's signature color */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #050506;
  overflow: hidden;
  font-family: "Inter", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---- Theatre: black surround ------------------------------------------- */
.theatre {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 120% at 50% 40%, #14141a 0%, #050506 70%);
}

/* ---- Fit wrapper: scales the fixed canvas ------------------------------ */
.fit {
  width: var(--stage-w);
  height: var(--stage-h);
  transform: scale(var(--scale));
  transform-origin: center center;
  will-change: transform;
}

/* ---- Fake browser window ----------------------------------------------- */
.browser {
  width: 100%;
  height: 100%;
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  box-shadow:
    0 40px 120px rgba(0,0,0,.65),
    0 0 0 1px rgba(255,255,255,.05);
  display: flex;
  flex-direction: column;
  transition: filter 1.2s steps(6), box-shadow 1.2s ease;
}

.chrome {
  height: 40px;
  flex: 0 0 40px;
  background: #e8e8ec;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border-bottom: 1px solid #d3d3d9;
  transition: background 1s steps(4);
}
.dot { width: 12px; height: 12px; border-radius: 50%; display: inline-block; }
.dot--r { background: #ff5f57; }
.dot--y { background: #febc2e; }
.dot--g { background: #28c840; }
.omnibar {
  margin-left: 10px;
  flex: 1;
  height: 22px;
  background: #fff;
  border-radius: 11px;
  border: 1px solid #d3d3d9;
  display: flex;
  align-items: center;
  padding: 0 12px;
  font-size: 12px;
  color: #6a6a72;
  font-family: "VT323", monospace;
  letter-spacing: .5px;
  overflow: hidden;
  white-space: nowrap;
}

/* ---- Viewport: the canvas everything renders into ---------------------- */
.viewport {
  position: relative;
  flex: 1;
  overflow: hidden;
  background: var(--paper);
  transition: background 1.2s steps(6);
}
.backdrop { position: absolute; inset: 0; }
.fx { position: absolute; inset: 0; pointer-events: none; z-index: 40; }

/* =========================================================================
   THE HERO PIXEL
   Outer element = position (moved by JS with stepped transitions).
   Inner .pixel-core = personality (jitter, wobble, squash).
   ========================================================================= */
.pixel {
  position: absolute;
  left: 0; top: 0;
  width: var(--px);
  height: var(--px);
  z-index: 30;
  /* Stepped motion is the whole trick: transforms snap frame-to-frame. */
  transition:
    transform var(--move-dur, 620ms) steps(var(--move-steps, 7)),
    width 300ms steps(4),
    height 300ms steps(4),
    opacity 240ms steps(3);
  transform: translate(480px, 270px);
}
.pixel-core {
  width: 100%;
  height: 100%;
  background: var(--hero);
  box-shadow: 0 0 0 0 rgba(255,93,59,0);
  animation: jitter 0.42s steps(2) infinite;
}
/* Constant tiny handmade jitter */
@keyframes jitter {
  0%   { transform: translate(0, 0) rotate(0deg); }
  50%  { transform: translate(0.6px, -0.6px) rotate(0.6deg); }
  100% { transform: translate(-0.4px, 0.5px) rotate(-0.5deg); }
}
/* Personality states toggled by JS */
.pixel--squash .pixel-core { animation: squash 360ms steps(5) 1; }
@keyframes squash {
  0%   { transform: scale(1, 1); }
  30%  { transform: scale(1.5, 0.55) translateY(4px); }
  60%  { transform: scale(0.8, 1.25); }
  100% { transform: scale(1, 1); }
}
.pixel--wobble .pixel-core { animation: wobble 0.5s steps(3) infinite; }
@keyframes wobble {
  0%   { transform: rotate(-8deg); }
  50%  { transform: rotate(9deg); }
  100% { transform: rotate(-8deg); }
}
.pixel--stretch { --px: 15px; }
.pixel--stretch .pixel-core { transform: scaleY(1.8) scaleX(0.7); transition: transform 200ms steps(3); }
.pixel--glow .pixel-core { box-shadow: 0 0 14px 4px rgba(255,93,59,.8); }
.pixel--hidden { opacity: 0; }
.pixel--big { --px: 34px; }
.pixel--tiny { --px: 9px; }

/* =========================================================================
   CAPTIONS (narration)
   ========================================================================= */
.caption {
  position: fixed;
  bottom: clamp(68px, 10vh, 92px);
  left: 50%;
  transform: translateX(-50%);
  max-width: min(760px, 86vw);
  text-align: center;
  color: #f4f1e8;
  font-size: clamp(17px, 2.4vw, 26px);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: .1px;
  text-shadow: 0 2px 18px rgba(0,0,0,.9), 0 0 2px rgba(0,0,0,.9);
  opacity: 0;
  z-index: 60;
  pointer-events: none;
}
.caption.show { opacity: 1; transition: opacity 260ms steps(3); }
.caption.hide { opacity: 0; transition: opacity 380ms steps(4); }
.caption em { font-style: normal; color: var(--hero); }

/* =========================================================================
   PLAYBACK CONTROLS
   ========================================================================= */
.controls {
  position: fixed;
  left: 50%;
  bottom: 18px;
  z-index: 80;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
  color: #d7d4cb;
  background: rgba(12,12,16,.82);
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 8px 30px rgba(0,0,0,.28);
  transform: translateX(-50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms steps(2);
}
.theatre.is-started .controls { opacity: 1; pointer-events: auto; }
.theatre.is-paused .browser *,
.theatre.is-paused .grain { animation-play-state: paused !important; }
.control {
  display: grid;
  width: 34px;
  height: 30px;
  place-items: center;
  padding: 0;
  color: inherit;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 0;
  cursor: pointer;
}
.control:hover, .control:focus-visible {
  color: #fff;
  background: rgba(255,255,255,.09);
  border-color: rgba(255,255,255,.18);
  outline: none;
}
.control:active { transform: translateY(1px); }
.icon { width: 17px; height: 17px; fill: currentColor; }
.icon--play { display: none; }
.is-paused .icon--pause { display: none; }
.is-paused .icon--play { display: block; }
.time {
  min-width: 42px;
  padding: 0 4px;
  color: #8f8e94;
  font-family: "VT323", monospace;
  font-size: 17px;
  letter-spacing: 1px;
  text-align: center;
}

/* =========================================================================
   OVERLAYS: grain + vignette
   ========================================================================= */
.vignette {
  position: fixed; inset: 0; z-index: 55; pointer-events: none;
  background: radial-gradient(130% 130% at 50% 45%, transparent 55%, rgba(0,0,0,.55) 100%);
}
.grain {
  position: fixed; inset: -50%; z-index: 56; pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  animation: grainshift 0.6s steps(3) infinite;
}
@keyframes grainshift {
  0% { transform: translate(0,0); }
  50% { transform: translate(-8px, 6px); }
  100% { transform: translate(5px, -7px); }
}

/* =========================================================================
   START POSTER
   ========================================================================= */
.start {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-content: center; justify-items: center; gap: 22px;
  background: #050506;
  border: 0; cursor: pointer;
  transition: opacity 700ms steps(5);
}
.start.gone { opacity: 0; pointer-events: none; }
.start__pixel {
  width: 26px; height: 26px; background: var(--hero);
  animation: jitter 0.42s steps(2) infinite, breathe 2.4s steps(8) infinite;
}
@keyframes breathe { 0%,100%{ box-shadow: 0 0 0 0 rgba(255,93,59,.0);} 50%{ box-shadow: 0 0 30px 8px rgba(255,93,59,.55);} }
.start__label {
  color: #7c7c86; font-family: "VT323", monospace; font-size: 22px; letter-spacing: 3px;
}

/* =========================================================================
   SMALL-SCREEN NOTICE
   ========================================================================= */
.mobile-notice { display: none; }

@media (max-width: 700px), (max-height: 500px) and (pointer: coarse) {
  .fit, .caption, .controls, .start, .grain, .vignette { display: none; }
  .mobile-notice {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: grid;
    align-content: center;
    justify-items: start;
    gap: 16px;
    padding: max(32px, env(safe-area-inset-top)) 28px max(32px, env(safe-area-inset-bottom));
    color: #e9e5da;
    background:
      linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
      linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px),
      #0b0b0e;
    background-size: 18px 18px;
  }
  .mobile-notice::after {
    content: "";
    position: absolute;
    right: -42px;
    bottom: -58px;
    width: 180px;
    height: 180px;
    border: 1px solid rgba(255,93,59,.28);
    transform: rotate(7deg);
  }
  .mobile-notice__pixel {
    width: 22px;
    height: 22px;
    background: var(--hero);
    animation: jitter .42s steps(2) infinite, breathe 2.4s steps(8) infinite;
  }
  .mobile-notice__eyebrow {
    margin: 4px 0 -8px;
    color: #ff8067;
    font-family: "VT323", monospace;
    font-size: 18px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
  }
  .mobile-notice h1 {
    max-width: 320px;
    margin: 0;
    font-size: clamp(40px, 13vw, 64px);
    font-weight: 600;
    line-height: .94;
    letter-spacing: -2px;
  }
  .mobile-notice p:last-child {
    max-width: 430px;
    margin: 4px 0 0;
    color: #a4a1a0;
    font-family: "VT323", monospace;
    font-size: 20px;
    line-height: 1.3;
  }
}

/* =========================================================================
   ACT ONE — THE WEB WAS A PLACE
   ========================================================================= */

/* Blank browser paper */
.scene-blank { background: var(--paper); }

/* --- GeoCities / dragon homepage --- */
.scene-geo {
  background:
    repeating-linear-gradient(45deg, #1a0033 0 22px, #24004d 22px 44px);
  color: #fbe94b;
  font-family: "Comic Neue", "Comic Sans MS", cursive;
  overflow: hidden;
}
.scene-geo::before { /* star field */
  content: "";
  position: absolute; inset: 0;
  background-image:
    radial-gradient(2px 2px at 20% 30%, #fff, transparent),
    radial-gradient(2px 2px at 70% 20%, #7cf, transparent),
    radial-gradient(3px 3px at 40% 70%, #ff5, transparent),
    radial-gradient(2px 2px at 85% 65%, #f7f, transparent),
    radial-gradient(2px 2px at 55% 45%, #fff, transparent),
    radial-gradient(3px 3px at 12% 80%, #6f6, transparent),
    radial-gradient(2px 2px at 90% 40%, #fff, transparent);
  animation: twinkle 0.5s steps(2) infinite;
}
@keyframes twinkle { 0%{opacity:.4;} 50%{opacity:1;} 100%{opacity:.4;} }
.geo-title {
  position: absolute; top: 26px; left: 0; right: 0; text-align: center;
  font-size: 42px; font-weight: 700;
  background: linear-gradient(90deg,#ff2d95,#ffd12d,#2dffa3,#2d8bff,#ff2d95);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: huerot 3s steps(6) infinite, blink 0.9s steps(1) infinite;
  text-shadow: 3px 3px 0 rgba(0,0,0,.35);
}
@keyframes huerot { to { filter: hue-rotate(360deg); } }
@keyframes blink { 0%,60%{opacity:1;} 61%,100%{opacity:.25;} }
.geo-sub {
  position: absolute; top: 84px; left: 0; right: 0; text-align: center;
  font-size: 18px; color: #7cf; text-decoration: underline;
}
/* crude pixel dragon */
.dragon {
  position: absolute; left: 90px; top: 150px;
  animation: dragonsway 0.6s steps(2) infinite;
}
@keyframes dragonsway { 0%{transform:translateY(0) rotate(-2deg);} 50%{transform:translateY(-6px) rotate(2deg);} 100%{transform:translateY(0) rotate(-2deg);} }
.dragon__body { width: 120px; height: 60px; background: #2ec13a; border-radius: 30px 40px 20px 40px; box-shadow: 4px 4px 0 rgba(0,0,0,.3); }
.dragon__head { position: absolute; right: -34px; top: -6px; width: 48px; height: 40px; background: #2ec13a; border-radius: 24px 8px 24px 8px; }
.dragon__eye { position: absolute; right: 10px; top: 8px; width: 8px; height: 8px; background: #fff; }
.fire {
  position: absolute; right: -110px; top: 8px; display: flex; gap: 3px;
}
.fire span { width: 14px; height: 14px; border-radius: 2px; animation: firepulse 0.28s steps(2) infinite; }
.fire span:nth-child(1){ background:#ffe14d; } .fire span:nth-child(2){ background:#ff9d2e; animation-delay:.08s;}
.fire span:nth-child(3){ background:#ff5d3b; animation-delay:.16s;} .fire span:nth-child(4){ background:#ff2e2e; animation-delay:.24s;}
@keyframes firepulse { 0%{transform:scale(1) translateX(0); opacity:1;} 50%{transform:scale(1.4) translateX(6px); opacity:.7;} 100%{transform:scale(1) translateX(0); opacity:1;} }

/* --- Under Construction sign --- */
.scene-construction { background: #000; display: grid; place-items: center; }
.construction {
  width: 420px; padding: 26px 20px; text-align: center;
  background: repeating-linear-gradient(45deg,#f4c20d 0 26px,#111 26px 52px);
  border: 6px solid #111;
  animation: signblink 0.8s steps(1) infinite;
}
@keyframes signblink { 0%,70%{filter:brightness(1);} 71%,100%{filter:brightness(1.6);} }
.construction__inner {
  background: #f4c20d; border: 4px dashed #111; padding: 14px;
  font-family: "VT323", monospace;
}
.construction__inner h2 { margin: 0; font-size: 34px; color: #111; letter-spacing: 2px; }
.construction__inner p { margin: 6px 0 0; font-size: 20px; color: #6b4c00; }
.hardhat { font-size: 40px; display:inline-block; animation: dig 0.5s steps(2) infinite; }
@keyframes dig { 0%{transform:rotate(-12deg);} 50%{transform:rotate(12deg);} 100%{transform:rotate(-12deg);} }

/* --- Visitor counter --- */
.scene-counter { background: #0a0a1a; display: grid; place-items: center; color:#0f0; }
.counter-wrap { text-align: center; font-family: "VT323", monospace; }
.counter-wrap .label { color:#5cf; font-size: 22px; margin-bottom: 12px; letter-spacing: 2px; }
.odometer { display: inline-flex; gap: 4px; }
.odometer .digit {
  width: 40px; height: 60px; background:#000; color:#39ff14; border:2px solid #143;
  display:grid; place-items:center; font-size: 44px; line-height: 1;
  box-shadow: inset 0 0 12px rgba(57,255,20,.4);
}

/* --- Web ring --- */
.scene-webring { background: radial-gradient(circle at 50% 50%, #201033, #05010a); display:grid; place-items:center; }
.ring {
  position: relative; width: 300px; height: 300px; border: 3px dashed #8a5cff; border-radius:50%;
  animation: spin 6s steps(24) infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.ring .node {
  position:absolute; width:44px; height:30px; margin:-15px 0 0 -22px; left:50%; top:50%;
  background: linear-gradient(#fff,#cfe); border:2px solid #8a5cff; font: 11px/30px "VT323",monospace;
  text-align:center; color:#513; border-radius:4px;
}
.ring-label { position:absolute; color:#b79cff; font-family:"VT323",monospace; font-size:20px; bottom:40px; width:100%; text-align:center; }

/* --- Winamp-style visualizer --- */
.scene-winamp { background: linear-gradient(#20242e,#0b0d12); display:flex; align-items:center; justify-content:center; }
.player {
  width: 460px; background:#2b2f3a; border:2px solid #565f74; border-radius:4px; padding:12px;
  box-shadow: inset 0 0 0 1px #1a1d24, 0 8px 30px rgba(0,0,0,.5);
}
.player__bar { height:14px; background:linear-gradient(90deg,#7a86ff,#3a3f52); margin-bottom:10px; display:flex; align-items:center; padding:0 6px; }
.player__bar span { font:10px "VT323",monospace; color:#dfe3ff; letter-spacing:1px; }
.viz { display:flex; align-items:flex-end; gap:4px; height:120px; padding:6px; background:#05070c; border:1px solid #3a4152; }
.viz i {
  display:block; width:12px; background:linear-gradient(#39ff14,#ffe14d,#ff5d3b);
  animation: eq 0.4s steps(4) infinite;
}
@keyframes eq { 0%{height:14px;} 50%{height:110px;} 100%{height:30px;} }

/* --- MySpace glitter profile --- */
.scene-myspace { background:#0a0a12; color:#fff; overflow:hidden; }
.myspace-top { height:56px; background:linear-gradient(90deg,#1e3a8a,#2563eb); display:flex; align-items:center; padding:0 16px; font-weight:700; letter-spacing:1px; }
.myspace-body { display:flex; gap:14px; padding:16px; }
.ms-card { background:#12121f; border:1px solid #2a2a44; padding:12px; }
.ms-avatar { width:120px; height:120px; background:conic-gradient(#ff2d95,#ffd12d,#2dffa3,#2d8bff,#ff2d95); }
.ms-avatar b { display:block; width:calc(100% - 12px); height:calc(100% - 12px); background:#0a0a12; margin:6px; }
.ms-name { margin-top:8px; font-family:"Comic Neue",cursive; color:#ff6ad5; font-size:20px; }
.ms-status { font-size:12px; color:#9aa; }
.ms-about { flex:1; font-family:"Comic Neue",cursive; color:#cfe; line-height:1.5; }
.ms-about h3 { color:#ffd12d; }

/* --- Custom cursor --- */
.scene-cursor { background:#e8f0ff; display:grid; place-items:center; }
.cursor-note { font-family:"VT323",monospace; color:#456; font-size:24px; text-align:center; }
.fake-cursor {
  position:absolute; width:0;height:0;
  border-left:16px solid #111; border-bottom:11px solid transparent; transform: rotate(-12deg);
  animation: cursormove 4s steps(28) infinite;
}
@keyframes cursormove {
  0%{ left:120px; top:120px;} 25%{ left:600px; top:180px;}
  50%{ left:500px; top:360px;} 75%{ left:220px; top:300px;} 100%{ left:120px; top:120px;}
}

/* --- Forum signature --- */
.scene-forum { background:#dfe6ee; color:#1b2733; font-family:"VT323",monospace; padding:22px; }
.post { background:#fff; border:1px solid #b9c4d0; margin-bottom:10px; display:flex; }
.post__user { width:130px; background:#eef3f8; border-right:1px solid #b9c4d0; padding:10px; font-size:14px; color:#3a5; }
.post__body { padding:10px; font-size:16px; }
.sig { margin-top:10px; border-top:1px dashed #9ab; padding-top:6px; font-size:13px; color:#a05; }
.sig .rainbow { background:linear-gradient(90deg,#ff2d95,#ffd12d,#2dffa3,#2d8bff); -webkit-background-clip:text; background-clip:text; color:transparent; }

/* --- Early blog + notification --- */
.scene-blog { background:#fffdf5; color:#333; padding:24px 30px; font-family: Georgia, serif; }
.blog-title { font-size:30px; color:#7a3; border-bottom:2px solid #dda; padding-bottom:8px; }
.blog-date { color:#999; font-size:13px; margin-top:4px; font-style:italic; }
.blog-text { margin-top:14px; line-height:1.6; color:#555; max-width:560px; }
.notif {
  position:absolute; right:26px; top:22px; background:#ff3b3b; color:#fff; font-family:"VT323",monospace;
  padding:6px 12px; border-radius:14px; font-size:18px; animation: notifpop 0.7s steps(2) infinite;
}
@keyframes notifpop { 0%,100%{transform:scale(1);} 50%{transform:scale(1.18);} }

/* --- First CSS hover heart --- */
.scene-hover { background:#fff0f5; display:grid; place-items:center; }
.hover-demo { text-align:center; font-family:"VT323",monospace; color:#a25; }
.heart {
  font-size:70px; display:inline-block; transition: transform 300ms steps(4);
  animation: heartbeat 1.1s steps(3) infinite;
}
@keyframes heartbeat { 0%,100%{ transform:scale(1);} 40%{ transform:scale(1.35);} }
.hover-demo code { display:block; margin-top:12px; font-size:16px; color:#c39; }

/* =========================================================================
   ACT TWO — THE GREAT COMPRESSION
   ========================================================================= */
.scene-grid { background:#fafafa; padding:24px; }
.grid {
  display:grid; grid-template-columns: repeat(4, 1fr); gap:14px; height:100%;
}
.card {
  background:#fff; border:1px solid #eee; border-radius:10px; padding:14px;
  display:flex; flex-direction:column; gap:8px;
}
.card .thumb { height:52px; background:#eef0f3; border-radius:6px; }
.card .line { height:8px; background:#e9ebee; border-radius:4px; }
.card .line.short { width:60%; }

/* Feed */
.scene-feed { background:#f2f3f5; overflow:hidden; }
.feed { position:absolute; left:50%; top:0; transform:translateX(-50%); width:420px; }
.feed .item {
  background:#fff; border:1px solid #e6e8eb; border-radius:12px; margin:14px 0; padding:14px;
  display:flex; flex-direction:column; gap:10px;
}
.feed .head { display:flex; align-items:center; gap:10px; }
.feed .ava { width:34px; height:34px; border-radius:50%; background:#dfe2e6; }
.feed .line { height:9px; background:#e9ebee; border-radius:5px; }
.feed .pic { height:150px; background:#e4e7ea; border-radius:8px; }
.feed.rolling { animation: feedroll linear infinite; }
@keyframes feedroll { to { transform: translate(-50%, -60%); } }

/* Chatbot */
.scene-chat { background:#ffffff; display:flex; flex-direction:column; }
.chat-head { height:44px; border-bottom:1px solid #ececf0; display:flex; align-items:center; padding:0 18px; gap:10px; color:#3a3a40; font-weight:600; font-size:15px; }
.chat-head .status { width:9px; height:9px; border-radius:50%; background:#28c840; }
.chat-body { flex:1; padding:26px 22% 20px; display:flex; flex-direction:column; gap:16px; justify-content:flex-end; }
.bubble { max-width:78%; padding:12px 16px; border-radius:16px; font-size:15px; line-height:1.5; opacity:0; }
.bubble.show { opacity:1; transition: opacity 200ms steps(3); }
.bubble.user { align-self:flex-end; background:#ff5d3b; color:#fff; border-bottom-right-radius:4px; }
.bubble.bot { align-self:flex-start; background:#f3f3f6; color:#222; border-bottom-left-radius:4px; }
.chat-input {
  margin: 0 22% 22px; height:46px; border:1px solid #e2e2e8; border-radius:24px;
  display:flex; align-items:center; padding:0 18px; color:#9a9aa2; font-size:14px; gap:2px;
}
.chat-caret { width:2px; height:20px; background:#111; animation: caret 1s steps(1) infinite; }
@keyframes caret { 0%,50%{opacity:1;} 51%,100%{opacity:0;} }

/* =========================================================================
   ACT THREE — THE WEB CAN STILL BE MADE
   ========================================================================= */
.scene-void { background:#0c0c10; }

/* Mini handmade pages that pop into being during the rebuild */
.minisite {
  position:absolute; border-radius:6px; overflow:hidden; opacity:0;
  box-shadow: 0 6px 20px rgba(0,0,0,.35); border:2px solid rgba(0,0,0,.15);
  transform: scale(.4); transform-origin:center;
}
.minisite.pop { opacity:1; transform: scale(1); transition: transform 420ms steps(5), opacity 300ms steps(4); }
.minisite .mtitle { font-size:12px; padding:5px 8px; font-weight:700; }
.minisite .mbody { padding:8px; font-size:9px; line-height:1.4; }

.ms-home   { background:#fff3d6; color:#9a5b00; }
.ms-home .mtitle{ background:#ffce54; }
.ms-hobby  { background:#e6ffe6; color:#0a6b1f; font-family:"Comic Neue",cursive; }
.ms-hobby .mtitle{ background:#7bd67b; }
.ms-photo  { background:#111; color:#eee; }
.ms-photo .mtitle{ background:#000; color:#fff; }
.ms-photo .shots{ display:grid; grid-template-columns:repeat(3,1fr); gap:3px; }
.ms-photo .shots i{ display:block; height:14px; background:linear-gradient(135deg,#556,#99a); }
.ms-experiment { background:#05010a; color:#0ff; font-family:"VT323",monospace; }
.ms-experiment .mtitle{ background:#7000ff; color:#fff; }
.ms-experiment .blobs{ display:flex; gap:4px; }
.ms-experiment .blobs b{ width:14px; height:14px; border-radius:50%; background:#0ff; animation:eq .5s steps(3) infinite; }
.ms-game   { background:#1a1030; color:#ffd12d; font-family:"VT323",monospace; text-align:center; }
.ms-game .mtitle{ background:#ff2d95; color:#fff; }
.ms-game .sprite{ width:14px;height:14px;background:#ffd12d; margin:4px auto; image-rendering:pixelated; }
.ms-blog   { background:#fffdf5; color:#555; font-family:Georgia,serif; }
.ms-blog .mtitle{ background:#a3d; color:#fff; }
.ms-kid    { background:#fff; color:#333; font-family:"VT323",monospace; }
.ms-kid .mtitle{ background:#39c; color:#fff; }
.ms-kid .mbody{ color:#e33; }
.ms-frog   { background:#dff5d0; color:#2b6b1f; font-family:"Comic Neue",cursive; text-align:center; }
.ms-frog .mtitle{ background:#5cb85c; color:#fff; }
.ms-frog .frog{ font-size:22px; }
.ms-delight{ background:conic-gradient(#ff2d95,#ffd12d,#2dffa3,#2d8bff,#ff2d95); color:#fff; text-align:center; }
.ms-delight .mtitle{ background:rgba(0,0,0,.35); }
.ms-delight .spin{ font-size:22px; display:inline-block; animation:spin 2s steps(8) infinite; }

/* The final mosaic — a webpage built from thousands of pixels */
.mosaic {
  position:absolute; inset:0; display:grid; opacity:0;
  transform: scale(46);              /* start zoomed into a single cell */
  transform-origin: 49% 49%;
  transition: opacity 400ms steps(3), transform 1700ms steps(12);
}
.mosaic.show { opacity:1; transform: scale(1); }
.mosaic i { display:block; }

/* =========================================================================
   TITLE CARD
   ========================================================================= */
.titlecard {
  position:absolute; inset:0; z-index:45; display:grid; place-content:center; justify-items:center; gap:20px;
  background:#0a0a0e; opacity:0; pointer-events:none;
  transition: opacity 900ms steps(6);
}
.titlecard.show { opacity:1; }
.titlecard__pixel { width:20px; height:20px; background:var(--hero); animation: jitter .42s steps(2) infinite, breathe 2.6s steps(8) infinite; }
.titlecard__title {
  margin:0; text-align:center; color:#f4f1e8; font-weight:600; line-height:1.15;
  font-size: clamp(30px, 6vw, 58px); letter-spacing:.5px;
}
.titlecard__tag {
  margin:0; color:#8a8a94; font-size: clamp(14px,2vw,19px); text-align:center; max-width:560px; min-height:1.4em;
  font-family:"VT323",monospace; letter-spacing:1px;
}

/* Reduced motion: dampen the busiest infinite animations, keep the story. */
@media (prefers-reduced-motion: reduce) {
  .grain, .viz i, .fire span, .ring, .fake-cursor { animation-duration: 2s; }
}
