From a550b06a586d73064dc48698bb95f30b2694f418 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sun, 12 Jul 2026 14:43:43 +0200 Subject: [PATCH] docs: plan EpicNext multitheme implementation --- .../plans/2026-07-12-epicnext-multitheme.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs/superpowers/plans/2026-07-12-epicnext-multitheme.md diff --git a/docs/superpowers/plans/2026-07-12-epicnext-multitheme.md b/docs/superpowers/plans/2026-07-12-epicnext-multitheme.md new file mode 100644 index 00000000..af3cd9e0 --- /dev/null +++ b/docs/superpowers/plans/2026-07-12-epicnext-multitheme.md @@ -0,0 +1,87 @@ +# EpicNext Multitheme Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Give every EpicNext preset complete, coherent light and dark palettes while retaining the visitor mode toggle and rebranding the CMS information popup. + +**Architecture:** A canonical theme-key contract defines every persisted/runtime color. Presets provide complete `light` and `dark` palettes; `ThemeVars` emits both scopes and the existing toggle only selects a scope. Admin preset application persists both variants atomically and legacy unqualified settings remain the light-mode compatibility source. + +**Tech Stack:** Next.js 16, React 19, TypeScript, CSS custom properties, Prisma website settings, Vitest. + +## Global Constraints + +- Work directly in `E:\Users\simol\Desktop\EpicNext-cms`; do not create a worktree. +- Preserve the existing uncommitted `package.json` change and never stage it. +- Keep `localStorage.theme` limited to `light` or `dark`. +- Every built-in preset must define every canonical color key in both modes. +- Build, typecheck, and the complete test suite must pass before publication. + +--- + +### Task 1: Canonical complete preset model + +**Files:** +- Modify: `src/lib/theme-presets.ts` +- Modify: `src/lib/theme-contrast.test.ts` + +**Interfaces:** +- Produces: `ThemeMode`, `ThemeColorKey`, `ThemePalette`, `ThemePreset`, `THEME_COLOR_KEYS`, and `PRESETS` with `{ light, dark }` variants. +- Consumes: existing color names used by `ThemeVars` and the admin editor. + +- [ ] Add failing tests that iterate every preset/mode and require exact coverage of `THEME_COLOR_KEYS`, then run `pnpm vitest run src/lib/theme-contrast.test.ts` and confirm missing dark variants fail. +- [ ] Define the canonical keys and typed palette/preset interfaces, convert every preset to complete light/dark variants, and include buttons, links, borders, and gradients. +- [ ] Update contrast tests to evaluate both variants and run the targeted test to green. +- [ ] Commit only `src/lib/theme-presets.ts` and `src/lib/theme-contrast.test.ts` with `feat: add complete light and dark presets`. + +### Task 2: Runtime light/dark variables + +**Files:** +- Modify: `src/components/theme-vars.tsx` +- Modify: `src/app/globals.css` +- Create: `src/components/theme-vars.test.tsx` + +**Interfaces:** +- Consumes: complete `ThemePreset` and mode-qualified website settings. +- Produces: one server-generated style containing `:root{...}` and `html.dark{...}` variables. + +- [ ] Add a failing render test that requires separate light/dark variable blocks and different preset-specific background values. +- [ ] Extract palette loading and CSS generation into testable helpers in `theme-vars.tsx`; read legacy keys for light fallback and `_dark` for dark overrides. +- [ ] Remove hardcoded color declarations from `html.dark` while retaining input/table behavioral selectors. +- [ ] Run the new test and existing contrast suite to green. +- [ ] Commit the three files with `feat: generate theme-aware light and dark variables`. + +### Task 3: Complete admin persistence + +**Files:** +- Modify: `src/actions/admin-theme.ts` +- Modify: `src/app/admin/theme/page.tsx` +- Create: `src/lib/theme-settings.ts` +- Create: `src/lib/theme-settings.test.ts` + +**Interfaces:** +- Produces: `settingKey(key: ThemeColorKey, mode: ThemeMode): string` and `presetSettings(preset: ThemePreset): Array<[string, string]>`. +- Consumes: canonical preset model from Task 1. + +- [ ] Add failing tests proving `presetSettings` returns every light key plus every `_dark` key with no duplicates. +- [ ] Implement pure setting mapping helpers and use them in `applyPreset` so a preset writes the full pair. +- [ ] Render light and dark color sections in the admin form and update `saveTheme` to persist both sets. +- [ ] Preserve legacy unqualified light keys and use `_dark` suffixes only for dark values. +- [ ] Run mapping, theme, action-contract, typecheck, and relevant UI tests. +- [ ] Commit the four files with `feat: persist complete multitheme palettes`. + +### Task 4: EpicNext popup and final verification + +**Files:** +- Modify: `src/components/cms-info-popup.tsx` +- Modify: `src/components/cms-info-popup.test.tsx` + +**Interfaces:** +- Consumes: semantic runtime CSS variables. +- Produces: EpicNext-branded footer trigger and modal copy. + +- [ ] Change the popup test first to require `EpicNext Info`, `EpicNext`, and `Modern Next.js CMS`; run it and confirm it fails on AtomCMS copy. +- [ ] Replace AtomCMS branding and credits without introducing literal theme colors. +- [ ] Run popup and theme tests, then `pnpm typecheck`, `pnpm test`, and `pnpm build`. +- [ ] Inspect `git diff --check` and confirm `package.json` remains unstaged and unchanged by this implementation. +- [ ] Commit popup files with `feat: rebrand CMS information as EpicNext`. +- [ ] Push the completed commits to `origin/main` only after all verification succeeds.