Compare commits
23 Commits
9d457caefd
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e6e3c8eda9 | |||
| cf09b8dd08 | |||
| 783359af98 | |||
| fa2c943817 | |||
| 27e3722668 | |||
| 8c750b880a | |||
| 7438498d4b | |||
| 8f44a3186a | |||
| a2aba434a8 | |||
| 0e60bbee4d | |||
| 629f461c33 | |||
| 9d4cb74280 | |||
| 29d8ed18c0 | |||
| 4cd9a13f3b | |||
| c46cd06954 | |||
| ce3be0143a | |||
| 00cdb383ee | |||
| d1ccf962ea | |||
| d015363430 | |||
| fe6c9dbe5d | |||
| 2517a84713 | |||
| 2f6e5e4842 | |||
| 29853d9c14 |
135
.superpowers/brainstorm/73376-1779100666/content/approaches.html
Normal file
135
.superpowers/brainstorm/73376-1779100666/content/approaches.html
Normal file
@@ -0,0 +1,135 @@
|
||||
<h2>3 Concrete Approaches</h2>
|
||||
<p class="subtitle">All share: Dracula bg (#282a36), dot matrix texture, rounded soft cards. They differ in accent color strategy.</p>
|
||||
|
||||
<style>
|
||||
/* Shared base */
|
||||
.mockup-wrap {
|
||||
font-family: ui-monospace, 'JetBrains Mono', 'Fira Code', monospace;
|
||||
background: #282a36;
|
||||
background-image: radial-gradient(circle, rgba(98,114,164,0.55) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
border-radius: 10px;
|
||||
padding: 18px 16px 14px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.mockup-title {
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
margin-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.mockup-cards {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
.mc {
|
||||
width: 120px;
|
||||
padding: 10px 11px;
|
||||
border-radius: 8px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.mc h5 { margin: 0 0 4px; font-size: 11px; }
|
||||
.mc p { margin: 0; font-size: 10px; opacity: 0.6; line-height: 1.4; }
|
||||
|
||||
/* ── Approach A: Purple Focus ── */
|
||||
.a-title {
|
||||
background: linear-gradient(90deg, #bd93f9 0%, #ff79c6 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.a-title::after { content: " ▌"; -webkit-text-fill-color: #bd93f9; animation: blink 1s step-end infinite; }
|
||||
@keyframes blink { 50% { opacity: 0; } }
|
||||
.a-card {
|
||||
background: #313244;
|
||||
border: 1px solid #44475a;
|
||||
box-shadow: 0 4px 14px rgba(0,0,0,0.4);
|
||||
color: #f8f8f2;
|
||||
}
|
||||
.a-card h5 { color: #bd93f9; }
|
||||
|
||||
/* ── Approach B: Cyan Dev ── */
|
||||
.b-title { color: #8be9fd; text-shadow: 0 0 12px rgba(139,233,253,0.5); }
|
||||
.b-title::after { content: " ▌"; animation: blink 1s step-end infinite; }
|
||||
.b-card {
|
||||
background: #313244;
|
||||
border: 1px solid #44475a;
|
||||
border-left: 2px solid #8be9fd;
|
||||
box-shadow: 0 4px 14px rgba(0,0,0,0.4);
|
||||
color: #f8f8f2;
|
||||
}
|
||||
.b-card h5 { color: #8be9fd; }
|
||||
|
||||
/* ── Approach C: Multi-accent ── */
|
||||
.c-title {
|
||||
background: linear-gradient(90deg, #ff79c6 0%, #bd93f9 33%, #8be9fd 66%, #50fa7b 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.c-card {
|
||||
background: #313244;
|
||||
border: 1px solid #44475a;
|
||||
box-shadow: 0 4px 14px rgba(0,0,0,0.4);
|
||||
color: #f8f8f2;
|
||||
}
|
||||
.c-card-1 { border-top: 2px solid #ff79c6; }
|
||||
.c-card-1 h5 { color: #ff79c6; }
|
||||
.c-card-2 { border-top: 2px solid #bd93f9; }
|
||||
.c-card-2 h5 { color: #bd93f9; }
|
||||
.c-card-3 { border-top: 2px solid #8be9fd; }
|
||||
.c-card-3 h5 { color: #8be9fd; }
|
||||
</style>
|
||||
|
||||
<div class="options">
|
||||
<div class="option" data-choice="purple" onclick="toggleSelect(this)">
|
||||
<div class="letter">A</div>
|
||||
<div class="content">
|
||||
<h3>Purple Focus <span style="font-size:11px;opacity:0.6;font-weight:normal">(recommended)</span></h3>
|
||||
<p>#bd93f9 mauve as the single accent. Gradient title (purple→pink). Clean card hover with purple glow. Cohesive and refined.</p>
|
||||
<div class="mockup-wrap">
|
||||
<div class="mockup-title a-title">IoT Learning</div>
|
||||
<div class="mockup-cards">
|
||||
<div class="mc a-card"><h5>OJ Platform</h5><p>Online judge</p></div>
|
||||
<div class="mc a-card"><h5>Code Runner</h5><p>Run snippets</p></div>
|
||||
<div class="mc a-card"><h5>Textbooks</h5><p>Reference books</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="cyan" onclick="toggleSelect(this)">
|
||||
<div class="letter">B</div>
|
||||
<div class="content">
|
||||
<h3>Cyan Dev</h3>
|
||||
<p>#8be9fd cyan as accent. Glowing title, left-border accent on cards. Closer to the old terminal vibe — just upgraded. More "code editor", less "app".</p>
|
||||
<div class="mockup-wrap">
|
||||
<div class="mockup-title b-title">IoT Learning</div>
|
||||
<div class="mockup-cards">
|
||||
<div class="mc b-card"><h5>OJ Platform</h5><p>Online judge</p></div>
|
||||
<div class="mc b-card"><h5>Code Runner</h5><p>Run snippets</p></div>
|
||||
<div class="mc b-card"><h5>Textbooks</h5><p>Reference books</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="multi" onclick="toggleSelect(this)">
|
||||
<div class="letter">C</div>
|
||||
<div class="content">
|
||||
<h3>Multi-Accent Rainbow</h3>
|
||||
<p>Each card gets a different Dracula color top border (pink, purple, cyan…). Title uses all colors. Most colorful — looks like syntax highlighting applied to the UI.</p>
|
||||
<div class="mockup-wrap">
|
||||
<div class="mockup-title c-title">IoT Learning</div>
|
||||
<div class="mockup-cards">
|
||||
<div class="mc c-card c-card-1"><h5>OJ Platform</h5><p>Online judge</p></div>
|
||||
<div class="mc c-card c-card-2"><h5>Code Runner</h5><p>Run snippets</p></div>
|
||||
<div class="mc c-card c-card-3"><h5>Textbooks</h5><p>Reference books</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,98 @@
|
||||
<h2>Background Treatment</h2>
|
||||
<p class="subtitle">The background sets the whole mood. All options use Dracula's base color (#282a36) as the foundation.</p>
|
||||
|
||||
<style>
|
||||
.bg-preview {
|
||||
width: 100%;
|
||||
height: 110px;
|
||||
border-radius: 8px;
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.bg-label {
|
||||
font-family: ui-monospace, monospace;
|
||||
font-size: 11px;
|
||||
color: rgba(248,248,242,0.5);
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
/* A: flat clean */
|
||||
.bg-flat {
|
||||
background: #282a36;
|
||||
}
|
||||
|
||||
/* B: radial aurora glow */
|
||||
.bg-aurora {
|
||||
background: #282a36;
|
||||
background-image:
|
||||
radial-gradient(ellipse at 20% 30%, rgba(189,147,249,0.18) 0%, transparent 55%),
|
||||
radial-gradient(ellipse at 80% 70%, rgba(255,121,198,0.12) 0%, transparent 50%),
|
||||
radial-gradient(ellipse at 55% 90%, rgba(139,233,253,0.08) 0%, transparent 45%);
|
||||
}
|
||||
|
||||
/* C: subtle grid */
|
||||
.bg-grid {
|
||||
background: #282a36;
|
||||
background-image:
|
||||
linear-gradient(rgba(68,71,90,0.4) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(68,71,90,0.4) 1px, transparent 1px);
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
|
||||
/* D: dot matrix */
|
||||
.bg-dots {
|
||||
background: #282a36;
|
||||
background-image: radial-gradient(circle, rgba(98,114,164,0.5) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="options">
|
||||
<div class="option" data-choice="flat" onclick="toggleSelect(this)">
|
||||
<div class="letter">A</div>
|
||||
<div class="content">
|
||||
<h3>Flat & Clean</h3>
|
||||
<p>Pure #282a36, no texture. Maximum focus on content. Closest to how most Dracula apps look.</p>
|
||||
<div class="bg-preview bg-flat">
|
||||
<span class="bg-label">#282a36 — pure</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="aurora" onclick="toggleSelect(this)">
|
||||
<div class="letter">B</div>
|
||||
<div class="content">
|
||||
<h3>Aurora Glow</h3>
|
||||
<p>Subtle radial gradients using Dracula's purple, pink, and cyan — like a soft aurora bleeding through the dark. Gives depth without noise.</p>
|
||||
<div class="bg-preview bg-aurora">
|
||||
<span class="bg-label">radial glows — purple / pink / cyan</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="grid" onclick="toggleSelect(this)">
|
||||
<div class="letter">C</div>
|
||||
<div class="content">
|
||||
<h3>Subtle Grid</h3>
|
||||
<p>Faint 24px grid overlay on the dark background. Keeps a technical/terminal feel while the cards are soft. Nod to graph paper or circuit boards.</p>
|
||||
<div class="bg-preview bg-grid">
|
||||
<span class="bg-label">24px grid — #44475a lines</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="dots" onclick="toggleSelect(this)">
|
||||
<div class="letter">D</div>
|
||||
<div class="content">
|
||||
<h3>Dot Matrix</h3>
|
||||
<p>Subtle dot pattern — evokes old terminal screens and LED matrices. Quiet texture, doesn't compete with content.</p>
|
||||
<div class="bg-preview bg-dots">
|
||||
<span class="bg-label">20px dot grid — comment color dots</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
<h2>Terminal Theme — Redesign Direction</h2>
|
||||
<p class="subtitle">The current theme is functional but sparse: green-on-black, square borders, blinking cursor. Which direction feels right?</p>
|
||||
|
||||
<div class="options">
|
||||
<div class="option" data-choice="crt" onclick="toggleSelect(this)">
|
||||
<div class="letter">A</div>
|
||||
<div class="content">
|
||||
<h3>CRT Phosphor Glow</h3>
|
||||
<p>Keep the green palette but push the retro CRT aesthetic much further — stronger scanlines, phosphor bloom on text, vignette darkening at corners, subtle screen curvature illusion. Very nostalgic, visually rich.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="bios" onclick="toggleSelect(this)">
|
||||
<div class="letter">B</div>
|
||||
<div class="content">
|
||||
<h3>Retro BIOS / DOS Amber</h3>
|
||||
<p>Shift the palette from green to amber/orange (#ffb000) — the classic monochrome phosphor of early PCs. Or go full IBM-BIOS blue (dark blue bg, bright white text, cyan highlights). A completely different retro personality.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="modern" onclick="toggleSelect(this)">
|
||||
<div class="letter">C</div>
|
||||
<div class="content">
|
||||
<h3>Modern Terminal (Dracula / Catppuccin)</h3>
|
||||
<p>Inspired by popular terminal themes (Dracula, Catppuccin Mocha, One Dark). Multiple accent colors, not just green — purple, cyan, pink, yellow all used. Clean, developer-aesthetic, but rich with color. Less "retro", more "everyday dev tool".</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="matrix" onclick="toggleSelect(this)">
|
||||
<div class="letter">D</div>
|
||||
<div class="content">
|
||||
<h3>Matrix / Hacker Aesthetic</h3>
|
||||
<p>Stay green but add drama — cascading character rain animation in the background (subtle, faint), stronger glow effects, maybe ASCII art borders on cards. Very cinematic, very "movie hacker screen".</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,232 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Terminal Theme — Full Mockup</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: ui-monospace, 'JetBrains Mono', 'Fira Code', monospace;
|
||||
background: #282a36;
|
||||
background-image: radial-gradient(circle, rgba(98,114,164,0.55) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
min-height: 100vh;
|
||||
color: #f8f8f2;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
/* Controls */
|
||||
.controls {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
z-index: 100;
|
||||
}
|
||||
.ctrl-btn {
|
||||
height: 44px;
|
||||
padding: 0 16px;
|
||||
background: rgba(40,42,54,0.92);
|
||||
border: 1px solid #44475a;
|
||||
border-radius: 8px;
|
||||
color: #f8f8f2;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
transition: all 0.2s;
|
||||
min-width: 118px;
|
||||
justify-content: center;
|
||||
}
|
||||
.ctrl-btn:hover {
|
||||
border-color: #bd93f9;
|
||||
color: #bd93f9;
|
||||
background: rgba(189,147,249,0.08);
|
||||
}
|
||||
.ctrl-icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
padding: 0;
|
||||
min-width: unset;
|
||||
justify-content: center;
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.ctrl-icon:hover { border-color: #44475a; color: #f8f8f2; background: rgba(40,42,54,0.92); }
|
||||
.chevron { opacity: 0.6; font-size: 10px; }
|
||||
|
||||
/* Main */
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 5rem 2rem 2rem;
|
||||
}
|
||||
|
||||
/* Title */
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
background: linear-gradient(90deg, #bd93f9 0%, #ff79c6 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
margin-bottom: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
.title-cursor {
|
||||
-webkit-text-fill-color: #bd93f9;
|
||||
animation: blink 1s step-end infinite;
|
||||
}
|
||||
@keyframes blink { 50% { opacity: 0; } }
|
||||
|
||||
/* Description */
|
||||
.description {
|
||||
color: #6272a4;
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Grid */
|
||||
.grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
max-width: 860px;
|
||||
}
|
||||
|
||||
/* Cards */
|
||||
.card {
|
||||
width: 260px;
|
||||
padding: 1.5rem;
|
||||
background: #313244;
|
||||
border: 1px solid #44475a;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.45);
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: block;
|
||||
}
|
||||
.card:hover {
|
||||
border-color: #bd93f9;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(189,147,249,0.25),
|
||||
0 8px 28px rgba(189,147,249,0.15),
|
||||
0 4px 12px rgba(0,0,0,0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.card.pin { background: #383a4a; }
|
||||
.card h2 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: #f8f8f2;
|
||||
margin-bottom: 0.5rem;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.card:hover h2 { color: #bd93f9; }
|
||||
.card p {
|
||||
font-size: 0.85rem;
|
||||
color: #6272a4;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.card:hover p { color: #cdd6f4; }
|
||||
|
||||
/* Beian */
|
||||
.beian {
|
||||
margin: 2rem 0 1.5rem;
|
||||
color: #6272a4;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
.beian a { color: #6272a4; text-decoration: none; transition: color 0.2s; }
|
||||
.beian a:hover { color: #bd93f9; }
|
||||
|
||||
/* Annotation layer */
|
||||
.annotation {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(30,32,43,0.97);
|
||||
border-top: 1px solid #44475a;
|
||||
padding: 14px 24px;
|
||||
font-size: 12px;
|
||||
color: #6272a4;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
flex-wrap: wrap;
|
||||
font-family: ui-monospace, monospace;
|
||||
z-index: 200;
|
||||
}
|
||||
.ann-item { display: flex; align-items: center; gap: 8px; }
|
||||
.swatch { width: 12px; height: 12px; border-radius: 2px; display: inline-block; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="controls">
|
||||
<button class="ctrl-btn">Terminal <span class="chevron">▾</span></button>
|
||||
<button class="ctrl-btn ctrl-icon">☽</button>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<h1 class="title">IoT Learning<span class="title-cursor"> ▌</span></h1>
|
||||
<p class="description">// your gateway to embedded systems & IoT resources</p>
|
||||
|
||||
<div class="grid">
|
||||
<a class="card pin" href="#">
|
||||
<h2>OJ Platform</h2>
|
||||
<p>Online judge — submit and test your code against real problems</p>
|
||||
</a>
|
||||
<a class="card" href="#">
|
||||
<h2>Code Runner</h2>
|
||||
<p>Instant code execution in-browser for quick experiments</p>
|
||||
</a>
|
||||
<a class="card" href="#">
|
||||
<h2>Reference Books</h2>
|
||||
<p>Curated textbooks and documentation for IoT & embedded dev</p>
|
||||
</a>
|
||||
<a class="card" href="#">
|
||||
<h2>Video Lectures</h2>
|
||||
<p>Course recordings and tutorials from the lab</p>
|
||||
</a>
|
||||
<a class="card" href="#">
|
||||
<h2>Arduino Docs</h2>
|
||||
<p>Official Arduino reference and community guides</p>
|
||||
</a>
|
||||
<a class="card" href="#">
|
||||
<h2>Forum</h2>
|
||||
<p>Ask questions, share projects with classmates</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="beian">
|
||||
<a href="#">备案号 12345678</a> · <a href="#">粤ICP备XXXXXXXX号</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Color annotations at bottom -->
|
||||
<div class="annotation">
|
||||
<div class="ann-item"><span class="swatch" style="background:#282a36;border:1px solid #44475a"></span> bg #282a36</div>
|
||||
<div class="ann-item"><span class="swatch" style="background:#313244"></span> card #313244</div>
|
||||
<div class="ann-item"><span class="swatch" style="background:#44475a"></span> border #44475a</div>
|
||||
<div class="ann-item"><span class="swatch" style="background:#bd93f9"></span> accent #bd93f9</div>
|
||||
<div class="ann-item"><span class="swatch" style="background:#ff79c6"></span> pink #ff79c6</div>
|
||||
<div class="ann-item"><span class="swatch" style="background:#6272a4"></span> muted #6272a4</div>
|
||||
<div class="ann-item"><span class="swatch" style="background:#f8f8f2"></span> fg #f8f8f2</div>
|
||||
<div class="ann-item" style="margin-left:auto">hover a card to preview interaction →</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,86 @@
|
||||
<h2>Which Palette?</h2>
|
||||
<p class="subtitle">Modern terminal themes each have a distinct personality. Which palette should drive the redesign?</p>
|
||||
|
||||
<style>
|
||||
.swatch-row { display: flex; gap: 6px; margin: 10px 0 6px; flex-wrap: wrap; }
|
||||
.swatch { width: 28px; height: 28px; border-radius: 4px; display: inline-block; }
|
||||
.palette-preview {
|
||||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
padding: 10px 14px;
|
||||
border-radius: 8px;
|
||||
margin-top: 8px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="options">
|
||||
<div class="option" data-choice="dracula" onclick="toggleSelect(this)">
|
||||
<div class="letter">A</div>
|
||||
<div class="content">
|
||||
<h3>Dracula</h3>
|
||||
<p>Dark purple background, vibrant pink/cyan/green accents. The most iconic dark theme — moody yet colorful.</p>
|
||||
<div class="swatch-row">
|
||||
<span class="swatch" style="background:#282a36" title="Background"></span>
|
||||
<span class="swatch" style="background:#44475a" title="Current Line"></span>
|
||||
<span class="swatch" style="background:#ff79c6" title="Pink"></span>
|
||||
<span class="swatch" style="background:#8be9fd" title="Cyan"></span>
|
||||
<span class="swatch" style="background:#50fa7b" title="Green"></span>
|
||||
<span class="swatch" style="background:#bd93f9" title="Purple"></span>
|
||||
<span class="swatch" style="background:#ffb86c" title="Orange"></span>
|
||||
<span class="swatch" style="background:#f1fa8c" title="Yellow"></span>
|
||||
</div>
|
||||
<div class="palette-preview" style="background:#282a36;color:#f8f8f2">
|
||||
<span style="color:#ff79c6">fn</span> <span style="color:#50fa7b">visit</span>(<span style="color:#8be9fd">url</span>: <span style="color:#bd93f9">str</span>) {<br>
|
||||
<span style="color:#ffb86c">// navigate to resource</span><br>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="catppuccin" onclick="toggleSelect(this)">
|
||||
<div class="letter">B</div>
|
||||
<div class="content">
|
||||
<h3>Catppuccin Mocha</h3>
|
||||
<p>Warm, desaturated dark background with soft pastel accents. Gentle on the eyes, cozy and modern.</p>
|
||||
<div class="swatch-row">
|
||||
<span class="swatch" style="background:#1e1e2e" title="Base"></span>
|
||||
<span class="swatch" style="background:#313244" title="Surface0"></span>
|
||||
<span class="swatch" style="background:#f38ba8" title="Red"></span>
|
||||
<span class="swatch" style="background:#89dceb" title="Sky"></span>
|
||||
<span class="swatch" style="background:#a6e3a1" title="Green"></span>
|
||||
<span class="swatch" style="background:#cba6f7" title="Mauve"></span>
|
||||
<span class="swatch" style="background:#fab387" title="Peach"></span>
|
||||
<span class="swatch" style="background:#f9e2af" title="Yellow"></span>
|
||||
</div>
|
||||
<div class="palette-preview" style="background:#1e1e2e;color:#cdd6f4">
|
||||
<span style="color:#f38ba8">fn</span> <span style="color:#a6e3a1">visit</span>(<span style="color:#89dceb">url</span>: <span style="color:#cba6f7">str</span>) {<br>
|
||||
<span style="color:#fab387">// navigate to resource</span><br>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="tokyonight" onclick="toggleSelect(this)">
|
||||
<div class="letter">C</div>
|
||||
<div class="content">
|
||||
<h3>Tokyo Night</h3>
|
||||
<p>Deep blue-navy background, electric blue and magenta highlights. Calm, cool, city-at-night aesthetic.</p>
|
||||
<div class="swatch-row">
|
||||
<span class="swatch" style="background:#1a1b26" title="Background"></span>
|
||||
<span class="swatch" style="background:#24283b" title="Surface"></span>
|
||||
<span class="swatch" style="background:#f7768e" title="Red"></span>
|
||||
<span class="swatch" style="background:#7dcfff" title="Cyan"></span>
|
||||
<span class="swatch" style="background:#9ece6a" title="Green"></span>
|
||||
<span class="swatch" style="background:#bb9af7" title="Purple"></span>
|
||||
<span class="swatch" style="background:#ff9e64" title="Orange"></span>
|
||||
<span class="swatch" style="background:#e0af68" title="Yellow"></span>
|
||||
</div>
|
||||
<div class="palette-preview" style="background:#1a1b26;color:#c0caf5">
|
||||
<span style="color:#f7768e">fn</span> <span style="color:#9ece6a">visit</span>(<span style="color:#7dcfff">url</span>: <span style="color:#bb9af7">str</span>) {<br>
|
||||
<span style="color:#ff9e64">// navigate to resource</span><br>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
106
.superpowers/brainstorm/73376-1779100666/content/vibe.html
Normal file
106
.superpowers/brainstorm/73376-1779100666/content/vibe.html
Normal file
@@ -0,0 +1,106 @@
|
||||
<h2>Dracula — How Far to Lean Into "Terminal"?</h2>
|
||||
<p class="subtitle">Same palette, different personality. Which card style feels right?</p>
|
||||
|
||||
<style>
|
||||
.preview-grid {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-top: 16px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
.preview-card-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; }
|
||||
.preview-card-wrap .label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; opacity: 0.6; }
|
||||
|
||||
/* Style A: still terminal — square, monospace, minimal */
|
||||
.card-terminal {
|
||||
width: 200px;
|
||||
padding: 16px;
|
||||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(80,250,123,0.4);
|
||||
color: #f8f8f2;
|
||||
font-size: 13px;
|
||||
}
|
||||
.card-terminal h4 { margin: 0 0 6px; color: #50fa7b; font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; }
|
||||
.card-terminal p { margin: 0; color: #6272a4; font-size: 12px; }
|
||||
.card-terminal:hover { background: rgba(80,250,123,0.06); border-color: #50fa7b; }
|
||||
|
||||
/* Style B: soft modern — rounded, card bg, subtle */
|
||||
.card-modern {
|
||||
width: 200px;
|
||||
padding: 16px;
|
||||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||||
background: #313244;
|
||||
border: 1px solid #44475a;
|
||||
border-radius: 10px;
|
||||
color: #f8f8f2;
|
||||
font-size: 13px;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.4);
|
||||
}
|
||||
.card-modern h4 { margin: 0 0 6px; color: #bd93f9; font-size: 13px; }
|
||||
.card-modern p { margin: 0; color: #6272a4; font-size: 12px; }
|
||||
|
||||
/* Style C: vibrant accented — colored top border, gradient glow */
|
||||
.card-vibrant {
|
||||
width: 200px;
|
||||
padding: 16px;
|
||||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||||
background: #282a36;
|
||||
border: 1px solid #44475a;
|
||||
border-top: 2px solid #ff79c6;
|
||||
border-radius: 0 0 8px 8px;
|
||||
color: #f8f8f2;
|
||||
font-size: 13px;
|
||||
box-shadow: 0 0 0 1px rgba(255,121,198,0.08), 0 8px 24px rgba(0,0,0,0.5);
|
||||
}
|
||||
.card-vibrant h4 { margin: 0 0 6px; color: #ff79c6; font-size: 13px; }
|
||||
.card-vibrant p { margin: 0; color: #6272a4; font-size: 12px; }
|
||||
</style>
|
||||
|
||||
<div class="options">
|
||||
<div class="option" data-choice="terminal-dracula" onclick="toggleSelect(this)">
|
||||
<div class="letter">A</div>
|
||||
<div class="content">
|
||||
<h3>Still Terminal</h3>
|
||||
<p>Square corners, transparent cards, Dracula green as primary accent. Same structural DNA as today — just a better palette and more glow.</p>
|
||||
<div style="background:#282a36;padding:16px;margin-top:10px;border-radius:6px">
|
||||
<div style="color:#6272a4;font-family:monospace;font-size:11px;margin-bottom:8px"># IoT Learning Portal</div>
|
||||
<div class="card-terminal">
|
||||
<h4>▶ OJ Platform</h4>
|
||||
<p>Online judge for practice</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="modern-dracula" onclick="toggleSelect(this)">
|
||||
<div class="letter">B</div>
|
||||
<div class="content">
|
||||
<h3>Soft Modern</h3>
|
||||
<p>Rounded cards with Dracula surface colors, purple accent, subtle shadows. Feels like a polished app — less "green terminal", more "Dracula theme everything".</p>
|
||||
<div style="background:#282a36;padding:16px;margin-top:10px;border-radius:6px">
|
||||
<div style="color:#6272a4;font-family:monospace;font-size:11px;margin-bottom:8px"># IoT Learning Portal</div>
|
||||
<div class="card-modern">
|
||||
<h4>OJ Platform</h4>
|
||||
<p>Online judge for practice</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="option" data-choice="vibrant-dracula" onclick="toggleSelect(this)">
|
||||
<div class="letter">C</div>
|
||||
<div class="content">
|
||||
<h3>Vibrant & Accented</h3>
|
||||
<p>Colored top border on cards (like Cyberpunk's treatment), pink/cyan/purple accents used actively, neon glow on hover. Most visually punchy of the three.</p>
|
||||
<div style="background:#282a36;padding:16px;margin-top:10px;border-radius:6px">
|
||||
<div style="color:#6272a4;font-family:monospace;font-size:11px;margin-bottom:8px"># IoT Learning Portal</div>
|
||||
<div class="card-vibrant">
|
||||
<h4>OJ Platform</h4>
|
||||
<p>Online judge for practice</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div style="display:flex;align-items:center;justify-content:center;min-height:60vh">
|
||||
<p class="subtitle">Continuing in terminal…</p>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
{"reason":"owner process exited","timestamp":1779101686437}
|
||||
@@ -0,0 +1 @@
|
||||
73384
|
||||
1
app.js
1
app.js
@@ -188,7 +188,6 @@ export function initApp() {
|
||||
titleEl.dataset.text = titleEl.textContent?.trim() || ""
|
||||
}
|
||||
|
||||
|
||||
const initialTheme = getInitialTheme()
|
||||
setTheme(initialTheme)
|
||||
|
||||
|
||||
485
docs/superpowers/plans/2026-05-18-animal-crossing-theme.md
Normal file
485
docs/superpowers/plans/2026-05-18-animal-crossing-theme.md
Normal file
@@ -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 `<li role="option" data-value="animal-crossing">` 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 `<li>` (currently line 45):
|
||||
```html
|
||||
<li role="option" data-value="nord" aria-selected="false">
|
||||
Nord
|
||||
</li>
|
||||
```
|
||||
add immediately after:
|
||||
```html
|
||||
<li role="option" data-value="animal-crossing" aria-selected="false">
|
||||
动森
|
||||
</li>
|
||||
```
|
||||
|
||||
- [ ] **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"
|
||||
```
|
||||
540
docs/superpowers/plans/2026-05-18-minecraft-theme.md
Normal file
540
docs/superpowers/plans/2026-05-18-minecraft-theme.md
Normal file
@@ -0,0 +1,540 @@
|
||||
# Minecraft 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 a "minecraft" design theme — zero border-radius, Minecraft GUI bevel shadows, 16px pixel grid background, monospace font, dark (Stone & Cave) + light (Overworld Day) modes.
|
||||
|
||||
**Architecture:** Four small file edits following the established theme pattern. Dark mode uses `html[data-theme="dark"][data-design-theme="minecraft"]` selectors (same specificity as the generic dark override rules, but placed later in the file so they win). Light mode uses `html[data-theme="light"][data-design-theme="minecraft"]`. No font imports — system monospace only.
|
||||
|
||||
**Tech Stack:** Vanilla JS, Vite, CSS custom properties. No test suite — verification is manual via `npm start`.
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| `theme.js:1` | Add `"minecraft"` to `DESIGN_THEMES` |
|
||||
| `index.html:48` | Add `<li role="option" data-value="minecraft">` after animal-crossing |
|
||||
| `i18n.js:136–226` | Add `minecraft` key in all 11 language objects of `DESIGN_THEME_LABELS` |
|
||||
| `style.css` | Append dark vars + light vars + body/grid/control/card overrides + reduced-motion |
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Register the theme slug
|
||||
|
||||
**Files:**
|
||||
- Modify: `theme.js:1`
|
||||
- Modify: `index.html:48`
|
||||
|
||||
- [ ] **Step 1: Add slug to DESIGN_THEMES in theme.js**
|
||||
|
||||
Change line 1 from:
|
||||
```js
|
||||
const DESIGN_THEMES = ["fluent", "material-you", "terminal", "cyberpunk", "nord", "animal-crossing"]
|
||||
```
|
||||
to:
|
||||
```js
|
||||
const DESIGN_THEMES = ["fluent", "material-you", "terminal", "cyberpunk", "nord", "animal-crossing", "minecraft"]
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Add dropdown option in index.html**
|
||||
|
||||
After the animal-crossing `<li>` (currently lines 46–48):
|
||||
```html
|
||||
<li role="option" data-value="animal-crossing" aria-selected="false">
|
||||
Animal Crossing
|
||||
</li>
|
||||
```
|
||||
add immediately after:
|
||||
```html
|
||||
<li role="option" data-value="minecraft" aria-selected="false">
|
||||
Minecraft
|
||||
</li>
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add theme.js index.html
|
||||
git commit -m "feat: register minecraft theme slug"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Add i18n labels
|
||||
|
||||
**Files:**
|
||||
- Modify: `i18n.js:136–226`
|
||||
|
||||
- [ ] **Step 1: Add `minecraft` key to every language object in DESIGN_THEME_LABELS**
|
||||
|
||||
Replace the entire `DESIGN_THEME_LABELS` constant with:
|
||||
|
||||
```js
|
||||
export const DESIGN_THEME_LABELS = {
|
||||
"zh-Hans": {
|
||||
fluent: "Fluent",
|
||||
"material-you": "Material You",
|
||||
terminal: "终端",
|
||||
cyberpunk: "赛博朋克",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "动森",
|
||||
minecraft: "我的世界",
|
||||
},
|
||||
"zh-Hant": {
|
||||
fluent: "Fluent",
|
||||
"material-you": "Material You",
|
||||
terminal: "終端",
|
||||
cyberpunk: "賽博龐克",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "動森",
|
||||
minecraft: "我的世界",
|
||||
},
|
||||
en: {
|
||||
fluent: "Fluent",
|
||||
"material-you": "Material You",
|
||||
terminal: "Terminal",
|
||||
cyberpunk: "Cyberpunk",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "Animal Crossing",
|
||||
minecraft: "Minecraft",
|
||||
},
|
||||
ja: {
|
||||
fluent: "Fluent",
|
||||
"material-you": "Material You",
|
||||
terminal: "ターミナル",
|
||||
cyberpunk: "サイバーパンク",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "どうぶつの森",
|
||||
minecraft: "マインクラフト",
|
||||
},
|
||||
ko: {
|
||||
fluent: "Fluent",
|
||||
"material-you": "Material You",
|
||||
terminal: "터미널",
|
||||
cyberpunk: "사이버펑크",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "동물의 숲",
|
||||
minecraft: "마인크래프트",
|
||||
},
|
||||
wenyan: {
|
||||
fluent: "流光",
|
||||
"material-you": "物材",
|
||||
terminal: "终端",
|
||||
cyberpunk: "赛博",
|
||||
nord: "清寒",
|
||||
"animal-crossing": "森友",
|
||||
minecraft: "方块世界",
|
||||
},
|
||||
mars: {
|
||||
fluent: "流↗光",
|
||||
"material-you": "材↘質",
|
||||
terminal: "終↗★端",
|
||||
cyberpunk: "賽↘!博",
|
||||
nord: "清↗寒★",
|
||||
"animal-crossing": "动↗森★",
|
||||
minecraft: "我↗的★世界",
|
||||
},
|
||||
garbled: {
|
||||
fluent: "◼è▦",
|
||||
"material-you": "拷▤屯ä锟◽",
|
||||
terminal: "¥¬▤▨¿¿",
|
||||
cyberpunk: "◼çæ¥烫¥",
|
||||
nord: "æ◽屯¿",
|
||||
"animal-crossing": "ä◼▤è",
|
||||
minecraft: "▤◼▦è屯",
|
||||
},
|
||||
bin: {
|
||||
fluent: "0101",
|
||||
"material-you": "010101",
|
||||
terminal: "01010101",
|
||||
cyberpunk: "0101010101",
|
||||
nord: "0101010",
|
||||
"animal-crossing": "01010101",
|
||||
minecraft: "0101010",
|
||||
},
|
||||
meow: {
|
||||
fluent: "喵喵",
|
||||
"material-you": "喵喵喵",
|
||||
terminal: "喵喵",
|
||||
cyberpunk: "喵喵喵喵",
|
||||
nord: "喵喵喵",
|
||||
"animal-crossing": "喵喵喵喵",
|
||||
minecraft: "喵喵喵",
|
||||
},
|
||||
emoji: {
|
||||
fluent: "💧",
|
||||
"material-you": "🧱",
|
||||
terminal: "⌨️",
|
||||
cyberpunk: "⚡",
|
||||
nord: "❄️",
|
||||
"animal-crossing": "🌿",
|
||||
minecraft: "⛏️",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add i18n.js
|
||||
git commit -m "feat: add minecraft labels for all 11 languages"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Add CSS — dark mode (Stone & Cave)
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` (append after the `prefers-reduced-motion` block at end of file)
|
||||
|
||||
- [ ] **Step 1: Append dark mode CSS block at end of style.css**
|
||||
|
||||
```css
|
||||
/* ─── Minecraft — Stone & Cave / Overworld Day ──────────────── */
|
||||
html[data-design-theme="minecraft"] {
|
||||
color-scheme: dark;
|
||||
|
||||
--accent: #5aaa3a;
|
||||
--accent-rgb: 90, 170, 58;
|
||||
--accent-2: #3d8a2a;
|
||||
--accent-3: #2a6e1a;
|
||||
--accent-secondary-rgb: 91, 191, 232;
|
||||
|
||||
--page-gradient: #1a1a1a;
|
||||
--page-texture: none;
|
||||
--title-gradient: linear-gradient(135deg, #5bbfe8 0%, #5aaa3a 100%);
|
||||
|
||||
--control-bg: rgba(62, 62, 62, 0.92);
|
||||
--control-border: #1a1a1a;
|
||||
--control-inset: rgba(255, 255, 255, 0.2);
|
||||
--control-fg: #f0f0f0;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] {
|
||||
color-scheme: dark;
|
||||
|
||||
--accent: #5aaa3a;
|
||||
--accent-rgb: 90, 170, 58;
|
||||
--accent-2: #3d8a2a;
|
||||
--accent-3: #2a6e1a;
|
||||
--accent-secondary-rgb: 91, 191, 232;
|
||||
|
||||
--page-gradient: #1a1a1a;
|
||||
--page-texture: none;
|
||||
--title-gradient: linear-gradient(135deg, #5bbfe8 0%, #5aaa3a 100%);
|
||||
|
||||
--control-bg: rgba(62, 62, 62, 0.92);
|
||||
--control-border: #1a1a1a;
|
||||
--control-inset: rgba(255, 255, 255, 0.2);
|
||||
--control-fg: #f0f0f0;
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"] body {
|
||||
font-family: ui-monospace, "Courier New", Courier, monospace;
|
||||
letter-spacing: 0.04em;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] body {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"] body::before {
|
||||
background-image:
|
||||
linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px);
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"] .design-theme-button,
|
||||
html[data-design-theme="minecraft"] .theme-toggle {
|
||||
border-radius: 0;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(255, 255, 255, 0.25),
|
||||
inset -2px -2px 0 rgba(0, 0, 0, 0.5);
|
||||
transition: all 0.1s steps(2, end);
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"] .design-theme-button:hover,
|
||||
html[data-design-theme="minecraft"] .theme-toggle:hover {
|
||||
background: rgba(82, 82, 82, 0.95);
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(255, 255, 255, 0.35),
|
||||
inset -2px -2px 0 rgba(0, 0, 0, 0.4);
|
||||
transform: none;
|
||||
border-color: rgba(var(--accent-rgb), 0.7);
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"] .design-theme-button:active,
|
||||
html[data-design-theme="minecraft"] .theme-toggle:active {
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(0, 0, 0, 0.4),
|
||||
inset -2px -2px 0 rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"] .design-theme-list {
|
||||
border-radius: 0;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
background: rgba(30, 30, 30, 0.96);
|
||||
border: 2px solid #111111;
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(255, 255, 255, 0.1),
|
||||
inset -2px -2px 0 rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"] .design-theme-list [role="option"] {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
html[data-design-theme="minecraft"]
|
||||
.design-theme-list
|
||||
[role="option"]:hover,
|
||||
html[data-design-theme="minecraft"]
|
||||
.design-theme-list
|
||||
[role="option"][aria-selected="true"] {
|
||||
background: rgba(var(--accent-rgb), 0.25);
|
||||
color: var(--control-fg);
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card {
|
||||
background: #3c3c3c;
|
||||
border: 2px solid #111111;
|
||||
border-radius: 0;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(255, 255, 255, 0.2),
|
||||
inset -2px -2px 0 rgba(0, 0, 0, 0.5);
|
||||
transition: all 0.1s steps(2, end);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card.pin {
|
||||
background: #454545;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card h2 {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card p {
|
||||
color: #c8c8c8;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card:hover,
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card:focus {
|
||||
background: #484848;
|
||||
transform: none;
|
||||
border-color: #5aaa3a;
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(0, 0, 0, 0.35),
|
||||
inset -2px -2px 0 rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card:hover h2,
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card:focus h2 {
|
||||
color: #5aaa3a;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card:hover p,
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .card:focus p {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .beian a {
|
||||
color: #c8c8c8;
|
||||
}
|
||||
|
||||
html[data-theme="dark"][data-design-theme="minecraft"] .beian a:hover {
|
||||
color: #5aaa3a;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify dark mode in browser**
|
||||
|
||||
Start dev server (`npm start`). Select "我的世界" in dark mode. Verify:
|
||||
- Background is `#1a1a1a` dark stone (not generic dark gray)
|
||||
- Title has blue-to-green gradient
|
||||
- Cards are `#3c3c3c` with visible bevel (lighter top-left, darker bottom-right inset)
|
||||
- Cards have NO rounded corners (sharp square edges)
|
||||
- Card hover inverts the bevel and border turns green
|
||||
- Controls have zero border-radius and bevel effect
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add style.css
|
||||
git commit -m "feat: add minecraft dark mode CSS"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Add CSS — light mode (Overworld Day)
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` (append after dark mode block from Task 3)
|
||||
|
||||
- [ ] **Step 1: Append light mode CSS block**
|
||||
|
||||
```css
|
||||
html[data-theme="light"][data-design-theme="minecraft"] {
|
||||
color-scheme: light;
|
||||
|
||||
--accent: #5c9e40;
|
||||
--accent-rgb: 92, 158, 64;
|
||||
--accent-2: #4a8a30;
|
||||
--accent-3: #8b6914;
|
||||
--accent-secondary-rgb: 135, 206, 235;
|
||||
|
||||
--page-gradient: linear-gradient(180deg, #87ceeb 0%, #c9e8f7 50%, #f0f8ff 100%);
|
||||
--page-texture: none;
|
||||
--title-gradient: linear-gradient(135deg, #5c9e40 0%, #8b6914 100%);
|
||||
|
||||
--control-bg: rgba(198, 198, 198, 0.92);
|
||||
--control-border: #555555;
|
||||
--control-inset: rgba(255, 255, 255, 0.5);
|
||||
--control-fg: #2a2a2a;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] body {
|
||||
color: #2a2a2a;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] body::before {
|
||||
background-image:
|
||||
linear-gradient(rgba(0, 0, 0, 0.04) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(0, 0, 0, 0.04) 1px, transparent 1px);
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .design-theme-list {
|
||||
background: rgba(210, 210, 210, 0.96);
|
||||
border: 2px solid #555555;
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(255, 255, 255, 0.7),
|
||||
inset -2px -2px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card {
|
||||
background: rgba(198, 198, 198, 0.85);
|
||||
border: 2px solid #555555;
|
||||
border-radius: 0;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(255, 255, 255, 0.6),
|
||||
inset -2px -2px 0 rgba(0, 0, 0, 0.25);
|
||||
transition: all 0.1s steps(2, end);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card.pin {
|
||||
background: rgba(210, 210, 210, 0.88);
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card h2 {
|
||||
color: #2a2a2a;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card p {
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card:hover,
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card:focus {
|
||||
background: rgba(212, 224, 198, 0.92);
|
||||
transform: none;
|
||||
border-color: #5c9e40;
|
||||
box-shadow:
|
||||
inset 2px 2px 0 rgba(0, 0, 0, 0.15),
|
||||
inset -2px -2px 0 rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card:hover h2,
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card:focus h2 {
|
||||
color: #5c9e40;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card:hover p,
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .card:focus p {
|
||||
color: #2a2a2a;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .beian a {
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
html[data-theme="light"][data-design-theme="minecraft"] .beian a:hover {
|
||||
color: #5c9e40;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html[data-design-theme="minecraft"] .card,
|
||||
html[data-design-theme="minecraft"] .design-theme-button,
|
||||
html[data-design-theme="minecraft"] .theme-toggle {
|
||||
transition-duration: 0.01ms !important;
|
||||
transform: none !important;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify light mode in browser**
|
||||
|
||||
Toggle to light mode with "我的世界" theme active. Verify:
|
||||
- Background is sky blue gradient (top `#87ceeb` to near-white at bottom)
|
||||
- Cards are stone gray `rgba(198,198,198)` with bevel (light top-left, darker bottom-right)
|
||||
- Cards have NO rounded corners
|
||||
- Card hover turns slightly green-tinted and border goes grass green
|
||||
- 16px grid is faintly visible on the sky background
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add style.css
|
||||
git commit -m "feat: add minecraft light mode CSS"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Final verification
|
||||
|
||||
- [ ] **Step 1: Check `minecraft` is not in FORCED_DARK_DESIGN_THEMES**
|
||||
|
||||
Read `theme.js` line 2. It must remain:
|
||||
```js
|
||||
const FORCED_DARK_DESIGN_THEMES = new Set(["terminal", "cyberpunk"])
|
||||
```
|
||||
"minecraft" must NOT appear here.
|
||||
|
||||
- [ ] **Step 2: Verify theme cycles cleanly**
|
||||
|
||||
Cycle through all 7 themes in the dropdown. No broken styles at any step.
|
||||
|
||||
- [ ] **Step 3: Verify forced-dark restore**
|
||||
|
||||
While on Minecraft (light mode), switch to Terminal (forces dark), then back to Minecraft — should restore light mode.
|
||||
|
||||
- [ ] **Step 4: Run formatter**
|
||||
|
||||
```bash
|
||||
npm run fmt
|
||||
```
|
||||
|
||||
If files changed, commit:
|
||||
```bash
|
||||
git add style.css index.html i18n.js theme.js
|
||||
git commit -m "style: run prettier after minecraft theme"
|
||||
```
|
||||
527
docs/superpowers/plans/2026-05-18-terminal-theme-redesign.md
Normal file
527
docs/superpowers/plans/2026-05-18-terminal-theme-redesign.md
Normal file
@@ -0,0 +1,527 @@
|
||||
# Terminal Theme Redesign 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:** Replace the green-on-black terminal theme with a Dracula-palette soft-modern style (purple accent, rounded cards, dot-matrix background).
|
||||
|
||||
**Architecture:** All changes are in `style.css` — update CSS variable overrides in the `html[data-design-theme="terminal"]` block, then update each component override section below it. No JS changes needed; the forced-dark logic and font chain stay unchanged.
|
||||
|
||||
**Tech Stack:** Vanilla CSS, Vite. No test suite — verification is visual via `npm start`.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-05-18-terminal-theme-design.md`
|
||||
|
||||
---
|
||||
|
||||
## File Map
|
||||
|
||||
| File | Action | What changes |
|
||||
|---|---|---|
|
||||
| `style.css` lines 51–80 | Modify | CSS variables block for terminal theme |
|
||||
| `style.css` lines 702–814 | Modify | All terminal component overrides |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Update CSS variable tokens
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css:51-80`
|
||||
|
||||
- [ ] **Step 1: Replace the terminal theme variable block**
|
||||
|
||||
Find this block (starts at line 51):
|
||||
```css
|
||||
html[data-design-theme="terminal"] {
|
||||
color-scheme: dark;
|
||||
|
||||
--accent: #33ff00;
|
||||
--accent-rgb: 51, 255, 0;
|
||||
--accent-2: #33ff00;
|
||||
--accent-3: #33ff00;
|
||||
--accent-secondary-rgb: 255, 176, 0;
|
||||
|
||||
--page-gradient: #0a0a0a;
|
||||
--page-texture:
|
||||
repeating-linear-gradient(
|
||||
to bottom,
|
||||
rgba(var(--accent-rgb), 0.035) 0px,
|
||||
rgba(var(--accent-rgb), 0.035) 1px,
|
||||
transparent 2px,
|
||||
transparent 4px
|
||||
),
|
||||
radial-gradient(
|
||||
circle at 50% 50%,
|
||||
rgba(var(--accent-rgb), 0.05) 0%,
|
||||
transparent 60%
|
||||
);
|
||||
--title-gradient: none;
|
||||
|
||||
--control-bg: rgba(10, 10, 10, 0.85);
|
||||
--control-border: rgba(var(--accent-rgb), 0.35);
|
||||
--control-inset: transparent;
|
||||
--control-fg: var(--accent);
|
||||
}
|
||||
```
|
||||
|
||||
Replace it with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] {
|
||||
color-scheme: dark;
|
||||
|
||||
--accent: #bd93f9;
|
||||
--accent-rgb: 189, 147, 249;
|
||||
--accent-2: #ff79c6;
|
||||
--accent-3: #8be9fd;
|
||||
--accent-secondary-rgb: 255, 121, 198;
|
||||
|
||||
--page-gradient: #282a36;
|
||||
--page-texture: radial-gradient(
|
||||
circle,
|
||||
rgba(98, 114, 164, 0.55) 1px,
|
||||
transparent 1px
|
||||
);
|
||||
--title-gradient: linear-gradient(90deg, #bd93f9 0%, #ff79c6 100%);
|
||||
|
||||
--control-bg: rgba(40, 42, 54, 0.92);
|
||||
--control-border: #44475a;
|
||||
--control-inset: transparent;
|
||||
--control-fg: #f8f8f2;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Start dev server and verify background color changed**
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
Open the app, switch design theme to **Terminal**. The page background should now be dark blue-purple (`#282a36`) with a faint dot grid, not pure black. The dot grid may be hard to see at first — look closely at a light source on a dark background.
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Fix dot-matrix background size + body text
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` — terminal `body` rule (~line 702) and add `body::before` size rule
|
||||
|
||||
- [ ] **Step 1: Update the terminal body rule**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] body {
|
||||
font-family:
|
||||
ui-monospace, "JetBrains Mono", "Fira Code", "VT323", Menlo, Consolas,
|
||||
"Liberation Mono", monospace;
|
||||
letter-spacing: 0.01em;
|
||||
color: var(--accent);
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] body {
|
||||
font-family:
|
||||
ui-monospace, "JetBrains Mono", "Fira Code", "VT323", Menlo, Consolas,
|
||||
"Liberation Mono", monospace;
|
||||
letter-spacing: 0.01em;
|
||||
color: #f8f8f2;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Add body::before background-size rule immediately after**
|
||||
|
||||
After the `body` rule above, insert:
|
||||
```css
|
||||
html[data-design-theme="terminal"] body::before {
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify in browser**
|
||||
|
||||
The dot matrix texture should now tile visibly at 20px intervals across the `#282a36` background. Body text should be `#f8f8f2` (off-white) instead of green.
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Update title styling
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` — terminal `.title` and `.title::after` rules (~lines 761–775)
|
||||
|
||||
- [ ] **Step 1: Update the title rule**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .title {
|
||||
background: none;
|
||||
-webkit-text-fill-color: currentColor;
|
||||
color: var(--accent);
|
||||
text-shadow: 0 0 5px rgba(var(--accent-rgb), 0.5);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
position: relative;
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .title {
|
||||
background: var(--title-gradient);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
color: transparent;
|
||||
text-shadow: none;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
position: relative;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Update the cursor rule to keep it visible**
|
||||
|
||||
The `::after` pseudo-element inherits `-webkit-text-fill-color: transparent` from the title, which would hide the cursor. Fix it explicitly.
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .title::after {
|
||||
content: "\2588";
|
||||
margin-left: 8px;
|
||||
animation: terminal-cursor-blink 1s step-end infinite;
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .title::after {
|
||||
content: "\2588";
|
||||
margin-left: 8px;
|
||||
animation: terminal-cursor-blink 1s step-end infinite;
|
||||
-webkit-text-fill-color: #bd93f9;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify in browser**
|
||||
|
||||
The page title should now show a purple-to-pink gradient text (uppercase). The blinking `█` cursor should be solid purple (`#bd93f9`), not transparent.
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Update card styling
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` — all terminal `.card` rules (~lines 777–814)
|
||||
|
||||
- [ ] **Step 1: Update the base card rule**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card {
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(var(--accent-rgb), 0.35);
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
transform: none;
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card {
|
||||
border-radius: 10px;
|
||||
background: #313244;
|
||||
border: 1px solid #44475a;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
transform: translateY(0);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Add pin card variant**
|
||||
|
||||
After the base card rule, add:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card.pin {
|
||||
background: #383a4a;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Update card h2, p, and beian (split the combined rule)**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card h2,
|
||||
html[data-design-theme="terminal"] .card p,
|
||||
html[data-design-theme="terminal"] .beian a {
|
||||
color: var(--accent);
|
||||
text-shadow: 0 0 5px rgba(var(--accent-rgb), 0.25);
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card h2 {
|
||||
color: #f8f8f2;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
html[data-design-theme="terminal"] .card p {
|
||||
color: #6272a4;
|
||||
text-shadow: none;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Update card hover/focus**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card:hover,
|
||||
html[data-design-theme="terminal"] .card:focus {
|
||||
background: rgba(var(--accent-rgb), 0.06);
|
||||
border-color: var(--accent);
|
||||
box-shadow: none;
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card:hover,
|
||||
html[data-design-theme="terminal"] .card:focus {
|
||||
background: #313244;
|
||||
border-color: #bd93f9;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(189, 147, 249, 0.25),
|
||||
0 8px 28px rgba(189, 147, 249, 0.15),
|
||||
0 4px 12px rgba(0, 0, 0, 0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Update hover h2 color**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card:hover h2,
|
||||
html[data-design-theme="terminal"] .card:focus h2 {
|
||||
color: var(--accent);
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card:hover h2,
|
||||
html[data-design-theme="terminal"] .card:focus h2 {
|
||||
color: #bd93f9;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 6: Add hover p color rule (currently missing)**
|
||||
|
||||
Immediately after the hover h2 rule, add:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .card:hover p,
|
||||
html[data-design-theme="terminal"] .card:focus p {
|
||||
color: #cdd6f4;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 7: Verify in browser**
|
||||
|
||||
Cards should now have rounded corners, a dark-purple surface (`#313244`), and lift with a purple glow on hover. Card titles should be off-white at rest and turn purple on hover. Card descriptions should be muted (`#6272a4`) at rest and lighten on hover.
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Update controls and dropdown
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` — terminal `.design-theme-button`, `.theme-toggle`, `.design-theme-list` rules (~lines 710–759)
|
||||
|
||||
- [ ] **Step 1: Update the base button/toggle rule**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-button,
|
||||
html[data-design-theme="terminal"] .theme-toggle {
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
border: 1px solid rgba(var(--accent-rgb), 0.55);
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-button,
|
||||
html[data-design-theme="terminal"] .theme-toggle {
|
||||
border-radius: 8px;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
border: 1px solid #44475a;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Update button/toggle hover**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-button:hover,
|
||||
html[data-design-theme="terminal"] .theme-toggle:hover {
|
||||
background: var(--accent);
|
||||
color: #0a0a0a;
|
||||
border-color: var(--accent);
|
||||
transform: none;
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-button:hover,
|
||||
html[data-design-theme="terminal"] .theme-toggle:hover {
|
||||
background: rgba(189, 147, 249, 0.08);
|
||||
color: #bd93f9;
|
||||
border-color: #bd93f9;
|
||||
transform: none;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Update dropdown list**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-list {
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
background: rgba(10, 10, 10, 0.92);
|
||||
border: 1px solid rgba(var(--accent-rgb), 0.55);
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-list {
|
||||
border-radius: 10px;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
background: rgba(40, 42, 54, 0.96);
|
||||
border: 1px solid #44475a;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Update dropdown option hover/selected**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-list [role="option"]:hover,
|
||||
html[data-design-theme="terminal"]
|
||||
.design-theme-list
|
||||
[role="option"][aria-selected="true"] {
|
||||
background: var(--accent);
|
||||
color: #0a0a0a;
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .design-theme-list [role="option"]:hover,
|
||||
html[data-design-theme="terminal"]
|
||||
.design-theme-list
|
||||
[role="option"][aria-selected="true"] {
|
||||
background: rgba(189, 147, 249, 0.15);
|
||||
color: #bd93f9;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Verify in browser**
|
||||
|
||||
The theme selector button should have rounded corners and a dark surface. Hovering it should show a subtle purple tint (not green invert). Opening the dropdown should show a rounded dark panel; hovering or selecting an option highlights it in purple.
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Update beian footer
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` — terminal `.beian a` and `.beian a:hover` rules (~lines 791–814)
|
||||
|
||||
- [ ] **Step 1: Add beian rest-state rule**
|
||||
|
||||
The old combined rule (`.card h2, .card p, .beian a`) was split in Task 4, which removed the beian rest-state color. Insert a new rule immediately **before** the existing `.beian a:hover` rule:
|
||||
|
||||
```css
|
||||
html[data-design-theme="terminal"] .beian a {
|
||||
color: #6272a4;
|
||||
text-shadow: none;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Update beian hover**
|
||||
|
||||
Find:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .beian a:hover {
|
||||
background: var(--accent);
|
||||
color: #0a0a0a;
|
||||
text-shadow: none;
|
||||
}
|
||||
```
|
||||
|
||||
Replace with:
|
||||
```css
|
||||
html[data-design-theme="terminal"] .beian a:hover {
|
||||
color: #bd93f9;
|
||||
background: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify in browser**
|
||||
|
||||
The footer ICP link should appear in muted purple-grey (`#6272a4`) at rest and turn accent purple (`#bd93f9`) on hover, with no background invert.
|
||||
|
||||
---
|
||||
|
||||
### Task 7: Format, QA, and commit
|
||||
|
||||
**Files:**
|
||||
- Modify: `style.css` (formatter pass)
|
||||
|
||||
- [ ] **Step 1: Run Prettier**
|
||||
|
||||
```bash
|
||||
npm run fmt
|
||||
```
|
||||
|
||||
Expected: `style.css` reformatted with no errors.
|
||||
|
||||
- [ ] **Step 2: Full visual QA checklist**
|
||||
|
||||
With `npm start` running, switch to the Terminal theme and check each item:
|
||||
|
||||
| Element | Expected |
|
||||
|---|---|
|
||||
| Page background | `#282a36` dark blue-purple with subtle 20px dot matrix |
|
||||
| Title | Purple-to-pink gradient text, uppercase, blinking purple `█` cursor |
|
||||
| Cards at rest | `#313244` rounded (10px), `#44475a` border, subtle shadow |
|
||||
| Pin card | Slightly lighter surface `#383a4a` |
|
||||
| Card h2 at rest | `#f8f8f2` off-white |
|
||||
| Card p at rest | `#6272a4` muted purple-grey |
|
||||
| Card on hover | Purple border glow, lifts 2px, h2 → `#bd93f9`, p → `#cdd6f4` |
|
||||
| Theme selector button | Rounded 8px, dark surface, purple hover tint (no invert) |
|
||||
| Dropdown panel | Rounded 10px, dark surface, purple option highlight |
|
||||
| Dark toggle | Greyed out / cursor: not-allowed (unchanged) |
|
||||
| Beian footer | `#6272a4` at rest, `#bd93f9` on hover, no bg invert |
|
||||
| Other themes | Completely unaffected — spot-check Cyberpunk and Fluent |
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add style.css
|
||||
git commit -m "redesign: terminal theme — Dracula purple focus (soft modern cards, dot matrix bg)"
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
# Animal Crossing Theme — Sunny Meadow
|
||||
|
||||
**Date:** 2026-05-18
|
||||
**Status:** Approved
|
||||
|
||||
## Summary
|
||||
|
||||
Add a fifth design theme ("animal-crossing") to the hyyzhome IoT learning portal. The theme captures the warm, cozy Animal Crossing aesthetic: leaf greens, cream backgrounds in light mode, and deep forest tones in dark mode.
|
||||
|
||||
Reference: https://guokaigdg.github.io/animal-island-ui/
|
||||
|
||||
## Behavior
|
||||
|
||||
- Supports both light and dark modes (no forced mode, unlike Terminal/Cyberpunk)
|
||||
- Default: follows the user's current light/dark preference
|
||||
- Slug: `"animal-crossing"` (kebab-case, consistent with `"material-you"`)
|
||||
|
||||
## Color Palette
|
||||
|
||||
### Light mode (Sunny Island Day)
|
||||
|
||||
| Token | Value | Role |
|
||||
|---|---|---|
|
||||
| `--accent` | `#6dbc7e` | Primary leaf green |
|
||||
| `--accent-rgb` | `109, 188, 126` | |
|
||||
| `--accent-2` | `#5aad6d` | Darker green |
|
||||
| `--accent-3` | `#4a9e5d` | Deepest green |
|
||||
| `--accent-secondary-rgb` | `244, 200, 66` | Warm yellow for texture |
|
||||
| `--page-gradient` | Warm cream `#fdf6e3` base with soft radial blobs | Background |
|
||||
| `--page-texture` | Soft radial green/yellow gradients | Overlay layer |
|
||||
| `--title-gradient` | `#6dbc7e` → `#5aad6d` → `#f4c842` | Title text fill |
|
||||
| `--control-bg` | `rgba(255, 252, 240, 0.82)` | Button/dropdown backgrounds |
|
||||
| `--control-border` | `rgba(109, 188, 126, 0.35)` | Button borders |
|
||||
| `--control-inset` | `rgba(255, 255, 255, 0.85)` | Inner highlight |
|
||||
| `--control-fg` | `#5c4824` | Warm brown text |
|
||||
| Card bg | `rgba(255, 252, 240, 0.85)` | Creamy white |
|
||||
| Card border | `rgba(109, 188, 126, 0.25)` | Soft green border |
|
||||
| Body text | `#5c4824` | Warm brown |
|
||||
| Muted text (card p) | `#7a6040` | Lighter warm brown |
|
||||
|
||||
### Dark mode (Night on the Island)
|
||||
|
||||
| Token | Value | Role |
|
||||
|---|---|---|
|
||||
| `--accent` | `#9ed98a` | Soft lime |
|
||||
| `--accent-rgb` | `158, 217, 138` | |
|
||||
| `--accent-2` | `#86cb72` | |
|
||||
| `--accent-3` | `#6dbc5e` | |
|
||||
| `--accent-secondary-rgb` | `245, 210, 90` | Lantern yellow |
|
||||
| `--page-gradient` | Deep forest `#1e2d1e` solid | Background |
|
||||
| `--page-texture` | Subtle radial lime/yellow glows | Overlay layer |
|
||||
| `--title-gradient` | `#9ed98a` → `#86cb72` → `#f5d25a` | Title text fill |
|
||||
| `--control-bg` | `rgba(25, 40, 25, 0.82)` | Dark forest controls |
|
||||
| `--control-border` | `rgba(158, 217, 138, 0.25)` | |
|
||||
| `--control-inset` | `rgba(255, 255, 255, 0.04)` | |
|
||||
| `--control-fg` | `#e8f4d8` | Off-white |
|
||||
| Card bg | `rgba(30, 48, 30, 0.82)` | Dark forest green |
|
||||
| Card border | `rgba(158, 217, 138, 0.18)` | |
|
||||
| Body text | `#e8f4d8` | Off-white |
|
||||
| Muted text | `#b0c8a0` | Muted sage |
|
||||
|
||||
## Visual Style
|
||||
|
||||
- **Border radius:** `16px` on cards (vs Fluent's `12px`), `14px` on controls — slightly softer
|
||||
- **Hover:** gentle `translateY(-2px)` lift + green glow shadow matching accent
|
||||
- **Backdrop filter:** same acrylic blur as Fluent (20px blur, 180% saturate)
|
||||
- **No special font override** — system sans-serif for legibility
|
||||
- **No animations** — keeps the theme calm and lightweight
|
||||
|
||||
## Files Changed
|
||||
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| `theme.js` | Add `"animal-crossing"` to `DESIGN_THEMES` array |
|
||||
| `style.css` | Add light + dark CSS variable blocks; card/hover overrides scoped to `[data-design-theme="animal-crossing"]` |
|
||||
| `i18n.js` | Add label in all 11 language variants in `DESIGN_THEME_LABELS` |
|
||||
| `index.html` | Add `<li role="option" data-value="animal-crossing" aria-selected="false">` |
|
||||
|
||||
## Labels by Language
|
||||
|
||||
| Language | Label |
|
||||
|---|---|
|
||||
| zh-Hans | 动森 |
|
||||
| zh-Hant | 動森 |
|
||||
| en | Animal Crossing |
|
||||
| ja | どうぶつの森 |
|
||||
| ko | 동물의 숲 |
|
||||
| wenyan | 森友 |
|
||||
| mars | 动↗森★ |
|
||||
| garbled | ä◼▤è |
|
||||
| bin | 01010101 |
|
||||
| meow | 喵喵喵喵 |
|
||||
| emoji | 🌿 |
|
||||
150
docs/superpowers/specs/2026-05-18-terminal-theme-design.md
Normal file
150
docs/superpowers/specs/2026-05-18-terminal-theme-design.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Terminal Theme Redesign — Design Spec
|
||||
|
||||
**Date:** 2026-05-18
|
||||
**Status:** Approved
|
||||
|
||||
## Summary
|
||||
|
||||
Redesign the existing Terminal design theme from a sparse green-on-black aesthetic into a polished **Dracula-palette, soft-modern** style. The theme keeps its forced-dark, monospace character while gaining a richer color story, rounded cards, and a more refined hover system.
|
||||
|
||||
## Design Direction
|
||||
|
||||
**Palette:** Dracula
|
||||
**Card style:** Soft modern — rounded corners, surface color fill, subtle shadow
|
||||
**Background:** Dot matrix — `#282a36` base with 20px radial dot grid
|
||||
**Accent strategy:** Purple Focus — single primary accent `#bd93f9`, pink `#ff79c6` used only in the title gradient
|
||||
|
||||
## Color Tokens
|
||||
|
||||
| Token | Value | Usage |
|
||||
|---|---|---|
|
||||
| Background | `#282a36` | Page base |
|
||||
| Surface | `#313244` | Card background |
|
||||
| Surface-alt | `#383a4a` | Pin card background |
|
||||
| Border | `#44475a` | Card/control border |
|
||||
| Accent (purple) | `#bd93f9` | Primary accent — borders on hover, h2 on hover, controls on hover, title start |
|
||||
| Pink | `#ff79c6` | Title gradient end only |
|
||||
| Foreground | `#f8f8f2` | Body text, card h2 |
|
||||
| Muted | `#6272a4` | Card p, beian, description |
|
||||
| Hover fg | `#cdd6f4` | Card p on hover |
|
||||
|
||||
CSS variables to set on `html[data-design-theme="terminal"]`:
|
||||
|
||||
```css
|
||||
--accent: #bd93f9;
|
||||
--accent-rgb: 189, 147, 249;
|
||||
--accent-2: #ff79c6;
|
||||
--accent-3: #8be9fd;
|
||||
--accent-secondary-rgb: 255, 121, 198;
|
||||
--page-gradient: #282a36;
|
||||
--page-texture: radial-gradient(circle, rgba(98,114,164,0.55) 1px, transparent 1px);
|
||||
--title-gradient: linear-gradient(90deg, #bd93f9 0%, #ff79c6 100%);
|
||||
--control-bg: rgba(40, 42, 54, 0.92);
|
||||
--control-border: #44475a;
|
||||
--control-inset: transparent;
|
||||
--control-fg: #f8f8f2;
|
||||
```
|
||||
|
||||
The `--page-texture` background-size must be set to `20px 20px` on the `body::before` element for terminal theme.
|
||||
|
||||
## Components
|
||||
|
||||
### Background
|
||||
|
||||
`body` uses `--page-gradient` (`#282a36`) as a flat color.
|
||||
`body::before` applies the dot matrix texture via `--page-texture` at `background-size: 20px 20px`.
|
||||
No `backdrop-filter` anywhere in the terminal theme.
|
||||
|
||||
### Title
|
||||
|
||||
- Gradient text: `linear-gradient(90deg, #bd93f9 0%, #ff79c6 100%)` via `-webkit-background-clip: text`
|
||||
- Uppercase, `letter-spacing: 0.04em`
|
||||
- Blinking `█` cursor via `::after` (`\2588`, unchanged), color `#bd93f9`
|
||||
- Remove the current `text-shadow` (conflicts with gradient text)
|
||||
|
||||
### Cards
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| `background` | `#313244` |
|
||||
| `border` | `1px solid #44475a` |
|
||||
| `border-radius` | `10px` |
|
||||
| `box-shadow` | `0 4px 16px rgba(0,0,0,0.45)` |
|
||||
| `backdrop-filter` | `none` |
|
||||
| `transform` | none (no translateY at rest) |
|
||||
|
||||
**Pin card:** `background: #383a4a`
|
||||
|
||||
**Hover / focus:**
|
||||
- `border-color: #bd93f9`
|
||||
- `box-shadow: 0 0 0 1px rgba(189,147,249,0.25), 0 8px 28px rgba(189,147,249,0.15), 0 4px 12px rgba(0,0,0,0.5)`
|
||||
- `transform: translateY(-2px)`
|
||||
- `h2 color: #bd93f9`
|
||||
- `p color: #cdd6f4`
|
||||
|
||||
**Card `::before`:** `display: none` (no gradient border overlay)
|
||||
|
||||
**Card h2:** `#f8f8f2` at rest
|
||||
**Card p:** `#6272a4` at rest
|
||||
|
||||
### Controls (theme button + toggle)
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| `background` | `rgba(40, 42, 54, 0.92)` |
|
||||
| `border` | `1px solid #44475a` |
|
||||
| `border-radius` | `8px` |
|
||||
| `color` | `#f8f8f2` |
|
||||
| `box-shadow` | `none` |
|
||||
| `backdrop-filter` | `none` |
|
||||
|
||||
**Hover:**
|
||||
- `border-color: #bd93f9`
|
||||
- `color: #bd93f9`
|
||||
- `background: rgba(189, 147, 249, 0.08)`
|
||||
- No `transform`
|
||||
|
||||
**Dark toggle:** remains `cursor: not-allowed` and visually disabled (terminal forces dark).
|
||||
|
||||
### Dropdown list
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| `background` | `rgba(40, 42, 54, 0.96)` |
|
||||
| `border` | `1px solid #44475a` |
|
||||
| `border-radius` | `10px` |
|
||||
| `box-shadow` | `none` |
|
||||
|
||||
**Options hover / selected:** `background: rgba(189, 147, 249, 0.15)`, `color: #bd93f9`
|
||||
**Options:** keep `text-transform: uppercase` (terminal feel)
|
||||
|
||||
### Beian
|
||||
|
||||
- Rest: `#6272a4`
|
||||
- Hover: `#bd93f9` (remove current invert-to-black-bg behavior)
|
||||
|
||||
### Body text
|
||||
|
||||
- `color: #f8f8f2`
|
||||
- Font chain unchanged: `ui-monospace, "JetBrains Mono", "Fira Code", "VT323", Menlo, Consolas, "Liberation Mono", monospace`
|
||||
|
||||
## What Changes vs Current
|
||||
|
||||
| Element | Before | After |
|
||||
|---|---|---|
|
||||
| Accent color | `#33ff00` green | `#bd93f9` purple |
|
||||
| Background | `#0a0a0a` | `#282a36` |
|
||||
| Texture | Horizontal scanlines | Dot matrix 20px |
|
||||
| Card bg | Transparent | `#313244` surface fill |
|
||||
| Card corners | `border-radius: 0` | `border-radius: 10px` |
|
||||
| Card hover | Green tint bg | Purple glow + lift |
|
||||
| Title | Green text-shadow | Purple→pink gradient |
|
||||
| Button hover | Full green bg invert | Subtle purple tint |
|
||||
| Dropdown options | Uppercase, green invert | Uppercase, purple highlight |
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- No changes to any other theme (Fluent, Material You, Nord, Cyberpunk, Animal Crossing, Minecraft)
|
||||
- No new animations beyond the existing cursor blink
|
||||
- No changes to `FORCED_DARK_DESIGN_THEMES` logic — terminal still forces dark
|
||||
- No font changes
|
||||
33
i18n.js
33
i18n.js
@@ -140,6 +140,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "终端",
|
||||
cyberpunk: "赛博朋克",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "动森",
|
||||
minecraft: "我的世界",
|
||||
"persona-5": "女神异闻录 5",
|
||||
},
|
||||
"zh-Hant": {
|
||||
fluent: "Fluent",
|
||||
@@ -147,6 +150,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "終端",
|
||||
cyberpunk: "賽博龐克",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "動森",
|
||||
minecraft: "我的世界",
|
||||
"persona-5": "女神異聞錄 5",
|
||||
},
|
||||
en: {
|
||||
fluent: "Fluent",
|
||||
@@ -154,6 +160,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "Terminal",
|
||||
cyberpunk: "Cyberpunk",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "Animal Crossing",
|
||||
minecraft: "Minecraft",
|
||||
"persona-5": "Persona 5",
|
||||
},
|
||||
ja: {
|
||||
fluent: "Fluent",
|
||||
@@ -161,6 +170,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "ターミナル",
|
||||
cyberpunk: "サイバーパンク",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "どうぶつの森",
|
||||
minecraft: "マインクラフト",
|
||||
"persona-5": "ペルソナ5",
|
||||
},
|
||||
ko: {
|
||||
fluent: "Fluent",
|
||||
@@ -168,6 +180,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "터미널",
|
||||
cyberpunk: "사이버펑크",
|
||||
nord: "Nord",
|
||||
"animal-crossing": "동물의 숲",
|
||||
minecraft: "마인크래프트",
|
||||
"persona-5": "페르소나 5",
|
||||
},
|
||||
wenyan: {
|
||||
fluent: "流光",
|
||||
@@ -175,6 +190,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "终端",
|
||||
cyberpunk: "赛博",
|
||||
nord: "清寒",
|
||||
"animal-crossing": "森友",
|
||||
minecraft: "方块世界",
|
||||
"persona-5": "异闻录五",
|
||||
},
|
||||
mars: {
|
||||
fluent: "流↗光",
|
||||
@@ -182,6 +200,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "終↗★端",
|
||||
cyberpunk: "賽↘!博",
|
||||
nord: "清↗寒★",
|
||||
"animal-crossing": "动↗森★",
|
||||
minecraft: "我↗的★世界",
|
||||
"persona-5": "女↘神★异闻5",
|
||||
},
|
||||
garbled: {
|
||||
fluent: "◼è▦",
|
||||
@@ -189,6 +210,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "¥¬▤▨¿¿",
|
||||
cyberpunk: "◼çæ¥烫¥",
|
||||
nord: "æ◽屯¿",
|
||||
"animal-crossing": "ä◼▤è",
|
||||
minecraft: "▤◼▦è屯",
|
||||
"persona-5": "▦¥◼ç5",
|
||||
},
|
||||
bin: {
|
||||
fluent: "0101",
|
||||
@@ -196,6 +220,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "01010101",
|
||||
cyberpunk: "0101010101",
|
||||
nord: "0101010",
|
||||
"animal-crossing": "01010101",
|
||||
minecraft: "0101010",
|
||||
"persona-5": "01010101",
|
||||
},
|
||||
meow: {
|
||||
fluent: "喵喵",
|
||||
@@ -203,6 +230,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "喵喵",
|
||||
cyberpunk: "喵喵喵喵",
|
||||
nord: "喵喵喵",
|
||||
"animal-crossing": "喵喵喵喵",
|
||||
minecraft: "喵喵喵",
|
||||
"persona-5": "喵喵喵喵喵",
|
||||
},
|
||||
emoji: {
|
||||
fluent: "💧",
|
||||
@@ -210,6 +240,9 @@ export const DESIGN_THEME_LABELS = {
|
||||
terminal: "⌨️",
|
||||
cyberpunk: "⚡",
|
||||
nord: "❄️",
|
||||
"animal-crossing": "🌿",
|
||||
minecraft: "⛏️",
|
||||
"persona-5": "🎭",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
16
index.html
16
index.html
@@ -42,8 +42,15 @@
|
||||
<li role="option" data-value="cyberpunk" aria-selected="false">
|
||||
Cyberpunk
|
||||
</li>
|
||||
<li role="option" data-value="nord" aria-selected="false">
|
||||
Nord
|
||||
<li role="option" data-value="nord" aria-selected="false">Nord</li>
|
||||
<li role="option" data-value="animal-crossing" aria-selected="false">
|
||||
Animal Crossing
|
||||
</li>
|
||||
<li role="option" data-value="minecraft" aria-selected="false">
|
||||
Minecraft
|
||||
</li>
|
||||
<li role="option" data-value="persona-5" aria-selected="false">
|
||||
Persona 5
|
||||
</li>
|
||||
</ul>
|
||||
</label>
|
||||
@@ -110,7 +117,10 @@
|
||||
<div class="container">
|
||||
<main class="main">
|
||||
<h1 class="title" data-i18n="appTitle">
|
||||
物联网专业の在线学习平台<span class="title-cursor" aria-hidden="true"></span>
|
||||
物联网专业の在线学习平台<span
|
||||
class="title-cursor"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
</h1>
|
||||
<div class="grid" id="sites"></div>
|
||||
</main>
|
||||
|
||||
BIN
public/textures/ac-tile.webp
Normal file
BIN
public/textures/ac-tile.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 158 KiB |
11
theme.js
11
theme.js
@@ -1,4 +1,13 @@
|
||||
const DESIGN_THEMES = ["fluent", "material-you", "terminal", "cyberpunk", "nord"]
|
||||
const DESIGN_THEMES = [
|
||||
"fluent",
|
||||
"material-you",
|
||||
"terminal",
|
||||
"cyberpunk",
|
||||
"nord",
|
||||
"animal-crossing",
|
||||
"minecraft",
|
||||
"persona-5",
|
||||
]
|
||||
const FORCED_DARK_DESIGN_THEMES = new Set(["terminal", "cyberpunk"])
|
||||
const THEME_BEFORE_FORCED_KEY = "themeBeforeForcedDark"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user