# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
cargo check # Quick compile check
cargo check --no-default-features --features core # Verify no_std compatibility
cargo check --all-features # All features
cargo test # All tests (unit + integration)
cargo test --lib # Unit tests only
cargo test --test colormaps # Integration tests only
cargo test registry_tests::find_by_name_works # Single test by name
cargo clippy -- -W clippy::all # Lint
cargo run -p xtask -- all # Fetch upstream data + generate Rust source
cargo run -p xtask -- fetch # Fetch upstream colormap data only
cargo run -p xtask -- generate # Generate Rust source from data/ only
```
## Architecture
Prismatica is a `#![no_std]` Rust crate providing 260+ scientific colormaps as compile-time constants. A colormap maps a scalar `t ∈ [0,1]` to an RGB color via a 256-entry lookup table with linear interpolation.
### Core library (`src/`)
- **`types.rs`** — All public types: `Color` (sRGB u8), `Colormap` (metadata + `&'static [[u8; 3]]` LUT), `ColormapKind` (Sequential/Diverging/Cyclic/Qualitative/MultiSequential), `ColormapMeta`, `ReversedColormap`, `DiscretePalette`
- **`registry.rs`** — Discovery API: `find_by_name()` (no alloc), `all_colormaps()`/`filter_by_kind()`/`filter_by_collection()` (alloc-gated). Uses a `for_each_colormap()` helper that iterates feature-gated collection `ALL` slices — new collections must be added here
- **`traits.rs`** — `IntoFrameworkColor<T>` trait (matches chromata's identical trait)
- **`integration/`** — Feature-gated `From<Color>` + `IntoFrameworkColor` impls for egui, plotters, image; serde derives on `ColormapKind`/`ColormapMeta`
- **`lib.rs`** — `#![no_std]`, `#![forbid(unsafe_code)]`, `#![deny(clippy::unwrap_used)]`, `extern crate alloc`, module declarations with `#[cfg(feature)]` gates, re-exports
### Collection modules (`src/{collection}/`)
Each collection (matplotlib, crameri, cet, etc.) follows the same generated pattern:
- **`mod.rs`** — `mod`/`pub use` for each colormap + `pub static ALL: &[&Colormap]`
- **`{name}.rs`** — `pub const {NAME}: Colormap` with full metadata + `static {NAME}_LUT: [[u8; 3]; 256]`
Files marked `// Auto-generated by prismatica xtask -- do not edit` are generated — modify the xtask instead.
### Code generation pipeline (`xtask/`)
A workspace binary crate that fetches real upstream data and generates Rust source:
1. **Fetch**: Downloads Crameri ZIP from Zenodo + matplotlib/seaborn Python source from GitHub. Parses float LUT data, normalizes to `data/{collection}/{name}.csv` (uint8) + `.json` (metadata). The `data/` directory is gitignored.
2. **Generate**: Reads `data/` and emits `src/{collection}/*.rs` files. Preserves `//!` doc comments from existing `mod.rs` files.
Currently implemented for matplotlib (8 maps) and crameri (40 maps). Adding a new collection requires: a fetch function, classification logic, and adding the collection to `generate_all()` and `registry.rs::for_each_colormap()`.
## Feature flags
- **`std`** (default) — depends on `alloc`, enables full API
- **`alloc`** — enables methods returning `String`/`Vec`: `to_css_hex()`, `colors(n)`, `all_colors()`, plus registry Vec-returning functions
- Integration flags: `egui-integration`, `plotters-integration`, `image-integration`, `serde-support`
- **`core`** (default) — enables `matplotlib` + `crameri` collections
- Collection flags: `matplotlib`, `crameri`, `cet`, `cmocean`, `colorbrewer`, `cmasher`, `ncar`, `cartocolors`, `moreland`, `d3`, `all`
Methods gated on alloc use `#[cfg(any(feature = "alloc", feature = "std"))]` and fully-qualified types like `alloc::vec::Vec<Color>`.
## Key conventions
- Crameri classification: cyclic maps end in `O` (e.g., `romaO`), diverging includes `berlin`/`broc`/`cork`/`vik`/`lisbon`/`tofino`/`vanimo`/`bam`/`roma`/`managua`, multi-sequential is `oleron`/`bukavu`/`fes`
- Const names are UPPER_SNAKE: `batlowK` → `BATLOWK`, `romaO` → `ROMAO`. Module names are lowercase: `batlowk.rs`, `romao.rs`
- The `meta.name` field preserves original mixed case: `"batlowK"`, `"romaO"`
- Tests run with `--test-threads=1` in CI
- Reference value tests allow ±2-3 tolerance due to resampling from upstream sources
- `Color` has WCAG methods (`luminance()`, `contrast_ratio()`) using `libm` for no_std `pow()` — matches chromata's identical implementation
- Sibling project: chromata (editor themes) uses the same Color type, traits, integration pattern, and lint attributes