{"asset_map": {"chess_king_white": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_king_white_5631a368-b805-4df3-b2a5-c52719b0b7d9.webp", "type": "image", "prompt": "Generate a full-body, front-view premium 3D chess king piece in classical Staunton design. Material: ivory marble with realistic texture and warm gold accents on the ornate 4-point crown and base. 3D isometric perspective (45 degree angle), soft directional lighting from top-right, subtle rim lighting, high-resolution game-ready asset, transparent background.", "description": "Premium 3D white king piece in ivory marble and gold, isometric view", "subtype": "character", "aspect_ratio": [547, 1312], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "chess_queen_white": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_queen_white_1791f5f6-3b2c-4a9a-bdea-036ab786a283.webp", "type": "image", "prompt": "Generate a full-body, front-view premium 3D chess queen piece. Match the ivory marble and warm gold material of chess_king_white. Features an ornate crown with 5 spherical points. 3D isometric perspective (45 degree angle), consistent lighting with king, polished finish, transparent background.", "description": "Premium 3D white queen piece in ivory marble and gold, isometric view", "subtype": "character", "aspect_ratio": [483, 1214], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "chess_rook_white": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_rook_white_6487e211-3ecd-4ae2-87b5-60b40704b724.webp", "type": "image", "prompt": "Generate a 3D chess rook piece, castle tower design with 4 battlements. Match the ivory marble and warm gold accents of chess_king_white. 3D isometric perspective (45 degree angle), polished finish, realistic shadows, transparent background.", "description": "Premium 3D white rook piece in ivory marble and gold, isometric view", "subtype": "character", "aspect_ratio": [523, 1128], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "chess_bishop_white": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_bishop_white_d16905f8-158d-4f46-b041-f24cc4c3740c.webp", "type": "image", "prompt": "Generate a 3D chess bishop piece with a pointed mitre and diagonal cut. Match the ivory marble and warm gold materials of chess_king_white. 3D isometric perspective (45 degree angle), polished finish, transparent background.", "description": "Premium 3D white bishop piece in ivory marble and gold, isometric view", "subtype": "character", "aspect_ratio": [481, 1178], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "chess_knight_white": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_knight_white_e05194e2-e394-45a7-815e-03a35f51709b.webp", "type": "image", "prompt": "Generate a highly detailed 3D chess knight piece featuring a noble horse head facing left. Match the ivory marble and warm gold accents of chess_king_white on the mane and bridle. 3D isometric perspective (45 degree angle), professional lighting, transparent background.", "description": "Premium 3D white knight piece (horse) in ivory marble and gold, isometric view", "subtype": "character", "aspect_ratio": [532, 1098], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "chess_pawn_white": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_pawn_white_40f41fd3-d837-434a-86a7-19cd6e2e6400.webp", "type": "image", "prompt": "Generate a 3D chess pawn piece with a spherical head. Match the ivory marble and gold band of chess_king_white. 3D isometric perspective (45 degree angle), simple and elegant, transparent background.", "description": "Premium 3D white pawn piece in ivory marble and gold, isometric view", "subtype": "character", "aspect_ratio": [522, 1174], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "chess_king_black": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_king_black_39dd4f1c-9219-4810-8595-dd44c8aed332.webp", "type": "image", "prompt": "Generate a 3D chess king piece identical in shape to chess_king_white but using deep obsidian black material with cool silver/platinum accents. 3D isometric perspective, polished finish, subtle rim lighting to define dark surfaces, transparent background.", "description": "Premium 3D black king piece in obsidian and silver, isometric view", "subtype": "character", "aspect_ratio": [484, 1237], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "chess_queen_black": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_queen_black_e9bb441f-3e48-4e75-b2d6-3739c1a7bc4a.webp", "type": "image", "prompt": "Generate a 3D chess queen piece identical in shape to chess_queen_white but using deep obsidian black material and silver accents matching chess_king_black. 3D isometric perspective, transparent background.", "description": "Premium 3D black queen piece in obsidian and silver, isometric view", "subtype": "character", "aspect_ratio": [488, 1246], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "chess_rook_black": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_rook_black_5ffba0d4-efbb-4d5f-af94-ff3af74821fa.webp", "type": "image", "prompt": "Generate a 3D chess rook piece identical in shape to chess_rook_white but using deep obsidian black and silver accents. 3D isometric perspective, transparent background.", "description": "Premium 3D black rook piece in obsidian and silver, isometric view", "subtype": "character", "aspect_ratio": [579, 1247], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "chess_bishop_black": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_bishop_black_226a2179-10d8-4730-802c-a1eeaa0a2543.webp", "type": "image", "prompt": "Generate a 3D chess bishop piece identical in shape to chess_bishop_white but using deep obsidian black and silver accents. 3D isometric perspective, transparent background.", "description": "Premium 3D black bishop piece in obsidian and silver, isometric view", "subtype": "character", "aspect_ratio": [510, 1246], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "chess_knight_black": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_knight_black_ad055e5c-1867-4d9e-8bfb-c4d1ff664ac6.webp", "type": "image", "prompt": "Generate a 3D chess knight piece identical in shape to chess_knight_white but using deep obsidian black and silver accents. 3D isometric perspective, extra rim lighting on mane details, transparent background.", "description": "Premium 3D black knight piece in obsidian and silver, isometric view", "subtype": "character", "aspect_ratio": [602, 1236], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "chess_pawn_black": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/chess_pawn_black_42e97471-5e3d-4709-86dc-43c145fe613c.webp", "type": "image", "prompt": "Generate a 3D chess pawn piece identical in shape to chess_pawn_white but using deep obsidian black and silver accents. 3D isometric perspective, transparent background.", "description": "Premium 3D black pawn piece in obsidian and silver, isometric view", "subtype": "character", "aspect_ratio": [556, 1248], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "board_light_square": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/board_light_square_60a5d90d-2e39-4eb8-8bc1-5e3d303721d0.webp", "type": "image", "prompt": "Generate a fully tileable texture for a light chess board square. Cream white polished marble or wood with subtle veining, smooth finish, soft reflections, neutral lighting, no shadows, 512x512 seamless texture.", "description": "Tileable texture for the light squares of the chess board", "subtype": "ground", "aspect_ratio": [1024, 1024], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "board_dark_square": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/board_dark_square_4222aff4-d8e9-47ef-a45d-159ba0eeb9f9.webp", "type": "image", "prompt": "Generate a fully tileable texture for a dark chess board square. Rich mahogany brown polished wood or marble with subtle grain matching the style of board_light_square. 512x512 seamless texture, neutral lighting.", "description": "Tileable texture for the dark squares of the chess board", "subtype": "ground", "aspect_ratio": [1024, 1024], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "background_sky_kingdom": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/background_sky_kingdom_bbc3d67f-7a33-43ba-bd80-fdd7513008c7.webp", "type": "image", "prompt": "Generate a wide 16:9 landscape image of a Vast sky vista with layered fluffy volumetric clouds. Gradient from light blue at horizon to deeper blue at top. Distant silhouetted floating islands. Soft warm sunlight from upper right with subtle god rays. Dreamy, peaceful, and atmospheric.", "description": "A wide, dreamy floating sky kingdom background with clouds and islands", "subtype": "background", "aspect_ratio": [1536, 1024], "compression_suggestion": "original", "duration_secs": null, "loop": null, "animation": null}, "cloud_platform_base": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/cloud_platform_base_fff6de2c-7b4f-44bf-b1ce-0944d41dbfc7.webp", "type": "image", "prompt": "Generate a large, solid fluffy cloud formation with a flat top surface. Decorative golden ornate railings around the edges with fantasy design. 3D isometric perspective matching a chess board view. Soft sunlight, subtle magical glow, transparent background.", "description": "Magical cloud platform with golden railings to support the chess board", "subtype": "other", "aspect_ratio": [1130, 792], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "power_square_extra_move": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/power_square_extra_move_af357cee-01bf-4d47-9a1e-f9651b4d08e1.webp", "type": "image", "prompt": "Generate a radiant golden glow square overlay for a chess board. Pulsing magical energy, warm golden rays (#FFD700), sparkle particles, soft edges, transparent background, top-down square view.", "description": "Golden glowing square effect for Extra Move power-up", "subtype": "effect", "aspect_ratio": [755, 794], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "power_square_shield": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/power_square_shield_47c2f2ab-0726-4913-b74d-34af6d668f62.webp", "type": "image", "prompt": "Generate a protective blue glow square overlay for a chess board. Hexagonal force field energy pattern, royal blue (#4169E1), subtle sparkle particles, consistent style with power_square_extra_move, transparent background.", "description": "Blue shield glow square effect for protection power-up", "subtype": "effect", "aspect_ratio": [1024, 1024], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "power_square_knight_boost": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/power_square_knight_boost_faac7c62-4a76-4ae9-9c25-79e1095eaf2a.webp", "type": "image", "prompt": "Generate a mystic purple glow square overlay for a chess board. Swirling magical energy, medium purple (#9370DB), subtle sparkle particles, consistent style with other power squares, transparent background.", "description": "Purple mystic glow square effect for Knight Boost power-up", "subtype": "effect", "aspect_ratio": [811, 803], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "particle_sparkle": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/particle_sparkle_7deb00ed-9d01-4fa3-8fbb-037a93b63548.webp", "type": "image", "prompt": "Generate a small bright white star-shaped sparkle particle with a soft glowing halo. Multiple variants of small magical glints, transparent background, high resolution.", "description": "Small magical sparkle particle for visual effects", "subtype": "effect", "aspect_ratio": [1126, 790], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "ui_button_primary": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ui_button_primary_19c61e4c-9d61-40f7-8067-aefea243d89e.webp", "type": "image", "prompt": "Generate a premium UI button, rounded rectangle with a golden gradient (#FFD700). Subtle 3D raised effect, thin light gold border, polished metal look, clean edges, transparent background.", "description": "Premium golden rounded rectangle button for main actions", "subtype": "ui", "aspect_ratio": [960, 370], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ui_button_secondary": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ui_button_secondary_9969adc5-4979-4929-96f9-8a4b939c529c.webp", "type": "image", "prompt": "Generate a premium UI button, rounded rectangle with a silver gradient (#C0C0C0). Matches the shape and 3D style of ui_button_primary but in silver, transparent background.", "description": "Premium silver rounded rectangle button for secondary actions", "subtype": "ui", "aspect_ratio": [1248, 474], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ui_panel_background": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ui_panel_background_4e2c8be3-b45f-476e-ae32-84a91f691ba1.webp", "type": "image", "prompt": "Generate a semi-transparent dark blue-gray UI panel with rounded corners. Thin gold and silver border, frosted glass effect, 70% opacity, clean and minimalist fantasy style, transparent background.", "description": "Semi-transparent dark panel background for menus", "subtype": "ui", "aspect_ratio": [1216, 821], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "icon_settings": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_settings_a330281f-e190-4bc9-8095-0a589b38b7f3.webp", "type": "image", "prompt": "Generate a clean vector-style gear icon in polished gold. Minimalist silhouette, matching the gold of ui_button_primary, sharp edges, transparent background.", "description": "Gold gear icon for settings", "subtype": "ui", "aspect_ratio": [588, 596], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "icon_hint": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_hint_2e6b6458-a2d1-437f-88c7-c210f8b4bcaa.webp", "type": "image", "prompt": "Generate a clean vector-style lightbulb icon in polished gold. Slight inner glow, minimalist design, matching the style of icon_settings, transparent background.", "description": "Gold lightbulb icon for hints", "subtype": "ui", "aspect_ratio": [455, 737], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "icon_undo": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_undo_a79a8a6a-5b1a-49cc-8746-233b216683ed.webp", "type": "image", "prompt": "Generate a clean vector-style curved undo arrow icon in polished gold. Counter-clockwise direction, matching the style of icon_settings, transparent background.", "description": "Gold curved arrow icon for undo", "subtype": "ui", "aspect_ratio": [727, 810], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "icon_resign": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_resign_51c9cd49-4fcf-4d45-b496-178717de15a0.webp", "type": "image", "prompt": "Generate a clean vector-style white flag icon with silver/gray pole. Minimalist design, matching the silver of ui_button_secondary, transparent background.", "description": "Silver flag icon for resigning", "subtype": "ui", "aspect_ratio": [382, 612], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "sfx_piece_move": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_piece_move_5c42bd15-d845-4870-816b-0e45287d812e.mp3", "type": "audio", "prompt": "Elegant and premium sound effect of a marble chess piece sliding across a polished hardwood board. Smooth, non-harsh tactile texture with a soft attack and clean release. Mid-range frequencies, realistic material interaction, suitable for frequent repetition in a professional chess game.", "description": "A smooth, elegant sound of a chess piece sliding across a polished wooden board.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.79, "loop": false, "animation": null}, "sfx_piece_capture": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_piece_capture_e775c16b-5df5-4ad0-9f7f-7ae7bdce6ab7.mp3", "type": "audio", "prompt": "Satisfying impact sound effect of two stone or marble chess pieces colliding. Sharp attack with a brief resonance and clean decay. Mid-to-low frequencies conveying weight and tactical feedback without being violent or explosive. Premium quality collision.", "description": "An impactful collision sound when one chess piece captures another.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 0.9, "loop": false, "animation": null}, "sfx_check": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_check_c2a0f594-b63f-4285-b8fb-dd7c82c3cdb7.mp3", "type": "audio", "prompt": "Clear warning chime or bell tone for a strategic game state. Pure tone in the mid-to-high frequency range with a slight reverb tail for presence. Noticeable and memorable but musical and non-alarming. Distinctive warning signal for a high-quality board game.", "description": "A clear, attention-grabbing warning chime indicating the king is in check.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.51, "loop": false, "animation": null}, "sfx_checkmate": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_checkmate_8796e067-2ac0-4c13-bb6f-f8dadff0f23b.mp3", "type": "audio", "prompt": "Dramatic and conclusive orchestral chord for a game-ending victory. Strong attack, rich full sustain, and a long cinematic reverb tail. Conveys finality and triumph. Full frequency range with a premium, high-stakes feel.", "description": "A dramatic, cinematic sound signaling the final conclusion of the match.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.79, "loop": false, "animation": null}, "sfx_power_activate": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_power_activate_7315504f-0bdb-4927-b55c-2ee31177132e.mp3", "type": "audio", "prompt": "Magical fantasy whoosh sound effect with a sparkling shimmer. Positive, empowering, and mystical vibe. Mid-to-high frequency ethereal textures with a gentle release trail. Distinctive from physical chess sounds, conveying a magical ability activation.", "description": "A magical, shimmering sound for when a power square ability is triggered.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.98, "loop": false, "animation": null}, "sfx_ui_click": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_ui_click_dd852ae6-5653-48bf-9f08-86ebe9559989.mp3", "type": "audio", "prompt": "Subtle and satisfying digital UI click sound. Very short, clean attack, minimal sustain. Professional and polished feedback for menu buttons. High-quality, non-distracting, suitable for repeated menu navigation.", "description": "A soft, professional digital click for UI button interactions.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 2, "loop": false, "animation": null}, "sfx_ui_hover": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_ui_hover_29614ac6-fb97-41e5-9bb5-ecffb51f3287.mp3", "type": "audio", "prompt": "Extremely subtle and soft UI hover tone. High-mid frequency, very quiet and gentle feedback. Barely noticeable but present for professional interface polish. Minimalist digital sound for frequent use.", "description": "An extremely subtle, soft tone for hovering over UI elements.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.23, "loop": false, "animation": null}, "music_main_menu": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/music_main_menu_613c3c20-2c80-4ff3-8646-b725f47877be.mp3", "type": "audio", "prompt": "Elegant orchestral background music for a strategic game menu. Tempo 90 BPM. Features a contemplative violin and cello melody, rhythmic piano harmonic support, and subtle woodwinds. Mysterious, thoughtful, and premium cinematic quality. Seamlessly loopable, gradual build and release, 4/4 time signature.", "description": "Elegant and strategic orchestral theme for the main menu.", "subtype": "music", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 30, "loop": true, "animation": null}, "music_gameplay": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/music_gameplay_9504a7a3-ea34-48e8-a501-c60ff95fbcca.mp3", "type": "audio", "prompt": "Calm, focused ambient music for deep strategic thinking. Tempo 75 BPM. Soft minimalist piano as the lead, layered with gentle string pads and subtle harp accents. Non-distracting, peaceful, and contemplative. Smooth, flowing progression with no dramatic changes. Seamlessly loopable for long gameplay sessions.", "description": "Calm, classical-inspired ambient music to support deep focus during gameplay.", "subtype": "music", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 30, "loop": true, "animation": null}, "music_victory": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/music_victory_f471762e-51f4-49e6-bcdd-9e4f019722c2.mp3", "type": "audio", "prompt": "Triumphant and celebratory orchestral fanfare for a game victory. Tempo 120 BPM. Bright brass section (trumpets and horns), rich strings, and impactful timpani percussion. Uplifting, cinematic, and rewarding with a strong resolution. One-shot composition.", "description": "A triumphant orchestral fanfare for winning a chess match.", "subtype": "music", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 25.000249433106575, "loop": false, "animation": null}, "music_defeat": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/music_defeat_4fbb3ec0-13c9-4174-ad3e-bae54e5d6073.mp3", "type": "audio", "prompt": "Somber but respectful orchestral music for match defeat. Tempo 65 BPM. Deep cello and bass strings, soft reflective piano, and subtle woodwinds. Dignified and reflective rather than depressing. Hopeful resolution to encourage a retry. One-shot composition.", "description": "A somber, reflective orchestral piece for match conclusion.", "subtype": "music", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 25.000249433106575, "loop": false, "animation": null}, "sfx_piece_place_wooden": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sfx_piece_place_wooden_ba3f9914-3b37-4ad1-85d5-80f52392927a.mp3", "type": "audio", "prompt": "A single, short, crisp sound of a solid wooden chess piece being placed firmly on a polished wooden chessboard. The sound should feature a natural, resonant 'thud' with a slight high-frequency 'click' on impact. No sliding, no dragging, no metallic ringing. Clean recording with a very short decay, suitable for a professional and elegant board game interface.", "description": "A crisp, satisfying thud of a wooden chess piece landing firmly on a wooden board.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 0.8, "loop": false, "animation": null}}, "game_code": "<!DOCTYPE html>\n<html>\n<head>\n    <title>Chess Revolution</title>\n    <style>\n        @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;600;700&family=Inter:wght@400;500;600&display=swap');\n\n        /* CSS Reset */\n        *, *::before, *::after {\n            box-sizing: border-box;\n            margin: 0;\n            padding: 0;\n        }\n\n        body, html {\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            touch-action: none;\n            -ms-touch-action: none;\n            font-family: 'Inter', sans-serif;\n            background: #1a1a2e;\n        }\n\n        /* Custom Properties */\n        :root {\n            --transition-fast: 150ms;\n            --transition-normal: 300ms;\n            --transition-slow: 500ms;\n            --ease-out: cubic-bezier(0.0, 0, 0.2, 1);\n            --ease-bounce: cubic-bezier(0.68, -0.6, 0.32, 1.6);\n            --space-xs: 8px;\n            --space-sm: 16px;\n            --space-md: 24px;\n            --space-lg: 32px;\n            --space-xl: 48px;\n            --color-gold: #FFD700;\n            --color-silver: #C0C0C0;\n            --color-dark: rgba(0, 0, 0, 0.85);\n        }\n\n        /* Game World */\n        #game-world {\n            position: relative;\n            width: 100%;\n            height: 100%;\n            background: linear-gradient(180deg, #87CEEB 0%, #4A90E2 100%);\n        }\n\n        /* Background */\n        #background {\n            position: absolute;\n            width: 100%;\n            height: 100%;\n            object-fit: cover;\n            z-index: 0;\n        }\n\n        /* Game Canvas */\n        #game-canvas {\n            position: absolute;\n            top: 0;\n            left: 0;\n            z-index: 1;\n        }\n\n        /* UI Overlay */\n        .ui-overlay {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            pointer-events: none;\n            z-index: 10;\n        }\n\n        .ui-overlay > * {\n            pointer-events: auto;\n        }\n\n        /* Main Menu */\n        #main-menu {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: linear-gradient(135deg, rgba(26, 26, 46, 0.95), rgba(52, 73, 94, 0.95));\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            padding: var(--space-lg);\n            z-index: 100;\n        }\n\n        #main-menu.hidden {\n            display: none;\n        }\n\n        .menu-title {\n            font-family: 'Cinzel', serif;\n            font-size: 56px;\n            font-weight: 700;\n            color: var(--color-gold);\n            text-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);\n            margin-bottom: var(--space-xl);\n            text-align: center;\n        }\n\n        .menu-subtitle {\n            font-size: 24px;\n            color: rgba(255, 255, 255, 0.8);\n            margin-bottom: var(--space-xl);\n            text-align: center;\n        }\n\n        .menu-buttons {\n            display: flex;\n            flex-direction: column;\n            gap: var(--space-md);\n            width: 100%;\n            max-width: 400px;\n        }\n\n        .menu-button {\n            width: 100%;\n            height: 72px;\n            background: linear-gradient(135deg, var(--color-gold), #DAA520);\n            border: 2px solid rgba(255, 255, 255, 0.3);\n            border-radius: 16px;\n            font-family: 'Cinzel', serif;\n            font-size: 24px;\n            font-weight: 600;\n            color: #1a1a2e;\n            cursor: pointer;\n            transition: transform var(--transition-fast) var(--ease-out);\n            box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);\n        }\n\n        .menu-button:hover {\n            transform: translateY(-2px);\n            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);\n        }\n\n        .menu-button:active {\n            transform: translateY(0);\n        }\n\n        .menu-button.secondary {\n            background: linear-gradient(135deg, var(--color-silver), #A0A0A0);\n        }\n\n        /* Game HUD */\n        .hud {\n            position: absolute;\n            width: 100%;\n            pointer-events: none;\n        }\n\n        .hud > * {\n            pointer-events: auto;\n        }\n\n        /* Top HUD */\n        .hud-top {\n            top: 0;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            padding: var(--space-sm);\n            background: linear-gradient(180deg, rgba(0, 0, 0, 0.7), transparent);\n        }\n\n        /* Bottom HUD */\n        .hud-bottom {\n            bottom: 0;\n            display: flex;\n            flex-direction: column;\n            padding: var(--space-sm);\n            padding-bottom: var(--space-md);\n            gap: var(--space-sm);\n            background: linear-gradient(0deg, rgba(0, 0, 0, 0.7), transparent);\n        }\n\n        /* Player Info */\n        .player-info {\n            display: flex;\n            align-items: center;\n            gap: var(--space-sm);\n            background: var(--color-dark);\n            padding: var(--space-sm);\n            border-radius: 12px;\n            border: 2px solid rgba(255, 255, 255, 0.2);\n        }\n\n        .player-name {\n            font-size: 20px;\n            font-weight: 600;\n            color: white;\n        }\n\n        .player-timer {\n            font-size: 24px;\n            font-family: 'Courier New', monospace;\n            color: var(--color-gold);\n            min-width: 80px;\n        }\n\n        .player-timer.warning {\n            color: #ff4444;\n            animation: pulse 1s infinite;\n        }\n\n        @keyframes pulse {\n            0%, 100% { opacity: 1; }\n            50% { opacity: 0.6; }\n        }\n\n        /* Captured Pieces */\n        .captured-pieces {\n            display: flex;\n            gap: 4px;\n            flex-wrap: wrap;\n            max-width: 200px;\n        }\n\n        .captured-piece {\n            width: 24px;\n            height: 24px;\n            opacity: 0.7;\n        }\n\n        /* Action Buttons */\n        .action-buttons {\n            display: flex;\n            gap: var(--space-sm);\n            justify-content: center;\n            flex-wrap: wrap;\n        }\n\n        .action-button {\n            width: 96px;\n            height: 96px;\n            background: var(--color-dark);\n            border: 2px solid var(--color-gold);\n            border-radius: 12px;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            gap: 4px;\n            cursor: pointer;\n            transition: all var(--transition-fast) var(--ease-out);\n        }\n\n        .action-button:hover {\n            background: rgba(255, 215, 0, 0.2);\n            transform: scale(1.05);\n        }\n\n        .action-button:active {\n            transform: scale(0.95);\n        }\n\n        .action-button img {\n            width: 48px;\n            height: 48px;\n        }\n\n        .action-button span {\n            font-size: 14px;\n            color: white;\n        }\n\n        /* Move History */\n        .move-history {\n            background: var(--color-dark);\n            border-radius: 12px;\n            padding: var(--space-sm);\n            max-height: 100px;\n            overflow-y: auto;\n        }\n\n        .move-history-title {\n            font-size: 18px;\n            font-weight: 600;\n            color: var(--color-gold);\n            margin-bottom: var(--space-xs);\n        }\n\n        .move-list {\n            display: grid;\n            grid-template-columns: auto 1fr 1fr;\n            gap: var(--space-xs);\n            font-size: 16px;\n            color: white;\n        }\n\n        .move-number {\n            color: var(--color-gold);\n        }\n\n        /* Status Message */\n        .status-message {\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            background: var(--color-dark);\n            padding: var(--space-lg);\n            border-radius: 16px;\n            border: 3px solid var(--color-gold);\n            text-align: center;\n            z-index: 50;\n            min-width: 300px;\n        }\n\n        .status-message.hidden {\n            display: none;\n        }\n\n        .status-message h2 {\n            font-family: 'Cinzel', serif;\n            font-size: 40px;\n            color: var(--color-gold);\n            margin-bottom: var(--space-md);\n        }\n\n        .status-message p {\n            font-size: 20px;\n            color: white;\n            margin-bottom: var(--space-lg);\n        }\n\n        /* Pause Menu */\n        #pause-menu {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.9);\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            z-index: 200;\n        }\n\n        #pause-menu.hidden {\n            display: none;\n        }\n\n        .pause-title {\n            font-family: 'Cinzel', serif;\n            font-size: 48px;\n            color: var(--color-gold);\n            margin-bottom: var(--space-xl);\n        }\n\n        /* Loading Screen */\n        #loading-screen {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: linear-gradient(135deg, #1a1a2e, #34495e);\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            z-index: 300;\n        }\n\n        #loading-screen.hidden {\n            display: none;\n        }\n\n        .loading-spinner {\n            width: 80px;\n            height: 80px;\n            border: 8px solid rgba(255, 215, 0, 0.2);\n            border-top-color: var(--color-gold);\n            border-radius: 50%;\n            animation: spin 1s linear infinite;\n        }\n\n        @keyframes spin {\n            to { transform: rotate(360deg); }\n        }\n\n        .loading-text {\n            font-size: 24px;\n            color: white;\n            margin-top: var(--space-lg);\n        }\n\n        /* Promotion Dialog */\n        #promotion-dialog {\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            background: var(--color-dark);\n            padding: var(--space-lg);\n            border-radius: 16px;\n            border: 3px solid var(--color-gold);\n            z-index: 150;\n        }\n\n        #promotion-dialog.hidden {\n            display: none;\n        }\n\n        .promotion-title {\n            font-family: 'Cinzel', serif;\n            font-size: 32px;\n            color: var(--color-gold);\n            text-align: center;\n            margin-bottom: var(--space-md);\n        }\n\n        .promotion-options {\n            display: grid;\n            grid-template-columns: repeat(2, 1fr);\n            gap: var(--space-sm);\n        }\n\n        .promotion-option {\n            width: 120px;\n            height: 120px;\n            background: rgba(255, 255, 255, 0.1);\n            border: 2px solid var(--color-gold);\n            border-radius: 12px;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            transition: all var(--transition-fast) var(--ease-out);\n        }\n\n        .promotion-option:hover {\n            background: rgba(255, 215, 0, 0.3);\n            transform: scale(1.05);\n        }\n\n        .promotion-option img {\n            width: 80px;\n            height: 80px;\n        }\n    </style>\n</head>\n<body>\n    <div id=\"game-world\">\n        <img id=\"background\" />\n        <canvas id=\"game-canvas\"></canvas>\n        \n        <!-- UI Overlay -->\n        <div class=\"ui-overlay\">\n            <!-- Main Menu -->\n            <div id=\"main-menu\">\n                <h1 class=\"menu-title\">Chess Revolution</h1>\n                <p class=\"menu-subtitle\">Strategic Chess with Magical Powers</p>\n                <div class=\"menu-buttons\">\n                    <button class=\"menu-button\" id=\"btn-vs-ai\">Play vs AI</button>\n                    <button class=\"menu-button\" id=\"btn-local-2p\">Local 2-Player</button>\n                    <button class=\"menu-button secondary\" id=\"btn-statistics\">Statistics</button>\n                </div>\n            </div>\n\n            <!-- Loading Screen -->\n            <div id=\"loading-screen\">\n                <div class=\"loading-spinner\"></div>\n                <div class=\"loading-text\">Loading Chess Revolution...</div>\n            </div>\n\n            <!-- Game HUD -->\n            <div class=\"hud hud-top hidden\" id=\"hud-top\">\n                <div class=\"player-info\" id=\"opponent-info\">\n                    <div class=\"player-name\" id=\"opponent-name\">Black</div>\n                    <div class=\"player-timer\" id=\"opponent-timer\">\u221e</div>\n                    <div class=\"captured-pieces\" id=\"opponent-captured\"></div>\n                </div>\n            </div>\n\n            <div class=\"hud hud-bottom hidden\" id=\"hud-bottom\">\n                <div class=\"move-history\" id=\"move-history\">\n                    <div class=\"move-history-title\">Move History</div>\n                    <div class=\"move-list\" id=\"move-list\"></div>\n                </div>\n                <div class=\"action-buttons\">\n                    <div class=\"action-button\" id=\"btn-hint\">\n                        <img id=\"icon-hint\" />\n                        <span>Hint</span>\n                    </div>\n                    <div class=\"action-button\" id=\"btn-undo\">\n                        <img id=\"icon-undo\" />\n                        <span>Undo</span>\n                    </div>\n                    <div class=\"action-button\" id=\"btn-settings\">\n                        <img id=\"icon-settings\" />\n                        <span>Menu</span>\n                    </div>\n                    <div class=\"action-button\" id=\"btn-resign\">\n                        <img id=\"icon-resign\" />\n                        <span>Resign</span>\n                    </div>\n                </div>\n                <div class=\"player-info\" id=\"player-info\">\n                    <div class=\"player-name\" id=\"player-name\">White</div>\n                    <div class=\"player-timer\" id=\"player-timer\">\u221e</div>\n                    <div class=\"captured-pieces\" id=\"player-captured\"></div>\n                </div>\n            </div>\n\n            <!-- Status Message -->\n            <div class=\"status-message hidden\" id=\"status-message\">\n                <h2 id=\"status-title\">Check!</h2>\n                <p id=\"status-text\">Your king is in danger</p>\n                <button class=\"menu-button\" id=\"btn-status-ok\">Continue</button>\n            </div>\n\n            <!-- Pause Menu -->\n            <div id=\"pause-menu\" class=\"hidden\">\n                <h1 class=\"pause-title\">Paused</h1>\n                <div class=\"menu-buttons\">\n                    <button class=\"menu-button\" id=\"btn-resume\">Resume</button>\n                    <button class=\"menu-button secondary\" id=\"btn-main-menu\">Main Menu</button>\n                </div>\n            </div>\n\n            <!-- Promotion Dialog -->\n            <div id=\"promotion-dialog\" class=\"hidden\">\n                <div class=\"promotion-title\">Choose Promotion</div>\n                <div class=\"promotion-options\" id=\"promotion-options\"></div>\n            </div>\n        </div>\n    </div>\n\n    <script>\n        // ===== GAME: CHESS REVOLUTION =====\n        // A modern chess game with power-ups and progression\n        // Implements official chess rules with magical enhancements\n\n        let gameState = null;\n        let audioContext = null;\n        let audioBuffers = {};\n        let musicSource = null;\n\n        async function run(mode) {\n            const gameWorld = document.getElementById('game-world');\n            const canvas = document.getElementById('game-canvas');\n            const ctx = canvas.getContext('2d');\n\n            // Initialize display\n            function resizeCanvas() {\n                canvas.width = gameWorld.clientWidth;\n                canvas.height = gameWorld.clientHeight;\n                if (gameState && gameState.boardRenderer) {\n                    gameState.boardRenderer.resize();\n                }\n            }\n            resizeCanvas();\n            window.addEventListener('resize', resizeCanvas);\n\n            // Initialize audio context\n            audioContext = new (window.AudioContext || window.webkitAudioContext)();\n\n            // Show loading screen\n            document.getElementById('loading-screen').classList.remove('hidden');\n\n            // Preload assets\n            await preloadAssets();\n\n            // Hide loading screen\n            document.getElementById('loading-screen').classList.add('hidden');\n\n            // Initialize game config with defaults if needed\n            if (!window.gameConfig.settings) {\n                window.gameConfig.settings = {\n                    aiDifficulty: 'medium',\n                    timeControl: 0,\n                    powerSquaresEnabled: false,\n                    powerSquareCount: 3,\n                    powerSquareFrequency: 5,\n                    animationSpeed: 1,\n                    particleIntensity: 'medium',\n                    masterVolume: 0.7,\n                    musicVolume: 0.5,\n                    sfxVolume: 0.8\n                };\n            }\n\n            // Load player state\n            let playerState = null;\n            try {\n                const savedState = await lib.getUserGameState();\n                if (savedState && savedState.state) {\n                    playerState = savedState.state;\n                    lib.log('Player progress loaded successfully');\n                }\n            } catch (e) {\n                lib.log('No saved progress found, starting fresh');\n            }\n\n            if (!playerState) {\n                playerState = {\n                    level: 1,\n                    xp: 0,\n                    pieceXP: {\n                        king: 0, queen: 0, rook: 0,\n                        bishop: 0, knight: 0, pawn: 0\n                    },\n                    statistics: {\n                        gamesPlayed: 0,\n                        wins: 0,\n                        losses: 0,\n                        draws: 0,\n                        totalCaptures: 0,\n                        fastestCheckmate: null,\n                        longestGame: null\n                    },\n                    matchHistory: []\n                };\n                lib.log('Initialized new player profile');\n            } else {\n                // Validate loaded state has all required fields\n                if (!playerState.statistics) {\n                    playerState.statistics = {\n                        gamesPlayed: 0,\n                        wins: 0,\n                        losses: 0,\n                        draws: 0,\n                        totalCaptures: 0,\n                        fastestCheckmate: null,\n                        longestGame: null\n                    };\n                }\n                if (!playerState.pieceXP) {\n                    playerState.pieceXP = {\n                        king: 0, queen: 0, rook: 0,\n                        bishop: 0, knight: 0, pawn: 0\n                    };\n                }\n                if (!playerState.matchHistory) {\n                    playerState.matchHistory = [];\n                }\n            }\n\n            // Show game parameters\n            lib.showGameParameters({\n                name: 'Game Settings',\n                params: {\n                    'AI Difficulty': {\n                        key: 'settings.aiDifficulty',\n                        type: 'dropdown',\n                        options: [\n                            { label: 'Easy', value: 'easy' },\n                            { label: 'Medium', value: 'medium' }\n                        ]\n                    },\n                    'Power Squares': {\n                        key: 'settings.powerSquaresEnabled',\n                        type: 'checkbox'\n                    },\n                    'Power Square Count': {\n                        key: 'settings.powerSquareCount',\n                        type: 'slider',\n                        min: 1,\n                        max: 5,\n                        step: 1\n                    },\n                    'Master Volume': {\n                        key: 'settings.masterVolume',\n                        type: 'slider',\n                        min: 0,\n                        max: 1,\n                        step: 0.1\n                    },\n                    'Music Volume': {\n                        key: 'settings.musicVolume',\n                        type: 'slider',\n                        min: 0,\n                        max: 1,\n                        step: 0.1\n                    },\n                    'SFX Volume': {\n                        key: 'settings.sfxVolume',\n                        type: 'slider',\n                        min: 0,\n                        max: 1,\n                        step: 0.1\n                    }\n                }\n            });\n\n            // Initialize game state\n            gameState = new GameState(canvas, ctx, playerState, mode);\n\n            // Start background music\n            playMusic('music_main_menu', true);\n\n            // Set up UI event listeners\n            setupUIListeners();\n\n            // Game loop\n            let lastTime = 0;\n            function gameLoop(timestamp) {\n                const deltaTime = Math.min((timestamp - lastTime) / 1000, 0.11);\n                lastTime = timestamp;\n\n                ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n                if (gameState) {\n                    gameState.update(deltaTime);\n                    gameState.render();\n                }\n\n                requestAnimationFrame(gameLoop);\n            }\n            requestAnimationFrame(gameLoop);\n        }\n\n        // ===== ASSET PRELOADING =====\n        const assets = {};\n\n        async function preloadAssets() {\n            const assetIds = [\n                // Chess pieces\n                'chess_king_white', 'chess_queen_white', 'chess_rook_white',\n                'chess_bishop_white', 'chess_knight_white', 'chess_pawn_white',\n                'chess_king_black', 'chess_queen_black', 'chess_rook_black',\n                'chess_bishop_black', 'chess_knight_black', 'chess_pawn_black',\n                // Board textures\n                'board_light_square', 'board_dark_square',\n                // Background\n                'background_sky_kingdom', 'cloud_platform_base',\n                // Power squares\n                'power_square_extra_move', 'power_square_shield', 'power_square_knight_boost',\n                // Particles\n                'particle_sparkle',\n                // UI elements\n                'ui_button_primary', 'ui_button_secondary', 'ui_panel_background',\n                // Icons\n                'icon_settings', 'icon_hint', 'icon_undo', 'icon_resign',\n                // Audio\n                'sfx_piece_move', 'sfx_piece_place_wooden', 'sfx_piece_capture', 'sfx_check', 'sfx_checkmate',\n                'sfx_power_activate', 'sfx_ui_click', 'sfx_ui_hover',\n                'music_main_menu', 'music_gameplay', 'music_victory', 'music_defeat'\n            ];\n\n            const promises = assetIds.map(async id => {\n                const assetInfo = lib.getAsset(id);\n                if (!assetInfo) return;\n\n                if (assetInfo.type === 'image') {\n                    return new Promise((resolve, reject) => {\n                        const img = new Image();\n                        img.onload = () => {\n                            assets[id] = { type: 'image', data: img, info: assetInfo };\n                            resolve();\n                        };\n                        img.onerror = reject;\n                        img.src = assetInfo.url;\n                    });\n                } else if (assetInfo.type === 'audio') {\n                    try {\n                        const response = await fetch(assetInfo.url);\n                        const arrayBuffer = await response.arrayBuffer();\n                        const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n                        audioBuffers[id] = audioBuffer;\n                        assets[id] = { type: 'audio', data: audioBuffer, info: assetInfo };\n                    } catch (e) {\n                        console.error(`Failed to load audio: ${id}`, e);\n                    }\n                }\n            });\n\n            await Promise.all(promises);\n\n            // Set background image\n            document.getElementById('background').src = assets['background_sky_kingdom'].data.src;\n\n            // Set icon images\n            document.getElementById('icon-hint').src = assets['icon_hint'].data.src;\n            document.getElementById('icon-undo').src = assets['icon_undo'].data.src;\n            document.getElementById('icon-settings').src = assets['icon_settings'].data.src;\n            document.getElementById('icon-resign').src = assets['icon_resign'].data.src;\n        }\n\n        // ===== AUDIO SYSTEM =====\n        function playSound(soundId) {\n            if (!audioBuffers[soundId]) return;\n            \n            const source = audioContext.createBufferSource();\n            const gainNode = audioContext.createGain();\n            \n            source.buffer = audioBuffers[soundId];\n            source.connect(gainNode);\n            gainNode.connect(audioContext.destination);\n            \n            const volume = window.gameConfig.settings.masterVolume * window.gameConfig.settings.sfxVolume;\n            gainNode.gain.value = volume;\n            \n            source.start(0);\n        }\n\n        function playMusic(musicId, loop = false) {\n            if (musicSource) {\n                musicSource.stop();\n                musicSource = null;\n            }\n\n            if (!audioBuffers[musicId]) return;\n\n            musicSource = audioContext.createBufferSource();\n            const gainNode = audioContext.createGain();\n            \n            musicSource.buffer = audioBuffers[musicId];\n            musicSource.loop = loop;\n            musicSource.connect(gainNode);\n            gainNode.connect(audioContext.destination);\n            \n            const volume = window.gameConfig.settings.masterVolume * window.gameConfig.settings.musicVolume;\n            gainNode.gain.value = volume;\n            \n            musicSource.start(0);\n        }\n\n        // ===== CHESS ENGINE =====\n        class ChessEngine {\n            constructor() {\n                this.board = this.initializeBoard();\n                this.currentPlayer = 'white';\n                this.moveHistory = [];\n                this.halfMoveClock = 0;\n                this.fullMoveNumber = 1;\n                this.castlingRights = {\n                    white: { kingSide: true, queenSide: true },\n                    black: { kingSide: true, queenSide: true }\n                };\n                this.enPassantTarget = null;\n                this.capturedPieces = { white: [], black: [] };\n            }\n\n            initializeBoard() {\n                const board = Array(8).fill(null).map(() => Array(8).fill(null));\n                \n                // Black pieces (top)\n                board[0] = [\n                    { type: 'rook', color: 'black' },\n                    { type: 'knight', color: 'black' },\n                    { type: 'bishop', color: 'black' },\n                    { type: 'queen', color: 'black' },\n                    { type: 'king', color: 'black' },\n                    { type: 'bishop', color: 'black' },\n                    { type: 'knight', color: 'black' },\n                    { type: 'rook', color: 'black' }\n                ];\n                board[1] = Array(8).fill(null).map(() => ({ type: 'pawn', color: 'black' }));\n                \n                // White pieces (bottom)\n                board[6] = Array(8).fill(null).map(() => ({ type: 'pawn', color: 'white' }));\n                board[7] = [\n                    { type: 'rook', color: 'white' },\n                    { type: 'knight', color: 'white' },\n                    { type: 'bishop', color: 'white' },\n                    { type: 'queen', color: 'white' },\n                    { type: 'king', color: 'white' },\n                    { type: 'bishop', color: 'white' },\n                    { type: 'knight', color: 'white' },\n                    { type: 'rook', color: 'white' }\n                ];\n\n                return board;\n            }\n\n            getPiece(row, col) {\n                if (row < 0 || row > 7 || col < 0 || col > 7 || !this.board[row]) return null;\n                return this.board[row][col];\n            }\n\n            getLegalMoves(row, col) {\n                const piece = this.getPiece(row, col);\n                if (!piece || piece.color !== this.currentPlayer) return [];\n\n                let moves = [];\n                switch (piece.type) {\n                    case 'pawn': moves = this.getPawnMoves(row, col); break;\n                    case 'rook': moves = this.getRookMoves(row, col); break;\n                    case 'knight': moves = this.getKnightMoves(row, col); break;\n                    case 'bishop': moves = this.getBishopMoves(row, col); break;\n                    case 'queen': moves = this.getQueenMoves(row, col); break;\n                    case 'king': moves = this.getKingMoves(row, col); break;\n                }\n\n                // Filter out moves that would leave king in check\n                return moves.filter(move => {\n                    if (!move || move.row === undefined || move.col === undefined) return false;\n                    return !this.wouldBeInCheck(row, col, move.row, move.col);\n                });\n            }\n\n            getPawnMoves(row, col) {\n                const moves = [];\n                const piece = this.board[row][col];\n                const direction = piece.color === 'white' ? -1 : 1;\n                const startRow = piece.color === 'white' ? 6 : 1;\n\n                // Forward move\n                if (!this.getPiece(row + direction, col)) {\n                    moves.push({ row: row + direction, col });\n                    \n                    // Double move from start\n                    if (row === startRow && !this.getPiece(row + 2 * direction, col)) {\n                        moves.push({ row: row + 2 * direction, col });\n                    }\n                }\n\n                // Captures\n                for (let dc of [-1, 1]) {\n                    const target = this.getPiece(row + direction, col + dc);\n                    if (target && target.color !== piece.color) {\n                        moves.push({ row: row + direction, col: col + dc });\n                    }\n                    \n                    // En passant\n                    if (this.enPassantTarget && \n                        this.enPassantTarget.row === row + direction && \n                        this.enPassantTarget.col === col + dc) {\n                        moves.push({ row: row + direction, col: col + dc, enPassant: true });\n                    }\n                }\n\n                return moves;\n            }\n\n            getRookMoves(row, col) {\n                return this.getSlidingMoves(row, col, [[0, 1], [0, -1], [1, 0], [-1, 0]]);\n            }\n\n            getBishopMoves(row, col) {\n                return this.getSlidingMoves(row, col, [[1, 1], [1, -1], [-1, 1], [-1, -1]]);\n            }\n\n            getQueenMoves(row, col) {\n                return this.getSlidingMoves(row, col, [\n                    [0, 1], [0, -1], [1, 0], [-1, 0],\n                    [1, 1], [1, -1], [-1, 1], [-1, -1]\n                ]);\n            }\n\n            getKnightMoves(row, col) {\n                const moves = [];\n                const piece = this.board[row][col];\n                const offsets = [\n                    [-2, -1], [-2, 1], [-1, -2], [-1, 2],\n                    [1, -2], [1, 2], [2, -1], [2, 1]\n                ];\n\n                for (let [dr, dc] of offsets) {\n                    const newRow = row + dr;\n                    const newCol = col + dc;\n                    if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {\n                        const target = this.board[newRow][newCol];\n                        if (!target || target.color !== piece.color) {\n                            moves.push({ row: newRow, col: newCol });\n                        }\n                    }\n                }\n\n                return moves;\n            }\n\n            getKingMoves(row, col) {\n                const moves = [];\n                const piece = this.board[row][col];\n\n                // Normal moves\n                for (let dr = -1; dr <= 1; dr++) {\n                    for (let dc = -1; dc <= 1; dc++) {\n                        if (dr === 0 && dc === 0) continue;\n                        const newRow = row + dr;\n                        const newCol = col + dc;\n                        if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {\n                            const target = this.board[newRow][newCol];\n                            if (!target || target.color !== piece.color) {\n                                moves.push({ row: newRow, col: newCol });\n                            }\n                        }\n                    }\n                }\n\n                // Castling\n                const rights = this.castlingRights[piece.color];\n                if (rights.kingSide && this.canCastle(row, col, 'king')) {\n                    moves.push({ row, col: col + 2, castle: 'king' });\n                }\n                if (rights.queenSide && this.canCastle(row, col, 'queen')) {\n                    moves.push({ row, col: col - 2, castle: 'queen' });\n                }\n\n                return moves;\n            }\n\n            getSlidingMoves(row, col, directions) {\n                const moves = [];\n                const piece = this.board[row][col];\n\n                for (let [dr, dc] of directions) {\n                    let newRow = row + dr;\n                    let newCol = col + dc;\n\n                    while (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {\n                        const target = this.board[newRow][newCol];\n                        if (!target) {\n                            moves.push({ row: newRow, col: newCol });\n                        } else {\n                            if (target.color !== piece.color) {\n                                moves.push({ row: newRow, col: newCol });\n                            }\n                            break;\n                        }\n                        newRow += dr;\n                        newCol += dc;\n                    }\n                }\n\n                return moves;\n            }\n\n            canCastle(row, col, side) {\n                const piece = this.board[row][col];\n                const rookCol = side === 'king' ? 7 : 0;\n                const rook = this.board[row][rookCol];\n\n                if (!rook || rook.type !== 'rook' || rook.color !== piece.color) return false;\n                if (this.isInCheck(piece.color)) return false;\n\n                const step = side === 'king' ? 1 : -1;\n                const end = side === 'king' ? 2 : 3;\n\n                for (let i = 1; i <= end; i++) {\n                    const checkCol = col + i * step;\n                    if (this.board[row][checkCol]) return false;\n                    if (i <= 2 && this.isSquareAttacked(row, checkCol, piece.color === 'white' ? 'black' : 'white')) {\n                        return false;\n                    }\n                }\n\n                return true;\n            }\n\n            wouldBeInCheck(fromRow, fromCol, toRow, toCol) {\n                if (fromRow === undefined || fromCol === undefined || toRow === undefined || toCol === undefined) return false;\n                if (fromRow < 0 || fromRow > 7 || fromCol < 0 || fromCol > 7) return false;\n                if (toRow < 0 || toRow > 7 || toCol < 0 || toCol > 7) return false;\n                \n                const piece = this.board[fromRow][fromCol];\n                if (!piece) return false;\n                \n                const captured = this.board[toRow][toCol];\n                \n                // Simulate\n                this.board[toRow][toCol] = piece;\n                this.board[fromRow][fromCol] = null;\n                \n                const inCheck = this.isInCheck(piece.color);\n                \n                // Undo\n                this.board[fromRow][fromCol] = piece;\n                this.board[toRow][toCol] = captured;\n                \n                return inCheck;\n            }\n\n            isInCheck(color) {\n                const kingPos = this.findKing(color);\n                if (!kingPos) return false;\n                return this.isSquareAttacked(kingPos.row, kingPos.col, color === 'white' ? 'black' : 'white');\n            }\n\n            isSquareAttacked(row, col, byColor) {\n                for (let r = 0; r < 8; r++) {\n                    const boardRow = this.board[r];\n                    if (!boardRow) continue;\n                    for (let c = 0; c < 8; c++) {\n                        const piece = boardRow[c];\n                        if (piece && piece.color === byColor) {\n                            const moves = this.getPseudoLegalMoves(r, c);\n                            if (moves && moves.some(m => m && m.row === row && m.col === col)) {\n                                return true;\n                            }\n                        }\n                    }\n                }\n                return false;\n            }\n\n            getPseudoLegalMoves(row, col) {\n                const piece = this.board[row][col];\n                if (!piece) return [];\n\n                switch (piece.type) {\n                    case 'pawn': return this.getPawnAttacks(row, col);\n                    case 'rook': return this.getRookMoves(row, col);\n                    case 'knight': return this.getKnightMoves(row, col);\n                    case 'bishop': return this.getBishopMoves(row, col);\n                    case 'queen': return this.getQueenMoves(row, col);\n                    case 'king': return this.getKingAttacks(row, col);\n                    default: return [];\n                }\n            }\n\n            getPawnAttacks(row, col) {\n                const moves = [];\n                const piece = this.board[row][col];\n                const direction = piece.color === 'white' ? -1 : 1;\n\n                for (let dc of [-1, 1]) {\n                    const newRow = row + direction;\n                    const newCol = col + dc;\n                    if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {\n                        moves.push({ row: newRow, col: newCol });\n                    }\n                }\n\n                return moves;\n            }\n\n            getKingAttacks(row, col) {\n                const moves = [];\n                for (let dr = -1; dr <= 1; dr++) {\n                    for (let dc = -1; dc <= 1; dc++) {\n                        if (dr === 0 && dc === 0) continue;\n                        const newRow = row + dr;\n                        const newCol = col + dc;\n                        if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {\n                            moves.push({ row: newRow, col: newCol });\n                        }\n                    }\n                }\n                return moves;\n            }\n\n            findKing(color) {\n                for (let r = 0; r < 8; r++) {\n                    const boardRow = this.board[r];\n                    if (!boardRow) continue;\n                    for (let c = 0; c < 8; c++) {\n                        const piece = boardRow[c];\n                        if (piece && piece.type === 'king' && piece.color === color) {\n                            return { row: r, col: c };\n                        }\n                    }\n                }\n                return null;\n            }\n\n            makeMove(fromRow, fromCol, toRow, toCol, promotion = null) {\n                const piece = this.board[fromRow][fromCol];\n                const captured = this.board[toRow][toCol];\n                const move = {\n                    from: { row: fromRow, col: fromCol },\n                    to: { row: toRow, col: toCol },\n                    piece: piece.type,\n                    color: piece.color,\n                    captured: captured ? captured.type : null\n                };\n\n                // Handle captures\n                if (captured) {\n                    const opponent = piece.color === 'white' ? 'black' : 'white';\n                    this.capturedPieces[opponent].push(captured);\n                    playSound('sfx_piece_capture');\n                } else {\n                    playSound('sfx_piece_place_wooden');\n                }\n\n                // Move piece\n                this.board[toRow][toCol] = piece;\n                this.board[fromRow][fromCol] = null;\n\n                // Handle en passant\n                if (piece.type === 'pawn' && Math.abs(toRow - fromRow) === 2) {\n                    this.enPassantTarget = { row: (fromRow + toRow) / 2, col: toCol };\n                } else if (piece.type === 'pawn' && this.enPassantTarget && \n                           toRow === this.enPassantTarget.row && toCol === this.enPassantTarget.col) {\n                    const capturedRow = piece.color === 'white' ? toRow + 1 : toRow - 1;\n                    const capturedPawn = this.board[capturedRow][toCol];\n                    this.capturedPieces[piece.color === 'white' ? 'black' : 'white'].push(capturedPawn);\n                    this.board[capturedRow][toCol] = null;\n                    move.enPassant = true;\n                } else {\n                    this.enPassantTarget = null;\n                }\n\n                // Handle castling\n                if (piece.type === 'king') {\n                    if (Math.abs(toCol - fromCol) === 2) {\n                        const rookCol = toCol > fromCol ? 7 : 0;\n                        const newRookCol = toCol > fromCol ? toCol - 1 : toCol + 1;\n                        const rook = this.board[toRow][rookCol];\n                        this.board[toRow][newRookCol] = rook;\n                        this.board[toRow][rookCol] = null;\n                        move.castle = toCol > fromCol ? 'king' : 'queen';\n                    }\n                    this.castlingRights[piece.color] = { kingSide: false, queenSide: false };\n                }\n\n                // Handle castling rights\n                if (piece.type === 'rook') {\n                    if (fromCol === 0) this.castlingRights[piece.color].queenSide = false;\n                    if (fromCol === 7) this.castlingRights[piece.color].kingSide = false;\n                }\n\n                // Handle pawn promotion\n                if (piece.type === 'pawn' && (toRow === 0 || toRow === 7)) {\n                    const promoteTo = promotion || 'queen';\n                    this.board[toRow][toCol] = { type: promoteTo, color: piece.color };\n                    move.promotion = promoteTo;\n                }\n\n                // Update move counters\n                if (piece.type === 'pawn' || captured) {\n                    this.halfMoveClock = 0;\n                } else {\n                    this.halfMoveClock++;\n                }\n\n                if (this.currentPlayer === 'black') {\n                    this.fullMoveNumber++;\n                }\n\n                // Switch player\n                this.currentPlayer = this.currentPlayer === 'white' ? 'black' : 'white';\n\n                // Add to history\n                this.moveHistory.push(move);\n\n                // Check for check/checkmate\n                if (this.isInCheck(this.currentPlayer)) {\n                    if (this.isCheckmate()) {\n                        playSound('sfx_checkmate');\n                        return 'checkmate';\n                    } else {\n                        playSound('sfx_check');\n                        return 'check';\n                    }\n                }\n\n                // Check for stalemate\n                if (this.isStalemate()) {\n                    return 'stalemate';\n                }\n\n                return 'normal';\n            }\n\n            isCheckmate() {\n                return this.isInCheck(this.currentPlayer) && !this.hasLegalMoves();\n            }\n\n            isStalemate() {\n                return !this.isInCheck(this.currentPlayer) && !this.hasLegalMoves();\n            }\n\n            hasLegalMoves() {\n                for (let r = 0; r < 8; r++) {\n                    const boardRow = this.board[r];\n                    if (!boardRow) continue;\n                    for (let c = 0; c < 8; c++) {\n                        const piece = boardRow[c];\n                        if (piece && piece.color === this.currentPlayer) {\n                            const moves = this.getLegalMoves(r, c);\n                            if (moves.length > 0) return true;\n                        }\n                    }\n                }\n                return false;\n            }\n\n            getAllLegalMoves() {\n                const moves = [];\n                for (let r = 0; r < 8; r++) {\n                    const boardRow = this.board[r];\n                    if (!boardRow) continue;\n                    for (let c = 0; c < 8; c++) {\n                        const piece = boardRow[c];\n                        if (piece && piece.color === this.currentPlayer) {\n                            const pieceMoves = this.getLegalMoves(r, c);\n                            for (let move of pieceMoves) {\n                                moves.push({\n                                    from: { row: r, col: c },\n                                    to: move,\n                                    piece: piece.type\n                                });\n                            }\n                        }\n                    }\n                }\n                return moves;\n            }\n        }\n\n        // ===== AI PLAYER =====\n        class AIPlayer {\n            constructor(difficulty) {\n                this.difficulty = difficulty;\n            }\n\n            getMove(engine) {\n                if (this.difficulty === 'easy') {\n                    return this.getRandomMove(engine);\n                } else {\n                    return this.getMiniMaxMove(engine, 2);\n                }\n            }\n\n            getRandomMove(engine) {\n                const moves = engine.getAllLegalMoves();\n                if (moves.length === 0) return null;\n                \n                // Prefer captures\n                const captures = moves.filter(m => {\n                    const target = engine.board[m.to.row][m.to.col];\n                    return target !== null;\n                });\n                \n                const movePool = captures.length > 0 && Math.random() < 0.7 ? captures : moves;\n                return movePool[Math.floor(Math.random() * movePool.length)];\n            }\n\n            getMiniMaxMove(engine, depth) {\n                const moves = engine.getAllLegalMoves();\n                if (moves.length === 0) return null;\n\n                let bestMove = null;\n                let bestValue = -Infinity;\n\n                for (let move of moves) {\n                    const value = this.minimax(engine, move, depth - 1, false, -Infinity, Infinity);\n                    if (value > bestValue) {\n                        bestValue = value;\n                        bestMove = move;\n                    }\n                }\n\n                return bestMove;\n            }\n\n            minimax(engine, move, depth, isMaximizing, alpha, beta) {\n                // Ensure valid move object and coordinates\n                if (!move || !move.from || !move.to) return 0;\n                const { from, to } = move;\n                if (from.row === undefined || from.col === undefined || to.row === undefined || to.col === undefined) return 0;\n\n                // Simulate move\n                const piece = engine.board[from.row][from.col];\n                if (!piece) return 0;\n\n                const captured = engine.board[to.row][to.col];\n                engine.board[to.row][to.col] = piece;\n                engine.board[from.row][from.col] = null;\n\n                const aiColor = 'black';\n                \n                // Switch player context for checking conditions\n                const originalPlayer = engine.currentPlayer;\n                engine.currentPlayer = originalPlayer === 'white' ? 'black' : 'white';\n\n                // Check terminal conditions\n                const isCheckmate = engine.isCheckmate();\n                const isStalemate = engine.isStalemate();\n\n                let value;\n                if (depth === 0 || isCheckmate || isStalemate) {\n                    value = this.evaluatePosition(engine, aiColor);\n                } else {\n                    const moves = engine.getAllLegalMoves();\n                    if (moves.length === 0) {\n                        value = this.evaluatePosition(engine, aiColor);\n                    } else if (isMaximizing) {\n                        value = -Infinity;\n                        for (let nextMove of moves) {\n                            const res = this.minimax(engine, nextMove, depth - 1, false, alpha, beta);\n                            value = Math.max(value, res);\n                            alpha = Math.max(alpha, value);\n                            if (beta <= alpha) break;\n                        }\n                    } else {\n                        value = Infinity;\n                        for (let nextMove of moves) {\n                            const res = this.minimax(engine, nextMove, depth - 1, true, alpha, beta);\n                            value = Math.min(value, res);\n                            beta = Math.min(beta, value);\n                            if (beta <= alpha) break;\n                        }\n                    }\n                }\n\n                // Restore state\n                engine.currentPlayer = originalPlayer;\n                engine.board[from.row][from.col] = piece;\n                engine.board[to.row][to.col] = captured;\n\n                return isFinite(value) ? value : 0;\n            }\n\n            evaluatePosition(engine, aiColor) {\n                const pieceValues = {\n                    pawn: 1,\n                    knight: 3,\n                    bishop: 3,\n                    rook: 5,\n                    queen: 9,\n                    king: 0\n                };\n\n                let score = 0;\n                const opponentColor = aiColor === 'white' ? 'black' : 'white';\n\n                // Material count\n                for (let r = 0; r < 8; r++) {\n                    const boardRow = engine.board[r];\n                    if (!boardRow) continue;\n                    for (let c = 0; c < 8; c++) {\n                        const piece = boardRow[c];\n                        if (piece) {\n                            const value = pieceValues[piece.type];\n                            if (piece.color === aiColor) {\n                                score += value;\n                            } else {\n                                score -= value;\n                            }\n                        }\n                    }\n                }\n\n                // Check/checkmate bonus\n                if (engine.isCheckmate()) {\n                    return engine.currentPlayer === aiColor ? -10000 : 10000;\n                }\n                if (engine.isInCheck(opponentColor)) {\n                    score += 0.5;\n                }\n\n                return score;\n            }\n        }\n\n        // ===== POWER-UP SYSTEM =====\n        class PowerUpSystem {\n            constructor() {\n                this.powerSquares = [];\n                this.activePowers = [];\n                this.turnsSinceLastSpawn = 0;\n            }\n\n            update(turnCount) {\n                if (!window.gameConfig.settings.powerSquaresEnabled) return;\n                \n                const frequency = window.gameConfig.settings.powerSquareFrequency;\n                const maxSquares = window.gameConfig.settings.powerSquareCount;\n\n                this.turnsSinceLastSpawn++;\n\n                // Spawn new power squares\n                if (turnCount >= 5 && this.turnsSinceLastSpawn >= frequency && this.powerSquares.length < maxSquares) {\n                    this.spawnPowerSquare();\n                    this.turnsSinceLastSpawn = 0;\n                }\n\n                // Remove expired power squares\n                this.powerSquares = this.powerSquares.filter(ps => {\n                    ps.turnsRemaining--;\n                    return ps.turnsRemaining > 0;\n                });\n\n                // Update active powers\n                this.activePowers = this.activePowers.filter(ap => {\n                    ap.turnsRemaining--;\n                    return ap.turnsRemaining > 0;\n                });\n            }\n\n            spawnPowerSquare() {\n                const types = ['extra_move', 'shield', 'knight_boost'];\n                const type = types[Math.floor(Math.random() * types.length)];\n                \n                // Find empty squares\n                const emptySquares = [];\n                for (let r = 0; r < 8; r++) {\n                    const boardRow = gameState.engine.board[r];\n                    if (!boardRow) continue;\n                    for (let c = 0; c < 8; c++) {\n                        if (!boardRow[c]) {\n                            emptySquares.push({ row: r, col: c });\n                        }\n                    }\n                }\n\n                if (emptySquares.length > 0) {\n                    const pos = emptySquares[Math.floor(Math.random() * emptySquares.length)];\n                    this.powerSquares.push({\n                        row: pos.row,\n                        col: pos.col,\n                        type: type,\n                        turnsRemaining: 5\n                    });\n                }\n            }\n\n            checkPowerSquare(row, col) {\n                const index = this.powerSquares.findIndex(ps => ps.row === row && ps.col === col);\n                if (index !== -1) {\n                    const power = this.powerSquares[index];\n                    this.powerSquares.splice(index, 1);\n                    this.activatePower(power.type);\n                    playSound('sfx_power_activate');\n                    return true;\n                }\n                return false;\n            }\n\n            activatePower(type) {\n                this.activePowers.push({\n                    type: type,\n                    turnsRemaining: type === 'extra_move' ? 1 : 2\n                });\n            }\n\n            hasPower(type) {\n                return this.activePowers.some(ap => ap.type === type);\n            }\n\n            getPowerSquareAt(row, col) {\n                return this.powerSquares.find(ps => ps.row === row && ps.col === col);\n            }\n        }\n\n        // ===== BOARD RENDERER =====\n        class BoardRenderer {\n            constructor(canvas, ctx) {\n                this.canvas = canvas;\n                this.ctx = ctx;\n                this.resize();\n                this.animations = [];\n                this.particles = [];\n            }\n\n            resize() {\n                const size = Math.min(this.canvas.width, this.canvas.height);\n                this.boardSize = size * 0.85;\n                this.squareSize = this.boardSize / 8;\n                this.offsetX = (this.canvas.width - this.boardSize) / 2;\n                this.offsetY = (this.canvas.height - this.boardSize) / 2 - 50;\n            }\n\n            render(engine, selectedSquare, legalMoves, powerUpSystem) {\n                // Draw board\n                for (let row = 0; row < 8; row++) {\n                    for (let col = 0; col < 8; col++) {\n                        this.drawSquare(row, col, selectedSquare, legalMoves);\n                    }\n                }\n\n                // Draw power squares\n                if (powerUpSystem && window.gameConfig.settings.powerSquaresEnabled) {\n                    for (let ps of powerUpSystem.powerSquares) {\n                        this.drawPowerSquare(ps);\n                    }\n                }\n\n                // Draw pieces\n                for (let row = 0; row < 8; row++) {\n                    const boardRow = engine.board[row];\n                    if (!boardRow) continue;\n                    for (let col = 0; col < 8; col++) {\n                        const piece = boardRow[col];\n                        if (piece) {\n                            this.drawPiece(row, col, piece);\n                        }\n                    }\n                }\n\n                // Draw selected piece on top\n                if (selectedSquare) {\n                    const piece = engine.board[selectedSquare.row][selectedSquare.col];\n                    if (piece) {\n                        this.drawPiece(selectedSquare.row, selectedSquare.col, piece, true);\n                    }\n                }\n\n                // Draw animations\n                this.updateAnimations();\n\n                // Draw particles\n                this.updateParticles();\n\n                // Draw coordinates\n                this.drawCoordinates();\n            }\n\n            drawSquare(row, col, selectedSquare, legalMoves) {\n                const x = this.offsetX + col * this.squareSize;\n                const y = this.offsetY + row * this.squareSize;\n                \n                const isLight = (row + col) % 2 === 0;\n                const isSelected = selectedSquare && selectedSquare.row === row && selectedSquare.col === col;\n                const isLegalMove = legalMoves && legalMoves.some(m => m.row === row && m.col === col);\n\n                // Draw base square\n                if (isLight) {\n                    this.ctx.fillStyle = '#F5F5DC';\n                } else {\n                    this.ctx.fillStyle = '#8B4513';\n                }\n                this.ctx.fillRect(x, y, this.squareSize, this.squareSize);\n\n                // Highlight selected square\n                if (isSelected) {\n                    this.ctx.fillStyle = 'rgba(255, 215, 0, 0.4)';\n                    this.ctx.fillRect(x, y, this.squareSize, this.squareSize);\n                }\n\n                // Highlight legal moves\n                if (isLegalMove) {\n                    this.ctx.fillStyle = 'rgba(0, 255, 255, 0.3)';\n                    this.ctx.fillRect(x, y, this.squareSize, this.squareSize);\n                    \n                    // Draw move indicator dot\n                    this.ctx.fillStyle = 'rgba(0, 255, 255, 0.6)';\n                    this.ctx.beginPath();\n                    this.ctx.arc(\n                        x + this.squareSize / 2,\n                        y + this.squareSize / 2,\n                        this.squareSize / 6,\n                        0,\n                        Math.PI * 2\n                    );\n                    this.ctx.fill();\n                }\n            }\n\n            drawPowerSquare(ps) {\n                const x = this.offsetX + ps.col * this.squareSize;\n                const y = this.offsetY + ps.row * this.squareSize;\n\n                let assetId;\n                switch (ps.type) {\n                    case 'extra_move': assetId = 'power_square_extra_move'; break;\n                    case 'shield': assetId = 'power_square_shield'; break;\n                    case 'knight_boost': assetId = 'power_square_knight_boost'; break;\n                }\n\n                if (assets[assetId]) {\n                    const img = assets[assetId].data;\n                    this.ctx.globalAlpha = 0.7 + Math.sin(Date.now() / 200) * 0.3;\n                    this.ctx.drawImage(img, x, y, this.squareSize, this.squareSize);\n                    this.ctx.globalAlpha = 1;\n                }\n            }\n\n            drawPiece(row, col, piece, lifted = false) {\n                const x = this.offsetX + col * this.squareSize;\n                const y = this.offsetY + row * this.squareSize;\n\n                const assetId = `chess_${piece.type}_${piece.color}`;\n                if (!assets[assetId]) return;\n\n                const img = assets[assetId].data;\n                const info = assets[assetId].info;\n\n                // Calculate size maintaining aspect ratio\n                let drawWidth, drawHeight;\n                if (info.aspect_ratio) {\n                    const [w, h] = info.aspect_ratio;\n                    const aspectRatio = w / h;\n                    drawHeight = this.squareSize * 0.9;\n                    drawWidth = drawHeight * aspectRatio;\n                } else {\n                    drawWidth = drawHeight = this.squareSize * 0.9;\n                }\n\n                const drawX = x + (this.squareSize - drawWidth) / 2;\n                let drawY = y + (this.squareSize - drawHeight) / 2;\n\n                // Lift effect for selected piece\n                if (lifted) {\n                    drawY -= 10;\n                    this.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';\n                    this.ctx.shadowBlur = 10;\n                }\n\n                this.ctx.drawImage(img, drawX, drawY, drawWidth, drawHeight);\n                this.ctx.shadowBlur = 0;\n            }\n\n            drawCoordinates() {\n                this.ctx.fillStyle = 'white';\n                this.ctx.font = '14px Inter';\n                this.ctx.textAlign = 'center';\n\n                // Column labels (a-h)\n                for (let col = 0; col < 8; col++) {\n                    const x = this.offsetX + col * this.squareSize + this.squareSize / 2;\n                    const y = this.offsetY + this.boardSize + 20;\n                    this.ctx.fillText(String.fromCharCode(97 + col), x, y);\n                }\n\n                // Row labels (1-8)\n                this.ctx.textAlign = 'right';\n                for (let row = 0; row < 8; row++) {\n                    const x = this.offsetX - 10;\n                    const y = this.offsetY + row * this.squareSize + this.squareSize / 2 + 5;\n                    this.ctx.fillText(String(8 - row), x, y);\n                }\n            }\n\n            addMoveAnimation(fromRow, fromCol, toRow, toCol) {\n                this.animations.push({\n                    type: 'move',\n                    fromRow, fromCol, toRow, toCol,\n                    progress: 0,\n                    duration: 0.3\n                });\n            }\n\n            addCaptureParticles(row, col) {\n                const x = this.offsetX + col * this.squareSize + this.squareSize / 2;\n                const y = this.offsetY + row * this.squareSize + this.squareSize / 2;\n                \n                for (let i = 0; i < 10; i++) {\n                    this.particles.push({\n                        x: x,\n                        y: y,\n                        vx: (Math.random() - 0.5) * 200,\n                        vy: (Math.random() - 0.5) * 200,\n                        life: 1,\n                        decay: 0.02\n                    });\n                }\n            }\n\n            updateAnimations() {\n                // Currently animations are handled by smooth board state updates\n            }\n\n            updateParticles() {\n                this.particles = this.particles.filter(p => {\n                    p.x += p.vx * 0.016;\n                    p.y += p.vy * 0.016;\n                    p.vy += 200 * 0.016; // Gravity\n                    p.life -= p.decay;\n                    \n                    if (p.life > 0) {\n                        this.ctx.globalAlpha = p.life;\n                        this.ctx.fillStyle = '#FFD700';\n                        this.ctx.beginPath();\n                        this.ctx.arc(p.x, p.y, 3, 0, Math.PI * 2);\n                        this.ctx.fill();\n                        this.ctx.globalAlpha = 1;\n                        return true;\n                    }\n                    return false;\n                });\n            }\n\n            screenToBoard(screenX, screenY) {\n                const col = Math.floor((screenX - this.offsetX) / this.squareSize);\n                const row = Math.floor((screenY - this.offsetY) / this.squareSize);\n                \n                if (row >= 0 && row < 8 && col >= 0 && col < 8) {\n                    return { row, col };\n                }\n                return null;\n            }\n        }\n\n        // ===== GAME STATE =====\n        class GameState {\n            constructor(canvas, ctx, playerState, mode) {\n                this.canvas = canvas;\n                this.ctx = ctx;\n                this.mode = mode;\n                this.playerState = playerState;\n                \n                this.engine = null;\n                this.boardRenderer = null;\n                this.powerUpSystem = new PowerUpSystem();\n                this.ai = null;\n                \n                this.gameMode = null; // 'ai', 'local'\n                this.selectedSquare = null;\n                this.legalMoves = [];\n                this.turnCount = 0;\n                this.gameOver = false;\n                this.waitingForPromotion = false;\n                this.promotionMove = null;\n                this.isAiThinking = false;\n\n                this.setupInputHandlers();\n            }\n\n            startGame(mode) {\n                this.gameMode = mode;\n                this.engine = new ChessEngine();\n                this.boardRenderer = new BoardRenderer(this.canvas, this.ctx);\n                this.powerUpSystem = new PowerUpSystem();\n                this.selectedSquare = null;\n                this.legalMoves = [];\n                this.turnCount = 0;\n                this.gameOver = false;\n                this.waitingForPromotion = false;\n\n                if (mode === 'ai') {\n                    this.ai = new AIPlayer(window.gameConfig.settings.aiDifficulty);\n                } else {\n                    this.ai = null;\n                }\n\n                // Show HUD\n                document.getElementById('hud-top').classList.remove('hidden');\n                document.getElementById('hud-bottom').classList.remove('hidden');\n                \n                // Update player names\n                document.getElementById('player-name').textContent = 'White (You)';\n                if (mode === 'ai') {\n                    document.getElementById('opponent-name').textContent = 'Black (AI)';\n                } else {\n                    document.getElementById('opponent-name').textContent = 'Black (Player 2)';\n                }\n\n                // Switch music\n                playMusic('music_gameplay', true);\n\n                // Update move history\n                this.updateMoveHistory();\n            }\n\n            update(deltaTime) {\n                if (!this.engine) return;\n\n                // AI turn\n                if (this.gameMode === 'ai' && !this.gameOver && this.engine.currentPlayer === 'black' && \n                    !this.waitingForPromotion && !this.isAiThinking) {\n                    this.makeAIMove();\n                }\n            }\n\n            render() {\n                if (!this.engine) return;\n                this.boardRenderer.render(this.engine, this.selectedSquare, this.legalMoves, this.powerUpSystem);\n            }\n\n            setupInputHandlers() {\n                this.canvas.addEventListener('click', (e) => this.handleClick(e));\n                this.canvas.addEventListener('touchstart', (e) => {\n                    e.preventDefault();\n                    const touch = e.touches[0];\n                    const rect = this.canvas.getBoundingClientRect();\n                    const mouseEvent = new MouseEvent('click', {\n                        clientX: touch.clientX,\n                        clientY: touch.clientY\n                    });\n                    this.handleClick(mouseEvent);\n                });\n            }\n\n            handleClick(e) {\n                if (!this.engine || this.gameOver || this.waitingForPromotion) return;\n                \n                // Don't allow moves during AI turn\n                if (this.gameMode === 'ai' && this.engine.currentPlayer === 'black') return;\n\n                const rect = this.canvas.getBoundingClientRect();\n                const x = e.clientX - rect.left;\n                const y = e.clientY - rect.top;\n                \n                const square = this.boardRenderer.screenToBoard(x, y);\n                if (!square) return;\n\n                const piece = this.engine.getPiece(square.row, square.col);\n\n                // If a square is selected and this is a legal move\n                if (this.selectedSquare) {\n                    const isLegalMove = this.legalMoves.some(m => m.row === square.row && m.col === square.col);\n                    \n                    if (isLegalMove) {\n                        this.makeMove(this.selectedSquare.row, this.selectedSquare.col, square.row, square.col);\n                        return;\n                    }\n                }\n\n                // Select new piece\n                if (piece && piece.color === this.engine.currentPlayer) {\n                    this.selectedSquare = square;\n                    this.legalMoves = this.engine.getLegalMoves(square.row, square.col);\n                } else {\n                    this.selectedSquare = null;\n                    this.legalMoves = [];\n                }\n            }\n\n            makeMove(fromRow, fromCol, toRow, toCol, promotion = null) {\n                const piece = this.engine.board[fromRow][fromCol];\n                \n                // Check for pawn promotion\n                if (piece.type === 'pawn' && (toRow === 0 || toRow === 7) && !promotion) {\n                    this.waitingForPromotion = true;\n                    this.promotionMove = { fromRow, fromCol, toRow, toCol };\n                    this.showPromotionDialog(piece.color);\n                    return;\n                }\n\n                // Check for power square\n                this.powerUpSystem.checkPowerSquare(toRow, toCol);\n\n                // Make the move\n                const result = this.engine.makeMove(fromRow, fromCol, toRow, toCol, promotion);\n                \n                this.selectedSquare = null;\n                this.legalMoves = [];\n                this.turnCount++;\n                \n                // Update power system\n                this.powerUpSystem.update(this.turnCount);\n\n                // Update UI\n                this.updateMoveHistory();\n                this.updateCapturedPieces();\n\n                // Handle game end\n                if (result === 'checkmate') {\n                    this.handleGameEnd('checkmate');\n                } else if (result === 'stalemate') {\n                    this.handleGameEnd('stalemate');\n                } else if (result === 'check') {\n                    this.showStatus('Check!', 'Your king is in danger');\n                }\n            }\n\n            makeAIMove() {\n                if (this.gameOver || this.isAiThinking) return;\n                this.isAiThinking = true;\n\n                setTimeout(() => {\n                    // Double check it's still AI's turn and game isn't over\n                    if (this.gameOver || !this.engine || this.engine.currentPlayer !== 'black') {\n                        this.isAiThinking = false;\n                        return;\n                    }\n\n                    const move = this.ai.getMove(this.engine);\n                    if (move) {\n                        this.makeMove(move.from.row, move.from.col, move.to.row, move.to.col);\n                    }\n                    this.isAiThinking = false;\n                }, 500);\n            }\n\n            showPromotionDialog(color) {\n                const dialog = document.getElementById('promotion-dialog');\n                const options = document.getElementById('promotion-options');\n                options.innerHTML = '';\n\n                const pieces = ['queen', 'rook', 'bishop', 'knight'];\n                for (let piece of pieces) {\n                    const div = document.createElement('div');\n                    div.className = 'promotion-option';\n                    \n                    const img = document.createElement('img');\n                    img.src = assets[`chess_${piece}_${color}`].data.src;\n                    div.appendChild(img);\n                    \n                    div.onclick = () => {\n                        this.completePromotion(piece);\n                    };\n                    \n                    options.appendChild(div);\n                }\n\n                dialog.classList.remove('hidden');\n            }\n\n            completePromotion(piece) {\n                document.getElementById('promotion-dialog').classList.add('hidden');\n                this.waitingForPromotion = false;\n                \n                const { fromRow, fromCol, toRow, toCol } = this.promotionMove;\n                this.makeMove(fromRow, fromCol, toRow, toCol, piece);\n                this.promotionMove = null;\n            }\n\n            handleGameEnd(result) {\n                this.gameOver = true;\n                \n                let title, text;\n                const isPlayerWhite = this.gameMode === 'ai' || this.engine.currentPlayer === 'black';\n                \n                if (result === 'checkmate') {\n                    if (isPlayerWhite && this.engine.currentPlayer === 'black') {\n                        title = 'Victory!';\n                        text = 'You won by checkmate!';\n                        playMusic('music_victory');\n                        this.playerState.statistics.wins++;\n                    } else if (!isPlayerWhite && this.engine.currentPlayer === 'white') {\n                        title = 'Victory!';\n                        text = 'You won by checkmate!';\n                        playMusic('music_victory');\n                        this.playerState.statistics.wins++;\n                    } else {\n                        title = 'Defeat';\n                        text = 'You were checkmated';\n                        playMusic('music_defeat');\n                        this.playerState.statistics.losses++;\n                    }\n                } else if (result === 'stalemate') {\n                    title = 'Draw';\n                    text = 'Game ended in stalemate';\n                    this.playerState.statistics.draws++;\n                }\n\n                this.playerState.statistics.gamesPlayed++;\n                \n                // Award XP\n                const xpGained = result === 'checkmate' ? 150 : 50;\n                this.playerState.xp += xpGained;\n                \n                // Level up check\n                const xpForLevel = this.playerState.level * 500;\n                if (this.playerState.xp >= xpForLevel) {\n                    this.playerState.xp -= xpForLevel;\n                    this.playerState.level++;\n                }\n\n                // Save player progress and submit to leaderboard\n                Promise.all([\n                    this.savePlayerState(),\n                    this.submitScoreToLeaderboard()\n                ]).then(([saveResult, leaderboardResult]) => {\n                    if (leaderboardResult && leaderboardResult.userRank) {\n                        lib.log(`\ud83c\udfc6 Global Rank: #${leaderboardResult.userRank}`);\n                    }\n                }).catch(err => {\n                    lib.log('\u26a0 Warning: Could not save all progress data.');\n                });\n\n                this.showStatus(title, text);\n                \n                // Add return to menu button\n                setTimeout(() => {\n                    const statusMsg = document.getElementById('status-message');\n                    const okBtn = document.getElementById('btn-status-ok');\n                    okBtn.textContent = 'Main Menu';\n                    okBtn.onclick = () => {\n                        statusMsg.classList.add('hidden');\n                        this.returnToMenu();\n                    };\n                }, 100);\n            }\n\n            showStatus(title, text) {\n                const statusMsg = document.getElementById('status-message');\n                document.getElementById('status-title').textContent = title;\n                document.getElementById('status-text').textContent = text;\n                statusMsg.classList.remove('hidden');\n                \n                document.getElementById('btn-status-ok').onclick = () => {\n                    statusMsg.classList.add('hidden');\n                };\n            }\n\n            updateMoveHistory() {\n                const moveList = document.getElementById('move-list');\n                moveList.innerHTML = '';\n\n                const history = this.engine.moveHistory;\n                for (let i = 0; i < history.length; i += 2) {\n                    const moveNum = document.createElement('div');\n                    moveNum.className = 'move-number';\n                    moveNum.textContent = `${Math.floor(i / 2) + 1}.`;\n                    moveList.appendChild(moveNum);\n\n                    const whiteMove = document.createElement('div');\n                    whiteMove.textContent = this.formatMove(history[i]);\n                    moveList.appendChild(whiteMove);\n\n                    const blackMove = document.createElement('div');\n                    if (i + 1 < history.length) {\n                        blackMove.textContent = this.formatMove(history[i + 1]);\n                    }\n                    moveList.appendChild(blackMove);\n                }\n\n                // Scroll to bottom\n                const container = document.getElementById('move-history');\n                container.scrollTop = container.scrollHeight;\n            }\n\n            formatMove(move) {\n                const files = 'abcdefgh';\n                const from = files[move.from.col] + (8 - move.from.row);\n                const to = files[move.to.col] + (8 - move.to.row);\n                \n                let notation = '';\n                if (move.castle === 'king') {\n                    notation = 'O-O';\n                } else if (move.castle === 'queen') {\n                    notation = 'O-O-O';\n                } else {\n                    const pieceSymbol = move.piece === 'pawn' ? '' : move.piece[0].toUpperCase();\n                    const capture = move.captured ? 'x' : '';\n                    notation = pieceSymbol + capture + to;\n                    if (move.promotion) {\n                        notation += '=' + move.promotion[0].toUpperCase();\n                    }\n                }\n                \n                return notation;\n            }\n\n            updateCapturedPieces() {\n                const playerCaptured = document.getElementById('player-captured');\n                const opponentCaptured = document.getElementById('opponent-captured');\n                \n                playerCaptured.innerHTML = '';\n                opponentCaptured.innerHTML = '';\n\n                for (let piece of this.engine.capturedPieces.black) {\n                    const img = document.createElement('img');\n                    img.className = 'captured-piece';\n                    img.src = assets[`chess_${piece.type}_black`].data.src;\n                    playerCaptured.appendChild(img);\n                }\n\n                for (let piece of this.engine.capturedPieces.white) {\n                    const img = document.createElement('img');\n                    img.className = 'captured-piece';\n                    img.src = assets[`chess_${piece.type}_white`].data.src;\n                    opponentCaptured.appendChild(img);\n                }\n            }\n\n            returnToMenu() {\n                this.engine = null;\n                this.gameMode = null;\n                this.gameOver = false;\n                \n                document.getElementById('hud-top').classList.add('hidden');\n                document.getElementById('hud-bottom').classList.add('hidden');\n                document.getElementById('main-menu').classList.remove('hidden');\n                \n                playMusic('music_main_menu', true);\n            }\n\n            async savePlayerState() {\n                try {\n                    // Ensure state is JSON-serializable (no functions, no undefined values)\n                    const cleanState = {\n                        level: this.playerState.level || 1,\n                        xp: this.playerState.xp || 0,\n                        pieceXP: this.playerState.pieceXP || {\n                            king: 0, queen: 0, rook: 0,\n                            bishop: 0, knight: 0, pawn: 0\n                        },\n                        statistics: {\n                            gamesPlayed: this.playerState.statistics?.gamesPlayed || 0,\n                            wins: this.playerState.statistics?.wins || 0,\n                            losses: this.playerState.statistics?.losses || 0,\n                            draws: this.playerState.statistics?.draws || 0,\n                            totalCaptures: this.playerState.statistics?.totalCaptures || 0,\n                            fastestCheckmate: this.playerState.statistics?.fastestCheckmate || null,\n                            longestGame: this.playerState.statistics?.longestGame || null\n                        },\n                        matchHistory: this.playerState.matchHistory || []\n                    };\n\n                    lib.log('Saving player state...');\n                    const result = await lib.saveUserGameState(cleanState);\n                    \n                    // Validate save result\n                    if (result && result.state) {\n                        lib.log(`\u2713 Progress saved successfully! Level ${cleanState.level}, XP ${cleanState.xp}, Wins ${cleanState.statistics.wins}`);\n                        return result;\n                    } else {\n                        lib.log('\u26a0 Save returned unexpected result:', JSON.stringify(result));\n                        return result;\n                    }\n                } catch (e) {\n                    lib.log(`\u2717 Failed to save progress: ${e.message || e.toString()}`);\n                    console.error('Save error details:', e);\n                    throw e;\n                }\n            }\n\n            async submitScoreToLeaderboard() {\n                try {\n                    const wins = this.playerState.statistics?.wins || 0;\n                    lib.log(`Submitting score to leaderboard: ${wins} wins`);\n                    \n                    const response = await lib.addPlayerScoreToLeaderboard(wins, 10);\n                    \n                    if (response.success) {\n                        lib.log(`\u2713 Leaderboard updated! Your rank: ${response.userRank}`);\n                        return response;\n                    } else {\n                        lib.log('\u26a0 Leaderboard update returned no success flag');\n                        return response;\n                    }\n                } catch (e) {\n                    lib.log(`\u2139 Leaderboard unavailable: ${e.message || e.toString()}`);\n                    // Game continues normally without leaderboard\n                    return null;\n                }\n            }\n        }\n\n        // ===== UI LISTENERS =====\n        function setupUIListeners() {\n            // Main menu buttons\n            document.getElementById('btn-vs-ai').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                document.getElementById('main-menu').classList.add('hidden');\n                gameState.startGame('ai');\n            });\n\n            document.getElementById('btn-local-2p').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                document.getElementById('main-menu').classList.add('hidden');\n                gameState.startGame('local');\n            });\n\n            document.getElementById('btn-statistics').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                showStatistics();\n            });\n\n            // Action buttons\n            document.getElementById('btn-hint').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                showHint();\n            });\n\n            document.getElementById('btn-undo').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                // Undo not implemented in Phase 1\n            });\n\n            document.getElementById('btn-settings').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                document.getElementById('pause-menu').classList.remove('hidden');\n            });\n\n            document.getElementById('btn-resign').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                gameState.showStatus('Resign Game?', 'Are you sure you want to resign?');\n                const okBtn = document.getElementById('btn-status-ok');\n                okBtn.textContent = 'Yes, Resign';\n                okBtn.onclick = () => {\n                    document.getElementById('status-message').classList.add('hidden');\n                    gameState.handleGameEnd('checkmate');\n                };\n            });\n\n            // Pause menu\n            document.getElementById('btn-resume').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                document.getElementById('pause-menu').classList.add('hidden');\n            });\n\n            document.getElementById('btn-main-menu').addEventListener('click', () => {\n                playSound('sfx_ui_click');\n                document.getElementById('pause-menu').classList.add('hidden');\n                gameState.returnToMenu();\n            });\n\n            // Hover sounds\n            document.querySelectorAll('.menu-button, .action-button').forEach(btn => {\n                btn.addEventListener('mouseenter', () => {\n                    playSound('sfx_ui_hover');\n                });\n            });\n        }\n\n        function showHint() {\n            if (!gameState.engine || gameState.gameOver) return;\n            \n            const moves = gameState.engine.getAllLegalMoves();\n            if (moves.length > 0) {\n                const hint = moves[Math.floor(Math.random() * moves.length)];\n                gameState.selectedSquare = hint.from;\n                gameState.legalMoves = gameState.engine.getLegalMoves(hint.from.row, hint.from.col);\n                \n                setTimeout(() => {\n                    gameState.selectedSquare = null;\n                    gameState.legalMoves = [];\n                }, 2000);\n            }\n        }\n\n        async function showStatistics() {\n            const stats = gameState.playerState.statistics;\n            let msg = `\nLevel: ${gameState.playerState.level}\nXP: ${gameState.playerState.xp}\n\nGames Played: ${stats.gamesPlayed}\nWins: ${stats.wins}\nLosses: ${stats.losses}\nDraws: ${stats.draws}\nTotal Captures: ${stats.totalCaptures}\n            `.trim();\n            \n            // Try to fetch leaderboard rank\n            try {\n                const leaderboardData = await lib.getTopNEntriesFromLeaderboard(10);\n                if (leaderboardData && leaderboardData.userRank) {\n                    msg += `\\n\\nGlobal Rank: #${leaderboardData.userRank}`;\n                    \n                    if (leaderboardData.entries && leaderboardData.entries.length > 0) {\n                        msg += '\\n\\nTop Players:';\n                        leaderboardData.entries.slice(0, 5).forEach((entry, index) => {\n                            msg += `\\n${index + 1}. ${entry.username}: ${entry.score} wins`;\n                        });\n                    }\n                }\n            } catch (e) {\n                // Leaderboard not available, continue without it\n            }\n            \n            gameState.showStatus('Statistics', msg);\n        }\n    </script>\n</body>\n</html>", "game_config": "{\n  \"settings\": {\n    \"aiDifficulty\": \"medium\",\n    \"timeControl\": 0,\n    \"powerSquaresEnabled\": false,\n    \"powerSquareCount\": 3,\n    \"powerSquareFrequency\": 5,\n    \"animationSpeed\": 1,\n    \"particleIntensity\": \"medium\",\n    \"masterVolume\": 0.7,\n    \"musicVolume\": 0.5,\n    \"sfxVolume\": 0.8\n  }\n}", "game_design_document": "## Core Game Loop and Mechanics\n\nChess Revolution transforms traditional chess into an engaging, progression-driven experience while maintaining the integrity of classic chess rules.\n\n**Moment-to-Moment Gameplay:**\n- Players make strategic chess moves following official rules\n- Visual feedback shows legal moves when selecting pieces\n- Pieces animate smoothly between squares\n- Capture animations play when pieces are taken (optional, can be toggled)\n- Power squares glow and grant temporary abilities when landed on\n- Hero abilities can be activated once per game at strategic moments\n\n**Progression and Engagement:**\n- Players earn XP after each match based on performance\n- Pieces level up individually, unlocking cosmetic upgrades\n- Completing matches unlocks new boards, themes, and hero abilities\n- Daily challenges and puzzle completion reward coins and trophies\n- Adventure Mode provides story-driven progression through chess masters\n\n**Win/Lose Conditions:**\n- Standard chess rules: checkmate, stalemate, resignation, time expiration\n- Adventure Mode: defeat AI opponents with special conditions\n- Puzzle Mode: find the correct sequence within move limits\n\n**Replayability:**\n- Multiple game modes (Classic, Power Chess, Chaos modes)\n- AI difficulty scaling from beginner to grandmaster\n- Cosmetic progression keeps players engaged\n- Daily puzzles and challenges refresh content\n\n## Starting Scope\n\nFor the initial implementation, we'll focus on creating a **polished, playable core experience** that demonstrates the game's unique features while keeping complexity manageable.\n\n**Phase 1 - Initial Release (Implement Now):**\n\n1. **Classic Chess Mode**\n   - Full chess rules implementation with legal move validation\n   - Single player vs AI (Easy and Medium difficulty only)\n   - Local 2-player mode on same device\n   - Move highlighting and basic hints\n   - Clean, intuitive UI for piece selection and movement\n\n2. **Power Squares System**\n   - 2-3 power squares appear randomly on board after turn 5\n   - Three power-up types: Extra Move, Shield, Knight Boost\n   - Visual indicators (glowing squares, particle effects)\n   - Clear UI feedback when powers are active\n\n3. **One Themed Board**\n   - Start with \"Floating Sky Kingdom\" theme\n   - Animated background elements\n   - Smooth camera transitions\n   - Beautiful lighting and atmosphere\n\n4. **Basic Progression**\n   - Player level and XP system\n   - Piece XP tracking (visual only, no unlocks yet)\n   - Match history (last 10 games)\n   - Simple statistics (wins, losses, captures)\n\n5. **Essential UI/UX**\n   - Main menu with mode selection\n   - In-game pause menu\n   - Settings (sound, animations on/off, board rotation)\n   - Move history display\n   - Timer display for timed modes\n   - Check/checkmate notifications\n\n6. **Polish Elements**\n   - Smooth piece movement animations\n   - Capture animations (simple, elegant)\n   - Sound effects for moves, captures, check\n   - Background music (calm, strategic)\n   - Particle effects for special moves\n\n**Phase 2 - Future Iterations (Plan For Later):**\n\n- Chess Heroes system with special abilities\n- Additional AI difficulties (Hard, Expert, Grandmaster)\n- More themed boards (5+ additional themes)\n- Adventure Mode with world map\n- Puzzle Kingdom with daily challenges\n- Piece evolution and cosmetic unlocks\n- Battle Chess cinematic animations\n- Chaos Chess modes (Fog of War, Random positions)\n- Time Attack Arena modes\n- Chess Academy AI analysis\n- Online multiplayer\n- Spectator mode and replays\n- Custom board/piece creator\n\n## Game Perspective\n\n**3D Third-Person Isometric View**\n\nThe game uses a dynamic 3D isometric perspective that provides:\n- Clear view of the entire chess board\n- Ability to rotate camera 360\u00b0 around the board\n- Smooth zoom in/out for better piece visibility\n- Cinematic camera angles during special moments (checkmate, power-up activation)\n- Optional board flip to always show current player's perspective\n\nThe camera is positioned at a 45\u00b0 angle above the board, providing depth while maintaining clarity of all pieces and squares.\n\n## Game World and Level Design\n\n**The Chess Board:**\n- Standard 8x8 chess board\n- Each square is clearly defined with alternating colors\n- Squares highlight on hover/touch to show interactivity\n- Legal move indicators appear as subtle glows or markers\n- Power squares pulse with colored light (gold for Extra Move, blue for Shield, purple for Knight Boost)\n\n**Floating Sky Kingdom Theme (Initial Board):**\n- Chess board floats on a cloud platform\n- Animated clouds drift in background\n- Soft sunlight creates dynamic shadows\n- Gentle wind particles flow across the scene\n- Distant floating islands visible in background\n- Sky transitions from dawn to dusk during long matches\n- Board edges have ornate golden railings\n\n**Piece Positioning:**\n- Standard chess starting positions\n- Pieces are 3D models with clear silhouettes\n- White pieces: Bright marble with gold accents\n- Black pieces: Dark obsidian with silver accents\n- Pieces cast subtle shadows on board\n- Selected piece lifts slightly and glows\n\n**UI Layout (Mobile-First, 720\u00d71280):**\n\n**Top Section (0-200px):**\n- Opponent info bar: avatar, name, captured pieces, timer\n- Score/level indicators\n\n**Middle Section (200-1000px):**\n- Main chess board (centered, ~700\u00d7700px visible area)\n- Camera controls (rotate buttons on sides)\n- Power square indicators\n\n**Bottom Section (1000-1280px):**\n- Player info bar: avatar, name, captured pieces, timer\n- Move history (scrollable, collapsible)\n- Action buttons: Undo, Hint, Settings, Resign\n- Hero ability button (when implemented)\n\n## Edit Mode Design\n\nEdit mode allows players to customize their chess experience and create unique scenarios.\n\n**Phase 1 - Basic Customization:**\n\n1. **Visual Settings**\n   - Board theme selection (when more themes added)\n   - Piece skin selection (when unlocked)\n   - Animation speed (0.5x, 1x, 1.5x, 2x)\n   - Particle effects intensity (Off, Low, Medium, High)\n   - Camera sensitivity\n\n2. **Gameplay Settings**\n   - AI difficulty selection\n   - Time control (No limit, 5min, 10min, 15min, 30min)\n   - Power squares enabled/disabled\n   - Number of power squares (1-5)\n   - Power square spawn frequency (every 3, 5, or 7 turns)\n\n3. **Audio Settings**\n   - Master volume\n   - Music volume\n   - SFX volume\n   - Background music selection (when multiple tracks added)\n\n**Phase 2 - Advanced Customization (Future):**\n\n4. **Board Editor**\n   - Custom starting positions\n   - Piece placement tool\n   - Save/load custom scenarios\n   - Share scenarios with friends\n\n5. **Cosmetic Unlocks**\n   - Piece skins (unlocked through progression)\n   - Board themes (unlocked through progression)\n   - Particle effects (unlocked through progression)\n   - Victory animations (unlocked through progression)\n\n**Constraints:**\n- Custom positions must be legal chess positions\n- Both kings must always be present\n- No more than 16 pieces per side\n- Pawns cannot be on first or eighth rank\n- Time controls between 1 minute and 60 minutes\n- Power squares limited to 1-5 active at once\n\n## Control Design\n\nChess Revolution uses a **tap/click-to-select, tap/click-to-move** control scheme optimized for both mobile touch and desktop mouse input.\n\n**Mobile Controls (Touch):**\n\n1. **Piece Selection and Movement**\n   - Tap a piece to select it (piece lifts and glows, legal moves highlight)\n   - Tap a highlighted square to move the piece there\n   - Tap the selected piece again or tap elsewhere to deselect\n   - Drag-and-drop also supported: press and hold piece, drag to destination, release\n\n2. **Camera Controls**\n   - Two-finger pinch to zoom in/out\n   - Two-finger drag to rotate camera around board\n   - Double-tap empty area to reset camera to default view\n   - Rotate buttons on left/right edges (90\u00b0 rotation)\n\n3. **UI Interactions**\n   - Tap buttons for actions (Hint, Undo, Settings, etc.)\n   - Swipe move history panel to scroll\n   - Tap and hold piece for info tooltip\n\n4. **Special Actions**\n   - Tap power square indicator to see power description\n   - Tap hero ability button when available (Phase 2)\n   - Tap captured pieces to see details\n\n**Desktop Controls (Keyboard + Mouse):**\n\n1. **Piece Selection and Movement**\n   - Click piece to select (legal moves highlight)\n   - Click highlighted square to move\n   - Click selected piece or elsewhere to deselect\n   - Drag-and-drop supported: click and hold, drag, release\n\n2. **Camera Controls**\n   - Mouse wheel to zoom in/out\n   - Right-click and drag to rotate camera\n   - Middle-click to reset camera\n   - Q/E keys for 90\u00b0 rotation left/right\n   - R key to reset camera\n\n3. **Keyboard Shortcuts**\n   - H - Toggle hints\n   - U - Undo last move (if allowed)\n   - ESC - Pause menu\n   - Space - Confirm move (when piece selected)\n   - Arrow keys - Navigate board (highlight squares)\n   - Enter - Select highlighted square\n\n4. **UI Interactions**\n   - Click buttons for actions\n   - Hover for tooltips\n   - Scroll wheel on move history to scroll\n\n**Input Handling Requirements:**\n\n- Clear visual feedback for all interactions (hover states, selection glow)\n- Prevent accidental moves with confirmation for critical actions\n- Disable controls during animations (piece movement, captures)\n- Handle touch and mouse simultaneously (hybrid devices)\n- Prevent default browser behaviors (pinch zoom, context menu on long press)\n- Clear input state on window blur\n- Support for both left and right-handed players (UI elements accessible from both sides)\n\n**Accessibility:**\n- Large touch targets (minimum 96\u00d796px for buttons)\n- Clear visual indicators for selected pieces and legal moves\n- Haptic feedback on mobile for piece selection and moves\n- Sound cues for all actions\n- Colorblind-friendly board themes (Phase 2)\n\n## Art Style and Visual Theme\n\n**Overall Aesthetic: Premium 3D Fantasy Chess**\n\nChess Revolution combines classical chess elegance with modern 3D graphics and fantasy elements, creating a visually stunning yet readable game board.\n\n**Art Style:**\n- **3D Realistic with Fantasy Elements**: Pieces and board have realistic materials (marble, metal, wood) but with magical/fantasy enhancements (glows, particles, ethereal effects)\n- **High Polish**: Smooth surfaces, realistic lighting, subtle reflections\n- **Readable Silhouettes**: Despite 3D complexity, pieces maintain clear, recognizable shapes\n- **Cinematic Quality**: Professional lighting, depth of field, atmospheric effects\n\n**Color Palette:**\n\n*Primary Colors:*\n- **White Pieces**: Bright ivory marble with warm gold accents and trim\n- **Black Pieces**: Deep obsidian black with cool silver/platinum accents\n- **Board Light Squares**: Cream white with subtle texture\n- **Board Dark Squares**: Rich mahogany brown\n\n*Accent Colors:*\n- **Power Squares**: \n  - Extra Move: Radiant gold (#FFD700)\n  - Shield: Protective blue (#4169E1)\n  - Knight Boost: Mystic purple (#9370DB)\n- **UI Accents**: Gold for primary actions, silver for secondary\n- **Highlights**: Soft cyan for legal moves, red for threats/checks\n\n**Lighting and Atmosphere:**\n- Soft, directional sunlight from top-right creates natural shadows\n- Ambient lighting prevents harsh shadows\n- Rim lighting on pieces for depth and separation\n- Subtle god rays through clouds in Floating Sky Kingdom\n- Pieces have slight self-illumination on metallic parts\n- Power squares emit localized colored light\n\n**Visual Effects:**\n- **Particle Systems**: \n  - Sparkles around power squares\n  - Dust motes in sunbeams\n  - Magical trails when pieces move\n  - Explosion/impact effects on captures\n- **Animations**:\n  - Smooth piece movement (0.3-0.5s duration)\n  - Piece rotation when captured (tumbling effect)\n  - Board square pulse on selection\n  - Camera smooth transitions\n- **Post-Processing**:\n  - Subtle bloom on bright elements\n  - Slight vignette to focus attention on board\n  - Depth of field (background slightly blurred)\n\n**Asset Specifications:**\n\n*Chess Pieces (3D Models):*\n- **Style**: Classical Staunton design with fantasy enhancements\n- **Size**: King ~120px tall, Pawn ~80px tall (relative scale)\n- **Detail Level**: High poly for close-ups, optimized for performance\n- **Materials**: PBR materials (albedo, metallic, roughness, normal maps)\n- **Variations**: White set (marble/gold), Black set (obsidian/silver)\n\n*Board:*\n- **Size**: 8\u00d78 grid, each square ~80\u00d780px in game space\n- **Materials**: Polished wood/stone with subtle grain texture\n- **Border**: Ornate frame with coordinate labels (a-h, 1-8)\n- **Elevation**: Slightly raised squares for depth\n\n*Environment (Floating Sky Kingdom):*\n- **Background**: Layered cloud parallax (3-4 layers)\n- **Sky**: Gradient from light blue (horizon) to deeper blue (zenith)\n- **Floating Islands**: Distant, silhouetted, various sizes\n- **Platform**: Cloud-like base with golden railings\n- **Atmosphere**: Soft, dreamy, peaceful\n\n*UI Elements:*\n- **Style**: Modern minimalist with fantasy touches\n- **Buttons**: Rounded rectangles with subtle gradients and borders\n- **Icons**: Clean, vector-style with gold/silver accents\n- **Fonts**: \n  - Headings: Elegant serif (Cinzel or similar)\n  - Body: Clean sans-serif (Roboto or similar)\n- **Panels**: Semi-transparent dark backgrounds with subtle borders\n\n**Consistency Guidelines:**\n- All pieces viewed from same isometric angle\n- Consistent lighting direction across all assets\n- Unified material quality (all marble has same finish)\n- Matching level of detail across all 3D elements\n- Coherent fantasy-realism blend throughout\n\n**Technical Rendering:**\n- Use Three.js for 3D rendering\n- WebGL for performance\n- Texture atlases for efficiency\n- LOD (Level of Detail) for pieces when zoomed out\n- Optimized shaders for mobile performance\n\n## Additional Game-Specific Elements\n\n**Chess Rules Implementation:**\n\nThe game must implement complete, official chess rules including:\n- Standard piece movements (King, Queen, Rook, Bishop, Knight, Pawn)\n- Special moves: Castling (kingside and queenside), En passant, Pawn promotion\n- Check and checkmate detection\n- Stalemate, insufficient material, threefold repetition, fifty-move rule\n- Legal move validation (cannot move into check, must resolve check)\n\n**AI System (Phase 1 - Easy and Medium):**\n\n*Easy AI:*\n- Random legal moves with slight preference for captures\n- No lookahead or position evaluation\n- Makes obvious blunders\n- Target: Beginner players (0-800 ELO equivalent)\n\n*Medium AI:*\n- 2-3 move lookahead using minimax algorithm\n- Basic position evaluation (material count, piece activity)\n- Recognizes simple tactics (forks, pins)\n- Avoids hanging pieces\n- Target: Intermediate players (800-1400 ELO equivalent)\n\n**Power-Up System Details:**\n\n*Extra Move Power:*\n- Grants one additional move immediately after current move\n- Cannot be used to move the same piece twice in a row\n- Visual: Golden aura around piece, \"Extra Move!\" text\n- Duration: One turn only\n\n*Shield Power:*\n- Protects piece from capture for one full turn (opponent's next move)\n- Shielded piece glows with blue energy field\n- Shield breaks if piece moves\n- Visual: Blue force field around piece\n\n*Knight Boost Power:*\n- Knight can move like a queen for one turn\n- Retains ability to jump over pieces\n- Visual: Purple energy trails, extended move indicators\n\n*Power Square Mechanics:*\n- Spawn randomly on empty squares starting turn 5\n- Maximum 3 power squares active at once\n- Disappear after 5 turns if not used\n- Cannot spawn on squares adjacent to kings\n- Power activates immediately when piece lands on square\n\n**Timer System:**\n\n- Countdown timer for each player\n- Time displayed prominently in player info bars\n- Visual warning when time drops below 30 seconds (red pulsing)\n- Audio warning at 10 seconds\n- Time increments per move (optional, Phase 2)\n- Pause functionality in single-player\n\n**Move Validation and Feedback:**\n\n- Instant validation of legal moves\n- Visual indicators for:\n  - Legal moves (cyan highlight)\n  - Captures (red highlight)\n  - Castling (special indicator)\n  - En passant (special indicator)\n  - Check (red glow on king)\n  - Checkmate (dramatic effect)\n- Illegal move attempts show brief red flash and error sound\n- Move history shows algebraic notation\n\n**Progression System (Phase 1 - Basic):**\n\n*Player XP:*\n- Earn XP for: Winning games (+100), Capturing pieces (+10 each), Checkmate (+50 bonus)\n- Level up every 500 XP\n- Level displayed on main menu and profile\n\n*Piece XP:*\n- Each piece type tracks XP separately\n- Earn XP when piece: Captures (+5), Survives game (+2), Delivers check (+10)\n- Visual indicator shows XP bar under piece when selected\n- No unlocks in Phase 1, just tracking\n\n*Statistics Tracking:*\n- Total games played\n- Wins/losses/draws\n- Total captures\n- Fastest checkmate\n- Longest game\n- Favorite piece (most captures)\n\n**Sound Design:**\n\n*Music:*\n- Main menu: Orchestral, mysterious, strategic\n- Gameplay: Calm, focused, classical-inspired\n- Victory: Triumphant fanfare\n- Defeat: Somber but respectful\n\n*Sound Effects:*\n- Piece selection: Soft \"click\"\n- Piece movement: Smooth \"slide\" with stone-on-wood sound\n- Capture: Impact sound with subtle crash\n- Check: Warning chime\n- Checkmate: Dramatic chord\n- Power-up activation: Magical \"whoosh\" with unique tone per power\n- UI interactions: Subtle clicks and confirmations\n- Timer warning: Urgent ticking\n\n**Performance Optimization:**\n\n- Target 60 FPS on mobile devices\n- Efficient 3D rendering with Three.js\n- Texture compression and atlasing\n- Particle system pooling\n- Animation frame limiting during background\n- Progressive asset loading\n- Fallback to simpler graphics on low-end devices\n\n**Accessibility Features (Phase 1):**\n\n- High contrast mode option\n- Piece movement sound cues\n- Clear visual indicators for all game states\n- Large, readable fonts\n- Colorblind-friendly highlights (Phase 2)\n- Screen reader support for UI (Phase 2)", "persistent_storage_config": {"leaderboard": {"sort_ascending": false}}, "game_metadata": {"game_id": "01KT6WZY0AM9KD1S14Q1447YGM", "title": "Chess Revolution", "description": "Master chess with stunning 3D visuals, unique power-ups, and epic battle animations in this next-gen strategy experience!", "thumbnail_url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/thumbnail_b46434a0-1cb3-4d2a-9453-37b13b9d108e.webp", "created_at": 1780495790, "updated_at": 1781447113774.1814, "art_style": null}, "task_plan": null}