rust-synth 0.18.0

Terminal modular ambient synthesizer — FunDSP + Ratatui. Long cinematic pads, Euclidean drum sequencer, per-track LFO, Valhalla-Supermassive-style reverb, genetic evolution coupled to Conway's Game of Life, TOML presets, FLAC recording.
Documentation
# CLAUDE.md — rust-synth

Terminal modular ambient synthesizer. FunDSP + cpal + Ratatui. Single binary.

> This file is a **map**, not a manual. Keep it short. Point to `docs/`.

## Stack
- **rustc** (edition 2021, MSRV 1.75+)
- **fundsp 0.20** — DSP graph, oscillators, filters, reverb
- **cpal 0.15** — audio output
- **ratatui 0.29** + **crossterm 0.28** — TUI
- **hound 3.5** — offline WAV render
- **parking_lot**, **tracing**, **anyhow**, **thiserror**

## Commands
`make help`. Primary: `make dev` (TUI debug), `make run` (TUI release),
`make render` (offline WAV), `make check` (fmt + clippy + test).

## Directory map
```
src/math/    pure math (sigmoid, smoothstep, perlin, brown_walk)
src/audio/   FunDSP presets, Track (Shared params), cpal engine
src/tui/     Ratatui widgets + event loop
cli/         offline WAV render (mirrors default track set)
```

## Architecture rules
1. **audio callback never locks.** All live params flow through
   `fundsp::Shared`. TUI calls `shared.set_value(x)`.
2. **Presets are pure formulas.** Don't hide state — build graphs from
   `var(&shared)`, `lfo(|t| …)`, and operator composition (`>>`, `|`, `+`, `*`).
3. **Math functions are deterministic.** Same seed + t → same output.
   Add tests in `src/math/*`.
4. **Direction:** `tui/ → EngineHandle (Shared) ← audio/ ← math/`. No reverse imports.

## SGR / Domain-First
`TrackParams` and `PresetKind` live in `src/audio/track.rs` and
`src/audio/preset.rs`. Change these **first** when adding features — TUI
reflects them, CLI renders them.

## Anti-patterns
- Parsing formulas from the TUI at runtime (build preset functions instead).
- Holding `Mutex` across an audio callback iteration — use `Shared`.
- Dropping into `unsafe` or `std::mem::transmute` — everything here is safe
  Rust; if you reach for unsafe, stop and ask.
- Adding dependencies beyond the six listed above without a reason in the PR.

## Skills
- `.claude/skills/dev/` — how to work on this project (run, test, extend).

## Docs
- `docs/prd.md` — problem, scope, architecture invariants.