How it works
Effects
The third seam. A template decides where the cards go, a track decides how they composite, and an effect filters the result — an ordered stack over the rendered scene rather than something applied per card.
Being straight about the state of it: 12 effects ship today — Grain, Vignette, Blur, Bloom, Tilt-shift, Liquid Glass, Halftone, Posterize, Scanlines, Pixelate, RGB Split, Wave. The panel and the contract are finished; the library behind them is not. That is deliberate rather than abandoned: the pattern was proven with one effect before filling a menu with them.
A stack, in order
Effects apply in the order you add them, over the whole frame. Order matters the way it does in any filter chain — pixelate then blur is a soft mosaic, blur then pixelate is mush.
Same self-declaring pattern as a template
An effect declares an id, a name, its own controls from the same nine-type vocabulary, and one function that builds the filter from those values. That is the whole file:
export const pixelate: Effect = {
meta: { id: 'pixelate', name: 'Pixelate' },
controls: [
{ key: 'size', label: 'Pixel Size', type: 'slider',
min: 1, max: 64, step: 1, default: 8 },
],
createFilter: (v) => new PixelateFilter(v.size ?? 8),
};Register it in effects/index.ts and the panel row, its controls and its defaults all follow — the same deal templates get, for the same reason.
Where they run
The stack is a 2D backend feature: it filters the rendered frame, so it applies to the Library scene. The 3D sections have their own stylised passes, which live with the scene rather than in this stack.