Add ARIA role=img with descriptive labels to world-map SVG and
donut-chart SVG. Include a screen-reader-only data table in world-map
for country/count pairs.
Add role=combobox, aria-expanded, aria-controls, and role=listbox/option
attributes. Support arrow key navigation, Enter to select, and Escape
to dismiss. Add aria-label to clear button.
- Add --highlight-rgb CSS custom property for light and dark themes
- Add MutationObserver to world-map for theme change detection
- Read choropleth colors from CSS custom properties instead of hardcoded values
- Simplify stats_map partial to use text-highlight class
Extract <chip-scroll> custom element into its own file and wrap
Recent Brews and Open Bags horizontal scrollers with desktop-only
chevron navigation that half-overlaps the card edges.
- New /stats page with Roasters, Roasts, Cups, and Cafes tabs
- Interactive choropleth world map (SVG) colored by country counts
- Clickable country chips that highlight individual countries on the map
- Horizontal chip scroller with chevron navigation on desktop
- Datastar-powered tab switching without page reload
- Domain layer: country name → ISO code mapping, flag emoji generation
- StatsRepository trait with four aggregate SQL queries
- <world-map> and <chip-scroll> custom elements for Datastar compatibility
- Split equipment into separate Grinder and Brewer collapsible sections
with summary bars showing current selection
- Make all summary bars, matched-entity cards, and searchable-select
selected values clickable anywhere to change (not just the X/Change button)
- Fix stepper buttons broken after manual input by switching from
data-attr:value to data-bind with Number() coercion
- Merge Water + Brew Time into single Recipe section
- Make all add/confirm buttons full-width
- Add sticky submit button on mobile
- Fix missing closing > on cafe indicator div
- Fix broken Askama syntax on checkin page from formatter
Native change events from child inputs were bubbling up and reaching
data-on:change handlers, which expect only the CustomEvent with
evt.detail. Capture and stop native change events so only the
component's own CustomEvent propagates.
- Add initial-value attribute to searchable-select web component
- Update bag card Brew link to pass bag_id query parameter to add page
- Thread bag_id through route handler and template to pre-select the bag
Replace ~268 hardcoded text-stone-* classes with theme-aware token
utilities (text-text, text-text-secondary, text-text-muted) across all
templates and JS components. Adjust dark mode token values to meet
WCAG AA contrast ratios on dark surfaces.
Move CSS, JS, favicon files to static/ directory to separate
compiled-in assets from Askama templates. Update all include paths,
build.rs, flake.nix, and Tailwind @source directives.