engine/heroes library

Hand-crafted hero themes (spec §5.2: "every ~8–12 swipes, inject a hand-crafted hero theme"; design doc: ≥ 3 per enabled family).

Heroes are literal ThemeSpecs: hand-picked ARGB palettes plus hand-tuned shape, type and motion. They never depend on the generator, so they cannot change when the generator does. Each one passes the same guardrails as generated themes (test/themes/engine/heroes_test.dart), and heroForAccessible repairs them for the Accessible lock.

Hero ids are stable (share codes carry them in the seed field with family 31); never reuse or renumber one.

Constants

heroThemes → const List<ThemeSpec>
Every hero, in id order. Ids 1–4: Material 3 Expressive; 5–7: NeoPOP; 20–22: Liquid Glass; 40–42: Neumorphism; 50–52: Retro hardware; 60–62: Neo-brutalism; 70–72: Claymorphism; 100–102: Y2K / Frutiger Aero; 110–112: Paper & ink; 130–132: Cyberpunk; 140–142: Vaporwave; 150–152: Bauhaus.

Functions

heroById(int id) → ThemeSpec?
The hero with id, or null.
heroesFor(ThemeFamily family) → List<ThemeSpec>
Heroes of family in id order.
heroFallback(int seed, ThemeFamily family, {bool accessible = false}) → ThemeSpec
The deterministic last-resort theme for (seed, family) when every generator attempt fails: one of the family's heroes (or any hero).
heroForAccessible(ThemeSpec hero, {bool accessible = true}) → ThemeSpec
hero repaired for the Accessible lock (labels and display text ≥ 7:1). Returns hero unchanged when accessible is false.