Wrap AnimatedBuilder in SizedBox.expand so the Stack fills the full
Scaffold body; alignment: Alignment.center now centers within the whole
screen instead of within the wordmark-sized intrinsic box.
Adds a regression widget test (test/ui/splash_screen_test.dart) that
asserts the wordmark dx is within 1px of screen-center at 1500ms into
the animation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Guard addPostFrameCallback with !_autoScrolled so it only fires once per
widget lifetime instead of on every LayoutBuilder rebuild.
- Derive seasonComplete flag; pass it into _node so the last stage uses
gold "done" styling (not "current/next") when the season is fully 3-starred.
- Extract const Color(0xFF232B4A) to GamePalette.lockedNode.
- Remove warnIfMissed: false from tap call in season_map_screen_test; ensureVisible
already guarantees hit-testing succeeds (confirmed: test still passes cleanly).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the plain GridView with a Candy-Crush-style journey map:
dotted serpentine path, circular nodes (gold=done, glowing=current,
dark+lock=locked), glass header, auto-scroll to current stage.
Updates season_map_screen_test to use Key('stage_node_$i') finders.
Shows "SEASON 1 / First Bloom / N stages" over the season background for
~1.6s between splash and home; tap anywhere skips. Bails to home on
content-load error. Adds seasonLabel/seasonStages l10n keys (en + ko).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After Ticker.stop(), elapsed resets to zero on the next start(). _now was
left frozen at the old elapsed, so effects added after a drain captured a
stale start time and their progress() clamped to 0 forever — ticker never
stopped, second batch broken. Fix: reset _now = Duration.zero on drain.
Adds @visibleForTesting getters and a regression test that catches the
stale value directly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces candy-gloss tile rendering (diagonal gradient + glass highlight
+ optional glow) via a shared paintGlossyTile() in tile_painter.dart,
applied to board filled-cells and tray/drag-overlay pieces. Adds
ThemeColors to palette.dart for UI-layer season color resolution, and
activeThemeProvider for one-call access to the active season's theme.
Regenerates the game_screen golden to reflect the new look.
SaveRepository (versioned JSON over prefs) with best-result merging and
unlock walking; ContentRepository loads the bundled pack; SeasonFlow/
Progress notifiers orchestrate stage start -> win record -> advance.
Season map grid with stars/locks, Home -> Map -> Game navigation,
close button, next-stage action on the win overlay.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pure-Dart WAV synthesizer (tool/gen_sfx.dart) generates place/clear/
combo/win/lose effects; AudioService player pool fires on placement,
line clears, combo streaks, and phase transitions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CustomPainter board with gems/ghost/clear-flash, finger-lifted drag
with snap preview, combo text effect, HUD chips, phase overlays with
rescue stubs, demo stage. E2E widget test drives a real drag gesture.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>