Skip to content

Upgrade fireworks: CSS custom-prop particles, 3-burst cascade, screen-wide coverage#28

Merged
Maangled merged 2 commits intomainfrom
copilot/add-rocket-animation-fireworks
Mar 21, 2026
Merged

Upgrade fireworks: CSS custom-prop particles, 3-burst cascade, screen-wide coverage#28
Maangled merged 2 commits intomainfrom
copilot/add-rocket-animation-fireworks

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 21, 2026

Replaces the 16 fixed-direction fwP* keyframes from PR A with a dynamic, randomized firework system that spreads particles across the full viewport on Genesis Pioneer unlock.

CSS

  • Dropped 16 bespoke @keyframes fwP1fwP16 (evenly spaced, 300px fixed radius)
  • Single @keyframes fireworkParticle reads --fw-dx/--fw-dy custom properties set per element:
    @keyframes fireworkParticle {
      0%   { transform: translate(0,0) scale(1); opacity: 1; }
      50%  { opacity: .85; }
      100% { transform: translate(var(--fw-dx),var(--fw-dy)) scale(0); opacity: 0; }
    }

JS — showFireworks()

Before After
Particles 16, fixed 16 directions 22/burst, random 360° angles
Radius 300 px fixed 150–500 px random
Bursts 1 3 staggered: 0 ms → 320 ms → 640 ms
Colors 8 10 (added teal #34d399, purple #a78bfa)
Glow single box-shadow double box-shadow for sparkle

Each particle gets --fw-dx/--fw-dy computed from a randomized angle + distance, so no shared keyframe conflicts and no DOM style-tag proliferation. Containers self-remove after 2 600 ms.

Original prompt

Context

This is a follow-up animation PR for docs/personal-profile.html. A companion PR (PR A) is fixing the Begin button blocker and adding the boot animation sequence. This PR (PR B) adds the achievement rocket animation and screen-wide fireworks that play AFTER the user clicks the Begin button.

CRITICAL: Read docs/AGENT_GUIDE.md before touching any code. All architecture constraints are binding. Key rules:

  • file:// protocol compatibility is mandatory — no external dependencies, no fetch(), no ES modules, no CDN links
  • saveProfile() is the ONLY localStorage write point — do not bypass
  • Do not restructure the stage flow (0→1→2→3) — it is load-bearing
  • Do not modify hashData() or remove the djb2 fallback
  • The file is a single self-contained HTML file with all CSS/JS embedded
  • Do not skip the Trade Window consent dialog on first visit

Read the ADRs in docs/adr/ — they are binding.

What This PR Does

1. Rocket Emoji Animation on Begin Click

When the user clicks the Begin button (or when the first achievement "Genesis Pioneer" unlocks):

  • A 🚀 rocket emoji element appears at the Begin button's position
  • It rockets upward, then traces a circular arc path in the air (like an orbit)
  • It swoops back down and lands directly on the Genesis Pioneer achievement card
  • Use CSS @keyframes with a custom motion-path or manual transform: translate() keyframes to trace the circular path
  • The rocket should have a slight rotation following its trajectory
  • Total animation duration: ~2 seconds
  • After landing, the rocket fades out and triggers the achievement unlock

Implementation approach:

@keyframes rocketLaunch {
  0%   { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  15%  { transform: translate(0, -150px) rotate(-20deg); opacity: 1; }
  40%  { transform: translate(100px, -250px) rotate(45deg); opacity: 1; }
  65%  { transform: translate(200px, -100px) rotate(120deg); opacity: 1; }
  85%  { transform: translate(var(--target-x), var(--target-y)) rotate(180deg); opacity: 1; }
  100% { transform: translate(var(--target-x), var(--target-y)) rotate(360deg); opacity: 0; }
}

Use JS to calculate the position offset between the Begin button and the Genesis Pioneer achievement card, set CSS custom properties, and trigger the animation.

2. Screen-Wide Fireworks on Achievement Unlock

When the Genesis Pioneer achievement unlocks (after the rocket lands):

  • Fireworks burst across the entire screen — not just the achievement card
  • Create multiple particle elements (15-25 small colored dots/sparks) that explode outward from the achievement card's position
  • Colors: gold, amber, cyan, white — matching the FERROS theme
  • Each particle follows a different trajectory (randomized angles) using CSS transforms
  • Particles fade out as they reach the edges
  • Optional: 2-3 separate bursts staggered by ~300ms for a cascading firework effect

Implementation approach:

@keyframes fireworkParticle {
  0%   { transform: translate(0, 0) scale(1); opacity: 1; }
  50%  { opacity: 0.8; }
  100% { transform: translate(var(--dx), var(--dy)) scale(0); opacity: 0; }
}

Use JS to:

  1. Create 20+ absolutely-positioned particle <div> elements
  2. Set random --dx and --dy CSS custom properties for each (range: -300px to +300px in both axes)
  3. Set random colors from the theme palette
  4. Set random sizes (3px to 8px border-radius circles)
  5. Apply the animation with slight random delays
  6. Remove the elements after animation completes (cleanup)

3. Enhanced Achievement Unlock Sequence

The full sequence when Begin is clicked or Genesis Pioneer triggers:

  1. 🚀 Rocket launches from button area (~0ms)
  2. 🚀 Rocket orbits and lands on achievement card (~2000ms)
  3. 🏆 Achievement card gold shimmer animation fires (existing from PR PR 2/3: Hero experience — android companion, begin button pulse, achievement unlock animations #23) (~2000ms)
  4. 🎆 Fireworks burst from achievement card (~2200ms)
  5. ✨ "+25 SP" float-up animation (existing from PR PR 2/3: Hero experience — android companion, begin button pulse, achievement unlock animations #23) (~2500ms)
  6. 🎆 Second firework burst (~2500ms)
  7. Elements clean up (~4000ms)

4. Achievement Hover Tooltip Fix (backup)

If PR A doesn't already fix this: The achievement card hover tooltips from PR #23 disappear when the user moves their cursor to click a button inside the tooltip.

Fix: Change from pure CSS :hover to a click-to-toggle pattern:

  • Click an achievement card → add an .tooltip-active class that keeps the tooltip visible
  • Click again or click elsewhere → remove the class
  • The tooltip's "Discover Profiles" button must remain clickable
  • Add a click-outside listener to dismiss

If PR A already fixed this, skip this section — check the current code on main first.

Implementation Notes

  • All CSS and JS must be inline in the single HTML file
  • The rocket and fireworks are temporary DOM elements — create them via JS, animate with CSS, then remove them
  • The animations should feel celebratory and rewarding — this is the user's first achievement!
  • Firework particles should be smal...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…overage via CSS custom props

Co-authored-by: Maangled <108793241+Maangled@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Maangled/ferros/sessions/c8ef5f9b-10db-4d57-bbd5-c8f2319a053c
Copilot AI changed the title [WIP] Add achievement rocket animation and screen-wide fireworks Upgrade fireworks: CSS custom-prop particles, 3-burst cascade, screen-wide coverage Mar 21, 2026
Copilot AI requested a review from Maangled March 21, 2026 22:16
@Maangled Maangled marked this pull request as ready for review March 21, 2026 22:17
@Maangled Maangled merged commit ccd88f4 into main Mar 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants