Acceptance Spec — Pro Website Color Schemes (Option B)
Status: Implemented 2026-05-30 · Feature: customer-selectable Pro Website colors
Code: churchwiseai-web/src/lib/website-color-themes.ts, src/components/templates/UnifiedTemplate.tsx, src/app/admin/[token]/components/WebsiteEditor/ColorsEditor.tsx
Migration: churchwiseai-web/migrations/2026-05-30-pro-website-color-theme.sql
Origin: Kevin Soodsma (Beckwith Hills CRC) asked to match his church's brand color (teal #507ea4); the site rendered navy because CRC/Reformed falls through to the protestant default.
What the customer can do
In the admin Website editor → Design → Colors, a Pro Website customer can:
- Pick a color theme from a curated set of 8 —
navy,gold(Sacred Gold),terracotta,teal,burgundy,forest,slate,plum— or Automatic (follows their denomination, the prior default). - Optionally set a custom brand accent hex (
#RRGGBB) applied to buttons, links, icons, and the chat widget. Section backgrounds/tints follow the chosen theme.
Saves are draft-aware (write to draft_* columns); changes go live only on Publish. The live ?draft= preview reflects edits before publishing.
Data model
premium_churches columns (+ draft_* twins, registered in DRAFT_TO_CANONICAL):
website_color_theme TEXT— CHECK in the curated set, or NULL = denomination default.website_accent_hex TEXT— CHECK^#[0-9A-Fa-f]{6}$, or NULL = theme default.
Expected output
| # | Input state | Expected render at /s/[slug] |
|---|---|---|
| 1 | No theme, no accent (every existing church) | Byte-identical to before this feature. protestant→navy, liturgical→gold, community→terracotta. Verified by website-color-themes.test.ts against getStyleByDenomination. |
| 2 | Theme = teal, no accent | All section accents (eyebrow labels, cards, gradient bars, staff, ministries, events, map), CTAs, and chat widget render teal (#0E7C86). |
| 3 | Theme = teal, accent = #507EA4 | Section class styling stays teal; buttons, links, icons, staff accent, map pin, contact form, giving button, and the chat widget render exactly #507EA4. A subtle accent bar under the hero uses #507EA4. |
| 4 | No theme, accent = #507EA4 | Denomination theme for class styling; brand hex #507EA4 on all inline accents + chat widget + the subtle hero accent bar (protestant-family only). |
| 5 | Invalid theme or hex submitted | API returns 400 ("Invalid color theme." / "Accent color must be a 6-digit hex code…"); DB CHECK constraints reject out-of-set values as defense-in-depth. |
| 6 | Theme cleared back to Automatic | Reverts to denomination default; website_color_theme set NULL on Publish. |
Lane split (why custom hex ≠ everything)
- Brand accent (the hex) drives every element that already consumes
style.accentHexinline: nav, what-to-expect icons, giving button, contact form, chat widget, staff accent, block buttons, map pin, and (protestant-family) the hero accent bar. - Theme class bundle drives Tailwind-class parts that can't be derived from one hex: eyebrow label color, card tints, gradient bars, dark-section backgrounds, page background. The customer picks the theme closest to their brand; the exact hex fine-tunes the interactive accents.
Known limitations (v1)
- Eyebrow label text + gradient bars follow the theme, not the exact custom hex (kept on theme-controlled shades for guaranteed contrast on white/dark). Picking the matching theme keeps this coherent.
- Extra pages (
/s/[slug]/[page], multi-page feature) still render with the denomination/default accent viaSimplePageTemplate— home-page theming is v1 scope. Follow-up: thread the resolved accent intoSimplePageTemplate. Adoption of extra pages is near-zero today.
Verification (evidence-or-nothing)
- Unit:
src/lib/__tests__/website-color-themes.test.ts— 18 tests, incl. byte-identical fallback (pass 2026-05-30). - Playwright (deployed URL, not localhost/preview-host for host-aliased checks): in admin pick
teal+#507EA4on a demo church → assert?draft=preview recolors → Publish → load live/s/[slug]→ assert a CTA/chat-widget computed color ==#507EA4and navy default is gone. Artifact for thecwa-pro-website-ssrcritical-path gate. pnpm exec tsc --noEmitclean;pnpm buildgreen.
Critical-path note
Touches critical_path: true registry entries cwa-pro-website-ssr (src/app/s/[slug]/page.tsx) and cwa-pro-website-edit. Both already describe "custom color scheme applied" / "change … color scheme." PR needs the cwa-pro-website-ssr Playwright artifact or a critical-path-override label + reason.