{"asset_map": {"cake_stand": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/cake_stand_632cf487-78b1-4715-b805-9062462e92d3.webp", "type": "image", "prompt": "Generate a high-quality cartoon illustration of a classic white porcelain cake stand. 3/4 angle view showing a wide, flat circular top platform and an elegant pedestal stem. Bright colors, soft shading, and subtle highlights to suggest a ceramic shine. Clean rounded edges, professional game asset, transparent background.", "description": "A decorative porcelain cake stand for displaying ice cream cakes.", "subtype": "object", "aspect_ratio": [972, 755], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_vanilla": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_vanilla_23b6959e-c224-4f2c-b82b-d6abe9bd16ad.webp", "type": "image", "prompt": "Generate a creamy vanilla ice cream layer for a cake. Side view (15-20 degree angle), thick cylindrical disc shape. Pale yellow off-white color, smooth glossy texture with gentle gradients and top highlights. Clean cartoon style, appetizing, transparent background.", "description": "A single cylindrical layer of vanilla ice cream.", "subtype": "object", "aspect_ratio": [1152, 734], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_chocolate": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_chocolate_496ba629-6b89-4751-b054-dcea37a9e20b.webp", "type": "image", "prompt": "Generate a rich chocolate ice cream layer for a cake. Side view (15-20 degree angle), thick cylindrical disc shape matching the dimensions of image 1. Deep brown color, smooth creamy texture with glossy highlights. Clean cartoon style, appetizing, transparent background.", "description": "A single cylindrical layer of rich chocolate ice cream.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_strawberry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_strawberry_3db875eb-5b50-4303-be1f-3776458ad951.webp", "type": "image", "prompt": "Generate a vibrant pink strawberry ice cream layer for a cake. Side view (15-20 degree angle), thick cylindrical disc shape matching the dimensions of image 1. Light red/pink color, smooth creamy texture with glossy highlights. Clean cartoon style, appetizing, transparent background.", "description": "A single cylindrical layer of sweet strawberry ice cream.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "topping_chocolate_chips": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_chocolate_chips_0b12654e-2c38-4281-a748-af39b0eb18ba.webp", "type": "image", "prompt": "Transform the scattered chips from image 1 into a SINGLE, standalone chocolate chip. Generate one individual dark chocolate chip with a classic teardrop shape, featuring a slight glossy shine and subtle highlights. Side view from a slight angle to emphasize its 3D form. Clean, professional game asset style, sharp edges, high resolution, transparent background.", "description": "A single, high-quality individual dark chocolate chip for precise cake decoration.", "subtype": "object", "aspect_ratio": [640, 739], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "topping_rainbow_sprinkles": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_rainbow_sprinkles_57ca7f26-832c-4ce0-9bb4-dda7b67114e6.webp", "type": "image", "prompt": "Transform the dense scatter in image 1 into a very sparse collection of just 3 to 5 individual cylindrical rainbow sprinkles. Show distinct pieces in pink, blue, yellow, and green colors arranged loosely with significant space between them. Each sprinkle should be clearly visible and detailed. Clean transparent background, high resolution, game-ready asset, top-down view.", "description": "A small set of individual rainbow sprinkles used as a sparse cake topping.", "subtype": "object", "aspect_ratio": [618, 610], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "topping_strawberry_slices": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_strawberry_slices_86549fe5-011d-4d59-a8ba-93fad5c06be4.webp", "type": "image", "prompt": "Transform the multiple strawberry slices in image 1 into ONE SINGLE prominent strawberry slice. Generate a high-resolution, detailed fresh red strawberry wedge with visible tiny seeds and a glossy, juicy highlight. The slice should be shown from a slight side angle to see the texture, presented as a clean game-ready asset on a transparent background. Match the color and artistic style of the original strawberry slices.", "description": "A single, fresh, and appetizing strawberry slice with visible seeds and juicy highlights.", "subtype": "object", "aspect_ratio": [750, 677], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "decoration_cherry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_cherry_a0da8602-ca99-4ce9-b2c3-1fcd5012fc8a.webp", "type": "image", "prompt": "Generate a single maraschino cherry with a stem. 3/4 angle, perfectly round and plump. Vibrant red color with a high-gloss glass-like shine and strong highlights. Dark green/brown curved stem. Cartoon style, appetizing, transparent background.", "description": "A glossy red maraschino cherry with a stem.", "subtype": "object", "aspect_ratio": [757, 1290], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "decoration_chocolate_drizzle": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_chocolate_drizzle_960f2dbf-35e7-4dff-8474-3e7550a20a68.webp", "type": "image", "prompt": "Generate dark chocolate sauce drizzle lines. Front view, showing vertical wavy drips of varying thickness with small pools at the bottom. Glossy liquid texture with bright highlights. Professional cartoon illustration, transparent background.", "description": "Glossy chocolate sauce drizzled for cake decoration.", "subtype": "effect", "aspect_ratio": [856, 1189], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "customer_1": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/customer_1_8cc4be0e-deda-400c-ae96-3e3a2a0d494f.webp", "type": "image", "prompt": "Generate a friendly cartoon customer portrait. Front-facing head and shoulders view. Smiling expressive face, large eyes, rosy cheeks. Simple, clean illustration style, warm and inviting. High quality, transparent background.", "description": "Friendly smiling cartoon customer portrait.", "subtype": "character", "aspect_ratio": [949, 1240], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "customer_2": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/customer_2_c59a5894-a6a7-426b-b8b8-9f1881603a56.webp", "type": "image", "prompt": "Generate a friendly cartoon customer portrait, matching the artistic style of image 1. Front-facing head and shoulders view. Different hairstyle and facial features from image 1. Smiling expressive face, warm colors, simple clean lines. High quality, transparent background.", "description": "A second friendly cartoon customer with a different look.", "subtype": "character", "aspect_ratio": [756, 1072], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "customer_3": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/customer_3_b5e7d188-45a2-4cb5-b107-9337fe67d52f.webp", "type": "image", "prompt": "Generate a friendly cartoon customer portrait, matching the artistic style of image 1 and 2. Front-facing head and shoulders view. Unique hairstyle, features, and clothing color. Smiling and cheerful expression. High quality, transparent background.", "description": "A third unique friendly cartoon customer portrait.", "subtype": "character", "aspect_ratio": [831, 1129], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "icon_flavors": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_flavors_54e7b4c6-67f9-4326-b205-8afb35aca3d8.webp", "type": "image", "prompt": "Generate a simple UI icon of an ice cream scoop in a bowl. Show vanilla, chocolate, and strawberry colors swirled together. Clean flat cartoon style with simple outlines. Transparent background.", "description": "UI tab icon for ice cream flavors.", "subtype": "ui", "aspect_ratio": [866, 885], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "icon_toppings": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_toppings_ade2a4f8-f0a1-4984-b60c-d0e5e7223a7c.webp", "type": "image", "prompt": "Generate a simple UI icon representing toppings. A small cluster of sprinkles, chocolate chips, and a fruit slice. Clean flat cartoon style, matching the style of image 1. Transparent background.", "description": "UI tab icon for cake toppings.", "subtype": "ui", "aspect_ratio": [611, 534], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "icon_decorations": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_decorations_6332f954-042b-402e-b1e6-92abea366394.webp", "type": "image", "prompt": "Generate a simple UI icon of a cherry with chocolate drizzle. Clean flat cartoon style, matching the style of image 1. Elegant and recognizable at small sizes. Transparent background.", "description": "UI tab icon for cake decorations.", "subtype": "ui", "aspect_ratio": [560, 892], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "star_empty": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/star_empty_862df68a-dca0-4e05-9614-0f1ba284964b.webp", "type": "image", "prompt": "Generate a simple cartoon star outline. Five-pointed star with rounded tips. Warm gray or light gold medium-thickness outline, empty inside. Transparent background.", "description": "Empty star outline for the rating system.", "subtype": "ui", "aspect_ratio": [767, 734], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "star_filled": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/star_filled_052c30c7-9de0-42e6-b89c-5cfe62b8bfd3.webp", "type": "image", "prompt": "Generate a shiny golden yellow filled star. Matches the shape and rounded tips of image 1. Subtle gradient and a soft glow, bright and rewarding. Professional cartoon style, transparent background.", "description": "Filled gold star for the rating system.", "subtype": "ui", "aspect_ratio": [1020, 978], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "coin_icon": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/coin_icon_71a8379d-81bc-48f1-aa29-2d7a80225e0f.webp", "type": "image", "prompt": "Generate a bright golden 3D coin icon. 3/4 angle view, glossy metallic finish with bright highlights. Simple rim and a currency symbol in the center. Cheerful cartoon style, transparent background.", "description": "Gold coin icon for the game currency.", "subtype": "ui", "aspect_ratio": [783, 822], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "sound_add_layer": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_add_layer_e87f5463-b758-487c-b60a-0b247906d017.mp3", "type": "audio", "prompt": "A satisfying, soft 'plop' sound effect for adding a creamy ice cream layer. Gentle, warm tone, slightly squishy but clean, medium pitch. No harsh transients, high-quality foley of soft material placement, suitable for casual mobile games.", "description": "A soft plop sound for placing a creamy ice cream layer.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 0.3, "loop": false, "animation": null}, "sound_add_topping": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_add_topping_86b175bc-0b9a-4d59-8ade-56ecad6ca62f.mp3", "type": "audio", "prompt": "Light and playful sprinkling sound effect. A series of tiny, bright taps suggesting small items falling onto a soft surface. Higher pitch, cheerful tone, scattered texture. Ideal for rainbow sprinkles or chocolate chips being added to a dessert.", "description": "A light, scattered sprinkling sound for toppings like sprinkles or nuts.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.82, "loop": false, "animation": null}, "sound_add_decoration": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_add_decoration_524079f8-9f52-411e-a077-a6bc7b616bc6.mp3", "type": "audio", "prompt": "Delicate and elegant sound effect for a finishing touch. A soft, clear chime or a gentle 'ting' with a bright shimmer. Suggests careful placement of a decorative item. Medium-high pitch, refined and clean, very brief decay.", "description": "A delicate finishing touch sound for placing cherries or candles.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 2, "loop": false, "animation": null}, "sound_submit_cake": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_submit_cake_4aef5065-e227-4875-98aa-c4a3037c3a64.mp3", "type": "audio", "prompt": "A rewarding and positive 'whoosh' to 'ding' transition sound effect. Accomplished mood, warm and full tone with an ascending pitch resolution. Suggests completion and pride. Clean production, suitable for UI feedback in a casual game.", "description": "A rewarding success sound for completing and submitting a cake order.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.32, "loop": false, "animation": null}, "sound_star_award": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_star_award_39219e79-ede8-4e99-a46f-bfa8ab5b9366.mp3", "type": "audio", "prompt": "Bright, sparkly magical chime sound effect. High-pitched twinkle quality, clear and shimmery. Short and punchy so it can be played in quick succession for multiple star awards. Celebratory and exciting fantasy-style UI sound.", "description": "A bright, magical twinkle for when a star rating appears.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.56, "loop": false, "animation": null}, "sound_coin_collect": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_coin_collect_e0d5e49d-2464-4b7f-825c-5bf0535ca433.mp3", "type": "audio", "prompt": "Satisfying coin collection sound. A bright, resonant metallic 'clink' or 'ding'. High-quality, suggests value and reward. Medium-high pitch with a very slight shimmer ring-out. Classic arcade style but polished for a modern casual game.", "description": "A classic, bright metallic clink for collecting currency.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.35, "loop": false, "animation": null}, "sound_unlock": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_unlock_a5654233-dc13-45d7-b462-3f1fb37ab7f4.mp3", "type": "audio", "prompt": "Exciting achievement sound effect for unlocking content. A short, bright fanfare or rising major chord. Celebratory, full-bodied tone, suggests a significant milestone. Positive energy, high-quality audio with a clean tail.", "description": "A celebratory fanfare for unlocking new flavors or ingredients.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.44, "loop": false, "animation": null}, "background_music": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/music/background_music_1bf21077-f3ec-40ef-9043-604ff8ac0022.mp3", "type": "audio", "prompt": "Cheerful, upbeat casual game background music for a sweet dessert shop. Light and whimsical atmosphere, featuring soft piano melodies, playful glockenspiel bells, and a gentle acoustic rhythm. Tempo ~110 BPM. Warm, inviting, and cozy cafe vibes. Seamlessly loopable, non-intrusive, and sweet. High-quality instrumental production.", "description": "Cheerful and whimsical background music for the ice cream shop.", "subtype": "music", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 60.02938775510204, "loop": true, "animation": null}, "icon_frostings": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/icon_frostings_55a564c9-588b-44fc-a04d-cc12bdaf83b6.webp", "type": "image", "prompt": "Generate a cute, simple UI tab icon for cake frostings featuring a small frosting swirl and a piping bag. Playful cartoon style, clean lines, pink and white color palette. Professional mobile game UI asset, isolated on a transparent background. Match the artistic style and level of detail of icon_flavors, icon_toppings, and icon_decorations.", "description": "UI tab icon for cake frostings featuring a pink and white frosting swirl.", "subtype": "ui", "aspect_ratio": [699, 680], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "frosting_vanilla": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_vanilla_4454f628-80cf-4412-bda2-c724a55edb57.webp", "type": "image", "prompt": "Generate a smooth layer of white vanilla frosting and icing designed to coat the outside of a cylindrical cake layer. Side view, 2D cartoon style. The icing should have a creamy white color with subtle shadows to indicate a soft, spreadable texture. Clean, polished game-ready asset for an ice cream cake maker game. Transparent background, high resolution. Match the art style of icon_frostings.", "description": "A smooth white vanilla frosting layer designed to wrap around a cylindrical cake side.", "subtype": "object", "aspect_ratio": [866, 690], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_strawberry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_strawberry_42f78baa-3be0-499b-b846-30307edf4e6d.webp", "type": "image", "prompt": "Generate a smooth layer of pink strawberry frosting or icing designed to wrap around a cylindrical cake layer. The asset should be viewed from the side, showing a pretty pink color with subtle shadows and creamy texture. Maintain a clean, polished cartoon style consistent with image 1. Transparent background, high resolution, game-ready asset.", "description": "A smooth layer of pink strawberry frosting for coating a cake layer, viewed from the side.", "subtype": "object", "aspect_ratio": [1043, 829], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_chocolate": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_chocolate_e3dee61a-6a12-4bfd-baea-6e88a0540899.webp", "type": "image", "prompt": "Generate a smooth layer of rich dark brown chocolate frosting or icing designed to wrap around a cylindrical cake layer. Side view perspective, glossy texture with subtle shadows, clean cartoon style. The frosting should look thick and delicious, matching the style of image 1 and image 2. High resolution, professional game asset, transparent background.", "description": "A smooth layer of rich chocolate frosting for coating a cake layer, viewed from the side.", "subtype": "object", "aspect_ratio": [1045, 830], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_mint": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_mint_5163cca2-86d8-4253-ae9a-fbb1af2c332b.webp", "type": "image", "prompt": "Generate a single cylindrical layer of mint chocolate chip ice cream. The ice cream should be a light pastel green color with small dark chocolate flecks throughout. Side-view perspective with clean, sharp edges. Polished cartoon game art style, matching the cylindrical shape and lighting of image 1, image 2, and image 3. High resolution, transparent background.", "description": "A single cylindrical layer of mint chocolate chip ice cream for building cakes.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_cookies_cream": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_cookies_cream_00c98a4f-7806-435b-a738-14f16d8481ed.webp", "type": "image", "prompt": "Generate a single cylindrical layer of cookies and cream ice cream, creamy white base with visible dark crushed cookie chunks throughout. Side-view perspective, clean sharp edges, consistent with the cylindrical shape of image ice_cream_vanilla. High-quality 2D cartoon game asset style, polished finish, transparent background.", "description": "A cylindrical layer of cookies and cream ice cream for cake building.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_mango": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_mango_22ae72de-acb3-4283-8868-25f890c256d1.webp", "type": "image", "prompt": "Generate a single cylindrical layer of mango ice cream with a bright golden orange-yellow color. High-quality game asset, side view, clean edges, smooth texture, transparent background. Stylistically match the existing layers in ice_cream_vanilla and ice_cream_strawberry, maintaining consistent lighting and cylindrical dimensions.", "description": "A single cylindrical layer of bright mango ice cream for building cakes.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_blueberry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_blueberry_ceb0c831-2bad-4ec1-8bfd-fdd39769cad6.webp", "type": "image", "prompt": "Generate a single cylindrical layer of blueberry ice cream, deep purple-blue color with subtle darker berry swirls. Side-view, clean smooth edges, polished cartoon game asset style. The layer should have a consistent height and width to match the existing cake layers. High resolution, detailed texture, transparent background.", "description": "A single cylindrical layer of blueberry ice cream with berry swirls.", "subtype": "object", "aspect_ratio": [1248, 794], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_caramel": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_caramel_033d02e2-4c33-4da7-b711-ff4974e299a2.webp", "type": "image", "prompt": "Generate a professional game asset of a single cylindrical layer of caramel ice cream. The ice cream has a rich golden brown color with visible caramel swirls. Side view perspective, clean sharp edges, smooth texture. Transparent background. Match the artistic style, lighting, and cylindrical dimensions of image 1.", "description": "A single cylindrical layer of rich caramel ice cream with golden swirls for cake building.", "subtype": "object", "aspect_ratio": [1241, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "topping_crushed_oreos": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_crushed_oreos_4f18032c-be5b-460a-90b8-6f632cff0610.webp", "type": "image", "prompt": "Transform the scattered crumbles in image 1 into one single, distinct broken Oreo cookie piece. Show a large chunk or half of a dark chocolate cookie with the white cream filling clearly visible. Clean, professional game asset, polished look, transparent background, front-facing view.", "description": "A single broken piece of an Oreo cookie with visible cream filling for cake decoration.", "subtype": "object", "aspect_ratio": [701, 353], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_nuts": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_nuts_358024d6-7916-45ea-8eff-c8973d6f6b6c.webp", "type": "image", "prompt": "Transform the scattered nuts in image 1 into a single, prominent light brown nut piece, like an almond or walnut fragment. Highly detailed natural texture, clean edges, professional game-ready asset, transparent background, top-down view.", "description": "A single piece of light brown nut for cake topping.", "subtype": "object", "aspect_ratio": [486, 622], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_gummy_bears": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_gummy_bears_931994b7-cf63-412f-981b-0c52f2b25ec0.webp", "type": "image", "prompt": "Transform the scattered gummy bears in image 1 into a single, prominent, and cute gummy bear. The gummy bear should be a vibrant red, orange, or yellow color with a glossy, semi-translucent jelly-like appearance. Focus on a high-quality, clean individual candy piece with soft lighting and a transparent background. Maintain the same cartoonish and friendly art style as the existing game decorations.", "description": "A single, cute, translucent gummy bear for cake decoration.", "subtype": "object", "aspect_ratio": [469, 699], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_caramel_drizzle": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_caramel_drizzle_2a4bb262-fae0-4e80-84a6-9ec55aa72994.webp", "type": "image", "prompt": "Generate a top-down view of golden caramel sauce drizzled in artistic, glossy swirls. The sauce should look delicious and reflective with rich amber tones. High resolution, clean edges, professional game asset style, transparent background. Match the artistic style and lighting of decoration_chocolate_drizzle.", "description": "Artistic golden caramel sauce drizzle for cake topping.", "subtype": "object", "aspect_ratio": [832, 1202], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_whipped_cream": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_whipped_cream_9b522491-cf60-43d1-93c0-d7b0a981d07e.webp", "type": "image", "prompt": "Generate a single dollop of whipped cream, fluffy and bright white with a perfect spiral peak at the top. Side view perspective, clean edges, cute cartoon game art style. The asset should be a high-quality, professional game-ready decoration with a transparent background. Stylistically match the existing ice cream cake decorations like decoration_cherry.", "description": "A fluffy white whipped cream dollop with a spiral peak for cake decoration.", "subtype": "object", "aspect_ratio": [744, 840], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_wafer_sticks": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_wafer_sticks_ff032c97-e57b-459f-b7eb-6a18ee74753f.webp", "type": "image", "prompt": "Change the asset in image 1 to show only a single, individual elegant rolled wafer stick instead of multiple. Maintain the exact same art style, light brown color with subtle darker stripes, and high-quality polished texture. The wafer stick should be shown from a side view, suitable for precise placement on an ice cream cake, on a transparent background.", "description": "A single elegant rolled wafer stick with light brown stripes for cake decoration.", "subtype": "object", "aspect_ratio": [1022, 562], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_candles": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_candles_ed0c9680-bf7c-48c7-8fb4-3051f9cbb339.webp", "type": "image", "prompt": "Change the group of candles in image 1 to be just a SINGLE festive birthday candle. The candle should have a glowing, flickering flame, a colorful striped pattern, and be rendered as a high-quality game asset. Perspective should be a slight side-view suitable for placing on top of a cake, with a transparent background. Maintain the cheerful cartoon style of the original.", "description": "A single festive birthday candle with a glowing flame for precise cake decoration placement.", "subtype": "object", "aspect_ratio": [171, 1197], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_star_sprinkles": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_star_sprinkles_3a3eb4cd-bb31-4970-8a56-4ae294c66c2d.webp", "type": "image", "prompt": "Change the asset in image 1 to show only a SINGLE magical star-shaped sprinkle instead of multiple. Maintain the same gold sparkly appearance, metallic sheen, and high-quality glossy finish. The single star should be centered on a transparent background, matching the style of the original sprinkles.", "description": "A single, individual magical gold star sprinkle for precise cake decoration.", "subtype": "object", "aspect_ratio": [443, 413], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "frosting_mint": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_mint_3d1a65b8-1019-4fc2-9c75-0006ef5a4231.webp", "type": "image", "prompt": "Generate a smooth layer of mint green frosting designed to wrap around a cylindrical cake side. Light green color with a subtle glossy finish, clean edges, viewed from a straight-on side perspective. The style should be polished, clean, and match the existing frosting assets like frosting_vanilla and frosting_strawberry. High resolution, transparent background.", "description": "A smooth layer of mint green frosting for coating a cake layer, viewed from the side.", "subtype": "object", "aspect_ratio": [1045, 830], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_caramel": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_caramel_366e7c07-abb4-4cd2-85f8-2cd05652095d.webp", "type": "image", "prompt": "Generate a smooth layer of rich golden brown caramel frosting designed to wrap around a cylindrical cake side. The frosting should have a glossy, polished finish and a clean, solid silhouette. Viewed from a side-on perspective to match existing cake assets. Clean edges, professional game-ready asset, transparent background. Match the style and dimensions of frosting_vanilla and frosting_chocolate.", "description": "A smooth, glossy golden brown caramel frosting layer for a cylindrical cake, viewed from the side.", "subtype": "object", "aspect_ratio": [1045, 830], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_coffee": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_coffee_049b8d20-24c4-4905-89a4-27d9304ec9c4.webp", "type": "image", "prompt": "Generate a single cylindrical layer of coffee and mocha ice cream, side-view perspective. The ice cream has a rich brown color with subtle, creamy coffee swirls. Polished cartoon style, clean edges, high-quality game asset, transparent background. Ensure it matches the height, shape, and lighting of image 1.", "description": "A cylindrical layer of coffee-flavored ice cream for cake building.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_pistachio": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_pistachio_0f6e60b0-fb57-4b45-a34a-d05167f22c5a.webp", "type": "image", "prompt": "Generate a single cylindrical layer of pistachio ice cream with a light green color and small visible pistachio bits. Side view, high-quality cartoon style, clean polished game asset. Match the perspective, lighting, and shape of the ice cream in image 1. Transparent background.", "description": "A single cylindrical layer of pistachio ice cream for building cakes.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_bubblegum": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_bubblegum_22b67bc0-6195-42ff-bdfb-8241e2639169.webp", "type": "image", "prompt": "Transform the ice cream layer in image 1 to be a solid, vibrant magenta hot pink color. Remove all blue swirls. Add small, colorful round bubblegum ball pieces (yellow, blue, green) embedded throughout the smooth pink texture. Maintain the exact cylindrical shape and side-view perspective of the original layer to ensure it fits the cake stand. High-quality, clean cartoon game art style with a transparent background.", "description": "A cylindrical layer of bright magenta bubblegum ice cream with embedded colorful gumballs for cake building.", "subtype": "object", "aspect_ratio": [1248, 794], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_lemon": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_lemon_01f65e8a-ac1e-4333-8301-54e1ca491ab7.webp", "type": "image", "prompt": "Generate a single cylindrical layer of lemon ice cream for building cakes. The asset should have a bright yellow citrus color and a smooth texture. Side view, 2D cartoon style with clean lines and soft shading, matching the visual style and dimensions of image 1. High resolution, professional quality, transparent background.", "description": "A cylindrical layer of bright yellow lemon ice cream for cake building.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "topping_marshmallows": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_marshmallows_979141a4-36d8-459a-9efe-81e59acaa11b.webp", "type": "image", "prompt": "Generate a single, cute mini marshmallow for cake decoration. It should look white, fluffy, and slightly squishy. High-quality cartoon style with clean lines and soft shading, matching the visual style of image 1. Side-view perspective, transparent background.", "description": "A single cute mini marshmallow for cake decoration.", "subtype": "object", "aspect_ratio": [651, 752], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_coconut": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_coconut_a31d1943-9386-4901-9597-457bb61916f4.webp", "type": "image", "prompt": "Generate a small, clean pile of shredded white coconut flakes for cake decoration. The flakes should look light, airy, and textured. Professional cartoon game asset style, consistent with the visual treatment of image 1. Side-view perspective, high resolution, detailed texture, transparent background.", "description": "A small pile of white shredded coconut flakes for cake topping.", "subtype": "object", "aspect_ratio": [767, 477], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_blueberries": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_blueberries_9af1dbde-aba1-4e66-9f3b-fcb72d9fb48e.webp", "type": "image", "prompt": "Generate a single, fresh, and appetizing blueberry for cake decoration. Deep blue/purple color with a glossy finish and natural highlights. Clean cartoon style, side view, transparent background, matching the art style and quality of image 1.", "description": "A single fresh blueberry for cake decoration, deep blue and glossy.", "subtype": "object", "aspect_ratio": [852, 838], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_cookie_crumbs": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_cookie_crumbs_14bbf683-6ee8-4443-b98d-d6aeca77a5dc.webp", "type": "image", "prompt": "Generate a single, small piece of golden cookie crumb for a cake topping. The crumb should look light brown, crunchy, and textured. Professional 2D cartoon style, clean polished game asset, side view, high resolution, transparent background. Match the artistic style of topping_chocolate_chips and topping_crushed_oreos.", "description": "A single small piece of golden-brown cookie crumb for cake decoration.", "subtype": "object", "aspect_ratio": [621, 581], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_chocolate_curl": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_chocolate_curl_f32269a5-d17f-4690-a71a-6e3a6892de1c.webp", "type": "image", "prompt": "Generate a single elegant dark chocolate curl shaving for cake decoration. It should be a rich dark brown color with a smooth, glossy finish and a delicate curled shape. The art style should be a clean, polished cartoon style that matches image 1. Side view, high resolution, transparent background.", "description": "A single elegant dark chocolate curl for cake decoration.", "subtype": "effect", "aspect_ratio": [1248, 685], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_fondant_flower": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_fondant_flower_fc071d0d-8437-474e-b835-74eca2fb16a0.webp", "type": "image", "prompt": "Generate a single cute fondant flower for cake decoration. Pink petals with a yellow center, delicate and pretty. Smooth edible sugar texture, side view, clean cartoon style, high resolution, transparent background, matching the visual style of existing decoration assets.", "description": "A single cute fondant flower for cake decoration with pink petals and a yellow center.", "subtype": "object", "aspect_ratio": [828, 624], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_sugar_pearls": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_sugar_pearls_85b1b6f3-fdbc-47e8-87fe-111c8ba7e777.webp", "type": "image", "prompt": "Generate a single, high-quality edible sugar pearl for cake decoration, round and glossy with a white-silver metallic sheen. Professional game asset, polished cartoon style, front view, transparent background, matching the style and lighting of image 1.", "description": "A single shiny edible sugar pearl for cake decoration.", "subtype": "object", "aspect_ratio": [623, 620], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_macaron": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_macaron_e293fb42-9b47-4b3f-8f20-93f6deac4d29.webp", "type": "image", "prompt": "Generate a single cute mini macaron for cake decoration, pastel pink color with white cream filling visible in the middle, French pastry style. Side-view perspective, clean and polished cartoon game asset style, high resolution with delicate details. Transparent background.", "description": "A single cute pastel pink mini macaron for cake decoration.", "subtype": "object", "aspect_ratio": [763, 658], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "frosting_lemon": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_lemon_7f859f83-ab64-4d06-ba2b-7440c76e87c3.webp", "type": "image", "prompt": "Generate a smooth layer of bright yellow lemon frosting for coating a cake layer, viewed from the side. It should have a clean cylindrical shape to perfectly wrap around a cake. Use a clean, polished cartoon style with subtle highlights to match the aesthetic of image 1. Transparent background, high resolution, game-ready asset.", "description": "A smooth layer of bright yellow lemon frosting designed to wrap around a cylindrical cake side.", "subtype": "other", "aspect_ratio": [1043, 829], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_blueberry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_blueberry_399c3d5f-8328-4d14-85b9-917853617367.webp", "type": "image", "prompt": "Generate a smooth layer of purple blueberry frosting designed to wrap around a cylindrical cake, viewed from the side. The frosting should have a clean, polished, cartoon-style appearance with subtle highlights and shadows to show volume. Match the artistic style, height, and cylindrical curvature of image 1. High resolution, professional game asset on a transparent background.", "description": "A smooth purple blueberry frosting layer for a cylindrical cake, viewed from the side.", "subtype": "other", "aspect_ratio": [1049, 832], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_cream_cheese": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_cream_cheese_2a283691-0077-408d-aa7e-2ce325e87842.webp", "type": "image", "prompt": "Generate a smooth layer of cream-colored cream cheese frosting for coating a cake layer, viewed from the side. The asset should have an ivory/off-white color and a cylindrical shape designed to wrap around a cake. Use a clean, polished cartoon style with soft shading to match the visual aesthetic of image 1. High resolution, transparent background, game-ready asset.", "description": "An off-white cream cheese frosting layer for a cylindrical cake, viewed from the side.", "subtype": "other", "aspect_ratio": [1044, 829], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_raspberry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_raspberry_8d900286-473c-42df-bf4a-9986d883b4d6.webp", "type": "image", "prompt": "Generate a single cylindrical layer of bright raspberry ice cream, viewed from a side-on perspective for a cake-building game. The ice cream should have a rich pink-red color with visible berry swirls and a smooth texture. The asset must be a clean, isolated object on a transparent background, matching the art style and dimensions of ice_cream_strawberry and ice_cream_blueberry. High resolution, professional game asset.", "description": "A single cylindrical layer of bright raspberry ice cream for building cakes.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_matcha": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_matcha_8a03ceaf-682a-4751-83d3-797ae6f349df.webp", "type": "image", "prompt": "Generate a single cylindrical layer of matcha green tea ice cream for a cake building game. The ice cream has a soft, light green color with a subtle earthy texture. Side view, clean 2D game asset style, polished finish. Transparent background. Match the cylindrical shape, dimensions, and lighting style of image 1.", "description": "A single cylindrical layer of matcha green tea ice cream for building cakes, viewed from the side.", "subtype": "object", "aspect_ratio": [1248, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_cotton_candy": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_cotton_candy_9393810d-e193-4586-838c-dbc05838a711.webp", "type": "image", "prompt": "Generate a single cylindrical layer of cotton candy ice cream, viewed from the side. The ice cream features dreamy, soft pastel pink and light blue swirls. It should be a clean, polished game-ready asset with a smooth texture, matching the cylindrical shape and art style of image 1. High resolution, professional quality, transparent background.", "description": "A cylindrical layer of pastel pink and blue swirled cotton candy ice cream for cake building.", "subtype": "object", "aspect_ratio": [1242, 795], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_banana": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_banana_4eb667da-0130-403f-a571-e9a9b2e7e4dd.webp", "type": "image", "prompt": "Generate a single cylindrical layer of banana ice cream, viewed from the side. The ice cream has a creamy pale yellow color and a smooth, realistic texture. Clean, professional game asset style, standing illustration on a transparent background. Maintain identical dimensions, perspective, and lighting as image 1.", "description": "A single cylindrical layer of creamy banana ice cream for cake building.", "subtype": "object", "aspect_ratio": [1248, 796], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "topping_raspberries": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_raspberries_ad201d95-95d4-4934-b902-3c9469eb3e69.webp", "type": "image", "prompt": "Generate a single, fresh, and high-quality raspberry for cake decoration. The raspberry should be deep red, glossy, and show visible drupelets with subtle highlights. View from the side, transparent background, matching the clean and polished cartoon style of topping_blueberries. High resolution, professional game asset.", "description": "A single fresh raspberry for cake decoration.", "subtype": "object", "aspect_ratio": [771, 940], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_banana_slices": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_banana_slices_db3438a2-e5ad-4428-8752-800c8fc0bf52.webp", "type": "image", "prompt": "Generate a single fresh banana slice for cake decoration, round shape, creamy yellow-white center with subtle seed patterns and light texture. Clean, polished, high-quality game asset, top-down view, transparent background. Match the artistic style and realistic lighting of image 1.", "description": "A single fresh banana slice for cake decoration with creamy texture and transparent background.", "subtype": "object", "aspect_ratio": [815, 824], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_candy_pieces": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_candy_pieces_604759de-cfc4-499a-b822-78f0f64c7c0e.webp", "type": "image", "prompt": "Generate a single, individual candy-coated chocolate piece with a bright, glossy shell, similar to an M&M. The candy should have a clean, polished look with realistic highlights and a smooth texture. Use a vibrant color like red or blue. Side-angled view, game-ready asset, transparent background. Match the cute, translucent, and glossy art style of image 1.", "description": "A single colorful candy-coated chocolate piece for cake decoration, similar to an M&M.", "subtype": "object", "aspect_ratio": [803, 631], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_graham_crumbs": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_graham_crumbs_3540c608-9e0f-42a8-96f8-72f820783b81.webp", "type": "image", "prompt": "Generate a single, small piece of golden-brown graham cracker crumb for cake decoration. The crumb should have a slightly rough, sandy texture typical of a graham cracker. High-quality game asset, sharp focus, clean edges, transparent background. Match the artistic style, lighting, and scale of image 1.", "description": "A single small piece of golden-brown graham cracker crumb for cake decoration.", "subtype": "object", "aspect_ratio": [916, 873], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_honey_drizzle": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_honey_drizzle_98cfba6e-4880-4876-84f8-52fdb07b4107.webp", "type": "image", "prompt": "Generate a high-quality, artistic golden honey drizzle for a cake topping. The honey should have a glossy, translucent amber color with realistic highlights and a viscous texture. Side view, transparent background. Ensure the artistic style and thickness match the existing `topping_caramel_drizzle` asset.", "description": "Artistic golden honey drizzle for cake topping with a glossy, translucent amber finish.", "subtype": "effect", "aspect_ratio": [832, 1117], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_mint_leaves": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_mint_leaves_99191017-02db-43c1-a855-41e3a469675b.webp", "type": "image", "prompt": "Generate a single fresh green mint leaf for cake decoration. Vibrant green color, delicate shape with serrated edges, glossy finish. Cute cartoon style with clean lines and simple shading. Match the artistic style of image 1. High resolution, transparent background, front view.", "description": "A single fresh mint leaf for cake decoration in a cute cartoon style.", "subtype": "object", "aspect_ratio": [700, 932], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_gold_flakes": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_gold_flakes_f3342a66-4038-4340-98d1-9816c07bfa85.webp", "type": "image", "prompt": "Generate a single, high-quality edible gold flake for cake decoration. The flake should be thin, irregular in shape, and have a shiny, luxurious metallic gold texture with realistic highlights. Polished cartoon style, front view, transparent background. Match the artistic style and scale of decoration_sugar_pearls.", "description": "A single edible gold flake for elegant cake decoration, featuring a shiny metallic texture.", "subtype": "object", "aspect_ratio": [616, 744], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_chocolate_heart": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_chocolate_heart_2e45a8e3-49d7-4416-9e2c-85206a86a7d4.webp", "type": "image", "prompt": "Generate a single, cute chocolate heart for cake decoration. The heart should be made of glossy dark chocolate with smooth, rounded edges and subtle highlights to show a polished finish. Front-facing view, professional game-ready asset, high resolution, clean lines, transparent background. Match the artistic style, lighting, and material quality of image 1.", "description": "A single cute chocolate heart for cake decoration.", "subtype": "effect", "aspect_ratio": [732, 670], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_unicorn_horn": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_unicorn_horn_bce29fb2-4b8b-4d57-be05-1ee82cf9388d.webp", "type": "image", "prompt": "Generate a single, cute fondant unicorn horn for cake decoration. The horn should feature soft pastel colors with a shiny gold spiral accent. Side view, high-quality 2D cartoon game asset style, polished and clean. Transparent background, professional quality, matching the artistic style of image 1.", "description": "A single cute fondant unicorn horn for whimsical cake decoration.", "subtype": "other", "aspect_ratio": [582, 805], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_sprinkle_hearts": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_sprinkle_hearts_3549942e-c2cd-4d5d-8067-e75487f912ef.webp", "type": "image", "prompt": "Generate a single, tiny heart-shaped sugar sprinkle for cake decoration. Cute glossy pink color, smooth texture, professional game-ready asset. Front-facing view, transparent background. Match the artistic style and scale of image 1.", "description": "A single tiny heart-shaped sprinkle for cake decoration.", "subtype": "object", "aspect_ratio": [420, 356], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "frosting_raspberry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_raspberry_1d7ade88-3da8-4994-bb7d-1f3ad2a83b97.webp", "type": "image", "prompt": "Generate a smooth, glossy layer of bright raspberry pink frosting designed to wrap around a cylindrical cake side, viewed from the side. High-quality game asset with a clean, polished finish and subtle highlights to show texture. The style and shape should perfectly match the existing `frosting_strawberry`. Transparent background, professional quality.", "description": "A smooth raspberry pink frosting layer designed to wrap around a cylindrical cake side.", "subtype": "other", "aspect_ratio": [1046, 831], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "frosting_matcha": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_matcha_28a20e56-e2e5-4c63-a3b1-0a126f0c4b60.webp", "type": "image", "prompt": "Generate a smooth, uniform layer of soft matcha green tea frosting designed to wrap around a cylindrical cake side. The asset should be viewed from a side-on perspective, appearing as a thick, clean band with a slight creamy texture. Style should be a polished, clean cartoon game asset with soft highlights and shadows, matching the visual aesthetic and shape of image 1. High resolution, transparent background.", "description": "A smooth matcha green frosting layer for a cylindrical cake, viewed from the side.", "subtype": "other", "aspect_ratio": [1040, 829], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_cookies_cream": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_cookies_cream_18b787a2-1896-4cac-bdd1-aa58749155de.webp", "type": "image", "prompt": "Generate a smooth layer of cookies and cream frosting designed to wrap around a cylindrical cake side, viewed from the side. The texture is a creamy light gray-white base with fine dark chocolate cookie specks throughout. Clean, polished cartoon game asset style, consistent with the shape and perspective of image 1. Transparent background, high resolution.", "description": "A smooth cookies and cream frosting layer for coating the side of a cylindrical cake.", "subtype": "other", "aspect_ratio": [1043, 829], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_peanut_butter": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_peanut_butter_eeee475f-aa9a-4704-a8f2-4ff001a01913.webp", "type": "image", "prompt": "Generate a smooth, creamy peanut butter frosting layer designed to wrap around a cylindrical cake side, viewed from the side. The color is a warm tan or light brown with a soft matte texture. Ensure it matches the perspective and artistic style of image 1. Transparent background, high quality game asset.", "description": "A creamy tan peanut butter frosting layer for cake building, viewed from the side.", "subtype": "other", "aspect_ratio": [1033, 830], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_rose": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_rose_66f39f3f-a16d-4c7d-9b39-a779844e6ce0.webp", "type": "image", "prompt": "Generate a side-view illustration of a smooth, cylindrical layer of elegant rose pink frosting. The frosting features delicate, subtle darker pink rose petal swirl patterns. Designed as a wrap-around coating for a cake, maintaining a clean cylindrical shape. Soft, cute cartoon style with polished highlights, high resolution, transparent background.", "description": "An elegant rose pink frosting layer with floral swirls for a cylindrical cake.", "subtype": "other", "aspect_ratio": [1046, 830], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_galaxy": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_galaxy_53932988-7e07-4f25-ada8-6f8ee0c34d0e.webp", "type": "image", "prompt": "Generate a smooth layer of magical galaxy frosting designed to wrap around a cylindrical cake side, viewed from the side. The texture features deep purple and dark blue swirls with tiny white sparkle dots resembling stars. Dreamy and magical appearance, clean vector-like cartoon style, high quality, transparent background.", "description": "A magical galaxy-themed frosting layer for a cylindrical cake with purple and blue swirls.", "subtype": "object", "aspect_ratio": [1195, 847], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_rainbow": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_rainbow_187781cd-cda2-4c0e-933e-e3212a7a98e3.webp", "type": "image", "prompt": "Generate a smooth layer of colorful rainbow frosting designed to wrap around a cylindrical cake side, viewed from a side perspective. The frosting features horizontal stripes of soft pastel rainbow colors\u2014red, orange, yellow, green, blue, and purple\u2014blending smoothly together. High-quality game asset, clean polished cartoon style, vibrant colors, transparent background, front-facing side view.", "description": "A smooth, pastel rainbow-striped frosting layer for the side of a cylindrical cake.", "subtype": "other", "aspect_ratio": [814, 771], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_gold_shimmer": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_gold_shimmer_7bf7ca41-cd1f-4d08-b99a-8a684b54fce8.webp", "type": "image", "prompt": "Generate a smooth layer of luxurious gold shimmer frosting designed to wrap around a cylindrical cake side, viewed from the side. The frosting should have a rich golden color with a metallic sheen and subtle sparkle effects. Maintain a clean, cute cartoon style consistent with a cake-building game. High-quality game asset, professional digital art, transparent background.", "description": "A luxurious gold shimmer frosting layer for a cylindrical cake, viewed from the side.", "subtype": "other", "aspect_ratio": [771, 612], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_lavender": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_lavender_4e941934-15bf-48c2-8de8-9d9f952397af.webp", "type": "image", "prompt": "Generate a smooth layer of soft pastel lavender purple frosting designed to wrap around the side of a cylindrical cake. The frosting has a creamy, thick texture and a clean silhouette. Side view, 2D cute cartoon style, polished game asset, high resolution with delicate shading, transparent background.", "description": "A smooth lavender purple frosting layer for a cylindrical cake, viewed from the side.", "subtype": "other", "aspect_ratio": [1046, 831], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_ombre_pink": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_ombre_pink_11442d9a-c2c4-409d-87a2-0ba579537c6b.webp", "type": "image", "prompt": "Generate a smooth layer of ombre pink frosting designed to wrap around a cylindrical cake side, viewed from a side perspective. The frosting features a beautiful vertical gradient from dark magenta pink at the bottom fading into a light blush pink at the top. Polished, clean cartoon game art style, high resolution, transparent background.", "description": "A smooth ombre pink gradient frosting layer for a cylindrical cake side.", "subtype": "other", "aspect_ratio": [1046, 831], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "frosting_bubblegum": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_bubblegum_91155c37-3e10-46dd-8745-d93c5d3de535.webp", "type": "image", "prompt": "Generate a side view of a smooth, glossy bright magenta bubblegum frosting layer designed to wrap around a cylindrical cake. The texture is creamy and features tiny, colorful gumball pieces embedded within the frosting. Maintain a clean, polished cartoon game art style consistent with a bakery or ice cream shop aesthetic. The asset should be a single horizontal band representing the side coating of a cake layer. High quality, transparent background.", "description": "A smooth magenta bubblegum frosting layer for the side of a cylindrical cake.", "subtype": "other", "aspect_ratio": [1238, 782], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_cotton_candy": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_cotton_candy_5113a850-9ef9-49c1-8d8c-95a131b46fe0.webp", "type": "image", "prompt": "Generate a smooth, side-view layer of cotton candy frosting for a cylindrical cake. The texture should look fluffy and dreamy with soft pastel pink and baby blue colors swirled together. Match the artistic style of the cotton candy ice cream asset. Clean edges, professional game-ready asset, cute cartoon style, transparent background.", "description": "A fluffy pastel pink and blue swirled cotton candy frosting layer for a cylindrical cake.", "subtype": "other", "aspect_ratio": [1244, 794], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_cheesecake": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_cheesecake_c03a3671-7deb-41f3-985b-49b57c29aabd.webp", "type": "image", "prompt": "Transform the ice cream layer in the image to be a wide, flat disc-shaped layer seen from a slight side-angle. Adjust the dimensions to be short in height and wide in width, matching the proportions of 'ice_cream_birthday_cake'. Maintain the creamy off-white color and the visible graham cracker swirls throughout the texture. The final asset should be a polished, clean game-ready illustration with a transparent background, suitable for stacking in a cake-building game.", "description": "A wide, disc-shaped layer of cheesecake ice cream with graham cracker swirls for cake building.", "subtype": "object", "aspect_ratio": [1248, 818], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_red_velvet": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_red_velvet_f0ac2438-127f-4f72-bea6-95cdcb9d7716.webp", "type": "image", "prompt": "Generate a single cylindrical layer of red velvet ice cream for building cakes, viewed from the side. The ice cream has a deep red color with visible white cream cheese swirls. Use a clean, polished cartoon style with soft shading to match the cute aesthetic of existing assets like 'ice_cream_cheesecake'. High resolution, professional quality game asset, transparent background.", "description": "A cylindrical layer of red velvet ice cream with cream cheese swirls for cake building.", "subtype": "object", "aspect_ratio": [1248, 820], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_peanut_butter": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_peanut_butter_0c0a64a4-230d-4689-b12b-9ea1de6010f5.webp", "type": "image", "prompt": "Transform the peanut butter ice cream layer from image 1 to match the exact proportions and shape of the birthday cake layer in image 2. Create a wider and flatter disc-shaped cylindrical layer of creamy tan peanut butter ice cream. Maintain a slight 3/4 top-down perspective showing the top surface. Include rich chocolate and caramel swirls within the texture. Use a cute, polished cartoon game art style with glossy highlights. Ensure a transparent background and consistent dimensions with image 2.", "description": "A wide, disc-shaped layer of peanut butter ice cream with swirls, matching the dimensions of the birthday cake layer.", "subtype": "object", "aspect_ratio": [1248, 801], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_birthday_cake": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_birthday_cake_462dd9c1-aaf6-4c1c-b3c9-914d094a2db7.webp", "type": "image", "prompt": "Generate a single cylindrical layer of birthday cake flavored ice cream for building cakes, viewed from the side. The ice cream has a creamy white vanilla base with vibrant colorful sprinkles mixed throughout. Maintain a clean, cute cartoon art style consistent with a food-based mobile game. High resolution, professional quality, transparent background, front-side perspective.", "description": "A cylindrical layer of birthday cake ice cream with colorful sprinkles, viewed from the side.", "subtype": "object", "aspect_ratio": [1008, 638], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_black_sesame": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_black_sesame_68165314-5f5d-4761-9ebf-5e9978084acd.webp", "type": "image", "prompt": "Generate a single cylindrical layer of black sesame ice cream for building cakes, viewed from the side. The ice cream has a gray and charcoal color palette with visible black sesame seed specks. Use a clean, polished cartoon style that matches the cute aesthetic of the existing ice cream layers like 'ice_cream_vanilla'. High quality, detailed texture, standing illustration on a transparent background.", "description": "A single cylindrical layer of black sesame ice cream for cake building, viewed from the side.", "subtype": "object", "aspect_ratio": [1248, 814], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ice_cream_salted_caramel": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ice_cream_salted_caramel_063623f2-170e-4617-9b1b-9626ccdc5d1c.webp", "type": "image", "prompt": "Generate a single cylindrical layer of salted caramel ice cream, viewed from the side. The ice cream has a rich golden caramel color with darker caramel swirls and tiny white salt crystal sparkles. Cute cartoon style, clean polished game asset, high resolution, professional quality. Full-body front view on a transparent background.", "description": "A single cylindrical layer of salted caramel ice cream with swirls and salt crystals for cake building.", "subtype": "object", "aspect_ratio": [1248, 799], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "topping_mini_oreos": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_mini_oreos_07e5459b-603d-4b88-93a3-b5e8ceef805d.webp", "type": "image", "prompt": "Generate a single mini chocolate sandwich cookie with white cream filling, similar to an Oreo, for a cake decoration asset. Style: cute polished cartoon, game-ready, high resolution. View: side perspective to show the layers. Transparent background, high quality, consistent with the style of topping_crushed_oreos.", "description": "A single mini Oreo cookie for cake decoration, showing the classic chocolate sandwich cookie with cream filling.", "subtype": "object", "aspect_ratio": [1244, 628], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_pretzel_pieces": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_pretzel_pieces_795b3d3c-b111-49a2-97a8-fb4d01526303.webp", "type": "image", "prompt": "Generate a single, high-quality individual pretzel piece for cake decoration. The pretzel should be a crunchy golden-brown with visible white salt crystals. Create it in a cute, clean cartoon style with soft shading and highlights to match a dessert-making game aesthetic. Front-facing view, transparent background, professional game asset.", "description": "A single small pretzel piece with salt crystals for cake decoration.", "subtype": "object", "aspect_ratio": [890, 734], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_caramel_bits": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_caramel_bits_1d88f82e-155a-4366-8f83-1b08f58ab544.webp", "type": "image", "prompt": "Generate a single small caramel candy bit for cake decoration, golden amber colored and glossy. High-quality game asset, cute cartoon style, polished look, 2D illustration. The caramel should look soft and chewy with highlights on the edges. Side view, transparent background.", "description": "A single small caramel candy bit for cake decoration, golden amber colored and glossy.", "subtype": "object", "aspect_ratio": [830, 789], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_chocolate_shavings": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_chocolate_shavings_47c7e145-109b-4ad7-8dea-57f0e2fa0129.webp", "type": "image", "prompt": "Generate a small, delicate pile of dark brown chocolate shavings and curls for cake decoration. Use a cute, clean cartoon style with soft highlights and simple shading. Side view, high resolution, transparent background, game-ready asset.", "description": "A small pile of delicate dark chocolate shavings for cake decoration.", "subtype": "object", "aspect_ratio": [1151, 678], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_toffee_bits": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_toffee_bits_0ada7829-b645-41c9-9be8-ccf2e4a6dc0e.webp", "type": "image", "prompt": "Generate a single, small toffee bit for cake decoration. It should have a golden brown, crystalline, and crunchy appearance. Use a cute, polished cartoon style with soft shading and highlights. View from a slight perspective angle. Professional game asset, high resolution, transparent background.", "description": "A single small toffee bit for cake decoration with a golden brown, crunchy texture.", "subtype": "object", "aspect_ratio": [788, 748], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "topping_peanuts": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/topping_peanuts_cd8f072f-3741-406a-8780-b625dfbe2a3b.webp", "type": "image", "prompt": "Generate a single, high-quality roasted peanut for cake decoration, light tan and brown color with realistic texture but in a cute polished cartoon style. View from a slight 3/4 angle, professional game-ready asset, isolated on a transparent background, high resolution.", "description": "A single roasted peanut for cake decoration, light tan/brown color.", "subtype": "object", "aspect_ratio": [832, 850], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_edible_glitter": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_edible_glitter_41b55b15-ce69-4f6a-8e0b-0882fbeb9b75.webp", "type": "image", "prompt": "Generate a small cluster of magical edible glitter for cake decoration, featuring shimmering gold and silver sparkles. The style should be a cute, polished cartoon game asset with a slight glow effect and tiny stars. Front view, high resolution, transparent background.", "description": "A sprinkle of magical gold and silver edible glitter for cake decoration.", "subtype": "effect", "aspect_ratio": [1219, 816], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_chocolate_shards": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_chocolate_shards_526652db-c44d-4bfd-9de7-54a745aa8e19.webp", "type": "image", "prompt": "Generate a single, elegant dark chocolate shard for cake decoration. The shard should have an angular, sharp-edged geometric shape with a smooth, glossy dark brown finish. Cute, polished cartoon game asset style with subtle highlights to show texture. Side view, transparent background, high resolution.", "description": "A single decorative dark chocolate shard for elegant cake decoration, angular and stylized.", "subtype": "object", "aspect_ratio": [668, 1391], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_candy_cane": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_candy_cane_14f5d06f-c7bf-4ce6-bae4-f735e713bd0d.webp", "type": "image", "prompt": "Generate a single mini candy cane for cake decoration, featuring classic red and white spiral stripes. The style is cute, polished cartoon game art with soft shading and glossy highlights. Professional quality game asset, standing illustration, high resolution, transparent background.", "description": "A single mini candy cane for cake decoration with classic red and white stripes.", "subtype": "object", "aspect_ratio": [589, 1159], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_gummy_worms": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_gummy_worms_c74d1d97-5e1e-46fb-87e3-cb6431dc9d33.webp", "type": "image", "prompt": "Generate a single, cute, two-toned gummy worm for cake decoration, featuring bright orange and yellow colors. The gummy worm should have a translucent, sugary texture with a glossy finish. Cute cartoon style, clean lines, high resolution, professional quality game asset. Side view, transparent background.", "description": "A single cute two-toned gummy worm for cake decoration.", "subtype": "object", "aspect_ratio": [1092, 820], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_lollipop": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_lollipop_59eebbdc-e626-4929-be04-6d0de69dcb83.webp", "type": "image", "prompt": "Generate a single, cute mini lollipop for cake decoration, featuring a vibrant colorful swirl pattern on a small white stick. Designed in a polished cartoon style with clean lines and soft shading, matching the cute aesthetic of the existing cake items. High resolution, professional quality, isolated on a transparent background, side view.", "description": "A single cute mini lollipop for cake decoration with a colorful swirl pattern.", "subtype": "object", "aspect_ratio": [803, 1395], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "decoration_strawberry": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/decoration_strawberry_d3f09a65-d0fa-49b6-afb1-825a70d15d5f.webp", "type": "image", "prompt": "Generate a single whole fresh strawberry for a cake decoration, bright red with small seeds and a small green leaf cap on top. Professional quality, clean lines, cute cartoon style with glossy highlights. Side view, 2D game asset, transparent background.", "description": "A single whole fresh strawberry for cake decoration, bright red with green leaves on top.", "subtype": "object", "aspect_ratio": [774, 954], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "frosting_red_velvet": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_red_velvet_4328a7b4-86b9-415f-895f-29dfeed88721.webp", "type": "image", "prompt": "Generate a smooth, deep red velvet frosting layer designed to wrap around the side of a cylindrical cake, viewed from a side-on perspective. The frosting should have a rich red color with a subtle creamy texture. Use a clean, polished cartoon art style consistent with a cute food decoration game. High resolution, professional quality, transparent background.", "description": "A smooth deep red velvet frosting layer for coating the side of a cylindrical ice cream cake.", "subtype": "other", "aspect_ratio": [1248, 832], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_cheesecake": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_cheesecake_91c49bd3-7c80-4a2a-870d-91afa1b4b7ba.webp", "type": "image", "prompt": "Change the color and texture of the frosting in frosting_birthday_cake to a smooth, creamy off-white cheesecake appearance. Remove the colorful sprinkles. Add subtle light-brown graham cracker swirls throughout the frosting. Maintain the exact same wide cylindrical shape, dimensions, side-view perspective, and illustrative cartoon style as frosting_birthday_cake to ensure it fits the cake layers perfectly. Transparent background.", "description": "A creamy off-white cheesecake frosting layer designed to perfectly wrap around a cylindrical ice cream cake.", "subtype": "other", "aspect_ratio": [1248, 729], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_birthday_cake": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_birthday_cake_955f892f-4394-4520-989b-acdf409c2cb5.webp", "type": "image", "prompt": "Generate a smooth white birthday cake frosting layer designed as a wide rectangular band to wrap around a cylindrical cake side. The frosting is decorated with vibrant, multi-colored rainbow sprinkles. Side-view perspective, clean lines, polished game-ready asset in a cute cartoon style. Transparent background, high resolution.", "description": "A festive white frosting layer with colorful sprinkles for the side of a cylindrical ice cream cake.", "subtype": "other", "aspect_ratio": [1235, 723], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "frosting_black_sesame": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_black_sesame_46464a52-e9a4-42e2-9d05-6ff2744c8470.webp", "type": "image", "prompt": "Generate a smooth, gray and charcoal-toned black sesame frosting layer designed to wrap around the side of a cylindrical cake. Side view, 2D cute cartoon style. The frosting should have subtle specks of black sesame seeds. Clean, polished game asset with a transparent background. High resolution, professional quality.", "description": "A smooth gray/charcoal black sesame frosting layer for a cylindrical cake side.", "subtype": "other", "aspect_ratio": [1099, 711], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "cake_mascot": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/cake_mascot_848a2fa8-2be6-4a94-bebc-4683b1ac23a2.webp", "type": "image", "prompt": "Generate a full-body, front-view illustration of a cute, friendly cartoon ice cream cake mascot character. The character is a stack of three cylindrical layers (strawberry pink, vanilla white, and chocolate brown), with big sparkly kawaii eyes and a happy smile. It has tiny cheerful arms waving. On top is a glossy red cherry with a stem acting as a hat. Pastel pink frosting drips down the sides. Include small decorative sparkles and stars around the character. Use a clean, polished kawaii art style with soft rounded features and bright, cheerful colors. Transparent background, high resolution, game-ready asset.", "description": "An adorable anthropomorphic multi-layered ice cream cake mascot for the game's loading screen and UI.", "subtype": "character", "aspect_ratio": [874, 1229], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "sound_button_click": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_button_click_7baa9666-fb9f-4623-8341-fdfb1c2df2c1.mp3", "type": "audio", "prompt": "Create a short, soft, and satisfying 'pop' sound effect for a cute dessert-themed mobile game UI. The sound should be gentle and playful, resembling a bubble popping or a light finger tap on a polished surface. It should have a high-pitched, sweet 'boop' quality without any harsh mechanical clicks or metallic tones. Clean, crisp, and extremely brief, suitable for frequent menu interactions in a whimsical ice cream cake maker game.", "description": "A soft, cute, and satisfying UI button click sound with a playful bubble-pop quality.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 0.36, "loop": false, "animation": null}, "sound_tab_switch": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_tab_switch_32fbdfb7-9da3-4d3e-ab85-66c0e07072a0.mp3", "type": "audio", "prompt": "A cute, soft 'swoosh' or 'swipe' sound effect for a kawaii UI. Light, airy, and playful high-pitched whistle-like breeze. Sounds like a gentle brush stroke or a tiny magical movement. Very short, snappy, and cheerful. Clean, minimal, non-metallic, designed for frequent menu navigation.", "description": "A cute, high-pitched soft swipe sound for UI tab navigation in a kawaii-themed game.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.14, "loop": false, "animation": null}, "sound_select": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_select_784652a0-f8a7-4489-a29b-59f7eb3b6502.mp3", "type": "audio", "prompt": "A tiny, high-pitched 'pip' or 'blip' sound effect for a kawaii mobile game. Very short, sharp attack with a high-frequency chirp, sounding like a small digital bubble or a light sparkle. Satisfying, playful, and cute. Minimal decay, clean and crisp, high-pitched frequency. 0.15 seconds duration, suitable for rapid UI interaction.", "description": "A tiny, high-pitched kawaii 'blip' for selecting ingredients, sounding like a small bubble or sparkle.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 2, "loop": false, "animation": null}, "sound_whoosh": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_whoosh_e8b1da3a-ccdf-4a76-967a-43c09e7f4e6e.mp3", "type": "audio", "prompt": "A soft, magical whoosh sound effect for a kawaii-style UI transition. Features a gentle airy wind movement layered with delicate fairy-dust sparkles and tiny crystalline chimes. Whimsical, light, and cute. High-pitched and clean with a very short, smooth decay. No dark tones, no heavy bass, suitable for a bright ice cream themed game.", "description": "A soft, magical UI whoosh sound with a sparkly texture for opening and closing menus.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.64, "loop": false, "animation": null}, "sound_pop": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_pop_de6da326-b310-42e9-b9e8-33c7bb20dc02.mp3", "type": "audio", "prompt": "A cute, high-pitched bubbly 'pop' sound effect for a kawaii-style game. Imagine a tiny soap bubble bursting or a soft miniature cork being pulled. Very short, snappy, and playful with a satisfying organic texture. Clean, no background noise, high-frequency focus, suitable for frequent UI or gameplay feedback.", "description": "A cute, bubbly pop sound for small interactions, similar to a soft cork or bubble popping.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.03, "loop": false, "animation": null}, "sound_swap": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_swap_9765755e-ae35-4d14-90a1-d43296fab1f5.mp3", "type": "audio", "prompt": "A cute and playful 'swapping' sound effect for a kawaii-style game. Two soft, rounded objects trading places with a quick double-bloop melody. High-pitched, bouncy, and squishy texture. Similar to a 'zip-zap' movement but with soft bubble-like qualities. Very short and snappy, non-aggressive, suitable for frequent use in a dessert-themed puzzle or decoration game.", "description": "A cute, bouncy double-bloop sound effect for swapping cake layers.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.05, "loop": false, "animation": null}, "sound_delete": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_delete_b0c61291-bf66-45a1-ab73-ef86e4c612fb.mp3", "type": "audio", "prompt": "A soft, gentle 'poof' or disappearing sound effect for a kawaii-style game. Magically vanishing with a soft, airy whoosh and a tiny hint of sparkle. Non-aggressive, non-negative, light and whimsical. High-pitched, clean, and satisfying, suitable for a cute ice cream shop aesthetic. Brief and subtle.", "description": "A soft, magical disappearing 'poof' sound for deleting items in a kawaii ice cream cake game.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 2, "loop": false, "animation": null}, "sound_drag": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_drag_19a62e54-856c-4fcc-937d-abb14e38c62b.mp3", "type": "audio", "prompt": "A cute, soft, and squishy 'pickup' sound effect for a kawaii-style game. High-pitched and tactile, resembling the sound of gently grasping a gummy candy or a soft marshmallow. Very short and snappy with a subtle wet/rubbery texture. Non-aggressive, playful, and satisfying. High-quality, clean, and minimalist, designed for frequent UI interaction during drag-and-drop gameplay.", "description": "A soft, squishy pickup sound for dragging decorations in a kawaii ice cream game.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.79, "loop": false, "animation": null}, "sound_drop": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_drop_bb8dc959-6106-4f23-91fc-4a950c785ec5.mp3", "type": "audio", "prompt": "A soft, satisfying 'plop' or 'drop' sound effect for a kawaii ice cream game. The sound should feel like a soft, squishy item landing gently on a creamy surface. High-pitched, cute, and bouncy with a subtle tactile squish. Clean, minimalist, and non-distressing, designed for frequent use in a playful, whimsical setting. No background noise, short decay.", "description": "A soft, cute, and satisfying 'plop' sound for placing items on a cake.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.23, "loop": false, "animation": null}, "sound_mode_switch": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_mode_switch_6f12a132-22ea-4279-934f-4382a0c0996b.mp3", "type": "audio", "prompt": "A short, cheerful magical transformation sound effect for a kawaii game. Features a bright, rising glissando of sparkly wind chimes and a soft magical twinkly dust sound. Upbeat, whimsical, and high-pitched. Clean and airy with a very fast attack and a soft shimmering decay. No dark or heavy tones, fits a sweet ice cream aesthetic.", "description": "A cheerful, magical sound effect for switching gameplay modes, featuring a sparkly chime transition.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 2, "loop": false, "animation": null}, "sound_new_order": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/sound_new_order_9ba319c7-2011-428a-bb6e-1782873ee347.mp3", "type": "audio", "prompt": "Create a cheerful, high-pitched 'ding-ding' shop bell notification for a kawaii-style ice cream game. The sound should be bright, inviting, and crystal clear, resembling a friendly service bell or a light metallic chime. It should feel rewarding and exciting, with a very quick decay and no harsh metallic resonance. Pure, clean, and cute aesthetic, suitable for frequent UI notifications.", "description": "A bright and inviting shop bell chime for new customer orders.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.35, "loop": false, "animation": null}, "frosting_mango": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_mango_bc1d83d2-455a-434e-8deb-70e0fde46ab5.webp", "type": "image", "prompt": "Generate a smooth layer of bright mango orange frosting designed to wrap around the side of a cylindrical ice cream cake, viewed from a side-on perspective. The texture should be vibrant tropical orange-yellow, glossy, and creamy. Match the clean, polished cartoon style and lighting of frosting_strawberry. Side view, high quality, transparent background.", "description": "A smooth, vibrant mango orange frosting layer for the side of a cylindrical ice cream cake.", "subtype": "other", "aspect_ratio": [1046, 831], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_coffee": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_coffee_dae14842-cbd9-460e-9649-42dceb928520.webp", "type": "image", "prompt": "Generate a smooth, glossy layer of rich coffee brown frosting designed to wrap around the side of a cylindrical ice cream cake, viewed from a side perspective. The color should be a warm medium-brown coffee tone with a creamy texture. Style should be clean, polished, and cute cartoon to match image 1. High resolution, professional game asset, transparent background.", "description": "A smooth coffee-flavored frosting layer for a cylindrical ice cream cake.", "subtype": "other", "aspect_ratio": [1047, 831], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_pistachio": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_pistachio_147dfe29-0c5a-4de0-89ea-28af2c3c58d3.webp", "type": "image", "prompt": "Generate a smooth, pale pistachio green frosting layer designed to wrap around the side of a cylindrical ice cream cake. The image should show the side-view of a thick, creamy frosting band. Use a cute, polished cartoon style with soft highlights and a glossy finish, matching the aesthetic of image 1. Transparent background, high resolution, game-ready asset.", "description": "A pale green pistachio frosting layer for a cylindrical ice cream cake side.", "subtype": "other", "aspect_ratio": [1047, 832], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_banana": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_banana_59c606af-7bf5-49e5-b878-cd773b0b9bea.webp", "type": "image", "prompt": "Generate a smooth layer of creamy banana yellow frosting designed to wrap around the side of a cylindrical ice cream cake layer, viewed from the side. Soft pale yellow color, glossy and creamy texture, cute polished cartoon game asset style. Match the perspective and artistic style of frosting_vanilla. Transparent background.", "description": "A smooth creamy banana yellow frosting layer for coating the side of a cylindrical ice cream cake.", "subtype": "other", "aspect_ratio": [1042, 828], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "frosting_salted_caramel": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/frosting_salted_caramel_346313b2-e7ce-4853-8d1d-f817f6441164.webp", "type": "image", "prompt": "Generate a smooth, rich golden amber salted caramel frosting layer designed to wrap around the side of a cylindrical ice cream cake, side-view perspective. The frosting should have a glossy, creamy texture with subtle shimmering salt crystal sparkles. Use a clean, polished cartoon style that matches the aesthetic of image 1. High resolution, professional game asset, transparent background.", "description": "A rich golden amber salted caramel frosting layer for a cylindrical ice cream cake.", "subtype": "other", "aspect_ratio": [1047, 831], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}}, "game_code": "<!DOCTYPE html>\n<html>\n<head>\n    <title>Sweet Stack Studio</title>\n    <link href=\"https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Poppins:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n    <style>\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        }\n\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\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: 'Poppins', sans-serif;\n        }\n\n        #game-world {\n            position: relative;\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n        }\n\n        #game-canvas {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\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        }\n\n        .ui-overlay > * {\n            pointer-events: auto;\n        }\n\n        /* Top Header with Title */\n        .top-header {\n            position: absolute;\n            top: 0;\n            left: 0;\n            right: 0;\n            background: linear-gradient(135deg, #FFB6C1 0%, #FFC0CB 100%);\n            padding: 8px var(--space-sm);\n            display: flex;\n            flex-direction: column;\n            gap: 8px;\n            box-shadow: 0 2px 10px rgba(255, 182, 193, 0.4);\n            border-bottom: 4px solid #FF69B4;\n            border-bottom-style: dotted;\n        }\n\n        .header-row {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            gap: 4px;\n        }\n\n        .game-title {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 26px;\n            font-weight: 700;\n            color: #E91E63;\n            text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8);\n        }\n\n        .mode-buttons {\n            display: flex;\n            gap: 4px;\n        }\n\n        .mode-btn {\n            padding: 14px 24px;\n            border: none;\n            border-radius: 20px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 18px;\n            font-weight: 600;\n            cursor: pointer;\n            transition: all var(--transition-fast) var(--ease-out);\n            background: rgba(255, 255, 255, 0.6);\n            color: #E91E63;\n            min-height: 52px;\n        }\n\n        .mode-btn.active {\n            background: white;\n            color: #E91E63;\n            box-shadow: 0 2px 8px rgba(233, 30, 99, 0.2);\n            animation: modeActivate 0.3s ease;\n        }\n\n        @keyframes modeActivate {\n            0% { transform: scale(1); }\n            50% { transform: scale(1.08); }\n            100% { transform: scale(1); }\n        }\n\n        .mode-btn:active {\n            transform: scale(0.95);\n        }\n\n        .mode-btn.gallery-top-btn {\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            color: white;\n            box-shadow: 0 2px 8px rgba(255, 105, 180, 0.4);\n        }\n\n        .mode-btn.gallery-top-btn:active {\n            transform: scale(0.95);\n        }\n\n        /* Order Card - Horizontal in Header */\n        .order-card-horizontal {\n            display: flex;\n            align-items: center;\n            gap: 12px;\n            background: linear-gradient(135deg, #FFFFFF 0%, #FFF5F8 100%);\n            padding: 12px 16px;\n            margin-top: 6px;\n            box-shadow: 0 3px 12px rgba(255, 182, 217, 0.4);\n            border-top: 2px solid rgba(255, 182, 217, 0.5);\n            border-bottom: 2px solid rgba(255, 182, 217, 0.5);\n            width: calc(100% + 32px);\n            margin-left: -16px;\n        }\n\n        .order-card-horizontal.hidden {\n            display: none;\n        }\n\n        .order-badge {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            background: linear-gradient(135deg, #FF69B4 0%, #E91E63 100%);\n            border-radius: 12px;\n            padding: 8px 14px;\n            min-width: 70px;\n            box-shadow: 0 3px 8px rgba(233, 30, 99, 0.4);\n            position: relative;\n        }\n\n        .order-badge::after {\n            content: '';\n            position: absolute;\n            right: -8px;\n            top: 50%;\n            transform: translateY(-50%);\n            width: 0;\n            height: 0;\n            border-top: 10px solid transparent;\n            border-bottom: 10px solid transparent;\n            border-left: 10px solid #E91E63;\n        }\n\n        .order-badge-label {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 11px;\n            font-weight: 600;\n            color: rgba(255, 255, 255, 0.9);\n            text-transform: uppercase;\n            letter-spacing: 0.5px;\n        }\n\n        .order-badge-number {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 22px;\n            font-weight: 700;\n            color: white;\n            text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);\n        }\n\n        .customer-avatar {\n            width: 52px;\n            height: 52px;\n            min-width: 52px;\n            border-radius: 50%;\n            overflow: hidden;\n            border: 3px solid #FF69B4;\n            display: none;\n        }\n\n        .customer-avatar img {\n            width: 100%;\n            height: 100%;\n            object-fit: cover;\n        }\n\n        .order-content {\n            display: flex;\n            flex-direction: column;\n            gap: 2px;\n            flex: 1;\n            min-width: 0;\n            padding-left: 8px;\n        }\n\n        .order-title {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 20px;\n            font-weight: 700;\n            color: white;\n            display: none;\n        }\n\n        .order-description {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 17px;\n            font-weight: 600;\n            color: #E91E63;\n            margin-bottom: 4px;\n            font-style: italic;\n        }\n\n        .order-items {\n            display: flex;\n            flex-direction: column;\n            gap: 6px;\n            font-size: 18px;\n            color: rgba(255, 255, 255, 0.9);\n            font-weight: 500;\n            max-height: 100px;\n            overflow-y: auto;\n        }\n\n        .order-category {\n            display: flex;\n            flex-wrap: wrap;\n            align-items: center;\n            gap: 4px;\n        }\n\n        .order-category-label {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 16px;\n            font-weight: 700;\n            color: #FF69B4;\n            text-transform: uppercase;\n            min-width: 80px;\n        }\n\n        .order-item {\n            display: flex;\n            align-items: center;\n            gap: 3px;\n            white-space: nowrap;\n            color: #8B0045;\n        }\n\n        .order-item-icon {\n            width: 32px;\n            height: 32px;\n            object-fit: contain;\n        }\n\n        /* Score Section in Header */\n        .score-section {\n            display: flex;\n            align-items: center;\n            gap: 4px;\n        }\n\n        /* Top Bar for additional spacing */\n        .top-bar {\n            position: absolute;\n            top: 8px;\n            right: var(--space-sm);\n            display: flex;\n            justify-content: flex-end;\n            align-items: center;\n            pointer-events: none;\n        }\n\n        .top-bar > * {\n            pointer-events: auto;\n        }\n\n        .coins-display {\n            display: flex;\n            align-items: center;\n            gap: 4px;\n            background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);\n            padding: 6px 10px;\n            border-radius: 16px;\n            box-shadow: 0 2px 8px rgba(255, 165, 0, 0.4);\n        }\n\n        .coins-display img {\n            width: 20px;\n            height: 20px;\n        }\n\n        .coins-display span {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 16px;\n            font-weight: 700;\n            color: #fff;\n            text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);\n            min-width: 30px;\n        }\n\n        .stars-display {\n            display: flex;\n            gap: 1px;\n            background: rgba(255, 255, 255, 0.3);\n            padding: 3px 6px;\n            border-radius: 10px;\n        }\n\n        .stars-display img {\n            width: 28px;\n            height: 28px;\n        }\n\n        /* Submit Button (now in action buttons) */\n        .submit-btn {\n            background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);\n            color: white;\n            border: none;\n            padding: 14px 20px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 17px;\n            font-weight: 600;\n            border-radius: 20px;\n            cursor: pointer;\n            box-shadow: 0 3px 10px rgba(76, 175, 80, 0.4);\n            transition: all var(--transition-fast) var(--ease-out);\n            flex: 1;\n            max-width: 200px;\n            min-height: 56px;\n        }\n\n        .submit-btn:active:not(:disabled) {\n            transform: scale(0.95);\n            box-shadow: 0 2px 10px rgba(76, 175, 80, 0.4);\n        }\n\n        .submit-btn.submitting {\n            animation: submitPulse 0.5s ease;\n        }\n\n        @keyframes submitPulse {\n            0% { transform: scale(1); }\n            30% { transform: scale(0.9); }\n            60% { transform: scale(1.1); }\n            100% { transform: scale(1); }\n        }\n\n        .submit-btn:disabled {\n            background: linear-gradient(135deg, #ccc 0%, #bbb 100%);\n            box-shadow: none;\n            cursor: not-allowed;\n            color: #888;\n            transform: none;\n        }\n\n        /* Bottom Panel */\n        .bottom-panel {\n            position: absolute;\n            bottom: 0;\n            left: 0;\n            right: 0;\n            background: linear-gradient(180deg, #FFF5F8 0%, #FFE4EC 100%);\n            border-radius: 16px 16px 0 0;\n            box-shadow: 0 -4px 24px rgba(255, 182, 193, 0.3);\n            padding: 4px 10px 10px 10px;\n            border-top: 4px dotted #FF69B4;\n        }\n\n        /* Layer Counter */\n        .layer-counter {\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            gap: 4px;\n            padding: 4px 10px;\n            background: linear-gradient(135deg, #FFE4EC 0%, #FFC0CB 100%);\n            border-radius: 12px;\n            margin-bottom: 4px;\n            border: 2px dashed #FFB6C1;\n        }\n\n        .layer-counter-icon {\n            font-size: 14px;\n        }\n\n        .layer-counter-text {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 18px;\n            font-weight: 600;\n            color: #E91E63;\n        }\n\n        .layer-counter-bar {\n            display: flex;\n            gap: 3px;\n            margin-left: 6px;\n        }\n\n        .layer-dot {\n            width: 12px;\n            height: 12px;\n            border-radius: 3px;\n            background: #f0f0f0;\n            border: 2px solid #ddd;\n            transition: all 0.2s ease;\n        }\n\n        .layer-dot.filled {\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            border-color: #FF1493;\n            animation: dotFill 0.3s ease;\n        }\n\n        @keyframes dotFill {\n            0% { transform: scale(0.5); opacity: 0; }\n            50% { transform: scale(1.3); }\n            100% { transform: scale(1); opacity: 1; }\n        }\n\n        /* Tutorial Text Above Tabs */\n        .tab-tutorial {\n            background: linear-gradient(135deg, #FFF0F5 0%, #FFE4EC 100%);\n            border-radius: 8px;\n            padding: 10px 14px;\n            font-size: 18px;\n            font-weight: 600;\n            color: #E91E63;\n            text-align: center;\n            line-height: 1.3;\n            border: 2px dashed #FF69B4;\n            margin-bottom: 4px;\n        }\n\n        /* Category Tabs */\n        .category-tabs {\n            display: flex;\n            justify-content: center;\n            gap: 4px;\n            margin-bottom: 4px;\n            padding: 6px;\n            background: rgba(255, 255, 255, 0.5);\n            border-radius: 14px;\n            border: 2px dashed #FFB6C1;\n        }\n\n        .category-tab {\n            display: flex;\n            flex-direction: row;\n            align-items: center;\n            justify-content: center;\n            gap: 4px;\n            padding: 6px 8px;\n            border: none;\n            background: rgba(255, 255, 255, 0.7);\n            border-radius: 10px;\n            cursor: pointer;\n            transition: all var(--transition-fast) var(--ease-out);\n            min-width: 60px;\n            min-height: 36px;\n            flex: 1;\n            border: 1px solid rgba(255, 182, 193, 0.3);\n        }\n\n        .category-tab:active {\n            transform: scale(0.95);\n        }\n\n        .category-tab.active {\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            box-shadow: 0 3px 10px rgba(255, 105, 180, 0.4);\n            animation: tabActivate 0.3s ease;\n        }\n\n        @keyframes tabActivate {\n            0% { transform: scale(1); }\n            50% { transform: scale(1.05); }\n            100% { transform: scale(1); }\n        }\n\n        .category-tab img {\n            width: 20px;\n            height: 20px;\n        }\n\n        .category-tab span {\n            font-size: 17px;\n            font-weight: 600;\n            color: #555;\n        }\n\n        .category-tab.active span {\n            color: white;\n        }\n\n        /* Ingredient Carousel - Vertical Grid Style */\n        .ingredient-carousel {\n            display: grid;\n            grid-template-columns: repeat(4, 1fr);\n            grid-auto-flow: row;\n            gap: 6px;\n            overflow-y: scroll;\n            overflow-x: hidden;\n            padding: 6px;\n            padding-right: 32px;\n            -webkit-overflow-scrolling: touch;\n            scrollbar-width: auto;\n            scrollbar-color: #FF69B4 #e0e0e0;\n            max-height: 150px;\n            scroll-behavior: smooth;\n            touch-action: pan-y;\n            background: rgba(255, 255, 255, 0.4);\n            border-radius: 12px;\n            border: 2px dashed #FFB6C1;\n        }\n\n        .ingredient-carousel::-webkit-scrollbar {\n            width: 28px;\n            display: block;\n        }\n\n        .ingredient-carousel::-webkit-scrollbar-track {\n            background: #e0e0e0;\n            border-radius: 14px;\n            margin: 6px 0;\n        }\n\n        .ingredient-carousel::-webkit-scrollbar-thumb {\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            border-radius: 14px;\n            border: 5px solid #e0e0e0;\n            min-height: 80px;\n        }\n\n        .ingredient-carousel::-webkit-scrollbar-thumb:hover {\n            background: linear-gradient(135deg, #FF1493 0%, #C71585 100%);\n        }\n\n        .ingredient-carousel::-webkit-scrollbar-thumb:active {\n            background: linear-gradient(135deg, #C71585 0%, #A00050 100%);\n        }\n\n        /* Ingredient Item Feedback */\n        .ingredient-item {\n            flex-shrink: 0;\n            width: 100%;\n            min-height: 120px;\n            padding: 8px 4px;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: flex-start;\n            background: rgba(255, 255, 255, 0.8);\n            border-radius: 8px;\n            cursor: pointer;\n            transition: all var(--transition-fast) var(--ease-out);\n            border: 2px solid rgba(255, 182, 193, 0.3);\n            position: relative;\n        }\n\n        .ingredient-item:active:not(.locked) {\n            transform: scale(0.92);\n            background: #e8e8e8;\n        }\n\n        .ingredient-item.selected {\n            border-color: #FF69B4;\n            background: #FFF0F5;\n            box-shadow: 0 2px 8px rgba(255, 105, 180, 0.3);\n            animation: selectedPulse 0.3s ease;\n        }\n\n        @keyframes selectedPulse {\n            0% { transform: scale(1); }\n            50% { transform: scale(1.05); }\n            100% { transform: scale(1); }\n        }\n\n        .ingredient-item.locked {\n            opacity: 0.5;\n            cursor: not-allowed;\n        }\n\n        .ingredient-item.locked:active {\n            animation: lockedShake 0.3s ease;\n        }\n\n        @keyframes lockedShake {\n            0%, 100% { transform: translateX(0); }\n            25% { transform: translateX(-4px); }\n            75% { transform: translateX(4px); }\n        }\n\n        .ingredient-item img {\n            width: 80px;\n            height: 80px;\n            object-fit: contain;\n        }\n\n        .ingredient-item span {\n            font-size: 15px;\n            font-weight: 600;\n            color: #444;\n            margin-top: 3px;\n            text-align: center;\n            line-height: 1.2;\n            max-width: 100%;\n            padding: 0 2px;\n            word-wrap: break-word;\n            white-space: normal;\n        }\n\n        .lock-icon {\n            position: absolute;\n            font-size: 14px;\n            top: 3px;\n            right: 3px;\n            background: rgba(0, 0, 0, 0.5);\n            border-radius: 50%;\n            width: 22px;\n            height: 22px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n        }\n\n        /* Action Buttons */\n        .action-buttons {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            gap: 4px;\n            margin-top: 4px;\n            padding: 6px;\n            background: rgba(255, 255, 255, 0.4);\n            border-radius: 14px;\n            border: 2px dashed #FFB6C1;\n        }\n\n        .action-btn {\n            padding: 12px 16px;\n            border: none;\n            border-radius: 16px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 15px;\n            font-weight: 600;\n            cursor: pointer;\n            transition: all var(--transition-fast) var(--ease-out);\n            min-height: 52px;\n        }\n\n        .action-btn.primary {\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            color: white;\n            box-shadow: 0 3px 10px rgba(255, 105, 180, 0.4);\n            flex: 1.5;\n            max-width: 220px;\n        }\n\n        .action-btn.primary:active:not(:disabled) {\n            transform: scale(0.95);\n        }\n\n        .action-btn.primary:disabled {\n            background: #d0d0d0;\n            box-shadow: none;\n            cursor: not-allowed;\n            transform: none;\n            color: #888;\n        }\n\n        .action-btn.secondary {\n            background: rgba(255, 255, 255, 0.8);\n            color: #E91E63;\n            flex: 1;\n            max-width: 130px;\n            padding: 12px 10px;\n            font-size: 14px;\n            border: 1px solid rgba(255, 182, 193, 0.5);\n        }\n\n        .action-btn.secondary:disabled {\n            opacity: 0.5;\n            cursor: not-allowed;\n        }\n\n        .action-btn.gallery {\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            color: white;\n            box-shadow: 0 3px 10px rgba(255, 105, 180, 0.4);\n            flex: 1;\n            max-width: 150px;\n        }\n\n        .action-btn.gallery:active {\n            transform: scale(0.95);\n        }\n\n        /* Gallery Modal */\n        .gallery-modal {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.8);\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: flex-start;\n            opacity: 0;\n            visibility: hidden;\n            transition: all var(--transition-normal) var(--ease-out);\n            z-index: 200;\n            padding: var(--space-md);\n            overflow-y: auto;\n        }\n\n        .gallery-modal.visible {\n            opacity: 1;\n            visibility: visible;\n        }\n\n        .gallery-modal.visible .gallery-grid {\n            animation: gallerySlideIn 0.4s ease;\n        }\n\n        @keyframes gallerySlideIn {\n            0% { transform: translateY(30px); opacity: 0; }\n            100% { transform: translateY(0); opacity: 1; }\n        }\n\n        .gallery-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            width: 100%;\n            margin-bottom: var(--space-md);\n        }\n\n        .gallery-title {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 28px;\n            font-weight: 700;\n            color: white;\n        }\n\n        .gallery-close-btn {\n            background: rgba(255, 255, 255, 0.2);\n            border: none;\n            color: white;\n            font-size: 24px;\n            width: 48px;\n            height: 48px;\n            border-radius: 50%;\n            cursor: pointer;\n            transition: all var(--transition-fast) var(--ease-out);\n        }\n\n        .gallery-close-btn:active {\n            transform: scale(0.9);\n            background: rgba(255, 255, 255, 0.3);\n        }\n\n        .gallery-grid {\n            display: grid;\n            grid-template-columns: repeat(2, 1fr);\n            gap: var(--space-sm);\n            width: 100%;\n            max-width: 600px;\n        }\n\n        .gallery-item {\n            background: white;\n            border-radius: 16px;\n            padding: var(--space-sm);\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            gap: 8px;\n            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n            position: relative;\n            cursor: pointer;\n            transition: transform 0.2s ease, box-shadow 0.2s ease;\n            min-height: 360px;\n        }\n\n        .gallery-item:active {\n            transform: scale(0.95);\n        }\n\n        .gallery-item:hover {\n            box-shadow: 0 6px 20px rgba(255, 105, 180, 0.4);\n        }\n\n        .gallery-load-hint {\n            position: absolute;\n            bottom: 40px;\n            left: 50%;\n            transform: translateX(-50%);\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            color: white;\n            padding: 6px 12px;\n            border-radius: 12px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 12px;\n            font-weight: 600;\n            white-space: nowrap;\n            opacity: 0.9;\n        }\n\n        .gallery-cake-preview {\n            width: 100%;\n            aspect-ratio: 1;\n            background: linear-gradient(135deg, #FFE4EC 0%, #FFC0CB 100%);\n            border-radius: 12px;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            padding: 0;\n            overflow: hidden;\n            min-height: 280px;\n        }\n\n        .gallery-cake-canvas {\n            width: 100%;\n            height: 100%;\n            object-fit: contain;\n        }\n\n        .gallery-grid {\n            grid-template-columns: repeat(2, 1fr);\n            gap: var(--space-md);\n        }\n\n        .gallery-item {\n            min-height: 220px;\n        }\n\n        .gallery-cake-name {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 14px;\n            font-weight: 600;\n            color: #333;\n            text-align: center;\n        }\n\n        .gallery-delete-btn {\n            position: absolute;\n            top: 8px;\n            right: 8px;\n            background: rgba(244, 67, 54, 0.9);\n            border: none;\n            color: white;\n            font-size: 14px;\n            width: 28px;\n            height: 28px;\n            border-radius: 50%;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n        }\n\n        .gallery-empty {\n            text-align: center;\n            color: rgba(255, 255, 255, 0.7);\n            font-size: 18px;\n            padding: var(--space-xl);\n        }\n\n        .gallery-save-btn {\n            background: linear-gradient(135deg, #FF69B4 0%, #FF1493 100%);\n            color: white;\n            border: none;\n            padding: 12px 24px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 16px;\n            font-weight: 600;\n            border-radius: 20px;\n            cursor: pointer;\n            margin-top: var(--space-md);\n            box-shadow: 0 3px 10px rgba(255, 105, 180, 0.4);\n        }\n\n        .gallery-save-btn:disabled {\n            background: #999;\n            box-shadow: none;\n            cursor: not-allowed;\n        }\n\n        .action-btn.secondary:active {\n            transform: scale(0.95);\n            background: #e0e0e0;\n        }\n\n        /* Button Feedback Effects */\n        .btn-pressed {\n            transform: scale(0.92) !important;\n            filter: brightness(0.95);\n        }\n\n        .btn-ripple {\n            position: absolute;\n            border-radius: 50%;\n            background: rgba(255, 255, 255, 0.5);\n            transform: scale(0);\n            animation: rippleEffect 0.6s ease-out;\n            pointer-events: none;\n        }\n\n        @keyframes rippleEffect {\n            to {\n                transform: scale(2.5);\n                opacity: 0;\n            }\n        }\n\n        /* Ensure buttons have relative positioning for ripple */\n        .mode-btn, .category-tab, .action-btn, .submit-btn, \n        .next-btn, .gallery-close-btn, .gallery-save-btn, \n        .gallery-delete-btn, .ingredient-item {\n            position: relative;\n            overflow: hidden;\n        }\n\n        /* Result Modal */\n        .result-modal {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.7);\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            opacity: 0;\n            visibility: hidden;\n            transition: all var(--transition-normal) var(--ease-out);\n        }\n\n        .result-modal.visible {\n            opacity: 1;\n            visibility: visible;\n        }\n\n        .result-content {\n            background: white;\n            border-radius: 24px;\n            padding: var(--space-lg) var(--space-lg);\n            text-align: center;\n            max-width: 400px;\n            width: 92%;\n            transform: scale(0.8);\n            transition: transform var(--transition-normal) var(--ease-bounce);\n            max-height: 92vh;\n            overflow-y: auto;\n        }\n\n        .result-modal.visible .result-content {\n            transform: scale(1);\n        }\n\n        .result-title {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 28px;\n            font-weight: 700;\n            color: #E91E63;\n            margin-bottom: var(--space-xs);\n        }\n\n        .result-subtitle {\n            font-size: 14px;\n            color: #888;\n            margin-bottom: var(--space-sm);\n        }\n\n        .result-stars {\n            display: flex;\n            justify-content: center;\n            gap: var(--space-xs);\n            margin-bottom: var(--space-sm);\n        }\n\n        .result-stars img {\n            width: 52px;\n            height: 52px;\n            transition: transform var(--transition-normal) var(--ease-bounce);\n        }\n\n        .result-stars img.earned {\n            animation: starPop 0.5s var(--ease-bounce);\n        }\n\n        @keyframes starPop {\n            0% { transform: scale(0); }\n            50% { transform: scale(1.3); }\n            100% { transform: scale(1); }\n        }\n\n        .result-accuracy {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 18px;\n            font-weight: 600;\n            color: #666;\n            margin-bottom: var(--space-sm);\n        }\n\n        .result-accuracy span {\n            color: #4CAF50;\n            font-size: 24px;\n        }\n\n        .result-summary {\n            background: #f8f8f8;\n            border-radius: 12px;\n            padding: var(--space-sm);\n            margin-bottom: var(--space-sm);\n            text-align: left;\n        }\n\n        .result-summary-title {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 14px;\n            font-weight: 600;\n            color: #E91E63;\n            margin-bottom: 6px;\n        }\n\n        .result-summary-row {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            font-size: 13px;\n            padding: 4px 0;\n            border-bottom: 1px solid #eee;\n        }\n\n        .result-summary-row:last-child {\n            border-bottom: none;\n        }\n\n        .result-summary-label {\n            color: #666;\n        }\n\n        .result-summary-value {\n            font-weight: 600;\n            color: #333;\n        }\n\n        .result-summary-value.match {\n            color: #4CAF50;\n        }\n\n        .result-summary-value.miss {\n            color: #F44336;\n        }\n\n        .result-rewards {\n            display: flex;\n            justify-content: center;\n            gap: var(--space-md);\n            margin-bottom: var(--space-md);\n        }\n\n        .result-reward-item {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            gap: 4px;\n        }\n\n        .result-reward-item img {\n            width: 32px;\n            height: 32px;\n        }\n\n        .result-reward-item span {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 20px;\n            font-weight: 600;\n            color: #FFA500;\n        }\n\n        .result-reward-label {\n            font-size: 11px;\n            color: #888;\n        }\n\n        .result-message {\n            font-size: 14px;\n            color: #666;\n            margin-bottom: var(--space-md);\n            padding: 8px 12px;\n            background: linear-gradient(135deg, #FFF0F5 0%, #FFE4EC 100%);\n            border-radius: 10px;\n        }\n\n        .next-btn {\n            background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);\n            color: white;\n            border: none;\n            padding: 14px 40px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 18px;\n            font-weight: 600;\n            border-radius: 25px;\n            cursor: pointer;\n            box-shadow: 0 4px 15px rgba(76, 175, 80, 0.4);\n            transition: all var(--transition-fast) var(--ease-out);\n        }\n\n        .next-btn:hover {\n            transform: scale(1.05);\n        }\n\n        /* Cake interaction feedback */\n        .cake-layer-added {\n            animation: layerBounce 0.4s ease;\n        }\n\n        @keyframes layerBounce {\n            0% { transform: translateY(-20px) scale(0.8); opacity: 0; }\n            50% { transform: translateY(5px) scale(1.05); }\n            100% { transform: translateY(0) scale(1); opacity: 1; }\n        }\n\n        /* Unlock Notification */\n        .unlock-notification {\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%) scale(0);\n            background: linear-gradient(135deg, #9C27B0 0%, #7B1FA2 100%);\n            color: white;\n            padding: var(--space-md) var(--space-lg);\n            border-radius: 20px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 24px;\n            font-weight: 600;\n            text-align: center;\n            box-shadow: 0 8px 30px rgba(156, 39, 176, 0.5);\n            z-index: 100;\n            transition: transform var(--transition-normal) var(--ease-bounce);\n        }\n\n        .unlock-notification.visible {\n            transform: translate(-50%, -50%) scale(1);\n        }\n\n        /* Edit Mode Styles */\n        .edit-mode-notice {\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            background: rgba(255, 255, 255, 0.98);\n            padding: var(--space-xl) var(--space-lg);\n            border-radius: 24px;\n            text-align: center;\n            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);\n            max-width: 340px;\n        }\n\n        .edit-mode-notice h2 {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 32px;\n            color: #E91E63;\n            margin-bottom: var(--space-md);\n        }\n\n        .edit-mode-notice p {\n            font-size: 18px;\n            color: #555;\n            line-height: 1.5;\n        }\n\n\n        /* Reduced motion support */\n        @media (prefers-reduced-motion: reduce) {\n            *, *::before, *::after {\n                animation-duration: 0.01ms !important;\n                transition-duration: 0.01ms !important;\n            }\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(180deg, #FFF5F8 0%, #FFE4EC 30%, #FFC0CB 70%, #FFB6C1 100%);\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            z-index: 1000;\n            transition: opacity 0.5s ease-out, visibility 0.5s ease-out;\n            overflow: hidden;\n        }\n\n        .loading-screen.hidden {\n            opacity: 0;\n            visibility: hidden;\n        }\n\n        /* Cute polka dot pattern overlay */\n        .loading-screen::before {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background-image: \n                radial-gradient(circle, rgba(255,255,255,0.4) 8px, transparent 8px),\n                radial-gradient(circle, rgba(255,182,193,0.3) 6px, transparent 6px);\n            background-size: 60px 60px, 40px 40px;\n            background-position: 0 0, 20px 20px;\n            pointer-events: none;\n        }\n\n        /* Decorative frosting drips at top */\n        .loading-frosting-top {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 80px;\n            background: linear-gradient(180deg, #FF69B4 0%, #FF69B4 40%, transparent 100%);\n            clip-path: polygon(\n                0% 0%, 100% 0%, 100% 50%,\n                95% 70%, 90% 55%, 85% 75%, 80% 50%,\n                75% 80%, 70% 55%, 65% 70%, 60% 50%,\n                55% 85%, 50% 55%, 45% 75%, 40% 50%,\n                35% 70%, 30% 55%, 25% 80%, 20% 50%,\n                15% 75%, 10% 55%, 5% 70%, 0% 50%\n            );\n            z-index: 1;\n        }\n\n        /* Decorative frosting drips at bottom */\n        .loading-frosting-bottom {\n            position: absolute;\n            bottom: 0;\n            left: 0;\n            width: 100%;\n            height: 60px;\n            background: linear-gradient(0deg, #E91E63 0%, #E91E63 40%, transparent 100%);\n            clip-path: polygon(\n                0% 100%, 100% 100%, 100% 40%,\n                95% 20%, 90% 45%, 85% 15%, 80% 50%,\n                75% 10%, 70% 45%, 65% 25%, 60% 50%,\n                55% 5%, 50% 45%, 45% 20%, 40% 50%,\n                35% 25%, 30% 45%, 25% 10%, 20% 50%,\n                15% 15%, 10% 45%, 5% 25%, 0% 50%\n            );\n            z-index: 1;\n        }\n\n        /* Floating cake decorations */\n        .loading-decoration {\n            position: absolute;\n            font-size: 40px;\n            opacity: 0.8;\n            animation: floatDecoration 4s ease-in-out infinite;\n            z-index: 0;\n        }\n\n        .loading-decoration:nth-child(1) { left: 5%; top: 15%; animation-delay: 0s; }\n        .loading-decoration:nth-child(2) { right: 8%; top: 20%; animation-delay: 0.5s; }\n        .loading-decoration:nth-child(3) { left: 10%; bottom: 25%; animation-delay: 1s; }\n        .loading-decoration:nth-child(4) { right: 12%; bottom: 20%; animation-delay: 1.5s; }\n        .loading-decoration:nth-child(5) { left: 20%; top: 8%; animation-delay: 2s; font-size: 30px; }\n        .loading-decoration:nth-child(6) { right: 20%; top: 12%; animation-delay: 2.5s; font-size: 30px; }\n\n        @keyframes floatDecoration {\n            0%, 100% { transform: translateY(0) rotate(-5deg); }\n            50% { transform: translateY(-15px) rotate(5deg); }\n        }\n\n        /* Confetti sprinkles */\n        .loading-sprinkle {\n            position: absolute;\n            width: 8px;\n            height: 20px;\n            border-radius: 4px;\n            opacity: 0.7;\n            animation: fallSprinkle 3s ease-in-out infinite;\n        }\n\n        @keyframes fallSprinkle {\n            0%, 100% { transform: translateY(0) rotate(0deg); opacity: 0.7; }\n            50% { transform: translateY(20px) rotate(180deg); opacity: 1; }\n        }\n\n        /* In-Game Mascot */\n        .game-mascot {\n            position: absolute;\n            bottom: 340px;\n            left: 10px;\n            width: 140px;\n            height: 140px;\n            z-index: 50;\n            transition: transform 0.3s ease;\n            pointer-events: none;\n        }\n\n        .game-mascot img {\n            width: 100%;\n            height: 100%;\n            object-fit: contain;\n            filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.2));\n            transition: transform 0.2s ease;\n        }\n\n        .game-mascot.bounce img {\n            animation: mascotBounceSmall 0.5s ease;\n        }\n\n        .game-mascot.excited img {\n            animation: mascotExcited 0.6s ease;\n        }\n\n        .game-mascot.happy img {\n            animation: mascotHappy 0.4s ease;\n        }\n\n        .game-mascot.celebrate img {\n            animation: mascotCelebrate 1s ease;\n        }\n\n        .game-mascot.thinking img {\n            animation: mascotThinking 1.5s ease-in-out infinite;\n        }\n\n        .game-mascot.idle img {\n            animation: mascotIdle 3s ease-in-out infinite;\n        }\n\n        @keyframes mascotBounceSmall {\n            0%, 100% { transform: translateY(0) scale(1); }\n            50% { transform: translateY(-15px) scale(1.1); }\n        }\n\n        @keyframes mascotExcited {\n            0%, 100% { transform: rotate(0deg) scale(1); }\n            25% { transform: rotate(-10deg) scale(1.15); }\n            75% { transform: rotate(10deg) scale(1.15); }\n        }\n\n        @keyframes mascotHappy {\n            0%, 100% { transform: scale(1); }\n            50% { transform: scale(1.2); }\n        }\n\n        @keyframes mascotCelebrate {\n            0%, 100% { transform: translateY(0) rotate(0deg); }\n            25% { transform: translateY(-20px) rotate(-15deg); }\n            50% { transform: translateY(-10px) rotate(15deg); }\n            75% { transform: translateY(-25px) rotate(-10deg); }\n        }\n\n        @keyframes mascotThinking {\n            0%, 100% { transform: translateY(0) rotate(0deg); }\n            50% { transform: translateY(-5px) rotate(5deg); }\n        }\n\n        @keyframes mascotIdle {\n            0%, 100% { transform: translateY(0); }\n            50% { transform: translateY(-8px); }\n        }\n\n        /* Speech Bubble */\n        .mascot-bubble {\n            position: absolute;\n            bottom: 85px;\n            left: 75px;\n            background: white;\n            border-radius: 16px;\n            padding: 8px 12px;\n            font-family: 'Fredoka', sans-serif;\n            font-size: 13px;\n            font-weight: 600;\n            color: #E91E63;\n            box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15);\n            white-space: nowrap;\n            opacity: 0;\n            transform: scale(0.8) translateY(10px);\n            transition: all 0.3s cubic-bezier(0.68, -0.6, 0.32, 1.6);\n            pointer-events: none;\n            z-index: 51;\n        }\n\n        .mascot-bubble.visible {\n            opacity: 1;\n            transform: scale(1) translateY(0);\n        }\n\n        .mascot-bubble::before {\n            content: '';\n            position: absolute;\n            bottom: -8px;\n            left: 15px;\n            width: 0;\n            height: 0;\n            border-left: 8px solid transparent;\n            border-right: 8px solid transparent;\n            border-top: 10px solid white;\n        }\n\n        .loading-mascot {\n            width: 200px;\n            height: 200px;\n            object-fit: contain;\n            animation: mascotBounce 1s ease-in-out infinite;\n            filter: drop-shadow(0 10px 20px rgba(255, 105, 180, 0.3));\n        }\n\n        @keyframes mascotBounce {\n            0%, 100% { transform: translateY(0) scale(1); }\n            50% { transform: translateY(-20px) scale(1.05); }\n        }\n\n        .loading-title {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 42px;\n            font-weight: 700;\n            color: #E91E63;\n            text-shadow: 3px 3px 0 white, 4px 4px 10px rgba(233, 30, 99, 0.3);\n            margin-top: 20px;\n            animation: titlePulse 2s ease-in-out infinite;\n        }\n\n        @keyframes titlePulse {\n            0%, 100% { transform: scale(1); }\n            50% { transform: scale(1.05); }\n        }\n\n        .loading-subtitle {\n            font-family: 'Poppins', sans-serif;\n            font-size: 18px;\n            color: #FF69B4;\n            margin-top: 8px;\n            font-weight: 500;\n        }\n\n        .loading-bar-container {\n            width: 260px;\n            height: 20px;\n            background: rgba(255, 255, 255, 0.6);\n            border-radius: 10px;\n            margin-top: 30px;\n            overflow: hidden;\n            box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);\n        }\n\n        .loading-bar {\n            height: 100%;\n            width: 0%;\n            background: linear-gradient(90deg, #FF69B4 0%, #FF1493 50%, #E91E63 100%);\n            border-radius: 10px;\n            transition: width 0.3s ease-out;\n            position: relative;\n        }\n\n        .loading-bar::after {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: 0;\n            right: 0;\n            height: 50%;\n            background: linear-gradient(180deg, rgba(255,255,255,0.4) 0%, transparent 100%);\n            border-radius: 10px 10px 0 0;\n        }\n\n        .loading-text {\n            font-family: 'Fredoka', sans-serif;\n            font-size: 16px;\n            color: #E91E63;\n            margin-top: 12px;\n        }\n\n        .loading-sparkles {\n            position: absolute;\n            width: 100%;\n            height: 100%;\n            pointer-events: none;\n            overflow: hidden;\n        }\n\n        .sparkle {\n            position: absolute;\n            font-size: 24px;\n            animation: sparkleFloat 3s ease-in-out infinite;\n            opacity: 0.7;\n        }\n\n        @keyframes sparkleFloat {\n            0%, 100% { transform: translateY(0) rotate(0deg); opacity: 0.7; }\n            50% { transform: translateY(-30px) rotate(180deg); opacity: 1; }\n        }\n    </style>\n</head>\n<body>\n    <div id=\"game-world\">\n        <canvas id=\"game-canvas\"></canvas>\n        <div class=\"ui-overlay\" id=\"ui-overlay\"></div>\n        \n        <!-- Loading Screen -->\n        <div class=\"loading-screen\" id=\"loading-screen\">\n            <!-- Frosting drips decoration -->\n            <div class=\"loading-frosting-top\"></div>\n            <div class=\"loading-frosting-bottom\"></div>\n            \n            <!-- Sprinkles container -->\n            <div class=\"loading-sprinkles-container\" id=\"loading-sprinkles-container\"></div>\n            \n            <div class=\"loading-sparkles\" id=\"loading-sparkles\"></div>\n            <img class=\"loading-mascot\" id=\"loading-mascot\" src=\"\" alt=\"Cake Mascot\">\n            <div class=\"loading-title\">Sweet Stack</div>\n            <div class=\"loading-subtitle\">Ice Cream Cake Studio</div>\n            <div class=\"loading-bar-container\">\n                <div class=\"loading-bar\" id=\"loading-bar\"></div>\n            </div>\n            <div class=\"loading-text\" id=\"loading-text\">Loading delicious treats...</div>\n        </div>\n    </div>\n\n    <script>\n        /**\n         * SWEET STACK STUDIO\n         * An ice cream cake maker game where players fulfill customer orders\n         * by building multi-layered cakes with various flavors, toppings, and decorations.\n         * \n         * Core Mechanics:\n         * - Customers present orders with specific requirements\n         * - Players select ingredients from categorized panels\n         * - Build cakes layer by layer with toppings and decorations\n         * - Score based on accuracy matching the order\n         * - Earn coins to unlock new ingredients\n         */\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            const uiOverlay = document.getElementById('ui-overlay');\n\n            // ==================== CONSTANTS ====================\n            const GAME_WIDTH = 720;\n            const GAME_HEIGHT = 1280;\n            \n            const FLAVORS = [\n                { id: 'vanilla', name: 'Vanilla', assetId: 'ice_cream_vanilla', unlockCost: 0 },\n                { id: 'chocolate', name: 'Chocolate', assetId: 'ice_cream_chocolate', unlockCost: 0 },\n                { id: 'strawberry', name: 'Strawberry', assetId: 'ice_cream_strawberry', unlockCost: 0 },\n                { id: 'mint', name: 'Mint Chip', assetId: 'ice_cream_mint', unlockCost: 0 },\n                { id: 'cookies_cream', name: 'Cookies & Cream', assetId: 'ice_cream_cookies_cream', unlockCost: 0 },\n                { id: 'mango', name: 'Mango', assetId: 'ice_cream_mango', unlockCost: 0 },\n                { id: 'blueberry', name: 'Blueberry', assetId: 'ice_cream_blueberry', unlockCost: 0 },\n                { id: 'caramel', name: 'Caramel', assetId: 'ice_cream_caramel', unlockCost: 0 },\n                { id: 'coffee', name: 'Coffee', assetId: 'ice_cream_coffee', unlockCost: 0 },\n                { id: 'pistachio', name: 'Pistachio', assetId: 'ice_cream_pistachio', unlockCost: 0 },\n                { id: 'bubblegum', name: 'Bubblegum', assetId: 'ice_cream_bubblegum', unlockCost: 0 },\n                { id: 'lemon', name: 'Lemon', assetId: 'ice_cream_lemon', unlockCost: 0 },\n                { id: 'raspberry', name: 'Raspberry', assetId: 'ice_cream_raspberry', unlockCost: 0 },\n                { id: 'matcha', name: 'Matcha', assetId: 'ice_cream_matcha', unlockCost: 0 },\n                { id: 'cotton_candy', name: 'Cotton Candy', assetId: 'ice_cream_cotton_candy', unlockCost: 0 },\n                { id: 'banana', name: 'Banana', assetId: 'ice_cream_banana', unlockCost: 0 },\n                { id: 'cheesecake', name: 'Cheesecake', assetId: 'ice_cream_cheesecake', unlockCost: 0 },\n                { id: 'red_velvet', name: 'Red Velvet', assetId: 'ice_cream_red_velvet', unlockCost: 0 },\n                { id: 'peanut_butter', name: 'Peanut Butter', assetId: 'ice_cream_peanut_butter', unlockCost: 0 },\n                { id: 'birthday_cake', name: 'Birthday Cake', assetId: 'ice_cream_birthday_cake', unlockCost: 0 },\n                { id: 'black_sesame', name: 'Black Sesame', assetId: 'ice_cream_black_sesame', unlockCost: 0 },\n                { id: 'salted_caramel', name: 'Salted Caramel', assetId: 'ice_cream_salted_caramel', unlockCost: 0 }\n            ];\n\n            const TOPPINGS = [\n                { id: 'chocolate_chips', name: 'Choco Chips', assetId: 'topping_chocolate_chips', unlockCost: 0 },\n                { id: 'rainbow_sprinkles', name: 'Sprinkles', assetId: 'topping_rainbow_sprinkles', unlockCost: 0 },\n                { id: 'strawberry_slices', name: 'Strawberries', assetId: 'topping_strawberry_slices', unlockCost: 0 },\n                { id: 'crushed_oreos', name: 'Oreo Crumbs', assetId: 'topping_crushed_oreos', unlockCost: 0 },\n                { id: 'nuts', name: 'Mixed Nuts', assetId: 'topping_nuts', unlockCost: 0 },\n                { id: 'gummy_bears', name: 'Gummy Bears', assetId: 'topping_gummy_bears', unlockCost: 0 },\n                { id: 'marshmallows', name: 'Marshmallows', assetId: 'topping_marshmallows', unlockCost: 0 },\n                { id: 'coconut', name: 'Coconut', assetId: 'topping_coconut', unlockCost: 0 },\n                { id: 'blueberries', name: 'Blueberries', assetId: 'topping_blueberries', unlockCost: 0 },\n                { id: 'cookie_crumbs', name: 'Cookie Crumbs', assetId: 'topping_cookie_crumbs', unlockCost: 0 },\n                { id: 'raspberries', name: 'Raspberries', assetId: 'topping_raspberries', unlockCost: 0 },\n                { id: 'banana_slices', name: 'Banana Slices', assetId: 'topping_banana_slices', unlockCost: 0 },\n                { id: 'candy_pieces', name: 'Candy Pieces', assetId: 'topping_candy_pieces', unlockCost: 0 },\n                { id: 'graham_crumbs', name: 'Graham Crumbs', assetId: 'topping_graham_crumbs', unlockCost: 0 },\n                { id: 'mini_oreos', name: 'Mini Oreos', assetId: 'topping_mini_oreos', unlockCost: 0 },\n                { id: 'pretzel_pieces', name: 'Pretzel Pieces', assetId: 'topping_pretzel_pieces', unlockCost: 0 },\n                { id: 'caramel_bits', name: 'Caramel Bits', assetId: 'topping_caramel_bits', unlockCost: 0 },\n                { id: 'chocolate_shavings', name: 'Choco Shavings', assetId: 'topping_chocolate_shavings', unlockCost: 0 },\n                { id: 'toffee_bits', name: 'Toffee Bits', assetId: 'topping_toffee_bits', unlockCost: 0 },\n                { id: 'peanuts', name: 'Peanuts', assetId: 'topping_peanuts', unlockCost: 0 }\n            ];\n\n            const DECORATIONS = [\n                { id: 'cherry', name: 'Cherry', assetId: 'decoration_cherry', unlockCost: 0 },\n                { id: 'chocolate_drizzle', name: 'Choco Drizzle', assetId: 'decoration_chocolate_drizzle', unlockCost: 0 },\n                { id: 'caramel_drizzle', name: 'Caramel Drizzle', assetId: 'topping_caramel_drizzle', unlockCost: 0 },\n                { id: 'honey_drizzle', name: 'Honey Drizzle', assetId: 'topping_honey_drizzle', unlockCost: 0 },\n                { id: 'whipped_cream', name: 'Whipped Cream', assetId: 'decoration_whipped_cream', unlockCost: 0 },\n                { id: 'wafer_sticks', name: 'Wafer Sticks', assetId: 'decoration_wafer_sticks', unlockCost: 0 },\n                { id: 'candles', name: 'Candles', assetId: 'decoration_candles', unlockCost: 0 },\n                { id: 'star_sprinkles', name: 'Star Sprinkles', assetId: 'decoration_star_sprinkles', unlockCost: 0 },\n                { id: 'chocolate_curl', name: 'Choco Curl', assetId: 'decoration_chocolate_curl', unlockCost: 0 },\n                { id: 'fondant_flower', name: 'Flower', assetId: 'decoration_fondant_flower', unlockCost: 0 },\n                { id: 'sugar_pearls', name: 'Sugar Pearl', assetId: 'decoration_sugar_pearls', unlockCost: 0 },\n                { id: 'macaron', name: 'Macaron', assetId: 'decoration_macaron', unlockCost: 0 },\n                { id: 'mint_leaves', name: 'Mint Leaf', assetId: 'decoration_mint_leaves', unlockCost: 0 },\n                { id: 'gold_flakes', name: 'Gold Flake', assetId: 'decoration_gold_flakes', unlockCost: 0 },\n                { id: 'chocolate_heart', name: 'Choco Heart', assetId: 'decoration_chocolate_heart', unlockCost: 0 },\n                { id: 'unicorn_horn', name: 'Unicorn Horn', assetId: 'decoration_unicorn_horn', unlockCost: 0 },\n                { id: 'sprinkle_hearts', name: 'Heart Sprinkle', assetId: 'decoration_sprinkle_hearts', unlockCost: 0 },\n                { id: 'edible_glitter', name: 'Edible Glitter', assetId: 'decoration_edible_glitter', unlockCost: 0 },\n                { id: 'chocolate_shards', name: 'Choco Shards', assetId: 'decoration_chocolate_shards', unlockCost: 0 },\n                { id: 'candy_cane', name: 'Candy Cane', assetId: 'decoration_candy_cane', unlockCost: 0 },\n                { id: 'gummy_worms', name: 'Gummy Worm', assetId: 'decoration_gummy_worms', unlockCost: 0 },\n                { id: 'lollipop', name: 'Lollipop', assetId: 'decoration_lollipop', unlockCost: 0 },\n                { id: 'strawberry_whole', name: 'Strawberry', assetId: 'decoration_strawberry', unlockCost: 0 }\n            ];\n\n            const FROSTINGS = [\n                { id: 'vanilla_frost', name: 'Vanilla', assetId: 'frosting_vanilla', unlockCost: 0 },\n                { id: 'strawberry_frost', name: 'Strawberry', assetId: 'frosting_strawberry', unlockCost: 0 },\n                { id: 'chocolate_frost', name: 'Chocolate', assetId: 'frosting_chocolate', unlockCost: 0 },\n                { id: 'mint_frost', name: 'Mint', assetId: 'frosting_mint', unlockCost: 0 },\n                { id: 'caramel_frost', name: 'Caramel', assetId: 'frosting_caramel', unlockCost: 0 },\n                { id: 'lemon_frost', name: 'Lemon', assetId: 'frosting_lemon', unlockCost: 0 },\n                { id: 'blueberry_frost', name: 'Blueberry', assetId: 'frosting_blueberry', unlockCost: 0 },\n                { id: 'cream_cheese_frost', name: 'Cream Cheese', assetId: 'frosting_cream_cheese', unlockCost: 0 },\n                { id: 'raspberry_frost', name: 'Raspberry', assetId: 'frosting_raspberry', unlockCost: 0 },\n                { id: 'matcha_frost', name: 'Matcha', assetId: 'frosting_matcha', unlockCost: 0 },\n                { id: 'cookies_cream_frost', name: 'Cookies & Cream', assetId: 'frosting_cookies_cream', unlockCost: 0 },\n                { id: 'peanut_butter_frost', name: 'Peanut Butter', assetId: 'frosting_peanut_butter', unlockCost: 0 },\n                { id: 'rose_frost', name: 'Rose', assetId: 'frosting_rose', unlockCost: 0 },\n                { id: 'galaxy_frost', name: 'Galaxy', assetId: 'frosting_galaxy', unlockCost: 0 },\n                { id: 'rainbow_frost', name: 'Rainbow', assetId: 'frosting_rainbow', unlockCost: 0 },\n                { id: 'gold_shimmer_frost', name: 'Gold Shimmer', assetId: 'frosting_gold_shimmer', unlockCost: 0 },\n                { id: 'lavender_frost', name: 'Lavender', assetId: 'frosting_lavender', unlockCost: 0 },\n                { id: 'ombre_pink_frost', name: 'Ombr\u00e9 Pink', assetId: 'frosting_ombre_pink', unlockCost: 0 },\n                { id: 'bubblegum_frost', name: 'Bubblegum', assetId: 'frosting_bubblegum', unlockCost: 0 },\n                { id: 'cotton_candy_frost', name: 'Cotton Candy', assetId: 'frosting_cotton_candy', unlockCost: 0 },\n                { id: 'red_velvet_frost', name: 'Red Velvet', assetId: 'frosting_red_velvet', unlockCost: 0 },\n                { id: 'cheesecake_frost', name: 'Cheesecake', assetId: 'frosting_cheesecake', unlockCost: 0 },\n                { id: 'birthday_cake_frost', name: 'Birthday Cake', assetId: 'frosting_birthday_cake', unlockCost: 0 },\n                { id: 'black_sesame_frost', name: 'Black Sesame', assetId: 'frosting_black_sesame', unlockCost: 0 },\n                { id: 'mango_frost', name: 'Mango', assetId: 'frosting_mango', unlockCost: 0 },\n                { id: 'coffee_frost', name: 'Coffee', assetId: 'frosting_coffee', unlockCost: 0 },\n                { id: 'pistachio_frost', name: 'Pistachio', assetId: 'frosting_pistachio', unlockCost: 0 },\n                { id: 'banana_frost', name: 'Banana', assetId: 'frosting_banana', unlockCost: 0 },\n                { id: 'salted_caramel_frost', name: 'Salted Caramel', assetId: 'frosting_salted_caramel', unlockCost: 0 }\n            ];\n\n            const CUSTOMERS = ['customer_1', 'customer_2', 'customer_3'];\n\n            // ==================== ASSET MANAGEMENT ====================\n            const imageCache = {};\n            const audioCache = {};\n            let audioContext = null;\n\n            function getAudioContext() {\n                if (!audioContext) {\n                    audioContext = new (window.AudioContext || window.webkitAudioContext)();\n                }\n                return audioContext;\n            }\n\n            async function loadImage(assetId) {\n                if (imageCache[assetId]) return imageCache[assetId];\n                \n                const assetInfo = lib.getAsset(assetId);\n                if (!assetInfo || assetInfo.type !== 'image') return null;\n\n                return new Promise((resolve) => {\n                    const img = new Image();\n                    img.onload = () => {\n                        imageCache[assetId] = img;\n                        resolve(img);\n                    };\n                    img.onerror = () => {\n                        lib.log(`Failed to load image: ${assetId}`);\n                        resolve(null);\n                    };\n                    img.src = assetInfo.url;\n                });\n            }\n\n            async function loadAudio(assetId) {\n                if (audioCache[assetId]) return audioCache[assetId];\n\n                const assetInfo = lib.getAsset(assetId);\n                if (!assetInfo || assetInfo.type !== 'audio') return null;\n\n                try {\n                    const response = await fetch(assetInfo.url);\n                    const arrayBuffer = await response.arrayBuffer();\n                    const audioBuffer = await getAudioContext().decodeAudioData(arrayBuffer);\n                    const audioData = { buffer: audioBuffer, loop: assetInfo.loop === 'true' };\n                    if (!audioCache[assetId]) {\n                        audioCache[assetId] = audioData;\n                    }\n                    return audioCache[assetId];\n                } catch (e) {\n                    lib.log(`Failed to load audio: ${assetId}`);\n                    return null;\n                }\n            }\n\n            function playSound(assetId, volume = 1.0) {\n                const audio = audioCache[assetId];\n                if (!audio) return null;\n\n                const ctx = getAudioContext();\n                const source = ctx.createBufferSource();\n                const gainNode = ctx.createGain();\n                \n                source.buffer = audio.buffer;\n                source.loop = audio.loop;\n                gainNode.gain.value = volume;\n                \n                source.connect(gainNode);\n                gainNode.connect(ctx.destination);\n                source.start(0);\n                \n                return { source, gainNode };\n            }\n\n            // Preload all assets\n            async function preloadAssets() {\n                const imageAssets = [\n                    'cake_stand',\n                    // Flavors\n                    'ice_cream_vanilla', 'ice_cream_chocolate', 'ice_cream_strawberry',\n                    'ice_cream_mint', 'ice_cream_cookies_cream', 'ice_cream_mango', \n                    'ice_cream_blueberry', 'ice_cream_caramel',\n                    'ice_cream_coffee', 'ice_cream_pistachio', 'ice_cream_bubblegum', 'ice_cream_lemon',\n                    'ice_cream_raspberry', 'ice_cream_matcha', 'ice_cream_cotton_candy', 'ice_cream_banana',\n                    'ice_cream_cheesecake', 'ice_cream_red_velvet', 'ice_cream_peanut_butter', 'ice_cream_birthday_cake', 'ice_cream_black_sesame', 'ice_cream_salted_caramel',\n                    // Toppings\n                    'topping_chocolate_chips', 'topping_rainbow_sprinkles', 'topping_strawberry_slices',\n                    'topping_crushed_oreos', 'topping_nuts', 'topping_gummy_bears', 'topping_caramel_drizzle',\n                    'topping_marshmallows', 'topping_coconut', 'topping_blueberries', 'topping_cookie_crumbs',\n                    'topping_raspberries', 'topping_banana_slices', 'topping_candy_pieces', 'topping_graham_crumbs', 'topping_honey_drizzle',\n                    'topping_mini_oreos', 'topping_pretzel_pieces', 'topping_caramel_bits', 'topping_chocolate_shavings', 'topping_toffee_bits', 'topping_peanuts',\n                    // Decorations\n                    'decoration_cherry', 'decoration_chocolate_drizzle',\n                    'decoration_whipped_cream', 'decoration_wafer_sticks', 'decoration_candles', 'decoration_star_sprinkles',\n                    'decoration_chocolate_curl', 'decoration_fondant_flower', 'decoration_sugar_pearls', 'decoration_macaron',\n                    'decoration_mint_leaves', 'decoration_gold_flakes', 'decoration_chocolate_heart', 'decoration_unicorn_horn', 'decoration_sprinkle_hearts',\n                    'decoration_edible_glitter', 'decoration_chocolate_shards', 'decoration_candy_cane', 'decoration_gummy_worms', 'decoration_lollipop', 'decoration_strawberry',\n                    // Frostings\n                    'frosting_vanilla', 'frosting_strawberry', 'frosting_chocolate',\n                    'frosting_mint', 'frosting_caramel',\n                    'frosting_lemon', 'frosting_blueberry', 'frosting_cream_cheese',\n                    'frosting_raspberry', 'frosting_matcha', 'frosting_cookies_cream', 'frosting_peanut_butter',\n                    'frosting_rose', 'frosting_galaxy', 'frosting_rainbow', 'frosting_gold_shimmer', 'frosting_lavender', 'frosting_ombre_pink', 'frosting_bubblegum', 'frosting_cotton_candy',\n                    'frosting_red_velvet', 'frosting_cheesecake', 'frosting_birthday_cake', 'frosting_black_sesame',\n                    'frosting_mango', 'frosting_coffee', 'frosting_pistachio', 'frosting_banana', 'frosting_salted_caramel',\n                    // UI\n                    'customer_1', 'customer_2', 'customer_3',\n                    'icon_flavors', 'icon_toppings', 'icon_decorations', 'icon_frostings',\n                    'star_empty', 'star_filled', 'coin_icon'\n                ];\n\n                const audioAssets = [\n                    'sound_add_layer', 'sound_add_topping', 'sound_add_decoration',\n                    'sound_submit_cake', 'sound_star_award', 'sound_coin_collect',\n                    'sound_unlock', 'background_music', 'sound_button_click',\n                    'sound_tab_switch', 'sound_select', 'sound_whoosh', 'sound_pop',\n                    'sound_swap', 'sound_delete', 'sound_drag', 'sound_drop',\n                    'sound_mode_switch', 'sound_new_order'\n                ];\n\n                await Promise.all([\n                    ...imageAssets.map(id => loadImage(id)),\n                    ...audioAssets.map(id => loadAudio(id))\n                ]);\n            }\n\n            // ==================== CANVAS SETUP ====================\n            function resizeCanvas() {\n                canvas.width = gameWorld.clientWidth;\n                canvas.height = gameWorld.clientHeight;\n            }\n            resizeCanvas();\n            window.addEventListener('resize', resizeCanvas);\n\n            // ==================== GAME STATE ====================\n            const config = window.gameConfig;\n            \n            // Runtime state (not persisted in gameConfig)\n            let currentOrder = null;\n            let currentCake = {\n                layers: [],      // Array of { flavor, toppings: [{id, x, y}], frosting }\n                decorations: []  // Array of { id, x, y }\n            };\n            \n            // Drag state for toppings and decorations on cake\n            let draggingItem = null; // { type: 'topping'|'decoration', layerIndex?, decorationIndex?, startX, startY }\n            let dragOffset = { x: 0, y: 0 };\n            let currentCustomer = null;\n            let selectedCategory = 'flavors';\n            let selectedIngredient = null;\n            let selectedLayerIndex = null; // Track which layer is selected for editing\n            let totalStars = 0;\n            let showingResult = false;\n            let resultData = null;\n            let backgroundMusicSource = null;\n            let gameMode = 'orders'; // 'orders' or 'free'\n            let isFirstGame = true; // Track if this is the first order\n            let savedCakes = []; // Gallery of saved cakes\n            let showingGallery = false;\n            let undoStack = []; // For undo/redo\n            let redoStack = [];\n            \n            // Mascot state\n            let mascotBubbleTimeout = null;\n            let mascotAnimTimeout = null;\n\n            // Animation state\n            let animations = [];\n            \n            // Bounds for hit detection (updated each frame)\n            let decorationBounds = [];\n            let layerBounds = []; // For layer selection\n\n            // ==================== HELPER FUNCTIONS ====================\n            function getUnlockedItems() {\n                return config.unlockedItems || ['vanilla', 'chocolate', 'strawberry', 'chocolate_chips', 'cherry'];\n            }\n\n            function isUnlocked(itemId) {\n                return getUnlockedItems().includes(itemId);\n            }\n\n            function getCoins() {\n                return config.totalCoins || 0;\n            }\n\n            function addCoins(amount) {\n                config.totalCoins = getCoins() + amount;\n            }\n\n            function unlockItem(itemId) {\n                if (!config.unlockedItems) {\n                    config.unlockedItems = ['vanilla', 'chocolate', 'strawberry', 'chocolate_chips', 'cherry'];\n                }\n                if (!config.unlockedItems.includes(itemId)) {\n                    config.unlockedItems.push(itemId);\n                }\n            }\n\n            function getAllIngredients() {\n                return [...FLAVORS, ...TOPPINGS, ...DECORATIONS, ...FROSTINGS];\n            }\n\n            function getLayerToppings(layer) {\n                if (Array.isArray(layer.toppings)) return layer.toppings;\n                if (layer.topping) {\n                    const existing = typeof layer.topping === 'object' ? layer.topping : { id: layer.topping };\n                    layer.toppings = [existing];\n                    layer.topping = null;\n                    return layer.toppings;\n                }\n                layer.toppings = [];\n                layer.topping = null;\n                return layer.toppings;\n            }\n\n            function getNextUnlockable() {\n                const allItems = getAllIngredients();\n                const unlocked = getUnlockedItems();\n                \n                for (const item of allItems) {\n                    if (!unlocked.includes(item.id) && item.unlockCost > 0) {\n                        return item;\n                    }\n                }\n                return null;\n            }\n\n            // ==================== ORDER GENERATION ====================\n            let orderCount = 0; // Track how many orders have been completed\n            \n            function generateOrder(isFirstOrder = false) {\n                // First order is a creative challenge - make anything you want!\n                if (isFirstOrder) {\n                    currentCustomer = 'customer_1';\n                    return {\n                        creative: true, // Special flag for creative orders\n                        layers: [],\n                        decorations: []\n                    };\n                }\n                \n                orderCount++;\n                \n                // Start easy: first few orders are simpler\n                // Order 1-3: 1-2 layers, no frostings, no decorations\n                // Order 4-6: 2-3 layers, maybe frosting, no decorations  \n                // Order 7+: use full complexity\n                let numLayers, allowFrosting, allowDecorations, allowToppings;\n                \n                if (orderCount <= 3) {\n                    // Very easy: 1-2 layers, no extras\n                    numLayers = 1 + Math.floor(Math.random() * 2);\n                    allowFrosting = false;\n                    allowDecorations = false;\n                    allowToppings = false;\n                } else if (orderCount <= 6) {\n                    // Easy: 2 layers, maybe topping\n                    numLayers = 2;\n                    allowFrosting = false;\n                    allowDecorations = false;\n                    allowToppings = Math.random() > 0.5;\n                } else if (orderCount <= 10) {\n                    // Medium: 2-3 layers, toppings, maybe frosting\n                    numLayers = 2 + Math.floor(Math.random() * 2);\n                    allowFrosting = Math.random() > 0.5;\n                    allowDecorations = false;\n                    allowToppings = true;\n                } else {\n                    // Full complexity based on settings\n                    const complexity = config.orderComplexity || 2;\n                    numLayers = Math.min(2 + Math.floor(Math.random() * complexity), 5);\n                    allowFrosting = true;\n                    allowDecorations = true;\n                    allowToppings = true;\n                }\n                \n                // Use simpler flavors for early orders\n                const simpleFlavors = FLAVORS.slice(0, 6); // First 6 flavors are basics\n                const unlockedFlavors = orderCount <= 6 ? simpleFlavors.filter(f => isUnlocked(f.id)) : FLAVORS.filter(f => isUnlocked(f.id));\n                const unlockedToppings = TOPPINGS.filter(t => isUnlocked(t.id));\n                const unlockedDecorations = DECORATIONS.filter(d => isUnlocked(d.id));\n                const unlockedFrostings = FROSTINGS.filter(f => isUnlocked(f.id));\n\n                const layers = [];\n                for (let i = 0; i < numLayers; i++) {\n                    const flavor = unlockedFlavors[Math.floor(Math.random() * unlockedFlavors.length)];\n                    const hasTopping = allowToppings && Math.random() > 0.4 && unlockedToppings.length > 0;\n                    const topping = hasTopping ? unlockedToppings[Math.floor(Math.random() * unlockedToppings.length)] : null;\n                    const hasFrosting = allowFrosting && Math.random() > 0.5 && unlockedFrostings.length > 0;\n                    const frosting = hasFrosting ? unlockedFrostings[Math.floor(Math.random() * unlockedFrostings.length)] : null;\n                    \n                    layers.push({\n                        flavor: flavor.id,\n                        topping: topping ? topping.id : null,\n                        frosting: frosting ? frosting.id : null\n                    });\n                }\n\n                const decorations = [];\n                if (allowDecorations && unlockedDecorations.length > 0 && Math.random() > 0.3) {\n                    const dec = unlockedDecorations[Math.floor(Math.random() * unlockedDecorations.length)];\n                    decorations.push(dec.id);\n                }\n\n                currentCustomer = CUSTOMERS[Math.floor(Math.random() * CUSTOMERS.length)];\n\n                return { layers, decorations };\n            }\n\n            // ==================== SCORING ====================\n            function calculateScore() {\n                if (!currentOrder) return { stars: 0, coins: 0, accuracy: 0, details: [] };\n\n                // Creative orders - score based on cake complexity\n                if (currentOrder.creative) {\n                    const numLayers = currentCake.layers.length;\n                    const numToppings = currentCake.layers.reduce((sum, layer) => {\n                        const toppings = getLayerToppings(layer);\n                        return sum + toppings.length;\n                    }, 0);\n                    const numFrostings = currentCake.layers.filter(l => l.frosting).length;\n                    const numDecorations = currentCake.decorations.length;\n                    \n                    // Award stars based on creativity/complexity\n                    let stars = 0;\n                    const totalItems = numLayers + numToppings + numFrostings + numDecorations;\n                    if (totalItems >= 1) stars = 1;\n                    if (totalItems >= 3) stars = 2;\n                    if (totalItems >= 5) stars = 3;\n                    \n                    const baseCoins = stars * 10;\n                    const bonus = stars === 3 ? (config.perfectMatchBonus || 25) : 0;\n                    \n                    return { \n                        stars, \n                        coins: baseCoins + bonus, \n                        accuracy: stars * 33,\n                        creative: true,\n                        details: [\n                            { label: 'Layers', value: numLayers, match: numLayers > 0 },\n                            { label: 'Frostings', value: numFrostings, match: numFrostings > 0 },\n                            { label: 'Toppings', value: numToppings, match: numToppings > 0 },\n                            { label: 'Decorations', value: numDecorations, match: numDecorations > 0 }\n                        ]\n                    };\n                }\n\n                let matches = 0;\n                let total = 0;\n                const details = [];\n\n                // Check layers\n                const orderLayers = currentOrder.layers;\n                const cakeLayers = currentCake.layers;\n                \n                // Layer count check\n                const layerCountMatch = orderLayers.length === cakeLayers.length;\n                details.push({ \n                    label: 'Layers', \n                    value: `${cakeLayers.length}/${orderLayers.length}`, \n                    match: layerCountMatch \n                });\n\n                let flavorMatches = 0;\n                let toppingMatches = 0;\n                let frostingMatches = 0;\n                let totalFlavors = orderLayers.length;\n                let totalToppings = 0;\n                let totalFrostings = 0;\n\n                for (let i = 0; i < Math.max(orderLayers.length, cakeLayers.length); i++) {\n                    total += 3; // flavor + topping + frosting potential\n                    \n                    if (i < orderLayers.length && i < cakeLayers.length) {\n                        // Flavor check\n                        if (orderLayers[i].flavor === cakeLayers[i].flavor) {\n                            matches++;\n                            flavorMatches++;\n                        }\n                        \n                        // Topping check\n                        const orderTopping = orderLayers[i].topping;\n                        const cakeToppings = getLayerToppings(cakeLayers[i]);\n                        const cakeToppingIds = cakeToppings.map(t => (typeof t === 'object' ? t.id : t));\n                        \n                        if (orderTopping) totalToppings++;\n                        \n                        if (orderTopping === null && cakeToppingIds.length === 0) {\n                            matches++;\n                        } else if (orderTopping && cakeToppingIds.includes(orderTopping)) {\n                            matches++;\n                            toppingMatches++;\n                        }\n                        \n                        // Frosting check\n                        if (orderLayers[i].frosting) totalFrostings++;\n                        \n                        if (orderLayers[i].frosting === cakeLayers[i].frosting) {\n                            matches++;\n                            if (orderLayers[i].frosting) frostingMatches++;\n                        }\n                    }\n                }\n\n                // Add flavor details\n                details.push({ \n                    label: 'Flavors', \n                    value: `${flavorMatches}/${totalFlavors}`, \n                    match: flavorMatches === totalFlavors \n                });\n\n                // Add frosting details if order has frostings\n                if (totalFrostings > 0) {\n                    details.push({ \n                        label: 'Frostings', \n                        value: `${frostingMatches}/${totalFrostings}`, \n                        match: frostingMatches === totalFrostings \n                    });\n                }\n\n                // Add topping details if order has toppings\n                if (totalToppings > 0) {\n                    details.push({ \n                        label: 'Toppings', \n                        value: `${toppingMatches}/${totalToppings}`, \n                        match: toppingMatches === totalToppings \n                    });\n                }\n\n                // Check decorations\n                const orderDecs = currentOrder.decorations;\n                const cakeDecs = currentCake.decorations.map(d => typeof d === 'object' ? d.id : d);\n                \n                let decMatches = 0;\n                total += Math.max(orderDecs.length, cakeDecs.length);\n                for (const dec of orderDecs) {\n                    if (cakeDecs.includes(dec)) {\n                        matches++;\n                        decMatches++;\n                    }\n                }\n\n                // Add decoration details if order has decorations\n                if (orderDecs.length > 0) {\n                    details.push({ \n                        label: 'Decorations', \n                        value: `${decMatches}/${orderDecs.length}`, \n                        match: decMatches === orderDecs.length \n                    });\n                }\n\n                const accuracy = total > 0 ? (matches / total) * 100 : 0;\n                \n                const thresholds = config.starThresholds || { oneStar: 40, twoStar: 70, threeStar: 90 };\n                let stars = 0;\n                if (accuracy >= thresholds.threeStar) stars = 3;\n                else if (accuracy >= thresholds.twoStar) stars = 2;\n                else if (accuracy >= thresholds.oneStar) stars = 1;\n\n                const baseCoins = stars * 10;\n                const bonus = stars === 3 ? (config.perfectMatchBonus || 25) : 0;\n                const coins = baseCoins + bonus;\n\n                return { stars, coins, accuracy: Math.round(accuracy), details };\n            }\n\n            // ==================== DRAWING FUNCTIONS ====================\n            function drawBackground() {\n                const bgColor = config.backgroundColor || '#FFE4EC';\n                \n                // Create soft pink gradient background\n                const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);\n                gradient.addColorStop(0, '#FFF5F8');\n                gradient.addColorStop(0.3, '#FFE4EC');\n                gradient.addColorStop(0.7, '#FFC0CB');\n                gradient.addColorStop(1, '#FFB6C1');\n                ctx.fillStyle = gradient;\n                ctx.fillRect(0, 0, canvas.width, canvas.height);\n                \n                // Add subtle radial glow in center\n                const centerGlow = ctx.createRadialGradient(\n                    canvas.width / 2, canvas.height * 0.45, 0,\n                    canvas.width / 2, canvas.height * 0.45, canvas.width * 0.6\n                );\n                centerGlow.addColorStop(0, 'rgba(255, 255, 255, 0.5)');\n                centerGlow.addColorStop(0.5, 'rgba(255, 255, 255, 0.2)');\n                centerGlow.addColorStop(1, 'rgba(255, 255, 255, 0)');\n                ctx.fillStyle = centerGlow;\n                ctx.fillRect(0, 0, canvas.width, canvas.height);\n                \n                // Draw decorative border stripes (top and bottom)\n                const stripeGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);\n                stripeGradient.addColorStop(0, '#FFB6C1');\n                stripeGradient.addColorStop(0.5, '#FF69B4');\n                stripeGradient.addColorStop(1, '#FFB6C1');\n                ctx.fillStyle = stripeGradient;\n                ctx.fillRect(0, 0, canvas.width, 4);\n                \n                // Draw floating sparkles/stars\n                const time = Date.now() / 1000;\n                for (let i = 0; i < 12; i++) {\n                    const baseX = (canvas.width * (i % 6 + 0.5)) / 6;\n                    const baseY = canvas.height * (0.2 + Math.floor(i / 6) * 0.25);\n                    const floatY = Math.sin(time + i * 0.7) * 8;\n                    const floatX = Math.cos(time * 0.5 + i) * 5;\n                    const size = 3 + Math.sin(time * 2 + i) * 1.5;\n                    const alpha = 0.4 + Math.sin(time * 1.5 + i * 0.5) * 0.2;\n                    \n                    // Draw star shape\n                    ctx.save();\n                    ctx.translate(baseX + floatX, baseY + floatY);\n                    ctx.fillStyle = `rgba(255, 105, 180, ${alpha})`;\n                    drawStar(ctx, 0, 0, 4, size, size / 2);\n                    ctx.restore();\n                }\n                \n                // Draw soft bokeh circles\n                for (let i = 0; i < 8; i++) {\n                    const x = (canvas.width * (i + 0.3)) / 8 + Math.sin(time * 0.3 + i) * 20;\n                    const y = canvas.height * (0.15 + (i % 3) * 0.2) + Math.cos(time * 0.4 + i) * 15;\n                    const radius = 20 + Math.sin(time + i * 2) * 8;\n                    const alpha = 0.15 + Math.sin(time * 0.5 + i) * 0.05;\n                    \n                    const bokehGrad = ctx.createRadialGradient(x, y, 0, x, y, radius);\n                    bokehGrad.addColorStop(0, `rgba(255, 255, 255, ${alpha})`);\n                    bokehGrad.addColorStop(1, 'rgba(255, 255, 255, 0)');\n                    ctx.fillStyle = bokehGrad;\n                    ctx.beginPath();\n                    ctx.arc(x, y, radius, 0, Math.PI * 2);\n                    ctx.fill();\n                }\n                \n                // Draw subtle diagonal lines pattern\n                ctx.strokeStyle = 'rgba(255, 255, 255, 0.15)';\n                ctx.lineWidth = 1;\n                for (let i = -canvas.height; i < canvas.width + canvas.height; i += 40) {\n                    ctx.beginPath();\n                    ctx.moveTo(i, 0);\n                    ctx.lineTo(i + canvas.height, canvas.height);\n                    ctx.stroke();\n                }\n            }\n            \n            // Helper function to draw star shapes\n            function drawStar(ctx, cx, cy, spikes, outerRadius, innerRadius) {\n                let rot = Math.PI / 2 * 3;\n                let x = cx;\n                let y = cy;\n                const step = Math.PI / spikes;\n                \n                ctx.beginPath();\n                ctx.moveTo(cx, cy - outerRadius);\n                for (let i = 0; i < spikes; i++) {\n                    x = cx + Math.cos(rot) * outerRadius;\n                    y = cy + Math.sin(rot) * outerRadius;\n                    ctx.lineTo(x, y);\n                    rot += step;\n                    \n                    x = cx + Math.cos(rot) * innerRadius;\n                    y = cy + Math.sin(rot) * innerRadius;\n                    ctx.lineTo(x, y);\n                    rot += step;\n                }\n                ctx.lineTo(cx, cy - outerRadius);\n                ctx.closePath();\n                ctx.fill();\n            }\n\n            function drawCakeStand() {\n                const standImg = imageCache['cake_stand'];\n                if (!standImg) return;\n\n                const standWidth = 420;\n                const aspectRatio = standImg.height / standImg.width;\n                const standHeight = standWidth * aspectRatio;\n                \n                const tableXOffset = config.tableHorizontalPosition || 0;\n                const x = (canvas.width - standWidth) / 2 + tableXOffset;\n                const tablePosition = (config.tableVerticalPosition || 55) / 100;\n                const y = canvas.height * tablePosition;\n\n                ctx.drawImage(standImg, x, y, standWidth, standHeight);\n\n                return { x: x + standWidth / 2, y: y, width: standWidth };\n            }\n\n            function drawCake(standInfo) {\n                if (!standInfo) return;\n\n                const cakeScale = (config.cakeScale || 100) / 100;\n                const layerWidth = 280 * cakeScale;\n                const layerHeight = 70 * cakeScale;\n                const cakeXOffset = config.cakeHorizontalPosition || 0;\n                const cakeOffset = config.cakeVerticalPosition !== undefined ? config.cakeVerticalPosition : 0;\n                const baseY = standInfo.y - 10 + cakeOffset;\n                const centerX = standInfo.x + cakeXOffset;\n\n                // FIRST: Draw all ice cream layers and frostings\n                layerBounds = []; // Reset layer bounds\n                currentCake.layers.forEach((layer, index) => {\n                    const y = baseY - (index + 1) * (layerHeight - 10);\n                    \n                    // Draw selection highlight if this layer is selected\n                    if (selectedLayerIndex === index) {\n                        ctx.save();\n                        ctx.strokeStyle = '#FF69B4';\n                        ctx.lineWidth = 4;\n                        ctx.setLineDash([10, 5]);\n                        ctx.beginPath();\n                        ctx.roundRect(centerX - layerWidth / 2 - 10, y - layerHeight / 2 - 10, layerWidth + 20, layerHeight + 10, 10);\n                        ctx.stroke();\n                        ctx.restore();\n                    }\n                    \n                    // Draw ice cream layer\n                    const flavorData = FLAVORS.find(f => f.id === layer.flavor);\n                    if (flavorData) {\n                        const img = imageCache[flavorData.assetId];\n                        if (img) {\n                            const aspectRatio = img.height / img.width;\n                            const drawHeight = layerWidth * aspectRatio;\n                            ctx.drawImage(img, centerX - layerWidth / 2, y - drawHeight / 2, layerWidth, drawHeight);\n                            \n                            // Store layer bounds for tap detection\n                            layerBounds.push({\n                                x: centerX - layerWidth / 2,\n                                y: y - drawHeight / 2,\n                                width: layerWidth,\n                                height: drawHeight,\n                                index: index\n                            });\n                        }\n                    }\n\n                    // Draw frosting on layer\n                    if (layer.frosting) {\n                        const frostingData = FROSTINGS.find(f => f.id === layer.frosting);\n                        if (frostingData) {\n                            const img = imageCache[frostingData.assetId];\n                            if (img) {\n                                const frostingWidth = layerWidth + 20 * cakeScale;\n                                const aspectRatio = img.height / img.width;\n                                const drawHeight = frostingWidth * aspectRatio;\n                                ctx.drawImage(img, centerX - frostingWidth / 2, y - drawHeight / 2, frostingWidth, drawHeight);\n                            }\n                        }\n                    }\n                });\n\n                // SECOND: Draw all toppings (in front of cake layers)\n                currentCake.layers.forEach((layer, index) => {\n                    const y = baseY - (index + 1) * (layerHeight - 10);\n                    \n                    const toppings = getLayerToppings(layer);\n                    layer.toppingBounds = [];\n                    toppings.forEach((toppingObj, tIndex) => {\n                        const toppingId = typeof toppingObj === 'object' ? toppingObj.id : toppingObj;\n                        const toppingData = TOPPINGS.find(t => t.id === toppingId);\n                        if (toppingData) {\n                            const img = imageCache[toppingData.assetId];\n                            if (img) {\n                                // Topping size\n                                const toppingSize = 36 * cakeScale;\n                                const aspectRatio = img.height / img.width;\n                                const drawHeight = toppingSize * aspectRatio;\n                                \n                                // Use custom position if available, otherwise default\n                                let drawX, drawY;\n                                if (typeof toppingObj === 'object' && toppingObj.x !== undefined) {\n                                    drawX = toppingObj.x - toppingSize / 2;\n                                    drawY = toppingObj.y - drawHeight / 2;\n                                } else {\n                                    const offsetX = (tIndex * 16 - 8) * cakeScale;\n                                    drawX = centerX - toppingSize / 2 + offsetX;\n                                    drawY = y - drawHeight / 2 - 15;\n                                    if (typeof toppingObj === 'object') {\n                                        toppingObj.x = drawX + toppingSize / 2;\n                                        toppingObj.y = drawY + drawHeight / 2;\n                                    }\n                                }\n                                \n                                ctx.drawImage(img, drawX, drawY, toppingSize, drawHeight);\n                                \n                                // Store bounds for hit detection\n                                layer.toppingBounds.push({ x: drawX, y: drawY, width: toppingSize, height: drawHeight, layerIndex: index, toppingIndex: tIndex });\n                            }\n                        }\n                    });\n                });\n\n                // THIRD: Draw decorations on top (in front of everything)\n                if (currentCake.layers.length > 0) {\n                    const topY = baseY - currentCake.layers.length * (layerHeight - 10) - 30 * cakeScale;\n                    \n                    // Store decoration bounds for hit detection\n                    decorationBounds = [];\n                    \n                    currentCake.decorations.forEach((dec, index) => {\n                        const decId = typeof dec === 'object' ? dec.id : dec;\n                        const decData = DECORATIONS.find(d => d.id === decId);\n                        if (decData) {\n                            const img = imageCache[decData.assetId];\n                            if (img) {\n                                // Tiny decoration sizes\n                                let decWidth;\n                                if (decId === 'chocolate_drizzle' || decId === 'caramel_drizzle' || decId === 'honey_drizzle') {\n                                    decWidth = 50 * cakeScale;\n                                } else if (decId === 'candles') {\n                                    decWidth = 10 * cakeScale;\n                                } else if (decId === 'star_sprinkles') {\n                                    decWidth = 12 * cakeScale;\n                                } else if (decId === 'cherry') {\n                                    decWidth = 18 * cakeScale;\n                                } else if (decId === 'wafer_sticks') {\n                                    decWidth = 14 * cakeScale;\n                                } else if (decId === 'whipped_cream') {\n                                    decWidth = 24 * cakeScale;\n                                } else {\n                                    decWidth = 20 * cakeScale;\n                                }\n                                const aspectRatio = img.height / img.width;\n                                const decHeight = decWidth * aspectRatio;\n                                \n                                // Use custom position if available, otherwise default\n                                let drawX, drawY;\n                                if (typeof dec === 'object' && dec.x !== undefined) {\n                                    drawX = dec.x - decWidth / 2;\n                                    drawY = dec.y - decHeight / 2;\n                                } else {\n                                    const offsetX = (index * 25 - 12) * cakeScale;\n                                    const extraYOffset = (decId === 'candles') ? -10 * cakeScale : 0;\n                                    drawX = centerX - decWidth / 2 + offsetX;\n                                    drawY = topY - decHeight + extraYOffset;\n                                }\n                                \n                                ctx.drawImage(img, drawX, drawY, decWidth, decHeight);\n                                \n                                // Store bounds for hit detection\n                                decorationBounds.push({ x: drawX, y: drawY, width: decWidth, height: decHeight, index: index });\n                            }\n                        }\n                    });\n                }\n            }\n\n            function drawAnimations() {\n                const now = Date.now();\n                animations = animations.filter(anim => {\n                    const elapsed = now - anim.startTime;\n                    const progress = Math.min(elapsed / anim.duration, 1);\n                    \n                    if (anim.type === 'addLayer') {\n                        const scale = 1 + Math.sin(progress * Math.PI) * 0.2;\n                        ctx.save();\n                        ctx.globalAlpha = 1 - progress * 0.5 + 0.5;\n                        // Animation handled by redraw\n                        ctx.restore();\n                    }\n                    \n                    return progress < 1;\n                });\n            }\n\n            // ==================== UI CREATION ====================\n            function createUI() {\n                uiOverlay.innerHTML = '';\n\n                if (mode === 'edit') {\n                    createEditModeUI();\n                    return;\n                }\n\n                // Top header with game title, mode buttons, and order card\n                const topHeader = document.createElement('div');\n                topHeader.className = 'top-header';\n                topHeader.innerHTML = `\n                    <div class=\"header-row\">\n                        <div class=\"game-title\">\ud83c\udf70 Sweet Stack</div>\n                        <div class=\"score-section\">\n                            <div class=\"mode-buttons\">\n                                <button class=\"mode-btn\" id=\"free-mode-btn\">Free</button>\n                                <button class=\"mode-btn active\" id=\"order-mode-btn\">Orders</button>\n                                <button class=\"mode-btn gallery-top-btn\" id=\"gallery-btn\">\ud83d\udcf8</button>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"order-card-horizontal\" id=\"order-card-horizontal\">\n                        <div class=\"order-badge\">\n                            <span class=\"order-badge-label\">ORDER</span>\n                            <span class=\"order-badge-number\" id=\"order-number\">#1</span>\n                        </div>\n                        <div class=\"customer-avatar\">\n                            <img id=\"customer-img\" src=\"\" alt=\"Customer\">\n                        </div>\n                        <div class=\"order-content\">\n                            <div class=\"order-title\">Order</div>\n                            <div class=\"order-description\" id=\"order-description\">This is what I'd like:</div>\n                            <div class=\"order-items\" id=\"order-items\"></div>\n                        </div>\n                    </div>\n                `;\n                uiOverlay.appendChild(topHeader);\n\n                // Top bar removed - content moved to header\n\n                // Bottom panel\n                const bottomPanel = document.createElement('div');\n                bottomPanel.className = 'bottom-panel';\n                bottomPanel.innerHTML = `\n                    <div class=\"layer-counter\" id=\"layer-counter\">\n                    <span class=\"layer-counter-icon\">\ud83c\udf70</span>\n                    <span class=\"layer-counter-text\">Layers:</span>\n                    <div class=\"layer-counter-bar\" id=\"layer-counter-bar\"></div>\n                </div>\n                <div class=\"tab-tutorial\" id=\"tab-tutorial\"></div>\n                <div class=\"category-tabs\" id=\"category-tabs\"></div>\n                <div class=\"ingredient-carousel\" id=\"ingredient-carousel\"></div>\n                <div class=\"action-buttons\">\n                        <button class=\"action-btn secondary\" id=\"undo-btn\">\u21a9 Undo</button>\n                        <button class=\"action-btn secondary\" id=\"redo-btn\">\u21aa Redo</button>\n                        <button class=\"action-btn secondary\" id=\"new-btn\">\u2728 New</button>\n                        <button class=\"action-btn secondary\" id=\"save-btn\">\ud83d\udcbe Save</button>\n                        <button class=\"submit-btn\" id=\"submit-btn\" disabled>Submit</button>\n                    </div>\n                `;\n                uiOverlay.appendChild(bottomPanel);\n\n                // Result modal\n                const resultModal = document.createElement('div');\n                resultModal.className = 'result-modal';\n                resultModal.id = 'result-modal';\n                resultModal.innerHTML = `\n                    <div class=\"result-content\">\n                        <div class=\"result-title\" id=\"result-title\">Great Job!</div>\n                        <div class=\"result-subtitle\" id=\"result-subtitle\">Order Complete</div>\n                        <div class=\"result-stars\" id=\"result-stars\"></div>\n                        <div class=\"result-accuracy\" id=\"result-accuracy\">Accuracy: <span>100%</span></div>\n                        <div class=\"result-summary\" id=\"result-summary\"></div>\n                        <div class=\"result-message\" id=\"result-message\"></div>\n\n                        <button class=\"next-btn\" id=\"next-btn\">Next Order</button>\n                    </div>\n                `;\n                uiOverlay.appendChild(resultModal);\n\n                // Game Mascot\n                const mascotContainer = document.createElement('div');\n                mascotContainer.className = 'game-mascot idle';\n                mascotContainer.id = 'game-mascot';\n                const mascotAsset = lib.getAsset('cake_mascot');\n                mascotContainer.innerHTML = `\n                    <img src=\"${mascotAsset ? mascotAsset.url : ''}\" alt=\"Cake Mascot\">\n                `;\n                uiOverlay.appendChild(mascotContainer);\n\n                // Unlock notification\n                const unlockNotif = document.createElement('div');\n                unlockNotif.className = 'unlock-notification';\n                unlockNotif.id = 'unlock-notification';\n                unlockNotif.textContent = 'New Item Unlocked!';\n                uiOverlay.appendChild(unlockNotif);\n\n                // Gallery modal\n                const galleryModal = document.createElement('div');\n                galleryModal.className = 'gallery-modal';\n                galleryModal.id = 'gallery-modal';\n                galleryModal.innerHTML = `\n                    <div class=\"gallery-header\">\n                        <div class=\"gallery-title\">\ud83c\udfa8 My Creations</div>\n                        <button class=\"gallery-close-btn\" id=\"gallery-close-btn\">\u2715</button>\n                    </div>\n                    <div class=\"gallery-grid\" id=\"gallery-grid\"></div>\n                    <button class=\"gallery-save-btn\" id=\"gallery-save-btn\" disabled>\ud83d\udcbe Save Current Cake</button>\n                `;\n                uiOverlay.appendChild(galleryModal);\n\n\n                // Set up event listeners\n                setupEventListeners();\n                \n                // Add button feedback to all interactive elements\n                setupButtonFeedback();\n                \n                // Initialize UI\n                updateUI();\n            }\n\n            function createEditModeUI() {\n                const notice = document.createElement('div');\n                notice.className = 'edit-mode-notice';\n                notice.innerHTML = `\n                    <h2>\ud83c\udf82 Edit Mode</h2>\n                    <p>Use the settings panel to customize your ice cream cake shop! Adjust colors, difficulty, and starting ingredients.</p>\n                `;\n                uiOverlay.appendChild(notice);\n            }\n\n            function setupEventListeners() {\n                // Category tabs\n                document.getElementById('category-tabs').addEventListener('click', (e) => {\n                    const tab = e.target.closest('.category-tab');\n                    if (tab) {\n                        const newCategory = tab.dataset.category;\n                        if (newCategory !== selectedCategory) {\n                            playSound('sound_tab_switch', 0.2);\n                        }\n                        selectedCategory = newCategory;\n                        selectedIngredient = null;\n                        selectedLayerIndex = null; // Clear layer selection when switching categories\n                        updateUI();\n                        // Scroll carousel back to top\n                        const carousel = document.getElementById('ingredient-carousel');\n                        if (carousel) {\n                            carousel.scrollTop = 0;\n                        }\n                    }\n                });\n\n                // Ingredient selection - tap to add directly\n                document.getElementById('ingredient-carousel').addEventListener('click', (e) => {\n                    const item = e.target.closest('.ingredient-item');\n                    if (item && !item.classList.contains('locked')) {\n                        const ingredientId = item.dataset.id;\n                        \n                        // For flavors and frostings\n                        if (selectedCategory === 'flavors' || selectedCategory === 'frostings') {\n                            // If a layer is selected, change that layer\n                            if (selectedLayerIndex !== null && selectedLayerIndex < currentCake.layers.length) {\n                                const layer = currentCake.layers[selectedLayerIndex];\n                                if (selectedCategory === 'flavors') {\n                                    layer.flavor = ingredientId;\n                                } else {\n                                    layer.frosting = ingredientId;\n                                }\n                                playSound('sound_add_layer', 0.15);\n                                selectedIngredient = ingredientId;\n                            } else {\n                                // No layer selected\n                                if (selectedCategory === 'flavors') {\n                                    // Flavors add new layers when nothing selected\n                                    addLayer(ingredientId);\n                                    selectedIngredient = ingredientId;\n                                } else {\n                                    // Frostings require selecting a layer first\n                                    // Removed sound - visual feedback is enough\n                                    selectedIngredient = ingredientId;\n                                }\n                            }\n                        } else {\n                            // Toppings and decorations - just select, don't add yet\n                            // Player must tap on the cake to place it\n                            selectedIngredient = ingredientId;\n                            playSound('sound_select', 0.2);\n                        }\n                        updateUI();\n                    } else if (item && item.classList.contains('locked')) {\n                        // Locked item feedback - removed sound\n                    }\n                });\n\n                // Mode buttons\n                document.getElementById('order-mode-btn').addEventListener('click', () => {\n                    if (gameMode !== 'orders') {\n                        playSound('sound_mode_switch', 0.3);\n                        gameMode = 'orders';\n                        document.getElementById('order-mode-btn').classList.add('active');\n                        document.getElementById('free-mode-btn').classList.remove('active');\n                        reactToModeSwitch();\n                        startNewOrder();\n                    }\n                });\n\n                document.getElementById('free-mode-btn').addEventListener('click', () => {\n                    if (gameMode !== 'free') {\n                        playSound('sound_mode_switch', 0.3);\n                        gameMode = 'free';\n                        document.getElementById('free-mode-btn').classList.add('active');\n                        document.getElementById('order-mode-btn').classList.remove('active');\n                        currentOrder = null;\n                        clearCake();\n                        reactToModeSwitch();\n                        updateUI();\n                    }\n                });\n\n                // Undo button\n                document.getElementById('undo-btn').addEventListener('click', () => {\n                    if (undoStack.length > 0) {\n                        undo();\n                        updateUI();\n                        reactToUndo();\n                    }\n                });\n\n                // Redo button\n                document.getElementById('redo-btn').addEventListener('click', () => {\n                    redo();\n                    updateUI();\n                });\n\n                // New button\n                document.getElementById('new-btn').addEventListener('click', () => {\n                    saveStateForUndo();\n                    playSound('sound_pop', 0.3);\n                    clearCake();\n                    updateUI();\n                });\n\n                // Save button\n                document.getElementById('save-btn').addEventListener('click', () => {\n                    saveCakeToGallery();\n                });\n\n                // Submit button\n                document.getElementById('submit-btn').addEventListener('click', () => {\n                    submitCake();\n                });\n\n                // Next order button\n                document.getElementById('next-btn').addEventListener('click', () => {\n                    hideResult();\n                    startNewOrder();\n                });\n\n                // Resume audio context on user interaction\n                document.addEventListener('click', () => {\n                    if (audioContext && audioContext.state === 'suspended') {\n                        audioContext.resume();\n                    }\n                }, { once: true });\n                \n                // Gallery button\n                document.getElementById('gallery-btn').addEventListener('click', () => {\n                    playSound('sound_whoosh', 0.2);\n                    openGallery();\n                });\n                \n                // Gallery close button\n                document.getElementById('gallery-close-btn').addEventListener('click', () => {\n                    playSound('sound_whoosh', 0.2);\n                    closeGallery();\n                });\n                \n                // Gallery save button\n                document.getElementById('gallery-save-btn').addEventListener('click', () => {\n                    saveCakeToGallery();\n                });\n                \n                // Drag and drop for toppings and decorations on cake\n                setupDragHandlers();\n            }\n            \n            function setupButtonFeedback() {\n                // Add ripple effect and sound to all interactive buttons\n                const interactiveSelectors = [\n                    '.mode-btn',\n                    '.category-tab',\n                    '.action-btn',\n                    '.submit-btn',\n                    '.next-btn',\n                    '.gallery-close-btn',\n                    '.gallery-save-btn',\n                    '.gallery-delete-btn'\n                ];\n                \n                function addButtonFeedback(element) {\n                    element.addEventListener('pointerdown', function(e) {\n                        if (this.disabled) return;\n                        \n                        // Removed click sound - too much noise\n                        \n                        // Add press animation class\n                        this.classList.add('btn-pressed');\n                        \n                        // Create ripple effect\n                        const ripple = document.createElement('span');\n                        ripple.className = 'btn-ripple';\n                        const rect = this.getBoundingClientRect();\n                        const size = Math.max(rect.width, rect.height);\n                        ripple.style.width = ripple.style.height = size + 'px';\n                        ripple.style.left = (e.clientX - rect.left - size / 2) + 'px';\n                        ripple.style.top = (e.clientY - rect.top - size / 2) + 'px';\n                        this.appendChild(ripple);\n                        \n                        // Remove ripple after animation\n                        setTimeout(() => ripple.remove(), 600);\n                    });\n                    \n                    element.addEventListener('pointerup', function() {\n                        this.classList.remove('btn-pressed');\n                    });\n                    \n                    element.addEventListener('pointerleave', function() {\n                        this.classList.remove('btn-pressed');\n                    });\n                }\n                \n                // Apply to existing buttons\n                interactiveSelectors.forEach(selector => {\n                    document.querySelectorAll(selector).forEach(addButtonFeedback);\n                });\n                \n                // Also handle ingredient items specially\n                document.querySelectorAll('.ingredient-item').forEach(item => {\n                    item.addEventListener('pointerdown', function(e) {\n                        if (this.classList.contains('locked')) return;\n                        // Removed sound - too much noise\n                        this.classList.add('btn-pressed');\n                    });\n                    \n                    item.addEventListener('pointerup', function() {\n                        this.classList.remove('btn-pressed');\n                    });\n                    \n                    item.addEventListener('pointerleave', function() {\n                        this.classList.remove('btn-pressed');\n                    });\n                });\n            }\n            \n\n\n            function updateUI() {\n                updateCoinsDisplay();\n                updateStarsDisplay();\n                updateOrderDisplay();\n                updateCategoryTabs();\n                updateIngredientCarousel();\n                updateActionButtons();\n            }\n\n            function updateCoinsDisplay() {\n                // Coins display removed\n            }\n\n            function updateStarsDisplay() {\n                // Stars display removed from top UI\n            }\n\n            function updateOrderDisplay() {\n                const orderCard = document.getElementById('order-card-horizontal');\n                const customerImg = document.getElementById('customer-img');\n                const orderItems = document.getElementById('order-items');\n                const orderTitle = document.querySelector('.order-title');\n                const orderNumber = document.getElementById('order-number');\n                const orderDescription = document.getElementById('order-description');\n                \n                if (!orderCard) return;\n                \n                // In free mode, hide the order card completely\n                if (gameMode === 'free') {\n                    orderCard.classList.add('hidden');\n                    return;\n                }\n                \n                // In orders mode\n                if (customerImg) customerImg.style.display = 'none';\n                if (orderTitle) orderTitle.textContent = 'Order';\n                \n                if (!currentOrder) {\n                    orderCard.classList.add('hidden');\n                    return;\n                }\n                \n                orderCard.classList.remove('hidden');\n                \n                // Update order number\n                if (orderNumber) {\n                    orderNumber.textContent = `#${Math.max(1, orderCount)}`;\n                }\n                \n                if (!orderItems) return;\n\n                if (customerImg && currentCustomer && imageCache[currentCustomer]) {\n                    customerImg.src = imageCache[currentCustomer].src;\n                }\n\n                // Check if this is a creative order\n                if (currentOrder.creative) {\n                    if (orderTitle) orderTitle.textContent = 'Challenge';\n                    if (orderDescription) orderDescription.textContent = 'Make anything you want!';\n                    orderItems.innerHTML = '<div class=\"order-item\" style=\"font-size: 18px; font-weight: 600; color: #E91E63;\">Be creative!</div>';\n                    return;\n                }\n\n                // Set description for regular orders\n                if (orderDescription) {\n                    orderDescription.textContent = \"This is what I'd like:\";\n                }\n\n                let html = '';\n                \n                // Collect all items by category\n                const flavors = [];\n                const frostings = [];\n                const toppings = [];\n                const decorations = [];\n                \n                currentOrder.layers.forEach((layer) => {\n                    const flavorData = FLAVORS.find(f => f.id === layer.flavor);\n                    const flavorImg = flavorData && imageCache[flavorData.assetId] ? imageCache[flavorData.assetId].src : '';\n                    flavors.push({ name: flavorData ? flavorData.name : layer.flavor, img: flavorImg });\n                    \n                    if (layer.frosting) {\n                        const frostingData = FROSTINGS.find(f => f.id === layer.frosting);\n                        const frostingImg = frostingData && imageCache[frostingData.assetId] ? imageCache[frostingData.assetId].src : '';\n                        frostings.push({ name: frostingData ? frostingData.name : layer.frosting, img: frostingImg });\n                    }\n                    \n                    if (layer.topping) {\n                        const toppingData = TOPPINGS.find(t => t.id === layer.topping);\n                        const toppingImg = toppingData && imageCache[toppingData.assetId] ? imageCache[toppingData.assetId].src : '';\n                        toppings.push({ name: toppingData ? toppingData.name : layer.topping, img: toppingImg });\n                    }\n                });\n\n                currentOrder.decorations.forEach(decId => {\n                    const decData = DECORATIONS.find(d => d.id === decId);\n                    const decImg = decData && imageCache[decData.assetId] ? imageCache[decData.assetId].src : '';\n                    decorations.push({ name: decData ? decData.name : decId, img: decImg });\n                });\n                \n                // Build categorized HTML\n                if (flavors.length > 0) {\n                    html += `<div class=\"order-category\"><span class=\"order-category-label\">Layers:</span>`;\n                    flavors.forEach(item => {\n                        html += `<div class=\"order-item\">${item.img ? `<img class=\"order-item-icon\" src=\"${item.img}\" alt=\"\">` : ''}<span>${item.name}</span></div>`;\n                    });\n                    html += `</div>`;\n                }\n                \n                if (frostings.length > 0) {\n                    html += `<div class=\"order-category\"><span class=\"order-category-label\">Frosting:</span>`;\n                    frostings.forEach(item => {\n                        html += `<div class=\"order-item\">${item.img ? `<img class=\"order-item-icon\" src=\"${item.img}\" alt=\"\">` : ''}<span>${item.name}</span></div>`;\n                    });\n                    html += `</div>`;\n                }\n                \n                if (toppings.length > 0) {\n                    html += `<div class=\"order-category\"><span class=\"order-category-label\">Toppings:</span>`;\n                    toppings.forEach(item => {\n                        html += `<div class=\"order-item\">${item.img ? `<img class=\"order-item-icon\" src=\"${item.img}\" alt=\"\">` : ''}<span>${item.name}</span></div>`;\n                    });\n                    html += `</div>`;\n                }\n                \n                if (decorations.length > 0) {\n                    html += `<div class=\"order-category\"><span class=\"order-category-label\">Decor:</span>`;\n                    decorations.forEach(item => {\n                        html += `<div class=\"order-item\">${item.img ? `<img class=\"order-item-icon\" src=\"${item.img}\" alt=\"\">` : ''}<span>${item.name}</span></div>`;\n                    });\n                    html += `</div>`;\n                }\n\n                orderItems.innerHTML = html;\n            }\n\n            function updateCategoryTabs() {\n                const tabsContainer = document.getElementById('category-tabs');\n                if (!tabsContainer) return;\n\n                const categories = [\n                    { id: 'flavors', name: 'Flavors', icon: 'icon_flavors' },\n                    { id: 'frostings', name: 'Frosting', icon: 'icon_frostings' },\n                    { id: 'toppings', name: 'Toppings', icon: 'icon_toppings' }\n                ];\n\n                tabsContainer.innerHTML = categories.map(cat => `\n                    <button class=\"category-tab ${selectedCategory === cat.id ? 'active' : ''}\" data-category=\"${cat.id}\">\n                        <img src=\"${imageCache[cat.icon] ? imageCache[cat.icon].src : ''}\" alt=\"${cat.name}\">\n                        <span>${cat.name}</span>\n                    </button>\n                `).join('');\n            }\n\n            function updateIngredientCarousel() {\n                const carousel = document.getElementById('ingredient-carousel');\n                const tutorialEl = document.getElementById('tab-tutorial');\n                if (!carousel) return;\n\n                let items = [];\n                let tutorialText = '';\n                \n                if (selectedCategory === 'flavors') {\n                    items = FLAVORS;\n                    tutorialText = '\ud83c\udf66 Tap to add layers. Tap layers to swap!';\n                } else if (selectedCategory === 'frostings') {\n                    items = FROSTINGS;\n                    tutorialText = '\ud83c\udf82 Select a layer, then tap to frost it!';\n                } else if (selectedCategory === 'toppings') {\n                    items = [...TOPPINGS, ...DECORATIONS];\n                    tutorialText = '\u2728 Pick a topping, then tap the cake to place it!';\n                }\n\n                // Update tutorial text above tabs\n                if (tutorialEl) {\n                    tutorialEl.textContent = tutorialText;\n                }\n\n                carousel.innerHTML = items.map(item => {\n                    const unlocked = isUnlocked(item.id);\n                    const selected = selectedIngredient === item.id;\n                    const img = imageCache[item.assetId];\n                    \n                    return `\n                        <div class=\"ingredient-item ${selected ? 'selected' : ''} ${!unlocked ? 'locked' : ''}\" \n                             data-id=\"${item.id}\">\n                            ${img ? `<img src=\"${img.src}\" alt=\"${item.name}\">` : ''}\n                            <span>${item.name}</span>\n                            ${!unlocked ? `<span class=\"lock-icon\">\ud83d\udd12</span>` : ''}\n                        </div>\n                    `;\n                }).join('');\n                \n                // Reapply button feedback to new ingredient items\n                document.querySelectorAll('.ingredient-item').forEach(item => {\n                    item.addEventListener('pointerdown', function(e) {\n                        if (this.classList.contains('locked')) return;\n                        // Removed sound - too much noise\n                        this.classList.add('btn-pressed');\n                    });\n                    \n                    item.addEventListener('pointerup', function() {\n                        this.classList.remove('btn-pressed');\n                    });\n                    \n                    item.addEventListener('pointerleave', function() {\n                        this.classList.remove('btn-pressed');\n                    });\n                });\n            }\n\n            function updateActionButtons() {\n                const submitBtn = document.getElementById('submit-btn');\n                const undoBtn = document.getElementById('undo-btn');\n                const redoBtn = document.getElementById('redo-btn');\n                const saveBtn = document.getElementById('save-btn');\n                \n                if (submitBtn) {\n                    // Disable submit in free mode or when no layers\n                    submitBtn.disabled = gameMode === 'free' || currentCake.layers.length === 0;\n                    submitBtn.style.display = gameMode === 'free' ? 'none' : 'block';\n                }\n                \n                if (undoBtn) {\n                    undoBtn.disabled = undoStack.length === 0;\n                }\n                \n                if (redoBtn) {\n                    redoBtn.disabled = redoStack.length === 0;\n                }\n                \n                if (saveBtn) {\n                    saveBtn.disabled = currentCake.layers.length === 0;\n                    saveBtn.style.display = gameMode === 'free' ? 'block' : 'none';\n                }\n                \n                // Update layer counter\n                updateLayerCounter();\n            }\n            \n            function updateLayerCounter() {\n                const MAX_LAYERS = 7;\n                const counterBar = document.getElementById('layer-counter-bar');\n                if (!counterBar) return;\n                \n                let dotsHtml = '';\n                for (let i = 0; i < MAX_LAYERS; i++) {\n                    const filled = i < currentCake.layers.length ? 'filled' : '';\n                    dotsHtml += `<div class=\"layer-dot ${filled}\"></div>`;\n                }\n                counterBar.innerHTML = dotsHtml;\n            }\n            \n            // ==================== DRAG AND DROP ====================\n            function setupDragHandlers() {\n                function getCanvasCoords(e) {\n                    const rect = canvas.getBoundingClientRect();\n                    const scaleX = canvas.width / rect.width;\n                    const scaleY = canvas.height / rect.height;\n                    \n                    let clientX, clientY;\n                    if (e.touches && e.touches.length > 0) {\n                        clientX = e.touches[0].clientX;\n                        clientY = e.touches[0].clientY;\n                    } else {\n                        clientX = e.clientX;\n                        clientY = e.clientY;\n                    }\n                    \n                    return {\n                        x: (clientX - rect.left) * scaleX,\n                        y: (clientY - rect.top) * scaleY\n                    };\n                }\n                \n                // Helper function to get cake bounds for constraining decorations/toppings\n                function getCakeBounds() {\n                    if (layerBounds.length === 0) return null;\n                    \n                    const bottomBound = layerBounds[0];\n                    const topBound = layerBounds[layerBounds.length - 1];\n                    \n                    // Tighter bounds - only allow placement on the actual cake\n                    return {\n                        left: bottomBound.x + 10,\n                        right: bottomBound.x + bottomBound.width - 10,\n                        top: topBound.y - 40, // Small space above for decorations on top\n                        bottom: bottomBound.y + bottomBound.height - 10\n                    };\n                }\n                \n                // Clamp position to stay within cake bounds\n                function clampToCakeBounds(x, y) {\n                    const bounds = getCakeBounds();\n                    if (!bounds) return { x, y };\n                    \n                    return {\n                        x: Math.max(bounds.left, Math.min(bounds.right, x)),\n                        y: Math.max(bounds.top, Math.min(bounds.bottom, y))\n                    };\n                }\n                \n                // Check if a point is within cake bounds\n                function isWithinCakeBounds(x, y) {\n                    const bounds = getCakeBounds();\n                    if (!bounds) return false;\n                    \n                    return x >= bounds.left && x <= bounds.right &&\n                           y >= bounds.top && y <= bounds.bottom;\n                }\n                \n                function hitTest(x, y) {\n                    // Check decorations first (on top)\n                    for (let i = decorationBounds.length - 1; i >= 0; i--) {\n                        const b = decorationBounds[i];\n                        if (x >= b.x && x <= b.x + b.width && y >= b.y && y <= b.y + b.height) {\n                            return { type: 'decoration', index: b.index };\n                        }\n                    }\n                    \n                    // Check toppings on layers\n                    for (let i = currentCake.layers.length - 1; i >= 0; i--) {\n                        const layer = currentCake.layers[i];\n                        if (Array.isArray(layer.toppingBounds)) {\n                            for (let j = layer.toppingBounds.length - 1; j >= 0; j--) {\n                                const b = layer.toppingBounds[j];\n                                if (x >= b.x && x <= b.x + b.width && y >= b.y && y <= b.y + b.height) {\n                                    return { type: 'topping', layerIndex: i, toppingIndex: b.toppingIndex };\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Check cake layers for selection\n                    for (let i = layerBounds.length - 1; i >= 0; i--) {\n                        const b = layerBounds[i];\n                        if (x >= b.x && x <= b.x + b.width && y >= b.y && y <= b.y + b.height) {\n                            return { type: 'layer', index: b.index };\n                        }\n                    }\n                    \n                    return null;\n                }\n                \n                let startX, startY;\n                let hasMoved = false;\n                let clickStartTime = 0;\n                const moveThreshold = 10;\n                const clickDuration = 300; // Max time for a tap/click in ms\n                \n                function onDragStart(e) {\n                    if (showingResult) return;\n                    \n                    const coords = getCanvasCoords(e);\n                    startX = coords.x;\n                    startY = coords.y;\n                    hasMoved = false;\n                    clickStartTime = Date.now();\n                    \n                    const hit = hitTest(coords.x, coords.y);\n                    \n                    if (hit && (hit.type === 'decoration' || hit.type === 'topping')) {\n                        e.preventDefault();\n                        playSound('sound_drag', 0.2);\n                        draggingItem = hit;\n                        \n                        // Calculate offset from item center\n                        if (hit.type === 'decoration') {\n                            const dec = currentCake.decorations[hit.index];\n                            if (typeof dec === 'object' && dec.x !== undefined) {\n                                dragOffset.x = coords.x - dec.x;\n                                dragOffset.y = coords.y - dec.y;\n                            } else {\n                                dragOffset.x = 0;\n                                dragOffset.y = 0;\n                                // Convert to object with position\n                                const decId = typeof dec === 'object' ? dec.id : dec;\n                                currentCake.decorations[hit.index] = { id: decId, x: coords.x, y: coords.y };\n                            }\n                        } else if (hit.type === 'topping') {\n                            const layer = currentCake.layers[hit.layerIndex];\n                            const toppings = getLayerToppings(layer);\n                            const toppingObj = toppings[hit.toppingIndex];\n                            if (typeof toppingObj === 'object' && toppingObj.x !== undefined) {\n                                dragOffset.x = coords.x - toppingObj.x;\n                                dragOffset.y = coords.y - toppingObj.y;\n                            } else {\n                                dragOffset.x = 0;\n                                dragOffset.y = 0;\n                                const toppingId = typeof toppingObj === 'object' ? toppingObj.id : toppingObj;\n                                toppings[hit.toppingIndex] = { id: toppingId, x: coords.x, y: coords.y };\n                            }\n                        }\n                        \n                        canvas.style.cursor = 'grabbing';\n                    }\n                }\n                \n                function onDragMove(e) {\n                    const coords = getCanvasCoords(e);\n                    \n                    // Check if we've moved enough to count as a drag\n                    if (startX !== undefined && startY !== undefined) {\n                        const dx = Math.abs(coords.x - startX);\n                        const dy = Math.abs(coords.y - startY);\n                        if (dx > moveThreshold || dy > moveThreshold) {\n                            hasMoved = true;\n                        }\n                    }\n                    \n                    if (!draggingItem) {\n                        // Show grab cursor when hovering over draggable items\n                        const hit = hitTest(coords.x, coords.y);\n                        if (hit && hit.type === 'layer') {\n                            canvas.style.cursor = 'pointer';\n                        } else {\n                            canvas.style.cursor = hit ? 'grab' : 'default';\n                        }\n                        return;\n                    }\n                    \n                    e.preventDefault();\n                    \n                    // Calculate desired position\n                    const desiredX = coords.x - dragOffset.x;\n                    const desiredY = coords.y - dragOffset.y;\n                    \n                    // Clamp to cake bounds\n                    const clamped = clampToCakeBounds(desiredX, desiredY);\n                    \n                    if (draggingItem.type === 'decoration') {\n                        const dec = currentCake.decorations[draggingItem.index];\n                        if (typeof dec === 'object') {\n                            dec.x = clamped.x;\n                            dec.y = clamped.y;\n                        }\n                    } else if (draggingItem.type === 'topping') {\n                        const layer = currentCake.layers[draggingItem.layerIndex];\n                        const toppings = getLayerToppings(layer);\n                        const toppingObj = toppings[draggingItem.toppingIndex];\n                        if (typeof toppingObj === 'object') {\n                            toppingObj.x = clamped.x;\n                            toppingObj.y = clamped.y;\n                        }\n                    }\n                }\n                \n                function onDragEnd(e) {\n                    const timeDiff = Date.now() - clickStartTime;\n                    \n                    // Check if this was a tap/click (not a drag)\n                    if (!hasMoved && timeDiff < clickDuration && !draggingItem) {\n                        const coords = getCanvasCoords(e.changedTouches ? e.changedTouches[0] : e);\n                        const hit = hitTest(coords.x, coords.y);\n                        \n                        // Check if we should add a topping/decoration by tapping on the cake\n                        if (selectedCategory === 'toppings' && selectedIngredient && currentCake.layers.length > 0) {\n                            const isTopping = TOPPINGS.some(t => t.id === selectedIngredient);\n                            const isDecoration = DECORATIONS.some(d => d.id === selectedIngredient);\n                            \n                            if (isTopping || isDecoration) {\n                                // Only allow placing on the actual cake area\n                                if (isWithinCakeBounds(coords.x, coords.y)) {\n                                    // Add topping or decoration at tap position\n                                    if (isTopping) {\n                                        addToppingAtPosition(selectedIngredient, coords.x, coords.y);\n                                    } else {\n                                        addDecorationAtPosition(selectedIngredient, coords.x, coords.y);\n                                    }\n                                    updateUI();\n                                    // Reset and return - don't process as layer tap\n                                    startX = undefined;\n                                    startY = undefined;\n                                    hasMoved = false;\n                                    return;\n                                }\n                            }\n                        }\n                        \n                        if (hit && hit.type === 'layer') {\n                            // Tap on a layer - change its flavor or frosting based on selected category\n                            handleLayerTap(hit.index);\n                        }\n                    }\n                    \n                    if (draggingItem) {\n                        playSound('sound_drop', 0.2);\n                        draggingItem = null;\n                        canvas.style.cursor = 'default';\n                    }\n                    \n                    startX = undefined;\n                    startY = undefined;\n                    hasMoved = false;\n                }\n                \n                function handleLayerTap(layerIndex) {\n                    const layer = currentCake.layers[layerIndex];\n                    if (!layer) return;\n                    \n                    // If a different layer is already selected, swap them\n                    if (selectedLayerIndex !== null && selectedLayerIndex !== layerIndex) {\n                        saveStateForUndo();\n                        // Swap the two layers\n                        const temp = currentCake.layers[selectedLayerIndex];\n                        currentCake.layers[selectedLayerIndex] = currentCake.layers[layerIndex];\n                        currentCake.layers[layerIndex] = temp;\n                        playSound('sound_swap', 0.3);\n                        selectedLayerIndex = null; // Deselect after swap\n                        updateUI();\n                        return;\n                    }\n                    \n                    // Select this layer for editing\n                    if (selectedLayerIndex === layerIndex) {\n                        // Tapping same layer again deselects it\n                        // Removed sound - visual feedback is enough\n                        selectedLayerIndex = null;\n                    } else {\n                        // Removed sound - visual feedback is enough\n                        selectedLayerIndex = layerIndex;\n                        // Mascot hints about layer editing\n                        reactToLayerSelect();\n                    }\n                    \n                    // If an ingredient is selected, apply it to the layer\n                    if (selectedIngredient && selectedLayerIndex === layerIndex) {\n                        if (selectedCategory === 'flavors') {\n                            layer.flavor = selectedIngredient;\n                            playSound('sound_add_layer', 0.15);\n                        } else if (selectedCategory === 'frostings') {\n                            layer.frosting = selectedIngredient;\n                            playSound('sound_add_layer', 0.15);\n                        }\n                    }\n                    \n                    updateUI();\n                }\n                \n                // Mouse events\n                canvas.addEventListener('mousedown', onDragStart);\n                canvas.addEventListener('mousemove', onDragMove);\n                canvas.addEventListener('mouseup', onDragEnd);\n                canvas.addEventListener('mouseleave', onDragEnd);\n                \n                // Touch events\n                canvas.addEventListener('touchstart', onDragStart, { passive: false });\n                canvas.addEventListener('touchmove', onDragMove, { passive: false });\n                canvas.addEventListener('touchend', onDragEnd);\n                canvas.addEventListener('touchcancel', onDragEnd);\n            }\n\n            // ==================== GAME ACTIONS ====================\n            function saveStateForUndo() {\n                undoStack.push(JSON.stringify(currentCake));\n                redoStack = []; // Clear redo stack on new action\n                if (undoStack.length > 20) undoStack.shift(); // Limit stack size\n            }\n\n            function undo() {\n                if (undoStack.length === 0) return;\n                playSound('sound_pop', 0.2);\n                redoStack.push(JSON.stringify(currentCake));\n                const prevState = undoStack.pop();\n                currentCake = JSON.parse(prevState);\n                selectedLayerIndex = null;\n            }\n\n            function redo() {\n                if (redoStack.length === 0) return;\n                playSound('sound_pop', 0.2);\n                undoStack.push(JSON.stringify(currentCake));\n                const nextState = redoStack.pop();\n                currentCake = JSON.parse(nextState);\n                selectedLayerIndex = null;\n            }\n\n            // ==================== MASCOT REACTIONS ====================\n            function triggerMascotReaction(animation = 'bounce', duration = 2000) {\n                const mascot = document.getElementById('game-mascot');\n                if (!mascot) return;\n\n                // Clear existing timeout\n                if (mascotAnimTimeout) clearTimeout(mascotAnimTimeout);\n\n                // Set animation\n                mascot.className = 'game-mascot ' + animation;\n\n                // Return to idle after animation\n                mascotAnimTimeout = setTimeout(() => {\n                    mascot.className = 'game-mascot idle';\n                }, duration);\n            }\n\n            function reactToAddLayer() {\n                triggerMascotReaction('bounce', 500);\n            }\n\n            function reactToAddFrosting() {\n                triggerMascotReaction('happy', 600);\n            }\n\n            function reactToAddTopping() {\n                triggerMascotReaction('excited', 600);\n            }\n\n            function reactToAddDecoration() {\n                triggerMascotReaction('excited', 700);\n            }\n\n            function reactToSubmit(stars) {\n                if (stars === 3) {\n                    triggerMascotReaction('celebrate', 2000);\n                } else if (stars === 2) {\n                    triggerMascotReaction('happy', 1500);\n                } else if (stars === 1) {\n                    triggerMascotReaction('bounce', 1200);\n                } else {\n                    triggerMascotReaction('thinking', 1500);\n                }\n            }\n\n            function reactToNewOrder() {\n                triggerMascotReaction('excited', 800);\n            }\n\n            function reactToClearCake() {\n                triggerMascotReaction('bounce', 600);\n            }\n\n            function reactToUndo() {\n                triggerMascotReaction('bounce', 500);\n            }\n\n            function reactToSave() {\n                triggerMascotReaction('celebrate', 1200);\n            }\n\n            function reactToLayerSelect() {\n                triggerMascotReaction('thinking', 800);\n            }\n            \n            function reactToModeSwitch() {\n                triggerMascotReaction('bounce', 600);\n            }\n\n            function addLayer(flavorId) {\n                if (currentCake.layers.length >= 7) return;\n                \n                saveStateForUndo();\n                currentCake.layers.push({\n                    flavor: flavorId,\n                    toppings: [],\n                    frosting: null\n                });\n\n                playSound('sound_add_layer', 0.15);\n                \n                // Mascot reaction\n                reactToAddLayer();\n                animations.push({\n                    type: 'addLayer',\n                    startTime: Date.now(),\n                    duration: 300\n                });\n            }\n\n            function addFrosting(frostingId) {\n                if (currentCake.layers.length === 0) return;\n                \n                saveStateForUndo();\n                // First try to frost an unfrosted layer (top to bottom)\n                for (let i = currentCake.layers.length - 1; i >= 0; i--) {\n                    if (!currentCake.layers[i].frosting) {\n                        currentCake.layers[i].frosting = frostingId;\n                        playSound('sound_add_layer', 0.15);\n                        return;\n                    }\n                }\n                \n                // If all layers are frosted, replace frosting on the top layer\n                currentCake.layers[currentCake.layers.length - 1].frosting = frostingId;\n                playSound('sound_add_layer', 0.15);\n                \n                // Mascot reaction\n                reactToAddFrosting();\n            }\n\n            function addTopping(toppingId) {\n                if (currentCake.layers.length === 0) return;\n                \n                saveStateForUndo();\n                const lastLayer = currentCake.layers[currentCake.layers.length - 1];\n                const toppings = getLayerToppings(lastLayer);\n                toppings.push({ id: toppingId });\n                playSound('sound_add_topping', 0.15);\n                \n                // Mascot reaction\n                reactToAddTopping();\n            }\n            \n            function addToppingAtPosition(toppingId, x, y) {\n                if (currentCake.layers.length === 0) return;\n                \n                saveStateForUndo();\n                // Find a layer without topping, prefer the one closest to y position\n                const cakeScale = (config.cakeScale || 100) / 100;\n                const layerHeight = 70 * cakeScale;\n                const tablePosition = (config.tableVerticalPosition || 55) / 100;\n                const cakeOffset = config.cakeVerticalPosition !== undefined ? config.cakeVerticalPosition : 0;\n                const baseY = canvas.height * tablePosition - 10 + cakeOffset;\n                \n                // Find which layer this y position is closest to\n                let targetLayerIndex = -1;\n                let minDist = Infinity;\n                \n                for (let i = 0; i < currentCake.layers.length; i++) {\n                    const layerY = baseY - (i + 1) * (layerHeight - 10);\n                    const dist = Math.abs(y - layerY);\n                    if (dist < minDist) {\n                        minDist = dist;\n                        targetLayerIndex = i;\n                    }\n                }\n                \n                if (targetLayerIndex === -1) return;\n                \n                const toppings = getLayerToppings(currentCake.layers[targetLayerIndex]);\n                toppings.push({ id: toppingId, x: x, y: y });\n                playSound('sound_add_topping', 0.15);\n                \n                // Mascot reaction\n                reactToAddTopping();\n            }\n\n            function addDecoration(decorationId) {\n                if (currentCake.layers.length === 0) return;\n                \n                saveStateForUndo();\n                // Add with default position (will be set properly in draw)\n                currentCake.decorations.push({ id: decorationId, x: undefined, y: undefined });\n                playSound('sound_add_decoration', 0.15);\n                \n                // Mascot reaction\n                reactToAddDecoration();\n            }\n            \n            function addDecorationAtPosition(decorationId, x, y) {\n                if (currentCake.layers.length === 0) return;\n                \n                saveStateForUndo();\n                currentCake.decorations.push({ id: decorationId, x: x, y: y });\n                playSound('sound_add_decoration', 0.15);\n                \n                // Mascot reaction\n                reactToAddDecoration();\n            }\n\n            function undoLastAction() {\n                if (currentCake.decorations.length > 0) {\n                    currentCake.decorations.pop();\n                } else if (currentCake.layers.length > 0) {\n                    const lastLayer = currentCake.layers[currentCake.layers.length - 1];\n                    const toppings = getLayerToppings(lastLayer);\n                    if (toppings.length > 0) {\n                        toppings.pop();\n                        lastLayer.toppingBounds = null;\n                    } else if (lastLayer.frosting) {\n                        lastLayer.frosting = null;\n                    } else {\n                        currentCake.layers.pop();\n                    }\n                }\n            }\n\n            function clearCake() {\n                const hadLayers = currentCake.layers.length > 0;\n                currentCake = {\n                    layers: [],\n                    decorations: []\n                };\n                selectedLayerIndex = null; // Clear layer selection\n                \n                // Mascot reaction (only if there was something to clear)\n                if (hadLayers) {\n                    reactToClearCake();\n                }\n            }\n\n            function submitCake() {\n                const submitBtn = document.getElementById('submit-btn');\n                if (submitBtn) {\n                    submitBtn.classList.add('submitting');\n                    setTimeout(() => submitBtn.classList.remove('submitting'), 500);\n                }\n                \n                playSound('sound_submit_cake', 0.6);\n                \n                const score = calculateScore();\n                resultData = score;\n                \n                // Award coins\n                addCoins(score.coins);\n                totalStars = score.stars;\n\n                // Check for unlocks\n                checkUnlocks();\n\n                // Mascot reaction\n                reactToSubmit(score.stars);\n\n                // Show result\n                setTimeout(() => {\n                    showResult(score);\n                }, 500);\n            }\n\n            function checkUnlocks() {\n                const nextItem = getNextUnlockable();\n                if (nextItem && getCoins() >= nextItem.unlockCost) {\n                    unlockItem(nextItem.id);\n                    addCoins(-nextItem.unlockCost);\n                    showUnlockNotification(nextItem.name);\n                    playSound('sound_unlock', 0.7);\n                }\n            }\n\n            function showUnlockNotification(itemName) {\n                const notif = document.getElementById('unlock-notification');\n                if (notif) {\n                    notif.textContent = `\ud83c\udf89 Unlocked: ${itemName}!`;\n                    notif.classList.add('visible');\n                    setTimeout(() => {\n                        notif.classList.remove('visible');\n                    }, 2000);\n                }\n            }\n\n            function showResult(score) {\n                showingResult = true;\n                const modal = document.getElementById('result-modal');\n                const title = document.getElementById('result-title');\n                const subtitle = document.getElementById('result-subtitle');\n                const starsContainer = document.getElementById('result-stars');\n                const accuracyDisplay = document.getElementById('result-accuracy');\n                const summaryDisplay = document.getElementById('result-summary');\n                const messageDisplay = document.getElementById('result-message');\n\n\n                // Set title based on stars\n                if (title) {\n                    if (score.stars === 3) title.textContent = 'Perfect! \ud83c\udf89';\n                    else if (score.stars === 2) title.textContent = 'Great Job! \ud83d\udc4d';\n                    else if (score.stars === 1) title.textContent = 'Good Try! \ud83d\ude0a';\n                    else title.textContent = 'Keep Practicing! \ud83d\udcaa';\n                }\n\n                // Set subtitle\n                if (subtitle) {\n                    subtitle.textContent = score.creative ? '\u2728 Creative Challenge' : 'Order Complete';\n                }\n\n                // Display stars\n                if (starsContainer) {\n                    starsContainer.innerHTML = '';\n                    for (let i = 0; i < 3; i++) {\n                        const img = document.createElement('img');\n                        const isFilled = i < score.stars;\n                        const assetId = isFilled ? 'star_filled' : 'star_empty';\n                        if (imageCache[assetId]) {\n                            img.src = imageCache[assetId].src;\n                        }\n                        if (isFilled) {\n                            img.classList.add('earned');\n                            img.style.animationDelay = `${i * 0.2}s`;\n                            setTimeout(() => playSound('sound_star_award', 0.4), i * 200 + 100);\n                        }\n                        starsContainer.appendChild(img);\n                    }\n                }\n\n                // Display accuracy\n                if (accuracyDisplay) {\n                    if (score.creative) {\n                        accuracyDisplay.innerHTML = `Creativity Score: <span>${score.accuracy}%</span>`;\n                    } else {\n                        accuracyDisplay.innerHTML = `Accuracy: <span>${score.accuracy}%</span>`;\n                    }\n                }\n\n                // Display summary breakdown\n                if (summaryDisplay && score.details && score.details.length > 0) {\n                    let summaryHTML = `<div class=\"result-summary-title\">${score.creative ? '\ud83c\udfa8 Your Creation' : '\ud83d\udccb Order Summary'}</div>`;\n                    \n                    score.details.forEach(detail => {\n                        const matchClass = detail.match ? 'match' : 'miss';\n                        const icon = detail.match ? '\u2713' : '\u2717';\n                        summaryHTML += `\n                            <div class=\"result-summary-row\">\n                                <span class=\"result-summary-label\">${detail.label}</span>\n                                <span class=\"result-summary-value ${matchClass}\">${icon} ${detail.value}</span>\n                            </div>\n                        `;\n                    });\n                    \n                    summaryDisplay.innerHTML = summaryHTML;\n                    summaryDisplay.style.display = 'block';\n                } else if (summaryDisplay) {\n                    summaryDisplay.style.display = 'none';\n                }\n\n                // Display encouraging message\n                if (messageDisplay) {\n                    const messages = {\n                        3: [\"\ud83c\udf1f Absolutely perfect!\", \"\ud83c\udfc6 Master cake decorator!\", \"\u2728 The customer loved it!\"],\n                        2: [\"\ud83d\ude04 Almost there!\", \"\ud83d\udc4f Nice work!\", \"\ud83c\udf82 Delicious cake!\"],\n                        1: [\"\ud83d\udcaa Keep it up!\", \"\ud83d\udcdd Check the order details!\", \"\ud83c\udf70 Practice makes perfect!\"],\n                        0: [\"\ud83e\udd14 Try matching the order!\", \"\ud83d\udccb Read the order carefully!\", \"\ud83d\udca1 Look at the layers needed!\"]\n                    };\n                    const msgList = messages[score.stars];\n                    messageDisplay.textContent = msgList[Math.floor(Math.random() * msgList.length)];\n                }\n\n\n                if (modal) {\n                    modal.classList.add('visible');\n                }\n            }\n\n            function hideResult() {\n                showingResult = false;\n                const modal = document.getElementById('result-modal');\n                if (modal) {\n                    modal.classList.remove('visible');\n                }\n            }\n\n            function startNewOrder() {\n                const hadPreviousOrder = currentOrder !== null;\n                currentCake = { layers: [], decorations: [] }; // Clear without triggering reaction\n                selectedLayerIndex = null;\n                currentOrder = generateOrder(isFirstGame);\n                isFirstGame = false; // After first order, use random generation\n                totalStars = 0;\n                selectedIngredient = null;\n                updateUI();\n                \n                // Mascot reaction and new order sound\n                if (hadPreviousOrder || gameMode === 'orders') {\n                    setTimeout(() => {\n                        playSound('sound_new_order', 0.5);\n                        reactToNewOrder();\n                    }, 300);\n                }\n            }\n\n            // ==================== GALLERY FUNCTIONS ====================\n            function openGallery() {\n                showingGallery = true;\n                const modal = document.getElementById('gallery-modal');\n                if (modal) {\n                    modal.classList.add('visible');\n                    updateGalleryDisplay();\n                }\n            }\n\n            function closeGallery() {\n                showingGallery = false;\n                const modal = document.getElementById('gallery-modal');\n                if (modal) {\n                    modal.classList.remove('visible');\n                }\n            }\n\n            function saveCakeToGallery() {\n                if (currentCake.layers.length === 0) return;\n                \n                // Deep copy the current cake\n                const cakeToSave = {\n                    id: Date.now(),\n                    name: `Cake #${savedCakes.length + 1}`,\n                    layers: JSON.parse(JSON.stringify(currentCake.layers)),\n                    decorations: JSON.parse(JSON.stringify(currentCake.decorations)),\n                    timestamp: new Date().toLocaleString()\n                };\n                \n                savedCakes.push(cakeToSave);\n                playSound('sound_submit_cake', 0.3);\n                updateGalleryDisplay();\n                reactToSave();\n                \n                // Show notification\n                const notif = document.getElementById('unlock-notification');\n                if (notif) {\n                    notif.textContent = '\ud83d\udcbe Cake Saved!';\n                    notif.classList.add('visible');\n                    setTimeout(() => {\n                        notif.classList.remove('visible');\n                    }, 1500);\n                }\n            }\n\n            function deleteCakeFromGallery(cakeId) {\n                playSound('sound_delete', 0.3);\n                savedCakes = savedCakes.filter(cake => cake.id !== cakeId);\n                updateGalleryDisplay();\n            }\n\n            function loadCakeFromGallery(cakeId) {\n                const cakeToLoad = savedCakes.find(cake => cake.id === cakeId);\n                if (!cakeToLoad) return;\n                \n                // Save current state for undo\n                saveStateForUndo();\n                \n                // Deep copy the saved cake to current cake\n                currentCake = {\n                    layers: JSON.parse(JSON.stringify(cakeToLoad.layers)),\n                    decorations: JSON.parse(JSON.stringify(cakeToLoad.decorations))\n                };\n                \n                selectedLayerIndex = null;\n                playSound('sound_add_layer', 0.15);\n                \n                // Close gallery and update UI\n                closeGallery();\n                updateUI();\n                \n                // Show notification\n                const notif = document.getElementById('unlock-notification');\n                if (notif) {\n                    notif.textContent = '\ud83c\udf82 Cake Loaded!';\n                    notif.classList.add('visible');\n                    setTimeout(() => {\n                        notif.classList.remove('visible');\n                    }, 1500);\n                }\n                \n                // Mascot reaction\n                triggerMascotReaction('excited', 800);\n            }\n\n            function drawCakeToCanvas(targetCanvas, cakeData, previewSize = 200) {\n                const previewCtx = targetCanvas.getContext('2d');\n                \n                // Use the same proportions as the main game - scale everything uniformly\n                // Main game uses canvas.width which is ~720, we're using previewSize\n                const gameScale = previewSize / canvas.width;\n                const cakeScale = ((config.cakeScale || 100) / 100) * gameScale;\n                const layerWidth = 280 * cakeScale;\n                const layerHeight = 70 * cakeScale;\n                \n                // Match the main game positioning\n                const tableXOffset = (config.tableHorizontalPosition || 0) * gameScale;\n                const cakeXOffset = (config.cakeHorizontalPosition || 0) * gameScale;\n                const tablePosition = (config.tableVerticalPosition || 55) / 100;\n                const cakeOffset = ((config.cakeVerticalPosition !== undefined ? config.cakeVerticalPosition : 0)) * gameScale;\n                \n                const standWidth = 420 * gameScale;\n                const standX = (previewSize - standWidth) / 2 + tableXOffset;\n                const standY = previewSize * tablePosition;\n                const centerX = standX + standWidth / 2 + cakeXOffset;\n                const baseY = standY - 10 * gameScale + cakeOffset;\n                \n                // Clear canvas\n                previewCtx.clearRect(0, 0, previewSize, previewSize);\n                \n                // Draw cake stand (plate) - match main game\n                const standImg = imageCache['cake_stand'];\n                if (standImg) {\n                    const aspectRatio = standImg.height / standImg.width;\n                    const standHeight = standWidth * aspectRatio;\n                    previewCtx.drawImage(standImg, standX, standY, standWidth, standHeight);\n                }\n                \n                // Draw layers - exact same logic as drawCake\n                cakeData.layers.forEach((layer, index) => {\n                    const y = baseY - (index + 1) * (layerHeight - 10 * gameScale);\n                    \n                    // Draw ice cream layer\n                    const flavorData = FLAVORS.find(f => f.id === layer.flavor);\n                    if (flavorData) {\n                        const img = imageCache[flavorData.assetId];\n                        if (img) {\n                            const aspectRatio = img.height / img.width;\n                            const drawHeight = layerWidth * aspectRatio;\n                            previewCtx.drawImage(img, centerX - layerWidth / 2, y - drawHeight / 2, layerWidth, drawHeight);\n                        }\n                    }\n                    \n                    // Draw frosting on layer\n                    if (layer.frosting) {\n                        const frostingData = FROSTINGS.find(f => f.id === layer.frosting);\n                        if (frostingData) {\n                            const img = imageCache[frostingData.assetId];\n                            if (img) {\n                                const frostingWidth = layerWidth + 20 * cakeScale;\n                                const aspectRatio = img.height / img.width;\n                                const drawHeight = frostingWidth * aspectRatio;\n                                previewCtx.drawImage(img, centerX - frostingWidth / 2, y - drawHeight / 2, frostingWidth, drawHeight);\n                            }\n                        }\n                    }\n                });\n                \n                // Draw toppings on layers - exact same logic as drawCake\n                cakeData.layers.forEach((layer, index) => {\n                    const y = baseY - (index + 1) * (layerHeight - 10 * gameScale);\n                    const toppings = Array.isArray(layer.toppings) ? layer.toppings : (layer.topping ? [{ id: layer.topping }] : []);\n                    \n                    toppings.forEach((toppingObj, tIndex) => {\n                        const toppingId = typeof toppingObj === 'object' ? toppingObj.id : toppingObj;\n                        const toppingData = TOPPINGS.find(t => t.id === toppingId);\n                        if (toppingData) {\n                            const img = imageCache[toppingData.assetId];\n                            if (img) {\n                                const toppingSize = 36 * cakeScale;\n                                const aspectRatio = img.height / img.width;\n                                const drawHeight = toppingSize * aspectRatio;\n                                \n                                let drawX, drawY;\n                                if (typeof toppingObj === 'object' && toppingObj.x !== undefined) {\n                                    // Scale position from main canvas to preview\n                                    drawX = toppingObj.x * gameScale - toppingSize / 2;\n                                    drawY = toppingObj.y * gameScale - drawHeight / 2;\n                                } else {\n                                    const offsetX = (tIndex * 16 - 8) * cakeScale;\n                                    drawX = centerX - toppingSize / 2 + offsetX;\n                                    drawY = y - drawHeight / 2 - 15 * gameScale;\n                                }\n                                previewCtx.drawImage(img, drawX, drawY, toppingSize, drawHeight);\n                            }\n                        }\n                    });\n                });\n                \n                // Draw decorations on top - exact same logic as drawCake\n                if (cakeData.layers.length > 0) {\n                    const topY = baseY - cakeData.layers.length * (layerHeight - 10 * gameScale) - 30 * cakeScale;\n                    \n                    cakeData.decorations.forEach((dec, index) => {\n                        const decId = typeof dec === 'object' ? dec.id : dec;\n                        const decData = DECORATIONS.find(d => d.id === decId);\n                        if (decData) {\n                            const img = imageCache[decData.assetId];\n                            if (img) {\n                                let decWidth;\n                                if (decId === 'chocolate_drizzle' || decId === 'caramel_drizzle' || decId === 'honey_drizzle') {\n                                    decWidth = 50 * cakeScale;\n                                } else if (decId === 'candles') {\n                                    decWidth = 10 * cakeScale;\n                                } else if (decId === 'star_sprinkles') {\n                                    decWidth = 12 * cakeScale;\n                                } else if (decId === 'cherry') {\n                                    decWidth = 18 * cakeScale;\n                                } else if (decId === 'wafer_sticks') {\n                                    decWidth = 14 * cakeScale;\n                                } else if (decId === 'whipped_cream') {\n                                    decWidth = 24 * cakeScale;\n                                } else {\n                                    decWidth = 20 * cakeScale;\n                                }\n                                const aspectRatio = img.height / img.width;\n                                const decHeight = decWidth * aspectRatio;\n                                \n                                let drawX, drawY;\n                                if (typeof dec === 'object' && dec.x !== undefined) {\n                                    // Scale position from main canvas to preview\n                                    drawX = dec.x * gameScale - decWidth / 2;\n                                    drawY = dec.y * gameScale - decHeight / 2;\n                                } else {\n                                    const offsetX = (index * 25 - 12) * cakeScale;\n                                    const extraYOffset = (decId === 'candles') ? -10 * cakeScale : 0;\n                                    drawX = centerX - decWidth / 2 + offsetX;\n                                    drawY = topY - decHeight + extraYOffset;\n                                }\n                                previewCtx.drawImage(img, drawX, drawY, decWidth, decHeight);\n                            }\n                        }\n                    });\n                }\n            }\n\n            function updateGalleryDisplay() {\n                const grid = document.getElementById('gallery-grid');\n                const saveBtn = document.getElementById('gallery-save-btn');\n                \n                if (saveBtn) {\n                    saveBtn.disabled = currentCake.layers.length === 0;\n                }\n                \n                if (!grid) return;\n                \n                if (savedCakes.length === 0) {\n                    grid.innerHTML = '<div class=\"gallery-empty\">No cakes saved yet!<br>Create a cake and tap \"Save Current Cake\"</div>';\n                    return;\n                }\n                \n                grid.innerHTML = savedCakes.map(cake => {\n                    return `\n                        <div class=\"gallery-item\" data-cake-id=\"${cake.id}\">\n                            <button class=\"gallery-delete-btn\" data-delete-id=\"${cake.id}\">\u2715</button>\n                            <div class=\"gallery-cake-preview\">\n                                <canvas class=\"gallery-cake-canvas\" data-cake-id=\"${cake.id}\" width=\"300\" height=\"300\"></canvas>\n                            </div>\n                            <div class=\"gallery-cake-name\">${cake.name}</div>\n                            <div class=\"gallery-load-hint\">Tap to Load</div>\n                        </div>\n                    `;\n                }).join('');\n                \n                // Draw cakes on canvases\n                savedCakes.forEach(cake => {\n                    const canvasEl = grid.querySelector(`.gallery-cake-canvas[data-cake-id=\"${cake.id}\"]`);\n                    if (canvasEl) {\n                        drawCakeToCanvas(canvasEl, cake, 300);\n                    }\n                });\n                \n                // Add delete button listeners\n                grid.querySelectorAll('.gallery-delete-btn').forEach(btn => {\n                    btn.addEventListener('click', (e) => {\n                        e.stopPropagation();\n                        const cakeId = parseInt(btn.dataset.deleteId);\n                        deleteCakeFromGallery(cakeId);\n                    });\n                });\n                \n                // Add load listeners to gallery items\n                grid.querySelectorAll('.gallery-item').forEach(item => {\n                    // Add button feedback\n                    item.addEventListener('pointerdown', function(e) {\n                        if (e.target.closest('.gallery-delete-btn')) return;\n                        // Removed sound - visual feedback enough\n                        this.style.transform = 'scale(0.95)';\n                    });\n                    \n                    item.addEventListener('pointerup', function() {\n                        this.style.transform = '';\n                    });\n                    \n                    item.addEventListener('pointerleave', function() {\n                        this.style.transform = '';\n                    });\n                    \n                    item.addEventListener('click', (e) => {\n                        // Don't load if clicking delete button\n                        if (e.target.closest('.gallery-delete-btn')) return;\n                        const cakeId = parseInt(item.dataset.cakeId);\n                        loadCakeFromGallery(cakeId);\n                    });\n                });\n            }\n\n            // ==================== GAME PARAMETERS ====================\n            function setupGameParameters() {\n                lib.showGameParameters({\n                    name: 'Settings',\n                    params: {\n                        'Background': {\n                            key: 'backgroundColor',\n                            type: 'color'\n                        },\n                        'Cake Size': {\n                            key: 'cakeScale',\n                            type: 'slider',\n                            min: 50,\n                            max: 150,\n                            step: 5\n                        },\n                        'Difficulty': {\n                            key: 'orderComplexity',\n                            type: 'slider',\n                            min: 1,\n                            max: 5,\n                            step: 1\n                        }\n                    }\n                });\n            }\n\n            // ==================== MAIN GAME LOOP ====================\n            function gameLoop(timestamp) {\n                // Clear and draw background\n                drawBackground();\n\n                // Draw cake stand and get position info\n                const standInfo = drawCakeStand();\n\n                // Draw current cake\n                drawCake(standInfo);\n\n                // Draw animations\n                drawAnimations();\n\n                requestAnimationFrame(gameLoop);\n            }\n\n            // ==================== LOADING SCREEN ====================\n            function initLoadingScreen() {\n                const loadingScreen = document.getElementById('loading-screen');\n                const loadingMascot = document.getElementById('loading-mascot');\n                const sparklesContainer = document.getElementById('loading-sparkles');\n                const sprinklesContainer = document.getElementById('loading-sprinkles-container');\n                \n                // Load mascot image\n                const mascotAsset = lib.getAsset('cake_mascot');\n                if (mascotAsset && loadingMascot) {\n                    loadingMascot.src = mascotAsset.url;\n                }\n                \n                // Sparkles container left empty (no emojis)\n                \n                // Add colorful sprinkles\n                if (sprinklesContainer) {\n                    const sprinkleColors = ['#FF69B4', '#FFD700', '#00CED1', '#FF6347', '#9370DB', '#32CD32', '#FF8C00', '#1E90FF'];\n                    for (let i = 0; i < 25; i++) {\n                        const sprinkle = document.createElement('div');\n                        sprinkle.className = 'loading-sprinkle';\n                        sprinkle.style.left = `${5 + Math.random() * 90}%`;\n                        sprinkle.style.top = `${Math.random() * 100}%`;\n                        sprinkle.style.background = sprinkleColors[Math.floor(Math.random() * sprinkleColors.length)];\n                        sprinkle.style.animationDelay = `${Math.random() * 3}s`;\n                        sprinkle.style.transform = `rotate(${Math.random() * 360}deg)`;\n                        sprinklesContainer.appendChild(sprinkle);\n                    }\n                }\n            }\n            \n            function updateLoadingProgress(progress, text) {\n                const loadingBar = document.getElementById('loading-bar');\n                const loadingText = document.getElementById('loading-text');\n                \n                if (loadingBar) {\n                    loadingBar.style.width = `${progress}%`;\n                }\n                if (loadingText && text) {\n                    loadingText.textContent = text;\n                }\n            }\n            \n            function hideLoadingScreen() {\n                const loadingScreen = document.getElementById('loading-screen');\n                if (loadingScreen) {\n                    loadingScreen.classList.add('hidden');\n                    // Remove from DOM after animation\n                    setTimeout(() => {\n                        loadingScreen.remove();\n                    }, 500);\n                }\n            }\n\n            // ==================== INITIALIZATION ====================\n            async function init() {\n                // Initialize loading screen first\n                initLoadingScreen();\n                updateLoadingProgress(10, 'Preparing ingredients...');\n                \n                // Small delay to show loading screen\n                await new Promise(resolve => setTimeout(resolve, 300));\n                \n                updateLoadingProgress(30, 'Mixing flavors...');\n                \n                // Preload all assets\n                await preloadAssets();\n                \n                updateLoadingProgress(70, 'Decorating cakes...');\n                await new Promise(resolve => setTimeout(resolve, 200));\n                \n                updateLoadingProgress(90, 'Almost ready...');\n                await new Promise(resolve => setTimeout(resolve, 200));\n                \n                // Setup game parameters for both modes\n                setupGameParameters();\n\n                // Create UI\n                createUI();\n                \n                updateLoadingProgress(100, 'Let\\'s bake!');\n                await new Promise(resolve => setTimeout(resolve, 400));\n                \n                // Hide loading screen\n                hideLoadingScreen();\n\n                if (mode === 'play') {\n                    // Start background music\n                    setTimeout(() => {\n                        backgroundMusicSource = playSound('background_music', 0.15);\n                    }, 500);\n\n                    // Generate first order\n                    startNewOrder();\n                }\n\n                // Start game loop\n                requestAnimationFrame(gameLoop);\n            }\n\n            // Start the game\n            init();\n        }\n    </script>\n</body>\n</html>", "game_config": "{\n  \"backgroundColor\": \"#FFE4EC\",\n  \"cakeStandStyle\": \"classic\",\n  \"orderComplexity\": 2,\n  \"unlockSpeed\": \"medium\",\n  \"perfectMatchBonus\": 25,\n  \"starThresholds\": {\n    \"oneStar\": 40,\n    \"twoStar\": 70,\n    \"threeStar\": 90\n  },\n  \"unlockedItems\": [\n    \"vanilla\",\n    \"chocolate\",\n    \"strawberry\",\n    \"mint\",\n    \"cookies_cream\",\n    \"mango\",\n    \"blueberry\",\n    \"caramel\",\n    \"coffee\",\n    \"pistachio\",\n    \"bubblegum\",\n    \"lemon\",\n    \"raspberry\",\n    \"matcha\",\n    \"cotton_candy\",\n    \"banana\",\n    \"cheesecake\",\n    \"red_velvet\",\n    \"peanut_butter\",\n    \"birthday_cake\",\n    \"black_sesame\",\n    \"salted_caramel\",\n    \"chocolate_chips\",\n    \"rainbow_sprinkles\",\n    \"strawberry_slices\",\n    \"crushed_oreos\",\n    \"nuts\",\n    \"gummy_bears\",\n    \"caramel_drizzle\",\n    \"marshmallows\",\n    \"coconut\",\n    \"blueberries\",\n    \"cookie_crumbs\",\n    \"raspberries\",\n    \"banana_slices\",\n    \"candy_pieces\",\n    \"graham_crumbs\",\n    \"honey_drizzle\",\n    \"mini_oreos\",\n    \"pretzel_pieces\",\n    \"caramel_bits\",\n    \"chocolate_shavings\",\n    \"toffee_bits\",\n    \"peanuts\",\n    \"cherry\",\n    \"chocolate_drizzle\",\n    \"whipped_cream\",\n    \"wafer_sticks\",\n    \"candles\",\n    \"star_sprinkles\",\n    \"chocolate_curl\",\n    \"fondant_flower\",\n    \"sugar_pearls\",\n    \"macaron\",\n    \"mint_leaves\",\n    \"gold_flakes\",\n    \"chocolate_heart\",\n    \"unicorn_horn\",\n    \"sprinkle_hearts\",\n    \"edible_glitter\",\n    \"chocolate_shards\",\n    \"candy_cane\",\n    \"gummy_worms\",\n    \"lollipop\",\n    \"strawberry_whole\",\n    \"vanilla_frost\",\n    \"strawberry_frost\",\n    \"chocolate_frost\",\n    \"mint_frost\",\n    \"caramel_frost\",\n    \"lemon_frost\",\n    \"blueberry_frost\",\n    \"cream_cheese_frost\",\n    \"raspberry_frost\",\n    \"matcha_frost\",\n    \"cookies_cream_frost\",\n    \"peanut_butter_frost\",\n    \"rose_frost\",\n    \"galaxy_frost\",\n    \"rainbow_frost\",\n    \"gold_shimmer_frost\",\n    \"lavender_frost\",\n    \"ombre_pink_frost\",\n    \"bubblegum_frost\",\n    \"cotton_candy_frost\",\n    \"red_velvet_frost\",\n    \"cheesecake_frost\",\n    \"birthday_cake_frost\",\n    \"black_sesame_frost\",\n    \"mango_frost\",\n    \"coffee_frost\",\n    \"pistachio_frost\",\n    \"banana_frost\",\n    \"salted_caramel_frost\"\n  ],\n  \"totalCoins\": 0,\n  \"cakeVerticalPosition\": 54,\n  \"tableVerticalPosition\": 46,\n  \"cakeHorizontalPosition\": 0,\n  \"tableHorizontalPosition\": -20,\n  \"cakeScale\": 85\n}", "game_design_document": "## Core Game Loop and Mechanics\n\n**Sweet Stack Studio** is a creative casual game where players run an ice cream cake shop, fulfilling customer orders by building beautiful multi-layered cakes.\n\n### Main Gameplay Flow\n\n1. **Order Phase**: A customer appears with a visual order card showing their desired cake (number of layers, flavors, toppings, decorations)\n2. **Building Phase**: Player constructs the cake by:\n   - Selecting ice cream flavors for each layer\n   - Adding the layer to the cake stand\n   - Applying toppings between layers\n   - Adding final decorations (sprinkles, fruits, chocolate drizzle, candles)\n3. **Submission Phase**: Player presents the finished cake to the customer\n4. **Scoring Phase**: Customer rates the cake based on accuracy (correct flavors, toppings, decorations) and awards stars and coins\n5. **Progression**: Earned coins unlock new flavors, toppings, and decorations for future orders\n\n### Win/Lose Conditions\n- **Success**: Complete orders accurately to earn 1-3 stars based on matching the order requirements\n- **Progression**: Unlock all available ingredients and decorations by completing orders\n- **Replayability**: Each order is randomly generated with increasing complexity, encouraging players to perfect their cake-making skills\n\n### What Makes It Compelling\n- **Creative Expression**: Players enjoy the visual satisfaction of building beautiful cakes\n- **Progression System**: Unlocking new ingredients creates a sense of achievement\n- **Order Variety**: Random orders keep gameplay fresh\n- **Low Pressure**: No time limits or failure states - players can take their time to create perfect cakes\n- **Visual Feedback**: Satisfying animations when adding layers and decorations\n\n## Starting Scope\n\nThe first iteration will focus on core cake-building mechanics with a simplified progression system:\n\n**Implement First:**\n- Single cake stand in center of screen\n- 3 basic ice cream flavors (vanilla, chocolate, strawberry)\n- 3 basic toppings (chocolate chips, rainbow sprinkles, strawberry slices)\n- 2 decorative elements (cherry on top, chocolate drizzle)\n- Simple customer order system (2-3 layer cakes)\n- Basic scoring (match order = 3 stars, close = 2 stars, far = 1 star)\n- Coin system with 5 unlockable items\n- Clean, intuitive UI for ingredient selection\n\n**Add Later:**\n- More complex orders (4-5 layers)\n- Additional flavors (mint, cookies & cream, mango, etc.)\n- More toppings (nuts, cookie crumbles, caramel sauce)\n- Advanced decorations (candles, edible flowers, chocolate shavings)\n- Customer personality variations\n- Achievement system\n- Daily challenges\n\n## Game Perspective\n\n**Fixed-screen** perspective with a centered cake stand. The camera remains stationary, showing:\n- The cake stand in the center-upper portion of the screen\n- Ingredient selection panels at the bottom (thumb-friendly zone)\n- Customer and order card in the upper-left corner\n- Score/coins display in the upper-right corner\n\nThis perspective works perfectly for the creative, focused nature of cake decoration.\n\n## Game World and Level Design\n\n### Screen Layout (720\u00d71280)\n\n**Upper Section (0-640px from top):**\n- Customer avatar and order card (upper-left, 80-300px from top)\n- Cake stand display area (center, 200-500px from top)\n- Score/coins/stars display (upper-right, 80-120px from top)\n- \"Submit Cake\" button (center, 520-600px from top, appears when cake is built)\n\n**Lower Section (640-1280px from top) - Touch Zone:**\n- Ingredient selection carousel (680-1200px from top)\n  - Scrollable horizontal panels for: Flavors, Toppings, Decorations\n  - Large, tappable ingredient icons (120\u00d7120px minimum)\n  - Tab system to switch between categories\n- Action buttons (1200-1260px from bottom):\n  - \"Undo Last Layer\" button (left)\n  - \"Clear Cake\" button (right)\n\n### Progression Structure\n\n**Level 1-5 (Tutorial Phase):**\n- Simple 2-layer cakes\n- Only basic flavors available\n- Orders show exactly what's needed with clear visual guides\n\n**Level 6-15 (Intermediate):**\n- 3-layer cakes introduced\n- New flavors and toppings unlock\n- Orders become slightly more complex\n\n**Level 16+ (Advanced):**\n- 4-5 layer cakes\n- All ingredients available\n- Complex decoration requirements\n\n## Edit Mode Design\n\nPlayers can customize various aspects of their cake shop experience:\n\n### Editable Properties\n\n**Shop Customization:**\n- `backgroundColor`: Background color of the game (color picker)\n- `cakeStandStyle`: Choose from different cake stand designs (dropdown: \"classic\", \"modern\", \"rustic\")\n\n**Difficulty Settings:**\n- `orderComplexity`: Control how complex orders are (slider: 1-5, affects layer count and ingredient variety)\n- `unlockSpeed`: How quickly new ingredients unlock (slider: \"slow\", \"medium\", \"fast\")\n\n**Starting Ingredients:**\n- `startingFlavors`: Which flavors are available from the start (multi-select checklist)\n- `startingToppings`: Which toppings are available from the start (multi-select checklist)\n- `startingDecorations`: Which decorations are available from the start (multi-select checklist)\n\n**Scoring:**\n- `perfectMatchBonus`: Bonus coins for perfect orders (number input, 10-100)\n- `starThresholds`: Accuracy percentages needed for 1/2/3 stars (three number inputs, 0-100%)\n\n### Constraints\n- At least 2 flavors must be available at start\n- At least 1 topping must be available at start\n- Order complexity cannot exceed available ingredients\n- Star thresholds must be: 1-star < 2-star < 3-star\n\n## Control Design\n\n### Mobile (Touch) Controls\n\n**Primary Interactions:**\n- **Tap ingredient icon**: Select flavor/topping/decoration from carousel\n- **Tap \"Add Layer\" button**: Add selected flavor as new cake layer\n- **Tap \"Add Topping\" button**: Apply selected topping to current layer\n- **Tap \"Add Decoration\" button**: Apply decoration to finished cake\n- **Swipe horizontally on carousel**: Scroll through available ingredients\n- **Tap category tabs**: Switch between Flavors, Toppings, Decorations\n- **Tap \"Submit Cake\"**: Present finished cake to customer\n- **Tap \"Undo\"**: Remove last added element\n- **Tap \"Clear\"**: Start over with empty cake stand\n\n**Carousel Navigation:**\n- Horizontal swipe gesture on ingredient panel to scroll\n- Smooth momentum scrolling\n- Snap to ingredient icons for easy selection\n- Visual highlight on selected ingredient\n\n### Desktop (Keyboard/Mouse) Controls\n\n**Mouse Controls:**\n- **Click ingredient icon**: Select ingredient\n- **Click action buttons**: Add layer/topping/decoration, submit, undo, clear\n- **Click and drag on carousel**: Scroll through ingredients\n- **Mouse wheel over carousel**: Scroll through ingredients\n- **Click category tabs**: Switch ingredient categories\n\n**Keyboard Shortcuts (Optional Enhancement):**\n- **Arrow keys**: Navigate through ingredients\n- **Enter**: Add selected ingredient\n- **Backspace**: Undo last action\n- **Space**: Submit cake\n- **Tab**: Switch between ingredient categories\n\n### Control Flow\n\n1. Player selects ingredient category (Flavors/Toppings/Decorations)\n2. Player browses and selects specific ingredient\n3. Player taps/clicks corresponding action button\n4. Visual feedback shows ingredient being added to cake\n5. Repeat until cake matches order\n6. Player submits cake for scoring\n\n### UI Feedback\n- Selected ingredients have visual highlight/border\n- Buttons disable when action isn't available (e.g., can't add topping without a layer)\n- Smooth animations when adding elements to cake\n- Haptic feedback on mobile for successful actions\n- Sound effects for each action\n\n## Art Style and Visual Theme\n\n### Overall Style\n**Bright, cheerful, cartoon illustration style** with a focus on making ice cream look delicious and appealing. Think vibrant colors, soft shadows, and a playful aesthetic that appeals to all ages.\n\n### Visual Direction\n- **Color Palette**: Pastel backgrounds with vibrant, saturated colors for ice cream and toppings\n- **Mood**: Cheerful, inviting, sweet, and fun\n- **Style Consistency**: All assets should have a cohesive cartoon/illustrated look with:\n  - Soft, rounded edges\n  - Subtle gradients for depth\n  - Light highlights to show texture\n  - Consistent line weight and shading style\n\n### Asset Specifications\n\n**Ice Cream Layers:**\n- Viewed from slight angle (15-20\u00b0 from side) to show depth\n- Circular/cylindrical shape, approximately 200\u00d780px\n- Visible texture (creamy, smooth appearance)\n- Distinct colors for each flavor\n- Slight shine/highlight on top surface\n\n**Toppings:**\n- Viewed from top-down angle to show how they sit on layers\n- Scattered/sprinkled appearance\n- Approximately 150\u00d7150px with transparent background\n- Should look like they're resting on the ice cream surface\n\n**Decorations:**\n- Viewed from front/slight angle\n- Sized appropriately for cake top (80-120px)\n- Should look three-dimensional with shading\n\n**UI Elements:**\n- Clean, modern interface with rounded corners\n- Soft drop shadows for depth\n- Consistent button styling\n- Clear iconography\n\n**Characters:**\n- Simple, friendly cartoon customers\n- Expressive faces showing anticipation/satisfaction\n- Approximately 150\u00d7150px\n- Diverse representation\n\n### Technical Considerations\n- All assets need transparent backgrounds (PNG format)\n- Consistent lighting direction (top-left) across all assets\n- Assets should be crisp at 2x resolution for retina displays\n- Color values should be vibrant but not oversaturated", "persistent_storage_config": null, "game_metadata": {"game_id": "01KQ6APQR8YR93HWAPF5Q7PEFV", "title": "Sweet Stack", "description": "Design dreamy ice cream cakes by stacking colorful layers, adding toppings, and decorating with flair to satisfy eager customers!", "thumbnail_url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/thumbnail_87cffe81-d976-4409-85a2-a7d18de075ff.webp", "created_at": 1777255293, "updated_at": 1777563912651.2576, "art_style": null}}