Community Drama debuff applyFn was mutating G.codeBoost *= 0.7 on every
updateRates() call, permanently degrading the boost. Now correctly
applies G.codeRate *= 0.7 to the rate output, not the persistent boost.
Fixes#64
Visual Identity Pass:
- Smooth phase transition overlay with staggered fade-in animation and particle burst
- Building purchase confetti at x10 milestones (gold + green particles)
- Animated resource counters (pulse on gain, shake on loss) - already existed, verified working
Ending Cinematic Enhancement:
- Beacon ending: fade-to-black transition, staggered text reveal, golden light rays,
continuous floating particles, expanded stat summary, 'Play Again' button
- Drift ending: glitch animation on title, fade-in overlay, stat summary with
buildings/projects/clicks/time/phase, dramatic line-by-line log reveal
Accessibility (#57):
- Sound mute toggle button (M key) with localStorage persistence
- High contrast mode toggle (C key) with CSS variable overrides
- Both toggles in fixed bottom-left toolbar with aria-labels
- Keyboard shortcuts M and C added, help overlay updated
- Drift ending button changed to 'Play AGAIN' with proper aria-label
Adds DOM-based particle burst animations when buying buildings and
completing research projects. Blue particles for buildings, gold for
projects. Lightweight CSS animation with no external dependencies.
Refs #57 — Night of Polish, Task 1 (Visual Identity)
Replace native browser title= tooltips with styled custom tooltips
that match the game's dark theme. Tooltips appear instantly on hover
with building/project name and educational content.
- Add CSS for #custom-tooltip with dark theme styling
- Add tooltip div to HTML body
- Add event delegation in main.js for [data-edu] elements
- Convert renderBuildings and renderProjects to use data-edu
and data-tooltip-label attrs instead of title=
- Tooltip follows cursor with screen-edge clamping
Refs: Epic #57 — Night of Polish, Task 4 (Tooltip system)
- Add CSS keyframes: res-pulse (scale up + blue flash) and res-shake (horizontal shake + red flash)
- Track previous resource values in _prevRes object
- Detect gain/loss on each renderResources() call and trigger appropriate animation
- Add rate color coding: green for positive, red for negative, dim for zero
- Clean up animation classes after 400ms to allow re-triggering
- No external dependencies, pure CSS + vanilla JS
- Remove duplicate clipboard/prompt-based exportSave/importSave from utils.js
(render.js file-based versions were already overriding them)
- Add toast notifications for export success and import errors
- Add isValidSaveData() with robust validation (checks totalCode, code, buildings, phase)
- Prevent duplicate file dialogs on rapid E key presses
- Clean up file input element when user cancels dialog
- Add toast for JSON parse errors on import
Auto-save game state when the browser tab is hidden (visibilitychange)
or closed/navigated away (beforeunload). Prevents data loss on mobile
where tab switching can kill the page without a save interval firing.
Part of epic #57 Night of Polish — Task 6: Mobile Polish.
playTime was defined in globals but never incremented and never
included in save/load. Now incremented each tick and persisted
in localStorage via the whitelist and save data.
applyFn was multiplying G.codeBoost by 0.7 on every updateRates() call
(building purchase, project, click, etc.), permanently degrading it.
After 10 calls the boost was effectively zero.
Fix: apply penalty to G.codeRate (computed per-tick) instead of
G.codeBoost (persistent multiplier). Debuffs must never mutate boost state.
Part of #57 — Task 4: Tutorial & Onboarding
- 5 click-through screens introducing game concepts (code, buildings,
research, phases, keyboard shortcuts)
- Skip button on every screen, keyboard support (Enter/Escape/arrows)
- Stores completion in localStorage — only shows once for new players
- Matches existing visual style (dark theme, accent colors, monospace)
- Start Playing button on final screen with shortcut hint (? overlay)
- index.html: role=region on phase-bar, strategy-panel; role=dialog+aria-modal on help overlay, offline popup, drift ending; aria-label on help button, close button, continue button, start over button; aria-live on progress label
- render.js: aria-label on alignment event buttons; fix exportSave() URL revoke race with setTimeout delay
- engine.js: aria-label+aria-pressed on buy amount buttons; role=button+tabindex+aria-expanded+aria-controls on completed projects header
- Building rate display now shows actual boosted rates (after multipliers)
instead of raw base rates, so players see their real production
- WRITE CODE button area now displays current click power dynamically
(updates each render tick as boosts change)
- Click power also reflected in button aria-label for accessibility
Closes#61
New panel in the stats area displays each owned wizard building with:
- Name and current status (Active/Idle/Stressed/Offline/Vanished/Present)
- Color-coded indicator: green=healthy, amber=reduced, red=problem
- Production contribution breakdown per wizard
- Timmy shows effectiveness % scaled by harmony
- Allegro shows idle warning when trust < 5
- Ezra shows offline status when debuff is active
- Bilbo shows vanished status when debuff is active
- Harmony summary bar at the bottom
Makes the harmony/wizard interaction system visible and actionable.
Players can now see at a glance which wizards need attention.
Players with 100+ max ops get a second row of 50-ops buttons
that convert 50 ops at once for proportionally larger boosts.
Shift+1/2/3 keyboard shortcuts for bulk code/compute/knowledge.
Eliminates late-game tedium of clicking 5-ops buttons hundreds
of times when you have thousands of ops banked.
Two new Phase 2 research projects that fill the gap between building
a Home Server and reaching Phase 3 (Deployment):
- Open Weights (compute: 3000, code: 1500): Triggers after having a
server and 1000 total code. Rewards 2x code boost and 1.5x compute
boost. Teaches about running models locally without cloud dependency.
- Prompt Engineering (knowledge: 500, code: 2000): Triggers after
200 knowledge and 3000 total code. Rewards 2x knowledge and 2x user
boost. Teaches that good prompting beats bigger models.
Both projects follow the game's existing pattern: unlock based on
total resources, cost resources, apply boosts, and log educational
messages. They give players more strategic options in early-to-mid
game progression.
The header now shows a pulsing beacon dot that reflects fleet state:
- Color: green (healthy harmony >70), amber (stressed 40-70), red (critical <40)
- Flicker speed: faster when production is high, fastest when debuffs are active
- Label: shows current phase, fleet size, and active alert count
- End states: DRIFTED (red) or SHINING (gold) for game endings
DESIGN.md called for this: "The Pulse — a central visual that brightens when
the fleet is healthy, flickers when harmony is low." Now it exists.