- Sticky labels: each bar's title slides down inside its rect under
the sticky timeline so it stays visible while any part of the rect
is in view, then slides off when the rect's bottom passes.
- Auto-wrap long bar names into multiple <tspan> lines so labels
no longer overrun their box.
- Drop browser-native <title> tooltips; the custom tooltip remains.
- Demote depth-1 nameSize to depth-2 size when a bar shows its name
but not its euro amount, so it doesn't outshout column-2 titles.
- Collapse the depth-4 column when the zoomed-in scope has no
Breakdown items; surviving columns expand to fill the canvas.
- Tighter year-budget centering, runtime gap (GAP_Y) instead of
d3 partition padding, gutter masks for year-frame strokes.
- Two-hue OKLCH palette tuned so all labels can stay a single colour
per flow (light on Aufwendungen, dark on Erträge).
- Sidebar: clickable Aufw/Ertr/Saldo to swap flow; Beschreibung +
collapsed Erläuterungen extracted from PG sections.
- Sticky timeline axis with active-year tick in the active flow's
colour; URL state sync for path/year/flow.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Editorial single-page viewer for the City of Münster's 2026/2027
budget draft, built as an Astro v6 SPA with a 4-level zoomable
icicle (Produktbereich → Produktgruppe → Category → Breakdown).
Highlights:
- Multi-flow data layer over the official open-data CSVs
(Aufwendungen + Erträge, 2008–2028) with overlap reconciliation
across plan years.
- Year slider as a 21-year mini-histogram of both flows;
drag-to-scrub and click-to-jump, with bars morphing via CSS
transitions on SVG geometry attributes.
- Vertically centred icicle with year-outline rectangles framing
each year's relative budget size, à la Bostock's animated treemap.
- Headline "ausgibt / einnimmt" toggle; sidebar Aufwendungen/Erträge
rows double as flow toggles. Active flow in Aufwendungen-purple /
Erträge-orange (OKLCH).
- Click-to-zoom via path-keyed lookup with ZOOM_COL_BOUNDS that
reallocate the depth axis per zoom state. Zoomed item moves to the
sidebar; canvas shows its descendants only (no adjacent-block leaks).
- Sidebar shows path-specific Aufwendungen/Erträge/Saldo plus the
source-PDF Beschreibung; Erläuterungen behind a collapsed details.
- Build-time PDF extraction (scripts/extract-pg-sections.mjs) parses
68 Produktgruppen' Beschreibung + Erläuterungen sections from
Band 1, including 10 cells of structured Mio.-€ breakdowns
(Steuern, Transferaufwendungen, etc.) that drive the level-4 view.
- URL state sync for path, year, and flow via history.replaceState
so any zoom is shareable.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>