A generative system for Aicher-style bar compositions. Every colour boundary is a radius-h quarter turn, no colour stacks on itself, and the ground never reaches inside - twelve invariants that make almost every seed look composed.
What the Lattice controls may and may not reach.
Bars of equal height h, full canvas width. Every boundary position is a multiple of h horizontally, so the composition lives on a square lattice.
What the Boundaries controls may and may not reach.
A boundary between two colours is always a quarter turn of radius exactly h — never a straight vertical edge, never any other radius, never a free Bézier. A boundary crossing a bar therefore always displaces by ±1 cell.
A boundary carries a tangent state across each bar edge, V or H, and a turn flips it. With B1 in force the states strictly alternate V H V H, so turns arrive in pairs and read as capsules (reversed) or S-curves (continued). No kinks are constructible.
A bar holds 2, 3 or 4 slots — never fewer, never more. There is no such thing as a bar of one field, so at least one boundary is live at every height.
What the Colour palette may and may not do.
A colour holds one run in the whole composition and never returns. Legal runs are exactly three: two adjacent bars; three adjacent bars; or four bars with a single gap, three of them coloured. Two separate pairs of the same colour is the violation this rule exists to forbid — so the palette is a budget, and the composition can only be as tall as eight colours will carry.
A colour may not sit on its own colour for more than 20% of the bar width. Measured as the overlap between a colour's horizontal extent in one bar and its extent in the next, it forces colours to cross the composition as they descend rather than pooling into blocks.
The page colour never appears inside the composition. It is admitted in the final bar only, closing it, which is how the composition ends without needing a termination rule. Being the ground, it is exempt from the vertical budget — it continues below the artwork indefinitely.
Eight colours plus the ground, and nothing else: 3D314A 54A39E 604DA1 A2AA9D B88969 E06D3B E8859A F1B521, on F1EAE6. Every one of them appears in every composition — see C6. Colours are never generated, tinted or mixed.
The vertical rule is not decoration and not independent. It is the column where the deepest boundary terminates, extended through the full canvas — so it is set by the geometry, never chosen. Drag it and the relation runs the other way: the boundary it holds travels with it, anything that boundary runs into joins the move once it catches up, and where a rigid move is impossible the chain re-routes around the wall. Every column it stops at is a legal composition; where it will not go, there is nothing legal to go to.
All eight colours and the ground are present in every composition — none sits out. With C1 capping each colour at three bars and C8 capping each bar at three colours, this closes the system from both ends: the palette must fit the height, and the height must fit the palette.
No outline, gradient, transparency, shadow or texture. Neighbouring fields in a bar never share a colour — a boundary that would vanish is a boundary that should not have been drawn.
At most three distinct colours per bar, the ground included where it appears. A four-slot bar therefore always carries one colour twice, separated by another — which makes a repeat read as rhythm rather than as an accident.
Everything above is built from these. Both are the same cubic with displacement b = ±1 and control handles at k = 0.5523h; the tangent state decides which end is vertical. b = 0 would be an exact straight cut and is exactly what B1 forbids, which is why the primitive is one parameter wide and animation is a slide along it.
Geometry first: boundaries walk down the lattice, one forced turn per bar, the primary one carrying the full height and the rest resting between runs. Colour is then a constraint problem, not a random draw — C1 and C2 are strict enough that a greedy assignment fails, so bars are filled by backtracking search with the colour budget carried forward as state. An independent checker re-verifies the finished composition against all twelve invariants; the search only prunes, the checker decides.
If a setting has no legal composition, the status line says so rather than showing you a quiet violation.
Animation moves through the state space, never through coordinates. Each beat offers one legal mutation — slide a boundary a column, exchange two colours, or flip a pair of turns so a capsule becomes an S-curve — re-checks it against every invariant, and discards it if it fails. Beats alternate between families — the family is drawn fresh each beat, but never more than three changes to the grid in a row, nor more than two colour changes — so the poster is never recolouring while nothing moves. Turns flip in pairs so the run’s foot stays put; a single flip would shift everything below it. Secondary reach has no move: changing a boundary’s length changes how many fields its bars hold, and colour is solved against that structure, so it cannot be stepped to a neighbour — only regenerated. A boundary runs the height of the composition, so sliding one redraws every bar it crosses at once; that is one move, not many. Dragging the anchor works the same way, one column per step, which is why it sometimes resists: it is refusing to enter an illegal state rather than being clamped to a range.
The whole composition is roughly 30 painted paths. SVG keeps it resolution-independent, inspectable and directly exportable as artwork, and re-rendering from the model each frame costs nothing at this node count. Canvas or WebGL would only pay off with hundreds of bars or per-pixel effects, neither of which this grammar has.