From ab614150a0f300bf5a1817f151e8cbe3c4c1c515 Mon Sep 17 00:00:00 2001 From: auricIecu Date: Mon, 11 May 2026 10:19:53 -0500 Subject: [PATCH] feat: celebrate every 10 dispatched trains Show a milestone overlay with the running dispatch count and falling confetti each time the counter crosses a multiple of 10. Also adds a CLAUDE.md describing the starter project for future agents. Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 33 ++++++++++++++++++++++ src/App.css | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/App.tsx | 69 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9325e57 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,33 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this project is + +A Conductor starter project: a single-page React 19 + TypeScript + Vite app where clicking (or pressing Space/Enter) dispatches an animated emoji train across the screen. It exists to give new Conductor workspaces something quick to install, run, edit, review, and ship. + +Conductor runs each workspace as an isolated git worktree. `conductor.json` defines the two scripts Conductor invokes: `setup` (`npm install`) on workspace creation and `run` (`npm run dev`) when the user clicks Run. + +## Commands + +- `npm run dev` — Vite dev server (Conductor's Run button calls this) +- `npm run build` — type-check (`tsc -b`) then production build +- `npm run lint` — ESLint over the repo +- `npm run preview` — preview the built output + +There is no test runner configured. + +## Architecture + +The entire app lives in `src/App.tsx`. Key things to know before editing it: + +- **State model**: `trains` and `puffs` are arrays of independent animated entities, each with a unique id from a single `nextIdRef` counter. They are removed from state via their CSS `onAnimationEnd` handler — animation duration is the source of truth for lifetime, so changing CSS timings without updating `MIN_DURATION_MS`/`MAX_DURATION_MS` will desync the steam puffs that are scheduled with `setTimeout`. +- **Dispatch throttling**: rapid clicks are gated by `DISPATCH_THROTTLE_MS` against `performance.now()` in `lastDispatchRef`. Lane and direction also alternate via refs so consecutive trains don't overlap. +- **Audio**: a single `