:root {
    --void: #12082b;
    --void-2: #0b0520;
    --panel: #1e1042;
    --panel-2: #2a1858;
    --ink: #f3eeff;
    --dim: #9d8ed0;
    --gold: #ffc233;
    --gold-ink: #2a1600;
    --cyan: #45e0ff;
    --cyan-ink: #002733;
    --rose: #ff4f79;
    --grid: rgba(157, 142, 208, 0.2);
    --arc: "Press Start 2P", ui-monospace, monospace;
    --jp: "DotGothic16", "Hiragino Kaku Gothic ProN", "Yu Gothic", system-ui, sans-serif;
    --en: "Archivo", ui-sans-serif, system-ui, sans-serif;
  }

  * { box-sizing: border-box; }

  html, body { height: 100%; }

  body {
    margin: 0;
    background: var(--void-2);
    color: var(--ink);
    font-family: var(--jp);
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
    display: flex;
    justify-content: center;
  }

  .cab {
    position: relative;
    width: 100%;
    max-width: 430px;
    height: 100svh;
    display: flex;
    flex-direction: column;
    background: var(--void);
    border-left: 1px solid var(--grid);
    border-right: 1px solid var(--grid);
    overflow: hidden;
  }

  .cab, .line, .w, .sky, .prompt, .falling, .pile, .rock {
    user-select: none;
    -webkit-user-select: none;
  }

  .gap, .pad button, .line {
    touch-action: manipulation;
  }

  /* CRT scanlines */
  .cab::after {
    content: "";
    position: absolute; inset: 0; z-index: 60; pointer-events: none;
    background: repeating-linear-gradient(to bottom, rgba(0,0,0,0.22) 0 1px, transparent 1px 3px);
    mix-blend-mode: multiply;
  }

  /* ---------- HUD ---------- */
  .hud {
    display: flex; align-items: center; gap: 5px;
    padding: 9px 6px; background: var(--void-2);
    border-bottom: 2px solid var(--grid); flex: none;
  }
  .hud .cell { display: flex; flex-direction: column; gap: 3px; }
  .hud .k { font-family: var(--arc); font-size: 6px; color: var(--dim); letter-spacing: 0.06em; }
  .hud .v { display: inline-block; font-family: var(--arc); font-size: 11px; color: var(--gold); font-variant-numeric: tabular-nums; }
  .hud .v.cy { color: var(--cyan); }
  #hHits { font-size: 13px; }
  .snd {
    flex: none; margin-left: 2px; padding: 5px 6px; font-size: 13px; line-height: 1;
    border-radius: 4px; border: 1px solid var(--grid); background: var(--panel-2);
    color: var(--cyan); box-shadow: none; font-family: var(--jp); cursor: pointer;
  }
  .snd.off { color: var(--dim); text-decoration: line-through; }
  #btnPause { margin-left: auto; }

  /* juice */
  .cab.shake { animation: shake 240ms ease-out; }
  .bump { animation: bump 380ms ease-out; }
  @keyframes bump {
    50% { transform: scale(1.35); color: var(--gold); }
  }
  @keyframes shake {
    20% { transform: translate(-2px, 3px); }
    40% { transform: translate(3px, -2px); }
    60% { transform: translate(-3px, 1px); }
    80% { transform: translate(2px, 2px); }
  }
  .spark {
    position: absolute; width: 6px; height: 6px; border-radius: 1px;
    background: var(--cyan); z-index: 5; pointer-events: none;
    animation: fly 620ms cubic-bezier(.2, .7, .4, 1) forwards;
  }
  @keyframes fly {
    to { transform: translate(var(--dx), var(--dy)) rotate(200deg) scale(0.3); opacity: 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .cab.shake, .cab.shake.hard, .rock.cracked, .rock.crumble { animation: none; }
    .spark, .chunk, .shard, .pop { display: none; }
    .rock.shattering { animation: none; }
  }

  /* ---------- prompt ---------- */
  /* The Japanese prompt floats just above the English line as a translucent
     overlay: clearly readable, but falling words pass over it and taps go
     through it - it takes part in nothing. */
  /* Below the danger line so the eye reads: NEXT, the line, the meaning,
     then the fall. Its color doubles as the rock warning for this sentence. */
  .prompt {
    position: absolute; left: 8px; right: 8px; top: 182px; z-index: 2;
    pointer-events: none;
    padding: 7px 10px; border-radius: 6px;
    background: rgba(11, 5, 32, 0.55);
    color: var(--ink); opacity: 0.86;
    font-size: 15px; line-height: 1.5; text-wrap: balance; text-align: left;
    text-shadow: 0 1px 3px rgba(11, 5, 32, 0.9);
  }
  .prompt-rock-badge{display:inline-flex;width:26px;height:24px;margin-left:7px;vertical-align:middle;align-items:center;justify-content:center;position:relative;clip-path:polygon(12% 23%,32% 4%,68% 7%,89% 27%,100% 69%,80% 95%,20% 92%,0 65%);background:var(--rock-edge);color:var(--rock-label);font:7px/1 var(--arc);text-shadow:1px 1px 0 var(--rock-shadow),-1px -1px 0 var(--rock-shadow);filter:drop-shadow(0 0 3px var(--rock-aura));pointer-events:none}
  .prompt-rock-badge::before{content:"";position:absolute;inset:2px;z-index:-1;clip-path:inherit;background-image:var(--rock-vein),radial-gradient(circle at 28% 30%,rgba(255,255,255,.2) 0 2px,transparent 3px),radial-gradient(circle at 72% 68%,rgba(0,0,0,.3) 0 2px,transparent 3px),linear-gradient(180deg,var(--rock-top),var(--rock-mid) 48%,var(--rock-bottom))}
  .prompt-rock-badge--wide{font-size:6px}.prompt-rock-badge--infinite{font-size:11px}
  .prompt--bronze, .prompt--steel, .prompt--obsidian, .prompt--eternal {
    border: 2px solid var(--warn-edge); background: rgba(11, 5, 32, 0.72);
    animation: promptWarn var(--warn-speed, 1100ms) steps(2) infinite;
  }
  .prompt--bronze { --warn-edge: #e08a47; --warn-glow: rgba(224,138,71,.7); --warn-speed: 1200ms; color: #ffcf9e; text-shadow: 0 0 8px rgba(224,138,71,.55), 0 1px 3px rgba(11,5,32,.9); }
  .prompt--steel { --warn-edge: #a9c9e8; --warn-glow: rgba(112,169,217,.75); --warn-speed: 1000ms; color: #cfe6ff; text-shadow: 0 0 8px rgba(112,169,217,.55), 0 1px 3px rgba(11,5,32,.9); }
  .prompt--obsidian { --warn-edge: #ff5668; --warn-glow: rgba(255,49,79,.85); --warn-speed: 700ms; color: #ff9aa8; text-shadow: 0 0 9px rgba(255,49,79,.6), 0 1px 3px rgba(11,5,32,.9); }
  .prompt--eternal { --warn-edge: #97f6ff; --warn-glow: rgba(151,246,255,.9); --warn-speed: 550ms; color: #e8ffff; text-shadow: 0 0 10px rgba(151,246,255,.8), 0 1px 3px rgba(11,5,32,.9); }
  @keyframes promptWarn {
    50% { box-shadow: 0 0 14px var(--warn-glow), inset 0 0 9px var(--warn-glow); border-color: #fff; }
  }
  .falling--bronze, .falling--steel { animation: fallWarn 1000ms steps(2) infinite; }
  .falling--obsidian { animation: fallWarn 700ms steps(2) infinite; }
  .falling--eternal { animation: fallWarn 550ms steps(2) infinite; }
  @keyframes fallWarn { 50% { filter: brightness(1.45); } }
  .line--bronze .w { border-color: #e08a47; background: rgba(224,138,71,.16); color: #ffe3c4; }
  .line--steel .w { border-color: #a9c9e8; background: rgba(112,169,217,.16); color: #e7f3ff; }
  .line--obsidian .w { border-color: #ff5668; background: rgba(255,49,79,.14); color: #ffd4da; }
  .line--eternal .w { border-color: #97f6ff; background: rgba(151,246,255,.13); color: #eaffff; }

  /* ---------- sky ---------- */
  .sky {
    /* min-height 0 so the rocks can squeeze the sky; the MIN_SKY check in JS
       ends the game before anything is clipped. */
    position: relative; flex: 1 1 auto; min-height: 0;
    background:
      repeating-linear-gradient(to right, var(--grid) 0 1px, transparent 1px 28px),
      repeating-linear-gradient(to bottom, var(--grid) 0 1px, transparent 1px 28px),
      var(--void-2);
    overflow: hidden;
  }
  /* The floor rises toward this line as rocks pile up. When they meet, it is
     over — so the line sits exactly MIN_SKY from the top of the sky. */
  .danger {
    /* Clamped to the sky's floor so the line is still on screen at the moment
       the stack crosses it. */
    position: absolute; left: 0; right: 0;
    top: min(var(--danger, 172px), calc(100% - 2px));
    z-index: 2; pointer-events: none;
    border-top: 2px dashed var(--rose);
  }
  .sky.squeeze .danger { animation: dblink 560ms steps(2) infinite; }
  @keyframes dblink { 50% { opacity: 0.4; } }

  .guide {
    position: absolute; top: 0; bottom: 0; width: 30px; transform: translateX(-50%);
    background: linear-gradient(to bottom, rgba(255,194,51,0), rgba(255,194,51,0.16));
    border-left: 1px dashed rgba(255,194,51,0.5); border-right: 1px dashed rgba(255,194,51,0.5);
    transition: left 110ms cubic-bezier(.2,.9,.3,1); z-index: 1;
  }
  .falling {
    position: absolute; top: 0; transform: translateX(-50%);
    padding: 7px 12px; border-radius: 4px;
    background: var(--gold); color: var(--gold-ink);
    border: 2px solid #fff3cf;
    box-shadow: 0 0 0 2px var(--gold-ink), 0 0 18px rgba(255,194,51,0.55);
    font-family: var(--en); font-size: 19px; font-weight: 900; line-height: 1;
    transition: left 110ms cubic-bezier(.2,.9,.3,1);
    z-index: 3; white-space: nowrap;
  }
  .falling.ok { background: var(--cyan); color: var(--cyan-ink); border-color: #d4f8ff; box-shadow: 0 0 0 2px #002733, 0 0 22px rgba(69,224,255,0.65); }
  .falling.ng { background: var(--rose); color: #fff; border-color: #ffd0da; box-shadow: 0 0 0 2px #3d0011, 0 0 22px rgba(255,79,121,0.6); }
  .falling.falling--bronze { border-color: #e08a47; box-shadow: 0 0 0 2px #643116, 0 0 20px rgba(224,138,71,.72); }
  .falling.falling--steel { border-color: #a9c9e8; box-shadow: 0 0 0 2px #344a64, 0 0 20px rgba(112,169,217,.7); }
  .falling.falling--obsidian { border-color: #ff5668; box-shadow: 0 0 0 2px #2a0a28, 0 0 22px rgba(255,49,79,.72); }
  .falling.falling--eternal { border-color: #e8ffff; box-shadow: 0 0 0 2px #123b4d, 0 0 24px rgba(151,246,255,.88); }
  .falling.hide { opacity: 0; }

  /* ---------- sentence ---------- */
  .line {
    flex: none; display: flex; flex-wrap: wrap; align-items: center;
    gap: 2px 3px; padding: 12px 10px; min-height: 66px;
    background: var(--panel-2); border-top: 2px solid var(--gold);
  }
  .w {
    padding: 5px 7px; border-radius: 3px;
    background: rgba(69, 224, 255, 0.14); border: 1px solid rgba(69, 224, 255, 0.35);
    color: var(--ink); font-family: var(--en);
    font-size: clamp(13px, 3.7vw, 17px); font-weight: 700; line-height: 1.15;
  }
  .w.punct { background: none; border: 0; padding: 0 2px 0 0; }
  .w.ok { background: var(--cyan); border-color: #d4f8ff; color: var(--cyan-ink); animation: pop 240ms ease; }
  .w.ng { background: var(--rose); border-color: #ffd0da; color: #fff; }
  @keyframes pop { 0% { transform: scale(0.6); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
  .gap {
    position: relative; z-index: 1;
    width: 9px; height: 32px; flex: none; border-radius: 3px; padding: 0;
    background: transparent; border: 1px dashed transparent; cursor: pointer;
    transition: width 110ms cubic-bezier(.2,.9,.3,1), background 110ms;
  }
  /* invisible hit area: a 9px slot is untappable with a thumb, so the touch
     target reaches over the neighboring (inert) word chips and line padding */
  .gap::before {
    content: ""; position: absolute; inset: -10px -7px;
  }
  /* the landing slot must read instantly, even mid-panic */
  .gap.aim {
    width: 40px; background: rgba(255, 194, 51, 0.30); border-color: var(--gold);
    box-shadow: 0 0 12px rgba(255, 194, 51, 0.55);
    animation: aimpulse 640ms ease-in-out infinite;
  }
  @keyframes aimpulse { 50% { background: rgba(255, 194, 51, 0.55); } }
  /* long sentences shrink word chips without shrinking their landing slots */
  .line.dense .w { font-size: 14px; padding: 4px 5px; }
  .line.denser { gap: 1px 2px; }
  .line.denser .w { font-size: 13px; padding: 3px 4px; }
  .line.denser .gap.aim { width: 32px; }
  .gap:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  .line.clear { animation: flash 420ms steps(2) 2 forwards; }
  @keyframes flash { 50% { background: var(--cyan); } }

  /* ---------- rocks ---------- */
  .pile { flex: none; background: var(--void-2); }
  .rock {
    position: relative;
    display: flex; align-items: center; justify-content: center;
    height: 44px; padding: 0 10px;
    border-top: 3px solid var(--rock-edge);
    border-bottom: 3px solid rgba(0, 0, 0, 0.62);
    box-shadow: inset 4px 0 0 var(--rock-chip), inset -4px 0 0 rgba(0,0,0,.42), var(--rock-glow);
    background-color: var(--rock-bottom);
    /* pits and catches of light, so it reads as stone rather than a card */
    background-image:
      var(--rock-vein),
      radial-gradient(circle at 13% 28%, rgba(255,255,255,0.11) 0 3px, transparent 4px),
      radial-gradient(circle at 61% 20%, rgba(0,0,0,0.36) 0 5px, transparent 6px),
      radial-gradient(circle at 85% 68%, rgba(0,0,0,0.32) 0 4px, transparent 5px),
      radial-gradient(circle at 33% 76%, rgba(255,255,255,0.07) 0 4px, transparent 5px),
      radial-gradient(circle at 46% 52%, rgba(0,0,0,0.22) 0 7px, transparent 9px),
      linear-gradient(180deg,var(--rock-top),var(--rock-mid) 46%,var(--rock-bottom));
    color: var(--rock-label);
    white-space: nowrap; overflow: hidden;
  }
  .rock--stone{--rock-top:#4f4268;--rock-mid:#3a2f4d;--rock-bottom:#241c34;--rock-edge:#756987;--rock-chip:rgba(255,255,255,.08);--rock-label:#f4edf8;--rock-shadow:#110b1c;--rock-aura:rgba(139,125,160,.5);--rock-glow:0 0 transparent;--rock-vein:linear-gradient(transparent,transparent)}
  .rock--bronze{--rock-top:#a65b2d;--rock-mid:#71391f;--rock-bottom:#3b2119;--rock-edge:#e08a47;--rock-chip:rgba(255,211,151,.16);--rock-label:#fff0cf;--rock-shadow:#37150a;--rock-aura:rgba(224,138,71,.7);--rock-glow:0 0 7px rgba(166,91,45,.25);--rock-vein:linear-gradient(transparent,transparent)}
  .rock--steel{--rock-top:#718aa5;--rock-mid:#455a72;--rock-bottom:#253348;--rock-edge:#a9c9e8;--rock-chip:rgba(222,241,255,.18);--rock-label:#f4fbff;--rock-shadow:#142238;--rock-aura:rgba(112,169,217,.7);--rock-glow:0 0 7px rgba(112,169,217,.25);--rock-vein:linear-gradient(transparent,transparent)}
  .rock--obsidian{--rock-top:#25152f;--rock-mid:#130c20;--rock-bottom:#07050d;--rock-edge:#6f355f;--rock-chip:rgba(193,96,169,.12);--rock-label:#fff1f4;--rock-shadow:#16000a;--rock-aura:rgba(255,49,79,.85);--rock-glow:inset 0 0 13px rgba(125,18,74,.42),0 0 10px rgba(255,38,72,.38);--rock-vein:linear-gradient(104deg,transparent 0 31%,rgba(255,38,72,.6) 32%,transparent 34% 68%,rgba(139,22,80,.7) 69%,transparent 71%)}
  .rock--eternal{--rock-top:#12182b;--rock-mid:#070b17;--rock-bottom:#010208;--rock-edge:#dffeff;--rock-chip:rgba(220,255,255,.17);--rock-label:#fff;--rock-shadow:#062c3a;--rock-aura:rgba(151,246,255,.95);--rock-glow:inset 0 0 15px rgba(80,205,230,.2),0 0 12px rgba(151,246,255,.42);--rock-vein:radial-gradient(circle at 74% 52%,rgba(223,255,255,.28) 0 2px,transparent 3px)}
  /* chipped, uneven top edge */
  .rock::before {
    content: ""; position: absolute; left: 0; right: 0; top: 0; height: 4px;
    background: repeating-linear-gradient(90deg,
      rgba(255,255,255,0.15) 0 6px, transparent 6px 10px,
      rgba(255,255,255,0.15) 10px 13px, transparent 13px 23px);
  }
  .rock .durability { position: relative; z-index: 2; font: 8px/1 var(--arc); text-shadow: 1px 1px var(--rock-shadow),0 0 5px var(--rock-shadow); }
  .rock .durability.infinite { font-size: 13px; text-shadow: 0 0 6px #fff,0 0 11px #69eaff; }
  .rock--eternal::after { content:"";position:absolute;left:17%;top:13px;width:12px;height:12px;border:2px solid #dffeff;box-shadow:0 0 7px #fff,0 0 12px #69eaff;transform:rotate(45deg);animation:runePulse 2.4s steps(4) infinite }
  @keyframes runePulse{50%{opacity:.38;filter:brightness(1.8);transform:rotate(45deg) scale(.78)}}

  /* Ten fracture layers reveal in proportion to durability already lost. */
  .crack {
    position: absolute; z-index: 1; background: #05010c;
    /* drop-shadow survives the clip, so each fracture gets a lit edge and reads
       as a groove rather than a painted line */
    filter: drop-shadow(1px 2px 0 rgba(255, 255, 255, 0.26));
    clip-path: polygon(52% 0, 68% 20%, 36% 38%, 70% 56%, 40% 76%, 60% 100%,
                       40% 100%, 20% 76%, 50% 56%, 16% 38%, 48% 20%, 32% 0);
    display: none;
  }
  .crack.c1 { left: 28%; top: -3px; bottom: -3px; width: 46px; }
  .crack.c2 { left: 8%;  top: -3px; height: 64%; width: 36px; transform: rotate(15deg); }
  .crack.c3 { left: 62%; bottom: -3px; height: 72%; width: 38px; transform: rotate(-12deg); }
  .crack.c4 { left: 38%; top: 30%; height: 44%; width: 62px; transform: rotate(78deg); }
  .crack.c5 { left: 76%; top: 4%; height: 48%; width: 30px; transform: rotate(-24deg); }
  .crack.c6  { left: 2%;  top: 34%; height: 60%; width: 32px; transform: rotate(-38deg); }
  .crack.c7  { left: 46%; top: -3px; height: 58%; width: 34px; transform: rotate(28deg); }
  .crack.c8  { left: 86%; bottom: -3px; height: 66%; width: 28px; transform: rotate(20deg); }
  .crack.c9  { left: 16%; top: 22%; height: 40%; width: 70px; transform: rotate(84deg); }
  .crack.c10 { left: 58%; top: 40%; height: 46%; width: 58px; transform: rotate(-72deg); }
  .crack.shown,.rock.shattering .crack { display: block; animation: crackin 160ms ease-out backwards; }
  .rock.cracked .c2 { animation-delay: 80ms; }
  .rock.cracked .c3 { animation-delay: 150ms; }
  .rock.cracked .c4 { animation-delay: 215ms; }
  .rock.cracked .c5 { animation-delay: 280ms; }
  .rock.cracked .c6  { animation-delay: 0ms; }
  .rock.cracked .c7  { animation-delay: 35ms; }
  .rock.cracked .c8  { animation-delay: 70ms; }
  .rock.cracked .c9  { animation-delay: 110ms; }
  .rock.cracked .c10 { animation-delay: 150ms; }
  .rock.shattering { animation: rumble 280ms linear; }
  @keyframes rumble {
    0%, 100% { transform: translate(0, 0); }
    20% { transform: translate(-2px, 1px); } 40% { transform: translate(2px, -1px); }
    60% { transform: translate(-2px, -1px); } 80% { transform: translate(2px, 1px); }
  }
  @keyframes crackin { from { opacity: 0; } }
  .rock.cracked { animation: jolt 260ms ease-out; }
  @keyframes jolt {
    20% { transform: translateX(-4px); } 45% { transform: translateX(4px); }
    70% { transform: translateX(-2px); }
  }

  /* the rock itself drops out fast; the two halves fly on top of the pile */
  .rock.crumble { animation: gone 300ms ease-in forwards; }
  @keyframes gone {
    0% { filter: brightness(3.2); }
    22% { filter: brightness(1); }
    100% { height: 0; border-width: 0; opacity: 0; }
  }
  /* Six pieces, each clipped to its own patch of the slab. */
  .shard {
    position: absolute; z-index: 7; pointer-events: none; overflow: hidden;
    animation: flyapart 820ms cubic-bezier(.25, .5, .5, 1) forwards;
  }
  .shard.p1 { clip-path: polygon(0 0, 34% 0, 30% 46%, 0 52%); }
  .shard.p2 { clip-path: polygon(34% 0, 68% 0, 64% 50%, 30% 46%); }
  .shard.p3 { clip-path: polygon(68% 0, 100% 0, 100% 48%, 64% 50%); }
  .shard.p4 { clip-path: polygon(0 52%, 30% 46%, 26% 100%, 0 100%); }
  .shard.p5 { clip-path: polygon(30% 46%, 64% 50%, 60% 100%, 26% 100%); }
  .shard.p6 { clip-path: polygon(64% 50%, 100% 48%, 100% 100%, 60% 100%); }
  @keyframes flyapart {
    0% { filter: brightness(3.4); }
    16% { filter: brightness(1); }
    100% { transform: translate(var(--sx), var(--sy)) rotate(var(--sr)); opacity: 0; }
  }
  .pop {
    position: absolute; z-index: 8; pointer-events: none;
    font-family: var(--arc); font-size: 13px; color: var(--gold);
    white-space: nowrap;
    text-shadow: 2px 2px 0 var(--rose), 0 0 12px rgba(255, 194, 51, 0.8);
    animation: popup 720ms ease-out forwards;
  }
  @keyframes popup {
    0% { transform: translate(-50%, 0) scale(0.5); opacity: 0; }
    22% { transform: translate(-50%, -16px) scale(1.2); opacity: 1; }
    100% { transform: translate(-50%, -52px) scale(1); opacity: 0; }
  }
  .cab.shake.hard { animation: shakehard 340ms ease-out; }
  @keyframes shakehard {
    15% { transform: translate(-6px, 5px); } 30% { transform: translate(6px, -5px); }
    45% { transform: translate(-5px, 3px); } 60% { transform: translate(5px, 4px); }
    80% { transform: translate(-3px, -2px); }
  }
  .chunk {
    position: absolute; z-index: 6; pointer-events: none;
    background: #6b5a86; border: 1px solid rgba(0, 0, 0, 0.5);
    animation: tumble 720ms cubic-bezier(.3, .6, .5, 1) forwards;
  }
  @keyframes tumble {
    to { transform: translate(var(--dx), var(--dy)) rotate(220deg); opacity: 0; }
  }
  .rock.new { animation: slam 300ms cubic-bezier(.3, 1.5, .5, 1); }
  @keyframes slam { 0% { transform: translateY(-52px); opacity: 0.35; } 100% { transform: none; } }
  .rock.clink { animation: clink 300ms steps(3); }
  @keyframes clink { 45% { filter: brightness(1.8); transform: translateX(2px); } }
  .clink-spark { position:absolute;z-index:10;width:4px;height:4px;pointer-events:none;background:#efffff;box-shadow:0 0 7px #8ef5ff;animation:clinkSpark 440ms steps(5) forwards }
  @keyframes clinkSpark { to { opacity:0;transform:translate(var(--cx),var(--cy)) rotate(135deg) scale(.2); } }
  .line.sink { animation: sink 320ms ease-in forwards; }
  @keyframes sink { to { transform: translateY(26px); opacity: 0; } }
  .sky.squeeze { box-shadow: inset 0 -12px 20px -8px rgba(255, 79, 121, 0.6); }

  /* ---------- pad ---------- */
  .pad {
    flex: none; display: grid; grid-template-columns: 1fr 1.5fr 1fr; gap: 8px;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
    background: var(--void-2); border-top: 2px solid var(--grid);
  }
  button {
    font-family: var(--arc); font-size: 11px; cursor: pointer;
    padding: 15px 6px; border-radius: 4px; color: var(--ink);
    background: var(--panel-2); border: 2px solid var(--grid);
    box-shadow: 0 3px 0 rgba(0,0,0,0.5); -webkit-tap-highlight-color: transparent;
  }
  button:active { transform: translateY(3px); box-shadow: none; }
  button.go { background: var(--gold); color: var(--gold-ink); border-color: #fff3cf; }
  /* Between a drop and the next word there is nothing to steer. Show that,
     rather than letting the pad look broken. */
  .pad button:disabled { opacity: 0.32; cursor: default; box-shadow: none; transform: none; }

  /* ---------- overlay ---------- */
  .ovl {
    position: absolute; inset: 0; z-index: 30; display: none;
    /* "safe" so a tall game-over screen scrolls from the top instead of
       clipping what center-justify pushes above the fold */
    flex-direction: column; justify-content: safe center; gap: 14px; padding: 26px 22px;
    background: rgba(11, 5, 32, 0.94); text-align: center;
  }
  .ovl.on { display: flex; }
  .ovl h1 { margin: 0; font-family: var(--arc); font-size: 17px; line-height: 1.6; color: var(--gold); }

  /* ---------- level card ---------- */
  .lvcard {
    position: absolute; inset: 0; z-index: 25;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
    background: rgba(11, 5, 32, 0.9);
    animation: lvfade 1500ms ease-out forwards;
  }
  .lvcard[hidden] { display: none; }
  .lvcard .k { font-family: var(--arc); font-size: 11px; letter-spacing: 0.34em; color: var(--cyan); }
  .lvcard b {
    font-family: var(--arc); font-size: clamp(52px, 21vw, 92px); line-height: 1; color: var(--gold);
    text-shadow: -3px -3px 0 var(--cyan), 3px 3px 0 var(--rose), 0 9px 0 #6b30c7, 0 18px 0 #3d1c78;
    animation: lvpunch 620ms cubic-bezier(.2, 1.7, .4, 1) both;
  }
  .lvcard .sub { font-family: var(--jp); font-size: 12px; color: var(--dim); margin-top: 10px; }
  @keyframes lvfade { 0% { opacity: 0; } 10% { opacity: 1; } 82% { opacity: 1; } 100% { opacity: 0; } }

  /* ---------- pause ---------- */
  .pausecard {
    position: absolute; inset: 0; z-index: 26;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
    background: rgba(11, 5, 32, 0.92);
  }
  .pausecard[hidden] { display: none; }
  .pausecard .k { font-family: var(--arc); font-size: 16px; letter-spacing: 0.34em; color: var(--gold); }
  /* Quitting ends the run for good, so it stands well away from RESUME. */
  .pausecard .quit {
    margin-top: 42px; padding: 9px 16px; border-radius: 4px;
    border: 1px solid var(--grid); background: none; color: var(--dim);
    font-family: var(--jp); font-size: 13px; cursor: pointer;
  }
  @keyframes lvpunch {
    0% { transform: scale(0.3) rotate(-9deg); opacity: 0; }
    60% { transform: scale(1.14) rotate(0); opacity: 1; }
    100% { transform: scale(1); }
  }
  .ovl .reached {
    display: block; font-family: var(--arc); font-size: 30px; color: var(--gold);
    text-shadow: 2px 2px 0 var(--rose); line-height: 1.3;
  }

  /* ---------- 8-bit title ---------- */
  .art { position: relative; padding: 44px 0 10px; }
  .art[hidden] { display: none; }

  /* retro sun: solid disc, sliced by bands that widen toward the bottom */
  .sun {
    position: absolute; left: 50%; top: 10px; transform: translateX(-50%);
    width: 200px; height: 200px; border-radius: 50%;
    background: linear-gradient(180deg, var(--gold) 0%, #ff8a3d 42%, var(--rose) 74%, #a8379b 100%);
    opacity: 0.9;
  }
  .sun::after {
    content: ""; position: absolute; inset: 0; border-radius: 50%;
    background: linear-gradient(to bottom,
      transparent 0 46%,
      var(--void-2) 46% 48.5%, transparent 48.5% 56%,
      var(--void-2) 56% 59.5%, transparent 59.5% 67%,
      var(--void-2) 67% 71.5%, transparent 71.5% 79%,
      var(--void-2) 79% 84.5%, transparent 84.5% 91%,
      var(--void-2) 91% 100%);
  }

  /* Purely decorative, and explicitly not tappable — these used to read as
     buttons. */
  .star {
    position: absolute; pointer-events: none; z-index: 1;
    clip-path: polygon(50% 0%, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0% 50%, 39% 39%);
    animation: twinkle 2600ms ease-in-out infinite;
  }
  .star.a { top: 10px; right: 14px; width: 18px; height: 18px; background: var(--cyan); }
  .star.b { bottom: 10px; left: 16px; width: 13px; height: 13px; background: var(--gold); animation-delay: 900ms; }
  .star.c { top: 78px; left: 4px; width: 10px; height: 10px; background: var(--rose); animation-delay: 1700ms; }
  @keyframes twinkle {
    0%, 100% { opacity: 0.25; transform: scale(0.7); }
    50% { opacity: 0.95; transform: scale(1); }
  }

  .logo {
    position: relative; z-index: 2; margin: 0;
    font-family: var(--arc); line-height: 1.5; letter-spacing: 0.02em;
    color: var(--gold);
    /* chromatic split + a stacked purple extrude, the way the reference does it */
    text-shadow:
      -2px -2px 0 var(--cyan),
      2px 2px 0 var(--rose),
      0 5px 0 #6b30c7,
      0 10px 0 #4a1f96,
      0 15px 0 #2c1166;
    animation: land 520ms cubic-bezier(.2, 1.5, .4, 1) both;
  }
  .logo span { display: block; }
  .logo .l1 { font-size: clamp(30px, 11vw, 46px); }
  .logo .l2 { font-size: clamp(20px, 7.4vw, 31px); margin-top: 12px; }
  @keyframes land { from { transform: translateY(-26px); opacity: 0; } }




  /* The home page wraps PRESS START as the conversion anchor and carries the
     site footer inside the title overlay. */
  .cta { width: 100%; }
  .cta .go { width: 100%; }
  .guest-footer {
    display: flex; flex-direction: column; gap: 7px; align-items: center;
    font-family: var(--jp); font-size: 10.5px; color: var(--dim);
  }
  .guest-footer strong { color: var(--ink); font-weight: 400; }
  .guest-footer div { display: flex; gap: 8px; align-items: baseline; }
  .guest-footer nav {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 10px;
  }
  .guest-footer a {
    color: var(--dim); text-decoration: none;
    border-bottom: 1px dotted var(--grid); padding-bottom: 1px;
  }
  .guest-footer a:hover, .guest-footer a:focus-visible { color: var(--cyan); border-bottom-color: var(--cyan); }
  .guest-footer > span { font-family: var(--arc); font-size: 7px; letter-spacing: 0.08em; opacity: 0.75; }

  /* Arcade cabinets sign themselves right under the marquee. */
  /* .ovl p would win on specificity, so the signature is scoped to the
     overlay too. It sits right under the marquee; the dark chip keeps it
     legible over the sun's lower bands. */
  .ovl .artcr {
    position: relative; z-index: 2; margin: 18px 0 0;
    display: inline-block; padding: 5px 10px 6px;
    background: rgba(11, 5, 32, 0.88); border-radius: 3px;
    font-family: var(--arc); font-size: 8px; letter-spacing: 0.12em;
    color: var(--dim);
  }

  #btnStart {
    font-size: clamp(13px, 4.6vw, 18px);
    padding: 19px 10px; letter-spacing: 0.05em;
    animation: pressblink 1000ms steps(2) infinite;
  }

  .legal { display: flex; flex-direction: column; gap: 7px; margin-top: 2px; }
  .legal[hidden] { display: none; }
  .legal nav {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 10px;
  }
  .legal a {
    font-family: var(--jp); font-size: 10.5px; line-height: 1.3;
    color: var(--dim); text-decoration: none; border-bottom: 1px dotted var(--grid);
    padding-bottom: 1px;
  }
  .legal a:hover, .legal a:focus-visible { color: var(--cyan); border-bottom-color: var(--cyan); }
  .legal .cr {
    font-family: var(--arc); font-size: 7px; letter-spacing: 0.08em;
    color: var(--dim); opacity: 0.75;
  }
  @keyframes pressblink { 50% { opacity: 0.55; } }
  @media (prefers-reduced-motion: reduce) {
    .logo, #btnStart, .star, .lvcard, .lvcard b, .ovl .best .newrec, .ovl .best.rec b, .ovl .rankin-msg { animation: none; }
  }
  .ovl h2 { margin: 0; font-family: var(--arc); font-size: 14px; line-height: 1.6; color: var(--rose); }
  .ovl p { margin: 0; font-size: 13px; line-height: 1.75; color: var(--dim); }
  #ovlBody:empty { display: none; }
  .ovl { overflow-y: auto; }

  .ovl .big { font-family: var(--arc); font-size: 22px; color: var(--cyan); }

  /* ---------- game over: personal best, name entry, ranking ---------- */
  .ovl .best { font-family: var(--arc); font-size: 10px; color: var(--cyan); letter-spacing: 0.06em; line-height: 2; }
  .ovl .best b { color: var(--gold); margin-left: 6px; }
  /* A fresh record announces itself the arcade way: blinking, tricolor. */
  .ovl .best .newrec {
    display: inline-block; font-size: 12px; letter-spacing: 0.18em;
    color: var(--gold);
    text-shadow: -2px -2px 0 var(--cyan), 2px 2px 0 var(--rose);
    animation: recblink 640ms steps(2, jump-none) infinite;
  }
  .ovl .best.rec b { animation: recblink 640ms steps(2, jump-none) infinite; }
  @keyframes recblink { 50% { opacity: 0.25; } }
  /* display:flex would beat the hidden attribute; these only exist on the
     result screen, never on the title. */
  .namebox[hidden], .rank[hidden], .ovl .best[hidden], .ovl .namemsg[hidden] { display: none; }
  .namebox { display: flex; align-items: center; justify-content: center; gap: 8px; }
  .namebox .k { font-family: var(--arc); font-size: 8px; color: var(--dim); }
  .namebox input {
    width: 10em; padding: 7px 8px; text-align: center;
    background: var(--panel-2); border: 1px solid var(--grid); border-radius: 4px;
    color: var(--ink); font-family: var(--jp); font-size: 15px;
    user-select: text; -webkit-user-select: text;
  }
  .namebox input::placeholder { color: var(--dim); opacity: 0.7; }
  .ovl .namemsg { font-family: var(--jp); font-size: 11px; color: var(--rose); }
  .namebox button {
    padding: 7px 10px; border-radius: 4px; border: 1px solid var(--grid);
    background: var(--panel-2); color: var(--cyan); font-family: var(--arc); font-size: 9px;
    cursor: pointer;
  }
  .rank { display: flex; flex-direction: column; gap: 5px; width: min(320px, 100%); margin: 0 auto; }
  .rk-title { font-family: var(--arc); font-size: 10px; color: var(--cyan); letter-spacing: 0.3em; margin-bottom: 2px; }
  .rk-tabs { display: flex; justify-content: center; gap: 8px; margin-bottom: 4px; }
  .rk-tab {
    padding: 5px 14px; border: 1px solid var(--grid); border-radius: 4px;
    background: none; color: var(--dim); font-family: var(--jp); font-size: 12px; cursor: pointer;
  }
  .rk-tab.on { border-color: var(--gold); color: var(--gold); background: rgba(255, 194, 51, 0.12); }
  /* the arcade rite: you made the board, leave your name */
  .ovl .rankin-msg {
    margin: 0; font-family: var(--jp); font-size: 13px; color: var(--gold);
    animation: recblink 640ms steps(2, jump-none) infinite;
  }
  .ovl .rankin-msg[hidden] { display: none; }
  .namebox.rankin input { border-color: var(--gold); box-shadow: 0 0 10px rgba(255, 194, 51, 0.45); }
  .rk-row {
    display: flex; align-items: baseline; gap: 8px; text-align: left;
    border-bottom: 1px dotted var(--grid); padding-bottom: 3px;
  }
  .rk-row .rk-no { font-family: var(--arc); font-size: 9px; color: var(--dim); width: 2.6em; flex: none; }
  .rk-row .rk-name {
    font-family: var(--jp); font-size: 13px; color: var(--ink); flex: 1;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .rk-row .rk-score { font-family: var(--arc); font-size: 10px; color: var(--dim); font-variant-numeric: tabular-nums; }
  .rk-row.me .rk-no, .rk-row.me .rk-name, .rk-row.me .rk-score { color: var(--gold); }
  .rk-gap { font-family: var(--arc); font-size: 9px; color: var(--dim); }
  .rk-row.empty { opacity: 0.45; }
  /* the share door: the loudest thing on the result screen after RETRY */
  .ovl .share {
    width: min(320px, 100%); margin: 0 auto; padding: 11px 14px;
    border: 2px solid var(--gold); border-radius: 4px;
    background: rgba(255, 194, 51, 0.14); color: var(--gold);
    font-family: var(--jp); font-size: 14px; cursor: pointer;
  }
  .ovl .share[hidden] { display: none; }
  .ovl .share-img {
    background: none; border: 0; box-shadow: none; padding: 2px 4px;
    font-family: var(--jp); font-size: 12px; color: var(--dim);
    text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
  }
  .ovl .share-img[hidden] { display: none; }

  /* quiet text links: back to the title, and the bashful recommendation */
  .ovl .home-link, .ovl .applink {
    background: none; border: 0; box-shadow: none; padding: 4px;
    font-family: var(--jp); font-size: 12px; color: var(--dim);
    text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
  }
  .ovl .home-link[hidden], .ovl .applink[hidden] { display: none; }

  /* the install rail: whichever affordance this browser deserves */
  .install { display: flex; flex-direction: column; align-items: center; gap: 8px; }
  .install[hidden] { display: none; }
  .install .install-btn {
    display: block; width: min(320px, 100%); padding: 9px 14px; text-align: center;
    border: 1px solid var(--cyan); border-radius: 4px; background: rgba(69, 224, 255, 0.10);
    color: var(--cyan); font-family: var(--jp); font-size: 13px;
    cursor: pointer; text-decoration: none; box-sizing: border-box;
  }
  .install .install-btn[hidden] { display: none; }
  .install .install-hint { margin: 0; font-family: var(--jp); font-size: 11px; color: var(--dim); }
  .install .install-hint[hidden] { display: none; }

  /* the door from the result screen to the mistakes screen */
  .ovl .miss-open {
    width: min(320px, 100%); margin: 0 auto; padding: 9px 14px;
    border: 1px solid var(--cyan); border-radius: 4px; background: rgba(69, 224, 255, 0.10);
    color: var(--cyan); font-family: var(--jp); font-size: 13px; cursor: pointer;
  }
  .ovl .miss-open[hidden] { display: none; }

  /* ---------- mistakes screen: the whole cabinet, roomy and readable ---------- */
  .misscard {
    position: absolute; inset: 0; z-index: 40;
    display: flex; flex-direction: column; gap: 14px; padding: 22px 18px;
    background:
      repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.025) 0 1px, transparent 1px 3px),
      var(--void-2);
  }
  .misscard[hidden] { display: none; }
  .miss-head { display: flex; align-items: baseline; justify-content: space-between; }
  .miss-head .k { font-family: var(--arc); font-size: 14px; letter-spacing: 0.3em; color: var(--rose); }
  .miss-head .miss-count { font-family: var(--jp); font-size: 12px; color: var(--dim); }
  .misscard .tally { flex: 1 1 auto; max-height: none; gap: 10px; }
  .misscard .cmp {
    font-size: 15px; padding: 10px 2px 9px;
    border-bottom: 1px dotted var(--grid);
  }
  .misscard .cmp .cja { font-size: 13px; }
  .misscard button { flex: none; }

  /* ---------- how to play: a full-screen 8-bit field guide ---------- */

  .tally { display: flex; flex-direction: column; gap: 5px; max-height: 46svh; overflow-y: auto; }
  .tally div {
    display: flex; justify-content: space-between; gap: 10px;
    font-size: 13px; color: var(--ink); border-bottom: 1px dotted var(--grid); padding-bottom: 4px;
  }
  .tally .cmp {
    display: flex; flex-direction: column; gap: 2px; text-align: left;
    font-family: var(--en); font-size: 12px; font-weight: 700; padding: 6px 0 5px;
  }
  .tally .cmp .cja { font-family: var(--jp); font-weight: 400; font-size: 11px; color: var(--dim); }
  .tally .cmp .mine, .tally .cmp .right { display: flex; gap: 7px; color: var(--ink); }
  .tally .cmp .mine::before, .tally .cmp .right::before {
    flex: none; width: 3.4em; font-family: var(--jp); font-weight: 400; opacity: 0.8; color: var(--dim);
  }
  .tally .cmp .mine::before { content: "あなた"; }
  .tally .cmp .right::before { content: "正しい"; }
  /* only where the two sentences differ changes color */
  .tally .cmp .mine .diff { color: var(--rose); }
  .tally .cmp .right .diff { color: var(--cyan); }
  .ovl button { width: 100%; }
  .ovl .link {
    background: none; border: 0; box-shadow: none; padding: 4px;
    font-family: var(--jp); font-size: 12px; color: var(--dim); text-decoration: underline;
  }

  .ready {
    position: absolute; inset: 0; z-index: 20; display: none;
    align-items: center; justify-content: center;
    font-family: var(--arc); font-size: 20px; color: var(--gold);
    text-shadow: 0 0 14px rgba(255, 194, 51, 0.7);
  }
  .ready.on { display: flex; animation: blink 380ms steps(2) infinite; }
  @keyframes blink { 50% { opacity: 0.25; } }

  .help { text-align: left; }
  .help p { color: var(--dim); font-size: 12.5px; }
  .help b { color: var(--ink); }
  .help .en { font-family: var(--en); font-weight: 700; color: var(--cyan); }

  @media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  }

  /* ---------- rocket port: space, workshop and word forge ---------- */
  .space{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}.stars{position:absolute;width:3px;height:3px;border-radius:50%;background:#fff;opacity:0;transition:opacity 500ms}
  .stars.a{left:8%;top:10%;box-shadow:52px 24px #fff,118px 5px #9eefff,204px 42px #fff3b0,285px 15px #fff,330px 82px #b6f5ff,18px 115px #fff,95px 205px #fff,250px 178px #9eefff,335px 262px #fff,40px 320px #fff3b0,180px 358px #fff,300px 415px #b6f5ff,70px 470px #fff,225px 505px #fff,345px 545px #9eefff,130px 590px #fff}
  .stars.b{left:3%;top:4%;box-shadow:19px 74px #fff,68px 123px #9eefff,108px 91px #fff,155px 142px #fff,198px 71px #fff3b0,236px 125px #fff,276px 12px #fff,305px 152px #9eefff,352px 107px #fff,373px 49px #fff,28px 238px #fff,152px 275px #fff3b0,290px 310px #fff,88px 385px #9eefff,320px 440px #fff,195px 462px #fff,45px 530px #fff3b0,265px 570px #fff,360px 610px #fff}
  .sky.level-2 .stars.a,.sky.level-3 .stars.a,.sky.level-4 .stars.a,.sky.level-5 .stars.a{opacity:.38}.sky.level-3 .stars.b,.sky.level-4 .stars.b,.sky.level-5 .stars.b{opacity:.42}.sky.level-4 .stars.a,.sky.level-5 .stars.a{animation:twinkleA 3.8s steps(2) infinite}.sky.level-4 .stars.b,.sky.level-5 .stars.b{animation:twinkleB 2.9s steps(2) 1s infinite}
  @keyframes twinkleA{50%{opacity:.1;transform:scale(.6)}}@keyframes twinkleB{50%{opacity:.12;transform:scale(1.5)}}.shooting-star{position:absolute;top:54px;left:-80px;width:60px;height:1px;opacity:0;transform:rotate(-18deg);background:linear-gradient(90deg,transparent,var(--cyan))}.sky.level-5 .shooting-star{animation:shoot 8s ease-in 2s infinite}@keyframes shoot{0%,72%{opacity:0;transform:translate(0) rotate(-18deg)}75%{opacity:.28}84%,100%{opacity:0;transform:translate(500px,150px) rotate(-18deg)}}
  .rocket-bay{position:absolute;left:8px;top:8px;z-index:2;width:132px;height:154px;pointer-events:none;border:1px solid rgba(157,142,208,.35);background:linear-gradient(180deg,rgba(30,16,66,.52),rgba(11,5,32,.2))}.bay-label{position:absolute;right:1px;bottom:1px;z-index:5;width:120px;color:var(--gold);font:10px/1.05 var(--arc);text-align:center;white-space:nowrap;text-shadow:1px 1px #2a1600,0 0 7px rgba(255,194,51,.5)}
  .bay-label.near .rocket-count{display:inline-block;animation:counterPulse 520ms steps(2) infinite}@keyframes counterPulse{50%{color:#fff;transform:scale(1.12);text-shadow:0 0 10px var(--gold)}}.gantry{position:absolute;right:8px;top:17px;width:55px;height:106px;border:3px solid #5b4b80;border-bottom:5px solid #70618f;background:repeating-linear-gradient(135deg,transparent 0 11px,rgba(157,142,208,.22) 11px 13px)}
  .gantry::before,.gantry::after{content:"";position:absolute;background:#75649b}.gantry::before{left:-7px;right:-7px;bottom:-8px;height:6px}.gantry::after{right:-6px;top:16px;width:8px;height:4px;box-shadow:0 31px #75649b,0 62px #75649b}.lever{position:absolute;right:3px;bottom:18px;width:4px;height:19px;background:#9d8ed0;transform-origin:bottom}.lever::before{content:"";position:absolute;left:-3px;top:-5px;width:10px;height:8px;background:var(--rose)}.rocket-bay.pull .lever{animation:leverPull 500ms steps(3)}@keyframes leverPull{50%,100%{transform:rotate(55deg)}}
  .mini-rocket{position:absolute;right:17px;bottom:31px;width:38px;height:102px;filter:drop-shadow(0 0 5px rgba(255,194,51,.35))}.rpart{position:absolute;opacity:.1;filter:grayscale(1);transition:opacity 180ms,filter 180ms}.rpart.on{opacity:1;filter:none;animation:partIn 430ms steps(4)}.rp-engine{left:10px;bottom:0;width:18px;height:22px;background:#725b8e;border:3px solid #b9a9d2}.rp-body{left:8px;bottom:19px;width:22px;height:45px;background:#d8d5e4;border-inline:3px solid #77708b}.rp-wings{left:0;bottom:10px;width:38px;height:31px;background:var(--rose);clip-path:polygon(0 100%,16% 15%,39% 55%,61% 55%,84% 15%,100% 100%,70% 82%,30% 82%)}.rp-nose{left:8px;bottom:63px;width:22px;height:29px;background:var(--gold);clip-path:polygon(50% 0,100% 78%,100% 100%,0 100%,0 78%)}.rp-paint{left:13px;bottom:45px;width:12px;height:12px;border:3px solid var(--gold);border-radius:50%;background:var(--cyan);box-shadow:0 0 7px var(--cyan)}@keyframes partIn{45%{transform:scale(1.35);filter:brightness(2)}}.rocket-bay.depart .mini-rocket{opacity:0}
  .kawaii-dwarf{position:absolute;width:32px;height:36px;transform-origin:bottom center}.dwarf-hat{position:absolute;left:3px;top:1px;width:26px;height:9px;z-index:3;border-radius:9px 9px 2px 2px;background:var(--hat,var(--gold));box-shadow:-2px 7px 0 -1px var(--hat,var(--gold)),8px 7px 0 -1px var(--hat,var(--gold))}.dwarf-hat::before{content:"";position:absolute;left:11px;top:-1px;width:5px;height:8px;border-radius:3px 3px 0 0;background:rgba(255,255,255,.28)}
  .dwarf-head{position:absolute;left:2px;top:8px;width:28px;height:20px;z-index:2;border:2px solid #9d573f;border-radius:9px 9px 7px 7px;background:#f3b083;box-shadow:inset 0 -3px rgba(190,91,75,.18)}.dwarf-head::before{content:"";position:absolute;left:4px;top:5px;width:6px;height:7px;border-radius:3px;background:#160d2a;box-shadow:12px 0 #160d2a,1px 1px #fff,13px 1px #fff}.dwarf-head::after{content:"";position:absolute;left:1px;top:12px;width:5px;height:3px;border-radius:3px;background:#f06f82;box-shadow:17px 0 #f06f82}
  .dwarf-body{position:absolute;left:7px;top:26px;width:18px;height:7px;z-index:1;border-radius:4px 4px 2px 2px;background:var(--shirt,var(--cyan));border-bottom:2px solid rgba(0,0,0,.28)}.dwarf-leg{position:absolute;top:32px;width:7px;height:4px;border-radius:0 0 3px 3px;background:#8060aa}.dwarf-leg.l{left:7px}.dwarf-leg.r{right:7px}.dwarf-arm{position:absolute;left:23px;top:27px;width:9px;height:4px;z-index:3;border-radius:3px;background:#f3b083;transform-origin:left}.dwarf-hammer{position:absolute;left:28px;top:17px;width:4px;height:14px;z-index:4;border-radius:2px;background:#b98551;transform-origin:bottom;opacity:0}.dwarf-hammer::before{content:"";position:absolute;left:-4px;top:-3px;width:12px;height:6px;border-radius:2px;background:#c8c2d2;box-shadow:inset 0 -2px #777184}
  .engineer{--hat:var(--engineer-hat,var(--gold));--shirt:var(--engineer-shirt,var(--cyan));left:8px;bottom:32px}.engineer.working{animation:engineerRun 900ms steps(6)}.engineer.working .dwarf-hammer{opacity:1;animation:hammer 180ms steps(2) 3 390ms}@keyframes engineerRun{0%{transform:translateX(0)}42%,80%{transform:translateX(50px)}100%{transform:translateX(0)}}@keyframes hammer{50%{transform:rotate(-65deg)}}
  .engineer.dance{animation:dance 600ms steps(2) 4}.engineer.dance .dwarf-arm{animation:wave 300ms steps(2) 8}@keyframes dance{50%{transform:translateY(-5px) rotate(-4deg)}}@keyframes wave{50%{transform:rotate(-70deg)}}.engineer.nap{animation:lieDown 300ms steps(3) forwards}.engineer.nap .zzz{display:block;animation:zzz 1.1s steps(3) infinite}@keyframes lieDown{to{transform:translate(-2px,7px) rotate(-88deg)}}.zzz{display:none;position:absolute;left:17px;top:-17px;color:var(--cyan);font:6px/1.6 var(--arc);transform:rotate(88deg)}@keyframes zzz{50%{transform:rotate(88deg) translateY(-5px);opacity:.35}}
  .engineer.celebrate{animation:celebrate 300ms steps(2) 5}.engineer.pull{animation:engineerPull 520ms steps(4) forwards}.engineer.pull .dwarf-arm{transform:rotate(-65deg)}@keyframes engineerPull{60%,100%{transform:translateX(88px)}}.engineer.celebrate .dwarf-arm{transform:rotate(-80deg)}@keyframes celebrate{50%{transform:translateY(-11px)}}.work-spark{position:absolute;right:49px;bottom:50px;width:5px;height:5px;opacity:0;background:var(--gold);transform:rotate(45deg)}.rocket-bay.work .work-spark{animation:workSpark 300ms steps(2) 2 420ms}.work-spark.s2{margin:7px -5px 0 0;animation-delay:500ms!important}@keyframes workSpark{50%{opacity:1;transform:translate(8px,-9px) rotate(90deg)}}
  .maker-station{position:absolute;right:7px;top:93px;z-index:7;width:126px;height:72px;pointer-events:none}.maker-ledge{position:absolute;left:0;right:0;bottom:0;height:9px;border:2px solid #75649b;border-radius:3px;background:#33245f;box-shadow:inset 0 3px rgba(255,255,255,.12),0 4px #170d35}.maker-dwarf{--hat:var(--maker-hat,#ff6fa4);--shirt:var(--maker-shirt,#9a78ff);left:8px;bottom:9px;z-index:2}.maker-dwarf .dwarf-arm{left:22px;transform:rotate(18deg)}.maker-dwarf.crafting{animation:makerBob 150ms steps(2) 3}.maker-dwarf.crafting .dwarf-hammer{opacity:1;animation:makerHammer 150ms steps(2) 3}.maker-dwarf.crafting+.maker-sparks i{animation:makerSpark 150ms steps(2) 3}.maker-dwarf.throwing{animation:makerThrow 460ms steps(4)}.maker-dwarf.throwing .dwarf-arm{animation:makerArmThrow 460ms steps(3)}
  @keyframes makerBob{50%{transform:translateY(2px)}}@keyframes makerHammer{50%{transform:rotate(-72deg)}}@keyframes makerThrow{45%{transform:translateX(-3px) rotate(-5deg)}72%{transform:translateX(3px) rotate(4deg)}}@keyframes makerArmThrow{60%{transform:rotate(-100deg)}}.maker-sparks{position:absolute;left:42px;bottom:28px;z-index:3;width:12px;height:12px}.maker-sparks i{position:absolute;width:4px;height:4px;opacity:0;background:var(--gold);transform:rotate(45deg)}.maker-sparks i:nth-child(2){left:8px;top:5px;animation-delay:55ms!important}.maker-sparks i:nth-child(3){left:2px;top:-7px;animation-delay:105ms!important}@keyframes makerSpark{50%{opacity:1;transform:translate(7px,-7px) rotate(90deg)}}
  .maker-next{position:absolute;right:4px;bottom:13px;z-index:1;max-width:79px;opacity:0;transform:translateY(3px) scale(.82);transform-origin:bottom center;text-align:center;transition:opacity 100ms,transform 150ms;filter:drop-shadow(0 0 5px rgba(255,194,51,.45))}.maker-next.show{opacity:1;transform:none}.maker-next.crafting{animation:chipForge 450ms steps(3)}.maker-next small{display:block;margin-bottom:3px;color:var(--gold);font:6px/1 var(--arc)}.maker-next b,.forge-flight{display:block;max-width:79px;overflow:hidden;text-overflow:ellipsis;padding:5px 6px;border:2px solid #fff3cf;border-radius:3px;color:var(--gold-ink);background:var(--gold);font:900 12px/1 var(--en);white-space:nowrap;box-shadow:0 0 0 1px var(--gold-ink)}@keyframes chipForge{0%,66%{filter:brightness(1.8);transform:translateY(3px) scale(.78)}}.maker-next.discard{animation:chipToss 420ms ease-in forwards}@keyframes chipToss{25%{transform:translate(-9px,-14px) rotate(-18deg)}100%{transform:translate(26px,64px) rotate(96deg);opacity:0}}.maker-dwarf.discarding{animation:dwarfShake 420ms steps(3)}@keyframes dwarfShake{33%{transform:translateX(-3px) rotate(-7deg)}66%{transform:translateX(2px) rotate(5deg)}}.forge-flight{position:absolute;z-index:9;pointer-events:none;transform:translate(-50%,-50%)}
  .sky.palette-1{--engineer-hat:#ffc233;--engineer-shirt:#45e0ff;--maker-hat:#ff6fa4;--maker-shirt:#9a78ff}.sky.palette-2{--engineer-hat:#70ef8e;--engineer-shirt:#ff6fa4;--maker-hat:#45e0ff;--maker-shirt:#ffc233}.sky.palette-3{--engineer-hat:#ff875c;--engineer-shirt:#9a78ff;--maker-hat:#fff07a;--maker-shirt:#45e0ff}.sky.palette-4{--engineer-hat:#72d6ff;--engineer-shirt:#ff708c;--maker-hat:#70ef8e;--maker-shirt:#b68cff}.sky.palette-5{--engineer-hat:#ff6bd6;--engineer-shirt:#68e6ba;--maker-hat:#ff9a5c;--maker-shirt:#65c7ff}.sky.palette-6{--engineer-hat:#b991ff;--engineer-shirt:#ffd25c;--maker-hat:#ff6f91;--maker-shirt:#72e8d1}
  /* ---------- full-cab effects and miss feedback ---------- */
  .milestone-layer{position:absolute;inset:0;z-index:45;overflow:hidden;pointer-events:none}.milestone-pop{position:absolute;left:50%;top:26%;z-index:3;transform:translateX(-50%) scale(.35);color:var(--gold);font:17px/1 var(--arc);white-space:nowrap;text-shadow:2px 2px #4d2600,0 0 13px rgba(255,194,51,.9);animation:milestonePop 1350ms steps(7) forwards}@keyframes milestonePop{0%{opacity:0;transform:translateX(-50%) scale(.35)}15%,68%{opacity:1;transform:translateX(-50%) scale(1)}85%{transform:translateX(-50%) scale(1.16)}100%{opacity:0;transform:translateX(-50%) scale(.6)}}
  .firework{position:absolute;width:4px;height:4px}.firework i{position:absolute;inset:0;width:4px;height:4px;background:var(--burst);box-shadow:0 0 5px var(--burst);animation:fireworkDot 850ms steps(7) var(--delay) forwards}@keyframes fireworkDot{0%{opacity:0;transform:translate(0) scale(.5)}18%{opacity:1}78%{opacity:1;transform:translate(var(--fx),var(--fy)) scale(1)}100%{opacity:0;transform:translate(var(--fx),var(--fy)) scale(.25)}}.meteor-burst{position:absolute;left:-100px;width:76px;height:2px;opacity:0;background:linear-gradient(90deg,transparent,var(--meteor));filter:drop-shadow(0 0 3px var(--meteor));transform:rotate(16deg);animation:meteorSweep 1100ms ease-in var(--delay) forwards}@keyframes meteorSweep{0%{opacity:0;transform:translate(0) rotate(16deg)}14%,72%{opacity:.9}100%{opacity:0;transform:translate(570px,var(--my)) rotate(16deg)}}
  .feedback{position:absolute;left:8px;right:8px;bottom:84px;z-index:35;max-height:calc(100% - 96px);overflow:auto;padding:15px 13px 12px;color:var(--ink);background:#1e1042;border:3px solid var(--rose);border-radius:7px;box-shadow:0 -8px 32px rgba(255,79,121,.27),0 0 0 3px var(--void-2);opacity:0;visibility:hidden;pointer-events:none;transform:translateY(125%);transition:transform 220ms cubic-bezier(.2,.9,.2,1),opacity 180ms,visibility 0s 220ms;cursor:pointer}.feedback.show{opacity:1;visibility:visible;pointer-events:auto;transform:translateY(0);transition:transform 220ms cubic-bezier(.2,.9,.2,1),opacity 180ms}.feedback h2{margin:0 0 13px;color:var(--rose);font:15px/1.2 var(--arc);text-shadow:2px 2px #55152c}.fb-row{display:grid;grid-template-columns:58px 1fr;gap:5px;margin:10px 0;align-items:start}.fb-label{padding-top:2px;color:var(--dim);font-size:12px}.fb-sentence{font:700 clamp(12px,3.5vw,15px)/1.5 var(--en)}.fb-sentence b{display:inline-block;padding-inline:3px;color:var(--rose);border-bottom:2px solid var(--rose)}.fb-row.correct b{color:var(--gold);border-color:var(--gold)}.tap-close{margin-top:15px;text-align:right;color:var(--dim);font:6px/1 var(--arc);animation:tapBlink 1s steps(2) infinite}@keyframes tapBlink{50%{opacity:.35}}
  .mega-rocket{display:none;position:absolute;left:50%;bottom:-185px;z-index:42;width:78px;height:158px;transform:translateX(-50%);pointer-events:none;filter:drop-shadow(0 0 15px rgba(255,194,51,.8))}.mega-rocket.fly{display:block;animation:megaLaunch 1.45s cubic-bezier(.55,0,.85,.38) forwards}.mega-body{position:absolute;left:18px;bottom:22px;width:42px;height:88px;background:#e9e7ef;border-inline:6px solid #8a8498;border-radius:18px 18px 5px 5px}.mega-nose{position:absolute;left:18px;bottom:105px;width:42px;height:46px;background:var(--gold);clip-path:polygon(50% 0,100% 80%,100% 100%,0 100%,0 80%)}.mega-wing{position:absolute;bottom:12px;width:31px;height:57px;background:var(--rose)}.mega-wing.l{left:0;clip-path:polygon(100% 0,100% 100%,0 100%,44% 30%)}.mega-wing.r{right:0;clip-path:polygon(0 0,0 100%,100% 100%,56% 30%)}.mega-window{position:absolute;left:29px;bottom:73px;width:20px;height:20px;z-index:2;border:5px solid var(--gold);border-radius:50%;background:var(--cyan);box-shadow:0 0 10px var(--cyan)}.mega-flame{position:absolute;left:25px;bottom:-39px;width:28px;height:64px;background:linear-gradient(var(--ink),var(--gold) 38%,var(--rose));clip-path:polygon(50% 100%,0 0,100% 0);animation:flame 120ms steps(2) infinite}@keyframes flame{50%{height:49px;filter:brightness(1.6)}}@keyframes megaLaunch{0%{transform:translate(-50%,0)}13%{transform:translate(-50%,12px)}100%{transform:translate(-50%,-1100px)}}
  .smoke{position:absolute;z-index:41;width:15px;height:15px;border-radius:50%;background:#d9d3e5;opacity:.7;pointer-events:none;animation:rocketSmoke 900ms ease-out forwards}@keyframes rocketSmoke{to{transform:translate(var(--dx),var(--dy)) scale(3);opacity:0}}.cab.launch-shake{animation:launchShake 900ms steps(2)}@keyframes launchShake{0%,100%{transform:translate(0)}20%{transform:translate(-4px,3px)}40%{transform:translate(4px,-3px)}60%{transform:translate(-3px,-2px)}80%{transform:translate(3px,3px)}}
  @media(max-width:350px){.rocket-bay{transform:scale(.9);transform-origin:top left}.maker-station{transform:scale(.9);transform-origin:top right}}@media(max-height:650px){.feedback{bottom:75px}}@media(prefers-reduced-motion:reduce){.stars,.shooting-star,.engineer,.dwarf-hammer,.maker-dwarf,.maker-sparks i,.maker-next,.maker-next.discard,.work-spark,.prompt,.falling,.tap-close,.firework i,.meteor-burst,.mega-rocket,.smoke{animation:none!important}}
