# The Aster System

Every aster in the brand comes from `aster.py`: one seeded, parametric generator, finished in PhotoCraft. Later phases (cans, posters, social) call the same code instead of redrawing the flower.

**Sheet:** `aster_system_sheet.png` (layered: `.psd`). It shows the bloom at 5 abstraction levels, the field in 3 lights, and the palette.

## How it splits between code and PhotoCraft
| Step | Where | Why |
|---|---|---|
| Bloom and field geometry: petals, clumps, drifts, grass, stems, depth bands | `aster.py` → SVG with semantic `id`s | PhotoCraft has no scatter or scripting engine reachable in automation |
| Import as **named vector layers** (`d3-petals-a`, `d1-grass-rust-front`, …) | PhotoCraft `doc_open` | SVG ids become layer names |
| Sky, sun, haze, ground shade | PhotoCraft gradient **fill layers** | editable stops and positions |
| Depth of field | each band → **smart object + live Gaussian Blur** (smart filter) | blur radius editable later |
| Light grade | **adjustment layers** (color balance, curves, hue/sat) | non-destructive |
| Grain, vignette | separate overlay layers | can be switched off |

`<name>.recipe.json` holds the PhotoCraft steps for a field (`command_batch` format). Recipes find layers by **name**, so they work on any regenerated field.

## Bloom parameters (`Bloom`)
| Param | Default | Notes |
|---|---|---|
| `petals` | **8** | Echoes the 8 oz can and suits the mark. Real asters carry 15–40+ rays, so botanical levels use 18–34 |
| `abstraction` | 1 | 0 geometric star · 1 geometric bloom · 2 flat illustration · 3 botanical · 4 loose botanical |
| `length_var`, `width_var`, `angle_jitter` | per level | 0 at levels 0–1 (perfectly even), rising to 0.16 / 0.18 / 5° at level 4 |
| `center` | 0.24 | disk radius relative to the ray tip |
| `back_ring` | per level | darker second ring at levels 3–4, so overlapping rays never fuse |
| `petal_color`, `petal_color_2`, `petal_shadow`, `center_color`, `center_shadow` | palette names | see `palette.json` |
| `florets` | True | level-of-detail switch for tiny blooms |
| `seed` | 0 | same seed, same bloom |

Levels 1–2 use a spacing-aware width cap, so neighbouring rays always keep a visible gap (no fused petals). At levels 3–4, the rust disk shows through between the gold florets, which is what an aging aster center does.

## Field parameters (`FieldParams`)
| Param | Default | Notes |
|---|---|---|
| `w`, `h` | 1920×1080 | any size; counts scale with width |
| `seed` | 7 | the same seed gives the same field in every light (see the sheet) |
| `density` | 0.8 | 0.2 sparse … 1.2 lush |
| `horizon` | 0.42 | fraction from top |
| `light` | golden | `golden` · `dusk` · `overcast` |
| `bloom_scale` | 1.0 | size of the nearest blooms |
| `clear_zone` | none | `(x0, x1)` keeps the front bands low there, as a spot to stand a can |
| `bokeh` | True | a few huge, very soft blooms at the lens |

Five depth bands run from the horizon to the lens. Bloom size follows the ground-plane perspective. Asters grow in **clumps on branched stems**, placed by smooth noise into **drifts**, so the field never looks tiled. Grass is drawn behind *and* in front of each band, so the flowers sit in the prairie rather than on top of it. Distant oak-savanna groves sit on the horizon under heavy haze.

```bash
python aster.py field --light dusk --seed 7 --density 0.85 --horizon 0.42 --w 1600 --h 900 --out field_dusk
```

```bash
python aster.py bloom --level 3 --petals 21 --seed 4 --center 0.27 --out bloom.svg
```

## Honest limits
- The look is **illustrated, not photographic**: flat vector forms finished with depth of field, haze and grain. PhotoCraft has no generative imagery.
- Field SVGs are large (5–13 MB) because each is fully vector. PSDs keep the bands as smart objects.
