{"project":{"id":"BFPA45f","userId":"davidyarham@gmail.com","username":null,"userPicture":null,"name":"Jessica's Gymnastics","thumbnail":"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","visible":true,"contributors":"","githubRepo":null,"forkedFrom":null,"tags":"","files":{"folder":"","files":[{"name":"index.html","content":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Untitled</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Lilita+One&family=Quicksand:wght@500;700&display=swap\" rel=\"stylesheet\">\n<script src=\"https://unpkg.com/lucide@latest/dist/umd/lucide.js\"></script>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\n</head>\n<body>\n<div class=\"game\">\n\t<div class=\"game__bg\">\n\t\t<div class=\"game__bg-stripe game__bg-stripe--1\"></div>\n\t\t<div class=\"game__bg-stripe game__bg-stripe--2\"></div>\n\t\t<div class=\"game__bg-stripe game__bg-stripe--3\"></div>\n\t</div>\n\n\t<div class=\"game__title-screen\" id=\"titleScreen\">\n\t\t<div class=\"game__logo\">\n\t\t\t<div class=\"game__logo-star\">★</div>\n\t\t\t<h1 class=\"game__title\">Jessica's<br>Gymnastics</h1>\n\t\t\t<p class=\"game__subtitle\">Tap & flip your way to gold!</p>\n\t\t</div>\n\t\t<button class=\"game__btn game__btn--start\" id=\"startBtn\">\n      <span>Start Routine</span>\n    </button>\n\t\t<div class=\"game__instructions\">\n\t\t\t<div class=\"game__instruction\">\n\t\t\t\t<kbd>←</kbd><kbd>→</kbd> or Swipe to move\n\t\t\t</div>\n\t\t\t<div class=\"game__instruction\">\n\t\t\t\t<kbd>Space</kbd> or Tap to flip\n\t\t\t</div>\n\t\t\t<div class=\"game__instruction\">\n\t\t\t\tLand on platforms to score!\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<div class=\"game__hud\" id=\"hud\">\n\t\t<div class=\"game__hud-item\">\n\t\t\t<span class=\"game__hud-label\">Score</span>\n\t\t\t<span class=\"game__hud-value\" id=\"scoreDisplay\">0</span>\n\t\t</div>\n\t\t<div class=\"game__hud-item\">\n\t\t\t<span class=\"game__hud-label\">Combo</span>\n\t\t\t<span class=\"game__hud-value game__hud-value--combo\" id=\"comboDisplay\">x1</span>\n\t\t</div>\n\t\t<div class=\"game__hud-item\">\n\t\t\t<span class=\"game__hud-label\">Best</span>\n\t\t\t<span class=\"game__hud-value\" id=\"bestDisplay\">0</span>\n\t\t</div>\n\t</div>\n\n\t<canvas id=\"gameCanvas\"></canvas>\n\n\t<div class=\"game__controls\" id=\"mobileControls\">\n\t\t<button class=\"game__ctrl game__ctrl--left\" id=\"btnLeft\">\n      <i data-lucide=\"chevron-left\"></i>\n    </button>\n\t\t<button class=\"game__ctrl game__ctrl--jump\" id=\"btnSuperJump\">\n      <i data-lucide=\"arrow-up\"></i>\n      <span>SUPER</span>\n    </button>\n\t\t<button class=\"game__ctrl game__ctrl--flip\" id=\"btnFlip\">\n      <i data-lucide=\"rotate-cw\"></i>\n      <span>FLIP!</span>\n    </button>\n\t\t<button class=\"game__ctrl game__ctrl--right\" id=\"btnRight\">\n      <i data-lucide=\"chevron-right\"></i>\n    </button>\n\t</div>\n\n\t<div class=\"game__over\" id=\"gameOver\">\n\t\t<div class=\"game__over-card\">\n\t\t\t<div class=\"game__over-stars\" id=\"overStars\">★★★</div>\n\t\t\t<h2 class=\"game__over-title\">Routine Complete!</h2>\n\t\t\t<div class=\"game__over-score\">\n\t\t\t\t<span>Final Score</span>\n\t\t\t\t<strong id=\"finalScore\">0</strong>\n\t\t\t</div>\n\t\t\t<div class=\"game__over-msg\" id=\"overMsg\">Great performance!</div>\n\t\t\t<button class=\"game__btn game__btn--retry\" id=\"retryBtn\">\n        <span>Try Again</span>\n      </button>\n\t\t</div>\n\t</div>\n\n\t<div class=\"game__particles\" id=\"particles\"></div>\n</div>\n  <script type=\"module\" src=\"main.js\"></script>\n</body>\n</html>"},{"name":"main.js","content":"// ===== SOUND ENGINE (Web Audio API) =====\nconst AudioCtx = window.AudioContext || window.webkitAudioContext;\nlet audioCtx;\n\nfunction ensureAudio() {\n\tif (!audioCtx) audioCtx = new AudioCtx();\n\tif (audioCtx.state === 'suspended') audioCtx.resume();\n}\n\nfunction playTone(freq, duration, type = 'square', volume = 0.15) {\n\tif (!audioCtx) return;\n\tconst osc = audioCtx.createOscillator();\n\tconst gain = audioCtx.createGain();\n\tosc.type = type;\n\tosc.frequency.setValueAtTime(freq, audioCtx.currentTime);\n\tgain.gain.setValueAtTime(volume, audioCtx.currentTime);\n\tgain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + duration);\n\tosc.connect(gain);\n\tgain.connect(audioCtx.destination);\n\tosc.start();\n\tosc.stop(audioCtx.currentTime + duration);\n}\n\nfunction sfxJump() {\n\tplayTone(400, 0.12, 'square', 0.1);\n\tsetTimeout(() => playTone(600, 0.1, 'square', 0.08), 50);\n}\n\nfunction sfxSuperJump() {\n\tplayTone(300, 0.15, 'sine', 0.12);\n\tsetTimeout(() => playTone(500, 0.12, 'sine', 0.1), 50);\n\tsetTimeout(() => playTone(800, 0.15, 'sine', 0.1), 100);\n\tsetTimeout(() => playTone(1000, 0.2, 'sine', 0.08), 150);\n}\n\nfunction sfxFlip() {\n\tplayTone(300, 0.15, 'sawtooth', 0.08);\n\tsetTimeout(() => playTone(500, 0.12, 'sawtooth', 0.06), 60);\n\tsetTimeout(() => playTone(700, 0.1, 'sawtooth', 0.05), 120);\n}\n\nfunction sfxLand(combo) {\n\tconst base = 500 + combo * 80;\n\tplayTone(base, 0.2, 'sine', 0.12);\n\tsetTimeout(() => playTone(base * 1.25, 0.15, 'sine', 0.1), 80);\n\tsetTimeout(() => playTone(base * 1.5, 0.12, 'sine', 0.08), 160);\n}\n\nfunction sfxPerfect() {\n\tconst notes = [523, 659, 784, 1047];\n\tnotes.forEach((n, i) => {\n\t\tsetTimeout(() => playTone(n, 0.25, 'sine', 0.1), i * 80);\n\t});\n}\n\nfunction sfxFall() {\n\tplayTone(300, 0.3, 'sawtooth', 0.1);\n\tsetTimeout(() => playTone(200, 0.3, 'sawtooth', 0.08), 100);\n\tsetTimeout(() => playTone(100, 0.4, 'sawtooth', 0.06), 200);\n}\n\nfunction sfxGameOver() {\n\tconst notes = [400, 350, 300, 200];\n\tnotes.forEach((n, i) => {\n\t\tsetTimeout(() => playTone(n, 0.35, 'triangle', 0.1), i * 150);\n\t});\n}\n\n// ===== GAME ENGINE =====\nconst canvas = document.getElementById('gameCanvas');\nconst ctx = canvas.getContext('2d');\nconst particles = document.getElementById('particles');\n\nlet W, H;\n\nfunction resize() {\n\tW = canvas.width = window.innerWidth;\n\tH = canvas.height = window.innerHeight;\n}\nwindow.addEventListener('resize', resize);\nresize();\n\n// Game State\nconst STATE = {\n\tTITLE: 0,\n\tPLAYING: 1,\n\tOVER: 2\n};\nlet state = STATE.TITLE;\nlet score = 0;\nlet bestScore = parseInt(localStorage.getItem('jessicaBest') || '0');\nlet combo = 0;\nlet flipping = false;\nlet flipAngle = 0;\nlet flipCount = 0;\n\n// Jessica (the gymnast)\nconst jessica = {\n\tx: 0,\n\ty: 0,\n\tvx: 0,\n\tvy: 0,\n\tw: 30,\n\th: 40,\n\tonGround: false,\n\trotation: 0,\n\ttargetRotation: 0,\n\tlives: 3,\n\ttrail: []\n};\n\n// Platforms\nlet platforms = [];\nlet platformSpeed = 1.5;\nlet spawnTimer = 0;\nlet difficulty = 0;\n\n// Stars (collectibles)\nlet stars = [];\n\n// Camera\nlet cameraY = 0;\n\n// Input\nconst keys = {};\nlet moveLeft = false;\nlet moveRight = false;\nlet doFlip = false;\nlet superJumpReady = true;\nlet superJumpActive = false;\nlet superJumpCooldown = 0;\nconst SUPER_JUMP_COOLDOWN = 3000;\n\nfunction initGame() {\n\tscore = 0;\n\tcombo = 0;\n\tflipping = false;\n\tflipAngle = 0;\n\tflipCount = 0;\n\tdifficulty = 0;\n\tplatformSpeed = 1.5;\n\tsuperJumpReady = true;\n\tsuperJumpActive = false;\n\tsuperJumpCooldown = 0;\n\tconst sjBtn = document.getElementById('btnSuperJump');\n\tif (sjBtn) sjBtn.classList.remove('cooldown');\n\n\tjessica.x = W / 2;\n\tjessica.y = H - 120;\n\tjessica.vx = 0;\n\tjessica.vy = 0;\n\tjessica.onGround = false;\n\tjessica.rotation = 0;\n\tjessica.trail = [];\n\n\tplatforms = [];\n\tstars = [];\n\tcameraY = 0;\n\n\t// Ground platform\n\tplatforms.push({\n\t\tx: 0,\n\t\ty: H - 60,\n\t\tw: W,\n\t\th: 20,\n\t\ttype: 'ground',\n\t\tcolor: '#a855f7'\n\t});\n\n\t// Initial platforms\n\tfor (let i = 0; i < 8; i++) {\n\t\tspawnPlatform(H - 140 - i * 100);\n\t}\n\n\tupdateHUD();\n}\n\nfunction spawnPlatform(y) {\n\tconst minW = Math.max(60, 120 - difficulty * 2);\n\tconst maxW = Math.max(80, 180 - difficulty * 3);\n\tconst w = minW + Math.random() * (maxW - minW);\n\tconst x = 30 + Math.random() * (W - w - 60);\n\n\tconst types = ['normal', 'normal', 'normal', 'bouncy', 'moving'];\n\tconst type = difficulty > 3 ? types[Math.floor(Math.random() * types.length)] : 'normal';\n\n\tconst colors = ['#ff2d78', '#06b6d4', '#a855f7', '#fbbf24', '#22c55e'];\n\n\tconst p = {\n\t\tx,\n\t\ty,\n\t\tw,\n\t\th: 14,\n\t\ttype,\n\t\tcolor: colors[Math.floor(Math.random() * colors.length)],\n\t\tmoveDir: Math.random() > 0.5 ? 1 : -1,\n\t\tmoveSpeed: 1 + Math.random() * 1.5,\n\t\torigX: x\n\t};\n\n\tplatforms.push(p);\n\n\t// Maybe spawn a star\n\tif (Math.random() < 0.3) {\n\t\tstars.push({\n\t\t\tx: x + w / 2,\n\t\t\ty: y - 30,\n\t\t\tcollected: false,\n\t\t\tbobOffset: Math.random() * Math.PI * 2\n\t\t});\n\t}\n}\n\nfunction updateHUD() {\n\tdocument.getElementById('scoreDisplay').textContent = score;\n\tdocument.getElementById('comboDisplay').textContent = 'x' + Math.max(1, combo);\n\tdocument.getElementById('bestDisplay').textContent = bestScore;\n}\n\nfunction spawnParticles(x, y, color, count = 8) {\n\tfor (let i = 0; i < count; i++) {\n\t\tconst el = document.createElement('div');\n\t\tel.className = 'game__particle';\n\t\tconst angle = (Math.PI * 2 / count) * i + Math.random() * 0.5;\n\t\tconst dist = 30 + Math.random() * 50;\n\t\tconst tx = Math.cos(angle) * dist;\n\t\tconst ty = Math.sin(angle) * dist;\n\t\tel.style.cssText = `\n      left: ${x}px;\n      top: ${y - cameraY}px;\n      width: ${4 + Math.random() * 6}px;\n      height: ${4 + Math.random() * 6}px;\n      background: ${color};\n      --tx: ${tx}px;\n      --ty: ${ty}px;\n    `;\n\t\tparticles.appendChild(el);\n\t\tsetTimeout(() => el.remove(), 800);\n\t}\n}\n\nfunction showFloatText(x, y, text, color = '#fbbf24') {\n\tconst el = document.createElement('div');\n\tel.className = 'game__float-text';\n\tel.textContent = text;\n\tel.style.left = x + 'px';\n\tel.style.top = (y - cameraY) + 'px';\n\tel.style.color = color;\n\tparticles.appendChild(el);\n\tsetTimeout(() => el.remove(), 1000);\n}\n\n// ===== GAME LOOP =====\nlet lastTime = 0;\nconst GRAVITY = 0.45;\nconst MOVE_SPEED = 5;\nconst JUMP_FORCE = -11;\nconst FLIP_SPEED = 12;\n\nfunction update(dt) {\n\tif (state !== STATE.PLAYING) return;\n\n\t// Input\n\tconst left = keys['ArrowLeft'] || keys['KeyA'] || moveLeft;\n\tconst right = keys['ArrowRight'] || keys['KeyD'] || moveRight;\n\n\tif (left) jessica.vx = -MOVE_SPEED;\n\telse if (right) jessica.vx = MOVE_SPEED;\n\telse jessica.vx *= 0.85;\n\n\t// Flip\n\tif ((keys['Space'] || doFlip) && !flipping && !jessica.onGround) {\n\t\tflipping = true;\n\t\tflipAngle = 0;\n\t\tflipCount++;\n\t\tsfxFlip();\n\t\tdoFlip = false;\n\t}\n\tif (doFlip) doFlip = false;\n\n\t// Super jump cooldown\n\tif (!superJumpReady) {\n\t\tsuperJumpCooldown -= dt;\n\t\tif (superJumpCooldown <= 0) {\n\t\t\tsuperJumpReady = true;\n\t\t\tconst sjBtn = document.getElementById('btnSuperJump');\n\t\t\tif (sjBtn) sjBtn.classList.remove('cooldown');\n\t\t}\n\t}\n\n\t// Apply gravity\n\tjessica.vy += GRAVITY;\n\tjessica.x += jessica.vx;\n\tjessica.y += jessica.vy;\n\n\t// Flip animation\n\tif (flipping) {\n\t\tflipAngle += FLIP_SPEED;\n\t\tjessica.rotation += FLIP_SPEED * (Math.PI / 180);\n\t\tif (flipAngle >= 360) {\n\t\t\tflipping = false;\n\t\t\tflipAngle = 0;\n\t\t\tjessica.rotation = 0;\n\t\t}\n\t} else if (jessica.onGround) {\n\t\tjessica.rotation *= 0.8;\n\t}\n\n\t// Trail\n\tjessica.trail.push({\n\t\tx: jessica.x,\n\t\ty: jessica.y,\n\t\tage: 0\n\t});\n\tif (jessica.trail.length > 12) jessica.trail.shift();\n\tjessica.trail.forEach(t => t.age++);\n\n\t// Wrap horizontal\n\tif (jessica.x < -jessica.w) jessica.x = W + jessica.w;\n\tif (jessica.x > W + jessica.w) jessica.x = -jessica.w;\n\n\t// Camera follows jessica upward\n\tconst targetCamY = Math.min(0, jessica.y - H * 0.4);\n\tcameraY += (targetCamY - cameraY) * 0.08;\n\n\t// Platform collision\n\tjessica.onGround = false;\n\tfor (const p of platforms) {\n\t\t// Moving platforms\n\t\tif (p.type === 'moving') {\n\t\t\tp.x += p.moveDir * p.moveSpeed;\n\t\t\tif (p.x < 20 || p.x + p.w > W - 20) p.moveDir *= -1;\n\t\t}\n\n\t\t// Collision from above\n\t\tif (\n\t\t\tjessica.vy >= 0 &&\n\t\t\tjessica.x + jessica.w / 2 > p.x &&\n\t\t\tjessica.x - jessica.w / 2 < p.x + p.w &&\n\t\t\tjessica.y + jessica.h / 2 > p.y &&\n\t\t\tjessica.y + jessica.h / 2 < p.y + p.h + jessica.vy + 5\n\t\t) {\n\t\t\tjessica.y = p.y - jessica.h / 2;\n\t\t\tjessica.onGround = true;\n\n\t\t\tconst wasFlipping = flipCount > 0;\n\n\t\t\tconst jumpMultiplier = superJumpActive ? 2.0 : 1.0;\n\t\t\tif (p.type === 'bouncy') {\n\t\t\t\tjessica.vy = JUMP_FORCE * 1.4 * jumpMultiplier;\n\t\t\t\tjessica.onGround = false;\n\t\t\t\tif (superJumpActive) {\n\t\t\t\t\tsfxSuperJump();\n\t\t\t\t} else {\n\t\t\t\t\tsfxJump();\n\t\t\t\t}\n\t\t\t\tspawnParticles(jessica.x, jessica.y + jessica.h / 2, superJumpActive ? '#06b6d4' : '#fbbf24', superJumpActive ? 16 : 10);\n\t\t\t} else {\n\t\t\t\tjessica.vy = JUMP_FORCE * jumpMultiplier;\n\t\t\t\tjessica.onGround = false;\n\t\t\t\tif (superJumpActive) {\n\t\t\t\t\tsfxSuperJump();\n\t\t\t\t} else {\n\t\t\t\t\tsfxJump();\n\t\t\t\t}\n\t\t\t\tif (superJumpActive) spawnParticles(jessica.x, jessica.y + jessica.h / 2, '#06b6d4', 14);\n\t\t\t}\n\t\t\tif (superJumpActive) {\n\t\t\t\tshowFloatText(jessica.x, jessica.y, 'SUPER JUMP!', '#06b6d4');\n\t\t\t\tsuperJumpActive = false;\n\t\t\t}\n\n\t\t\t// Score flips\n\t\t\tif (wasFlipping) {\n\t\t\t\tconst points = flipCount * 100 * Math.max(1, combo);\n\t\t\t\tscore += points;\n\t\t\t\tcombo++;\n\t\t\t\tsfxLand(combo);\n\n\t\t\t\tconst screenY = jessica.y - cameraY;\n\t\t\t\tif (flipCount >= 2) {\n\t\t\t\t\tsfxPerfect();\n\t\t\t\t\tshowFloatText(jessica.x, jessica.y, `AMAZING! +${points}`, '#ff2d78');\n\t\t\t\t\tspawnParticles(jessica.x, jessica.y, '#ff2d78', 16);\n\t\t\t\t} else {\n\t\t\t\t\tshowFloatText(jessica.x, jessica.y, `+${points}`);\n\t\t\t\t\tspawnParticles(jessica.x, jessica.y + jessica.h / 2, p.color, 8);\n\t\t\t\t}\n\n\t\t\t\t// Combo bump animation\n\t\t\t\tconst comboEl = document.getElementById('comboDisplay');\n\t\t\t\tcomboEl.classList.remove('bump');\n\t\t\t\tvoid comboEl.offsetWidth;\n\t\t\t\tcomboEl.classList.add('bump');\n\t\t\t} else {\n\t\t\t\tcombo = 0;\n\t\t\t\tscore += 10;\n\t\t\t\tspawnParticles(jessica.x, jessica.y + jessica.h / 2, p.color, 4);\n\t\t\t}\n\n\t\t\tflipCount = 0;\n\t\t\tflipping = false;\n\t\t\tflipAngle = 0;\n\t\t\tjessica.rotation = 0;\n\n\t\t\tupdateHUD();\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Star collection\n\tfor (const s of stars) {\n\t\tif (s.collected) continue;\n\t\tconst dx = jessica.x - s.x;\n\t\tconst dy = jessica.y - s.y;\n\t\tif (Math.sqrt(dx * dx + dy * dy) < 30) {\n\t\t\ts.collected = true;\n\t\t\tscore += 50;\n\t\t\tsfxPerfect();\n\t\t\tspawnParticles(s.x, s.y, '#fbbf24', 12);\n\t\t\tshowFloatText(s.x, s.y, '★ +50', '#fbbf24');\n\t\t\tupdateHUD();\n\t\t}\n\t}\n\n\t// Spawn new platforms as we go up\n\tconst highestPlatform = Math.min(...platforms.map(p => p.y));\n\tif (highestPlatform > cameraY - 200) {\n\t\tconst count = 3 + Math.floor(Math.random() * 2);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tspawnPlatform(highestPlatform - 80 - i * (90 + Math.random() * 40));\n\t\t}\n\t\tdifficulty += 0.3;\n\t}\n\n\t// Remove far below platforms\n\tplatforms = platforms.filter(p => p.y < cameraY + H + 200);\n\tstars = stars.filter(s => s.y < cameraY + H + 200);\n\n\t// Fall death\n\tif (jessica.y > cameraY + H + 100) {\n\t\tgameOver();\n\t}\n}\n\nfunction drawJessica() {\n\tctx.save();\n\tctx.translate(jessica.x, jessica.y);\n\tctx.rotate(jessica.rotation);\n\n\t// Body\n\tconst gradient = ctx.createLinearGradient(-12, -20, 12, 20);\n\tgradient.addColorStop(0, '#ff6ba6');\n\tgradient.addColorStop(1, '#ff2d78');\n\n\t// Leotard body\n\tctx.fillStyle = gradient;\n\tctx.beginPath();\n\tctx.ellipse(0, 0, 12, 18, 0, 0, Math.PI * 2);\n\tctx.fill();\n\n\t// Head\n\tctx.fillStyle = '#fdd9b5';\n\tctx.beginPath();\n\tctx.arc(0, -22, 10, 0, Math.PI * 2);\n\tctx.fill();\n\n\t// Hair\n\tctx.fillStyle = '#5c3317';\n\tctx.beginPath();\n\tctx.arc(0, -25, 10, Math.PI, 0);\n\tctx.fill();\n\n\t// Hair ponytail\n\tctx.beginPath();\n\tctx.moveTo(5, -28);\n\tctx.quadraticCurveTo(18, -35, 14, -20);\n\tctx.lineWidth = 3;\n\tctx.strokeStyle = '#5c3317';\n\tctx.stroke();\n\n\t// Eyes\n\tctx.fillStyle = '#333';\n\tctx.beginPath();\n\tctx.arc(-4, -22, 2, 0, Math.PI * 2);\n\tctx.arc(4, -22, 2, 0, Math.PI * 2);\n\tctx.fill();\n\n\t// Smile\n\tctx.strokeStyle = '#e74c6f';\n\tctx.lineWidth = 1.5;\n\tctx.beginPath();\n\tctx.arc(0, -19, 4, 0.2, Math.PI - 0.2);\n\tctx.stroke();\n\n\t// Arms\n\tctx.strokeStyle = '#fdd9b5';\n\tctx.lineWidth = 4;\n\tctx.lineCap = 'round';\n\n\tconst armWave = Math.sin(Date.now() / 150) * 0.3;\n\t// Left arm\n\tctx.beginPath();\n\tctx.moveTo(-10, -8);\n\tctx.lineTo(-22, -15 + Math.sin(armWave) * 5);\n\tctx.stroke();\n\t// Right arm\n\tctx.beginPath();\n\tctx.moveTo(10, -8);\n\tctx.lineTo(22, -15 + Math.cos(armWave) * 5);\n\tctx.stroke();\n\n\t// Legs\n\tctx.strokeStyle = '#fdd9b5';\n\tctx.lineWidth = 4;\n\tconst legAngle = jessica.onGround ? 0 : Math.sin(Date.now() / 100) * 0.4;\n\t// Left leg\n\tctx.beginPath();\n\tctx.moveTo(-6, 14);\n\tctx.lineTo(-10 - Math.sin(legAngle) * 5, 30);\n\tctx.stroke();\n\t// Right leg\n\tctx.beginPath();\n\tctx.moveTo(6, 14);\n\tctx.lineTo(10 + Math.sin(legAngle) * 5, 30);\n\tctx.stroke();\n\n\t// Sparkle effect when flipping\n\tif (flipping) {\n\t\tctx.globalAlpha = 0.6;\n\t\tfor (let i = 0; i < 3; i++) {\n\t\t\tconst angle = (Date.now() / 50 + i * 2.1);\n\t\t\tconst sx = Math.cos(angle) * 25;\n\t\t\tconst sy = Math.sin(angle) * 25;\n\t\t\tctx.fillStyle = i % 2 === 0 ? '#fbbf24' : '#ff2d78';\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(sx, sy, 3, 0, Math.PI * 2);\n\t\t\tctx.fill();\n\t\t}\n\t\tctx.globalAlpha = 1;\n\t}\n\n\tctx.restore();\n}\n\nfunction draw() {\n\tctx.clearRect(0, 0, W, H);\n\n\tctx.save();\n\tctx.translate(0, -cameraY);\n\n\t// Draw trail\n\tfor (let i = 0; i < jessica.trail.length; i++) {\n\t\tconst t = jessica.trail[i];\n\t\tconst alpha = (1 - t.age / 15) * 0.3;\n\t\tif (alpha <= 0) continue;\n\t\tctx.globalAlpha = alpha;\n\t\tctx.fillStyle = '#ff2d78';\n\t\tctx.beginPath();\n\t\tctx.arc(t.x, t.y, 6 - (t.age / 15) * 4, 0, Math.PI * 2);\n\t\tctx.fill();\n\t}\n\tctx.globalAlpha = 1;\n\n\t// Draw platforms\n\tfor (const p of platforms) {\n\t\tctx.save();\n\n\t\tif (p.type === 'ground') {\n\t\t\t// Ground\n\t\t\tconst gGrad = ctx.createLinearGradient(0, p.y, 0, p.y + p.h);\n\t\t\tgGrad.addColorStop(0, '#a855f7');\n\t\t\tgGrad.addColorStop(1, '#7c3aed');\n\t\t\tctx.fillStyle = gGrad;\n\t\t\tctx.fillRect(p.x, p.y, p.w, p.h + 200);\n\n\t\t\t// Mat pattern\n\t\t\tctx.fillStyle = 'rgba(255,255,255,0.05)';\n\t\t\tfor (let i = 0; i < p.w; i += 40) {\n\t\t\t\tctx.fillRect(p.x + i, p.y, 20, p.h);\n\t\t\t}\n\t\t} else {\n\t\t\t// Platform shadow\n\t\t\tctx.fillStyle = 'rgba(0,0,0,0.2)';\n\t\t\troundRect(ctx, p.x + 2, p.y + 3, p.w, p.h, 7);\n\t\t\tctx.fill();\n\n\t\t\t// Platform body\n\t\t\tconst pGrad = ctx.createLinearGradient(p.x, p.y, p.x, p.y + p.h);\n\t\t\tpGrad.addColorStop(0, p.color);\n\t\t\tpGrad.addColorStop(1, shadeColor(p.color, -30));\n\t\t\tctx.fillStyle = pGrad;\n\t\t\troundRect(ctx, p.x, p.y, p.w, p.h, 7);\n\t\t\tctx.fill();\n\n\t\t\t// Shine\n\t\t\tctx.fillStyle = 'rgba(255,255,255,0.25)';\n\t\t\troundRect(ctx, p.x + 3, p.y + 2, p.w - 6, p.h / 2 - 1, 4);\n\t\t\tctx.fill();\n\n\t\t\t// Bouncy indicator\n\t\t\tif (p.type === 'bouncy') {\n\t\t\t\tctx.fillStyle = 'rgba(255,255,255,0.5)';\n\t\t\t\tconst bounce = Math.sin(Date.now() / 200) * 2;\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(p.x + p.w / 2 - 8, p.y - 4 + bounce);\n\t\t\t\tctx.lineTo(p.x + p.w / 2, p.y - 10 + bounce);\n\t\t\t\tctx.lineTo(p.x + p.w / 2 + 8, p.y - 4 + bounce);\n\t\t\t\tctx.fill();\n\t\t\t}\n\n\t\t\t// Moving indicator\n\t\t\tif (p.type === 'moving') {\n\t\t\t\tctx.fillStyle = 'rgba(255,255,255,0.4)';\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.arc(p.x + 8, p.y + p.h / 2, 2, 0, Math.PI * 2);\n\t\t\t\tctx.arc(p.x + p.w - 8, p.y + p.h / 2, 2, 0, Math.PI * 2);\n\t\t\t\tctx.fill();\n\t\t\t}\n\t\t}\n\n\t\tctx.restore();\n\t}\n\n\t// Draw stars\n\tfor (const s of stars) {\n\t\tif (s.collected) continue;\n\t\tconst bob = Math.sin(Date.now() / 300 + s.bobOffset) * 4;\n\t\tctx.save();\n\t\tctx.translate(s.x, s.y + bob);\n\t\tctx.rotate(Date.now() / 500);\n\n\t\t// Glow\n\t\tctx.shadowColor = '#fbbf24';\n\t\tctx.shadowBlur = 15;\n\n\t\tctx.fillStyle = '#fbbf24';\n\t\tdrawStar(ctx, 0, 0, 5, 10, 5);\n\t\tctx.fill();\n\n\t\tctx.shadowBlur = 0;\n\t\tctx.restore();\n\t}\n\n\t// Draw Jessica\n\tdrawJessica();\n\n\tctx.restore();\n}\n\nfunction drawStar(ctx, cx, cy, spikes, outerR, innerR) {\n\tlet rot = Math.PI / 2 * 3;\n\tlet x = cx;\n\tlet y = cy;\n\tconst step = Math.PI / spikes;\n\n\tctx.beginPath();\n\tctx.moveTo(cx, cy - outerR);\n\tfor (let i = 0; i < spikes; i++) {\n\t\tx = cx + Math.cos(rot) * outerR;\n\t\ty = cy + Math.sin(rot) * outerR;\n\t\tctx.lineTo(x, y);\n\t\trot += step;\n\t\tx = cx + Math.cos(rot) * innerR;\n\t\ty = cy + Math.sin(rot) * innerR;\n\t\tctx.lineTo(x, y);\n\t\trot += step;\n\t}\n\tctx.lineTo(cx, cy - outerR);\n\tctx.closePath();\n}\n\nfunction roundRect(ctx, x, y, w, h, r) {\n\tctx.beginPath();\n\tctx.moveTo(x + r, y);\n\tctx.lineTo(x + w - r, y);\n\tctx.quadraticCurveTo(x + w, y, x + w, y + r);\n\tctx.lineTo(x + w, y + h - r);\n\tctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\n\tctx.lineTo(x + r, y + h);\n\tctx.quadraticCurveTo(x, y + h, x, y + h - r);\n\tctx.lineTo(x, y + r);\n\tctx.quadraticCurveTo(x, y, x + r, y);\n\tctx.closePath();\n}\n\nfunction shadeColor(color, percent) {\n\tlet R = parseInt(color.substring(1, 3), 16);\n\tlet G = parseInt(color.substring(3, 5), 16);\n\tlet B = parseInt(color.substring(5, 7), 16);\n\tR = Math.min(255, Math.max(0, R + percent));\n\tG = Math.min(255, Math.max(0, G + percent));\n\tB = Math.min(255, Math.max(0, B + percent));\n\treturn '#' + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1);\n}\n\nfunction gameOver() {\n\tstate = STATE.OVER;\n\tsfxGameOver();\n\n\tif (score > bestScore) {\n\t\tbestScore = score;\n\t\tlocalStorage.setItem('jessicaBest', bestScore);\n\t}\n\n\tdocument.getElementById('finalScore').textContent = score;\n\tdocument.getElementById('bestDisplay').textContent = bestScore;\n\n\t// Stars rating\n\tlet starCount = 1;\n\tif (score >= 500) starCount = 2;\n\tif (score >= 1500) starCount = 3;\n\tdocument.getElementById('overStars').textContent = '★'.repeat(starCount) + '☆'.repeat(3 - starCount);\n\n\t// Message\n\tconst messages = [{\n\t\t\tmin: 0,\n\t\t\tmsg: 'Keep practicing! 💪'\n\t\t},\n\t\t{\n\t\t\tmin: 200,\n\t\t\tmsg: 'Nice moves, Jessica!'\n\t\t},\n\t\t{\n\t\t\tmin: 500,\n\t\t\tmsg: 'Great routine!'\n\t\t},\n\t\t{\n\t\t\tmin: 1000,\n\t\t\tmsg: 'Incredible performance!'\n\t\t},\n\t\t{\n\t\t\tmin: 2000,\n\t\t\tmsg: 'Olympic champion! 🥇'\n\t\t},\n\t\t{\n\t\t\tmin: 5000,\n\t\t\tmsg: 'LEGENDARY! 🏆'\n\t\t}\n\t];\n\tlet msg = messages[0].msg;\n\tfor (const m of messages) {\n\t\tif (score >= m.min) msg = m.msg;\n\t}\n\tdocument.getElementById('overMsg').textContent = msg;\n\n\tdocument.getElementById('gameOver').classList.add('visible');\n\tdocument.getElementById('mobileControls').classList.remove('visible');\n}\n\nfunction loop(time) {\n\tconst dt = Math.min(time - lastTime, 32);\n\tlastTime = time;\n\n\tupdate(dt);\n\tdraw();\n\n\trequestAnimationFrame(loop);\n}\n\n// ===== CONTROLS =====\nwindow.addEventListener('keydown', e => {\n\tkeys[e.code] = true;\n\tif (e.code === 'Space') {\n\t\te.preventDefault();\n\t\tif (state === STATE.PLAYING && !jessica.onGround) {\n\t\t\tdoFlip = true;\n\t\t}\n\t}\n\tif (e.code === 'ShiftLeft' || e.code === 'ShiftRight') {\n\t\te.preventDefault();\n\t\tactivateSuperJump();\n\t}\n});\n\nwindow.addEventListener('keyup', e => {\n\tkeys[e.code] = false;\n});\n\n// Mobile buttons\nconst btnLeft = document.getElementById('btnLeft');\nconst btnRight = document.getElementById('btnRight');\nconst btnFlip = document.getElementById('btnFlip');\nconst btnSuperJump = document.getElementById('btnSuperJump');\n\nfunction activateSuperJump() {\n\tif (!superJumpReady || state !== STATE.PLAYING) return;\n\tsuperJumpActive = true;\n\tsuperJumpReady = false;\n\tsuperJumpCooldown = SUPER_JUMP_COOLDOWN;\n\tbtnSuperJump.classList.add('cooldown');\n\tsfxSuperJump();\n\tspawnParticles(jessica.x, jessica.y, '#06b6d4', 8);\n}\n\nbtnSuperJump.addEventListener('touchstart', e => {\n\te.preventDefault();\n\tactivateSuperJump();\n});\nbtnSuperJump.addEventListener('mousedown', () => activateSuperJump());\n\nbtnLeft.addEventListener('touchstart', e => {\n\te.preventDefault();\n\tmoveLeft = true;\n});\nbtnLeft.addEventListener('touchend', e => {\n\te.preventDefault();\n\tmoveLeft = false;\n});\nbtnRight.addEventListener('touchstart', e => {\n\te.preventDefault();\n\tmoveRight = true;\n});\nbtnRight.addEventListener('touchend', e => {\n\te.preventDefault();\n\tmoveRight = false;\n});\nbtnFlip.addEventListener('touchstart', e => {\n\te.preventDefault();\n\tif (state === STATE.PLAYING && !jessica.onGround) doFlip = true;\n});\n\n// Also mouse for testing\nbtnLeft.addEventListener('mousedown', () => moveLeft = true);\nbtnLeft.addEventListener('mouseup', () => moveLeft = false);\nbtnLeft.addEventListener('mouseleave', () => moveLeft = false);\nbtnRight.addEventListener('mousedown', () => moveRight = true);\nbtnRight.addEventListener('mouseup', () => moveRight = false);\nbtnRight.addEventListener('mouseleave', () => moveRight = false);\nbtnFlip.addEventListener('mousedown', () => {\n\tif (state === STATE.PLAYING && !jessica.onGround) doFlip = true;\n});\n\n// Touch swipe on canvas\nlet touchStartX = 0;\nlet touchStartY = 0;\ncanvas.addEventListener('touchstart', e => {\n\tconst t = e.touches[0];\n\ttouchStartX = t.clientX;\n\ttouchStartY = t.clientY;\n});\n\ncanvas.addEventListener('touchend', e => {\n\t// Quick tap = flip\n\tif (state === STATE.PLAYING && !jessica.onGround) {\n\t\tdoFlip = true;\n\t}\n});\n\n// ===== START / RETRY =====\ndocument.getElementById('startBtn').addEventListener('click', () => {\n\tensureAudio();\n\tstartGame();\n});\n\ndocument.getElementById('retryBtn').addEventListener('click', () => {\n\tensureAudio();\n\tdocument.getElementById('gameOver').classList.remove('visible');\n\tstartGame();\n});\n\nfunction startGame() {\n\tstate = STATE.PLAYING;\n\tinitGame();\n\tdocument.getElementById('titleScreen').classList.add('hidden');\n\tdocument.getElementById('hud').classList.add('visible');\n\tdocument.getElementById('mobileControls').classList.add('visible');\n\n\t// Play start jingle\n\tconst notes = [523, 659, 784];\n\tnotes.forEach((n, i) => {\n\t\tsetTimeout(() => playTone(n, 0.2, 'sine', 0.1), i * 100);\n\t});\n}\n\n// Init Lucide icons\nif (typeof lucide !== 'undefined') lucide.createIcons();\n\n// Start loop\nrequestAnimationFrame(loop);"},{"name":"style.css","content":"@import url('https://fonts.googleapis.com/css2?family=Lilita+One&family=Quicksand:wght@500;700&display=swap');\n\n:root {\n\tcolor-scheme: light;\n\t--pink-hot: #ff2d78;\n\t--pink-light: #ffb3d0;\n\t--purple-deep: #6b21a8;\n\t--purple-mid: #a855f7;\n\t--purple-light: #e9d5ff;\n\t--gold: #fbbf24;\n\t--gold-dark: #d97706;\n\t--cyan: #06b6d4;\n\t--white: #ffffff;\n\t--cream: #fef7f0;\n\t--floor: #2d1b4e;\n\tfont-family: 'Quicksand', sans-serif;\n}\n\n* {\n\tbox-sizing: border-box;\n\tmargin: 0;\n\tpadding: 0;\n}\n\nhtml, body {\n\theight: 100%;\n\toverflow: hidden;\n\ttouch-action: none;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.game {\n\tposition: relative;\n\twidth: 100vw;\n\theight: 100vh;\n\toverflow: hidden;\n\tbackground: linear-gradient(180deg, #1e0533 0%, #3b0764 40%, #581c87 70%, #7c3aed 100%);\n}\n\n.game__bg {\n\tposition: absolute;\n\tinset: 0;\n\tpointer-events: none;\n\toverflow: hidden;\n}\n\n.game__bg-stripe {\n\tposition: absolute;\n\tborder-radius: 50%;\n\topacity: 0.08;\n\tfilter: blur(60px);\n}\n\n.game__bg-stripe--1 {\n\twidth: 600px;\n\theight: 600px;\n\tbackground: var(--pink-hot);\n\ttop: -200px;\n\tright: -100px;\n}\n\n.game__bg-stripe--2 {\n\twidth: 500px;\n\theight: 500px;\n\tbackground: var(--cyan);\n\tbottom: -150px;\n\tleft: -100px;\n}\n\n.game__bg-stripe--3 {\n\twidth: 400px;\n\theight: 400px;\n\tbackground: var(--gold);\n\ttop: 40%;\n\tleft: 30%;\n}\n\n/* Title Screen */\n.game__title-screen {\n\tposition: absolute;\n\tinset: 0;\n\tz-index: 20;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 30px;\n\tbackground: linear-gradient(180deg, #1e0533ee 0%, #3b0764ee 50%, #581c87ee 100%);\n\tbackdrop-filter: blur(10px);\n\ttransition: opacity 0.5s, visibility 0.5s;\n}\n\n.game__title-screen.hidden {\n\topacity: 0;\n\tvisibility: hidden;\n\tpointer-events: none;\n}\n\n.game__logo {\n\ttext-align: center;\n\tposition: relative;\n}\n\n.game__logo-star {\n\tfont-size: 48px;\n\tcolor: var(--gold);\n\ttext-shadow: 0 0 30px rgba(251, 191, 36, 0.6);\n\tanimation: starPulse 2s ease-in-out infinite;\n}\n\n@keyframes starPulse {\n\t0%, 100% {\n\t\ttransform: scale(1) rotate(0deg);\n\t}\n\n\t50% {\n\t\ttransform: scale(1.15) rotate(10deg);\n\t}\n}\n\n.game__title {\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: clamp(42px, 10vw, 72px);\n\tcolor: var(--white);\n\tline-height: 1;\n\ttext-shadow:\n\t\t3px 3px 0 var(--pink-hot),\n\t\t6px 6px 0 rgba(255, 45, 120, 0.3);\n\tletter-spacing: -1px;\n}\n\n.game__subtitle {\n\tfont-size: clamp(14px, 3vw, 20px);\n\tcolor: var(--pink-light);\n\tfont-weight: 700;\n\tmargin-top: 8px;\n\tletter-spacing: 2px;\n\ttext-transform: uppercase;\n}\n\n.game__btn {\n\tborder: none;\n\tcursor: pointer;\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: 22px;\n\tletter-spacing: 1px;\n\tborder-radius: 50px;\n\tpadding: 16px 48px;\n\ttransition: transform 0.15s, box-shadow 0.15s;\n\tposition: relative;\n\toverflow: hidden;\n}\n\n.game__btn:active {\n\ttransform: scale(0.95);\n}\n\n.game__btn--start, .game__btn--retry {\n\tbackground: linear-gradient(135deg, var(--pink-hot), #ff6ba6);\n\tcolor: var(--white);\n\tbox-shadow:\n\t\t0 4px 20px rgba(255, 45, 120, 0.5),\n\t\t0 0 0 3px rgba(255, 255, 255, 0.15),\n\t\tinset 0 1px 0 rgba(255, 255, 255, 0.3);\n}\n\n.game__btn--start:hover, .game__btn--retry:hover {\n\ttransform: translateY(-2px);\n\tbox-shadow:\n\t\t0 8px 30px rgba(255, 45, 120, 0.6),\n\t\t0 0 0 3px rgba(255, 255, 255, 0.2),\n\t\tinset 0 1px 0 rgba(255, 255, 255, 0.3);\n}\n\n.game__instructions {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\ttext-align: center;\n}\n\n.game__instruction {\n\tcolor: var(--purple-light);\n\tfont-size: 14px;\n\tfont-weight: 700;\n}\n\n.game__instruction kbd {\n\tdisplay: inline-block;\n\tbackground: rgba(255, 255, 255, 0.12);\n\tborder: 1px solid rgba(255, 255, 255, 0.2);\n\tborder-radius: 6px;\n\tpadding: 2px 8px;\n\tfont-family: 'Quicksand', sans-serif;\n\tfont-size: 13px;\n\tmargin: 0 2px;\n}\n\n/* HUD */\n.game__hud {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tz-index: 10;\n\tdisplay: flex;\n\tjustify-content: space-around;\n\tpadding: 12px 16px;\n\tbackground: linear-gradient(180deg, rgba(30, 5, 51, 0.8) 0%, transparent 100%);\n\topacity: 0;\n\ttransition: opacity 0.4s;\n}\n\n.game__hud.visible {\n\topacity: 1;\n}\n\n.game__hud-item {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tgap: 2px;\n}\n\n.game__hud-label {\n\tfont-size: 11px;\n\ttext-transform: uppercase;\n\tletter-spacing: 2px;\n\tcolor: var(--pink-light);\n\tfont-weight: 700;\n}\n\n.game__hud-value {\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: 28px;\n\tcolor: var(--white);\n\ttext-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);\n}\n\n.game__hud-value--combo {\n\tcolor: var(--gold);\n\ttransition: transform 0.2s;\n}\n\n.game__hud-value--combo.bump {\n\tanimation: comboBump 0.3s ease;\n}\n\n@keyframes comboBump {\n\t0% {\n\t\ttransform: scale(1);\n\t}\n\n\t50% {\n\t\ttransform: scale(1.4);\n\t}\n\n\t100% {\n\t\ttransform: scale(1);\n\t}\n}\n\n/* Canvas */\n#gameCanvas {\n\tposition: absolute;\n\tinset: 0;\n\twidth: 100%;\n\theight: 100%;\n\tz-index: 5;\n}\n\n/* Mobile Controls */\n.game__controls {\n\tposition: absolute;\n\tbottom: 20px;\n\tleft: 0;\n\tright: 0;\n\tz-index: 15;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tgap: 16px;\n\tpadding: 0 20px;\n\topacity: 0;\n\ttransition: opacity 0.4s;\n\tpointer-events: none;\n}\n\n.game__controls.visible {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n.game__ctrl {\n\tborder: none;\n\tcursor: pointer;\n\tborder-radius: 50%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\ttransition: transform 0.1s;\n\t-webkit-tap-highlight-color: transparent;\n}\n\n.game__ctrl:active {\n\ttransform: scale(0.9);\n}\n\n.game__ctrl--left, .game__ctrl--right {\n\twidth: 64px;\n\theight: 64px;\n\tbackground: rgba(255, 255, 255, 0.12);\n\tborder: 2px solid rgba(255, 255, 255, 0.25);\n\tcolor: var(--white);\n\tbackdrop-filter: blur(8px);\n}\n\n.game__ctrl--jump {\n\twidth: 72px;\n\theight: 72px;\n\tbackground: linear-gradient(135deg, #06b6d4, #0891b2);\n\tcolor: var(--white);\n\tflex-direction: column;\n\tgap: 2px;\n\tbox-shadow: 0 4px 25px rgba(6, 182, 212, 0.5);\n\tborder: 2px solid rgba(255, 255, 255, 0.3);\n\ttransition: transform 0.1s, opacity 0.3s, box-shadow 0.3s;\n}\n\n.game__ctrl--jump span {\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: 10px;\n\tletter-spacing: 1px;\n}\n\n.game__ctrl--jump.cooldown {\n\topacity: 0.4;\n\tbox-shadow: 0 2px 10px rgba(6, 182, 212, 0.2);\n\tpointer-events: none;\n}\n\n.game__ctrl--jump svg {\n\twidth: 22px;\n\theight: 22px;\n}\n\n.game__ctrl--flip {\n\twidth: 88px;\n\theight: 88px;\n\tbackground: linear-gradient(135deg, var(--pink-hot), var(--purple-mid));\n\tcolor: var(--white);\n\tflex-direction: column;\n\tgap: 2px;\n\tbox-shadow: 0 4px 25px rgba(255, 45, 120, 0.5);\n\tborder: 2px solid rgba(255, 255, 255, 0.3);\n}\n\n.game__ctrl--flip span {\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: 11px;\n\tletter-spacing: 1px;\n}\n\n.game__ctrl svg {\n\twidth: 28px;\n\theight: 28px;\n}\n\n.game__ctrl--flip svg {\n\twidth: 24px;\n\theight: 24px;\n}\n\n/* Game Over */\n.game__over {\n\tposition: absolute;\n\tinset: 0;\n\tz-index: 25;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: rgba(30, 5, 51, 0.85);\n\tbackdrop-filter: blur(12px);\n\topacity: 0;\n\tvisibility: hidden;\n\tpointer-events: none;\n\ttransition: opacity 0.5s, visibility 0.5s;\n}\n\n.game__over.visible {\n\topacity: 1;\n\tvisibility: visible;\n\tpointer-events: auto;\n}\n\n.game__over-card {\n\tbackground: linear-gradient(160deg, #2d1b4e, #1e0533);\n\tborder: 2px solid rgba(168, 85, 247, 0.3);\n\tborder-radius: 24px;\n\tpadding: 40px;\n\ttext-align: center;\n\tmax-width: 340px;\n\twidth: 90%;\n\tbox-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);\n}\n\n.game__over-stars {\n\tfont-size: 40px;\n\tcolor: var(--gold);\n\ttext-shadow: 0 0 20px rgba(251, 191, 36, 0.5);\n\tmargin-bottom: 12px;\n}\n\n.game__over-title {\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: 28px;\n\tcolor: var(--white);\n\tmargin-bottom: 20px;\n}\n\n.game__over-score {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmargin-bottom: 16px;\n}\n\n.game__over-score span {\n\tfont-size: 13px;\n\tcolor: var(--pink-light);\n\ttext-transform: uppercase;\n\tletter-spacing: 2px;\n\tfont-weight: 700;\n}\n\n.game__over-score strong {\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: 52px;\n\tcolor: var(--gold);\n\ttext-shadow: 0 2px 20px rgba(251, 191, 36, 0.4);\n}\n\n.game__over-msg {\n\tcolor: var(--purple-light);\n\tfont-size: 15px;\n\tfont-weight: 700;\n\tmargin-bottom: 24px;\n}\n\n/* Particles */\n.game__particles {\n\tposition: absolute;\n\tinset: 0;\n\tz-index: 12;\n\tpointer-events: none;\n\toverflow: hidden;\n}\n\n.game__particle {\n\tposition: absolute;\n\tborder-radius: 50%;\n\tpointer-events: none;\n\tanimation: particleFly 0.8s ease-out forwards;\n}\n\n@keyframes particleFly {\n\t0% {\n\t\topacity: 1;\n\t\ttransform: translate(0, 0) scale(1);\n\t}\n\n\t100% {\n\t\topacity: 0;\n\t\ttransform: translate(var(--tx), var(--ty)) scale(0);\n\t}\n}\n\n.game__float-text {\n\tposition: absolute;\n\tz-index: 13;\n\tpointer-events: none;\n\tfont-family: 'Lilita One', cursive;\n\tfont-size: 24px;\n\tcolor: var(--gold);\n\ttext-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);\n\tanimation: floatUp 1s ease-out forwards;\n}\n\n@keyframes floatUp {\n\t0% {\n\t\topacity: 1;\n\t\ttransform: translateY(0) scale(1);\n\t}\n\n\t100% {\n\t\topacity: 0;\n\t\ttransform: translateY(-80px) scale(1.3);\n\t}\n}\n\n@media (min-width: 768px) {\n\t.game__controls {\n\t\tdisplay: none !important;\n\t}\n}\n\n@media (max-width: 767px) {\n\t.game__instruction kbd {\n\t\tdisplay: none;\n\t}\n\n\t.game__instructions {\n\t\tgap: 6px;\n\t}\n\n\t.game__instruction:nth-child(1)::before {\n\t\tcontent: 'Swipe or buttons to move';\n\t}\n\n\t.game__instruction:nth-child(1) {\n\t\tfont-size: 0;\n\t}\n\n\t.game__instruction:nth-child(1)::before {\n\t\tfont-size: 14px;\n\t}\n}"}],"folders":[]},"variants":null,"createdAt":"2026-02-28T13:50:23.140Z","updatedAt":"2026-03-02T00:31:00.473Z"}}