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"
+```