From c46cd0695498e4524fed24afc21f465cf3d9543d Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 18 May 2026 03:44:07 -0600 Subject: [PATCH] update --- .../plans/2026-05-18-animal-crossing-theme.md | 485 ++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-18-animal-crossing-theme.md diff --git a/docs/superpowers/plans/2026-05-18-animal-crossing-theme.md b/docs/superpowers/plans/2026-05-18-animal-crossing-theme.md new file mode 100644 index 0000000..1cdefad --- /dev/null +++ b/docs/superpowers/plans/2026-05-18-animal-crossing-theme.md @@ -0,0 +1,485 @@ +# Animal Crossing Theme 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:** Add an "animal-crossing" design theme (warm cream light / deep forest dark) to the hyyzhome IoT portal. + +**Architecture:** Four small, independent file edits. No new files created. The theme slug is registered in `theme.js`, a dropdown option added in `index.html`, CSS variables + component overrides added in `style.css`, and display labels added in `i18n.js`. Changes are order-independent but committing theme.js + index.html first lets you visually verify the option appears before styling is complete. + +**Tech Stack:** Vanilla JS, Vite, CSS custom properties. No framework. No test suite — verification is manual in the dev server (`npm start`). + +--- + +## Files Modified + +| File | Change | +|---|---| +| `theme.js:1` | Add `"animal-crossing"` to `DESIGN_THEMES` array | +| `index.html:45` | Add `
  • ` after the Nord option | +| `i18n.js:136–213` | Add `"animal-crossing"` key to every language in `DESIGN_THEME_LABELS` | +| `style.css` | Append light + dark variable blocks and component overrides at end of file | + +--- + +## Task 1: Register the theme slug + +**Files:** +- Modify: `theme.js:1` +- Modify: `index.html:45` + +- [ ] **Step 1: Add slug to DESIGN_THEMES** + +In `theme.js`, change line 1 from: +```js +const DESIGN_THEMES = ["fluent", "material-you", "terminal", "cyberpunk", "nord"] +``` +to: +```js +const DESIGN_THEMES = ["fluent", "material-you", "terminal", "cyberpunk", "nord", "animal-crossing"] +``` + +- [ ] **Step 2: Add dropdown option in index.html** + +In `index.html`, after the Nord `
  • ` (currently line 45): +```html +
  • + Nord +
  • +``` +add immediately after: +```html +
  • + 动森 +
  • +``` + +- [ ] **Step 3: Start dev server and verify option appears** + +```bash +npm start +``` + +Open the app in a browser. Click the design theme dropdown — "动森" should appear as a new option. Selecting it will show unstyled (inherits Fluent variables) — that's expected at this stage. + +- [ ] **Step 4: Commit** + +```bash +git add theme.js index.html +git commit -m "feat: register animal-crossing theme slug" +``` + +--- + +## Task 2: Add i18n labels + +**Files:** +- Modify: `i18n.js:136–213` + +- [ ] **Step 1: Add label to every language in DESIGN_THEME_LABELS** + +In `i18n.js`, add `"animal-crossing"` to each language object inside `DESIGN_THEME_LABELS`. The full updated constant (lines 136–214) should be: + +```js +export const DESIGN_THEME_LABELS = { + "zh-Hans": { + fluent: "Fluent", + "material-you": "Material You", + terminal: "终端", + cyberpunk: "赛博朋克", + nord: "Nord", + "animal-crossing": "动森", + }, + "zh-Hant": { + fluent: "Fluent", + "material-you": "Material You", + terminal: "終端", + cyberpunk: "賽博龐克", + nord: "Nord", + "animal-crossing": "動森", + }, + en: { + fluent: "Fluent", + "material-you": "Material You", + terminal: "Terminal", + cyberpunk: "Cyberpunk", + nord: "Nord", + "animal-crossing": "Animal Crossing", + }, + ja: { + fluent: "Fluent", + "material-you": "Material You", + terminal: "ターミナル", + cyberpunk: "サイバーパンク", + nord: "Nord", + "animal-crossing": "どうぶつの森", + }, + ko: { + fluent: "Fluent", + "material-you": "Material You", + terminal: "터미널", + cyberpunk: "사이버펑크", + nord: "Nord", + "animal-crossing": "동물의 숲", + }, + wenyan: { + fluent: "流光", + "material-you": "物材", + terminal: "终端", + cyberpunk: "赛博", + nord: "清寒", + "animal-crossing": "森友", + }, + mars: { + fluent: "流↗光", + "material-you": "材↘質", + terminal: "終↗★端", + cyberpunk: "賽↘!博", + nord: "清↗寒★", + "animal-crossing": "动↗森★", + }, + garbled: { + fluent: "◼è▦", + "material-you": "拷▤屯ä锟◽", + terminal: "¥¬▤▨¿¿", + cyberpunk: "◼çæ¥烫¥", + nord: "æ◽屯¿", + "animal-crossing": "ä◼▤è", + }, + bin: { + fluent: "0101", + "material-you": "010101", + terminal: "01010101", + cyberpunk: "0101010101", + nord: "0101010", + "animal-crossing": "01010101", + }, + meow: { + fluent: "喵喵", + "material-you": "喵喵喵", + terminal: "喵喵", + cyberpunk: "喵喵喵喵", + nord: "喵喵喵", + "animal-crossing": "喵喵喵喵", + }, + emoji: { + fluent: "💧", + "material-you": "🧱", + terminal: "⌨️", + cyberpunk: "⚡", + nord: "❄️", + "animal-crossing": "🌿", + }, +} +``` + +- [ ] **Step 2: Verify labels in browser** + +With the dev server still running, switch language to English — the dropdown option should now read "Animal Crossing" instead of "动森". Switch to Japanese — should read "どうぶつの森". Switch to emoji — should read "🌿". + +- [ ] **Step 3: Commit** + +```bash +git add i18n.js +git commit -m "feat: add animal-crossing labels for all 11 languages" +``` + +--- + +## Task 3: Add CSS — light mode + +**Files:** +- Modify: `style.css` (append after the Nord section, before the `@media (max-width: 600px)` block) + +- [ ] **Step 1: Append light-mode CSS block** + +At the end of the Nord section in `style.css` (before the `@media (max-width: 600px)` rule), append: + +```css +/* ─── Animal Crossing — Sunny Meadow ───────────────────────── */ +html[data-design-theme="animal-crossing"] { + color-scheme: light; + + --accent: #6dbc7e; + --accent-rgb: 109, 188, 126; + --accent-2: #5aad6d; + --accent-3: #4a9e5d; + --accent-secondary-rgb: 244, 200, 66; + + --page-gradient: linear-gradient( + 135deg, + #fdf6e3 0%, + #f5f0d8 25%, + #fdf6e3 50%, + #f8f2e0 75%, + #fdf6e3 100% + ); + --page-texture: + radial-gradient( + circle at 20% 50%, + rgba(109, 188, 126, 0.08) 0%, + transparent 50% + ), + radial-gradient( + circle at 80% 80%, + rgba(244, 200, 66, 0.06) 0%, + transparent 50% + ); + --title-gradient: linear-gradient( + 135deg, + #6dbc7e 0%, + #5aad6d 40%, + #f4c842 100% + ); + + --control-bg: rgba(255, 252, 240, 0.82); + --control-border: rgba(109, 188, 126, 0.35); + --control-inset: rgba(255, 255, 255, 0.85); + --control-fg: #5c4824; +} + +html[data-design-theme="animal-crossing"] body { + color: #5c4824; +} + +html[data-design-theme="animal-crossing"] .design-theme-button, +html[data-design-theme="animal-crossing"] .theme-toggle { + border-radius: 14px; +} + +html[data-design-theme="animal-crossing"] .card { + background: rgba(255, 252, 240, 0.85); + border: 1px solid rgba(109, 188, 126, 0.25); + border-radius: 16px; + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.06), + 0 1px 2px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.9); +} + +html[data-design-theme="animal-crossing"] .card::before { + display: none; +} + +html[data-design-theme="animal-crossing"] .card.pin { + background: rgba(245, 242, 228, 0.88); +} + +html[data-design-theme="animal-crossing"] .card h2 { + color: #5c4824; +} + +html[data-design-theme="animal-crossing"] .card p { + color: #7a6040; +} + +html[data-design-theme="animal-crossing"] .card:hover, +html[data-design-theme="animal-crossing"] .card:focus { + color: var(--accent); + transform: translateY(-2px); + border-color: rgba(109, 188, 126, 0.45); + box-shadow: + 0 8px 24px rgba(109, 188, 126, 0.2), + 0 4px 8px rgba(0, 0, 0, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.95); +} + +html[data-design-theme="animal-crossing"] .card:hover h2, +html[data-design-theme="animal-crossing"] .card:focus h2 { + color: var(--accent); +} + +html[data-design-theme="animal-crossing"] .card:hover p, +html[data-design-theme="animal-crossing"] .card:focus p { + color: #5c4824; +} + +html[data-design-theme="animal-crossing"] .beian a { + color: #7a6040; +} + +html[data-design-theme="animal-crossing"] .beian a:hover { + color: var(--accent); +} +``` + +- [ ] **Step 2: Verify light mode in browser** + +Select "Animal Crossing" / "动森" in the dropdown with light mode active. Verify: +- Background is warm cream (not white/dark) +- Title has green-to-yellow gradient +- Cards are creamy with rounded corners (16px) +- Card hover shows green glow and lifts up +- Control buttons have 14px border radius + +- [ ] **Step 3: Commit** + +```bash +git add style.css +git commit -m "feat: add animal-crossing light mode CSS" +``` + +--- + +## Task 4: Add CSS — dark mode + +**Files:** +- Modify: `style.css` (append immediately after the light-mode block from Task 3) + +- [ ] **Step 1: Append dark-mode CSS block** + +Immediately after the light-mode block (still before `@media (max-width: 600px)`), append: + +```css +html[data-theme="dark"][data-design-theme="animal-crossing"] { + color-scheme: dark; + + --accent: #9ed98a; + --accent-rgb: 158, 217, 138; + --accent-2: #86cb72; + --accent-3: #6dbc5e; + --accent-secondary-rgb: 245, 210, 90; + + --page-gradient: #1e2d1e; + --page-texture: + radial-gradient( + circle at 20% 50%, + rgba(158, 217, 138, 0.06) 0%, + transparent 50% + ), + radial-gradient( + circle at 80% 80%, + rgba(245, 210, 90, 0.04) 0%, + transparent 50% + ); + --title-gradient: linear-gradient( + 135deg, + #9ed98a 0%, + #86cb72 40%, + #f5d25a 100% + ); + + --control-bg: rgba(25, 40, 25, 0.82); + --control-border: rgba(158, 217, 138, 0.25); + --control-inset: rgba(255, 255, 255, 0.04); + --control-fg: #e8f4d8; +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] body { + color: #e8f4d8; +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card { + background: rgba(30, 48, 30, 0.82); + border: 1px solid rgba(158, 217, 138, 0.18); + border-radius: 16px; + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.3), + 0 1px 2px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.04); +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card::before { + display: none; +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card.pin { + background: rgba(38, 58, 38, 0.88); +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card h2 { + color: #e8f4d8; +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card p { + color: #b0c8a0; +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card:hover, +html[data-theme="dark"][data-design-theme="animal-crossing"] .card:focus { + border-color: rgba(158, 217, 138, 0.45); + box-shadow: + 0 8px 24px rgba(158, 217, 138, 0.2), + 0 4px 8px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.05); +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card:hover h2, +html[data-theme="dark"][data-design-theme="animal-crossing"] .card:focus h2 { + color: var(--accent); +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .card:hover p, +html[data-theme="dark"][data-design-theme="animal-crossing"] .card:focus p { + color: #c8deb8; +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .design-theme-list { + background: rgba(22, 36, 22, 0.9); + box-shadow: + 0 12px 30px rgba(0, 0, 0, 0.55), + 0 6px 12px rgba(0, 0, 0, 0.35), + inset 0 1px 0 rgba(255, 255, 255, 0.04); +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .beian a { + color: #b0c8a0; +} + +html[data-theme="dark"][data-design-theme="animal-crossing"] .beian a:hover { + color: var(--accent); +} + +@media (prefers-reduced-motion: reduce) { + html[data-design-theme="animal-crossing"] .card, + html[data-design-theme="animal-crossing"] .design-theme-button, + html[data-design-theme="animal-crossing"] .theme-toggle { + transition-duration: 0.01ms !important; + transform: none !important; + } +} +``` + +- [ ] **Step 2: Verify dark mode in browser** + +Toggle to dark mode while "Animal Crossing" theme is active. Verify: +- Background is deep forest green `#1e2d1e` (not generic dark grey) +- Title has soft lime-to-yellow gradient +- Cards are dark forest green with subtle lime border +- Card hover shows lime glow +- Toggling back to light mode restores the cream palette + +- [ ] **Step 3: Commit** + +```bash +git add style.css +git commit -m "feat: add animal-crossing dark mode CSS" +``` + +--- + +## Task 5: Final verification + +- [ ] **Step 1: Check theme persists across reload** + +Select "Animal Crossing" in dark mode. Reload the page. Theme and dark/light preference should both be restored from `localStorage`. + +- [ ] **Step 2: Check theme switching is clean** + +Cycle through all 6 themes (Fluent → Material You → Terminal → Cyberpunk → Nord → Animal Crossing → Fluent). No visual artifacts or broken styles should appear at any step. + +- [ ] **Step 3: Check forced-dark themes restore correctly** + +While on Animal Crossing (light mode), switch to Terminal (forces dark). Then switch back to Animal Crossing — it should restore the light mode you had before. + +- [ ] **Step 4: Run formatter** + +```bash +npm run fmt +``` + +Confirm no diff beyond whitespace normalisation. Commit if formatter changed anything: + +```bash +git add -p +git commit -m "style: run prettier after animal-crossing theme" +```