[object Object]

← back to Games Agentabrams

auto-save: 2026-07-25T00:32:03 (39 files) — games.json index.html sync.sh games-data.js games/2048/Abrams2048.aa

db80d5db4ace440854e8c22be3c9097cb82411de · 2026-07-25 00:32:16 -0700 · Steve Abrams

Files touched

Diff

commit db80d5db4ace440854e8c22be3c9097cb82411de
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat Jul 25 00:32:16 2026 -0700

    auto-save: 2026-07-25T00:32:03 (39 files) — games.json index.html sync.sh games-data.js games/2048/Abrams2048.aa
---
 games-data.js                                   | 296 ++++++++
 games.json                                      |  80 +++
 games/2048/Abrams2048.aa                        | 213 ++++++
 games/asteroids/AbramsAsteroids.aa              | 828 ++++++++++++++++++++++
 games/atmos-skyfire/AtmosSkyfire.aa             | 436 ++++++++++++
 games/backgammon/90210Backgammon.aa             | 686 ++++++++++++++++++
 games/breakout/AbramsBreak.aa                   | 240 +++++++
 games/chomp/AbramsChomp.aa                      | 855 +++++++++++++++++++++++
 games/connect-four/AbramsConnect4.aa            | 720 +++++++++++++++++++
 games/constellation-clock/ConstellationClock.aa | 364 ++++++++++
 games/dvd-bounce/DVDBounce.aa                   | 312 +++++++++
 games/emoji-memory/EmojiMemory.aa               | 401 +++++++++++
 games/flappy-clone/FlappyClone.aa               | 673 ++++++++++++++++++
 games/flappy-flight/FlappyFlight.aa             | 645 +++++++++++++++++
 games/flappy-sky/FlappySky.aa                   | 832 ++++++++++++++++++++++
 games/gems/NeonGems.aa                          | 755 ++++++++++++++++++++
 games/hopper/AbramsHopper.aa                    | 790 +++++++++++++++++++++
 games/invaders/NeonInvaders.aa                  | 891 ++++++++++++++++++++++++
 games/lights-out/AbramsLightsOut.aa             | 471 +++++++++++++
 games/maze/AbramsMaze.aa                        | 692 ++++++++++++++++++
 games/minesweeper/AbramsMines.aa                | 820 ++++++++++++++++++++++
 games/missile/MissileCommand.aa                 | 886 +++++++++++++++++++++++
 games/particle-text/ParticleWord.aa             | 143 ++++
 games/pong/AbramsPong.aa                        | 293 ++++++++
 games/racer/NeonDrifter.aa                      | 882 +++++++++++++++++++++++
 games/rope-physics/VerletRope.aa                | 350 ++++++++++
 games/rubiks-cube/AbramsCube.aa                 | 399 +++++++++++
 games/simon/AbramsSimon.aa                      | 632 +++++++++++++++++
 games/snake/AbramsSnake.aa                      | 211 ++++++
 games/sokoban/NeonSokoban.aa                    | 712 +++++++++++++++++++
 games/spirograph/Spirograph.aa                  | 495 +++++++++++++
 games/sudoku/NeonSudoku.aa                      | 799 +++++++++++++++++++++
 games/tetris/AbramsBlocks.aa                    | 511 ++++++++++++++
 games/tower-stack/AbramsStack.aa                | 513 ++++++++++++++
 games/tron/AbramsTron.aa                        | 454 ++++++++++++
 games/whack-a-mole/AbramsWhack.aa               | 728 +++++++++++++++++++
 games/wordle/AbramsWordle.aa                    | 477 +++++++++++++
 index.html                                      |  19 +-
 sync.sh                                         |  18 +
 39 files changed, 20519 insertions(+), 3 deletions(-)

diff --git a/games-data.js b/games-data.js
new file mode 100644
index 0000000..fa59dbe
--- /dev/null
+++ b/games-data.js
@@ -0,0 +1,296 @@
+/* AUTO-GENERATED from games.json by sync.sh — do not edit by hand.
+   file:// fallback: <script src> works from a local file, fetch() does not. */
+window.__GAMES_DATA__ = {
+  "games": [
+    {
+      "id": "asteroids",
+      "file": "AbramsAsteroids.aa",
+      "title": "Abrams Asteroids",
+      "desc": "A neon vector shooter: thrust, spin, and blast splitting asteroids across wrapping space through escalating waves, with hyperspace and sound. Pure Canvas 2D, zero dependencies.",
+      "path": "games/asteroids/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "minesweeper",
+      "file": "AbramsMines.aa",
+      "title": "Abrams Minesweeper",
+      "desc": "Classic Minesweeper reborn in neon-on-dark — flood-fill sweeps, tap-to-flag, first-click-safe, best-time chasing across three difficulties. Pure vanilla JS, zero dependencies.",
+      "path": "games/minesweeper/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "simon",
+      "file": "AbramsSimon.aa",
+      "title": "Abrams Simon",
+      "desc": "Neon four-pad Simon memory game with Web Audio tones, speeding rounds, strict mode, and a saved best score. Pure vanilla JS, zero dependencies.",
+      "path": "games/simon/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "connect-four",
+      "file": "AbramsConnect4.aa",
+      "title": "Abrams Connect 4",
+      "desc": "Drop glowing neon discs to line up four in a row and outsmart an alpha-beta minimax AI, with silky physics drops and Web Audio. Pure vanilla JS, zero dependencies.",
+      "path": "games/connect-four/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "tower-stack",
+      "file": "AbramsStack.aa",
+      "title": "Abrams Stack",
+      "desc": "Time your taps to stack neon blocks into a sky-high tower — nail a perfect drop for combo bonuses before the overhang slices you down. Pure Canvas 2D, zero dependencies.",
+      "path": "games/tower-stack/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "maze",
+      "file": "AbramsMaze.aa",
+      "title": "Abrams Maze",
+      "desc": "A neon procedurally-generated maze runner: race the timer through ever-larger perfect mazes, drop breadcrumbs, and flash the solution path. Pure Canvas 2D, zero dependencies.",
+      "path": "games/maze/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "lights-out",
+      "file": "AbramsLightsOut.aa",
+      "title": "Abrams Lights Out",
+      "desc": "Toggle glowing neon cells and their neighbors to switch every light off in this slick, solvable-only Lights Out puzzle. Pure vanilla JS, zero dependencies.",
+      "path": "games/lights-out/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "whack-a-mole",
+      "file": "AbramsWhack.aa",
+      "title": "Abrams Whack",
+      "desc": "A neon whack-a-mole arcade sprint — smash glowing moles for combo multipliers, snag gold jackpots, dodge bombs that cost lives. Pure vanilla JS, zero dependencies.",
+      "path": "games/whack-a-mole/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "dvd-bounce",
+      "file": "DVDBounce.aa",
+      "title": "DVD Bounce — Elevated",
+      "desc": "The classic bouncing-logo screensaver, elevated — glowing trails, corner-hit celebration, color shifts on every wall bounce. An ambient toy, not a scored game. Model Arena winner (Claude). Pure Canvas 2D, zero dependencies.",
+      "path": "games/dvd-bounce/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "rope-physics",
+      "file": "VerletRope.aa",
+      "title": "Verlet Rope",
+      "desc": "A physics toy — drag to swing a Verlet-integrated rope, watch it settle and whip under gravity. A generative-physics playground, not a scored game. Model Arena winner (Claude). Pure Canvas 2D, zero dependencies.",
+      "path": "games/rope-physics/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "particle-text",
+      "file": "ParticleWord.aa",
+      "title": "Particle Word",
+      "desc": "Type a word and watch it assemble from a swarm of particles that scatter and reform. An interactive typography toy, not a scored game. Model Arena winner (Qwen3-14B). Pure Canvas 2D, zero dependencies.",
+      "path": "games/particle-text/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "particle-text-starling",
+      "file": "Starling.aa",
+      "icon": "🐦",
+      "title": "Starling",
+      "desc": "Type a word or phrase and thousands of particles murmurate into it — sweep the mouse to scatter, watch them reform, click for a burst. 5 color themes, live typing, multi-line wrapping. Pure Canvas 2D, zero dependencies.",
+      "path": "games/particle-text-starling/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "rubiks-cube",
+      "file": "AbramsCube.aa",
+      "title": "Abrams Cube",
+      "desc": "Pure CSS-3D twist cube — drag to orbit, scramble, solve, undo, timer.",
+      "path": "games/rubiks-cube/",
+      "added": "2026-07-23"
+    },
+    {
+      "id": "atmos-skyfire",
+      "file": "AtmosSkyfire.aa",
+      "title": "ATMOS — Skyfire",
+      "desc": "Three.js arcade flyer — bank through a gradient sky, fire twin missiles (SPACE/click), dodge or shoot incoming birds. Steer with arrows/WASD/mouse.",
+      "path": "games/atmos-skyfire/",
+      "added": "2026-07-23"
+    },
+    {
+      "id": "flappy-clone",
+      "file": "FlappyClone.aa",
+      "title": "Flappy Clone",
+      "desc": "Polished Flappy-Bird clone — Space/click/tap to flap through scrolling pipes. Parallax daytime sky, medals, persistent best, sound (M), pause (P). Pure Canvas 2D, zero dependencies.",
+      "path": "games/flappy-clone/",
+      "added": "2026-07-23"
+    },
+    {
+      "id": "flappy-sky",
+      "file": "FlappySky.aa",
+      "title": "Flappy Sky",
+      "desc": "Flap through the neon gates against a twinkling night sky — how far can you fly? Medals, persistent best, sound (M), pause (P/Esc). Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/flappy-sky/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "tetris",
+      "file": "AbramsBlocks.aa",
+      "title": "Abrams Blocks",
+      "desc": "Full-featured Tetris — SRS rotation with wall kicks, 7-bag randomizer, ghost piece, hold, next-queue, level speed-up, line-clear scoring. Arrows move, ↑/Z rotate, Space hard-drop, C hold. Touch: swipe to move, tap to rotate, fling down to drop. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/tetris/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "flappy-flight",
+      "file": "FlappyFlight.aa",
+      "title": "Flappy Flight",
+      "desc": "Polished Flappy-Bird-style flyer — Space/click/tap to flap through scrolling pipes. Twinkling parallax night sky, moon, medals, persistent best. True pause (P/Esc, auto-pauses off-focus), mute (M or speaker icon). Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/flappy-flight/",
+      "added": "2026-07-23"
+    },
+    {
+      "id": "snake",
+      "file": "AbramsSnake.aa",
+      "title": "Abrams Snake",
+      "desc": "Classic grid snake — eat the pink, grow, and speed up as you go. Walls and your own tail are fatal. Arrows/WASD to steer, swipe on touch, P pause, M mute. Persistent best. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/snake/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "breakout",
+      "file": "AbramsBreak.aa",
+      "title": "Abrams Break",
+      "desc": "Brick-breaker — steer the paddle with mouse/arrows/drag, launch with Space or click, clear every brick, ride the ball's contact angle. Multi-row levels that get tougher, lives, tough top row, persistent best. P pause, M mute. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/breakout/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "2048",
+      "file": "Abrams2048.aa",
+      "title": "Abrams 2048",
+      "desc": "Sliding-tile puzzle — merge equal tiles to reach 2048 and beyond. Arrows/WASD or swipe to slide the whole board, merges pop and chime, persistent best, keep-playing after the win. Pure DOM grid, procedural Web Audio, zero dependencies.",
+      "path": "games/2048/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "pong",
+      "file": "AbramsPong.aa",
+      "title": "Abrams Pong 2P",
+      "desc": "Two-player table tennis — Left: W/S, Right: ↑/↓, first to 11. Contact-angle english off the paddle, speed-up rallies, procedural blips. Toggle 'vs CPU' to play solo. Touch: drag your own half of the screen. P pause, M mute. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/pong/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "emoji-memory",
+      "file": "EmojiMemory.aa",
+      "title": "Abrams Emoji Memory",
+      "desc": "Flip-and-match memory game — find every emoji pair in the fewest moves. 3D card flips, move counter + timer, persistent best-per-size, three difficulties (4×4 / 6×6 / 8×8), and a light/dark theme toggle. Click/tap to flip, N new game. Pure DOM grid, procedural Web Audio, zero dependencies.",
+      "path": "games/emoji-memory/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "spirograph",
+      "file": "Spirograph.aa",
+      "title": "Spirograph Studio",
+      "desc": "Hypotrochoid/epitrochoid pattern toy — tune the fixed & rolling gear radii and pen offset to draw endless looping curves, layer colors, and export the art. A generative-art playground, not a scored game. Pure Canvas 2D, zero dependencies.",
+      "path": "games/spirograph/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "constellation-clock",
+      "file": "ConstellationClock.aa",
+      "title": "Constellation Clock",
+      "desc": "A live clock rendered as a drifting star-field constellation — the current time drawn in connected stars against a twinkling night sky. An ambient visualizer, not a scored game. Pure Canvas 2D, zero dependencies.",
+      "path": "games/constellation-clock/",
+      "added": "2026-07-24"
+    },
+    {
+      "id": "backgammon",
+      "file": "90210Backgammon.aa",
+      "title": "90210 Backgammon",
+      "icon": "🎲",
+      "desc": "A lavish Beverly Hills take on classic backgammon — roll the dice, bear off your checkers, and hit the bar against an opponent on a gold-and-marble 90210 board. Self-contained HTML, zero runtime dependencies.",
+      "path": "games/backgammon/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "chomp",
+      "file": "AbramsChomp.aa",
+      "title": "Abrams Chomp",
+      "desc": "Neon maze-chomper — weave through the maze eating every pellet, grab power pellets to turn the tables and chase the ghosts, and clear the board. Arrows/WASD to steer, swipe on touch. Pure Canvas 2D, zero dependencies.",
+      "path": "games/chomp/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "gems",
+      "file": "NeonGems.aa",
+      "title": "Neon Gems",
+      "desc": "Match-3 puzzle — swap adjacent neon gems to line up three or more, trigger cascading chain combos, and rack up the score. Click/tap or drag to swap. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/gems/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "hopper",
+      "file": "AbramsHopper.aa",
+      "title": "Abrams Hopper",
+      "desc": "Frogger-style road-and-river crosser — hop across busy neon traffic lanes and ride logs over the water to reach the home slots without getting squashed or wet. Arrows/WASD to hop, swipe on touch. Pure Canvas 2D, zero dependencies.",
+      "path": "games/hopper/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "invaders",
+      "file": "NeonInvaders.aa",
+      "title": "Neon Invaders",
+      "desc": "Space-Invaders arcade shooter — slide your cannon, blast the descending grid of neon aliens before they reach the ground, and dodge their return fire. ←/→ move, Space fire, P pause. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/invaders/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "missile",
+      "file": "MissileCommand.aa",
+      "title": "Missile Command",
+      "desc": "City-defense classic — aim and detonate interceptor missiles to destroy incoming salvos before they wipe out your cities, across escalating waves. Click/tap to fire at a point. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/missile/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "racer",
+      "file": "NeonDrifter.aa",
+      "title": "Neon Drifter",
+      "desc": "Endless top-down racer — drift a neon car down a scrolling track, weave through traffic, and chase distance as the speed ramps up. Arrows/WASD to steer, swipe on touch. Pure Canvas 2D, zero dependencies.",
+      "path": "games/racer/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "sokoban",
+      "file": "NeonSokoban.aa",
+      "title": "Neon Sokoban",
+      "desc": "Crate-pushing puzzle — push every glowing crate onto its target pad in the fewest moves; you can only push, never pull, so plan ahead. Arrows/WASD to push, U undo, R restart. Pure vanilla JS, zero dependencies.",
+      "path": "games/sokoban/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "sudoku",
+      "file": "NeonSudoku.aa",
+      "title": "Neon Sudoku",
+      "desc": "Classic 9×9 Sudoku reborn in neon — fill the grid so every row, column, and box holds 1–9, with pencil marks, mistake highlighting, and multiple difficulties. Click a cell then type, or tap the number pad. Pure vanilla JS, zero dependencies.",
+      "path": "games/sudoku/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "tron",
+      "file": "AbramsTron.aa",
+      "title": "Abrams Tron",
+      "desc": "Light-cycle duel — race a neon trail across the grid, box out the AI rider, and force it to crash while you thread your own wall. Arrows/WASD to turn, P pause. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/tron/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "wordle",
+      "file": "AbramsWordle.aa",
+      "title": "Abrams Wordle",
+      "desc": "Guess the hidden five-letter word in six tries — green marks the right letter in the right spot, yellow the right letter misplaced, gray the misses. On-screen + physical keyboard, persistent stats. Pure vanilla JS, zero dependencies.",
+      "path": "games/wordle/",
+      "added": "2026-07-25"
+    }
+  ]
+};
diff --git a/games.json b/games.json
index f550251..b16dcbc 100644
--- a/games.json
+++ b/games.json
@@ -209,6 +209,86 @@
       "desc": "A lavish Beverly Hills take on classic backgammon — roll the dice, bear off your checkers, and hit the bar against an opponent on a gold-and-marble 90210 board. Self-contained HTML, zero runtime dependencies.",
       "path": "games/backgammon/",
       "added": "2026-07-25"
+    },
+    {
+      "id": "chomp",
+      "file": "AbramsChomp.aa",
+      "title": "Abrams Chomp",
+      "desc": "Neon maze-chomper — weave through the maze eating every pellet, grab power pellets to turn the tables and chase the ghosts, and clear the board. Arrows/WASD to steer, swipe on touch. Pure Canvas 2D, zero dependencies.",
+      "path": "games/chomp/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "gems",
+      "file": "NeonGems.aa",
+      "title": "Neon Gems",
+      "desc": "Match-3 puzzle — swap adjacent neon gems to line up three or more, trigger cascading chain combos, and rack up the score. Click/tap or drag to swap. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/gems/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "hopper",
+      "file": "AbramsHopper.aa",
+      "title": "Abrams Hopper",
+      "desc": "Frogger-style road-and-river crosser — hop across busy neon traffic lanes and ride logs over the water to reach the home slots without getting squashed or wet. Arrows/WASD to hop, swipe on touch. Pure Canvas 2D, zero dependencies.",
+      "path": "games/hopper/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "invaders",
+      "file": "NeonInvaders.aa",
+      "title": "Neon Invaders",
+      "desc": "Space-Invaders arcade shooter — slide your cannon, blast the descending grid of neon aliens before they reach the ground, and dodge their return fire. ←/→ move, Space fire, P pause. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/invaders/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "missile",
+      "file": "MissileCommand.aa",
+      "title": "Missile Command",
+      "desc": "City-defense classic — aim and detonate interceptor missiles to destroy incoming salvos before they wipe out your cities, across escalating waves. Click/tap to fire at a point. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/missile/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "racer",
+      "file": "NeonDrifter.aa",
+      "title": "Neon Drifter",
+      "desc": "Endless top-down racer — drift a neon car down a scrolling track, weave through traffic, and chase distance as the speed ramps up. Arrows/WASD to steer, swipe on touch. Pure Canvas 2D, zero dependencies.",
+      "path": "games/racer/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "sokoban",
+      "file": "NeonSokoban.aa",
+      "title": "Neon Sokoban",
+      "desc": "Crate-pushing puzzle — push every glowing crate onto its target pad in the fewest moves; you can only push, never pull, so plan ahead. Arrows/WASD to push, U undo, R restart. Pure vanilla JS, zero dependencies.",
+      "path": "games/sokoban/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "sudoku",
+      "file": "NeonSudoku.aa",
+      "title": "Neon Sudoku",
+      "desc": "Classic 9×9 Sudoku reborn in neon — fill the grid so every row, column, and box holds 1–9, with pencil marks, mistake highlighting, and multiple difficulties. Click a cell then type, or tap the number pad. Pure vanilla JS, zero dependencies.",
+      "path": "games/sudoku/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "tron",
+      "file": "AbramsTron.aa",
+      "title": "Abrams Tron",
+      "desc": "Light-cycle duel — race a neon trail across the grid, box out the AI rider, and force it to crash while you thread your own wall. Arrows/WASD to turn, P pause. Pure Canvas 2D, procedural Web Audio, zero dependencies.",
+      "path": "games/tron/",
+      "added": "2026-07-25"
+    },
+    {
+      "id": "wordle",
+      "file": "AbramsWordle.aa",
+      "title": "Abrams Wordle",
+      "desc": "Guess the hidden five-letter word in six tries — green marks the right letter in the right spot, yellow the right letter misplaced, gray the misses. On-screen + physical keyboard, persistent stats. Pure vanilla JS, zero dependencies.",
+      "path": "games/wordle/",
+      "added": "2026-07-25"
     }
   ]
 }
diff --git a/games/2048/Abrams2048.aa b/games/2048/Abrams2048.aa
new file mode 100644
index 0000000..9b93431
--- /dev/null
+++ b/games/2048/Abrams2048.aa
@@ -0,0 +1,213 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Abrams 2048</title>
+<style>
+  :root { --bg:#0a0e14; --ink:#e5e7eb; --board:#141b25; --cell:#1e2735; }
+  * { box-sizing:border-box; margin:0; padding:0; }
+  html,body { height:100%; }
+  body {
+    background:radial-gradient(1200px 600px at 50% -10%, #16202e, var(--bg));
+    color:var(--ink); font:15px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
+    display:flex; flex-direction:column; align-items:center; justify-content:center;
+    min-height:100%; gap:12px; padding:14px; overscroll-behavior:none; touch-action:none;
+  }
+  h1 { font-size:14px; letter-spacing:.28em; text-transform:uppercase; color:#93c5fd; font-weight:600; }
+  .hud { display:flex; gap:14px; align-items:center; }
+  .stat { background:var(--cell); border-radius:10px; padding:6px 14px; text-align:center; min-width:76px; }
+  .stat .k { font-size:10px; letter-spacing:.15em; text-transform:uppercase; color:#8b97a7; }
+  .stat .v { font-size:19px; font-weight:700; font-variant-numeric:tabular-nums; }
+  .btn { padding:8px 14px; border-radius:10px; border:1px solid #2a3441; background:var(--cell); color:#cbd5e1; cursor:pointer; font-size:13px; font-weight:600; }
+  #wrap { position:relative; }
+  #board { background:var(--board); border-radius:14px; padding:10px; display:grid; grid-template-columns:repeat(4,1fr); gap:10px; box-shadow:0 10px 40px rgba(0,0,0,.5); }
+  .tile { width:70px; height:70px; border-radius:10px; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:26px; background:var(--cell); color:#e5e7eb; transition:transform .09s ease; }
+  .tile.pop { animation:pop .16s ease; }
+  @keyframes pop { 0%{transform:scale(.6)} 60%{transform:scale(1.08)} 100%{transform:scale(1)} }
+  .overlay { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; text-align:center; background:rgba(8,12,18,.8); border-radius:14px; backdrop-filter:blur(2px); }
+  .overlay.hide { display:none; }
+  .big { font-size:24px; font-weight:800; }
+  .sub { font-size:13px; color:#9aa4b2; max-width:260px; }
+  .tag { font-size:11px; color:#93c5fd; letter-spacing:.2em; text-transform:uppercase; }
+  button.play { margin-top:4px; padding:10px 22px; border:0; border-radius:999px; cursor:pointer; background:linear-gradient(180deg,#60a5fa,#3b82f6); color:#fff; font-weight:700; font-size:14px; }
+  .hint { font-size:11px; color:#5b6673; }
+</style>
+</head>
+<body>
+  <h1>Abrams 2048</h1>
+  <div class="hud">
+    <div class="stat"><div class="k">Score</div><div class="v" id="score">0</div></div>
+    <div class="stat"><div class="k">Best</div><div class="v" id="best">0</div></div>
+    <button class="btn" id="newBtn">New</button>
+  </div>
+  <div id="wrap">
+    <div id="board"></div>
+    <div class="overlay hide" id="ov">
+      <div class="tag" id="ovTag">Nice</div>
+      <div class="big" id="ovTitle">2048!</div>
+      <div class="sub" id="ovSub"></div>
+      <button class="play" id="playBtn">New game</button>
+      <div class="hint">Arrows / WASD · swipe on touch</div>
+    </div>
+  </div>
+
+<script>
+(function () {
+  var boardEl = document.getElementById('board');
+  var scoreEl = document.getElementById('score'), bestEl = document.getElementById('best');
+  var ov = document.getElementById('ov'), ovTag = document.getElementById('ovTag'), ovTitle = document.getElementById('ovTitle'), ovSub = document.getElementById('ovSub');
+  var playBtn = document.getElementById('playBtn'), newBtn = document.getElementById('newBtn');
+
+  var BEST_KEY = 'abrams-2048-best';
+  var best = parseInt(localStorage.getItem(BEST_KEY) || '0', 10) || 0; bestEl.textContent = best;
+
+  var TILE_COLORS = {
+    2:'#334155', 4:'#3f5170', 8:'#5b7fb8', 16:'#38bdf8', 32:'#22c1a6', 64:'#4ade80',
+    128:'#facc15', 256:'#fb923c', 512:'#f472b6', 1024:'#e879f9', 2048:'#a78bfa', 4096:'#fca5a5'
+  };
+  var grid, score, won, ended;
+  var actx = null;
+  function beep(freq, dur, vol) {
+    try {
+      if (!actx) actx = new (window.AudioContext || window.webkitAudioContext)();
+      var o = actx.createOscillator(), g = actx.createGain();
+      o.type = 'sine'; o.frequency.value = freq; g.gain.value = vol || 0.04;
+      o.connect(g); g.connect(actx.destination);
+      var t = actx.currentTime; o.start(t); g.gain.exponentialRampToValueAtTime(0.0001, t + (dur || 0.08)); o.stop(t + (dur || 0.08));
+    } catch (e) {}
+  }
+
+  function empty() { var g = []; for (var i = 0; i < 16; i++) g.push(0); return g; }
+  function spawn() {
+    var free = [];
+    for (var i = 0; i < 16; i++) if (grid[i] === 0) free.push(i);
+    if (!free.length) return null;
+    var idx = free[(Math.random() * free.length) | 0];
+    grid[idx] = Math.random() < 0.9 ? 2 : 4;
+    return idx;
+  }
+  function newGame() {
+    grid = empty(); score = 0; won = false; ended = false;
+    spawn(); spawn(); ov.classList.add('hide'); render([], -1);
+    updateScore();
+    if (actx && actx.state === 'suspended') actx.resume();
+  }
+  function updateScore() {
+    scoreEl.textContent = score;
+    if (score > best) { best = score; localStorage.setItem(BEST_KEY, best); bestEl.textContent = best; }
+  }
+
+  // slide+merge one row (array of 4) toward index 0; returns {row, gained, moved, merges:[positions]}
+  function collapse(line) {
+    var vals = line.filter(function (v) { return v !== 0; });
+    var out = [], gained = 0, mergedAt = [];
+    for (var i = 0; i < vals.length; i++) {
+      if (i + 1 < vals.length && vals[i] === vals[i + 1]) {
+        var m = vals[i] * 2; out.push(m); gained += m; mergedAt.push(out.length - 1); i++;
+      } else out.push(vals[i]);
+    }
+    while (out.length < 4) out.push(0);
+    var moved = out.some(function (v, k) { return v !== line[k]; });
+    return { row: out, gained: gained, moved: moved, merges: mergedAt };
+  }
+
+  // dir: 'l','r','u','d'. Returns true if anything moved.
+  function move(dir) {
+    if (ended) return false;
+    var moved = false, gained = 0, mergedCells = [];
+    function get(r, c) { return grid[r * 4 + c]; }
+    function set(r, c, v) { grid[r * 4 + c] = v; }
+
+    for (var k = 0; k < 4; k++) {
+      var line = [];
+      for (var i = 0; i < 4; i++) {
+        if (dir === 'l') line.push(get(k, i));
+        else if (dir === 'r') line.push(get(k, 3 - i));
+        else if (dir === 'u') line.push(get(i, k));
+        else line.push(get(3 - i, k));
+      }
+      var res = collapse(line);
+      if (res.moved) moved = true;
+      gained += res.gained;
+      for (var i2 = 0; i2 < 4; i2++) {
+        var v = res.row[i2], r, c;
+        if (dir === 'l') { r = k; c = i2; } else if (dir === 'r') { r = k; c = 3 - i2; }
+        else if (dir === 'u') { r = i2; c = k; } else { r = 3 - i2; c = k; }
+        set(r, c, v);
+        if (res.merges.indexOf(i2) >= 0) mergedCells.push(r * 4 + c);
+      }
+    }
+    if (moved) {
+      score += gained; updateScore();
+      var spawnIdx = spawn();
+      var popCells = mergedCells.slice(); if (spawnIdx !== null) popCells.push(spawnIdx);
+      render(popCells, -1);
+      if (gained > 0) beep(400 + Math.min(600, gained), 0.07, 0.05);
+      if (!won && grid.indexOf(2048) >= 0) { won = true; finish('2048!', 'You hit 2048 — keep going for a higher score.', 'Keep playing'); }
+      else if (isStuck()) finish('Game Over', 'No moves left. Score ' + score + ', best ' + best + '.', 'New game');
+    }
+    return moved;
+  }
+
+  function isStuck() {
+    if (grid.indexOf(0) >= 0) return false;
+    for (var r = 0; r < 4; r++) for (var c = 0; c < 4; c++) {
+      var v = grid[r * 4 + c];
+      if (c < 3 && grid[r * 4 + c + 1] === v) return false;
+      if (r < 3 && grid[(r + 1) * 4 + c] === v) return false;
+    }
+    return true;
+  }
+
+  function finish(title, sub, btn) {
+    if (title === 'Game Over') ended = true;
+    ovTag.textContent = title === 'Game Over' ? 'Done' : 'Milestone';
+    ovTitle.textContent = title; ovSub.textContent = sub; playBtn.textContent = btn;
+    ov.classList.remove('hide');
+    beep(title === 'Game Over' ? 180 : 880, 0.25, 0.07);
+  }
+
+  function render(popCells, _) {
+    boardEl.innerHTML = '';
+    for (var i = 0; i < 16; i++) {
+      var v = grid[i], d = document.createElement('div');
+      d.className = 'tile' + (popCells && popCells.indexOf(i) >= 0 ? ' pop' : '');
+      if (v) {
+        d.textContent = v;
+        d.style.background = TILE_COLORS[v] || '#a78bfa';
+        d.style.color = v <= 4 ? '#cbd5e1' : '#0a0e14';
+        d.style.fontSize = v >= 1024 ? '20px' : v >= 128 ? '23px' : '26px';
+      }
+      boardEl.appendChild(d);
+    }
+  }
+
+  // input
+  window.addEventListener('keydown', function (e) {
+    var k = e.key.toLowerCase(), d = null;
+    if (k === 'arrowleft' || k === 'a') d = 'l';
+    else if (k === 'arrowright' || k === 'd') d = 'r';
+    else if (k === 'arrowup' || k === 'w') d = 'u';
+    else if (k === 'arrowdown' || k === 's') d = 'd';
+    if (d) { move(d); e.preventDefault(); }
+  });
+  var tsx = 0, tsy = 0;
+  boardEl.addEventListener('touchstart', function (e) { var t = e.touches[0]; tsx = t.clientX; tsy = t.clientY; }, { passive: true });
+  boardEl.addEventListener('touchend', function (e) {
+    var t = e.changedTouches[0], dx = t.clientX - tsx, dy = t.clientY - tsy;
+    if (Math.abs(dx) < 20 && Math.abs(dy) < 20) return;
+    if (Math.abs(dx) > Math.abs(dy)) move(dx > 0 ? 'r' : 'l'); else move(dy > 0 ? 'd' : 'u');
+  }, { passive: true });
+
+  playBtn.addEventListener('click', function () {
+    if (won && !ended && playBtn.textContent === 'Keep playing') { ov.classList.add('hide'); return; }
+    newGame();
+  });
+  newBtn.addEventListener('click', newGame);
+
+  newGame();
+})();
+</script>
+</body>
+</html>
diff --git a/games/asteroids/AbramsAsteroids.aa b/games/asteroids/AbramsAsteroids.aa
new file mode 100644
index 0000000..b0f04be
--- /dev/null
+++ b/games/asteroids/AbramsAsteroids.aa
@@ -0,0 +1,828 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<title>Abrams Asteroids</title>
+<style>
+  :root {
+    --neon: #00f0ff;
+    --neon2: #ff2bd6;
+    --accent: #b6ff3a;
+    --bg0: #04060f;
+    --bg1: #0a0f24;
+  }
+  * { box-sizing: border-box; margin: 0; padding: 0; }
+  html, body {
+    width: 100%; height: 100%;
+    overflow: hidden;
+    background: var(--bg0);
+    font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
+    -webkit-user-select: none; user-select: none;
+    -webkit-tap-highlight-color: transparent;
+    touch-action: none;
+  }
+  #wrap {
+    position: fixed; inset: 0;
+    background:
+      radial-gradient(ellipse at 50% 30%, #0d1636 0%, var(--bg0) 70%),
+      var(--bg0);
+  }
+  canvas { position: absolute; inset: 0; display: block; }
+
+  /* HUD */
+  #hud {
+    position: absolute; top: 0; left: 0; right: 0;
+    display: flex; justify-content: space-between; align-items: flex-start;
+    padding: 14px 18px;
+    pointer-events: none;
+    font-variant-numeric: tabular-nums;
+    text-shadow: 0 0 8px currentColor;
+    z-index: 5;
+  }
+  #hud .col { display: flex; flex-direction: column; gap: 4px; }
+  #hud .col.right { align-items: flex-end; text-align: right; }
+  .label { font-size: 11px; letter-spacing: 3px; color: #6f7bb5; text-shadow: none; }
+  .val { font-size: 22px; font-weight: 700; letter-spacing: 1px; color: var(--neon); }
+  .val.best { color: var(--accent); font-size: 16px; }
+  #lives { display: flex; gap: 6px; margin-top: 2px; }
+  #lives svg { filter: drop-shadow(0 0 4px var(--neon)); }
+  #wave { color: var(--neon2); font-size: 16px; }
+
+  /* Overlay */
+  #overlay {
+    position: absolute; inset: 0;
+    display: flex; flex-direction: column;
+    align-items: center; justify-content: center;
+    text-align: center;
+    background: radial-gradient(ellipse at 50% 45%, rgba(6,10,28,.72) 0%, rgba(2,4,12,.94) 75%);
+    z-index: 10;
+    padding: 24px;
+    backdrop-filter: blur(2px);
+  }
+  #overlay.hidden { display: none; }
+  #title {
+    font-size: clamp(34px, 9vw, 84px);
+    font-weight: 800;
+    letter-spacing: clamp(2px, 1.5vw, 12px);
+    color: #eafcff;
+    text-shadow: 0 0 18px var(--neon), 0 0 40px var(--neon), 0 0 4px #fff;
+    line-height: 1;
+  }
+  #title .sub { display:block; font-size: clamp(13px,3.5vw,22px); letter-spacing: clamp(3px,2vw,16px); color: var(--neon2); text-shadow: 0 0 12px var(--neon2); margin-top: 10px; }
+  #ovMsg { margin-top: 18px; font-size: clamp(14px,4vw,20px); color: #b9c6ff; min-height: 1.2em; text-shadow: 0 0 8px rgba(120,150,255,.4);}
+  #ovScore { margin-top: 6px; font-size: clamp(13px,3.6vw,18px); color: var(--accent); }
+  #playBtn {
+    margin-top: 26px;
+    pointer-events: auto; cursor: pointer;
+    background: linear-gradient(180deg, rgba(0,240,255,.16), rgba(0,240,255,.04));
+    border: 2px solid var(--neon);
+    color: #eafcff;
+    font-size: clamp(16px,4.5vw,22px); font-weight: 700; letter-spacing: 4px;
+    padding: 14px 40px; border-radius: 40px;
+    text-shadow: 0 0 10px var(--neon);
+    box-shadow: 0 0 22px rgba(0,240,255,.35), inset 0 0 18px rgba(0,240,255,.18);
+    transition: transform .08s ease, box-shadow .2s ease;
+  }
+  #playBtn:hover { box-shadow: 0 0 34px rgba(0,240,255,.6), inset 0 0 24px rgba(0,240,255,.28); }
+  #playBtn:active { transform: scale(.96); }
+  #hint {
+    margin-top: 26px; font-size: clamp(11px,3vw,14px); color: #6f7bb5;
+    letter-spacing: 1px; line-height: 1.9; max-width: 560px;
+  }
+  #hint b { color: var(--neon); font-weight: 700; }
+
+  /* Toast / status pills */
+  #statusPills {
+    position: absolute; top: 56px; left: 50%; transform: translateX(-50%);
+    display: flex; gap: 10px; z-index: 6; pointer-events: none;
+  }
+  .pill {
+    font-size: 11px; letter-spacing: 2px; padding: 4px 10px; border-radius: 20px;
+    border: 1px solid rgba(120,150,255,.4); color: #9fb0f0; background: rgba(10,16,40,.6);
+    opacity: 0; transition: opacity .3s;
+  }
+  .pill.on { opacity: 1; }
+  .pill.paused { color: var(--accent); border-color: var(--accent); }
+  .pill.muted { color: var(--neon2); border-color: var(--neon2); }
+
+  #centerToast {
+    position: absolute; top: 42%; left: 50%; transform: translate(-50%,-50%);
+    font-size: clamp(20px,7vw,48px); font-weight: 800; letter-spacing: 6px;
+    color: #eafcff; text-shadow: 0 0 20px var(--neon2), 0 0 40px var(--neon2);
+    z-index: 7; pointer-events: none; opacity: 0; transition: opacity .4s;
+  }
+  #centerToast.on { opacity: 1; }
+
+  /* Touch controls */
+  #touch { position: absolute; inset: 0; z-index: 8; display: none; pointer-events: none; }
+  #touch.show { display: block; }
+  .tbtn {
+    position: absolute; pointer-events: auto;
+    display: flex; align-items: center; justify-content: center;
+    border-radius: 50%;
+    border: 2px solid rgba(0,240,255,.55);
+    background: rgba(8,14,36,.42);
+    color: var(--neon); font-weight: 700; font-size: 13px; letter-spacing: 1px;
+    box-shadow: 0 0 14px rgba(0,240,255,.22), inset 0 0 12px rgba(0,240,255,.12);
+    backdrop-filter: blur(2px);
+    -webkit-user-select: none; user-select: none;
+    transition: background .08s, transform .08s;
+  }
+  .tbtn:active, .tbtn.active { background: rgba(0,240,255,.28); transform: scale(.94); }
+  .tbtn svg { width: 44%; height: 44%; fill: var(--neon); filter: drop-shadow(0 0 4px var(--neon)); }
+  #tLeft  { left: 20px;  bottom: 96px; width: 74px; height: 74px; }
+  #tRight { left: 110px; bottom: 30px; width: 74px; height: 74px; }
+  #tThrust{ right: 110px; bottom: 96px; width: 82px; height: 82px; }
+  #tFire  { right: 20px;  bottom: 30px; width: 82px; height: 82px; border-color: var(--neon2); color: var(--neon2); box-shadow: 0 0 14px rgba(255,43,214,.3), inset 0 0 12px rgba(255,43,214,.14); }
+  #tFire svg { fill: var(--neon2); filter: drop-shadow(0 0 4px var(--neon2)); }
+  #tHyper { right: 24px; top: 84px; width: 56px; height: 56px; font-size: 11px; border-color: var(--accent); color: var(--accent); }
+</style>
+</head>
+<body>
+<div id="wrap">
+  <canvas id="game"></canvas>
+
+  <div id="hud">
+    <div class="col">
+      <span class="label">SCORE</span>
+      <span class="val" id="score">0</span>
+      <span class="val best" id="best">BEST 0</span>
+    </div>
+    <div class="col right">
+      <span class="label">WAVE</span>
+      <span class="val" id="wave">1</span>
+      <span class="label" style="margin-top:6px;">SHIPS</span>
+      <div id="lives"></div>
+    </div>
+  </div>
+
+  <div id="statusPills">
+    <span class="pill paused" id="pillPaused">PAUSED</span>
+    <span class="pill muted" id="pillMuted">MUTED</span>
+  </div>
+
+  <div id="centerToast"></div>
+
+  <!-- Touch controls -->
+  <div id="touch">
+    <div class="tbtn" id="tLeft"><svg viewBox="0 0 100 100"><path d="M65 15 L30 50 L65 85 Z"/></svg></div>
+    <div class="tbtn" id="tRight"><svg viewBox="0 0 100 100"><path d="M35 15 L70 50 L35 85 Z"/></svg></div>
+    <div class="tbtn" id="tThrust"><svg viewBox="0 0 100 100"><path d="M50 12 L80 78 L50 62 L20 78 Z"/></svg></div>
+    <div class="tbtn" id="tFire"><svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="26"/></svg></div>
+    <div class="tbtn" id="tHyper">HYP</div>
+  </div>
+
+  <div id="overlay">
+    <div id="title">ABRAMS<span class="sub">ASTEROIDS</span></div>
+    <div id="ovMsg">Clear the field. Survive the swarm.</div>
+    <div id="ovScore"></div>
+    <button id="playBtn">LAUNCH</button>
+    <div id="hint">
+      <b>&#9650; / W</b> Thrust &nbsp; <b>&#9664; &#9654; / A D</b> Rotate &nbsp; <b>SPACE</b> Fire<br>
+      <b>SHIFT</b> Hyperspace &nbsp; <b>P</b> Pause &nbsp; <b>M</b> Mute &nbsp; <b>R</b> Restart<br>
+      <span style="opacity:.75">Touch devices: use the on-screen pads.</span>
+    </div>
+  </div>
+</div>
+
+<script>
+(function () {
+  "use strict";
+
+  // ---------- Setup ----------
+  var canvas = document.getElementById("game");
+  var ctx = canvas.getContext("2d");
+  var wrap = document.getElementById("wrap");
+
+  var W = 0, H = 0, DPR = 1;
+
+  function resize() {
+    DPR = Math.min(window.devicePixelRatio || 1, 2);
+    var r = wrap.getBoundingClientRect();
+    W = Math.max(320, r.width);
+    H = Math.max(240, r.height);
+    canvas.width = Math.floor(W * DPR);
+    canvas.height = Math.floor(H * DPR);
+    canvas.style.width = W + "px";
+    canvas.style.height = H + "px";
+    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+  }
+  window.addEventListener("resize", resize);
+  resize();
+
+  // ---------- Audio (Web Audio, procedural) ----------
+  var Audio = (function () {
+    var actx = null, master = null;
+    var muted = false;
+    function ensure() {
+      if (actx) return;
+      try {
+        var AC = window.AudioContext || window.webkitAudioContext;
+        actx = new AC();
+        master = actx.createGain();
+        master.gain.value = 0.35;
+        master.connect(actx.destination);
+      } catch (e) { actx = null; }
+    }
+    function resume() { if (actx && actx.state === "suspended") actx.resume(); }
+    function tone(freq, dur, type, vol, slideTo) {
+      if (muted || !actx) return;
+      var t = actx.currentTime;
+      var o = actx.createOscillator();
+      var g = actx.createGain();
+      o.type = type || "square";
+      o.frequency.setValueAtTime(freq, t);
+      if (slideTo) o.frequency.exponentialRampToValueAtTime(Math.max(20, slideTo), t + dur);
+      g.gain.setValueAtTime(0.0001, t);
+      g.gain.exponentialRampToValueAtTime(vol || 0.3, t + 0.008);
+      g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
+      o.connect(g); g.connect(master);
+      o.start(t); o.stop(t + dur + 0.02);
+    }
+    function noise(dur, vol, freq) {
+      if (muted || !actx) return;
+      var t = actx.currentTime;
+      var n = Math.floor(actx.sampleRate * dur);
+      var buf = actx.createBuffer(1, n, actx.sampleRate);
+      var d = buf.getChannelData(0);
+      for (var i = 0; i < n; i++) d[i] = (Math.random() * 2 - 1) * (1 - i / n);
+      var src = actx.createBufferSource(); src.buffer = buf;
+      var flt = actx.createBiquadFilter();
+      flt.type = "lowpass"; flt.frequency.value = freq || 1200;
+      var g = actx.createGain();
+      g.gain.setValueAtTime(vol || 0.4, t);
+      g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
+      src.connect(flt); flt.connect(g); g.connect(master);
+      src.start(t);
+    }
+    return {
+      init: function () { ensure(); resume(); },
+      resume: resume,
+      isMuted: function () { return muted; },
+      toggleMute: function () { muted = !muted; return muted; },
+      shoot: function () { tone(880, 0.09, "square", 0.14, 300); },
+      thrust: function () { noise(0.05, 0.06, 500); },
+      bangBig: function () { noise(0.32, 0.5, 700); tone(70, 0.3, "sawtooth", 0.2, 40); },
+      bangMed: function () { noise(0.22, 0.4, 1000); tone(120, 0.2, "sawtooth", 0.15, 60); },
+      bangSmall: function () { noise(0.14, 0.3, 1600); tone(200, 0.12, "square", 0.12, 90); },
+      hyper: function () { tone(200, 0.35, "sine", 0.25, 1400); },
+      death: function () { noise(0.6, 0.55, 500); tone(160, 0.6, "sawtooth", 0.3, 30); },
+      wave: function () { tone(523, 0.12, "triangle", 0.2); setTimeout(function(){tone(784,0.16,"triangle",0.2);}, 120); },
+      extraLife: function () { tone(660, 0.1, "triangle", 0.2); setTimeout(function(){tone(990,0.14,"triangle",0.22);}, 100); }
+    };
+  })();
+
+  // ---------- Input ----------
+  var keys = {};
+  var touch = { left: false, right: false, thrust: false, fire: false };
+
+  function down(code) {
+    if (code === "KeyM") { toggleMute(); return; }
+    if (code === "KeyP") { togglePause(); return; }
+    if (code === "KeyR") { if (state === "play" || state === "over") restart(); return; }
+    keys[code] = true;
+  }
+  function up(code) { keys[code] = false; }
+
+  window.addEventListener("keydown", function (e) {
+    var c = e.code;
+    if (["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Space"].indexOf(c) >= 0) e.preventDefault();
+    if (state !== "play") {
+      if (c === "Space" || c === "Enter") {
+        if (state === "start" || state === "over") { startGame(); return; }
+      }
+    }
+    Audio.init();
+    down(c);
+  });
+  window.addEventListener("keyup", function (e) { up(e.code); });
+
+  // Touch buttons
+  function bindTouch(id, prop) {
+    var el = document.getElementById(id);
+    function on(e) { e.preventDefault(); Audio.init(); touch[prop] = true; el.classList.add("active"); }
+    function off(e) { e.preventDefault(); touch[prop] = false; el.classList.remove("active"); }
+    el.addEventListener("touchstart", on, { passive: false });
+    el.addEventListener("touchend", off, { passive: false });
+    el.addEventListener("touchcancel", off, { passive: false });
+    el.addEventListener("mousedown", on);
+    el.addEventListener("mouseup", off);
+    el.addEventListener("mouseleave", off);
+  }
+  bindTouch("tLeft", "left");
+  bindTouch("tRight", "right");
+  bindTouch("tThrust", "thrust");
+  bindTouch("tFire", "fire");
+  (function () {
+    var el = document.getElementById("tHyper");
+    function on(e) { e.preventDefault(); Audio.init(); doHyperspace(); el.classList.add("active"); }
+    function off(e) { e.preventDefault(); el.classList.remove("active"); }
+    el.addEventListener("touchstart", on, { passive: false });
+    el.addEventListener("touchend", off, { passive: false });
+    el.addEventListener("mousedown", on);
+    el.addEventListener("mouseup", off);
+  })();
+
+  var isTouch = ("ontouchstart" in window) || navigator.maxTouchPoints > 0;
+  if (isTouch) document.getElementById("touch").classList.add("show");
+
+  // ---------- Game constants ----------
+  var SHIP_R = 14;
+  var TURN = 4.2;           // rad/sec
+  var THRUST = 340;         // px/sec^2
+  var FRICTION = 0.72;      // per sec (velocity retained ~)
+  var MAX_SPEED = 460;
+  var BULLET_SPEED = 560;
+  var BULLET_LIFE = 0.85;
+  var FIRE_COOLDOWN = 0.16;
+  var INVULN_TIME = 2.4;
+  var START_LIVES = 3;
+  var EXTRA_LIFE_EVERY = 10000;
+
+  var AST_SIZES = { big: 46, med: 26, small: 15 };
+  var AST_SCORE = { big: 20, med: 50, small: 100 };
+  var AST_SPEED = { big: 42, med: 66, small: 92 };
+
+  // ---------- State ----------
+  var state = "start"; // start | play | paused | over
+  var ship, bullets, asteroids, particles;
+  var score, best, lives, wave, fireTimer, hyperCooldown, nextExtra;
+  var thrustSoundTimer = 0;
+
+  best = parseInt(localStorage.getItem("abrams-asteroids-best") || "0", 10) || 0;
+
+  function rand(a, b) { return a + Math.random() * (b - a); }
+  function wrapPos(o) {
+    if (o.x < 0) o.x += W; else if (o.x >= W) o.x -= W;
+    if (o.y < 0) o.y += H; else if (o.y >= H) o.y -= H;
+  }
+
+  function makeShip() {
+    return { x: W / 2, y: H / 2, a: -Math.PI / 2, vx: 0, vy: 0, r: SHIP_R, invuln: INVULN_TIME, thrusting: false, alive: true };
+  }
+
+  function makeAsteroid(x, y, size) {
+    var speed = AST_SPEED[size] * rand(0.7, 1.35);
+    var ang = rand(0, Math.PI * 2);
+    var r = AST_SIZES[size];
+    var verts = [], n = Math.floor(rand(9, 14));
+    for (var i = 0; i < n; i++) {
+      verts.push(rand(0.72, 1.15));
+    }
+    return {
+      x: x, y: y, size: size, r: r,
+      vx: Math.cos(ang) * speed, vy: Math.sin(ang) * speed,
+      rot: rand(-1, 1), spin: rand(-0.9, 0.9),
+      verts: verts, hue: rand(180, 300)
+    };
+  }
+
+  function spawnWave(n) {
+    asteroids = [];
+    for (var i = 0; i < n; i++) {
+      // spawn away from ship center
+      var x, y, tries = 0;
+      do {
+        x = rand(0, W); y = rand(0, H);
+        tries++;
+      } while (ship && Math.hypot(x - ship.x, y - ship.y) < 180 && tries < 30);
+      asteroids.push(makeAsteroid(x, y, "big"));
+    }
+  }
+
+  function resetRound() {
+    ship = makeShip();
+    bullets = [];
+    particles = [];
+    fireTimer = 0;
+    hyperCooldown = 0;
+  }
+
+  function startGame() {
+    Audio.init();
+    score = 0; lives = START_LIVES; wave = 1; nextExtra = EXTRA_LIFE_EVERY;
+    resetRound();
+    spawnWave(4);
+    state = "play";
+    hideOverlay();
+    Audio.wave();
+    lastT = performance.now();
+    showToast("WAVE 1", 900);
+  }
+
+  function restart() {
+    startGame();
+  }
+
+  function nextWave() {
+    wave++;
+    spawnWave(Math.min(4 + wave, 12));
+    ship.invuln = Math.max(ship.invuln, 1.2);
+    Audio.wave();
+    showToast("WAVE " + wave, 900);
+  }
+
+  function gameOver() {
+    state = "over";
+    if (score > best) {
+      best = score;
+      localStorage.setItem("abrams-asteroids-best", String(best));
+    }
+    updateHud();
+    showOverlay(
+      "GAME OVER",
+      "The field claimed your fleet.",
+      "SCORE " + score + "   •   BEST " + best,
+      "PLAY AGAIN"
+    );
+  }
+
+  // ---------- Actions ----------
+  function fire() {
+    if (fireTimer > 0 || !ship || !ship.alive) return;
+    if (bullets.length > 8) return;
+    var nx = Math.cos(ship.a), ny = Math.sin(ship.a);
+    bullets.push({
+      x: ship.x + nx * ship.r, y: ship.y + ny * ship.r,
+      vx: ship.vx + nx * BULLET_SPEED, vy: ship.vy + ny * BULLET_SPEED,
+      life: BULLET_LIFE
+    });
+    fireTimer = FIRE_COOLDOWN;
+    Audio.shoot();
+  }
+
+  function doHyperspace() {
+    if (state !== "play" || !ship || !ship.alive || hyperCooldown > 0) return;
+    hyperCooldown = 1.2;
+    // small risk: 12% chance of misjump explosion
+    ship.x = rand(40, W - 40);
+    ship.y = rand(40, H - 40);
+    ship.vx = 0; ship.vy = 0;
+    ship.invuln = Math.max(ship.invuln, 0.8);
+    Audio.hyper();
+    for (var i = 0; i < 14; i++) spawnParticle(ship.x, ship.y, 200, "#00f0ff");
+    if (Math.random() < 0.12) {
+      killShip();
+    }
+  }
+
+  function killShip() {
+    if (!ship.alive) return;
+    ship.alive = false;
+    Audio.death();
+    for (var i = 0; i < 26; i++) spawnParticle(ship.x, ship.y, 240, "#ff2bd6");
+    lives--;
+    updateHud();
+    if (lives <= 0) {
+      setTimeout(gameOver, 900);
+    } else {
+      setTimeout(function () {
+        if (state !== "play") return;
+        ship = makeShip();
+      }, 900);
+    }
+  }
+
+  function splitAsteroid(a, idx) {
+    // score
+    addScore(AST_SCORE[a.size]);
+    // particles
+    var col = "hsl(" + a.hue + ",90%,65%)";
+    var pc = a.size === "big" ? 16 : a.size === "med" ? 11 : 7;
+    for (var i = 0; i < pc; i++) spawnParticle(a.x, a.y, a.size === "big" ? 220 : 160, col);
+    if (a.size === "big") Audio.bangBig();
+    else if (a.size === "med") Audio.bangMed();
+    else Audio.bangSmall();
+
+    asteroids.splice(idx, 1);
+    if (a.size === "big") {
+      asteroids.push(makeAsteroid(a.x, a.y, "med"));
+      asteroids.push(makeAsteroid(a.x, a.y, "med"));
+    } else if (a.size === "med") {
+      asteroids.push(makeAsteroid(a.x, a.y, "small"));
+      asteroids.push(makeAsteroid(a.x, a.y, "small"));
+    }
+  }
+
+  function addScore(n) {
+    score += n;
+    if (score >= nextExtra) {
+      lives++;
+      nextExtra += EXTRA_LIFE_EVERY;
+      Audio.extraLife();
+      showToast("EXTRA SHIP", 800);
+    }
+    updateHud();
+  }
+
+  function spawnParticle(x, y, spd, color) {
+    var a = rand(0, Math.PI * 2);
+    var s = rand(spd * 0.25, spd);
+    particles.push({
+      x: x, y: y, vx: Math.cos(a) * s, vy: Math.sin(a) * s,
+      life: rand(0.4, 0.9), max: 0.9, color: color
+    });
+  }
+
+  // ---------- Update ----------
+  function update(dt) {
+    if (state !== "play") return;
+
+    // ship controls
+    if (ship && ship.alive) {
+      var left = keys["ArrowLeft"] || keys["KeyA"] || touch.left;
+      var right = keys["ArrowRight"] || keys["KeyD"] || touch.right;
+      var thr = keys["ArrowUp"] || keys["KeyW"] || touch.thrust;
+      var shift = keys["ShiftLeft"] || keys["ShiftRight"];
+
+      if (left) ship.a -= TURN * dt;
+      if (right) ship.a += TURN * dt;
+
+      ship.thrusting = !!thr;
+      if (thr) {
+        ship.vx += Math.cos(ship.a) * THRUST * dt;
+        ship.vy += Math.sin(ship.a) * THRUST * dt;
+        thrustSoundTimer -= dt;
+        if (thrustSoundTimer <= 0) { Audio.thrust(); thrustSoundTimer = 0.06; }
+      }
+      // clamp speed
+      var sp = Math.hypot(ship.vx, ship.vy);
+      if (sp > MAX_SPEED) { ship.vx *= MAX_SPEED / sp; ship.vy *= MAX_SPEED / sp; }
+      // friction
+      var f = Math.pow(FRICTION, dt);
+      ship.vx *= f; ship.vy *= f;
+
+      ship.x += ship.vx * dt; ship.y += ship.vy * dt;
+      wrapPos(ship);
+
+      if (shift && hyperCooldown <= 0) doHyperspace();
+
+      if (keys["Space"] || touch.fire) fire();
+
+      if (ship.invuln > 0) ship.invuln -= dt;
+    }
+
+    if (fireTimer > 0) fireTimer -= dt;
+    if (hyperCooldown > 0) hyperCooldown -= dt;
+
+    // bullets
+    for (var i = bullets.length - 1; i >= 0; i--) {
+      var b = bullets[i];
+      b.x += b.vx * dt; b.y += b.vy * dt;
+      wrapPos(b);
+      b.life -= dt;
+      if (b.life <= 0) { bullets.splice(i, 1); continue; }
+    }
+
+    // asteroids
+    for (var j = 0; j < asteroids.length; j++) {
+      var a = asteroids[j];
+      a.x += a.vx * dt; a.y += a.vy * dt;
+      a.rot += a.spin * dt;
+      wrapPos(a);
+    }
+
+    // bullet vs asteroid
+    for (var bi = bullets.length - 1; bi >= 0; bi--) {
+      var bu = bullets[bi];
+      for (var ai = asteroids.length - 1; ai >= 0; ai--) {
+        var as = asteroids[ai];
+        if ((bu.x - as.x) * (bu.x - as.x) + (bu.y - as.y) * (bu.y - as.y) < as.r * as.r) {
+          bullets.splice(bi, 1);
+          splitAsteroid(as, ai);
+          break; // this bullet is gone; move to next bullet
+        }
+      }
+    }
+
+    // ship vs asteroid
+    if (ship && ship.alive && ship.invuln <= 0) {
+      for (var k = 0; k < asteroids.length; k++) {
+        var ak = asteroids[k];
+        var rr = ak.r + ship.r * 0.7;
+        if ((ship.x - ak.x) * (ship.x - ak.x) + (ship.y - ak.y) * (ship.y - ak.y) < rr * rr) {
+          killShip();
+          break;
+        }
+      }
+    }
+
+    // particles
+    for (var p = particles.length - 1; p >= 0; p--) {
+      var pt = particles[p];
+      pt.x += pt.vx * dt; pt.y += pt.vy * dt;
+      pt.vx *= Math.pow(0.4, dt); pt.vy *= Math.pow(0.4, dt);
+      pt.life -= dt;
+      if (pt.life <= 0) particles.splice(p, 1);
+    }
+
+    // wave clear
+    if (asteroids.length === 0) nextWave();
+  }
+
+  // ---------- Render ----------
+  var starField = null;
+  function buildStars() {
+    starField = [];
+    var n = Math.floor((W * H) / 6500);
+    for (var i = 0; i < n; i++) {
+      starField.push({ x: Math.random() * W, y: Math.random() * H, r: Math.random() * 1.4 + 0.2, a: Math.random() * 0.6 + 0.2 });
+    }
+  }
+  buildStars();
+  var lastStarKey = W + "x" + H;
+
+  function drawStars() {
+    var key = W + "x" + H;
+    if (key !== lastStarKey || !starField) { buildStars(); lastStarKey = key; }
+    ctx.save();
+    for (var i = 0; i < starField.length; i++) {
+      var s = starField[i];
+      ctx.globalAlpha = s.a;
+      ctx.fillStyle = "#9fc7ff";
+      ctx.beginPath();
+      ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
+      ctx.fill();
+    }
+    ctx.restore();
+  }
+
+  function drawShip() {
+    if (!ship || !ship.alive) return;
+    if (ship.invuln > 0 && Math.floor(ship.invuln * 12) % 2 === 0) return; // blink
+    ctx.save();
+    ctx.translate(ship.x, ship.y);
+    ctx.rotate(ship.a);
+    // thrust flame
+    if (ship.thrusting && Math.random() > 0.35) {
+      ctx.beginPath();
+      ctx.moveTo(-ship.r * 0.6, -5);
+      ctx.lineTo(-ship.r * 1.5 - Math.random() * 8, 0);
+      ctx.lineTo(-ship.r * 0.6, 5);
+      ctx.strokeStyle = "#ff9b2b";
+      ctx.lineWidth = 2;
+      ctx.shadowBlur = 14; ctx.shadowColor = "#ff6a00";
+      ctx.stroke();
+    }
+    // hull
+    ctx.beginPath();
+    ctx.moveTo(ship.r, 0);
+    ctx.lineTo(-ship.r * 0.7, -ship.r * 0.75);
+    ctx.lineTo(-ship.r * 0.4, 0);
+    ctx.lineTo(-ship.r * 0.7, ship.r * 0.75);
+    ctx.closePath();
+    ctx.strokeStyle = "#eafcff";
+    ctx.lineWidth = 2;
+    ctx.shadowBlur = 12; ctx.shadowColor = "#00f0ff";
+    ctx.stroke();
+    ctx.restore();
+  }
+
+  function drawAsteroid(a) {
+    ctx.save();
+    ctx.translate(a.x, a.y);
+    ctx.rotate(a.rot);
+    ctx.beginPath();
+    var n = a.verts.length;
+    for (var i = 0; i < n; i++) {
+      var ang = (i / n) * Math.PI * 2;
+      var rr = a.r * a.verts[i];
+      var px = Math.cos(ang) * rr, py = Math.sin(ang) * rr;
+      if (i === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
+    }
+    ctx.closePath();
+    ctx.strokeStyle = "hsl(" + a.hue + ",85%,68%)";
+    ctx.lineWidth = 2;
+    ctx.shadowBlur = 12; ctx.shadowColor = "hsl(" + a.hue + ",90%,55%)";
+    ctx.stroke();
+    ctx.restore();
+  }
+
+  function drawBullets() {
+    ctx.save();
+    ctx.fillStyle = "#eafcff";
+    ctx.shadowBlur = 10; ctx.shadowColor = "#00f0ff";
+    for (var i = 0; i < bullets.length; i++) {
+      var b = bullets[i];
+      ctx.beginPath();
+      ctx.arc(b.x, b.y, 2.4, 0, Math.PI * 2);
+      ctx.fill();
+    }
+    ctx.restore();
+  }
+
+  function drawParticles() {
+    ctx.save();
+    for (var i = 0; i < particles.length; i++) {
+      var p = particles[i];
+      ctx.globalAlpha = Math.max(0, p.life / p.max);
+      ctx.fillStyle = p.color;
+      ctx.beginPath();
+      ctx.arc(p.x, p.y, 2, 0, Math.PI * 2);
+      ctx.fill();
+    }
+    ctx.restore();
+  }
+
+  function render() {
+    ctx.clearRect(0, 0, W, H);
+    drawStars();
+    if (state === "play" || state === "paused" || state === "over") {
+      drawParticles();
+      for (var i = 0; i < (asteroids ? asteroids.length : 0); i++) drawAsteroid(asteroids[i]);
+      drawBullets();
+      drawShip();
+    }
+  }
+
+  // ---------- HUD / overlay ----------
+  var elScore = document.getElementById("score");
+  var elBest = document.getElementById("best");
+  var elWave = document.getElementById("wave");
+  var elLives = document.getElementById("lives");
+  var overlay = document.getElementById("overlay");
+  var ovTitle = document.getElementById("title");
+  var ovMsg = document.getElementById("ovMsg");
+  var ovScore = document.getElementById("ovScore");
+  var playBtn = document.getElementById("playBtn");
+  var pillPaused = document.getElementById("pillPaused");
+  var pillMuted = document.getElementById("pillMuted");
+  var centerToast = document.getElementById("centerToast");
+
+  function shipIcon() {
+    return '<svg width="16" height="16" viewBox="0 0 100 100"><path d="M85 50 L20 20 L38 50 L20 80 Z" fill="none" stroke="#00f0ff" stroke-width="8"/></svg>';
+  }
+
+  function updateHud() {
+    elScore.textContent = score != null ? score : 0;
+    elBest.textContent = "BEST " + best;
+    elWave.textContent = wave != null ? wave : 1;
+    var html = "";
+    var n = Math.max(0, lives != null ? lives : 0);
+    for (var i = 0; i < Math.min(n, 6); i++) html += shipIcon();
+    if (n > 6) html += '<span style="color:#00f0ff;font-size:14px;align-self:center;">x' + n + '</span>';
+    elLives.innerHTML = html;
+  }
+
+  function showOverlay(title, msg, sc, btn) {
+    ovTitle.innerHTML = title === "ABRAMS" ? 'ABRAMS<span class="sub">ASTEROIDS</span>' :
+      (title + '<span class="sub" style="visibility:hidden">.</span>');
+    if (title === "GAME OVER") {
+      ovTitle.innerHTML = 'GAME<span class="sub">OVER</span>';
+    }
+    ovMsg.textContent = msg || "";
+    ovScore.textContent = sc || "";
+    playBtn.textContent = btn || "LAUNCH";
+    overlay.classList.remove("hidden");
+  }
+  function hideOverlay() { overlay.classList.add("hidden"); }
+
+  playBtn.addEventListener("click", function () { Audio.init(); startGame(); });
+
+  var toastTimer = null;
+  function showToast(text, ms) {
+    centerToast.textContent = text;
+    centerToast.classList.add("on");
+    if (toastTimer) clearTimeout(toastTimer);
+    toastTimer = setTimeout(function () { centerToast.classList.remove("on"); }, ms || 800);
+  }
+
+  function togglePause() {
+    if (state === "play") {
+      state = "paused";
+      pillPaused.classList.add("on");
+    } else if (state === "paused") {
+      state = "play";
+      pillPaused.classList.remove("on");
+      lastT = performance.now();
+    }
+  }
+  function toggleMute() {
+    var m = Audio.toggleMute();
+    if (m) pillMuted.classList.add("on"); else pillMuted.classList.remove("on");
+  }
+
+  // ---------- Main loop ----------
+  var lastT = performance.now();
+  function loop(now) {
+    var dt = (now - lastT) / 1000;
+    lastT = now;
+    if (dt > 0.05) dt = 0.05; // clamp to avoid huge steps
+    if (dt < 0) dt = 0;
+
+    update(dt);
+    render();
+    requestAnimationFrame(loop);
+  }
+
+  // init HUD + overlay
+  score = 0; lives = START_LIVES; wave = 1;
+  updateHud();
+  showOverlay("ABRAMS", "Clear the field. Survive the swarm.", "", "LAUNCH");
+
+  requestAnimationFrame(loop);
+})();
+</script>
+</body>
+</html>
diff --git a/games/atmos-skyfire/AtmosSkyfire.aa b/games/atmos-skyfire/AtmosSkyfire.aa
new file mode 100644
index 0000000..8cfb328
--- /dev/null
+++ b/games/atmos-skyfire/AtmosSkyfire.aa
@@ -0,0 +1,436 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
+<title>ATMOS — Skyfire</title>
+<style>
+  :root { --ink:#0c1b2a; --sky:#8ec9e8; }
+  * { margin:0; padding:0; box-sizing:border-box; }
+  html,body { height:100%; overflow:hidden; background:var(--sky); font-family:"Helvetica Neue",Arial,sans-serif; color:#fff; }
+  #canvas { position:fixed; inset:0; display:block; }
+
+  /* ---- HUD ---- */
+  #hud { position:fixed; inset:0; pointer-events:none; z-index:10; }
+  .corner { position:absolute; padding:16px 20px; text-shadow:0 1px 3px rgba(8,20,32,.45); }
+  #score  { top:0; left:0; font-size:14px; letter-spacing:.18em; }
+  #score b { display:block; font-size:34px; font-weight:600; letter-spacing:.02em; margin-top:2px; }
+  #right  { top:0; right:0; text-align:right; font-size:12px; letter-spacing:.18em; opacity:.85; }
+  #hpwrap { position:absolute; bottom:26px; left:50%; transform:translateX(-50%); width:min(360px,60vw); }
+  #hpwrap span { font-size:11px; letter-spacing:.25em; opacity:.85; }
+  #hpbar { height:8px; margin-top:6px; border-radius:6px; background:rgba(255,255,255,.25); overflow:hidden; }
+  #hpfill { height:100%; width:100%; border-radius:6px; background:linear-gradient(90deg,#ffd36e,#ff7a59); transition:width .18s ease; }
+
+  /* ---- Overlays ---- */
+  .overlay { position:fixed; inset:0; z-index:20; display:flex; flex-direction:column;
+             align-items:center; justify-content:center; text-align:center; gap:18px;
+             background:radial-gradient(120% 90% at 50% 20%, rgba(142,201,232,.25), rgba(12,27,42,.72));
+             backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px); transition:opacity .5s ease; }
+  .overlay h1 { font-size:clamp(42px,9vw,96px); font-weight:200; letter-spacing:.42em; margin-left:.42em; }
+  .overlay p  { font-size:14px; letter-spacing:.28em; opacity:.9; text-transform:uppercase; }
+  .keys { display:flex; gap:26px; margin-top:6px; font-size:12px; letter-spacing:.14em; opacity:.85; }
+  .keys div span { display:inline-block; min-width:34px; padding:5px 9px; margin-right:8px; border:1px solid rgba(255,255,255,.5);
+                   border-radius:6px; font-weight:600; letter-spacing:.05em; }
+  .cta { margin-top:14px; font-size:13px; letter-spacing:.3em; opacity:.75; animation:pulse 2.2s ease-in-out infinite; }
+  @keyframes pulse { 0%,100%{opacity:.45} 50%{opacity:.95} }
+  #gameover { opacity:0; pointer-events:none; }
+  #gameover.show { opacity:1; pointer-events:auto; }
+  .stat { font-size:16px; letter-spacing:.16em; }
+  .stat b { font-size:26px; font-weight:600; }
+  .hidden { opacity:0 !important; pointer-events:none !important; }
+  .credit { position:fixed; bottom:10px; right:14px; z-index:15; font-size:10px; letter-spacing:.16em; opacity:.5; }
+</style>
+</head>
+<body>
+  <canvas id="canvas"></canvas>
+
+  <div id="hud">
+    <div id="score" class="corner">SCORE<b>0</b></div>
+    <div id="right" class="corner">ALT <span id="alt">32,000</span> FT<br/>DIST <span id="dist">0</span> KM</div>
+    <div id="hpwrap"><span>HULL INTEGRITY</span><div id="hpbar"><div id="hpfill"></div></div></div>
+  </div>
+
+  <div id="start" class="overlay">
+    <p>Leeroy's Playground · unofficial tribute</p>
+    <h1>ATMOS</h1>
+    <p>Skyfire</p>
+    <div class="keys">
+      <div><span>◀ ▶</span>steer &nbsp; <span>▲ ▼</span>climb / dive</div>
+      <div><span>SPACE</span>fire missiles</div>
+    </div>
+    <div class="cta">click or press space to begin the journey</div>
+  </div>
+
+  <div id="gameover" class="overlay">
+    <p>flight terminated</p>
+    <h1 style="letter-spacing:.2em;margin-left:.2em;font-size:clamp(34px,7vw,72px)">DOWN</h1>
+    <div class="stat">FINAL SCORE <b id="finalScore">0</b></div>
+    <div class="stat" style="opacity:.8">DISTANCE <b id="finalDist">0</b> KM · BIRDS DOWNED <b id="finalKills">0</b></div>
+    <div class="cta">click or press space to fly again</div>
+  </div>
+
+  <div class="credit">Unofficial tribute to Leeroy's ATMOS (atmos.leeroy.ca) · original build — no code or art from the original</div>
+
+<script type="importmap">
+{ "imports": { "three": "./three.module.js" } }
+</script>
+
+<script type="module">
+import * as THREE from 'three';
+
+/* ============================================================================
+   ATMOS · Skyfire  — an original Three.js homage to atmos.leeroy.ca
+   The original is a scroll-driven cloud "journey". This turns that aesthetic
+   into a playable arcade flyer: fly the plane, FIRE MISSILES, DODGE BIRDS.
+   ========================================================================== */
+
+// ---- Tunables (one place to feel the game) --------------------------------
+const CFG = {
+  worldFar:   -260,   // z where obstacles spawn (deep into the scene)
+  worldNear:    16,   // z past the camera where they get recycled
+  baseSpeed:    60,   // forward world speed (units/sec) — the "journey" pace
+  steerX:       15,   // horizontal fly bounds (+/-)
+  steerYmin:   -8,
+  steerYmax:    9,
+  missileSpeed:220,
+  fireCooldown: 0.16, // seconds between shots
+  birdMax:      14,   // active birds in the pool
+  cloudCount:  120,
+  hitRadiusBird:2.6,  // plane<->bird collision
+  hitRadiusShot:3.4,  // missile<->bird collision
+  birdDamage:   26,
+};
+
+// ---- Renderer / scene / camera --------------------------------------------
+const canvas   = document.getElementById('canvas');
+const renderer = new THREE.WebGLRenderer({ canvas, antialias:true });
+renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
+renderer.setSize(innerWidth, innerHeight);
+
+const scene = new THREE.Scene();
+const SKY_TOP = new THREE.Color(0x2f7fb5);
+const SKY_BOT = new THREE.Color(0xbfe6f5);
+scene.background = SKY_BOT.clone();
+scene.fog = new THREE.Fog(0xbfe6f5, 60, 250);   // depth haze — the ATMOS mood
+
+const camera = new THREE.PerspectiveCamera(62, innerWidth/innerHeight, 0.1, 600);
+camera.position.set(0, 2.5, 14);
+camera.lookAt(0, 1, -30);
+
+// ---- Lights ----------------------------------------------------------------
+scene.add(new THREE.HemisphereLight(0xffffff, 0x6f97b0, 1.05));
+const sun = new THREE.DirectionalLight(0xfff4e0, 1.15);
+sun.position.set(-8, 14, 6);
+scene.add(sun);
+
+// ---- Gradient sky dome (backdrop behind the fog) ---------------------------
+{
+  const skyGeo = new THREE.SphereGeometry(400, 24, 12);
+  const skyMat = new THREE.ShaderMaterial({
+    side: THREE.BackSide, depthWrite:false, fog:false,
+    uniforms:{ top:{value:SKY_TOP}, bot:{value:SKY_BOT} },
+    vertexShader:`varying vec3 vp; void main(){ vp=position; gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);}`,
+    fragmentShader:`varying vec3 vp; uniform vec3 top; uniform vec3 bot;
+      void main(){ float h=clamp(vp.y/400.0*0.5+0.5,0.0,1.0); gl_FragColor=vec4(mix(bot,top,pow(h,0.8)),1.0);}`
+  });
+  scene.add(new THREE.Mesh(skyGeo, skyMat));
+}
+
+// ---- Soft cloud sprite texture (drawn once to a canvas) --------------------
+function makePuffTexture(){
+  const s=128, c=document.createElement('canvas'); c.width=c.height=s;
+  const g=c.getContext('2d');
+  const grd=g.createRadialGradient(s/2,s/2,4,s/2,s/2,s/2);
+  grd.addColorStop(0,'rgba(255,255,255,0.95)');
+  grd.addColorStop(0.5,'rgba(255,255,255,0.55)');
+  grd.addColorStop(1,'rgba(255,255,255,0)');
+  g.fillStyle=grd; g.beginPath(); g.arc(s/2,s/2,s/2,0,Math.PI*2); g.fill();
+  const t=new THREE.CanvasTexture(c); t.needsUpdate=true; return t;
+}
+const puffTex = makePuffTexture();
+
+// ---- Cloud field: recycled billboard sprites -------------------------------
+const clouds = [];
+for (let i=0;i<CFG.cloudCount;i++){
+  const m = new THREE.Sprite(new THREE.SpriteMaterial({
+    map:puffTex, transparent:true, depthWrite:false, fog:true,
+    opacity:0.55+Math.random()*0.35, color:0xffffff
+  }));
+  resetCloud(m, true);
+  scene.add(m); clouds.push(m);
+}
+function resetCloud(m, initial){
+  const sc = 14 + Math.random()*46;
+  m.scale.set(sc, sc*(0.55+Math.random()*0.3), 1);
+  m.position.set(
+    (Math.random()*2-1)*70,
+    -14 + Math.random()*40,
+    initial ? CFG.worldNear - Math.random()*(CFG.worldNear-CFG.worldFar)
+            : CFG.worldFar - Math.random()*40
+  );
+  m.userData.spin = (Math.random()*2-1)*0.05;
+}
+
+// ---- The player plane (stylized low-poly, built from primitives) -----------
+const plane = new THREE.Group();
+{
+  const body = new THREE.Mesh(
+    new THREE.CylinderGeometry(0.5,0.28,4.4,16),
+    new THREE.MeshStandardMaterial({color:0xf5f7fa, metalness:0.2, roughness:0.55}));
+  body.rotation.x = Math.PI/2; plane.add(body);
+
+  const nose = new THREE.Mesh(new THREE.ConeGeometry(0.5,1.1,16),
+    new THREE.MeshStandardMaterial({color:0xff7a59, metalness:0.1, roughness:0.5}));
+  nose.rotation.x = -Math.PI/2; nose.position.z=-2.5; plane.add(nose);
+
+  const wingMat = new THREE.MeshStandardMaterial({color:0xdfe6ee, metalness:0.15, roughness:0.6});
+  const wing = new THREE.Mesh(new THREE.BoxGeometry(7.4,0.14,1.5), wingMat);
+  wing.position.set(0,0,0.2); plane.add(wing);
+
+  const tailWing = new THREE.Mesh(new THREE.BoxGeometry(2.8,0.12,0.9), wingMat);
+  tailWing.position.set(0,0,1.9); plane.add(tailWing);
+
+  const fin = new THREE.Mesh(new THREE.BoxGeometry(0.12,1.3,1.0), wingMat);
+  fin.position.set(0,0.6,2.0); plane.add(fin);
+
+  const stripe = new THREE.Mesh(new THREE.BoxGeometry(0.55,0.02,4.2),
+    new THREE.MeshStandardMaterial({color:0xff7a59}));
+  stripe.position.set(0,0.5,0.1); plane.add(stripe);
+}
+plane.position.set(0,0,2);
+scene.add(plane);
+
+// ---- Missile pool ----------------------------------------------------------
+const missiles = [];
+const missileGeo = new THREE.CapsuleGeometry(0.16,0.7,4,8);
+const missileMat = new THREE.MeshStandardMaterial({color:0xffca3a, emissive:0xff7a00, emissiveIntensity:0.8});
+for (let i=0;i<40;i++){
+  const m = new THREE.Mesh(missileGeo, missileMat);
+  m.rotation.x = Math.PI/2; m.visible=false; m.userData.alive=false;
+  scene.add(m); missiles.push(m);
+}
+function fireMissile(){
+  // two barrels, one per wingtip-ish
+  for (const dx of [-1.1, 1.1]){
+    const m = missiles.find(x=>!x.userData.alive);
+    if (!m) return;
+    m.position.set(plane.position.x+dx, plane.position.y, plane.position.z-2.4);
+    m.visible=true; m.userData.alive=true;
+  }
+}
+
+// ---- Bird pool (dark low-poly, flapping) -----------------------------------
+const birds = [];
+function makeBird(){
+  const g = new THREE.Group();
+  const mat = new THREE.MeshStandardMaterial({color:0x243242, roughness:0.9, metalness:0.0});
+  const wl = new THREE.Mesh(new THREE.BoxGeometry(2.2,0.12,0.9), mat);
+  const wr = wl.clone();
+  wl.position.x = -1.15; wr.position.x = 1.15;
+  const bodyB = new THREE.Mesh(new THREE.SphereGeometry(0.42,10,8), mat);
+  g.add(wl,wr,bodyB);
+  g.userData = {wl, wr, alive:false, flap:Math.random()*6, sway:Math.random()*6, swayAmp:2+Math.random()*4};
+  return g;
+}
+for (let i=0;i<CFG.birdMax;i++){ const b=makeBird(); b.visible=false; scene.add(b); birds.push(b); }
+function spawnBird(b){
+  b.position.set((Math.random()*2-1)*CFG.steerX, CFG.steerYmin + Math.random()*(CFG.steerYmax-CFG.steerYmin), CFG.worldFar - Math.random()*30);
+  b.userData.alive=true; b.visible=true;
+  b.userData.baseX = b.position.x;
+  b.userData.sway = Math.random()*6;
+}
+
+// ---- Explosion puff pool (sprites that expand + fade) ----------------------
+const puffs = [];
+for (let i=0;i<24;i++){
+  const p = new THREE.Sprite(new THREE.SpriteMaterial({map:puffTex, transparent:true, color:0xffce7a, depthWrite:false}));
+  p.visible=false; p.userData.alive=false; scene.add(p); puffs.push(p);
+}
+function boom(x,y,z,color){
+  for (let i=0;i<5;i++){
+    const p = puffs.find(q=>!q.userData.alive); if(!p) break;
+    p.position.set(x+(Math.random()*2-1), y+(Math.random()*2-1), z);
+    p.material.color.set(color); p.material.opacity=0.95;
+    p.userData.alive=true; p.userData.life=0; p.userData.max=0.45+Math.random()*0.2;
+    p.userData.grow=6+Math.random()*8; p.visible=true; p.scale.set(2,2,1);
+  }
+}
+
+// ---- Input -----------------------------------------------------------------
+const keys = {};
+const target = { x:0, y:1 };   // where the plane wants to be
+addEventListener('keydown', e=>{
+  keys[e.code]=true;
+  if (e.code==='Space'){ e.preventDefault(); if(state==='play') firing=true; else beginOrRestart(); }
+});
+addEventListener('keyup', e=>{ keys[e.code]=false; if(e.code==='Space') firing=false; });
+// pointer steering (mouse / touch)
+function pointerMove(cx, cy){
+  const nx = (cx/innerWidth)*2-1;
+  const ny = (cy/innerHeight)*2-1;
+  target.x = nx*CFG.steerX;
+  target.y = THREE.MathUtils.clamp(-ny*CFG.steerYmax, CFG.steerYmin, CFG.steerYmax);
+}
+addEventListener('mousemove', e=>pointerMove(e.clientX, e.clientY));
+addEventListener('touchmove', e=>{ const t=e.touches[0]; pointerMove(t.clientX,t.clientY); firing=true; }, {passive:true});
+addEventListener('touchend',  ()=>{ firing=false; });
+canvas.addEventListener('click', ()=>{ if(state!=='play') beginOrRestart(); });
+
+// ---- Game state ------------------------------------------------------------
+let state='start';               // 'start' | 'play' | 'over'
+let firing=false, cooldown=0;
+let score=0, kills=0, dist=0, hp=100;
+const startEl=document.getElementById('start');
+const overEl =document.getElementById('gameover');
+const hpFill =document.getElementById('hpfill');
+const scoreEl=document.querySelector('#score b');
+const distEl =document.getElementById('dist');
+const altEl  =document.getElementById('alt');
+
+function beginOrRestart(){
+  if (state==='play') return;
+  score=0; kills=0; dist=0; hp=100; firing=false; cooldown=0;
+  target.x=0; target.y=1; plane.position.set(0,0,2);
+  birds.forEach(b=>{ b.userData.alive=false; b.visible=false; });
+  missiles.forEach(m=>{ m.userData.alive=false; m.visible=false; });
+  state='play';
+  startEl.classList.add('hidden');
+  overEl.classList.remove('show');
+}
+function endGame(){
+  state='over';
+  document.getElementById('finalScore').textContent=score;
+  document.getElementById('finalDist').textContent=Math.floor(dist/100);
+  document.getElementById('finalKills').textContent=kills;
+  overEl.classList.add('show');
+}
+
+// ---- Resize ----------------------------------------------------------------
+addEventListener('resize', ()=>{
+  camera.aspect=innerWidth/innerHeight; camera.updateProjectionMatrix();
+  renderer.setSize(innerWidth,innerHeight);
+});
+
+// ---- Main loop -------------------------------------------------------------
+const clock = new THREE.Clock();
+let flash=0;                       // red damage flash amount
+let spawnTimer=0;
+
+function tick(){
+  requestAnimationFrame(tick);
+  const dt = Math.min(clock.getDelta(), 0.05);
+  const t  = clock.elapsedTime;
+
+  // world always drifts (even on menus) so the sky feels alive
+  const worldSpeed = (state==='play') ? CFG.baseSpeed : CFG.baseSpeed*0.35;
+
+  // clouds
+  for (const c of clouds){
+    c.position.z += worldSpeed*dt;
+    c.material.rotation += c.userData.spin*dt;
+    if (c.position.z > CFG.worldNear) resetCloud(c, false);
+  }
+
+  if (state==='play'){
+    // ---- steer plane toward target (keyboard nudges the pointer target) ----
+    if (keys['ArrowLeft']||keys['KeyA'])  target.x -= 42*dt;
+    if (keys['ArrowRight']||keys['KeyD']) target.x += 42*dt;
+    if (keys['ArrowUp']||keys['KeyW'])    target.y += 30*dt;
+    if (keys['ArrowDown']||keys['KeyS'])  target.y -= 30*dt;
+    target.x = THREE.MathUtils.clamp(target.x, -CFG.steerX, CFG.steerX);
+    target.y = THREE.MathUtils.clamp(target.y, CFG.steerYmin, CFG.steerYmax);
+
+    const prevX = plane.position.x;
+    plane.position.x += (target.x - plane.position.x)*Math.min(1, 6*dt);
+    plane.position.y += (target.y - plane.position.y)*Math.min(1, 6*dt);
+    // bank into the turn + pitch with climb — reads as real flight
+    const dx = plane.position.x - prevX;
+    plane.rotation.z += ((-dx*4) - plane.rotation.z)*Math.min(1,8*dt);
+    plane.rotation.x += ((-(target.y-plane.position.y)*0.06) - plane.rotation.x)*Math.min(1,6*dt);
+    plane.position.y += Math.sin(t*2.2)*0.004;  // subtle idle bob
+
+    // ---- firing ----
+    cooldown -= dt;
+    if (firing && cooldown<=0){ fireMissile(); cooldown=CFG.fireCooldown; }
+
+    // ---- distance / score-over-time ----
+    dist  += worldSpeed*dt;
+    score += Math.floor(worldSpeed*dt*0.1);
+
+    // ---- spawn birds ----
+    spawnTimer -= dt;
+    const activeBirds = birds.filter(b=>b.userData.alive).length;
+    if (spawnTimer<=0 && activeBirds < CFG.birdMax){
+      const b = birds.find(x=>!x.userData.alive);
+      if (b) spawnBird(b);
+      spawnTimer = 0.5 + Math.random()*0.7;   // difficulty knob
+    }
+  }
+
+  // ---- missiles fly forward, cull, and hit birds ----
+  for (const m of missiles){
+    if (!m.userData.alive) continue;
+    m.position.z -= CFG.missileSpeed*dt;
+    if (m.position.z < CFG.worldFar-20){ m.userData.alive=false; m.visible=false; continue; }
+    for (const b of birds){
+      if (!b.userData.alive) continue;
+      if (m.position.distanceTo(b.position) < CFG.hitRadiusShot){
+        boom(b.position.x,b.position.y,b.position.z,0xffce7a);
+        b.userData.alive=false; b.visible=false;
+        m.userData.alive=false; m.visible=false;
+        kills++; score+=100;
+        break;
+      }
+    }
+  }
+
+  // ---- birds fly toward the player, flap, and can hit the plane ----
+  for (const b of birds){
+    if (!b.userData.alive) continue;
+    b.position.z += (worldSpeed + 22)*dt;              // birds close faster than clouds
+    b.userData.sway += dt;
+    b.position.x = b.userData.baseX + Math.sin(b.userData.sway*1.3)*b.userData.swayAmp*0.15;
+    const flap = Math.sin(t*16 + b.userData.flap)*0.7; // wing beat
+    b.userData.wl.rotation.z =  flap;
+    b.userData.wr.rotation.z = -flap;
+    if (state==='play' && b.position.distanceTo(plane.position) < CFG.hitRadiusBird){
+      boom(plane.position.x,plane.position.y,plane.position.z,0xff5a4d);
+      b.userData.alive=false; b.visible=false;
+      hp -= CFG.birdDamage; flash=1;
+      if (hp<=0){ hp=0; endGame(); }
+    }
+    if (b.position.z > CFG.worldNear){ b.userData.alive=false; b.visible=false; }  // dodged — recycle
+  }
+
+  // ---- explosion puffs ----
+  for (const p of puffs){
+    if (!p.userData.alive) continue;
+    p.userData.life += dt;
+    const k = p.userData.life/p.userData.max;
+    const s = 2 + p.userData.grow*k;
+    p.scale.set(s,s,1);
+    p.material.opacity = 0.95*(1-k);
+    if (k>=1){ p.userData.alive=false; p.visible=false; }
+  }
+
+  // ---- camera gently trails the plane ----
+  camera.position.x += (plane.position.x*0.5 - camera.position.x)*Math.min(1,3*dt);
+  camera.position.y += ((plane.position.y*0.4+2.5) - camera.position.y)*Math.min(1,3*dt);
+  camera.lookAt(plane.position.x*0.6, plane.position.y*0.5+1, -30);
+
+  // ---- damage flash via background tint ----
+  if (flash>0){ flash=Math.max(0,flash-dt*2.2); scene.background.copy(SKY_BOT).lerp(new THREE.Color(0xff4433), flash*0.5); }
+  else scene.background.copy(SKY_BOT);
+
+  // ---- HUD ----
+  hpFill.style.width = hp+'%';
+  scoreEl.textContent = score;
+  distEl.textContent  = Math.floor(dist/100);
+  altEl.textContent   = (32000 + Math.round(plane.position.y*140)).toLocaleString();
+
+  renderer.render(scene, camera);
+}
+tick();
+</script>
+</body>
+</html>
diff --git a/games/backgammon/90210Backgammon.aa b/games/backgammon/90210Backgammon.aa
new file mode 100644
index 0000000..b17751d
--- /dev/null
+++ b/games/backgammon/90210Backgammon.aa
@@ -0,0 +1,686 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>90210 Backgammon — The Beverly Hills Board</title>
+<style>
+@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700;900&family=Inter:wght@400;500;600;700&display=swap');
+*{margin:0;padding:0;box-sizing:border-box;}
+html{-webkit-text-size-adjust:100%;text-size-adjust:100%;}
+/* iPad / iOS touch hardening: no double-tap zoom, no 300ms delay,
+   no grey tap-flash, no text-selection / long-press callout on taps */
+body{touch-action:manipulation;-webkit-tap-highlight-color:transparent;}
+.point,.bar-zone,.tray,.checker,.chip-off,.die3d,.cube,button,.btn,.btn-roll,.seg button{
+  touch-action:manipulation;-webkit-tap-highlight-color:transparent;
+  -webkit-user-select:none;user-select:none;-webkit-touch-callout:none;}
+:root{
+  --ivory:#efe3c8; --ivory-dk:#c9b07a;
+  --gold:#e9c46a; --peach:#f4a261; --burnt:#e76f51; --teal:#2a9d8f;
+}
+body{
+  background:radial-gradient(1200px 700px at 50% -10%,#243048,#12172a 60%,#0c0f1c);
+  font-family:'Inter',sans-serif; min-height:100vh; display:flex; flex-direction:column;
+  align-items:center; padding:18px; color:#e7e2d6;
+}
+h1{font-family:'Playfair Display',serif;font-weight:900;font-size:2.5rem;letter-spacing:2px;
+  color:transparent;background:linear-gradient(180deg,#f7d9a6,#e9a15a 60%,#c9772f);
+  -webkit-background-clip:text;background-clip:text;text-shadow:0 2px 10px rgba(0,0,0,.4);margin-bottom:2px;}
+.subtitle{color:#caa; font-size:.78rem; letter-spacing:4px; text-transform:uppercase; margin-bottom:14px; opacity:.85;}
+
+/* ---- top dice controls ---- */
+.top-controls{display:flex;align-items:center;justify-content:center;gap:22px;margin-bottom:16px;min-height:66px;}
+.dice-tray{display:flex;gap:14px;align-items:center;min-height:60px;}
+.btn-roll{
+  border:none;border-radius:11px;cursor:pointer;font-family:'Inter';font-weight:700;letter-spacing:1px;
+  text-transform:uppercase;font-size:.95rem;padding:15px 26px;white-space:nowrap;color:#20140a;
+  background:linear-gradient(180deg,#f6cf8f,#e39b4b);box-shadow:0 5px 0 #a9691f,0 8px 18px rgba(0,0,0,.4);
+  transition:transform .08s, box-shadow .08s;
+}
+.btn-roll:active:not(:disabled){transform:translateY(4px);box-shadow:0 1px 0 #a9691f,0 4px 10px rgba(0,0,0,.4);}
+.btn-roll:disabled{filter:grayscale(.6) brightness(.7);cursor:not-allowed;box-shadow:0 5px 0 #5a4020;}
+
+/* real pip dice */
+.die3d{width:56px;height:56px;border-radius:13px;position:relative;
+  display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);
+  padding:9px;gap:2px;box-shadow:inset 0 3px 4px rgba(255,255,255,.85),inset 0 -5px 8px rgba(0,0,0,.28),0 4px 9px rgba(0,0,0,.5);}
+.die3d.light{background:linear-gradient(155deg,#fffdf6,#e8dcc2);}
+.die3d.dark{background:linear-gradient(155deg,#43434f,#191920);}
+.die3d .pip{align-self:center;justify-self:center;width:10px;height:10px;border-radius:50%;}
+.die3d.light .pip{background:radial-gradient(circle at 35% 30%,#6a4a22,#2c1c0a);box-shadow:inset 0 1px 1px rgba(0,0,0,.6);}
+.die3d.dark .pip{background:radial-gradient(circle at 35% 30%,#f4d9a6,#c98f3d);}
+.die3d.used{opacity:.32;transform:scale(.82);}
+@keyframes tumble{0%{transform:rotate(0) translateY(0);}30%{transform:rotate(-160deg) translateY(-14px);}
+  60%{transform:rotate(180deg) translateY(6px);}100%{transform:rotate(360deg) translateY(0);}}
+.die3d.rolling{animation:tumble .5s ease-out;}
+
+/* ---- the board ---- */
+.stage{
+  padding:20px;border-radius:16px;
+  background:url('data:image/jpeg;base64,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bnRGI1JsdAAAAAAAAAAAAAAAAEJsZCBVbnRGI1JsdAAAAAAAAAAAAAAAAFJzbHRVbnRGI1B4bEBSAAAAAAAAAAAACnZlY3RvckRhdGFib29sAQAAAABQZ1BzZW51bQAAAABQZ1BzAAAAAFBnUEMAAAAATGVmdFVudEYjUmx0AAAAAAAAAAAAAAAAVG9wIFVudEYjUmx0AAAAAAAAAAAAAAAAU2NsIFVudEYjUHJjQFkAAAAAAAAAAAAQY3JvcFdoZW5QcmludGluZ2Jvb2wAAAAADmNyb3BSZWN0Qm90dG9tbG9uZwAAAAAAAAAMY3JvcFJlY3RMZWZ0bG9uZwAAAAAAAAANY3JvcFJlY3RSaWdodGxvbmcAAAAAAAAAC2Nyb3BSZWN0VG9wbG9uZwAAAAAAOEJJTQPtAAAAAAAQAEgAAAABAAEASAAAAAEAAThCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAAOEJJTQQNAAAAAAAEAAAAWjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAAAAAAAAEAOEJJTScQAAAAAAAKAAEAAAAAAAAAAThCSU0D9QAAAAAASAAvZmYAAQBsZmYABgAAAAAAAQAvZmYAAQChmZoABgAAAAAAAQAyAAAAAQBaAAAABgAAAAAAAQA1AAAAAQAtAAAABgAAAAAAAThCSU0D+AAAAAAAcAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAA4QklNBAgAAAAAABAAAAABAAACQAAAAkAAAAAAOEJJTQREAAAAAAAQAAAAAgAAAkAAAAJAAAAAADhCSU0ESQAAAAAABAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAANNAAAABgAAAAAAAAAAAAACWAAAAlgAAAAMAE4AZQB3ACAARABvAGMAdQBtAGUAbgB0AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAJYAAACWAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAAAAbnVsbAAAAAIAAAAGYm91bmRzT2Jq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OEJJTQQGAAAAAAAHAAMAAAABAQD/4Q5uaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSAxMC4wLWMwMDAgNzkuZDIwZTQ2NjMwLCAyMDI1LzEyLzA5LTAyOjExOjIzICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjcuOCAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjYtMDctMjRUMjM6NTE6MzQtMDc6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDI2LTA3LTI0VDIzOjUyOjE5LTA3OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDI2LTA3LTI0VDIzOjUyOjE5LTA3OjAwIiBkYzpmb3JtYXQ9ImltYWdlL2pwZWciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5OTdlZWQ0ZS0yYTc0LTQ4YWQtYWVmZS0xMDk2NDRkMjMzYjIiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDpiMzU1NjkwOS1kN2JlLTI5NDItYjcyZC0yM2E1OThlMDBmODciIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyNjg3OWU1Ny02MTBhLTQ5YzMtOGU5Zi1jOWVkN2VmNDdkOWEiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjI2ODc5ZTU3LTYxMGEtNDljMy04ZTlmLWM5ZWQ3ZWY0N2Q5YSIgc3RFdnQ6d2hlbj0iMjAyNi0wNy0yNFQyMzo1MTozNC0wNzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI3LjggKE1hY2ludG9zaCkiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNvbnZlcnRlZCIgc3RFdnQ6cGFyYW1ldGVycz0iZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL2pwZWciLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjk5N2VlZDRlLTJhNzQtNDhhZC1hZWZlLTEwOTY0NGQyMzNiMiIgc3RFdnQ6d2hlbj0iMjAyNi0wNy0yNFQyMzo1MjoxOS0wNzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI3LjggKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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');background-size:cover;background-position:center;
+  box-shadow:0 26px 60px rgba(0,0,0,.65), inset 0 2px 3px rgba(255,255,255,.15), inset 0 -6px 14px rgba(0,0,0,.5);
+  display:flex;gap:0;align-items:stretch;
+}
+.playfield{
+  position:relative;padding:6px;border-radius:8px;
+  background:url('data:image/jpeg;base64,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AAAAUkdCQwAAAAMAAAAAUmQgIGRvdWJAb+AAAAAAAAAAAABHcm4gZG91YkBv4AAAAAAAAAAAAEJsICBkb3ViQG/gAAAAAAAAAAAAQnJkVFVudEYjUmx0AAAAAAAAAAAAAAAAQmxkIFVudEYjUmx0AAAAAAAAAAAAAAAAUnNsdFVudEYjUHhsQFIAAAAAAAAAAAAKdmVjdG9yRGF0YWJvb2wBAAAAAFBnUHNlbnVtAAAAAFBnUHMAAAAAUGdQQwAAAABMZWZ0VW50RiNSbHQAAAAAAAAAAAAAAABUb3AgVW50RiNSbHQAAAAAAAAAAAAAAABTY2wgVW50RiNQcmNAWQAAAAAAAAAAABBjcm9wV2hlblByaW50aW5nYm9vbAAAAAAOY3JvcFJlY3RCb3R0b21sb25nAAAAAAAAAAxjcm9wUmVjdExlZnRsb25nAAAAAAAAAA1jcm9wUmVjdFJpZ2h0bG9uZwAAAAAAAAALY3JvcFJlY3RUb3Bsb25nAAAAAAA4QklNA+0AAAAAABAASAAAAAEAAQBIAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD+AAAA4QklNBA0AAAAAAAQAAABaOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNJxAAAAAAAAoAAQAAAAAAAAABOEJJTQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBEQAAAAAABAAAAACAAACQAAAAkAAAAAAOEJJTQRJAAAAAAAEAAAAADhCSU0EHgAAAAAABAAAAAA4QklNBBoAAAAAA00AAAAGAAAAAAAAAAAAAAIAAAACAAAAAAwATgBlAHcAIABEAG8AYwB1AG0AZQBuAHQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA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NzowMCIgZGM6Zm9ybWF0PSJpbWFnZS9qcGVnIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MGI3YzMzNjYtMGY4NC00ZGY4LWEzYjYtOGI2MTcwZDBhNjFmIiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6NDgxY2Y1NjctMWQyYi03NTQxLTlkOTctZGY1OTlhZTgzMmNhIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OTZlNTE4NmEtYTBjYy00NWNhLTgxNDgtODM1MjQ5NDM0ZWQ1Ij4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo5NmU1MTg2YS1hMGNjLTQ1Y2EtODE0OC04MzUyNDk0MzRlZDUiIHN0RXZ0OndoZW49IjIwMjYtMDctMjRUMjM6NTE6MzQtMDc6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNy44IChNYWNpbnRvc2gpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjb252ZXJ0ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9qcGVnIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowYjdjMzM2Ni0wZjg0LTRkZjgtYTNiNi04YjYxNzBkMGE2MWYiIHN0RXZ0OndoZW49IjIwMjYtMDctMjRUMjM6NTM6MDAtMDc6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNy44IChNYWNpbnRvc2gpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSJ3Ij8+/+IMWElDQ19QUk9GSUxFAAEBAAAMSExpbm8CEAAAbW50clJHQiBYWVogB84AAgAJAAYAMQAAYWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAAAAEAAPbWAAEAAAAA0y1IUCAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARY3BydAAAAVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAUclhZWgAAAhgAAAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABwZG1kZAAAAsQAAACIdnVlZAAAA0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gAAAAUbWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAABDwAAAgMZ1RSQwAABDwAAAgMYlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTggSGV3bGV0dC1QYWNrYXJkIENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAAARbMWFlaIAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9kZXNjAAAAAAAA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');background-size:cover;
+  box-shadow:inset 0 0 46px rgba(0,0,0,.62), inset 0 0 4px rgba(0,0,0,.8);
+}
+#board{
+  display:grid;
+  grid-template-columns:repeat(6,52px) 46px repeat(6,52px);
+  grid-template-rows:20px 232px 20px 232px 20px;
+}
+.label{display:flex;align-items:center;justify-content:center;font-size:.64rem;font-weight:700;color:#f4ecd6;opacity:.5;}
+
+.point{position:relative;display:flex;flex-direction:column;align-items:center;cursor:pointer;}
+.point.top{justify-content:flex-start;}
+.point.bottom{justify-content:flex-end;}
+.tri{position:absolute;left:3px;right:3px;height:100%;z-index:0;filter:drop-shadow(0 3px 5px rgba(0,0,0,.45));}
+.point.top .tri{top:0;clip-path:polygon(0 0,100% 0,50% 96%);}
+.point.bottom .tri{bottom:0;clip-path:polygon(50% 4%,0 100%,100% 100%);}
+.tri.lt{background:linear-gradient(90deg,#f0e4c9,#d7c199 55%,#c3aa7d);}
+.tri.dk{background:linear-gradient(90deg,#8a5230,#5f3420 55%,#4a2717);}
+.point.playable-src::before{content:'';position:absolute;top:0;bottom:0;left:3px;right:3px;z-index:1;
+  background:radial-gradient(circle at 50% 30%,rgba(233,196,106,.55),transparent 65%);}
+.point.playable-dst::after{content:'';position:absolute;width:26px;height:26px;border-radius:50%;z-index:4;
+  top:50%;left:50%;transform:translate(-50%,-50%);
+  background:radial-gradient(circle,rgba(255,255,255,.9),rgba(233,196,106,.4) 60%,transparent 72%);
+  box-shadow:0 0 12px rgba(255,236,180,.9);animation:glow 1s infinite;pointer-events:none;}
+@keyframes glow{0%,100%{opacity:1;}50%{opacity:.4;}}
+.point.selected::before{content:'';position:absolute;top:0;bottom:0;left:3px;right:3px;z-index:1;
+  background:radial-gradient(circle at 50% 30%,rgba(231,111,81,.65),transparent 68%);}
+
+/* checkers — beveled marble discs */
+.checker{width:44px;height:44px;border-radius:50%;z-index:3;margin:-5px 0;position:relative;
+  display:flex;align-items:center;justify-content:center;font-size:.9rem;
+  box-shadow:inset 0 3px 4px rgba(255,255,255,.55),inset 0 -5px 8px rgba(0,0,0,.55),0 3px 5px rgba(0,0,0,.55);}
+.checker.white{background:radial-gradient(circle at 35% 28%,#fdf6e6,#ecdcbb 46%,#b9986190 78%,#9c7e4d);}
+.checker.black{background:radial-gradient(circle at 35% 28%,#5a5a67,#2c2c36 46%,#121218 78%,#07070b);}
+.checker::after{content:'';position:absolute;inset:5px;border-radius:50%;}
+.checker.white::after{box-shadow:inset 0 0 0 2px rgba(244,162,97,.5);}
+.checker.black::after{box-shadow:inset 0 0 0 2px rgba(42,157,143,.55);}
+.checker .cnt{font-weight:800;font-size:.82rem;z-index:2;}
+.checker.white .cnt{color:#7a5322;}
+.checker.black .cnt{color:#e9c46a;}
+.checker.mini{width:20px;height:20px;margin:1px;}
+
+/* center bar (wood) */
+.bar{grid-row:1 / 6;grid-column:7;position:relative;
+  background:url('data:image/jpeg;base64,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bnRGI1JsdAAAAAAAAAAAAAAAAEJsZCBVbnRGI1JsdAAAAAAAAAAAAAAAAFJzbHRVbnRGI1B4bEBSAAAAAAAAAAAACnZlY3RvckRhdGFib29sAQAAAABQZ1BzZW51bQAAAABQZ1BzAAAAAFBnUEMAAAAATGVmdFVudEYjUmx0AAAAAAAAAAAAAAAAVG9wIFVudEYjUmx0AAAAAAAAAAAAAAAAU2NsIFVudEYjUHJjQFkAAAAAAAAAAAAQY3JvcFdoZW5QcmludGluZ2Jvb2wAAAAADmNyb3BSZWN0Qm90dG9tbG9uZwAAAAAAAAAMY3JvcFJlY3RMZWZ0bG9uZwAAAAAAAAANY3JvcFJlY3RSaWdodGxvbmcAAAAAAAAAC2Nyb3BSZWN0VG9wbG9uZwAAAAAAOEJJTQPtAAAAAAAQAEgAAAABAAEASAAAAAEAAThCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAAOEJJTQQNAAAAAAAEAAAAWjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAAAAAAAAEAOEJJTScQAAAAAAAKAAEAAAAAAAAAAThCSU0D9QAAAAAASAAvZmYAAQBsZmYABgAAAAAAAQAvZmYAAQChmZoABgAAAAAAAQAyAAAAAQBaAAAABgAAAAAAAQA1AAAAAQAtAAAABgAAAAAAAThCSU0D+AAAAAAAcAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAA4QklNBAgAAAAAABAAAAABAAACQAAAAkAAAAAAOEJJTQREAAAAAAAQAAAAAgAAAkAAAAJAAAAAADhCSU0ESQAAAAAABAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAANNAAAABgAAAAAAAAAAAAACWAAAAlgAAAAMAE4AZQB3ACAARABvAGMAdQBtAGUAbgB0AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAJYAAACWAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAAAAbnVsbAAAAAIAAAAGYm91bmRzT2Jq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OEJJTQQGAAAAAAAHAAMAAAABAQD/4Q5uaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSAxMC4wLWMwMDAgNzkuZDIwZTQ2NjMwLCAyMDI1LzEyLzA5LTAyOjExOjIzICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjcuOCAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjYtMDctMjRUMjM6NTE6MzQtMDc6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDI2LTA3LTI0VDIzOjUyOjE5LTA3OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDI2LTA3LTI0VDIzOjUyOjE5LTA3OjAwIiBkYzpmb3JtYXQ9ImltYWdlL2pwZWciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5OTdlZWQ0ZS0yYTc0LTQ4YWQtYWVmZS0xMDk2NDRkMjMzYjIiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDpiMzU1NjkwOS1kN2JlLTI5NDItYjcyZC0yM2E1OThlMDBmODciIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyNjg3OWU1Ny02MTBhLTQ5YzMtOGU5Zi1jOWVkN2VmNDdkOWEiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjI2ODc5ZTU3LTYxMGEtNDljMy04ZTlmLWM5ZWQ3ZWY0N2Q5YSIgc3RFdnQ6d2hlbj0iMjAyNi0wNy0yNFQyMzo1MTozNC0wNzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI3LjggKE1hY2ludG9zaCkiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNvbnZlcnRlZCIgc3RFdnQ6cGFyYW1ldGVycz0iZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL2pwZWciLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjk5N2VlZDRlLTJhNzQtNDhhZC1hZWZlLTEwOTY0NGQyMzNiMiIgc3RFdnQ6d2hlbj0iMjAyNi0wNy0yNFQyMzo1MjoxOS0wNzowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI3LjggKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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');background-size:cover;
+  box-shadow:inset 3px 0 6px rgba(0,0,0,.5),inset -3px 0 6px rgba(0,0,0,.5),inset 0 0 0 1px rgba(255,255,255,.08);
+  display:flex;flex-direction:column;align-items:center;justify-content:space-between;padding:6px 0;z-index:2;}
+.bar-zone{display:flex;flex-direction:column;align-items:center;gap:2px;cursor:pointer;width:100%;padding:3px 0;}
+.bar-zone.playable-src{outline:2px dashed rgba(255,236,180,.9);outline-offset:-3px;border-radius:6px;}
+.bar-zone.selected{outline:3px solid var(--burnt);outline-offset:-3px;border-radius:6px;}
+.bar-cap{font-size:.5rem;color:#f4ecd6;opacity:.6;text-transform:uppercase;letter-spacing:1px;}
+
+/* doubling cube on bar */
+.cube-holder{display:flex;flex-direction:column;align-items:center;gap:3px;}
+.cube{width:34px;height:34px;border-radius:7px;background:linear-gradient(150deg,#fffdf6,#dccfae);
+  color:#3a2a10;font-weight:900;font-size:1rem;display:flex;align-items:center;justify-content:center;
+  box-shadow:inset 0 2px 2px rgba(255,255,255,.8),inset 0 -3px 5px rgba(0,0,0,.3),0 3px 6px rgba(0,0,0,.5);}
+
+/* bear-off trays */
+.trays{display:flex;flex-direction:column;justify-content:space-between;margin-left:14px;padding:2px;gap:8px;}
+.tray{width:60px;flex:1;border-radius:7px;padding:6px 4px;
+  background:rgba(0,0,0,.28);box-shadow:inset 0 0 14px rgba(0,0,0,.6),inset 0 0 0 1px rgba(255,255,255,.06);
+  display:flex;flex-direction:column;align-items:center;cursor:pointer;position:relative;}
+.tray.top{justify-content:flex-start;} .tray.bot{justify-content:flex-end;}
+.tray.playable-dst{box-shadow:inset 0 0 14px rgba(0,0,0,.6),0 0 0 2px var(--gold),0 0 12px rgba(233,196,106,.7);}
+.tray-cap{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);
+  font-size:.6rem;letter-spacing:2px;color:#f4ecd6;opacity:.35;text-transform:uppercase;white-space:nowrap;pointer-events:none;}
+.chip-off{width:48px;height:11px;border-radius:3px;margin:1.5px 0;
+  box-shadow:inset 0 1px 1px rgba(255,255,255,.5),inset 0 -2px 3px rgba(0,0,0,.5),0 1px 2px rgba(0,0,0,.5);}
+.chip-off.white{background:linear-gradient(180deg,#f3e6c6,#c7a86e);}
+.chip-off.black{background:linear-gradient(180deg,#4a4a56,#111117);}
+
+/* ---- info panel ---- */
+.wrap{display:flex;gap:22px;align-items:flex-start;flex-wrap:wrap;justify-content:center;}
+.panel{background:linear-gradient(180deg,#141a2c,#0d1120);padding:18px;border-radius:14px;
+  border:1px solid rgba(233,196,106,.25);min-width:250px;max-width:280px;box-shadow:0 14px 40px rgba(0,0,0,.5);}
+.panel h2{font-family:'Playfair Display',serif;color:var(--gold);font-size:1.1rem;margin-bottom:12px;
+  border-bottom:1px solid rgba(233,196,106,.2);padding-bottom:8px;}
+.setup{display:flex;flex-direction:column;gap:9px;margin-bottom:14px;padding-bottom:12px;border-bottom:1px solid rgba(233,196,106,.15);}
+.setup-row{display:flex;flex-direction:column;gap:4px;}
+.setup-lab{font-size:.58rem;text-transform:uppercase;letter-spacing:1.4px;color:#9ab;opacity:.75;}
+.seg{display:flex;gap:4px;background:rgba(0,0,0,.28);padding:3px;border-radius:9px;}
+.seg button{flex:1;border:none;border-radius:6px;cursor:pointer;font-family:'Inter';font-weight:600;
+  font-size:.66rem;padding:7px 3px;color:#bcd;background:transparent;transition:.15s;letter-spacing:.2px;white-space:nowrap;}
+.seg button:hover{background:rgba(255,255,255,.06);}
+.seg button.on{background:linear-gradient(180deg,#f6cf8f,#e39b4b);color:#20140a;box-shadow:0 2px 6px rgba(0,0,0,.4);}
+.turn{padding:10px;border-radius:9px;text-align:center;font-weight:700;margin-bottom:12px;font-size:.95rem;}
+.turn.w{background:linear-gradient(90deg,rgba(244,162,97,.18),rgba(244,162,97,.05));border:1px solid var(--peach);color:var(--peach);}
+.turn.b{background:linear-gradient(90deg,rgba(42,157,143,.2),rgba(42,157,143,.05));border:1px solid var(--teal);color:#7fd3c6;}
+
+.pips{display:flex;gap:8px;margin-bottom:12px;}
+.pipbox{flex:1;text-align:center;padding:8px 4px;border-radius:8px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);}
+.pipbox .lab{font-size:.6rem;text-transform:uppercase;letter-spacing:1px;opacity:.6;}
+.pipbox .val{font-size:1.5rem;font-weight:800;font-family:'Playfair Display',serif;}
+.pipbox.w .val{color:var(--peach);} .pipbox.b .val{color:#7fd3c6;}
+
+.double-row{display:flex;align-items:center;gap:10px;margin-bottom:12px;padding:9px;border-radius:8px;
+  background:rgba(233,196,106,.07);border:1px solid rgba(233,196,106,.2);}
+.double-row .stake{font-size:.75rem;opacity:.8;flex:1;}
+.double-row .stake b{color:var(--gold);font-size:1.05rem;}
+.btn{border:none;border-radius:8px;cursor:pointer;font-family:'Inter';font-weight:600;letter-spacing:.5px;
+  text-transform:uppercase;font-size:.72rem;padding:9px 12px;transition:.15s;color:#fff;}
+.btn:disabled{opacity:.35;cursor:not-allowed;}
+.btn-dbl{background:#8e6b1e;}.btn-dbl:hover:not(:disabled){background:#a67d24;}
+.row{display:flex;gap:8px;margin-top:8px;}
+.btn-undo{flex:1;background:#3a5a75;}.btn-undo:hover:not(:disabled){background:#456a8a;}
+.btn-reset{flex:1;background:var(--burnt);}.btn-reset:hover{background:var(--peach);color:#20140a;}
+
+.status{margin-top:12px;padding:10px;border-radius:8px;text-align:center;font-weight:600;font-size:.82rem;
+  min-height:40px;display:flex;align-items:center;justify-content:center;
+  background:rgba(42,157,143,.1);color:#8fd;border:1px solid rgba(42,157,143,.3);}
+.status.win{background:rgba(233,196,106,.18);color:var(--gold);border-color:var(--gold);font-size:.95rem;}
+
+.opts{display:flex;align-items:center;gap:8px;margin-top:12px;font-size:.75rem;color:#9ab;}
+.opts input{accent-color:var(--gold);}
+.cast{list-style:none;font-size:.72rem;margin-top:10px;color:#9aa;line-height:1.6;}
+.cast b{color:var(--gold);}
+
+/* modal */
+.overlay{position:fixed;inset:0;background:rgba(0,0,0,.72);display:none;align-items:center;justify-content:center;z-index:100;}
+.overlay.on{display:flex;}
+.modal{background:linear-gradient(180deg,#161c30,#0d1120);border:1px solid var(--gold);border-radius:14px;
+  padding:24px 28px;text-align:center;max-width:340px;box-shadow:0 20px 60px rgba(0,0,0,.8);}
+.modal h3{font-family:'Playfair Display',serif;color:var(--gold);margin-bottom:8px;font-size:1.3rem;}
+.modal p{font-size:.85rem;color:#cdd;margin-bottom:16px;line-height:1.5;}
+.modal .mbtns{display:flex;gap:12px;justify-content:center;}
+.modal .btn{font-size:.8rem;padding:11px 18px;}
+.btn-accept{background:var(--teal);}.btn-decline{background:var(--burnt);}
+.btn-ok{background:var(--gold);color:#20140a;}
+
+@media(max-width:900px){
+  #board{grid-template-columns:repeat(6,40px) 36px repeat(6,40px);grid-template-rows:18px 176px 18px 176px 18px;}
+  .checker{width:34px;height:34px;} h1{font-size:1.8rem;} .trays{margin-left:8px;} .tray{width:44px;}
+  .chip-off{width:34px;}
+}
+</style>
+</head>
+<body>
+<h1>Beverly Hills, 90210</h1>
+<div class="subtitle">The Peach Pit Backgammon Room</div>
+
+<div class="top-controls">
+  <div id="diceTray" class="dice-tray"></div>
+  <button class="btn-roll" id="rollBtn" onclick="rollDice()">🎲 Roll</button>
+</div>
+
+<div class="wrap">
+  <div class="stage">
+    <div class="playfield"><div id="board"></div></div>
+    <div class="trays">
+      <div class="tray top" id="trayBlack" onclick="trayClick('black')"><span class="tray-cap">The World</span></div>
+      <div class="tray bot" id="trayWhite" onclick="trayClick('white')"><span class="tray-cap">West Beverly</span></div>
+    </div>
+  </div>
+
+  <div class="panel">
+    <h2>🎲 The Match</h2>
+
+    <div class="setup">
+      <div class="setup-row">
+        <span class="setup-lab">Opponent</span>
+        <div class="seg" id="segMode">
+          <button data-v="ai" class="on">🤖 Computer</button>
+          <button data-v="hot">👥 2-Player</button>
+        </div>
+      </div>
+      <div class="setup-row" id="skillRow">
+        <span class="setup-lab">Skill level</span>
+        <div class="seg" id="segSkill">
+          <button data-v="rookie">Rookie</button>
+          <button data-v="amateur" class="on">Amateur</button>
+          <button data-v="pro">Pro</button>
+          <button data-v="legend">Legend</button>
+        </div>
+      </div>
+      <div class="setup-row" id="sideRow">
+        <span class="setup-lab">You play</span>
+        <div class="seg" id="segSide">
+          <button data-v="white" class="on">🍑 W. Beverly</button>
+          <button data-v="black">The World</button>
+        </div>
+      </div>
+    </div>
+
+    <div id="turn" class="turn w">West Beverly (White)</div>
+
+    <div class="pips">
+      <div class="pipbox w"><div class="lab">W. Beverly pips</div><div class="val" id="pipW">167</div></div>
+      <div class="pipbox b"><div class="lab">The World pips</div><div class="val" id="pipB">167</div></div>
+    </div>
+
+    <div class="double-row">
+      <div class="stake">Stake: <b id="stakeVal">1</b> point<span id="cubeOwn"></span></div>
+      <button class="btn btn-dbl" id="dblBtn" onclick="offerDouble()">Double ✦</button>
+    </div>
+
+    <div id="status" class="status">Press Roll — high die opens the game.</div>
+
+    <div class="row">
+      <button class="btn btn-undo" id="undoBtn" onclick="undoMove()">↶ Undo</button>
+      <button class="btn btn-reset" onclick="resetGame()">New Game</button>
+    </div>
+
+    <label class="opts"><input type="checkbox" id="sound" checked> Table sounds</label>
+
+    <ul class="cast">
+      <li><b>White</b> = West Beverly · moves 24→1 · bears off bottom-right</li>
+      <li><b>Black</b> = The World · moves 1→24 · bears off top-right</li>
+      <li>Doubles = 4 moves. Must play both dice if legal (larger die wins ties).</li>
+    </ul>
+  </div>
+</div>
+
+<div class="overlay" id="overlay"><div class="modal" id="modal"></div></div>
+
+<script>
+/* =====================================================================
+   90210 BACKGAMMON — premium build
+   idx 0..23 = points 1..24.  White moves ↓ toward 0 (home 0..5).
+   Black moves ↑ toward 23 (home 18..23).
+   ===================================================================== */
+const opp=c=>c==='white'?'black':'white';
+const homeS=c=>c==='white'?0:18, homeE=c=>c==='white'?5:23;
+
+let points,bar,off,turn,dice,selected,history,gameOver,phase,cube,cubeOwner,winInfo;
+let vsAI=true, playerSide='white', aiSide='black', aiLevel='amateur', aiGen=0;
+
+function startPos(){const p=Array(24).fill(null);const s=(i,c,n)=>p[i]={color:c,count:n};
+  s(23,'white',2);s(12,'white',5);s(7,'white',3);s(5,'white',5);
+  s(0,'black',2);s(11,'black',5);s(16,'black',3);s(18,'black',5);return p;}
+
+function initGame(){
+  points=startPos();bar={white:0,black:0};off={white:0,black:0};
+  turn='white';dice=[];selected=null;history=[];gameOver=false;
+  phase='opening';cube=1;cubeOwner=null;winInfo=null;aiGen++;
+  closeModal();renderAll();
+  setStatus('Press Roll — each side rolls one die, high die opens the game.');
+}
+
+/* ---------- pure state helpers (for the max-dice rule) ---------- */
+const snap=()=>({points:points.map(p=>p?{...p}:null),bar:{...bar},off:{...off}});
+const clone=st=>({points:st.points.map(p=>p?{...p}:null),bar:{...st.bar},off:{...st.off}});
+function allHomeSt(st,c){if(st.bar[c]>0)return false;const s=homeS(c),e=homeE(c);
+  for(let i=0;i<24;i++)if(st.points[i]&&st.points[i].color===c&&(i<s||i>e))return false;return true;}
+function genForDie(st,c,dv){const mv=[];
+  if(st.bar[c]>0){const e=c==='white'?24-dv:dv-1;
+    if(e>=0&&e<24){const t=st.points[e];if(!t||t.color===c||t.count===1)mv.push({from:'bar',die:dv,to:e});}
+    return mv;}
+  const bear=allHomeSt(st,c);
+  for(let i=0;i<24;i++){const p=st.points[i];if(!p||p.color!==c)continue;
+    const d=c==='white'?i-dv:i+dv;
+    if(d>=0&&d<24){const t=st.points[d];if(!t||t.color===c||t.count===1)mv.push({from:i,die:dv,to:d});}
+    else if(bear){const s=homeS(c),e=homeE(c);
+      const exact=c==='white'?(i-dv===-1):(i+dv===24);
+      if(exact)mv.push({from:i,die:dv,to:'off'});
+      else{const over=c==='white'?(i-dv<-1):(i+dv>24);
+        if(over){let higher=false;
+          if(c==='white'){for(let k=i+1;k<=e;k++)if(st.points[k]&&st.points[k].color===c){higher=true;break;}}
+          else{for(let k=s;k<i;k++)if(st.points[k]&&st.points[k].color===c){higher=true;break;}}
+          if(!higher)mv.push({from:i,die:dv,to:'off'});}}}}
+  return mv;}
+function applyToSt(st,c,m){
+  if(m.from==='bar')st.bar[c]--;else{st.points[m.from].count--;if(!st.points[m.from].count)st.points[m.from]=null;}
+  if(m.to==='off')st.off[c]++;
+  else{const t=st.points[m.to];
+    if(t&&t.color!==c){st.bar[opp(c)]++;st.points[m.to]={color:c,count:1};}
+    else if(t)t.count++;else st.points[m.to]={color:c,count:1};}}
+function maxDepth(st,c,arr){if(!arr.length)return 0;let best=0;const tried=new Set();
+  for(let k=0;k<arr.length;k++){const dv=arr[k];if(tried.has(dv))continue;tried.add(dv);
+    const rest=arr.slice(0,k).concat(arr.slice(k+1));
+    for(const m of genForDie(st,c,dv)){const ns=clone(st);applyToSt(ns,c,m);
+      const d=1+maxDepth(ns,c,rest);if(d>best)best=d;if(best===arr.length)return best;}}
+  return best;}
+
+/* legal FIRST moves for the current turn/dice, honoring the use-both / larger-die rule */
+function legalMoves(){
+  if(!dice.length)return[];
+  const st=snap(),c=turn,md=maxDepth(st,c,dice);
+  if(md===0)return[];
+  const res=[],tried=new Set();
+  for(let k=0;k<dice.length;k++){const dv=dice[k];if(tried.has(dv))continue;tried.add(dv);
+    const rest=dice.slice(0,k).concat(dice.slice(k+1));
+    for(const m of genForDie(st,c,dv)){const ns=clone(st);applyToSt(ns,c,m);
+      if(1+maxDepth(ns,c,rest)===md)res.push(m);}}
+  if(md===1&&dice.length===2&&dice[0]!==dice[1]){
+    const big=Math.max(dice[0],dice[1]);
+    if(res.some(m=>m.die===big))return res.filter(m=>m.die===big);}
+  return res;}
+
+function pipCount(c){let n=bar[c]*25;
+  for(let i=0;i<24;i++){const p=points[i];if(p&&p.color===c)n+=p.count*(c==='white'?i+1:24-i);}return n;}
+
+/* ---------- performing a move ---------- */
+function doMove(m){
+  history.push(JSON.stringify({points,bar,off,dice,turn,cube,cubeOwner}));
+  const c=turn;
+  if(m.from==='bar')bar[c]--;else{points[m.from].count--;if(!points[m.from].count)points[m.from]=null;}
+  let hit=false;
+  if(m.to==='off'){off[c]++;}
+  else{const t=points[m.to];
+    if(t&&t.color!==c){bar[opp(c)]++;points[m.to]={color:c,count:1};hit=true;}
+    else if(t)t.count++;else points[m.to]={color:c,count:1};}
+  const di=dice.indexOf(m.die);if(di!==-1)dice.splice(di,1);
+  selected=null;
+  sound(hit?'hit':'move');
+  if(off[c]===15){endGame(c);return;}
+  if(dice.length===0||legalMoves().length===0){
+    if(dice.length&&legalMoves().length===0)setStatus('No move for the remaining die — turn passes.');
+    setTimeout(endTurn,dice.length?650:0);
+    renderAll();
+  }else{renderAll();setStatus(`${name(c)}: ${dice.length} to play.`);}
+}
+function endTurn(){turn=opp(turn);dice=[];history=[];selected=null;renderAll();
+  setStatus(`${name(turn)} — Double or Roll.`);maybeAI();}
+
+function endGame(c){
+  gameOver=true;
+  // gammon / backgammon multiplier
+  const loser=opp(c);let mult=1,kind='single game';
+  if(off[loser]===0){
+    let inWinnerHome=bar[loser]>0;
+    const s=homeS(c),e=homeE(c);
+    for(let i=s;i<=e;i++)if(points[i]&&points[i].color===loser)inWinnerHome=true;
+    mult=inWinnerHome?3:2;kind=inWinnerHome?'BACKGAMMON':'GAMMON';
+  }
+  const pts=cube*mult;
+  renderAll();
+  showModal(`🏆 ${name(c)} wins!`,
+    `${kind==='single game'?'A clean single game':'A '+kind+'!'} — worth <b>${pts}</b> point${pts>1?'s':''} at the current stake (cube ${cube}${mult>1?' × '+mult:''}).`,
+    [{t:'New Game',cls:'btn-ok',fn:resetGame}]);
+  setStatus(`${name(c)} bears off all 15 — ${kind}! (${pts} pts)`,true);
+}
+
+/* ---------- doubling cube ---------- */
+function offerDouble(){
+  if(gameOver||phase!=='play'||dice.length)return;
+  if(vsAI&&turn===aiSide)return;
+  if(cubeOwner&&cubeOwner!==turn)return;      // you must own the cube (or centered) to offer
+  const offerer=turn,taker=opp(turn);
+  if(vsAI&&taker===aiSide){                    // AI decides for itself
+    if(aiTakesDouble()){cube*=2;cubeOwner=aiSide;sound('move');renderAll();setStatus(`The World takes. Stake is now ${cube}.`);}
+    else{gameOver=true;renderAll();
+      showModal('The World declines',`You win <b>${cube}</b> point${cube>1?'s':''} without playing it out.`,
+        [{t:'New Game',cls:'btn-ok',fn:resetGame}]);setStatus(`The World drops — you win ${cube}.`,true);}
+    return;
+  }
+  showModal(`${name(offerer)} offers to double`,
+    `Raise the stake from <b>${cube}</b> to <b>${cube*2}</b> points? ${name(taker)}, do you accept?`,
+    [{t:'Accept ('+(cube*2)+')',cls:'btn-accept',fn:()=>{cube*=2;cubeOwner=taker;closeModal();sound('move');renderAll();setStatus(`${name(taker)} takes. Stake is now ${cube}.`);}},
+     {t:'Decline',cls:'btn-decline',fn:()=>{closeModal();gameOver=true;renderAll();
+        showModal(`${name(taker)} declines`,`${name(offerer)} wins <b>${cube}</b> point${cube>1?'s':''} without playing it out.`,
+        [{t:'New Game',cls:'btn-ok',fn:resetGame}]);setStatus(`${name(offerer)} wins ${cube} on the drop.`,true);}}]);
+}
+
+/* ---------- dice / opening ---------- */
+function rollDice(){
+  if(gameOver||dice.length)return;
+  if(phase==='play'&&vsAI&&turn===aiSide)return;
+  if(phase==='opening'){
+    let a,b;do{a=d6();b=d6();}while(a===b);
+    turn=a>b?'white':'black';dice=[a,b];phase='play';
+    document.getElementById('rollBtn').disabled=true;
+    sound('roll');renderDice(true);renderAll();
+    setStatus(`Opening roll ${a}-${b}. ${name(turn)} plays it.${vsAI&&turn===aiSide?'':' Move a checker.'}`);
+    if(vsAI&&turn===aiSide)maybeAI();
+    return;
+  }
+  const a=d6(),b=d6();dice=a===b?[a,a,a,a]:[a,b];history=[];
+  document.getElementById('rollBtn').disabled=true;
+  sound('roll');renderDice(true);renderAll();
+  if(legalMoves().length===0){
+    setStatus(`${name(turn)} rolled ${a}-${b} — no legal moves. Passing…`);
+    setTimeout(endTurn,1400);
+  }else setStatus(`Rolled ${a}${a===b?' (doubles → 4!)':'-'+b}. Move a checker.`);
+}
+const d6=()=>1+Math.floor(Math.random()*6);
+
+/* ---------- interaction ---------- */
+function clickBar(){if(gameOver||!dice.length||bar[turn]===0)return;
+  if(vsAI&&turn===aiSide)return;
+  if(!legalMoves().some(m=>m.from==='bar'))return;
+  selected={type:'bar'};renderAll();setStatus('Enter from the BAR — click a glowing point.');}
+function clickPoint(idx){
+  if(gameOver||!dice.length)return;
+  if(vsAI&&turn===aiSide)return;
+  if(selected){const src=selected.type==='bar'?'bar':selected.idx;
+    const cand=legalMoves().filter(m=>m.from===src&&m.to===idx);
+    if(cand.length){cand.sort((x,y)=>x.die-y.die);doMove(cand[0]);return;}}
+  if(bar[turn]>0){clickBar();return;}
+  const p=points[idx];
+  if(p&&p.color===turn&&legalMoves().some(m=>m.from===idx)){
+    selected={type:'point',idx};renderAll();
+    const canOff=legalMoves().some(m=>m.from===idx&&m.to==='off');
+    setStatus(canOff?'Click a glowing point — or your bear-off tray to bear this checker off. 🏁'
+                    :'Click a glowing destination.');
+  }else{selected=null;renderAll();}
+}
+function trayClick(color){
+  if(gameOver||!selected||selected.type!=='point'||color!==turn)return;
+  if(vsAI&&turn===aiSide)return;
+  const cand=legalMoves().filter(m=>m.from===selected.idx&&m.to==='off');
+  if(cand.length){cand.sort((x,y)=>x.die-y.die);doMove(cand[0]);}
+}
+function undoMove(){if(!history.length||gameOver)return;
+  const s=JSON.parse(history.pop());points=s.points;bar=s.bar;off=s.off;dice=s.dice;turn=s.turn;cube=s.cube;cubeOwner=s.cubeOwner;
+  selected=null;renderAll();setStatus('Move undone.');}
+function resetGame(){initGame();}
+const name=c=>c==='white'?'West Beverly':'The World';
+
+/* ---------- rendering ---------- */
+const TOP=[12,13,14,15,16,17,18,19,20,21,22,23];
+const BOT=[11,10,9,8,7,6,5,4,3,2,1,0];
+const PIPMAP={1:[4],2:[0,8],3:[0,4,8],4:[0,2,6,8],5:[0,2,4,6,8],6:[0,2,3,5,6,8]};
+
+function checkerHTML(color,count){
+  let h='';const show=Math.min(count,5);
+  for(let i=0;i<show;i++){
+    const lbl=(i===4&&count>5)?`<span class="cnt">${count}</span>`:'';
+    h+=`<div class="checker ${color}">${lbl}</div>`;}
+  return h;}
+
+function renderAll(){
+  const b=document.getElementById('board');b.innerHTML='';
+  const legal=dice.length?legalMoves():[];
+  const srcs=new Set(legal.map(m=>m.from));
+  let dsts=new Set(),offSel=false;
+  if(selected){const s=selected.type==='bar'?'bar':selected.idx;
+    legal.filter(m=>m.from===s).forEach(m=>{if(m.to==='off')offSel=true;else dsts.add(m.to);});}
+
+  const mkLabel=(col,row,txt)=>{const d=document.createElement('div');d.className='label';
+    d.style.gridColumn=col;d.style.gridRow=row;d.textContent=txt;b.appendChild(d);};
+  const colOf=i=>i<6?i+1:i+2;
+
+  TOP.forEach((idx,i)=>mkLabel(colOf(i),1,idx+1));
+  BOT.forEach((idx,i)=>mkLabel(colOf(i),5,idx+1));
+
+  const mkPoint=(idx,row,col,place)=>{
+    const d=document.createElement('div');
+    const isSel=selected&&selected.type==='point'&&selected.idx===idx;
+    d.className=`point ${place}`
+      +(srcs.has(idx)&&!selected?' playable-src':'')
+      +(isSel?' selected':'')
+      +(dsts.has(idx)?' playable-dst':'');
+    d.style.gridColumn=col;d.style.gridRow=row;
+    const dark=(idx%2===0);
+    d.innerHTML=`<div class="tri ${dark?'dk':'lt'}"></div>`;
+    const p=points[idx];if(p)d.innerHTML+=checkerHTML(p.color,p.count);
+    d.onclick=()=>{if(isSel){const off=legalMoves().filter(m=>m.from===idx&&m.to==='off');
+      if(off.length){off.sort((x,y)=>x.die-y.die);doMove(off[0]);return;}}clickPoint(idx);};
+    b.appendChild(d);};
+
+  TOP.forEach((idx,i)=>mkPoint(idx,'2',colOf(i),'top'));
+  BOT.forEach((idx,i)=>mkPoint(idx,'4',colOf(i),'bottom'));
+
+  // BAR
+  const barEl=document.createElement('div');barEl.className='bar';
+  const zone=c=>{const canSel=bar[c]>0&&turn===c&&dice.length&&legal.some(m=>m.from==='bar');
+    const sel=selected&&selected.type==='bar'&&turn===c;
+    let chips='';for(let i=0;i<bar[c];i++)chips+=`<div class="checker ${c}"></div>`;
+    return `<div class="bar-zone ${canSel?'playable-src':''} ${sel?'selected':''}" data-c="${c}">
+      <span class="bar-cap">${c==='white'?'W.B.':'World'}</span>${chips}</div>`;};
+  const cubeH=`<div class="cube-holder"><span class="bar-cap">stake</span><div class="cube">${cube}</div></div>`;
+  barEl.innerHTML=zone('black')+cubeH+zone('white');
+  barEl.querySelectorAll('.bar-zone').forEach(z=>z.onclick=()=>{if(z.dataset.c===turn)clickBar();});
+  b.appendChild(barEl);
+
+  // trays
+  const tw=document.getElementById('trayWhite'),tb=document.getElementById('trayBlack');
+  tw.className='tray bot'+(offSel&&turn==='white'?' playable-dst':'');
+  tb.className='tray top'+(offSel&&turn==='black'?' playable-dst':'');
+  tw.innerHTML='<span class="tray-cap">West Beverly</span>'+'<div class="chip-off white"></div>'.repeat(off.white);
+  tb.innerHTML='<span class="tray-cap">The World</span>'+'<div class="chip-off black"></div>'.repeat(off.black);
+
+  // panel
+  document.getElementById('pipW').textContent=pipCount('white');
+  document.getElementById('pipB').textContent=pipCount('black');
+  const t=document.getElementById('turn');
+  t.className='turn '+(turn==='white'?'w':'b');
+  t.textContent=name(turn)+(turn==='white'?' (White)':' (Black)');
+  document.getElementById('stakeVal').textContent=cube;
+  document.getElementById('cubeOwn').textContent=cubeOwner?` · held by ${cubeOwner==='white'?'W.B.':'World'}`:' · centered';
+  const aiTurn=vsAI&&turn===aiSide;
+  document.getElementById('dblBtn').disabled=gameOver||phase!=='play'||dice.length>0||(cubeOwner&&cubeOwner!==turn)||aiTurn;
+  document.getElementById('undoBtn').disabled=history.length===0||gameOver||aiTurn;
+  document.getElementById('rollBtn').disabled=dice.length>0||gameOver||aiTurn;
+  renderDice();
+}
+function renderDice(anim){
+  const tray=document.getElementById('diceTray');tray.innerHTML='';
+  if(!dice.length){tray.innerHTML=gameOver?'':'<span style="color:#556;font-size:.8rem;letter-spacing:2px;">READY</span>';return;}
+  dice.forEach(v=>{const d=document.createElement('div');
+    d.className='die3d '+(turn==='white'?'light':'dark')+(anim?' rolling':'');
+    for(let c=0;c<9;c++){const cell=document.createElement('span');
+      if(PIPMAP[v].includes(c))cell.className='pip';d.appendChild(cell);}
+    tray.appendChild(d);});
+}
+function setStatus(msg,win){const el=document.getElementById('status');
+  el.className='status'+(win?' win':'');el.innerHTML=msg;}
+
+/* ---------- modal ---------- */
+function showModal(title,body,btns){
+  const m=document.getElementById('modal');
+  m.innerHTML=`<h3>${title}</h3><p>${body}</p><div class="mbtns"></div>`;
+  const box=m.querySelector('.mbtns');
+  btns.forEach(b=>{const el=document.createElement('button');el.className='btn '+b.cls;el.textContent=b.t;el.onclick=b.fn;box.appendChild(el);});
+  document.getElementById('overlay').classList.add('on');}
+function closeModal(){document.getElementById('overlay').classList.remove('on');}
+
+/* ---------- sound (WebAudio, no assets) ---------- */
+let actx;
+function sound(kind){
+  if(!document.getElementById('sound').checked)return;
+  try{actx=actx||new(window.AudioContext||window.webkitAudioContext)();
+    if(kind==='roll'){for(let i=0;i<7;i++)tick(0.02+i*0.05,900+Math.random()*700,0.05);}
+    else if(kind==='hit'){tick(0,180,0.16,'sawtooth');tick(0.02,120,0.2,'sawtooth');}
+    else tick(0,520,0.06);}catch(e){}}
+function tick(delay,freq,dur,type){
+  const o=actx.createOscillator(),g=actx.createGain(),t=actx.currentTime+delay;
+  o.type=type||'square';o.frequency.value=freq;o.connect(g);g.connect(actx.destination);
+  g.gain.setValueAtTime(0.0001,t);g.gain.exponentialRampToValueAtTime(0.18,t+0.005);
+  g.gain.exponentialRampToValueAtTime(0.0001,t+dur);o.start(t);o.stop(t+dur+0.02);}
+
+/* ============================ COMPUTER OPPONENT ============================ */
+const LEVELS={
+  rookie:null,
+  amateur:{off:30,pip:.7,barMe:20,barYou:12,blot:5,shots:false,shotW:0,point:4,homePoint:2,anchor:2,topN:3},
+  pro:{off:35,pip:1,barMe:30,barYou:22,blot:10,shots:true,shotW:26,point:6,homePoint:4,anchor:5,topN:1},
+  legend:{off:40,pip:1.1,barMe:34,barYou:26,blot:12,shots:true,shotW:34,point:7,homePoint:6,anchor:5,topN:1,cube:true}
+};
+function pipOf(st,c){let n=st.bar[c]*25;for(let i=0;i<24;i++){const p=st.points[i];if(p&&p.color===c)n+=p.count*(c==='white'?i+1:24-i);}return n;}
+function canHitRoll(st,i,you,a,b){
+  for(const die of (a===b?[a]:[a,b])){for(let j=0;j<24;j++){const p=st.points[j];if(!p||p.color!==you)continue;
+    if((you==='white'?j-die:j+die)===i)return true;}}
+  const orders=a===b?[[a,a]]:[[a,b],[b,a]];
+  for(const[d1,d2]of orders){for(let j=0;j<24;j++){const p=st.points[j];if(!p||p.color!==you)continue;
+    const mid=you==='white'?j-d1:j+d1;if(mid<0||mid>23)continue;const mp=st.points[mid];
+    if(mp&&mp.color!==you&&mp.count>=2)continue;if((you==='white'?mid-d2:mid+d2)===i)return true;}}
+  return false;}
+function shotsFrac(st,i,you){let c=0;for(let a=1;a<=6;a++)for(let b=1;b<=6;b++)if(canHitRoll(st,i,you,a,b))c++;return c/36;}
+function evalState(st,me,W){const you=opp(me);let s=(st.off[me]-st.off[you])*W.off+(pipOf(st,you)-pipOf(st,me))*W.pip;
+  s-=st.bar[me]*W.barMe;s+=st.bar[you]*W.barYou;
+  for(let i=0;i<24;i++){const p=st.points[i];if(!p)continue;
+    if(p.color===me){if(p.count===1){let ex=W.blot;if(W.shots)ex+=shotsFrac(st,i,you)*W.shotW;s-=ex;}
+      else{s+=W.point;if(i>=homeS(me)&&i<=homeE(me))s+=W.homePoint;if(i>=homeS(you)&&i<=homeE(you))s+=W.anchor;}}}
+  return s;}
+function sigOf(st){let s='';for(let i=0;i<24;i++){const p=st.points[i];s+=p?(p.color==='white'?'W':'B')+p.count:'.';}
+  return s+'|w'+st.bar.white+'b'+st.bar.black+'o'+st.off.white+','+st.off.black;}
+function enumerateSequences(st0,color,diceArr){const md=maxDepth(st0,color,diceArr);const out=new Map();
+  if(md===0){out.set(sigOf(st0),{state:st0,moves:[]});return[...out.values()];}
+  (function dfs(st,rem,path){const cur=maxDepth(st,color,rem);
+    if(cur===0){const g=sigOf(st);if(!out.has(g))out.set(g,{state:st,moves:path});return;}
+    const tried=new Set();
+    for(let k=0;k<rem.length;k++){const dv=rem[k];if(tried.has(dv))continue;tried.add(dv);
+      const rest=rem.slice(0,k).concat(rem.slice(k+1));
+      for(const m of genForDie(st,color,dv)){const ns=clone(st);applyToSt(ns,color,m);
+        if(1+maxDepth(ns,color,rest)===cur)dfs(ns,rest,path.concat([{from:m.from,die:m.die,to:m.to}]));}}
+  })(clone(st0),diceArr,[]);return[...out.values()];}
+function aiBestSequence(){const seqs=enumerateSequences(snap(),turn,dice);
+  if(seqs.length<=1)return seqs[0]?seqs[0].moves:[];
+  const W=LEVELS[aiLevel];if(!W)return seqs[(Math.random()*seqs.length)|0].moves;
+  const sc=seqs.map(s=>({m:s.moves,v:evalState(s.state,turn,W)})).sort((a,b)=>b.v-a.v);
+  return sc[(Math.random()*Math.min(W.topN||1,sc.length))|0].m;}
+function aiTakesDouble(){const behind=pipCount(aiSide)-pipCount(opp(aiSide));return !(behind>60&&off[opp(aiSide)]>0);}
+function aiWantsToDouble(){const you=opp(aiSide);
+  return pipCount(you)-pipCount(aiSide)>=25&&off[you]===0&&bar[aiSide]===0&&Math.random()<0.6;}
+
+function maybeAI(){
+  if(!vsAI||gameOver||turn!==aiSide)return;
+  const g=aiGen;
+  setTimeout(()=>{
+    if(g!==aiGen||gameOver||turn!==aiSide)return;
+    if(dice.length){aiThinkPlay(g);return;}
+    const W=LEVELS[aiLevel];
+    if(W&&W.cube&&(cubeOwner===null||cubeOwner===aiSide)&&cube<8&&aiWantsToDouble()){aiOfferDouble(g);return;}
+    aiRoll(g);
+  },650);
+}
+function aiRoll(g){if(g!==aiGen||gameOver||turn!==aiSide)return;
+  const a=d6(),b=d6();dice=a===b?[a,a,a,a]:[a,b];history=[];
+  sound('roll');renderDice(true);renderAll();
+  setStatus(`The World rolled ${a}${a===b?' (doubles!)':'-'+b}…`);
+  setTimeout(()=>aiThinkPlay(g),780);}
+function aiThinkPlay(g){if(g!==aiGen||gameOver||turn!==aiSide)return;
+  if(legalMoves().length===0){setStatus('The World has no move — passing.');setTimeout(endTurn,850);return;}
+  setStatus('The World is plotting… 🤔');
+  setTimeout(()=>{if(g!==aiGen)return;const seq=aiBestSequence();
+    if(!seq.length){setTimeout(endTurn,300);return;}aiPlaySeq(seq,0,g);},280);}
+function aiPlaySeq(moves,i,g){if(g!==aiGen||gameOver||i>=moves.length)return;
+  const legal=legalMoves();let m=moves[i];
+  if(!legal.some(x=>x.from===m.from&&x.die===m.die&&x.to===m.to)){
+    if(!legal.length){setTimeout(endTurn,300);return;}m=legal[0];}
+  selected=m.from==='bar'?{type:'bar'}:{type:'point',idx:m.from};renderAll();
+  setTimeout(()=>{if(g!==aiGen)return;doMove(m);if(gameOver)return;
+    if(turn===aiSide&&dice.length&&legalMoves().length)setTimeout(()=>aiPlaySeq(moves,i+1,g),470);},330);}
+function aiOfferDouble(g){if(g!==aiGen)return;
+  showModal('The World offers to double',
+    `The World raises the stake from <b>${cube}</b> to <b>${cube*2}</b> points. Do you accept?`,
+    [{t:'Accept ('+(cube*2)+')',cls:'btn-accept',fn:()=>{cube*=2;cubeOwner=opp(aiSide);closeModal();sound('move');renderAll();setStatus(`You take. Stake is now ${cube}.`);maybeAI();}},
+     {t:'Decline',cls:'btn-decline',fn:()=>{closeModal();gameOver=true;renderAll();
+        showModal('You decline',`The World wins <b>${cube}</b> point${cube>1?'s':''}.`,[{t:'New Game',cls:'btn-ok',fn:resetGame}]);
+        setStatus(`Declined — The World wins ${cube}.`,true);}}]);
+}
+
+/* ---------- setup segmented controls ---------- */
+function bindSeg(id,fn){const grp=document.getElementById(id);
+  grp.querySelectorAll('button').forEach(b=>b.onclick=()=>{
+    grp.querySelectorAll('button').forEach(x=>x.classList.remove('on'));b.classList.add('on');fn(b.dataset.v);});}
+function freshGame(){aiSide=opp(playerSide);initGame();}
+function setupControls(){
+  bindSeg('segMode',v=>{vsAI=v==='ai';
+    document.getElementById('skillRow').style.display=vsAI?'':'none';
+    document.getElementById('sideRow').style.display=vsAI?'':'none';freshGame();});
+  bindSeg('segSkill',v=>{aiLevel=v;freshGame();});
+  bindSeg('segSide',v=>{playerSide=v;freshGame();});
+}
+
+setupControls();
+freshGame();
+</script>
+</body>
+</html>
diff --git a/games/breakout/AbramsBreak.aa b/games/breakout/AbramsBreak.aa
new file mode 100644
index 0000000..f5935f2
--- /dev/null
+++ b/games/breakout/AbramsBreak.aa
@@ -0,0 +1,240 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Abrams Break</title>
+<style>
+  :root { --bg:#0a0e14; --ink:#e5e7eb; }
+  * { box-sizing:border-box; margin:0; padding:0; }
+  html,body { height:100%; }
+  body {
+    background:radial-gradient(1200px 600px at 50% -10%, #16202e, var(--bg));
+    color:var(--ink); font:15px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
+    display:flex; flex-direction:column; align-items:center; justify-content:center;
+    min-height:100%; gap:10px; padding:12px; overscroll-behavior:none; touch-action:none;
+  }
+  h1 { font-size:14px; letter-spacing:.28em; text-transform:uppercase; color:#93c5fd; font-weight:600; }
+  .hud { display:flex; gap:18px; font-variant-numeric:tabular-nums; font-size:13px; color:#9aa4b2; }
+  .hud b { color:var(--ink); font-weight:600; }
+  #wrap { position:relative; }
+  canvas { background:#0d131c; border-radius:12px; box-shadow:0 10px 40px rgba(0,0,0,.5); display:block; }
+  .overlay {
+    position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
+    gap:10px; text-align:center; background:rgba(8,12,18,.72); border-radius:12px; backdrop-filter:blur(2px);
+  }
+  .overlay.hide { display:none; }
+  .big { font-size:22px; font-weight:700; }
+  .sub { font-size:13px; color:#9aa4b2; max-width:300px; }
+  .tag { font-size:11px; color:#93c5fd; letter-spacing:.2em; text-transform:uppercase; }
+  button.play { margin-top:4px; padding:10px 22px; border:0; border-radius:999px; cursor:pointer; background:linear-gradient(180deg,#60a5fa,#3b82f6); color:#fff; font-weight:700; font-size:14px; }
+  .btns { position:absolute; top:8px; right:10px; display:flex; gap:6px; }
+  .btns button { width:30px; height:30px; border-radius:8px; border:1px solid #2a3441; background:#141b25; color:#cbd5e1; cursor:pointer; font-size:14px; }
+  .hint { font-size:11px; color:#5b6673; }
+</style>
+</head>
+<body>
+  <h1>Abrams Break</h1>
+  <div class="hud"><span>Score <b id="score">0</b></span><span>Lives <b id="lives">3</b></span><span>Level <b id="lvl">1</b></span><span>Best <b id="best">0</b></span></div>
+  <div id="wrap">
+    <canvas id="c" width="440" height="480"></canvas>
+    <div class="btns">
+      <button id="mute" title="Mute (M)">🔊</button>
+      <button id="pauseBtn" title="Pause (P)">⏸</button>
+    </div>
+    <div class="overlay" id="ov">
+      <div class="tag" id="ovTag">Ready</div>
+      <div class="big" id="ovTitle">Abrams Break</div>
+      <div class="sub" id="ovSub">Clear every brick. Move the paddle with mouse / arrows, or drag on touch. Don't drop the ball.</div>
+      <button class="play" id="playBtn">Play</button>
+      <div class="hint">P pause · M mute · Space launch</div>
+    </div>
+  </div>
+
+<script>
+(function () {
+  var cv = document.getElementById('c'), ctx = cv.getContext('2d');
+  var W = cv.width, H = cv.height;
+  var scoreEl = document.getElementById('score'), livesEl = document.getElementById('lives'),
+      lvlEl = document.getElementById('lvl'), bestEl = document.getElementById('best');
+  var ov = document.getElementById('ov'), ovTag = document.getElementById('ovTag'), ovTitle = document.getElementById('ovTitle'), ovSub = document.getElementById('ovSub');
+  var playBtn = document.getElementById('playBtn'), pauseBtn = document.getElementById('pauseBtn'), muteBtn = document.getElementById('mute');
+
+  var BEST_KEY = 'abrams-break-best';
+  var best = parseInt(localStorage.getItem(BEST_KEY) || '0', 10) || 0; bestEl.textContent = best;
+
+  var COLS = 10, PAD = 6, TOP = 46, BRICK_H = 20;
+  var brickW = (W - PAD * (COLS + 1)) / COLS;
+  var COLORS = ['#f472b6', '#fb923c', '#facc15', '#4ade80', '#38bdf8', '#a78bfa'];
+
+  var paddle, ball, bricks, score, lives, level, running, paused, launched, muted = false;
+  var last = 0;
+
+  var actx = null;
+  function beep(freq, dur, type, vol) {
+    if (muted) return;
+    try {
+      if (!actx) actx = new (window.AudioContext || window.webkitAudioContext)();
+      var o = actx.createOscillator(), g = actx.createGain();
+      o.type = type || 'square'; o.frequency.value = freq; g.gain.value = vol || 0.05;
+      o.connect(g); g.connect(actx.destination);
+      var t = actx.currentTime; o.start(t);
+      g.gain.exponentialRampToValueAtTime(0.0001, t + (dur || 0.07)); o.stop(t + (dur || 0.07));
+    } catch (e) {}
+  }
+
+  function buildBricks(lv) {
+    bricks = [];
+    var rows = Math.min(4 + lv, 7);
+    for (var r = 0; r < rows; r++) for (var c = 0; c < COLS; c++) {
+      bricks.push({
+        x: PAD + c * (brickW + PAD), y: TOP + r * (BRICK_H + PAD),
+        w: brickW, h: BRICK_H, color: COLORS[r % COLORS.length],
+        hits: r < 1 ? 2 : 1                 // top row tougher
+      });
+    }
+  }
+  function resetBallPaddle() {
+    paddle = { w: 84, h: 12, x: W / 2 - 42, y: H - 28, speed: 7 };
+    var sp = 4.2 + level * 0.4;
+    ball = { x: W / 2, y: paddle.y - 8, r: 7, vx: sp * (Math.random() < 0.5 ? -1 : 1) * 0.7, vy: -sp };
+    launched = false;
+  }
+  function newGame() {
+    score = 0; lives = 3; level = 1; buildBricks(level); resetBallPaddle(); updateHud();
+  }
+  function updateHud() { scoreEl.textContent = score; livesEl.textContent = lives; lvlEl.textContent = level; }
+
+  function launch() { if (!launched) { launched = true; beep(520, 0.06, 'square', 0.05); } }
+
+  function tick() {
+    if (!launched) { ball.x = paddle.x + paddle.w / 2; ball.y = paddle.y - ball.r - 1; return; }
+    ball.x += ball.vx; ball.y += ball.vy;
+    // walls
+    if (ball.x - ball.r < 0) { ball.x = ball.r; ball.vx *= -1; beep(300, 0.04, 'square', 0.04); }
+    if (ball.x + ball.r > W) { ball.x = W - ball.r; ball.vx *= -1; beep(300, 0.04, 'square', 0.04); }
+    if (ball.y - ball.r < 0) { ball.y = ball.r; ball.vy *= -1; beep(300, 0.04, 'square', 0.04); }
+    // paddle
+    if (ball.vy > 0 && ball.y + ball.r >= paddle.y && ball.y + ball.r <= paddle.y + paddle.h + 8 &&
+        ball.x >= paddle.x - ball.r && ball.x <= paddle.x + paddle.w + ball.r) {
+      var hit = (ball.x - (paddle.x + paddle.w / 2)) / (paddle.w / 2); // -1..1
+      var speed = Math.min(9, Math.hypot(ball.vx, ball.vy) + 0.06);
+      var ang = hit * 1.05;                 // steer by contact point
+      ball.vx = speed * Math.sin(ang); ball.vy = -Math.abs(speed * Math.cos(ang));
+      ball.y = paddle.y - ball.r - 1; beep(440, 0.05, 'square', 0.05);
+    }
+    // bricks
+    for (var i = 0; i < bricks.length; i++) {
+      var b = bricks[i];
+      if (ball.x + ball.r > b.x && ball.x - ball.r < b.x + b.w && ball.y + ball.r > b.y && ball.y - ball.r < b.y + b.h) {
+        // decide bounce axis by shallowest overlap
+        var overL = ball.x + ball.r - b.x, overR = b.x + b.w - (ball.x - ball.r);
+        var overT = ball.y + ball.r - b.y, overB = b.y + b.h - (ball.y - ball.r);
+        var minX = Math.min(overL, overR), minY = Math.min(overT, overB);
+        if (minX < minY) ball.vx *= -1; else ball.vy *= -1;
+        b.hits--; score += 10; updateHud(); beep(660, 0.05, 'square', 0.05);
+        if (b.hits <= 0) { bricks.splice(i, 1); score += 5; updateHud(); }
+        break;
+      }
+    }
+    // lost ball
+    if (ball.y - ball.r > H) {
+      lives--; updateHud(); beep(160, 0.25, 'sawtooth', 0.07);
+      if (lives <= 0) { gameOver(); return; }
+      resetBallPaddle();
+    }
+    // level clear
+    if (bricks.length === 0) {
+      level++; score += 100; updateHud(); buildBricks(level); resetBallPaddle();
+      beep(880, 0.12, 'triangle', 0.07);
+      overlay('Level ' + level, 'Cleared!', 'Nice. Space or click to launch the next wave.', 'Continue');
+      running = false;
+    }
+  }
+
+  function draw() {
+    ctx.clearRect(0, 0, W, H);
+    for (var i = 0; i < bricks.length; i++) {
+      var b = bricks[i]; ctx.fillStyle = b.color; ctx.globalAlpha = b.hits > 1 ? 1 : 0.82;
+      round(b.x, b.y, b.w, b.h, 4); ctx.fill(); ctx.globalAlpha = 1;
+    }
+    ctx.fillStyle = '#e5e7eb'; round(paddle.x, paddle.y, paddle.w, paddle.h, 6); ctx.fill();
+    ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.r, 0, 7); ctx.fillStyle = '#a7f3d0'; ctx.fill();
+  }
+  function round(x, y, w, h, r) {
+    ctx.beginPath(); ctx.moveTo(x + r, y);
+    ctx.arcTo(x + w, y, x + w, y + h, r); ctx.arcTo(x + w, y + h, x, y + h, r);
+    ctx.arcTo(x, y + h, x, y, r); ctx.arcTo(x, y, x + w, y, r); ctx.closePath();
+  }
+
+  function loop(ts) {
+    requestAnimationFrame(loop);
+    if (!running || paused) { last = ts; return; }
+    if (!last) last = ts;
+    var steps = Math.min(3, Math.round((ts - last) / 16.67)) || 1; last = ts;
+    for (var s = 0; s < steps; s++) if (running) tick();
+    draw();
+  }
+
+  function overlay(tag, title, sub, btn) { ovTag.textContent = tag; ovTitle.textContent = title; ovSub.textContent = sub; playBtn.textContent = btn; ov.classList.remove('hide'); }
+  function gameOver() {
+    running = false;
+    if (score > best) { best = score; localStorage.setItem(BEST_KEY, best); bestEl.textContent = best; }
+    overlay(score >= best && score > 0 ? 'New Best!' : 'Game Over', 'Score ' + score, 'Best ' + best + '. Play again?', 'Play again');
+  }
+
+  function start() {
+    // If overlay was a level-clear pause, just resume; otherwise fresh game.
+    if (bricks && bricks.length > 0 && lives > 0 && !paused && running === false && launched === false && score > 0) {
+      running = true; ov.classList.add('hide'); last = 0; return;
+    }
+    newGame(); running = true; paused = false; last = 0; ov.classList.add('hide');
+    if (actx && actx.state === 'suspended') actx.resume();
+  }
+  function togglePause() {
+    if (!running && !paused) return;
+    paused = !paused; pauseBtn.textContent = paused ? '▶' : '⏸';
+    if (paused) overlay('Paused', 'Paused', 'Press P to resume.', 'Resume');
+    else { ov.classList.add('hide'); last = 0; }
+  }
+
+  // input
+  function movePaddleTo(px) { paddle.x = Math.max(0, Math.min(W - paddle.w, px - paddle.w / 2)); }
+  cv.addEventListener('mousemove', function (e) { if (!paddle) return; var r = cv.getBoundingClientRect(); movePaddleTo((e.clientX - r.left) * (W / r.width)); });
+  cv.addEventListener('click', function () { if (!running && !paused) start(); else launch(); });
+  cv.addEventListener('touchmove', function (e) { if (!paddle) return; var r = cv.getBoundingClientRect(); movePaddleTo((e.touches[0].clientX - r.left) * (W / r.width)); e.preventDefault(); }, { passive: false });
+  cv.addEventListener('touchstart', function () { if (!running && !paused) start(); else launch(); }, { passive: true });
+
+  var leftDown = false, rightDown = false;
+  window.addEventListener('keydown', function (e) {
+    var k = e.key.toLowerCase();
+    if (k === 'arrowleft' || k === 'a') { leftDown = true; e.preventDefault(); }
+    else if (k === 'arrowright' || k === 'd') { rightDown = true; e.preventDefault(); }
+    else if (k === ' ') { if (!running && !paused) start(); else launch(); e.preventDefault(); }
+    else if (k === 'p' || k === 'escape') togglePause();
+    else if (k === 'm') toggleMute();
+  });
+  window.addEventListener('keyup', function (e) {
+    var k = e.key.toLowerCase();
+    if (k === 'arrowleft' || k === 'a') leftDown = false;
+    if (k === 'arrowright' || k === 'd') rightDown = false;
+  });
+  // keyboard paddle drift
+  setInterval(function () {
+    if (!paddle || !running || paused) return;
+    if (leftDown) movePaddleTo(paddle.x + paddle.w / 2 - paddle.speed);
+    if (rightDown) movePaddleTo(paddle.x + paddle.w / 2 + paddle.speed);
+  }, 16);
+
+  playBtn.addEventListener('click', function () { if (paused) togglePause(); else start(); });
+  pauseBtn.addEventListener('click', togglePause);
+  function toggleMute() { muted = !muted; muteBtn.textContent = muted ? '🔈' : '🔊'; }
+  muteBtn.addEventListener('click', toggleMute);
+  window.addEventListener('blur', function () { if (running && !paused) togglePause(); });
+
+  newGame(); draw();
+  requestAnimationFrame(loop);
+})();
+</script>
+</body>
+</html>
diff --git a/games/chomp/AbramsChomp.aa b/games/chomp/AbramsChomp.aa
new file mode 100644
index 0000000..e2d9abc
--- /dev/null
+++ b/games/chomp/AbramsChomp.aa
@@ -0,0 +1,855 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Abrams Chomp</title>
+<style>
+  :root {
+    --bg:#0a0e14; --grid:#070a10; --wall:#2563eb; --wall-glow:#60a5fa;
+    --player:#fde047; --pellet:#f5d7a1; --power:#fbbf24; --ink:#e5e7eb;
+  }
+  * { box-sizing:border-box; margin:0; padding:0; }
+  html,body { height:100%; }
+  body {
+    background:radial-gradient(1200px 600px at 50% -10%, #16202e, var(--bg));
+    color:var(--ink); font:15px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
+    display:flex; flex-direction:column; align-items:center; justify-content:center;
+    min-height:100%; gap:10px; padding:12px; overscroll-behavior:none; touch-action:none;
+  }
+  h1 { font-size:14px; letter-spacing:.28em; text-transform:uppercase; color:#93c5fd; font-weight:600; }
+  .hud { display:flex; gap:18px; font-variant-numeric:tabular-nums; font-size:13px; color:#9aa4b2; }
+  .hud b { color:var(--ink); font-weight:600; }
+  #wrap { position:relative; }
+  canvas { background:var(--grid); border-radius:12px; box-shadow:0 10px 40px rgba(0,0,0,.5); display:block; }
+  .overlay {
+    position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
+    gap:10px; text-align:center; background:rgba(8,12,18,.78); border-radius:12px; backdrop-filter:blur(2px);
+  }
+  .overlay.hide { display:none; }
+  .big { font-size:22px; font-weight:700; letter-spacing:.02em; }
+  .sub { font-size:13px; color:#9aa4b2; max-width:300px; }
+  .tag { font-size:11px; color:#93c5fd; letter-spacing:.2em; text-transform:uppercase; }
+  button.play {
+    margin-top:4px; padding:10px 22px; border:0; border-radius:999px; cursor:pointer;
+    background:linear-gradient(180deg,#facc15,#eab308); color:#1a1500; font-weight:700; font-size:14px;
+  }
+  .btns { position:absolute; top:8px; right:10px; display:flex; gap:6px; z-index:5; }
+  .btns button { width:30px; height:30px; border-radius:8px; border:1px solid #2a3441; background:#141b25; color:#cbd5e1; cursor:pointer; font-size:14px; }
+  .hint { font-size:11px; color:#5b6673; }
+  /* D-pad */
+  #dpad {
+    display:grid; grid-template-columns:repeat(3,52px); grid-template-rows:repeat(3,52px);
+    gap:6px; margin-top:4px; touch-action:none;
+  }
+  #dpad button {
+    border:1px solid #223; border-radius:10px; background:#111926; color:#93c5fd;
+    font-size:20px; cursor:pointer; -webkit-user-select:none; user-select:none; touch-action:none;
+  }
+  #dpad button:active { background:#1b2740; }
+  #dpad .sp { visibility:hidden; }
+  @media (hover:hover) and (pointer:fine) { #dpad { display:none; } }
+</style>
+</head>
+<body>
+  <h1>Abrams Chomp</h1>
+  <div class="hud">
+    <span>Score <b id="score">0</b></span>
+    <span>Lives <b id="lives">3</b></span>
+    <span>Best <b id="best">0</b></span>
+    <span>Lvl <b id="level">1</b></span>
+  </div>
+  <div id="wrap">
+    <canvas id="c" width="448" height="496"></canvas>
+    <div class="btns"><button id="mute" title="Sound">&#128266;</button></div>
+    <div id="overlay" class="overlay">
+      <div class="tag">Neon Maze Chomper</div>
+      <div class="big" id="ovTitle">ABRAMS CHOMP</div>
+      <div class="sub" id="ovSub">Eat every pellet. Grab a power pellet to hunt the ghosts. Arrow keys / WASD or the D-pad.</div>
+      <button class="play" id="playBtn">PLAY</button>
+    </div>
+  </div>
+  <div id="dpad">
+    <button class="sp"></button><button data-dir="up">&#9650;</button><button class="sp"></button>
+    <button data-dir="left">&#9664;</button><button class="sp"></button><button data-dir="right">&#9654;</button>
+    <button class="sp"></button><button data-dir="down">&#9660;</button><button class="sp"></button>
+  </div>
+  <div class="hint">Arrow keys / WASD to steer &middot; P to pause</div>
+
+<script>
+(function () {
+  "use strict";
+
+  // ---- Maze layout (hand-authored ASCII) ----
+  // # wall, . pellet, o power pellet, space empty, - ghost house door, T tunnel row cell
+  // Grid is 28 wide x 31 tall (classic proportions).
+  var MAZE = [
+    "############################",
+    "#............##............#",
+    "#.####.#####.##.#####.####.#",
+    "#o####.#####.##.#####.####o#",
+    "#.####.#####.##.#####.####.#",
+    "#..........................#",
+    "#.####.##.########.##.####.#",
+    "#.####.##.########.##.####.#",
+    "#......##....##....##......#",
+    "######.##### ## #####.######",
+    "######.##### ## #####.######",
+    "######.##          ##.######",
+    "######.## ###--### ##.######",
+    "######.## #      # ##.######",
+    "T     .   #      #   .     T",
+    "######.## #      # ##.######",
+    "######.## ######## ##.######",
+    "######.##          ##.######",
+    "######.## ######## ##.######",
+    "######.## ######## ##.######",
+    "#............##............#",
+    "#.####.#####.##.#####.####.#",
+    "#.####.#####.##.#####.####.#",
+    "#o..##.......  .......##..o#",
+    "###.##.##.########.##.##.###",
+    "###.##.##.########.##.##.###",
+    "#......##....##....##......#",
+    "#.##########.##.##########.#",
+    "#.##########.##.##########.#",
+    "#..........................#",
+    "############################"
+  ];
+
+  var ROWS = MAZE.length, COLS = MAZE[0].length;
+  var TILE = 16;
+
+  var canvas = document.getElementById("c");
+  var ctx = canvas.getContext("2d");
+  canvas.width = COLS * TILE;   // 448
+  canvas.height = ROWS * TILE;  // 496
+
+  // ---- responsive scaling to fit iframe ----
+  function fit() {
+    try {
+      var wrap = document.getElementById("wrap");
+      var pad = 24;
+      var maxW = Math.max(160, (window.innerWidth || canvas.width) - pad);
+      var availH = (window.innerHeight || canvas.height) - 200; // leave room for hud/dpad
+      var maxH = Math.max(160, availH);
+      var scale = Math.min(maxW / canvas.width, maxH / canvas.height, 1.4);
+      if (!isFinite(scale) || scale <= 0) scale = 1;
+      canvas.style.width = Math.round(canvas.width * scale) + "px";
+      canvas.style.height = Math.round(canvas.height * scale) + "px";
+    } catch (e) { /* no-op */ }
+  }
+  window.addEventListener("resize", fit);
+
+  // ---- grid state ----
+  var grid = [];       // char per cell (walls/paths)
+  var pellets = [];     // 0 none, 1 pellet, 2 power
+  var pelletCount = 0;
+
+  function isWall(c, r) {
+    if (r < 0 || r >= ROWS) return true;
+    if (c < 0 || c >= COLS) return false; // horizontal tunnels are open
+    return grid[r][c] === "#";
+  }
+
+  function buildGrid() {
+    grid = [];
+    pellets = [];
+    pelletCount = 0;
+    for (var r = 0; r < ROWS; r++) {
+      var gr = [], pr = [];
+      var line = MAZE[r];
+      for (var c = 0; c < COLS; c++) {
+        var ch = line[c] || " ";
+        var pel = 0;
+        if (ch === ".") { pel = 1; pelletCount++; }
+        else if (ch === "o") { pel = 2; pelletCount++; }
+        gr.push(ch === "#" ? "#" : (ch === "-" ? "-" : " "));
+        pr.push(pel);
+      }
+      grid.push(gr);
+      pellets.push(pr);
+    }
+  }
+
+  // ---- entities ----
+  var DIRS = {
+    up:    { x: 0, y: -1 },
+    down:  { x: 0, y: 1 },
+    left:  { x: -1, y: 0 },
+    right: { x: 1, y: 0 },
+    none:  { x: 0, y: 0 }
+  };
+
+  var player = null;
+  var ghosts = [];
+  var GHOST_COLORS = ["#ef4444", "#f9a8d4", "#22d3ee", "#fb923c"];
+  var GHOST_NAMES = ["blinky", "pinky", "inky", "clyde"];
+
+  function makePlayer() {
+    return {
+      c: 13, r: 23,
+      px: 13 * TILE, py: 23 * TILE,
+      dir: "left", next: "left",
+      speed: 96,   // px / second
+      mouth: 0
+    };
+  }
+
+  // ghost home center (in tiles) and spawn positions inside the house
+  var HOME = { c: 13, r: 14 };
+  var GHOST_SPAWNS = [
+    { c: 13, r: 11 }, // starts outside on top
+    { c: 13, r: 14 },
+    { c: 12, r: 14 },
+    { c: 14, r: 14 }
+  ];
+
+  function makeGhost(i) {
+    var sp = GHOST_SPAWNS[i];
+    return {
+      name: GHOST_NAMES[i],
+      color: GHOST_COLORS[i],
+      c: sp.c, r: sp.r,
+      px: sp.c * TILE, py: sp.r * TILE,
+      dir: (i === 0 ? "left" : "up"),
+      speed: 84 + (level - 1) * 4,   // px / second, ramps with level
+      state: "scatter",     // scatter | chase | frightened | eaten
+      inHouse: i !== 0,
+      releaseAt: i * 2.2,   // seconds staggered release
+      scatterTarget: [
+        { c: COLS - 2, r: 0 }, { c: 1, r: 0 },
+        { c: COLS - 2, r: ROWS - 1 }, { c: 1, r: ROWS - 1 }
+      ][i]
+    };
+  }
+
+  // ---- game state ----
+  var state = "menu"; // menu | play | paused | dead | over | win
+  var score = 0, lives = 3, level = 1, best = 0;
+  var frightTimer = 0;    // seconds remaining of frightened mode
+  var ghostEatChain = 0;  // for 200/400/800/1600 scoring
+  var modeTimer = 0;      // scatter/chase alternation
+  var modePhase = 0;
+  var levelElapsed = 0;   // for staggered ghost release
+  var deathAnim = 0;
+  var readyTimer = 0;
+
+  var BEST_KEY = "abrams-chomp-best";
+  try {
+    var stored = localStorage.getItem(BEST_KEY);
+    if (stored != null && !isNaN(parseInt(stored, 10))) best = parseInt(stored, 10);
+  } catch (e) { best = 0; }
+
+  // scatter/chase schedule (seconds): scatter, chase, scatter, chase...
+  var MODE_SCHEDULE = [7, 20, 7, 20, 5, 20, 5, 99999];
+
+  // ---- audio (lazy, must never throw) ----
+  var audioCtx = null, muted = false;
+  function ensureAudio() {
+    if (audioCtx) return;
+    try {
+      var AC = window.AudioContext || window.webkitAudioContext;
+      if (AC) audioCtx = new AC();
+    } catch (e) { audioCtx = null; }
+  }
+  function blip(freq, dur, type, vol) {
+    if (muted || !audioCtx) return;
+    try {
+      var o = audioCtx.createOscillator();
+      var g = audioCtx.createGain();
+      o.type = type || "square";
+      o.frequency.value = freq;
+      g.gain.value = vol || 0.05;
+      o.connect(g); g.connect(audioCtx.destination);
+      var t = audioCtx.currentTime;
+      g.gain.setValueAtTime(g.gain.value, t);
+      g.gain.exponentialRampToValueAtTime(0.0001, t + (dur || 0.08));
+      o.start(t); o.stop(t + (dur || 0.08));
+    } catch (e) { /* ignore */ }
+  }
+
+  // ---- helpers ----
+  // c/r are the entity's CURRENT tile (the tile its top-left snaps to at a center).
+  // px/py are the top-left pixel; the entity is "centered" when px==c*TILE & py==r*TILE.
+  function canMove(c, r, dir, isGhost, allowDoor) {
+    var d = DIRS[dir];
+    var nc = c + d.x, nr = r + d.y;
+    if (nr < 0 || nr >= ROWS) return false;
+    // tunnel columns
+    if (nc < 0 || nc >= COLS) return true;
+    var cell = grid[nr][nc];
+    if (cell === "#") return false;
+    if (cell === "-") return !!allowDoor; // door only for ghosts entering/leaving
+    return true;
+  }
+
+  function opposite(dir) {
+    return { up: "down", down: "up", left: "right", right: "left", none: "none" }[dir];
+  }
+
+  // ---- input ----
+  var keymap = {
+    ArrowUp: "up", ArrowDown: "down", ArrowLeft: "left", ArrowRight: "right",
+    w: "up", s: "down", a: "left", d: "right",
+    W: "up", S: "down", A: "left", D: "right"
+  };
+  window.addEventListener("keydown", function (e) {
+    var k = e.key;
+    if (k === " " || k === "ArrowUp" || k === "ArrowDown" || k === "ArrowLeft" || k === "ArrowRight") {
+      e.preventDefault();
+    }
+    if (k === "p" || k === "P") { togglePause(); return; }
+    if ((k === "Enter" || k === " ") && (state === "menu" || state === "over" || state === "win")) {
+      startGame(); return;
+    }
+    var dir = keymap[k];
+    if (dir && player) { player.next = dir; ensureAudio(); }
+  }, { passive: false });
+
+  function setDir(dir) {
+    if (player && (state === "play")) { player.next = dir; }
+    ensureAudio();
+  }
+  var dpad = document.getElementById("dpad");
+  if (dpad) {
+    dpad.querySelectorAll("button[data-dir]").forEach(function (b) {
+      var dir = b.getAttribute("data-dir");
+      b.addEventListener("touchstart", function (e) { e.preventDefault(); setDir(dir); }, { passive: false });
+      b.addEventListener("mousedown", function (e) { e.preventDefault(); setDir(dir); });
+    });
+  }
+
+  document.getElementById("mute").addEventListener("click", function () {
+    muted = !muted;
+    this.innerHTML = muted ? "&#128263;" : "&#128266;";
+    ensureAudio();
+  });
+
+  document.getElementById("playBtn").addEventListener("click", function () {
+    ensureAudio(); startGame();
+  });
+
+  function togglePause() {
+    if (state === "play") { state = "paused"; showOverlay("PAUSED", "Press P to resume.", false); }
+    else if (state === "paused") { hideOverlay(); state = "play"; }
+  }
+
+  // ---- overlay ----
+  var overlay = document.getElementById("overlay");
+  function showOverlay(title, sub, showBtn) {
+    document.getElementById("ovTitle").textContent = title;
+    document.getElementById("ovSub").textContent = sub;
+    document.getElementById("playBtn").style.display = showBtn ? "" : "none";
+    overlay.classList.remove("hide");
+  }
+  function hideOverlay() { overlay.classList.add("hide"); }
+
+  // ---- lifecycle ----
+  function resetPositions() {
+    player = makePlayer();
+    ghosts = [makeGhost(0), makeGhost(1), makeGhost(2), makeGhost(3)];
+    frightTimer = 0; ghostEatChain = 0;
+    modeTimer = 0; modePhase = 0; levelElapsed = 0;
+    readyTimer = 1.1;
+  }
+
+  function newLevel() {
+    buildGrid();
+    resetPositions();
+  }
+
+  function startGame() {
+    score = 0; lives = 3; level = 1;
+    buildGrid();
+    resetPositions();
+    state = "play";
+    hideOverlay();
+    updateHUD();
+  }
+
+  function loseLife() {
+    lives--;
+    updateHUD();
+    if (lives <= 0) {
+      state = "over";
+      if (score > best) {
+        best = score;
+        try { localStorage.setItem(BEST_KEY, String(best)); } catch (e) {}
+      }
+      updateHUD();
+      showOverlay("GAME OVER", "Score " + score + "  ·  Best " + best + ". Press PLAY to try again.", true);
+    } else {
+      resetPositions();
+      state = "play";
+    }
+  }
+
+  function winLevel() {
+    level++;
+    if (score > best) {
+      best = score;
+      try { localStorage.setItem(BEST_KEY, String(best)); } catch (e) {}
+    }
+    updateHUD();
+    newLevel();
+    state = "play";
+  }
+
+  function updateHUD() {
+    document.getElementById("score").textContent = score;
+    document.getElementById("lives").textContent = lives;
+    document.getElementById("best").textContent = best;
+    document.getElementById("level").textContent = level;
+  }
+
+  // ---- movement logic ----
+  // Move an entity `dist` pixels along its direction, snapping to tile centers so it
+  // can only turn / re-decide at a center, and never overshoots into a wall.
+  function moveEntity(ent, isGhost, dt) {
+    var sp = ent.speed;
+    if (isGhost && ent.state === "frightened") sp *= 0.62;
+    if (isGhost && ent.state === "eaten") sp *= 2.0;
+
+    // speed is in pixels/second; clamp dt so a stall can't teleport across the maze
+    var remaining = sp * Math.min(dt, 0.05);
+    var guard = 0;
+    while (remaining > 0.0001 && guard++ < 20) {
+      var atCenter = (ent.px === ent.c * TILE) && (ent.py === ent.r * TILE);
+
+      if (atCenter) {
+        // Decision point: choose direction.
+        if (!isGhost) {
+          if (player.next && canMove(ent.c, ent.r, player.next, false, false)) {
+            ent.dir = player.next;
+          }
+          if (!canMove(ent.c, ent.r, ent.dir, false, false)) {
+            ent.dir = "none";
+          }
+        } else {
+          chooseGhostDir(ent);
+        }
+      }
+
+      if (ent.dir === "none") break;
+
+      var d = DIRS[ent.dir];
+      // How far until the next tile boundary in this direction:
+      var targetC = ent.c + d.x, targetR = ent.r + d.y;
+
+      // If currently at center, verify we can enter the next tile.
+      if (atCenter) {
+        var allowDoor = isGhost && (ent.state === "eaten" || ent.inHouse);
+        if (!canMove(ent.c, ent.r, ent.dir, isGhost, allowDoor)) {
+          ent.dir = "none";
+          break;
+        }
+      }
+
+      var targetPx = targetC * TILE, targetPy = targetR * TILE;
+      var dxToTarget = targetPx - ent.px, dyToTarget = targetPy - ent.py;
+      var distToCenter = Math.abs(dxToTarget) + Math.abs(dyToTarget); // straight-line along one axis
+
+      if (distToCenter <= remaining) {
+        // arrive exactly at the next tile center
+        ent.px = targetPx; ent.py = targetPy;
+        ent.c = targetC; ent.r = targetR;
+        remaining -= distToCenter;
+        tunnelWrap(ent);
+      } else {
+        ent.px += d.x * remaining;
+        ent.py += d.y * remaining;
+        remaining = 0;
+      }
+    }
+  }
+
+  function tunnelWrap(ent) {
+    var w = COLS * TILE;
+    if (ent.c < 0) { ent.c = COLS - 1; ent.px = ent.c * TILE; }
+    else if (ent.c >= COLS) { ent.c = 0; ent.px = ent.c * TILE; }
+  }
+
+  function ghostTarget(g) {
+    if (g.state === "eaten") return { c: HOME.c, r: HOME.r - 3 }; // return to house entrance
+    if (g.state === "frightened") return null; // random
+    if (g.state === "scatter") return g.scatterTarget;
+
+    // chase — per-ghost AI
+    if (g.name === "blinky") {
+      return { c: player.c, r: player.r };
+    } else if (g.name === "pinky") {
+      var d = DIRS[player.dir];
+      return { c: player.c + d.x * 4, r: player.r + d.y * 4 };
+    } else if (g.name === "inky") {
+      var blinky = ghosts[0];
+      var d2 = DIRS[player.dir];
+      var ax = player.c + d2.x * 2, ay = player.r + d2.y * 2;
+      return { c: ax + (ax - blinky.c), r: ay + (ay - blinky.r) };
+    } else { // clyde
+      var dist = Math.abs(g.c - player.c) + Math.abs(g.r - player.r);
+      if (dist > 8) return { c: player.c, r: player.r };
+      return g.scatterTarget;
+    }
+  }
+
+  function chooseGhostDir(g) {
+    g.px = g.c * TILE; g.py = g.r * TILE;
+
+    // handle leaving / entering house
+    if (g.inHouse) {
+      // bob toward door and out
+      if (g.releaseAt <= levelElapsed) {
+        // move up out of the house through the door
+        var above = "up";
+        if (canMove(g.c, g.r, above, true, true)) {
+          // steer toward door column (13/14)
+          if (g.c < 13 && canMove(g.c, g.r, "right", true, true)) { g.dir = "right"; return; }
+          if (g.c > 14 && canMove(g.c, g.r, "left", true, true)) { g.dir = "left"; return; }
+          g.dir = "up";
+          if (g.r <= 11) { g.inHouse = false; }
+          return;
+        }
+      }
+      // idle bob
+      g.dir = (g.r <= 13) ? "down" : "up";
+      return;
+    }
+
+    if (g.state === "eaten" && g.c >= 12 && g.c <= 15 && g.r >= 11 && g.r <= 12) {
+      // reached house entrance: revive
+      g.state = (modePhase % 2 === 0) ? "scatter" : "chase";
+      g.inHouse = false;
+      g.speed = 84 + (level - 1) * 4;
+    }
+
+    var target = ghostTarget(g);
+    var options = ["up", "left", "down", "right"];
+    var best = null, bestDist = Infinity;
+    var back = opposite(g.dir);
+
+    // frightened: pick a random valid non-reverse direction
+    if (g.state === "frightened") {
+      var valid = [];
+      for (var i = 0; i < options.length; i++) {
+        var dir = options[i];
+        if (dir === back) continue;
+        if (canMove(g.c, g.r, dir, true, false)) valid.push(dir);
+      }
+      if (valid.length === 0) {
+        if (canMove(g.c, g.r, back, true, false)) g.dir = back;
+      } else {
+        g.dir = valid[(Math.random() * valid.length) | 0];
+      }
+      return;
+    }
+
+    for (var j = 0; j < options.length; j++) {
+      var dr = options[j];
+      if (dr === back) continue;
+      var allowDoor = (g.state === "eaten");
+      if (!canMove(g.c, g.r, dr, true, allowDoor)) continue;
+      var nd = DIRS[dr];
+      var nc = g.c + nd.x, nr = g.r + nd.y;
+      var dx = nc - target.c, dy = nr - target.r;
+      var dist = dx * dx + dy * dy;
+      // priority order up>left>down>right resolves ties naturally by iteration
+      if (dist < bestDist) { bestDist = dist; best = dr; }
+    }
+    if (best) g.dir = best;
+    else if (canMove(g.c, g.r, back, true, g.state === "eaten")) g.dir = back;
+  }
+
+  // ---- update ----
+  function update(dt) {
+    if (readyTimer > 0) {
+      readyTimer -= dt;
+      player.mouth += dt * 8;
+      return;
+    }
+
+    levelElapsed += dt;
+
+    // scatter/chase phase machine (only affects non-frightened, non-eaten)
+    if (frightTimer <= 0) {
+      modeTimer += dt;
+      if (modeTimer >= MODE_SCHEDULE[Math.min(modePhase, MODE_SCHEDULE.length - 1)]) {
+        modeTimer = 0; modePhase++;
+        var newMode = (modePhase % 2 === 0) ? "scatter" : "chase";
+        for (var i = 0; i < ghosts.length; i++) {
+          if (ghosts[i].state === "scatter" || ghosts[i].state === "chase") {
+            ghosts[i].state = newMode;
+            // reverse on mode switch (classic behavior)
+            ghosts[i].dir = opposite(ghosts[i].dir);
+          }
+        }
+      }
+    }
+
+    // fright timer
+    if (frightTimer > 0) {
+      frightTimer -= dt;
+      if (frightTimer <= 0) {
+        frightTimer = 0;
+        for (var g = 0; g < ghosts.length; g++) {
+          if (ghosts[g].state === "frightened") {
+            ghosts[g].state = (modePhase % 2 === 0) ? "scatter" : "chase";
+          }
+        }
+      }
+    }
+
+    // player move
+    moveEntity(player, false, dt);
+    player.mouth += dt * 10;
+
+    // eat pellet
+    if (player.c >= 0 && player.c < COLS && player.r >= 0 && player.r < ROWS) {
+      var p = pellets[player.r][player.c];
+      if (p === 1) {
+        pellets[player.r][player.c] = 0; pelletCount--; score += 10;
+        updateHUD(); blip(520, 0.04, "square", 0.03);
+      } else if (p === 2) {
+        pellets[player.r][player.c] = 0; pelletCount--; score += 50;
+        updateHUD();
+        // power!
+        frightTimer = Math.max(2.5, 7 - (level - 1) * 0.5);
+        ghostEatChain = 0;
+        for (var k = 0; k < ghosts.length; k++) {
+          if (ghosts[k].state === "scatter" || ghosts[k].state === "chase") {
+            ghosts[k].state = "frightened";
+            ghosts[k].dir = opposite(ghosts[k].dir);
+          }
+        }
+        blip(180, 0.2, "sawtooth", 0.05);
+      }
+    }
+
+    // ghosts move + collisions
+    for (var gi = 0; gi < ghosts.length; gi++) {
+      var gh = ghosts[gi];
+      moveEntity(gh, true, dt);
+      // collision (tile-level, tolerant)
+      var close = Math.abs(gh.px - player.px) < TILE * 0.7 && Math.abs(gh.py - player.py) < TILE * 0.7;
+      if (close) {
+        if (gh.state === "frightened") {
+          ghostEatChain++;
+          var pts = 200 * Math.pow(2, Math.min(ghostEatChain - 1, 3));
+          score += pts; updateHUD();
+          gh.state = "eaten"; gh.inHouse = false;
+          blip(880, 0.12, "square", 0.06);
+        } else if (gh.state !== "eaten") {
+          // player dies
+          blip(120, 0.5, "sawtooth", 0.06);
+          state = "dead"; deathAnim = 0;
+          return;
+        }
+      }
+    }
+
+    // win check
+    if (pelletCount <= 0) {
+      state = "win"; blip(660, 0.3, "triangle", 0.05);
+    }
+  }
+
+  function updateDeath(dt) {
+    deathAnim += dt;
+    if (deathAnim > 1.1) { loseLife(); }
+  }
+
+  function updateWin(dt) {
+    deathAnim += dt;
+    if (deathAnim > 0.9) { deathAnim = 0; winLevel(); }
+  }
+
+  // ---- draw ----
+  function draw() {
+    ctx.fillStyle = "#070a10";
+    ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+    // walls
+    ctx.lineWidth = 2;
+    for (var r = 0; r < ROWS; r++) {
+      for (var c = 0; c < COLS; c++) {
+        var cell = grid[r][c];
+        if (cell === "#") {
+          drawWall(c, r);
+        } else if (cell === "-") {
+          ctx.fillStyle = "#f9a8d4";
+          ctx.fillRect(c * TILE + 2, r * TILE + TILE / 2 - 1, TILE - 4, 2);
+        }
+      }
+    }
+
+    // pellets
+    for (var r2 = 0; r2 < ROWS; r2++) {
+      for (var c2 = 0; c2 < COLS; c2++) {
+        var pp = pellets[r2][c2];
+        if (pp === 1) {
+          ctx.fillStyle = "#f5d7a1";
+          ctx.beginPath();
+          ctx.arc(c2 * TILE + TILE / 2, r2 * TILE + TILE / 2, 2, 0, Math.PI * 2);
+          ctx.fill();
+        } else if (pp === 2) {
+          var pulse = 3 + Math.sin(Date.now() / 180) * 1.6;
+          ctx.fillStyle = "#fbbf24";
+          ctx.shadowColor = "#fbbf24"; ctx.shadowBlur = 8;
+          ctx.beginPath();
+          ctx.arc(c2 * TILE + TILE / 2, r2 * TILE + TILE / 2, pulse, 0, Math.PI * 2);
+          ctx.fill();
+          ctx.shadowBlur = 0;
+        }
+      }
+    }
+
+    // ghosts
+    for (var gi = 0; gi < ghosts.length; gi++) drawGhost(ghosts[gi]);
+
+    // player
+    drawPlayer();
+
+    // ready text
+    if (readyTimer > 0 && state === "play") {
+      ctx.fillStyle = "#fde047";
+      ctx.font = "bold 16px -apple-system, sans-serif";
+      ctx.textAlign = "center";
+      ctx.fillText("READY!", canvas.width / 2, 17 * TILE + 4);
+    }
+  }
+
+  function drawWall(c, r) {
+    var x = c * TILE, y = r * TILE;
+    ctx.fillStyle = "#0e2a5e";
+    // inset rounded block with neon border
+    ctx.strokeStyle = "#3b82f6";
+    ctx.shadowColor = "#60a5fa"; ctx.shadowBlur = 4;
+    ctx.strokeRect(x + 2.5, y + 2.5, TILE - 5, TILE - 5);
+    ctx.shadowBlur = 0;
+  }
+
+  function drawPlayer() {
+    var cx = player.px + TILE / 2, cy = player.py + TILE / 2;
+    var rad = TILE / 2 - 1.5;
+    var m = 0;
+    if (state === "dead") {
+      // shrink/fade mouth open
+      m = Math.min(Math.PI, deathAnim * Math.PI * 1.6);
+    } else {
+      m = (Math.abs(Math.sin(player.mouth)) * 0.28 + 0.06) * Math.PI;
+    }
+    var ang = { up: -Math.PI / 2, down: Math.PI / 2, left: Math.PI, right: 0, none: 0 }[player.dir] || 0;
+
+    ctx.save();
+    ctx.translate(cx, cy);
+    ctx.rotate(ang);
+    ctx.fillStyle = "#fde047";
+    ctx.shadowColor = "#fde047"; ctx.shadowBlur = 8;
+    ctx.beginPath();
+    ctx.moveTo(0, 0);
+    ctx.arc(0, 0, rad, m, Math.PI * 2 - m);
+    ctx.closePath();
+    ctx.fill();
+    ctx.shadowBlur = 0;
+    ctx.restore();
+  }
+
+  function drawGhost(g) {
+    var x = g.px, y = g.py;
+    var cx = x + TILE / 2, cy = y + TILE / 2;
+    var rad = TILE / 2 - 1.5;
+    var body;
+    var eyesVisible = true;
+
+    if (g.state === "eaten") {
+      body = null; // only eyes
+    } else if (g.state === "frightened") {
+      var blink = frightTimer < 2 && (Math.floor(frightTimer * 6) % 2 === 0);
+      body = blink ? "#e5e7eb" : "#1e3a8a";
+      eyesVisible = false;
+    } else {
+      body = g.color;
+    }
+
+    if (body) {
+      ctx.fillStyle = body;
+      ctx.shadowColor = body; ctx.shadowBlur = 6;
+      ctx.beginPath();
+      ctx.arc(cx, cy - 1, rad, Math.PI, 0);
+      ctx.lineTo(cx + rad, cy + rad - 1);
+      // wavy skirt
+      var feet = 3, step = (rad * 2) / feet;
+      for (var f = 0; f < feet; f++) {
+        var fx = cx + rad - step * f;
+        ctx.lineTo(fx - step / 2, cy + rad - 4);
+        ctx.lineTo(fx - step, cy + rad - 1);
+      }
+      ctx.closePath();
+      ctx.fill();
+      ctx.shadowBlur = 0;
+    }
+
+    // eyes
+    if (g.state === "frightened") {
+      // scared face
+      ctx.fillStyle = "#fde047";
+      ctx.fillRect(cx - 4, cy - 2, 2, 2);
+      ctx.fillRect(cx + 2, cy - 2, 2, 2);
+      ctx.strokeStyle = "#fde047"; ctx.lineWidth = 1;
+      ctx.beginPath();
+      ctx.moveTo(cx - 4, cy + 4);
+      ctx.lineTo(cx - 1, cy + 2);
+      ctx.lineTo(cx + 1, cy + 4);
+      ctx.lineTo(cx + 4, cy + 2);
+      ctx.stroke();
+    } else {
+      var d = DIRS[g.dir];
+      ctx.fillStyle = "#ffffff";
+      ctx.beginPath(); ctx.arc(cx - 3, cy - 1, 2.4, 0, Math.PI * 2); ctx.fill();
+      ctx.beginPath(); ctx.arc(cx + 3, cy - 1, 2.4, 0, Math.PI * 2); ctx.fill();
+      ctx.fillStyle = "#1e3a8a";
+      ctx.beginPath(); ctx.arc(cx - 3 + d.x * 1.2, cy - 1 + d.y * 1.2, 1.2, 0, Math.PI * 2); ctx.fill();
+      ctx.beginPath(); ctx.arc(cx + 3 + d.x * 1.2, cy - 1 + d.y * 1.2, 1.2, 0, Math.PI * 2); ctx.fill();
+    }
+  }
+
+  // ---- main loop ----
+  var last = 0;
+  function loop(ts) {
+    try {
+      if (!last) last = ts;
+      var dt = Math.min(0.05, (ts - last) / 1000);
+      last = ts;
+
+      if (state === "play") update(dt);
+      else if (state === "dead") updateDeath(dt);
+      else if (state === "win") updateWin(dt);
+
+      if (grid.length) draw();
+    } catch (e) {
+      // keep the loop alive; never let the iframe throw
+    }
+    requestAnimationFrame(loop);
+  }
+
+  // ---- boot ----
+  function boot() {
+    buildGrid();
+    resetPositions();
+    fit();
+    updateHUD();
+    state = "menu";
+    showOverlay("ABRAMS CHOMP",
+      "Eat every pellet. Grab a power pellet to hunt the ghosts. Arrow keys / WASD or the D-pad.", true);
+    requestAnimationFrame(loop);
+  }
+
+  if (document.readyState === "loading") {
+    document.addEventListener("DOMContentLoaded", boot);
+  } else {
+    boot();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/connect-four/AbramsConnect4.aa b/games/connect-four/AbramsConnect4.aa
new file mode 100644
index 0000000..091370a
--- /dev/null
+++ b/games/connect-four/AbramsConnect4.aa
@@ -0,0 +1,720 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<title>Abrams Connect 4</title>
+<style>
+  :root{
+    --bg0:#070912;
+    --bg1:#0d1226;
+    --board:#0b1030;
+    --board-edge:#1b2a6b;
+    --cell:#050814;
+    --p1:#ff2d78;      /* neon pink */
+    --p1b:#ff8fc0;
+    --p2:#22e0ff;      /* neon cyan */
+    --p2b:#a9f4ff;
+    --ink:#eaf0ff;
+    --muted:#8b96c4;
+    --line:#2a3670;
+    --win:#ffe14d;
+    --accent:#8a6bff;
+  }
+  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
+  html,body{margin:0;height:100%;}
+  body{
+    background:
+      radial-gradient(1200px 700px at 15% -10%, #16205a55, transparent 60%),
+      radial-gradient(1000px 700px at 110% 120%, #4a1e6b55, transparent 55%),
+      linear-gradient(160deg,var(--bg1),var(--bg0));
+    color:var(--ink);
+    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
+    display:flex;flex-direction:column;align-items:center;
+    min-height:100%;overflow:hidden;
+    user-select:none;
+  }
+  .wrap{
+    width:100%;max-width:640px;height:100dvh;
+    display:flex;flex-direction:column;
+    padding:10px clamp(8px,3vw,18px);
+    gap:10px;
+  }
+  header{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;}
+  .title{
+    font-weight:800;letter-spacing:.5px;font-size:clamp(18px,5vw,26px);
+    background:linear-gradient(90deg,var(--p1),var(--accent),var(--p2));
+    -webkit-background-clip:text;background-clip:text;color:transparent;
+    text-shadow:0 0 24px #8a6bff33;
+    display:flex;align-items:center;gap:8px;
+  }
+  .title .dot{width:12px;height:12px;border-radius:50%;background:var(--p1);box-shadow:0 0 12px var(--p1);}
+  .controls{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
+  select,button{
+    font:inherit;color:var(--ink);
+    background:linear-gradient(180deg,#141c40,#0c1330);
+    border:1px solid var(--line);border-radius:10px;
+    padding:8px 10px;cursor:pointer;transition:.15s;
+    font-size:13px;
+  }
+  button:hover,select:hover{border-color:var(--accent);box-shadow:0 0 0 1px #8a6bff44;}
+  button:active{transform:translateY(1px);}
+  .btn-primary{background:linear-gradient(180deg,#6d54ff,#4b32d6);border-color:#7a63ff;font-weight:700;}
+  .iconbtn{padding:8px 11px;}
+
+  .scorebar{
+    display:flex;gap:8px;align-items:stretch;justify-content:center;
+  }
+  .score{
+    flex:1;max-width:190px;
+    display:flex;align-items:center;gap:10px;
+    background:linear-gradient(180deg,#0f1638,#0a1029);
+    border:1px solid var(--line);border-radius:12px;
+    padding:8px 12px;position:relative;overflow:hidden;
+  }
+  .score.active{border-color:currentColor;box-shadow:0 0 18px -4px currentColor, inset 0 0 22px -12px currentColor;}
+  .score.p1{color:var(--p1);}
+  .score.p2{color:var(--p2);}
+  .score .chip{
+    width:26px;height:26px;border-radius:50%;flex:0 0 auto;
+    background:radial-gradient(circle at 35% 30%,#fff8,currentColor 60%);
+    box-shadow:0 0 12px currentColor;
+  }
+  .score .meta{display:flex;flex-direction:column;line-height:1.15;}
+  .score .name{font-size:12px;color:var(--muted);}
+  .score .val{font-size:20px;font-weight:800;color:var(--ink);}
+
+  .status{
+    text-align:center;font-size:14px;min-height:20px;color:var(--muted);
+    font-weight:600;letter-spacing:.3px;
+  }
+  .status b.p1{color:var(--p1);} .status b.p2{color:var(--p2);}
+
+  .boardwrap{flex:1;display:flex;align-items:center;justify-content:center;min-height:0;}
+  canvas{
+    display:block;width:100%;height:100%;
+    touch-action:none;border-radius:16px;
+    cursor:pointer;
+  }
+  footer{
+    text-align:center;font-size:11px;color:#5b6699;padding-bottom:4px;
+  }
+  .thinking{color:var(--accent);}
+  @media (max-width:420px){
+    .score .val{font-size:18px;}
+  }
+</style>
+</head>
+<body>
+<div class="wrap">
+  <header>
+    <div class="title"><span class="dot"></span>Abrams Connect 4</div>
+    <div class="controls">
+      <select id="mode" title="Game mode">
+        <option value="ai">vs Computer</option>
+        <option value="2p">2 Players</option>
+      </select>
+      <select id="diff" title="Difficulty">
+        <option value="1">Easy</option>
+        <option value="3">Medium</option>
+        <option value="5" selected>Hard</option>
+        <option value="7">Expert</option>
+      </select>
+      <button id="mute" class="iconbtn" title="Toggle sound">🔊</button>
+      <button id="newgame" class="btn-primary">New Game</button>
+    </div>
+  </header>
+
+  <div class="scorebar">
+    <div class="score p1 active" id="score1">
+      <span class="chip"></span>
+      <span class="meta"><span class="name" id="name1">You</span><span class="val" id="val1">0</span></span>
+    </div>
+    <div class="score p2" id="score2">
+      <span class="chip"></span>
+      <span class="meta"><span class="name" id="name2">Computer</span><span class="val" id="val2">0</span></span>
+    </div>
+  </div>
+
+  <div class="status" id="status">Your turn — drop a disc</div>
+
+  <div class="boardwrap">
+    <canvas id="board"></canvas>
+  </div>
+
+  <footer>Connect four in a row — horizontal, vertical, or diagonal · Pure vanilla JS, zero dependencies.</footer>
+</div>
+
+<script>
+(() => {
+  "use strict";
+
+  // ---------- Constants ----------
+  const COLS = 7, ROWS = 6, NEED = 4;
+  const EMPTY = 0, P1 = 1, P2 = 2;
+
+  // ---------- DOM ----------
+  const canvas = document.getElementById('board');
+  const ctx = canvas.getContext('2d');
+  const $ = id => document.getElementById(id);
+  const modeSel = $('mode'), diffSel = $('diff'), muteBtn = $('mute');
+  const statusEl = $('status');
+  const val1 = $('val1'), val2 = $('val2'), name1 = $('name1'), name2 = $('name2');
+  const score1El = $('score1'), score2El = $('score2');
+
+  // ---------- State ----------
+  let board = [];            // board[r][c], r=0 is TOP
+  let current = P1;
+  let scores = { 1:0, 2:0 };
+  let gameOver = false;
+  let winLine = null;        // array of [r,c]
+  let winPlayer = 0;
+  let aiThinking = false;
+  let hoverCol = -1;
+  let muted = false;
+  let animating = false;
+
+  // Animated / falling discs
+  const discs = [];  // {r,c,player,y (px), targetY, vy, settled}
+  let dropAnim = null;
+
+  // Layout (recomputed on resize)
+  let L = { size: 0, pad: 0, cell: 0, radius: 0, boardX: 0, boardY: 0, boardW: 0, boardH: 0, top: 0 };
+
+  function newBoard() {
+    board = Array.from({length: ROWS}, () => new Array(COLS).fill(EMPTY));
+  }
+
+  // ---------- Audio (procedural, optional) ----------
+  let audioCtx = null;
+  function ac() {
+    if (muted) return null;
+    if (!audioCtx) {
+      try { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); }
+      catch (e) { return null; }
+    }
+    if (audioCtx.state === 'suspended') audioCtx.resume();
+    return audioCtx;
+  }
+  function tone(freq, dur, type = 'sine', gain = 0.12, slideTo = null) {
+    const a = ac(); if (!a) return;
+    const o = a.createOscillator(), g = a.createGain();
+    o.type = type; o.frequency.value = freq;
+    if (slideTo) o.frequency.exponentialRampToValueAtTime(slideTo, a.currentTime + dur);
+    g.gain.setValueAtTime(0, a.currentTime);
+    g.gain.linearRampToValueAtTime(gain, a.currentTime + 0.008);
+    g.gain.exponentialRampToValueAtTime(0.0001, a.currentTime + dur);
+    o.connect(g); g.connect(a.destination);
+    o.start(); o.stop(a.currentTime + dur + 0.02);
+  }
+  const sfx = {
+    drop(){ tone(220, 0.14, 'triangle', 0.13, 140); },
+    land(){ tone(120, 0.10, 'sine', 0.16); tone(180, 0.06, 'square', 0.05); },
+    hover(){ tone(660, 0.03, 'sine', 0.04); },
+    win(){ [523,659,784,1046].forEach((f,i)=>setTimeout(()=>tone(f,0.22,'triangle',0.14),i*110)); },
+    draw(){ tone(300,0.2,'sine',0.1,180); },
+    click(){ tone(440,0.04,'square',0.05); }
+  };
+
+  // ---------- Layout ----------
+  function resize() {
+    const wrap = canvas.parentElement;
+    const availW = wrap.clientWidth;
+    const availH = wrap.clientHeight;
+    // board aspect: COLS wide, ROWS+~1 (drop lane) tall
+    const laneRows = ROWS + 1;
+    const targetRatio = COLS / laneRows;
+    let w = availW, h = w / targetRatio;
+    if (h > availH) { h = availH; w = h * targetRatio; }
+    const dpr = Math.min(window.devicePixelRatio || 1, 2.5);
+    canvas.style.width = w + 'px';
+    canvas.style.height = h + 'px';
+    canvas.width = Math.round(w * dpr);
+    canvas.height = Math.round(h * dpr);
+    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
+
+    L.cell = w / COLS;
+    L.top = L.cell;                 // drop lane height (one cell)
+    L.boardX = 0;
+    L.boardY = L.top;
+    L.boardW = w;
+    L.boardH = L.cell * ROWS;
+    L.radius = L.cell * 0.40;
+    L.w = w; L.h = h;
+    // sync any settled disc pixel positions
+    for (const d of discs) if (d.settled) d.y = cellCenterY(d.r);
+    draw();
+  }
+
+  function cellCenterX(c){ return L.cell * c + L.cell/2; }
+  function cellCenterY(r){ return L.top + L.cell * r + L.cell/2; }
+
+  // ---------- Drawing ----------
+  function roundRect(x,y,w,h,r){
+    ctx.beginPath();
+    ctx.moveTo(x+r,y);
+    ctx.arcTo(x+w,y,x+w,y+h,r);
+    ctx.arcTo(x+w,y+h,x,y+h,r);
+    ctx.arcTo(x,y+h,x,y,r);
+    ctx.arcTo(x,y,x+w,y,r);
+    ctx.closePath();
+  }
+
+  function discColors(p){
+    return p === P1
+      ? { a:'#ff2d78', b:'#ff8fc0', glow:'#ff2d78' }
+      : { a:'#22e0ff', b:'#a9f4ff', glow:'#22e0ff' };
+  }
+
+  function drawDisc(cx, cy, p, r, highlight){
+    const col = discColors(p);
+    ctx.save();
+    ctx.shadowColor = col.glow;
+    ctx.shadowBlur = highlight ? r*1.1 : r*0.55;
+    const g = ctx.createRadialGradient(cx - r*0.35, cy - r*0.4, r*0.1, cx, cy, r);
+    g.addColorStop(0, col.b);
+    g.addColorStop(0.55, col.a);
+    g.addColorStop(1, p===P1 ? '#a3134b' : '#0f7f96');
+    ctx.fillStyle = g;
+    ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI*2); ctx.fill();
+    ctx.shadowBlur = 0;
+    // rim
+    ctx.lineWidth = Math.max(1, r*0.06);
+    ctx.strokeStyle = 'rgba(255,255,255,.22)';
+    ctx.beginPath(); ctx.arc(cx, cy, r*0.96, 0, Math.PI*2); ctx.stroke();
+    // gloss
+    ctx.fillStyle = 'rgba(255,255,255,.28)';
+    ctx.beginPath(); ctx.ellipse(cx - r*0.3, cy - r*0.35, r*0.34, r*0.2, -0.5, 0, Math.PI*2); ctx.fill();
+    ctx.restore();
+  }
+
+  function draw(){
+    if (!L.w) return;
+    ctx.clearRect(0,0,L.w,L.h);
+
+    // hover preview in the lane
+    if (!gameOver && !aiThinking && hoverCol >= 0 && dropRow(hoverCol) >= 0) {
+      const cx = cellCenterX(hoverCol);
+      ctx.save();
+      ctx.globalAlpha = 0.5;
+      drawDisc(cx, L.top/2, current, L.radius, false);
+      ctx.restore();
+      // column guide
+      ctx.save();
+      ctx.globalAlpha = 0.10;
+      ctx.fillStyle = discColors(current).a;
+      ctx.fillRect(L.cell*hoverCol, L.boardY, L.cell, L.boardH);
+      ctx.restore();
+    }
+
+    // board panel
+    ctx.save();
+    ctx.shadowColor = '#1b2a6b';
+    ctx.shadowBlur = 30;
+    const bg = ctx.createLinearGradient(0, L.boardY, 0, L.boardY+L.boardH);
+    bg.addColorStop(0, '#131a44');
+    bg.addColorStop(1, '#0a1030');
+    ctx.fillStyle = bg;
+    roundRect(L.boardX+2, L.boardY, L.boardW-4, L.boardH, L.cell*0.28);
+    ctx.fill();
+    ctx.restore();
+    // board edge stroke
+    ctx.lineWidth = 2;
+    ctx.strokeStyle = 'rgba(120,150,255,.25)';
+    roundRect(L.boardX+2, L.boardY, L.boardW-4, L.boardH, L.cell*0.28);
+    ctx.stroke();
+
+    // holes + settled discs
+    for (let r=0;r<ROWS;r++){
+      for (let c=0;c<COLS;c++){
+        const cx = cellCenterX(c), cy = cellCenterY(r);
+        // hole
+        ctx.save();
+        ctx.fillStyle = '#050814';
+        ctx.beginPath(); ctx.arc(cx, cy, L.radius, 0, Math.PI*2); ctx.fill();
+        ctx.lineWidth = Math.max(1, L.radius*0.05);
+        ctx.strokeStyle = 'rgba(0,0,0,.6)';
+        ctx.beginPath(); ctx.arc(cx, cy, L.radius, 0, Math.PI*2); ctx.stroke();
+        ctx.restore();
+      }
+    }
+
+    // discs (settled + falling)
+    for (const d of discs) {
+      const cx = cellCenterX(d.c);
+      const hi = winLine && winLine.some(p => p[0]===d.r && p[1]===d.c);
+      drawDisc(cx, d.y, d.player, L.radius, hi);
+    }
+
+    // win line
+    if (winLine && winLine.length) {
+      const a = winLine[0], b = winLine[winLine.length-1];
+      ctx.save();
+      ctx.strokeStyle = 'rgba(255,225,77,.9)';
+      ctx.lineWidth = L.radius*0.22;
+      ctx.lineCap = 'round';
+      ctx.shadowColor = '#ffe14d';
+      ctx.shadowBlur = 24;
+      ctx.beginPath();
+      ctx.moveTo(cellCenterX(a[1]), cellCenterY(a[0]));
+      ctx.lineTo(cellCenterX(b[1]), cellCenterY(b[0]));
+      ctx.stroke();
+      ctx.restore();
+    }
+  }
+
+  // ---------- Game logic ----------
+  function dropRow(c){
+    for (let r=ROWS-1;r>=0;r--) if (board[r][c]===EMPTY) return r;
+    return -1;
+  }
+
+  function validCols(bd){
+    const out=[];
+    for (let c=0;c<COLS;c++) if (bd[0][c]===EMPTY) out.push(c);
+    return out;
+  }
+
+  function boardFull(bd){
+    for (let c=0;c<COLS;c++) if (bd[0][c]===EMPTY) return false;
+    return true;
+  }
+
+  // returns winning line (array of [r,c]) for player p, or null
+  function findWin(bd, p){
+    const dirs = [[0,1],[1,0],[1,1],[1,-1]];
+    for (let r=0;r<ROWS;r++){
+      for (let c=0;c<COLS;c++){
+        if (bd[r][c]!==p) continue;
+        for (const [dr,dc] of dirs){
+          const line=[[r,c]];
+          let rr=r+dr, cc=c+dc;
+          while (rr>=0 && rr<ROWS && cc>=0 && cc<COLS && bd[rr][cc]===p){
+            line.push([rr,cc]);
+            if (line.length===NEED) return line;
+            rr+=dr; cc+=dc;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  // ---------- Human move ----------
+  function attemptDrop(c){
+    if (gameOver || animating || aiThinking) return;
+    if (modeSel.value==='ai' && current===P2) return; // not human's turn
+    const r = dropRow(c);
+    if (r<0) return;
+    doDrop(c, current);
+  }
+
+  function doDrop(c, player){
+    const r = dropRow(c);
+    if (r<0) return;
+    board[r][c] = player;
+    animating = true;
+    sfx.drop();
+    const targetY = cellCenterY(r);
+    const disc = { r, c, player, y: L.top/2, vy: 0, settled:false };
+    discs.push(disc);
+    startFall(disc, targetY);
+  }
+
+  function startFall(disc, targetY){
+    const grav = L.cell * 0.06;   // px per frame^2 (scaled by cell)
+    let last = performance.now();
+    let bounced = false;
+    function step(now){
+      const dt = Math.min(2, (now - last)/16.6667); last = now;
+      disc.vy += grav * dt;
+      disc.y += disc.vy * dt;
+      if (disc.y >= targetY){
+        disc.y = targetY;
+        if (!bounced && disc.vy > L.cell*0.25){
+          disc.vy = -disc.vy * 0.28;  // small bounce
+          bounced = true;
+          sfx.land();
+          draw();
+          requestAnimationFrame(step);
+          return;
+        }
+        disc.settled = true;
+        animating = false;
+        if (!bounced) sfx.land();
+        draw();
+        afterMove(disc.r, disc.c, disc.player);
+        return;
+      }
+      draw();
+      requestAnimationFrame(step);
+    }
+    requestAnimationFrame(step);
+  }
+
+  function afterMove(r, c, player){
+    const win = findWin(board, player);
+    if (win){
+      winLine = win; winPlayer = player; gameOver = true;
+      scores[player]++;
+      updateScores();
+      sfx.win();
+      setStatus(playerName(player, true) + ' wins the round! 🎉');
+      flashWin();
+      draw();
+      return;
+    }
+    if (boardFull(board)){
+      gameOver = true;
+      sfx.draw();
+      setStatus("It's a draw — board full.");
+      draw();
+      return;
+    }
+    current = player===P1 ? P2 : P1;
+    updateTurnUI();
+    if (modeSel.value==='ai' && current===P2 && !gameOver){
+      queueAI();
+    }
+  }
+
+  let winFlashTimer = null;
+  function flashWin(){
+    let n=0;
+    clearInterval(winFlashTimer);
+    winFlashTimer = setInterval(()=>{
+      n++;
+      // toggle handled implicitly by redraw jitter of glow via time — simple pulse:
+      draw();
+      if (n>8) clearInterval(winFlashTimer);
+    }, 140);
+  }
+
+  // ---------- AI: minimax + alpha-beta ----------
+  function queueAI(){
+    aiThinking = true;
+    setStatus('<span class="thinking">Computer is thinking…</span>');
+    draw();
+    // yield to let UI paint, keep responsive
+    setTimeout(runAI, 60);
+  }
+
+  function runAI(){
+    const depth = parseInt(diffSel.value, 10) || 5;
+    const move = bestMove(board, depth);
+    aiThinking = false;
+    if (move == null){ // no move (shouldn't happen)
+      updateTurnUI();
+      return;
+    }
+    doDrop(move, P2);
+  }
+
+  // Order columns center-first for better pruning
+  const COL_ORDER = (() => {
+    const mid=(COLS-1)/2;
+    return [...Array(COLS).keys()].sort((a,b)=>Math.abs(a-mid)-Math.abs(b-mid));
+  })();
+
+  function bestMove(bd, depth){
+    // immediate win / block shortcuts for snappiness at low depth
+    const valid = validColsOrdered(bd);
+    if (!valid.length) return null;
+    // win now?
+    for (const c of valid){ const b2=cloneDrop(bd,c,P2); if (findWin(b2,P2)) return c; }
+    // block opponent win?
+    for (const c of valid){ const b2=cloneDrop(bd,c,P1); if (findWin(b2,P1)) return c; }
+
+    let bestScore = -Infinity, bestCols = [valid[0]];
+    for (const c of valid){
+      const b2 = cloneDrop(bd, c, P2);
+      const s = minimax(b2, depth-1, -Infinity, Infinity, false);
+      if (s > bestScore){ bestScore = s; bestCols = [c]; }
+      else if (s === bestScore){ bestCols.push(c); }
+    }
+    // prefer central among ties
+    bestCols.sort((a,b)=>Math.abs(a-(COLS-1)/2)-Math.abs(b-(COLS-1)/2));
+    return bestCols[0];
+  }
+
+  function validColsOrdered(bd){
+    return COL_ORDER.filter(c => bd[0][c]===EMPTY);
+  }
+
+  function cloneDrop(bd, c, p){
+    const b2 = bd.map(row => row.slice());
+    for (let r=ROWS-1;r>=0;r--){ if (b2[r][c]===EMPTY){ b2[r][c]=p; break; } }
+    return b2;
+  }
+
+  function minimax(bd, depth, alpha, beta, maximizing){
+    if (findWin(bd, P2)) return 100000 + depth;      // AI win, sooner better
+    if (findWin(bd, P1)) return -100000 - depth;     // human win
+    if (depth===0 || boardFull(bd)) return evaluate(bd);
+
+    const cols = validColsOrdered(bd);
+    if (maximizing){
+      let value = -Infinity;
+      for (const c of cols){
+        const b2 = cloneDrop(bd, c, P2);
+        value = Math.max(value, minimax(b2, depth-1, alpha, beta, false));
+        alpha = Math.max(alpha, value);
+        if (alpha >= beta) break;
+      }
+      return value;
+    } else {
+      let value = Infinity;
+      for (const c of cols){
+        const b2 = cloneDrop(bd, c, P1);
+        value = Math.min(value, minimax(b2, depth-1, alpha, beta, true));
+        beta = Math.min(beta, value);
+        if (beta <= alpha) break;
+      }
+      return value;
+    }
+  }
+
+  // Heuristic evaluation from AI (P2) perspective
+  function evaluate(bd){
+    let score = 0;
+    // center column preference
+    const centerC = Math.floor(COLS/2);
+    let centerCount = 0;
+    for (let r=0;r<ROWS;r++) if (bd[r][centerC]===P2) centerCount++;
+    score += centerCount * 6;
+
+    const windows = [];
+    // horizontal
+    for (let r=0;r<ROWS;r++)
+      for (let c=0;c<=COLS-4;c++)
+        windows.push([bd[r][c],bd[r][c+1],bd[r][c+2],bd[r][c+3]]);
+    // vertical
+    for (let c=0;c<COLS;c++)
+      for (let r=0;r<=ROWS-4;r++)
+        windows.push([bd[r][c],bd[r+1][c],bd[r+2][c],bd[r+3][c]]);
+    // diag down-right
+    for (let r=0;r<=ROWS-4;r++)
+      for (let c=0;c<=COLS-4;c++)
+        windows.push([bd[r][c],bd[r+1][c+1],bd[r+2][c+2],bd[r+3][c+3]]);
+    // diag up-right
+    for (let r=3;r<ROWS;r++)
+      for (let c=0;c<=COLS-4;c++)
+        windows.push([bd[r][c],bd[r-1][c+1],bd[r-2][c+2],bd[r-3][c+3]]);
+
+    for (const w of windows) score += scoreWindow(w);
+    return score;
+  }
+
+  function scoreWindow(w){
+    let ai=0, hu=0, e=0;
+    for (const v of w){ if (v===P2) ai++; else if (v===P1) hu++; else e++; }
+    if (ai>0 && hu>0) return 0; // mixed, dead
+    let s=0;
+    if (ai===4) s+=1000;
+    else if (ai===3 && e===1) s+=12;
+    else if (ai===2 && e===2) s+=4;
+    if (hu===4) s-=1000;
+    else if (hu===3 && e===1) s-=16;   // block threats a bit harder
+    else if (hu===2 && e===2) s-=4;
+    return s;
+  }
+
+  // ---------- UI helpers ----------
+  function playerName(p, cap){
+    if (modeSel.value==='ai') return p===P1 ? 'You' : 'Computer';
+    return p===P1 ? 'Player 1' : 'Player 2';
+  }
+  function setStatus(html){ statusEl.innerHTML = html; }
+  function updateScores(){ val1.textContent = scores[P1]; val2.textContent = scores[P2]; }
+  function updateNames(){
+    if (modeSel.value==='ai'){ name1.textContent='You'; name2.textContent='Computer'; }
+    else { name1.textContent='Player 1'; name2.textContent='Player 2'; }
+  }
+  function updateTurnUI(){
+    score1El.classList.toggle('active', current===P1);
+    score2El.classList.toggle('active', current===P2);
+    if (gameOver) return;
+    const cls = current===P1 ? 'p1' : 'p2';
+    const who = playerName(current);
+    if (modeSel.value==='ai' && current===P2){
+      setStatus('<span class="thinking">Computer is thinking…</span>');
+    } else {
+      setStatus(`<b class="${cls}">${who}</b> — drop a disc`);
+    }
+  }
+
+  // ---------- New game ----------
+  function newGame(){
+    clearInterval(winFlashTimer);
+    newBoard();
+    discs.length = 0;
+    current = P1;
+    gameOver = false; winLine = null; winPlayer = 0; aiThinking = false; animating = false;
+    hoverCol = -1;
+    updateNames();
+    updateScores();
+    updateTurnUI();
+    resize();
+    // if AI is P1? No — human/P1 always starts here.
+  }
+
+  // ---------- Input ----------
+  function colFromEvent(e){
+    const rect = canvas.getBoundingClientRect();
+    const x = (e.clientX ?? (e.touches && e.touches[0].clientX)) - rect.left;
+    const c = Math.floor(x / (rect.width / COLS));
+    return Math.max(0, Math.min(COLS-1, c));
+  }
+
+  canvas.addEventListener('mousemove', e => {
+    if (gameOver || aiThinking) { if (hoverCol!==-1){hoverCol=-1;draw();} return; }
+    const c = colFromEvent(e);
+    if (c !== hoverCol){ hoverCol = c; if(!muted && dropRow(c)>=0) sfx.hover(); draw(); }
+  });
+  canvas.addEventListener('mouseleave', () => { if (hoverCol!==-1){ hoverCol=-1; draw(); } });
+  canvas.addEventListener('click', e => { ac(); attemptDrop(colFromEvent(e)); });
+
+  // Touch
+  let touchCol = -1;
+  canvas.addEventListener('touchstart', e => {
+    ac();
+    e.preventDefault();
+    touchCol = colFromEvent(e);
+    hoverCol = touchCol;
+    draw();
+  }, {passive:false});
+  canvas.addEventListener('touchmove', e => {
+    e.preventDefault();
+    const c = colFromEvent(e);
+    if (c!==hoverCol){ hoverCol=c; draw(); }
+  }, {passive:false});
+  canvas.addEventListener('touchend', e => {
+    e.preventDefault();
+    if (hoverCol>=0){ const c=hoverCol; hoverCol=-1; attemptDrop(c); draw(); }
+  }, {passive:false});
+
+  // Keyboard: 1-7 to drop, N new game
+  window.addEventListener('keydown', e => {
+    if (e.key>='1' && e.key<='7'){ ac(); attemptDrop(parseInt(e.key,10)-1); }
+    else if (e.key==='n' || e.key==='N'){ newGame(); }
+  });
+
+  // Controls
+  $('newgame').addEventListener('click', () => { ac(); sfx.click(); newGame(); });
+  modeSel.addEventListener('change', () => { sfx.click(); scores={1:0,2:0}; newGame(); });
+  diffSel.addEventListener('change', () => { sfx.click(); });
+  muteBtn.addEventListener('click', () => {
+    muted = !muted;
+    muteBtn.textContent = muted ? '🔇' : '🔊';
+    if (!muted) { ac(); sfx.click(); }
+  });
+
+  window.addEventListener('resize', resize);
+  window.addEventListener('orientationchange', () => setTimeout(resize, 120));
+
+  // ---------- Boot ----------
+  newGame();
+})();
+</script>
+</body>
+</html>
diff --git a/games/constellation-clock/ConstellationClock.aa b/games/constellation-clock/ConstellationClock.aa
new file mode 100644
index 0000000..8ffc77f
--- /dev/null
+++ b/games/constellation-clock/ConstellationClock.aa
@@ -0,0 +1,364 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Constellation Clock</title>
+<style>
+  html, body {
+    margin: 0;
+    padding: 0;
+    height: 100%;
+    overflow: hidden;
+    background: #05060f;
+  }
+  #sky {
+    display: block;
+    width: 100vw;
+    height: 100vh;
+  }
+  #digital {
+    position: fixed;
+    right: 22px;
+    bottom: 18px;
+    font-family: "Courier New", ui-monospace, monospace;
+    color: rgba(200, 220, 255, 0.85);
+    letter-spacing: 3px;
+    font-size: 26px;
+    text-shadow: 0 0 8px rgba(120,170,255,0.6), 0 0 18px rgba(80,120,255,0.35);
+    user-select: none;
+    z-index: 5;
+  }
+  #digital .date {
+    display: block;
+    font-size: 12px;
+    letter-spacing: 4px;
+    text-align: right;
+    margin-top: 4px;
+    color: rgba(150, 180, 230, 0.6);
+  }
+  #label {
+    position: fixed;
+    left: 22px;
+    top: 16px;
+    font-family: "Courier New", ui-monospace, monospace;
+    color: rgba(160, 190, 240, 0.5);
+    font-size: 12px;
+    letter-spacing: 4px;
+    text-transform: uppercase;
+    user-select: none;
+    z-index: 5;
+  }
+</style>
+</head>
+<body>
+<canvas id="sky"></canvas>
+<div id="label">Celestial Chronometer</div>
+<div id="digital"><span id="clock">00:00:00</span><span class="date" id="date"></span></div>
+
+<script>
+(function () {
+  "use strict";
+
+  const canvas = document.getElementById("sky");
+  const ctx = canvas.getContext("2d");
+  const clockEl = document.getElementById("clock");
+  const dateEl = document.getElementById("date");
+
+  let W = 0, H = 0, CX = 0, CY = 0, DPR = 1;
+
+  function resize() {
+    DPR = Math.min(window.devicePixelRatio || 1, 2);
+    W = window.innerWidth;
+    H = window.innerHeight;
+    canvas.width = Math.floor(W * DPR);
+    canvas.height = Math.floor(H * DPR);
+    canvas.style.width = W + "px";
+    canvas.style.height = H + "px";
+    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+    CX = W / 2;
+    CY = H / 2;
+    buildStars();
+  }
+
+  // ---------- Background starfield ----------
+  let bgStars = [];
+  function buildStars() {
+    bgStars = [];
+    const count = Math.round((W * H) / 5200);
+    for (let i = 0; i < count; i++) {
+      bgStars.push({
+        x: Math.random() * W,
+        y: Math.random() * H,
+        r: Math.random() * 1.3 + 0.2,
+        base: Math.random() * 0.5 + 0.2,
+        amp: Math.random() * 0.5 + 0.1,
+        speed: Math.random() * 2 + 0.5,
+        phase: Math.random() * Math.PI * 2,
+        hue: 210 + Math.random() * 40
+      });
+    }
+  }
+
+  function drawBackground(t) {
+    // subtle vertical nebula gradient
+    const g = ctx.createRadialGradient(CX, CY, 0, CX, CY, Math.max(W, H) * 0.75);
+    g.addColorStop(0, "#0a1230");
+    g.addColorStop(0.5, "#070a1c");
+    g.addColorStop(1, "#03040c");
+    ctx.fillStyle = g;
+    ctx.fillRect(0, 0, W, H);
+
+    for (let i = 0; i < bgStars.length; i++) {
+      const s = bgStars[i];
+      const tw = s.base + s.amp * Math.sin(t * s.speed + s.phase);
+      const a = Math.max(0, Math.min(1, tw));
+      ctx.beginPath();
+      ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
+      ctx.fillStyle = "hsla(" + s.hue + ",70%,85%," + a + ")";
+      ctx.fill();
+    }
+  }
+
+  // ---------- Constellation hand definitions ----------
+  // Each hand is a chain of stars at given radius fractions along the hand.
+  // Points: {r: fraction of handRadius, o: sideways offset fraction, mag: star size}
+  const secondShape = [
+    { r: 0.00, o: 0.00, mag: 2.0 },
+    { r: 0.30, o: 0.05, mag: 1.6 },
+    { r: 0.55, o: -0.05, mag: 1.8 },
+    { r: 0.78, o: 0.04, mag: 1.5 },
+    { r: 0.95, o: 0.00, mag: 2.6 }
+  ];
+  const minuteShape = [
+    { r: 0.00, o: 0.00, mag: 2.4 },
+    { r: 0.22, o: 0.07, mag: 2.0 },
+    { r: 0.42, o: -0.06, mag: 2.2 },
+    { r: 0.60, o: 0.08, mag: 2.0 },
+    { r: 0.78, o: -0.04, mag: 2.4 },
+    { r: 0.92, o: 0.05, mag: 3.2 }
+  ];
+  const hourShape = [
+    { r: 0.00, o: 0.00, mag: 2.8 },
+    { r: 0.25, o: 0.10, mag: 2.4 },
+    { r: 0.30, o: -0.10, mag: 2.4 },
+    { r: 0.52, o: 0.06, mag: 2.6 },
+    { r: 0.70, o: -0.08, mag: 2.6 },
+    { r: 0.88, o: 0.00, mag: 3.6 }
+  ];
+
+  function drawConstellation(shape, angle, handRadius, color, glow, t, twinkle) {
+    // angle: 0 = 12 o'clock (up). rotate coordinate.
+    const ca = Math.cos(angle - Math.PI / 2);
+    const sa = Math.sin(angle - Math.PI / 2);
+    const pts = [];
+    for (let i = 0; i < shape.length; i++) {
+      const p = shape[i];
+      const along = p.r * handRadius;
+      const side = p.o * handRadius;
+      // local coords: along axis + perpendicular offset
+      const lx = along;
+      const ly = side;
+      const x = CX + lx * ca - ly * sa;
+      const y = CY + lx * sa + ly * ca;
+      pts.push({ x: x, y: y, mag: p.mag });
+    }
+
+    // connecting lines
+    ctx.save();
+    ctx.lineWidth = 1.2;
+    ctx.strokeStyle = color.line;
+    ctx.shadowColor = color.glow;
+    ctx.shadowBlur = glow;
+    ctx.beginPath();
+    ctx.moveTo(pts[0].x, pts[0].y);
+    for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i].x, pts[i].y);
+    ctx.stroke();
+    ctx.restore();
+
+    // stars
+    for (let i = 0; i < pts.length; i++) {
+      const p = pts[i];
+      const tw = twinkle ? (0.75 + 0.25 * Math.sin(t * 3 + i * 1.7)) : 1;
+      const rad = p.mag * tw;
+      ctx.save();
+      ctx.shadowColor = color.glow;
+      ctx.shadowBlur = glow * 1.4;
+      const grd = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, rad * 3);
+      grd.addColorStop(0, color.core);
+      grd.addColorStop(0.4, color.star);
+      grd.addColorStop(1, "rgba(0,0,0,0)");
+      ctx.fillStyle = grd;
+      ctx.beginPath();
+      ctx.arc(p.x, p.y, rad * 3, 0, Math.PI * 2);
+      ctx.fill();
+      // bright core
+      ctx.shadowBlur = 0;
+      ctx.fillStyle = color.core;
+      ctx.beginPath();
+      ctx.arc(p.x, p.y, rad * 0.8, 0, Math.PI * 2);
+      ctx.fill();
+      ctx.restore();
+    }
+    return pts;
+  }
+
+  // ---------- Hour ticks as faint stars around the dial ----------
+  function drawDialStars(t) {
+    const R = Math.min(W, H) * 0.44;
+    for (let i = 0; i < 12; i++) {
+      const a = (i / 12) * Math.PI * 2 - Math.PI / 2;
+      const x = CX + Math.cos(a) * R;
+      const y = CY + Math.sin(a) * R;
+      const tw = 0.5 + 0.5 * Math.sin(t * 1.5 + i);
+      const big = (i % 3 === 0);
+      ctx.beginPath();
+      ctx.arc(x, y, big ? 2.4 : 1.4, 0, Math.PI * 2);
+      ctx.fillStyle = "rgba(180,205,255," + (0.35 + 0.35 * tw) + ")";
+      ctx.shadowColor = "rgba(140,180,255,0.8)";
+      ctx.shadowBlur = big ? 10 : 5;
+      ctx.fill();
+      ctx.shadowBlur = 0;
+    }
+    // center star (the pole)
+    const cg = ctx.createRadialGradient(CX, CY, 0, CX, CY, 14);
+    cg.addColorStop(0, "rgba(255,255,255,0.95)");
+    cg.addColorStop(0.4, "rgba(180,210,255,0.6)");
+    cg.addColorStop(1, "rgba(0,0,0,0)");
+    ctx.fillStyle = cg;
+    ctx.beginPath();
+    ctx.arc(CX, CY, 14, 0, Math.PI * 2);
+    ctx.fill();
+  }
+
+  // ---------- Shooting stars ----------
+  let shootings = [];
+  let nextShoot = 2 + Math.random() * 4;
+  function spawnShoot() {
+    const edge = Math.random();
+    const startX = Math.random() * W;
+    const startY = Math.random() * H * 0.5;
+    const angle = Math.PI * 0.15 + Math.random() * Math.PI * 0.2; // downward-right-ish
+    const speed = 500 + Math.random() * 400;
+    shootings.push({
+      x: startX,
+      y: startY,
+      vx: Math.cos(angle) * speed * (Math.random() < 0.5 ? 1 : -1),
+      vy: Math.sin(angle) * speed,
+      life: 0,
+      maxLife: 0.9 + Math.random() * 0.5,
+      len: 80 + Math.random() * 120
+    });
+  }
+  function updateShoot(dt) {
+    nextShoot -= dt;
+    if (nextShoot <= 0) {
+      spawnShoot();
+      nextShoot = 4 + Math.random() * 7;
+    }
+    for (let i = shootings.length - 1; i >= 0; i--) {
+      const s = shootings[i];
+      s.life += dt;
+      s.x += s.vx * dt;
+      s.y += s.vy * dt;
+      if (s.life > s.maxLife) shootings.splice(i, 1);
+    }
+  }
+  function drawShoot() {
+    for (let i = 0; i < shootings.length; i++) {
+      const s = shootings[i];
+      const prog = s.life / s.maxLife;
+      const alpha = Math.sin(prog * Math.PI); // fade in/out
+      const mag = Math.hypot(s.vx, s.vy) || 1;
+      const ux = s.vx / mag, uy = s.vy / mag;
+      const tx = s.x - ux * s.len;
+      const ty = s.y - uy * s.len;
+      const grd = ctx.createLinearGradient(s.x, s.y, tx, ty);
+      grd.addColorStop(0, "rgba(255,255,255," + (0.9 * alpha) + ")");
+      grd.addColorStop(1, "rgba(255,255,255,0)");
+      ctx.strokeStyle = grd;
+      ctx.lineWidth = 2;
+      ctx.shadowColor = "rgba(200,220,255,0.9)";
+      ctx.shadowBlur = 8;
+      ctx.beginPath();
+      ctx.moveTo(s.x, s.y);
+      ctx.lineTo(tx, ty);
+      ctx.stroke();
+      ctx.shadowBlur = 0;
+      // head
+      ctx.beginPath();
+      ctx.arc(s.x, s.y, 2, 0, Math.PI * 2);
+      ctx.fillStyle = "rgba(255,255,255," + alpha + ")";
+      ctx.fill();
+    }
+  }
+
+  // ---------- Main loop ----------
+  const colHour = {
+    line: "rgba(255,200,120,0.45)",
+    glow: "rgba(255,180,90,0.9)",
+    star: "rgba(255,190,110,0.9)",
+    core: "rgba(255,240,210,1)"
+  };
+  const colMinute = {
+    line: "rgba(140,200,255,0.5)",
+    glow: "rgba(120,180,255,0.9)",
+    star: "rgba(150,200,255,0.9)",
+    core: "rgba(235,245,255,1)"
+  };
+  const colSecond = {
+    line: "rgba(180,255,220,0.45)",
+    glow: "rgba(140,255,200,0.85)",
+    star: "rgba(170,255,210,0.9)",
+    core: "rgba(240,255,250,1)"
+  };
+
+  let lastTime = null;
+
+  function frame(now) {
+    if (lastTime === null) lastTime = now;
+    let dt = (now - lastTime) / 1000;
+    if (dt > 0.1) dt = 0.1;
+    lastTime = now;
+    const t = now / 1000;
+
+    const d = new Date();
+    const ms = d.getMilliseconds();
+    const sec = d.getSeconds() + ms / 1000;
+    const min = d.getMinutes() + sec / 60;
+    const hr = (d.getHours() % 12) + min / 60;
+
+    const secAngle = (sec / 60) * Math.PI * 2;
+    const minAngle = (min / 60) * Math.PI * 2;
+    const hrAngle = (hr / 12) * Math.PI * 2;
+
+    const base = Math.min(W, H);
+    const hourR = base * 0.20;
+    const minR = base * 0.33;
+    const secR = base * 0.40;
+
+    drawBackground(t);
+    drawDialStars(t);
+
+    updateShoot(dt);
+    drawShoot();
+
+    drawConstellation(hourShape, hrAngle, hourR, colHour, 16, t, true);
+    drawConstellation(minuteShape, minAngle, minR, colMinute, 14, t, true);
+    drawConstellation(secondShape, secAngle, secR, colSecond, 12, t, true);
+
+    // digital readout
+    const pad = (n) => (n < 10 ? "0" + n : "" + n);
+    clockEl.textContent = pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds());
+    dateEl.textContent = d.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" });
+
+    requestAnimationFrame(frame);
+  }
+
+  window.addEventListener("resize", resize);
+  resize();
+  requestAnimationFrame(frame);
+})();
+</script>
+</body>
+</html>
diff --git a/games/dvd-bounce/DVDBounce.aa b/games/dvd-bounce/DVDBounce.aa
new file mode 100644
index 0000000..4d24ee9
--- /dev/null
+++ b/games/dvd-bounce/DVDBounce.aa
@@ -0,0 +1,312 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>DVD Bounce — Elevated</title>
+<style>
+  :root{
+    --bg:#05060a;
+    --ink:#e8ecf5;
+    --accent:#7c5cff;
+  }
+  *{box-sizing:border-box;margin:0;padding:0}
+  html,body{height:100%;overflow:hidden}
+  body{
+    background:radial-gradient(120% 120% at 50% 0%, #0d1020 0%, #04050a 60%, #000 100%);
+    color:var(--ink);
+    font-family:"Segoe UI",system-ui,-apple-system,sans-serif;
+    -webkit-font-smoothing:antialiased;
+  }
+  #stage{position:fixed;inset:0;display:block}
+  /* HUD */
+  .hud{
+    position:fixed;top:16px;left:16px;z-index:10;
+    display:flex;flex-direction:column;gap:10px;
+    pointer-events:none;
+  }
+  .panel{
+    pointer-events:auto;
+    background:rgba(18,20,34,.55);
+    backdrop-filter:blur(12px) saturate(140%);
+    -webkit-backdrop-filter:blur(12px) saturate(140%);
+    border:1px solid rgba(255,255,255,.09);
+    border-radius:14px;
+    padding:14px 16px;
+    box-shadow:0 10px 40px rgba(0,0,0,.45);
+  }
+  .stats{display:flex;gap:22px;align-items:center}
+  .stat{display:flex;flex-direction:column;line-height:1.1}
+  .stat .num{font-size:26px;font-weight:800;letter-spacing:.5px;font-variant-numeric:tabular-nums}
+  .stat .lbl{font-size:10px;text-transform:uppercase;letter-spacing:2px;opacity:.55;margin-top:3px}
+  .corner .num{color:#ffd35c;text-shadow:0 0 18px rgba(255,211,92,.55)}
+  .controls{display:flex;gap:8px;flex-wrap:wrap}
+  button{
+    pointer-events:auto;
+    font:inherit;font-size:12px;font-weight:600;letter-spacing:.4px;
+    color:var(--ink);
+    background:linear-gradient(180deg,rgba(124,92,255,.35),rgba(124,92,255,.15));
+    border:1px solid rgba(124,92,255,.5);
+    border-radius:10px;
+    padding:9px 14px;cursor:pointer;
+    transition:transform .08s ease, background .15s ease, box-shadow .15s ease;
+  }
+  button:hover{background:linear-gradient(180deg,rgba(124,92,255,.55),rgba(124,92,255,.25));box-shadow:0 0 22px rgba(124,92,255,.4)}
+  button:active{transform:translateY(1px) scale(.98)}
+  button.ghost{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.14)}
+  button.ghost:hover{background:rgba(255,255,255,.1);box-shadow:none}
+  .hint{
+    position:fixed;bottom:14px;right:16px;z-index:10;
+    font-size:11px;opacity:.4;letter-spacing:.5px;pointer-events:none;
+  }
+  .flash{animation:pop .4s ease}
+  @keyframes pop{0%{transform:scale(1)}35%{transform:scale(1.28)}100%{transform:scale(1)}}
+</style>
+</head>
+<body>
+<canvas id="stage"></canvas>
+
+<div class="hud">
+  <div class="panel stats">
+    <div class="stat corner">
+      <span class="num" id="cornerCount">0</span>
+      <span class="lbl">Corners</span>
+    </div>
+    <div class="stat">
+      <span class="num" id="wallCount">0</span>
+      <span class="lbl">Wall hits</span>
+    </div>
+    <div class="stat">
+      <span class="num" id="logoCount">1</span>
+      <span class="lbl">Logos</span>
+    </div>
+  </div>
+  <div class="panel controls">
+    <button id="addBtn">+ Add logo</button>
+    <button id="chaosBtn">Chaos ×5</button>
+    <button class="ghost" id="resetBtn">Reset</button>
+  </div>
+</div>
+
+<div class="hint">corner hits trigger the confetti · click canvas to spawn</div>
+
+<script>
+(() => {
+  const canvas = document.getElementById('stage');
+  const ctx = canvas.getContext('2d');
+
+  const cornerEl = document.getElementById('cornerCount');
+  const wallEl   = document.getElementById('wallCount');
+  const logoEl   = document.getElementById('logoCount');
+
+  let W = 0, H = 0, DPR = 1;
+  function resize() {
+    DPR = Math.min(window.devicePixelRatio || 1, 2);
+    W = window.innerWidth;
+    H = window.innerHeight;
+    canvas.width  = Math.floor(W * DPR);
+    canvas.height = Math.floor(H * DPR);
+    canvas.style.width  = W + 'px';
+    canvas.style.height = H + 'px';
+    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+  }
+  window.addEventListener('resize', resize);
+  resize();
+
+  // ---- palette ----
+  const PALETTE = [
+    '#ff4d6d','#ffd35c','#4ade80','#38bdf8','#7c5cff',
+    '#f472b6','#fb923c','#22d3ee','#a3e635','#e879f9'
+  ];
+  const rand  = (a, b) => a + Math.random() * (b - a);
+  const pick  = arr => arr[(Math.random() * arr.length) | 0];
+  const nextColor = cur => { let c; do { c = pick(PALETTE); } while (c === cur); return c; };
+
+  // ---- state ----
+  let logos = [];
+  let particles = [];
+  let cornerHits = 0, wallHits = 0;
+
+  // The DVD wordmark, drawn once to an offscreen canvas and tinted per-logo.
+  function makeLogoSprite() {
+    const w = 150, h = 78;
+    const c = document.createElement('canvas');
+    c.width = w; c.height = h;
+    const g = c.getContext('2d');
+
+    g.fillStyle = '#fff';
+    g.textAlign = 'center';
+    g.textBaseline = 'middle';
+
+    // "DVD"
+    g.font = 'italic 900 52px "Arial Black", Arial, sans-serif';
+    g.save();
+    g.translate(w/2, h*0.36);
+    g.scale(1, 0.82);
+    g.fillText('DVD', 0, 0);
+    g.restore();
+
+    // squashed ellipse under it (the classic logo oval)
+    g.beginPath();
+    g.ellipse(w/2, h*0.70, 46, 12, 0, 0, Math.PI*2);
+    g.fill();
+    // knock out the label bar
+    g.save();
+    g.globalCompositeOperation = 'destination-out';
+    g.fillRect(w/2 - 34, h*0.66, 68, 8);
+    g.restore();
+    // small "video" text on the bar
+    g.font = '900 11px Arial, sans-serif';
+    g.fillText('V I D E O', w/2, h*0.70);
+
+    return c;
+  }
+  const SPRITE = makeLogoSprite();
+  const LW = SPRITE.width, LH = SPRITE.height;
+
+  function spawnLogo(x, y) {
+    const speed = rand(2.2, 3.6);
+    const ang = rand(0, Math.PI * 2);
+    logos.push({
+      x: x != null ? x : rand(0, Math.max(0, W - LW)),
+      y: y != null ? y : rand(0, Math.max(0, H - LH)),
+      vx: Math.cos(ang) * speed * (Math.random() < .5 ? 1 : -1),
+      vy: Math.sin(ang) * speed * (Math.random() < .5 ? 1 : -1),
+      color: pick(PALETTE),
+      trail: []
+    });
+    updateHUD();
+  }
+
+  function burst(x, y, big) {
+    const n = big ? 90 : 22;
+    for (let i = 0; i < n; i++) {
+      const a = Math.random() * Math.PI * 2;
+      const sp = rand(big ? 2 : 1, big ? 9 : 4);
+      particles.push({
+        x, y,
+        vx: Math.cos(a) * sp,
+        vy: Math.sin(a) * sp - (big ? 1.5 : 0),
+        life: 1,
+        decay: rand(0.012, 0.03),
+        size: rand(2, big ? 6 : 4),
+        color: pick(PALETTE),
+        spin: rand(-0.3, 0.3),
+        rot: Math.random() * Math.PI
+      });
+    }
+  }
+
+  function flash(el){ el.classList.remove('flash'); void el.offsetWidth; el.classList.add('flash'); }
+  function updateHUD() {
+    cornerEl.textContent = cornerHits;
+    wallEl.textContent   = wallHits;
+    logoEl.textContent   = logos.length;
+  }
+
+  // ---- main loop ----
+  function frame() {
+    // fade previous frame → motion trail
+    ctx.fillStyle = 'rgba(4,5,10,0.20)';
+    ctx.fillRect(0, 0, W, H);
+
+    const maxX = W - LW, maxY = H - LH;
+
+    for (const L of logos) {
+      L.x += L.vx;
+      L.y += L.vy;
+
+      let hitX = false, hitY = false;
+      if (L.x <= 0)     { L.x = 0;    L.vx =  Math.abs(L.vx); hitX = true; }
+      else if (L.x >= maxX) { L.x = maxX; L.vx = -Math.abs(L.vx); hitX = true; }
+      if (L.y <= 0)     { L.y = 0;    L.vy =  Math.abs(L.vy); hitY = true; }
+      else if (L.y >= maxY) { L.y = maxY; L.vy = -Math.abs(L.vy); hitY = true; }
+
+      if (hitX || hitY) {
+        L.color = nextColor(L.color);
+        if (hitX && hitY) {
+          // CORNER!
+          cornerHits++;
+          burst(L.x + LW/2, L.y + LH/2, true);
+          flash(cornerEl);
+        } else {
+          wallHits++;
+          burst(hitX ? (L.x <= 0 ? 0 : W) : L.x + LW/2,
+                hitY ? (L.y <= 0 ? 0 : H) : L.y + LH/2, false);
+        }
+        updateHUD();
+      }
+
+      // trail
+      L.trail.push({ x: L.x, y: L.y });
+      if (L.trail.length > 14) L.trail.shift();
+      for (let i = 0; i < L.trail.length; i++) {
+        const t = L.trail[i];
+        const alpha = (i / L.trail.length) * 0.28;
+        drawSprite(t.x, t.y, L.color, alpha);
+      }
+
+      drawSprite(L.x, L.y, L.color, 1);
+    }
+
+    // particles
+    for (let i = particles.length - 1; i >= 0; i--) {
+      const p = particles[i];
+      p.vy += 0.08;             // gravity
+      p.vx *= 0.99;
+      p.x += p.vx;
+      p.y += p.vy;
+      p.rot += p.spin;
+      p.life -= p.decay;
+      if (p.life <= 0) { particles.splice(i, 1); continue; }
+
+      ctx.save();
+      ctx.globalAlpha = Math.max(0, p.life);
+      ctx.translate(p.x, p.y);
+      ctx.rotate(p.rot);
+      ctx.fillStyle = p.color;
+      ctx.shadowColor = p.color;
+      ctx.shadowBlur = 8;
+      const s = p.size;
+      ctx.fillRect(-s/2, -s/2, s, s * 1.6);
+      ctx.restore();
+    }
+
+    requestAnimationFrame(frame);
+  }
+
+  function drawSprite(x, y, color, alpha) {
+    ctx.save();
+    ctx.globalAlpha = alpha;
+    // tint: draw white sprite then multiply the color through
+    ctx.drawImage(SPRITE, x, y);
+    ctx.globalCompositeOperation = 'source-atop';
+    ctx.globalAlpha = alpha;
+    ctx.fillStyle = color;
+    ctx.fillRect(x, y, LW, LH);
+    ctx.restore();
+  }
+
+  // ---- controls ----
+  document.getElementById('addBtn').addEventListener('click', () => spawnLogo());
+  document.getElementById('chaosBtn').addEventListener('click', () => {
+    for (let i = 0; i < 5; i++) spawnLogo();
+  });
+  document.getElementById('resetBtn').addEventListener('click', () => {
+    logos = []; particles = [];
+    cornerHits = 0; wallHits = 0;
+    spawnLogo(W/2 - LW/2, H/2 - LH/2);
+  });
+  canvas.addEventListener('pointerdown', e => spawnLogo(
+    Math.min(Math.max(0, e.clientX - LW/2), W - LW),
+    Math.min(Math.max(0, e.clientY - LH/2), H - LH)
+  ));
+
+  // ---- go ----
+  spawnLogo(W/2 - LW/2, H/2 - LH/2);
+  updateHUD();
+  requestAnimationFrame(frame);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/games/emoji-memory/EmojiMemory.aa b/games/emoji-memory/EmojiMemory.aa
new file mode 100644
index 0000000..0ceb407
--- /dev/null
+++ b/games/emoji-memory/EmojiMemory.aa
@@ -0,0 +1,401 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Free-Roster — Emoji Memory Match</title>
+<style>
+  :root{
+    --bg1:#1e1b4b; --bg2:#312e81; --accent:#a78bfa; --accent2:#f472b6;
+    --card-back:linear-gradient(135deg,#7c3aed,#db2777);
+    --card-face:#ffffff; --matched:#34d399; --miss:#f87171;
+    --text:#f8fafc; --panel:rgba(255,255,255,.07); --panel-bd:rgba(255,255,255,.1);
+    --seg-bg:rgba(255,255,255,.08); --seg-bd:rgba(255,255,255,.12); --seg-txt:#e2e8f0;
+    --foot:rgba(255,255,255,.4);
+  }
+  body.light{
+    --bg1:#ede9fe; --bg2:#c7d2fe;
+    --card-face:#ffffff;
+    --text:#1e1b4b; --panel:rgba(30,27,75,.06); --panel-bd:rgba(30,27,75,.12);
+    --seg-bg:rgba(30,27,75,.06); --seg-bd:rgba(30,27,75,.14); --seg-txt:#312e81;
+    --foot:rgba(30,27,75,.5);
+  }
+  *{box-sizing:border-box;margin:0;padding:0}
+  body{
+    min-height:100vh;
+    font-family:'Segoe UI',system-ui,-apple-system,sans-serif;
+    background:linear-gradient(160deg,var(--bg1),var(--bg2));
+    color:var(--text);
+    display:flex;flex-direction:column;align-items:center;
+    padding:20px;gap:16px;
+    transition:background .3s,color .3s;
+  }
+  h1{
+    font-size:clamp(1.6rem,5vw,2.6rem);
+    font-weight:800;letter-spacing:.5px;
+    background:linear-gradient(90deg,var(--accent),var(--accent2));
+    -webkit-background-clip:text;background-clip:text;color:transparent;
+    text-align:center;
+  }
+  .controls{
+    display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:center;
+  }
+  .seg{
+    display:inline-flex;background:var(--seg-bg);
+    border-radius:999px;padding:4px;gap:4px;
+    border:1px solid var(--seg-bd);
+  }
+  .seg button{
+    border:none;background:transparent;color:var(--seg-txt);
+    padding:8px 16px;border-radius:999px;cursor:pointer;
+    font-size:.95rem;font-weight:600;transition:.2s;
+  }
+  .icon-btn{
+    border:1px solid var(--seg-bd);background:var(--seg-bg);color:var(--seg-txt);
+    cursor:pointer;font-size:1.1rem;font-weight:600;line-height:1;
+    width:42px;height:42px;border-radius:50%;transition:.2s;
+    display:inline-flex;align-items:center;justify-content:center;
+  }
+  .icon-btn:hover{transform:translateY(-2px)}
+  .icon-btn:focus-visible{outline:3px solid #fde68a;outline-offset:2px}
+  .icon-btn.off{opacity:.45}
+  .seg button.active{background:linear-gradient(135deg,var(--accent),var(--accent2));color:#fff;box-shadow:0 4px 14px rgba(167,139,250,.4)}
+  .seg button:focus-visible,.btn:focus-visible{outline:3px solid #fde68a;outline-offset:2px}
+  .btn{
+    border:none;cursor:pointer;font-weight:700;font-size:.95rem;
+    padding:10px 22px;border-radius:999px;color:#fff;
+    background:linear-gradient(135deg,var(--accent),var(--accent2));
+    box-shadow:0 4px 14px rgba(244,114,182,.35);transition:transform .15s,box-shadow .15s;
+  }
+  .btn:hover{transform:translateY(-2px);box-shadow:0 8px 22px rgba(244,114,182,.5)}
+  .btn:active{transform:translateY(0)}
+  .stats{
+    display:flex;gap:22px;font-size:1.05rem;font-weight:600;flex-wrap:wrap;justify-content:center;
+    background:var(--panel);padding:12px 26px;border-radius:16px;
+    border:1px solid var(--panel-bd);
+  }
+  .stats span{color:var(--accent);font-variant-numeric:tabular-nums}
+  .stats .best{color:#fcd34d}
+  .board-wrap{position:relative;width:100%;max-width:560px}
+  #board{
+    display:grid;gap:10px;perspective:900px;width:100%;
+  }
+  #board.locked{pointer-events:none}
+  .card{
+    position:relative;aspect-ratio:1;cursor:pointer;
+    transform-style:preserve-3d;transition:transform .45s cubic-bezier(.4,.2,.2,1);
+    border-radius:14px;border:none;padding:0;background:transparent;
+  }
+  .card.flipped,.card.matched{transform:rotateY(180deg)}
+  .card.matched{cursor:default}
+  .card:focus-visible{outline:3px solid #fde68a;outline-offset:3px}
+  .card.miss{animation:shake .4s}
+  @keyframes shake{
+    0%,100%{transform:rotateY(180deg) translateX(0)}
+    25%{transform:rotateY(180deg) translateX(-7px)}
+    75%{transform:rotateY(180deg) translateX(7px)}
+  }
+  .face{
+    position:absolute;inset:0;border-radius:14px;
+    display:flex;align-items:center;justify-content:center;
+    backface-visibility:hidden;-webkit-backface-visibility:hidden;
+    user-select:none;
+  }
+  .back{
+    background:var(--card-back);
+    box-shadow:0 4px 12px rgba(0,0,0,.3), inset 0 0 0 2px rgba(255,255,255,.15);
+  }
+  .back::after{content:"?";font-size:clamp(1.2rem,5vw,2rem);font-weight:800;color:rgba(255,255,255,.85)}
+  .front{
+    background:var(--card-face);color:#111;
+    transform:rotateY(180deg);
+    font-size:clamp(1.4rem,6vw,2.8rem);
+    box-shadow:0 4px 12px rgba(0,0,0,.3);
+  }
+  .card.miss .front{background:var(--miss)}
+  .card.matched .front{background:var(--matched);animation:pop .4s ease}
+  @keyframes pop{0%{transform:rotateY(180deg) scale(1)}50%{transform:rotateY(180deg) scale(1.12)}100%{transform:rotateY(180deg) scale(1)}}
+  .overlay{
+    position:fixed;inset:0;background:rgba(15,12,41,.8);
+    display:flex;align-items:center;justify-content:center;
+    opacity:0;pointer-events:none;transition:opacity .35s;backdrop-filter:blur(4px);z-index:10;
+  }
+  .overlay.show{opacity:1;pointer-events:auto}
+  .win-card{
+    background:linear-gradient(160deg,#312e81,#1e1b4b);
+    border:1px solid rgba(255,255,255,.15);
+    padding:36px 40px;border-radius:24px;text-align:center;
+    box-shadow:0 20px 60px rgba(0,0,0,.5);transform:scale(.85);transition:transform .35s;
+    max-width:90vw;
+  }
+  .overlay.show .win-card{transform:scale(1)}
+  .win-card h2{font-size:2rem;margin-bottom:8px}
+  .win-card .emoji{font-size:3rem;margin-bottom:6px}
+  .win-card p{color:#cbd5e1;margin-bottom:6px;font-size:1.05rem}
+  .win-card p b{color:var(--accent)}
+  .win-card .newbest{color:#fcd34d;font-weight:700;margin-top:4px}
+  .win-card .btn{margin-top:18px}
+  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}
+  footer{font-size:.8rem;color:var(--foot);margin-top:6px}
+</style>
+</head>
+<body>
+  <h1>🧠 Emoji Memory Match</h1>
+
+  <div class="controls">
+    <div class="seg" id="difficulty" role="group" aria-label="Difficulty">
+      <button data-size="4" class="active" aria-pressed="true">4 × 4</button>
+      <button data-size="6" aria-pressed="false">6 × 6</button>
+      <button data-size="8" aria-pressed="false">8 × 8</button>
+    </div>
+    <button class="btn" id="restart">↻ Restart</button>
+    <button class="icon-btn" id="soundToggle" title="Toggle sound" aria-pressed="true">🔊</button>
+    <button class="icon-btn" id="themeToggle" title="Toggle light / dark theme">🌙</button>
+  </div>
+
+  <div class="stats" aria-hidden="true">
+    <div>Moves: <span id="moves">0</span></div>
+    <div>Time: <span id="time">0:00</span></div>
+    <div>Pairs: <span id="pairs">0 / 0</span></div>
+    <div class="best">Best: <span id="best">—</span></div>
+  </div>
+
+  <div class="board-wrap">
+    <div id="board" role="grid" aria-label="Memory board"></div>
+  </div>
+
+  <div class="sr-only" role="status" aria-live="polite" id="live"></div>
+
+  <div class="overlay" id="overlay" role="dialog" aria-modal="true" aria-labelledby="winTitle">
+    <div class="win-card">
+      <div class="emoji">🎉</div>
+      <h2 id="winTitle">You Won!</h2>
+      <p>Solved in <b id="winMoves">0</b> moves</p>
+      <p>Time: <b id="winTime">0:00</b></p>
+      <p class="newbest" id="newBest" hidden>🏆 New best time!</p>
+      <button class="btn" id="playAgain">Play Again</button>
+    </div>
+  </div>
+
+  <footer>Free-Roster · flip two cards to find a match · use mouse or keyboard</footer>
+
+<script>
+  const EMOJIS = ['🍕','🎸','🚀','🐱','🌈','⚽','🎮','🍩','🦊','🌵','🐙','🎈',
+                  '🍔','🦄','🎧','🍦','🐳','🔥','🌸','🎲','🧩','🍭','🐢','🎁',
+                  '🐝','🌙','🍉','🎯','🦋','🍄','⭐','🐧','🍎','🐸','🎃','🌻',
+                  '🍇','🐬','🎹','🍓','🦖','🌴','🍒','🐨','🎨','🍿','🦉','🌊'];
+
+  const board   = document.getElementById('board');
+  const movesEl = document.getElementById('moves');
+  const timeEl  = document.getElementById('time');
+  const pairsEl = document.getElementById('pairs');
+  const bestEl  = document.getElementById('best');
+  const liveEl  = document.getElementById('live');
+  const overlay = document.getElementById('overlay');
+
+  let size = 4, first = null, lock = false;
+  let moves = 0, matched = 0, totalPairs = 0;
+  let timer = null, seconds = 0, started = false;
+  let soundOn = localStorage.getItem('freeRoster.sound') !== 'off';
+
+  /* ---- self-contained Web Audio sound engine (no files) ---- */
+  let audioCtx = null;
+  function tone(freq, start, dur, type='sine', gain=0.18){
+    if(!audioCtx) return;
+    const o = audioCtx.createOscillator(), g = audioCtx.createGain();
+    o.type = type; o.frequency.value = freq;
+    o.connect(g); g.connect(audioCtx.destination);
+    const t0 = audioCtx.currentTime + start;
+    g.gain.setValueAtTime(0, t0);
+    g.gain.linearRampToValueAtTime(gain, t0 + 0.01);
+    g.gain.exponentialRampToValueAtTime(0.0001, t0 + dur);
+    o.start(t0); o.stop(t0 + dur);
+  }
+  function ensureAudio(){
+    if(!soundOn) return;
+    if(!audioCtx){
+      const AC = window.AudioContext || window.webkitAudioContext;
+      if(AC) audioCtx = new AC();
+    }
+    if(audioCtx && audioCtx.state === 'suspended') audioCtx.resume();
+  }
+  const sfx = {
+    flip(){ if(soundOn){ ensureAudio(); tone(520, 0, 0.09, 'triangle', 0.14); } },
+    match(){ if(soundOn){ ensureAudio(); tone(660,0,0.12,'sine',0.18); tone(880,0.08,0.16,'sine',0.16); } },
+    miss(){ if(soundOn){ ensureAudio(); tone(200,0,0.18,'sawtooth',0.12); } },
+    win(){ if(soundOn){ ensureAudio(); [523,659,784,1047].forEach((f,i)=>tone(f, i*0.13, 0.28, 'sine', 0.18)); } }
+  };
+
+  const fmt = s => Math.floor(s/60) + ':' + String(s%60).padStart(2,'0');
+  const bestKey = () => 'freeRoster.best.' + size;
+  const say = msg => { liveEl.textContent = msg; };
+
+  function shuffle(a){
+    for(let i=a.length-1;i>0;i--){
+      const j = Math.floor(Math.random()*(i+1));
+      [a[i],a[j]]=[a[j],a[i]];
+    }
+    return a;
+  }
+
+  function loadBest(){
+    const raw = localStorage.getItem(bestKey());
+    if(!raw){ bestEl.textContent = '—'; return null; }
+    try{
+      const b = JSON.parse(raw);
+      bestEl.textContent = fmt(b.seconds) + ' · ' + b.moves + ' mv';
+      return b;
+    }catch{ bestEl.textContent = '—'; return null; }
+  }
+
+  function startTimer(){
+    if(started) return;
+    started = true;
+    timer = setInterval(()=>{ seconds++; timeEl.textContent = fmt(seconds); }, 1000);
+  }
+  function stopTimer(){ clearInterval(timer); timer = null; }
+
+  function newGame(){
+    stopTimer();
+    started = false; seconds = 0; moves = 0; matched = 0; first = null; lock = false;
+    totalPairs = (size*size)/2;
+    movesEl.textContent = '0';
+    timeEl.textContent = '0:00';
+    pairsEl.textContent = '0 / ' + totalPairs;
+    overlay.classList.remove('show');
+    board.classList.remove('locked');
+    loadBest();
+
+    const chosen = shuffle([...EMOJIS]).slice(0, totalPairs);
+    const deck = shuffle([...chosen, ...chosen]);
+
+    board.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
+    board.innerHTML = '';
+
+    deck.forEach((emoji)=>{
+      const card = document.createElement('button');
+      card.className = 'card';
+      card.type = 'button';
+      card.dataset.emoji = emoji;
+      card.setAttribute('aria-label', 'Hidden card');
+      card.innerHTML = `<span class="face back" aria-hidden="true"></span><span class="face front" aria-hidden="true">${emoji}</span>`;
+      card.addEventListener('click', ()=>flip(card));
+      board.appendChild(card);
+    });
+    say(size + ' by ' + size + ' game started. ' + totalPairs + ' pairs.');
+  }
+
+  function flip(card){
+    if(lock) return;
+    if(card.classList.contains('flipped') || card.classList.contains('matched')) return;
+
+    startTimer();
+    sfx.flip();
+    card.classList.add('flipped');
+    card.setAttribute('aria-label', card.dataset.emoji);
+
+    if(!first){ first = card; return; }
+    if(first === card) return;
+
+    moves++;
+    movesEl.textContent = moves;
+
+    if(first.dataset.emoji === card.dataset.emoji){
+      const a = first; first = null;
+      a.classList.add('matched');
+      card.classList.add('matched');
+      a.setAttribute('aria-label', a.dataset.emoji + ', matched');
+      card.setAttribute('aria-label', card.dataset.emoji + ', matched');
+      matched++;
+      pairsEl.textContent = matched + ' / ' + totalPairs;
+      say('Match! ' + matched + ' of ' + totalPairs + ' pairs.');
+      if(matched === totalPairs){ win(); } else { sfx.match(); }
+    } else {
+      lock = true;
+      board.classList.add('locked');
+      const a = first, b = card;
+      first = null;
+      a.classList.add('miss'); b.classList.add('miss');
+      sfx.miss();
+      say('No match.');
+      setTimeout(()=>{
+        [a,b].forEach(c=>{
+          c.classList.remove('flipped','miss');
+          c.setAttribute('aria-label','Hidden card');
+        });
+        lock = false;
+        board.classList.remove('locked');
+      }, 800);
+    }
+  }
+
+  function win(){
+    stopTimer();
+    const prev = loadBest();
+    const isBest = !prev || seconds < prev.seconds ||
+                   (seconds === prev.seconds && moves < prev.moves);
+    if(isBest){
+      localStorage.setItem(bestKey(), JSON.stringify({seconds, moves}));
+      loadBest();
+    }
+    document.getElementById('winMoves').textContent = moves;
+    document.getElementById('winTime').textContent = fmt(seconds);
+    document.getElementById('newBest').hidden = !isBest;
+    say('You won in ' + moves + ' moves and ' + fmt(seconds) + '.');
+    sfx.win();
+    setTimeout(()=>{ overlay.classList.add('show'); document.getElementById('playAgain').focus(); }, 500);
+  }
+
+  document.getElementById('difficulty').addEventListener('click', (e)=>{
+    const b = e.target.closest('button');
+    if(!b) return;
+    document.querySelectorAll('#difficulty button').forEach(x=>{
+      const on = x === b;
+      x.classList.toggle('active', on);
+      x.setAttribute('aria-pressed', on ? 'true' : 'false');
+    });
+    size = parseInt(b.dataset.size, 10);
+    newGame();
+  });
+
+  document.getElementById('restart').addEventListener('click', newGame);
+  document.getElementById('playAgain').addEventListener('click', newGame);
+  // Close win overlay with Escape → restart
+  document.addEventListener('keydown', (e)=>{
+    if(e.key === 'Escape' && overlay.classList.contains('show')) newGame();
+  });
+
+  /* ---- sound toggle ---- */
+  const soundBtn = document.getElementById('soundToggle');
+  function renderSound(){
+    soundBtn.textContent = soundOn ? '🔊' : '🔇';
+    soundBtn.classList.toggle('off', !soundOn);
+    soundBtn.setAttribute('aria-pressed', soundOn ? 'true' : 'false');
+  }
+  soundBtn.addEventListener('click', ()=>{
+    soundOn = !soundOn;
+    localStorage.setItem('freeRoster.sound', soundOn ? 'on' : 'off');
+    renderSound();
+    if(soundOn){ ensureAudio(); sfx.flip(); }
+  });
+  renderSound();
+
+  /* ---- theme toggle ---- */
+  const themeBtn = document.getElementById('themeToggle');
+  function applyTheme(theme){
+    const light = theme === 'light';
+    document.body.classList.toggle('light', light);
+    themeBtn.textContent = light ? '☀️' : '🌙';
+    themeBtn.setAttribute('aria-label', light ? 'Switch to dark theme' : 'Switch to light theme');
+  }
+  applyTheme(localStorage.getItem('freeRoster.theme') || 'dark');
+  themeBtn.addEventListener('click', ()=>{
+    const next = document.body.classList.contains('light') ? 'dark' : 'light';
+    localStorage.setItem('freeRoster.theme', next);
+    applyTheme(next);
+  });
+
+  newGame();
+</script>
+</body>
+</html>
diff --git a/games/flappy-clone/FlappyClone.aa b/games/flappy-clone/FlappyClone.aa
new file mode 100644
index 0000000..a19602e
--- /dev/null
+++ b/games/flappy-clone/FlappyClone.aa
@@ -0,0 +1,673 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
+<meta name="theme-color" content="#4ec0ca">
+<title>Flappy Clone</title>
+<style>
+*{margin:0;padding:0;box-sizing:border-box}
+html,body{width:100%;height:100%;overflow:hidden;background:#1a1a2e;font-family:system-ui,-apple-system,sans-serif}
+canvas{display:block;margin:0 auto;background:#70c5ce;cursor:pointer;touch-action:none}
+</style>
+</head>
+<body>
+<canvas id="c"></canvas>
+<script>
+(function(){
+const canvas=document.getElementById('c');
+const ctx=canvas.getContext('2d');
+
+// ---- Virtual world: all game logic runs in a fixed 480x720 space. ----
+// The canvas is scaled to the display only at draw time, so resizing never
+// corrupts object positions and physics stays resolution-independent.
+const VW=480, VH=720;
+let cssW=VW, cssH=VH, dpr=1;
+
+function resize(){
+  const maxW=480, maxH=720;
+  const rw=window.innerWidth, rh=window.innerHeight;
+  // Fit the 480:720 (2:3) frame inside the viewport, allow slight upscale.
+  const s=Math.min(rw/maxW, rh/maxH, 1.5);
+  cssW=Math.floor(maxW*s);
+  cssH=Math.floor(maxH*s);
+  dpr=Math.min(window.devicePixelRatio||1, 2);
+  canvas.width=Math.floor(cssW*dpr);
+  canvas.height=Math.floor(cssH*dpr);
+  canvas.style.width=cssW+'px';
+  canvas.style.height=cssH+'px';
+}
+resize();
+window.addEventListener('resize',resize);
+
+// ---- Tunable constants (in virtual units / per 60Hz tick) ----
+const GRAVITY=0.35;
+const FLAP=-6.8;
+const PIPE_W=60;
+const PIPE_GAP=150;
+const PIPE_SPEED=2.2;
+const BIRD_R=16;
+const GROUND_H=80;
+const STEP=1000/60;            // fixed physics timestep (ms)
+
+let bird,pipes,score,best,state,frame,particles,clouds,hills,speed,gapSize,shake;
+let muted=false;
+
+try{ best=parseInt(localStorage.getItem('flappy_best'))||0; }catch(e){ best=0; }
+try{ muted=localStorage.getItem('flappy_muted')==='1'; }catch(e){ muted=false; }
+
+// UI buttons in virtual coords (top-left, away from centered score).
+const BTN={size:30, y:14, muteX:14, pauseX:52};
+
+function init(){
+  bird={x:VW*0.28,y:VH*0.4,vy:0,rot:0,wing:0};
+  pipes=[];
+  score=0;
+  state='ready';
+  frame=0;
+  particles=[];
+  speed=PIPE_SPEED;
+  gapSize=PIPE_GAP;
+  shake=0;
+  spawnClouds();
+  spawnHills();
+}
+
+function spawnClouds(){
+  clouds=[];
+  for(let i=0;i<6;i++){
+    clouds.push({
+      x:Math.random()*VW*1.5,
+      y:VH*0.05+Math.random()*VH*0.35,
+      w:40+Math.random()*60,
+      speed:0.15+Math.random()*0.25,
+      op:0.4+Math.random()*0.4
+    });
+  }
+}
+
+function spawnHills(){
+  hills=[];
+  for(let i=0;i<8;i++){
+    hills.push({
+      x:i*VW*0.4+Math.random()*50,
+      y:VH-GROUND_H,
+      w:120+Math.random()*100,
+      h:40+Math.random()*80,
+      layer:i%2,
+      speed:0.3+(i%2)*0.2
+    });
+  }
+}
+
+function addPipe(){
+  const minY=100;
+  const maxY=VH-GROUND_H-gapSize-80;
+  const top=minY+Math.random()*(maxY-minY);
+  pipes.push({x:VW+10,top:top,gap:gapSize,passed:false});
+}
+
+// ---- Web Audio: tiny synthesized blips, no external assets ----
+let actx=null;
+function beep(freq,dur,type,vol,slideTo){
+  if(muted)return;
+  try{
+    if(!actx)actx=new (window.AudioContext||window.webkitAudioContext)();
+    if(actx.state==='suspended')actx.resume();
+    const o=actx.createOscillator(), g=actx.createGain();
+    o.type=type||'square';
+    const t=actx.currentTime;
+    o.frequency.setValueAtTime(freq,t);
+    if(slideTo)o.frequency.exponentialRampToValueAtTime(slideTo,t+dur);
+    g.gain.setValueAtTime((vol||0.15),t);
+    g.gain.exponentialRampToValueAtTime(0.0001,t+dur);
+    o.connect(g);g.connect(actx.destination);
+    o.start(t);o.stop(t+dur);
+  }catch(e){}
+}
+const sndFlap =()=>beep(520,0.09,'square',0.12,300);
+const sndScore=()=>{beep(660,0.08,'square',0.12);setTimeout(()=>beep(880,0.09,'square',0.12),70);};
+const sndHit  =()=>beep(180,0.25,'sawtooth',0.2,60);
+const sndDie  =()=>setTimeout(()=>beep(120,0.4,'triangle',0.18,50),120);
+
+function flap(){
+  if(state==='ready'){state='play';bird.vy=FLAP;sndFlap();}
+  else if(state==='play'){bird.vy=FLAP;burst(bird.x,bird.y,6,'#fff');sndFlap();}
+  else if(state==='over'){init();}
+  // if paused, flap does nothing (resume is via button/key)
+}
+
+function togglePause(){
+  if(state==='play')state='paused';
+  else if(state==='paused')state='play';
+}
+
+function toggleMute(){
+  muted=!muted;
+  try{localStorage.setItem('flappy_muted',muted?'1':'0');}catch(e){}
+}
+
+function burst(x,y,n,col){
+  for(let i=0;i<n;i++){
+    particles.push({
+      x,y,
+      vx:(Math.random()-0.5)*4,
+      vy:(Math.random()-0.5)*4-1,
+      life:20+Math.random()*15,
+      max:35,
+      col:col||'#ffd700',
+      r:2+Math.random()*3
+    });
+  }
+}
+
+// ---- Input: map pointer to virtual coords, test UI buttons first ----
+function toVirtual(clientX,clientY){
+  const r=canvas.getBoundingClientRect();
+  return {
+    x:(clientX-r.left)*(VW/r.width),
+    y:(clientY-r.top)*(VH/r.height)
+  };
+}
+function hitBtn(v,bx){
+  return v.x>=bx && v.x<=bx+BTN.size && v.y>=BTN.y && v.y<=BTN.y+BTN.size;
+}
+function handlePointer(clientX,clientY){
+  const v=toVirtual(clientX,clientY);
+  if(hitBtn(v,BTN.muteX)){toggleMute();return;}
+  if(hitBtn(v,BTN.pauseX)){ if(state==='play'||state==='paused')togglePause(); return; }
+  flap();
+}
+
+canvas.addEventListener('mousedown',e=>{e.preventDefault();handlePointer(e.clientX,e.clientY);});
+canvas.addEventListener('touchstart',e=>{
+  e.preventDefault();
+  const t=e.changedTouches[0];
+  handlePointer(t.clientX,t.clientY);
+},{passive:false});
+window.addEventListener('keydown',e=>{
+  if(e.code==='Space'||e.key===' '){e.preventDefault();flap();}
+  else if(e.key==='p'||e.key==='P'||e.code==='Escape'){e.preventDefault();togglePause();}
+  else if(e.key==='m'||e.key==='M'){e.preventDefault();toggleMute();}
+});
+// Pause when the tab/window loses focus so you don't die while away.
+window.addEventListener('blur',()=>{ if(state==='play')state='paused'; });
+
+function update(){
+  frame++;
+  if(shake>0)shake*=0.9;
+
+  // parallax (also drifts slowly on non-play screens)
+  const bgMul=(state==='play')?1:0.3;
+  clouds.forEach(c=>{
+    c.x-=c.speed*bgMul;
+    if(c.x+c.w<-10){c.x=VW+Math.random()*100;c.y=VH*0.05+Math.random()*VH*0.35;}
+  });
+  hills.forEach(h=>{
+    h.x-=h.speed*(state==='play'?1:0.2);
+    if(h.x+h.w<-10){h.x=VW+Math.random()*80;h.h=40+Math.random()*80;h.w=120+Math.random()*100;}
+  });
+
+  particles=particles.filter(p=>{
+    p.x+=p.vx;p.y+=p.vy;p.vy+=0.08;p.life--;
+    return p.life>0;
+  });
+
+  if(state!=='play')return;
+
+  bird.vy+=GRAVITY;
+  bird.y+=bird.vy;
+  bird.rot=Math.min(Math.PI/3,Math.max(-Math.PI/4,bird.vy*0.06));
+  bird.wing=Math.sin(frame*0.4)*0.4;
+
+  // soft ceiling: bonk instead of instant death (fairer than the original)
+  if(bird.y-BIRD_R<0){bird.y=BIRD_R;if(bird.vy<0)bird.vy=0;}
+
+  // difficulty ramps with score
+  const diff=Math.min(score*0.08,2.5);
+  speed=PIPE_SPEED+diff;
+  gapSize=Math.max(PIPE_GAP-score*2.5,100);
+
+  if(pipes.length===0||pipes[pipes.length-1].x<VW-180-diff*15){
+    addPipe();
+  }
+
+  for(let i=pipes.length-1;i>=0;i--){
+    const p=pipes[i];
+    p.x-=speed;
+    if(!p.passed&&p.x+PIPE_W<bird.x){
+      p.passed=true;
+      score++;
+      burst(bird.x+20,bird.y,8,'#ffd700');
+      sndScore();
+      if(score>best){best=score;try{localStorage.setItem('flappy_best',best);}catch(e){}}
+    }
+    if(p.x+PIPE_W<-10)pipes.splice(i,1);
+
+    // collision (circle-vs-rect, forgiving radius)
+    const bx=bird.x,by=bird.y,br=BIRD_R*0.85;
+    const px=p.x,pw=PIPE_W;
+    if(bx+br>px&&bx-br<px+pw){
+      if(by-br<p.top||by+br>p.top+p.gap){
+        die();
+      }
+    }
+  }
+
+  const groundY=VH-GROUND_H;
+  if(bird.y+BIRD_R>groundY)die();
+}
+
+function die(){
+  if(state!=='play')return;
+  state='over';
+  shake=12;
+  burst(bird.x,bird.y,20,'#ff6b6b');
+  burst(bird.x,bird.y,12,'#fff');
+  sndHit();sndDie();
+}
+
+function roundRect(x,y,w,h,r){
+  ctx.beginPath();
+  ctx.moveTo(x+r,y);
+  ctx.arcTo(x+w,y,x+w,y+h,r);
+  ctx.arcTo(x+w,y+h,x,y+h,r);
+  ctx.arcTo(x,y+h,x,y,r);
+  ctx.arcTo(x,y,x+w,y,r);
+  ctx.closePath();
+}
+
+function drawBg(){
+  const g=ctx.createLinearGradient(0,0,0,VH);
+  g.addColorStop(0,'#4ec0ca');
+  g.addColorStop(0.5,'#70c5ce');
+  g.addColorStop(1,'#b8e0e8');
+  ctx.fillStyle=g;
+  ctx.fillRect(0,0,VW,VH);
+
+  // sun
+  ctx.beginPath();
+  ctx.arc(VW*0.82,VH*0.12,30,0,Math.PI*2);
+  ctx.fillStyle='rgba(255,240,180,0.7)';
+  ctx.fill();
+  ctx.beginPath();
+  ctx.arc(VW*0.82,VH*0.12,18,0,Math.PI*2);
+  ctx.fillStyle='rgba(255,250,220,0.9)';
+  ctx.fill();
+
+  // clouds
+  clouds.forEach(c=>{
+    ctx.globalAlpha=c.op;
+    ctx.fillStyle='#fff';
+    drawCloud(c.x,c.y,c.w/50);
+  });
+  ctx.globalAlpha=1;
+
+  // hills (far then near)
+  hills.filter(h=>h.layer===0).forEach(h=>{
+    ctx.fillStyle='#5aad5a';
+    ctx.beginPath();
+    ctx.ellipse(h.x+h.w/2,h.y,h.w/2,h.h,0,Math.PI,0);
+    ctx.fill();
+  });
+  hills.filter(h=>h.layer===1).forEach(h=>{
+    ctx.fillStyle='#4a9a4a';
+    ctx.beginPath();
+    ctx.ellipse(h.x+h.w/2,h.y,h.w/2,h.h*1.1,0,Math.PI,0);
+    ctx.fill();
+  });
+}
+
+function drawCloud(x,y,s){
+  ctx.beginPath();
+  ctx.arc(x,y,12*s,0,Math.PI*2);
+  ctx.arc(x+16*s,y-6*s,14*s,0,Math.PI*2);
+  ctx.arc(x+34*s,y,13*s,0,Math.PI*2);
+  ctx.arc(x+16*s,y+4*s,11*s,0,Math.PI*2);
+  ctx.fill();
+}
+
+function drawGround(){
+  const gy=VH-GROUND_H;
+  ctx.fillStyle='#ded895';
+  ctx.fillRect(0,gy,VW,GROUND_H);
+  ctx.fillStyle='#5ee05e';
+  ctx.fillRect(0,gy,VW,14);
+  ctx.fillStyle='#4ec04e';
+  ctx.fillRect(0,gy+10,VW,6);
+  // scrolling grass tufts
+  const off=(frame*(state==='play'?speed:0.3)*0.5)%24;
+  ctx.fillStyle='#3da83d';
+  for(let x=-off;x<VW;x+=24){
+    ctx.beginPath();
+    ctx.moveTo(x,gy+14);
+    ctx.lineTo(x+8,gy);
+    ctx.lineTo(x+16,gy+14);
+    ctx.fill();
+  }
+  ctx.strokeStyle='#c4a84a';
+  ctx.lineWidth=2;
+  ctx.beginPath();
+  ctx.moveTo(0,gy);
+  ctx.lineTo(VW,gy);
+  ctx.stroke();
+}
+
+function drawPipes(){
+  const pw=PIPE_W;
+  pipes.forEach(p=>{
+    const cap=pw*0.15;
+    const grad1=ctx.createLinearGradient(p.x,0,p.x+pw,0);
+    grad1.addColorStop(0,'#3d9e2f');
+    grad1.addColorStop(0.3,'#5ed14a');
+    grad1.addColorStop(0.7,'#4caf3a');
+    grad1.addColorStop(1,'#2d7a22');
+    // top pipe body
+    ctx.fillStyle=grad1;
+    ctx.fillRect(p.x+2,0,pw-4,p.top);
+    roundRect(p.x-cap,p.top-28,pw+cap*2,28,4);
+    ctx.fill();
+    ctx.fillStyle='rgba(255,255,255,0.15)';
+    ctx.fillRect(p.x+4,0,6,p.top-28);
+    // bottom pipe
+    const by=p.top+p.gap;
+    ctx.fillStyle=grad1;
+    ctx.fillRect(p.x+2,by,pw-4,VH-by-GROUND_H);
+    roundRect(p.x-cap,by,pw+cap*2,28,4);
+    ctx.fill();
+    ctx.fillStyle='rgba(255,255,255,0.15)';
+    ctx.fillRect(p.x+4,by+28,6,VH-by-GROUND_H-28);
+    // outlines
+    ctx.strokeStyle='rgba(0,0,0,0.2)';
+    ctx.lineWidth=2;
+    ctx.strokeRect(p.x+2,0,pw-4,p.top-28);
+    ctx.strokeRect(p.x+2,by+28,pw-4,VH-by-GROUND_H-28);
+  });
+}
+
+function drawBird(){
+  const r=BIRD_R;
+  ctx.save();
+  ctx.translate(bird.x,bird.y);
+  ctx.rotate(bird.rot);
+
+  ctx.beginPath();
+  ctx.ellipse(0,0,r*1.1,r*0.95,0,0,Math.PI*2);
+  const bg=ctx.createRadialGradient(-r*0.3,-r*0.3,0,0,0,r);
+  bg.addColorStop(0,'#ffe566');
+  bg.addColorStop(1,'#f0c020');
+  ctx.fillStyle=bg;
+  ctx.fill();
+  ctx.strokeStyle='#d4a010';
+  ctx.lineWidth=1.5;
+  ctx.stroke();
+
+  ctx.save();
+  ctx.rotate(bird.wing);
+  ctx.beginPath();
+  ctx.ellipse(-2,2,r*0.65,r*0.4,0.3,0,Math.PI*2);
+  ctx.fillStyle='#f5d040';
+  ctx.fill();
+  ctx.strokeStyle='#d4a010';
+  ctx.lineWidth=1;
+  ctx.stroke();
+  ctx.restore();
+
+  ctx.beginPath();
+  ctx.arc(r*0.4,-r*0.25,r*0.38,0,Math.PI*2);
+  ctx.fillStyle='#fff';
+  ctx.fill();
+  ctx.strokeStyle='#333';
+  ctx.lineWidth=1;
+  ctx.stroke();
+  ctx.beginPath();
+  ctx.arc(r*0.5,-r*0.25,r*0.18,0,Math.PI*2);
+  ctx.fillStyle='#222';
+  ctx.fill();
+  ctx.beginPath();
+  ctx.arc(r*0.55,-r*0.35,r*0.08,0,Math.PI*2);
+  ctx.fillStyle='#fff';
+  ctx.fill();
+
+  ctx.beginPath();
+  ctx.moveTo(r*0.7,0);
+  ctx.lineTo(r*1.45,r*0.12);
+  ctx.lineTo(r*0.7,r*0.3);
+  ctx.closePath();
+  ctx.fillStyle='#ff8c00';
+  ctx.fill();
+  ctx.strokeStyle='#e07000';
+  ctx.lineWidth=1;
+  ctx.stroke();
+  ctx.beginPath();
+  ctx.moveTo(r*0.7,r*0.12);
+  ctx.lineTo(r*1.3,r*0.12);
+  ctx.strokeStyle='#e07000';
+  ctx.stroke();
+
+  ctx.beginPath();
+  ctx.ellipse(2,r*0.35,r*0.55,r*0.4,0,0,Math.PI*2);
+  ctx.fillStyle='rgba(255,255,255,0.35)';
+  ctx.fill();
+
+  ctx.restore();
+}
+
+function drawParticles(){
+  particles.forEach(p=>{
+    ctx.globalAlpha=p.life/p.max;
+    ctx.fillStyle=p.col;
+    ctx.beginPath();
+    ctx.arc(p.x,p.y,p.r*0.6,0,Math.PI*2);
+    ctx.fill();
+  });
+  ctx.globalAlpha=1;
+}
+
+function drawButtons(){
+  // Mute button
+  drawIconBtn(BTN.muteX,BTN.y,()=>{
+    ctx.strokeStyle='#fff';ctx.fillStyle='#fff';ctx.lineWidth=2;
+    const cx=BTN.muteX+9,cy=BTN.y+BTN.size/2;
+    ctx.beginPath();
+    ctx.moveTo(cx-4,cy-4);ctx.lineTo(cx,cy-4);ctx.lineTo(cx+5,cy-9);
+    ctx.lineTo(cx+5,cy+9);ctx.lineTo(cx,cy+4);ctx.lineTo(cx-4,cy+4);
+    ctx.closePath();ctx.fill();
+    if(muted){
+      ctx.beginPath();ctx.moveTo(cx+9,cy-6);ctx.lineTo(cx+16,cy+6);
+      ctx.moveTo(cx+16,cy-6);ctx.lineTo(cx+9,cy+6);ctx.stroke();
+    }else{
+      ctx.beginPath();ctx.arc(cx+8,cy,5,-0.6,0.6);ctx.stroke();
+      ctx.beginPath();ctx.arc(cx+8,cy,9,-0.6,0.6);ctx.stroke();
+    }
+  });
+  // Pause / play button (only while in a round)
+  if(state==='play'||state==='paused'){
+    drawIconBtn(BTN.pauseX,BTN.y,()=>{
+      ctx.fillStyle='#fff';
+      const cx=BTN.pauseX+BTN.size/2,cy=BTN.y+BTN.size/2;
+      if(state==='play'){
+        ctx.fillRect(cx-6,cy-7,4,14);
+        ctx.fillRect(cx+2,cy-7,4,14);
+      }else{
+        ctx.beginPath();
+        ctx.moveTo(cx-5,cy-7);ctx.lineTo(cx+7,cy);ctx.lineTo(cx-5,cy+7);
+        ctx.closePath();ctx.fill();
+      }
+    });
+  }
+}
+function drawIconBtn(x,y,drawIcon){
+  ctx.fillStyle='rgba(0,0,0,0.25)';
+  roundRect(x,y,BTN.size,BTN.size,7);ctx.fill();
+  drawIcon();
+}
+
+function medalFor(s){
+  if(s>=40)return{name:'PLATINUM',c1:'#e5e4e2',c2:'#b0c4de'};
+  if(s>=30)return{name:'GOLD',c1:'#ffd700',c2:'#daa520'};
+  if(s>=20)return{name:'SILVER',c1:'#e0e0e0',c2:'#a8a8a8'};
+  if(s>=10)return{name:'BRONZE',c1:'#cd7f32',c2:'#8c5a2b'};
+  return null;
+}
+
+function drawUI(){
+  ctx.textAlign='center';
+  ctx.textBaseline='middle';
+
+  if(state==='ready'){
+    ctx.font='bold 42px system-ui,sans-serif';
+    ctx.fillStyle='rgba(0,0,0,0.25)';
+    ctx.fillText('FLAPPY',VW/2+2,VH*0.22+2);
+    ctx.fillStyle='#fff';
+    ctx.strokeStyle='#e87a20';
+    ctx.lineWidth=4;
+    ctx.strokeText('FLAPPY',VW/2,VH*0.22);
+    ctx.fillText('FLAPPY',VW/2,VH*0.22);
+
+    ctx.font='bold 28px system-ui,sans-serif';
+    ctx.fillStyle='rgba(0,0,0,0.25)';
+    ctx.fillText('CLONE',VW/2+2,VH*0.29+2);
+    ctx.fillStyle='#ffd700';
+    ctx.strokeStyle='#c49000';
+    ctx.lineWidth=3;
+    ctx.strokeText('CLONE',VW/2,VH*0.29);
+    ctx.fillText('CLONE',VW/2,VH*0.29);
+
+    const pulse=0.7+Math.sin(frame*0.08)*0.3;
+    ctx.globalAlpha=pulse;
+    ctx.font='16px system-ui,sans-serif';
+    ctx.fillStyle='#fff';
+    ctx.strokeStyle='rgba(0,0,0,0.3)';
+    ctx.lineWidth=3;
+    ctx.strokeText('Click / Tap / Space to flap',VW/2,VH*0.55);
+    ctx.fillText('Click / Tap / Space to flap',VW/2,VH*0.55);
+    ctx.globalAlpha=1;
+
+    if(best>0){
+      ctx.font='14px system-ui,sans-serif';
+      ctx.fillStyle='rgba(255,255,255,0.75)';
+      ctx.fillText('Best: '+best,VW/2,VH*0.62);
+    }
+  }
+
+  if(state==='play'||state==='over'||state==='paused'){
+    ctx.font='bold 48px system-ui,sans-serif';
+    ctx.fillStyle='rgba(0,0,0,0.2)';
+    ctx.fillText(String(score),VW/2+2,VH*0.12+2);
+    ctx.fillStyle='#fff';
+    ctx.strokeStyle='rgba(0,0,0,0.4)';
+    ctx.lineWidth=4;
+    ctx.strokeText(String(score),VW/2,VH*0.12);
+    ctx.fillText(String(score),VW/2,VH*0.12);
+  }
+
+  if(state==='paused'){
+    ctx.fillStyle='rgba(0,0,0,0.35)';
+    ctx.fillRect(0,0,VW,VH);
+    ctx.font='bold 34px system-ui,sans-serif';
+    ctx.fillStyle='#fff';
+    ctx.fillText('PAUSED',VW/2,VH*0.44);
+    ctx.font='15px system-ui,sans-serif';
+    ctx.fillStyle='rgba(255,255,255,0.85)';
+    ctx.fillText('Press P or tap ▶ to resume',VW/2,VH*0.52);
+  }
+
+  if(state==='over'){
+    const pw=220,ph=200;
+    const px=(VW-pw)/2,py=VH*0.26;
+    ctx.fillStyle='rgba(0,0,0,0.45)';
+    roundRect(px+3,py+3,pw,ph,12);ctx.fill();
+    ctx.fillStyle='rgba(255,255,255,0.94)';
+    roundRect(px,py,pw,ph,12);ctx.fill();
+    ctx.strokeStyle='#e87a20';
+    ctx.lineWidth=3;
+    roundRect(px,py,pw,ph,12);ctx.stroke();
+
+    ctx.font='bold 28px system-ui,sans-serif';
+    ctx.fillStyle='#e74c3c';
+    ctx.fillText('GAME OVER',VW/2,py+32);
+
+    // medal
+    const med=medalFor(score);
+    const medX=px+42, medY=py+92;
+    if(med){
+      const mg=ctx.createRadialGradient(medX-6,medY-6,2,medX,medY,26);
+      mg.addColorStop(0,med.c1);mg.addColorStop(1,med.c2);
+      ctx.beginPath();ctx.arc(medX,medY,26,0,Math.PI*2);
+      ctx.fillStyle=mg;ctx.fill();
+      ctx.strokeStyle='rgba(0,0,0,0.25)';ctx.lineWidth=2;ctx.stroke();
+      ctx.font='9px system-ui,sans-serif';
+      ctx.fillStyle='rgba(0,0,0,0.55)';
+      ctx.fillText(med.name,medX,medY);
+    }else{
+      ctx.beginPath();ctx.arc(medX,medY,26,0,Math.PI*2);
+      ctx.strokeStyle='#ccc';ctx.setLineDash([4,4]);ctx.lineWidth=2;ctx.stroke();
+      ctx.setLineDash([]);
+      ctx.font='9px system-ui,sans-serif';ctx.fillStyle='#bbb';
+      ctx.fillText('—',medX,medY);
+    }
+
+    ctx.textAlign='left';
+    ctx.font='13px system-ui,sans-serif';
+    ctx.fillStyle='#888';
+    ctx.fillText('SCORE',px+92,py+78);
+    ctx.fillText('BEST',px+92,py+112);
+    ctx.font='bold 26px system-ui,sans-serif';
+    ctx.fillStyle='#333';
+    ctx.fillText(String(score),px+92,py+98);
+    ctx.fillStyle=(score>=best&&score>0)?'#e87a20':'#333';
+    ctx.fillText(String(best),px+92,py+132);
+    ctx.textAlign='center';
+
+    if(score>=best&&score>0){
+      ctx.font='bold 12px system-ui,sans-serif';
+      ctx.fillStyle='#e87a20';
+      ctx.fillText('NEW BEST!',VW/2,py+160);
+    }
+
+    const bp=0.85+Math.sin(frame*0.1)*0.15;
+    ctx.globalAlpha=bp;
+    ctx.font='14px system-ui,sans-serif';
+    ctx.fillStyle='#e87a20';
+    ctx.fillText('Click / Space to restart',VW/2,py+183);
+    ctx.globalAlpha=1;
+  }
+}
+
+function render(){
+  const s=cssW/VW;                 // uniform virtual->CSS scale (aspect preserved)
+  ctx.setTransform(dpr*s,0,0,dpr*s,0,0);
+  ctx.clearRect(0,0,VW,VH);
+  ctx.save();
+  if(shake>0){
+    ctx.translate((Math.random()-0.5)*shake,(Math.random()-0.5)*shake);
+  }
+  drawBg();
+  drawPipes();
+  drawGround();
+  drawBird();
+  drawParticles();
+  ctx.restore();
+  drawButtons();
+  drawUI();
+}
+
+// ---- Fixed-timestep main loop: physics is framerate-independent ----
+let last=performance.now(), acc=0;
+function loop(now){
+  let dt=now-last; last=now;
+  if(dt>250)dt=250;              // clamp after tab-switch / stalls
+  acc+=dt;
+  let steps=0;
+  while(acc>=STEP && steps<5){ update(); acc-=STEP; steps++; }
+  render();
+  requestAnimationFrame(loop);
+}
+
+init();
+requestAnimationFrame(loop);
+})();
+</script>
+</body>
+</html>
diff --git a/games/flappy-flight/FlappyFlight.aa b/games/flappy-flight/FlappyFlight.aa
new file mode 100644
index 0000000..f647b99
--- /dev/null
+++ b/games/flappy-flight/FlappyFlight.aa
@@ -0,0 +1,645 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
+<meta name="theme-color" content="#0e1420">
+<meta name="description" content="Flappy Flight — a polished, self-contained Flappy-Bird-style game. No assets, no libraries.">
+<title>Flappy Flight</title>
+<style>
+  * { margin: 0; padding: 0; box-sizing: border-box; }
+  html, body {
+    width: 100%; height: 100%;
+    background: #0e1420;
+    overflow: hidden;
+    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
+    -webkit-user-select: none; user-select: none;
+    touch-action: manipulation;
+  }
+  #wrap {
+    position: absolute; inset: 0;
+    display: flex; align-items: center; justify-content: center;
+  }
+  canvas {
+    display: block;
+    border-radius: 12px;
+    box-shadow: 0 20px 60px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.06);
+    cursor: pointer;
+  }
+</style>
+</head>
+<body>
+<div id="wrap"><canvas id="game" aria-label="Flappy Flight game canvas" role="img"></canvas></div>
+<script>
+(() => {
+'use strict';
+
+const canvas = document.getElementById('game');
+const ctx = canvas.getContext('2d');
+
+// ---------- sizing ----------
+const GW = 420, GH = 640;          // logical game size
+let scale = 1;
+function resize() {
+  const dpr = Math.min(window.devicePixelRatio || 1, 2);
+  const availW = window.innerWidth, availH = window.innerHeight;
+  scale = Math.min(availW / GW, availH / GH) * 0.98;
+  canvas.style.width  = (GW * scale) + 'px';
+  canvas.style.height = (GH * scale) + 'px';
+  canvas.width  = Math.round(GW * scale * dpr);
+  canvas.height = Math.round(GH * scale * dpr);
+  ctx.setTransform(canvas.width / GW, 0, 0, canvas.height / GH, 0, 0);
+}
+window.addEventListener('resize', resize);
+resize();
+
+// ---------- game clock ----------
+// A single monotonic clock that ONLY advances while the game is actively
+// running (never during a pause). All time-based visuals read from this so a
+// pause genuinely freezes the whole scene instead of letting the sky, clouds,
+// and parallax hills keep drifting.
+let clock = 0;
+
+// ---------- audio (generated, no assets) ----------
+let actx = null;
+let muted = false;
+try { muted = localStorage.getItem('ff_muted') === '1'; } catch (e) {}
+function audio() {
+  if (muted) return null;
+  if (!actx) { try { actx = new (window.AudioContext || window.webkitAudioContext)(); } catch(e){} }
+  if (actx && actx.state === 'suspended') actx.resume();
+  return actx;
+}
+function beep(freq, dur, type, vol, slide) {
+  const a = audio(); if (!a) return;
+  const o = a.createOscillator(), g = a.createGain();
+  o.type = type || 'sine';
+  o.frequency.setValueAtTime(freq, a.currentTime);
+  if (slide) o.frequency.exponentialRampToValueAtTime(Math.max(slide, 1), a.currentTime + dur);
+  g.gain.setValueAtTime(vol || 0.08, a.currentTime);
+  g.gain.exponentialRampToValueAtTime(0.0001, a.currentTime + dur);
+  o.connect(g); g.connect(a.destination);
+  o.start(); o.stop(a.currentTime + dur);
+}
+const sfx = {
+  flap:  () => beep(430, 0.09, 'triangle', 0.06, 620),
+  score: () => { beep(880, 0.09, 'sine', 0.07); setTimeout(() => beep(1320, 0.12, 'sine', 0.07), 70); },
+  hit:   () => beep(200, 0.25, 'sawtooth', 0.10, 60),
+  swoosh:() => beep(320, 0.18, 'sine', 0.04, 90)
+};
+function toggleMute() {
+  muted = !muted;
+  try { localStorage.setItem('ff_muted', muted ? '1' : '0'); } catch (e) {}
+  if (!muted) sfx.swoosh();
+}
+
+// ---------- constants ----------
+const GROUND_H = 88;
+const SKY_H = GH - GROUND_H;
+const GRAVITY = 1350;          // px/s^2
+const FLAP_V = -410;           // px/s
+const MAX_FALL = 620;
+const BIRD_X = GW * 0.30;
+const BIRD_R = 14;
+const PIPE_W = 66;
+
+// speaker icon hit-box (top-right), in logical coords
+const SPK = { x: GW - 40, y: 26, w: 30, h: 26 };
+
+// difficulty ramps with score
+function diff(score) {
+  const t = Math.min(score / 30, 1);
+  return {
+    speed: 145 + 95 * t,                       // scroll speed px/s
+    gap:   Math.max(196 - score * 2.2, 128),   // gap height
+    spacing: Math.max(258 - score * 1.6, 205)  // px between pipes
+  };
+}
+
+// ---------- state ----------
+const STATE = { READY: 0, PLAY: 1, DYING: 2, OVER: 3 };
+let state = STATE.READY;
+let paused = false;
+let bird, pipes, score, best, distSincePipe, shake, flash, wingT, deadT, overT, groundX;
+let clouds = [], stars = [];
+best = 0;
+try { best = +localStorage.getItem('ff_best') || 0; } catch(e) {}
+
+function seedScenery() {
+  clouds = [];
+  for (let i = 0; i < 7; i++) clouds.push({
+    x: Math.random() * GW, y: 30 + Math.random() * 200,
+    s: 0.5 + Math.random() * 0.9, layer: Math.random() < 0.5 ? 0 : 1
+  });
+  stars = [];
+  for (let i = 0; i < 26; i++) stars.push({
+    x: Math.random() * GW, y: Math.random() * SKY_H * 0.7,
+    r: 0.6 + Math.random() * 1.3, tw: Math.random() * Math.PI * 2
+  });
+}
+seedScenery();
+
+function reset() {
+  bird = { y: SKY_H * 0.45, v: 0, rot: 0 };
+  pipes = [];
+  score = 0;
+  distSincePipe = diff(0).spacing * 0.55;
+  shake = 0; flash = 0; wingT = 0; deadT = 0; overT = 0; groundX = 0;
+  paused = false;
+}
+reset();
+
+function spawnPipe() {
+  const d = diff(score);
+  const margin = 56;
+  const gapY = margin + Math.random() * (SKY_H - d.gap - margin * 2);
+  pipes.push({ x: GW + PIPE_W, gapY, gap: d.gap, scored: false, wob: Math.random() * Math.PI * 2 });
+}
+
+// ---------- input ----------
+function flap() {
+  if (paused) { paused = false; return; }   // any tap un-pauses
+  if (state === STATE.READY) {
+    state = STATE.PLAY;
+    bird.v = FLAP_V;
+    sfx.flap();
+    return;
+  }
+  if (state === STATE.PLAY) {
+    bird.v = FLAP_V;
+    wingT = 0;
+    sfx.flap();
+    return;
+  }
+  if (state === STATE.OVER && overT > 0.45) {
+    reset();
+    state = STATE.READY;
+    sfx.swoosh();
+  }
+}
+function togglePause() {
+  if (state !== STATE.PLAY) return;
+  paused = !paused;
+  if (!paused) sfx.swoosh();
+}
+window.addEventListener('keydown', e => {
+  if (e.code === 'Space' || e.code === 'ArrowUp' || e.code === 'KeyW') {
+    e.preventDefault();
+    if (!e.repeat) flap();
+  } else if (e.code === 'KeyP' || e.code === 'Escape') {
+    e.preventDefault();
+    if (!e.repeat) togglePause();
+  } else if (e.code === 'KeyM') {
+    e.preventDefault();
+    if (!e.repeat) toggleMute();
+  }
+});
+canvas.addEventListener('pointerdown', e => {
+  e.preventDefault();
+  // hit-test the speaker icon (convert client px -> logical coords)
+  const r = canvas.getBoundingClientRect();
+  const lx = (e.clientX - r.left) / r.width * GW;
+  const ly = (e.clientY - r.top) / r.height * GH;
+  if (lx >= SPK.x - 6 && lx <= SPK.x + SPK.w + 6 && ly >= SPK.y - 8 && ly <= SPK.y + SPK.h + 6) {
+    toggleMute();
+    return;
+  }
+  flap();
+});
+// auto-pause when the tab/window loses focus so you never come back mid-fall
+window.addEventListener('blur', () => { if (state === STATE.PLAY) paused = true; });
+document.addEventListener('visibilitychange', () => {
+  if (document.hidden && state === STATE.PLAY) paused = true;
+});
+
+// ---------- collision ----------
+function circleRect(cx, cy, r, rx, ry, rw, rh) {
+  const nx = Math.max(rx, Math.min(cx, rx + rw));
+  const ny = Math.max(ry, Math.min(cy, ry + rh));
+  const dx = cx - nx, dy = cy - ny;
+  return dx * dx + dy * dy < r * r;
+}
+
+function die() {
+  state = STATE.DYING;
+  deadT = 0;
+  shake = 1;
+  flash = 1;
+  bird.v = Math.min(bird.v, -220);
+  sfx.hit();
+  if (score > best) {
+    best = score;
+    try { localStorage.setItem('ff_best', best); } catch(e) {}
+  }
+}
+
+// ---------- update ----------
+function update(dt) {
+  const d = diff(score);
+  wingT += dt;
+  if (shake > 0) shake = Math.max(0, shake - dt * 2.6);
+  if (flash > 0) flash = Math.max(0, flash - dt * 3.2);
+
+  // parallax scenery always drifts a little
+  const sceneSpeed = (state === STATE.PLAY || state === STATE.READY) ? d.speed : 20;
+  for (const c of clouds) {
+    c.x -= sceneSpeed * (c.layer === 0 ? 0.18 : 0.32) * c.s * dt;
+    if (c.x < -120) { c.x = GW + 60 + Math.random() * 60; c.y = 30 + Math.random() * 200; }
+  }
+
+  if (state === STATE.READY) {
+    bird.y = SKY_H * 0.45 + Math.sin(clock * 2.63) * 9;
+    bird.rot = 0;
+    groundX = (groundX - d.speed * dt) % 24;
+    return;
+  }
+
+  if (state === STATE.PLAY) {
+    groundX = (groundX - d.speed * dt) % 24;
+
+    // bird physics
+    bird.v = Math.min(bird.v + GRAVITY * dt, MAX_FALL);
+    bird.y += bird.v * dt;
+    const target = bird.v < 0 ? -0.42 : Math.min(bird.v / MAX_FALL * 1.45, 1.35);
+    bird.rot += (target - bird.rot) * Math.min(1, dt * (bird.v < 0 ? 14 : 6));
+
+    // ceiling clamp
+    if (bird.y < BIRD_R) { bird.y = BIRD_R; bird.v = 0; }
+
+    // pipes
+    distSincePipe += d.speed * dt;
+    if (distSincePipe >= d.spacing) { distSincePipe = 0; spawnPipe(); }
+    for (const p of pipes) {
+      p.x -= d.speed * dt;
+      if (!p.scored && p.x + PIPE_W < BIRD_X - BIRD_R) {
+        p.scored = true;
+        score++;
+        sfx.score();
+      }
+      // collide
+      if (circleRect(BIRD_X, bird.y, BIRD_R - 1, p.x, -10, PIPE_W, p.gapY + 10) ||
+          circleRect(BIRD_X, bird.y, BIRD_R - 1, p.x, p.gapY + p.gap, PIPE_W, SKY_H - p.gapY - p.gap)) {
+        die();
+      }
+    }
+    pipes = pipes.filter(p => p.x > -PIPE_W - 10);
+
+    // ground
+    if (bird.y > SKY_H - BIRD_R) { bird.y = SKY_H - BIRD_R; die(); }
+    return;
+  }
+
+  if (state === STATE.DYING) {
+    deadT += dt;
+    bird.v = Math.min(bird.v + GRAVITY * 1.15 * dt, MAX_FALL * 1.2);
+    bird.y += bird.v * dt;
+    bird.rot = Math.min(bird.rot + dt * 7, Math.PI / 2);
+    if (bird.y >= SKY_H - BIRD_R) {
+      bird.y = SKY_H - BIRD_R;
+      state = STATE.OVER;
+      overT = 0;
+      sfx.swoosh();
+    }
+    return;
+  }
+
+  if (state === STATE.OVER) overT += dt;
+}
+
+// ---------- drawing ----------
+function roundRect(x, y, w, h, r) {
+  ctx.beginPath();
+  ctx.moveTo(x + r, y);
+  ctx.arcTo(x + w, y, x + w, y + h, r);
+  ctx.arcTo(x + w, y + h, x, y + h, r);
+  ctx.arcTo(x, y + h, x, y, r);
+  ctx.arcTo(x, y, x + w, y, r);
+  ctx.closePath();
+}
+
+function drawSky() {
+  const g = ctx.createLinearGradient(0, 0, 0, SKY_H);
+  g.addColorStop(0, '#1b2a52');
+  g.addColorStop(0.55, '#3f5f9e');
+  g.addColorStop(1, '#7fa8d9');
+  ctx.fillStyle = g;
+  ctx.fillRect(0, 0, GW, SKY_H);
+
+  // stars (subtle, twinkling in the upper sky)
+  const t = clock;
+  for (const s of stars) {
+    const a = 0.25 + 0.25 * Math.sin(t * 2 + s.tw);
+    ctx.fillStyle = `rgba(255,255,240,${a.toFixed(3)})`;
+    ctx.beginPath(); ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2); ctx.fill();
+  }
+
+  // moon
+  ctx.fillStyle = 'rgba(255,248,220,0.9)';
+  ctx.beginPath(); ctx.arc(GW - 74, 78, 26, 0, Math.PI * 2); ctx.fill();
+  ctx.fillStyle = 'rgba(63,95,158,0.55)';
+  ctx.beginPath(); ctx.arc(GW - 84, 70, 22, 0, Math.PI * 2); ctx.fill();
+}
+
+function drawCloudShape(x, y, s, alpha) {
+  ctx.fillStyle = `rgba(255,255,255,${alpha})`;
+  ctx.beginPath();
+  ctx.arc(x, y, 18 * s, 0, Math.PI * 2);
+  ctx.arc(x + 22 * s, y - 8 * s, 14 * s, 0, Math.PI * 2);
+  ctx.arc(x + 42 * s, y, 16 * s, 0, Math.PI * 2);
+  ctx.arc(x + 20 * s, y + 6 * s, 15 * s, 0, Math.PI * 2);
+  ctx.fill();
+}
+
+function drawParallax() {
+  // far clouds
+  for (const c of clouds) if (c.layer === 0) drawCloudShape(c.x, c.y, c.s * 0.8, 0.16);
+
+  // far mountain ridge (drifts with a slow phase tied to the game clock)
+  const t = clock;
+  ctx.fillStyle = 'rgba(38,58,102,0.85)';
+  ctx.beginPath();
+  ctx.moveTo(0, SKY_H);
+  for (let x = 0; x <= GW; x += 8) {
+    const y = SKY_H - 96 - Math.sin((x + t * 12) * 0.012) * 34 - Math.sin((x + t * 12) * 0.031) * 16;
+    ctx.lineTo(x, y);
+  }
+  ctx.lineTo(GW, SKY_H); ctx.closePath(); ctx.fill();
+
+  // near hills
+  ctx.fillStyle = 'rgba(52,84,128,0.95)';
+  ctx.beginPath();
+  ctx.moveTo(0, SKY_H);
+  for (let x = 0; x <= GW; x += 8) {
+    const y = SKY_H - 44 - Math.sin((x + t * 34) * 0.02) * 22 - Math.cos((x + t * 34) * 0.043) * 10;
+    ctx.lineTo(x, y);
+  }
+  ctx.lineTo(GW, SKY_H); ctx.closePath(); ctx.fill();
+
+  // near clouds
+  for (const c of clouds) if (c.layer === 1) drawCloudShape(c.x, c.y, c.s, 0.28);
+}
+
+function drawPipes() {
+  for (const p of pipes) {
+    const bodyG = ctx.createLinearGradient(p.x, 0, p.x + PIPE_W, 0);
+    bodyG.addColorStop(0, '#3f9d4e');
+    bodyG.addColorStop(0.35, '#6fce74');
+    bodyG.addColorStop(0.6, '#57b95f');
+    bodyG.addColorStop(1, '#2f7a3b');
+
+    // top pipe
+    ctx.fillStyle = bodyG;
+    ctx.fillRect(p.x + 4, 0, PIPE_W - 8, p.gapY - 24);
+    roundRect(p.x, p.gapY - 26, PIPE_W, 26, 5); ctx.fill();
+    // bottom pipe
+    ctx.fillRect(p.x + 4, p.gapY + p.gap + 24, PIPE_W - 8, SKY_H - p.gapY - p.gap - 24);
+    roundRect(p.x, p.gapY + p.gap, PIPE_W, 26, 5); ctx.fill();
+
+    // rim highlights
+    ctx.fillStyle = 'rgba(255,255,255,0.22)';
+    ctx.fillRect(p.x + 9, 0, 6, p.gapY - 26);
+    ctx.fillRect(p.x + 9, p.gapY + p.gap + 26, 6, SKY_H - p.gapY - p.gap - 26);
+    ctx.fillStyle = 'rgba(0,0,0,0.18)';
+    ctx.fillRect(p.x + PIPE_W - 12, 0, 6, p.gapY - 26);
+    ctx.fillRect(p.x + PIPE_W - 12, p.gapY + p.gap + 26, 6, SKY_H - p.gapY - p.gap - 26);
+    // cap shading
+    ctx.fillStyle = 'rgba(255,255,255,0.18)';
+    ctx.fillRect(p.x + 3, p.gapY - 23, PIPE_W - 6, 5);
+    ctx.fillRect(p.x + 3, p.gapY + p.gap + 3, PIPE_W - 6, 5);
+  }
+}
+
+function drawGround() {
+  const g = ctx.createLinearGradient(0, SKY_H, 0, GH);
+  g.addColorStop(0, '#c9b26a');
+  g.addColorStop(0.12, '#9ac162');
+  g.addColorStop(0.16, '#77a94e');
+  g.addColorStop(1, '#5b8340');
+  ctx.fillStyle = g;
+  ctx.fillRect(0, SKY_H, GW, GROUND_H);
+
+  // striped turf edge
+  ctx.save();
+  ctx.beginPath(); ctx.rect(0, SKY_H, GW, 14); ctx.clip();
+  for (let x = groundX - 24; x < GW + 24; x += 24) {
+    ctx.fillStyle = 'rgba(255,255,255,0.16)';
+    ctx.beginPath();
+    ctx.moveTo(x, SKY_H); ctx.lineTo(x + 12, SKY_H);
+    ctx.lineTo(x + 4, SKY_H + 14); ctx.lineTo(x - 8, SKY_H + 14);
+    ctx.closePath(); ctx.fill();
+  }
+  ctx.restore();
+  ctx.fillStyle = 'rgba(0,0,0,0.20)';
+  ctx.fillRect(0, SKY_H, GW, 3);
+
+  // pebbles
+  ctx.fillStyle = 'rgba(0,0,0,0.10)';
+  for (let i = 0; i < 9; i++) {
+    const x = ((i * 97 + groundX * 2.5) % (GW + 40)) - 20;
+    ctx.beginPath(); ctx.arc(x, SKY_H + 34 + (i * 37 % 40), 3 + (i % 3), 0, Math.PI * 2); ctx.fill();
+  }
+}
+
+function drawBird() {
+  ctx.save();
+  ctx.translate(BIRD_X, bird.y);
+  ctx.rotate(bird.rot);
+
+  // body
+  const g = ctx.createRadialGradient(-4, -5, 3, 0, 0, BIRD_R + 4);
+  g.addColorStop(0, '#ffe38a');
+  g.addColorStop(0.6, '#ffc73d');
+  g.addColorStop(1, '#f0a020');
+  ctx.fillStyle = g;
+  ctx.beginPath(); ctx.ellipse(0, 0, BIRD_R + 2, BIRD_R, 0, 0, Math.PI * 2); ctx.fill();
+  ctx.strokeStyle = 'rgba(120,70,0,0.35)'; ctx.lineWidth = 1.5; ctx.stroke();
+
+  // wing (flaps). During pause, hold a neutral pose.
+  const flapping = (state === STATE.PLAY || state === STATE.READY) && !paused;
+  const wingA = flapping ? Math.sin(wingT * 22) * 0.9 - 0.2 : 0.6;
+  ctx.save();
+  ctx.translate(-3, 1);
+  ctx.rotate(wingA * 0.6);
+  ctx.fillStyle = '#f7b32b';
+  ctx.beginPath(); ctx.ellipse(-2, 2, 9, 6, -0.4, 0, Math.PI * 2); ctx.fill();
+  ctx.strokeStyle = 'rgba(120,70,0,0.3)'; ctx.lineWidth = 1; ctx.stroke();
+  ctx.restore();
+
+  // belly
+  ctx.fillStyle = 'rgba(255,250,230,0.85)';
+  ctx.beginPath(); ctx.ellipse(1, 5, 8, 5.5, 0, 0, Math.PI * 2); ctx.fill();
+
+  // eye
+  ctx.fillStyle = '#fff';
+  ctx.beginPath(); ctx.arc(6, -5, 5.4, 0, Math.PI * 2); ctx.fill();
+  ctx.fillStyle = '#222';
+  ctx.beginPath(); ctx.arc(7.6, -5, 2.5, 0, Math.PI * 2); ctx.fill();
+  ctx.fillStyle = '#fff';
+  ctx.beginPath(); ctx.arc(8.4, -6, 0.9, 0, Math.PI * 2); ctx.fill();
+
+  // beak
+  ctx.fillStyle = '#ff7043';
+  ctx.beginPath();
+  ctx.moveTo(12, -1); ctx.lineTo(21, 1.5); ctx.lineTo(12, 5);
+  ctx.closePath(); ctx.fill();
+  ctx.strokeStyle = 'rgba(150,40,0,0.4)'; ctx.lineWidth = 1; ctx.stroke();
+
+  ctx.restore();
+}
+
+function text(str, x, y, size, fill, align, weight) {
+  ctx.font = `${weight || 800} ${size}px 'Segoe UI', system-ui, sans-serif`;
+  ctx.textAlign = align || 'center';
+  ctx.textBaseline = 'middle';
+  ctx.lineWidth = Math.max(3, size * 0.14);
+  ctx.strokeStyle = 'rgba(20,30,50,0.85)';
+  ctx.strokeText(str, x, y);
+  ctx.fillStyle = fill;
+  ctx.fillText(str, x, y);
+}
+
+function drawSpeaker() {
+  const x = SPK.x, y = SPK.y + SPK.h / 2;
+  ctx.save();
+  ctx.globalAlpha = 0.9;
+  // speaker body
+  ctx.fillStyle = '#fff';
+  ctx.strokeStyle = 'rgba(20,30,50,0.8)';
+  ctx.lineWidth = 2;
+  ctx.beginPath();
+  ctx.moveTo(x, y - 4);
+  ctx.lineTo(x + 6, y - 4);
+  ctx.lineTo(x + 12, y - 10);
+  ctx.lineTo(x + 12, y + 10);
+  ctx.lineTo(x + 6, y + 4);
+  ctx.lineTo(x, y + 4);
+  ctx.closePath();
+  ctx.fill(); ctx.stroke();
+  if (muted) {
+    // red slash
+    ctx.strokeStyle = '#ff5a5a'; ctx.lineWidth = 2.6;
+    ctx.beginPath(); ctx.moveTo(x + 15, y - 8); ctx.lineTo(x + 25, y + 8); ctx.stroke();
+  } else {
+    // sound waves
+    ctx.strokeStyle = 'rgba(255,255,255,0.95)'; ctx.lineWidth = 2;
+    ctx.beginPath(); ctx.arc(x + 13, y, 6, -0.8, 0.8); ctx.stroke();
+    ctx.beginPath(); ctx.arc(x + 13, y, 10, -0.7, 0.7); ctx.stroke();
+  }
+  ctx.restore();
+}
+
+function drawUI() {
+  if (state === STATE.PLAY || state === STATE.DYING) {
+    text(String(score), GW / 2, 64, 52, '#fff');
+  }
+
+  if (state === STATE.READY) {
+    text('FLAPPY FLIGHT', GW / 2, 130, 40, '#ffe066');
+    const pulse = 0.75 + 0.25 * Math.sin(clock * 3.33);
+    ctx.globalAlpha = pulse;
+    text('Tap / Click / Space to flap', GW / 2, SKY_H * 0.66, 20, '#fff', 'center', 600);
+    ctx.globalAlpha = 1;
+    if (best > 0) text('Best: ' + best, GW / 2, SKY_H * 0.66 + 34, 17, '#cfe3ff', 'center', 600);
+    text('P pause  ·  M mute', GW / 2, SKY_H * 0.66 + 62, 13, 'rgba(255,255,255,0.7)', 'center', 600);
+
+    // hint arrow near bird
+    ctx.strokeStyle = 'rgba(255,255,255,0.7)';
+    ctx.lineWidth = 3;
+    const ay = bird.y - 40 - Math.sin(clock * 4) * 5;
+    ctx.beginPath();
+    ctx.moveTo(BIRD_X, ay + 16); ctx.lineTo(BIRD_X, ay);
+    ctx.moveTo(BIRD_X - 7, ay + 8); ctx.lineTo(BIRD_X, ay);
+    ctx.lineTo(BIRD_X + 7, ay + 8);
+    ctx.stroke();
+  }
+
+  if (state === STATE.OVER) {
+    const slide = Math.min(overT / 0.35, 1);
+    const ease = 1 - Math.pow(1 - slide, 3);
+    ctx.save();
+    ctx.globalAlpha = ease;
+    ctx.translate(0, (1 - ease) * -30);
+
+    // panel
+    const pw = 280, ph = 190, px = (GW - pw) / 2, py = 150;
+    ctx.fillStyle = 'rgba(18,28,48,0.92)';
+    roundRect(px, py, pw, ph, 14); ctx.fill();
+    ctx.strokeStyle = 'rgba(255,255,255,0.15)'; ctx.lineWidth = 2; ctx.stroke();
+
+    text('GAME OVER', GW / 2, py + 36, 30, '#ff8a65');
+    text('SCORE', GW / 2 - 66, py + 82, 14, '#9fb4d8', 'center', 600);
+    text(String(score), GW / 2 - 66, py + 112, 34, '#fff');
+    text('BEST', GW / 2 + 66, py + 82, 14, '#9fb4d8', 'center', 600);
+    text(String(best), GW / 2 + 66, py + 112, 34, score >= best && score > 0 ? '#ffe066' : '#fff');
+
+    // medal
+    if (score >= 10) {
+      const medal = score >= 40 ? '#ffd700' : score >= 25 ? '#c0c0c0' : '#cd7f32';
+      ctx.fillStyle = medal;
+      ctx.beginPath(); ctx.arc(GW / 2, py + 148, 13, 0, Math.PI * 2); ctx.fill();
+      ctx.strokeStyle = 'rgba(0,0,0,0.3)'; ctx.lineWidth = 2; ctx.stroke();
+      ctx.fillStyle = 'rgba(255,255,255,0.55)';
+      ctx.beginPath(); ctx.arc(GW / 2 - 4, py + 144, 4, 0, Math.PI * 2); ctx.fill();
+    }
+
+    if (overT > 0.45) {
+      const pulse = 0.7 + 0.3 * Math.sin(clock * 3.57);
+      ctx.globalAlpha = ease * pulse;
+      text('Tap or press Space to restart', GW / 2, py + ph + 40, 18, '#fff', 'center', 600);
+    }
+    ctx.restore();
+  }
+
+  if (paused && state === STATE.PLAY) {
+    ctx.fillStyle = 'rgba(10,16,28,0.55)';
+    ctx.fillRect(0, 0, GW, GH);
+    text('PAUSED', GW / 2, SKY_H * 0.42, 40, '#ffe066');
+    const pulse = 0.7 + 0.3 * Math.sin(clock * 3.33);
+    ctx.globalAlpha = pulse;
+    text('Tap or press P to resume', GW / 2, SKY_H * 0.42 + 42, 18, '#fff', 'center', 600);
+    ctx.globalAlpha = 1;
+  }
+
+  drawSpeaker();
+}
+
+function draw() {
+  ctx.save();
+  if (shake > 0) {
+    const s = shake * shake * 9;
+    ctx.translate((Math.random() - 0.5) * s, (Math.random() - 0.5) * s);
+  }
+  drawSky();
+  drawParallax();
+  drawPipes();
+  drawGround();
+  drawBird();
+  ctx.restore();
+
+  drawUI();
+
+  if (flash > 0) {
+    ctx.fillStyle = `rgba(255,255,255,${(flash * 0.75).toFixed(3)})`;
+    ctx.fillRect(0, 0, GW, GH);
+  }
+}
+
+// ---------- main loop ----------
+let last = performance.now();
+function frame(now) {
+  let dt = (now - last) / 1000;
+  last = now;
+  if (dt > 0.05) dt = 0.05;   // clamp after tab-switch
+  if (!paused) {
+    clock += dt;
+    update(dt);
+  }
+  draw();
+  requestAnimationFrame(frame);
+}
+requestAnimationFrame(frame);
+
+})();
+</script>
+</body>
+</html>
diff --git a/games/flappy-sky/FlappySky.aa b/games/flappy-sky/FlappySky.aa
new file mode 100644
index 0000000..3350124
--- /dev/null
+++ b/games/flappy-sky/FlappySky.aa
@@ -0,0 +1,832 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover" />
+<meta name="theme-color" content="#0e1018" />
+<meta name="description" content="Flappy Sky — a polished, self-contained Flappy-Bird-style game. Space, click, or tap to flap through neon gates." />
+<title>Flappy Sky</title>
+<style>
+  :root { --ink: #f8f8ff; }
+
+  html, body {
+    margin: 0;
+    padding: 0;
+    background: #0e1018;
+    overflow: hidden;
+    height: 100%;
+    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+    -webkit-tap-highlight-color: transparent;
+    touch-action: none;
+  }
+
+  canvas {
+    display: block;
+    background: radial-gradient(circle at 20% 20%, #586df2 0, #243046 40%, #0e1018 100%);
+    /* keeps focus outline from ever painting a box around the game */
+    outline: none;
+  }
+
+  /* --- overlay + ui --------------------------------------------------- */
+  #overlay {
+    position: absolute;
+    inset: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    pointer-events: none;
+    user-select: none;
+    padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
+    box-sizing: border-box;
+  }
+
+  #ui {
+    color: var(--ink);
+    text-align: center;
+    text-shadow: 0 2px 14px rgba(0,0,0,0.8);
+    transition: opacity .25s ease, transform .25s ease;
+    max-width: 92vw;
+  }
+  #ui.pop { animation: pop .4s cubic-bezier(.2,1.3,.4,1) both; }
+  @keyframes pop { 0% { transform: scale(.85); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
+
+  #title {
+    font-size: clamp(34px, 8vw, 54px);
+    font-weight: 900;
+    letter-spacing: 0.08em;
+    text-transform: uppercase;
+    margin: 0 0 6px;
+    background: linear-gradient(180deg, #fff 0%, #b9d3ff 60%, #72fffb 100%);
+    -webkit-background-clip: text;
+    background-clip: text;
+    -webkit-text-fill-color: transparent;
+    filter: drop-shadow(0 3px 10px rgba(0,0,0,.6));
+  }
+
+  #subtitle { font-size: clamp(13px, 3.4vw, 16px); opacity: 0.85; margin-bottom: 22px; }
+
+  /* medal + result block on game over */
+  #result { display: none; margin-bottom: 18px; }
+  #result.show { display: block; }
+  #medal {
+    width: 92px; height: 92px; margin: 4px auto 10px;
+    border-radius: 50%;
+    display: grid; place-items: center;
+    font-size: 34px;
+    box-shadow: 0 0 0 4px rgba(255,255,255,.15), 0 8px 24px rgba(0,0,0,.55), inset 0 2px 10px rgba(255,255,255,.4);
+    position: relative;
+  }
+  #medal::after {
+    content: ""; position: absolute; inset: 8px; border-radius: 50%;
+    border: 2px dashed rgba(255,255,255,.35);
+  }
+  .scoreline { display:flex; gap: 26px; justify-content:center; margin: 6px 0 2px; }
+  .scoreline .k { font-size: 11px; letter-spacing:.18em; text-transform:uppercase; opacity:.65; }
+  .scoreline .v { font-size: 30px; font-weight: 800; line-height: 1.05; }
+  #newbest { font-size: 12px; font-weight: 800; letter-spacing:.12em; color:#ffe07a;
+             text-transform: uppercase; margin-top: 6px; opacity: 0; }
+  #newbest.show { opacity: 1; animation: flick .8s ease-in-out infinite alternate; }
+  @keyframes flick { from { filter: brightness(1);} to { filter: brightness(1.6);} }
+
+  #prompt {
+    font-size: clamp(14px, 3.6vw, 17px);
+    opacity: 0.95;
+    display: inline-flex; align-items: center; gap: 8px;
+    padding: 10px 18px; border-radius: 999px;
+    background: rgba(255,255,255,.08);
+    border: 1px solid rgba(255,255,255,.16);
+    backdrop-filter: blur(3px);
+    animation: breathe 1.8s ease-in-out infinite;
+  }
+  @keyframes breathe { 0%,100% { transform: translateY(0);} 50% { transform: translateY(-4px);} }
+
+  /* --- HUD ------------------------------------------------------------ */
+  #scoreTop {
+    position: absolute;
+    top: calc(14px + env(safe-area-inset-top));
+    left: 50%;
+    transform: translateX(-50%);
+    color: #fff;
+    font-size: clamp(34px, 9vw, 52px);
+    font-weight: 900;
+    text-shadow: 0 3px 0 rgba(0,0,0,.35), 0 0 18px rgba(120,180,255,.5);
+    pointer-events: none;
+    transition: transform .08s ease;
+  }
+  #scoreTop.bump { transform: translateX(-50%) scale(1.28); }
+  #scoreTop.hidden { display: none; }
+
+  #best {
+    position: absolute;
+    top: calc(16px + env(safe-area-inset-top));
+    right: calc(14px + env(safe-area-inset-right));
+    color: rgba(255,255,255,.8);
+    font-size: 13px; font-weight: 700; letter-spacing:.05em;
+    text-shadow: 0 0 6px rgba(0,0,0,.8);
+    pointer-events: none;
+  }
+  #best.hidden { display: none; }
+
+  /* control buttons (mute / pause) */
+  #controls {
+    position: absolute;
+    top: calc(12px + env(safe-area-inset-top));
+    left: calc(12px + env(safe-area-inset-left));
+    display: flex; gap: 8px;
+  }
+  .btn {
+    width: 38px; height: 38px; border-radius: 10px;
+    border: 1px solid rgba(255,255,255,.18);
+    background: rgba(255,255,255,.07);
+    color: #fff; font-size: 17px; cursor: pointer;
+    display: grid; place-items: center;
+    backdrop-filter: blur(4px);
+    transition: background .15s ease, transform .1s ease;
+    -webkit-user-select: none; user-select: none;
+  }
+  .btn:hover { background: rgba(255,255,255,.16); }
+  .btn:active { transform: scale(.9); }
+
+  #smallInfo {
+    position: absolute;
+    bottom: calc(9px + env(safe-area-inset-bottom));
+    right: calc(12px + env(safe-area-inset-right));
+    font-size: 11px;
+    color: rgba(255,255,255,0.4);
+    text-shadow: 0 0 4px rgba(0,0,0,0.8);
+    pointer-events: none;
+  }
+
+  /* pause veil */
+  #pauseVeil {
+    position: absolute; inset: 0;
+    display: none; align-items: center; justify-content: center;
+    background: rgba(6,8,16,.55); backdrop-filter: blur(2px);
+    color: #fff; font-size: clamp(22px, 6vw, 34px); font-weight: 800;
+    letter-spacing: .12em; text-transform: uppercase; pointer-events: none;
+  }
+  #pauseVeil.show { display: flex; }
+
+  .hidden { display: none; }
+</style>
+</head>
+<body>
+<canvas id="game" tabindex="-1" aria-label="Flappy Sky game canvas"></canvas>
+
+<div id="scoreTop" class="hidden"><span id="scoreVal">0</span></div>
+<div id="best" class="hidden">Best <span id="bestVal">0</span></div>
+
+<div id="controls">
+  <button id="muteBtn" class="btn" title="Mute (M)" aria-label="Toggle sound">🔊</button>
+  <button id="pauseBtn" class="btn" title="Pause (P)" aria-label="Pause game">⏸</button>
+</div>
+
+<div id="overlay">
+  <div id="ui" class="pop">
+    <div id="title">FLAPPY SKY</div>
+    <div id="subtitle">Flap through the neon gates. How far can you fly?</div>
+
+    <div id="result">
+      <div id="medal">🥇</div>
+      <div class="scoreline">
+        <div><div class="k">Score</div><div class="v" id="rScore">0</div></div>
+        <div><div class="k">Best</div><div class="v" id="rBest">0</div></div>
+      </div>
+      <div id="newbest">★ New Best! ★</div>
+    </div>
+
+    <div id="prompt">Press <b>Space</b>, Click, or Tap to Start</div>
+  </div>
+</div>
+
+<div id="pauseVeil">Paused</div>
+
+<div id="smallInfo">Space / Click / Tap · P pause · M mute</div>
+
+<script>
+(function () {
+  "use strict";
+
+  const canvas = document.getElementById("game");
+  const ctx = canvas.getContext("2d", { alpha: false });
+
+  // ---- DOM refs -------------------------------------------------------
+  const overlay   = document.getElementById("overlay");
+  const ui        = document.getElementById("ui");
+  const uiPrompt  = document.getElementById("prompt");
+  const result    = document.getElementById("result");
+  const medalEl    = document.getElementById("medal");
+  const rScore    = document.getElementById("rScore");
+  const rBest     = document.getElementById("rBest");
+  const newbest   = document.getElementById("newbest");
+  const scoreTop  = document.getElementById("scoreTop");
+  const scoreVal  = document.getElementById("scoreVal");
+  const bestBox   = document.getElementById("best");
+  const bestVal   = document.getElementById("bestVal");
+  const pauseVeil = document.getElementById("pauseVeil");
+  const muteBtn   = document.getElementById("muteBtn");
+  const pauseBtn  = document.getElementById("pauseBtn");
+
+  const reduceMotion = window.matchMedia &&
+    window.matchMedia("(prefers-reduced-motion: reduce)").matches;
+
+  // ---- viewport -------------------------------------------------------
+  let W, H, scale, groundH;
+  function resize() {
+    const dpr = Math.min(window.devicePixelRatio || 1, 2.5);
+    W = window.innerWidth;
+    H = window.innerHeight;
+    canvas.width  = Math.round(W * dpr);
+    canvas.height = Math.round(H * dpr);
+    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
+    scale = Math.min(Math.max(Math.min(W, H) / 600, 0.6), 1.6);
+    groundH = Math.round(Math.min(90 * scale, H * 0.14));
+    initBackground();
+    // keep the idle bird sensibly placed after a rotate/resize
+    if (bird && state !== "playing") { bird.x = W * 0.3; bird.baseY = H * 0.42; }
+  }
+
+  // ---- tuning ---------------------------------------------------------
+  const GRAVITY = 1500;      // px/s^2
+  const FLAP    = -450;      // impulse
+  const PIPE_W  = 84;        // pipe width (px, scaled at draw)
+  const PIPE_INTERVAL_START = 1500;  // ms between pipes
+  const PIPE_INTERVAL_MIN   = 950;
+  const GAP_START = 200;     // px gap (pre-scale)
+  const GAP_MIN   = 138;
+  const SPEED_START = 200;   // px/s
+  const SPEED_MAX   = 400;
+  const RAMP = 25;           // score at which difficulty maxes out
+  const FIXED_DT = 1 / 120;  // physics step
+
+  // ---- state ----------------------------------------------------------
+  let state = "ready"; // ready | playing | paused | gameover
+  let bird, pipes, particles, stars, hills, ground;
+  let score = 0, best = 0;
+  let pipeInterval, gapSize, speed;
+  let timeSincePipe = 0;
+  let shake = 0, flashAlpha = 0, hitStop = 0;
+  let lastTime = 0, acc = 0;
+  let muted = false;
+  let bgScroll = 0;
+
+  try { best = parseInt(localStorage.getItem("flappy_sky_best"), 10) || 0; } catch (e) {}
+  try { muted = localStorage.getItem("flappy_sky_muted") === "1"; } catch (e) {}
+  bestVal.textContent = best;
+
+  // ---- audio (WebAudio, no assets) -----------------------------------
+  let actx = null;
+  function audio() {
+    if (!actx) {
+      try { actx = new (window.AudioContext || window.webkitAudioContext)(); }
+      catch (e) { actx = null; }
+    }
+    if (actx && actx.state === "suspended") actx.resume();
+    return actx;
+  }
+  function tone(freq, dur, type, vol, slideTo) {
+    if (muted) return;
+    const a = audio(); if (!a) return;
+    const t0 = a.currentTime;
+    const osc = a.createOscillator();
+    const g = a.createGain();
+    osc.type = type || "square";
+    osc.frequency.setValueAtTime(freq, t0);
+    if (slideTo) osc.frequency.exponentialRampToValueAtTime(Math.max(1, slideTo), t0 + dur);
+    g.gain.setValueAtTime(0.0001, t0);
+    g.gain.exponentialRampToValueAtTime(vol || 0.12, t0 + 0.008);
+    g.gain.exponentialRampToValueAtTime(0.0001, t0 + dur);
+    osc.connect(g); g.connect(a.destination);
+    osc.start(t0); osc.stop(t0 + dur + 0.02);
+  }
+  const sfx = {
+    flap:  () => tone(560, 0.12, "square",   0.10, 780),
+    score: () => { tone(720, 0.09, "triangle", 0.12); setTimeout(() => tone(960, 0.10, "triangle", 0.12), 70); },
+    hit:   () => { tone(200, 0.18, "sawtooth", 0.16, 80); },
+    die:   () => { tone(340, 0.5, "sine", 0.12, 60); },
+    swoosh:() => tone(300, 0.14, "sine", 0.05, 120)
+  };
+
+  // ---- background -----------------------------------------------------
+  function initBackground() {
+    stars = [];
+    const starCount = Math.round((W * H) / 16000);
+    for (let i = 0; i < starCount; i++) {
+      stars.push({
+        x: Math.random() * W,
+        y: Math.random() * (H - groundH) * 0.9,
+        r: Math.random() * 1.5 + 0.4,
+        speed: 6 + Math.random() * 12,
+        phase: Math.random() * Math.PI * 2,
+        tw: 1.2 + Math.random() * 1.6
+      });
+    }
+    hills = [
+      { base: 0.70, amp: 42 * scale, freq: 0.0042, speed: 16, off: 0,   color: "#141a33" },
+      { base: 0.78, amp: 58 * scale, freq: 0.0030, speed: 30, off: 240, color: "#0c1024" }
+    ];
+    ground = { off: 0 };
+  }
+
+  // ---- game objects ---------------------------------------------------
+  function resetGame() {
+    bird = { x: W * 0.3, baseY: H * 0.42, y: H * 0.42, vy: 0, r: 16 * scale, rot: 0, flapT: 0 };
+    pipes = [];
+    particles = [];
+    timeSincePipe = 0;
+    score = 0;
+    scoreVal.textContent = "0";
+    pipeInterval = PIPE_INTERVAL_START;
+    gapSize = GAP_START * scale;
+    speed = SPEED_START;
+    shake = 0; flashAlpha = 0; hitStop = 0;
+  }
+
+  function difficulty() {
+    const t = Math.min(score / RAMP, 1);
+    pipeInterval = PIPE_INTERVAL_START - (PIPE_INTERVAL_START - PIPE_INTERVAL_MIN) * t;
+    gapSize = (GAP_START - (GAP_START - GAP_MIN) * t) * scale;
+    speed = SPEED_START + (SPEED_MAX - SPEED_START) * t;
+  }
+
+  function spawnPipe() {
+    const playH = H - groundH;
+    const margin = Math.max(50 * scale, playH * 0.09);
+    const minTop = margin;
+    const maxTop = playH - margin - gapSize;
+    const top = maxTop <= minTop ? (playH - gapSize) / 2
+                                 : minTop + Math.random() * (maxTop - minTop);
+    // hue drifts a touch over the run so later pipes read hotter
+    const hue = 165 - Math.min(score, 40) * 1.2;
+    pipes.push({ x: W + PIPE_W, top: top, gap: gapSize, scored: false, hue: hue });
+  }
+
+  function addParticles(x, y, count, hue, power) {
+    if (reduceMotion) count = Math.ceil(count / 3);
+    for (let i = 0; i < count; i++) {
+      const ang = Math.random() * Math.PI * 2;
+      const mag = (Math.random() * 150 + 40) * scale * (power || 1);
+      particles.push({
+        x, y,
+        vx: Math.cos(ang) * mag,
+        vy: Math.sin(ang) * mag - 40 * scale,
+        life: 0.5 + Math.random() * 0.35, age: 0,
+        size: (Math.random() * 3 + 2) * scale,
+        hue: hue + (Math.random() * 30 - 15)
+      });
+    }
+  }
+
+  // ---- input (single unified path, dedupes touch+mouse) --------------
+  let lastFlap = 0;
+  function flap() {
+    audio(); // unlock on first gesture
+    const now = performance.now();
+    if (now - lastFlap < 55) return; // debounce double-fire (touch->mouse)
+    lastFlap = now;
+
+    if (state === "ready") {
+      startGame();
+      doFlap();
+    } else if (state === "playing") {
+      doFlap();
+    } else if (state === "paused") {
+      resume();
+    } else if (state === "gameover") {
+      // small guard so the death tap doesn't instantly restart
+      if (now - gameoverAt > 350) toReady();
+    }
+  }
+  function doFlap() {
+    bird.vy = FLAP;
+    bird.flapT = 1;
+    addParticles(bird.x - bird.r * 0.8, bird.y + bird.r * 0.4, 6, 205, 0.7);
+    sfx.flap();
+  }
+
+  function startGame() {
+    state = "playing";
+    ui.classList.remove("pop");
+    overlay.classList.add("hidden");
+    scoreTop.classList.remove("hidden");
+    bestBox.classList.remove("hidden");
+    result.classList.remove("show");
+    sfx.swoosh();
+  }
+
+  function toReady() {
+    state = "ready";
+    resetGame();
+    result.classList.remove("show");
+    newbest.classList.remove("show");
+    uiPrompt.textContent = "Press Space, Click, or Tap to Start";
+    overlay.classList.remove("hidden");
+    ui.classList.remove("pop"); void ui.offsetWidth; ui.classList.add("pop");
+    scoreTop.classList.add("hidden");
+    bestBox.classList.add("hidden");
+  }
+
+  let gameoverAt = 0;
+  function gameOver() {
+    if (state !== "playing") return;
+    state = "gameover";
+    gameoverAt = performance.now();
+    hitStop = 0.08;
+    shake = reduceMotion ? 0 : 16;
+    flashAlpha = reduceMotion ? 0.25 : 0.6;
+    addParticles(bird.x, bird.y, reduceMotion ? 10 : 30, 40, 1.5);
+    sfx.hit(); sfx.die();
+
+    const isBest = score > best;
+    if (isBest) { best = score; try { localStorage.setItem("flappy_sky_best", best); } catch (e) {} }
+    bestVal.textContent = best;
+
+    rScore.textContent = score;
+    rBest.textContent = best;
+    setMedal(score);
+    result.classList.add("show");
+    newbest.classList.toggle("show", isBest);
+    uiPrompt.textContent = "Click / Tap / Space to Play Again";
+
+    // reveal overlay a beat after the death punch
+    setTimeout(() => {
+      if (state === "gameover") {
+        overlay.classList.remove("hidden");
+        ui.classList.remove("pop"); void ui.offsetWidth; ui.classList.add("pop");
+      }
+    }, 260);
+  }
+
+  function setMedal(s) {
+    let icon = "🥉", bg = "linear-gradient(160deg,#c9865b,#8a5a34)";
+    if (s >= 40)      { icon = "💎"; bg = "linear-gradient(160deg,#8ef7ff,#2aa7c9)"; }
+    else if (s >= 25) { icon = "🥇"; bg = "linear-gradient(160deg,#ffe27a,#d3a520)"; }
+    else if (s >= 12) { icon = "🥈"; bg = "linear-gradient(160deg,#e8eef7,#9aa7bd)"; }
+    else if (s >= 4)  { icon = "🥉"; bg = "linear-gradient(160deg,#c9865b,#8a5a34)"; }
+    else              { icon = "🍃"; bg = "linear-gradient(160deg,#7f8aa3,#4a5570)"; }
+    medalEl.textContent = icon;
+    medalEl.style.background = bg;
+  }
+
+  // ---- pause ----------------------------------------------------------
+  function togglePause() {
+    if (state === "playing") pause();
+    else if (state === "paused") resume();
+  }
+  function pause() {
+    if (state !== "playing") return;
+    state = "paused";
+    pauseVeil.classList.add("show");
+    pauseBtn.textContent = "▶";
+  }
+  function resume() {
+    if (state !== "paused") return;
+    state = "playing";
+    pauseVeil.classList.remove("show");
+    pauseBtn.textContent = "⏸";
+    lastTime = performance.now(); acc = 0; // avoid a physics jump
+  }
+
+  function toggleMute() {
+    muted = !muted;
+    muteBtn.textContent = muted ? "🔇" : "🔊";
+    try { localStorage.setItem("flappy_sky_muted", muted ? "1" : "0"); } catch (e) {}
+    if (!muted) sfx.swoosh();
+  }
+  muteBtn.textContent = muted ? "🔇" : "🔊";
+
+  // ---- listeners ------------------------------------------------------
+  window.addEventListener("resize", resize);
+  window.addEventListener("orientationchange", resize);
+
+  document.addEventListener("keydown", (e) => {
+    if (e.code === "Space" || e.code === "ArrowUp" || e.code === "Enter") {
+      e.preventDefault(); flap();
+    } else if (e.code === "KeyP") {
+      e.preventDefault(); togglePause();
+    } else if (e.code === "KeyM") {
+      e.preventDefault(); toggleMute();
+    }
+  });
+
+  // pointer handles mouse + touch + pen uniformly; debounce covers the rest
+  canvas.addEventListener("pointerdown", (e) => { e.preventDefault(); flap(); });
+  overlay.addEventListener("pointerdown", (e) => { e.preventDefault(); flap(); });
+  // fallback for browsers without pointer events
+  if (!window.PointerEvent) {
+    canvas.addEventListener("mousedown", flap);
+    canvas.addEventListener("touchstart", (e) => { e.preventDefault(); flap(); }, { passive: false });
+  }
+
+  muteBtn.addEventListener("pointerdown", (e) => { e.stopPropagation(); e.preventDefault(); toggleMute(); });
+  pauseBtn.addEventListener("pointerdown", (e) => { e.stopPropagation(); e.preventDefault(); togglePause(); });
+
+  // auto-pause when the tab/window loses focus mid-game
+  document.addEventListener("visibilitychange", () => { if (document.hidden) pause(); });
+  window.addEventListener("blur", () => pause());
+
+  // ---- physics --------------------------------------------------------
+  function step(dt) {
+    bgScroll += dt;
+
+    // parallax always animates (even on menus) for a living background
+    for (const s of stars) {
+      s.x -= s.speed * dt;
+      if (s.x < -4) { s.x = W + 4; s.y = Math.random() * (H - groundH) * 0.9; }
+      s.phase += dt * s.tw;
+    }
+    for (const h of hills) h.off += h.speed * dt;
+
+    if (state === "playing") {
+      ground.off = (ground.off + speed * dt) % 48;
+      difficulty();
+
+      bird.flapT = Math.max(0, bird.flapT - dt * 6);
+      bird.vy += GRAVITY * dt;
+      bird.y  += bird.vy * dt;
+      bird.rot = Math.max(-0.55, Math.min(1.4, Math.atan2(bird.vy, 420)));
+
+      // soft ceiling — clamp instead of instant death (classic feel)
+      if (bird.y - bird.r < 0) { bird.y = bird.r; if (bird.vy < 0) bird.vy = 0; }
+
+      timeSincePipe += dt * 1000;
+      if (timeSincePipe >= pipeInterval) { timeSincePipe -= pipeInterval; spawnPipe(); }
+
+      const bx = bird.x, by = bird.y, br = bird.r * 0.82;
+      const pw = PIPE_W * scale;
+
+      for (let i = pipes.length - 1; i >= 0; i--) {
+        const p = pipes[i];
+        p.x -= speed * dt;
+        if (p.x + pw < -20) { pipes.splice(i, 1); continue; }
+
+        if (!p.scored && p.x + pw < bx) {
+          p.scored = true; score++;
+          scoreVal.textContent = score;
+          scoreTop.classList.remove("bump"); void scoreTop.offsetWidth; scoreTop.classList.add("bump");
+          sfx.score();
+        }
+        // circle-vs-rect collision (accurate)
+        if (hitPipe(bx, by, br, p, pw)) { gameOver(); return; }
+      }
+
+      // ground death
+      if (by + br > H - groundH) { bird.y = H - groundH - br; gameOver(); return; }
+    } else if (state === "ready" || state === "gameover") {
+      // clean bob around a fixed base — no accumulating drift
+      const t = bgScroll;
+      bird.y = bird.baseY + Math.sin(t * 2.4) * 8 * scale;
+      bird.rot = Math.sin(t * 1.6) * 0.18;
+    }
+
+    // particles
+    for (let i = particles.length - 1; i >= 0; i--) {
+      const p = particles[i];
+      p.age += dt;
+      if (p.age >= p.life) { particles.splice(i, 1); continue; }
+      p.x += p.vx * dt; p.y += p.vy * dt;
+      p.vy += 520 * dt; p.vx *= 0.986;
+    }
+
+    if (shake > 0)      shake = Math.max(0, shake - dt * 60);
+    if (flashAlpha > 0) flashAlpha = Math.max(0, flashAlpha - dt * 2.2);
+  }
+
+  function hitPipe(cx, cy, r, p, pw) {
+    // top rect: (p.x,0,pw,p.top) ; bottom rect: (p.x,p.top+gap,pw,rest)
+    const bottomY = p.top + p.gap;
+    return rectHit(cx, cy, r, p.x, 0, pw, p.top) ||
+           rectHit(cx, cy, r, p.x, bottomY, pw, (H - groundH) - bottomY);
+  }
+  function rectHit(cx, cy, r, rx, ry, rw, rh) {
+    const nx = Math.max(rx, Math.min(cx, rx + rw));
+    const ny = Math.max(ry, Math.min(cy, ry + rh));
+    const dx = cx - nx, dy = cy - ny;
+    return dx * dx + dy * dy < r * r;
+  }
+
+  // ---- rendering ------------------------------------------------------
+  function drawBackground() {
+    // Opaque full-frame sky. This is also the per-frame CLEAR — the canvas is
+    // created with { alpha: false }, so the CSS background never shows through
+    // and a translucent fill here would let every prior frame ghost through
+    // (the bird/pipes/particles smeared into a trail). Paint the sky solid.
+    const grd = ctx.createRadialGradient(W * 0.2, H * 0.2, 0, W * 0.2, H * 0.2, Math.max(W, H));
+    grd.addColorStop(0, "#586df2");
+    grd.addColorStop(0.4, "#243046");
+    grd.addColorStop(1, "#0e1018");
+    ctx.fillStyle = grd;
+    ctx.fillRect(0, 0, W, H);
+
+    for (const s of stars) {
+      const a = 0.25 + 0.55 * (0.5 + 0.5 * Math.sin(s.phase));
+      ctx.fillStyle = "rgba(230,240,255," + a.toFixed(3) + ")";
+      ctx.beginPath(); ctx.arc(s.x, s.y, s.r, 0, 6.2832); ctx.fill();
+    }
+
+    // haze band
+    const cy = H * 0.3;
+    const cg = ctx.createLinearGradient(0, cy - 80, 0, cy + 80);
+    cg.addColorStop(0, "rgba(160,190,255,0)");
+    cg.addColorStop(0.4, "rgba(150,180,255,0.07)");
+    cg.addColorStop(1, "rgba(80,110,170,0)");
+    ctx.fillStyle = cg;
+    ctx.fillRect(0, cy - 80, W, 160);
+
+    for (const h of hills) {
+      const baseY = (H - groundH) * h.base;
+      ctx.fillStyle = h.color;
+      ctx.beginPath();
+      ctx.moveTo(0, H);
+      for (let x = 0; x <= W + 24; x += 20) {
+        const y = baseY + Math.sin((x + h.off) * h.freq) * h.amp;
+        ctx.lineTo(x, y);
+      }
+      ctx.lineTo(W, H); ctx.closePath(); ctx.fill();
+    }
+  }
+
+  function drawPipes() {
+    const pw = PIPE_W * scale;
+    const lip = 14 * scale;
+    const playH = H - groundH;
+    for (const p of pipes) {
+      const bottomY = p.top + p.gap;
+      const c1 = "hsl(" + p.hue + ",90%,55%)";
+      const c2 = "hsl(" + (p.hue + 18) + ",95%,72%)";
+      const c3 = "hsl(" + (p.hue - 8) + ",85%,42%)";
+
+      ctx.save();
+      ctx.shadowColor = "hsla(" + p.hue + ",100%,60%,0.6)";
+      ctx.shadowBlur = reduceMotion ? 0 : 16;
+
+      drawPipeBody(p.x, 0, pw, p.top, c1, c2, c3, lip, true);
+      drawPipeBody(p.x, bottomY, pw, playH - bottomY, c1, c2, c3, lip, false);
+      ctx.restore();
+    }
+  }
+  function drawPipeBody(x, y, w, h, c1, c2, c3, lip, isTop) {
+    if (h <= 0) return;
+    const g = ctx.createLinearGradient(x, 0, x + w, 0);
+    g.addColorStop(0, c3); g.addColorStop(0.18, c1);
+    g.addColorStop(0.5, c2); g.addColorStop(0.82, c1); g.addColorStop(1, c3);
+    ctx.fillStyle = g;
+    // main shaft
+    ctx.fillRect(x, y, w, h);
+    // lip (mouth end)
+    const ly = isTop ? y + h - lip : y;
+    const lw = w + 8 * scale;
+    ctx.fillRect(x - 4 * scale, ly, lw, lip);
+    // glossy highlight
+    ctx.fillStyle = "rgba(255,255,255,0.22)";
+    ctx.fillRect(x + w * 0.16, y, w * 0.1, h);
+  }
+
+  function drawGround() {
+    const gy = H - groundH;
+    const g = ctx.createLinearGradient(0, gy, 0, H);
+    g.addColorStop(0, "#3a3f2e");
+    g.addColorStop(0.12, "#4a5136");
+    g.addColorStop(1, "#20241a");
+    ctx.fillStyle = g;
+    ctx.fillRect(0, gy, W, groundH);
+
+    // top rim
+    ctx.fillStyle = "rgba(120,200,150,0.35)";
+    ctx.fillRect(0, gy, W, 3 * scale);
+
+    // scrolling hatch
+    ctx.strokeStyle = "rgba(0,0,0,0.18)";
+    ctx.lineWidth = 2;
+    ctx.beginPath();
+    for (let x = -48 + (-ground.off); x < W + 48; x += 24) {
+      ctx.moveTo(x, gy + 6 * scale);
+      ctx.lineTo(x + 14, H);
+    }
+    ctx.stroke();
+  }
+
+  function drawBird() {
+    const b = bird;
+    ctx.save();
+    ctx.translate(b.x, b.y);
+    ctx.rotate(b.rot);
+    const R = b.r;
+
+    // body
+    const bg = ctx.createRadialGradient(-R * 0.2, -R * 0.2, R * 0.2, 0, 0, R * 1.2);
+    bg.addColorStop(0, "#fffbe6"); bg.addColorStop(0.5, "#ffe07a"); bg.addColorStop(1, "#ff9f3f");
+    ctx.fillStyle = bg;
+    ctx.beginPath(); ctx.ellipse(0, 0, R * 1.15, R * 0.92, 0, 0, 6.2832); ctx.fill();
+
+    // belly
+    ctx.fillStyle = "rgba(255,255,255,0.85)";
+    ctx.beginPath(); ctx.ellipse(-R * 0.1, R * 0.12, R * 0.68, R * 0.56, 0, 0, 6.2832); ctx.fill();
+
+    // wing — flap amplitude tied to flapT (springs on each flap)
+    const wingBase = state === "playing" ? (0.35 - bird.flapT * 1.3)
+                                         : Math.sin(bgScroll * 8) * 0.4;
+    ctx.save();
+    ctx.translate(-R * 0.1, 0);
+    ctx.rotate(-0.7 + wingBase);
+    const wg = ctx.createLinearGradient(-R * 0.2, -R * 0.4, R * 0.5, R * 0.6);
+    wg.addColorStop(0, "#ffe7a3"); wg.addColorStop(1, "#ffb25a");
+    ctx.fillStyle = wg;
+    ctx.beginPath(); ctx.ellipse(0, 0, R * 0.92, R * 0.5, 0, 0, 6.2832); ctx.fill();
+    ctx.strokeStyle = "rgba(180,110,40,0.35)"; ctx.lineWidth = 1;
+    ctx.stroke();
+    ctx.restore();
+
+    // eye
+    ctx.fillStyle = "#fff";
+    ctx.beginPath(); ctx.arc(R * 0.42, -R * 0.22, R * 0.26, 0, 6.2832); ctx.fill();
+    ctx.fillStyle = "#1c1f2b";
+    ctx.beginPath(); ctx.arc(R * 0.5, -R * 0.22, R * 0.14, 0, 6.2832); ctx.fill();
+    ctx.fillStyle = "rgba(255,255,255,0.8)";
+    ctx.beginPath(); ctx.arc(R * 0.55, -R * 0.26, R * 0.05, 0, 6.2832); ctx.fill();
+
+    // beak
+    ctx.fillStyle = "#ff9f2f";
+    ctx.beginPath();
+    ctx.moveTo(R * 0.92, -R * 0.05);
+    ctx.lineTo(R * 1.42, R * 0.14);
+    ctx.lineTo(R * 0.92, R * 0.3);
+    ctx.closePath(); ctx.fill();
+    ctx.fillStyle = "#e07a1e";
+    ctx.beginPath();
+    ctx.moveTo(R * 0.92, R * 0.14);
+    ctx.lineTo(R * 1.42, R * 0.14);
+    ctx.lineTo(R * 0.92, R * 0.3);
+    ctx.closePath(); ctx.fill();
+
+    // tail
+    ctx.fillStyle = "#ffb562";
+    ctx.beginPath();
+    ctx.moveTo(-R * 1.05, -R * 0.12);
+    ctx.lineTo(-R * 1.55, -R * 0.32);
+    ctx.lineTo(-R * 1.2, R * 0.18);
+    ctx.closePath(); ctx.fill();
+
+    ctx.restore();
+  }
+
+  function drawParticles() {
+    for (const p of particles) {
+      const t = p.age / p.life;
+      ctx.globalAlpha = (1 - t) * 0.9;
+      ctx.fillStyle = "hsl(" + p.hue + ",100%,72%)";
+      ctx.beginPath();
+      ctx.arc(p.x, p.y, p.size * (1 - t * 0.5), 0, 6.2832);
+      ctx.fill();
+    }
+    ctx.globalAlpha = 1;
+  }
+
+  function render() {
+    let sx = 0, sy = 0;
+    if (shake > 0) {
+      sx = (Math.random() * 2 - 1) * shake;
+      sy = (Math.random() * 2 - 1) * shake;
+    }
+    ctx.save();
+    ctx.translate(sx, sy);
+
+    drawBackground();
+    drawPipes();
+    drawGround();
+    drawParticles();
+    drawBird();
+
+    ctx.restore();
+
+    if (flashAlpha > 0) {
+      ctx.fillStyle = "rgba(255,80,80," + flashAlpha.toFixed(3) + ")";
+      ctx.fillRect(0, 0, W, H);
+    }
+  }
+
+  // ---- main loop (fixed-step physics, smooth render) ------------------
+  function loop(ts) {
+    if (!lastTime) lastTime = ts;
+    let frame = (ts - lastTime) / 1000;
+    lastTime = ts;
+    if (frame > 0.1) frame = 0.1; // clamp big gaps (tab restore)
+
+    if (hitStop > 0) { hitStop -= frame; }
+    else {
+      acc += frame;
+      while (acc >= FIXED_DT) { step(FIXED_DT); acc -= FIXED_DT; }
+    }
+
+    render();
+    requestAnimationFrame(loop);
+  }
+
+  // ---- boot -----------------------------------------------------------
+  resize();
+  resetGame();
+  requestAnimationFrame(loop);
+})();
+</script>
+</body>
+</html>
diff --git a/games/gems/NeonGems.aa b/games/gems/NeonGems.aa
new file mode 100644
index 0000000..64548fa
--- /dev/null
+++ b/games/gems/NeonGems.aa
@@ -0,0 +1,755 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>NEON GEMS</title>
+<style>
+  :root{
+    --bg:#0a0e14;
+    --panel:#0f1622;
+    --line:#1c2735;
+    --ink:#e8f0ff;
+    --muted:#7f93ad;
+    --accent:#3df2ff;
+  }
+  *{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
+  html,body{ margin:0; padding:0; height:100%; }
+  body{
+    background:
+      radial-gradient(1200px 700px at 50% -10%, #12213a 0%, rgba(18,33,58,0) 60%),
+      var(--bg);
+    color:var(--ink);
+    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
+    touch-action:none;
+    overflow:hidden;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    min-height:100%;
+    user-select:none;
+    -webkit-user-select:none;
+  }
+  #wrap{
+    display:flex;
+    flex-direction:column;
+    align-items:center;
+    gap:14px;
+    padding:16px;
+    width:100%;
+    max-width:560px;
+  }
+  #title{
+    margin:0;
+    font-size:clamp(20px,6vw,34px);
+    font-weight:800;
+    letter-spacing:.42em;
+    text-transform:uppercase;
+    text-indent:.42em;
+    background:linear-gradient(90deg,#3df2ff,#8a7dff 45%,#ff5db8);
+    -webkit-background-clip:text;
+    background-clip:text;
+    color:transparent;
+    filter:drop-shadow(0 0 12px rgba(61,242,255,.35));
+    text-align:center;
+  }
+  #hud{
+    width:100%;
+    display:flex;
+    gap:10px;
+    justify-content:center;
+  }
+  .stat{
+    flex:1;
+    background:linear-gradient(180deg,var(--panel),#0b1220);
+    border:1px solid var(--line);
+    border-radius:12px;
+    padding:8px 10px;
+    text-align:center;
+    box-shadow:inset 0 1px 0 rgba(255,255,255,.03);
+  }
+  .stat .lbl{
+    font-size:10px;
+    letter-spacing:.22em;
+    text-transform:uppercase;
+    color:var(--muted);
+  }
+  .stat .val{
+    font-size:clamp(16px,5vw,24px);
+    font-weight:800;
+    margin-top:2px;
+    font-variant-numeric:tabular-nums;
+    color:var(--ink);
+  }
+  #boardWrap{
+    position:relative;
+    width:100%;
+    border-radius:16px;
+    background:linear-gradient(180deg,#0c1420,#080c13);
+    border:1px solid var(--line);
+    box-shadow:0 20px 60px rgba(0,0,0,.55), inset 0 0 60px rgba(61,242,255,.04);
+    padding:10px;
+    touch-action:none;
+  }
+  canvas{ display:block; width:100%; height:auto; border-radius:10px; touch-action:none; }
+  #foot{
+    display:flex;
+    gap:10px;
+    align-items:center;
+    justify-content:center;
+    width:100%;
+  }
+  button{
+    font-family:inherit;
+    font-weight:700;
+    letter-spacing:.16em;
+    text-transform:uppercase;
+    font-size:11px;
+    color:var(--ink);
+    background:linear-gradient(180deg,#132033,#0c1524);
+    border:1px solid var(--line);
+    border-radius:10px;
+    padding:9px 14px;
+    cursor:pointer;
+    transition:transform .08s ease, border-color .15s ease, box-shadow .15s ease;
+  }
+  button:hover{ border-color:var(--accent); box-shadow:0 0 14px rgba(61,242,255,.25); }
+  button:active{ transform:translateY(1px); }
+  #msg{
+    min-height:16px;
+    font-size:11px;
+    letter-spacing:.16em;
+    text-transform:uppercase;
+    color:var(--muted);
+    text-align:center;
+  }
+</style>
+</head>
+<body>
+  <div id="wrap">
+    <h1 id="title">Neon Gems</h1>
+    <div id="hud">
+      <div class="stat"><div class="lbl">Score</div><div class="val" id="scoreEl">0</div></div>
+      <div class="stat"><div class="lbl">Moves</div><div class="val" id="movesEl">30</div></div>
+      <div class="stat"><div class="lbl">Best</div><div class="val" id="bestEl">0</div></div>
+    </div>
+    <div id="boardWrap">
+      <canvas id="game"></canvas>
+    </div>
+    <div id="msg">Swap gems to match 3 or more</div>
+    <div id="foot">
+      <button id="soundBtn" type="button">Sound: On</button>
+      <button id="newBtn" type="button">New Game</button>
+    </div>
+  </div>
+
+<script>
+(function(){
+  "use strict";
+
+  function boot(){
+    var canvas = document.getElementById('game');
+    if(!canvas) return;
+    var ctx = canvas.getContext('2d');
+    if(!ctx) return;
+
+    var scoreEl = document.getElementById('scoreEl');
+    var movesEl = document.getElementById('movesEl');
+    var bestEl  = document.getElementById('bestEl');
+    var msgEl   = document.getElementById('msg');
+    var soundBtn= document.getElementById('soundBtn');
+    var newBtn  = document.getElementById('newBtn');
+    var boardWrap = document.getElementById('boardWrap');
+
+    var N = 8;              // grid size
+    var START_MOVES = 30;
+    var BEST_KEY = "abrams-gems-best";
+
+    // Gem palette: distinct saturated neon hues
+    var GEMS = [
+      { core:"#ff3d6e", glow:"#ff3d6e" }, // pink/red
+      { core:"#ffb43d", glow:"#ffb43d" }, // amber
+      { core:"#ffe93d", glow:"#ffe93d" }, // yellow
+      { core:"#4dff88", glow:"#4dff88" }, // green
+      { core:"#3df2ff", glow:"#3df2ff" }, // cyan
+      { core:"#7d8bff", glow:"#7d8bff" }, // indigo
+      { core:"#c96dff", glow:"#c96dff" }  // violet
+    ];
+    var NC = GEMS.length;
+
+    // DPR-aware sizing
+    var cell = 48;          // logical px per cell (set in resize)
+    var dpr = 1;
+
+    // Board state: grid[r][c] = color index (0..NC-1) or -1 empty
+    var grid = [];
+    var score = 0, moves = START_MOVES, best = 0;
+    var soundOn = true;
+
+    // Per-cell render offset (for fall/swap animation)
+    // offset[r][c] = {dx, dy} in logical pixels, animated to 0
+    var offX = [], offY = [];
+    // pop animation: pop[r][c] = scale factor while clearing (1 -> 0)
+    var popScale = [];
+    var spawnScale = []; // 0 -> 1 for newly spawned/fallen gems
+
+    var sel = null;        // {r,c} currently selected
+    var animating = false; // block input during resolve animations
+    var gameOver = false;
+
+    // ---------- storage ----------
+    function loadBest(){
+      try{
+        var v = localStorage.getItem(BEST_KEY);
+        best = v ? (parseInt(v,10)||0) : 0;
+      }catch(e){ best = 0; }
+    }
+    function saveBest(){
+      try{ localStorage.setItem(BEST_KEY, String(best)); }catch(e){}
+    }
+
+    // ---------- audio ----------
+    var audioCtx = null;
+    function ensureAudio(){
+      if(audioCtx) return;
+      try{
+        var AC = window.AudioContext || window.webkitAudioContext;
+        if(AC) audioCtx = new AC();
+      }catch(e){ audioCtx = null; }
+    }
+    function blip(freq, dur, type, vol){
+      if(!soundOn || !audioCtx) return;
+      try{
+        var t = audioCtx.currentTime;
+        var o = audioCtx.createOscillator();
+        var g = audioCtx.createGain();
+        o.type = type || "sine";
+        o.frequency.setValueAtTime(freq, t);
+        g.gain.setValueAtTime(0.0001, t);
+        g.gain.exponentialRampToValueAtTime(vol||0.14, t+0.01);
+        g.gain.exponentialRampToValueAtTime(0.0001, t+(dur||0.12));
+        o.connect(g); g.connect(audioCtx.destination);
+        o.start(t);
+        o.stop(t+(dur||0.12)+0.02);
+      }catch(e){}
+    }
+    function sfxSwap(){ blip(420,0.09,"triangle",0.10); }
+    function sfxBad(){ blip(160,0.14,"sawtooth",0.08); }
+    function sfxMatch(chain){ blip(520 + chain*90, 0.14, "square", 0.12); }
+    function sfxDrop(){ blip(300,0.06,"sine",0.06); }
+
+    // ---------- grid helpers ----------
+    function rndColor(){ return Math.floor(Math.random()*NC); }
+
+    function inBounds(r,c){ return r>=0 && r<N && c>=0 && c<N; }
+
+    // Build initial board with NO pre-existing match-3
+    function fillInitial(){
+      grid = [];
+      for(var r=0;r<N;r++){
+        grid[r] = [];
+        for(var c=0;c<N;c++){
+          var col;
+          var guard = 0;
+          do{
+            col = rndColor();
+            guard++;
+            // reject if it completes a horizontal or vertical run of 3
+          }while(guard<50 && (
+            (c>=2 && grid[r][c-1]===col && grid[r][c-2]===col) ||
+            (r>=2 && grid[r-1][c]===col && grid[r-2][c]===col)
+          ));
+          grid[r][c] = col;
+        }
+      }
+      // guarantee at least one valid move
+      if(!hasValidMove()){ shuffleBoard(); }
+    }
+
+    // find all matched cells (>=3 in row/col). returns 2D boolean.
+    function findMatches(){
+      var mark = [];
+      for(var r=0;r<N;r++){ mark[r]=[]; for(var c=0;c<N;c++) mark[r][c]=false; }
+      var r,c;
+      // horizontal
+      for(r=0;r<N;r++){
+        var run=1;
+        for(c=1;c<N;c++){
+          if(grid[r][c]!==-1 && grid[r][c]===grid[r][c-1]) run++;
+          else {
+            if(run>=3){ for(var k=0;k<run;k++) mark[r][c-1-k]=true; }
+            run=1;
+          }
+        }
+        if(run>=3){ for(var k2=0;k2<run;k2++) mark[r][N-1-k2]=true; }
+      }
+      // vertical
+      for(c=0;c<N;c++){
+        var run2=1;
+        for(r=1;r<N;r++){
+          if(grid[r][c]!==-1 && grid[r][c]===grid[r-1][c]) run2++;
+          else {
+            if(run2>=3){ for(var k3=0;k3<run2;k3++) mark[r-1-k3][c]=true; }
+            run2=1;
+          }
+        }
+        if(run2>=3){ for(var k4=0;k4<run2;k4++) mark[N-1-k4][c]=true; }
+      }
+      return mark;
+    }
+
+    function countMarked(mark){
+      var n=0;
+      for(var r=0;r<N;r++) for(var c=0;c<N;c++) if(mark[r][c]) n++;
+      return n;
+    }
+
+    // would swapping (r1,c1)<->(r2,c2) produce a match?
+    function swapProducesMatch(r1,c1,r2,c2){
+      var t = grid[r1][c1]; grid[r1][c1]=grid[r2][c2]; grid[r2][c2]=t;
+      var m = findMatches();
+      var ok = countMarked(m) > 0;
+      var t2 = grid[r1][c1]; grid[r1][c1]=grid[r2][c2]; grid[r2][c2]=t2;
+      return ok;
+    }
+
+    function hasValidMove(){
+      for(var r=0;r<N;r++){
+        for(var c=0;c<N;c++){
+          if(c<N-1 && swapProducesMatch(r,c,r,c+1)) return true;
+          if(r<N-1 && swapProducesMatch(r,c,r+1,c)) return true;
+        }
+      }
+      return false;
+    }
+
+    function shuffleBoard(){
+      var guard=0;
+      do{
+        // Fisher-Yates over flat colors
+        var flat=[];
+        for(var r=0;r<N;r++) for(var c=0;c<N;c++) flat.push(grid[r][c]);
+        for(var i=flat.length-1;i>0;i--){
+          var j=Math.floor(Math.random()*(i+1));
+          var tmp=flat[i]; flat[i]=flat[j]; flat[j]=tmp;
+        }
+        var idx=0;
+        for(var r2=0;r2<N;r2++) for(var c2=0;c2<N;c2++) grid[r2][c2]=flat[idx++];
+        guard++;
+      }while(guard<80 && (countMarked(findMatches())>0 || !hasValidMove()));
+    }
+
+    // ---------- animation arrays ----------
+    function resetAnimArrays(){
+      offX=[]; offY=[]; popScale=[]; spawnScale=[];
+      for(var r=0;r<N;r++){
+        offX[r]=[]; offY[r]=[]; popScale[r]=[]; spawnScale[r]=[];
+        for(var c=0;c<N;c++){ offX[r][c]=0; offY[r][c]=0; popScale[r][c]=1; spawnScale[r][c]=1; }
+      }
+    }
+
+    // ---------- new game ----------
+    function newGame(){
+      score=0; moves=START_MOVES; gameOver=false; sel=null; animating=false;
+      fillInitial();
+      resetAnimArrays();
+      updateHUD();
+      setMsg("Swap gems to match 3 or more");
+      draw();
+    }
+
+    // ---------- HUD ----------
+    function updateHUD(){
+      scoreEl.textContent = String(score);
+      movesEl.textContent = String(moves);
+      bestEl.textContent  = String(best);
+    }
+    function setMsg(t){ msgEl.textContent = t; }
+
+    // ---------- sizing ----------
+    function resize(){
+      // available width from wrapper (minus padding)
+      var wrapW = boardWrap.clientWidth - 20; // 10px padding each side
+      if(wrapW < 120) wrapW = 120;
+      // keep board square, cap so it fits typical iframe heights too
+      var maxByH = (window.innerHeight || 600) - 230;
+      var size = Math.min(wrapW, maxByH > 200 ? maxByH : wrapW);
+      size = Math.max(200, Math.min(size, 520));
+      cell = size / N;
+      dpr = Math.max(1, Math.min(window.devicePixelRatio || 1, 3));
+      canvas.width = Math.round(size * dpr);
+      canvas.height = Math.round(size * dpr);
+      canvas.style.width = size + "px";
+      canvas.style.height = size + "px";
+      draw();
+    }
+
+    // ---------- drawing ----------
+    function drawGem(cx, cy, rad, gi, alpha, scale){
+      if(gi<0) return;
+      var g = GEMS[gi];
+      var R = rad*scale;
+      if(R<=0.5) return;
+      ctx.save();
+      ctx.globalAlpha = alpha;
+      // outer glow
+      ctx.shadowColor = g.glow;
+      ctx.shadowBlur = R*0.9;
+      // body gradient
+      var grad = ctx.createRadialGradient(cx - R*0.3, cy - R*0.35, R*0.15, cx, cy, R);
+      grad.addColorStop(0, "#ffffff");
+      grad.addColorStop(0.18, g.core);
+      grad.addColorStop(1, shade(g.core, -0.45));
+      ctx.fillStyle = grad;
+      roundRectPath(cx-R, cy-R, R*2, R*2, R*0.42);
+      ctx.fill();
+      // inner rim
+      ctx.shadowBlur = 0;
+      ctx.lineWidth = Math.max(1, R*0.10);
+      ctx.strokeStyle = shade(g.core, 0.35);
+      ctx.globalAlpha = alpha*0.8;
+      roundRectPath(cx-R*0.92, cy-R*0.92, R*1.84, R*1.84, R*0.36);
+      ctx.stroke();
+      // sparkle highlight
+      ctx.globalAlpha = alpha*0.85;
+      ctx.fillStyle = "rgba(255,255,255,0.85)";
+      ctx.beginPath();
+      ctx.ellipse(cx - R*0.32, cy - R*0.38, R*0.22, R*0.13, -0.6, 0, Math.PI*2);
+      ctx.fill();
+      ctx.restore();
+    }
+
+    function roundRectPath(x,y,w,h,r){
+      if(r>w/2) r=w/2; if(r>h/2) r=h/2;
+      ctx.beginPath();
+      ctx.moveTo(x+r,y);
+      ctx.arcTo(x+w,y,x+w,y+h,r);
+      ctx.arcTo(x+w,y+h,x,y+h,r);
+      ctx.arcTo(x,y+h,x,y,r);
+      ctx.arcTo(x,y,x+w,y,r);
+      ctx.closePath();
+    }
+
+    // shade a hex color by amt (-1..1)
+    function shade(hex, amt){
+      var h = hex.replace('#','');
+      var r = parseInt(h.substring(0,2),16);
+      var g = parseInt(h.substring(2,4),16);
+      var b = parseInt(h.substring(4,6),16);
+      if(amt<0){
+        r = Math.round(r*(1+amt)); g = Math.round(g*(1+amt)); b = Math.round(b*(1+amt));
+      } else {
+        r = Math.round(r+(255-r)*amt); g = Math.round(g+(255-g)*amt); b = Math.round(b+(255-b)*amt);
+      }
+      r=Math.max(0,Math.min(255,r)); g=Math.max(0,Math.min(255,g)); b=Math.max(0,Math.min(255,b));
+      return "rgb("+r+","+g+","+b+")";
+    }
+
+    function draw(){
+      var W = canvas.width, H = canvas.height;
+      ctx.setTransform(dpr,0,0,dpr,0,0);
+      var size = W/dpr;
+      // bg
+      ctx.clearRect(0,0,size,size);
+      var bg = ctx.createLinearGradient(0,0,0,size);
+      bg.addColorStop(0,"#0b1220");
+      bg.addColorStop(1,"#070b11");
+      ctx.fillStyle = bg;
+      ctx.fillRect(0,0,size,size);
+
+      // grid cells backdrop
+      for(var r=0;r<N;r++){
+        for(var c=0;c<N;c++){
+          var x = c*cell, y = r*cell;
+          ctx.fillStyle = ((r+c)%2===0) ? "rgba(255,255,255,0.018)" : "rgba(255,255,255,0.006)";
+          ctx.fillRect(x,y,cell,cell);
+        }
+      }
+
+      // selection highlight
+      if(sel){
+        var sx = sel.c*cell, sy = sel.r*cell;
+        ctx.save();
+        ctx.strokeStyle = "#3df2ff";
+        ctx.shadowColor = "#3df2ff";
+        ctx.shadowBlur = 14;
+        ctx.lineWidth = 3;
+        roundRectPath(sx+3, sy+3, cell-6, cell-6, cell*0.2);
+        ctx.stroke();
+        ctx.restore();
+      }
+
+      // gems
+      var rad = cell*0.40;
+      for(var r2=0;r2<N;r2++){
+        for(var c2=0;c2<N;c2++){
+          var gi = grid[r2][c2];
+          if(gi<0) continue;
+          var cx = c2*cell + cell/2 + offX[r2][c2];
+          var cy = r2*cell + cell/2 + offY[r2][c2];
+          var ps = popScale[r2][c2];
+          var ss = spawnScale[r2][c2];
+          var sc = ps * ss;
+          if(sc<=0.02) continue;
+          drawGem(cx, cy, rad, gi, Math.min(1, sc<1?sc:1)*(ps<1?ps:1), sc);
+        }
+      }
+    }
+
+    // ---------- animation loop ----------
+    var rafId = null;
+    function animateOffsets(cb){
+      animating = true;
+      var speed = 0.22; // easing factor per frame
+      function step(){
+        var moving = false;
+        for(var r=0;r<N;r++){
+          for(var c=0;c<N;c++){
+            // ease offsets to 0
+            if(Math.abs(offX[r][c])>0.5){ offX[r][c]*= (1-speed); moving=true; } else offX[r][c]=0;
+            if(Math.abs(offY[r][c])>0.5){ offY[r][c]*= (1-speed); moving=true; } else offY[r][c]=0;
+            // spawn scale ease to 1
+            if(spawnScale[r][c] < 0.999){ spawnScale[r][c] += (1-spawnScale[r][c])*0.28; if(spawnScale[r][c]>0.995) spawnScale[r][c]=1; moving=true; }
+          }
+        }
+        draw();
+        if(moving){ rafId = requestAnimationFrame(step); }
+        else { animating=false; cb && cb(); }
+      }
+      rafId = requestAnimationFrame(step);
+    }
+
+    function animatePops(marks, cb){
+      animating = true;
+      function step(){
+        var moving=false;
+        for(var r=0;r<N;r++){
+          for(var c=0;c<N;c++){
+            if(marks[r][c] && popScale[r][c]>0.02){
+              popScale[r][c] -= 0.14;
+              if(popScale[r][c]<0) popScale[r][c]=0;
+              moving=true;
+            }
+          }
+        }
+        draw();
+        if(moving) rafId=requestAnimationFrame(step);
+        else { animating=false; cb && cb(); }
+      }
+      rafId=requestAnimationFrame(step);
+    }
+
+    // ---------- resolve cascades ----------
+    function resolveBoard(chain){
+      var marks = findMatches();
+      var n = countMarked(marks);
+      if(n===0){
+        // done cascading
+        animating=false;
+        checkEndAndShuffle();
+        draw();
+        return;
+      }
+      sfxMatch(chain||0);
+      // score: base 10 per gem, cascade multiplier
+      var mult = 1 + (chain||0)*0.5;
+      var gained = Math.round(n * 10 * mult);
+      score += gained;
+      if(score>best){ best=score; saveBest(); }
+      updateHUD();
+      if((chain||0)>0) setMsg("Combo x"+(chain+1)+"  +"+gained);
+      else setMsg("+"+gained);
+
+      // animate pop, then collapse + refill
+      animatePops(marks, function(){
+        // clear matched
+        for(var r=0;r<N;r++) for(var c=0;c<N;c++){ if(marks[r][c]){ grid[r][c]=-1; popScale[r][c]=1; } }
+        collapseAndRefill();
+        // animate the falls then resolve again (cascade)
+        animateOffsets(function(){
+          resolveBoard((chain||0)+1);
+        });
+      });
+    }
+
+    // gravity: pull down, spawn new at top; set offY so they animate falling
+    function collapseAndRefill(){
+      for(var c=0;c<N;c++){
+        // gather existing from bottom up
+        var writeR = N-1;
+        for(var r=N-1;r>=0;r--){
+          if(grid[r][c]!==-1){
+            if(writeR!==r){
+              grid[writeR][c]=grid[r][c];
+              grid[r][c]=-1;
+              // offset so it visually starts where it was, then eases to 0
+              offY[writeR][c] = (r-writeR)*cell;
+              spawnScale[writeR][c]=1;
+            }
+            writeR--;
+          }
+        }
+        // fill remaining top with new gems, dropping in from above
+        var spawnIdx = 0;
+        for(var rr=writeR; rr>=0; rr--){
+          grid[rr][c]=rndColor();
+          offY[rr][c] = -(cell*(spawnIdx+1)) - cell; // start above the board
+          spawnScale[rr][c]=0.35;
+          spawnIdx++;
+        }
+      }
+      sfxDrop();
+    }
+
+    function checkEndAndShuffle(){
+      if(!hasValidMove()){
+        setMsg("No moves — reshuffling…");
+        shuffleBoard();
+        resetAnimArrays();
+        draw();
+        // after shuffle there should be no immediate matches (guarded)
+      }
+      if(moves<=0){
+        gameOver=true;
+        setMsg("Out of moves — Score "+score+". Tap New Game.");
+      }
+    }
+
+    // ---------- input ----------
+    function cellFromEvent(clientX, clientY){
+      var rect = canvas.getBoundingClientRect();
+      var x = clientX - rect.left;
+      var y = clientY - rect.top;
+      // canvas CSS size maps to N*cell logical (cell already logical)
+      var px = x * (canvas.width/dpr) / rect.width;
+      var py = y * (canvas.height/dpr) / rect.height;
+      var c = Math.floor(px / cell);
+      var r = Math.floor(py / cell);
+      if(!inBounds(r,c)) return null;
+      return {r:r,c:c};
+    }
+
+    function tryMove(a, b){
+      // must be adjacent
+      var dr = Math.abs(a.r-b.r), dc = Math.abs(a.c-b.c);
+      if(dr+dc!==1) return false;
+      if(gameOver) return false;
+      sfxSwap();
+      // do swap
+      var t=grid[a.r][a.c]; grid[a.r][a.c]=grid[b.r][b.c]; grid[b.r][b.c]=t;
+      // set offsets for swap animation (each moves toward its new home)
+      offX[a.r][a.c] = (b.c-a.c)*cell; offY[a.r][a.c] = (b.r-a.r)*cell;
+      offX[b.r][b.c] = (a.c-b.c)*cell; offY[b.r][b.c] = (a.r-b.r)*cell;
+
+      var m = findMatches();
+      if(countMarked(m)===0){
+        // invalid: animate swap in, then swap back
+        sfxBad();
+        animateOffsets(function(){
+          var t2=grid[a.r][a.c]; grid[a.r][a.c]=grid[b.r][b.c]; grid[b.r][b.c]=t2;
+          offX[a.r][a.c]=(b.c-a.c)*cell; offY[a.r][a.c]=(b.r-a.r)*cell;
+          offX[b.r][b.c]=(a.c-b.c)*cell; offY[b.r][b.c]=(a.r-b.r)*cell;
+          animateOffsets(function(){ setMsg("No match there"); });
+        });
+        return true; // was a valid adjacent attempt (but no match)
+      }
+      // valid move
+      moves--;
+      updateHUD();
+      animateOffsets(function(){
+        resolveBoard(0);
+      });
+      return true;
+    }
+
+    var pointerDown = null; // {r,c,x,y}
+    function onDown(clientX, clientY){
+      ensureAudio();
+      if(animating || gameOver) return;
+      var cellPos = cellFromEvent(clientX, clientY);
+      if(!cellPos) return;
+      pointerDown = {r:cellPos.r, c:cellPos.c, x:clientX, y:clientY};
+      if(sel){
+        // second click: attempt swap or reselect
+        if(sel.r===cellPos.r && sel.c===cellPos.c){
+          sel=null; draw(); return;
+        }
+        var dr=Math.abs(sel.r-cellPos.r), dc=Math.abs(sel.c-cellPos.c);
+        if(dr+dc===1){
+          var a={r:sel.r,c:sel.c}; sel=null;
+          tryMove(a, cellPos);
+          draw();
+        } else {
+          sel={r:cellPos.r,c:cellPos.c}; draw();
+        }
+      } else {
+        sel={r:cellPos.r,c:cellPos.c}; draw();
+      }
+    }
+
+    function onUp(clientX, clientY){
+      if(!pointerDown) return;
+      if(animating || gameOver){ pointerDown=null; return; }
+      var dx = clientX - pointerDown.x;
+      var dy = clientY - pointerDown.y;
+      var absx=Math.abs(dx), absy=Math.abs(dy);
+      var threshold = cell*0.3;
+      if(Math.max(absx,absy) > threshold){
+        // treat as swipe from the down cell
+        var a={r:pointerDown.r, c:pointerDown.c};
+        var b;
+        if(absx>absy) b={r:a.r, c:a.c + (dx>0?1:-1)};
+        else b={r:a.r + (dy>0?1:-1), c:a.c};
+        if(inBounds(b.r,b.c)){
+          sel=null;
+          tryMove(a,b);
+          draw();
+        }
+      }
+      pointerDown=null;
+    }
+
+    // mouse
+    canvas.addEventListener('mousedown', function(e){ e.preventDefault(); onDown(e.clientX,e.clientY); });
+    window.addEventListener('mouseup', function(e){ onUp(e.clientX,e.clientY); });
+    // touch
+    canvas.addEventListener('touchstart', function(e){
+      if(e.touches.length){ e.preventDefault(); var t=e.touches[0]; onDown(t.clientX,t.clientY); }
+    }, {passive:false});
+    canvas.addEventListener('touchmove', function(e){ e.preventDefault(); }, {passive:false});
+    canvas.addEventListener('touchend', function(e){
+      e.preventDefault();
+      var t = (e.changedTouches && e.changedTouches.length) ? e.changedTouches[0] : null;
+      if(t) onUp(t.clientX,t.clientY);
+    }, {passive:false});
+
+    // buttons
+    soundBtn.addEventListener('click', function(){
+      soundOn = !soundOn;
+      soundBtn.textContent = "Sound: " + (soundOn?"On":"Off");
+      if(soundOn){ ensureAudio(); blip(660,0.08,"sine",0.1); }
+    });
+    newBtn.addEventListener('click', function(){ ensureAudio(); newGame(); });
+
+    // resize handling
+    var resizeTimer=null;
+    window.addEventListener('resize', function(){
+      clearTimeout(resizeTimer);
+      resizeTimer=setTimeout(resize, 60);
+    });
+
+    // ---------- init ----------
+    loadBest();
+    newGame();
+    resize();
+  }
+
+  if(document.readyState === "loading"){
+    document.addEventListener("DOMContentLoaded", boot);
+  } else {
+    boot();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/hopper/AbramsHopper.aa b/games/hopper/AbramsHopper.aa
new file mode 100644
index 0000000..d8ee5b4
--- /dev/null
+++ b/games/hopper/AbramsHopper.aa
@@ -0,0 +1,790 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>HOPPER</title>
+<style>
+  html,body{margin:0;padding:0;height:100%;background:#0a0e14;overflow:hidden;}
+  body{
+    touch-action:none;
+    -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;
+    font-family:'Trebuchet MS','Segoe UI',system-ui,-apple-system,sans-serif;
+    display:flex;align-items:center;justify-content:center;
+    color:#cfe;
+  }
+  #wrap{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;}
+  canvas{display:block;background:#0a0e14;touch-action:none;image-rendering:optimizeQuality;}
+</style>
+</head>
+<body>
+<div id="wrap"><canvas id="c"></canvas></div>
+<script>
+(function(){
+  "use strict";
+
+  function boot(){
+    var canvas = document.getElementById('c');
+    if(!canvas){ return; }
+    var ctx = canvas.getContext('2d');
+    if(!ctx){ return; }
+
+    // ---------- Config ----------
+    var COLS = 13;          // grid columns
+    var ROWS = 15;          // grid rows (0 = home row, 14 = start row)
+    var BEST_KEY = "abrams-hopper-best";
+    var DPR = 1;
+    var cell = 40;          // px per cell (computed on resize)
+    var W = COLS*cell, H = ROWS*cell;
+    var offX = 0, offY = 0; // canvas draw offsets (letterbox)
+
+    // ---------- Audio (lazy) ----------
+    var actx = null;
+    function ensureAudio(){
+      if(actx) return;
+      try{
+        var AC = window.AudioContext || window.webkitAudioContext;
+        if(AC){ actx = new AC(); }
+      }catch(e){ actx = null; }
+    }
+    function blip(freq, dur, type, vol){
+      if(!actx) return;
+      try{
+        if(actx.state === "suspended"){ actx.resume(); }
+        var o = actx.createOscillator();
+        var g = actx.createGain();
+        o.type = type || "square";
+        o.frequency.value = freq;
+        g.gain.value = 0.0001;
+        o.connect(g); g.connect(actx.destination);
+        var t = actx.currentTime;
+        var v = (vol==null?0.12:vol);
+        g.gain.setValueAtTime(0.0001, t);
+        g.gain.exponentialRampToValueAtTime(v, t+0.01);
+        g.gain.exponentialRampToValueAtTime(0.0001, t+dur);
+        o.start(t);
+        o.stop(t+dur+0.02);
+      }catch(e){}
+    }
+    function sHop(){ blip(660,0.08,"square",0.10); }
+    function sSplat(){ blip(120,0.28,"sawtooth",0.16); setTimeout(function(){blip(80,0.22,"sawtooth",0.14);},40); }
+    function sHome(){ blip(880,0.10,"triangle",0.14); setTimeout(function(){blip(1320,0.14,"triangle",0.12);},90); }
+    function sLevel(){ blip(523,0.10,"triangle",0.12); setTimeout(function(){blip(659,0.10,"triangle",0.12);},110); setTimeout(function(){blip(784,0.16,"triangle",0.12);},220); }
+
+    // ---------- Layout ----------
+    // Rows (top to bottom):
+    // 0        : HOME row (goal slots)
+    // 1..5     : RIVER lanes (logs/turtles)
+    // 6        : SAFE median
+    // 7..11    : ROAD lanes (cars)
+    // 12       : SAFE start-adjacent
+    // 13..14   : start area (grass)
+    var HOME_ROW = 0;
+    var RIVER_ROWS = [1,2,3,4,5];
+    var MEDIAN_ROW = 6;
+    var ROAD_ROWS = [7,8,9,10,11];
+    var SAFE_ROW = 12;
+    var START_ROW = 13;
+
+    // Home slots: positions (in columns) that must be filled
+    var HOME_SLOTS = []; // {col, filled}
+    function setupHomeSlots(){
+      HOME_SLOTS = [];
+      var cols = [1,4,6,8,11]; // 5 slots spread across
+      for(var i=0;i<cols.length;i++){
+        HOME_SLOTS.push({col:cols[i], filled:false});
+      }
+    }
+
+    // ---------- Entities ----------
+    var lanes = []; // active moving lanes: {row, type:'car'|'log', dir, speed, gap, len, color, items:[{x}]}
+    function buildLanes(level){
+      lanes = [];
+      var baseSpeed = 1.4 + (level-1)*0.28; // cells/sec baseline
+      // Road lanes (cars)
+      var carColors = ["#ff3b6b","#ffd23b","#3bff9d","#5b8cff","#ff8f3b"];
+      for(var r=0;r<ROAD_ROWS.length;r++){
+        var row = ROAD_ROWS[r];
+        var dir = (r%2===0)? 1 : -1;
+        var speed = baseSpeed*(0.75 + r*0.16) * (1 + (level-1)*0.05);
+        var len = 1 + (r%2); // 1 or 2 cells long
+        var gap = 3.2 + (r%3)*0.9;
+        lanes.push(makeLane(row,'car',dir,speed,gap,len,carColors[r%carColors.length]));
+      }
+      // River lanes (logs & turtles)
+      for(var rr=0;rr<RIVER_ROWS.length;rr++){
+        var rw = RIVER_ROWS[rr];
+        var d = (rr%2===0)? -1 : 1;
+        var sp = baseSpeed*(0.6 + rr*0.14) * (1 + (level-1)*0.05);
+        var isTurtle = (rr%2===1);
+        var llen = isTurtle ? (2 + (rr%2)) : (2 + (rr%3)); // 2..4
+        var lgap = 2.6 + (rr%2)*0.8;
+        var lane = makeLane(rw, 'log', d, sp, lgap, llen, isTurtle?"#2ee6c8":"#c8975a");
+        lane.turtle = isTurtle;
+        lanes.push(lane);
+      }
+    }
+    function makeLane(row,type,dir,speed,gap,len,color){
+      var items = [];
+      var span = len + gap;
+      // fill across a wider range so wrap looks continuous
+      var total = Math.ceil((COLS + span*2)/span);
+      var startX = -span;
+      for(var i=0;i<total;i++){
+        items.push({ x: startX + i*span + (Math.random()*0.4-0.2) });
+      }
+      return {row:row,type:type,dir:dir,speed:speed,gap:gap,len:len,color:color,items:items,span:span};
+    }
+
+    // ---------- Player ----------
+    var player = {col:6, row:START_ROW, px:6, py:START_ROW, riding:null, alive:true};
+    function resetPlayerPos(){
+      player.col = 6; player.row = START_ROW;
+      player.px = 6; player.py = START_ROW;
+      player.riding = null; player.alive = true;
+    }
+
+    // ---------- Game State ----------
+    var state = "title"; // title | play | dead | over | win
+    var level = 1;
+    var lives = 3;
+    var score = 0;
+    var best = 0;
+    try{ var b = localStorage.getItem(BEST_KEY); if(b){ best = parseInt(b,10)||0; } }catch(e){}
+    var timeMax = 30;      // seconds per crossing
+    var timeLeft = timeMax;
+    var deadTimer = 0;
+    var farthestRow = START_ROW;
+
+    function startGame(){
+      level = 1; lives = 3; score = 0;
+      setupHomeSlots();
+      buildLanes(level);
+      resetPlayerPos();
+      timeMax = 30; timeLeft = timeMax;
+      farthestRow = START_ROW;
+      state = "play";
+    }
+    function nextLevel(){
+      level++;
+      setupHomeSlots();
+      buildLanes(level);
+      resetPlayerPos();
+      timeMax = Math.max(18, 30 - (level-1)*2);
+      timeLeft = timeMax;
+      farthestRow = START_ROW;
+      score += 500; // level bonus
+      state = "play";
+      sLevel();
+    }
+    function loseLife(){
+      lives--;
+      sSplat();
+      if(lives<=0){
+        commitBest();
+        state = "over";
+      }else{
+        state = "dead";
+        deadTimer = 0.9;
+      }
+    }
+    function commitBest(){
+      if(score>best){
+        best = score;
+        try{ localStorage.setItem(BEST_KEY, String(best)); }catch(e){}
+      }
+    }
+
+    // ---------- Movement ----------
+    function tryMove(dc,dr){
+      if(state!=="play" || !player.alive) return;
+      var nc = player.col + dc;
+      var nr = player.row + dr;
+      if(nc<0||nc>=COLS||nr<0||nr>ROWS-1) return;
+      // Landing on home row: must hit an empty slot
+      if(nr===HOME_ROW){
+        var slot = null;
+        for(var i=0;i<HOME_SLOTS.length;i++){
+          if(!HOME_SLOTS[i].filled && Math.abs(HOME_SLOTS[i].col - nc) <= 0){
+            slot = HOME_SLOTS[i]; break;
+          }
+        }
+        // allow snapping to nearest empty slot within 1 col
+        if(!slot){
+          for(var j=0;j<HOME_SLOTS.length;j++){
+            if(!HOME_SLOTS[j].filled && Math.abs(HOME_SLOTS[j].col - nc) === 1){
+              slot = HOME_SLOTS[j]; break;
+            }
+          }
+        }
+        if(slot){
+          slot.filled = true;
+          score += 100 + Math.round(timeLeft*10);
+          sHome();
+          // Check all filled
+          var allFilled = true;
+          for(var k=0;k<HOME_SLOTS.length;k++){ if(!HOME_SLOTS[k].filled){ allFilled=false; break; } }
+          if(allFilled){
+            nextLevel();
+          }else{
+            resetPlayerPos();
+            timeLeft = timeMax;
+            farthestRow = START_ROW;
+          }
+          return;
+        }else{
+          // hit the wall between slots => death
+          player.col = nc; player.row = nr;
+          player.px = nc; player.py = nr;
+          player.alive = false;
+          loseLife();
+          return;
+        }
+      }
+      player.col = nc; player.row = nr;
+      player.px = nc; player.py = nr;
+      player.riding = null;
+      // forward progress score
+      if(nr < farthestRow){
+        farthestRow = nr;
+        score += 10;
+      }
+      sHop();
+    }
+
+    // ---------- Update ----------
+    function update(dt){
+      if(state==="dead"){
+        deadTimer -= dt;
+        if(deadTimer<=0){
+          resetPlayerPos();
+          timeLeft = timeMax;
+          farthestRow = START_ROW;
+          state = "play";
+        }
+        return;
+      }
+      if(state!=="play") return;
+
+      // move lanes
+      for(var i=0;i<lanes.length;i++){
+        var ln = lanes[i];
+        var d = ln.dir * ln.speed * dt;
+        for(var m=0;m<ln.items.length;m++){
+          ln.items[m].x += d;
+          // wrap
+          if(ln.dir>0 && ln.items[m].x > COLS+1){
+            ln.items[m].x -= ln.span * ln.items.length;
+          }else if(ln.dir<0 && ln.items[m].x < -ln.len-1){
+            ln.items[m].x += ln.span * ln.items.length;
+          }
+        }
+      }
+
+      // timer
+      timeLeft -= dt;
+      if(timeLeft<=0){
+        timeLeft = 0;
+        player.alive = false;
+        loseLife();
+        return;
+      }
+
+      // River carry / drown logic
+      var row = player.row;
+      var inRiver = (RIVER_ROWS.indexOf(row) !== -1);
+      if(inRiver){
+        var onLog = null;
+        for(var L=0;L<lanes.length;L++){
+          if(lanes[L].row!==row) continue;
+          var lane = lanes[L];
+          for(var it=0; it<lane.items.length; it++){
+            var x0 = lane.items[it].x;
+            var x1 = x0 + lane.len;
+            // player center on this log?
+            if(player.px+0.5 >= x0-0.05 && player.px+0.5 <= x1+0.05){
+              onLog = {lane:lane, item:lane.items[it]};
+              break;
+            }
+          }
+          if(onLog) break;
+        }
+        if(onLog){
+          // carried by log
+          player.px += onLog.lane.dir * onLog.lane.speed * dt;
+          player.riding = onLog;
+          // carried off screen => drown
+          if(player.px < -0.6 || player.px > COLS-0.4){
+            player.alive = false;
+            loseLife();
+            return;
+          }
+          player.col = Math.round(player.px);
+        }else{
+          // in water, no log => drown
+          player.alive = false;
+          loseLife();
+          return;
+        }
+      }else{
+        player.riding = null;
+        player.px = player.col;
+      }
+
+      // Road collision
+      if(ROAD_ROWS.indexOf(row) !== -1){
+        for(var c=0;c<lanes.length;c++){
+          if(lanes[c].row!==row) continue;
+          var cl = lanes[c];
+          for(var ci=0; ci<cl.items.length; ci++){
+            var cx0 = cl.items[ci].x;
+            var cx1 = cx0 + cl.len;
+            var pcx = player.col + 0.5;
+            if(pcx > cx0 && pcx < cx1){
+              player.alive = false;
+              loseLife();
+              return;
+            }
+          }
+        }
+      }
+    }
+
+    // ---------- Render ----------
+    function drawRoundRect(x,y,w,h,r){
+      var rr = Math.min(r, w/2, h/2);
+      ctx.beginPath();
+      ctx.moveTo(x+rr,y);
+      ctx.arcTo(x+w,y,x+w,y+h,rr);
+      ctx.arcTo(x+w,y+h,x,y+h,rr);
+      ctx.arcTo(x,y+h,x,y,rr);
+      ctx.arcTo(x,y,x+w,y,rr);
+      ctx.closePath();
+    }
+
+    function render(){
+      ctx.save();
+      ctx.setTransform(DPR,0,0,DPR,0,0);
+      ctx.clearRect(0,0,canvas.width,canvas.height);
+      // full bg
+      ctx.fillStyle = "#0a0e14";
+      ctx.fillRect(0,0,canvas.width/DPR,canvas.height/DPR);
+      ctx.translate(offX, offY);
+
+      // playfield bg
+      ctx.fillStyle = "#080b11";
+      ctx.fillRect(0,0,W,H);
+
+      // ----- row backgrounds -----
+      // home band
+      ctx.fillStyle = "#0d1a14";
+      ctx.fillRect(0, HOME_ROW*cell, W, cell);
+      // river band
+      ctx.fillStyle = "#071726";
+      ctx.fillRect(0, RIVER_ROWS[0]*cell, W, RIVER_ROWS.length*cell);
+      // subtle water lines
+      ctx.strokeStyle = "rgba(60,140,220,0.12)";
+      ctx.lineWidth = 1;
+      for(var rl=0; rl<RIVER_ROWS.length; rl++){
+        var ry = (RIVER_ROWS[rl])*cell + cell*0.5;
+        ctx.beginPath(); ctx.moveTo(0,ry); ctx.lineTo(W,ry); ctx.stroke();
+      }
+      // median
+      ctx.fillStyle = "#12241a";
+      ctx.fillRect(0, MEDIAN_ROW*cell, W, cell);
+      // road band
+      ctx.fillStyle = "#0c0f16";
+      ctx.fillRect(0, ROAD_ROWS[0]*cell, W, ROAD_ROWS.length*cell);
+      // lane dashes
+      ctx.strokeStyle = "rgba(255,255,255,0.10)";
+      ctx.setLineDash([cell*0.35, cell*0.3]);
+      ctx.lineWidth = 2;
+      for(var rd=0; rd<ROAD_ROWS.length; rd++){
+        var yy = (ROAD_ROWS[rd])*cell + cell;
+        if(rd<ROAD_ROWS.length){
+          ctx.beginPath(); ctx.moveTo(0,yy); ctx.lineTo(W,yy); ctx.stroke();
+        }
+      }
+      ctx.setLineDash([]);
+      // safe & start grass
+      ctx.fillStyle = "#0e1f16";
+      ctx.fillRect(0, SAFE_ROW*cell, W, (ROWS-SAFE_ROW)*cell);
+
+      // neon band edges
+      ctx.strokeStyle = "rgba(46,230,200,0.25)";
+      ctx.lineWidth = 2;
+      ctx.strokeRect(1,1,W-2,H-2);
+
+      // ----- home slots -----
+      for(var hs=0; hs<HOME_SLOTS.length; hs++){
+        var slot = HOME_SLOTS[hs];
+        var sx = slot.col*cell;
+        var sy = HOME_ROW*cell;
+        ctx.save();
+        if(slot.filled){
+          ctx.shadowColor = "#2ee6c8"; ctx.shadowBlur = 14;
+          ctx.fillStyle = "#2ee6c8";
+          drawRoundRect(sx+cell*0.16, sy+cell*0.16, cell*0.68, cell*0.68, 8);
+          ctx.fill();
+          ctx.shadowBlur = 0;
+          ctx.fillStyle = "#04120e";
+          ctx.fillRect(sx+cell*0.42, sy+cell*0.28, cell*0.16, cell*0.34);
+        }else{
+          ctx.strokeStyle = "rgba(120,255,220,0.55)";
+          ctx.lineWidth = 2;
+          drawRoundRect(sx+cell*0.14, sy+cell*0.14, cell*0.72, cell*0.72, 8);
+          ctx.stroke();
+        }
+        ctx.restore();
+      }
+
+      // ----- lanes -----
+      for(var i=0;i<lanes.length;i++){
+        var ln = lanes[i];
+        var y = ln.row*cell;
+        for(var m=0;m<ln.items.length;m++){
+          var ix = ln.items[m].x*cell;
+          if(ix > W+cell || ix < -ln.len*cell-cell) continue;
+          if(ln.type==='car'){
+            ctx.save();
+            ctx.shadowColor = ln.color; ctx.shadowBlur = 12;
+            ctx.fillStyle = ln.color;
+            drawRoundRect(ix+3, y+cell*0.18, ln.len*cell-6, cell*0.64, 7);
+            ctx.fill();
+            ctx.shadowBlur = 0;
+            // windows
+            ctx.fillStyle = "rgba(10,14,20,0.6)";
+            ctx.fillRect(ix+ (ln.dir>0? ln.len*cell-16 : 8), y+cell*0.28, 8, cell*0.44);
+            ctx.restore();
+          }else{
+            // log or turtle
+            ctx.save();
+            if(ln.turtle){
+              ctx.shadowColor = ln.color; ctx.shadowBlur = 10;
+              ctx.fillStyle = ln.color;
+              for(var t=0;t<ln.len;t++){
+                ctx.beginPath();
+                ctx.ellipse(ix + t*cell + cell*0.5, y+cell*0.5, cell*0.34, cell*0.30, 0, 0, Math.PI*2);
+                ctx.fill();
+              }
+              ctx.shadowBlur=0;
+              ctx.fillStyle="rgba(4,30,26,0.5)";
+              for(var t2=0;t2<ln.len;t2++){
+                ctx.beginPath();
+                ctx.ellipse(ix + t2*cell + cell*0.5, y+cell*0.5, cell*0.16, cell*0.14, 0, 0, Math.PI*2);
+                ctx.fill();
+              }
+            }else{
+              ctx.shadowColor = "rgba(200,150,90,0.5)"; ctx.shadowBlur = 8;
+              ctx.fillStyle = ln.color;
+              drawRoundRect(ix+2, y+cell*0.20, ln.len*cell-4, cell*0.60, 9);
+              ctx.fill();
+              ctx.shadowBlur=0;
+              ctx.strokeStyle="rgba(80,50,20,0.5)";
+              ctx.lineWidth=1;
+              for(var g=1;g<ln.len;g++){
+                ctx.beginPath();
+                ctx.moveTo(ix+g*cell, y+cell*0.22);
+                ctx.lineTo(ix+g*cell, y+cell*0.78);
+                ctx.stroke();
+              }
+            }
+            ctx.restore();
+          }
+        }
+      }
+
+      // ----- player -----
+      if(state!=="over" && state!=="title"){
+        var pxPix = player.px*cell;
+        var pyPix = player.row*cell;
+        ctx.save();
+        var glow = player.alive ? "#7dffb0" : "#ff5b6b";
+        ctx.shadowColor = glow; ctx.shadowBlur = 18;
+        ctx.fillStyle = glow;
+        // body
+        drawRoundRect(pxPix+cell*0.18, pyPix+cell*0.18, cell*0.64, cell*0.64, 10);
+        ctx.fill();
+        ctx.shadowBlur = 0;
+        // eyes
+        ctx.fillStyle = "#04120e";
+        ctx.beginPath();
+        ctx.arc(pxPix+cell*0.38, pyPix+cell*0.40, cell*0.07, 0, Math.PI*2);
+        ctx.arc(pxPix+cell*0.62, pyPix+cell*0.40, cell*0.07, 0, Math.PI*2);
+        ctx.fill();
+        ctx.restore();
+      }
+
+      // ----- HUD -----
+      drawHUD();
+
+      // overlays
+      if(state==="title") drawTitle();
+      else if(state==="over") drawOver();
+
+      ctx.restore();
+    }
+
+    function drawHUD(){
+      var pad = 6;
+      ctx.save();
+      ctx.textBaseline = "top";
+      // score
+      var fs = Math.max(11, Math.round(cell*0.32));
+      ctx.font = "bold "+fs+"px 'Trebuchet MS',sans-serif";
+      ctx.fillStyle = "#8ff";
+      ctx.textAlign = "left";
+      ctx.fillText("SCORE "+score, pad+2, pad);
+      ctx.fillStyle = "#8fa";
+      ctx.textAlign = "center";
+      ctx.fillText("BEST "+best, W/2, pad);
+      // lives
+      ctx.textAlign = "right";
+      ctx.fillStyle = "#ff7d9c";
+      var lifeStr = "";
+      for(var i=0;i<lives;i++){ lifeStr += "♥"; }
+      ctx.fillText("LV"+level+"  "+lifeStr, W-pad-2, pad);
+
+      // timer bar
+      if(state==="play" || state==="dead"){
+        var barY = HOME_ROW*cell + cell + 3;
+        var barH = 5;
+        var frac = Math.max(0, timeLeft/timeMax);
+        ctx.fillStyle = "rgba(255,255,255,0.08)";
+        ctx.fillRect(6, barY, W-12, barH);
+        var col = frac>0.5? "#2ee6c8" : (frac>0.25? "#ffd23b" : "#ff3b6b");
+        ctx.shadowColor = col; ctx.shadowBlur = 8;
+        ctx.fillStyle = col;
+        ctx.fillRect(6, barY, (W-12)*frac, barH);
+        ctx.shadowBlur = 0;
+      }
+      ctx.restore();
+    }
+
+    function neonTitleText(txt, cx, cy, size, color){
+      ctx.save();
+      ctx.textAlign = "center";
+      ctx.textBaseline = "middle";
+      ctx.font = "bold "+size+"px 'Trebuchet MS',sans-serif";
+      // letter-spacing manual
+      var ls = size*0.16;
+      var chars = txt.split("");
+      var total = 0;
+      for(var i=0;i<chars.length;i++){ total += ctx.measureText(chars[i]).width + ls; }
+      total -= ls;
+      var x = cx - total/2;
+      ctx.shadowColor = color; ctx.shadowBlur = 22;
+      ctx.fillStyle = color;
+      for(var j=0;j<chars.length;j++){
+        var w = ctx.measureText(chars[j]).width;
+        ctx.fillText(chars[j], x + w/2, cy);
+        x += w + ls;
+      }
+      ctx.restore();
+    }
+
+    function drawTitle(){
+      ctx.save();
+      ctx.fillStyle = "rgba(4,7,12,0.82)";
+      ctx.fillRect(0,0,W,H);
+      neonTitleText("HOPPER", W/2, H*0.30, Math.round(cell*1.05), "#2ee6c8");
+      ctx.textAlign = "center";
+      ctx.fillStyle = "#bfe";
+      var s = Math.max(12, Math.round(cell*0.34));
+      ctx.font = s+"px 'Trebuchet MS',sans-serif";
+      ctx.fillText("Cross the road & river", W/2, H*0.44);
+      ctx.fillText("Fill all home slots", W/2, H*0.50);
+      ctx.fillStyle = "#8fa";
+      ctx.font = "bold "+s+"px 'Trebuchet MS',sans-serif";
+      ctx.fillText("ARROWS / WASD to hop", W/2, H*0.60);
+      // pulsing prompt
+      var a = 0.55 + 0.45*Math.sin(Date.now()/300);
+      ctx.fillStyle = "rgba(125,255,176,"+a.toFixed(3)+")";
+      ctx.font = "bold "+Math.round(cell*0.42)+"px 'Trebuchet MS',sans-serif";
+      ctx.fillText("TAP / PRESS TO START", W/2, H*0.72);
+      ctx.restore();
+    }
+
+    function drawOver(){
+      ctx.save();
+      ctx.fillStyle = "rgba(12,4,8,0.85)";
+      ctx.fillRect(0,0,W,H);
+      neonTitleText("GAME OVER", W/2, H*0.34, Math.round(cell*0.82), "#ff3b6b");
+      ctx.textAlign="center";
+      var s = Math.max(12, Math.round(cell*0.4));
+      ctx.font = "bold "+s+"px 'Trebuchet MS',sans-serif";
+      ctx.fillStyle = "#8ff";
+      ctx.fillText("SCORE "+score, W/2, H*0.48);
+      ctx.fillStyle = "#8fa";
+      ctx.fillText("BEST "+best, W/2, H*0.55);
+      var a = 0.55 + 0.45*Math.sin(Date.now()/300);
+      ctx.fillStyle = "rgba(125,255,176,"+a.toFixed(3)+")";
+      ctx.font = "bold "+Math.round(cell*0.42)+"px 'Trebuchet MS',sans-serif";
+      ctx.fillText("TAP / PRESS TO RETRY", W/2, H*0.68);
+      ctx.restore();
+    }
+
+    // ---------- D-pad (touch) ----------
+    var dpad = null; // {cx,cy,r} in canvas coords
+    function computeDpad(){
+      // place bottom-left area over start grass
+      var r = cell*1.1;
+      dpad = { cx: r*1.15, cy: H - r*1.15, r: r };
+    }
+    function drawDpad(){
+      if(!dpad) return;
+      if(state!=="play" && state!=="dead") return;
+      ctx.save();
+      ctx.translate(offX, offY);
+      ctx.globalAlpha = 0.5;
+      var d = dpad;
+      var arm = d.r*0.62, w = d.r*0.42;
+      ctx.fillStyle = "rgba(46,230,200,0.14)";
+      ctx.strokeStyle = "rgba(46,230,200,0.55)";
+      ctx.lineWidth = 2;
+      function armRect(ang){
+        ctx.save();
+        ctx.translate(d.cx,d.cy);
+        ctx.rotate(ang);
+        drawRoundRect(w*0.2, -w/2, arm, w, 6);
+        ctx.fill(); ctx.stroke();
+        // arrow tip
+        ctx.fillStyle="rgba(180,255,235,0.8)";
+        ctx.beginPath();
+        ctx.moveTo(arm+w*0.2, 0);
+        ctx.lineTo(arm-w*0.05, -w*0.28);
+        ctx.lineTo(arm-w*0.05, w*0.28);
+        ctx.closePath();
+        ctx.fill();
+        ctx.fillStyle="rgba(46,230,200,0.14)";
+        ctx.restore();
+      }
+      armRect(-Math.PI/2); // up
+      armRect(Math.PI/2);  // down
+      armRect(Math.PI);    // left
+      armRect(0);          // right
+      ctx.restore();
+    }
+    function dpadHit(x,y){
+      if(!dpad) return null;
+      var dx = x - dpad.cx, dy = y - dpad.cy;
+      var dist = Math.sqrt(dx*dx+dy*dy);
+      if(dist > dpad.r*1.35) return null;
+      if(dist < dpad.r*0.18) return null;
+      if(Math.abs(dx) > Math.abs(dy)){
+        return dx>0 ? "right" : "left";
+      }else{
+        return dy>0 ? "down" : "up";
+      }
+    }
+
+    // ---------- Input ----------
+    function handleDir(dir){
+      if(dir==="up") tryMove(0,-1);
+      else if(dir==="down") tryMove(0,1);
+      else if(dir==="left") tryMove(-1,0);
+      else if(dir==="right") tryMove(1,0);
+    }
+
+    function onKey(e){
+      var k = e.key;
+      var used = false;
+      if(k==="ArrowUp"||k==="w"||k==="W"){ used=true; act("up"); }
+      else if(k==="ArrowDown"||k==="s"||k==="S"){ used=true; act("down"); }
+      else if(k==="ArrowLeft"||k==="a"||k==="A"){ used=true; act("left"); }
+      else if(k==="ArrowRight"||k==="d"||k==="D"){ used=true; act("right"); }
+      else if(k===" "||k==="Enter"){ used=true; act("start"); }
+      if(used){ e.preventDefault(); }
+    }
+    function act(dir){
+      ensureAudio();
+      if(state==="title"){ startGame(); return; }
+      if(state==="over"){ startGame(); return; }
+      handleDir(dir);
+    }
+
+    window.addEventListener("keydown", onKey, {passive:false});
+
+    // touch / pointer
+    function canvasPoint(e){
+      var rect = canvas.getBoundingClientRect();
+      var cx = (e.clientX - rect.left) - offX;
+      var cy = (e.clientY - rect.top) - offY;
+      return {x:cx, y:cy};
+    }
+    function onPointerDown(e){
+      e.preventDefault();
+      ensureAudio();
+      if(state==="title"||state==="over"){ startGame(); return; }
+      var p = canvasPoint(e);
+      var hit = dpadHit(p.x, p.y);
+      if(hit){ handleDir(hit); return; }
+      // swipe-region fallback: tap relative to player => hop toward tap
+      var pcx = (player.px+0.5)*cell;
+      var pcy = (player.row+0.5)*cell;
+      var dx = p.x - pcx, dy = p.y - pcy;
+      if(Math.abs(dx)<cell*0.4 && Math.abs(dy)<cell*0.4){ tryMove(0,-1); return; }
+      if(Math.abs(dx) > Math.abs(dy)){ handleDir(dx>0?"right":"left"); }
+      else{ handleDir(dy>0?"down":"up"); }
+    }
+    canvas.addEventListener("pointerdown", onPointerDown, {passive:false});
+    canvas.addEventListener("touchstart", function(e){ e.preventDefault(); }, {passive:false});
+
+    // ---------- Resize ----------
+    function resize(){
+      var wrap = document.getElementById("wrap");
+      var availW = wrap.clientWidth || window.innerWidth;
+      var availH = wrap.clientHeight || window.innerHeight;
+      if(availW<=0) availW = window.innerWidth;
+      if(availH<=0) availH = window.innerHeight;
+      DPR = Math.min(window.devicePixelRatio||1, 2);
+
+      // choose cell to fit both dims
+      var cw = Math.floor(availW / COLS);
+      var ch = Math.floor(availH / ROWS);
+      cell = Math.max(12, Math.min(cw, ch));
+      W = COLS*cell; H = ROWS*cell;
+
+      canvas.width = Math.floor(availW*DPR);
+      canvas.height = Math.floor(availH*DPR);
+      canvas.style.width = availW+"px";
+      canvas.style.height = availH+"px";
+
+      offX = Math.floor((availW - W)/2);
+      offY = Math.floor((availH - H)/2);
+
+      computeDpad();
+
+      // rebuild lane item x extents not needed (grid-relative), but ensure lanes exist
+      if(lanes.length===0 && state!=="title"){ buildLanes(level); }
+    }
+    window.addEventListener("resize", resize);
+
+    // ---------- Loop ----------
+    var last = 0;
+    function frame(ts){
+      if(!last) last = ts;
+      var dt = (ts - last)/1000;
+      last = ts;
+      if(dt>0.1) dt = 0.1; // clamp
+      update(dt);
+      render();
+      drawDpad();
+      requestAnimationFrame(frame);
+    }
+
+    // ---------- Init ----------
+    setupHomeSlots();
+    resize();
+    requestAnimationFrame(frame);
+  }
+
+  if(document.readyState === "loading"){
+    document.addEventListener("DOMContentLoaded", boot);
+  }else{
+    boot();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/invaders/NeonInvaders.aa b/games/invaders/NeonInvaders.aa
new file mode 100644
index 0000000..0b75e8c
--- /dev/null
+++ b/games/invaders/NeonInvaders.aa
@@ -0,0 +1,891 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>NEON INVADERS</title>
+<style>
+  * { margin: 0; padding: 0; box-sizing: border-box; }
+  html, body {
+    width: 100%; height: 100%;
+    background: #05070c;
+    overflow: hidden;
+    touch-action: none;
+    -webkit-user-select: none; user-select: none;
+    -webkit-tap-highlight-color: transparent;
+    font-family: "Courier New", ui-monospace, monospace;
+  }
+  #wrap {
+    position: fixed; inset: 0;
+    display: flex; flex-direction: column;
+    align-items: center; justify-content: center;
+    background:
+      radial-gradient(ellipse at 50% 30%, #101a2b 0%, #0a0e14 55%, #05070c 100%);
+  }
+  #title {
+    color: #39ff14;
+    font-weight: bold;
+    letter-spacing: 0.42em;
+    text-transform: uppercase;
+    font-size: clamp(14px, 3.6vw, 26px);
+    text-shadow: 0 0 8px #39ff14, 0 0 18px rgba(57,255,20,.5);
+    padding: 8px 0 6px;
+    text-align: center;
+  }
+  #stage {
+    position: relative;
+    border: 1px solid rgba(57,255,20,.28);
+    box-shadow: 0 0 22px rgba(57,255,20,.15), inset 0 0 40px rgba(10,20,40,.6);
+    background: #060a12;
+    border-radius: 6px;
+    overflow: hidden;
+  }
+  canvas { display: block; touch-action: none; }
+  #touch {
+    position: absolute; inset: 0;
+    display: none;
+    pointer-events: none;
+  }
+  .tbtn {
+    position: absolute;
+    pointer-events: auto;
+    display: flex; align-items: center; justify-content: center;
+    color: #7ffcff;
+    border: 1px solid rgba(127,252,255,.4);
+    background: rgba(10,20,35,.35);
+    border-radius: 12px;
+    font-size: 26px; font-weight: bold;
+    text-shadow: 0 0 6px #7ffcff;
+    backdrop-filter: blur(2px);
+    user-select: none;
+  }
+  .tbtn:active { background: rgba(127,252,255,.22); }
+  #bLeft  { left: 12px;  bottom: 14px; width: 62px; height: 62px; }
+  #bRight { left: 88px;  bottom: 14px; width: 62px; height: 62px; }
+  #bFire  { right: 14px; bottom: 14px; width: 78px; height: 78px;
+            color:#ff4fd8; border-color:rgba(255,79,216,.5); text-shadow:0 0 6px #ff4fd8; }
+  #hint {
+    color: rgba(160,200,220,.55);
+    font-size: clamp(9px, 1.9vw, 12px);
+    letter-spacing: .12em;
+    padding: 8px 6px 10px;
+    text-align: center;
+  }
+</style>
+</head>
+<body>
+  <div id="wrap">
+    <div id="title">Neon Invaders</div>
+    <div id="stage">
+      <canvas id="c"></canvas>
+      <div id="touch">
+        <div class="tbtn" id="bLeft">&#9664;</div>
+        <div class="tbtn" id="bRight">&#9654;</div>
+        <div class="tbtn" id="bFire">FIRE</div>
+      </div>
+    </div>
+    <div id="hint">&larr; &rarr; / A D MOVE &nbsp;&bull;&nbsp; SPACE FIRE &nbsp;&bull;&nbsp; P PAUSE</div>
+  </div>
+
+<script>
+(function () {
+  "use strict";
+
+  var BEST_KEY = "abrams-invaders-best";
+
+  function boot() {
+    var canvas = document.getElementById("c");
+    var ctx = canvas.getContext("2d");
+    var stage = document.getElementById("stage");
+    var touchLayer = document.getElementById("touch");
+
+    // Logical resolution (game world). Canvas is scaled to fit.
+    var W = 480, H = 640;
+    var DPR = 1;
+
+    function fitCanvas() {
+      // Available space inside the wrap, minus title/hint chrome.
+      var availW = Math.min(window.innerWidth - 12, 520);
+      var availH = window.innerHeight - 120;
+      if (availW < 200) availW = 200;
+      if (availH < 300) availH = 300;
+      var scale = Math.min(availW / W, availH / H);
+      if (!isFinite(scale) || scale <= 0) scale = 1;
+      var cssW = Math.round(W * scale);
+      var cssH = Math.round(H * scale);
+      DPR = Math.min(window.devicePixelRatio || 1, 2);
+      canvas.style.width = cssW + "px";
+      canvas.style.height = cssH + "px";
+      canvas.width = Math.round(W * DPR);
+      canvas.height = Math.round(H * DPR);
+      stage.style.width = cssW + "px";
+      stage.style.height = cssH + "px";
+      ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+    }
+
+    // ---- Audio (lazy) ----
+    var actx = null, muted = false;
+    function ensureAudio() {
+      if (actx || muted) return;
+      try {
+        var AC = window.AudioContext || window.webkitAudioContext;
+        if (!AC) { muted = true; return; }
+        actx = new AC();
+      } catch (e) { muted = true; actx = null; }
+    }
+    function blip(type, freq, dur, vol) {
+      if (!actx) return;
+      try {
+        if (actx.state === "suspended") { actx.resume().catch(function(){}); }
+        var o = actx.createOscillator();
+        var g = actx.createGain();
+        o.type = type;
+        o.frequency.value = freq;
+        var t = actx.currentTime;
+        g.gain.setValueAtTime(0.0001, t);
+        g.gain.exponentialRampToValueAtTime(vol, t + 0.008);
+        g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
+        o.connect(g); g.connect(actx.destination);
+        o.start(t); o.stop(t + dur + 0.02);
+      } catch (e) { /* never throw from audio */ }
+    }
+    function sShoot()  { blip("square", 880, 0.09, 0.05); }
+    function sHit()    { blip("triangle", 320, 0.10, 0.06); }
+    function sBoom()   { blip("sawtooth", 120, 0.32, 0.08); }
+    function sUfo()    { blip("sine", 1200, 0.14, 0.05); }
+    function sStep(i)  { blip("square", 200 + (i % 4) * 30, 0.05, 0.03); }
+
+    // ---- Game state ----
+    var STATE = { MENU: 0, PLAY: 1, WAVE: 2, OVER: 3, PAUSED: 4 };
+    var state = STATE.MENU;
+
+    var best = 0;
+    try {
+      var stored = localStorage.getItem(BEST_KEY);
+      if (stored != null) { var n = parseInt(stored, 10); if (!isNaN(n)) best = n; }
+    } catch (e) { best = 0; }
+
+    var score = 0, lives = 3, wave = 1;
+
+    var player, bullets, bombs, invaders, bunkers, ufo, particles;
+    var invDir, invStepTimer, invStepInterval, invDropPending;
+    var fireCooldown, ufoTimer, stepIndex;
+    var flashTimer = 0;
+
+    var keys = {};
+    var touch = { left: false, right: false, fire: false };
+
+    // ---- Entity setup ----
+    function makePlayer() {
+      return { x: W / 2, y: H - 46, w: 40, h: 18, speed: 260, cool: 0 };
+    }
+
+    function makeBunkers() {
+      var arr = [];
+      var count = 4;
+      var bw = 58, bh = 40;
+      var gap = (W - count * bw) / (count + 1);
+      var by = H - 130;
+      for (var b = 0; b < count; b++) {
+        var bx = gap + b * (bw + gap);
+        var cellsX = 7, cellsY = 5;
+        var cw = bw / cellsX, ch = bh / cellsY;
+        var cells = [];
+        for (var yy = 0; yy < cellsY; yy++) {
+          for (var xx = 0; xx < cellsX; xx++) {
+            // carve an arch shape
+            var isNotch = (yy >= 3) && (xx >= 2 && xx <= 4);
+            if (isNotch) continue;
+            cells.push({
+              x: bx + xx * cw, y: by + yy * ch,
+              w: cw, h: ch, hp: 3
+            });
+          }
+        }
+        arr.push({ cells: cells });
+      }
+      return arr;
+    }
+
+    function buildInvaders() {
+      invaders = [];
+      var cols = 8, rows = 5;
+      var cellW = 44, cellH = 34;
+      var gridW = cols * cellW;
+      var startX = (W - gridW) / 2 + cellW / 2;
+      var startY = 70;
+      for (var r = 0; r < rows; r++) {
+        for (var col = 0; col < cols; col++) {
+          var type = r === 0 ? 2 : (r < 3 ? 1 : 0);
+          invaders.push({
+            x: startX + col * cellW,
+            y: startY + r * cellH,
+            w: 28, h: 20,
+            type: type,
+            alive: true,
+            row: r, col: col
+          });
+        }
+      }
+      invDir = 1;
+      invStepTimer = 0;
+      invStepInterval = Math.max(0.18, 0.75 - (wave - 1) * 0.06);
+      invDropPending = false;
+      stepIndex = 0;
+    }
+
+    function startGame() {
+      score = 0; lives = 3; wave = 1;
+      player = makePlayer();
+      bullets = []; bombs = []; particles = [];
+      bunkers = makeBunkers();
+      ufo = null;
+      fireCooldown = 0;
+      ufoTimer = rand(8, 16);
+      buildInvaders();
+      state = STATE.PLAY;
+    }
+
+    function nextWave() {
+      wave++;
+      player.x = W / 2;
+      bullets = []; bombs = [];
+      bunkers = makeBunkers();
+      ufo = null;
+      ufoTimer = rand(8, 16);
+      buildInvaders();
+      state = STATE.PLAY;
+      flashTimer = 0.6;
+    }
+
+    function rand(a, b) { return a + Math.random() * (b - a); }
+
+    // ---- Particles ----
+    function burst(x, y, color, n) {
+      for (var i = 0; i < n; i++) {
+        var a = Math.random() * Math.PI * 2;
+        var sp = rand(30, 160);
+        particles.push({
+          x: x, y: y,
+          vx: Math.cos(a) * sp, vy: Math.sin(a) * sp,
+          life: rand(0.3, 0.7), max: 0.7, color: color
+        });
+      }
+    }
+
+    // ---- Collision ----
+    function overlap(ax, ay, aw, ah, bx, by, bw, bh) {
+      return ax < bx + bw && ax + aw > bx && ay < by + bh && ay + ah > by;
+    }
+
+    // ---- Update ----
+    function update(dt) {
+      if (state !== STATE.PLAY) {
+        // still animate particles on OVER for a moment
+        updateParticles(dt);
+        return;
+      }
+
+      if (flashTimer > 0) flashTimer -= dt;
+
+      // player movement
+      var mv = 0;
+      if (keys.left || touch.left) mv -= 1;
+      if (keys.right || touch.right) mv += 1;
+      player.x += mv * player.speed * dt;
+      var half = player.w / 2;
+      if (player.x < half) player.x = half;
+      if (player.x > W - half) player.x = W - half;
+
+      // firing
+      if (player.cool > 0) player.cool -= dt;
+      if ((keys.fire || touch.fire) && player.cool <= 0) {
+        bullets.push({ x: player.x, y: player.y - 12, w: 3, h: 14, vy: -520 });
+        player.cool = 0.34;
+        sShoot();
+      }
+
+      // bullets
+      for (var i = bullets.length - 1; i >= 0; i--) {
+        var bl = bullets[i];
+        bl.y += bl.vy * dt;
+        if (bl.y + bl.h < 0) { bullets.splice(i, 1); continue; }
+      }
+
+      // invader movement (grid step)
+      updateInvaders(dt);
+
+      // bombs (from invaders)
+      for (var j = bombs.length - 1; j >= 0; j--) {
+        var bo = bombs[j];
+        bo.y += bo.vy * dt;
+        bo.t = (bo.t || 0) + dt;
+        if (bo.y > H) { bombs.splice(j, 1); continue; }
+      }
+
+      // UFO
+      updateUfo(dt);
+
+      // collisions
+      handleCollisions();
+
+      updateParticles(dt);
+
+      // win condition
+      var anyAlive = false;
+      for (var k = 0; k < invaders.length; k++) { if (invaders[k].alive) { anyAlive = true; break; } }
+      if (!anyAlive) {
+        state = STATE.WAVE;
+        waveDelay = 1.4;
+      }
+    }
+
+    var waveDelay = 0;
+
+    function updateInvaders(dt) {
+      var aliveList = [];
+      var minX = 1e9, maxX = -1e9, maxY = -1e9;
+      for (var i = 0; i < invaders.length; i++) {
+        var inv = invaders[i];
+        if (!inv.alive) continue;
+        aliveList.push(inv);
+        if (inv.x - inv.w / 2 < minX) minX = inv.x - inv.w / 2;
+        if (inv.x + inv.w / 2 > maxX) maxX = inv.x + inv.w / 2;
+        if (inv.y + inv.h / 2 > maxY) maxY = inv.y + inv.h / 2;
+      }
+      if (aliveList.length === 0) return;
+
+      // Speed scales up as fewer remain.
+      var frac = aliveList.length / invaders.length;
+      var interval = invStepInterval * (0.35 + 0.65 * frac);
+      invStepTimer += dt;
+      if (invStepTimer >= interval) {
+        invStepTimer = 0;
+        stepIndex++;
+        sStep(stepIndex);
+
+        var stepX = 12;
+        var willHit = (invDir > 0 && maxX + stepX >= W - 6) ||
+                      (invDir < 0 && minX - stepX <= 6);
+        if (willHit) {
+          invDir *= -1;
+          for (var d = 0; d < aliveList.length; d++) aliveList[d].y += 18;
+        } else {
+          for (var m = 0; m < aliveList.length; m++) aliveList[m].x += stepX * invDir;
+        }
+
+        // reached player level -> game over
+        for (var q = 0; q < aliveList.length; q++) {
+          if (aliveList[q].y + aliveList[q].h / 2 >= player.y - 6) {
+            loseAllLives();
+            return;
+          }
+        }
+      }
+
+      // random bomb drops from bottom-most invaders per column
+      var dropChance = (0.35 + wave * 0.12) * dt;
+      if (Math.random() < dropChance && aliveList.length) {
+        // find a random column's lowest alive invader
+        var shooter = aliveList[(Math.random() * aliveList.length) | 0];
+        // ensure it's the lowest in its column
+        var lowest = shooter;
+        for (var c = 0; c < aliveList.length; c++) {
+          if (aliveList[c].col === shooter.col && aliveList[c].y > lowest.y) lowest = aliveList[c];
+        }
+        bombs.push({ x: lowest.x, y: lowest.y + 12, w: 5, h: 12, vy: rand(170, 210) + wave * 8, t: 0 });
+      }
+    }
+
+    function updateUfo(dt) {
+      if (ufo) {
+        ufo.x += ufo.vx * dt;
+        if ((ufo.vx > 0 && ufo.x > W + 40) || (ufo.vx < 0 && ufo.x < -40)) {
+          ufo = null;
+        }
+      } else {
+        ufoTimer -= dt;
+        if (ufoTimer <= 0) {
+          var fromLeft = Math.random() < 0.5;
+          ufo = {
+            x: fromLeft ? -30 : W + 30,
+            y: 42, w: 40, h: 16,
+            vx: fromLeft ? 90 : -90,
+            value: [50, 100, 150, 300][(Math.random() * 4) | 0]
+          };
+          ufoTimer = rand(12, 22);
+        }
+      }
+    }
+
+    function updateParticles(dt) {
+      for (var i = particles.length - 1; i >= 0; i--) {
+        var p = particles[i];
+        p.life -= dt;
+        if (p.life <= 0) { particles.splice(i, 1); continue; }
+        p.x += p.vx * dt;
+        p.y += p.vy * dt;
+        p.vy += 120 * dt;
+      }
+    }
+
+    function damageBunkerAt(x, y, w, h) {
+      for (var b = 0; b < bunkers.length; b++) {
+        var cells = bunkers[b].cells;
+        for (var i = cells.length - 1; i >= 0; i--) {
+          var cl = cells[i];
+          if (overlap(x, y, w, h, cl.x, cl.y, cl.w, cl.h)) {
+            cl.hp--;
+            burst(cl.x + cl.w / 2, cl.y + cl.h / 2, "#39ff14", 4);
+            if (cl.hp <= 0) cells.splice(i, 1);
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+
+    function handleCollisions() {
+      // player bullets
+      for (var i = bullets.length - 1; i >= 0; i--) {
+        var bl = bullets[i];
+        var bx = bl.x - bl.w / 2, by = bl.y;
+
+        // bunkers
+        if (damageBunkerAt(bx, by, bl.w, bl.h)) { bullets.splice(i, 1); continue; }
+
+        // ufo
+        if (ufo && overlap(bx, by, bl.w, bl.h, ufo.x - ufo.w / 2, ufo.y - ufo.h / 2, ufo.w, ufo.h)) {
+          addScore(ufo.value);
+          burst(ufo.x, ufo.y, "#ff4fd8", 22);
+          sUfo();
+          ufo = null;
+          bullets.splice(i, 1);
+          continue;
+        }
+
+        // invaders
+        var hitInv = false;
+        for (var k = 0; k < invaders.length; k++) {
+          var inv = invaders[k];
+          if (!inv.alive) continue;
+          if (overlap(bx, by, bl.w, bl.h, inv.x - inv.w / 2, inv.y - inv.h / 2, inv.w, inv.h)) {
+            inv.alive = false;
+            addScore((inv.type + 1) * 10);
+            burst(inv.x, inv.y, invColor(inv.type), 16);
+            sHit();
+            hitInv = true;
+            break;
+          }
+        }
+        if (hitInv) { bullets.splice(i, 1); continue; }
+      }
+
+      // enemy bombs
+      for (var j = bombs.length - 1; j >= 0; j--) {
+        var bo = bombs[j];
+        var ox = bo.x - bo.w / 2, oy = bo.y;
+
+        if (damageBunkerAt(ox, oy, bo.w, bo.h)) { bombs.splice(j, 1); continue; }
+
+        if (overlap(ox, oy, bo.w, bo.h, player.x - player.w / 2, player.y - player.h / 2, player.w, player.h)) {
+          bombs.splice(j, 1);
+          playerHit();
+          continue;
+        }
+      }
+    }
+
+    function invColor(type) {
+      return type === 2 ? "#ff4fd8" : (type === 1 ? "#7ffcff" : "#39ff14");
+    }
+
+    function addScore(v) {
+      score += v;
+      if (score > best) {
+        best = score;
+        try { localStorage.setItem(BEST_KEY, String(best)); } catch (e) { /* ignore */ }
+      }
+    }
+
+    function playerHit() {
+      lives--;
+      burst(player.x, player.y, "#ffd23f", 26);
+      sBoom();
+      flashTimer = 0.35;
+      if (lives <= 0) {
+        gameOver();
+      } else {
+        player.x = W / 2;
+        player.cool = 0.6;
+      }
+    }
+
+    function loseAllLives() {
+      lives = 0;
+      burst(player.x, player.y, "#ffd23f", 30);
+      sBoom();
+      gameOver();
+    }
+
+    function gameOver() {
+      state = STATE.OVER;
+    }
+
+    // ---- Render ----
+    function draw() {
+      ctx.clearRect(0, 0, W, H);
+
+      // starfield backdrop
+      drawStars();
+
+      if (flashTimer > 0 && (state === STATE.PLAY || state === STATE.WAVE)) {
+        ctx.fillStyle = "rgba(255,210,63," + Math.min(0.25, flashTimer * 0.4) + ")";
+        ctx.fillRect(0, 0, W, H);
+      }
+
+      if (state === STATE.MENU) {
+        drawMenu();
+        drawParticles();
+        return;
+      }
+
+      // bunkers
+      for (var b = 0; b < bunkers.length; b++) {
+        var cells = bunkers[b].cells;
+        for (var i = 0; i < cells.length; i++) {
+          var cl = cells[i];
+          var a = cl.hp / 3;
+          ctx.fillStyle = "rgba(57,255,20," + (0.35 + a * 0.55) + ")";
+          ctx.fillRect(cl.x + 0.5, cl.y + 0.5, cl.w - 1, cl.h - 1);
+        }
+      }
+
+      // invaders
+      for (var k = 0; k < invaders.length; k++) {
+        if (invaders[k].alive) drawInvader(invaders[k]);
+      }
+
+      // ufo
+      if (ufo) drawUfo(ufo);
+
+      // bullets
+      ctx.save();
+      ctx.shadowBlur = 8; ctx.shadowColor = "#ffffff";
+      ctx.fillStyle = "#ffffff";
+      for (var m = 0; m < bullets.length; m++) {
+        var bl = bullets[m];
+        ctx.fillRect(bl.x - bl.w / 2, bl.y, bl.w, bl.h);
+      }
+      ctx.restore();
+
+      // bombs
+      ctx.save();
+      ctx.shadowBlur = 8; ctx.shadowColor = "#ff4fd8";
+      for (var n = 0; n < bombs.length; n++) {
+        var bo = bombs[n];
+        ctx.fillStyle = ((bo.t * 20) | 0) % 2 ? "#ff4fd8" : "#ffb0ec";
+        ctx.fillRect(bo.x - bo.w / 2, bo.y, bo.w, bo.h);
+      }
+      ctx.restore();
+
+      // player
+      if (state === STATE.PLAY || state === STATE.WAVE || state === STATE.PAUSED) drawPlayer();
+
+      drawParticles();
+      drawHUD();
+
+      if (state === STATE.OVER) drawGameOver();
+      if (state === STATE.PAUSED) drawPaused();
+      if (state === STATE.WAVE) drawWaveBanner();
+    }
+
+    var stars = [];
+    function initStars() {
+      stars = [];
+      for (var i = 0; i < 60; i++) {
+        stars.push({ x: Math.random() * W, y: Math.random() * H, s: Math.random() * 1.6 + 0.4, t: Math.random() * 6.28 });
+      }
+    }
+    function drawStars() {
+      for (var i = 0; i < stars.length; i++) {
+        var st = stars[i];
+        var tw = 0.4 + 0.6 * Math.abs(Math.sin(st.t + performance.now() / 900));
+        ctx.fillStyle = "rgba(120,180,220," + (tw * 0.5) + ")";
+        ctx.fillRect(st.x, st.y, st.s, st.s);
+      }
+    }
+
+    function drawPlayer() {
+      var px = player.x, py = player.y, w = player.w, h = player.h;
+      ctx.save();
+      ctx.shadowBlur = 12; ctx.shadowColor = "#39ff14";
+      ctx.fillStyle = "#39ff14";
+      // cannon body
+      ctx.beginPath();
+      ctx.moveTo(px - w / 2, py + h / 2);
+      ctx.lineTo(px + w / 2, py + h / 2);
+      ctx.lineTo(px + w / 2, py + h / 2 - 6);
+      ctx.lineTo(px + 8, py + h / 2 - 6);
+      ctx.lineTo(px + 4, py - h / 2 + 2);
+      ctx.lineTo(px - 4, py - h / 2 + 2);
+      ctx.lineTo(px - 8, py + h / 2 - 6);
+      ctx.lineTo(px - w / 2, py + h / 2 - 6);
+      ctx.closePath();
+      ctx.fill();
+      ctx.fillRect(px - 2, py - h / 2 - 4, 4, 6);
+      ctx.restore();
+    }
+
+    function drawInvader(inv) {
+      var x = inv.x - inv.w / 2, y = inv.y - inv.h / 2, w = inv.w, h = inv.h;
+      var col = invColor(inv.type);
+      var frame = stepIndex % 2;
+      ctx.save();
+      ctx.shadowBlur = 8; ctx.shadowColor = col;
+      ctx.fillStyle = col;
+      var px = w / 8, py = h / 5;
+      // simple 8x5 sprite bitmaps
+      var A = [
+        [0,0,1,0,0,1,0,0],
+        [0,1,1,1,1,1,1,0],
+        [1,1,0,1,1,0,1,1],
+        [1,1,1,1,1,1,1,1],
+        frame ? [0,1,0,0,0,0,1,0] : [1,0,1,0,0,1,0,1]
+      ];
+      for (var ry = 0; ry < 5; ry++) {
+        for (var rx = 0; rx < 8; rx++) {
+          if (A[ry][rx]) ctx.fillRect(x + rx * px, y + ry * py, px + 0.5, py + 0.5);
+        }
+      }
+      ctx.restore();
+    }
+
+    function drawUfo(u) {
+      ctx.save();
+      ctx.shadowBlur = 12; ctx.shadowColor = "#ff4fd8";
+      ctx.fillStyle = "#ff4fd8";
+      ctx.beginPath();
+      ctx.ellipse(u.x, u.y, u.w / 2, u.h / 2, 0, 0, Math.PI * 2);
+      ctx.fill();
+      ctx.fillStyle = "#ffd23f";
+      ctx.beginPath();
+      ctx.ellipse(u.x, u.y - 3, u.w / 4, u.h / 3, 0, Math.PI, 0);
+      ctx.fill();
+      ctx.restore();
+    }
+
+    function drawParticles() {
+      for (var i = 0; i < particles.length; i++) {
+        var p = particles[i];
+        var a = Math.max(0, p.life / p.max);
+        ctx.globalAlpha = a;
+        ctx.fillStyle = p.color;
+        ctx.fillRect(p.x - 1.5, p.y - 1.5, 3, 3);
+      }
+      ctx.globalAlpha = 1;
+    }
+
+    function drawHUD() {
+      ctx.save();
+      ctx.font = "bold 15px 'Courier New', monospace";
+      ctx.textBaseline = "top";
+      ctx.fillStyle = "#39ff14";
+      ctx.shadowBlur = 6; ctx.shadowColor = "#39ff14";
+      ctx.textAlign = "left";
+      ctx.fillText("SCORE " + pad(score, 5), 12, 10);
+      ctx.textAlign = "center";
+      ctx.fillStyle = "#7ffcff"; ctx.shadowColor = "#7ffcff";
+      ctx.fillText("WAVE " + wave, W / 2, 10);
+      ctx.textAlign = "right";
+      ctx.fillStyle = "#ffd23f"; ctx.shadowColor = "#ffd23f";
+      ctx.fillText("BEST " + pad(best, 5), W - 12, 10);
+      ctx.restore();
+
+      // lives
+      for (var i = 0; i < lives; i++) {
+        var lx = 20 + i * 26, ly = H - 22;
+        ctx.save();
+        ctx.shadowBlur = 6; ctx.shadowColor = "#39ff14";
+        ctx.fillStyle = "#39ff14";
+        ctx.beginPath();
+        ctx.moveTo(lx - 8, ly + 6);
+        ctx.lineTo(lx + 8, ly + 6);
+        ctx.lineTo(lx + 4, ly - 4);
+        ctx.lineTo(lx - 4, ly - 4);
+        ctx.closePath();
+        ctx.fill();
+        ctx.fillRect(lx - 1, ly - 8, 2, 4);
+        ctx.restore();
+      }
+    }
+
+    function drawMenu() {
+      centerText("NEON INVADERS", W / 2, H / 2 - 70, "bold 34px 'Courier New', monospace", "#39ff14", 8, 0.12);
+      centerText("DEFEND THE GRID", W / 2, H / 2 - 30, "14px 'Courier New', monospace", "#7ffcff", 4, 0.3);
+      var blink = (Math.floor(performance.now() / 500) % 2) === 0;
+      if (blink) centerText("PRESS SPACE / TAP TO START", W / 2, H / 2 + 30, "bold 15px 'Courier New', monospace", "#ffd23f", 6, 0.1);
+      centerText("BEST  " + pad(best, 5), W / 2, H / 2 + 80, "14px 'Courier New', monospace", "#ff4fd8", 4, 0.2);
+    }
+
+    function drawGameOver() {
+      ctx.fillStyle = "rgba(5,7,12,.6)";
+      ctx.fillRect(0, 0, W, H);
+      centerText("GAME OVER", W / 2, H / 2 - 50, "bold 34px 'Courier New', monospace", "#ff4fd8", 10, 0.1);
+      centerText("SCORE  " + pad(score, 5), W / 2, H / 2, "16px 'Courier New', monospace", "#39ff14", 5, 0.15);
+      centerText("BEST   " + pad(best, 5), W / 2, H / 2 + 26, "16px 'Courier New', monospace", "#ffd23f", 5, 0.15);
+      var blink = (Math.floor(performance.now() / 500) % 2) === 0;
+      if (blink) centerText("PRESS SPACE / TAP TO RESTART", W / 2, H / 2 + 70, "bold 14px 'Courier New', monospace", "#7ffcff", 5, 0.08);
+    }
+
+    function drawPaused() {
+      ctx.fillStyle = "rgba(5,7,12,.55)";
+      ctx.fillRect(0, 0, W, H);
+      centerText("PAUSED", W / 2, H / 2 - 10, "bold 30px 'Courier New', monospace", "#7ffcff", 8, 0.2);
+      centerText("PRESS P TO RESUME", W / 2, H / 2 + 30, "13px 'Courier New', monospace", "#ffd23f", 4, 0.1);
+    }
+
+    function drawWaveBanner() {
+      centerText("WAVE " + wave + " CLEARED", W / 2, H / 2 - 10, "bold 26px 'Courier New', monospace", "#39ff14", 8, 0.14);
+    }
+
+    function centerText(txt, x, y, font, color, glow, spacing) {
+      ctx.save();
+      ctx.font = font;
+      ctx.textAlign = "center";
+      ctx.textBaseline = "middle";
+      ctx.shadowBlur = glow || 0;
+      ctx.shadowColor = color;
+      ctx.fillStyle = color;
+      if (spacing) {
+        // manual letter spacing
+        var total = 0, i;
+        var widths = [];
+        for (i = 0; i < txt.length; i++) {
+          var wch = ctx.measureText(txt[i]).width + spacing * 20;
+          widths.push(wch); total += wch;
+        }
+        var cx = x - total / 2;
+        ctx.textAlign = "left";
+        for (i = 0; i < txt.length; i++) {
+          ctx.fillText(txt[i], cx, y);
+          cx += widths[i];
+        }
+      } else {
+        ctx.fillText(txt, x, y);
+      }
+      ctx.restore();
+    }
+
+    function pad(n, len) {
+      var s = String(Math.max(0, n | 0));
+      while (s.length < len) s = "0" + s;
+      return s;
+    }
+
+    // ---- Input ----
+    function onKeyDown(e) {
+      var k = e.key;
+      if (k === "ArrowLeft" || k === "a" || k === "A") { keys.left = true; e.preventDefault(); }
+      else if (k === "ArrowRight" || k === "d" || k === "D") { keys.right = true; e.preventDefault(); }
+      else if (k === " " || k === "Spacebar" || k === "ArrowUp") {
+        keys.fire = true; e.preventDefault();
+        ensureAudio();
+        if (state === STATE.MENU || state === STATE.OVER) startGame();
+      }
+      else if (k === "p" || k === "P") {
+        if (state === STATE.PLAY) state = STATE.PAUSED;
+        else if (state === STATE.PAUSED) state = STATE.PLAY;
+      }
+      else if (k === "m" || k === "M") { muted = !muted; }
+    }
+    function onKeyUp(e) {
+      var k = e.key;
+      if (k === "ArrowLeft" || k === "a" || k === "A") keys.left = false;
+      else if (k === "ArrowRight" || k === "d" || k === "D") keys.right = false;
+      else if (k === " " || k === "Spacebar" || k === "ArrowUp") keys.fire = false;
+    }
+
+    window.addEventListener("keydown", onKeyDown, { passive: false });
+    window.addEventListener("keyup", onKeyUp);
+
+    // Touch controls
+    function bindTouch(el, key) {
+      function down(ev) {
+        ev.preventDefault();
+        ensureAudio();
+        touch[key] = true;
+        if (key === "fire" && (state === STATE.MENU || state === STATE.OVER)) startGame();
+      }
+      function up(ev) { ev.preventDefault(); touch[key] = false; }
+      el.addEventListener("touchstart", down, { passive: false });
+      el.addEventListener("touchend", up, { passive: false });
+      el.addEventListener("touchcancel", up, { passive: false });
+      el.addEventListener("mousedown", down);
+      el.addEventListener("mouseup", up);
+      el.addEventListener("mouseleave", up);
+    }
+    bindTouch(document.getElementById("bLeft"), "left");
+    bindTouch(document.getElementById("bRight"), "right");
+    bindTouch(document.getElementById("bFire"), "fire");
+
+    // Tap on canvas also starts / fires on touch devices
+    canvas.addEventListener("touchstart", function (ev) {
+      ev.preventDefault();
+      ensureAudio();
+      if (state === STATE.MENU || state === STATE.OVER) startGame();
+    }, { passive: false });
+    canvas.addEventListener("mousedown", function () {
+      ensureAudio();
+      if (state === STATE.MENU || state === STATE.OVER) startGame();
+    });
+
+    // Show touch controls when a touch is detected
+    function enableTouchUI() {
+      touchLayer.style.display = "block";
+      window.removeEventListener("touchstart", enableTouchUI);
+    }
+    window.addEventListener("touchstart", enableTouchUI, { passive: true });
+    if (("ontouchstart" in window) || (navigator.maxTouchPoints > 0)) {
+      touchLayer.style.display = "block";
+    }
+
+    window.addEventListener("resize", fitCanvas);
+
+    // ---- Loop ----
+    var last = performance.now();
+    function frame(now) {
+      var dt = (now - last) / 1000;
+      last = now;
+      if (dt > 0.05) dt = 0.05; // clamp for tab-switch spikes
+
+      if (state === STATE.WAVE) {
+        updateParticles(dt);
+        waveDelay -= dt;
+        if (waveDelay <= 0) nextWave();
+      } else {
+        update(dt);
+      }
+
+      draw();
+      requestAnimationFrame(frame);
+    }
+
+    // ---- Init ----
+    initStars();
+    fitCanvas();
+    // initialize placeholder arrays for menu particle draws
+    particles = [];
+    bullets = []; bombs = []; invaders = []; bunkers = []; player = makePlayer();
+    requestAnimationFrame(frame);
+  }
+
+  if (document.readyState === "loading") {
+    document.addEventListener("DOMContentLoaded", boot);
+  } else {
+    boot();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/lights-out/AbramsLightsOut.aa b/games/lights-out/AbramsLightsOut.aa
new file mode 100644
index 0000000..badcefd
--- /dev/null
+++ b/games/lights-out/AbramsLightsOut.aa
@@ -0,0 +1,471 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<title>Abrams Lights Out</title>
+<style>
+  :root{
+    --bg:#070a12;
+    --bg2:#0d1220;
+    --panel:rgba(255,255,255,.045);
+    --stroke:rgba(140,180,255,.14);
+    --txt:#e8eefc;
+    --dim:#8a96b4;
+    --neon:#38f0d6;
+    --neon2:#12b8d8;
+    --lit-a:#3bffe0;
+    --lit-b:#1aa9ff;
+    --gap:clamp(6px,1.4vmin,14px);
+  }
+  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
+  html,body{height:100%;margin:0}
+  body{
+    font-family:'Trebuchet MS',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
+    color:var(--txt);
+    background:
+      radial-gradient(1100px 700px at 15% -10%,rgba(30,200,220,.14),transparent 60%),
+      radial-gradient(900px 600px at 110% 120%,rgba(60,120,255,.13),transparent 55%),
+      linear-gradient(160deg,var(--bg),var(--bg2));
+    min-height:100%;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    padding:clamp(8px,2vmin,20px);
+    overflow:hidden;
+    user-select:none;
+  }
+  .wrap{
+    width:100%;
+    max-width:min(560px,94vmin);
+    display:flex;
+    flex-direction:column;
+    gap:clamp(10px,2vmin,16px);
+  }
+  header{text-align:center;line-height:1.05}
+  h1{
+    margin:0;
+    font-size:clamp(22px,5.4vmin,40px);
+    font-weight:800;
+    letter-spacing:.5px;
+    background:linear-gradient(90deg,var(--lit-a),var(--lit-b));
+    -webkit-background-clip:text;background-clip:text;
+    -webkit-text-fill-color:transparent;
+    filter:drop-shadow(0 0 14px rgba(56,240,214,.35));
+  }
+  .sub{margin:3px 0 0;color:var(--dim);font-size:clamp(10px,2.4vmin,13px);letter-spacing:2px;text-transform:uppercase}
+
+  .stats{
+    display:flex;justify-content:center;gap:clamp(8px,2vmin,14px);flex-wrap:wrap;
+  }
+  .stat{
+    background:var(--panel);border:1px solid var(--stroke);border-radius:12px;
+    padding:clamp(6px,1.4vmin,10px) clamp(10px,2.4vmin,18px);
+    min-width:74px;text-align:center;backdrop-filter:blur(6px);
+  }
+  .stat .k{font-size:clamp(9px,2vmin,10px);color:var(--dim);letter-spacing:1.5px;text-transform:uppercase}
+  .stat .v{font-size:clamp(16px,4vmin,24px);font-weight:800;font-variant-numeric:tabular-nums;margin-top:2px}
+  .stat.best .v{color:var(--neon)}
+
+  .boardwrap{position:relative;width:100%;aspect-ratio:1/1;margin:0 auto}
+  #board{
+    position:absolute;inset:0;
+    display:grid;gap:var(--gap);
+    padding:var(--gap);
+    background:rgba(4,8,16,.5);
+    border:1px solid var(--stroke);
+    border-radius:clamp(14px,3vmin,22px);
+    box-shadow:inset 0 0 40px rgba(0,0,0,.5), 0 20px 60px rgba(0,0,0,.5);
+  }
+  .cell{
+    border:none;padding:0;margin:0;cursor:pointer;outline:none;
+    border-radius:clamp(8px,2.2vmin,16px);
+    position:relative;
+    background:linear-gradient(160deg,#12182a,#0a0f1c);
+    box-shadow:inset 0 1px 0 rgba(255,255,255,.05), inset 0 0 0 1px rgba(120,150,220,.08),
+               0 6px 14px rgba(0,0,0,.35);
+    transition:transform .16s cubic-bezier(.3,1.4,.5,1),
+               box-shadow .3s ease, background .3s ease, filter .3s ease;
+    color:transparent;
+    -webkit-appearance:none;appearance:none;
+  }
+  .cell::after{
+    content:"";position:absolute;inset:22%;border-radius:50%;
+    background:radial-gradient(circle at 35% 30%,rgba(255,255,255,.15),transparent 60%);
+    opacity:.25;transition:opacity .3s ease;
+  }
+  .cell.on{
+    background:linear-gradient(160deg,var(--lit-a),var(--lit-b));
+    box-shadow:inset 0 0 18px rgba(255,255,255,.5),
+               0 0 22px rgba(56,240,214,.65),
+               0 0 46px rgba(26,169,255,.45),
+               0 6px 16px rgba(0,0,0,.3);
+    filter:saturate(1.15);
+  }
+  .cell.on::after{opacity:.85}
+  .cell:active{transform:scale(.9)}
+  .cell.pulse{animation:pulse .4s ease}
+  @keyframes pulse{0%{transform:scale(1)}45%{transform:scale(1.12)}100%{transform:scale(1)}}
+  @media (hover:hover){
+    .cell:hover{transform:translateY(-2px)}
+    .cell.on:hover{filter:saturate(1.3) brightness(1.06)}
+  }
+
+  .controls{display:flex;flex-wrap:wrap;gap:clamp(6px,1.6vmin,10px);justify-content:center;align-items:center}
+  button.btn,select.btn{
+    font-family:inherit;font-size:clamp(11px,2.6vmin,14px);font-weight:700;
+    color:var(--txt);background:var(--panel);border:1px solid var(--stroke);
+    border-radius:11px;padding:clamp(8px,1.8vmin,11px) clamp(12px,3vmin,18px);
+    cursor:pointer;letter-spacing:.5px;transition:.2s;backdrop-filter:blur(6px);
+    -webkit-appearance:none;appearance:none;
+  }
+  button.btn:hover,select.btn:hover{border-color:var(--neon);color:#fff;box-shadow:0 0 14px rgba(56,240,214,.25)}
+  button.btn:active{transform:translateY(1px)}
+  button.primary{
+    background:linear-gradient(160deg,rgba(56,240,214,.22),rgba(26,169,255,.18));
+    border-color:rgba(56,240,214,.4);color:#eafffb;
+  }
+  select.btn{padding-right:30px;background-image:linear-gradient(45deg,transparent 50%,var(--neon) 50%),linear-gradient(135deg,var(--neon) 50%,transparent 50%);background-position:calc(100% - 15px) center,calc(100% - 10px) center;background-size:5px 5px,5px 5px;background-repeat:no-repeat}
+  select.btn option{background:#0d1220;color:var(--txt)}
+
+  .win-overlay{
+    position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
+    border-radius:clamp(14px,3vmin,22px);
+    background:radial-gradient(circle at 50% 40%,rgba(56,240,214,.14),rgba(4,8,16,.86));
+    backdrop-filter:blur(3px);opacity:0;pointer-events:none;transition:opacity .45s ease;
+    z-index:5;text-align:center;
+  }
+  .win-overlay.show{opacity:1;pointer-events:auto}
+  .win-card h2{
+    margin:0;font-size:clamp(28px,8vmin,54px);font-weight:800;
+    background:linear-gradient(90deg,var(--lit-a),#fff,var(--lit-b));
+    -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
+    filter:drop-shadow(0 0 20px rgba(56,240,214,.6));
+    animation:pop .5s cubic-bezier(.2,1.6,.4,1);
+  }
+  @keyframes pop{0%{transform:scale(.4);opacity:0}100%{transform:scale(1);opacity:1}}
+  .win-card p{margin:10px 0 16px;color:var(--txt);font-size:clamp(13px,3.2vmin,16px)}
+  .win-card .big{color:var(--neon);font-weight:800}
+  canvas.confetti{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:4}
+  footer{text-align:center;color:var(--dim);font-size:clamp(9px,2.2vmin,11px);letter-spacing:1px}
+</style>
+</head>
+<body>
+<div class="wrap">
+  <header>
+    <h1>ABRAMS LIGHTS OUT</h1>
+    <p class="sub">Turn every light off</p>
+  </header>
+
+  <div class="stats">
+    <div class="stat"><div class="k">Moves</div><div class="v" id="moves">0</div></div>
+    <div class="stat"><div class="k">Time</div><div class="v" id="time">0:00</div></div>
+    <div class="stat best"><div class="k">Best</div><div class="v" id="best">—</div></div>
+  </div>
+
+  <div class="boardwrap">
+    <div id="board"></div>
+    <canvas class="confetti" id="confetti"></canvas>
+    <div class="win-overlay" id="overlay">
+      <div class="win-card">
+        <h2>SOLVED!</h2>
+        <p>Cleared in <span class="big" id="winMoves">0</span> moves &middot; <span class="big" id="winTime">0:00</span></p>
+        <button class="btn primary" id="againBtn">New Puzzle</button>
+      </div>
+    </div>
+  </div>
+
+  <div class="controls">
+    <button class="btn primary" id="newBtn">New Puzzle</button>
+    <select class="btn" id="sizeSel" title="Grid size">
+      <option value="4">4 × 4</option>
+      <option value="5" selected>5 × 5</option>
+      <option value="6">6 × 6</option>
+    </select>
+    <button class="btn" id="muteBtn" title="Sound">🔊 Sound</button>
+  </div>
+
+  <footer>Click a light to toggle it and its neighbors · Pure vanilla JS, zero dependencies</footer>
+</div>
+
+<script>
+(function(){
+  "use strict";
+  var boardEl = document.getElementById('board');
+  var movesEl = document.getElementById('moves');
+  var timeEl  = document.getElementById('time');
+  var bestEl  = document.getElementById('best');
+  var overlay = document.getElementById('overlay');
+  var winMovesEl = document.getElementById('winMoves');
+  var winTimeEl  = document.getElementById('winTime');
+  var sizeSel = document.getElementById('sizeSel');
+  var muteBtn = document.getElementById('muteBtn');
+  var confettiCanvas = document.getElementById('confetti');
+
+  var N = parseInt(localStorage.getItem('lo_size') || '5', 10);
+  if ([4,5,6].indexOf(N) < 0) N = 5;
+  sizeSel.value = String(N);
+
+  var grid = [];          // boolean[N*N]
+  var cells = [];         // button elements
+  var moves = 0;
+  var solved = false;
+  var startTime = 0;
+  var elapsed = 0;
+  var timerId = null;
+  var muted = localStorage.getItem('lo_muted') === '1';
+
+  updateMuteBtn();
+
+  /* ---------- Audio (procedural, zero assets) ---------- */
+  var actx = null;
+  function audio(){
+    if (muted) return null;
+    if (!actx){
+      try { actx = new (window.AudioContext || window.webkitAudioContext)(); }
+      catch(e){ return null; }
+    }
+    if (actx.state === 'suspended') actx.resume();
+    return actx;
+  }
+  function beep(freq, dur, type, gainVal){
+    var ac = audio(); if (!ac) return;
+    var o = ac.createOscillator();
+    var g = ac.createGain();
+    o.type = type || 'sine';
+    o.frequency.value = freq;
+    g.gain.value = 0;
+    o.connect(g); g.connect(ac.destination);
+    var t = ac.currentTime;
+    var peak = (gainVal == null ? 0.12 : gainVal);
+    g.gain.setValueAtTime(0, t);
+    g.gain.linearRampToValueAtTime(peak, t + 0.008);
+    g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
+    o.start(t);
+    o.stop(t + dur + 0.02);
+  }
+  function toggleSound(litCount){
+    // pitch nudges up as fewer lights remain
+    var base = 300 + (N*N - litCount) * 12;
+    beep(base, 0.12, 'triangle', 0.09);
+  }
+  function winSound(){
+    var notes = [523.25, 659.25, 783.99, 1046.5];
+    for (var i=0;i<notes.length;i++){
+      (function(f,i){ setTimeout(function(){ beep(f, 0.35, 'sine', 0.13); }, i*110); })(notes[i], i);
+    }
+  }
+
+  /* ---------- Board build ---------- */
+  function build(){
+    boardEl.style.gridTemplateColumns = 'repeat(' + N + ',1fr)';
+    boardEl.style.gridTemplateRows = 'repeat(' + N + ',1fr)';
+    boardEl.innerHTML = '';
+    cells = [];
+    for (var i=0;i<N*N;i++){
+      var b = document.createElement('button');
+      b.className = 'cell';
+      b.setAttribute('data-i', i);
+      b.setAttribute('aria-label', 'light ' + (i+1));
+      (function(idx){
+        b.addEventListener('click', function(){ press(idx, true); });
+      })(i);
+      boardEl.appendChild(b);
+      cells.push(b);
+    }
+  }
+
+  function render(){
+    for (var i=0;i<N*N;i++){
+      if (grid[i]) cells[i].classList.add('on');
+      else cells[i].classList.remove('on');
+    }
+  }
+
+  function neighbors(idx){
+    var r = Math.floor(idx / N), c = idx % N;
+    var out = [idx];
+    if (r > 0)     out.push(idx - N);
+    if (r < N-1)   out.push(idx + N);
+    if (c > 0)     out.push(idx - 1);
+    if (c < N-1)   out.push(idx + 1);
+    return out;
+  }
+
+  function applyPress(idx){
+    var ns = neighbors(idx);
+    for (var k=0;k<ns.length;k++) grid[ns[k]] = !grid[ns[k]];
+  }
+
+  function litCount(){
+    var n = 0;
+    for (var i=0;i<N*N;i++) if (grid[i]) n++;
+    return n;
+  }
+
+  function press(idx, human){
+    if (solved) return;
+    if (human && moves === 0 && !timerId) startTimer();
+    applyPress(idx);
+    // visual pulse on affected cells
+    var ns = neighbors(idx);
+    for (var k=0;k<ns.length;k++){
+      (function(el){
+        el.classList.remove('pulse');
+        void el.offsetWidth;
+        el.classList.add('pulse');
+      })(cells[ns[k]]);
+    }
+    render();
+    if (human){
+      moves++;
+      movesEl.textContent = moves;
+      var lc = litCount();
+      toggleSound(lc);
+      if (lc === 0) onWin();
+    }
+  }
+
+  /* ---------- Solvable board generation ---------- */
+  function newPuzzle(){
+    solved = false;
+    overlay.classList.remove('show');
+    stopConfetti();
+    moves = 0;
+    movesEl.textContent = '0';
+    resetTimer();
+
+    // start all-off, apply random valid presses -> guaranteed solvable
+    grid = new Array(N*N).fill(false);
+    var total = N*N;
+    var pressCount = Math.max(3, Math.floor(total * (0.35 + Math.random()*0.35)));
+    var used = {};
+    var applied = 0, guard = 0;
+    while (applied < pressCount && guard < 1000){
+      guard++;
+      var idx = Math.floor(Math.random()*total);
+      applyPress(idx);
+      applied++;
+    }
+    // ensure not already solved
+    if (litCount() === 0){ applyPress(Math.floor(Math.random()*total)); }
+    render();
+    loadBest();
+  }
+
+  /* ---------- Win ---------- */
+  function onWin(){
+    solved = true;
+    stopTimer();
+    winSound();
+    winMovesEl.textContent = moves;
+    winTimeEl.textContent = fmt(elapsed);
+    // best
+    var key = bestKey();
+    var prev = parseInt(localStorage.getItem(key) || '0', 10);
+    if (!prev || moves < prev){
+      localStorage.setItem(key, String(moves));
+    }
+    loadBest();
+    setTimeout(function(){ overlay.classList.add('show'); startConfetti(); }, 250);
+  }
+
+  function bestKey(){ return 'lo_best_' + N; }
+  function loadBest(){
+    var v = localStorage.getItem(bestKey());
+    bestEl.textContent = v ? v : '—';
+  }
+
+  /* ---------- Timer ---------- */
+  function fmt(sec){
+    var m = Math.floor(sec/60), s = sec%60;
+    return m + ':' + (s<10?'0':'') + s;
+  }
+  function startTimer(){
+    startTime = Date.now() - elapsed*1000;
+    if (timerId) clearInterval(timerId);
+    timerId = setInterval(function(){
+      elapsed = Math.floor((Date.now()-startTime)/1000);
+      timeEl.textContent = fmt(elapsed);
+    }, 250);
+  }
+  function stopTimer(){ if (timerId){ clearInterval(timerId); timerId = null; } }
+  function resetTimer(){
+    stopTimer(); elapsed = 0; timeEl.textContent = '0:00';
+  }
+
+  /* ---------- Confetti ---------- */
+  var cctx, particles = [], cfRAF = null;
+  function startConfetti(){
+    var wrap = confettiCanvas.parentElement;
+    confettiCanvas.width = wrap.clientWidth;
+    confettiCanvas.height = wrap.clientHeight;
+    cctx = confettiCanvas.getContext('2d');
+    particles = [];
+    var colors = ['#3bffe0','#1aa9ff','#ffffff','#12b8d8','#7cf9ff'];
+    for (var i=0;i<90;i++){
+      particles.push({
+        x: Math.random()*confettiCanvas.width,
+        y: Math.random()*-confettiCanvas.height,
+        r: 3 + Math.random()*5,
+        c: colors[Math.floor(Math.random()*colors.length)],
+        vx: (Math.random()-0.5)*2,
+        vy: 2 + Math.random()*3.5,
+        rot: Math.random()*Math.PI,
+        vr: (Math.random()-0.5)*0.3
+      });
+    }
+    if (cfRAF) cancelAnimationFrame(cfRAF);
+    var frames = 0;
+    (function loop(){
+      frames++;
+      cctx.clearRect(0,0,confettiCanvas.width,confettiCanvas.height);
+      for (var i=0;i<particles.length;i++){
+        var p = particles[i];
+        p.x += p.vx; p.y += p.vy; p.rot += p.vr;
+        cctx.save();
+        cctx.translate(p.x,p.y); cctx.rotate(p.rot);
+        cctx.fillStyle = p.c;
+        cctx.globalAlpha = 0.9;
+        cctx.fillRect(-p.r/2,-p.r/2,p.r,p.r*1.6);
+        cctx.restore();
+        if (p.y > confettiCanvas.height + 20){ p.y = -20; p.x = Math.random()*confettiCanvas.width; }
+      }
+      if (frames < 240 && solved) cfRAF = requestAnimationFrame(loop);
+      else if (solved) { /* fade */ cctx.clearRect(0,0,confettiCanvas.width,confettiCanvas.height); }
+    })();
+  }
+  function stopConfetti(){
+    if (cfRAF) cancelAnimationFrame(cfRAF);
+    if (cctx) cctx.clearRect(0,0,confettiCanvas.width,confettiCanvas.height);
+  }
+
+  /* ---------- Controls ---------- */
+  function updateMuteBtn(){
+    muteBtn.textContent = muted ? '🔇 Muted' : '🔊 Sound';
+  }
+  muteBtn.addEventListener('click', function(){
+    muted = !muted;
+    localStorage.setItem('lo_muted', muted ? '1':'0');
+    updateMuteBtn();
+    if (!muted) beep(500,0.1,'sine',0.08);
+  });
+  document.getElementById('newBtn').addEventListener('click', newPuzzle);
+  document.getElementById('againBtn').addEventListener('click', newPuzzle);
+  sizeSel.addEventListener('change', function(){
+    N = parseInt(sizeSel.value,10);
+    localStorage.setItem('lo_size', String(N));
+    build(); newPuzzle();
+  });
+
+  window.addEventListener('resize', function(){
+    if (solved && overlay.classList.contains('show')) startConfetti();
+  });
+
+  /* ---------- Init ---------- */
+  build();
+  newPuzzle();
+})();
+</script>
+</body>
+</html>
diff --git a/games/maze/AbramsMaze.aa b/games/maze/AbramsMaze.aa
new file mode 100644
index 0000000..e1009f3
--- /dev/null
+++ b/games/maze/AbramsMaze.aa
@@ -0,0 +1,692 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+<title>Abrams Maze</title>
+<style>
+  :root {
+    --bg: #05060c;
+    --panel: rgba(10, 14, 28, 0.72);
+    --wall: #1b2350;
+    --wall-glow: #4b63ff;
+    --floor: #090c1a;
+    --player: #38ffd4;
+    --player-glow: #16f0c8;
+    --goal: #ff5cc8;
+    --goal-glow: #ff2fb0;
+    --trail: rgba(56, 255, 212, 0.16);
+    --hint: #ffe45c;
+    --text: #cfe0ff;
+    --muted: #7488c2;
+    --accent: #6c8bff;
+  }
+  * { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
+  html, body {
+    width: 100%; height: 100%;
+    background: var(--bg);
+    color: var(--text);
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
+    overflow: hidden;
+    overscroll-behavior: none;
+    user-select: none;
+    -webkit-user-select: none;
+    touch-action: none;
+  }
+  #app {
+    position: fixed; inset: 0;
+    display: flex; flex-direction: column;
+    background:
+      radial-gradient(1200px 700px at 50% -10%, rgba(76, 99, 255, 0.16), transparent 60%),
+      radial-gradient(900px 600px at 100% 110%, rgba(255, 92, 200, 0.10), transparent 60%),
+      var(--bg);
+  }
+  header {
+    display: flex; align-items: center; justify-content: space-between;
+    gap: 8px; padding: 10px 14px;
+    flex-wrap: wrap;
+  }
+  .title {
+    font-weight: 800; letter-spacing: 2px; font-size: 17px;
+    text-transform: uppercase;
+    background: linear-gradient(90deg, var(--player), var(--accent), var(--goal));
+    -webkit-background-clip: text; background-clip: text; color: transparent;
+    text-shadow: 0 0 24px rgba(108, 139, 255, 0.35);
+    white-space: nowrap;
+  }
+  .stats { display: flex; gap: 8px; flex-wrap: wrap; }
+  .stat {
+    background: var(--panel);
+    border: 1px solid rgba(108, 139, 255, 0.22);
+    border-radius: 10px;
+    padding: 5px 10px;
+    font-size: 12px;
+    line-height: 1.15;
+    min-width: 62px;
+    text-align: center;
+    backdrop-filter: blur(6px);
+  }
+  .stat b { display: block; font-size: 15px; color: #fff; font-variant-numeric: tabular-nums; margin-top: 1px; }
+  .stat span { color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: 1px; }
+  #stage { flex: 1; position: relative; min-height: 0; }
+  canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
+  .toolbar {
+    display: flex; gap: 8px; justify-content: center; align-items: center;
+    padding: 8px 12px 4px; flex-wrap: wrap;
+  }
+  button.tool {
+    background: var(--panel);
+    border: 1px solid rgba(108, 139, 255, 0.28);
+    color: var(--text);
+    border-radius: 10px;
+    padding: 8px 12px;
+    font-size: 12px; font-weight: 600;
+    letter-spacing: 0.5px;
+    cursor: pointer;
+    transition: transform .08s ease, border-color .15s ease, background .15s ease;
+  }
+  button.tool:hover { border-color: var(--accent); }
+  button.tool:active { transform: scale(0.94); }
+  button.tool.on { border-color: var(--player); color: var(--player); box-shadow: 0 0 14px rgba(56, 255, 212, 0.25); }
+  /* D-pad */
+  #dpad {
+    display: grid;
+    grid-template-columns: repeat(3, 60px);
+    grid-template-rows: repeat(3, 60px);
+    gap: 8px;
+    justify-content: center;
+    padding: 6px 0 16px;
+    touch-action: none;
+  }
+  .dbtn {
+    background: var(--panel);
+    border: 1px solid rgba(108, 139, 255, 0.3);
+    border-radius: 14px;
+    color: var(--accent);
+    font-size: 26px; font-weight: 700;
+    display: flex; align-items: center; justify-content: center;
+    cursor: pointer;
+    transition: transform .06s ease, background .1s ease;
+    user-select: none;
+  }
+  .dbtn:active, .dbtn.press { background: rgba(108, 139, 255, 0.28); transform: scale(0.9); color: #fff; }
+  .dbtn.up { grid-column: 2; grid-row: 1; }
+  .dbtn.left { grid-column: 1; grid-row: 2; }
+  .dbtn.right { grid-column: 3; grid-row: 2; }
+  .dbtn.down { grid-column: 2; grid-row: 3; }
+  .dbtn.spacer { visibility: hidden; }
+  #banner {
+    position: absolute; left: 50%; top: 42%;
+    transform: translate(-50%, -50%) scale(0.8);
+    text-align: center; pointer-events: none;
+    opacity: 0; transition: opacity .35s ease, transform .35s ease;
+    z-index: 5;
+  }
+  #banner.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
+  #banner .big {
+    font-size: clamp(28px, 8vw, 60px); font-weight: 900; letter-spacing: 2px;
+    background: linear-gradient(90deg, var(--player), var(--goal));
+    -webkit-background-clip: text; background-clip: text; color: transparent;
+    text-shadow: 0 0 40px rgba(255, 92, 200, 0.4);
+  }
+  #banner .sub { color: var(--text); margin-top: 6px; font-size: clamp(13px, 3.5vw, 18px); }
+  .hint-desktop { color: var(--muted); font-size: 11px; text-align: center; padding: 0 12px 4px; }
+  @media (min-width: 760px) and (hover: hover) {
+    #dpad { display: none; }
+  }
+  @media (max-width: 380px) {
+    #dpad { grid-template-columns: repeat(3, 52px); grid-template-rows: repeat(3, 52px); }
+  }
+</style>
+</head>
+<body>
+<div id="app">
+  <header>
+    <div class="title">Abrams Maze</div>
+    <div class="stats">
+      <div class="stat"><span>Level</span><b id="s-level">1</b></div>
+      <div class="stat"><span>Time</span><b id="s-time">0.0</b></div>
+      <div class="stat"><span>Best Time</span><b id="s-best">—</b></div>
+      <div class="stat"><span>Top Level</span><b id="s-top">1</b></div>
+    </div>
+  </header>
+
+  <div id="stage">
+    <canvas id="c"></canvas>
+    <div id="banner"><div class="big" id="banner-big">LEVEL UP</div><div class="sub" id="banner-sub"></div></div>
+  </div>
+
+  <div class="toolbar">
+    <button class="tool" id="btn-hint">💡 Hint Path</button>
+    <button class="tool on" id="btn-trail">🍞 Trail</button>
+    <button class="tool" id="btn-sound">🔇 Sound</button>
+    <button class="tool" id="btn-new">🎲 New Maze</button>
+  </div>
+  <div class="hint-desktop">Arrow keys / WASD to move · hold to glide · reach the pink goal</div>
+
+  <div id="dpad">
+    <div class="dbtn spacer"></div>
+    <div class="dbtn up" data-dir="up">▲</div>
+    <div class="dbtn spacer"></div>
+    <div class="dbtn left" data-dir="left">◀</div>
+    <div class="dbtn spacer"></div>
+    <div class="dbtn right" data-dir="right">▶</div>
+    <div class="dbtn spacer"></div>
+    <div class="dbtn down" data-dir="down">▼</div>
+    <div class="dbtn spacer"></div>
+  </div>
+</div>
+
+<script>
+(function () {
+  "use strict";
+
+  // ---------- Persistent state ----------
+  var LS_KEY = "abrams-maze-v1";
+  var store = { bestTime: null, topLevel: 1, sound: false, trail: true };
+  try {
+    var raw = localStorage.getItem(LS_KEY);
+    if (raw) { var p = JSON.parse(raw); for (var k in p) if (p[k] !== undefined) store[k] = p[k]; }
+  } catch (e) {}
+  function save() { try { localStorage.setItem(LS_KEY, JSON.stringify(store)); } catch (e) {} }
+
+  // ---------- DOM ----------
+  var canvas = document.getElementById("c");
+  var ctx = canvas.getContext("2d");
+  var stage = document.getElementById("stage");
+  var elLevel = document.getElementById("s-level");
+  var elTime = document.getElementById("s-time");
+  var elBest = document.getElementById("s-best");
+  var elTop = document.getElementById("s-top");
+  var banner = document.getElementById("banner");
+  var bannerBig = document.getElementById("banner-big");
+  var bannerSub = document.getElementById("banner-sub");
+
+  // ---------- Audio (procedural, optional) ----------
+  var actx = null;
+  function ensureAudio() {
+    if (!store.sound) return;
+    if (!actx) {
+      try { actx = new (window.AudioContext || window.webkitAudioContext)(); } catch (e) { actx = null; }
+    }
+    if (actx && actx.state === "suspended") actx.resume();
+  }
+  function beep(freq, dur, type, vol) {
+    if (!store.sound || !actx) return;
+    try {
+      var o = actx.createOscillator(), g = actx.createGain();
+      o.type = type || "sine";
+      o.frequency.value = freq;
+      g.gain.value = 0;
+      o.connect(g); g.connect(actx.destination);
+      var t = actx.currentTime;
+      g.gain.setValueAtTime(0, t);
+      g.gain.linearRampToValueAtTime(vol || 0.08, t + 0.008);
+      g.gain.exponentialRampToValueAtTime(0.0001, t + (dur || 0.09));
+      o.start(t); o.stop(t + (dur || 0.09) + 0.02);
+    } catch (e) {}
+  }
+  function sfxStep() { beep(180 + Math.random() * 40, 0.05, "triangle", 0.04); }
+  function sfxBump() { beep(90, 0.08, "square", 0.05); }
+  function sfxWin() {
+    if (!store.sound || !actx) return;
+    var notes = [523, 659, 784, 1046];
+    notes.forEach(function (f, i) { setTimeout(function () { beep(f, 0.16, "sine", 0.09); }, i * 90); });
+  }
+
+  // ---------- Maze generation (recursive backtracker) ----------
+  // Each cell stores wall bits: 1=N,2=E,4=S,8=W (bit set means wall present)
+  var maze = null; // {cols, rows, cells}
+  var N = 1, E = 2, S = 4, W = 8;
+  var DX = { 1: 0, 2: 1, 4: 0, 8: -1 };
+  var DY = { 1: -1, 2: 0, 4: 1, 8: 0 };
+  var OPP = { 1: 4, 2: 8, 4: 1, 8: 2 };
+
+  function genMaze(cols, rows) {
+    var cells = new Uint8Array(cols * rows);
+    for (var i = 0; i < cells.length; i++) cells[i] = 15; // all walls
+    var visited = new Uint8Array(cols * rows);
+    var stack = [];
+    var startIdx = 0;
+    visited[startIdx] = 1;
+    stack.push(startIdx);
+    while (stack.length) {
+      var cur = stack[stack.length - 1];
+      var cx = cur % cols, cy = (cur / cols) | 0;
+      var dirs = [N, E, S, W];
+      // shuffle
+      for (var s = dirs.length - 1; s > 0; s--) {
+        var r = (Math.random() * (s + 1)) | 0;
+        var tmp = dirs[s]; dirs[s] = dirs[r]; dirs[r] = tmp;
+      }
+      var moved = false;
+      for (var d = 0; d < 4; d++) {
+        var dir = dirs[d];
+        var nx = cx + DX[dir], ny = cy + DY[dir];
+        if (nx < 0 || ny < 0 || nx >= cols || ny >= rows) continue;
+        var nIdx = ny * cols + nx;
+        if (visited[nIdx]) continue;
+        cells[cur] &= ~dir;
+        cells[nIdx] &= ~OPP[dir];
+        visited[nIdx] = 1;
+        stack.push(nIdx);
+        moved = true;
+        break;
+      }
+      if (!moved) stack.pop();
+    }
+    return { cols: cols, rows: rows, cells: cells };
+  }
+
+  function canMove(m, cx, cy, dir) {
+    var idx = cy * m.cols + cx;
+    return (m.cells[idx] & dir) === 0;
+  }
+
+  // BFS solution path from start to goal
+  function solvePath(m, sx, sy, gx, gy) {
+    var cols = m.cols, rows = m.rows;
+    var prev = new Int32Array(cols * rows).fill(-1);
+    var seen = new Uint8Array(cols * rows);
+    var q = [sy * cols + sx];
+    seen[q[0]] = 1;
+    var head = 0;
+    while (head < q.length) {
+      var cur = q[head++];
+      if (cur === gy * cols + gx) break;
+      var cx = cur % cols, cy = (cur / cols) | 0;
+      var dirs = [N, E, S, W];
+      for (var d = 0; d < 4; d++) {
+        var dir = dirs[d];
+        if (m.cells[cur] & dir) continue;
+        var nx = cx + DX[dir], ny = cy + DY[dir];
+        if (nx < 0 || ny < 0 || nx >= cols || ny >= rows) continue;
+        var nIdx = ny * cols + nx;
+        if (seen[nIdx]) continue;
+        seen[nIdx] = 1; prev[nIdx] = cur; q.push(nIdx);
+      }
+    }
+    var path = [];
+    var t = gy * cols + gx;
+    if (!seen[t]) return path;
+    while (t !== -1) { path.push(t); t = prev[t]; }
+    path.reverse();
+    return path;
+  }
+
+  // ---------- Game state ----------
+  var game = {
+    level: 1,
+    cols: 8, rows: 8,
+    player: { cx: 0, cy: 0, x: 0, y: 0 }, // cx/cy = cell, x/y = pixel (animated)
+    goal: { cx: 0, cy: 0 },
+    startTime: 0,
+    elapsed: 0,
+    running: false,
+    won: false,
+    trail: {},          // "cx,cy" -> visit count
+    hintPath: null,     // array of idx
+    hintUntil: 0,
+    cell: 24, ox: 0, oy: 0
+  };
+
+  function sizeForLevel(lvl) {
+    var base = 7 + lvl; // grows each level
+    return Math.min(base, 45);
+  }
+
+  function newLevel(lvl, isNewGame) {
+    game.level = lvl;
+    var sz = sizeForLevel(lvl);
+    game.cols = sz; game.rows = sz;
+    maze = genMaze(sz, sz);
+    game.player.cx = 0; game.player.cy = 0;
+    game.goal.cx = sz - 1; game.goal.cy = sz - 1;
+    game.trail = {};
+    game.trail["0,0"] = 1;
+    game.hintPath = null;
+    game.hintUntil = 0;
+    game.won = false;
+    game.running = true;
+    game.elapsed = 0;
+    game.startTime = performance.now();
+    layout();
+    // snap pixel pos to start cell
+    game.player.x = game.ox + game.player.cx * game.cell + game.cell / 2;
+    game.player.y = game.oy + game.player.cy * game.cell + game.cell / 2;
+    elLevel.textContent = lvl;
+    updateBanner(isNewGame);
+  }
+
+  function updateBanner(isNewGame) {
+    if (isNewGame) return;
+    bannerBig.textContent = "LEVEL " + game.level;
+    bannerSub.textContent = game.cols + " × " + game.rows + " maze";
+    banner.classList.add("show");
+    setTimeout(function () { banner.classList.remove("show"); }, 1100);
+  }
+
+  // ---------- Layout / sizing ----------
+  var dpr = 1;
+  function layout() {
+    dpr = Math.max(1, Math.min(window.devicePixelRatio || 1, 2));
+    var w = stage.clientWidth, h = stage.clientHeight;
+    canvas.width = Math.floor(w * dpr);
+    canvas.height = Math.floor(h * dpr);
+    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
+    var pad = 14;
+    var avail = Math.min(w, h) - pad * 2;
+    game.cell = Math.max(6, Math.floor(avail / game.cols));
+    var gridW = game.cell * game.cols;
+    var gridH = game.cell * game.rows;
+    game.ox = Math.floor((w - gridW) / 2);
+    game.oy = Math.floor((h - gridH) / 2);
+  }
+
+  window.addEventListener("resize", function () {
+    var pcx = game.player.cx, pcy = game.player.cy;
+    layout();
+    // keep player pixel aligned to its cell after resize
+    game.player.x = game.ox + pcx * game.cell + game.cell / 2;
+    game.player.y = game.oy + pcy * game.cell + game.cell / 2;
+  });
+
+  // ---------- Movement ----------
+  var moveCooldown = 0;
+  function tryMove(dir) {
+    if (!game.running || game.won) return;
+    var p = game.player;
+    if (!canMove(maze, p.cx, p.cy, dir)) { sfxBump(); return; }
+    p.cx += DX[dir]; p.cy += DY[dir];
+    var key = p.cx + "," + p.cy;
+    game.trail[key] = (game.trail[key] || 0) + 1;
+    sfxStep();
+    if (p.cx === game.goal.cx && p.cy === game.goal.cy) win();
+  }
+
+  var dirMap = {
+    ArrowUp: N, KeyW: N, ArrowRight: E, KeyD: E,
+    ArrowDown: S, KeyS: S, ArrowLeft: W, KeyA: W
+  };
+  var held = {}; // dir -> true
+  var repeatTimer = 0;
+
+  window.addEventListener("keydown", function (e) {
+    var dir = dirMap[e.code];
+    if (dir) {
+      e.preventDefault();
+      ensureAudio();
+      if (!held[dir]) { held[dir] = true; tryMove(dir); repeatTimer = 0; }
+    } else if (e.code === "Space") {
+      e.preventDefault(); doHint();
+    }
+  });
+  window.addEventListener("keyup", function (e) {
+    var dir = dirMap[e.code];
+    if (dir) held[dir] = false;
+  });
+
+  // D-pad + held-to-glide
+  var dpad = document.getElementById("dpad");
+  var dpadHeld = {};
+  var dirWord = { up: N, down: S, left: W, right: E };
+  function dpadPress(word, el) {
+    ensureAudio();
+    var dir = dirWord[word];
+    if (!dpadHeld[dir]) { dpadHeld[dir] = true; tryMove(dir); }
+    if (el) el.classList.add("press");
+  }
+  function dpadRelease(word, el) {
+    dpadHeld[dirWord[word]] = false;
+    if (el) el.classList.remove("press");
+  }
+  Array.prototype.forEach.call(dpad.querySelectorAll(".dbtn[data-dir]"), function (btn) {
+    var word = btn.getAttribute("data-dir");
+    btn.addEventListener("touchstart", function (e) { e.preventDefault(); dpadPress(word, btn); }, { passive: false });
+    btn.addEventListener("touchend", function (e) { e.preventDefault(); dpadRelease(word, btn); }, { passive: false });
+    btn.addEventListener("touchcancel", function (e) { dpadRelease(word, btn); });
+    btn.addEventListener("mousedown", function (e) { e.preventDefault(); dpadPress(word, btn); });
+    btn.addEventListener("mouseup", function () { dpadRelease(word, btn); });
+    btn.addEventListener("mouseleave", function () { dpadRelease(word, btn); });
+  });
+
+  // Swipe on canvas as an alternate touch control
+  var swipe = null;
+  stage.addEventListener("touchstart", function (e) {
+    if (e.target !== canvas) return;
+    ensureAudio();
+    var t = e.touches[0];
+    swipe = { x: t.clientX, y: t.clientY };
+  }, { passive: true });
+  stage.addEventListener("touchmove", function (e) {
+    if (!swipe) return;
+    var t = e.touches[0];
+    var dx = t.clientX - swipe.x, dy = t.clientY - swipe.y;
+    var thresh = 26;
+    if (Math.abs(dx) > thresh || Math.abs(dy) > thresh) {
+      if (Math.abs(dx) > Math.abs(dy)) tryMove(dx > 0 ? E : W);
+      else tryMove(dy > 0 ? S : N);
+      swipe = { x: t.clientX, y: t.clientY };
+    }
+  }, { passive: true });
+  stage.addEventListener("touchend", function () { swipe = null; });
+
+  // ---------- Win / level up ----------
+  function win() {
+    game.won = true;
+    game.running = false;
+    game.elapsed = (performance.now() - game.startTime) / 1000;
+    sfxWin();
+    var t = game.elapsed;
+    var newBest = (store.bestTime == null || t < store.bestTime);
+    if (newBest) store.bestTime = t;
+    if (game.level + 1 > store.topLevel) store.topLevel = game.level + 1;
+    save();
+    refreshHUD();
+    bannerBig.textContent = "SOLVED!";
+    bannerSub.textContent = "Level " + game.level + " · " + t.toFixed(2) + "s" + (newBest ? " · NEW BEST!" : "");
+    banner.classList.add("show");
+    setTimeout(function () {
+      banner.classList.remove("show");
+      setTimeout(function () { newLevel(game.level + 1, false); }, 250);
+    }, 1400);
+  }
+
+  // ---------- Hint path ----------
+  function doHint() {
+    if (!game.running || game.won) return;
+    ensureAudio();
+    game.hintPath = solvePath(maze, game.player.cx, game.player.cy, game.goal.cx, game.goal.cy);
+    game.hintUntil = performance.now() + 1600;
+    beep(660, 0.12, "sine", 0.06);
+  }
+
+  // ---------- HUD ----------
+  function refreshHUD() {
+    elBest.textContent = store.bestTime == null ? "—" : store.bestTime.toFixed(2) + "s";
+    elTop.textContent = store.topLevel;
+  }
+
+  // ---------- Buttons ----------
+  var btnHint = document.getElementById("btn-hint");
+  var btnTrail = document.getElementById("btn-trail");
+  var btnSound = document.getElementById("btn-sound");
+  var btnNew = document.getElementById("btn-new");
+
+  btnHint.addEventListener("click", doHint);
+  btnTrail.addEventListener("click", function () {
+    store.trail = !store.trail; save();
+    btnTrail.classList.toggle("on", store.trail);
+  });
+  btnSound.addEventListener("click", function () {
+    store.sound = !store.sound; save();
+    btnSound.classList.toggle("on", store.sound);
+    btnSound.textContent = store.sound ? "🔊 Sound" : "🔇 Sound";
+    if (store.sound) { ensureAudio(); beep(520, 0.1, "sine", 0.07); }
+  });
+  btnNew.addEventListener("click", function () { ensureAudio(); newLevel(game.level, false); });
+
+  // init button visual states
+  btnTrail.classList.toggle("on", store.trail);
+  btnSound.classList.toggle("on", store.sound);
+  btnSound.textContent = store.sound ? "🔊 Sound" : "🔇 Sound";
+
+  // ---------- Render ----------
+  function draw(now) {
+    var w = stage.clientWidth, h = stage.clientHeight;
+    ctx.clearRect(0, 0, w, h);
+
+    var cell = game.cell, ox = game.ox, oy = game.oy, cols = game.cols, rows = game.rows;
+    var gridW = cell * cols, gridH = cell * rows;
+
+    // floor
+    ctx.fillStyle = getVar("--floor");
+    roundRect(ctx, ox - 4, oy - 4, gridW + 8, gridH + 8, 8);
+    ctx.fill();
+
+    // trail
+    if (store.trail) {
+      ctx.fillStyle = getVar("--trail");
+      for (var key in game.trail) {
+        var parts = key.split(","); var tx = +parts[0], ty = +parts[1];
+        ctx.fillRect(ox + tx * cell + 1, oy + ty * cell + 1, cell - 2, cell - 2);
+      }
+    }
+
+    // hint path
+    if (game.hintPath && now < game.hintUntil) {
+      var pulse = 0.35 + 0.35 * (0.5 + 0.5 * Math.sin(now / 120));
+      ctx.save();
+      ctx.strokeStyle = getVar("--hint");
+      ctx.globalAlpha = pulse;
+      ctx.lineWidth = Math.max(2, cell * 0.28);
+      ctx.lineJoin = "round"; ctx.lineCap = "round";
+      ctx.shadowColor = getVar("--hint");
+      ctx.shadowBlur = 12;
+      ctx.beginPath();
+      for (var hi = 0; hi < game.hintPath.length; hi++) {
+        var id = game.hintPath[hi];
+        var hx = id % cols, hy = (id / cols) | 0;
+        var px = ox + hx * cell + cell / 2, py = oy + hy * cell + cell / 2;
+        if (hi === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
+      }
+      ctx.stroke();
+      ctx.restore();
+    } else if (game.hintPath && now >= game.hintUntil) {
+      game.hintPath = null;
+    }
+
+    // walls
+    ctx.save();
+    ctx.strokeStyle = getVar("--wall-glow");
+    ctx.shadowColor = getVar("--wall-glow");
+    ctx.shadowBlur = Math.min(10, cell * 0.4);
+    ctx.lineWidth = Math.max(1.4, cell * 0.09);
+    ctx.lineCap = "round";
+    ctx.beginPath();
+    for (var y = 0; y < rows; y++) {
+      for (var x = 0; x < cols; x++) {
+        var c = maze.cells[y * cols + x];
+        var x0 = ox + x * cell, y0 = oy + y * cell, x1 = x0 + cell, y1 = y0 + cell;
+        if (c & N) { ctx.moveTo(x0, y0); ctx.lineTo(x1, y0); }
+        if (c & W) { ctx.moveTo(x0, y0); ctx.lineTo(x0, y1); }
+        if (c & E) { ctx.moveTo(x1, y0); ctx.lineTo(x1, y1); }
+        if (c & S) { ctx.moveTo(x0, y1); ctx.lineTo(x1, y1); }
+      }
+    }
+    ctx.stroke();
+    ctx.restore();
+
+    // goal
+    var gx = ox + game.goal.cx * cell + cell / 2;
+    var gy = oy + game.goal.cy * cell + cell / 2;
+    var gr = cell * 0.3;
+    var gpulse = 1 + 0.14 * Math.sin(now / 220);
+    ctx.save();
+    ctx.shadowColor = getVar("--goal-glow");
+    ctx.shadowBlur = 22;
+    ctx.fillStyle = getVar("--goal");
+    star(ctx, gx, gy, gr * gpulse, gr * 0.45 * gpulse, 5, now / 900);
+    ctx.fill();
+    ctx.restore();
+
+    // player (animate pixel toward its cell)
+    var targetX = ox + game.player.cx * cell + cell / 2;
+    var targetY = oy + game.player.cy * cell + cell / 2;
+    game.player.x += (targetX - game.player.x) * 0.35;
+    game.player.y += (targetY - game.player.y) * 0.35;
+    var pr = cell * 0.30;
+    ctx.save();
+    ctx.shadowColor = getVar("--player-glow");
+    ctx.shadowBlur = 20;
+    var grad = ctx.createRadialGradient(game.player.x, game.player.y, 1, game.player.x, game.player.y, pr);
+    grad.addColorStop(0, "#eafffb");
+    grad.addColorStop(0.5, getVar("--player"));
+    grad.addColorStop(1, getVar("--player-glow"));
+    ctx.fillStyle = grad;
+    ctx.beginPath();
+    ctx.arc(game.player.x, game.player.y, pr, 0, Math.PI * 2);
+    ctx.fill();
+    ctx.restore();
+
+    // live timer
+    if (game.running && !game.won) {
+      game.elapsed = (now - game.startTime) / 1000;
+    }
+    elTime.textContent = game.elapsed.toFixed(1);
+  }
+
+  function star(c, cx, cy, outer, inner, points, rot) {
+    c.beginPath();
+    for (var i = 0; i < points * 2; i++) {
+      var rr = (i % 2 === 0) ? outer : inner;
+      var a = rot + (i * Math.PI) / points;
+      var px = cx + Math.cos(a) * rr, py = cy + Math.sin(a) * rr;
+      if (i === 0) c.moveTo(px, py); else c.lineTo(px, py);
+    }
+    c.closePath();
+  }
+  function roundRect(c, x, y, w, h, r) {
+    c.beginPath();
+    c.moveTo(x + r, y);
+    c.arcTo(x + w, y, x + w, y + h, r);
+    c.arcTo(x + w, y + h, x, y + h, r);
+    c.arcTo(x, y + h, x, y, r);
+    c.arcTo(x, y, x + w, y, r);
+    c.closePath();
+  }
+  var varCache = {};
+  function getVar(name) {
+    if (varCache[name]) return varCache[name];
+    var v = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
+    varCache[name] = v || "#fff";
+    return varCache[name];
+  }
+
+  // ---------- Main loop (held-to-glide repeat) ----------
+  var lastRepeat = 0;
+  function loop(now) {
+    // handle held movement (keyboard + dpad) with a steady cadence
+    var anyHeld = false, heldDir = 0;
+    for (var d in held) if (held[d]) { anyHeld = true; heldDir = +d; }
+    if (!anyHeld) for (var d2 in dpadHeld) if (dpadHeld[d2]) { anyHeld = true; heldDir = +d2; }
+    if (anyHeld && heldDir) {
+      if (now - lastRepeat > 110) { tryMove(heldDir); lastRepeat = now; }
+    }
+    draw(now);
+    requestAnimationFrame(loop);
+  }
+
+  // ---------- Boot ----------
+  function boot() {
+    refreshHUD();
+    // Resume best progress: start at level 1 fresh each session, but keep records.
+    newLevel(1, false);
+    requestAnimationFrame(loop);
+  }
+  // ensure stage has size before first layout
+  requestAnimationFrame(boot);
+})();
+</script>
+</body>
+</html>
diff --git a/games/minesweeper/AbramsMines.aa b/games/minesweeper/AbramsMines.aa
new file mode 100644
index 0000000..0165f34
--- /dev/null
+++ b/games/minesweeper/AbramsMines.aa
@@ -0,0 +1,820 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+<title>Abrams Minesweeper</title>
+<style>
+  :root{
+    --bg:#080b14;
+    --bg2:#0d1220;
+    --panel:#111a2e;
+    --panel2:#0b1120;
+    --grid:#0a0f1c;
+    --cell:#1a2540;
+    --cell-hi:#243258;
+    --cell-lo:#0f1830;
+    --revealed:#0c1424;
+    --line:#22304f;
+    --neon:#00f0ff;
+    --neon2:#ff2bd6;
+    --neon3:#7cff5c;
+    --amber:#ffb020;
+    --danger:#ff3b5c;
+    --text:#cfe3ff;
+    --muted:#6b83ad;
+    --n1:#4ea1ff;
+    --n2:#5cffb0;
+    --n3:#ff6b8a;
+    --n4:#b48bff;
+    --n5:#ffb020;
+    --n6:#38e8ff;
+    --n7:#ff8ad6;
+    --n8:#c8d4ee;
+  }
+  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
+  html,body{margin:0;padding:0;height:100%;}
+  body{
+    font-family:"Segoe UI",Roboto,-apple-system,system-ui,sans-serif;
+    background:
+      radial-gradient(1200px 600px at 20% -10%, rgba(0,240,255,.10), transparent 60%),
+      radial-gradient(900px 500px at 110% 10%, rgba(255,43,214,.10), transparent 55%),
+      linear-gradient(160deg,var(--bg),var(--bg2));
+    color:var(--text);
+    min-height:100%;
+    display:flex;
+    flex-direction:column;
+    align-items:center;
+    justify-content:flex-start;
+    overflow:hidden;
+    user-select:none;
+    -webkit-user-select:none;
+  }
+  #app{
+    width:100%;
+    max-width:920px;
+    min-height:100%;
+    display:flex;
+    flex-direction:column;
+    padding:10px clamp(8px,2vw,18px) 14px;
+    gap:10px;
+  }
+  header{
+    display:flex;
+    align-items:center;
+    justify-content:space-between;
+    gap:10px;
+    flex-wrap:wrap;
+  }
+  .title{
+    display:flex;
+    align-items:baseline;
+    gap:8px;
+    letter-spacing:.5px;
+  }
+  .title h1{
+    margin:0;
+    font-size:clamp(18px,3.4vw,26px);
+    font-weight:800;
+    background:linear-gradient(90deg,var(--neon),var(--neon2));
+    -webkit-background-clip:text;background-clip:text;
+    -webkit-text-fill-color:transparent;
+    text-shadow:0 0 18px rgba(0,240,255,.25);
+  }
+  .title .sub{
+    font-size:11px;
+    color:var(--muted);
+    text-transform:uppercase;
+    letter-spacing:2px;
+  }
+  .controls{
+    display:flex;
+    align-items:center;
+    gap:8px;
+    flex-wrap:wrap;
+  }
+  select,button{
+    font-family:inherit;
+    font-size:13px;
+    color:var(--text);
+    background:linear-gradient(180deg,var(--cell-hi),var(--cell));
+    border:1px solid var(--line);
+    border-radius:9px;
+    padding:8px 12px;
+    cursor:pointer;
+    transition:transform .06s ease,box-shadow .15s ease,border-color .15s ease,background .15s ease;
+    outline:none;
+  }
+  select{padding-right:26px;}
+  button:hover,select:hover{border-color:var(--neon);box-shadow:0 0 12px rgba(0,240,255,.25);}
+  button:active{transform:translateY(1px) scale(.98);}
+  button.primary{
+    background:linear-gradient(180deg,rgba(0,240,255,.22),rgba(0,240,255,.06));
+    border-color:rgba(0,240,255,.5);
+    color:#eafcff;
+    font-weight:700;
+  }
+  button.icon{padding:8px 11px;}
+  button.on{border-color:var(--neon3);box-shadow:0 0 12px rgba(124,255,92,.35);color:#eaffee;}
+  .status{
+    display:flex;
+    align-items:stretch;
+    justify-content:space-between;
+    gap:10px;
+    background:linear-gradient(180deg,var(--panel),var(--panel2));
+    border:1px solid var(--line);
+    border-radius:14px;
+    padding:10px 14px;
+    box-shadow:inset 0 0 24px rgba(0,240,255,.05), 0 6px 20px rgba(0,0,0,.35);
+  }
+  .stat{
+    display:flex;
+    flex-direction:column;
+    align-items:center;
+    gap:2px;
+    min-width:74px;
+  }
+  .stat .label{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:1.5px;}
+  .stat .val{
+    font-family:"Courier New",monospace;
+    font-weight:800;
+    font-size:clamp(20px,4.4vw,28px);
+    letter-spacing:1px;
+    line-height:1;
+  }
+  .stat.mines .val{color:var(--danger);text-shadow:0 0 10px rgba(255,59,92,.45);}
+  .stat.time .val{color:var(--neon);text-shadow:0 0 10px rgba(0,240,255,.4);}
+  .face{
+    display:flex;align-items:center;justify-content:center;
+    font-size:clamp(24px,6vw,34px);
+    width:clamp(52px,11vw,64px);height:clamp(52px,11vw,64px);
+    border-radius:14px;
+    background:linear-gradient(180deg,var(--cell-hi),var(--cell-lo));
+    border:1px solid var(--line);
+    cursor:pointer;
+    box-shadow:0 4px 14px rgba(0,0,0,.4);
+    transition:transform .06s ease,box-shadow .15s ease;
+  }
+  .face:hover{box-shadow:0 0 16px rgba(0,240,255,.3);}
+  .face:active{transform:translateY(1px) scale(.96);}
+  .boardwrap{
+    flex:1;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    min-height:0;
+    position:relative;
+  }
+  .board{
+    display:grid;
+    gap:3px;
+    padding:10px;
+    background:linear-gradient(180deg,var(--grid),#060a14);
+    border:1px solid var(--line);
+    border-radius:16px;
+    box-shadow:inset 0 0 40px rgba(0,240,255,.06), 0 10px 34px rgba(0,0,0,.5);
+    touch-action:manipulation;
+  }
+  .cell{
+    display:flex;align-items:center;justify-content:center;
+    font-weight:800;
+    line-height:1;
+    border-radius:6px;
+    background:linear-gradient(180deg,var(--cell-hi),var(--cell));
+    border:1px solid rgba(255,255,255,.04);
+    box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 2px 4px rgba(0,0,0,.35);
+    cursor:pointer;
+    transition:background .08s ease,transform .05s ease,box-shadow .12s ease;
+    color:var(--text);
+    overflow:hidden;
+  }
+  .cell:hover:not(.open):not(.flag){background:linear-gradient(180deg,#2c3d68,#1e2c50);}
+  .cell.open{
+    background:var(--revealed);
+    box-shadow:inset 0 0 0 1px rgba(0,240,255,.05);
+    cursor:default;
+    border-color:rgba(0,240,255,.06);
+  }
+  .cell.open.empty{background:#0a1120;}
+  .cell.flag{background:linear-gradient(180deg,#2a1636,#1c0f26);}
+  .cell.mine{background:radial-gradient(circle at 50% 45%,rgba(255,59,92,.5),#200712);}
+  .cell.exploded{background:radial-gradient(circle at 50% 45%,#ff3b5c,#7a0018);box-shadow:0 0 18px rgba(255,59,92,.7);}
+  .cell.wrong{background:linear-gradient(180deg,#2a2030,#221018);}
+  .cell.hint{animation:pulse 1s ease infinite;}
+  @keyframes pulse{0%,100%{box-shadow:inset 0 0 0 2px var(--neon);}50%{box-shadow:inset 0 0 12px 2px var(--neon);}}
+  .n1{color:var(--n1);}.n2{color:var(--n2);}.n3{color:var(--n3);}.n4{color:var(--n4);}
+  .n5{color:var(--n5);}.n6{color:var(--n6);}.n7{color:var(--n7);}.n8{color:var(--n8);}
+  .flagbar{
+    display:flex;align-items:center;justify-content:center;gap:10px;
+    flex-wrap:wrap;
+  }
+  .flagtoggle{
+    display:flex;align-items:center;gap:10px;
+    padding:10px 18px;
+    font-size:15px;font-weight:700;
+    border-radius:12px;
+    background:linear-gradient(180deg,var(--cell-hi),var(--cell));
+    border:1px solid var(--line);
+  }
+  .flagtoggle.armed{
+    border-color:var(--neon2);
+    box-shadow:0 0 18px rgba(255,43,214,.4);
+    background:linear-gradient(180deg,rgba(255,43,214,.25),rgba(255,43,214,.08));
+    color:#ffeafb;
+  }
+  .flagtoggle .mode{font-size:11px;letter-spacing:1px;text-transform:uppercase;opacity:.85;}
+  .hintbtn{font-size:13px;}
+  .overlay{
+    position:absolute;inset:0;
+    display:none;
+    align-items:center;justify-content:center;
+    background:rgba(4,8,16,.72);
+    backdrop-filter:blur(3px);
+    border-radius:16px;
+    z-index:5;
+    padding:16px;
+  }
+  .overlay.show{display:flex;animation:fade .25s ease;}
+  @keyframes fade{from{opacity:0}to{opacity:1}}
+  .card{
+    text-align:center;
+    background:linear-gradient(180deg,var(--panel),var(--panel2));
+    border:1px solid var(--line);
+    border-radius:18px;
+    padding:26px 30px;
+    box-shadow:0 16px 50px rgba(0,0,0,.6);
+    max-width:340px;
+  }
+  .card h2{
+    margin:0 0 6px;
+    font-size:30px;
+    letter-spacing:1px;
+  }
+  .card.win h2{color:var(--neon3);text-shadow:0 0 20px rgba(124,255,92,.5);}
+  .card.lose h2{color:var(--danger);text-shadow:0 0 20px rgba(255,59,92,.5);}
+  .card p{margin:6px 0;color:var(--text);font-size:14px;}
+  .card .best{color:var(--amber);font-weight:700;}
+  .card .newbest{color:var(--neon3);font-weight:800;animation:pulse 1s infinite;}
+  .card button{margin-top:16px;font-size:15px;padding:12px 26px;}
+  footer{
+    text-align:center;font-size:11px;color:var(--muted);letter-spacing:.5px;
+  }
+  footer .best-line{color:var(--amber);}
+  @media (max-width:520px){
+    .stat{min-width:58px;}
+    .controls{width:100%;justify-content:center;}
+  }
+</style>
+</head>
+<body>
+<div id="app">
+  <header>
+    <div class="title">
+      <h1>ABRAMS MINESWEEPER</h1>
+      <span class="sub">neon sweep</span>
+    </div>
+    <div class="controls">
+      <select id="difficulty" aria-label="Difficulty">
+        <option value="beginner">Beginner · 9×9 · 10</option>
+        <option value="intermediate">Intermediate · 16×16 · 40</option>
+        <option value="expert">Expert · 16×30 · 99</option>
+      </select>
+      <button id="newgame" class="primary">↻ New Game</button>
+      <button id="mute" class="icon on" title="Toggle sound">🔊</button>
+    </div>
+  </header>
+
+  <div class="status">
+    <div class="stat mines">
+      <span class="label">Mines</span>
+      <span class="val" id="mineCount">010</span>
+    </div>
+    <div class="face" id="face" title="New game">🙂</div>
+    <div class="stat time">
+      <span class="label">Time</span>
+      <span class="val" id="timer">000</span>
+    </div>
+  </div>
+
+  <div class="flagbar">
+    <div class="flagtoggle" id="flagToggle" role="button" tabindex="0" aria-pressed="false">
+      <span id="flagIcon">⛏️</span>
+      <span class="mode" id="flagMode">Dig mode</span>
+    </div>
+    <button class="hintbtn" id="hint">💡 Hint</button>
+  </div>
+
+  <div class="boardwrap">
+    <div class="board" id="board"></div>
+    <div class="overlay" id="overlay">
+      <div class="card" id="card">
+        <h2 id="ovTitle">You Win!</h2>
+        <p id="ovMsg"></p>
+        <p id="ovBest"></p>
+        <button class="primary" id="ovBtn">Play Again</button>
+      </div>
+    </div>
+  </div>
+
+  <footer>
+    <div class="best-line" id="footerBest"></div>
+    <div>Left-click / tap to dig · Right-click or Flag toggle to mark · First click is always safe</div>
+  </footer>
+</div>
+
+<script>
+(function(){
+  "use strict";
+
+  const DIFFS = {
+    beginner:     { rows:9,  cols:9,  mines:10, label:"Beginner" },
+    intermediate: { rows:16, cols:16, mines:40, label:"Intermediate" },
+    expert:       { rows:16, cols:30, mines:99, label:"Expert" }
+  };
+
+  const LS_KEY = "abrams_minesweeper_best_v1";
+  const LS_MUTE = "abrams_minesweeper_mute_v1";
+
+  // --- DOM refs
+  const boardEl   = document.getElementById("board");
+  const mineCountEl = document.getElementById("mineCount");
+  const timerEl   = document.getElementById("timer");
+  const faceEl    = document.getElementById("face");
+  const diffSel   = document.getElementById("difficulty");
+  const newBtn    = document.getElementById("newgame");
+  const muteBtn   = document.getElementById("mute");
+  const flagToggle= document.getElementById("flagToggle");
+  const flagIcon  = document.getElementById("flagIcon");
+  const flagMode  = document.getElementById("flagMode");
+  const hintBtn   = document.getElementById("hint");
+  const overlay   = document.getElementById("overlay");
+  const card      = document.getElementById("card");
+  const ovTitle   = document.getElementById("ovTitle");
+  const ovMsg     = document.getElementById("ovMsg");
+  const ovBest    = document.getElementById("ovBest");
+  const ovBtn     = document.getElementById("ovBtn");
+  const footerBest= document.getElementById("footerBest");
+
+  // --- state
+  let cfg, grid, cellEls, flagMode_on=false, firstClickDone, gameOver, won;
+  let flagsPlaced=0, revealedCount=0, totalSafe=0;
+  let timer=0, timerId=null, muted=false;
+
+  // ---------- Web Audio (procedural, no assets) ----------
+  let audioCtx=null;
+  function ac(){
+    if(muted) return null;
+    if(!audioCtx){
+      try{ audioCtx = new (window.AudioContext||window.webkitAudioContext)(); }
+      catch(e){ return null; }
+    }
+    if(audioCtx.state==="suspended") audioCtx.resume();
+    return audioCtx;
+  }
+  function blip(freq, dur, type, vol){
+    const ctx=ac(); if(!ctx) return;
+    const o=ctx.createOscillator(), g=ctx.createGain();
+    o.type=type||"square"; o.frequency.value=freq;
+    g.gain.value=0.0001;
+    o.connect(g); g.connect(ctx.destination);
+    const t=ctx.currentTime;
+    g.gain.setValueAtTime(0.0001,t);
+    g.gain.exponentialRampToValueAtTime(vol||0.12, t+0.008);
+    g.gain.exponentialRampToValueAtTime(0.0001, t+dur);
+    o.start(t); o.stop(t+dur+0.02);
+  }
+  const S = {
+    reveal(){ blip(520,0.05,"triangle",0.08); },
+    flood(){ blip(680,0.07,"sine",0.06); },
+    flag(){ blip(880,0.06,"square",0.10); },
+    unflag(){ blip(300,0.06,"square",0.08); },
+    win(){ [523,659,784,1047].forEach((f,i)=>setTimeout(()=>blip(f,0.18,"triangle",0.14),i*110)); },
+    lose(){ blip(160,0.4,"sawtooth",0.16); setTimeout(()=>blip(90,0.5,"sawtooth",0.14),140); },
+    click(){ blip(440,0.03,"square",0.05); }
+  };
+
+  // ---------- persistence ----------
+  function loadBest(){
+    try{ return JSON.parse(localStorage.getItem(LS_KEY)) || {}; }
+    catch(e){ return {}; }
+  }
+  function saveBest(o){
+    try{ localStorage.setItem(LS_KEY, JSON.stringify(o)); }catch(e){}
+  }
+  function getBest(key){ const b=loadBest(); return (typeof b[key]==="number")?b[key]:null; }
+  function setBest(key,val){ const b=loadBest(); b[key]=val; saveBest(b); }
+
+  function loadMute(){
+    try{ return localStorage.getItem(LS_MUTE)==="1"; }catch(e){ return false; }
+  }
+  function saveMute(v){ try{ localStorage.setItem(LS_MUTE, v?"1":"0"); }catch(e){} }
+
+  // ---------- helpers ----------
+  function pad3(n){ n=Math.max(0,Math.min(999,n|0)); return String(n).padStart(3,"0"); }
+  function idx(r,c){ return r*cfg.cols+c; }
+  function inBounds(r,c){ return r>=0 && r<cfg.rows && c>=0 && c<cfg.cols; }
+  function neighbors(r,c){
+    const out=[];
+    for(let dr=-1;dr<=1;dr++)for(let dc=-1;dc<=1;dc++){
+      if(dr===0&&dc===0) continue;
+      if(inBounds(r+dr,c+dc)) out.push([r+dr,c+dc]);
+    }
+    return out;
+  }
+
+  // ---------- board sizing ----------
+  function sizeBoard(){
+    // Compute cell size that fits the available viewport.
+    const app = document.getElementById("app");
+    const appW = app.clientWidth - (parseFloat(getComputedStyle(app).paddingLeft)+parseFloat(getComputedStyle(app).paddingRight));
+    // available height: viewport minus other chrome (approx). Use boardwrap.
+    const wrap = boardEl.parentElement;
+    const wrapH = wrap.clientHeight || (window.innerHeight*0.55);
+    const gap=3, pad=10;
+    const availW = Math.max(120, appW) - pad*2 - gap*(cfg.cols-1);
+    const availH = Math.max(120, wrapH) - pad*2 - gap*(cfg.rows-1) - 4;
+    let size = Math.floor(Math.min(availW/cfg.cols, availH/cfg.rows));
+    size = Math.max(16, Math.min(46, size));
+    boardEl.style.gridTemplateColumns = `repeat(${cfg.cols}, ${size}px)`;
+    boardEl.style.gridTemplateRows    = `repeat(${cfg.rows}, ${size}px)`;
+    const fs = Math.max(10, Math.round(size*0.56));
+    for(const el of cellEls){ el.style.fontSize = fs+"px"; }
+  }
+
+  // ---------- new game ----------
+  function newGame(){
+    const key = diffSel.value;
+    cfg = DIFFS[key];
+    grid = [];
+    cellEls = [];
+    firstClickDone=false; gameOver=false; won=false;
+    flagsPlaced=0; revealedCount=0;
+    totalSafe = cfg.rows*cfg.cols - cfg.mines;
+    stopTimer(); timer=0; timerEl.textContent="000";
+    faceEl.textContent="🙂";
+    overlay.classList.remove("show");
+    setFlagMode(false);
+
+    for(let i=0;i<cfg.rows*cfg.cols;i++){
+      grid.push({ mine:false, count:0, open:false, flag:false, r:Math.floor(i/cfg.cols), c:i%cfg.cols });
+    }
+
+    boardEl.innerHTML="";
+    const frag=document.createDocumentFragment();
+    for(let r=0;r<cfg.rows;r++){
+      for(let c=0;c<cfg.cols;c++){
+        const el=document.createElement("div");
+        el.className="cell";
+        el.dataset.r=r; el.dataset.c=c;
+        frag.appendChild(el);
+        cellEls.push(el);
+      }
+    }
+    boardEl.appendChild(frag);
+    mineCountEl.textContent = pad3(cfg.mines);
+    sizeBoard();
+    updateFooterBest();
+  }
+
+  // ---------- mine placement (first click safe) ----------
+  function placeMines(safeR, safeC){
+    // build forbidden set: the clicked cell + its neighbors (guarantees an opening)
+    const forbidden = new Set();
+    forbidden.add(idx(safeR,safeC));
+    for(const [nr,nc] of neighbors(safeR,safeC)) forbidden.add(idx(nr,nc));
+
+    // if board too small to keep all neighbors safe, at least keep the clicked cell safe
+    let openable = cfg.rows*cfg.cols - forbidden.size;
+    let localForbidden = forbidden;
+    if(openable < cfg.mines){
+      localForbidden = new Set([idx(safeR,safeC)]);
+    }
+
+    const candidates=[];
+    for(let i=0;i<cfg.rows*cfg.cols;i++){ if(!localForbidden.has(i)) candidates.push(i); }
+    // Fisher-Yates partial shuffle
+    for(let i=candidates.length-1;i>0;i--){
+      const j=Math.floor(Math.random()*(i+1));
+      [candidates[i],candidates[j]]=[candidates[j],candidates[i]];
+    }
+    for(let i=0;i<cfg.mines;i++){ grid[candidates[i]].mine=true; }
+
+    // counts
+    for(let r=0;r<cfg.rows;r++)for(let c=0;c<cfg.cols;c++){
+      const cell=grid[idx(r,c)];
+      if(cell.mine){ cell.count=-1; continue; }
+      let n=0;
+      for(const [nr,nc] of neighbors(r,c)){ if(grid[idx(nr,nc)].mine) n++; }
+      cell.count=n;
+    }
+  }
+
+  // ---------- rendering a cell ----------
+  function renderCell(i){
+    const cell=grid[i], el=cellEls[i];
+    el.className="cell";
+    el.textContent="";
+    if(cell.flag && !cell.open){
+      el.classList.add("flag");
+      el.textContent="🚩";
+      return;
+    }
+    if(cell.open){
+      el.classList.add("open");
+      if(cell.mine){
+        el.classList.add("mine");
+        el.textContent="💣";
+      } else if(cell.count>0){
+        el.classList.add("n"+cell.count);
+        el.textContent=String(cell.count);
+      } else {
+        el.classList.add("empty");
+      }
+    }
+  }
+
+  // ---------- reveal / flood ----------
+  function reveal(r,c){
+    if(gameOver) return;
+    const start=grid[idx(r,c)];
+    if(start.open || start.flag) return;
+
+    if(!firstClickDone){
+      placeMines(r,c);
+      firstClickDone=true;
+      startTimer();
+    }
+
+    if(start.mine){
+      explode(idx(r,c));
+      return;
+    }
+
+    // iterative flood fill
+    const stack=[[r,c]];
+    let flooded=0;
+    while(stack.length){
+      const [cr,cc]=stack.pop();
+      const ci=idx(cr,cc);
+      const cell=grid[ci];
+      if(cell.open || cell.flag || cell.mine) continue;
+      cell.open=true; revealedCount++; flooded++;
+      renderCell(ci);
+      if(cell.count===0){
+        for(const [nr,nc] of neighbors(cr,cc)){
+          const ni=idx(nr,nc);
+          if(!grid[ni].open && !grid[ni].flag && !grid[ni].mine){
+            stack.push([nr,nc]);
+          }
+        }
+      }
+    }
+    if(flooded>1) S.flood(); else S.reveal();
+    checkWin();
+  }
+
+  // chord: if an open numbered cell has exactly `count` flags around it, reveal the rest
+  function chord(r,c){
+    if(gameOver) return;
+    const cell=grid[idx(r,c)];
+    if(!cell.open || cell.count<=0) return;
+    let flags=0; const toOpen=[];
+    for(const [nr,nc] of neighbors(r,c)){
+      const nb=grid[idx(nr,nc)];
+      if(nb.flag) flags++;
+      else if(!nb.open) toOpen.push([nr,nc]);
+    }
+    if(flags===cell.count){
+      for(const [nr,nc] of toOpen){ reveal(nr,nc); if(gameOver) return; }
+    }
+  }
+
+  function explode(i){
+    grid[i].open=true;
+    gameOver=true; won=false;
+    stopTimer();
+    // reveal all mines + mark wrong flags
+    for(let k=0;k<grid.length;k++){
+      const cell=grid[k];
+      if(cell.mine){
+        cell.open=true; renderCell(k);
+        if(k===i) cellEls[k].classList.add("exploded");
+      } else if(cell.flag){
+        renderCell(k);
+        cellEls[k].classList.add("wrong");
+        cellEls[k].textContent="❌";
+      }
+    }
+    cellEls[i].classList.add("exploded");
+    faceEl.textContent="😵";
+    S.lose();
+    setTimeout(()=>showOverlay(false), 380);
+  }
+
+  function checkWin(){
+    if(gameOver) return;
+    if(revealedCount>=totalSafe){
+      gameOver=true; won=true;
+      stopTimer();
+      // auto-flag remaining mines
+      for(let k=0;k<grid.length;k++){
+        if(grid[k].mine && !grid[k].flag){ grid[k].flag=true; renderCell(k); }
+      }
+      flagsPlaced=cfg.mines;
+      mineCountEl.textContent="000";
+      faceEl.textContent="😎";
+      S.win();
+      handleWinRecord();
+      setTimeout(()=>showOverlay(true), 260);
+    }
+  }
+
+  // ---------- flag ----------
+  function toggleFlag(r,c){
+    if(gameOver) return;
+    const cell=grid[idx(r,c)];
+    if(cell.open) return;
+    if(!firstClickDone){ startTimer(); firstClickDone=false; } // don't place mines on flag
+    cell.flag=!cell.flag;
+    flagsPlaced += cell.flag?1:-1;
+    renderCell(idx(r,c));
+    mineCountEl.textContent = pad3(cfg.mines - flagsPlaced);
+    if(cell.flag) S.flag(); else S.unflag();
+  }
+
+  // ---------- timer ----------
+  function startTimer(){
+    if(timerId) return;
+    timerId=setInterval(()=>{
+      timer++; if(timer>999) timer=999;
+      timerEl.textContent=pad3(timer);
+    },1000);
+  }
+  function stopTimer(){ if(timerId){ clearInterval(timerId); timerId=null; } }
+
+  // ---------- win record ----------
+  function handleWinRecord(){
+    const key=diffSel.value;
+    const prev=getBest(key);
+    if(prev===null || timer<prev){
+      setBest(key, timer);
+      won_newBest=true;
+    } else {
+      won_newBest=false;
+    }
+    updateFooterBest();
+  }
+  let won_newBest=false;
+
+  // ---------- overlay ----------
+  function showOverlay(isWin){
+    card.classList.remove("win","lose");
+    if(isWin){
+      card.classList.add("win");
+      ovTitle.textContent="⚡ CLEARED ⚡";
+      ovMsg.textContent = `${DIFFS[diffSel.value].label} swept in ${timer}s`;
+      const best=getBest(diffSel.value);
+      if(won_newBest){
+        ovBest.innerHTML = `<span class="newbest">★ NEW BEST TIME ★</span>`;
+      } else {
+        ovBest.innerHTML = best!==null ? `<span class="best">Best: ${best}s</span>` : "";
+      }
+    } else {
+      card.classList.add("lose");
+      ovTitle.textContent="💥 BOOM 💥";
+      ovMsg.textContent="You hit a mine.";
+      const best=getBest(diffSel.value);
+      ovBest.innerHTML = best!==null ? `<span class="best">Best: ${best}s</span>` : "";
+    }
+    overlay.classList.add("show");
+  }
+
+  function updateFooterBest(){
+    const best=getBest(diffSel.value);
+    footerBest.textContent = best!==null
+      ? `Best ${DIFFS[diffSel.value].label}: ${best}s`
+      : `No best time yet for ${DIFFS[diffSel.value].label}`;
+  }
+
+  // ---------- flag mode toggle ----------
+  function setFlagMode(on){
+    flagMode_on=on;
+    flagToggle.classList.toggle("armed",on);
+    flagToggle.setAttribute("aria-pressed", on?"true":"false");
+    flagIcon.textContent = on?"🚩":"⛏️";
+    flagMode.textContent = on?"Flag mode":"Dig mode";
+  }
+
+  // ---------- hint ----------
+  function giveHint(){
+    if(gameOver) return;
+    if(!firstClickDone){
+      // hint the center-ish safe first click
+      const r=Math.floor(cfg.rows/2), c=Math.floor(cfg.cols/2);
+      pulseHint(idx(r,c));
+      return;
+    }
+    // find a safe unopened, unflagged cell
+    const safe=[];
+    for(let k=0;k<grid.length;k++){
+      if(!grid[k].open && !grid[k].flag && !grid[k].mine) safe.push(k);
+    }
+    if(safe.length){
+      pulseHint(safe[Math.floor(Math.random()*safe.length)]);
+      S.click();
+    }
+  }
+  function pulseHint(i){
+    const el=cellEls[i];
+    el.classList.add("hint");
+    setTimeout(()=>el.classList.remove("hint"),1600);
+  }
+
+  // ---------- event handling ----------
+  let touchTimer=null, touchMoved=false, longPressed=false;
+
+  function cellFromEvent(e){
+    const t = e.target.closest ? e.target.closest(".cell") : null;
+    if(!t) return null;
+    return { r:+t.dataset.r, c:+t.dataset.c };
+  }
+
+  boardEl.addEventListener("click", (e)=>{
+    if(longPressed){ longPressed=false; return; }
+    const pos=cellFromEvent(e); if(!pos) return;
+    if(gameOver) return;
+    ac(); // unlock audio on gesture
+    const cell=grid[idx(pos.r,pos.c)];
+    if(flagMode_on){
+      toggleFlag(pos.r,pos.c);
+    } else if(cell.open && cell.count>0){
+      chord(pos.r,pos.c);
+    } else {
+      reveal(pos.r,pos.c);
+    }
+  });
+
+  boardEl.addEventListener("contextmenu",(e)=>{
+    e.preventDefault();
+    const pos=cellFromEvent(e); if(!pos) return;
+    if(gameOver) return;
+    ac();
+    const cell=grid[idx(pos.r,pos.c)];
+    if(cell.open && cell.count>0) chord(pos.r,pos.c);
+    else toggleFlag(pos.r,pos.c);
+  });
+
+  // touch: long-press = flag
+  boardEl.addEventListener("touchstart",(e)=>{
+    if(gameOver) return;
+    const pos=cellFromEvent(e); if(!pos) return;
+    touchMoved=false; longPressed=false;
+    touchTimer=setTimeout(()=>{
+      longPressed=true;
+      ac();
+      const cell=grid[idx(pos.r,pos.c)];
+      if(cell.open && cell.count>0) chord(pos.r,pos.c);
+      else toggleFlag(pos.r,pos.c);
+    },420);
+  },{passive:true});
+  boardEl.addEventListener("touchmove",()=>{ touchMoved=true; if(touchTimer){clearTimeout(touchTimer);touchTimer=null;} },{passive:true});
+  boardEl.addEventListener("touchend",()=>{ if(touchTimer){clearTimeout(touchTimer);touchTimer=null;} });
+
+  // ---------- control wiring ----------
+  newBtn.addEventListener("click", ()=>{ S.click(); newGame(); });
+  faceEl.addEventListener("click", ()=>{ S.click(); newGame(); });
+  ovBtn.addEventListener("click", ()=>{ newGame(); });
+  diffSel.addEventListener("change", ()=>{ newGame(); });
+
+  flagToggle.addEventListener("click", ()=>{ setFlagMode(!flagMode_on); S.click(); });
+  flagToggle.addEventListener("keydown",(e)=>{ if(e.key===" "||e.key==="Enter"){ e.preventDefault(); setFlagMode(!flagMode_on); }});
+  hintBtn.addEventListener("click", ()=>{ giveHint(); });
+
+  muteBtn.addEventListener("click", ()=>{
+    muted=!muted; saveMute(muted);
+    muteBtn.textContent = muted?"🔇":"🔊";
+    muteBtn.classList.toggle("on",!muted);
+    if(!muted) S.click();
+  });
+
+  // keyboard: F toggles flag mode, N new game, H hint
+  document.addEventListener("keydown",(e)=>{
+    if(e.target && (e.target.tagName==="SELECT")) return;
+    const k=e.key.toLowerCase();
+    if(k==="f"){ setFlagMode(!flagMode_on); }
+    else if(k==="n"){ newGame(); }
+    else if(k==="h"){ giveHint(); }
+  });
+
+  window.addEventListener("resize", ()=>{ if(cfg) sizeBoard(); });
+  window.addEventListener("orientationchange", ()=>{ setTimeout(()=>{ if(cfg) sizeBoard(); },200); });
+
+  // ---------- init ----------
+  muted=loadMute();
+  muteBtn.textContent = muted?"🔇":"🔊";
+  muteBtn.classList.toggle("on",!muted);
+  newGame();
+})();
+</script>
+</body>
+</html>
diff --git a/games/missile/MissileCommand.aa b/games/missile/MissileCommand.aa
new file mode 100644
index 0000000..a8a3c16
--- /dev/null
+++ b/games/missile/MissileCommand.aa
@@ -0,0 +1,886 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>MISSILE COMMAND</title>
+<style>
+  html, body {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+    background: #0a0e14;
+    overflow: hidden;
+    touch-action: none;
+    -webkit-user-select: none;
+    user-select: none;
+    -webkit-tap-highlight-color: transparent;
+  }
+  #wrap {
+    position: fixed;
+    inset: 0;
+    display: block;
+    background: #0a0e14;
+  }
+  canvas {
+    display: block;
+    width: 100%;
+    height: 100%;
+    background: #0a0e14;
+    cursor: crosshair;
+  }
+</style>
+</head>
+<body>
+<div id="wrap">
+  <canvas id="game"></canvas>
+</div>
+<script>
+(function () {
+  "use strict";
+
+  function boot() {
+    var canvas = document.getElementById("game");
+    if (!canvas || !canvas.getContext) return;
+    var ctx = canvas.getContext("2d");
+    if (!ctx) return;
+
+    var BEST_KEY = "abrams-missile-best";
+    var best = 0;
+    try {
+      var stored = localStorage.getItem(BEST_KEY);
+      if (stored !== null) { var n = parseInt(stored, 10); if (!isNaN(n)) best = n; }
+    } catch (e) { best = 0; }
+
+    // Logical design resolution; we scale to fit the iframe.
+    var W = 900, H = 600;
+    var dpr = 1;
+
+    function resize() {
+      var cw = window.innerWidth || document.documentElement.clientWidth || W;
+      var ch = window.innerHeight || document.documentElement.clientHeight || H;
+      dpr = Math.max(1, Math.min(2, window.devicePixelRatio || 1));
+      canvas.width = Math.max(1, Math.floor(cw * dpr));
+      canvas.height = Math.max(1, Math.floor(ch * dpr));
+      canvas.style.width = cw + "px";
+      canvas.style.height = ch + "px";
+      W = cw;
+      H = ch;
+    }
+
+    window.addEventListener("resize", resize, { passive: true });
+    resize();
+
+    // ---- Audio (lazy) ----
+    var audioCtx = null;
+    var audioOK = true;
+    function ensureAudio() {
+      if (audioCtx || !audioOK) return;
+      try {
+        var AC = window.AudioContext || window.webkitAudioContext;
+        if (!AC) { audioOK = false; return; }
+        audioCtx = new AC();
+      } catch (e) { audioOK = false; audioCtx = null; }
+    }
+    function blip(type, freq, dur, vol) {
+      if (!audioOK) return;
+      try {
+        ensureAudio();
+        if (!audioCtx) return;
+        if (audioCtx.state === "suspended" && audioCtx.resume) { audioCtx.resume(); }
+        var o = audioCtx.createOscillator();
+        var g = audioCtx.createGain();
+        o.type = type;
+        o.frequency.setValueAtTime(freq, audioCtx.currentTime);
+        g.gain.setValueAtTime(vol, audioCtx.currentTime);
+        g.gain.exponentialRampToValueAtTime(0.0001, audioCtx.currentTime + dur);
+        o.connect(g);
+        g.connect(audioCtx.destination);
+        o.start();
+        o.stop(audioCtx.currentTime + dur + 0.02);
+      } catch (e) { /* never throw */ }
+    }
+    function sfxLaunch() { blip("square", 660, 0.12, 0.06); }
+    function sfxExplode() {
+      blip("sawtooth", 180, 0.30, 0.09);
+      blip("triangle", 90, 0.35, 0.06);
+    }
+    function sfxCityHit() { blip("sawtooth", 70, 0.5, 0.12); }
+
+    // ---- Game state ----
+    var STATE_START = 0, STATE_PLAY = 1, STATE_WAVEEND = 2, STATE_OVER = 3;
+    var state = STATE_START;
+
+    var cities = [];      // {x, alive}
+    var bases = [];       // {x, ammo, maxAmmo}
+    var enemies = [];     // incoming missiles
+    var friendlies = [];  // counter-missiles
+    var blasts = [];      // explosions
+    var particles = [];
+
+    var wave = 1;
+    var score = 0;
+    var waveEnemiesTotal = 0;
+    var waveEnemiesSpawned = 0;
+    var spawnTimer = 0;
+    var spawnInterval = 1.2;
+    var waveEndTimer = 0;
+    var bonusStep = 0;
+    var bonusCityIndex = 0;
+    var bonusAmmoBase = 0;
+    var bonusAmmoLeft = 0;
+    var flashTimer = 0;
+
+    var GROUND_H = 70; // reserved from bottom in logical coords (relative to H)
+
+    function groundY() { return H - 64; }
+
+    function cityBaseCount() { return 6; }
+
+    function setupField() {
+      cities = [];
+      bases = [];
+      var n = cityBaseCount();
+      // 3 bases + 6 cities arranged: base, 2 cities, base, 2 cities, base? classic: bases at far L, mid, far R
+      // We'll spread bases and cities across width.
+      var margin = W * 0.06;
+      var usable = W - margin * 2;
+      // base positions: left, center, right
+      var basePositions = [0.5 / 10, 5 / 10, 9.5 / 10];
+      // city positions between bases
+      var cityFractions = [1.7 / 10, 2.6 / 10, 3.5 / 10, 6.5 / 10, 7.4 / 10, 8.3 / 10];
+      for (var i = 0; i < basePositions.length; i++) {
+        bases.push({ x: margin + basePositions[i] * usable, ammo: 10, maxAmmo: 10 });
+      }
+      for (var j = 0; j < cityFractions.length; j++) {
+        cities.push({ x: margin + cityFractions[j] * usable, alive: true });
+      }
+    }
+
+    function repositionField() {
+      // Recompute x positions on resize while preserving alive/ammo.
+      var margin = W * 0.06;
+      var usable = W - margin * 2;
+      var basePositions = [0.5 / 10, 5 / 10, 9.5 / 10];
+      var cityFractions = [1.7 / 10, 2.6 / 10, 3.5 / 10, 6.5 / 10, 7.4 / 10, 8.3 / 10];
+      for (var i = 0; i < bases.length && i < basePositions.length; i++) {
+        bases[i].x = margin + basePositions[i] * usable;
+      }
+      for (var j = 0; j < cities.length && j < cityFractions.length; j++) {
+        cities[j].x = margin + cityFractions[j] * usable;
+      }
+    }
+
+    function startWave(w) {
+      wave = w;
+      enemies = [];
+      friendlies = [];
+      blasts = [];
+      particles = [];
+      waveEnemiesTotal = 8 + Math.floor(w * 2.5);
+      waveEnemiesSpawned = 0;
+      spawnTimer = 0.5;
+      spawnInterval = Math.max(0.35, 1.3 - w * 0.07);
+      // refill ammo
+      for (var i = 0; i < bases.length; i++) {
+        bases[i].ammo = bases[i].maxAmmo;
+      }
+      state = STATE_PLAY;
+    }
+
+    function newGame() {
+      score = 0;
+      wave = 1;
+      setupField();
+      startWave(1);
+    }
+
+    function aliveCities() {
+      var c = 0;
+      for (var i = 0; i < cities.length; i++) if (cities[i].alive) c++;
+      return c;
+    }
+
+    function enemySpeed() {
+      return (28 + wave * 5) * (H / 600);
+    }
+
+    function spawnEnemy() {
+      var speed = enemySpeed() * (0.8 + Math.random() * 0.5);
+      var sx = Math.random() * W;
+      // target a city or base
+      var targets = [];
+      for (var i = 0; i < cities.length; i++) if (cities[i].alive) targets.push(cities[i].x);
+      for (var j = 0; j < bases.length; j++) targets.push(bases[j].x);
+      if (targets.length === 0) targets = [W / 2];
+      var tx = targets[Math.floor(Math.random() * targets.length)] + (Math.random() - 0.5) * 40;
+      var ty = groundY();
+      var canSplit = wave >= 3 && Math.random() < Math.min(0.5, 0.15 + wave * 0.03);
+      var smart = wave >= 5 && Math.random() < Math.min(0.4, (wave - 4) * 0.06);
+      enemies.push({
+        x: sx, y: -10,
+        tx: tx, ty: ty,
+        sx: sx, sy: -10,
+        speed: speed,
+        split: canSplit,
+        splitY: H * (0.35 + Math.random() * 0.2),
+        smart: smart,
+        trail: [],
+        dead: false
+      });
+    }
+
+    function spawnSplit(e) {
+      var count = 2 + (Math.random() < 0.3 ? 1 : 0);
+      for (var i = 0; i < count; i++) {
+        var speed = e.speed * (0.9 + Math.random() * 0.3);
+        var targets = [];
+        for (var c = 0; c < cities.length; c++) if (cities[c].alive) targets.push(cities[c].x);
+        for (var b = 0; b < bases.length; b++) targets.push(bases[b].x);
+        if (targets.length === 0) targets = [W / 2];
+        var tx = targets[Math.floor(Math.random() * targets.length)] + (Math.random() - 0.5) * 60;
+        enemies.push({
+          x: e.x, y: e.y,
+          tx: tx, ty: groundY(),
+          sx: e.x, sy: e.y,
+          speed: speed,
+          split: false,
+          splitY: 0,
+          smart: false,
+          trail: [],
+          dead: false
+        });
+      }
+    }
+
+    function launchAt(px, py) {
+      // choose nearest base with ammo
+      var best_i = -1, bestD = Infinity;
+      for (var i = 0; i < bases.length; i++) {
+        if (bases[i].ammo <= 0) continue;
+        var d = Math.abs(bases[i].x - px);
+        if (d < bestD) { bestD = d; best_i = i; }
+      }
+      if (best_i < 0) return; // no ammo anywhere
+      var b = bases[best_i];
+      b.ammo--;
+      var ox = b.x;
+      var oy = groundY();
+      var dx = px - ox, dy = py - oy;
+      var dist = Math.sqrt(dx * dx + dy * dy) || 1;
+      var spd = 620 * (H / 600);
+      friendlies.push({
+        x: ox, y: oy,
+        vx: dx / dist * spd,
+        vy: dy / dist * spd,
+        tx: px, ty: py,
+        trail: [],
+        dead: false
+      });
+      sfxLaunch();
+    }
+
+    function addBlast(x, y, maxR) {
+      blasts.push({ x: x, y: y, r: 4, maxR: maxR, growing: true, life: 0 });
+      sfxExplode();
+    }
+
+    function addParticles(x, y, color, n) {
+      for (var i = 0; i < n; i++) {
+        var a = Math.random() * Math.PI * 2;
+        var s = 30 + Math.random() * 120;
+        particles.push({
+          x: x, y: y,
+          vx: Math.cos(a) * s,
+          vy: Math.sin(a) * s - 30,
+          life: 0.5 + Math.random() * 0.6,
+          maxLife: 1,
+          color: color
+        });
+      }
+    }
+
+    function destroyCity(c) {
+      if (!c.alive) return;
+      c.alive = false;
+      addParticles(c.x, groundY() - 8, "#ff5a7a", 26);
+      flashTimer = 0.35;
+      sfxCityHit();
+    }
+
+    // ---- Input ----
+    function pointerToLogical(clientX, clientY) {
+      var rect = canvas.getBoundingClientRect();
+      var x = (clientX - rect.left) / rect.width * W;
+      var y = (clientY - rect.top) / rect.height * H;
+      return { x: x, y: y };
+    }
+
+    function handleFire(clientX, clientY) {
+      ensureAudio();
+      if (state === STATE_START) { newGame(); return; }
+      if (state === STATE_OVER) { newGame(); return; }
+      if (state === STATE_WAVEEND) { return; }
+      if (state !== STATE_PLAY) return;
+      var p = pointerToLogical(clientX, clientY);
+      if (p.y > groundY() - 6) p.y = groundY() - 6;
+      launchAt(p.x, p.y);
+    }
+
+    canvas.addEventListener("mousedown", function (e) {
+      e.preventDefault();
+      handleFire(e.clientX, e.clientY);
+    });
+
+    canvas.addEventListener("touchstart", function (e) {
+      e.preventDefault();
+      if (e.changedTouches && e.changedTouches.length) {
+        var t = e.changedTouches[0];
+        handleFire(t.clientX, t.clientY);
+      }
+    }, { passive: false });
+
+    window.addEventListener("keydown", function (e) {
+      if (e.key === " " || e.key === "Enter") {
+        if (state === STATE_START || state === STATE_OVER) newGame();
+      }
+    });
+
+    // ---- Update ----
+    function update(dt) {
+      flashTimer = Math.max(0, flashTimer - dt);
+
+      if (state === STATE_PLAY) {
+        // spawn
+        if (waveEnemiesSpawned < waveEnemiesTotal) {
+          spawnTimer -= dt;
+          if (spawnTimer <= 0) {
+            spawnEnemy();
+            waveEnemiesSpawned++;
+            spawnTimer = spawnInterval * (0.6 + Math.random() * 0.8);
+          }
+        }
+      }
+
+      // update enemies
+      var gy = groundY();
+      for (var i = enemies.length - 1; i >= 0; i--) {
+        var e = enemies[i];
+        if (e.dead) { enemies.splice(i, 1); continue; }
+        var dx = e.tx - e.x, dy = e.ty - e.y;
+        var dd = Math.sqrt(dx * dx + dy * dy) || 1;
+        var step = e.speed * dt;
+        // smart bombs slightly weave / retarget toward alive cities
+        e.x += dx / dd * step;
+        e.y += dy / dd * step;
+
+        e.trail.push({ x: e.x, y: e.y });
+        if (e.trail.length > 16) e.trail.shift();
+
+        // split
+        if (e.split && e.y >= e.splitY) {
+          e.split = false;
+          spawnSplit(e);
+        }
+
+        if (e.y >= e.ty - 2 || e.y >= gy) {
+          // hit ground: destroy nearest city/base if near
+          e.dead = true;
+          addParticles(e.x, gy - 4, "#ff8a5a", 10);
+          // check city hits
+          for (var c = 0; c < cities.length; c++) {
+            if (cities[c].alive && Math.abs(cities[c].x - e.x) < W * 0.035) {
+              destroyCity(cities[c]);
+            }
+          }
+          for (var b = 0; b < bases.length; b++) {
+            if (Math.abs(bases[b].x - e.x) < W * 0.03) {
+              bases[b].ammo = 0; // knocked out for the wave visually
+            }
+          }
+          enemies.splice(i, 1);
+        }
+      }
+
+      // update friendlies
+      for (var f = friendlies.length - 1; f >= 0; f--) {
+        var fm = friendlies[f];
+        if (fm.dead) { friendlies.splice(f, 1); continue; }
+        fm.x += fm.vx * dt;
+        fm.y += fm.vy * dt;
+        fm.trail.push({ x: fm.x, y: fm.y });
+        if (fm.trail.length > 22) fm.trail.shift();
+        var ddx = fm.tx - fm.x, ddy = fm.ty - fm.y;
+        // reached target when passing it
+        if (ddx * fm.vx + ddy * fm.vy <= 0) {
+          fm.dead = true;
+          addBlast(fm.tx, fm.ty, Math.max(46, W * 0.06));
+          friendlies.splice(f, 1);
+        }
+      }
+
+      // update blasts
+      for (var bl = blasts.length - 1; bl >= 0; bl--) {
+        var B = blasts[bl];
+        B.life += dt;
+        if (B.growing) {
+          B.r += (B.maxR) * dt * 3.2;
+          if (B.r >= B.maxR) { B.r = B.maxR; B.growing = false; }
+        } else {
+          B.r -= B.maxR * dt * 1.9;
+          if (B.r <= 0) { blasts.splice(bl, 1); continue; }
+        }
+        // destroy enemies inside blast
+        for (var ei = enemies.length - 1; ei >= 0; ei--) {
+          var en = enemies[ei];
+          var edx = en.x - B.x, edy = en.y - B.y;
+          if (edx * edx + edy * edy <= B.r * B.r) {
+            en.dead = true;
+            score += 25;
+            addParticles(en.x, en.y, "#7dffea", 8);
+            enemies.splice(ei, 1);
+          }
+        }
+      }
+
+      // update particles
+      for (var p = particles.length - 1; p >= 0; p--) {
+        var pt = particles[p];
+        pt.life -= dt;
+        if (pt.life <= 0) { particles.splice(p, 1); continue; }
+        pt.vy += 140 * dt;
+        pt.x += pt.vx * dt;
+        pt.y += pt.vy * dt;
+      }
+
+      // check wave end / game over
+      if (state === STATE_PLAY) {
+        if (aliveCities() === 0) {
+          // let remaining blasts fade a touch, then game over
+          state = STATE_OVER;
+          if (score > best) {
+            best = score;
+            try { localStorage.setItem(BEST_KEY, String(best)); } catch (e2) {}
+          }
+        } else if (waveEnemiesSpawned >= waveEnemiesTotal && enemies.length === 0 && friendlies.length === 0) {
+          // wave clear -> bonus phase
+          state = STATE_WAVEEND;
+          waveEndTimer = 0;
+          bonusStep = 0;
+          bonusCityIndex = 0;
+          bonusAmmoLeft = 0;
+          for (var bb = 0; bb < bases.length; bb++) bonusAmmoLeft += bases[bb].ammo;
+          bonusAmmoBase = bonusAmmoLeft;
+        }
+      }
+
+      if (state === STATE_WAVEEND) {
+        waveEndTimer += dt;
+        // tally city bonus (100 each) then ammo bonus (10 each)
+        // simple timed tally for feel
+        if (bonusStep === 0 && waveEndTimer > 0.4) {
+          bonusStep = 1;
+        } else if (bonusStep === 1) {
+          if (waveEndTimer > 0.5 + bonusCityIndex * 0.12) {
+            if (bonusCityIndex < cities.length) {
+              if (cities[bonusCityIndex].alive) { score += 100; blip("sine", 880, 0.08, 0.05); }
+              bonusCityIndex++;
+            } else {
+              bonusStep = 2;
+              waveEndTimer = 0;
+            }
+          }
+        } else if (bonusStep === 2) {
+          if (waveEndTimer > 0.05 && bonusAmmoLeft > 0) {
+            if (waveEndTimer > 0.02) {
+              score += 5;
+              bonusAmmoLeft--;
+              waveEndTimer = 0;
+              blip("sine", 1200, 0.04, 0.04);
+            }
+          } else if (bonusAmmoLeft <= 0) {
+            bonusStep = 3;
+            waveEndTimer = 0;
+          }
+        } else if (bonusStep === 3) {
+          if (waveEndTimer > 1.0) {
+            startWave(wave + 1);
+          }
+        }
+      }
+    }
+
+    // ---- Draw ----
+    var starField = null;
+    function buildStars() {
+      starField = [];
+      var n = 70;
+      for (var i = 0; i < n; i++) {
+        starField.push({
+          x: Math.random(),
+          y: Math.random() * 0.75,
+          s: Math.random() * 1.6 + 0.3,
+          tw: Math.random() * Math.PI * 2
+        });
+      }
+    }
+    buildStars();
+
+    var tGlobal = 0;
+
+    function drawBackground() {
+      // gradient sky
+      var g = ctx.createLinearGradient(0, 0, 0, H);
+      g.addColorStop(0, "#0a0e14");
+      g.addColorStop(0.6, "#0b1220");
+      g.addColorStop(1, "#0d1a2b");
+      ctx.fillStyle = g;
+      ctx.fillRect(0, 0, W, H);
+
+      // stars
+      for (var i = 0; i < starField.length; i++) {
+        var st = starField[i];
+        var a = 0.4 + 0.5 * Math.abs(Math.sin(tGlobal * 1.5 + st.tw));
+        ctx.fillStyle = "rgba(180,220,255," + a.toFixed(3) + ")";
+        ctx.fillRect(st.x * W, st.y * H, st.s, st.s);
+      }
+    }
+
+    function drawGround() {
+      var gy = groundY();
+      // ground glow line
+      ctx.save();
+      ctx.strokeStyle = "#1de9b6";
+      ctx.shadowColor = "#1de9b6";
+      ctx.shadowBlur = 14;
+      ctx.lineWidth = 2;
+      ctx.beginPath();
+      ctx.moveTo(0, gy + 10);
+      ctx.lineTo(W, gy + 10);
+      ctx.stroke();
+      ctx.restore();
+
+      // ground fill
+      ctx.fillStyle = "#08131c";
+      ctx.fillRect(0, gy + 10, W, H - (gy + 10));
+    }
+
+    function drawCity(c) {
+      var gy = groundY();
+      var cw = W * 0.05;
+      var bx = c.x - cw / 2;
+      if (!c.alive) {
+        // rubble
+        ctx.save();
+        ctx.fillStyle = "#20303c";
+        for (var r = 0; r < 4; r++) {
+          var rw = cw * (0.2 + Math.random() * 0.1);
+          ctx.fillRect(bx + r * (cw / 4), gy - 4 - Math.random() * 5, rw, 5 + Math.random() * 4);
+        }
+        ctx.restore();
+        return;
+      }
+      ctx.save();
+      ctx.shadowColor = "#36e0ff";
+      ctx.shadowBlur = 12;
+      // skyline: a few towers
+      var towers = [
+        { w: cw * 0.20, h: 20 },
+        { w: cw * 0.16, h: 32 },
+        { w: cw * 0.22, h: 26 },
+        { w: cw * 0.16, h: 16 }
+      ];
+      var tx = bx;
+      var hue = "#2ad4ff";
+      for (var t = 0; t < towers.length; t++) {
+        var tw = towers[t].w;
+        var th = towers[t].h * (H / 600);
+        ctx.fillStyle = hue;
+        ctx.globalAlpha = 0.9;
+        ctx.fillRect(tx, gy - th, tw, th);
+        tx += tw + cw * 0.02;
+      }
+      ctx.globalAlpha = 1;
+      ctx.restore();
+      // little windows
+      ctx.fillStyle = "rgba(255,255,180,0.5)";
+      var wx = bx + 3;
+      for (var wxi = 0; wxi < 5; wxi++) {
+        ctx.fillRect(wx + wxi * (cw / 6), gy - 10, 1.5, 1.5);
+      }
+    }
+
+    function drawBase(b) {
+      var gy = groundY();
+      ctx.save();
+      var lowAmmo = b.ammo <= 0;
+      var col = lowAmmo ? "#5a6b78" : "#ffd23f";
+      ctx.shadowColor = col;
+      ctx.shadowBlur = lowAmmo ? 0 : 14;
+      ctx.fillStyle = col;
+      // triangular battery
+      ctx.beginPath();
+      var bw = W * 0.03;
+      ctx.moveTo(b.x - bw, gy + 8);
+      ctx.lineTo(b.x + bw, gy + 8);
+      ctx.lineTo(b.x, gy - 16);
+      ctx.closePath();
+      ctx.fill();
+      ctx.restore();
+
+      // ammo count
+      ctx.fillStyle = lowAmmo ? "#7a8792" : "#fff3c4";
+      ctx.font = "bold " + Math.round(11 * (H / 600) + 6) + "px monospace";
+      ctx.textAlign = "center";
+      ctx.textBaseline = "top";
+      ctx.fillText(String(b.ammo), b.x, gy + 12);
+    }
+
+    function drawEnemies() {
+      for (var i = 0; i < enemies.length; i++) {
+        var e = enemies[i];
+        // trail
+        ctx.save();
+        var col = e.smart ? "#ff4de0" : "#ff5a5a";
+        ctx.strokeStyle = col;
+        ctx.shadowColor = col;
+        ctx.shadowBlur = 8;
+        ctx.lineWidth = 1.6;
+        ctx.beginPath();
+        ctx.moveTo(e.sx, e.sy);
+        for (var t = 0; t < e.trail.length; t++) {
+          ctx.lineTo(e.trail[t].x, e.trail[t].y);
+        }
+        ctx.lineTo(e.x, e.y);
+        ctx.stroke();
+        // head
+        ctx.fillStyle = "#fff";
+        ctx.beginPath();
+        ctx.arc(e.x, e.y, e.smart ? 3.4 : 2.6, 0, Math.PI * 2);
+        ctx.fill();
+        ctx.restore();
+      }
+    }
+
+    function drawFriendlies() {
+      for (var i = 0; i < friendlies.length; i++) {
+        var f = friendlies[i];
+        ctx.save();
+        ctx.strokeStyle = "#7dffea";
+        ctx.shadowColor = "#7dffea";
+        ctx.shadowBlur = 10;
+        ctx.lineWidth = 1.8;
+        ctx.beginPath();
+        if (f.trail.length) {
+          ctx.moveTo(f.trail[0].x, f.trail[0].y);
+          for (var t = 1; t < f.trail.length; t++) ctx.lineTo(f.trail[t].x, f.trail[t].y);
+          ctx.lineTo(f.x, f.y);
+        }
+        ctx.stroke();
+        // target marker
+        ctx.strokeStyle = "rgba(125,255,234,0.5)";
+        ctx.shadowBlur = 0;
+        ctx.lineWidth = 1;
+        ctx.beginPath();
+        ctx.moveTo(f.tx - 5, f.ty); ctx.lineTo(f.tx + 5, f.ty);
+        ctx.moveTo(f.tx, f.ty - 5); ctx.lineTo(f.tx, f.ty + 5);
+        ctx.stroke();
+        ctx.restore();
+      }
+    }
+
+    function drawBlasts() {
+      for (var i = 0; i < blasts.length; i++) {
+        var B = blasts[i];
+        var hueT = (tGlobal * 6 + i) % 3;
+        var color = hueT < 1 ? "#fff6a8" : (hueT < 2 ? "#7dffea" : "#ff8ad4");
+        ctx.save();
+        ctx.globalCompositeOperation = "lighter";
+        // outer ring
+        ctx.strokeStyle = color;
+        ctx.shadowColor = color;
+        ctx.shadowBlur = 20;
+        ctx.lineWidth = 3;
+        ctx.beginPath();
+        ctx.arc(B.x, B.y, B.r, 0, Math.PI * 2);
+        ctx.stroke();
+        // inner fill
+        var grad = ctx.createRadialGradient(B.x, B.y, 0, B.x, B.y, B.r);
+        grad.addColorStop(0, "rgba(255,255,255,0.5)");
+        grad.addColorStop(0.5, "rgba(125,255,234,0.25)");
+        grad.addColorStop(1, "rgba(125,255,234,0)");
+        ctx.fillStyle = grad;
+        ctx.beginPath();
+        ctx.arc(B.x, B.y, B.r, 0, Math.PI * 2);
+        ctx.fill();
+        ctx.restore();
+      }
+    }
+
+    function drawParticles() {
+      for (var i = 0; i < particles.length; i++) {
+        var p = particles[i];
+        var a = Math.max(0, Math.min(1, p.life));
+        ctx.save();
+        ctx.globalAlpha = a;
+        ctx.fillStyle = p.color;
+        ctx.shadowColor = p.color;
+        ctx.shadowBlur = 6;
+        ctx.fillRect(p.x, p.y, 2.2, 2.2);
+        ctx.restore();
+      }
+    }
+
+    function drawHUD() {
+      ctx.save();
+      ctx.textBaseline = "top";
+      var fs = Math.round(14 * (H / 600) + 6);
+      ctx.font = "bold " + fs + "px monospace";
+      ctx.textAlign = "left";
+      ctx.fillStyle = "#7dffea";
+      ctx.shadowColor = "#7dffea";
+      ctx.shadowBlur = 8;
+      ctx.fillText("SCORE " + score, 14, 12);
+      ctx.textAlign = "center";
+      ctx.fillStyle = "#ffd23f";
+      ctx.shadowColor = "#ffd23f";
+      ctx.fillText("WAVE " + wave, W / 2, 12);
+      ctx.textAlign = "right";
+      ctx.fillStyle = "#ff8ad4";
+      ctx.shadowColor = "#ff8ad4";
+      ctx.fillText("BEST " + best, W - 14, 12);
+      ctx.restore();
+    }
+
+    function drawTitleText(lines, subLines) {
+      ctx.save();
+      ctx.textAlign = "center";
+      ctx.textBaseline = "middle";
+      var cy = H * 0.4;
+      var big = Math.round(Math.min(W * 0.075, 54));
+      ctx.font = "bold " + big + "px monospace";
+      // letter-spaced uppercase title with glow
+      for (var li = 0; li < lines.length; li++) {
+        var txt = lines[li];
+        ctx.fillStyle = "#7dffea";
+        ctx.shadowColor = "#36e0ff";
+        ctx.shadowBlur = 24;
+        drawSpaced(txt.toUpperCase(), W / 2, cy + li * (big * 1.2), big * 0.18);
+      }
+      ctx.shadowBlur = 0;
+      var sm = Math.round(Math.min(W * 0.03, 18));
+      ctx.font = "bold " + sm + "px monospace";
+      ctx.fillStyle = "#ffd23f";
+      var sy = cy + lines.length * (big * 1.2) + 24;
+      for (var si = 0; si < subLines.length; si++) {
+        ctx.shadowColor = "#ffd23f";
+        ctx.shadowBlur = 10;
+        ctx.fillText(subLines[si], W / 2, sy + si * (sm * 1.6));
+      }
+      ctx.restore();
+    }
+
+    function drawSpaced(text, cx, cy, extra) {
+      // measure with tracking
+      var widths = [];
+      var total = 0;
+      for (var i = 0; i < text.length; i++) {
+        var w = ctx.measureText(text[i]).width;
+        widths.push(w);
+        total += w + (i < text.length - 1 ? extra : 0);
+      }
+      var x = cx - total / 2;
+      for (var j = 0; j < text.length; j++) {
+        ctx.textAlign = "left";
+        ctx.fillText(text[j], x, cy);
+        x += widths[j] + extra;
+      }
+      ctx.textAlign = "center";
+    }
+
+    function draw() {
+      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
+      drawBackground();
+
+      // field
+      var i;
+      for (i = 0; i < cities.length; i++) drawCity(cities[i]);
+      for (i = 0; i < bases.length; i++) drawBase(bases[i]);
+      drawGround();
+
+      drawEnemies();
+      drawFriendlies();
+      drawBlasts();
+      drawParticles();
+
+      // city-hit flash
+      if (flashTimer > 0) {
+        ctx.save();
+        ctx.fillStyle = "rgba(255,60,110," + (flashTimer * 0.6).toFixed(3) + ")";
+        ctx.fillRect(0, 0, W, H);
+        ctx.restore();
+      }
+
+      drawHUD();
+
+      if (state === STATE_START) {
+        drawTitleText(["Missile", "Command"], ["TAP / CLICK TO DEFEND", "PROTECT YOUR 6 CITIES"]);
+      } else if (state === STATE_OVER) {
+        drawTitleText(["Game", "Over"], ["SCORE " + score, "TAP TO PLAY AGAIN"]);
+      } else if (state === STATE_WAVEEND) {
+        ctx.save();
+        ctx.textAlign = "center";
+        ctx.textBaseline = "middle";
+        var big = Math.round(Math.min(W * 0.05, 34));
+        ctx.font = "bold " + big + "px monospace";
+        ctx.fillStyle = "#ffd23f";
+        ctx.shadowColor = "#ffd23f";
+        ctx.shadowBlur = 18;
+        drawSpaced("WAVE " + wave + " CLEAR", W / 2, H * 0.4, big * 0.14);
+        ctx.shadowBlur = 8;
+        var sm = Math.round(Math.min(W * 0.028, 16));
+        ctx.font = "bold " + sm + "px monospace";
+        ctx.fillStyle = "#7dffea";
+        ctx.shadowColor = "#7dffea";
+        ctx.fillText("BONUS TALLY...", W / 2, H * 0.4 + big + 20);
+        ctx.restore();
+      }
+    }
+
+    // ---- Loop ----
+    var last = 0;
+    var running = true;
+    function frame(now) {
+      if (!running) return;
+      if (!last) last = now;
+      var dt = (now - last) / 1000;
+      last = now;
+      if (dt > 0.05) dt = 0.05; // clamp
+      tGlobal += dt;
+
+      // keep field positions in sync with size
+      repositionField();
+
+      try {
+        update(dt);
+        draw();
+      } catch (err) {
+        // never let a frame throw a pageerror
+        running = false;
+      }
+      window.requestAnimationFrame(frame);
+    }
+
+    window.requestAnimationFrame(frame);
+  }
+
+  if (document.readyState === "loading") {
+    document.addEventListener("DOMContentLoaded", boot);
+  } else {
+    boot();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/particle-text/ParticleWord.aa b/games/particle-text/ParticleWord.aa
new file mode 100644
index 0000000..36408d4
--- /dev/null
+++ b/games/particle-text/ParticleWord.aa
@@ -0,0 +1,143 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Particle Word</title>
+  <style>
+    html, body {
+      margin: 0;
+      padding: 0;
+      overflow: hidden;
+      background: #000;
+      height: 100%;
+      width: 100%;
+      font-family: 'Arial', sans-serif;
+    }
+    #word {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      color: #fff;
+      font-size: 48px;
+      pointer-events: none;
+      text-transform: uppercase;
+      text-align: center;
+    }
+    #controls {
+      position: absolute;
+      top: 20px;
+      left: 50%;
+      transform: translateX(-50%);
+      color: #fff;
+      font-size: 18px;
+    }
+  </style>
+</head>
+<body>
+  <div id="word">TYPE HERE</div>
+  <div id="controls">Type a word to see particles form it</div>
+  <canvas id="canvas"></canvas>
+  <script>
+    const canvas = document.getElementById('canvas');
+    const ctx = canvas.getContext('2d');
+    let width, height;
+    let particles = [];
+    let targetWord = 'TYPE HERE';
+    let isHovering = false;
+
+    function resize() {
+      width = canvas.width = window.innerWidth;
+      height = canvas.height = window.innerHeight;
+    }
+    window.addEventListener('resize', resize);
+    resize();
+
+    function createParticles(word, count = 2000) {
+      particles = [];
+      const chars = word.split('');
+      const totalChars = chars.length;
+      for (let i = 0; i < count; i++) {
+        const charIndex = Math.floor(i / (count / totalChars));
+        const char = chars[charIndex % totalChars];
+        const angle = (Math.random() * Math.PI * 2);
+        const radius = Math.random() * 150 + 100;
+        const x = width / 2 + Math.cos(angle) * radius;
+        const y = height / 2 + Math.sin(angle) * radius;
+        const size = Math.random() * 2 + 1;
+        const speed = Math.random() * 0.5 + 0.2;
+        particles.push({
+          x,
+          y,
+          targetX: width / 2 + (char.charCodeAt(0) - 65) * 30,
+          targetY: height / 2 + (Math.floor(i / totalChars)) * 30,
+          size,
+          speed,
+          vx: (Math.random() - 0.5) * 2,
+          vy: (Math.random() - 0.5) * 2,
+          char: char
+        });
+      }
+    }
+
+    function updateParticles() {
+      for (let p of particles) {
+        const dx = p.targetX - p.x;
+        const dy = p.targetY - p.y;
+        const dist = Math.sqrt(dx * dx + dy * dy);
+        if (dist < 2) {
+          p.x = p.targetX;
+          p.y = p.targetY;
+        } else {
+          const angle = Math.atan2(dy, dx);
+          p.x += Math.cos(angle) * p.speed;
+          p.y += Math.sin(angle) * p.speed;
+        }
+        if (isHovering) {
+          const nx = (Math.random() - 0.5) * 10;
+          const ny = (Math.random() - 0.5) * 10;
+          p.x += nx;
+          p.y += ny;
+        }
+      }
+    }
+
+    function drawParticles() {
+      ctx.clearRect(0, 0, width, height);
+      ctx.fillStyle = '#00ffcc';
+      for (let p of particles) {
+        ctx.beginPath();
+        ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
+        ctx.fill();
+      }
+    }
+
+    function animate() {
+      updateParticles();
+      drawParticles();
+      requestAnimationFrame(animate);
+    }
+
+    function resetParticles() {
+      createParticles(targetWord);
+    }
+
+    window.addEventListener('mousemove', () => {
+      isHovering = true;
+      setTimeout(() => {
+        isHovering = false;
+      }, 500);
+    });
+
+    window.addEventListener('keydown', (e) => {
+      if (e.key.length === 1 && e.key.match(/[a-zA-Z]/)) {
+        targetWord = e.key.toUpperCase();
+        resetParticles();
+      }
+    });
+
+    createParticles(targetWord);
+    animate();
+  </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/games/pong/AbramsPong.aa b/games/pong/AbramsPong.aa
new file mode 100644
index 0000000..3ce1461
--- /dev/null
+++ b/games/pong/AbramsPong.aa
@@ -0,0 +1,293 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Abrams Pong 2P</title>
+<style>
+  :root { --accent:#7c5cff; --accent2:#ff4d9d; --ink:#e8e9ef; }
+  * { box-sizing:border-box; }
+  html,body { height:100%; margin:0; }
+  body {
+    background:#0e1016; color:var(--ink);
+    font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
+    overflow:hidden; display:flex; align-items:center; justify-content:center;
+    user-select:none; -webkit-user-select:none; touch-action:none;
+  }
+  #wrap { position:relative; width:100%; height:100%; }
+  canvas { display:block; width:100%; height:100%; }
+  #hud {
+    position:absolute; top:10px; left:50%; transform:translateX(-50%);
+    display:flex; gap:8px; align-items:center; font-size:11px; letter-spacing:.5px;
+    background:rgba(20,23,31,.72); border:1px solid #2b3140; border-radius:999px;
+    padding:6px 12px; backdrop-filter:blur(6px); z-index:3;
+  }
+  #hud button {
+    background:none; border:1px solid #3d4763; color:var(--ink); font:inherit;
+    font-size:11px; border-radius:999px; padding:3px 9px; cursor:pointer;
+  }
+  #hud button:hover { background:#222839; }
+  #hud button.on { background:var(--accent); border-color:var(--accent); }
+  #msg {
+    position:absolute; inset:0; display:flex; flex-direction:column; gap:12px;
+    align-items:center; justify-content:center; text-align:center; z-index:2;
+    background:rgba(14,16,22,.55); pointer-events:none;
+  }
+  #msg h2 { margin:0; font-size:26px; letter-spacing:2px; }
+  #msg p { margin:0; font-size:12px; opacity:.6; line-height:1.9; max-width:340px; }
+  #msg .go { color:var(--accent); font-size:12px; opacity:1; margin-top:6px; }
+  .hidden { display:none !important; }
+</style>
+</head>
+<body>
+<div id="wrap">
+  <canvas id="c"></canvas>
+  <div id="hud">
+    <span id="mode-lbl">2 PLAYER</span>
+    <button id="mode">vs CPU</button>
+    <button id="pause">⏸</button>
+    <button id="mute">🔊</button>
+  </div>
+  <div id="msg">
+    <h2 id="title">ABRAMS PONG</h2>
+    <p id="sub">Left: <b>W / S</b> &nbsp;·&nbsp; Right: <b>↑ / ↓</b><br>Touch: drag your own half of the screen<br>First to 11 wins</p>
+    <p class="go" id="go">Press SPACE or tap to serve</p>
+  </div>
+</div>
+<script>
+(function () {
+  var cv = document.getElementById('c'), ctx = cv.getContext('2d');
+  var msg = document.getElementById('msg'), titleEl = document.getElementById('title');
+  var subEl = document.getElementById('sub'), goEl = document.getElementById('go');
+  var modeBtn = document.getElementById('mode'), modeLbl = document.getElementById('mode-lbl');
+  var pauseBtn = document.getElementById('pause'), muteBtn = document.getElementById('mute');
+
+  var W = 0, H = 0, dpr = 1;
+  function resize() {
+    dpr = Math.min(window.devicePixelRatio || 1, 2);
+    W = cv.clientWidth; H = cv.clientHeight;
+    cv.width = Math.floor(W * dpr); cv.height = Math.floor(H * dpr);
+    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
+  }
+  window.addEventListener('resize', resize); resize();
+
+  // ---- audio (procedural, zero-dep) ----
+  var AC = null, muted = false;
+  try { muted = localStorage.getItem('aa-pong-mute') === '1'; } catch (e) {}
+  function actx() { if (!AC) { try { AC = new (window.AudioContext || window.webkitAudioContext)(); } catch (e) {} } return AC; }
+  function beep(freq, dur, type, vol) {
+    if (muted) return; var a = actx(); if (!a) return;
+    if (a.state === 'suspended') a.resume();
+    var o = a.createOscillator(), g = a.createGain();
+    o.type = type || 'square'; o.frequency.value = freq;
+    g.gain.value = vol || 0.06;
+    o.connect(g); g.connect(a.destination);
+    var t = a.currentTime; o.start(t);
+    g.gain.exponentialRampToValueAtTime(0.0001, t + (dur || 0.06));
+    o.stop(t + (dur || 0.06) + 0.02);
+  }
+  function updMute() { muteBtn.textContent = muted ? '🔇' : '🔊'; }
+  updMute();
+
+  // ---- state ----
+  var WIN = 11;
+  var vsCPU = false;
+  var padH = 92, padW = 12, ballR = 8;
+  var L = { y: 0, score: 0 }, R = { y: 0, score: 0 };
+  var ball = { x: 0, y: 0, vx: 0, vy: 0, speed: 0 };
+  var state = 'idle';   // idle | serve | play | point | over
+  var paused = false, server = 1, winner = 0, flash = 0;
+  var keys = {};
+
+  function centerPads() { L.y = H / 2 - padH / 2; R.y = H / 2 - padH / 2; }
+
+  function resetBall(dir) {
+    ball.x = W / 2; ball.y = H / 2;
+    ball.speed = Math.max(4.2, W * 0.006);
+    var ang = (Math.random() * 0.7 - 0.35);
+    ball.vx = Math.cos(ang) * ball.speed * dir;
+    ball.vy = Math.sin(ang) * ball.speed;
+  }
+
+  function newGame() {
+    L.score = 0; R.score = 0; winner = 0;
+    centerPads(); server = Math.random() < 0.5 ? 1 : -1;
+    state = 'serve'; showServe();
+  }
+  function showServe() {
+    titleEl.textContent = (L.score + R.score === 0) ? 'ABRAMS PONG' : (L.score + ' — ' + R.score);
+    subEl.style.display = 'none';
+    goEl.textContent = 'Press SPACE or tap to serve';
+    msg.classList.remove('hidden');
+  }
+  function hideMsg() { msg.classList.add('hidden'); }
+
+  function serve() {
+    if (state !== 'serve') return;
+    resetBall(server); state = 'play'; hideMsg();
+    if (actx() && actx().state === 'suspended') actx().resume();
+    beep(440, 0.05);
+  }
+
+  function point(side) {
+    if (side === 1) L.score++; else R.score++;
+    beep(180, 0.14, 'sawtooth', 0.05); flash = 8;
+    if (L.score >= WIN || R.score >= WIN) {
+      winner = L.score > R.score ? 1 : -1; state = 'over';
+      titleEl.textContent = (winner === 1 ? 'LEFT' : (vsCPU ? 'CPU' : 'RIGHT')) + ' WINS';
+      subEl.style.display = 'block';
+      subEl.innerHTML = 'Final &nbsp;' + L.score + ' — ' + R.score;
+      goEl.textContent = 'Press SPACE or tap to play again';
+      msg.classList.remove('hidden');
+      beep(660, 0.18, 'triangle', 0.06);
+      setTimeout(function(){ beep(880, 0.22, 'triangle', 0.06); }, 120);
+    } else {
+      server = -side;      // loser serves
+      state = 'serve'; showServe();
+    }
+  }
+
+  // ---- input ----
+  window.addEventListener('keydown', function (e) {
+    var k = e.key;
+    if (k === 'w' || k === 'W' || k === 's' || k === 'S' ||
+        k === 'ArrowUp' || k === 'ArrowDown' || k === ' ') e.preventDefault();
+    keys[k.toLowerCase()] = true;
+    if (k === ' ') { if (state === 'serve') serve(); else if (state === 'over') newGame(); }
+    if (k === 'p' || k === 'P') togglePause();
+    if (k === 'm' || k === 'M') toggleMute();
+  });
+  window.addEventListener('keyup', function (e) { keys[e.key.toLowerCase()] = false; });
+
+  function togglePause() {
+    if (state !== 'play') return;
+    paused = !paused; pauseBtn.classList.toggle('on', paused);
+    pauseBtn.textContent = paused ? '▶' : '⏸';
+    if (paused) { titleEl.textContent = 'PAUSED'; subEl.style.display='none'; goEl.textContent='Press P to resume'; msg.classList.remove('hidden'); }
+    else hideMsg();
+  }
+  function toggleMute() {
+    muted = !muted; updMute();
+    try { localStorage.setItem('aa-pong-mute', muted ? '1' : '0'); } catch (e) {}
+  }
+  pauseBtn.onclick = togglePause;
+  muteBtn.onclick = toggleMute;
+  modeBtn.onclick = function () {
+    vsCPU = !vsCPU;
+    modeLbl.textContent = vsCPU ? '1 P vs CPU' : '2 PLAYER';
+    modeBtn.textContent = vsCPU ? '2 Player' : 'vs CPU';
+    modeBtn.classList.toggle('on', vsCPU);
+    newGame();
+  };
+
+  // ---- touch: left half controls left paddle, right half controls right ----
+  var touches = {};
+  function handleTouch(e) {
+    e.preventDefault();
+    for (var i = 0; i < e.touches.length; i++) {
+      var t = e.touches[i];
+      var rect = cv.getBoundingClientRect();
+      var x = t.clientX - rect.left, y = t.clientY - rect.top;
+      if (x < W / 2) L.y = y - padH / 2;
+      else if (!vsCPU) R.y = y - padH / 2;
+    }
+  }
+  cv.addEventListener('touchstart', function (e) {
+    if (state === 'serve') serve(); else if (state === 'over') newGame();
+    handleTouch(e);
+  }, { passive: false });
+  cv.addEventListener('touchmove', handleTouch, { passive: false });
+  // mouse fallback for the message overlay / desktop serve
+  cv.addEventListener('mousedown', function () {
+    if (state === 'serve') serve(); else if (state === 'over') newGame();
+  });
+
+  // ---- update ----
+  function clampPad(p) { if (p.y < 0) p.y = 0; if (p.y > H - padH) p.y = H - padH; }
+
+  function step() {
+    var sp = Math.max(6, H * 0.011);
+    if (keys['w']) L.y -= sp; if (keys['s']) L.y += sp;
+    if (!vsCPU) { if (keys['arrowup']) R.y -= sp; if (keys['arrowdown']) R.y += sp; }
+    else {
+      // CPU: track ball with capped speed + a little lag
+      var target = ball.vx > 0 ? ball.y - padH / 2 : H / 2 - padH / 2;
+      var diff = target - R.y, cap = sp * 0.82;
+      R.y += Math.max(-cap, Math.min(cap, diff));
+    }
+    clampPad(L); clampPad(R);
+
+    if (state !== 'play' || paused) return;
+
+    ball.x += ball.vx; ball.y += ball.vy;
+
+    // top / bottom walls
+    if (ball.y - ballR < 0) { ball.y = ballR; ball.vy = Math.abs(ball.vy); beep(520, 0.03); }
+    if (ball.y + ballR > H) { ball.y = H - ballR; ball.vy = -Math.abs(ball.vy); beep(520, 0.03); }
+
+    // left paddle
+    if (ball.vx < 0 && ball.x - ballR < 24 + padW && ball.x - ballR > 12 &&
+        ball.y > L.y && ball.y < L.y + padH) {
+      bounce(L, 24 + padW, 1);
+    }
+    // right paddle
+    if (ball.vx > 0 && ball.x + ballR > W - 24 - padW && ball.x + ballR < W - 12 &&
+        ball.y > R.y && ball.y < R.y + padH) {
+      bounce(R, W - 24 - padW, -1);
+    }
+
+    // out of bounds → point
+    if (ball.x < -20) point(-1);
+    else if (ball.x > W + 20) point(1);
+  }
+
+  function bounce(pad, edgeX, dir) {
+    var rel = (ball.y - (pad.y + padH / 2)) / (padH / 2);   // -1..1
+    rel = Math.max(-1, Math.min(1, rel));
+    ball.speed = Math.min(ball.speed * 1.045, W * 0.02);
+    var ang = rel * 1.05;                                   // up to ~60°
+    ball.vx = Math.cos(ang) * ball.speed * dir;
+    ball.vy = Math.sin(ang) * ball.speed;
+    ball.x = edgeX + dir * (ballR + 1);
+    beep(680, 0.04, 'square', 0.05);
+  }
+
+  // ---- draw ----
+  function draw() {
+    ctx.clearRect(0, 0, W, H);
+    // subtle vignette bg
+    ctx.fillStyle = '#0e1016'; ctx.fillRect(0, 0, W, H);
+    // center dashed net
+    ctx.strokeStyle = 'rgba(124,92,255,.28)'; ctx.lineWidth = 3;
+    ctx.setLineDash([10, 14]); ctx.beginPath();
+    ctx.moveTo(W / 2, 0); ctx.lineTo(W / 2, H); ctx.stroke(); ctx.setLineDash([]);
+    // scores
+    ctx.fillStyle = 'rgba(232,233,239,.16)';
+    ctx.font = '700 ' + Math.min(120, H * 0.22) + 'px ui-monospace, monospace';
+    ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
+    ctx.fillText(L.score, W * 0.28, H * 0.24);
+    ctx.fillText(R.score, W * 0.72, H * 0.24);
+    // paddles
+    ctx.fillStyle = '#37c7ff'; roundRect(24, L.y, padW, padH, 6); ctx.fill();
+    ctx.fillStyle = '#ff4d9d'; roundRect(W - 24 - padW, R.y, padW, padH, 6); ctx.fill();
+    // ball
+    if (state === 'play' || state === 'point') {
+      ctx.fillStyle = flash > 0 ? '#fff' : '#ffd23e';
+      ctx.beginPath(); ctx.arc(ball.x, ball.y, ballR, 0, Math.PI * 2); ctx.fill();
+    }
+    if (flash > 0) flash--;
+  }
+  function roundRect(x, y, w, h, r) {
+    ctx.beginPath();
+    ctx.moveTo(x + r, y); ctx.arcTo(x + w, y, x + w, y + h, r);
+    ctx.arcTo(x + w, y + h, x, y + h, r); ctx.arcTo(x, y + h, x, y, r);
+    ctx.arcTo(x, y, x + w, y, r); ctx.closePath();
+  }
+
+  function loop() { step(); draw(); requestAnimationFrame(loop); }
+  centerPads(); newGame(); loop();
+  window.focus();
+})();
+</script>
+</body>
+</html>
diff --git a/games/racer/NeonDrifter.aa b/games/racer/NeonDrifter.aa
new file mode 100644
index 0000000..84c5673
--- /dev/null
+++ b/games/racer/NeonDrifter.aa
@@ -0,0 +1,882 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
+<title>NEON DRIFTER</title>
+<style>
+  :root {
+    --bg: #0a0e14;
+    --neon: #ff2fd0;
+    --cyan: #22e7ff;
+    --amber: #ffd23f;
+    --edge: #7a3cff;
+  }
+  * { box-sizing: border-box; margin: 0; padding: 0; }
+  html, body {
+    width: 100%; height: 100%;
+    background: var(--bg);
+    overflow: hidden;
+    touch-action: none;
+    -webkit-user-select: none;
+    user-select: none;
+    -webkit-tap-highlight-color: transparent;
+    font-family: "Segoe UI", Helvetica, Arial, sans-serif;
+  }
+  #wrap {
+    position: fixed;
+    inset: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background: radial-gradient(ellipse at 50% 120%, #16203a 0%, #0a0e14 60%, #05070c 100%);
+  }
+  canvas { display: block; touch-action: none; }
+
+  /* Touch controls */
+  .touch {
+    position: fixed;
+    bottom: 0;
+    width: 40%;
+    height: 45%;
+    max-height: 320px;
+    z-index: 20;
+    display: none;
+    align-items: flex-end;
+    justify-content: center;
+    padding-bottom: 22px;
+    -webkit-user-select: none;
+    user-select: none;
+  }
+  .touch.left { left: 0; }
+  .touch.right { right: 0; }
+  .touch .btn {
+    width: 92px; height: 92px;
+    border-radius: 50%;
+    border: 2px solid rgba(34,231,255,0.55);
+    background: rgba(34,231,255,0.08);
+    color: #cffcff;
+    font-size: 40px;
+    line-height: 88px;
+    text-align: center;
+    box-shadow: 0 0 18px rgba(34,231,255,0.35), inset 0 0 14px rgba(34,231,255,0.15);
+    backdrop-filter: blur(2px);
+  }
+  .touch.active .btn {
+    background: rgba(255,47,208,0.22);
+    border-color: rgba(255,47,208,0.8);
+    box-shadow: 0 0 24px rgba(255,47,208,0.6), inset 0 0 16px rgba(255,47,208,0.25);
+  }
+  @media (pointer: coarse) {
+    .touch { display: flex; }
+  }
+</style>
+</head>
+<body>
+  <div id="wrap">
+    <canvas id="game"></canvas>
+  </div>
+  <div class="touch left" id="touchLeft"><div class="btn">&#8592;</div></div>
+  <div class="touch right" id="touchRight"><div class="btn">&#8594;</div></div>
+
+<script>
+(function () {
+  "use strict";
+
+  function boot() {
+    var canvas = document.getElementById("game");
+    if (!canvas) return;
+    var ctx = canvas.getContext("2d");
+    if (!ctx) return;
+
+    var BEST_KEY = "abrams-racer-best";
+
+    // ---- logical dimensions (portrait road) ----
+    var W = 480, H = 800;   // logical
+    var DPR = 1;
+
+    function fitCanvas() {
+      var vw = Math.max(1, window.innerWidth || document.documentElement.clientWidth || 480);
+      var vh = Math.max(1, window.innerHeight || document.documentElement.clientHeight || 800);
+      var targetAR = W / H;
+      var winAR = vw / vh;
+      var cssW, cssH;
+      if (winAR > targetAR) { cssH = vh; cssW = vh * targetAR; }
+      else { cssW = vw; cssH = vw / targetAR; }
+      DPR = Math.min(window.devicePixelRatio || 1, 2);
+      canvas.style.width = cssW + "px";
+      canvas.style.height = cssH + "px";
+      canvas.width = Math.round(W * DPR);
+      canvas.height = Math.round(H * DPR);
+      ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+    }
+    window.addEventListener("resize", fitCanvas, { passive: true });
+    window.addEventListener("orientationchange", fitCanvas, { passive: true });
+    fitCanvas();
+
+    // ---- road geometry ----
+    var LANES = 4;
+    var ROAD_MARGIN = 56;              // side margin to road edge
+    var roadLeft = ROAD_MARGIN;
+    var roadRight = W - ROAD_MARGIN;
+    var roadW = roadRight - roadLeft;
+    var laneW = roadW / LANES;
+
+    function laneCenter(i) { return roadLeft + laneW * (i + 0.5); }
+
+    // ---- game state ----
+    var STATE_MENU = 0, STATE_PLAY = 1, STATE_OVER = 2;
+    var state = STATE_MENU;
+
+    var best = 0;
+    try {
+      var stored = localStorage.getItem(BEST_KEY);
+      if (stored != null) { var b = parseFloat(stored); if (isFinite(b)) best = b; }
+    } catch (e) {}
+
+    var player, traffic, pickups, particles;
+    var dashOffset, scroll, distance, score, speed, baseSpeed, elapsed, spawnTimer, pickTimer;
+    var boost, shakeMag, newBest;
+
+    function resetGame() {
+      player = {
+        x: laneCenter(1),
+        y: H - 150,
+        w: 46, h: 84,
+        vx: 0,
+        color: "#22e7ff"
+      };
+      traffic = [];
+      pickups = [];
+      particles = [];
+      dashOffset = 0;
+      scroll = 0;
+      distance = 0;
+      score = 0;
+      baseSpeed = 260;      // px/sec world scroll
+      speed = baseSpeed;
+      elapsed = 0;
+      spawnTimer = 0.6;
+      pickTimer = 3.0;
+      boost = 0;
+      shakeMag = 0;
+      newBest = false;
+    }
+    resetGame();
+
+    // ---- input ----
+    var keys = { left: false, right: false, up: false, down: false };
+    var touchL = false, touchR = false;
+
+    function onKeyDown(e) {
+      var k = e.key;
+      var handled = true;
+      if (k === "ArrowLeft" || k === "a" || k === "A") keys.left = true;
+      else if (k === "ArrowRight" || k === "d" || k === "D") keys.right = true;
+      else if (k === "ArrowUp" || k === "w" || k === "W") keys.up = true;
+      else if (k === "ArrowDown" || k === "s" || k === "S") keys.down = true;
+      else if (k === " " || k === "Enter") {
+        if (state === STATE_MENU) startPlay();
+        else if (state === STATE_OVER) { resetGame(); startPlay(); }
+      } else handled = false;
+
+      if (handled) {
+        // resume/init audio on first gesture
+        ensureAudio();
+        if (state === STATE_MENU && (k === "ArrowLeft" || k === "ArrowRight" || k === "a" || k === "A" || k === "d" || k === "D")) {
+          startPlay();
+        }
+        e.preventDefault();
+      }
+    }
+    function onKeyUp(e) {
+      var k = e.key;
+      if (k === "ArrowLeft" || k === "a" || k === "A") keys.left = false;
+      else if (k === "ArrowRight" || k === "d" || k === "D") keys.right = false;
+      else if (k === "ArrowUp" || k === "w" || k === "W") keys.up = false;
+      else if (k === "ArrowDown" || k === "s" || k === "S") keys.down = false;
+    }
+    window.addEventListener("keydown", onKeyDown, { passive: false });
+    window.addEventListener("keyup", onKeyUp, { passive: false });
+
+    // touch buttons
+    function bindTouch(el, setter) {
+      if (!el) return;
+      function down(e) {
+        e.preventDefault();
+        ensureAudio();
+        el.classList.add("active");
+        setter(true);
+        if (state === STATE_MENU) startPlay();
+        else if (state === STATE_OVER) { resetGame(); startPlay(); }
+      }
+      function up(e) {
+        e.preventDefault();
+        el.classList.remove("active");
+        setter(false);
+      }
+      el.addEventListener("touchstart", down, { passive: false });
+      el.addEventListener("touchend", up, { passive: false });
+      el.addEventListener("touchcancel", up, { passive: false });
+      el.addEventListener("mousedown", down);
+      window.addEventListener("mouseup", up);
+    }
+    bindTouch(document.getElementById("touchLeft"), function (v) { touchL = v; });
+    bindTouch(document.getElementById("touchRight"), function (v) { touchR = v; });
+
+    // tap canvas to start/restart
+    canvas.addEventListener("pointerdown", function (e) {
+      ensureAudio();
+      if (state === STATE_MENU) { e.preventDefault(); startPlay(); }
+      else if (state === STATE_OVER) { e.preventDefault(); resetGame(); startPlay(); }
+    });
+
+    // prevent scroll gestures
+    document.addEventListener("touchmove", function (e) { e.preventDefault(); }, { passive: false });
+
+    // ---- audio (lazy) ----
+    var actx = null, engineOsc = null, engineGain = null, engineFilter = null;
+    function ensureAudio() {
+      try {
+        if (!actx) {
+          var AC = window.AudioContext || window.webkitAudioContext;
+          if (!AC) return;
+          actx = new AC();
+          engineGain = actx.createGain();
+          engineGain.gain.value = 0.0;
+          engineFilter = actx.createBiquadFilter();
+          engineFilter.type = "lowpass";
+          engineFilter.frequency.value = 700;
+          engineOsc = actx.createOscillator();
+          engineOsc.type = "sawtooth";
+          engineOsc.frequency.value = 70;
+          engineOsc.connect(engineFilter);
+          engineFilter.connect(engineGain);
+          engineGain.connect(actx.destination);
+          engineOsc.start();
+        }
+        if (actx.state === "suspended") actx.resume();
+      } catch (e) { actx = null; }
+    }
+    function blip(freq, dur, type, vol) {
+      if (!actx) return;
+      try {
+        var o = actx.createOscillator();
+        var g = actx.createGain();
+        o.type = type || "square";
+        o.frequency.value = freq;
+        g.gain.value = 0.0001;
+        o.connect(g); g.connect(actx.destination);
+        var t = actx.currentTime;
+        g.gain.setValueAtTime(0.0001, t);
+        g.gain.exponentialRampToValueAtTime(vol || 0.15, t + 0.01);
+        g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
+        o.start(t);
+        o.stop(t + dur + 0.02);
+      } catch (e) {}
+    }
+    function crashSound() {
+      if (!actx) return;
+      try {
+        var o = actx.createOscillator();
+        var g = actx.createGain();
+        o.type = "sawtooth";
+        o.frequency.setValueAtTime(220, actx.currentTime);
+        o.frequency.exponentialRampToValueAtTime(40, actx.currentTime + 0.45);
+        g.gain.setValueAtTime(0.3, actx.currentTime);
+        g.gain.exponentialRampToValueAtTime(0.0001, actx.currentTime + 0.5);
+        o.connect(g); g.connect(actx.destination);
+        o.start();
+        o.stop(actx.currentTime + 0.55);
+      } catch (e) {}
+    }
+    function updateEngine() {
+      if (!actx || !engineGain || !engineOsc) return;
+      try {
+        var target = state === STATE_PLAY ? 0.05 : 0.0;
+        engineGain.gain.setTargetAtTime(target, actx.currentTime, 0.1);
+        var f = 55 + (speed - baseSpeed) * 0.06 + (boost > 0 ? 40 : 0);
+        engineOsc.frequency.setTargetAtTime(f, actx.currentTime, 0.08);
+        engineFilter.frequency.setTargetAtTime(600 + (speed - 200) * 1.2, actx.currentTime, 0.1);
+      } catch (e) {}
+    }
+
+    function startPlay() {
+      if (state === STATE_PLAY) return;
+      state = STATE_PLAY;
+      ensureAudio();
+      blip(660, 0.08, "square", 0.12);
+    }
+
+    // ---- spawning ----
+    var TRAFFIC_COLORS = ["#ff2fd0", "#ffd23f", "#9d5bff", "#ff5a3c", "#3cff8a"];
+
+    function spawnTraffic() {
+      var lane = Math.floor(Math.random() * LANES);
+      var w = 46, h = 84;
+      // occasionally a wider slow truck
+      if (Math.random() < 0.18) { w = 54; h = 110; }
+      var carSpeed = 60 + Math.random() * 120; // slower than world; downward relative
+      traffic.push({
+        lane: lane,
+        x: laneCenter(lane),
+        y: -h - 20,
+        w: w, h: h,
+        rel: carSpeed,
+        color: TRAFFIC_COLORS[(Math.random() * TRAFFIC_COLORS.length) | 0]
+      });
+    }
+
+    function spawnPickup() {
+      var lane = Math.floor(Math.random() * LANES);
+      var type = Math.random() < 0.4 ? "boost" : "coin";
+      pickups.push({
+        x: laneCenter(lane),
+        y: -30,
+        r: 14,
+        type: type,
+        t: 0
+      });
+    }
+
+    function laneOccupiedNear(lane, y, minGap) {
+      for (var i = 0; i < traffic.length; i++) {
+        var t = traffic[i];
+        if (t.lane === lane && Math.abs(t.y - y) < minGap) return true;
+      }
+      return false;
+    }
+
+    // ---- particles ----
+    function addParticles(x, y, color, n, spread) {
+      for (var i = 0; i < n; i++) {
+        particles.push({
+          x: x, y: y,
+          vx: (Math.random() - 0.5) * spread,
+          vy: (Math.random() - 0.5) * spread - 30,
+          life: 0.4 + Math.random() * 0.5,
+          age: 0,
+          color: color,
+          size: 2 + Math.random() * 3
+        });
+      }
+    }
+
+    // ---- collision ----
+    function rectsOverlap(ax, ay, aw, ah, bx, by, bw, bh) {
+      return Math.abs(ax - bx) * 2 < (aw + bw) && Math.abs(ay - by) * 2 < (ah + bh);
+    }
+
+    // ---- update ----
+    function update(dt) {
+      if (state === STATE_PLAY) {
+        elapsed += dt;
+        // speed ramps over time
+        baseSpeed = 260 + elapsed * 9;
+        if (baseSpeed > 720) baseSpeed = 720;
+        var boostFactor = boost > 0 ? 1.55 : 1;
+        // throttle (up/down) small modifier
+        var throttle = 1;
+        if (keys.up) throttle = 1.18;
+        else if (keys.down) throttle = 0.72;
+        speed = baseSpeed * boostFactor * throttle;
+
+        if (boost > 0) boost -= dt;
+
+        // steering
+        var steerLeft = keys.left || touchL;
+        var steerRight = keys.right || touchR;
+        var accel = 900;
+        if (steerLeft && !steerRight) player.vx -= accel * dt;
+        else if (steerRight && !steerLeft) player.vx += accel * dt;
+        else player.vx *= Math.pow(0.001, dt); // strong damping when no input
+        // clamp lateral speed
+        var maxVx = 420;
+        if (player.vx > maxVx) player.vx = maxVx;
+        if (player.vx < -maxVx) player.vx = -maxVx;
+        player.x += player.vx * dt;
+        // road clamp
+        var half = player.w / 2 + 4;
+        if (player.x < roadLeft + half) { player.x = roadLeft + half; player.vx = 0; }
+        if (player.x > roadRight - half) { player.x = roadRight - half; player.vx = 0; }
+
+        // scroll + distance
+        scroll += speed * dt;
+        dashOffset = (dashOffset + speed * dt) % 80;
+        distance += speed * dt * 0.02; // meters-ish
+        score += speed * dt * 0.05;
+
+        // spawn traffic
+        spawnTimer -= dt;
+        var spawnEvery = Math.max(0.35, 1.1 - elapsed * 0.01);
+        if (spawnTimer <= 0) {
+          spawnTimer = spawnEvery * (0.6 + Math.random() * 0.8);
+          // try a lane that isn't crowded near top
+          var tries = 3;
+          while (tries-- > 0) {
+            var lane = Math.floor(Math.random() * LANES);
+            if (!laneOccupiedNear(lane, -60, 160)) {
+              var w = 46, h = 84;
+              if (Math.random() < 0.18) { w = 54; h = 110; }
+              traffic.push({
+                lane: lane, x: laneCenter(lane), y: -h - 20,
+                w: w, h: h, rel: 60 + Math.random() * 120,
+                color: TRAFFIC_COLORS[(Math.random() * TRAFFIC_COLORS.length) | 0]
+              });
+              break;
+            }
+          }
+        }
+
+        // spawn pickups
+        pickTimer -= dt;
+        if (pickTimer <= 0) {
+          pickTimer = 3.5 + Math.random() * 3.5;
+          var plane = Math.floor(Math.random() * LANES);
+          if (!laneOccupiedNear(plane, -40, 120)) {
+            pickups.push({
+              x: laneCenter(plane), y: -30, r: 14,
+              type: Math.random() < 0.4 ? "boost" : "coin", t: 0
+            });
+          }
+        }
+
+        // move traffic (world scrolls down; traffic moves down toward player)
+        for (var i = traffic.length - 1; i >= 0; i--) {
+          var t = traffic[i];
+          t.y += (speed - t.rel) * dt;   // relative to player
+          // engine exhaust trail
+          if (Math.random() < 0.3) addParticles(t.x, t.y - t.h / 2, "rgba(120,140,180,0.4)", 1, 20);
+          if (t.y - t.h > H + 40) { traffic.splice(i, 1); continue; }
+          // collision
+          if (rectsOverlap(player.x, player.y, player.w - 8, player.h - 10, t.x, t.y, t.w - 8, t.h - 10)) {
+            gameOver();
+            return;
+          }
+        }
+
+        // move pickups
+        for (var j = pickups.length - 1; j >= 0; j--) {
+          var p = pickups[j];
+          p.y += speed * dt;
+          p.t += dt;
+          if (p.y - p.r > H + 40) { pickups.splice(j, 1); continue; }
+          var dx = p.x - player.x, dy = p.y - player.y;
+          if (Math.abs(dx) < (player.w / 2 + p.r) && Math.abs(dy) < (player.h / 2 + p.r)) {
+            if (p.type === "boost") {
+              boost = 2.2;
+              score += 50;
+              addParticles(p.x, p.y, "#22e7ff", 18, 220);
+              blip(880, 0.14, "sawtooth", 0.16);
+              blip(1320, 0.14, "sawtooth", 0.1);
+            } else {
+              score += 100;
+              addParticles(p.x, p.y, "#ffd23f", 14, 180);
+              blip(1046, 0.09, "square", 0.14);
+            }
+            pickups.splice(j, 1);
+          }
+        }
+
+        // player exhaust / speed particles
+        if (Math.random() < (boost > 0 ? 0.9 : 0.4)) {
+          addParticles(player.x + (Math.random() - 0.5) * 18, player.y + player.h / 2,
+            boost > 0 ? "#22e7ff" : "rgba(255,120,220,0.6)", 1, 40);
+        }
+      }
+
+      // particles always update
+      for (var k = particles.length - 1; k >= 0; k--) {
+        var pt = particles[k];
+        pt.age += dt;
+        if (pt.age >= pt.life) { particles.splice(k, 1); continue; }
+        pt.x += pt.vx * dt;
+        pt.y += pt.vy * dt;
+        pt.vy += 60 * dt;
+      }
+
+      // shake decay
+      if (shakeMag > 0) { shakeMag -= dt * 40; if (shakeMag < 0) shakeMag = 0; }
+
+      updateEngine();
+    }
+
+    function gameOver() {
+      state = STATE_OVER;
+      shakeMag = 18;
+      addParticles(player.x, player.y, "#ff5a3c", 40, 400);
+      addParticles(player.x, player.y, "#ffd23f", 30, 320);
+      crashSound();
+      if (distance > best) {
+        best = distance;
+        newBest = true;
+        try { localStorage.setItem(BEST_KEY, String(Math.floor(best))); } catch (e) {}
+      }
+    }
+
+    // ---- rendering ----
+    function drawCar(x, y, w, h, color, isPlayer) {
+      ctx.save();
+      ctx.translate(x, y);
+      // glow
+      ctx.shadowColor = color;
+      ctx.shadowBlur = isPlayer ? 22 : 14;
+      // body
+      ctx.fillStyle = color;
+      roundRect(-w / 2, -h / 2, w, h, 10);
+      ctx.fill();
+      ctx.shadowBlur = 0;
+      // cockpit / windows
+      ctx.fillStyle = "rgba(6,10,20,0.85)";
+      roundRect(-w / 2 + 7, -h / 2 + 12, w - 14, h * 0.28, 6);
+      ctx.fill();
+      roundRect(-w / 2 + 7, h / 2 - h * 0.32, w - 14, h * 0.20, 6);
+      ctx.fill();
+      // center stripe
+      ctx.fillStyle = "rgba(255,255,255,0.18)";
+      ctx.fillRect(-2, -h / 2 + 6, 4, h - 12);
+      // headlights/taillights
+      if (isPlayer) {
+        ctx.fillStyle = "#fff6c8";
+        ctx.fillRect(-w / 2 + 5, -h / 2 + 2, 8, 5);
+        ctx.fillRect(w / 2 - 13, -h / 2 + 2, 8, 5);
+      } else {
+        ctx.fillStyle = "#ff3b3b";
+        ctx.shadowColor = "#ff3b3b"; ctx.shadowBlur = 8;
+        ctx.fillRect(-w / 2 + 5, h / 2 - 7, 8, 5);
+        ctx.fillRect(w / 2 - 13, h / 2 - 7, 8, 5);
+        ctx.shadowBlur = 0;
+      }
+      ctx.restore();
+    }
+
+    function roundRect(x, y, w, h, r) {
+      if (r > w / 2) r = w / 2;
+      if (r > h / 2) r = h / 2;
+      ctx.beginPath();
+      ctx.moveTo(x + r, y);
+      ctx.arcTo(x + w, y, x + w, y + h, r);
+      ctx.arcTo(x + w, y + h, x, y + h, r);
+      ctx.arcTo(x, y + h, x, y, r);
+      ctx.arcTo(x, y, x + w, y, r);
+      ctx.closePath();
+    }
+
+    function draw() {
+      ctx.save();
+      // screen shake
+      if (shakeMag > 0) {
+        ctx.translate((Math.random() - 0.5) * shakeMag, (Math.random() - 0.5) * shakeMag);
+      }
+
+      // background
+      ctx.fillStyle = "#05070c";
+      ctx.fillRect(-40, -40, W + 80, H + 80);
+
+      // side "grass"/gradient synth glow bands
+      var g = ctx.createLinearGradient(0, 0, 0, H);
+      g.addColorStop(0, "#0c1226");
+      g.addColorStop(1, "#141a33");
+      ctx.fillStyle = g;
+      ctx.fillRect(-40, -40, W + 80, H + 80);
+
+      // road surface
+      var rg = ctx.createLinearGradient(0, 0, 0, H);
+      rg.addColorStop(0, "#12141f");
+      rg.addColorStop(1, "#1a1d2e");
+      ctx.fillStyle = rg;
+      ctx.fillRect(roadLeft, -40, roadW, H + 80);
+
+      // glowing road edges
+      drawGlowLine(roadLeft, 0, roadLeft, H, "#ff2fd0", 4);
+      drawGlowLine(roadRight, 0, roadRight, H, "#22e7ff", 4);
+
+      // moving dashed lane markers
+      ctx.save();
+      ctx.lineWidth = 5;
+      ctx.setLineDash([32, 48]);
+      ctx.lineDashOffset = -dashOffset;
+      ctx.strokeStyle = "rgba(180,200,255,0.55)";
+      ctx.shadowColor = "rgba(120,150,255,0.5)";
+      ctx.shadowBlur = 8;
+      for (var li = 1; li < LANES; li++) {
+        var lx = roadLeft + laneW * li;
+        ctx.beginPath();
+        ctx.moveTo(lx, -40);
+        ctx.lineTo(lx, H + 40);
+        ctx.stroke();
+      }
+      ctx.restore();
+
+      // horizon glow lines (perspective illusion) faint moving cross-lines
+      ctx.save();
+      ctx.strokeStyle = "rgba(122,60,255,0.10)";
+      ctx.lineWidth = 2;
+      for (var hy = 0; hy < H + 80; hy += 80) {
+        var yy = (hy - (dashOffset % 80));
+        ctx.beginPath();
+        ctx.moveTo(roadLeft, yy);
+        ctx.lineTo(roadRight, yy);
+        ctx.stroke();
+      }
+      ctx.restore();
+
+      // pickups
+      for (var i = 0; i < pickups.length; i++) {
+        var p = pickups[i];
+        var pulse = 1 + Math.sin(p.t * 8) * 0.12;
+        ctx.save();
+        ctx.translate(p.x, p.y);
+        ctx.scale(pulse, pulse);
+        if (p.type === "boost") {
+          ctx.shadowColor = "#22e7ff"; ctx.shadowBlur = 18;
+          ctx.fillStyle = "#22e7ff";
+          // lightning bolt
+          ctx.beginPath();
+          ctx.moveTo(-4, -14); ctx.lineTo(6, -2); ctx.lineTo(0, -2);
+          ctx.lineTo(4, 14); ctx.lineTo(-6, 0); ctx.lineTo(0, 0);
+          ctx.closePath();
+          ctx.fill();
+        } else {
+          ctx.shadowColor = "#ffd23f"; ctx.shadowBlur = 16;
+          ctx.fillStyle = "#ffd23f";
+          ctx.beginPath();
+          ctx.arc(0, 0, 12, 0, Math.PI * 2);
+          ctx.fill();
+          ctx.fillStyle = "rgba(120,80,0,0.55)";
+          ctx.font = "bold 15px sans-serif";
+          ctx.textAlign = "center";
+          ctx.textBaseline = "middle";
+          ctx.fillText("$", 0, 1);
+        }
+        ctx.restore();
+      }
+
+      // traffic
+      for (var t = 0; t < traffic.length; t++) {
+        var c = traffic[t];
+        drawCar(c.x, c.y, c.w, c.h, c.color, false);
+      }
+
+      // particles
+      for (var pp = 0; pp < particles.length; pp++) {
+        var pt = particles[pp];
+        var a = 1 - pt.age / pt.life;
+        ctx.globalAlpha = a < 0 ? 0 : a;
+        ctx.fillStyle = pt.color;
+        ctx.fillRect(pt.x - pt.size / 2, pt.y - pt.size / 2, pt.size, pt.size);
+      }
+      ctx.globalAlpha = 1;
+
+      // player
+      if (state !== STATE_OVER || (Math.floor(elapsed * 10) % 2 === 0)) {
+        // boost aura
+        if (boost > 0) {
+          ctx.save();
+          ctx.globalAlpha = 0.5 + Math.sin(elapsed * 30) * 0.2;
+          ctx.shadowColor = "#22e7ff"; ctx.shadowBlur = 30;
+          ctx.fillStyle = "rgba(34,231,255,0.15)";
+          roundRect(player.x - player.w / 2 - 6, player.y - player.h / 2 - 6, player.w + 12, player.h + 12, 12);
+          ctx.fill();
+          ctx.restore();
+        }
+        drawCar(player.x, player.y, player.w, player.h, player.color, true);
+      }
+
+      ctx.restore(); // shake
+
+      // HUD
+      drawHUD();
+
+      // overlays
+      if (state === STATE_MENU) drawMenu();
+      else if (state === STATE_OVER) drawGameOver();
+    }
+
+    function drawGlowLine(x1, y1, x2, y2, color, width) {
+      ctx.save();
+      ctx.strokeStyle = color;
+      ctx.lineWidth = width;
+      ctx.shadowColor = color;
+      ctx.shadowBlur = 16;
+      ctx.beginPath();
+      ctx.moveTo(x1, y1);
+      ctx.lineTo(x2, y2);
+      ctx.stroke();
+      ctx.restore();
+    }
+
+    function drawHUD() {
+      ctx.save();
+      ctx.textBaseline = "top";
+      // distance (big)
+      ctx.textAlign = "left";
+      ctx.fillStyle = "rgba(180,220,255,0.55)";
+      ctx.font = "600 13px 'Segoe UI', sans-serif";
+      ctx.fillText("DISTANCE", 18, 18);
+      ctx.fillStyle = "#e8f6ff";
+      ctx.shadowColor = "#22e7ff"; ctx.shadowBlur = 12;
+      ctx.font = "800 30px 'Segoe UI', sans-serif";
+      ctx.fillText(Math.floor(distance) + " m", 18, 32);
+      ctx.shadowBlur = 0;
+
+      // score (right)
+      ctx.textAlign = "right";
+      ctx.fillStyle = "rgba(255,180,240,0.55)";
+      ctx.font = "600 13px 'Segoe UI', sans-serif";
+      ctx.fillText("SCORE", W - 18, 18);
+      ctx.fillStyle = "#ffe3f8";
+      ctx.shadowColor = "#ff2fd0"; ctx.shadowBlur = 12;
+      ctx.font = "800 30px 'Segoe UI', sans-serif";
+      ctx.fillText(String(Math.floor(score)), W - 18, 32);
+      ctx.shadowBlur = 0;
+
+      // best (top center)
+      ctx.textAlign = "center";
+      ctx.fillStyle = "rgba(255,210,63,0.75)";
+      ctx.font = "700 13px 'Segoe UI', sans-serif";
+      ctx.fillText("BEST  " + Math.floor(best) + " m", W / 2, 22);
+
+      // speedometer bar
+      var spNorm = Math.min(1, (speed - 200) / 560);
+      var barW = 160, barH = 8, barX = W / 2 - barW / 2, barY = 44;
+      ctx.fillStyle = "rgba(255,255,255,0.08)";
+      roundRect(barX, barY, barW, barH, 4); ctx.fill();
+      var sg = ctx.createLinearGradient(barX, 0, barX + barW, 0);
+      sg.addColorStop(0, "#22e7ff");
+      sg.addColorStop(0.6, "#ff2fd0");
+      sg.addColorStop(1, "#ff5a3c");
+      ctx.fillStyle = sg;
+      roundRect(barX, barY, Math.max(6, barW * spNorm), barH, 4); ctx.fill();
+
+      if (boost > 0) {
+        ctx.textAlign = "center";
+        ctx.fillStyle = "#22e7ff";
+        ctx.shadowColor = "#22e7ff"; ctx.shadowBlur = 14;
+        ctx.font = "800 16px 'Segoe UI', sans-serif";
+        ctx.fillText("⚡ BOOST", W / 2, 58);
+        ctx.shadowBlur = 0;
+      }
+      ctx.restore();
+    }
+
+    function drawTitle(cx, cy) {
+      ctx.save();
+      ctx.textAlign = "center";
+      ctx.textBaseline = "middle";
+      // "NEON DRIFTER" uppercase, letter-spaced
+      var title = "N E O N   D R I F T E R";
+      ctx.font = "800 34px 'Segoe UI', sans-serif";
+      ctx.fillStyle = "#22e7ff";
+      ctx.shadowColor = "#ff2fd0"; ctx.shadowBlur = 24;
+      ctx.fillText(title, cx, cy);
+      ctx.shadowColor = "#22e7ff"; ctx.shadowBlur = 18;
+      ctx.fillStyle = "#ff2fd0";
+      ctx.fillText(title, cx + 1.5, cy + 1.5);
+      ctx.restore();
+    }
+
+    function overlayPanel() {
+      ctx.save();
+      ctx.fillStyle = "rgba(5,7,12,0.72)";
+      ctx.fillRect(0, 0, W, H);
+      ctx.restore();
+    }
+
+    function drawMenu() {
+      overlayPanel();
+      drawTitle(W / 2, H * 0.32);
+      ctx.save();
+      ctx.textAlign = "center";
+      ctx.textBaseline = "middle";
+      ctx.fillStyle = "rgba(200,225,255,0.85)";
+      ctx.font = "600 17px 'Segoe UI', sans-serif";
+      ctx.fillText("Weave through neon traffic. Don't crash.", W / 2, H * 0.44);
+
+      var pulse = 0.6 + Math.sin(elapsed * 4) * 0.4;
+      ctx.globalAlpha = pulse;
+      ctx.fillStyle = "#ffd23f";
+      ctx.shadowColor = "#ffd23f"; ctx.shadowBlur = 14;
+      ctx.font = "800 22px 'Segoe UI', sans-serif";
+      ctx.fillText("TAP / PRESS  ← →  TO START", W / 2, H * 0.55);
+      ctx.globalAlpha = 1;
+      ctx.shadowBlur = 0;
+
+      ctx.fillStyle = "rgba(160,190,230,0.6)";
+      ctx.font = "500 14px 'Segoe UI', sans-serif";
+      ctx.fillText("Arrows / A-D steer  •  Up/Down throttle", W / 2, H * 0.63);
+      ctx.fillText("⚡ = boost   $ = coin", W / 2, H * 0.67);
+      ctx.fillText("BEST  " + Math.floor(best) + " m", W / 2, H * 0.73);
+      ctx.restore();
+    }
+
+    function drawGameOver() {
+      overlayPanel();
+      ctx.save();
+      ctx.textAlign = "center";
+      ctx.textBaseline = "middle";
+
+      ctx.fillStyle = "#ff5a3c";
+      ctx.shadowColor = "#ff2fd0"; ctx.shadowBlur = 22;
+      ctx.font = "800 44px 'Segoe UI', sans-serif";
+      ctx.fillText("CRASHED", W / 2, H * 0.30);
+      ctx.shadowBlur = 0;
+
+      if (newBest) {
+        ctx.fillStyle = "#ffd23f";
+        ctx.shadowColor = "#ffd23f"; ctx.shadowBlur = 16;
+        ctx.font = "800 22px 'Segoe UI', sans-serif";
+        ctx.fillText("★ NEW BEST ★", W / 2, H * 0.40);
+        ctx.shadowBlur = 0;
+      }
+
+      ctx.fillStyle = "#e8f6ff";
+      ctx.font = "700 26px 'Segoe UI', sans-serif";
+      ctx.fillText(Math.floor(distance) + " m", W / 2, H * 0.47);
+      ctx.fillStyle = "rgba(200,225,255,0.7)";
+      ctx.font = "600 16px 'Segoe UI', sans-serif";
+      ctx.fillText("SCORE  " + Math.floor(score), W / 2, H * 0.52);
+      ctx.fillText("BEST  " + Math.floor(best) + " m", W / 2, H * 0.56);
+
+      var pulse = 0.6 + Math.sin(elapsed * 5) * 0.4;
+      ctx.globalAlpha = pulse;
+      ctx.fillStyle = "#22e7ff";
+      ctx.shadowColor = "#22e7ff"; ctx.shadowBlur = 14;
+      ctx.font = "800 20px 'Segoe UI', sans-serif";
+      ctx.fillText("TAP / PRESS SPACE TO RACE AGAIN", W / 2, H * 0.66);
+      ctx.globalAlpha = 1;
+      ctx.restore();
+    }
+
+    // ---- main loop ----
+    var lastT = 0;
+    function frame(ts) {
+      if (!lastT) lastT = ts;
+      var dt = (ts - lastT) / 1000;
+      lastT = ts;
+      if (dt > 0.05) dt = 0.05; // clamp big gaps
+      if (dt < 0) dt = 0;
+
+      // on game over let elapsed keep advancing for pulsing text
+      if (state === STATE_OVER || state === STATE_MENU) elapsed += dt;
+
+      try {
+        update(dt);
+        draw();
+      } catch (e) {
+        // never throw out of RAF
+      }
+      requestAnimationFrame(frame);
+    }
+    requestAnimationFrame(frame);
+  }
+
+  if (document.readyState === "loading") {
+    document.addEventListener("DOMContentLoaded", boot);
+  } else {
+    boot();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/rope-physics/VerletRope.aa b/games/rope-physics/VerletRope.aa
new file mode 100644
index 0000000..265a9c3
--- /dev/null
+++ b/games/rope-physics/VerletRope.aa
@@ -0,0 +1,350 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Verlet Rope · Physics Toy</title>
+<style>
+  :root{
+    --bg0:#0b0f1a; --bg1:#151b2e; --ink:#e8ecf7; --muted:#8a93ad;
+    --accent:#5ad1ff; --accent2:#ff5a8a; --line:rgba(255,255,255,.08);
+  }
+  *{box-sizing:border-box}
+  html,body{margin:0;height:100%;overflow:hidden;background:var(--bg0);color:var(--ink);
+    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
+    -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
+  #stage{position:fixed;inset:0}
+  canvas{display:block;width:100%;height:100%;touch-action:none;cursor:grab}
+  canvas.cut{cursor:crosshair}
+  canvas:active{cursor:grabbing}
+
+  .hud{position:fixed;top:16px;left:16px;right:16px;display:flex;gap:14px;
+    align-items:flex-start;justify-content:space-between;pointer-events:none;flex-wrap:wrap}
+  .panel{pointer-events:auto;background:linear-gradient(180deg,rgba(21,27,46,.86),rgba(11,15,26,.86));
+    backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
+    border:1px solid var(--line);border-radius:14px;padding:12px 14px;
+    box-shadow:0 10px 40px rgba(0,0,0,.45)}
+  .title{font-weight:700;letter-spacing:.3px;font-size:15px;display:flex;align-items:center;gap:9px}
+  .dot{width:9px;height:9px;border-radius:50%;background:var(--accent);
+    box-shadow:0 0 12px var(--accent)}
+  .hint{color:var(--muted);font-size:12px;margin-top:5px;line-height:1.5;max-width:280px}
+  .controls{display:flex;gap:9px;flex-wrap:wrap;align-items:center}
+  button{font:inherit;font-size:13px;font-weight:600;color:var(--ink);cursor:pointer;
+    border:1px solid var(--line);background:rgba(255,255,255,.05);
+    padding:9px 14px;border-radius:10px;transition:.15s;display:inline-flex;align-items:center;gap:7px}
+  button:hover{background:rgba(255,255,255,.11);transform:translateY(-1px)}
+  button:active{transform:translateY(0)}
+  button.on{background:var(--accent2);border-color:transparent;color:#fff;
+    box-shadow:0 4px 18px rgba(255,90,138,.5)}
+  button.on .ic{filter:none}
+  .ic{font-size:15px;line-height:1}
+  .seg{display:flex;gap:6px;align-items:center;color:var(--muted);font-size:12px}
+  input[type=range]{-webkit-appearance:none;appearance:none;width:96px;height:4px;border-radius:4px;
+    background:rgba(255,255,255,.18);outline:none}
+  input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:15px;height:15px;border-radius:50%;
+    background:var(--accent);cursor:pointer;box-shadow:0 0 8px var(--accent)}
+  input[type=range]::-moz-range-thumb{width:15px;height:15px;border:none;border-radius:50%;
+    background:var(--accent);cursor:pointer}
+  .stats{position:fixed;bottom:14px;left:16px;color:var(--muted);font-size:11px;
+    font-variant-numeric:tabular-nums;letter-spacing:.4px;pointer-events:none}
+  kbd{background:rgba(255,255,255,.09);border:1px solid var(--line);border-bottom-width:2px;
+    border-radius:5px;padding:1px 6px;font-family:inherit;font-size:11px}
+</style>
+</head>
+<body>
+<div id="stage">
+  <canvas id="c"></canvas>
+</div>
+
+<div class="hud">
+  <div class="panel">
+    <div class="title"><span class="dot"></span>Verlet Rope Toy</div>
+    <div class="hint">Drag any point to swing the rope. Toggle <b>Cut</b> and slice across
+      strands to sever them. Everything is verlet-integrated cloth physics — no libraries.</div>
+  </div>
+  <div class="panel controls">
+    <button id="cutBtn" title="Toggle cut tool"><span class="ic">✂️</span><span>Cut</span></button>
+    <button id="resetBtn" title="Rebuild the rope"><span class="ic">↺</span><span>Reset</span></button>
+    <div class="seg"><span>Gravity</span><input id="grav" type="range" min="0" max="200" value="70"></div>
+    <div class="seg"><span>Wind</span><input id="wind" type="range" min="0" max="100" value="0"></div>
+  </div>
+</div>
+
+<div class="stats" id="stats"></div>
+
+<script>
+(() => {
+  "use strict";
+  const canvas = document.getElementById('c');
+  const ctx = canvas.getContext('2d');
+  const statsEl = document.getElementById('stats');
+  const cutBtn = document.getElementById('cutBtn');
+  const resetBtn = document.getElementById('resetBtn');
+  const gravSlider = document.getElementById('grav');
+  const windSlider = document.getElementById('wind');
+
+  let W = 0, H = 0, DPR = 1;
+  function resize(){
+    DPR = Math.min(window.devicePixelRatio || 1, 2);
+    W = window.innerWidth; H = window.innerHeight;
+    canvas.width = W * DPR; canvas.height = H * DPR;
+    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+  }
+  window.addEventListener('resize', () => { resize(); rebuild(); });
+
+  // ---------- Physics model ----------
+  // Points: {x,y,px,py,pinned}   Sticks: {a,b,len,live}
+  let points = [], sticks = [];
+  const FRICTION = 0.995;          // velocity damping
+  const BOUNCE = 0.9;
+  let gravity = 70, wind = 0;
+
+  function makePoint(x, y, pinned=false){
+    return { x, y, px:x, py:y, pinned, ox:x, oy:y };
+  }
+  function makeStick(a, b){
+    const p = points[a], q = points[b];
+    const len = Math.hypot(p.x - q.x, p.y - q.y);
+    return { a, b, len, live:true };
+  }
+
+  // Build a hanging rope grid: several ropes pinned at the top,
+  // cross-linked into a light cloth-like lattice.
+  function rebuild(){
+    points = []; sticks = [];
+    const cols = Math.max(5, Math.min(11, Math.round(W / 90)));
+    const rows = Math.max(9, Math.min(20, Math.round(H / 55)));
+    const spanW = Math.min(W * 0.72, cols * 70);
+    const spacing = spanW / (cols - 1);
+    const startX = (W - spanW) / 2;
+    const startY = H * 0.14;
+
+    const idx = (r, c) => r * cols + c;
+    for (let r = 0; r < rows; r++){
+      for (let c = 0; c < cols; c++){
+        const pinned = (r === 0) && (c % 2 === 0);
+        points.push(makePoint(startX + c * spacing, startY + r * spacing * 0.8, pinned));
+      }
+    }
+    for (let r = 0; r < rows; r++){
+      for (let c = 0; c < cols; c++){
+        if (c < cols - 1) sticks.push(makeStick(idx(r,c), idx(r,c+1)));   // horizontal
+        if (r < rows - 1) sticks.push(makeStick(idx(r,c), idx(r+1,c)));   // vertical
+      }
+    }
+  }
+
+  // ---------- Interaction ----------
+  let cutMode = false;
+  let dragPoint = null;
+  const mouse = { x:0, y:0, px:0, py:0, down:false };
+
+  function pointerPos(e){
+    const t = e.touches ? e.touches[0] : e;
+    return { x: t.clientX, y: t.clientY };
+  }
+  function nearestPoint(x, y, maxD){
+    let best = null, bd = maxD * maxD;
+    for (const p of points){
+      const dx = p.x - x, dy = p.y - y, d = dx*dx + dy*dy;
+      if (d < bd){ bd = d; best = p; }
+    }
+    return best;
+  }
+
+  function down(e){
+    e.preventDefault();
+    const {x,y} = pointerPos(e);
+    mouse.x = mouse.px = x; mouse.y = mouse.py = y; mouse.down = true;
+    if (!cutMode){
+      dragPoint = nearestPoint(x, y, 40);
+    }
+  }
+  function move(e){
+    const {x,y} = pointerPos(e);
+    mouse.px = mouse.x; mouse.py = mouse.y;
+    mouse.x = x; mouse.y = y;
+    if (cutMode && mouse.down) sliceAt(mouse.px, mouse.py, x, y);
+  }
+  function up(){ mouse.down = false; dragPoint = null; }
+
+  // Segment intersection for the cutting blade
+  function segHit(x1,y1,x2,y2, x3,y3,x4,y4){
+    const d = (x2-x1)*(y4-y3) - (y2-y1)*(x4-x3);
+    if (d === 0) return false;
+    const t = ((x3-x1)*(y4-y3) - (y3-y1)*(x4-x3)) / d;
+    const u = ((x3-x1)*(y2-y1) - (y3-y1)*(x2-x1)) / d;
+    return t >= 0 && t <= 1 && u >= 0 && u <= 1;
+  }
+  let cutFlashes = [];
+  function sliceAt(x1,y1,x2,y2){
+    for (const s of sticks){
+      if (!s.live) continue;
+      const p = points[s.a], q = points[s.b];
+      if (segHit(x1,y1,x2,y2, p.x,p.y, q.x,q.y)){
+        s.live = false;
+        cutFlashes.push({ x:(p.x+q.x)/2, y:(p.y+q.y)/2, life:1 });
+      }
+    }
+  }
+
+  canvas.addEventListener('mousedown', down);
+  window.addEventListener('mousemove', move);
+  window.addEventListener('mouseup', up);
+  canvas.addEventListener('touchstart', down, {passive:false});
+  canvas.addEventListener('touchmove', e => { e.preventDefault(); move(e); }, {passive:false});
+  window.addEventListener('touchend', up);
+
+  cutBtn.addEventListener('click', () => {
+    cutMode = !cutMode;
+    cutBtn.classList.toggle('on', cutMode);
+    canvas.classList.toggle('cut', cutMode);
+  });
+  resetBtn.addEventListener('click', rebuild);
+  gravSlider.addEventListener('input', () => gravity = +gravSlider.value);
+  windSlider.addEventListener('input', () => wind = +windSlider.value);
+
+  window.addEventListener('keydown', e => {
+    if (e.key === 'c' || e.key === 'C') cutBtn.click();
+    if (e.key === 'r' || e.key === 'R') rebuild();
+  });
+
+  // ---------- Simulation ----------
+  let t = 0;
+  function integrate(dt){
+    const g = gravity * dt;
+    const windForce = wind * 0.02 * Math.sin(t * 1.7) * dt;
+    for (const p of points){
+      if (p.pinned) continue;
+      let vx = (p.x - p.px) * FRICTION;
+      let vy = (p.y - p.py) * FRICTION;
+      p.px = p.x; p.py = p.y;
+      p.x += vx + windForce;
+      p.y += vy + g;
+    }
+  }
+  function constrain(){
+    // Drag: pull the grabbed point toward the mouse
+    if (dragPoint && mouse.down){
+      dragPoint.x = mouse.x; dragPoint.y = mouse.y;
+      dragPoint.px = mouse.x; dragPoint.py = mouse.y;
+    }
+    // Solve stick constraints several times for stiffness
+    const iterations = 12;
+    for (let k = 0; k < iterations; k++){
+      for (const s of sticks){
+        if (!s.live) continue;
+        const p = points[s.a], q = points[s.b];
+        let dx = q.x - p.x, dy = q.y - p.y;
+        let d = Math.hypot(dx, dy) || 0.0001;
+        const diff = (s.len - d) / d * 0.5;
+        const ox = dx * diff, oy = dy * diff;
+        if (!p.pinned){ p.x -= ox; p.y -= oy; }
+        if (!q.pinned){ q.x += ox; q.y += oy; }
+      }
+      // keep points on screen
+      for (const p of points){
+        if (p.pinned) continue;
+        if (p.x < 0){ p.x = 0; p.px = p.x + (p.x - p.px)*BOUNCE; }
+        else if (p.x > W){ p.x = W; p.px = p.x + (p.x - p.px)*BOUNCE; }
+        if (p.y > H){ p.y = H; p.py = p.y + (p.y - p.py)*BOUNCE; }
+      }
+    }
+  }
+
+  // ---------- Render ----------
+  function render(){
+    ctx.clearRect(0, 0, W, H);
+
+    // subtle vignette background
+    const bg = ctx.createRadialGradient(W/2, H*0.3, 50, W/2, H*0.5, Math.max(W,H)*0.8);
+    bg.addColorStop(0, 'rgba(30,40,66,.55)');
+    bg.addColorStop(1, 'rgba(6,9,17,0)');
+    ctx.fillStyle = bg;
+    ctx.fillRect(0,0,W,H);
+
+    // strands
+    ctx.lineCap = 'round';
+    ctx.lineWidth = 2.4;
+    let live = 0;
+    for (const s of sticks){
+      if (!s.live) continue;
+      live++;
+      const p = points[s.a], q = points[s.b];
+      const d = Math.hypot(q.x-p.x, q.y-p.y);
+      // color from tension (stretched = warmer)
+      const stretch = Math.min(1, Math.max(0, (d - s.len) / (s.len)));
+      const hue = 195 - stretch * 200;      // cyan -> pink when taut
+      const sat = 70 + stretch * 30;
+      ctx.strokeStyle = `hsla(${hue},${sat}%,${62 - stretch*10}%,0.9)`;
+      ctx.beginPath();
+      ctx.moveTo(p.x, p.y);
+      ctx.lineTo(q.x, q.y);
+      ctx.stroke();
+    }
+
+    // nodes
+    for (const p of points){
+      if (p.pinned){
+        ctx.fillStyle = '#ffd166';
+        ctx.beginPath(); ctx.arc(p.x, p.y, 4.5, 0, Math.PI*2); ctx.fill();
+        ctx.strokeStyle = 'rgba(255,209,102,.35)';
+        ctx.lineWidth = 1;
+        ctx.beginPath(); ctx.arc(p.x, p.y, 8, 0, Math.PI*2); ctx.stroke();
+      } else {
+        ctx.fillStyle = 'rgba(200,225,255,.55)';
+        ctx.beginPath(); ctx.arc(p.x, p.y, 2.2, 0, Math.PI*2); ctx.fill();
+      }
+    }
+
+    // highlight the point under the cursor / being dragged
+    if (dragPoint){
+      ctx.strokeStyle = 'var(--accent)';
+      ctx.strokeStyle = '#5ad1ff';
+      ctx.lineWidth = 2;
+      ctx.beginPath(); ctx.arc(dragPoint.x, dragPoint.y, 12, 0, Math.PI*2); ctx.stroke();
+    }
+
+    // cut blade trail
+    if (cutMode && mouse.down){
+      ctx.strokeStyle = 'rgba(255,90,138,.9)';
+      ctx.lineWidth = 2;
+      ctx.beginPath(); ctx.moveTo(mouse.px, mouse.py); ctx.lineTo(mouse.x, mouse.y); ctx.stroke();
+    }
+
+    // cut flashes
+    for (const f of cutFlashes){
+      ctx.fillStyle = `rgba(255,120,160,${f.life*0.8})`;
+      ctx.beginPath(); ctx.arc(f.x, f.y, (1-f.life)*14 + 3, 0, Math.PI*2); ctx.fill();
+      f.life -= 0.06;
+    }
+    cutFlashes = cutFlashes.filter(f => f.life > 0);
+
+    statsEl.textContent = `${points.length} points · ${live} strands · ` +
+      `gravity ${gravity} · wind ${wind}  —  keys: C cut · R reset`;
+  }
+
+  // ---------- Loop ----------
+  let lastT = performance.now();
+  function frame(now){
+    let dt = (now - lastT) / 1000;
+    lastT = now;
+    dt = Math.min(dt, 0.033);       // clamp big gaps
+    t += dt;
+    // fixed-ish substeps for stability
+    const steps = 2;
+    for (let i = 0; i < steps; i++){
+      integrate(dt * 55 / steps);   // scale so units feel right
+      constrain();
+    }
+    render();
+    requestAnimationFrame(frame);
+  }
+
+  resize();
+  rebuild();
+  requestAnimationFrame(frame);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/games/rubiks-cube/AbramsCube.aa b/games/rubiks-cube/AbramsCube.aa
new file mode 100644
index 0000000..692b46c
--- /dev/null
+++ b/games/rubiks-cube/AbramsCube.aa
@@ -0,0 +1,399 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Abrams Cube — CSS 3D</title>
+<style>
+  :root { --s: 60px; }
+  * { box-sizing: border-box; user-select: none; -webkit-user-select: none; }
+  html, body { height: 100%; }
+  body {
+    margin: 0; display: flex; flex-direction: column; align-items: center;
+    background: radial-gradient(circle at 50% 30%, #2b303c, #12141a 75%);
+    font-family: system-ui, -apple-system, sans-serif; color: #e8e9ef; overflow: hidden;
+  }
+  h1 { font-size: 16px; font-weight: 600; letter-spacing: 3px; text-transform: uppercase; margin: 14px 0 2px; opacity: .85; }
+  .hint { font-size: 12px; opacity: .5; margin: 0 0 2px; text-align: center; padding: 0 12px; }
+  #hud {
+    display: flex; gap: 18px; font-size: 13px; opacity: .85; margin: 4px 0 0;
+    font-variant-numeric: tabular-nums; letter-spacing: .5px;
+  }
+  #hud b { font-weight: 700; color: #fff; }
+  #viewport {
+    flex: 1; width: 100%; display: flex; align-items: center; justify-content: center;
+    perspective: 1000px; cursor: grab; touch-action: none; position: relative;
+  }
+  #viewport.dragging { cursor: grabbing; }
+  #banner {
+    position: absolute; left: 50%; top: 14%; transform: translateX(-50%);
+    background: linear-gradient(180deg, #2f8f5b, #1f6f44); border: 1px solid #3fae72;
+    border-radius: 12px; padding: 12px 22px; font-size: 16px; font-weight: 700;
+    letter-spacing: .5px; box-shadow: 0 8px 30px rgba(0,0,0,.45);
+    opacity: 0; transition: opacity .35s; pointer-events: none; white-space: nowrap;
+  }
+  #banner.show { opacity: 1; }
+  #cube { position: relative; width: 0; height: 0; transform-style: preserve-3d; }
+  .cubie {
+    position: absolute; width: var(--s); height: var(--s);
+    left: calc(var(--s) / -2); top: calc(var(--s) / -2);
+    transform-style: preserve-3d;
+  }
+  .face {
+    position: absolute; inset: 0; border-radius: 14%;
+    border: 3px solid #0b0d11;
+    box-shadow: inset 0 0 6px rgba(0,0,0,.35);
+  }
+  .f-front  { transform: translateZ(calc(var(--s) / 2)); }
+  .f-back   { transform: rotateY(180deg) translateZ(calc(var(--s) / 2)); }
+  .f-right  { transform: rotateY(90deg)  translateZ(calc(var(--s) / 2)); }
+  .f-left   { transform: rotateY(-90deg) translateZ(calc(var(--s) / 2)); }
+  .f-top    { transform: rotateX(90deg)  translateZ(calc(var(--s) / 2)); }
+  .f-bottom { transform: rotateX(-90deg) translateZ(calc(var(--s) / 2)); }
+  #controls { padding: 8px 12px 16px; display: flex; flex-direction: column; gap: 7px; align-items: center; }
+  .row { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
+  button {
+    font: 600 14px/1 system-ui, sans-serif; color: #e8e9ef;
+    background: linear-gradient(180deg, #3a4152, #2a3040);
+    border: 1px solid #4a5268; border-radius: 9px;
+    min-width: 44px; padding: 10px 8px; cursor: pointer;
+    transition: transform .08s, background .15s;
+  }
+  button:hover { background: linear-gradient(180deg, #4a5268, #333a4c); }
+  button:active { transform: scale(.93); }
+  button.slice { opacity: .8; }
+  .big { min-width: 96px; letter-spacing: 1px; }
+  #scramble { background: linear-gradient(180deg, #7c5cff, #5b3fe0); border-color: #8f78ff; }
+  #scramble:hover { background: linear-gradient(180deg, #8d70ff, #6a4ef0); }
+  #reset { background: linear-gradient(180deg, #2f8f5b, #1f6f44); border-color: #3fae72; }
+  #reset:hover { background: linear-gradient(180deg, #37a066, #27804f); }
+  #undo { background: linear-gradient(180deg, #b3823a, #8f6425); border-color: #cf9c50; }
+  #undo:hover { background: linear-gradient(180deg, #c4914a, #a0722e); }
+</style>
+</head>
+<body>
+<h1>Abrams Cube</h1>
+<p class="hint">Drag to orbit &middot; scroll to zoom &middot; keys U/D/L/R/F/B/M/E/S turn faces (Shift = counter-clockwise) &middot; &#8984;Z / Ctrl+Z undo</p>
+<div id="hud"><span>Moves <b id="movesHud">0</b></span><span>Time <b id="timeHud">0:00</b></span></div>
+<div id="viewport">
+  <div id="cube"></div>
+  <div id="banner"></div>
+</div>
+<div id="controls">
+  <div class="row" id="movesRow"></div>
+  <div class="row" id="primesRow"></div>
+  <div class="row">
+    <button id="scramble" class="big">Scramble</button>
+    <button id="undo" class="big">Undo</button>
+    <button id="reset" class="big">Reset</button>
+  </div>
+</div>
+<script>
+(function () {
+  var viewport = document.getElementById('viewport');
+  var cubeEl = document.getElementById('cube');
+  var banner = document.getElementById('banner');
+  var movesHud = document.getElementById('movesHud');
+  var timeHud = document.getElementById('timeHud');
+
+  var S = 60;
+  function sizeCube() {
+    S = Math.max(34, Math.min(72, Math.floor(Math.min(innerWidth, innerHeight - 230) / 5.2)));
+    document.documentElement.style.setProperty('--s', S + 'px');
+  }
+  sizeCube();
+
+  var DARK = '#171a20';
+  var I3 = [1,0,0, 0,1,0, 0,0,1];
+
+  function mul(a, b) { // 3x3 row-major
+    var r = new Array(9);
+    for (var i = 0; i < 3; i++) for (var j = 0; j < 3; j++)
+      r[i*3+j] = a[i*3]*b[j] + a[i*3+1]*b[3+j] + a[i*3+2]*b[6+j];
+    return r;
+  }
+  function applyM(m, v) {
+    return [ m[0]*v[0]+m[1]*v[1]+m[2]*v[2],
+             m[3]*v[0]+m[4]*v[1]+m[5]*v[2],
+             m[6]*v[0]+m[7]*v[1]+m[8]*v[2] ];
+  }
+  function roundM(m) { return m.map(function (v) { return Math.round(v); }); }
+  function axisRot(axis, deg) {
+    var r = deg * Math.PI / 180, c = Math.cos(r), s = Math.sin(r);
+    if (axis === 'x') return [1,0,0, 0,c,-s, 0,s,c];
+    if (axis === 'y') return [c,0,s, 0,1,0, -s,0,c];
+    return [c,-s,0, s,c,0, 0,0,1];
+  }
+
+  var cubies = [];
+  function makeFace(cls, color) {
+    var f = document.createElement('div');
+    f.className = 'face ' + cls;
+    f.style.background = color === DARK ? DARK
+      : 'linear-gradient(145deg, ' + color + ', ' + color + ' 60%, rgba(0,0,0,.18))';
+    if (color !== DARK) f.style.backgroundColor = color;
+    return f;
+  }
+  function build() {
+    cubeEl.innerHTML = '';
+    cubies = [];
+    for (var x = -1; x <= 1; x++) for (var y = -1; y <= 1; y++) for (var z = -1; z <= 1; z++) {
+      if (!x && !y && !z) continue;
+      var el = document.createElement('div');
+      el.className = 'cubie';
+      el.appendChild(makeFace('f-top',    y === -1 ? '#f4f6f5' : DARK)); // white up
+      el.appendChild(makeFace('f-bottom', y ===  1 ? '#ffd60a' : DARK)); // yellow down
+      el.appendChild(makeFace('f-right',  x ===  1 ? '#e5484d' : DARK)); // red right
+      el.appendChild(makeFace('f-left',   x === -1 ? '#ff9f1c' : DARK)); // orange left
+      el.appendChild(makeFace('f-front',  z ===  1 ? '#30c04f' : DARK)); // green front
+      el.appendChild(makeFace('f-back',   z === -1 ? '#3b82f6' : DARK)); // blue back
+      cubeEl.appendChild(el);
+      var c = { x: x, y: y, z: z, ix: x, iy: y, iz: z, m: I3.slice(), el: el };
+      cubies.push(c);
+      render(c, null);
+    }
+  }
+  function render(c, R) {
+    var m = R ? mul(R, c.m) : c.m;
+    var p = [c.x * S, c.y * S, c.z * S];
+    if (R) p = applyM(R, p);
+    c.el.style.transform = 'matrix3d(' +
+      m[0] + ',' + m[3] + ',' + m[6] + ',0,' +
+      m[1] + ',' + m[4] + ',' + m[7] + ',0,' +
+      m[2] + ',' + m[5] + ',' + m[8] + ',0,' +
+      p[0] + ',' + p[1] + ',' + p[2] + ',1)';
+  }
+
+  // Face turns: clockwise viewed from outside = +90deg about the outward normal.
+  // Slices follow standard notation: M follows L, E follows D, S follows F.
+  var MOVES = {
+    U: { axis: 'y', layer: -1, dir: -1 },
+    D: { axis: 'y', layer:  1, dir:  1 },
+    R: { axis: 'x', layer:  1, dir:  1 },
+    L: { axis: 'x', layer: -1, dir: -1 },
+    F: { axis: 'z', layer:  1, dir:  1 },
+    B: { axis: 'z', layer: -1, dir: -1 },
+    M: { axis: 'x', layer:  0, dir: -1 },
+    E: { axis: 'y', layer:  0, dir:  1 },
+    S: { axis: 'z', layer:  0, dir:  1 }
+  };
+  var OUTER = ['U','D','L','R','F','B'];
+
+  // ---- state ----
+  var queue = [], animating = false, gen = 0;
+  var history = [], moves = 0, scrambled = false;
+  var timerStart = null, elapsed = 0;
+
+  function coordOf(c, axis) { return axis === 'x' ? c.x : axis === 'y' ? c.y : c.z; }
+
+  function enqueue(name, prime, dur, src) {
+    var mv = MOVES[name];
+    if (!mv) return;
+    src = src || 'user';
+    if (src === 'user') {
+      hideBanner();
+      if (scrambled && timerStart === null) timerStart = performance.now();
+    }
+    queue.push({ name: name, prime: !!prime, src: src,
+                 axis: mv.axis, layer: mv.layer, dir: mv.dir * (prime ? -1 : 1),
+                 dur: dur || 260 });
+    if (!animating) next();
+  }
+
+  function next() {
+    var item = queue.shift();
+    if (!item) { animating = false; return; }
+    animating = true;
+    var myGen = gen;
+    var affected = cubies.filter(function (c) { return coordOf(c, item.axis) === item.layer; });
+    var t0 = performance.now();
+    function frame(now) {
+      if (myGen !== gen) return;
+      var t = Math.min(1, (now - t0) / item.dur);
+      var e = t < .5 ? 2*t*t : 1 - Math.pow(-2*t + 2, 2) / 2;
+      var R = axisRot(item.axis, 90 * item.dir * e);
+      affected.forEach(function (c) { render(c, R); });
+      if (t < 1) { requestAnimationFrame(frame); return; }
+      var Rq = roundM(axisRot(item.axis, 90 * item.dir));
+      affected.forEach(function (c) {
+        var p = applyM(Rq, [c.x, c.y, c.z]).map(Math.round);
+        c.x = p[0]; c.y = p[1]; c.z = p[2];
+        c.m = roundM(mul(Rq, c.m));
+        render(c, null);
+      });
+      commit(item);
+      next();
+    }
+    requestAnimationFrame(frame);
+  }
+
+  function commit(item) {
+    if (item.src === 'user') {
+      history.push({ name: item.name, prime: item.prime });
+      moves++;
+    } else if (item.src === 'undo') {
+      history.pop();
+      moves = Math.max(0, moves - 1);
+    }
+    updateHud();
+    if (scrambled && item.src !== 'scramble' && isSolved()) celebrate();
+  }
+
+  // Solved when every sticker's current world direction equals its home direction.
+  // (Sufficient for any state reachable by legal turns; catches slice moves too.)
+  function isSolved() {
+    for (var i = 0; i < cubies.length; i++) {
+      var c = cubies[i], dirs = [];
+      if (c.ix) dirs.push([c.ix, 0, 0]);
+      if (c.iy) dirs.push([0, c.iy, 0]);
+      if (c.iz) dirs.push([0, 0, c.iz]);
+      for (var j = 0; j < dirs.length; j++) {
+        var d = dirs[j], w = applyM(c.m, d);
+        if (Math.round(w[0]) !== d[0] || Math.round(w[1]) !== d[1] || Math.round(w[2]) !== d[2]) return false;
+      }
+    }
+    return true;
+  }
+
+  function fmtTime(ms) {
+    var s = Math.floor(ms / 1000);
+    return Math.floor(s / 60) + ':' + ('0' + (s % 60)).slice(-2);
+  }
+  function updateHud() { movesHud.textContent = moves; }
+  setInterval(function () {
+    if (timerStart !== null) elapsed = performance.now() - timerStart;
+    timeHud.textContent = fmtTime(elapsed);
+  }, 200);
+
+  function celebrate() {
+    scrambled = false;
+    if (timerStart !== null) { elapsed = performance.now() - timerStart; timerStart = null; }
+    banner.textContent = '🎉 Solved in ' + moves + ' move' + (moves === 1 ? '' : 's') +
+      (elapsed > 0 ? ' · ' + fmtTime(elapsed) : '') + '!';
+    banner.classList.add('show');
+    clearTimeout(celebrate.t);
+    celebrate.t = setTimeout(hideBanner, 6000);
+  }
+  function hideBanner() { banner.classList.remove('show'); }
+
+  function scramble() {
+    hideBanner();
+    scrambled = true;
+    history.length = 0; moves = 0;
+    timerStart = null; elapsed = 0;
+    updateHud();
+    var last = '';
+    for (var i = 0; i < 22; i++) {
+      var n;
+      do { n = OUTER[Math.floor(Math.random() * OUTER.length)]; } while (n === last);
+      last = n;
+      enqueue(n, Math.random() < .5, 110, 'scramble');
+    }
+  }
+
+  function reset() {
+    gen++; queue.length = 0; animating = false;
+    history.length = 0; moves = 0;
+    scrambled = false; timerStart = null; elapsed = 0;
+    hideBanner(); updateHud();
+    cubies.forEach(function (c) {
+      c.x = c.ix; c.y = c.iy; c.z = c.iz; c.m = I3.slice();
+      render(c, null);
+    });
+  }
+
+  function undo() {
+    if (animating || queue.length || !history.length) return;
+    var last = history[history.length - 1];
+    enqueue(last.name, !last.prime, 200, 'undo');
+  }
+
+  // ---- controls ----
+  var movesRow = document.getElementById('movesRow');
+  var primesRow = document.getElementById('primesRow');
+  ['U','D','L','R','F','B','M','E','S'].forEach(function (n) {
+    var slice = 'MES'.indexOf(n) !== -1;
+    var b = document.createElement('button');
+    b.textContent = n;
+    if (slice) b.className = 'slice';
+    b.title = 'Turn ' + n + ' clockwise';
+    b.onclick = function () { enqueue(n, false); };
+    movesRow.appendChild(b);
+    var bp = document.createElement('button');
+    bp.textContent = n + '′';
+    if (slice) bp.className = 'slice';
+    bp.title = 'Turn ' + n + ' counter-clockwise';
+    bp.onclick = function () { enqueue(n, true); };
+    primesRow.appendChild(bp);
+  });
+  document.getElementById('scramble').onclick = scramble;
+  document.getElementById('reset').onclick = reset;
+  document.getElementById('undo').onclick = undo;
+
+  document.addEventListener('keydown', function (ev) {
+    if (ev.metaKey || ev.ctrlKey) {
+      if (ev.key.toLowerCase() === 'z') { ev.preventDefault(); undo(); }
+      return;
+    }
+    if (ev.repeat) return;
+    var k = ev.key.toUpperCase();
+    if (MOVES[k]) { ev.preventDefault(); enqueue(k, ev.shiftKey); }
+    else if (ev.key === '+' || ev.key === '=') setZoom(zoom * 1.12);
+    else if (ev.key === '-' || ev.key === '_') setZoom(zoom / 1.12);
+  });
+
+  // ---- orbit + zoom ----
+  var rx = -28, ry = -38, zoom = 1, dragging = false, px = 0, py = 0;
+  function applyOrbit() {
+    cubeEl.style.transform = 'scale3d(' + zoom + ',' + zoom + ',' + zoom + ') ' +
+      'rotateX(' + rx + 'deg) rotateY(' + ry + 'deg)';
+  }
+  function setZoom(z) { zoom = Math.max(.5, Math.min(1.9, z)); applyOrbit(); }
+  applyOrbit();
+
+  viewport.addEventListener('pointerdown', function (ev) {
+    dragging = true; px = ev.clientX; py = ev.clientY;
+    viewport.classList.add('dragging');
+    viewport.setPointerCapture(ev.pointerId);
+  });
+  viewport.addEventListener('pointermove', function (ev) {
+    if (!dragging) return;
+    ry += (ev.clientX - px) * 0.4;
+    rx -= (ev.clientY - py) * 0.4;
+    rx = Math.max(-90, Math.min(90, rx));
+    px = ev.clientX; py = ev.clientY;
+    applyOrbit();
+  });
+  function endDrag() { dragging = false; viewport.classList.remove('dragging'); }
+  viewport.addEventListener('pointerup', endDrag);
+  viewport.addEventListener('pointercancel', endDrag);
+  viewport.addEventListener('wheel', function (ev) {
+    ev.preventDefault();
+    setZoom(zoom * Math.exp(-ev.deltaY * 0.0012));
+  }, { passive: false });
+
+  var resizeT;
+  addEventListener('resize', function () {
+    clearTimeout(resizeT);
+    resizeT = setTimeout(function () {
+      sizeCube();
+      cubies.forEach(function (c) { render(c, null); });
+    }, 120);
+  });
+
+  build();
+
+  // Test/debug hook (harmless in normal use)
+  window.__cube = {
+    isSolved: isSolved,
+    isBusy: function () { return animating || queue.length > 0; },
+    getMoves: function () { return moves; },
+    getHistoryLength: function () { return history.length; },
+    getOrbit: function () { return { rx: rx, ry: ry, zoom: zoom }; },
+    enqueue: function (n, p) { enqueue(n, p, 40); },
+    scramble: scramble, reset: reset, undo: undo
+  };
+})();
+</script>
+</body>
+</html>
diff --git a/games/simon/AbramsSimon.aa b/games/simon/AbramsSimon.aa
new file mode 100644
index 0000000..469dd39
--- /dev/null
+++ b/games/simon/AbramsSimon.aa
@@ -0,0 +1,632 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+<title>Abrams Simon</title>
+<style>
+  :root {
+    --bg0: #05060a;
+    --bg1: #0b0f1c;
+    --ink: #e8f0ff;
+    --muted: #7b88a8;
+    --accent: #45e6ff;
+    --green: #1fd67a;
+    --red: #ff3b5c;
+    --yellow: #ffd23b;
+    --blue: #3b7bff;
+  }
+
+  * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
+
+  html, body {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    background:
+      radial-gradient(circle at 50% 8%, #12203f 0%, var(--bg1) 45%, var(--bg0) 100%);
+    color: var(--ink);
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
+    user-select: none;
+    -webkit-user-select: none;
+    touch-action: manipulation;
+  }
+
+  #app {
+    position: absolute;
+    inset: 0;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: clamp(8px, 2.4vmin, 24px);
+    gap: clamp(8px, 2vmin, 20px);
+  }
+
+  header {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 4px;
+    text-align: center;
+  }
+
+  h1 {
+    margin: 0;
+    font-size: clamp(20px, 5vmin, 40px);
+    font-weight: 800;
+    letter-spacing: 0.18em;
+    text-transform: uppercase;
+    background: linear-gradient(90deg, var(--green), var(--yellow), var(--red), var(--blue), var(--accent));
+    -webkit-background-clip: text;
+    background-clip: text;
+    color: transparent;
+    filter: drop-shadow(0 0 12px rgba(69, 230, 255, 0.35));
+  }
+
+  .subtitle {
+    font-size: clamp(10px, 1.8vmin, 13px);
+    color: var(--muted);
+    letter-spacing: 0.24em;
+    text-transform: uppercase;
+  }
+
+  .stats {
+    display: flex;
+    gap: clamp(10px, 3vmin, 28px);
+    align-items: stretch;
+  }
+
+  .stat {
+    min-width: clamp(70px, 18vmin, 110px);
+    padding: clamp(6px, 1.4vmin, 12px) clamp(10px, 2.4vmin, 18px);
+    border-radius: 14px;
+    background: rgba(20, 30, 56, 0.55);
+    border: 1px solid rgba(90, 120, 190, 0.18);
+    box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.35);
+    text-align: center;
+  }
+  .stat .label {
+    font-size: clamp(9px, 1.5vmin, 11px);
+    letter-spacing: 0.16em;
+    text-transform: uppercase;
+    color: var(--muted);
+  }
+  .stat .value {
+    font-size: clamp(20px, 5vmin, 34px);
+    font-weight: 800;
+    line-height: 1.05;
+    color: var(--accent);
+    text-shadow: 0 0 14px rgba(69, 230, 255, 0.4);
+  }
+  .stat.best .value { color: var(--yellow); text-shadow: 0 0 14px rgba(255, 210, 59, 0.4); }
+
+  /* Board */
+  .board-wrap {
+    position: relative;
+    width: min(78vmin, 560px);
+    height: min(78vmin, 560px);
+    max-width: 90vw;
+    max-height: 60vh;
+  }
+
+  .board {
+    position: absolute;
+    inset: 0;
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: 1fr 1fr;
+    gap: clamp(8px, 2.2vmin, 20px);
+    border-radius: 50%;
+    padding: clamp(8px, 2.2vmin, 20px);
+    background:
+      radial-gradient(circle at center, rgba(15, 22, 44, 0.9), rgba(5, 7, 14, 0.9));
+    box-shadow:
+      0 0 0 2px rgba(90, 120, 190, 0.15),
+      0 0 60px rgba(0, 0, 0, 0.6),
+      inset 0 0 40px rgba(0, 0, 0, 0.7);
+  }
+
+  .pad {
+    position: relative;
+    border: none;
+    cursor: pointer;
+    background: var(--c);
+    filter: brightness(0.42) saturate(0.9);
+    transition: filter 0.09s ease, box-shadow 0.09s ease, transform 0.06s ease;
+    outline: none;
+    box-shadow: inset 0 0 30px rgba(0, 0, 0, 0.55);
+  }
+  .pad::after {
+    content: "";
+    position: absolute;
+    inset: 0;
+    border-radius: inherit;
+    box-shadow: inset 0 0 22px rgba(255, 255, 255, 0.08);
+    pointer-events: none;
+  }
+
+  .pad.tl { border-top-left-radius: 100%; --c: var(--green); }
+  .pad.tr { border-top-right-radius: 100%; --c: var(--red); }
+  .pad.bl { border-bottom-left-radius: 100%; --c: var(--yellow); }
+  .pad.br { border-bottom-right-radius: 100%; --c: var(--blue); }
+
+  .pad.lit {
+    filter: brightness(1.5) saturate(1.25);
+    box-shadow:
+      0 0 46px 8px var(--c),
+      inset 0 0 40px rgba(255, 255, 255, 0.5);
+    transform: scale(1.015);
+  }
+
+  .board.playable .pad:not(:disabled):active {
+    filter: brightness(1.35) saturate(1.2);
+  }
+
+  /* Center hub */
+  .hub {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    width: 34%;
+    height: 34%;
+    border-radius: 50%;
+    background: radial-gradient(circle at 35% 30%, #16223f, #080b16 72%);
+    border: 2px solid rgba(90, 120, 190, 0.25);
+    box-shadow: 0 0 30px rgba(0, 0, 0, 0.7), inset 0 0 26px rgba(0, 0, 0, 0.7);
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    gap: 2px;
+    z-index: 3;
+    text-align: center;
+    padding: 4px;
+  }
+  .hub .hub-title {
+    font-size: clamp(10px, 2.1vmin, 15px);
+    font-weight: 800;
+    letter-spacing: 0.16em;
+    color: var(--accent);
+    text-shadow: 0 0 12px rgba(69, 230, 255, 0.5);
+  }
+  .hub .hub-msg {
+    font-size: clamp(9px, 1.7vmin, 12px);
+    color: var(--muted);
+    letter-spacing: 0.06em;
+    min-height: 1.1em;
+  }
+
+  /* Controls */
+  .controls {
+    display: flex;
+    flex-wrap: wrap;
+    gap: clamp(8px, 2vmin, 16px);
+    align-items: center;
+    justify-content: center;
+  }
+
+  button.ctrl {
+    font-family: inherit;
+    font-weight: 700;
+    letter-spacing: 0.1em;
+    text-transform: uppercase;
+    font-size: clamp(11px, 2vmin, 14px);
+    color: var(--ink);
+    background: linear-gradient(180deg, rgba(40, 58, 100, 0.75), rgba(20, 30, 56, 0.75));
+    border: 1px solid rgba(90, 130, 210, 0.35);
+    border-radius: 12px;
+    padding: clamp(8px, 1.8vmin, 12px) clamp(16px, 4vmin, 26px);
+    cursor: pointer;
+    transition: transform 0.08s ease, box-shadow 0.15s ease, border-color 0.15s ease;
+    box-shadow: 0 0 0 rgba(69, 230, 255, 0);
+  }
+  button.ctrl:hover { border-color: var(--accent); box-shadow: 0 0 18px rgba(69, 230, 255, 0.25); }
+  button.ctrl:active { transform: translateY(1px) scale(0.98); }
+
+  button.start {
+    background: linear-gradient(180deg, var(--accent), #1b9fbf);
+    color: #041018;
+    border-color: rgba(69, 230, 255, 0.6);
+    box-shadow: 0 0 22px rgba(69, 230, 255, 0.35);
+  }
+  button.start:hover { box-shadow: 0 0 30px rgba(69, 230, 255, 0.55); }
+
+  .toggle {
+    display: inline-flex;
+    align-items: center;
+    gap: 8px;
+    font-size: clamp(10px, 1.8vmin, 13px);
+    letter-spacing: 0.08em;
+    text-transform: uppercase;
+    color: var(--muted);
+    cursor: pointer;
+    padding: clamp(7px, 1.6vmin, 11px) clamp(12px, 3vmin, 18px);
+    border-radius: 12px;
+    border: 1px solid rgba(90, 130, 210, 0.22);
+    background: rgba(20, 30, 56, 0.4);
+    transition: border-color 0.15s ease, color 0.15s ease;
+  }
+  .toggle.on { color: var(--ink); border-color: rgba(69, 230, 255, 0.5); }
+  .toggle .dot {
+    width: 12px; height: 12px; border-radius: 50%;
+    background: rgba(120, 140, 180, 0.4);
+    box-shadow: inset 0 0 4px rgba(0,0,0,0.6);
+    transition: background 0.15s ease, box-shadow 0.15s ease;
+  }
+  .toggle.on .dot {
+    background: var(--green);
+    box-shadow: 0 0 10px var(--green);
+  }
+  .toggle.strict.on .dot { background: var(--red); box-shadow: 0 0 10px var(--red); }
+
+  .board.flash-fail { animation: shake 0.4s ease; }
+  @keyframes shake {
+    0%,100% { transform: translateX(0); }
+    20% { transform: translateX(-8px); }
+    40% { transform: translateX(8px); }
+    60% { transform: translateX(-5px); }
+    80% { transform: translateX(5px); }
+  }
+
+  @media (max-height: 560px) {
+    header .subtitle { display: none; }
+    .board-wrap { max-height: 52vh; }
+  }
+</style>
+</head>
+<body>
+<div id="app">
+  <header>
+    <h1>Abrams Simon</h1>
+    <div class="subtitle">Watch &middot; Remember &middot; Repeat</div>
+  </header>
+
+  <div class="stats">
+    <div class="stat"><div class="label">Round</div><div class="value" id="roundVal">0</div></div>
+    <div class="stat best"><div class="label">Best</div><div class="value" id="bestVal">0</div></div>
+  </div>
+
+  <div class="board-wrap">
+    <div class="board" id="board">
+      <button class="pad tl" data-i="0" aria-label="green" disabled></button>
+      <button class="pad tr" data-i="1" aria-label="red" disabled></button>
+      <button class="pad bl" data-i="2" aria-label="yellow" disabled></button>
+      <button class="pad br" data-i="3" aria-label="blue" disabled></button>
+    </div>
+    <div class="hub">
+      <div class="hub-title" id="hubTitle">READY?</div>
+      <div class="hub-msg" id="hubMsg">Press Start</div>
+    </div>
+  </div>
+
+  <div class="controls">
+    <button class="ctrl start" id="startBtn">Start</button>
+    <div class="toggle strict" id="strictToggle" role="switch" aria-checked="false" tabindex="0">
+      <span class="dot"></span><span>Strict</span>
+    </div>
+    <div class="toggle on" id="soundToggle" role="switch" aria-checked="true" tabindex="0">
+      <span class="dot"></span><span>Sound</span>
+    </div>
+  </div>
+</div>
+
+<script>
+(function () {
+  "use strict";
+
+  // ---- Elements ----
+  const pads = Array.from(document.querySelectorAll(".pad"));
+  const board = document.getElementById("board");
+  const roundVal = document.getElementById("roundVal");
+  const bestVal = document.getElementById("bestVal");
+  const hubTitle = document.getElementById("hubTitle");
+  const hubMsg = document.getElementById("hubMsg");
+  const startBtn = document.getElementById("startBtn");
+  const strictToggle = document.getElementById("strictToggle");
+  const soundToggle = document.getElementById("soundToggle");
+
+  // ---- State ----
+  const BEST_KEY = "abrams-simon-best";
+  const SOUND_KEY = "abrams-simon-sound";
+  const STRICT_KEY = "abrams-simon-strict";
+
+  let sequence = [];
+  let userStep = 0;
+  let acceptingInput = false;
+  let playing = false;
+  let busy = false; // during playback / transitions
+  let best = 0;
+
+  // pad tones (green, red, yellow, blue) — pleasant-ish intervals
+  const TONES = [329.63, 261.63, 220.0, 164.81]; // E4, C4, A3, E3
+  const FAIL_TONE = 110.0;
+
+  // ---- Audio ----
+  let audioCtx = null;
+  let soundOn = true;
+
+  function ensureAudio() {
+    if (!audioCtx) {
+      try {
+        const AC = window.AudioContext || window.webkitAudioContext;
+        audioCtx = new AC();
+      } catch (e) {
+        audioCtx = null;
+      }
+    }
+    if (audioCtx && audioCtx.state === "suspended") {
+      audioCtx.resume().catch(function () {});
+    }
+    return audioCtx;
+  }
+
+  function playTone(freq, durationMs, type) {
+    if (!soundOn) return;
+    const ctx = ensureAudio();
+    if (!ctx) return;
+    const now = ctx.currentTime;
+    const dur = durationMs / 1000;
+
+    const osc = ctx.createOscillator();
+    const gain = ctx.createGain();
+    osc.type = type || "sine";
+    osc.frequency.setValueAtTime(freq, now);
+
+    gain.gain.setValueAtTime(0.0001, now);
+    gain.gain.exponentialRampToValueAtTime(0.28, now + 0.012);
+    gain.gain.setValueAtTime(0.28, now + Math.max(0.012, dur - 0.06));
+    gain.gain.exponentialRampToValueAtTime(0.0001, now + dur);
+
+    osc.connect(gain).connect(ctx.destination);
+    osc.start(now);
+    osc.stop(now + dur + 0.02);
+  }
+
+  function playFail() {
+    if (!soundOn) return;
+    const ctx = ensureAudio();
+    if (!ctx) return;
+    const now = ctx.currentTime;
+    const osc = ctx.createOscillator();
+    const gain = ctx.createGain();
+    osc.type = "sawtooth";
+    osc.frequency.setValueAtTime(FAIL_TONE, now);
+    osc.frequency.exponentialRampToValueAtTime(55, now + 0.7);
+    gain.gain.setValueAtTime(0.0001, now);
+    gain.gain.exponentialRampToValueAtTime(0.3, now + 0.02);
+    gain.gain.exponentialRampToValueAtTime(0.0001, now + 0.75);
+    osc.connect(gain).connect(ctx.destination);
+    osc.start(now);
+    osc.stop(now + 0.8);
+  }
+
+  function winChime() {
+    if (!soundOn) return;
+    const ctx = ensureAudio();
+    if (!ctx) return;
+    [523.25, 659.25, 783.99].forEach(function (f, k) {
+      setTimeout(function () { playTone(f, 160, "triangle"); }, k * 90);
+    });
+  }
+
+  // ---- Timing (speeds up with level) ----
+  function litDuration() {
+    // starts ~560ms, floors ~200ms
+    return Math.max(200, 560 - sequence.length * 22);
+  }
+  function gapDuration() {
+    return Math.max(80, 200 - sequence.length * 8);
+  }
+
+  // ---- Visual pad flash ----
+  function litPad(i, duration) {
+    return new Promise(function (resolve) {
+      const pad = pads[i];
+      pad.classList.add("lit");
+      playTone(TONES[i], duration, "sine");
+      setTimeout(function () {
+        pad.classList.remove("lit");
+        resolve();
+      }, duration);
+    });
+  }
+
+  function sleep(ms) {
+    return new Promise(function (r) { setTimeout(r, ms); });
+  }
+
+  // ---- Sequence playback ----
+  async function playSequence() {
+    busy = true;
+    acceptingInput = false;
+    setBoardPlayable(false);
+    hubTitle.textContent = "WATCH";
+    hubMsg.textContent = "Round " + sequence.length;
+    await sleep(500);
+    const dur = litDuration();
+    const gap = gapDuration();
+    for (let k = 0; k < sequence.length; k++) {
+      await litPad(sequence[k], dur);
+      await sleep(gap);
+    }
+    busy = false;
+    acceptingInput = true;
+    userStep = 0;
+    setBoardPlayable(true);
+    hubTitle.textContent = "YOUR TURN";
+    hubMsg.textContent = "0 / " + sequence.length;
+  }
+
+  function setBoardPlayable(on) {
+    pads.forEach(function (p) { p.disabled = !on; });
+    board.classList.toggle("playable", on);
+  }
+
+  // ---- Round flow ----
+  function nextRound() {
+    sequence.push(Math.floor(Math.random() * 4));
+    roundVal.textContent = sequence.length;
+    playSequence();
+  }
+
+  function startGame() {
+    ensureAudio();
+    sequence = [];
+    userStep = 0;
+    playing = true;
+    acceptingInput = false;
+    roundVal.textContent = "0";
+    startBtn.textContent = "Restart";
+    board.classList.remove("flash-fail");
+    hubTitle.textContent = "GO!";
+    hubMsg.textContent = "";
+    setTimeout(nextRound, 350);
+  }
+
+  async function handlePress(i) {
+    if (!acceptingInput || busy || !playing) return;
+
+    // flash the pressed pad
+    const dur = 220;
+    acceptingInput = false;
+    await litPad(i, dur);
+
+    if (i !== sequence[userStep]) {
+      gameOver();
+      return;
+    }
+
+    userStep++;
+    hubMsg.textContent = userStep + " / " + sequence.length;
+
+    if (userStep >= sequence.length) {
+      // round cleared
+      updateBest(sequence.length);
+      winChime();
+      hubTitle.textContent = "NICE";
+      hubMsg.textContent = "Round " + sequence.length + " cleared";
+      acceptingInput = false;
+      setBoardPlayable(false);
+      await sleep(650);
+      nextRound();
+    } else {
+      acceptingInput = true;
+    }
+  }
+
+  async function gameOver() {
+    playing = false;
+    acceptingInput = false;
+    setBoardPlayable(false);
+    playFail();
+    board.classList.add("flash-fail");
+
+    // flash all pads red-ish
+    pads.forEach(function (p) { p.classList.add("lit"); });
+    await sleep(320);
+    pads.forEach(function (p) { p.classList.remove("lit"); });
+    board.classList.remove("flash-fail");
+
+    const reached = Math.max(0, sequence.length - 1);
+    hubTitle.textContent = "GAME OVER";
+    hubMsg.textContent = "Reached round " + reached;
+    startBtn.textContent = "Start";
+
+    if (strictOn) {
+      // strict: sequence resets fully (already will on Start)
+      sequence = [];
+      roundVal.textContent = "0";
+    }
+  }
+
+  function updateBest(level) {
+    if (level > best) {
+      best = level;
+      bestVal.textContent = best;
+      try { localStorage.setItem(BEST_KEY, String(best)); } catch (e) {}
+    }
+  }
+
+  // ---- Toggles ----
+  let strictOn = false;
+
+  function setSound(on) {
+    soundOn = on;
+    soundToggle.classList.toggle("on", on);
+    soundToggle.setAttribute("aria-checked", on ? "true" : "false");
+    try { localStorage.setItem(SOUND_KEY, on ? "1" : "0"); } catch (e) {}
+    if (on) ensureAudio();
+  }
+
+  function setStrict(on) {
+    strictOn = on;
+    strictToggle.classList.toggle("on", on);
+    strictToggle.setAttribute("aria-checked", on ? "true" : "false");
+    try { localStorage.setItem(STRICT_KEY, on ? "1" : "0"); } catch (e) {}
+  }
+
+  // ---- Wire events ----
+  pads.forEach(function (pad) {
+    const i = parseInt(pad.getAttribute("data-i"), 10);
+    // Pointer events cover mouse + touch; prevent double-fire.
+    pad.addEventListener("pointerdown", function (ev) {
+      ev.preventDefault();
+      handlePress(i);
+    });
+    // keyboard access
+    pad.addEventListener("keydown", function (ev) {
+      if (ev.key === "Enter" || ev.key === " ") {
+        ev.preventDefault();
+        handlePress(i);
+      }
+    });
+  });
+
+  startBtn.addEventListener("click", function () {
+    ensureAudio();
+    startGame();
+  });
+
+  soundToggle.addEventListener("click", function () { setSound(!soundOn); });
+  soundToggle.addEventListener("keydown", function (ev) {
+    if (ev.key === "Enter" || ev.key === " ") { ev.preventDefault(); setSound(!soundOn); }
+  });
+
+  strictToggle.addEventListener("click", function () { setStrict(!strictOn); });
+  strictToggle.addEventListener("keydown", function (ev) {
+    if (ev.key === "Enter" || ev.key === " ") { ev.preventDefault(); setStrict(!strictOn); }
+  });
+
+  // number-key shortcuts 1-4
+  window.addEventListener("keydown", function (ev) {
+    if (ev.repeat) return;
+    const map = { "1": 0, "2": 1, "3": 2, "4": 3 };
+    if (ev.key in map) { handlePress(map[ev.key]); }
+    else if (ev.key === "Enter" && !playing) { ensureAudio(); startGame(); }
+  });
+
+  // ---- Init from storage ----
+  (function init() {
+    try {
+      const b = parseInt(localStorage.getItem(BEST_KEY) || "0", 10);
+      if (!isNaN(b) && b > 0) { best = b; bestVal.textContent = b; }
+    } catch (e) {}
+
+    let s = true, st = false;
+    try {
+      const sv = localStorage.getItem(SOUND_KEY);
+      if (sv !== null) s = sv === "1";
+      const stv = localStorage.getItem(STRICT_KEY);
+      if (stv !== null) st = stv === "1";
+    } catch (e) {}
+    setSound(s);
+    setStrict(st);
+  })();
+})();
+</script>
+</body>
+</html>
diff --git a/games/snake/AbramsSnake.aa b/games/snake/AbramsSnake.aa
new file mode 100644
index 0000000..60cb63c
--- /dev/null
+++ b/games/snake/AbramsSnake.aa
@@ -0,0 +1,211 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Abrams Snake</title>
+<style>
+  :root { --bg:#0a0e14; --grid:#121821; --snake:#4ade80; --head:#a7f3d0; --food:#f472b6; --ink:#e5e7eb; }
+  * { box-sizing:border-box; margin:0; padding:0; }
+  html,body { height:100%; }
+  body {
+    background:radial-gradient(1200px 600px at 50% -10%, #16202e, var(--bg));
+    color:var(--ink); font:15px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
+    display:flex; flex-direction:column; align-items:center; justify-content:center;
+    min-height:100%; gap:10px; padding:12px; overscroll-behavior:none; touch-action:none;
+  }
+  h1 { font-size:14px; letter-spacing:.28em; text-transform:uppercase; color:#93c5fd; font-weight:600; }
+  .hud { display:flex; gap:18px; font-variant-numeric:tabular-nums; font-size:13px; color:#9aa4b2; }
+  .hud b { color:var(--ink); font-weight:600; }
+  #wrap { position:relative; }
+  canvas { background:var(--grid); border-radius:12px; box-shadow:0 10px 40px rgba(0,0,0,.5); display:block; }
+  .overlay {
+    position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
+    gap:10px; text-align:center; background:rgba(8,12,18,.72); border-radius:12px; backdrop-filter:blur(2px);
+  }
+  .overlay.hide { display:none; }
+  .big { font-size:22px; font-weight:700; letter-spacing:.02em; }
+  .sub { font-size:13px; color:#9aa4b2; max-width:280px; }
+  .tag { font-size:11px; color:#93c5fd; letter-spacing:.2em; text-transform:uppercase; }
+  button.play {
+    margin-top:4px; padding:10px 22px; border:0; border-radius:999px; cursor:pointer;
+    background:linear-gradient(180deg,#60a5fa,#3b82f6); color:#fff; font-weight:700; font-size:14px;
+  }
+  .btns { position:absolute; top:8px; right:10px; display:flex; gap:6px; }
+  .btns button { width:30px; height:30px; border-radius:8px; border:1px solid #2a3441; background:#141b25; color:#cbd5e1; cursor:pointer; font-size:14px; }
+  .hint { font-size:11px; color:#5b6673; }
+</style>
+</head>
+<body>
+  <h1>Abrams Snake</h1>
+  <div class="hud"><span>Score <b id="score">0</b></span><span>Best <b id="best">0</b></span><span>Speed <b id="lvl">1</b></span></div>
+  <div id="wrap">
+    <canvas id="c" width="420" height="420"></canvas>
+    <div class="btns">
+      <button id="mute" title="Mute (M)">🔊</button>
+      <button id="pauseBtn" title="Pause (P)">⏸</button>
+    </div>
+    <div class="overlay" id="ov">
+      <div class="tag" id="ovTag">Ready</div>
+      <div class="big" id="ovTitle">Abrams Snake</div>
+      <div class="sub" id="ovSub">Eat the pink. Don't hit the walls or yourself. Arrows / WASD to steer, swipe on touch.</div>
+      <button class="play" id="playBtn">Play</button>
+      <div class="hint">P pause · M mute</div>
+    </div>
+  </div>
+
+<script>
+(function () {
+  var cv = document.getElementById('c'), ctx = cv.getContext('2d');
+  var N = 21, CELL = cv.width / N;               // 21x21 grid
+  var scoreEl = document.getElementById('score'), bestEl = document.getElementById('best'), lvlEl = document.getElementById('lvl');
+  var ov = document.getElementById('ov'), ovTag = document.getElementById('ovTag'), ovTitle = document.getElementById('ovTitle'), ovSub = document.getElementById('ovSub');
+  var playBtn = document.getElementById('playBtn'), pauseBtn = document.getElementById('pauseBtn'), muteBtn = document.getElementById('mute');
+
+  var BEST_KEY = 'abrams-snake-best';
+  var best = parseInt(localStorage.getItem(BEST_KEY) || '0', 10) || 0; bestEl.textContent = best;
+
+  var snake, dir, nextDir, food, score, alive, running, paused, muted = false;
+  var stepMs, acc = 0, last = 0;
+
+  // ---- audio (procedural, zero-dep) ----
+  var actx = null;
+  function beep(freq, dur, type, vol) {
+    if (muted) return;
+    try {
+      if (!actx) actx = new (window.AudioContext || window.webkitAudioContext)();
+      var o = actx.createOscillator(), g = actx.createGain();
+      o.type = type || 'square'; o.frequency.value = freq;
+      g.gain.value = vol || 0.05;
+      o.connect(g); g.connect(actx.destination);
+      var t = actx.currentTime; o.start(t);
+      g.gain.exponentialRampToValueAtTime(0.0001, t + (dur || 0.09));
+      o.stop(t + (dur || 0.09));
+    } catch (e) {}
+  }
+
+  function reset() {
+    snake = [{ x: 10, y: 10 }, { x: 9, y: 10 }, { x: 8, y: 10 }];
+    dir = { x: 1, y: 0 }; nextDir = dir;
+    score = 0; alive = true; stepMs = 130; acc = 0;
+    placeFood(); updateHud();
+  }
+  function placeFood() {
+    do { food = { x: (Math.random() * N) | 0, y: (Math.random() * N) | 0 }; }
+    while (snake.some(function (s) { return s.x === food.x && s.y === food.y; }));
+  }
+  function updateHud() {
+    scoreEl.textContent = score;
+    lvlEl.textContent = Math.max(1, Math.min(9, 1 + ((score / 5) | 0)));
+  }
+
+  function step() {
+    dir = nextDir;
+    var head = { x: snake[0].x + dir.x, y: snake[0].y + dir.y };
+    // wall or self collision = death
+    if (head.x < 0 || head.y < 0 || head.x >= N || head.y >= N ||
+        snake.some(function (s) { return s.x === head.x && s.y === head.y; })) {
+      die(); return;
+    }
+    snake.unshift(head);
+    if (head.x === food.x && head.y === food.y) {
+      score++; updateHud(); beep(660, 0.08, 'square', 0.06);
+      stepMs = Math.max(60, 130 - score * 4);   // speed up
+      placeFood();
+    } else {
+      snake.pop();
+    }
+  }
+
+  function die() {
+    alive = false; running = false; beep(160, 0.3, 'sawtooth', 0.08);
+    if (score > best) { best = score; localStorage.setItem(BEST_KEY, best); bestEl.textContent = best; }
+    ovTag.textContent = score >= best && score > 0 ? 'New Best!' : 'Game Over';
+    ovTitle.textContent = 'Score ' + score;
+    ovSub.textContent = 'Best ' + best + '. Press Play or hit Space to go again.';
+    playBtn.textContent = 'Play again';
+    ov.classList.remove('hide');
+  }
+
+  function draw() {
+    ctx.clearRect(0, 0, cv.width, cv.height);
+    // subtle grid dots
+    ctx.fillStyle = 'rgba(255,255,255,0.03)';
+    for (var i = 0; i < N; i++) for (var j = 0; j < N; j++) ctx.fillRect(i * CELL + CELL / 2 - 1, j * CELL + CELL / 2 - 1, 2, 2);
+    // food
+    ctx.fillStyle = '#f472b6';
+    roundRect(food.x * CELL + 3, food.y * CELL + 3, CELL - 6, CELL - 6, 5); ctx.fill();
+    // snake
+    for (var k = snake.length - 1; k >= 0; k--) {
+      ctx.fillStyle = k === 0 ? '#a7f3d0' : 'rgba(74,222,128,' + (0.55 + 0.45 * (1 - k / snake.length)) + ')';
+      roundRect(snake[k].x * CELL + 2, snake[k].y * CELL + 2, CELL - 4, CELL - 4, 5); ctx.fill();
+    }
+  }
+  function roundRect(x, y, w, h, r) {
+    ctx.beginPath();
+    ctx.moveTo(x + r, y); ctx.arcTo(x + w, y, x + w, y + h, r); ctx.arcTo(x + w, y + h, x, y + h, r);
+    ctx.arcTo(x, y + h, x, y, r); ctx.arcTo(x, y, x + w, y, r); ctx.closePath();
+  }
+
+  function loop(ts) {
+    requestAnimationFrame(loop);
+    if (!running || paused) { last = ts; return; }
+    if (!last) last = ts;
+    acc += ts - last; last = ts;
+    while (acc >= stepMs) { acc -= stepMs; if (alive) step(); }
+    draw();
+  }
+
+  function start() {
+    reset(); running = true; paused = false; last = 0;
+    ov.classList.add('hide'); draw();
+    if (actx && actx.state === 'suspended') actx.resume();
+  }
+  function togglePause() {
+    if (!running) return;
+    paused = !paused;
+    pauseBtn.textContent = paused ? '▶' : '⏸';
+    if (paused) { ovTag.textContent = 'Paused'; ovTitle.textContent = 'Paused'; ovSub.textContent = 'Press P to resume.'; playBtn.textContent = 'Resume'; ov.classList.remove('hide'); }
+    else { ov.classList.add('hide'); last = 0; }
+  }
+
+  function setDir(x, y) {
+    // no 180° reversal
+    if (x === -dir.x && y === -dir.y) return;
+    nextDir = { x: x, y: y };
+  }
+
+  // ---- input ----
+  window.addEventListener('keydown', function (e) {
+    var k = e.key.toLowerCase();
+    if (k === 'arrowup' || k === 'w') { setDir(0, -1); e.preventDefault(); }
+    else if (k === 'arrowdown' || k === 's') { setDir(0, 1); e.preventDefault(); }
+    else if (k === 'arrowleft' || k === 'a') { setDir(-1, 0); e.preventDefault(); }
+    else if (k === 'arrowright' || k === 'd') { setDir(1, 0); e.preventDefault(); }
+    else if (k === 'p' || k === 'escape') { togglePause(); }
+    else if (k === 'm') { toggleMute(); }
+    else if (k === ' ') { if (!running) start(); e.preventDefault(); }
+  });
+  playBtn.addEventListener('click', function () { if (paused) { togglePause(); } else { start(); } });
+  pauseBtn.addEventListener('click', togglePause);
+  function toggleMute() { muted = !muted; muteBtn.textContent = muted ? '🔈' : '🔊'; }
+  muteBtn.addEventListener('click', toggleMute);
+
+  // touch swipe
+  var tsx = 0, tsy = 0;
+  cv.addEventListener('touchstart', function (e) { var t = e.touches[0]; tsx = t.clientX; tsy = t.clientY; }, { passive: true });
+  cv.addEventListener('touchend', function (e) {
+    var t = e.changedTouches[0], dx = t.clientX - tsx, dy = t.clientY - tsy;
+    if (Math.abs(dx) < 12 && Math.abs(dy) < 12) { if (!running) start(); return; }
+    if (Math.abs(dx) > Math.abs(dy)) setDir(dx > 0 ? 1 : -1, 0); else setDir(0, dy > 0 ? 1 : -1);
+  }, { passive: true });
+
+  // pause when iframe loses focus
+  window.addEventListener('blur', function () { if (running && !paused) togglePause(); });
+
+  reset(); draw();
+  requestAnimationFrame(loop);
+})();
+</script>
+</body>
+</html>
diff --git a/games/sokoban/NeonSokoban.aa b/games/sokoban/NeonSokoban.aa
new file mode 100644
index 0000000..88a4a2b
--- /dev/null
+++ b/games/sokoban/NeonSokoban.aa
@@ -0,0 +1,712 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>NEON SOKOBAN</title>
+<style>
+  :root{
+    --bg:#0a0e14;
+    --panel:#0f1622;
+    --wall:#1b2a44;
+    --wall-glow:#2f6bff;
+    --floor:#0d131e;
+    --crate:#f0a500;
+    --crate-done:#2ee6a6;
+    --target:#ff3d81;
+    --player:#41d6ff;
+    --ink:#cfe3ff;
+    --ink-dim:#6f86a8;
+  }
+  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
+  html,body{margin:0;padding:0;height:100%;}
+  body{
+    background:var(--bg);
+    color:var(--ink);
+    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
+    display:flex;flex-direction:column;align-items:center;
+    min-height:100%;
+    touch-action:none;
+    overflow:hidden;
+    user-select:none;-webkit-user-select:none;
+  }
+  #app{
+    width:100%;max-width:640px;
+    display:flex;flex-direction:column;
+    height:100vh;height:100dvh;
+    padding:8px;
+  }
+  header{flex:0 0 auto;text-align:center;padding:2px 0 6px;}
+  h1{
+    margin:0;
+    font-size:clamp(16px,5vw,26px);
+    font-weight:800;
+    letter-spacing:0.42em;
+    text-transform:uppercase;
+    color:var(--player);
+    text-shadow:0 0 8px rgba(65,214,255,.55),0 0 22px rgba(65,214,255,.25);
+    padding-left:0.42em;
+  }
+  .bar{
+    display:flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:center;
+    flex:0 0 auto;margin:2px 0 6px;
+  }
+  select,button{
+    font-family:inherit;font-size:13px;
+    background:var(--panel);color:var(--ink);
+    border:1px solid #24344f;border-radius:8px;
+    padding:7px 10px;cursor:pointer;
+    transition:border-color .12s,background .12s,transform .05s;
+  }
+  button:hover,select:hover{border-color:var(--wall-glow);}
+  button:active{transform:translateY(1px);}
+  .stats{
+    display:flex;gap:14px;justify-content:center;flex-wrap:wrap;
+    font-size:12px;letter-spacing:.08em;color:var(--ink-dim);
+    text-transform:uppercase;flex:0 0 auto;margin-bottom:4px;
+  }
+  .stats b{color:var(--ink);font-weight:700;}
+  .stats .solved{color:var(--crate-done);}
+  #boardWrap{
+    flex:1 1 auto;
+    display:flex;align-items:center;justify-content:center;
+    min-height:0;position:relative;
+  }
+  canvas{
+    display:block;
+    image-rendering:auto;
+    border-radius:10px;
+    background:var(--floor);
+    box-shadow:0 0 0 1px #1a2740, 0 8px 30px rgba(0,0,0,.5);
+    touch-action:none;
+  }
+  #win{
+    position:absolute;inset:0;display:none;
+    align-items:center;justify-content:center;flex-direction:column;
+    background:rgba(6,10,16,.82);border-radius:10px;text-align:center;
+    gap:12px;padding:16px;
+  }
+  #win.show{display:flex;}
+  #win .big{
+    font-size:clamp(22px,7vw,40px);font-weight:800;letter-spacing:.3em;
+    color:var(--crate-done);text-shadow:0 0 16px rgba(46,230,166,.6);
+    text-transform:uppercase;padding-left:.3em;
+  }
+  #win .sub{font-size:13px;color:var(--ink);letter-spacing:.06em;}
+  #controls{
+    flex:0 0 auto;
+    display:flex;align-items:center;justify-content:space-between;
+    gap:10px;padding:8px 4px 12px;
+  }
+  #dpad{
+    display:grid;
+    grid-template-columns:repeat(3,54px);
+    grid-template-rows:repeat(3,54px);
+    gap:6px;
+  }
+  #dpad button{
+    font-size:22px;padding:0;border-radius:12px;
+    display:flex;align-items:center;justify-content:center;
+    color:var(--player);background:#101a2b;border-color:#22344f;
+  }
+  #dpad button:active{background:#16233a;box-shadow:0 0 12px rgba(65,214,255,.35) inset;}
+  .du{grid-column:2;grid-row:1;}
+  .dl{grid-column:1;grid-row:2;}
+  .dr{grid-column:3;grid-row:2;}
+  .dd{grid-column:2;grid-row:3;}
+  #dpad .ctr{grid-column:2;grid-row:2;visibility:hidden;}
+  #sideBtns{display:flex;flex-direction:column;gap:8px;}
+  #sideBtns button{min-width:88px;font-weight:700;letter-spacing:.08em;}
+  #btnUndo{color:var(--crate);border-color:#3a2f12;}
+  #btnReset{color:var(--target);border-color:#3a1424;}
+  .hint{font-size:10px;color:var(--ink-dim);letter-spacing:.06em;text-align:center;flex:0 0 auto;padding-bottom:4px;}
+  @media (max-height:620px){
+    #dpad{grid-template-columns:repeat(3,46px);grid-template-rows:repeat(3,46px);}
+    h1{font-size:16px;}
+  }
+</style>
+</head>
+<body>
+<div id="app">
+  <header><h1>Neon Sokoban</h1></header>
+  <div class="bar">
+    <select id="levelSelect" aria-label="Select level"></select>
+    <button id="btnPrev">◀ Prev</button>
+    <button id="btnNext">Next ▶</button>
+  </div>
+  <div class="stats">
+    <span>Level <b id="statLevel">1</b></span>
+    <span>Moves <b id="statMoves">0</b></span>
+    <span>Pushes <b id="statPushes">0</b></span>
+    <span>Best <b id="statBest">—</b></span>
+    <span class="solved" id="statSolved"></span>
+  </div>
+  <div id="boardWrap">
+    <canvas id="board"></canvas>
+    <div id="win">
+      <div class="big">Solved</div>
+      <div class="sub" id="winSub"></div>
+      <button id="btnWinNext">Next Level ▶</button>
+    </div>
+  </div>
+  <div id="controls">
+    <div id="dpad">
+      <button class="du" data-dir="up" aria-label="Up">▲</button>
+      <button class="dl" data-dir="left" aria-label="Left">◀</button>
+      <span class="ctr"></span>
+      <button class="dr" data-dir="right" aria-label="Right">▶</button>
+      <button class="dd" data-dir="down" aria-label="Down">▼</button>
+    </div>
+    <div id="sideBtns">
+      <button id="btnUndo">↶ UNDO</button>
+      <button id="btnReset">⟳ RESET</button>
+    </div>
+  </div>
+  <div class="hint">Arrows / WASD move · U undo · R reset</div>
+</div>
+<script>
+(function(){
+  "use strict";
+
+  // ---- Level data (ASCII). # wall, space floor, . target, $ crate, * crate-on-target, @ player, + player-on-target ----
+  var LEVELS = [
+    { name:"Warmup", grid:[
+      "#####",
+      "#@$.#",
+      "#####"
+    ]},
+    { name:"Corner", grid:[
+      "######",
+      "#.   #",
+      "# $$ #",
+      "# $. #",
+      "#. @ #",
+      "######"
+    ]},
+    { name:"Twist", grid:[
+      "  #####",
+      "###   #",
+      "#.@$  #",
+      "### $.#",
+      "#.##$ #",
+      "# # . ##",
+      "#$ *$$.#",
+      "#   .  #",
+      "########"
+    ]},
+    { name:"Detour", grid:[
+      "########",
+      "#      #",
+      "# .$.  #",
+      "# $@$  #",
+      "# .$.  #",
+      "#      #",
+      "########"
+    ]},
+    { name:"Chamber", grid:[
+      "#######",
+      "#  .  #",
+      "# $#$ #",
+      "#. @ .#",
+      "# $#$ #",
+      "#  .  #",
+      "#######"
+    ]},
+    { name:"Zigzag", grid:[
+      "########",
+      "#      #",
+      "# $ $  #",
+      "#.##.# #",
+      "# $ @  #",
+      "#.## # #",
+      "#      #",
+      "########"
+    ]},
+    { name:"Lockbox", grid:[
+      "#########",
+      "#   #   #",
+      "# $ # . #",
+      "# $ #.. #",
+      "# @ $   #",
+      "#   #   #",
+      "#########"
+    ]},
+    { name:"Gauntlet", grid:[
+      "########",
+      "#. #   #",
+      "#. $$@ #",
+      "#. $ $ #",
+      "#.     #",
+      "#      #",
+      "########"
+    ]},
+    { name:"Spiral", grid:[
+      "########",
+      "#. .  .#",
+      "# $$$  #",
+      "#  @   #",
+      "# $$$  #",
+      "#. .  .#",
+      "########"
+    ]},
+    { name:"Vault", grid:[
+      "#########",
+      "#  ...  #",
+      "#  $$$  #",
+      "#  $@   #",
+      "#  $$   #",
+      "#  ...  #",
+      "#########"
+    ]}
+  ];
+
+  var STORE_KEY = "abrams-sokoban";
+
+  // ---- Tile constants ----
+  var WALL=1, FLOOR=0, TARGET=2;
+
+  // ---- State ----
+  var state = null; // { statics, w, h, crates(Set of index), player, targets(Set), moves, pushes, history[] }
+  var current = 0;
+  var progress = loadProgress();
+
+  var canvas = document.getElementById("board");
+  var ctx = canvas.getContext("2d");
+  var cell = 32;
+
+  function loadProgress(){
+    try{
+      var raw = localStorage.getItem(STORE_KEY);
+      if(!raw) return {};
+      var p = JSON.parse(raw);
+      return (p && typeof p === "object") ? p : {};
+    }catch(e){ return {}; }
+  }
+  function saveProgress(){
+    try{ localStorage.setItem(STORE_KEY, JSON.stringify(progress)); }catch(e){}
+  }
+
+  function idx(x,y,w){ return y*w + x; }
+
+  // Parse a level into a fresh state object
+  function buildState(levelIndex){
+    var grid = LEVELS[levelIndex].grid;
+    var h = grid.length;
+    var w = 0;
+    for(var i=0;i<h;i++){ if(grid[i].length>w) w = grid[i].length; }
+    var statics = new Array(w*h); // WALL / FLOOR / TARGET
+    var crates = {}; // index -> true
+    var targets = {};
+    var player = 0;
+    for(var y=0;y<h;y++){
+      var row = grid[y];
+      for(var x=0;x<w;x++){
+        var ch = x < row.length ? row[x] : " ";
+        var index = idx(x,y,w);
+        var isTarget=false, isCrate=false, isPlayer=false, isWall=false;
+        switch(ch){
+          case "#": isWall=true; break;
+          case ".": isTarget=true; break;
+          case "$": isCrate=true; break;
+          case "*": isCrate=true; isTarget=true; break;
+          case "@": isPlayer=true; break;
+          case "+": isPlayer=true; isTarget=true; break;
+          default: break; // space => floor
+        }
+        statics[index] = isWall ? WALL : (isTarget ? TARGET : FLOOR);
+        if(isTarget) targets[index]=true;
+        if(isCrate) crates[index]=true;
+        if(isPlayer) player=index;
+      }
+    }
+    return {
+      w:w, h:h, statics:statics,
+      crates:crates, targets:targets,
+      player:player, moves:0, pushes:0,
+      history:[]
+    };
+  }
+
+  var DIRS = {
+    up:   {dx:0, dy:-1},
+    down: {dx:0, dy:1},
+    left: {dx:-1,dy:0},
+    right:{dx:1, dy:0}
+  };
+
+  function isWall(s,index){ return s.statics[index] === WALL; }
+
+  function tryMove(dir){
+    if(!state) return;
+    var d = DIRS[dir];
+    if(!d) return;
+    var s = state;
+    var w = s.w;
+    var px = s.player % w, py = (s.player - (s.player%w))/w;
+    var nx = px + d.dx, ny = py + d.dy;
+    if(nx<0||ny<0||nx>=w||ny>=s.h) return;
+    var nIndex = idx(nx,ny,w);
+    if(isWall(s,nIndex)) return;
+
+    var pushed = false;
+    if(s.crates[nIndex]){
+      // crate ahead — check the cell beyond
+      var bx = nx + d.dx, by = ny + d.dy;
+      if(bx<0||by<0||bx>=w||by>=s.h) return;
+      var bIndex = idx(bx,by,w);
+      if(isWall(s,bIndex) || s.crates[bIndex]) return; // blocked
+      // move crate
+      delete s.crates[nIndex];
+      s.crates[bIndex] = true;
+      pushed = true;
+    }
+    // record history for undo
+    s.history.push({ from:s.player, to:nIndex, pushed:pushed });
+    s.player = nIndex;
+    s.moves++;
+    if(pushed) s.pushes++;
+    render();
+    checkWin();
+  }
+
+  function undo(){
+    if(!state || state.history.length===0) return;
+    var s = state;
+    var last = s.history.pop();
+    // player moves back
+    s.player = last.from;
+    if(s.moves>0) s.moves--;
+    if(last.pushed){
+      // crate was pushed from 'to' to beyond; revert it
+      var w = s.w;
+      var tx = last.to % w, ty = (last.to - (last.to%w))/w;
+      var dx = tx - (last.from % w);
+      var dy = ty - ((last.from - (last.from%w))/w);
+      var bIndex = idx(tx+dx, ty+dy, w);
+      delete s.crates[bIndex];
+      s.crates[last.to] = true;
+      if(s.pushes>0) s.pushes--;
+    }
+    hideWin();
+    render();
+  }
+
+  function reset(){
+    state = buildState(current);
+    hideWin();
+    layout();
+    render();
+    updateStats();
+  }
+
+  function isSolved(s){
+    for(var t in s.targets){
+      if(!s.crates[t]) return false;
+    }
+    return true;
+  }
+
+  function checkWin(){
+    updateStats();
+    if(state && isSolved(state)){
+      recordSolve();
+      showWin();
+    }
+  }
+
+  function recordSolve(){
+    var key = String(current);
+    var rec = progress[key] || {};
+    rec.solved = true;
+    if(typeof rec.best !== "number" || state.moves < rec.best){
+      rec.best = state.moves;
+    }
+    progress[key] = rec;
+    saveProgress();
+    buildLevelSelect();
+    updateStats();
+  }
+
+  // ---- Rendering ----
+  function layout(){
+    if(!state) return;
+    var wrap = document.getElementById("boardWrap");
+    var availW = wrap.clientWidth - 4;
+    var availH = wrap.clientHeight - 4;
+    if(availW<=0) availW = 300;
+    if(availH<=0) availH = 300;
+    var c = Math.floor(Math.min(availW/state.w, availH/state.h));
+    c = Math.max(14, Math.min(c, 64));
+    cell = c;
+    canvas.width = state.w * cell;
+    canvas.height = state.h * cell;
+    canvas.style.width = canvas.width + "px";
+    canvas.style.height = canvas.height + "px";
+  }
+
+  function render(){
+    if(!state) return;
+    var s = state, w=s.w, h=s.h;
+    ctx.clearRect(0,0,canvas.width,canvas.height);
+    // floor bg
+    ctx.fillStyle = "#0d131e";
+    ctx.fillRect(0,0,canvas.width,canvas.height);
+
+    for(var y=0;y<h;y++){
+      for(var x=0;x<w;x++){
+        var index = idx(x,y,w);
+        var st = s.statics[index];
+        var px = x*cell, py=y*cell;
+        if(st===WALL){
+          drawWall(px,py);
+        } else {
+          drawFloor(px,py);
+          if(st===TARGET){ drawTarget(px,py); }
+        }
+      }
+    }
+    // crates
+    for(var ci in s.crates){
+      var i = +ci;
+      var cx = (i % w)*cell, cy = ((i-(i%w))/w)*cell;
+      var onTarget = s.statics[i]===TARGET;
+      drawCrate(cx,cy,onTarget);
+    }
+    // player
+    var pi = s.player;
+    var ppx = (pi % w)*cell, ppy = ((pi-(pi%w))/w)*cell;
+    drawPlayer(ppx,ppy);
+  }
+
+  function drawFloor(px,py){
+    ctx.fillStyle = "#0d131e";
+    ctx.fillRect(px,py,cell,cell);
+    ctx.strokeStyle = "rgba(40,60,95,.28)";
+    ctx.lineWidth = 1;
+    ctx.strokeRect(px+0.5,py+0.5,cell-1,cell-1);
+  }
+  function drawWall(px,py){
+    var g = ctx.createLinearGradient(px,py,px,py+cell);
+    g.addColorStop(0,"#20335a");
+    g.addColorStop(1,"#152340");
+    ctx.fillStyle = g;
+    ctx.fillRect(px,py,cell,cell);
+    ctx.strokeStyle = "rgba(47,107,255,.55)";
+    ctx.lineWidth = Math.max(1, cell*0.06);
+    ctx.strokeRect(px+ctx.lineWidth/2, py+ctx.lineWidth/2, cell-ctx.lineWidth, cell-ctx.lineWidth);
+  }
+  function drawTarget(px,py){
+    var cx = px+cell/2, cy=py+cell/2;
+    var r = cell*0.18;
+    ctx.save();
+    ctx.shadowColor = "rgba(255,61,129,.85)";
+    ctx.shadowBlur = cell*0.4;
+    ctx.strokeStyle = "#ff3d81";
+    ctx.lineWidth = Math.max(1.5, cell*0.07);
+    ctx.beginPath();
+    ctx.arc(cx,cy,r,0,Math.PI*2);
+    ctx.stroke();
+    ctx.restore();
+  }
+  function drawCrate(px,py,onTarget){
+    var pad = cell*0.12;
+    var x=px+pad, y=py+pad, sz=cell-pad*2;
+    var col = onTarget ? "#2ee6a6" : "#f0a500";
+    var glow = onTarget ? "rgba(46,230,166,.75)" : "rgba(240,165,0,.55)";
+    ctx.save();
+    ctx.shadowColor = glow;
+    ctx.shadowBlur = onTarget ? cell*0.5 : cell*0.28;
+    var g = ctx.createLinearGradient(x,y,x,y+sz);
+    g.addColorStop(0, onTarget ? "#3af0b4" : "#ffbe2e");
+    g.addColorStop(1, col);
+    ctx.fillStyle = g;
+    roundRect(x,y,sz,sz,cell*0.12);
+    ctx.fill();
+    ctx.restore();
+    // inner cross detail
+    ctx.strokeStyle = onTarget ? "rgba(6,30,22,.55)" : "rgba(60,40,0,.5)";
+    ctx.lineWidth = Math.max(1, cell*0.04);
+    ctx.beginPath();
+    ctx.moveTo(x,y); ctx.lineTo(x+sz,y+sz);
+    ctx.moveTo(x+sz,y); ctx.lineTo(x,y+sz);
+    ctx.stroke();
+  }
+  function drawPlayer(px,py){
+    var cx=px+cell/2, cy=py+cell/2;
+    var r = cell*0.32;
+    ctx.save();
+    ctx.shadowColor = "rgba(65,214,255,.85)";
+    ctx.shadowBlur = cell*0.45;
+    var g = ctx.createRadialGradient(cx,cy-r*0.3,r*0.2,cx,cy,r);
+    g.addColorStop(0,"#bff2ff");
+    g.addColorStop(1,"#41d6ff");
+    ctx.fillStyle = g;
+    ctx.beginPath();
+    ctx.arc(cx,cy,r,0,Math.PI*2);
+    ctx.fill();
+    ctx.restore();
+    ctx.strokeStyle = "rgba(10,40,55,.6)";
+    ctx.lineWidth = Math.max(1, cell*0.04);
+    ctx.beginPath();
+    ctx.arc(cx,cy,r,0,Math.PI*2);
+    ctx.stroke();
+  }
+  function roundRect(x,y,w,h,r){
+    r = Math.min(r, w/2, h/2);
+    ctx.beginPath();
+    ctx.moveTo(x+r,y);
+    ctx.arcTo(x+w,y,x+w,y+h,r);
+    ctx.arcTo(x+w,y+h,x,y+h,r);
+    ctx.arcTo(x,y+h,x,y,r);
+    ctx.arcTo(x,y,x+w,y,r);
+    ctx.closePath();
+  }
+
+  // ---- UI ----
+  function updateStats(){
+    document.getElementById("statLevel").textContent = String(current+1);
+    document.getElementById("statMoves").textContent = state ? String(state.moves) : "0";
+    document.getElementById("statPushes").textContent = state ? String(state.pushes) : "0";
+    var rec = progress[String(current)];
+    document.getElementById("statBest").textContent = (rec && typeof rec.best==="number") ? String(rec.best) : "—";
+    var solvedCount = 0;
+    for(var k in progress){ if(progress[k] && progress[k].solved) solvedCount++; }
+    document.getElementById("statSolved").textContent = solvedCount>0 ? ("✓ " + solvedCount + "/" + LEVELS.length + " solved") : "";
+  }
+
+  function buildLevelSelect(){
+    var sel = document.getElementById("levelSelect");
+    var prev = sel.value;
+    sel.innerHTML = "";
+    for(var i=0;i<LEVELS.length;i++){
+      var opt = document.createElement("option");
+      opt.value = String(i);
+      var rec = progress[String(i)];
+      var tag = (rec && rec.solved) ? " ✓" : "";
+      var best = (rec && typeof rec.best==="number") ? (" · " + rec.best) : "";
+      opt.textContent = (i+1) + ". " + LEVELS[i].name + tag + best;
+      sel.appendChild(opt);
+    }
+    sel.value = String(current);
+    if(prev==="" ){ /* noop */ }
+  }
+
+  function loadLevel(i){
+    if(i<0) i=0;
+    if(i>=LEVELS.length) i=LEVELS.length-1;
+    current = i;
+    document.getElementById("levelSelect").value = String(current);
+    reset();
+  }
+
+  function showWin(){
+    var el = document.getElementById("win");
+    var sub = document.getElementById("winSub");
+    var rec = progress[String(current)] || {};
+    var bestTxt = (typeof rec.best==="number") ? (" · Best " + rec.best) : "";
+    sub.textContent = state.moves + " moves · " + state.pushes + " pushes" + bestTxt;
+    var nextBtn = document.getElementById("btnWinNext");
+    nextBtn.style.display = (current < LEVELS.length-1) ? "" : "none";
+    el.classList.add("show");
+  }
+  function hideWin(){ document.getElementById("win").classList.remove("show"); }
+
+  // ---- Input ----
+  var KEYMAP = {
+    "ArrowUp":"up","ArrowDown":"down","ArrowLeft":"left","ArrowRight":"right",
+    "w":"up","s":"down","a":"left","d":"right",
+    "W":"up","S":"down","A":"left","D":"right"
+  };
+  window.addEventListener("keydown", function(e){
+    var k = e.key;
+    if(KEYMAP[k]){
+      e.preventDefault();
+      tryMove(KEYMAP[k]);
+      return;
+    }
+    if(k==="u"||k==="U"){ e.preventDefault(); undo(); return; }
+    if(k==="r"||k==="R"){ e.preventDefault(); reset(); return; }
+    if(k==="n"||k==="N"){ e.preventDefault(); loadLevel(current+1); return; }
+  }, {passive:false});
+
+  // Prevent arrow/space page scroll fallback
+  window.addEventListener("keydown", function(e){
+    if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"," "].indexOf(e.key) !== -1){
+      e.preventDefault();
+    }
+  }, {passive:false});
+
+  function bindTap(el, fn){
+    if(!el) return;
+    el.addEventListener("click", function(e){ e.preventDefault(); fn(); });
+    el.addEventListener("touchstart", function(e){ e.preventDefault(); fn(); }, {passive:false});
+  }
+
+  var dpadBtns = document.querySelectorAll("#dpad button[data-dir]");
+  for(var i=0;i<dpadBtns.length;i++){
+    (function(btn){
+      var dir = btn.getAttribute("data-dir");
+      btn.addEventListener("click", function(e){ e.preventDefault(); tryMove(dir); });
+      btn.addEventListener("touchstart", function(e){ e.preventDefault(); tryMove(dir); }, {passive:false});
+    })(dpadBtns[i]);
+  }
+
+  bindTap(document.getElementById("btnUndo"), undo);
+  bindTap(document.getElementById("btnReset"), reset);
+  bindTap(document.getElementById("btnPrev"), function(){ loadLevel(current-1); });
+  bindTap(document.getElementById("btnNext"), function(){ loadLevel(current+1); });
+  bindTap(document.getElementById("btnWinNext"), function(){ loadLevel(current+1); });
+
+  document.getElementById("levelSelect").addEventListener("change", function(e){
+    loadLevel(parseInt(e.target.value,10)||0);
+  });
+
+  // Swipe on canvas
+  var touchStart = null;
+  canvas.addEventListener("touchstart", function(e){
+    if(e.touches.length===1){
+      touchStart = {x:e.touches[0].clientX, y:e.touches[0].clientY};
+    }
+  }, {passive:true});
+  canvas.addEventListener("touchend", function(e){
+    if(!touchStart) return;
+    var t = e.changedTouches[0];
+    var dx = t.clientX - touchStart.x;
+    var dy = t.clientY - touchStart.y;
+    touchStart = null;
+    var ax = Math.abs(dx), ay = Math.abs(dy);
+    if(Math.max(ax,ay) < 22) return;
+    if(ax>ay){ tryMove(dx>0?"right":"left"); }
+    else{ tryMove(dy>0?"down":"up"); }
+  }, {passive:true});
+
+  var resizeTimer = null;
+  window.addEventListener("resize", function(){
+    if(resizeTimer) clearTimeout(resizeTimer);
+    resizeTimer = setTimeout(function(){ layout(); render(); }, 60);
+  });
+
+  // ---- Init (guarded until DOM ready) ----
+  function init(){
+    buildLevelSelect();
+    // start at first unsolved level, else level 0
+    var start = 0;
+    for(var i=0;i<LEVELS.length;i++){
+      var rec = progress[String(i)];
+      if(!rec || !rec.solved){ start = i; break; }
+    }
+    current = start;
+    loadLevel(current);
+    // second layout pass after fonts/flex settle
+    setTimeout(function(){ layout(); render(); }, 50);
+  }
+
+  if(document.readyState === "loading"){
+    document.addEventListener("DOMContentLoaded", init);
+  } else {
+    init();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/spirograph/Spirograph.aa b/games/spirograph/Spirograph.aa
new file mode 100644
index 0000000..1d7b450
--- /dev/null
+++ b/games/spirograph/Spirograph.aa
@@ -0,0 +1,495 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Spirograph Studio</title>
+<style>
+  :root{
+    --bg:#0d0f1a; --panel:#161a2e; --panel2:#1e2340;
+    --ink:#e8ecff; --muted:#8b91b8; --accent:#5eead4; --accent2:#a78bfa;
+    --line:#2a3055;
+  }
+  *{box-sizing:border-box}
+  [hidden]{display:none!important}
+  html,body{height:100%}
+  body{
+    margin:0; font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
+    background:radial-gradient(1200px 800px at 70% -10%,#1b2145 0%,var(--bg) 55%);
+    color:var(--ink); display:flex; min-height:100%; overflow:hidden;
+  }
+  .wrap{display:flex; width:100%; height:100vh}
+  .stage{
+    flex:1; display:flex; align-items:center; justify-content:center;
+    position:relative; padding:24px; min-width:0;
+  }
+  #canvas{
+    background:#07080f;
+    border-radius:16px;
+    box-shadow:0 20px 60px rgba(0,0,0,.55), inset 0 0 0 1px rgba(255,255,255,.04);
+    max-width:100%; max-height:100%;
+    touch-action:none;
+  }
+  .panel{
+    width:320px; flex-shrink:0; background:linear-gradient(180deg,var(--panel),var(--panel2));
+    border-left:1px solid var(--line);
+    padding:22px 22px 26px; display:flex; flex-direction:column; gap:18px;
+    overflow-y:auto;
+  }
+  .brand{display:flex; align-items:center; gap:11px}
+  .brand .dot{
+    width:30px;height:30px;border-radius:9px;
+    background:conic-gradient(from 0deg,var(--accent),var(--accent2),#f472b6,var(--accent));
+    box-shadow:0 0 18px rgba(94,234,212,.4);
+  }
+  .brand h1{font-size:17px; margin:0; letter-spacing:.4px; font-weight:650}
+  .brand span{font-size:11px; color:var(--muted); display:block; margin-top:1px; letter-spacing:.5px}
+
+  .ctrl{display:flex; flex-direction:column; gap:8px}
+  .ctrl label{display:flex; justify-content:space-between; align-items:baseline; font-size:12.5px; color:var(--muted); letter-spacing:.3px}
+  .ctrl label b{color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums; font-size:13px}
+  input[type=range]{
+    -webkit-appearance:none; appearance:none; width:100%; height:6px; border-radius:6px;
+    background:linear-gradient(90deg,var(--accent),var(--accent2)); outline:none; cursor:pointer;
+  }
+  input[type=range]::-webkit-slider-thumb{
+    -webkit-appearance:none; width:18px;height:18px;border-radius:50%;
+    background:#fff; border:3px solid var(--accent); box-shadow:0 2px 8px rgba(0,0,0,.5); cursor:pointer;
+  }
+  input[type=range]::-moz-range-thumb{
+    width:16px;height:16px;border-radius:50%; background:#fff; border:3px solid var(--accent); cursor:pointer;
+  }
+  select{
+    width:100%; font:inherit; font-size:12.5px; color:var(--ink);
+    background:rgba(255,255,255,.04); border:1px solid var(--line); border-radius:9px;
+    padding:8px 10px; cursor:pointer; outline:none;
+  }
+  select:focus{border-color:var(--accent2)}
+  input[type=color]{
+    -webkit-appearance:none; appearance:none; width:34px; height:26px; padding:0;
+    border:1px solid var(--line); border-radius:7px; background:none; cursor:pointer;
+  }
+  input[type=color]::-webkit-color-swatch-wrapper{padding:2px}
+  input[type=color]::-webkit-color-swatch{border:none; border-radius:5px}
+  .colorwrap{display:flex; align-items:center; gap:10px}
+  .row{display:flex; gap:10px}
+  .toggle{
+    display:flex; align-items:center; justify-content:space-between; gap:10px;
+    font-size:12.5px; color:var(--muted); background:rgba(255,255,255,.03);
+    padding:10px 12px; border-radius:10px; border:1px solid var(--line);
+  }
+  .switch{position:relative; width:42px; height:23px; flex-shrink:0}
+  .switch input{opacity:0; width:0; height:0}
+  .slider-sw{
+    position:absolute; inset:0; background:#3a4066; border-radius:23px; transition:.2s; cursor:pointer;
+  }
+  .slider-sw:before{
+    content:""; position:absolute; height:17px; width:17px; left:3px; top:3px;
+    background:#fff; border-radius:50%; transition:.2s;
+  }
+  .switch input:checked + .slider-sw{background:linear-gradient(90deg,var(--accent),var(--accent2))}
+  .switch input:checked + .slider-sw:before{transform:translateX(19px)}
+
+  button{
+    flex:1; font:inherit; font-size:13px; font-weight:600; letter-spacing:.3px;
+    padding:12px 10px; border-radius:11px; border:1px solid var(--line);
+    background:rgba(255,255,255,.04); color:var(--ink); cursor:pointer; transition:.15s;
+  }
+  button:hover{background:rgba(255,255,255,.09); transform:translateY(-1px)}
+  button:active{transform:translateY(0)}
+  button.primary{
+    background:linear-gradient(90deg,var(--accent),var(--accent2)); color:#0b0d18; border:none;
+  }
+  button.primary:hover{filter:brightness(1.08)}
+  .seg{display:flex; gap:6px; flex-wrap:wrap}
+  .seg button{flex:1 1 auto; padding:8px 6px; font-size:11.5px; font-weight:600}
+
+  .readout{
+    font-size:11px; color:var(--muted); line-height:1.6; letter-spacing:.2px;
+    background:rgba(255,255,255,.02); border:1px solid var(--line); border-radius:9px; padding:9px 11px;
+    font-variant-numeric:tabular-nums;
+  }
+  .readout b{color:var(--accent)}
+  .foot{margin-top:auto; font-size:11px; color:var(--muted); line-height:1.5; letter-spacing:.2px}
+  .hint{font-size:11px; color:var(--muted); margin-top:-4px}
+  kbd{
+    font-family:ui-monospace,monospace; font-size:10px; background:rgba(255,255,255,.06);
+    border:1px solid var(--line); border-bottom-width:2px; border-radius:5px; padding:1px 5px; color:var(--ink);
+  }
+  @media (max-width:760px){
+    body{overflow:auto}
+    .wrap{flex-direction:column; height:auto}
+    .panel{width:100%; border-left:none; border-top:1px solid var(--line)}
+    .stage{padding:16px; min-height:56vh}
+  }
+</style>
+</head>
+<body>
+<div class="wrap">
+  <div class="stage">
+    <canvas id="canvas"></canvas>
+  </div>
+
+  <aside class="panel">
+    <div class="brand">
+      <div class="dot"></div>
+      <div>
+        <h1>Spirograph Studio</h1>
+        <span>HYPOTROCHOID PLOTTER</span>
+      </div>
+    </div>
+
+    <div class="ctrl">
+      <label>Fixed gear radius <span>R</span> <b id="vR">140</b></label>
+      <input type="range" id="R" min="40" max="230" value="140" step="1">
+    </div>
+
+    <div class="ctrl">
+      <label>Rolling gear radius <span>r</span> <b id="vr">53</b></label>
+      <input type="range" id="r" min="8" max="220" value="53" step="1">
+    </div>
+
+    <div class="ctrl">
+      <label>Pen offset <span>d</span> <b id="vd">78</b></label>
+      <input type="range" id="d" min="0" max="180" value="78" step="1">
+    </div>
+
+    <div class="ctrl">
+      <label>Speed <b id="vs">6</b></label>
+      <input type="range" id="speed" min="1" max="40" value="6" step="1">
+    </div>
+
+    <div class="ctrl">
+      <label>Line width <b id="vw">1.6</b></label>
+      <input type="range" id="lw" min="0.4" max="6" value="1.6" step="0.1">
+    </div>
+
+    <div class="ctrl">
+      <label>Color mode</label>
+      <select id="colormode">
+        <option value="cycle">Rainbow — cycle</option>
+        <option value="angle">Rainbow — by angle</option>
+        <option value="solid">Solid</option>
+      </select>
+    </div>
+
+    <div class="ctrl" id="solidRow" hidden>
+      <label>Ink color</label>
+      <div class="colorwrap">
+        <input type="color" id="ink" value="#5eead4">
+        <span class="hint" style="margin:0">used in Solid mode</span>
+      </div>
+    </div>
+
+    <div class="toggle">
+      <span>Show gears</span>
+      <label class="switch"><input type="checkbox" id="gears" checked><span class="slider-sw"></span></label>
+    </div>
+
+    <div class="toggle">
+      <span>Glow</span>
+      <label class="switch"><input type="checkbox" id="glow"><span class="slider-sw"></span></label>
+    </div>
+
+    <div class="ctrl">
+      <label>Presets</label>
+      <div class="seg">
+        <button data-preset="rose">Rose</button>
+        <button data-preset="star">Star</button>
+        <button data-preset="web">Web</button>
+        <button data-preset="loop">Loops</button>
+      </div>
+    </div>
+
+    <div class="row">
+      <button id="play" class="primary">⏸ Pause</button>
+      <button id="random">🎲 Random</button>
+    </div>
+    <div class="row">
+      <button id="clear">Clear</button>
+      <button id="save" class="primary">Save PNG</button>
+    </div>
+
+    <div class="readout" id="readout">—</div>
+
+    <div class="hint">
+      <kbd>Space</kbd> play/pause · <kbd>C</kbd> clear · <kbd>R</kbd> random · <kbd>S</kbd> save
+    </div>
+
+    <div class="foot">
+      Curve: x = (R−r)·cos t + d·cos((R−r)/r·t)<br>
+      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = (R−r)·sin t − d·sin((R−r)/r·t)
+    </div>
+  </aside>
+</div>
+
+<script>
+(function(){
+  "use strict";
+  const canvas = document.getElementById('canvas');
+  const ctx = canvas.getContext('2d');
+
+  // Logical drawing size (device-independent). Backing stores are scaled by DPR
+  // so the curve is crisp on retina displays — the original blurred on hi-DPI.
+  const W = 760, H = 760;
+  const cx = W/2, cy = H/2;
+  const DPR = Math.min(window.devicePixelRatio || 1, 2);
+
+  canvas.width = W*DPR; canvas.height = H*DPR;
+  canvas.style.width = W+'px'; canvas.style.height = H+'px';
+  ctx.scale(DPR, DPR);
+
+  // Offscreen trail layer (persists between frames; gear overlay is drawn fresh each frame)
+  const trail = document.createElement('canvas');
+  trail.width = W*DPR; trail.height = H*DPR;
+  const tctx = trail.getContext('2d');
+  tctx.scale(DPR, DPR);
+
+  // Controls
+  const el = id => document.getElementById(id);
+  const R = el('R'), r = el('r'), d = el('d'), speed = el('speed'), lw = el('lw');
+  const colormode = el('colormode'), ink = el('ink');
+  const gears = el('gears'), glow = el('glow');
+  const vR=el('vR'), vr=el('vr'), vd=el('vd'), vs=el('vs'), vw=el('vw');
+  const readout = el('readout'), playBtn = el('play'), solidRow = el('solidRow');
+
+  // Drawing state
+  let t = 0;                    // parameter angle
+  let hue = Math.random()*360;
+  let lastPt = null;            // last plotted point on the persistent trail
+  let period = 0;               // t value at which the curve closes
+  let running = true;
+  let laps = 0;                 // completed closed patterns since last clear
+
+  const num  = inp => parseFloat(inp.value);
+  const inti = inp => parseInt(inp.value,10);
+
+  function gcd(a,b){ a=Math.round(a); b=Math.round(b); while(b){ const tmp=a%b; a=b; b=tmp; } return a||1; }
+
+  function computePeriod(){
+    const rr = Math.max(1, inti(r));
+    const RR = inti(R);
+    // Full pattern closes after r/gcd(R,r) revolutions of the driving angle.
+    const revs = rr / gcd(RR, rr);
+    period = 2*Math.PI*revs;
+  }
+
+  function point(tt){
+    const RR = inti(R);
+    const rr = Math.max(1, inti(r));
+    const dd = inti(d);
+    const k = RR - rr;
+    const ratio = k / rr;
+    return {
+      x: cx + k*Math.cos(tt) + dd*Math.cos(ratio*tt),
+      y: cy + k*Math.sin(tt) - dd*Math.sin(ratio*tt)
+    };
+  }
+
+  function updateReadout(){
+    const RR = inti(R), rr = Math.max(1, inti(r)), dd = inti(d);
+    const g = gcd(RR, rr);
+    const revs = rr / g;
+    const pct = period ? Math.min(100, (t/period)*100) : 0;
+    readout.innerHTML =
+      'R/r ratio <b>'+ (RR/rr).toFixed(3) +'</b> · closes in <b>'+ revs +'</b> rev'+(revs===1?'':'s')+'<br>'+
+      'petals <b>'+ (RR/g) +'</b> · pen d <b>'+ dd +'</b> · pass <b>'+ Math.round(pct) +'%</b> · laps <b>'+ laps +'</b>';
+  }
+
+  function strokeFor(){
+    const mode = colormode.value;
+    if(mode === 'solid') return ink.value;
+    if(mode === 'angle'){
+      const h = period ? (t/period*360*3) % 360 : hue;
+      return 'hsl('+h.toFixed(1)+',85%,62%)';
+    }
+    return 'hsl('+hue.toFixed(1)+',85%,62%)'; // cycle
+  }
+
+  function resetTrail(){
+    tctx.clearRect(0,0,W,H);
+    t = 0; laps = 0;
+    lastPt = point(0);
+    computePeriod();
+    updateReadout();
+  }
+
+  // Called when a shape parameter changes: fresh curve, new base hue.
+  function restart(){
+    hue = (hue + 47) % 360;
+    resetTrail();
+    render();
+  }
+
+  // Rolling-gear schematic for the current t (overlay only).
+  function drawGears(octx, tt){
+    const RR = inti(R), rr = Math.max(1, inti(r));
+    const k = RR - rr;
+    octx.save();
+    octx.strokeStyle = 'rgba(255,255,255,.16)';
+    octx.lineWidth = 1;
+    octx.beginPath(); octx.arc(cx, cy, RR, 0, Math.PI*2); octx.stroke();
+    const gx = cx + k*Math.cos(tt);
+    const gy = cy + k*Math.sin(tt);
+    octx.strokeStyle = 'rgba(167,139,250,.55)';
+    octx.beginPath(); octx.arc(gx, gy, rr, 0, Math.PI*2); octx.stroke();
+    const p = point(tt);
+    octx.strokeStyle = 'rgba(94,234,212,.5)';
+    octx.beginPath(); octx.moveTo(gx,gy); octx.lineTo(p.x,p.y); octx.stroke();
+    octx.fillStyle = '#5eead4';
+    octx.beginPath(); octx.arc(p.x,p.y,3.2,0,Math.PI*2); octx.fill();
+    octx.fillStyle = 'rgba(167,139,250,.9)';
+    octx.beginPath(); octx.arc(gx,gy,2.5,0,Math.PI*2); octx.fill();
+    octx.restore();
+  }
+
+  function render(){
+    ctx.clearRect(0,0,W,H);
+    ctx.drawImage(trail,0,0,W,H);
+    if(gears.checked && running) drawGears(ctx, t);
+  }
+
+  function frame(){
+    if(running){
+      const steps = inti(speed);
+      const width = num(lw);
+      const dt = 0.012; // base angular step per micro-segment
+      tctx.lineCap = 'round';
+      tctx.lineJoin = 'round';
+      tctx.lineWidth = width;
+      if(glow.checked){ tctx.shadowBlur = 8; } else { tctx.shadowBlur = 0; }
+
+      for(let i=0;i<steps;i++){
+        const nt = t + dt;
+        const p = point(nt);
+        if(colormode.value === 'cycle') hue = (hue + 0.35) % 360;
+        const stroke = strokeFor();
+        tctx.strokeStyle = stroke;
+        if(glow.checked) tctx.shadowColor = stroke;
+        tctx.beginPath();
+        tctx.moveTo(lastPt.x,lastPt.y);
+        tctx.lineTo(p.x,p.y);
+        tctx.stroke();
+        lastPt = p;
+        t = nt;
+        if(t >= period){
+          // Pattern complete: keep it, start a fresh overlaid pass with a new base hue.
+          t = 0; laps++;
+          lastPt = point(0);
+          hue = (hue + 63) % 360;
+        }
+      }
+      tctx.shadowBlur = 0;
+      updateReadout();
+    }
+    render();
+    requestAnimationFrame(frame);
+  }
+
+  // ---- Value labels + persistence ----
+  function bind(input, label, fmt){
+    const upd = ()=> label.textContent = fmt ? fmt(input.value) : input.value;
+    input.addEventListener('input', upd); upd();
+  }
+  bind(R, vR); bind(r, vr); bind(d, vd); bind(speed, vs); bind(lw, vw);
+
+  const SETTINGS = ['R','r','d','speed','lw','colormode','ink'];
+  const TOGGLES = ['gears','glow'];
+  function saveSettings(){
+    try{
+      const s = {};
+      SETTINGS.forEach(k=> s[k] = el(k).value);
+      TOGGLES.forEach(k=> s[k] = el(k).checked);
+      localStorage.setItem('spiro-settings', JSON.stringify(s));
+    }catch(e){}
+  }
+  function loadSettings(){
+    try{
+      const s = JSON.parse(localStorage.getItem('spiro-settings')||'null');
+      if(!s) return;
+      SETTINGS.forEach(k=>{ if(s[k]!=null) el(k).value = s[k]; });
+      TOGGLES.forEach(k=>{ if(s[k]!=null) el(k).checked = s[k]; });
+      [vR,vr,vd,vs,vw].forEach(()=>{});
+      vR.textContent=R.value; vr.textContent=r.value; vd.textContent=d.value;
+      vs.textContent=speed.value; vw.textContent=lw.value;
+    }catch(e){}
+  }
+  loadSettings();
+
+  // Shape-changing sliders restart the curve; all controls persist.
+  [R,r,d].forEach(inp => inp.addEventListener('input', restart));
+  [R,r,d,speed,lw,colormode,ink,gears,glow].forEach(inp =>
+    inp.addEventListener('input', saveSettings));
+
+  colormode.addEventListener('input', ()=>{ solidRow.hidden = colormode.value !== 'solid'; });
+  solidRow.hidden = colormode.value !== 'solid';
+
+  // ---- Buttons ----
+  function setPlaying(on){
+    running = on;
+    playBtn.textContent = on ? '⏸ Pause' : '▶ Play';
+  }
+  playBtn.addEventListener('click', ()=> setPlaying(!running));
+  el('clear').addEventListener('click', restart);
+
+  el('random').addEventListener('click', ()=>{
+    const rnd = (min,max)=> Math.floor(min + Math.random()*(max-min+1));
+    R.value = rnd(90, 230);
+    r.value = rnd(20, Math.max(30, +R.value - 10)); // keep a real hypotrochoid (r < R mostly)
+    d.value = rnd(20, 170);
+    const modes = ['cycle','angle','solid'];
+    colormode.value = modes[rnd(0,2)];
+    solidRow.hidden = colormode.value !== 'solid';
+    vR.textContent=R.value; vr.textContent=r.value; vd.textContent=d.value;
+    saveSettings();
+    restart();
+    setPlaying(true);
+  });
+
+  const PRESETS = {
+    rose: {R:200, r:60, d:120, mode:'cycle'},
+    star: {R:150, r:37, d:90,  mode:'angle'},
+    web:  {R:220, r:99, d:150, mode:'cycle'},
+    loop: {R:120, r:29, d:170, mode:'solid'}
+  };
+  document.querySelectorAll('[data-preset]').forEach(btn=>{
+    btn.addEventListener('click', ()=>{
+      const p = PRESETS[btn.dataset.preset]; if(!p) return;
+      R.value=p.R; r.value=p.r; d.value=p.d; colormode.value=p.mode;
+      solidRow.hidden = colormode.value !== 'solid';
+      vR.textContent=R.value; vr.textContent=r.value; vd.textContent=d.value;
+      saveSettings(); restart(); setPlaying(true);
+    });
+  });
+
+  el('save').addEventListener('click', ()=>{
+    // Composite onto a dark background so the PNG isn't transparent.
+    const out = document.createElement('canvas');
+    out.width = trail.width; out.height = trail.height;
+    const octx = out.getContext('2d');
+    octx.fillStyle = '#07080f';
+    octx.fillRect(0,0,out.width,out.height);
+    octx.drawImage(trail,0,0);
+    const link = document.createElement('a');
+    link.download = 'spirograph-' + Date.now() + '.png';
+    link.href = out.toDataURL('image/png');
+    link.click();
+  });
+
+  // ---- Keyboard shortcuts ----
+  addEventListener('keydown', e=>{
+    if(e.target.matches('input,select,textarea')) return;
+    const k = e.key.toLowerCase();
+    if(k === ' '){ e.preventDefault(); setPlaying(!running); }
+    else if(k === 'c'){ restart(); }
+    else if(k === 'r'){ el('random').click(); }
+    else if(k === 's'){ el('save').click(); }
+  });
+
+  // Init
+  resetTrail();
+  requestAnimationFrame(frame);
+})();
+</script>
+</body>
+</html>
diff --git a/games/sudoku/NeonSudoku.aa b/games/sudoku/NeonSudoku.aa
new file mode 100644
index 0000000..8c0de66
--- /dev/null
+++ b/games/sudoku/NeonSudoku.aa
@@ -0,0 +1,799 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>NEON SUDOKU</title>
+<style>
+  :root{
+    --bg:#0a0e14;
+    --panel:#0f151f;
+    --grid-line:#1c2a3a;
+    --grid-line-strong:#2fd2ff;
+    --given:#e6f4ff;
+    --entry:#38f0c0;
+    --note:#5f7a92;
+    --conflict:#ff3b5c;
+    --accent:#2fd2ff;
+    --sel:#12303f;
+    --sel-peer:#0e1f2b;
+    --sameval:#123448;
+  }
+  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
+  html,body{margin:0;padding:0;height:100%;}
+  body{
+    background:var(--bg);
+    color:#cfe6f5;
+    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
+    display:flex;
+    flex-direction:column;
+    align-items:center;
+    justify-content:flex-start;
+    min-height:100%;
+    padding:12px 10px 24px;
+    touch-action:manipulation;
+    overflow-x:hidden;
+  }
+  h1{
+    margin:4px 0 10px;
+    font-size:clamp(18px,5vw,30px);
+    font-weight:800;
+    letter-spacing:.34em;
+    text-transform:uppercase;
+    color:#eaf7ff;
+    text-shadow:0 0 8px rgba(47,210,255,.6),0 0 22px rgba(47,210,255,.25);
+    text-align:center;
+  }
+  .hud{
+    display:flex;
+    flex-wrap:wrap;
+    gap:8px 14px;
+    align-items:center;
+    justify-content:center;
+    margin-bottom:12px;
+    width:100%;
+    max-width:560px;
+  }
+  .hud .item{
+    display:flex;
+    flex-direction:column;
+    align-items:center;
+    line-height:1.1;
+  }
+  .hud .label{
+    font-size:10px;
+    letter-spacing:.18em;
+    text-transform:uppercase;
+    color:#5f7a92;
+  }
+  .hud .val{
+    font-size:16px;
+    font-weight:700;
+    font-variant-numeric:tabular-nums;
+    color:var(--accent);
+    text-shadow:0 0 8px rgba(47,210,255,.4);
+  }
+  .controls{
+    display:flex;
+    flex-wrap:wrap;
+    gap:8px;
+    justify-content:center;
+    margin-bottom:14px;
+    width:100%;
+    max-width:560px;
+  }
+  select,button{
+    font-family:inherit;
+    background:var(--panel);
+    color:#cfe6f5;
+    border:1px solid var(--grid-line);
+    border-radius:8px;
+    padding:9px 12px;
+    font-size:13px;
+    letter-spacing:.05em;
+    cursor:pointer;
+    transition:border-color .15s,box-shadow .15s,background .15s;
+  }
+  select:focus,button:focus{outline:none;border-color:var(--accent);}
+  button:hover,select:hover{border-color:var(--accent);}
+  button:active{transform:translateY(1px);}
+  button.primary{
+    border-color:var(--accent);
+    color:#eaf7ff;
+    box-shadow:0 0 10px rgba(47,210,255,.25) inset;
+  }
+  button.toggled{
+    background:#123448;
+    border-color:var(--entry);
+    color:var(--entry);
+    box-shadow:0 0 10px rgba(56,240,192,.3) inset;
+  }
+  #boardWrap{
+    width:min(94vw,520px);
+    aspect-ratio:1/1;
+    max-height:60vh;
+    margin-bottom:16px;
+  }
+  #board{
+    width:100%;
+    height:100%;
+    display:grid;
+    grid-template-columns:repeat(9,1fr);
+    grid-template-rows:repeat(9,1fr);
+    background:var(--grid-line-strong);
+    border:2px solid var(--grid-line-strong);
+    border-radius:6px;
+    gap:1px;
+    box-shadow:0 0 22px rgba(47,210,255,.25);
+    overflow:hidden;
+  }
+  .cell{
+    position:relative;
+    background:var(--panel);
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    font-size:clamp(16px,5vw,28px);
+    font-weight:600;
+    color:var(--entry);
+    cursor:pointer;
+    user-select:none;
+    font-variant-numeric:tabular-nums;
+  }
+  .cell.given{color:var(--given);font-weight:700;}
+  /* thick 3x3 box borders using margins */
+  .cell.br{margin-right:1px;box-shadow:2px 0 0 0 var(--grid-line-strong);}
+  .cell.bb{margin-bottom:1px;box-shadow:0 2px 0 0 var(--grid-line-strong);}
+  .cell.br.bb{box-shadow:2px 0 0 0 var(--grid-line-strong),0 2px 0 0 var(--grid-line-strong);}
+  .cell.peer{background:var(--sel-peer);}
+  .cell.sameval{background:var(--sameval);}
+  .cell.selected{background:var(--sel);box-shadow:inset 0 0 0 2px var(--accent);}
+  .cell.selected.br,.cell.selected.bb,.cell.selected.br.bb{box-shadow:inset 0 0 0 2px var(--accent);}
+  .cell.conflict{color:var(--conflict);text-shadow:0 0 10px rgba(255,59,92,.7);}
+  .cell.conflict.given{color:var(--conflict);}
+  .notes{
+    position:absolute;
+    inset:2px;
+    display:grid;
+    grid-template-columns:repeat(3,1fr);
+    grid-template-rows:repeat(3,1fr);
+    pointer-events:none;
+  }
+  .notes span{
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    font-size:clamp(7px,2vw,11px);
+    font-weight:600;
+    color:var(--note);
+    line-height:1;
+  }
+  .pad{
+    display:grid;
+    grid-template-columns:repeat(5,1fr);
+    gap:8px;
+    width:min(94vw,520px);
+    margin-bottom:10px;
+  }
+  .pad button{
+    padding:14px 0;
+    font-size:20px;
+    font-weight:700;
+    border-radius:10px;
+  }
+  .pad .num{color:#eaf7ff;}
+  .pad .fn{font-size:12px;letter-spacing:.08em;}
+  .msg{
+    min-height:22px;
+    font-size:14px;
+    letter-spacing:.1em;
+    text-transform:uppercase;
+    color:var(--entry);
+    text-shadow:0 0 10px rgba(56,240,192,.5);
+    text-align:center;
+    font-weight:700;
+  }
+  .best{font-size:11px;color:#5f7a92;letter-spacing:.12em;text-transform:uppercase;text-align:center;margin-top:2px;}
+  @media (max-width:360px){
+    h1{letter-spacing:.2em;}
+    .pad button{padding:11px 0;font-size:17px;}
+  }
+</style>
+</head>
+<body>
+  <h1>Neon Sudoku</h1>
+
+  <div class="hud">
+    <div class="item"><span class="label">Time</span><span class="val" id="timer">00:00</span></div>
+    <div class="item"><span class="label">Difficulty</span><span class="val" id="diffLbl">Easy</span></div>
+    <div class="item"><span class="label">Mode</span><span class="val" id="modeLbl">Fill</span></div>
+  </div>
+
+  <div class="controls">
+    <select id="diffSel" aria-label="Difficulty">
+      <option value="easy">Easy</option>
+      <option value="medium">Medium</option>
+      <option value="hard">Hard</option>
+    </select>
+    <button class="primary" id="newBtn">New Puzzle</button>
+    <button id="notesBtn">Notes: Off</button>
+  </div>
+
+  <div id="boardWrap"><div id="board" aria-label="Sudoku board"></div></div>
+
+  <div class="pad" id="pad"></div>
+
+  <div class="msg" id="msg"></div>
+  <div class="best" id="best"></div>
+
+<script>
+(function(){
+  "use strict";
+
+  var STORE_KEY = "abrams-sudoku";
+  var SIZE = 9;
+
+  // ---------- utilities ----------
+  function shuffled(arr){
+    var a = arr.slice();
+    for (var i = a.length - 1; i > 0; i--){
+      var j = Math.floor(Math.random() * (i + 1));
+      var t = a[i]; a[i] = a[j]; a[j] = t;
+    }
+    return a;
+  }
+
+  // ---------- solution generator (bounded backtracking) ----------
+  // Returns a full valid 9x9 grid (array of 81 ints 1-9), or null on failure.
+  function generateSolution(){
+    var grid = new Array(81).fill(0);
+    var steps = { count: 0 };
+    var MAX_STEPS = 600000; // hard cap so we can never spin forever
+
+    function fits(idx, val){
+      var r = (idx / 9) | 0, c = idx % 9;
+      var br = r - r % 3, bc = c - c % 3;
+      for (var i = 0; i < 9; i++){
+        if (grid[r*9 + i] === val) return false;
+        if (grid[i*9 + c] === val) return false;
+      }
+      for (var rr = 0; rr < 3; rr++){
+        for (var cc = 0; cc < 3; cc++){
+          if (grid[(br+rr)*9 + (bc+cc)] === val) return false;
+        }
+      }
+      return true;
+    }
+
+    function solve(pos){
+      if (steps.count++ > MAX_STEPS) return false;
+      if (pos >= 81) return true;
+      if (grid[pos] !== 0) return solve(pos + 1);
+      var nums = shuffled([1,2,3,4,5,6,7,8,9]);
+      for (var k = 0; k < 9; k++){
+        var v = nums[k];
+        if (fits(pos, v)){
+          grid[pos] = v;
+          if (solve(pos + 1)) return true;
+          grid[pos] = 0;
+        }
+        if (steps.count > MAX_STEPS) return false;
+      }
+      return false;
+    }
+
+    if (solve(0)) return grid;
+    return null;
+  }
+
+  // ---------- solver: count solutions up to a limit (for uniqueness) ----------
+  function countSolutions(puzzle, limit){
+    var grid = puzzle.slice();
+    var steps = { count: 0 };
+    var MAX_STEPS = 400000;
+    var found = 0;
+
+    function fits(idx, val){
+      var r = (idx / 9) | 0, c = idx % 9;
+      var br = r - r % 3, bc = c - c % 3;
+      for (var i = 0; i < 9; i++){
+        if (grid[r*9 + i] === val) return false;
+        if (grid[i*9 + c] === val) return false;
+      }
+      for (var rr = 0; rr < 3; rr++){
+        for (var cc = 0; cc < 3; cc++){
+          if (grid[(br+rr)*9 + (bc+cc)] === val) return false;
+        }
+      }
+      return true;
+    }
+
+    // find the empty cell with fewest candidates (MRV) to keep it fast/bounded
+    function pickCell(){
+      var best = -1, bestCount = 10;
+      for (var idx = 0; idx < 81; idx++){
+        if (grid[idx] !== 0) continue;
+        var cnt = 0;
+        for (var v = 1; v <= 9; v++){ if (fits(idx, v)) cnt++; }
+        if (cnt < bestCount){ bestCount = cnt; best = idx; if (cnt <= 1) break; }
+      }
+      return best;
+    }
+
+    function solve(){
+      if (steps.count++ > MAX_STEPS) return true; // bail -> treat as "give up", stops recursion
+      var idx = pickCell();
+      if (idx === -1){ found++; return found >= limit; }
+      for (var v = 1; v <= 9; v++){
+        if (fits(idx, v)){
+          grid[idx] = v;
+          if (solve()) { grid[idx] = 0; return true; }
+          grid[idx] = 0;
+        }
+        if (steps.count > MAX_STEPS) return true;
+      }
+      return false;
+    }
+
+    solve();
+    return found;
+  }
+
+  // ---------- build a puzzle at difficulty ----------
+  var DIFF = {
+    easy:   { clues: 40 },
+    medium: { clues: 32 },
+    hard:   { clues: 26 }
+  };
+
+  // Make puzzle: start from full solution, remove cells (symmetric) while
+  // keeping a unique solution, bounded by attempts. Falls back gracefully.
+  function makePuzzle(difficulty){
+    var solution = null;
+    // bounded retries to obtain a solution
+    for (var g = 0; g < 8 && !solution; g++){
+      solution = generateSolution();
+    }
+    if (!solution){
+      // absolute fallback: a hard-coded valid solved grid
+      solution = FALLBACK_SOLUTION.slice();
+    }
+
+    var targetClues = (DIFF[difficulty] || DIFF.easy).clues;
+    var puzzle = solution.slice();
+
+    var order = shuffled((function(){ var a=[]; for(var i=0;i<81;i++) a.push(i); return a; })());
+    var removed = 0;
+    var toRemove = 81 - targetClues;
+    var attempts = 0;
+    var MAX_ATTEMPTS = 200; // hard cap on removal attempts
+
+    for (var oi = 0; oi < order.length && removed < toRemove && attempts < MAX_ATTEMPTS; oi++){
+      var idx = order[oi];
+      if (puzzle[idx] === 0) continue;
+      attempts++;
+      var saved = puzzle[idx];
+      puzzle[idx] = 0;
+      // keep unique: count solutions up to 2
+      var cnt = countSolutions(puzzle, 2);
+      if (cnt !== 1){
+        puzzle[idx] = saved; // revert, not removable
+      } else {
+        removed++;
+      }
+    }
+
+    return { puzzle: puzzle, solution: solution };
+  }
+
+  // A known-good completed grid used only if generation ever fails entirely.
+  var FALLBACK_SOLUTION = [
+    5,3,4, 6,7,8, 9,1,2,
+    6,7,2, 1,9,5, 3,4,8,
+    1,9,8, 3,4,2, 5,6,7,
+    8,5,9, 7,6,1, 4,2,3,
+    4,2,6, 8,5,3, 7,9,1,
+    7,1,3, 9,2,4, 8,5,6,
+    9,6,1, 5,3,7, 2,8,4,
+    2,8,7, 4,1,9, 6,3,5,
+    3,4,5, 2,8,6, 1,7,9
+  ];
+
+  // ---------- game state ----------
+  var state = {
+    puzzle: [],       // starting clues (0 = empty)
+    solution: [],     // full solution
+    values: [],       // current user values (includes givens)
+    notes: [],        // array of Set-like objects per cell
+    given: [],        // boolean per cell
+    selected: -1,
+    notesMode: false,
+    difficulty: "easy",
+    startTime: 0,
+    elapsed: 0,
+    running: false,
+    solved: false
+  };
+
+  var timerHandle = null;
+
+  // ---------- DOM refs ----------
+  var boardEl = document.getElementById("board");
+  var padEl = document.getElementById("pad");
+  var timerEl = document.getElementById("timer");
+  var diffLblEl = document.getElementById("diffLbl");
+  var modeLblEl = document.getElementById("modeLbl");
+  var diffSelEl = document.getElementById("diffSel");
+  var newBtn = document.getElementById("newBtn");
+  var notesBtn = document.getElementById("notesBtn");
+  var msgEl = document.getElementById("msg");
+  var bestEl = document.getElementById("best");
+
+  var cellEls = [];
+
+  function buildBoard(){
+    boardEl.innerHTML = "";
+    cellEls = [];
+    for (var idx = 0; idx < 81; idx++){
+      var r = (idx / 9) | 0, c = idx % 9;
+      var cell = document.createElement("div");
+      cell.className = "cell";
+      if (c === 2 || c === 5) cell.classList.add("br");
+      if (r === 2 || r === 5) cell.classList.add("bb");
+      cell.setAttribute("data-idx", String(idx));
+      (function(i){
+        cell.addEventListener("click", function(){ selectCell(i); });
+      })(idx);
+      var notes = document.createElement("div");
+      notes.className = "notes";
+      for (var n = 1; n <= 9; n++){
+        var sp = document.createElement("span");
+        sp.setAttribute("data-n", String(n));
+        notes.appendChild(sp);
+      }
+      cell.appendChild(notes);
+      boardEl.appendChild(cell);
+      cellEls.push(cell);
+    }
+  }
+
+  function buildPad(){
+    padEl.innerHTML = "";
+    for (var n = 1; n <= 9; n++){
+      var b = document.createElement("button");
+      b.className = "num";
+      b.textContent = String(n);
+      (function(v){ b.addEventListener("click", function(){ inputNumber(v); }); })(n);
+      padEl.appendChild(b);
+    }
+    var eraseB = document.createElement("button");
+    eraseB.className = "fn";
+    eraseB.textContent = "ERASE";
+    eraseB.addEventListener("click", function(){ inputNumber(0); });
+    padEl.appendChild(eraseB);
+  }
+
+  // ---------- timer ----------
+  function fmt(sec){
+    var m = Math.floor(sec / 60), s = sec % 60;
+    return (m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s;
+  }
+  function startTimer(){
+    stopTimer();
+    state.startTime = Date.now() - state.elapsed * 1000;
+    state.running = true;
+    timerHandle = setInterval(function(){
+      if (!state.running) return;
+      state.elapsed = Math.floor((Date.now() - state.startTime) / 1000);
+      timerEl.textContent = fmt(state.elapsed);
+    }, 250);
+  }
+  function stopTimer(){
+    state.running = false;
+    if (timerHandle){ clearInterval(timerHandle); timerHandle = null; }
+  }
+
+  // ---------- best times ----------
+  function loadBest(){
+    try {
+      var raw = localStorage.getItem(STORE_KEY);
+      if (!raw) return {};
+      var obj = JSON.parse(raw);
+      return (obj && typeof obj === "object") ? obj : {};
+    } catch (e) { return {}; }
+  }
+  function saveBest(obj){
+    try { localStorage.setItem(STORE_KEY, JSON.stringify(obj)); } catch (e) {}
+  }
+  function showBest(){
+    var b = loadBest();
+    var t = b[state.difficulty];
+    if (typeof t === "number"){
+      bestEl.textContent = "Best (" + state.difficulty + "): " + fmt(t);
+    } else {
+      bestEl.textContent = "Best (" + state.difficulty + "): --:--";
+    }
+  }
+  function recordBest(){
+    var b = loadBest();
+    var cur = b[state.difficulty];
+    if (typeof cur !== "number" || state.elapsed < cur){
+      b[state.difficulty] = state.elapsed;
+      saveBest(b);
+      return true;
+    }
+    return false;
+  }
+
+  // ---------- conflict detection ----------
+  function conflictSet(){
+    var conflicts = {};
+    // rows, cols, boxes
+    function check(indices){
+      var seen = {};
+      for (var i = 0; i < indices.length; i++){
+        var v = state.values[indices[i]];
+        if (v === 0) continue;
+        if (seen[v] === undefined) seen[v] = [indices[i]];
+        else seen[v].push(indices[i]);
+      }
+      for (var val in seen){
+        if (seen[val].length > 1){
+          for (var j = 0; j < seen[val].length; j++){
+            conflicts[seen[val][j]] = true;
+          }
+        }
+      }
+    }
+    var r, c, i;
+    for (r = 0; r < 9; r++){
+      var row = [];
+      for (c = 0; c < 9; c++) row.push(r*9 + c);
+      check(row);
+    }
+    for (c = 0; c < 9; c++){
+      var col = [];
+      for (r = 0; r < 9; r++) col.push(r*9 + c);
+      check(col);
+    }
+    for (var br = 0; br < 3; br++){
+      for (var bc = 0; bc < 3; bc++){
+        var box = [];
+        for (var rr = 0; rr < 3; rr++)
+          for (var cc = 0; cc < 3; cc++)
+            box.push((br*3+rr)*9 + (bc*3+cc));
+        check(box);
+      }
+    }
+    return conflicts;
+  }
+
+  // ---------- rendering ----------
+  function render(){
+    var conflicts = conflictSet();
+    var selVal = state.selected >= 0 ? state.values[state.selected] : 0;
+    var selR = state.selected >= 0 ? (state.selected / 9) | 0 : -1;
+    var selC = state.selected >= 0 ? state.selected % 9 : -1;
+
+    for (var idx = 0; idx < 81; idx++){
+      var cell = cellEls[idx];
+      var v = state.values[idx];
+      // reset classes but keep border classes + base
+      cell.classList.remove("given","conflict","selected","peer","sameval");
+
+      if (state.given[idx]) cell.classList.add("given");
+
+      var notesEl = cell.querySelector(".notes");
+      var textNode = cell.childNodes[cell.childNodes.length - 1];
+      // We store text in a dedicated text node: rebuild it
+      // Clear existing value text node (first non-notes child)
+      // Simpler: set cell's own text via a data span
+      // Remove any prior value text nodes:
+      for (var k = cell.childNodes.length - 1; k >= 0; k--){
+        var ch = cell.childNodes[k];
+        if (ch.nodeType === 3) cell.removeChild(ch);
+      }
+
+      if (v !== 0){
+        notesEl.style.display = "none";
+        cell.insertBefore(document.createTextNode(String(v)), notesEl);
+      } else {
+        notesEl.style.display = "";
+        var set = state.notes[idx];
+        var spans = notesEl.querySelectorAll("span");
+        for (var s = 0; s < spans.length; s++){
+          var n = s + 1;
+          spans[s].textContent = (set && set[n]) ? String(n) : "";
+        }
+      }
+
+      if (conflicts[idx]) cell.classList.add("conflict");
+
+      // highlighting relative to selection
+      if (state.selected >= 0 && idx !== state.selected){
+        var r = (idx / 9) | 0, c = idx % 9;
+        var sameBox = ((r - r%3) === (selR - selR%3)) && ((c - c%3) === (selC - selC%3));
+        if (r === selR || c === selC || sameBox) cell.classList.add("peer");
+        if (selVal !== 0 && v === selVal) cell.classList.add("sameval");
+      }
+    }
+
+    if (state.selected >= 0){
+      cellEls[state.selected].classList.add("selected");
+    }
+  }
+
+  function selectCell(idx){
+    state.selected = idx;
+    render();
+  }
+
+  // ---------- input ----------
+  function inputNumber(v){
+    if (state.selected < 0 || state.solved) return;
+    var idx = state.selected;
+    if (state.given[idx]) return;
+
+    if (v === 0){
+      // erase
+      state.values[idx] = 0;
+      state.notes[idx] = {};
+      render();
+      return;
+    }
+
+    if (state.notesMode){
+      if (state.values[idx] !== 0) state.values[idx] = 0;
+      if (!state.notes[idx]) state.notes[idx] = {};
+      state.notes[idx][v] = !state.notes[idx][v];
+      render();
+    } else {
+      state.values[idx] = (state.values[idx] === v) ? 0 : v;
+      state.notes[idx] = {};
+      render();
+      checkSolved();
+    }
+  }
+
+  function checkSolved(){
+    // must be fully filled
+    for (var i = 0; i < 81; i++){
+      if (state.values[i] === 0) return;
+    }
+    // must match solution (guarantees valid & correct)
+    for (var j = 0; j < 81; j++){
+      if (state.values[j] !== state.solution[j]) return;
+    }
+    // solved!
+    state.solved = true;
+    stopTimer();
+    var isBest = recordBest();
+    showBest();
+    msgEl.textContent = isBest ? "Solved! New best time!" : "Solved!";
+  }
+
+  // ---------- new game ----------
+  function newGame(){
+    msgEl.textContent = "Generating...";
+    // defer so the "Generating..." paints before the (bounded) work
+    setTimeout(function(){
+      try {
+        var built = makePuzzle(state.difficulty);
+        state.puzzle = built.puzzle.slice();
+        state.solution = built.solution.slice();
+        state.values = built.puzzle.slice();
+        state.given = [];
+        state.notes = [];
+        for (var i = 0; i < 81; i++){
+          state.given.push(built.puzzle[i] !== 0);
+          state.notes.push({});
+        }
+        state.selected = -1;
+        state.solved = false;
+        state.elapsed = 0;
+        timerEl.textContent = "00:00";
+        msgEl.textContent = "";
+        render();
+        startTimer();
+        showBest();
+      } catch (e) {
+        // never throw to the page; fail to a trivial fallback
+        msgEl.textContent = "";
+        var sol = FALLBACK_SOLUTION.slice();
+        var pz = sol.slice();
+        // blank out a handful of cells deterministically
+        var blanks = [0,10,20,30,40,50,60,70,80];
+        for (var b = 0; b < blanks.length; b++) pz[blanks[b]] = 0;
+        state.puzzle = pz.slice();
+        state.solution = sol.slice();
+        state.values = pz.slice();
+        state.given = [];
+        state.notes = [];
+        for (var k = 0; k < 81; k++){ state.given.push(pz[k] !== 0); state.notes.push({}); }
+        state.selected = -1;
+        state.solved = false;
+        state.elapsed = 0;
+        timerEl.textContent = "00:00";
+        render();
+        startTimer();
+        showBest();
+      }
+    }, 20);
+  }
+
+  // ---------- controls ----------
+  function setNotesMode(on){
+    state.notesMode = on;
+    notesBtn.textContent = "Notes: " + (on ? "On" : "Off");
+    notesBtn.classList.toggle("toggled", on);
+    modeLblEl.textContent = on ? "Notes" : "Fill";
+  }
+
+  function moveSelection(dr, dc){
+    var idx = state.selected;
+    if (idx < 0){ selectCell(0); return; }
+    var r = (idx / 9) | 0, c = idx % 9;
+    r = Math.max(0, Math.min(8, r + dr));
+    c = Math.max(0, Math.min(8, c + dc));
+    selectCell(r*9 + c);
+  }
+
+  function onKey(e){
+    var key = e.key;
+    if (key >= "1" && key <= "9"){
+      inputNumber(parseInt(key, 10));
+      e.preventDefault();
+      return;
+    }
+    if (key === "0" || key === "Backspace" || key === "Delete"){
+      inputNumber(0);
+      e.preventDefault();
+      return;
+    }
+    if (key === "ArrowUp"){ moveSelection(-1, 0); e.preventDefault(); return; }
+    if (key === "ArrowDown"){ moveSelection(1, 0); e.preventDefault(); return; }
+    if (key === "ArrowLeft"){ moveSelection(0, -1); e.preventDefault(); return; }
+    if (key === "ArrowRight"){ moveSelection(0, 1); e.preventDefault(); return; }
+    if (key === "n" || key === "N"){ setNotesMode(!state.notesMode); e.preventDefault(); return; }
+  }
+
+  // ---------- init ----------
+  function init(){
+    buildBoard();
+    buildPad();
+
+    diffSelEl.addEventListener("change", function(){
+      state.difficulty = diffSelEl.value;
+      diffLblEl.textContent = diffSelEl.options[diffSelEl.selectedIndex].text;
+      newGame();
+    });
+    newBtn.addEventListener("click", function(){ newGame(); });
+    notesBtn.addEventListener("click", function(){ setNotesMode(!state.notesMode); });
+    document.addEventListener("keydown", onKey);
+
+    // pause timer when tab hidden, resume on return
+    document.addEventListener("visibilitychange", function(){
+      if (document.hidden){
+        state.running = false;
+      } else if (!state.solved && state.values.length){
+        state.startTime = Date.now() - state.elapsed * 1000;
+        state.running = true;
+      }
+    });
+
+    state.difficulty = diffSelEl.value;
+    diffLblEl.textContent = diffSelEl.options[diffSelEl.selectedIndex].text;
+    setNotesMode(false);
+    showBest();
+    newGame();
+  }
+
+  if (document.readyState === "loading"){
+    document.addEventListener("DOMContentLoaded", init);
+  } else {
+    init();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/games/tetris/AbramsBlocks.aa b/games/tetris/AbramsBlocks.aa
new file mode 100644
index 0000000..fef354e
--- /dev/null
+++ b/games/tetris/AbramsBlocks.aa
@@ -0,0 +1,511 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+<title>Abrams Blocks — Tetris</title>
+<style>
+  * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
+  html, body { height: 100%; margin: 0; }
+  body {
+    display: flex; align-items: center; justify-content: center;
+    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
+    background: radial-gradient(120% 120% at 50% 0%, #1b2030 0%, #0c0e15 70%);
+    color: #e8e9ef; overflow: hidden; user-select: none; touch-action: none;
+  }
+  #wrap {
+    display: flex; gap: 18px; padding: 16px;
+    align-items: flex-start; max-width: 100%;
+  }
+  canvas { display: block; }
+  #board {
+    background: #0a0c12;
+    border: 1px solid #2b3140; border-radius: 10px;
+    box-shadow: 0 0 0 1px #000 inset, 0 20px 60px rgba(0,0,0,.5);
+  }
+  #side {
+    display: flex; flex-direction: column; gap: 14px; width: 138px;
+  }
+  .card {
+    background: linear-gradient(180deg, #171b26, #12151d);
+    border: 1px solid #2b3140; border-radius: 10px; padding: 10px 12px;
+  }
+  .card h2 {
+    margin: 0 0 6px; font-size: 9.5px; font-weight: 700; letter-spacing: 2px;
+    opacity: .45; text-transform: uppercase;
+  }
+  .stat { font-size: 22px; font-weight: 700; letter-spacing: 1px; line-height: 1.1; }
+  .stat.small { font-size: 15px; }
+  .pcanvas { display: block; margin: 0 auto; }
+  #keys { font-size: 9.5px; opacity: .4; line-height: 1.9; letter-spacing: .5px; }
+  #keys b { color: #7c5cff; font-weight: 700; }
+  #brand { font-size: 10px; letter-spacing: 2px; opacity: .5; text-align: center; }
+  #brand .dot { color: #7c5cff; }
+  #btns { display: flex; gap: 8px; }
+  #btns button {
+    flex: 1; background: #1d2230; border: 1px solid #2f3648; color: #cfd3df;
+    border-radius: 8px; padding: 7px 0; font: inherit; font-size: 11px; cursor: pointer;
+  }
+  #btns button:hover { background: #262d40; }
+  /* overlay */
+  #overlay {
+    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
+    background: rgba(8,10,16,.72); backdrop-filter: blur(2px); z-index: 5;
+  }
+  #overlay.hidden { display: none; }
+  #panel {
+    text-align: center; padding: 28px 34px; border-radius: 14px;
+    background: linear-gradient(180deg, #1a1f2c, #12151d);
+    border: 1px solid #313a52; box-shadow: 0 24px 70px rgba(0,0,0,.6);
+    max-width: 320px;
+  }
+  #panel .title { font-size: 26px; font-weight: 800; letter-spacing: 2px; margin-bottom: 4px; }
+  #panel .title .dot { color: #7c5cff; }
+  #panel .sub { font-size: 11px; opacity: .55; line-height: 1.8; margin: 10px 0 18px; }
+  #panel button {
+    background: #7c5cff; border: 0; color: #fff; font: inherit; font-weight: 700;
+    letter-spacing: 1px; padding: 11px 26px; border-radius: 10px; cursor: pointer; font-size: 13px;
+  }
+  #panel button:hover { background: #8f72ff; }
+  #panel .score { font-size: 13px; opacity: .8; margin-bottom: 4px; }
+  #panel .score b { color: #ffd166; }
+  @media (max-width: 620px) {
+    #wrap { gap: 10px; padding: 8px; }
+    #side { width: 84px; gap: 8px; }
+    .card { padding: 7px 8px; }
+    .stat { font-size: 16px; }
+    #keys { display: none; }
+  }
+</style>
+</head>
+<body>
+<div id="wrap" style="position:relative">
+  <canvas id="board"></canvas>
+  <div id="side">
+    <div id="brand">AGENT<span class="dot">·</span>ABRAMS</div>
+    <div class="card">
+      <h2>Score</h2><div class="stat" id="score">0</div>
+    </div>
+    <div class="card">
+      <h2>Best</h2><div class="stat small" id="best">0</div>
+    </div>
+    <div class="card" style="display:flex;gap:12px;justify-content:space-between">
+      <div><h2>Lines</h2><div class="stat small" id="lines">0</div></div>
+      <div><h2>Level</h2><div class="stat small" id="level">1</div></div>
+    </div>
+    <div class="card">
+      <h2>Next</h2><canvas id="next" class="pcanvas"></canvas>
+    </div>
+    <div class="card">
+      <h2>Hold</h2><canvas id="hold" class="pcanvas"></canvas>
+    </div>
+    <div id="btns">
+      <button id="pauseBtn">Pause</button>
+      <button id="muteBtn">🔊</button>
+    </div>
+    <div id="keys">
+      <b>← →</b> move<br>
+      <b>↑ / X</b> rotate cw<br>
+      <b>Z</b> rotate ccw<br>
+      <b>↓</b> soft drop<br>
+      <b>Space</b> hard drop<br>
+      <b>C</b> hold<br>
+      <b>P</b> pause · <b>M</b> mute
+    </div>
+  </div>
+
+  <div id="overlay">
+    <div id="panel">
+      <div class="title">ABRAMS<span class="dot">·</span>BLOCKS</div>
+      <div class="sub" id="panelSub">
+        Stack the falling tetrominoes, clear lines, chase the level.<br>
+        Arrows to move · ↑/Z rotate · Space hard-drop · C hold.
+      </div>
+      <div class="score" id="panelScore" style="display:none"></div>
+      <button id="startBtn">Play</button>
+    </div>
+  </div>
+</div>
+
+<script>
+(() => {
+  "use strict";
+
+  // ---------- constants ----------
+  const COLS = 10, ROWS = 20, HIDDEN = 2; // 2 hidden rows above the top
+  const TOTAL_ROWS = ROWS + HIDDEN;
+  const COLORS = {
+    I: "#38e1e1", O: "#f5d442", T: "#b46bff", S: "#5be36a",
+    Z: "#ff5d6c", J: "#4d7dff", L: "#ff9f43", G: "#2a3145"
+  };
+  // SRS piece definitions — each is a list of 4 rotation states, cells as [x,y] in a 4x4 box
+  const SHAPES = {
+    I: [[[0,1],[1,1],[2,1],[3,1]], [[2,0],[2,1],[2,2],[2,3]], [[0,2],[1,2],[2,2],[3,2]], [[1,0],[1,1],[1,2],[1,3]]],
+    J: [[[0,0],[0,1],[1,1],[2,1]], [[1,0],[2,0],[1,1],[1,2]], [[0,1],[1,1],[2,1],[2,2]], [[1,0],[1,1],[0,2],[1,2]]],
+    L: [[[2,0],[0,1],[1,1],[2,1]], [[1,0],[1,1],[1,2],[2,2]], [[0,1],[1,1],[2,1],[0,2]], [[0,0],[1,0],[1,1],[1,2]]],
+    O: [[[1,0],[2,0],[1,1],[2,1]], [[1,0],[2,0],[1,1],[2,1]], [[1,0],[2,0],[1,1],[2,1]], [[1,0],[2,0],[1,1],[2,1]]],
+    S: [[[1,0],[2,0],[0,1],[1,1]], [[1,0],[1,1],[2,1],[2,2]], [[1,1],[2,1],[0,2],[1,2]], [[0,0],[0,1],[1,1],[1,2]]],
+    T: [[[1,0],[0,1],[1,1],[2,1]], [[1,0],[1,1],[2,1],[1,2]], [[0,1],[1,1],[2,1],[1,2]], [[1,0],[0,1],[1,1],[1,2]]],
+    Z: [[[0,0],[1,0],[1,1],[2,1]], [[2,0],[1,1],[2,1],[1,2]], [[0,1],[1,1],[1,2],[2,2]], [[1,0],[0,1],[1,1],[0,2]]]
+  };
+  // SRS wall-kick data (JLSTZ). I-piece has its own table.
+  const KICKS = {
+    "0>1":[[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]], "1>0":[[0,0],[1,0],[1,-1],[0,2],[1,2]],
+    "1>2":[[0,0],[1,0],[1,-1],[0,2],[1,2]],     "2>1":[[0,0],[-1,0],[-1,1],[0,-2],[-1,-2]],
+    "2>3":[[0,0],[1,0],[1,1],[0,-2],[1,-2]],    "3>2":[[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],
+    "3>0":[[0,0],[-1,0],[-1,-1],[0,2],[-1,2]],  "0>3":[[0,0],[1,0],[1,1],[0,-2],[1,-2]]
+  };
+  const KICKS_I = {
+    "0>1":[[0,0],[-2,0],[1,0],[-2,-1],[1,2]], "1>0":[[0,0],[2,0],[-1,0],[2,1],[-1,-2]],
+    "1>2":[[0,0],[-1,0],[2,0],[-1,2],[2,-1]], "2>1":[[0,0],[1,0],[-2,0],[1,-2],[-2,1]],
+    "2>3":[[0,0],[2,0],[-1,0],[2,1],[-1,-2]], "3>2":[[0,0],[-2,0],[1,0],[-2,-1],[1,2]],
+    "3>0":[[0,0],[1,0],[-2,0],[1,-2],[-2,1]], "0>3":[[0,0],[-1,0],[2,0],[-1,2],[2,-1]]
+  };
+  const TYPES = ["I","J","L","O","S","T","Z"];
+
+  // ---------- canvas sizing ----------
+  const board = document.getElementById("board");
+  const bctx = board.getContext("2d");
+  let CELL = 30; // px, recomputed on resize
+  const nextCv = document.getElementById("next"), nctx = nextCv.getContext("2d");
+  const holdCv = document.getElementById("hold"), hctx = holdCv.getContext("2d");
+
+  function fitCanvas() {
+    const maxH = Math.min(window.innerHeight - 40, 720);
+    const maxW = Math.min(window.innerWidth - 190, 480);
+    CELL = Math.max(14, Math.floor(Math.min(maxH / ROWS, maxW / COLS)));
+    const dpr = window.devicePixelRatio || 1;
+    board.width = COLS * CELL * dpr; board.height = ROWS * CELL * dpr;
+    board.style.width = COLS * CELL + "px"; board.style.height = ROWS * CELL + "px";
+    bctx.setTransform(dpr,0,0,dpr,0,0);
+    const pc = Math.max(12, Math.floor(CELL * 0.62));
+    for (const [cv,ctx] of [[nextCv,nctx],[holdCv,hctx]]) {
+      cv.width = 4*pc*dpr; cv.height = 4*pc*dpr;
+      cv.style.width = 4*pc+"px"; cv.style.height = 4*pc+"px";
+      ctx.setTransform(dpr,0,0,dpr,0,0);
+    }
+    nctx._c = pc; hctx._c = pc;
+    draw();
+  }
+  window.addEventListener("resize", fitCanvas);
+
+  // ---------- audio (procedural, zero-dep) ----------
+  let audioCtx = null, muted = (localStorage.getItem("blocks.muted") === "1");
+  function ac() { if (!audioCtx) { try { audioCtx = new (window.AudioContext||window.webkitAudioContext)(); } catch(e){} } return audioCtx; }
+  function beep(freq, dur, type="square", vol=0.05) {
+    if (muted) return; const c = ac(); if (!c) return;
+    const o = c.createOscillator(), g = c.createGain();
+    o.type = type; o.frequency.value = freq;
+    g.gain.setValueAtTime(vol, c.currentTime);
+    g.gain.exponentialRampToValueAtTime(0.0001, c.currentTime + dur);
+    o.connect(g); g.connect(c.destination); o.start(); o.stop(c.currentTime + dur);
+  }
+  const S = {
+    move:  () => beep(220, .03, "square", .03),
+    rotate:() => beep(330, .04, "square", .035),
+    drop:  () => beep(140, .08, "sawtooth", .05),
+    lock:  () => beep(180, .05, "triangle", .04),
+    clear: (n) => { const base=[440,554,659,880][Math.min(n-1,3)]; beep(base,.10,"square",.06); setTimeout(()=>beep(base*1.5,.12,"square",.05),90); },
+    hold:  () => beep(400, .05, "triangle", .04),
+    over:  () => { beep(200,.2,"sawtooth",.06); setTimeout(()=>beep(120,.35,"sawtooth",.06),160); },
+    level: () => { beep(660,.08,"square",.05); setTimeout(()=>beep(990,.12,"square",.05),80); }
+  };
+
+  // ---------- game state ----------
+  let grid, cur, nextQ, holdType, canHold, bag;
+  let score, best, lines, level, dropMs, dropAcc, lastT;
+  let state = "menu"; // menu | playing | paused | over
+  best = +(localStorage.getItem("blocks.best") || 0);
+
+  function newBag() {
+    const b = TYPES.slice();
+    for (let i=b.length-1;i>0;i--){ const j=Math.floor(Math.random()*(i+1)); [b[i],b[j]]=[b[j],b[i]]; }
+    return b;
+  }
+  function pullType() {
+    if (!bag || bag.length === 0) bag = newBag();
+    return bag.pop();
+  }
+  function spawn(type) {
+    const p = { type, rot: 0, x: 3, y: 0 };
+    // I and O spawn a touch higher/centered per SRS box; y offset into hidden area
+    p.y = (type === "I") ? -1 : 0;
+    return p;
+  }
+  function cellsOf(p, rot = p.rot, x = p.x, y = p.y) {
+    return SHAPES[p.type][((rot % 4) + 4) % 4].map(([cx,cy]) => [x+cx, y+cy]);
+  }
+  function collides(p, rot = p.rot, x = p.x, y = p.y) {
+    for (const [cx,cy] of cellsOf(p, rot, x, y)) {
+      if (cx < 0 || cx >= COLS || cy >= ROWS) return true;
+      if (cy >= 0 && grid[cy][cx]) return true;
+    }
+    return false;
+  }
+
+  function reset() {
+    grid = Array.from({length: ROWS}, () => Array(COLS).fill(null));
+    bag = newBag();
+    nextQ = [pullType(), pullType(), pullType()];
+    holdType = null; canHold = true;
+    score = 0; lines = 0; level = 1;
+    dropMs = levelSpeed(1); dropAcc = 0;
+    nextPiece();
+  }
+  function levelSpeed(lv) { return Math.max(60, Math.round(800 * Math.pow(0.83, lv - 1))); }
+
+  function nextPiece() {
+    const t = nextQ.shift();
+    nextQ.push(pullType());
+    cur = spawn(t);
+    canHold = true;
+    if (collides(cur)) { gameOver(); }
+  }
+
+  function move(dx) {
+    if (!collides(cur, cur.rot, cur.x + dx, cur.y)) { cur.x += dx; S.move(); draw(); return true; }
+    return false;
+  }
+  function rotate(dir) {
+    const from = cur.rot, to = ((from + dir) % 4 + 4) % 4;
+    const table = cur.type === "I" ? KICKS_I : KICKS;
+    if (cur.type === "O") { return; }
+    const kicks = table[`${from}>${to}`] || [[0,0]];
+    for (const [kx,ky] of kicks) {
+      if (!collides(cur, to, cur.x + kx, cur.y - ky)) {
+        cur.rot = to; cur.x += kx; cur.y -= ky; S.rotate(); draw(); return;
+      }
+    }
+  }
+  function softDrop() {
+    if (!collides(cur, cur.rot, cur.x, cur.y + 1)) { cur.y++; score += 1; updateHUD(); draw(); }
+    else lock();
+  }
+  function hardDrop() {
+    let d = 0;
+    while (!collides(cur, cur.rot, cur.x, cur.y + 1)) { cur.y++; d++; }
+    score += d * 2; S.drop();
+    lock();
+  }
+  function hold() {
+    if (!canHold) return;
+    S.hold();
+    if (holdType == null) { holdType = cur.type; nextPiece(); }
+    else { const t = holdType; holdType = cur.type; cur = spawn(t); if (collides(cur)) gameOver(); }
+    canHold = false;
+    draw();
+  }
+  function lock() {
+    for (const [cx,cy] of cellsOf(cur)) { if (cy >= 0) grid[cy][cx] = cur.type; }
+    S.lock();
+    // clear lines
+    let cleared = 0;
+    for (let y = ROWS - 1; y >= 0; y--) {
+      if (grid[y].every(c => c)) {
+        grid.splice(y, 1); grid.unshift(Array(COLS).fill(null)); cleared++; y++;
+      }
+    }
+    if (cleared > 0) {
+      const pts = [0, 100, 300, 500, 800][cleared] * level;
+      score += pts; lines += cleared;
+      const newLevel = Math.floor(lines / 10) + 1;
+      if (newLevel > level) { level = newLevel; dropMs = levelSpeed(level); S.level(); }
+      else S.clear(cleared);
+    }
+    updateHUD();
+    if (state === "playing") nextPiece();
+    draw();
+  }
+
+  function ghostY() {
+    let y = cur.y;
+    while (!collides(cur, cur.rot, cur.x, y + 1)) y++;
+    return y;
+  }
+
+  // ---------- rendering ----------
+  function roundedCell(ctx, x, y, s, color, alpha = 1) {
+    ctx.globalAlpha = alpha;
+    ctx.fillStyle = color;
+    const r = Math.max(2, s * 0.14), pad = Math.max(1, s * 0.06);
+    const px = x + pad, py = y + pad, ps = s - pad * 2;
+    ctx.beginPath();
+    ctx.roundRect(px, py, ps, ps, r);
+    ctx.fill();
+    // top highlight
+    ctx.globalAlpha = alpha * 0.28; ctx.fillStyle = "#ffffff";
+    ctx.beginPath(); ctx.roundRect(px, py, ps, ps * 0.42, r); ctx.fill();
+    ctx.globalAlpha = 1;
+  }
+
+  function draw() {
+    bctx.clearRect(0, 0, COLS * CELL, ROWS * CELL);
+    // grid dots
+    bctx.strokeStyle = "rgba(255,255,255,0.03)";
+    bctx.lineWidth = 1;
+    for (let x = 1; x < COLS; x++) { bctx.beginPath(); bctx.moveTo(x*CELL,0); bctx.lineTo(x*CELL,ROWS*CELL); bctx.stroke(); }
+    for (let y = 1; y < ROWS; y++) { bctx.beginPath(); bctx.moveTo(0,y*CELL); bctx.lineTo(COLS*CELL,y*CELL); bctx.stroke(); }
+
+    // settled
+    for (let y = 0; y < ROWS; y++) for (let x = 0; x < COLS; x++) {
+      if (grid[y][x]) roundedCell(bctx, x*CELL, y*CELL, CELL, COLORS[grid[y][x]]);
+    }
+
+    if (cur && (state === "playing" || state === "paused")) {
+      // ghost
+      const gy = ghostY();
+      for (const [cx,cy] of cellsOf(cur, cur.rot, cur.x, gy)) {
+        if (cy >= 0) roundedCell(bctx, cx*CELL, cy*CELL, CELL, COLORS[cur.type], 0.18);
+      }
+      // active
+      for (const [cx,cy] of cellsOf(cur)) {
+        if (cy >= 0) roundedCell(bctx, cx*CELL, cy*CELL, CELL, COLORS[cur.type]);
+      }
+    }
+
+    if (state === "paused") {
+      bctx.fillStyle = "rgba(8,10,16,.6)";
+      bctx.fillRect(0,0,COLS*CELL,ROWS*CELL);
+      bctx.fillStyle = "#e8e9ef"; bctx.font = `700 ${CELL*0.7}px ui-monospace, monospace`;
+      bctx.textAlign = "center"; bctx.textBaseline = "middle";
+      bctx.fillText("PAUSED", COLS*CELL/2, ROWS*CELL/2);
+    }
+    drawPreview(nctx, nextQ && nextQ[0]);
+    drawPreview(hctx, holdType, !canHold && holdType);
+  }
+
+  function drawPreview(ctx, type, dim) {
+    const pc = ctx._c || 18;
+    ctx.clearRect(0,0,4*pc,4*pc);
+    if (!type) return;
+    const cells = SHAPES[type][0];
+    const xs = cells.map(c=>c[0]), ys = cells.map(c=>c[1]);
+    const minx = Math.min(...xs), maxx = Math.max(...xs);
+    const miny = Math.min(...ys), maxy = Math.max(...ys);
+    const w = maxx - minx + 1, h = maxy - miny + 1;
+    const ox = (4 - w) / 2 - minx, oy = (4 - h) / 2 - miny;
+    for (const [cx,cy] of cells) roundedCell(ctx, (cx+ox)*pc, (cy+oy)*pc, pc, COLORS[type], dim ? 0.35 : 1);
+  }
+
+  function updateHUD() {
+    document.getElementById("score").textContent = score.toLocaleString();
+    document.getElementById("lines").textContent = lines;
+    document.getElementById("level").textContent = level;
+    if (score > best) { best = score; localStorage.setItem("blocks.best", best); }
+    document.getElementById("best").textContent = best.toLocaleString();
+  }
+
+  // ---------- loop ----------
+  function tick(t) {
+    if (state !== "playing") { lastT = t; requestAnimationFrame(tick); return; }
+    const dt = t - lastT; lastT = t;
+    dropAcc += dt;
+    if (dropAcc >= dropMs) {
+      dropAcc = 0;
+      if (!collides(cur, cur.rot, cur.x, cur.y + 1)) cur.y++;
+      else lock();
+      draw();
+    }
+    requestAnimationFrame(tick);
+  }
+
+  // ---------- state transitions ----------
+  const overlay = document.getElementById("overlay");
+  const panelSub = document.getElementById("panelSub");
+  const panelScore = document.getElementById("panelScore");
+  const startBtn = document.getElementById("startBtn");
+
+  function startGame() {
+    ac();
+    reset(); updateHUD();
+    state = "playing"; lastT = performance.now(); dropAcc = 0;
+    overlay.classList.add("hidden");
+    draw();
+  }
+  function gameOver() {
+    state = "over"; S.over();
+    panelScore.style.display = "block";
+    panelScore.innerHTML = `Score <b>${score.toLocaleString()}</b> · Best <b>${best.toLocaleString()}</b> · Lines ${lines}`;
+    document.querySelector("#panel .title").innerHTML = 'GAME<span class="dot">·</span>OVER';
+    panelSub.innerHTML = "The stack topped out.<br>Clear lines faster to survive higher levels.";
+    startBtn.textContent = "Play Again";
+    overlay.classList.remove("hidden");
+  }
+  function togglePause() {
+    if (state === "playing") { state = "paused"; draw(); document.getElementById("pauseBtn").textContent = "Resume"; }
+    else if (state === "paused") { state = "playing"; lastT = performance.now(); document.getElementById("pauseBtn").textContent = "Pause"; draw(); }
+  }
+
+  // ---------- input ----------
+  const KEYMAP = {
+    ArrowLeft: () => move(-1), ArrowRight: () => move(1),
+    ArrowDown: () => softDrop(),
+    ArrowUp: () => rotate(1), x: () => rotate(1), X: () => rotate(1),
+    z: () => rotate(-1), Z: () => rotate(-1),
+    c: () => hold(), C: () => hold(),
+    " ": () => hardDrop()
+  };
+  window.addEventListener("keydown", (e) => {
+    if (["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"," "].includes(e.key)) e.preventDefault();
+    if (e.key === "p" || e.key === "P" || e.key === "Escape") { if (state==="playing"||state==="paused") togglePause(); return; }
+    if (e.key === "m" || e.key === "M") { toggleMute(); return; }
+    if (e.repeat && (e.key===" "||e.key==="c"||e.key==="C"||e.key==="z"||e.key==="Z"||e.key==="x"||e.key==="X"||e.key==="ArrowUp")) return;
+    if (state !== "playing") { if ((e.key===" "||e.key==="Enter") && state!=="playing") startBtn.click(); return; }
+    const fn = KEYMAP[e.key]; if (fn) fn();
+  });
+
+  function toggleMute() {
+    muted = !muted; localStorage.setItem("blocks.muted", muted ? "1" : "0");
+    document.getElementById("muteBtn").textContent = muted ? "🔇" : "🔊";
+  }
+
+  document.getElementById("pauseBtn").addEventListener("click", () => { if (state==="playing"||state==="paused") togglePause(); });
+  document.getElementById("muteBtn").addEventListener("click", toggleMute);
+  startBtn.addEventListener("click", startGame);
+
+  // auto-pause when tab/frame loses focus
+  window.addEventListener("blur", () => { if (state === "playing") togglePause(); });
+
+  // ---------- touch controls ----------
+  let tStart = null, tMoved = false, lastTapT = 0;
+  const SWIPE = 24;
+  board.addEventListener("touchstart", (e) => {
+    if (state === "menu" || state === "over") { startBtn.click(); return; }
+    if (state === "paused") { togglePause(); return; }
+    tStart = { x: e.touches[0].clientX, y: e.touches[0].clientY, t: performance.now(), cx: cur.x }; tMoved = false;
+  }, { passive: true });
+  board.addEventListener("touchmove", (e) => {
+    if (!tStart || state !== "playing") return;
+    const dx = e.touches[0].clientX - tStart.x, dy = e.touches[0].clientY - tStart.y;
+    if (Math.abs(dx) > Math.abs(dy)) {
+      const target = tStart.cx + Math.round(dx / (CELL));
+      while (cur.x < target) { if (!move(1)) break; }
+      while (cur.x > target) { if (!move(-1)) break; }
+      if (Math.abs(dx) > SWIPE) tMoved = true;
+    } else if (dy > SWIPE * 2) { softDrop(); tStart.y = e.touches[0].clientY; tMoved = true; }
+  }, { passive: true });
+  board.addEventListener("touchend", (e) => {
+    if (!tStart || state !== "playing") { tStart = null; return; }
+    const dur = performance.now() - tStart.t;
+    const dy = (e.changedTouches[0].clientY - tStart.y);
+    if (!tMoved && dur < 250) {
+      // tap = rotate; double-tap-ish fast downward fling handled above
+      rotate(1);
+    } else if (dy > CELL * 6 && dur < 260) {
+      hardDrop();
+    }
+    tStart = null;
+  }, { passive: true });
+
+  // ---------- boot ----------
+  document.getElementById("muteBtn").textContent = muted ? "🔇" : "🔊";
+  document.getElementById("best").textContent = best.toLocaleString();
+  // idle empty board behind the menu — init grid BEFORE first draw (fitCanvas draws)
+  grid = Array.from({length: ROWS}, () => Array(COLS).fill(null));
+  fitCanvas();
+  draw();
+  requestAnimationFrame(tick);
+})();
+</script>
+</body>
+</html>
diff --git a/games/tower-stack/AbramsStack.aa b/games/tower-stack/AbramsStack.aa
new file mode 100644
index 0000000..d25f198
--- /dev/null
+++ b/games/tower-stack/AbramsStack.aa
@@ -0,0 +1,513 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+<title>Abrams Stack</title>
+<style>
+  * { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
+  html, body { width: 100%; height: 100%; overflow: hidden; background: #0a0a18; }
+  #wrap {
+    position: fixed; inset: 0;
+    display: flex; align-items: center; justify-content: center;
+    background: radial-gradient(ellipse at 50% 0%, #1a1240 0%, #0a0a18 60%, #050510 100%);
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+    user-select: none;
+  }
+  canvas { display: block; touch-action: none; }
+
+  /* HUD */
+  #hud {
+    position: absolute; top: 0; left: 0; right: 0;
+    display: flex; justify-content: space-between; align-items: flex-start;
+    padding: 18px 20px; pointer-events: none; z-index: 5;
+  }
+  .stat { color: #fff; text-shadow: 0 2px 12px rgba(0,0,0,.6); }
+  .stat .label { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; opacity: .55; }
+  .stat .val { font-size: 34px; font-weight: 800; line-height: 1; margin-top: 2px;
+    background: linear-gradient(180deg,#fff,#b9c4ff); -webkit-background-clip: text; background-clip: text; color: transparent; }
+  .stat.right { text-align: right; }
+  #combo {
+    position:absolute; top: 78px; left: 50%; transform: translateX(-50%);
+    font-size: 15px; font-weight: 700; letter-spacing: 1px; color: #ffe27a;
+    text-shadow: 0 0 18px rgba(255,210,80,.7); opacity: 0; transition: opacity .2s; pointer-events:none; z-index:5;
+  }
+
+  /* Mute */
+  #mute {
+    position: absolute; top: 16px; right: 50%; transform: translateX(50%);
+    width: 42px; height: 42px; border-radius: 12px;
+    background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
+    color: #fff; font-size: 19px; cursor: pointer; z-index: 6;
+    display:flex; align-items:center; justify-content:center; backdrop-filter: blur(6px);
+    transition: background .15s, transform .1s;
+  }
+  #mute:hover { background: rgba(255,255,255,.14); }
+  #mute:active { transform: translateX(50%) scale(.9); }
+
+  /* Overlay */
+  #overlay {
+    position: absolute; inset: 0; z-index: 10;
+    display: flex; flex-direction: column; align-items: center; justify-content: center;
+    text-align: center; padding: 24px;
+    background: radial-gradient(ellipse at 50% 40%, rgba(30,20,70,.55), rgba(5,5,16,.9));
+    backdrop-filter: blur(3px);
+    transition: opacity .35s;
+  }
+  #overlay.hidden { opacity: 0; pointer-events: none; }
+  #title {
+    font-size: clamp(42px, 12vw, 92px); font-weight: 900; letter-spacing: -1px; line-height: .95;
+    background: linear-gradient(120deg,#7af0ff,#a97bff 45%,#ff7ac6 90%);
+    -webkit-background-clip: text; background-clip: text; color: transparent;
+    filter: drop-shadow(0 4px 26px rgba(160,110,255,.45));
+  }
+  #subtitle { margin-top: 14px; font-size: 15px; letter-spacing: 3px; text-transform: uppercase; color: rgba(255,255,255,.6); }
+  #big {
+    margin: 26px 0 6px; font-size: clamp(34px,9vw,60px); font-weight: 900; color:#fff;
+    text-shadow: 0 0 30px rgba(140,110,255,.6);
+  }
+  #ovBest { font-size: 14px; letter-spacing: 2px; color:#8fe0ff; text-transform: uppercase; }
+  #hint {
+    margin-top: 34px; font-size: 15px; color: rgba(255,255,255,.82);
+    padding: 14px 26px; border: 1px solid rgba(255,255,255,.16); border-radius: 50px;
+    background: rgba(255,255,255,.05); animation: pulse 1.8s ease-in-out infinite;
+  }
+  @keyframes pulse { 0%,100%{ transform: scale(1); opacity:.85 } 50%{ transform: scale(1.05); opacity:1 } }
+  #credit { position:absolute; bottom: 16px; font-size: 11px; letter-spacing: 2px; color: rgba(255,255,255,.28); text-transform: uppercase; }
+</style>
+</head>
+<body>
+<div id="wrap">
+  <canvas id="c"></canvas>
+
+  <div id="hud">
+    <div class="stat">
+      <div class="label">Height</div>
+      <div class="val" id="score">0</div>
+    </div>
+    <div class="stat right">
+      <div class="label">Best</div>
+      <div class="val" id="best">0</div>
+    </div>
+  </div>
+  <div id="combo"></div>
+  <button id="mute" aria-label="Toggle sound">🔊</button>
+
+  <div id="overlay">
+    <div id="title">ABRAMS<br>STACK</div>
+    <div id="subtitle">stack it high</div>
+    <div id="big" style="display:none"></div>
+    <div id="ovBest"></div>
+    <div id="hint">Tap / Click / Space to drop</div>
+  </div>
+  <div id="credit">Pure Canvas 2D · Zero Dependencies</div>
+</div>
+
+<script>
+(function () {
+  "use strict";
+
+  var canvas = document.getElementById("c");
+  var ctx = canvas.getContext("2d");
+  var scoreEl = document.getElementById("score");
+  var bestEl = document.getElementById("best");
+  var comboEl = document.getElementById("combo");
+  var overlay = document.getElementById("overlay");
+  var titleEl = document.getElementById("title");
+  var subtitleEl = document.getElementById("subtitle");
+  var bigEl = document.getElementById("big");
+  var ovBestEl = document.getElementById("ovBest");
+  var hintEl = document.getElementById("hint");
+  var muteBtn = document.getElementById("mute");
+
+  // ---------- Sizing (DPR aware, iframe responsive) ----------
+  var W = 0, H = 0, DPR = 1;
+  function resize() {
+    DPR = Math.min(window.devicePixelRatio || 1, 2);
+    W = window.innerWidth;
+    H = window.innerHeight;
+    canvas.width = Math.floor(W * DPR);
+    canvas.height = Math.floor(H * DPR);
+    canvas.style.width = W + "px";
+    canvas.style.height = H + "px";
+    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
+  }
+  window.addEventListener("resize", resize);
+  resize();
+
+  // ---------- Persistent best ----------
+  var best = 0;
+  try { best = parseInt(localStorage.getItem("abramsStackBest") || "0", 10) || 0; } catch (e) {}
+  bestEl.textContent = best;
+
+  // ---------- Audio (procedural, optional) ----------
+  var muted = false;
+  try { muted = localStorage.getItem("abramsStackMuted") === "1"; } catch (e) {}
+  muteBtn.textContent = muted ? "🔇" : "🔊";
+  var actx = null;
+  function ensureAudio() {
+    if (muted) return;
+    if (!actx) {
+      try { actx = new (window.AudioContext || window.webkitAudioContext)(); } catch (e) { actx = null; }
+    }
+    if (actx && actx.state === "suspended") actx.resume();
+  }
+  function tone(freq, dur, type, vol, glideTo) {
+    if (muted || !actx) return;
+    var t = actx.currentTime;
+    var o = actx.createOscillator();
+    var g = actx.createGain();
+    o.type = type || "sine";
+    o.frequency.setValueAtTime(freq, t);
+    if (glideTo) o.frequency.exponentialRampToValueAtTime(glideTo, t + dur);
+    g.gain.setValueAtTime(0.0001, t);
+    g.gain.exponentialRampToValueAtTime(vol || 0.2, t + 0.008);
+    g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
+    o.connect(g); g.connect(actx.destination);
+    o.start(t); o.stop(t + dur + 0.02);
+  }
+  function sndDrop() { tone(220, 0.14, "sine", 0.22, 150); }
+  function sndSlice() { tone(140, 0.12, "sawtooth", 0.14, 90); }
+  function sndPerfect(n) {
+    if (muted || !actx) return;
+    var base = 520 + Math.min(n, 8) * 40;
+    tone(base, 0.14, "triangle", 0.22);
+    setTimeout(function () { tone(base * 1.5, 0.16, "triangle", 0.18); }, 70);
+  }
+  function sndOver() {
+    tone(300, 0.5, "sawtooth", 0.2, 70);
+    setTimeout(function () { tone(160, 0.5, "sine", 0.15, 60); }, 90);
+  }
+  muteBtn.addEventListener("click", function (e) {
+    e.stopPropagation();
+    muted = !muted;
+    muteBtn.textContent = muted ? "🔇" : "🔊";
+    try { localStorage.setItem("abramsStackMuted", muted ? "1" : "0"); } catch (er) {}
+    if (!muted) ensureAudio();
+  });
+
+  // ---------- Game state ----------
+  var STATE_START = 0, STATE_PLAY = 1, STATE_OVER = 2;
+  var state = STATE_START;
+
+  var BLOCK_H = 46;        // logical pixel height of each block
+  var baseWidth = 0;       // starting block width
+  var blocks = [];         // placed blocks {x, w, hue}
+  var current = null;      // moving block {x, w, dir, hue}
+  var speed = 0;
+  var camY = 0;            // camera vertical offset (target)
+  var camYCur = 0;         // smoothed
+  var score = 0;
+  var combo = 0;
+  var particles = [];
+  var slices = [];         // falling sliced-off pieces
+  var flash = 0;           // perfect flash intensity
+
+  function hueForLevel(n) { return (200 + n * 9) % 360; }
+
+  function groundY() { return H - 90; } // y of top of base row in world space (before camera)
+
+  function reset() {
+    blocks = [];
+    slices = [];
+    particles = [];
+    score = 0;
+    combo = 0;
+    camY = 0; camYCur = 0;
+    flash = 0;
+    baseWidth = Math.min(W * 0.5, 300);
+    speed = Math.max(2.6, W / 300);
+    var bx = (W - baseWidth) / 2;
+    blocks.push({ x: bx, w: baseWidth, hue: hueForLevel(0) });
+    spawnCurrent();
+  }
+
+  function spawnCurrent() {
+    var prev = blocks[blocks.length - 1];
+    var fromLeft = blocks.length % 2 === 0;
+    var startX = fromLeft ? -prev.w : W;
+    current = {
+      x: fromLeft ? -prev.w * 0.6 : W - prev.w * 0.4,
+      w: prev.w,
+      dir: fromLeft ? 1 : -1,
+      hue: hueForLevel(blocks.length)
+    };
+    // speed scales with height
+    speed = Math.max(2.6, W / 300) * (1 + blocks.length * 0.035);
+  }
+
+  // world Y (bottom-up) for the top of a block at index i (i=0 is base)
+  function blockWorldY(i) { return groundY() - i * BLOCK_H; }
+
+  function showCombo(txt) {
+    comboEl.textContent = txt;
+    comboEl.style.opacity = "1";
+    clearTimeout(showCombo._t);
+    showCombo._t = setTimeout(function () { comboEl.style.opacity = "0"; }, 800);
+  }
+
+  function drop() {
+    if (state !== STATE_PLAY) return;
+    var prev = blocks[blocks.length - 1];
+    var cx = current.x, cw = current.w;
+    var overlapL = Math.max(cx, prev.x);
+    var overlapR = Math.min(cx + cw, prev.x + prev.w);
+    var overlap = overlapR - overlapL;
+
+    if (overlap <= 0) {
+      // total miss -> game over. add the whole falling block as a slice
+      slices.push({ x: cx, w: cw, y: blockWorldY(blocks.length - 1) - BLOCK_H, hue: current.hue, vy: 0, vx: current.dir * 1.5, rot: 0, vr: current.dir * 0.05 });
+      gameOver();
+      return;
+    }
+
+    // perfect detection
+    var diff = Math.abs(cx - prev.x);
+    var perfect = diff < 4;
+
+    if (perfect) {
+      combo++;
+      flash = 1;
+      sndPerfect(combo);
+      // snap to perfect alignment (no shrink), small bonus width back on combo
+      cx = prev.x;
+      showCombo(combo > 1 ? "PERFECT ×" + combo + "  +" + (combo) : "PERFECT!");
+      spawnParticles(cx + cw / 2, blockWorldY(blocks.length - 1) - BLOCK_H / 2, current.hue, 22, true);
+    } else {
+      combo = 0;
+      sndDrop();
+      // slice off the overhang
+      if (cx < prev.x) {
+        // overhang on the left
+        var offW = prev.x - cx;
+        slices.push({ x: cx, w: offW, y: blockWorldY(blocks.length - 1) - BLOCK_H, hue: current.hue, vy: 0, vx: -1.4, rot: 0, vr: -0.06 });
+      } else {
+        var offW2 = (cx + cw) - (prev.x + prev.w);
+        if (offW2 > 0) slices.push({ x: prev.x + prev.w, w: offW2, y: blockWorldY(blocks.length - 1) - BLOCK_H, hue: current.hue, vy: 0, vx: 1.4, rot: 0, vr: 0.06 });
+      }
+      sndSlice();
+      cx = overlapL;
+      cw = overlap;
+      spawnParticles(overlapL + overlap / 2, blockWorldY(blocks.length - 1) - BLOCK_H / 2, current.hue, 8, false);
+    }
+
+    blocks.push({ x: cx, w: cw, hue: current.hue });
+    score++;
+    scoreEl.textContent = score;
+
+    // camera pans up as tower grows (keep top few visible)
+    var visibleRows = Math.max(4, Math.floor((H - 200) / BLOCK_H));
+    if (blocks.length > visibleRows) {
+      camY = (blocks.length - visibleRows) * BLOCK_H;
+    }
+
+    spawnCurrent();
+  }
+
+  function spawnParticles(x, worldY, hue, count, sparkle) {
+    for (var i = 0; i < count; i++) {
+      var a = Math.random() * Math.PI * 2;
+      var sp = (sparkle ? 2 + Math.random() * 4 : 1 + Math.random() * 2.5);
+      particles.push({
+        x: x, wy: worldY,
+        vx: Math.cos(a) * sp,
+        vy: Math.sin(a) * sp - (sparkle ? 1.5 : 0.5),
+        life: 1, hue: hue, size: 2 + Math.random() * (sparkle ? 4 : 2)
+      });
+    }
+  }
+
+  function gameOver() {
+    state = STATE_OVER;
+    sndOver();
+    if (score > best) {
+      best = score;
+      try { localStorage.setItem("abramsStackBest", String(best)); } catch (e) {}
+      bestEl.textContent = best;
+    }
+    titleEl.style.display = "none";
+    subtitleEl.style.display = "none";
+    bigEl.style.display = "block";
+    bigEl.textContent = "Height  " + score;
+    ovBestEl.textContent = (score >= best && score > 0 ? "★ NEW BEST ★" : "Best  " + best);
+    hintEl.textContent = "Tap / Click / Space to retry";
+    overlay.classList.remove("hidden");
+  }
+
+  function startGame() {
+    ensureAudio();
+    overlay.classList.add("hidden");
+    titleEl.style.display = "";
+    subtitleEl.style.display = "";
+    bigEl.style.display = "none";
+    reset();
+    state = STATE_PLAY;
+  }
+
+  // ---------- Input ----------
+  function onAction(e) {
+    if (e && e.target === muteBtn) return;
+    if (e) e.preventDefault();
+    ensureAudio();
+    if (state === STATE_PLAY) {
+      drop();
+    } else {
+      startGame();
+    }
+  }
+  window.addEventListener("pointerdown", onAction, { passive: false });
+  window.addEventListener("keydown", function (e) {
+    if (e.code === "Space" || e.key === " " || e.code === "Enter") {
+      e.preventDefault();
+      onAction();
+    }
+  });
+
+  // ---------- Render helpers ----------
+  function roundRect(x, y, w, h, r) {
+    r = Math.min(r, w / 2, h / 2);
+    ctx.beginPath();
+    ctx.moveTo(x + r, y);
+    ctx.arcTo(x + w, y, x + w, y + h, r);
+    ctx.arcTo(x + w, y + h, x, y + h, r);
+    ctx.arcTo(x, y + h, x, y, r);
+    ctx.arcTo(x, y, x + w, y, r);
+    ctx.closePath();
+  }
+
+  function drawBlock(x, screenY, w, hue, glow) {
+    var top = "hsl(" + hue + ",78%,64%)";
+    var bot = "hsl(" + hue + ",70%,44%)";
+    var grad = ctx.createLinearGradient(0, screenY, 0, screenY + BLOCK_H);
+    grad.addColorStop(0, top);
+    grad.addColorStop(1, bot);
+    if (glow) {
+      ctx.save();
+      ctx.shadowColor = "hsla(" + hue + ",90%,65%,0.9)";
+      ctx.shadowBlur = 26;
+    }
+    ctx.fillStyle = grad;
+    roundRect(x, screenY, w, BLOCK_H - 3, 7);
+    ctx.fill();
+    if (glow) ctx.restore();
+    // top highlight
+    ctx.fillStyle = "hsla(" + hue + ",90%,80%,0.5)";
+    roundRect(x + 3, screenY + 2, w - 6, 5, 3);
+    ctx.fill();
+  }
+
+  // ---------- Loop ----------
+  var lastT = performance.now();
+  function frame(now) {
+    var dt = Math.min((now - lastT) / 16.6667, 3); // normalized to 60fps
+    lastT = now;
+
+    // smooth camera
+    camYCur += (camY - camYCur) * Math.min(1, 0.12 * dt);
+    if (flash > 0) flash = Math.max(0, flash - 0.05 * dt);
+
+    // update moving block
+    if (state === STATE_PLAY && current) {
+      current.x += current.dir * speed * dt;
+      var prev = blocks[blocks.length - 1];
+      // bounce within a range slightly beyond the tower so it fully crosses
+      var leftLimit = -current.w * 0.9;
+      var rightLimit = W - current.w * 0.1;
+      if (current.x < leftLimit) { current.x = leftLimit; current.dir = 1; }
+      if (current.x > rightLimit) { current.x = rightLimit; current.dir = -1; }
+    }
+
+    // update particles
+    for (var i = particles.length - 1; i >= 0; i--) {
+      var p = particles[i];
+      p.x += p.vx * dt;
+      p.wy += p.vy * dt;
+      p.vy += 0.18 * dt;
+      p.life -= 0.02 * dt;
+      if (p.life <= 0) particles.splice(i, 1);
+    }
+    // update slices (falling debris)
+    for (var s = slices.length - 1; s >= 0; s--) {
+      var sl = slices[s];
+      sl.vy += 0.55 * dt;
+      sl.y += sl.vy * dt;
+      sl.x += sl.vx * dt;
+      sl.rot += sl.vr * dt;
+      if (sl.y - camYCur > H + 200) slices.splice(s, 1);
+    }
+
+    draw();
+    requestAnimationFrame(frame);
+  }
+
+  function draw() {
+    ctx.clearRect(0, 0, W, H);
+
+    // subtle drifting bg glow tied to height
+    var topHue = hueForLevel(blocks.length);
+    var g = ctx.createRadialGradient(W / 2, H * 0.2, 40, W / 2, H * 0.2, Math.max(W, H));
+    g.addColorStop(0, "hsla(" + topHue + ",55%,22%,0.55)");
+    g.addColorStop(1, "rgba(5,5,16,0)");
+    ctx.fillStyle = g;
+    ctx.fillRect(0, 0, W, H);
+
+    function worldToScreen(wy) { return wy - camYCur; }
+
+    // placed blocks
+    for (var i = 0; i < blocks.length; i++) {
+      var b = blocks[i];
+      var wy = blockWorldY(i);            // world y of top of this block
+      var sy = worldToScreen(wy) - BLOCK_H;
+      if (sy > H + BLOCK_H || sy < -BLOCK_H) continue;
+      drawBlock(b.x, sy, b.w, b.hue, i === blocks.length - 1 && state === STATE_PLAY ? false : false);
+    }
+
+    // moving block
+    if (state === STATE_PLAY && current) {
+      var wyc = blockWorldY(blocks.length);
+      var syc = worldToScreen(wyc) - BLOCK_H;
+      drawBlock(current.x, syc, current.w, current.hue, true);
+    }
+
+    // slices (debris)
+    for (var s = 0; s < slices.length; s++) {
+      var sl = slices[s];
+      var sy2 = worldToScreen(sl.y);
+      ctx.save();
+      ctx.translate(sl.x + sl.w / 2, sy2 + BLOCK_H / 2);
+      ctx.rotate(sl.rot);
+      ctx.globalAlpha = 0.9;
+      var gr = ctx.createLinearGradient(0, -BLOCK_H / 2, 0, BLOCK_H / 2);
+      gr.addColorStop(0, "hsl(" + sl.hue + ",78%,60%)");
+      gr.addColorStop(1, "hsl(" + sl.hue + ",70%,42%)");
+      ctx.fillStyle = gr;
+      roundRect(-sl.w / 2, -BLOCK_H / 2, sl.w, BLOCK_H - 3, 6);
+      ctx.fill();
+      ctx.restore();
+    }
+
+    // particles
+    ctx.globalAlpha = 1;
+    for (var p = 0; p < particles.length; p++) {
+      var pa = particles[p];
+      ctx.globalAlpha = Math.max(0, pa.life);
+      ctx.fillStyle = "hsl(" + pa.hue + ",90%,68%)";
+      var py = pa.wy - camYCur;
+      ctx.beginPath();
+      ctx.arc(pa.x, py, pa.size, 0, Math.PI * 2);
+      ctx.fill();
+    }
+    ctx.globalAlpha = 1;
+
+    // perfect flash overlay
+    if (flash > 0) {
+      ctx.fillStyle = "rgba(255,255,255," + (flash * 0.18) + ")";
+      ctx.fillRect(0, 0, W, H);
+    }
+  }
+
+  requestAnimationFrame(frame);
+})();
+</script>
+</body>
+</html>
diff --git a/games/tron/AbramsTron.aa b/games/tron/AbramsTron.aa
new file mode 100644
index 0000000..ad192f3
--- /dev/null
+++ b/games/tron/AbramsTron.aa
@@ -0,0 +1,454 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Abrams Tron</title>
+<style>
+  :root {
+    --bg:#0a0e14; --arena:#0b1018; --grid:#122130; --gridGlow:#0e3a4a;
+    --p1:#22d3ee; --p1glow:#0891b2; --p2:#f59e0b; --p2glow:#b45309;
+    --ink:#e5e7eb; --dim:#8aa0b2;
+  }
+  * { box-sizing:border-box; margin:0; padding:0; }
+  html,body { height:100%; }
+  body {
+    background:radial-gradient(1200px 700px at 50% -12%, #10202e, var(--bg));
+    color:var(--ink); font:14px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
+    display:flex; flex-direction:column; align-items:center; justify-content:center;
+    min-height:100%; gap:10px; padding:12px; overscroll-behavior:none; touch-action:none;
+    -webkit-user-select:none; user-select:none;
+  }
+  h1 {
+    font-size:15px; letter-spacing:.42em; text-transform:uppercase; font-weight:700;
+    color:#e0f7ff; text-shadow:0 0 12px rgba(34,211,238,.55), 0 0 30px rgba(34,211,238,.25);
+    padding-left:.42em;
+  }
+  .hud {
+    display:flex; gap:16px; align-items:center; font-variant-numeric:tabular-nums;
+    font-size:12px; color:var(--dim); flex-wrap:wrap; justify-content:center;
+  }
+  .hud .pill { display:flex; align-items:center; gap:6px; padding:3px 10px; border-radius:999px;
+    border:1px solid #1c2a38; background:rgba(12,18,26,.6); }
+  .hud b { color:var(--ink); font-weight:700; }
+  .dot { width:9px; height:9px; border-radius:50%; }
+  .dot.p1 { background:var(--p1); box-shadow:0 0 8px var(--p1); }
+  .dot.p2 { background:var(--p2); box-shadow:0 0 8px var(--p2); }
+  .streak b { color:#fde68a; }
+  #wrap { position:relative; line-height:0; }
+  canvas {
+    background:var(--arena); border-radius:14px; display:block;
+    box-shadow:0 0 0 1px #16354a, 0 0 40px rgba(34,211,238,.12), 0 14px 50px rgba(0,0,0,.6);
+    max-width:96vw; max-height:70vh; touch-action:none;
+  }
+  .overlay {
+    position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
+    gap:10px; text-align:center; background:rgba(7,11,17,.78); border-radius:14px; backdrop-filter:blur(2px);
+    padding:16px;
+  }
+  .overlay.hide { display:none; }
+  .tag { font-size:11px; letter-spacing:.28em; text-transform:uppercase; color:var(--p1);
+    text-shadow:0 0 10px rgba(34,211,238,.5); }
+  .big { font-size:24px; font-weight:800; letter-spacing:.04em; }
+  .big.p1c { color:#67e8f9; text-shadow:0 0 16px rgba(34,211,238,.5); }
+  .big.p2c { color:#fbbf24; text-shadow:0 0 16px rgba(245,158,11,.5); }
+  .sub { font-size:12.5px; color:var(--dim); max-width:300px; }
+  button.play {
+    margin-top:4px; padding:11px 26px; border:0; border-radius:999px; cursor:pointer;
+    background:linear-gradient(180deg,#22d3ee,#0891b2); color:#031419; font-weight:800; font-size:14px;
+    letter-spacing:.06em; text-transform:uppercase; box-shadow:0 6px 20px rgba(34,211,238,.35);
+  }
+  .btns { position:absolute; top:8px; right:10px; display:flex; gap:6px; z-index:3; }
+  .btns button { width:32px; height:32px; border-radius:9px; border:1px solid #21384a;
+    background:rgba(15,24,34,.85); color:#bfe6f2; cursor:pointer; font-size:15px; }
+  .hint { font-size:11px; color:#5b6673; }
+  /* touch turn buttons */
+  .turns { display:none; gap:14px; margin-top:2px; }
+  .turns button {
+    width:74px; height:52px; border-radius:14px; border:1px solid #21384a;
+    background:rgba(15,24,34,.9); color:var(--p1); font-size:24px; cursor:pointer;
+    box-shadow:0 0 14px rgba(34,211,238,.15);
+  }
+  .turns button:active { background:rgba(34,211,238,.18); }
+  body.touch .turns { display:flex; }
+  body.touch .hint { display:none; }
+</style>
+</head>
+<body>
+  <h1>Abrams Tron</h1>
+  <div class="hud">
+    <span class="pill"><i class="dot p1"></i>YOU <b id="s1">0</b></span>
+    <span class="pill"><i class="dot p2"></i>CPU <b id="s2">0</b></span>
+    <span class="pill">Round <b id="round">1</b>/<b id="rounds">5</b></span>
+    <span class="pill streak">Streak <b id="streak">0</b> · Best <b id="best">0</b></span>
+  </div>
+  <div id="wrap">
+    <canvas id="c" width="480" height="480"></canvas>
+    <div class="btns">
+      <button id="pauseBtn" title="Pause (P)">⏸</button>
+    </div>
+    <div class="overlay" id="ov">
+      <div class="tag" id="ovTag">Ready</div>
+      <div class="big" id="ovTitle">Abrams Tron</div>
+      <div class="sub" id="ovSub">Ride the cyan cycle. Steer to box in the CPU and avoid every trail. First to 3 rounds wins the match.</div>
+      <button class="play" id="playBtn">Play</button>
+      <div class="hint">Arrows / WASD to turn · P pause</div>
+    </div>
+  </div>
+  <div class="turns">
+    <button id="tLeft" aria-label="Turn left">↺</button>
+    <button id="tRight" aria-label="Turn right">↻</button>
+  </div>
+
+<script>
+(function () {
+  "use strict";
+  function boot() {
+    var cv = document.getElementById('c');
+    if (!cv || !cv.getContext) return;
+    var ctx = cv.getContext('2d');
+
+    // ---- config ----
+    var COLS = 60, ROWS = 60;      // logical grid
+    var CELL = cv.width / COLS;    // pixel size per cell
+    var WIN_ROUNDS = 3;            // first to N rounds wins match
+    var MAX_ROUNDS = 5;
+    var TICK_MS = 55;              // movement cadence
+
+    var DIRS = { up:{x:0,y:-1}, down:{x:0,y:1}, left:{x:-1,y:0}, right:{x:1,y:0} };
+    var OPP = { up:'down', down:'up', left:'right', right:'left' };
+
+    var best = 0;
+    try { best = parseInt(localStorage.getItem('abrams-tron-best') || '0', 10) || 0; } catch (e) {}
+
+    // ---- state ----
+    var grid;                 // occupancy: 0 empty, 1 player, 2 ai
+    var player, ai;
+    var score1 = 0, score2 = 0, roundNo = 1, streak = 0;
+    var state = 'ready';      // ready | play | paused | roundover | matchover
+    var raf = null, acc = 0, last = 0;
+    var flash = 0, flashOwner = 0;
+
+    var $ = function (id) { return document.getElementById(id); };
+    var ov = $('ov');
+
+    function newCycle(col, row, dir, id) {
+      return { x:col, y:row, dir:dir, next:dir, id:id, alive:true, trail:[{x:col,y:row}] };
+    }
+
+    function resetRound() {
+      grid = new Array(COLS * ROWS);
+      for (var i = 0; i < grid.length; i++) grid[i] = 0;
+      // player left, heading right; ai right, heading left
+      var py = Math.floor(ROWS / 2);
+      player = newCycle(6, py, 'right', 1);
+      ai = newCycle(COLS - 7, py, 'left', 2);
+      grid[idx(player.x, player.y)] = 1;
+      grid[idx(ai.x, ai.y)] = 2;
+      acc = 0; flash = 0;
+    }
+
+    function idx(x, y) { return y * COLS + x; }
+    function inb(x, y) { return x >= 0 && y >= 0 && x < COLS && y < ROWS; }
+    function free(x, y) { return inb(x, y) && grid[idx(x, y)] === 0; }
+
+    // queue a turn (ignore reversals)
+    function turn(dir) {
+      if (state !== 'play') return;
+      if (dir === OPP[player.dir]) return;
+      player.next = dir;
+    }
+    // relative left/right turn for touch
+    function turnRel(rel) {
+      var order = ['up','right','down','left'];
+      var i = order.indexOf(player.dir);
+      var ni = (i + (rel > 0 ? 1 : 3)) % 4;
+      turn(order[ni]);
+    }
+
+    // ---- AI ----
+    // count how many free cells reachable within `limit` steps (flood) from a start cell,
+    // treating a hypothetical occupied set. Cheap space estimate to avoid trapping self.
+    function floodSpace(sx, sy, limit) {
+      if (!free(sx, sy)) return 0;
+      var seen = {};
+      var q = [[sx, sy]];
+      seen[idx(sx, sy)] = 1;
+      var count = 0, head = 0;
+      while (head < q.length && count < limit) {
+        var c = q[head++]; count++;
+        var nx, ny, dd = [[1,0],[-1,0],[0,1],[0,-1]];
+        for (var k = 0; k < 4; k++) {
+          nx = c[0] + dd[k][0]; ny = c[1] + dd[k][1];
+          var id2 = idx(nx, ny);
+          if (free(nx, ny) && !seen[id2]) { seen[id2] = 1; q.push([nx, ny]); }
+        }
+      }
+      return count;
+    }
+
+    function aiChoose() {
+      var options = ['up','down','left','right'];
+      var cur = ai.dir;
+      var best2 = null, bestScore = -1e9;
+      for (var i = 0; i < options.length; i++) {
+        var d = options[i];
+        if (d === OPP[cur]) continue;              // no reversing
+        var nx = ai.x + DIRS[d].x, ny = ai.y + DIRS[d].y;
+        if (!free(nx, ny)) continue;               // immediate death
+        // lookahead: space available after this move
+        grid[idx(nx, ny)] = 2;                     // tentatively occupy
+        var space = floodSpace(nx, ny, 260);
+        grid[idx(nx, ny)] = 0;                     // undo
+
+        var sc = space;
+        // prefer keeping straight a bit (smoother), small bonus
+        if (d === cur) sc += 6;
+        // aggression: bias toward cutting the player off — move that reduces
+        // player's open space is favored, but not at cost of our own survival.
+        var pdist = Math.abs(nx - player.x) + Math.abs(ny - player.y);
+        if (space > 40) sc += (30 - Math.min(pdist, 30)) * 0.6; // close in when safe
+        // tiny randomness to avoid deterministic loops
+        sc += Math.random() * 2;
+
+        if (sc > bestScore) { bestScore = sc; best2 = d; }
+      }
+      if (best2) ai.next = best2;
+      // if nothing safe, keep current dir (will crash — fair)
+    }
+
+    // ---- step ----
+    function step() {
+      aiChoose();
+      player.dir = player.next;
+      ai.dir = ai.next;
+
+      var p1x = player.x + DIRS[player.dir].x, p1y = player.y + DIRS[player.dir].y;
+      var a1x = ai.x + DIRS[ai.dir].x,       a1y = ai.y + DIRS[ai.dir].y;
+
+      var pDead = !free(p1x, p1y);
+      var aDead = !free(a1x, a1y);
+      // head-on into same cell = both dead
+      if (p1x === a1x && p1y === a1y) { pDead = true; aDead = true; }
+
+      if (!pDead) { grid[idx(p1x, p1y)] = 1; player.x = p1x; player.y = p1y; player.trail.push({x:p1x,y:p1y}); }
+      if (!aDead) { grid[idx(a1x, a1y)] = 2; ai.x = a1x; ai.y = a1y; ai.trail.push({x:a1x,y:a1y}); }
+
+      if (pDead || aDead) {
+        player.alive = !pDead; ai.alive = !aDead;
+        endRound(pDead, aDead);
+      }
+    }
+
+    function endRound(pDead, aDead) {
+      var winner; // 1 player, 2 ai, 0 draw
+      if (pDead && aDead) winner = 0;
+      else if (pDead) winner = 2;
+      else winner = 1;
+
+      if (winner === 1) { score1++; streak++; if (streak > best) { best = streak; saveBest(); } }
+      else if (winner === 2) { score2++; streak = 0; }
+      // draw: no score, no streak change
+
+      flash = 1; flashOwner = winner;
+      render();
+
+      var matchDone = score1 >= WIN_ROUNDS || score2 >= WIN_ROUNDS || roundNo >= MAX_ROUNDS;
+      if (matchDone) {
+        state = 'matchover';
+        var youWin = score1 > score2;
+        showOverlay(
+          youWin ? 'Match Won' : (score1 === score2 ? 'Match Draw' : 'Match Lost'),
+          youWin ? 'DERES.' : (score1 === score2 ? 'DEADLOCK.' : 'GAME OVER'),
+          'Final ' + score1 + ' – ' + score2 + '.  Best win streak ' + best + '.',
+          'Play Again', youWin ? 'p1c' : 'p2c'
+        );
+      } else {
+        state = 'roundover';
+        var msg = winner === 1 ? 'You boxed in the CPU.' : winner === 2 ? 'The CPU cut you off.' : 'Both cycles crashed.';
+        showOverlay(
+          'Round ' + roundNo + ' — ' + (winner === 1 ? 'You' : winner === 2 ? 'CPU' : 'Draw'),
+          winner === 1 ? 'ROUND WON' : winner === 2 ? 'ROUND LOST' : 'DRAW',
+          msg + '  ' + score1 + ' – ' + score2,
+          'Next Round', winner === 1 ? 'p1c' : winner === 2 ? 'p2c' : ''
+        );
+      }
+      updateHud();
+    }
+
+    function saveBest() { try { localStorage.setItem('abrams-tron-best', String(best)); } catch (e) {} }
+
+    function nextRound() {
+      roundNo++;
+      resetRound();
+      state = 'play';
+      hideOverlay();
+      updateHud();
+    }
+
+    function restartMatch() {
+      score1 = 0; score2 = 0; roundNo = 1; streak = 0;
+      resetRound();
+      state = 'play';
+      hideOverlay();
+      updateHud();
+    }
+
+    // ---- rendering ----
+    function drawGrid() {
+      ctx.fillStyle = '#0b1018';
+      ctx.fillRect(0, 0, cv.width, cv.height);
+      ctx.strokeStyle = 'rgba(20,52,72,.55)';
+      ctx.lineWidth = 1;
+      ctx.beginPath();
+      for (var x = 0; x <= COLS; x += 3) {
+        var px = Math.round(x * CELL) + 0.5;
+        ctx.moveTo(px, 0); ctx.lineTo(px, cv.height);
+      }
+      for (var y = 0; y <= ROWS; y += 3) {
+        var py = Math.round(y * CELL) + 0.5;
+        ctx.moveTo(0, py); ctx.lineTo(cv.width, py);
+      }
+      ctx.stroke();
+      // border glow
+      ctx.strokeStyle = 'rgba(34,211,238,.45)';
+      ctx.lineWidth = 2;
+      ctx.strokeRect(1, 1, cv.width - 2, cv.height - 2);
+    }
+
+    function drawTrail(cyc, color, glow) {
+      var t = cyc.trail;
+      ctx.save();
+      ctx.shadowColor = glow; ctx.shadowBlur = 8;
+      ctx.fillStyle = color;
+      for (var i = 0; i < t.length; i++) {
+        ctx.fillRect(t[i].x * CELL, t[i].y * CELL, CELL, CELL);
+      }
+      ctx.restore();
+      // head brighter
+      var h = t[t.length - 1];
+      ctx.save();
+      ctx.shadowColor = glow; ctx.shadowBlur = 16;
+      ctx.fillStyle = '#ffffff';
+      ctx.globalAlpha = 0.9;
+      ctx.fillRect(h.x * CELL, h.y * CELL, CELL, CELL);
+      ctx.restore();
+    }
+
+    function render() {
+      drawGrid();
+      drawTrail(ai, '#f59e0b', '#b45309');
+      drawTrail(player, '#22d3ee', '#0891b2');
+      if (flash > 0) {
+        var c = flashOwner === 1 ? 'rgba(34,211,238,' : flashOwner === 2 ? 'rgba(245,158,11,' : 'rgba(200,210,220,';
+        ctx.fillStyle = c + (0.18 * flash) + ')';
+        ctx.fillRect(0, 0, cv.width, cv.height);
+      }
+    }
+
+    // ---- loop ----
+    function frame(ts) {
+      raf = requestAnimationFrame(frame);
+      if (!last) last = ts;
+      var dt = ts - last; last = ts;
+      if (flash > 0) flash = Math.max(0, flash - dt / 400);
+
+      if (state === 'play') {
+        acc += dt;
+        while (acc >= TICK_MS && state === 'play') {
+          acc -= TICK_MS;
+          step();
+        }
+        render();
+      } else if (flash > 0) {
+        render();
+      }
+    }
+
+    // ---- overlay / hud ----
+    function showOverlay(tag, title, sub, btn, cls) {
+      $('ovTag').textContent = tag;
+      var t = $('ovTitle');
+      t.textContent = title;
+      t.className = 'big' + (cls ? ' ' + cls : '');
+      $('ovSub').textContent = sub;
+      $('playBtn').textContent = btn;
+      ov.classList.remove('hide');
+    }
+    function hideOverlay() { ov.classList.add('hide'); }
+
+    function updateHud() {
+      $('s1').textContent = score1;
+      $('s2').textContent = score2;
+      $('round').textContent = roundNo;
+      $('rounds').textContent = MAX_ROUNDS;
+      $('streak').textContent = streak;
+      $('best').textContent = best;
+    }
+
+    // ---- input ----
+    function onPlayBtn() {
+      if (state === 'ready' || state === 'matchover') restartMatch();
+      else if (state === 'roundover') nextRound();
+    }
+
+    var keyMap = {
+      ArrowUp:'up', ArrowDown:'down', ArrowLeft:'left', ArrowRight:'right',
+      w:'up', s:'down', a:'left', d:'right', W:'up', S:'down', A:'left', D:'right'
+    };
+    window.addEventListener('keydown', function (e) {
+      if (e.key === 'p' || e.key === 'P') { togglePause(); return; }
+      if (e.key === 'Enter' || e.key === ' ') {
+        if (state === 'ready' || state === 'roundover' || state === 'matchover') { e.preventDefault(); onPlayBtn(); }
+        return;
+      }
+      var d = keyMap[e.key];
+      if (d) {
+        // prevent page scroll for arrows/space
+        if (e.key.indexOf('Arrow') === 0) e.preventDefault();
+        turn(d);
+      }
+    }, { passive:false });
+
+    function togglePause() {
+      if (state === 'play') { state = 'paused'; showOverlay('Paused', 'PAUSED', 'Press P or Play to resume.', 'Resume', ''); }
+      else if (state === 'paused') { state = 'play'; hideOverlay(); }
+    }
+
+    $('playBtn').addEventListener('click', function () {
+      if (state === 'paused') { state = 'play'; hideOverlay(); return; }
+      onPlayBtn();
+    });
+    $('pauseBtn').addEventListener('click', togglePause);
+
+    // touch turn buttons
+    $('tLeft').addEventListener('click', function () { turnRel(-1); });
+    $('tRight').addEventListener('click', function () { turnRel(1); });
+
+    // tap-left-half / tap-right-half on canvas for touch
+    cv.addEventListener('pointerdown', function (e) {
+      if (e.pointerType === 'mouse') return; // mouse uses buttons/keys
+      var r = cv.getBoundingClientRect();
+      var rel = (e.clientX - r.left) < r.width / 2 ? -1 : 1;
+      turnRel(rel);
+      e.preventDefault();
+    }, { passive:false });
+
+    // detect touch to reveal on-screen controls
+    function markTouch() { document.body.classList.add('touch'); window.removeEventListener('touchstart', markTouch); }
+    window.addEventListener('touchstart', markTouch, { passive:true });
+    if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0)) document.body.classList.add('touch');
+
+    // ---- init ----
+    resetRound();
+    updateHud();
+    render();
+    raf = requestAnimationFrame(frame);
+  }
+
+  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);
+  else boot();
+})();
+</script>
+</body>
+</html>
diff --git a/games/whack-a-mole/AbramsWhack.aa b/games/whack-a-mole/AbramsWhack.aa
new file mode 100644
index 0000000..3d0e27f
--- /dev/null
+++ b/games/whack-a-mole/AbramsWhack.aa
@@ -0,0 +1,728 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+<title>Abrams Whack</title>
+<style>
+  :root{
+    --bg0:#080012;
+    --bg1:#12002a;
+    --neon:#00f0ff;
+    --neon2:#ff2bd6;
+    --neon3:#b14bff;
+    --good:#33ff9e;
+    --bad:#ff3b5c;
+    --gold:#ffd23f;
+    --ink:#eafcff;
+  }
+  *{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent;}
+  html,body{height:100%;width:100%;overflow:hidden;}
+  body{
+    font-family:"Trebuchet MS","Segoe UI",system-ui,sans-serif;
+    background:
+      radial-gradient(circle at 20% 10%, rgba(177,75,255,.28), transparent 45%),
+      radial-gradient(circle at 85% 90%, rgba(0,240,255,.24), transparent 45%),
+      linear-gradient(160deg,var(--bg1),var(--bg0));
+    color:var(--ink);
+    user-select:none;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+  }
+  #app{
+    position:relative;
+    width:100%;
+    height:100%;
+    max-width:900px;
+    max-height:900px;
+    margin:auto;
+    display:flex;
+    flex-direction:column;
+    padding:clamp(8px,2vmin,20px);
+  }
+
+  /* HUD */
+  #hud{
+    display:flex;
+    align-items:center;
+    justify-content:space-between;
+    gap:clamp(6px,1.5vmin,14px);
+    flex-wrap:wrap;
+    padding:clamp(6px,1.4vmin,12px) clamp(8px,2vmin,16px);
+    border-radius:16px;
+    background:rgba(10,0,25,.45);
+    border:1px solid rgba(0,240,255,.25);
+    box-shadow:0 0 24px rgba(0,240,255,.12) inset;
+    backdrop-filter:blur(4px);
+  }
+  .stat{
+    display:flex;
+    flex-direction:column;
+    align-items:center;
+    line-height:1.05;
+    min-width:0;
+  }
+  .stat .label{
+    font-size:clamp(8px,1.6vmin,11px);
+    letter-spacing:.14em;
+    text-transform:uppercase;
+    opacity:.7;
+  }
+  .stat .val{
+    font-size:clamp(16px,4vmin,30px);
+    font-weight:800;
+    font-variant-numeric:tabular-nums;
+    text-shadow:0 0 10px currentColor;
+  }
+  #score .val{color:var(--neon);}
+  #best .val{color:var(--gold);}
+  #time .val{color:var(--good);}
+  #combo .val{color:var(--neon2);}
+  #time.low .val{color:var(--bad); animation:pulse .6s infinite;}
+  @keyframes pulse{50%{opacity:.35;}}
+
+  #lives{display:flex;gap:4px;font-size:clamp(14px,3vmin,22px);}
+
+  #muteBtn{
+    cursor:pointer;
+    border:1px solid rgba(255,255,255,.3);
+    background:rgba(255,255,255,.06);
+    color:var(--ink);
+    border-radius:10px;
+    padding:clamp(4px,1vmin,8px) clamp(6px,1.4vmin,10px);
+    font-size:clamp(12px,2.6vmin,18px);
+    line-height:1;
+    transition:.15s;
+  }
+  #muteBtn:hover{background:rgba(0,240,255,.15);border-color:var(--neon);}
+
+  #title{
+    text-align:center;
+    margin:clamp(4px,1.2vmin,10px) 0;
+    font-size:clamp(18px,5vmin,40px);
+    font-weight:900;
+    letter-spacing:.06em;
+    background:linear-gradient(90deg,var(--neon),var(--neon2),var(--neon3),var(--neon));
+    background-size:300% 100%;
+    -webkit-background-clip:text;
+    background-clip:text;
+    color:transparent;
+    animation:shift 6s linear infinite;
+    filter:drop-shadow(0 0 12px rgba(255,43,214,.4));
+  }
+  @keyframes shift{to{background-position:300% 0;}}
+
+  /* Board */
+  #boardWrap{
+    flex:1;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    min-height:0;
+  }
+  #board{
+    display:grid;
+    grid-template-columns:repeat(3,1fr);
+    grid-template-rows:repeat(3,1fr);
+    gap:clamp(6px,2vmin,18px);
+    width:min(100%,min(72vh,560px));
+    aspect-ratio:1/1;
+  }
+  .hole{
+    position:relative;
+    border-radius:50%;
+    background:
+      radial-gradient(circle at 50% 38%, #1a0033 0%, #0c0018 60%, #05000d 100%);
+    box-shadow:
+      0 0 0 2px rgba(0,240,255,.18),
+      inset 0 10px 26px rgba(0,0,0,.9),
+      inset 0 -6px 14px rgba(177,75,255,.18);
+    overflow:hidden;
+    cursor:pointer;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    transition:box-shadow .12s;
+  }
+  .hole::after{ /* rim glow */
+    content:"";
+    position:absolute;
+    inset:0;
+    border-radius:50%;
+    box-shadow:inset 0 6px 18px rgba(0,240,255,.10);
+    pointer-events:none;
+  }
+  .hole.hit{
+    box-shadow:
+      0 0 24px 6px rgba(51,255,158,.6),
+      inset 0 10px 26px rgba(0,0,0,.9);
+  }
+  .hole.badhit{
+    box-shadow:
+      0 0 24px 6px rgba(255,59,92,.7),
+      inset 0 10px 26px rgba(0,0,0,.9);
+  }
+
+  /* the pop target */
+  .target{
+    position:absolute;
+    left:50%;
+    bottom:-72%;
+    transform:translateX(-50%);
+    width:78%;
+    height:78%;
+    border-radius:50% 50% 46% 46%;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    font-size:clamp(22px,9vmin,64px);
+    transition:bottom .13s cubic-bezier(.2,.9,.3,1.4), transform .13s;
+    pointer-events:none;
+    will-change:bottom;
+  }
+  .target.up{ bottom:8%; }
+  .target.mole{
+    background:radial-gradient(circle at 50% 35%, var(--neon3), #4a007a 70%, #22003a);
+    box-shadow:0 0 18px rgba(177,75,255,.7), inset 0 -8px 12px rgba(0,0,0,.5), inset 0 6px 10px rgba(255,255,255,.15);
+    border:2px solid rgba(0,240,255,.5);
+  }
+  .target.bomb{
+    background:radial-gradient(circle at 50% 35%, #ff5a78, #b3001d 72%, #4a000c);
+    box-shadow:0 0 20px rgba(255,59,92,.85), inset 0 -8px 12px rgba(0,0,0,.5);
+    border:2px solid rgba(255,210,63,.7);
+  }
+  .target.gold{
+    background:radial-gradient(circle at 50% 35%, #fff2a8, var(--gold) 68%, #b98900);
+    box-shadow:0 0 26px rgba(255,210,63,.9), inset 0 -8px 12px rgba(0,0,0,.35);
+    border:2px solid #fff;
+  }
+  .target.whacked{ transform:translateX(-50%) scale(.55) rotate(8deg); opacity:0; transition:transform .18s, opacity .18s; }
+
+  /* floating score popup */
+  .pop{
+    position:absolute;
+    left:50%;
+    top:30%;
+    transform:translate(-50%,-50%);
+    font-weight:900;
+    font-size:clamp(14px,4.5vmin,30px);
+    pointer-events:none;
+    text-shadow:0 0 8px currentColor;
+    animation:floatUp .7s ease-out forwards;
+    z-index:5;
+  }
+  @keyframes floatUp{
+    0%{opacity:0; transform:translate(-50%,-30%) scale(.6);}
+    20%{opacity:1;}
+    100%{opacity:0; transform:translate(-50%,-160%) scale(1.1);}
+  }
+
+  /* ripple on whack */
+  .ripple{
+    position:absolute;
+    inset:0;
+    border-radius:50%;
+    pointer-events:none;
+    animation:rip .45s ease-out forwards;
+  }
+  @keyframes rip{
+    from{box-shadow:0 0 0 0 rgba(255,255,255,.6);}
+    to{box-shadow:0 0 0 40px rgba(255,255,255,0);}
+  }
+
+  /* Overlay */
+  #overlay{
+    position:absolute;
+    inset:0;
+    display:flex;
+    align-items:center;
+    justify-content:center;
+    background:rgba(4,0,14,.82);
+    backdrop-filter:blur(6px);
+    z-index:20;
+    text-align:center;
+    padding:20px;
+  }
+  #overlay.hidden{display:none;}
+  .panel{
+    max-width:440px;
+    width:100%;
+    background:linear-gradient(160deg, rgba(28,0,54,.9), rgba(8,0,20,.9));
+    border:1px solid rgba(0,240,255,.4);
+    border-radius:22px;
+    padding:clamp(20px,4vmin,36px);
+    box-shadow:0 0 40px rgba(177,75,255,.35), inset 0 0 30px rgba(0,240,255,.08);
+  }
+  .panel h1{
+    font-size:clamp(26px,7vmin,46px);
+    font-weight:900;
+    letter-spacing:.04em;
+    background:linear-gradient(90deg,var(--neon),var(--neon2));
+    -webkit-background-clip:text;background-clip:text;color:transparent;
+    filter:drop-shadow(0 0 10px rgba(0,240,255,.5));
+    margin-bottom:8px;
+  }
+  .panel p{opacity:.85; font-size:clamp(12px,2.6vmin,15px); line-height:1.5; margin-bottom:16px;}
+  .legend{
+    display:flex;justify-content:center;gap:16px;flex-wrap:wrap;
+    margin-bottom:18px;font-size:clamp(11px,2.4vmin,14px);
+  }
+  .legend span{display:inline-flex;align-items:center;gap:6px;}
+  .dot{width:16px;height:16px;border-radius:50%;display:inline-block;box-shadow:0 0 8px currentColor;}
+  .dot.m{background:var(--neon3);color:var(--neon3);}
+  .dot.b{background:var(--bad);color:var(--bad);}
+  .dot.g{background:var(--gold);color:var(--gold);}
+  #finalScore{
+    font-size:clamp(28px,8vmin,52px);
+    font-weight:900;
+    color:var(--neon);
+    text-shadow:0 0 16px var(--neon);
+    margin:6px 0;
+    font-variant-numeric:tabular-nums;
+  }
+  #finalBest{color:var(--gold);font-weight:700;margin-bottom:16px;}
+  #newBest{
+    color:var(--gold);font-weight:900;letter-spacing:.1em;
+    animation:pulse .8s infinite; margin-bottom:8px; font-size:clamp(13px,3vmin,18px);
+  }
+  #newBest.hidden{display:none;}
+  .btn{
+    cursor:pointer;
+    border:none;
+    border-radius:14px;
+    padding:clamp(12px,2.6vmin,16px) clamp(24px,5vmin,40px);
+    font-size:clamp(15px,3.4vmin,22px);
+    font-weight:800;
+    letter-spacing:.05em;
+    color:#08001a;
+    background:linear-gradient(90deg,var(--neon),var(--neon2));
+    box-shadow:0 6px 24px rgba(255,43,214,.4);
+    transition:transform .1s, box-shadow .15s;
+  }
+  .btn:hover{transform:translateY(-2px); box-shadow:0 10px 30px rgba(0,240,255,.5);}
+  .btn:active{transform:translateY(1px) scale(.98);}
+
+  /* screen shake */
+  @keyframes shake{
+    0%,100%{transform:translate(0,0);}
+    25%{transform:translate(-4px,2px);}
+    50%{transform:translate(4px,-2px);}
+    75%{transform:translate(-3px,-1px);}
+  }
+  #app.shake{animation:shake .28s;}
+</style>
+</head>
+<body>
+<div id="app">
+  <div id="hud">
+    <div id="score" class="stat"><span class="label">Score</span><span class="val">0</span></div>
+    <div id="combo" class="stat"><span class="label">Combo</span><span class="val">x1</span></div>
+    <div id="title" style="flex:1;">ABRAMS WHACK</div>
+    <div id="time" class="stat"><span class="label">Time</span><span class="val">45</span></div>
+    <div id="best" class="stat"><span class="label">Best</span><span class="val">0</span></div>
+    <div id="livesWrap" class="stat"><span class="label">Lives</span><span id="lives" class="val"></span></div>
+    <button id="muteBtn" title="Mute / unmute">🔊</button>
+  </div>
+
+  <div id="boardWrap">
+    <div id="board"></div>
+  </div>
+
+  <div id="overlay">
+    <div class="panel">
+      <h1 id="ovTitle">ABRAMS WHACK</h1>
+      <div id="newBest" class="hidden">★ NEW HIGH SCORE ★</div>
+      <div id="finalScore" style="display:none;">0</div>
+      <div id="finalBest" style="display:none;"></div>
+      <p id="ovDesc">Whack the neon moles before they vanish. Hit fast for combo multipliers.
+        Dodge the red bombs — they cost a life. Grab the gold ones for big points.</p>
+      <div class="legend">
+        <span><i class="dot m"></i>Mole +pts</span>
+        <span><i class="dot g"></i>Gold jackpot</span>
+        <span><i class="dot b"></i>Bomb −life</span>
+      </div>
+      <button id="startBtn" class="btn">START</button>
+    </div>
+  </div>
+</div>
+
+<script>
+(function(){
+  "use strict";
+
+  // ---------- Config ----------
+  const ROUND_TIME = 45;          // seconds
+  const HOLES = 9;                 // 3x3
+  const START_LIVES = 3;
+  const BASE_POINTS = 10;
+  const GOLD_POINTS = 50;
+  const MISS_PENALTY = 5;          // missed mole
+  const BOMB_PENALTY = 15;         // whacking a bomb
+  const COMBO_WINDOW = 1400;       // ms to keep combo alive between hits
+  const MAX_COMBO = 8;
+
+  // ---------- State ----------
+  let board, holes = [];
+  let score = 0, best = 0, timeLeft = ROUND_TIME, lives = START_LIVES;
+  let combo = 0, lastHitAt = 0;
+  let running = false;
+  let spawnTimer = null, tickTimer = null;
+  let elapsed = 0;                 // seconds into round (for difficulty ramp)
+  let muted = false;
+
+  // per-hole occupancy: {kind, el, timeout, whacked}
+  const occ = new Array(HOLES).fill(null);
+
+  // ---------- DOM ----------
+  const $ = s => document.querySelector(s);
+  const app = $("#app");
+  const scoreVal = $("#score .val");
+  const comboVal = $("#combo .val");
+  const timeStat = $("#time");
+  const timeVal = $("#time .val");
+  const bestVal = $("#best .val");
+  const livesEl = $("#lives");
+  const overlay = $("#overlay");
+  const ovTitle = $("#ovTitle");
+  const ovDesc = $("#ovDesc");
+  const finalScore = $("#finalScore");
+  const finalBest = $("#finalBest");
+  const newBest = $("#newBest");
+  const startBtn = $("#startBtn");
+  const muteBtn = $("#muteBtn");
+
+  // ---------- Persistence ----------
+  const LS_KEY = "abramsWhack.best";
+  try { best = parseInt(localStorage.getItem(LS_KEY) || "0", 10) || 0; } catch(e){ best = 0; }
+  try { muted = localStorage.getItem("abramsWhack.muted") === "1"; } catch(e){}
+  bestVal.textContent = best;
+  muteBtn.textContent = muted ? "🔇" : "🔊";
+
+  // ---------- Audio (procedural Web Audio) ----------
+  let actx = null;
+  function audio(){
+    if (muted) return null;
+    if (!actx){
+      try { actx = new (window.AudioContext || window.webkitAudioContext)(); }
+      catch(e){ return null; }
+    }
+    if (actx.state === "suspended") actx.resume();
+    return actx;
+  }
+  function tone(freq, dur, type, gain, slideTo){
+    const ac = audio(); if(!ac) return;
+    const o = ac.createOscillator();
+    const g = ac.createGain();
+    o.type = type || "sine";
+    o.frequency.setValueAtTime(freq, ac.currentTime);
+    if (slideTo) o.frequency.exponentialRampToValueAtTime(slideTo, ac.currentTime + dur);
+    g.gain.setValueAtTime(0.0001, ac.currentTime);
+    g.gain.exponentialRampToValueAtTime(gain || 0.2, ac.currentTime + 0.01);
+    g.gain.exponentialRampToValueAtTime(0.0001, ac.currentTime + dur);
+    o.connect(g); g.connect(ac.destination);
+    o.start(); o.stop(ac.currentTime + dur + 0.02);
+  }
+  function noiseBurst(dur, gain){
+    const ac = audio(); if(!ac) return;
+    const n = Math.floor(ac.sampleRate * dur);
+    const buf = ac.createBuffer(1, n, ac.sampleRate);
+    const data = buf.getChannelData(0);
+    for (let i=0;i<n;i++) data[i] = (Math.random()*2-1) * (1 - i/n);
+    const src = ac.createBufferSource(); src.buffer = buf;
+    const g = ac.createGain(); g.gain.value = gain || 0.25;
+    const f = ac.createBiquadFilter(); f.type="highpass"; f.frequency.value=800;
+    src.connect(f); f.connect(g); g.connect(ac.destination);
+    src.start();
+  }
+  const sfx = {
+    whack(c){ tone(420 + Math.min(c,MAX_COMBO)*55, 0.12, "square", 0.22, 180); },
+    gold(){ tone(660,0.1,"triangle",0.25,1320); setTimeout(()=>tone(990,0.14,"triangle",0.22,1760),70); },
+    bomb(){ noiseBurst(0.28,0.35); tone(120,0.3,"sawtooth",0.3,40); },
+    miss(){ tone(200,0.14,"sine",0.15,120); },
+    pop(){ tone(300,0.06,"sine",0.08,500); },
+    over(){ tone(440,0.2,"triangle",0.2,110); setTimeout(()=>tone(220,0.4,"triangle",0.2,80),160); },
+    start(){ tone(330,0.1,"triangle",0.2,660); setTimeout(()=>tone(660,0.14,"triangle",0.2,990),100); }
+  };
+
+  // ---------- Build board ----------
+  function buildBoard(){
+    board = $("#board");
+    board.innerHTML = "";
+    holes = [];
+    for (let i=0;i<HOLES;i++){
+      const h = document.createElement("div");
+      h.className = "hole";
+      h.dataset.i = i;
+      h.addEventListener("pointerdown", onHolePress, {passive:false});
+      board.appendChild(h);
+      holes.push(h);
+    }
+  }
+
+  // ---------- Difficulty ramp ----------
+  // returns {upTime, gap} in ms. As elapsed grows, moles stay up shorter & spawn faster.
+  function difficulty(){
+    const t = elapsed / ROUND_TIME;               // 0..1
+    const upTime = Math.max(520, 1150 - t*760);   // 1150 -> 520 ms visible
+    const gap = Math.max(340, 900 - t*620);       // spawn interval
+    return { upTime, gap };
+  }
+
+  function chooseKind(){
+    // gold rare, bomb scales up a bit with difficulty
+    const t = elapsed / ROUND_TIME;
+    const r = Math.random();
+    if (r < 0.06) return "gold";
+    if (r < 0.06 + 0.14 + t*0.12) return "bomb";  // 14% -> ~26%
+    return "mole";
+  }
+
+  // ---------- Spawn ----------
+  function spawn(){
+    if (!running) return;
+    // find a free hole
+    const free = [];
+    for (let i=0;i<HOLES;i++) if (!occ[i]) free.push(i);
+    if (free.length){
+      // sometimes spawn 2 at once late-game
+      const t = elapsed / ROUND_TIME;
+      const count = (t > 0.5 && Math.random() < 0.3 && free.length > 1) ? 2 : 1;
+      for (let k=0;k<count && free.length;k++){
+        const idx = free.splice(Math.floor(Math.random()*free.length),1)[0];
+        placeTarget(idx);
+      }
+    }
+    const { gap } = difficulty();
+    spawnTimer = setTimeout(spawn, gap + Math.random()*120);
+  }
+
+  function placeTarget(i){
+    const kind = chooseKind();
+    const { upTime } = difficulty();
+    const el = document.createElement("div");
+    el.className = "target " + kind;
+    el.textContent = kind === "bomb" ? "💣" : (kind === "gold" ? "⭐" : "🐹");
+    holes[i].appendChild(el);
+    sfx.pop();
+    // force reflow then raise
+    // eslint-disable-next-line no-unused-expressions
+    el.offsetHeight;
+    requestAnimationFrame(()=> el.classList.add("up"));
+
+    const record = { kind, el, whacked:false, timeout:null };
+    occ[i] = record;
+
+    record.timeout = setTimeout(()=>{
+      if (record.whacked) return;
+      // duck back down
+      el.classList.remove("up");
+      // a mole that escaped un-whacked = miss penalty (bombs escaping are fine)
+      if (kind === "mole" || kind === "gold"){
+        onMissed();
+      }
+      setTimeout(()=>{ if (el.parentNode) el.parentNode.removeChild(el); }, 180);
+      if (occ[i] === record) occ[i] = null;
+    }, upTime);
+  }
+
+  // ---------- Interaction ----------
+  function onHolePress(e){
+    e.preventDefault();
+    if (!running) return;
+    const i = +this.dataset.i;
+    const rec = occ[i];
+    if (!rec || rec.whacked){
+      return; // whacked empty hole -> nothing (no penalty for empties)
+    }
+    whack(i, rec, this);
+  }
+
+  function whack(i, rec, holeEl){
+    rec.whacked = true;
+    clearTimeout(rec.timeout);
+    rec.el.classList.add("whacked");
+    ripple(holeEl);
+    setTimeout(()=>{ if (rec.el.parentNode) rec.el.parentNode.removeChild(rec.el); }, 200);
+    if (occ[i] === rec) occ[i] = null;
+
+    const now = performance.now();
+    if (rec.kind === "bomb"){
+      // penalty + life loss
+      combo = 0; lastHitAt = 0;
+      score = Math.max(0, score - BOMB_PENALTY);
+      loseLife();
+      holeEl.classList.add("badhit");
+      setTimeout(()=>holeEl.classList.remove("badhit"),200);
+      floatPop(holeEl, "−"+BOMB_PENALTY, "var(--bad)");
+      sfx.bomb();
+      shake();
+      updateHUD();
+      return;
+    }
+
+    // good hit -> combo
+    if (now - lastHitAt < COMBO_WINDOW) combo = Math.min(MAX_COMBO, combo + 1);
+    else combo = 1;
+    lastHitAt = now;
+
+    const mult = combo;
+    let gained;
+    if (rec.kind === "gold"){
+      gained = GOLD_POINTS * mult;
+      sfx.gold();
+      floatPop(holeEl, "+"+gained, "var(--gold)");
+    } else {
+      gained = BASE_POINTS * mult;
+      sfx.whack(combo);
+      floatPop(holeEl, "+"+gained, "var(--good)");
+    }
+    score += gained;
+    holeEl.classList.add("hit");
+    setTimeout(()=>holeEl.classList.remove("hit"),160);
+    updateHUD();
+  }
+
+  function onMissed(){
+    combo = 0; lastHitAt = 0;
+    score = Math.max(0, score - MISS_PENALTY);
+    sfx.miss();
+    updateHUD();
+  }
+
+  function loseLife(){
+    lives = Math.max(0, lives - 1);
+    renderLives();
+    if (lives <= 0) endRound();
+  }
+
+  // ---------- FX ----------
+  function ripple(holeEl){
+    const r = document.createElement("div");
+    r.className = "ripple";
+    holeEl.appendChild(r);
+    setTimeout(()=>{ if (r.parentNode) r.parentNode.removeChild(r); }, 460);
+  }
+  function floatPop(holeEl, text, color){
+    const p = document.createElement("div");
+    p.className = "pop";
+    p.textContent = text;
+    p.style.color = color;
+    holeEl.appendChild(p);
+    setTimeout(()=>{ if (p.parentNode) p.parentNode.removeChild(p); }, 720);
+  }
+  function shake(){
+    app.classList.remove("shake");
+    // reflow
+    void app.offsetWidth;
+    app.classList.add("shake");
+  }
+
+  // ---------- HUD ----------
+  function updateHUD(){
+    scoreVal.textContent = score;
+    comboVal.textContent = "x" + Math.max(1, combo);
+    comboVal.style.transform = combo > 1 ? "scale(1.15)" : "scale(1)";
+  }
+  function renderLives(){
+    livesEl.textContent = "❤".repeat(lives) + "♡".repeat(Math.max(0,START_LIVES-lives));
+  }
+  function renderTime(){
+    timeVal.textContent = timeLeft;
+    if (timeLeft <= 10) timeStat.classList.add("low");
+    else timeStat.classList.remove("low");
+  }
+
+  // ---------- Round control ----------
+  function startRound(){
+    // reset
+    score = 0; combo = 0; lastHitAt = 0; lives = START_LIVES;
+    timeLeft = ROUND_TIME; elapsed = 0; running = true;
+    clearAll();
+    updateHUD(); renderLives(); renderTime();
+    bestVal.textContent = best;
+    overlay.classList.add("hidden");
+    sfx.start();
+
+    // ticking clock
+    tickTimer = setInterval(()=>{
+      timeLeft--; elapsed++;
+      renderTime();
+      if (timeLeft <= 0) endRound();
+    }, 1000);
+
+    // start spawning
+    spawn();
+  }
+
+  function endRound(){
+    if (!running) return;
+    running = false;
+    clearTimeout(spawnTimer);
+    clearInterval(tickTimer);
+    clearAll();
+    sfx.over();
+
+    // high score
+    const isNew = score > best;
+    if (isNew){
+      best = score;
+      try { localStorage.setItem(LS_KEY, String(best)); } catch(e){}
+    }
+    bestVal.textContent = best;
+
+    // show overlay in game-over mode
+    ovTitle.textContent = "GAME OVER";
+    ovDesc.style.display = "none";
+    finalScore.style.display = "block";
+    finalScore.textContent = score;
+    finalBest.style.display = "block";
+    finalBest.textContent = "Best: " + best;
+    newBest.classList.toggle("hidden", !isNew);
+    startBtn.textContent = "PLAY AGAIN";
+    overlay.classList.remove("hidden");
+  }
+
+  function clearAll(){
+    for (let i=0;i<HOLES;i++){
+      const rec = occ[i];
+      if (rec){ clearTimeout(rec.timeout); if (rec.el && rec.el.parentNode) rec.el.parentNode.removeChild(rec.el); }
+      occ[i] = null;
+    }
+    holes.forEach(h=>{
+      h.classList.remove("hit","badhit");
+      // strip leftover pops/ripples
+      Array.from(h.querySelectorAll(".pop,.ripple,.target")).forEach(n=>n.remove());
+    });
+  }
+
+  // ---------- Mute ----------
+  muteBtn.addEventListener("click", (e)=>{
+    e.stopPropagation();
+    muted = !muted;
+    muteBtn.textContent = muted ? "🔇" : "🔊";
+    try { localStorage.setItem("abramsWhack.muted", muted ? "1":"0"); } catch(e){}
+    if (!muted) audio(); // wake context
+  });
+
+  // ---------- Start button ----------
+  startBtn.addEventListener("click", ()=>{ audio(); startRound(); });
+
+  // keyboard: space/enter to start when not running
+  window.addEventListener("keydown", (e)=>{
+    if (!running && (e.code === "Space" || e.code === "Enter")){
+      e.preventDefault(); audio(); startRound();
+    }
+  });
+
+  // prevent iOS double-tap zoom on board taps handled via pointerdown already
+  document.addEventListener("gesturestart", e=>e.preventDefault());
+
+  // ---------- Init ----------
+  buildBoard();
+  updateHUD(); renderLives(); renderTime();
+
+})();
+</script>
+</body>
+</html>
diff --git a/games/wordle/AbramsWordle.aa b/games/wordle/AbramsWordle.aa
new file mode 100644
index 0000000..7044fe6
--- /dev/null
+++ b/games/wordle/AbramsWordle.aa
@@ -0,0 +1,477 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>Abrams Wordle</title>
+<style>
+  :root {
+    --bg:#0a0e14; --ink:#e5e7eb; --muted:#8b97a7;
+    --tile:#141b25; --tile-border:#2a3441;
+    --green:#2fbf71; --yellow:#e0b23a; --gray:#3a4655;
+    --key:#28323f; --key-ink:#dbe3ec;
+    --neon:#7dd3fc;
+  }
+  * { box-sizing:border-box; margin:0; padding:0; -webkit-tap-highlight-color:transparent; }
+  html,body { height:100%; }
+  body {
+    background:radial-gradient(1200px 600px at 50% -10%, #16202e, var(--bg));
+    color:var(--ink); font:15px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
+    display:flex; flex-direction:column; align-items:center;
+    min-height:100%; gap:10px; padding:12px 10px; overscroll-behavior:none;
+    touch-action:manipulation; user-select:none; -webkit-user-select:none;
+  }
+  h1 {
+    font-size:15px; letter-spacing:.34em; text-transform:uppercase;
+    color:var(--neon); font-weight:700; text-align:center;
+    text-shadow:0 0 12px rgba(125,211,252,.35);
+  }
+  .hud { display:flex; gap:8px; align-items:stretch; flex-wrap:wrap; justify-content:center; }
+  .stat { background:var(--tile); border:1px solid var(--tile-border); border-radius:10px; padding:5px 10px; text-align:center; min-width:58px; }
+  .stat .k { font-size:9px; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
+  .stat .v { font-size:17px; font-weight:700; font-variant-numeric:tabular-nums; }
+  .btn {
+    padding:7px 14px; border-radius:10px; border:1px solid var(--tile-border);
+    background:var(--tile); color:#cbd5e1; cursor:pointer; font-size:13px; font-weight:600;
+  }
+  .btn:active { transform:scale(.96); }
+
+  #board { display:grid; grid-template-rows:repeat(6,1fr); gap:6px; margin-top:2px; }
+  .brow { display:grid; grid-template-columns:repeat(5,1fr); gap:6px; }
+  .tile {
+    width:52px; height:52px; border:2px solid var(--tile-border);
+    border-radius:8px; display:flex; align-items:center; justify-content:center;
+    font-weight:800; font-size:26px; text-transform:uppercase; color:var(--ink);
+    background:transparent; transition:transform .08s ease, border-color .12s ease;
+  }
+  .tile.filled { border-color:#4a586b; }
+  .tile.pop { animation:pop .12s ease; }
+  @keyframes pop { 0%{transform:scale(1)} 50%{transform:scale(1.12)} 100%{transform:scale(1)} }
+  .tile.flip { animation:flip .5s ease forwards; }
+  @keyframes flip {
+    0% { transform:rotateX(0); }
+    45% { transform:rotateX(90deg); }
+    55% { transform:rotateX(90deg); }
+    100% { transform:rotateX(0); }
+  }
+  .tile.g { background:var(--green); border-color:var(--green); color:#062015; box-shadow:0 0 14px rgba(47,191,113,.4); }
+  .tile.y { background:var(--yellow); border-color:var(--yellow); color:#241a03; box-shadow:0 0 14px rgba(224,178,58,.35); }
+  .tile.x { background:var(--gray); border-color:var(--gray); color:#cdd6e0; }
+  .brow.shake { animation:shake .4s ease; }
+  @keyframes shake {
+    0%,100%{transform:translateX(0)} 20%{transform:translateX(-7px)}
+    40%{transform:translateX(7px)} 60%{transform:translateX(-5px)} 80%{transform:translateX(5px)}
+  }
+
+  #msg { height:20px; font-size:13px; font-weight:600; color:var(--neon); letter-spacing:.02em; text-align:center; }
+
+  #kb { display:flex; flex-direction:column; gap:6px; width:100%; max-width:500px; margin-top:2px; }
+  .krow { display:flex; gap:5px; justify-content:center; }
+  .key {
+    flex:1 1 auto; min-width:0; height:50px; border-radius:7px; border:0;
+    background:var(--key); color:var(--key-ink); font-weight:700; font-size:14px;
+    text-transform:uppercase; cursor:pointer; display:flex; align-items:center; justify-content:center;
+    transition:transform .06s ease, background .12s ease;
+  }
+  .key.wide { flex:1.5 1 auto; font-size:11px; letter-spacing:.04em; }
+  .key:active { transform:scale(.93); }
+  .key.g { background:var(--green); color:#062015; }
+  .key.y { background:var(--yellow); color:#241a03; }
+  .key.x { background:var(--gray); color:#9aa6b3; }
+
+  .overlay {
+    position:fixed; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
+    gap:10px; text-align:center; background:rgba(6,10,16,.86); backdrop-filter:blur(3px); z-index:10; padding:20px;
+  }
+  .overlay.hide { display:none; }
+  .tag { font-size:11px; color:var(--neon); letter-spacing:.24em; text-transform:uppercase; }
+  .big { font-size:26px; font-weight:800; }
+  .word { font-size:20px; font-weight:800; letter-spacing:.18em; text-transform:uppercase; color:var(--green); }
+  .sub { font-size:13px; color:var(--muted); max-width:280px; }
+  button.play { margin-top:6px; padding:11px 26px; border:0; border-radius:999px; cursor:pointer;
+    background:linear-gradient(180deg,#7dd3fc,#38bdf8); color:#03202e; font-weight:800; font-size:14px; }
+  .ostats { display:flex; gap:14px; margin-top:6px; }
+  .ostats .k { font-size:9px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
+  .ostats .v { font-size:20px; font-weight:800; }
+
+  @media (max-width:380px){
+    .tile{ width:46px; height:46px; font-size:22px; }
+    .key{ height:46px; }
+    h1{ letter-spacing:.24em; }
+  }
+</style>
+</head>
+<body>
+  <h1>Abrams Wordle</h1>
+  <div class="hud">
+    <div class="stat"><div class="k">Played</div><div class="v" id="sPlayed">0</div></div>
+    <div class="stat"><div class="k">Win %</div><div class="v" id="sWin">0</div></div>
+    <div class="stat"><div class="k">Streak</div><div class="v" id="sStreak">0</div></div>
+    <div class="stat"><div class="k">Max</div><div class="v" id="sMax">0</div></div>
+    <button class="btn" id="newBtn">New</button>
+  </div>
+  <div id="board"></div>
+  <div id="msg"></div>
+  <div id="kb"></div>
+
+  <div class="overlay hide" id="ov">
+    <div class="tag" id="ovTag">Result</div>
+    <div class="big" id="ovTitle"></div>
+    <div class="word" id="ovWord"></div>
+    <div class="sub" id="ovSub"></div>
+    <div class="ostats">
+      <div><div class="k">Played</div><div class="v" id="oPlayed">0</div></div>
+      <div><div class="k">Win %</div><div class="v" id="oWin">0</div></div>
+      <div><div class="k">Streak</div><div class="v" id="oStreak">0</div></div>
+      <div><div class="k">Max</div><div class="v" id="oMax">0</div></div>
+    </div>
+    <button class="play" id="playBtn">New game</button>
+  </div>
+
+<script>
+(function () {
+  "use strict";
+
+  // ---- Answer words (common 5-letter solutions) ----
+  var ANSWERS = ["about","above","abuse","actor","acute","admit","adopt","adult","after","again","agent","agree","ahead","alarm","album","alert","alike","alive","allow","alone","along","alter","among","anger","angle","angry","apart","apple","apply","arena","argue","arise","array","aside","asset","audio","audit","avoid","award","aware","badly","baker","bases","basic","beach","began","begin","being","below","bench","billy","birth","black","blame","blank","blast","blind","block","blood","board","boost","booth","bound","brain","brand","brass","brave","bread","break","breed","brief","bring","broad","broke","brown","brush","build","built","buyer","cable","calif","carry","catch","cause","chain","chair","chaos","charm","chart","chase","cheap","check","chest","chief","child","china","chose","civil","claim","class","clean","clear","click","climb","clock","close","cloud","coach","coast","could","count","court","cover","craft","crash","crazy","cream","crime","cross","crowd","crown","crude","curve","cycle","daily","dance","dated","dealt","death","debut","delay","depth","doing","doubt","dozen","draft","drama","drank","drawn","dream","dress","drill","drink","drive","drove","dying","eager","early","earth","eight","elite","empty","enemy","enjoy","enter","entry","equal","error","event","every","exact","exist","extra","faith","false","fault","favor","fence","fever","fewer","field","fifth","fifty","fight","final","first","fixed","flame","flash","fleet","floor","fluid","focus","force","forth","forty","forum","found","frame","frank","fraud","fresh","front","fruit","fully","funny","giant","given","glass","globe","going","grace","grade","grain","grand","grant","grass","grave","great","green","gross","group","grown","guard","guess","guest","guide","happy","harsh","heart","heavy","hence","henry","horse","hotel","house","human","ideal","image","index","inner","input","issue","japan","jimmy","joint","jones","judge","known","label","large","laser","later","laugh","layer","learn","lease","least","leave","legal","level","lewis","light","limit","links","lives","local","logic","loose","lower","lucky","lunch","lying","magic","major","maker","march","maria","match","maybe","mayor","meant","medal","media","metal","meter","might","minor","minus","mixed","model","money","month","moral","motor","mount","mouse","mouth","moved","movie","music","needs","never","newly","night","noise","north","noted","novel","nurse","occur","ocean","offer","often","order","other","ought","paint","panel","paper","party","peace","penny","peter","phase","phone","photo","piano","piece","pilot","pitch","place","plain","plane","plant","plate","point","pound","power","press","price","pride","prime","print","prior","prize","proof","proud","prove","queen","quick","quiet","quite","radio","raise","range","rapid","ratio","reach","ready","realm","rebel","refer","relax","reply","right","rigid","rival","river","robin","roger","roman","rough","round","route","royal","rural","scale","scene","scope","score","sense","serve","seven","shall","shape","share","sharp","sheet","shelf","shell","shift","shine","shirt","shock","shoot","short","shown","sight","silly","since","sixth","sixty","sized","skill","sleep","slide","small","smart","smile","smith","smoke","snake","snowy","solid","solve","sorry","sound","south","space","spare","speak","speed","spend","spent","split","spoke","sport","staff","stage","stake","stand","start","state","steam","steel","steep","steer","stern","stick","still","stock","stone","stood","store","storm","story","strip","stuck","study","stuff","style","sugar","suite","super","sweet","table","taken","taste","taxes","teach","teeth","terry","texas","thank","theft","their","theme","there","these","thick","thing","think","third","those","three","threw","throw","thumb","tiger","tight","timer","title","today","topic","total","touch","tough","tower","track","trade","trail","train","treat","trend","trial","tribe","trick","tried","tries","truck","truly","trunk","trust","truth","twice","under","undue","union","unity","until","upper","upset","urban","usage","usual","valid","value","video","virus","visit","vital","voice","waste","watch","water","wheel","where","which","while","white","whole","whose","woman","women","world","worry","worse","worst","worth","would","wound","write","wrong","wrote","yield","young","youth","zebra","zesty","chalk","chart","chord","churn","cider","cliff","cloak","clone","clown","coral","couch","cough","cramp","crank","crate","crept","crisp","crook","daisy","dandy","dodge","donor","drift","drown","dwarf","ebony","elbow","ember","evoke","exile","fable","fairy","fancy","feast","ferry","fetch","fiber","fjord","flask","flint","float","flock","flora","flour","flung","folly","forge","frost","gauge","gecko","ghost","gland","gleam","glide","glint","gloom","glory","gloss","grasp","grill","grind","groan","grove","gruff","habit","haste","hazel","hedge","hinge","hoard","hobby","honey","humid","hunch","hutch","icing","igloo","ivory","jelly","jewel","jolly","joust","kiosk","kneel","knock","lapse","larva","latch","lemon","liver","llama","lobby","lodge","loyal","lyric","manor","maple","marsh","medic","melon","mercy","merge","merit","mirth","mocha","moist","mound","mourn","mucky","mummy","nasty","navel","nerve","niche","noble","nudge","oaken","olive","onset","opera","orbit","organ","otter","ozone","pansy","parka","pasta","patch","pause","peach","pearl","pecan","perch","petal","piety","pixel","plaid","pluck","plumb","plume","plush","poise","polar","porch","posse","pouch","prank","prawn","preen","prism","probe","prong","prune","pupil","quail","quake","qualm","quart","quash","quell","query","quest","quill","quilt","quota","quote","rabid","ranch","raven","razor","realm","rerun","resin","rhino","ridge","rinse","risky","roast","robot","rogue","rowdy","ruddy","rugby","salsa","salty","sandy","sassy","sauna","savor","scald","scalp","scarf","scoff","scold","scoop","scorn","scout","scowl","scrap","scrub","seize","serum","sever","sewer","shack","shade","shady","shaft","shale","shame","shard","shawl","shear","sheen","sheep","sheer","shied","shiny","shoal","shone","shore","shorn","showy","shrub","shrug","shuck","siege","sieve","skate","skimp","skunk","slack","slain","slang","slant","slash","slate","sleek","sleet","slept","slick","slime","sling","slink","slope","slosh","sloth","slump","slung","slunk","slush","smash","smear","smelt","smirk","snack","snail","snare","sneak","sneer","snort","snout","snowy","soggy","solar","sonic","sooty","sound","spade","spank","spawn","spear","speck","spell","spice","spicy","spied","spike","spiky","spine","spiny","spire","spite","splat","spoof","spool","spoon","spore","sprig","spurn","spurt","squad","squat","squid","stack","stage","staid","stain","stair","stalk","stall","stamp","stank","stare","stash","steak","stead","steed","stink","stint","stirs","stoke","stole","stomp","stony","stool","stoop","stork","stout","stove","stown","strap","straw","stray","strum","strut","stump","stung","stunk","stunt","suave","surge","swamp","swash","swath","swear","sweat","swell","swept","swift","swine","swing","swirl","swoon","swoop","sword","swore","sworn","swung","syrup","tabby","tacit","taffy","tally","talon","tango","tardy","tarot","taunt","tawny","tease","tepid","thick","thigh","thong","thorn","those","throb","throw","thump","tibia","tidal","tiger","tilde","timid","tipsy","toast","today","toddy","token","tonal","tonic","topaz","torch","torso","total","touch","towel","tower","toxic","toxin","trace","tract","trail","tramp","trash","trawl","tread","treat","tress","triad","trill","tripe","troll","troop","trout","trove","truce","tulip","tumor","tunic","turbo","tutor","tweak","tweed","twine","twirl","twist","udder","ulcer","ultra","umbra","uncle","undid","unfit","unify","unlit","unmet","untie","upend","upper","usher","utter","vague","valor","vapor","vault","vegan","venom","verse","verve","vigor","villa","viper","vivid","vixen","vodka","vogue","vouch","vowel","wafer","wager","wagon","waist","waltz","waste","weary","weave","wedge","weedy","weigh","weird","whale","wharf","wheat","which","whiff","whine","whirl","whisk","white","whoop","whorl","widow","wield","wince","windy","wiser","witch","wooly","woozy","world","wrath","wreak","wreck","wrest","wring","wrist","wrote","yacht","yearn","yeast","yield","yodel","yokel","young","yummy","zebra","zesty","zonal"];
+
+  // ---- Additional allowed guesses (common valid words, not usually answers) ----
+  var EXTRA = ["aback","abbey","abbot","abhor","abide","abled","abode","aboil","abort","about","abyss","ached","aches","acids","acres","acrid","addle","adept","adieu","adobe","affix","afire","afoot","afoul","agape","agile","aging","agora","ahold","aisle","alarm","alder","alert","algae","alias","alibi","alien","align","alkyl","allay","alley","allot","aloft","aloof","aloud","altar","amass","amaze","amber","amble","amend","amiss","amity","ample","amply","amuse","angel","anime","anion","ankle","annex","annoy","antic","antsy","aorta","aphid","aptly","arbor","ardor","areas","arena","argon","aroma","arose","arrow","arson","ascot","ashen","ashes","aspen","aspic","assay","aster","astir","atlas","atoll","atone","attic","augur","aunts","avail","avast","avert","avian","await","awake","aware","awash","awful","awoke","axial","axiom","axion","azure","bacon","badge","badly","bagel","baggy","baked","baker","baler","balls","balmy","banal","banjo","barge","baron","basil","basin","baste","bathe","baton","batty","bawdy","bayou","beach","beady","beard","beast","befit","began","begat","beget","begin","begun","being","belch","belie","belle","belly","below","bench","beret","berry","berth","beset","betel","bevel","bezel","bicep","biddy","bigot","bilge","billy","binge","biome","birch","birth","bison","bitty","black","blade","blame","bland","blank","blare","blast","blaze","bleak","bleat","bleed","bleep","blend","bless","blimp","blind","blink","bliss","blitz","bloat","block","bloke","blond","blood","bloom","blown","bluff","blunt","blurb","blurt","blush","board","boast","bobby","boded","bogey","boggy","bongo","bonus","booby","boost","booth","booty","booze","borax","borne","bosom","bossy","botch","bough","boule","bound","bowel","boxer","brace","braid","brain","brake","brand","brash","brass","brave","bravo","brawl","brawn","bread","break","breed","briar","bribe","brick","bride","brine","bring","brink","briny","brisk","broad","broil","broke","brood","brook","broom","broth","brown","brunt","brush","brute","buddy","budge","buggy","bugle","build","built","bulge","bulky","bully","bunch","bunny","burly","burnt","burst","bushy","butte","buxom","buyer","bylaw","cabal","cabby","cabin","cable","cacao","cache","cacti","caddy","cadet","cagey","cairn","camel","cameo","canal","candy","canny","canoe","canon","caper","caput","carat","cargo","carol","carry","carve","caste","catch","cater","catty","caulk","cause","cavil","cease","cedar","cello","chafe","chaff","chain","chair","chalk","champ","chant","chaos","chard","charm","chart","chase","chasm","cheap","cheat","check","cheek","cheer","chess","chest","chick","chide","chief","child","chili","chill","chime","china","chirp","chock","choir","choke","chord","chore","chose","chuck","chump","chunk","churn","chute","cider","cigar","cinch","circa","civet","civic","civil","clack","claim","clamp","clang","clank","clash","clasp","class","clean","clear","cleat","cleft","clerk","click","cliff","climb","cling","clink","cloak","clock","clone","close","cloth","cloud","clout","clove","clown","cluck","clued","clump","clung","coach","coast","cobra","cocoa","colon","color","comet","comfy","comic","comma","conch","condo","conic","copse","coral","corny","couch","cough","could","count","coupe","court","coven","cover","covet","covey","cower","coyly","crack","craft","cramp","crane","crank","crash","crass","crate","crave","crawl","craze","crazy","creak","cream","credo","creed","creek","creep","creme","crepe","crept","cress","crest","crick","cried","crier","crime","crimp","crisp","croak","crock","crony","crook","croon","cross","croup","crowd","crown","crude","cruel","crumb","crump","crush","crust","crypt","cubic","cumin","curio","curly","curry","curse","curve","curvy","cutie","cyber","cycle","cynic","daddy","daily","dairy","daisy","dally","dance","dandy","datum","daunt","dealt","death","debit","debug","debut","decal","decay","decor","decoy","decry","defer","deign","deity","delta","delve","demon","demur","denim","dense","depot","depth","derby","deter","detox","devil","diary","dicey","digit","dilly","dimly","diner","dingo","dingy","diode","dirge","dirty","disco","ditch","ditto","ditty","diver","dizzy","dodge","dodgy","dogma","doing","dolly","donor","donut","dopey","doubt","dough","dowdy","dowel","downy","dowry","dozen","draft","drain","drake","drama","drank","drape","drawl","drawn","dread","dream","dress","dried","drier","drift","drill","drink","drive","droit","droll","drone","drool","droop","dross","drove","drown","druid","drunk","dryer","dryly","duchy","dully","dummy","dumpy","dunce","dusky","dusty","dutch","duvet","dwarf","dwell","dwelt","dying","eager","eagle","early","earth","easel","eaten","eater","ebony","eclat","edict","edify","eerie","egret","eight","eject","eking","elate","elbow","elder","elect","elegy","elfin","elide","elite","elope","elude","email","embed","ember","emcee","emote","empty","enact","endow","enema","enemy","enjoy","ennui","ensue","enter","entry","envoy","epoch","epoxy","equal","equip","erase","erect","erode","error","erupt","essay","ester","ether","ethic","ethos","etude","evade","event","every","evict","evoke","exact","exalt","excel","exert","exile","exist","expel","extol","extra","exult","fable","facet","faint","fairy","faith","false","fancy","farce","fatal","fatty","fault","fauna","favor","feast","fecal","feign","fella","felon","femur","fence","feral","ferry","fetal","fetch","fetid","fever","fewer","fiber","fibre","ficus","field","fiend","fiery","fifth","fifty","fight","filet","filly","filmy","filth","final","finch","finer","first","fishy","fixer","fizzy","fjord","flack","flail","flair","flake","flaky","flame","flank","flare","flash","flask","fleck","fleet","flesh","flick","flier","fling","flint","flirt","float","flock","flood","floor","flora","floss","flour","flout","flown","fluff","fluid","fluke","flume","flung","flush","flute","foamy","focal","focus","foggy","foist","folio","folly","foray","force","forge","forgo","forte","forth","forty","forum","found","foyer","frail","frame","frank","fraud","freak","freed","freer","fresh","friar","fried","frill","frisk","fritz","frock","frond","front","frost","froth","frown","froze","fruit","fudge","fugue","fully","fumes","fungi","funky","funny","furor","furry","fussy","fuzzy","gaffe","gaily","gamer","gamma","gamut","gassy","gaudy","gauge","gaunt","gauze","gavel","gawky","gayer","gayly","gazer","gecko","geeky","geese","genie","genre","ghost","ghoul","giant","giddy","gipsy","girly","girth","given","giver","gizmo","glade","gland","glare","glass","glaze","gleam","glean","glide","glint","gloat","globe","gloom","glory","gloss","glove","glyph","gnash","gnome","godly","going","golem","golly","gonad","goner","goody","gooey","goofy","goose","gorge","gouge","gourd","grace","grade","graft","grail","grain","grand","grant","grape","graph","grasp","grass","grate","grave","gravy","graze","great","greed","green","greet","grief","grill","grime","grimy","grind","gripe","groan","groin","groom","grope","gross","group","grout","grove","growl","grown","gruel","gruff","grunt","guard","guava","guess","guest","guide","guild","guile","guilt","guise","gulch","gully","gumbo","gummy","guppy","gusto","gusty","gypsy","habit","hairy","halve","handy","happy","hardy","harem","harpy","harsh","haste","hasty","hatch","hater","haunt","haute","haven","havoc","hazel","heady","heard","heart","heath","heave","heavy","hedge","hefty","heist","helix","hello","hence","heron","hilly","hinge","hippo","hippy","hitch","hoard","hobby","hoist","holly","homer","honey","honor","horde","horny","horse","hotel","hotly","hound","house","hovel","hover","howdy","human","humid","humor","humph","humus","hunch","hunky","hurry","husky","hussy","hutch","hydro","hyena","hymen","hyper","icily","icing","ideal","idiom","idiot","idler","idyll","igloo","iliac","image","imbue","impel","imply","inane","inbox","incur","index","inept","inert","infer","ingot","inlay","inlet","inner","input","inter","intro","ionic","irate","irony","islet","issue","itchy","ivory","jaunt","jazzy","jelly","jerky","jetty","jewel","jiffy","joint","joist","joker","jolly","joust","judge","juice","juicy","jumbo","jumpy","junta","junto","juror","kappa","karma","kayak","kebab","khaki","kinky","kiosk","kitty","knack","knave","knead","kneed","kneel","knelt","knife","knock","knoll","known","koala","krill","label","labor","laden","ladle","lager","lance","lanky","lapel","lapse","larva","laser","lasso","latch","later","lathe","laugh","layer","leach","leafy","leaky","leant","leapt","learn","lease","leash","least","leave","ledge","leech","leery","lefty","legal","leggy","lemon","lemur","leper","level","lever","libel","liege","light","liken","lilac","limbo","limit","linen","liner","lingo","lipid","lithe","liver","livid","llama","loamy","loath","lobby","local","locus","lodge","lofty","logic","login","loopy","loose","lorry","loser","louse","lousy","lover","lower","lowly","loyal","lucid","lucky","lumen","lumpy","lunar","lunch","lunge","lupus","lurch","lurid","lusty","lying","lymph","lynch","lyric","macaw","macho","macro","madam","madly","mafia","magic","magma","maize","major","maker","mambo","mamma","mammy","manga","mange","mango","mangy","mania","manic","manly","manor","maple","march","marge","marry","marsh","mason","masse","match","matey","mauve","maxim","maybe","mayor","mealy","meant","meaty","mecca","medal","media","medic","melee","melon","mercy","merge","merit","merry","metal","meter","metro","micro","midge","midst","might","milky","mimic","mince","miner","minim","minor","minty","minus","mirth","miser","missy","mocha","modal","model","modem","mogul","moist","molar","moldy","money","month","moody","moose","moral","moron","morph","mossy","motel","motif","motor","motto","moult","mound","mount","mourn","mouse","mousy","mouth","moved","mover","movie","mower","mucky","mucus","muddy","mulch","mummy","munch","mural","murky","mushy","music","musky","musty","myrrh","nadir","naive","nanny","nasal","nasty","natal","naval","navel","needy","neigh","nerdy","nerve","never","newer","newly","nicer","niche","niece","night","ninja","ninny","ninth","noble","nobly","noise","noisy","nomad","noose","north","nosey","notch","noted","novel","nudge","nurse","nutty","nylon","nymph","oaken","obese","occur","ocean","octal","octet","odder","oddly","offal","offer","often","olden","older","olive","ombre","omega","onion","onset","opera","opine","opium","optic","orbit","order","organ","other","otter","ought","ounce","outdo","outer","outgo","ovary","ovate","overt","ovine","ovoid","owing","owner","oxide","ozone","paddy","pagan","paint","paler","palsy","panel","panic","pansy","paper","parer","parka","parry","parse","party","pasta","paste","pasty","patch","patio","patsy","patty","pause","payee","payer","peace","peach","pearl","pecan","pedal","penal","pence","penne","penny","perch","peril","perky","pesky","pesto","petal","petty","phase","phone","phony","photo","piano","picky","piece","piety","piggy","pilot","pinch","piney","pinky","pinto","piper","pique","pitch","pithy","pivot","pixel","pixie","pizza","place","plaid","plain","plait","plane","plank","plant","plate","plaza","plead","pleat","plied","plier","pluck","plumb","plume","plump","plunk","plush","poesy","point","poise","poker","polar","polka","polyp","pooch","poppy","porch","poser","posit","posse","pouch","pound","pouty","power","prank","prawn","preen","press","preen","price","prick","pride","pried","prime","primo","primp","print","prior","prism","privy","prize","probe","prone","prong","proof","prose","proud","prove","prowl","proxy","prude","prune","psalm","pubic","pudgy","puffy","pulpy","pulse","punch","pupal","pupil","puppy","puree","purer","purge","purse","pushy","putty","pygmy","quack","quail","quake","qualm","quark","quart","quash","quasi","queen","queer","quell","query","quest","queue","quick","quiet","quill","quilt","quirk","quite","quota","quote","quoth","rabbi","rabid","racer","radar","radii","radio","rainy","raise","rajah","rally","ralph","ramen","ranch","randy","range","rapid","rarer","raspy","ratio","ratty","raven","rayon","razor","reach","react","ready","realm","rearm","rebar","rebel","rebus","rebut","recap","recur","recut","reedy","refer","refit","regal","rehab","reign","relax","relay","relic","remit","renal","renew","repay","repel","reply","rerun","reset","resin","retch","retro","retry","reuse","revel","revue","rhino","rhyme","rider","ridge","rifle","right","rigid","rigor","rinse","ripen","riper","risen","riser","risky","rival","river","rivet","roach","roast","robin","robot","rocky","rodeo","roger","rogue","roomy","roost","rotor","rouge","rough","round","rouse","route","rowdy","royal","ruddy","ruder","rugby","ruler","rumba","rumor","rupee","rural","rusty","sadly","safer","saint","salad","sally","salon","salsa","salty","salve","salvo","sandy","saner","sappy","sassy","satin","satyr","sauce","saucy","sauna","saute","savor","savoy","savvy","scald","scale","scalp","scaly","scamp","scant","scare","scarf","scary","scene","scent","scion","scoff","scold","scone","scoop","scope","score","scorn","scour","scout","scowl","scram","scrap","scree","screw","scrub","scrum","scuba","sedan","seedy","segue","seize","semen","sense","sepia","serif","serum","serve","setup","seven","sever","sewer","shack","shade","shady","shaft","shake","shaky","shale","shall","shalt","shame","shank","shape","shard","share","shark","sharp","shave","shawl","shear","sheen","sheep","sheer","sheet","sheik","shelf","shell","shied","shift","shine","shiny","shire","shirk","shirt","shoal","shock","shone","shook","shoot","shore","shorn","short","shout","shove","shown","showy","shrew","shrub","shrug","shuck","shunt","shush","shyly","siege","sieve","sight","sigma","silky","silly","since","sinew","singe","siren","sissy","sixth","sixty","skate","skier","skiff","skill","skimp","skirt","skulk","skull","skunk","slack","slain","slang","slant","slash","slate","slave","sleek","sleep","sleet","slept","slice","slick","slide","slime","slimy","sling","slink","sloop","slope","slosh","sloth","slump","slung","slunk","slurp","slush","slyly","smack","small","smart","smash","smear","smell","smelt","smile","smirk","smite","smith","smock","smoke","smoky","smote","snack","snail","snake","snaky","snare","snarl","sneak","sneer","snide","sniff","snipe","snoop","snore","snort","snout","snowy","snuck","snuff","soapy","sober","soggy","solar","solid","solve","sonar","sonic","sooth","sooty","sorry","sound","south","sowed","space","spade","spank","spare","spark","spasm","spawn","speak","spear","speck","speed","spell","spelt","spend","spent","sperm","spice","spicy","spied","spiel","spike","spiky","spill","spilt","spine","spiny","spire","spite","splat","split","spoil","spoke","spoof","spook","spool","spoon","spore","sport","spout","spray","spree","sprig","spume","spunk","spurn","spurt","squad","squat","squib","squid","stack","staff","stage","staid","stain","stair","stake","stale","stalk","stall","stamp","stand","stank","stare","stark","start","stash","state","stave","stead","steak","steal","steam","steed","steel","steep","steer","stein","stern","stick","stiff","still","stilt","sting","stink","stint","stock","stoic","stoke","stole","stomp","stone","stony","stood","stool","stoop","store","stork","storm","story","stout","stove","strap","straw","stray","strip","strut","stuck","study","stuff","stump","stung","stunk","stunt","style","suave","sugar","suing","suite","sulky","sully","sumac","sunny","super","surer","surge","surly","sushi","swami","swamp","swash","swath","swear","sweat","sweep","sweet","swell","swept","swift","swill","swine","swing","swirl","swish","swoon","swoop","sword","swore","sworn","swung","synod","syrup","tabby","table","taboo","tacit","tacky","taffy","taint","taken","taker","tally","talon","tamer","tango","tangy","taper","tapir","tardy","tarot","taste","tasty","tatty","taunt","tawny","teach","teary","tease","teddy","teeth","tempo","tenet","tenor","tense","tenth","tepee","tepid","terra","terse","testy","thank","theft","their","theme","there","these","theta","thick","thief","thigh","thing","think","third","thong","thorn","those","three","threw","throb","throw","thrum","thumb","thump","thyme","tiara","tibia","tidal","tiger","tight","tilde","timer","timid","tipsy","titan","tithe","title","toast","today","toddy","token","tonal","tonga","tonic","tooth","topaz","topic","torch","torso","torus","total","totem","touch","tough","towel","tower","toxic","toxin","trace","track","tract","trade","trail","train","trait","tramp","trash","trawl","tread","treat","trend","triad","trial","tribe","trice","trick","tried","tripe","trite","troll","troop","trope","trout","trove","truce","truck","truer","truly","trump","trunk","truss","trust","truth","tryst","tubal","tuber","tulip","tulle","tumor","tunic","turbo","tutor","twang","tweak","tweed","tweet","twice","twine","twirl","twist","twixt","tying","udder","ulcer","ultra","umbra","uncle","uncut","under","undid","undue","unfed","unfit","unify","union","unite","unity","unlit","unmet","unset","untie","until","unwed","unzip","upend","upper","upset","urban","urine","usage","usher","using","usual","usurp","utile","utter","vague","valet","valid","valor","value","valve","vapid","vapor","vault","vaunt","vegan","venom","venue","verge","verse","verso","verve","vicar","video","vigil","vigor","villa","vinyl","viola","viper","viral","virus","visit","visor","vista","vital","vivid","vixen","vocal","vodka","vogue","voice","voila","vomit","voter","vouch","vowel","vying","wacky","wafer","wager","wagon","waist","waive","waltz","warty","waste","watch","water","waver","waxen","weary","weave","wedge","weedy","weigh","weird","welch","welsh","whack","whale","wharf","wheat","wheel","whelp","where","which","whiff","while","whine","whiny","whirl","whisk","white","whole","whoop","whorl","whose","widen","wider","widow","width","wield","wight","willy","wimpy","wince","winch","windy","wiser","wispy","witch","witty","woken","woman","women","woody","wooer","wooly","woozy","wordy","world","worry","worse","worst","worth","would","wound","woven","wrack","wrath","wreak","wreck","wrest","wring","wrist","write","wrong","wrote","wrung","wryly","yacht","yearn","yeast","yield","yodel","yokel","young","youth","zebra","zesty","zonal"];
+
+  // Build validity set (deduped, 5-letter, lowercase)
+  var VALID = {};
+  var i, w;
+  var ans = [];
+  var seen = {};
+  for (i = 0; i < ANSWERS.length; i++) {
+    w = String(ANSWERS[i]).toLowerCase();
+    if (w.length === 5 && /^[a-z]{5}$/.test(w)) {
+      VALID[w] = 1;
+      if (!seen[w]) { seen[w] = 1; ans.push(w); }
+    }
+  }
+  for (i = 0; i < EXTRA.length; i++) {
+    w = String(EXTRA[i]).toLowerCase();
+    if (w.length === 5 && /^[a-z]{5}$/.test(w)) VALID[w] = 1;
+  }
+  var ANSWER_POOL = ans;
+
+  // ---- State ----
+  var ROWS = 6, COLS = 5;
+  var STORE_KEY = "abrams-wordle-stats";
+  var target = "", row = 0, col = 0, cur = "", over = false, busy = false;
+  var boardEl, msgEl, kbEl;
+  var tiles = [];     // tiles[r][c]
+  var keyEls = {};    // letter -> key element
+  var keyState = {};  // letter -> best status 0 none, 1 x, 2 y, 3 g
+
+  function loadStats() {
+    var s = { played:0, wins:0, streak:0, max:0 };
+    try {
+      var raw = localStorage.getItem(STORE_KEY);
+      if (raw) {
+        var p = JSON.parse(raw);
+        if (p && typeof p === "object") {
+          s.played = p.played|0; s.wins = p.wins|0;
+          s.streak = p.streak|0; s.max = p.max|0;
+        }
+      }
+    } catch (e) {}
+    return s;
+  }
+  function saveStats(s) {
+    try { localStorage.setItem(STORE_KEY, JSON.stringify(s)); } catch (e) {}
+  }
+  var stats = loadStats();
+
+  function renderStats() {
+    var pct = stats.played ? Math.round(stats.wins / stats.played * 100) : 0;
+    setText("sPlayed", stats.played);
+    setText("sWin", pct);
+    setText("sStreak", stats.streak);
+    setText("sMax", stats.max);
+    setText("oPlayed", stats.played);
+    setText("oWin", pct);
+    setText("oStreak", stats.streak);
+    setText("oMax", stats.max);
+  }
+  function setText(id, v) {
+    var el = document.getElementById(id);
+    if (el) el.textContent = String(v);
+  }
+
+  function buildBoard() {
+    boardEl.innerHTML = "";
+    tiles = [];
+    for (var r = 0; r < ROWS; r++) {
+      var rowEl = document.createElement("div");
+      rowEl.className = "brow";
+      var rowTiles = [];
+      for (var c = 0; c < COLS; c++) {
+        var t = document.createElement("div");
+        t.className = "tile";
+        rowEl.appendChild(t);
+        rowTiles.push(t);
+      }
+      boardEl.appendChild(rowEl);
+      tiles.push(rowTiles);
+    }
+  }
+
+  var KB_ROWS = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
+  function buildKeyboard() {
+    kbEl.innerHTML = "";
+    keyEls = {};
+    for (var r = 0; r < KB_ROWS.length; r++) {
+      var rowEl = document.createElement("div");
+      rowEl.className = "krow";
+      if (r === 2) {
+        rowEl.appendChild(makeKey("ENTER", "enter", true));
+      }
+      var letters = KB_ROWS[r];
+      for (var c = 0; c < letters.length; c++) {
+        var ch = letters.charAt(c);
+        var k = makeKey(ch, ch, false);
+        keyEls[ch] = k;
+        rowEl.appendChild(k);
+      }
+      if (r === 2) {
+        rowEl.appendChild(makeKey("DEL", "backspace", true));
+      }
+      kbEl.appendChild(rowEl);
+    }
+  }
+  function makeKey(label, action, wide) {
+    var b = document.createElement("button");
+    b.className = "key" + (wide ? " wide" : "");
+    b.textContent = label;
+    b.setAttribute("data-action", action);
+    b.setAttribute("type", "button");
+    return b;
+  }
+
+  function newGame() {
+    target = ANSWER_POOL[Math.floor(Math.random() * ANSWER_POOL.length)];
+    row = 0; col = 0; cur = ""; over = false; busy = false;
+    keyState = {};
+    buildBoard();
+    for (var k in keyEls) {
+      if (keyEls.hasOwnProperty(k)) keyEls[k].className = "key";
+    }
+    setMsg("");
+    hideOverlay();
+  }
+
+  function setMsg(m) { if (msgEl) msgEl.textContent = m || ""; }
+
+  function flashMsg(m) {
+    setMsg(m);
+    if (flashMsg._t) clearTimeout(flashMsg._t);
+    flashMsg._t = setTimeout(function () { setMsg(""); }, 1400);
+  }
+
+  function addLetter(ch) {
+    if (over || busy) return;
+    if (cur.length >= COLS) return;
+    var t = tiles[row][cur.length];
+    t.textContent = ch;
+    t.classList.add("filled", "pop");
+    (function (tt) { setTimeout(function () { tt.classList.remove("pop"); }, 130); })(t);
+    cur += ch;
+  }
+
+  function delLetter() {
+    if (over || busy) return;
+    if (cur.length === 0) return;
+    cur = cur.slice(0, -1);
+    var t = tiles[row][cur.length];
+    t.textContent = "";
+    t.classList.remove("filled");
+  }
+
+  function shakeRow() {
+    var rowEl = boardEl.children[row];
+    if (!rowEl) return;
+    rowEl.classList.add("shake");
+    setTimeout(function () { rowEl.classList.remove("shake"); }, 420);
+  }
+
+  function scoreGuess(guess, answer) {
+    // returns array of "g"/"y"/"x"
+    var res = ["x","x","x","x","x"];
+    var counts = {};
+    var a, gch;
+    for (var j = 0; j < COLS; j++) {
+      a = answer.charAt(j);
+      counts[a] = (counts[a] || 0) + 1;
+    }
+    for (j = 0; j < COLS; j++) {
+      if (guess.charAt(j) === answer.charAt(j)) {
+        res[j] = "g";
+        counts[guess.charAt(j)]--;
+      }
+    }
+    for (j = 0; j < COLS; j++) {
+      if (res[j] === "g") continue;
+      gch = guess.charAt(j);
+      if (counts[gch] > 0) {
+        res[j] = "y";
+        counts[gch]--;
+      }
+    }
+    return res;
+  }
+
+  var RANK = { "x":1, "y":2, "g":3 };
+  function updateKey(ch, st) {
+    var prev = keyState[ch] || 0;
+    if (RANK[st] > prev) {
+      keyState[ch] = RANK[st];
+      var el = keyEls[ch];
+      if (el) {
+        el.classList.remove("g", "y", "x");
+        el.classList.add(st);
+      }
+    }
+  }
+
+  function submit() {
+    if (over || busy) return;
+    if (cur.length < COLS) { flashMsg("Not enough letters"); shakeRow(); return; }
+    var guess = cur;
+    if (!VALID[guess]) { flashMsg("Not in word list"); shakeRow(); return; }
+
+    busy = true;
+    var res = scoreGuess(guess, target);
+    var rowTiles = tiles[row];
+    var thisRow = row;
+
+    for (var c = 0; c < COLS; c++) {
+      (function (c) {
+        setTimeout(function () {
+          var t = rowTiles[c];
+          t.classList.add("flip");
+          setTimeout(function () {
+            t.classList.add(res[c]);
+            updateKey(guess.charAt(c), res[c]);
+          }, 250);
+          setTimeout(function () { t.classList.remove("flip"); }, 500);
+        }, c * 180);
+      })(c);
+    }
+
+    var total = (COLS - 1) * 180 + 520;
+    setTimeout(function () {
+      finishRow(guess, res, thisRow);
+    }, total);
+  }
+
+  function finishRow(guess, res, guessRow) {
+    var won = true;
+    for (var c = 0; c < COLS; c++) { if (res[c] !== "g") { won = false; break; } }
+
+    if (won) {
+      over = true; busy = false;
+      recordResult(true);
+      showOverlay(true, guessRow + 1);
+      return;
+    }
+
+    row++;
+    cur = "";
+    if (row >= ROWS) {
+      over = true; busy = false;
+      recordResult(false);
+      showOverlay(false, 0);
+    } else {
+      busy = false;
+    }
+  }
+
+  function recordResult(won) {
+    stats.played++;
+    if (won) {
+      stats.wins++;
+      stats.streak++;
+      if (stats.streak > stats.max) stats.max = stats.streak;
+    } else {
+      stats.streak = 0;
+    }
+    saveStats(stats);
+    renderStats();
+  }
+
+  var WIN_MSGS = ["Genius","Magnificent","Impressive","Splendid","Great","Phew"];
+  function showOverlay(won, guessNum) {
+    var ov = document.getElementById("ov");
+    setText("ovTag", won ? "You win" : "Out of guesses");
+    setText("ovTitle", won ? (WIN_MSGS[Math.min(guessNum - 1, WIN_MSGS.length - 1)] || "Nice") : "So close");
+    setText("ovWord", target);
+    setText("ovSub", won
+      ? ("Solved in " + guessNum + (guessNum === 1 ? " guess" : " guesses"))
+      : "Better luck next round");
+    renderStats();
+    ov.classList.remove("hide");
+  }
+  function hideOverlay() {
+    var ov = document.getElementById("ov");
+    ov.classList.add("hide");
+  }
+
+  // ---- Input ----
+  function handleAction(action) {
+    if (action === "enter") submit();
+    else if (action === "backspace") delLetter();
+    else if (action.length === 1 && action >= "a" && action <= "z") addLetter(action);
+  }
+
+  function onKeydown(e) {
+    if (e.ctrlKey || e.metaKey || e.altKey) return;
+    var key = e.key;
+    if (key === "Enter") { e.preventDefault(); handleAction("enter"); }
+    else if (key === "Backspace") { e.preventDefault(); handleAction("backspace"); }
+    else if (key && key.length === 1) {
+      var lc = key.toLowerCase();
+      if (lc >= "a" && lc <= "z") { e.preventDefault(); handleAction(lc); }
+    }
+  }
+
+  function onKbClick(e) {
+    var el = e.target;
+    while (el && el !== kbEl && !el.getAttribute) el = el.parentNode;
+    if (!el || el === kbEl) return;
+    var action = el.getAttribute && el.getAttribute("data-action");
+    if (action) {
+      e.preventDefault();
+      handleAction(action);
+    }
+  }
+
+  function init() {
+    boardEl = document.getElementById("board");
+    msgEl = document.getElementById("msg");
+    kbEl = document.getElementById("kb");
+
+    buildBoard();
+    buildKeyboard();
+    renderStats();
+    newGame();
+
+    document.addEventListener("keydown", onKeydown);
+    kbEl.addEventListener("click", onKbClick);
+
+    var newBtn = document.getElementById("newBtn");
+    if (newBtn) newBtn.addEventListener("click", function () { newGame(); });
+    var playBtn = document.getElementById("playBtn");
+    if (playBtn) playBtn.addEventListener("click", function () { newGame(); });
+  }
+
+  if (document.readyState === "loading") {
+    document.addEventListener("DOMContentLoaded", init);
+  } else {
+    init();
+  }
+})();
+</script>
+</body>
+</html>
diff --git a/index.html b/index.html
index ded0dad..a2c9df8 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,8 @@
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <title>games.agentabrams.com</title>
+<!-- file:// fallback: inlined mirror of games.json (a <script src> works over file://, fetch() does not). Regenerated by sync.sh. -->
+<script src="games-data.js"></script>
 <style>
   * { box-sizing: border-box; }
   html, body { height: 100%; margin: 0; }
@@ -184,8 +186,8 @@
     if (push !== false) history.replaceState(null, '', '#' + id);
   }
 
-  // cache-bust so a newly-added game shows up without a hard refresh
-  fetch('games.json?cb=' + Date.now(), { cache: 'no-store' }).then(function (r) { return r.json(); }).then(function (data) {
+  // Build the gallery from a data object ({ games: [...] }).
+  function render(data) {
     games = data.games || [];
     games.forEach(function (g) {
       var b = document.createElement('button');
@@ -211,7 +213,18 @@
       want = games.length ? games[0].id : null;
     }
     if (want) select(want, false);
-  });
+  }
+
+  // Prefer a live fetch (freshest, cache-busted) so a newly-added game shows
+  // up without a hard refresh. Fall back to the inlined games-data.js when
+  // running from file:// — browsers block fetch() of a sibling file there.
+  fetch('games.json?cb=' + Date.now(), { cache: 'no-store' })
+    .then(function (r) { if (!r.ok) throw new Error('http ' + r.status); return r.json(); })
+    .then(render)
+    .catch(function () {
+      if (window.__GAMES_DATA__) { render(window.__GAMES_DATA__); }
+      else { list.innerHTML = '<div style="padding:16px;color:#8b93a7;font:13px ui-monospace,monospace">Could not load games. Serve over http:// or ensure games-data.js is present.</div>'; }
+    });
 
   addEventListener('hashchange', function () {
     var id = location.hash.replace('#', '');
diff --git a/sync.sh b/sync.sh
index d3364d9..e39fb0b 100755
--- a/sync.sh
+++ b/sync.sh
@@ -20,6 +20,24 @@ while IFS=$'\t' read -r id src; do
   for aa in "$src"/*.aa; do [ -e "$aa" ] || continue; cp "$aa" "$dest/"; done
 done < "$MAP"
 [ "$changed" = 1 ] && echo "sync: updates applied" || echo "sync: all in sync"
+
+# Regenerate the file:// fallback mirror of games.json (a <script src> loads
+# from a local file; fetch() is blocked over file://). Keeps games-data.js in
+# lockstep with games.json so double-clicking index.html shows every game.
+if [ -f "$HUB/games.json" ]; then
+  python3 - "$HUB" <<'PY'
+import json, os, sys
+hub = sys.argv[1]
+d = json.load(open(os.path.join(hub, 'games.json')))
+with open(os.path.join(hub, 'games-data.js'), 'w') as f:
+    f.write('/* AUTO-GENERATED from games.json by sync.sh — do not edit by hand.\n')
+    f.write('   file:// fallback: <script src> works from a local file, fetch() does not. */\n')
+    f.write('window.__GAMES_DATA__ = ')
+    json.dump(d, f, ensure_ascii=False, indent=2)
+    f.write(';\n')
+PY
+  echo "regenerated games-data.js ($(grep -c '"id"' "$HUB/games.json") games)"
+fi
 if [ "${1:-}" = "--commit" ] && [ -n "$(git -C "$HUB" status --porcelain)" ]; then
   git -C "$HUB" add -A
   git -C "$HUB" -c user.email="steve@designerwallcoverings.com" -c user.name="Steve" commit -q -m "sync builds from source" && echo "committed hub"

← 1aa9269 Backgammon: 🎲 per-game hub icon (was default 🎮)  ·  back to Games Agentabrams  ·  Retire old particle-text (Particle Word); keep improved Star 0bbf2b0 →