🌈 v0.23.3 — Theme Color Resolver & Wizard Polish
This release adds a way to read Midwest's theme colors from Ruby — Midwest::Theme (and three matching view helpers) resolve a named theme or a custom hex value to a real color for the places a CSS class can't reach. It also polishes carousels and wizards embedded in narrow cards, makes the live form summary responsive, opens up the color picker's gray swatch, and fixes a dropdown indicator bug. No breaking API changes.
What's New
Midwest::Theme — resolve a color to a real value
A stored color (an account's theme_color, an event's color) is often a named theme like "green" or a hex string like "#1c7ed6". Feeding a name to a hex parser silently produces garbage, so Midwest::Theme resolves either form to a real value. Named themes are parsed straight from color-system.css — the same literals the .theme-* classes render, so the Ruby values can never drift — and custom hex colors resolve through ColorScale. Every accessor takes a shade (0 = lightest … 12 = darkest, default 6) and returns nil when the value can't be resolved, leaving the fallback to the caller.
Midwest::Theme.hex("green") # => "#16a34a"Midwest::Theme.rgb("green") # => "rgb(22, 163, 74)"Midwest::Theme.channels("green") # => "22 163 74" (drop into a --*-channels var)Midwest::Theme.hex("green", 8) # => a darker shadeMidwest::Theme.hex("#1c7ed6") # => custom hex, via ColorScaleMidwest::Theme.hex("nope") # => nilMidwest::Theme.named?("green") # => trueMidwest::Theme.names # => ["gray", "red", ..., "pink"]The same three accessors are exposed on Midwest::ViewHelper for the cases a CSS class can't reach — a <meta name="theme-color"> tag, an inline SVG fill, a chart color, or an HTML email:
<%= tag.meta(name: "theme-color", content: midwest_theme_hex(current_account.theme_color)) %><div style="--accent-channels: <%= midwest_theme_channels(current_account.theme_color) %>">…</div>Prefer a CSS class (midwest_theme_class, or a theme-{color} utility) whenever one will do — a class keeps opacity modifiers (bg-theme-6/50) and dark-mode inheritance. Reach for Midwest::Theme only when you need the literal value. See the extended Custom Color System guide for details.
What Changed
Form::ColorPickerComponent — gray is now selectable
The picker previously dropped gray from its swatches. It now offers the full theme set, so gray is available as a color choice like every other theme.
CarouselComponent — container-query aware, wizard-in-card friendly
The carousel now establishes a container-name: midwest-carousel query container, so slides can respond to the carousel's own width rather than the viewport. On narrow carousels (under 700px — e.g. a wizard embedded in a small card column) slides automatically drop their arrow-clearance padding. New MCP guidance documents how to run wizard-mode step forms and how to keep a carousel from overflowing a narrow card (min-width: 0 + overflow-x: clip on the collapsing container).
Form::LiveSummaryComponent — responsive at narrow widths
The live summary is now its own query container. Under 450px it collapses its list to a single column with tighter spacing, so it reads cleanly inside a wizard's final review slide or any small card.
DropdownComponent — indicator no longer flips on sibling dropdowns
Fixed a bug where the open-indicator rotation used a general sibling selector (~), which also matched the toggle buttons of following sibling dropdowns and flipped their indicators into the open state. It now uses an adjacent sibling selector (+), scoping the indicator to its own dropdown.
What Was Removed
Nothing was removed in this release. All changes are additive or behavior-preserving.
Dev Process
- MCP guidance —
component_guidance.ymlgains carousel anti-patterns (overflow in narrow cards) and a wizard-mode best practice with a full step-form example, surfaced through the MCP guidance tools. - Docs — the Custom Color System guide documents
Midwest::Themeand the newmidwest_theme_hex/midwest_theme_rgb/midwest_theme_channelshelpers. - Tests — new
Midwest::Themetest suite, addedViewHelpercoverage for the three color helpers, and an updatedColorPickerComponenttest for the full swatch set.