feat(web): make brand colors skin-overridable (BUNYIP-500) #501

Merged
nrupard merged 2 commits from feat/BUNYIP-500-theming into main 2026-08-07 19:55:37 +02:00
Owner

B2 of the BUNYIP-459 theme-agnostic-web-kit epic.

What

Make bunyip-web's brand colors theme-agnostic: the reed/water ramps become brand-neutral tokens backed by CSS custom properties a skin can override, defaulting to bunyip's palette.

Changes

  • Renamed the Tailwind tokens bunyip-reed -> brand-primary and bunyip-water -> brand-accent in input.css (the @theme ramps and the @layer base references) and the 28 class usages across handlers/ and views/.
  • The brand ramp @theme values now read var(--skin-<name>, <default hex>) instead of a baked hex, so a skin recolors the UI by setting --skin-* on :root; unset falls back to the current hex.
  • Config.theme_css (BRAND_THEME_CSS, optional) supplies a skin's --skin-* declarations; document() emits them inside a :root { ... } <style> block, installed via a views::layout OnceLock (the same install-once pattern as B1's app name). CSP already allows style-src 'unsafe-inline', and the value is deploy config (trusted).
  • Regenerated the committed assets/styles.css.

Byte-identical by default

BRAND_THEME_CSS unset -> no <style> block -> every var(--skin-*, #hex) resolves to the original hex, so the rendered palette is unchanged. The Tailwind class names change (bunyip-reed-* -> brand-primary-*) but the colors are identical, and the bunyip-web tests pass unchanged.

Sibling of B1

Branches off main independently of B1 (PR #500). Both add a Config field, a layout OnceLock, a main install, and edit the document() head, so expect a trivial additive conflict when the second of the two merges.

Scope

B2 only (theme colors). Skin-content de-brand (B3 / BUNYIP-501), the web-kit crate (B4 / BUNYIP-502), and CSP config (B5 / BUNYIP-503) remain separate. The meta description and other marketing copy still name Bunyip; that is B3.

Validation

bun run build:css regenerates assets/styles.css; cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, and cargo test -p bunyip-web are green.

B2 of the BUNYIP-459 theme-agnostic-web-kit epic. ## What Make bunyip-web's brand colors theme-agnostic: the reed/water ramps become brand-neutral tokens backed by CSS custom properties a skin can override, defaulting to bunyip's palette. ## Changes - Renamed the Tailwind tokens `bunyip-reed` -> `brand-primary` and `bunyip-water` -> `brand-accent` in `input.css` (the `@theme` ramps and the `@layer base` references) and the 28 class usages across `handlers/` and `views/`. - The brand ramp `@theme` values now read `var(--skin-<name>, <default hex>)` instead of a baked hex, so a skin recolors the UI by setting `--skin-*` on `:root`; unset falls back to the current hex. - `Config.theme_css` (`BRAND_THEME_CSS`, optional) supplies a skin's `--skin-*` declarations; `document()` emits them inside a `:root { ... }` `<style>` block, installed via a `views::layout` `OnceLock` (the same install-once pattern as B1's app name). CSP already allows `style-src 'unsafe-inline'`, and the value is deploy config (trusted). - Regenerated the committed `assets/styles.css`. ## Byte-identical by default `BRAND_THEME_CSS` unset -> no `<style>` block -> every `var(--skin-*, #hex)` resolves to the original hex, so the rendered palette is unchanged. The Tailwind class names change (`bunyip-reed-*` -> `brand-primary-*`) but the colors are identical, and the `bunyip-web` tests pass unchanged. ## Sibling of B1 Branches off `main` independently of B1 (PR #500). Both add a `Config` field, a `layout` `OnceLock`, a `main` install, and edit the `document()` head, so expect a trivial additive conflict when the second of the two merges. ## Scope B2 only (theme colors). Skin-content de-brand (B3 / BUNYIP-501), the web-kit crate (B4 / BUNYIP-502), and CSP config (B5 / BUNYIP-503) remain separate. The `meta description` and other marketing copy still name Bunyip; that is B3. ## Validation `bun run build:css` regenerates `assets/styles.css`; `cargo fmt --all --check`, `cargo clippy --workspace --all-targets -- -D warnings`, and `cargo test -p bunyip-web` are green.
feat(web): make brand colors skin-overridable
Some checks failed
E2E / PR gate (pull_request) Successful in 31s
Check / fmt + clippy + build + tests (pull_request) Has been cancelled
fe2ec5e38d
B2 of the theme-agnostic web-kit epic. bunyip-web's brand palette is now theme-agnostic: the reed/water ramps are brand-neutral tokens backed by CSS custom properties a skin can override, defaulting to bunyip's colors.

Renamed the Tailwind tokens bunyip-reed -> brand-primary and bunyip-water -> brand-accent in input.css (the @theme ramps and @layer base references) and the 28 class usages across handlers/ and views/. The brand @theme values now read var(--skin-<name>, <default hex>) instead of a baked hex, so a skin recolors the UI by setting --skin-* on :root. Config.theme_css (BRAND_THEME_CSS, optional) supplies those declarations; document() emits them in a :root {} <style> block, installed via a views::layout OnceLock (the B1 pattern). CSP already allows style-src 'unsafe-inline', and the value is deploy config.

With BRAND_THEME_CSS unset every var(--skin-*, #hex) resolves to the original hex, so the rendered palette is byte-identical (only the Tailwind class names change); the regenerated assets/styles.css keeps the same colors and the 211 bunyip-web tests pass. Sibling of B1 (PR #500): both touch Config, a layout OnceLock, the main installs, and document()'s head, so expect a trivial additive conflict when the second merges.

#BUNYIP-500

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard scheduled this pull request to auto merge when all checks succeed 2026-08-07 19:39:27 +02:00
nrupard canceled auto merging this pull request when all checks succeed 2026-08-07 19:39:54 +02:00
Merge main into feat/BUNYIP-500-theming
All checks were successful
E2E / PR gate (pull_request) Successful in 27s
Check / fmt + clippy + build + tests (pull_request) Successful in 9m2s
Create release / Create release from merged PR (pull_request) Has been skipped
b384a060f9
B1 (BUNYIP-499, app name from config) merged to main. B2 branched off main before it, so the two siblings conflict in the files both extend with the same OnceLock/config pattern: config.rs (app_name + theme_css fields), main.rs (both installs), views/layout.rs (both OnceLock blocks; the brand-mark span, where B2's brand-primary token rename meets B1's app_name() accessor), the three test Config constructors, and .env.example. All additive: kept both sides, merged the brand span to `text-brand-primary-* { (app_name()) }`. fmt + clippy (-D warnings) and the 211 bunyip-web tests green.

#BUNYIP-500
nrupard scheduled this pull request to auto merge when all checks succeed 2026-08-07 19:53:05 +02:00
nrupard deleted branch feat/BUNYIP-500-theming 2026-08-07 19:55:37 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!501
No description provided.