Commit Graph

4 Commits

Author SHA1 Message Date
3f4d8d4e90 bucket_catch: split usePuzzleGameLoop.ts 386 -> 194 + two modules
puzzleGeometry.ts (127)  board constants, ScheduledPiece, and the Union-Find
                           interval clustering in assignXPositions that makes a
                           100% score achievable; plus aabbCollision
  puzzleRender.ts (110)    the four canvas draw functions

Both were module-private, so nothing outside the hook sees either seam.

One thing was reshaped rather than moved: the inline clearRect+gradient in the
tick became a named drawBackdrop, so the render module owns every canvas call.
That is why coverage goes 583/217/97/534 -> 584/217/98/535 -- one statement,
one function, branches unchanged.

eslint reports 45 errors, exactly as it did before the split, which is the
check that matters here: the extraction added none. Those 45 are pre-existing
and were unmasked by the previous commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-17 10:05:37 +02:00
394c919f9a bucket_catch: fix typecheck so build works and eslint runs
npm run build and npm run lint were both failing at HEAD on two errors:

  TS2769  vitest 4 no longer contributes `test` to vite's defineConfig, so
          the /// <reference types="vitest" /> directive had gone inert
  TS6133  an unused `const { result } =` in usePuzzleGameLoop.test.ts

Because lint is `tsc --noEmit && eslint src`, the failing tsc short-circuited
the &&, so eslint had never actually run on this package. Fixing tsc unmasks
45 pre-existing eslint errors across 10 files -- 18 no-non-null-assertion,
10 unbound-method, 9 non-nullable-type-assertion-style, and a tail. Those need
per-site judgment and are NOT fixed here; lint still exits 1 on them.

So this does not make lint green. It makes build work (52 modules, was
failing) and makes the eslint failures visible instead of hidden behind a
short-circuit. Coverage unchanged at 583/217/97/534, which is what proves the
config is still read after changing its import.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-17 10:02:58 +02:00
a7596d0442 bucket_catch: introduce a real design-token system, fix reversed gradients
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Fixes every violation in DESIGN_AUDIT_TODO.md's bucket_catch frontend
section. The app previously had no shared tokens at all (index.css was a
12-line reset) and 19 hardcoded hex colors duplicated independently
across 6 *.module.css files.

New :root token block in index.css: bg gradient stops, a drag-state
gradient, the indigo/pink accent pair collapsed to one canonical
--gradient-accent direction, text/surface colors, success/error, 2
consolidated muted-gray roles (down from 4 unrelated shades), a 4px
spacing scale, and a radius scale. All 6 component files migrated onto it.

Fixes the real reversed-gradient-stop bug the audit named
(PuzzleResult.module.css .grade was pink->indigo vs every other heading's
indigo->pink) plus a second instance of the same bug the audit's prose
didn't cite by line number (ModeSelect.module.css .puzzleStart button) --
both now reference --gradient-accent so this class of bug can't recur.
Also fixes: .preset's border contrast (was under 3:1), cardDesc's
sub-16px font-size, 4 buttons' off-ratio padding (now exact 2x), 2 large
icons' full-contrast rendering next to muted text (now dimmed), the
explicitly-cited off-grid spacing values, and ModeSelect's gridInput
background color which had drifted from its DropZone sibling's.

Verified: 145/145 tests at 100% coverage (CSS-only, confirms no
functional regression), a real vite build succeeds, re-verified identical
in an isolated worktree at HEAD, and pixel-checked the production build
via a headless-Chrome screenshot (gradient direction now matches between
heading and button; preset chip borders clearly visible).
`npm run lint` (tsc -b + eslint) was already broken on a clean checkout
before this change (1 pre-existing tsc error in vite.config.ts, 46
pre-existing eslint errors in untouched test/lib files) -- confirmed via
an isolated worktree at the parent commit, left alone as out of scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 19:18:12 +02:00
5a9296d8aa Add bucket_catch: osu!catch browser game with 100% frontend test coverage
Frontend (React 19 + Vite 6 + TypeScript strict):
- DropZone, ModeSelect, GameCanvas, PuzzleCanvas, ScoreScreen, PuzzleResult
- File-drop game with AABB collision; download (JSZip) and upload (NestJS) modes
- Puzzle mode: NxN image slice via OffscreenCanvas; Union-Find spatial clustering
  guarantees 100% catch rate is always achievable regardless of piece speeds
- ESLint typescript-eslint strict-type-checked (zero errors)
- 145 Vitest tests; 100% coverage on statements/branches/functions/lines

Backend (NestJS 11):
- POST /files/upload (multer disk storage) and GET /health

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YZ8QTmreFcaqrsvVb38Grd
2026-06-27 12:21:35 +02:00