# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
yarn dev       # start dev server (Vite)
yarn build     # tsc type-check + Vite production build
yarn preview   # serve the production build locally
```

No test runner is configured.

## Architecture

This is a learning project — a canvas-based sprite animation demo. Content is organized by chapter under `src/module/chapter-*/`.

**Data flow for Chapter 1:**

1. `src/main.ts` — entry point; injects a `<canvas>` into `#app` and calls `chapter1()`.
2. `chapter-1.ts` — owns the canvas and the `requestAnimationFrame` loop. Reads the current animation state name (e.g. `"run"`, `"idle"`) and advances `gameFrame` each tick to step through sprite frames.
3. `select.ts` — creates a `<select>` dropdown populated from `animationPhases`. Returns an RxJS `Observable<Event>` (via `fromEvent`) that `chapter-1.ts` subscribes to for switching the active animation.
4. `data/animationPhases.ts` — defines each animation by name and frame count (the sprite sheet has 10 rows × 12 columns; each row is one animation).
5. `data/spriteAnimationData.ts` — `getAnimationStates()` converts the phases array into a keyed map of `{ loc: {x,y}[] }`, computing pixel offsets into the sprite sheet from `SPRITE_W`/`SPRITE_H`.

**Sprite sheet layout:** `shadow_dog.png` (6876 × 5230 px) — 12 columns, 10 rows. Each cell is one frame; rows map 1-to-1 to animation names in declaration order in `animationPhases`.

**CSS modules** are enabled with scoped names (`[name]_[local]__[hash:base64:5]`). Component styles live in `*.module.css` next to their `.ts` file.

**RxJS** is used only for DOM event streams (no state management or complex operators yet).
