@whykusanagi/corrupted-theme 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +157 -0
- package/README.md +6 -0
- package/docs/CHARACTER_LEVEL_CORRUPTION.md +264 -0
- package/docs/CORRUPTION_PHRASES.md +529 -0
- package/docs/ROADMAP.md +266 -0
- package/docs/STYLE_GUIDE.md +605 -0
- package/docs/brand/BRAND_OVERVIEW.md +413 -0
- package/docs/brand/COLOR_SYSTEM.md +583 -0
- package/docs/brand/DESIGN_TOKENS.md +1009 -0
- package/docs/brand/TRANSLATION_FAILURE_AESTHETIC.md +525 -0
- package/docs/brand/TYPOGRAPHY.md +624 -0
- package/docs/components/ANIMATION_GUIDELINES.md +901 -0
- package/docs/components/COMPONENT_LIBRARY.md +1061 -0
- package/docs/components/GLASSMORPHISM.md +602 -0
- package/docs/components/INTERACTIVE_STATES.md +766 -0
- package/docs/governance/CONTRIBUTION_GUIDELINES.md +593 -0
- package/docs/governance/DESIGN_SYSTEM_GOVERNANCE.md +451 -0
- package/docs/governance/VERSION_MANAGEMENT.md +447 -0
- package/docs/governance/VERSION_REFERENCES.md +229 -0
- package/docs/platforms/COMPONENT_MAPPING.md +579 -0
- package/docs/platforms/NPM_PACKAGE.md +854 -0
- package/docs/platforms/WEB_IMPLEMENTATION.md +1221 -0
- package/docs/standards/ACCESSIBILITY.md +715 -0
- package/docs/standards/ANTI_PATTERNS.md +554 -0
- package/docs/standards/SPACING_SYSTEM.md +549 -0
- package/examples/button.html +1 -1
- package/examples/card.html +1 -1
- package/examples/form.html +1 -1
- package/examples/index.html +2 -2
- package/examples/layout.html +1 -1
- package/examples/nikke-team-builder.html +1 -1
- package/examples/showcase-complete.html +840 -15
- package/examples/showcase.html +1 -1
- package/package.json +16 -3
- package/src/css/components.css +676 -0
- package/src/lib/character-corruption.js +563 -0
- package/src/lib/components.js +283 -0
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
# Component Mapping Guide
|
|
2
|
+
|
|
3
|
+
> **Celeste Brand System** | Platform Documentation
|
|
4
|
+
> **Document**: Cross-Platform Component Mapping
|
|
5
|
+
> **Version**: 1.0.0
|
|
6
|
+
> **Last Updated**: 2025-12-13
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
1. [Overview](#overview)
|
|
13
|
+
2. [Complete Mapping Table](#complete-mapping-table)
|
|
14
|
+
3. [Container Components](#container-components)
|
|
15
|
+
4. [Interactive Components](#interactive-components)
|
|
16
|
+
5. [Data Display Components](#data-display-components)
|
|
17
|
+
6. [Feedback Components](#feedback-components)
|
|
18
|
+
7. [Implementation Comparison](#implementation-comparison)
|
|
19
|
+
8. [When to Diverge](#when-to-diverge)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Overview
|
|
24
|
+
|
|
25
|
+
This document maps **web components** (from @whykusanagi/corrupted-theme) to their **CLI equivalents** (from celeste-cli), showing how the same visual language translates across platforms.
|
|
26
|
+
|
|
27
|
+
### Mapping Philosophy
|
|
28
|
+
|
|
29
|
+
- **Visual Consistency**: Same brand aesthetic across platforms
|
|
30
|
+
- **Platform-Appropriate**: Respect each platform's constraints
|
|
31
|
+
- **Functional Equivalence**: Same purpose, different implementation
|
|
32
|
+
- **Shared Attributes**: Same colors, spacing ratios, corruption intensity
|
|
33
|
+
|
|
34
|
+
### Legend
|
|
35
|
+
|
|
36
|
+
| Symbol | Meaning |
|
|
37
|
+
|--------|---------|
|
|
38
|
+
| ✅ | 1:1 equivalent (same visual + function) |
|
|
39
|
+
| 🔄 | Adapted (same purpose, different implementation) |
|
|
40
|
+
| 🌐 | Web-only (no CLI equivalent) |
|
|
41
|
+
| 💻 | CLI-only (no web equivalent) |
|
|
42
|
+
| ⚠️ | Partial match (limited similarity) |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Complete Mapping Table
|
|
47
|
+
|
|
48
|
+
| npm Component | CLI Pattern | Match | Shared Attributes | Notes |
|
|
49
|
+
|---------------|-------------|-------|-------------------|-------|
|
|
50
|
+
| **Containers** |
|
|
51
|
+
| `.glass-card` | Dashboard section with borders | ✅ | Pink borders, glass bg, padding | Perfect 1:1 match |
|
|
52
|
+
| `.glass-panel` | Full-screen TUI view | ✅ | Background blur simulation | Uses block chars |
|
|
53
|
+
| `.container` | Terminal width container (80-120 chars) | ✅ | Max-width, centered | Responsive width |
|
|
54
|
+
| `.section` | Vertical section spacing | ✅ | 2-3 line gaps | Line-based spacing |
|
|
55
|
+
| `.box` | `lipgloss.Border()` box | ✅ | Rounded borders, padding | Unicode box chars |
|
|
56
|
+
| `.modal` | Alt-screen buffer | 🔄 | Full-screen overlay | Different UX pattern |
|
|
57
|
+
| `.sidebar` | N/A | 🌐 | N/A | Web-only (no CLI sidebar) |
|
|
58
|
+
| `.drawer` | N/A | 🌐 | N/A | Web-only (slide-out panels) |
|
|
59
|
+
| **Interactive** |
|
|
60
|
+
| `.btn` | Highlighted option with arrow | ✅ | Accent color, hover state | `[•] OPTION` pattern |
|
|
61
|
+
| `.btn-primary` | Primary action indicator | ✅ | Pink/bold text | Most prominent |
|
|
62
|
+
| `.btn-secondary` | Secondary option | ✅ | Muted color | Less prominent |
|
|
63
|
+
| `.input` | Text input field | ✅ | Border, padding | `textinput` component |
|
|
64
|
+
| `.textarea` | Multi-line input | ✅ | Scrollable content | `textarea` component |
|
|
65
|
+
| `.select` | Arrow-key selection list | ✅ | Highlighted option | `list` component |
|
|
66
|
+
| `.checkbox` | `[x]` / `[ ]` indicator | ✅ | Square brackets | Literal checkbox chars |
|
|
67
|
+
| `.radio` | `(•)` / `( )` indicator | ✅ | Round brackets | Literal radio chars |
|
|
68
|
+
| `.toggle` | `[ON/OFF]` text | 🔄 | Bold state indicator | Text-based toggle |
|
|
69
|
+
| `.slider` | Progress bar with handle | 🔄 | Block character bar | `████▓▒░░` pattern |
|
|
70
|
+
| `.dropdown` | Vertical list | ✅ | Arrow navigation | Same UX pattern |
|
|
71
|
+
| `.tooltip` | Status line message | 🔄 | Bottom-aligned text | No hover in terminal |
|
|
72
|
+
| **Data Display** |
|
|
73
|
+
| `.badge` | Emoji status indicator | ✅ | 🟢🟡🔴 color-coded | Same colors |
|
|
74
|
+
| `.pill` | `[TAG]` bracket notation | 🔄 | Brackets + color | Text-based |
|
|
75
|
+
| `.tag` | Same as `.pill` | 🔄 | Brackets + color | Identical to pill |
|
|
76
|
+
| `.progress-bar` | `████▓▒░░` block chars | ✅ | Fill/empty ratio | Perfect match |
|
|
77
|
+
| `.progress-circle` | Percentage text | 🔄 | `67%` display | No circles in terminal |
|
|
78
|
+
| `.table` | Box-drawing table | ✅ | Unicode borders | `├─┼─┤` pattern |
|
|
79
|
+
| `.stat-card` | Dashboard stat block | ✅ | Label + large number | Identical layout |
|
|
80
|
+
| `.list` | Bullet list | ✅ | `•` or `[•]` markers | Same bullets |
|
|
81
|
+
| `.icon` | Emoji or Unicode symbol | ✅ | Same emoji set | Limited icon set |
|
|
82
|
+
| `.avatar` | Initials or emoji | 🔄 | First letter or emoji | No images |
|
|
83
|
+
| `.image` | N/A | 🌐 | N/A | No images in terminal |
|
|
84
|
+
| `.code-block` | Syntax-highlighted text | ✅ | Same colors | ANSI color codes |
|
|
85
|
+
| `.kbd` | `<key>` notation | ✅ | Same format | `<Ctrl+C>` |
|
|
86
|
+
| `.divider` | `───────────` horizontal line | ✅ | Full-width line | Unicode chars |
|
|
87
|
+
| `.spinner` | `⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏` animation | ✅ | 150ms frame rate | Same timing |
|
|
88
|
+
| **Navigation** |
|
|
89
|
+
| `.navbar` | N/A | 🌐 | N/A | Web-only (persistent header) |
|
|
90
|
+
| `.breadcrumb` | Status line path | 🔄 | `/path/to/current` | Bottom status |
|
|
91
|
+
| `.tabs` | Mode indicator | 🔄 | `[CHAT] [STATS]` | Text-based tabs |
|
|
92
|
+
| `.pagination` | Page numbers | ✅ | `Page 2 of 10` | Same format |
|
|
93
|
+
| `.stepper` | Progress steps | 🔄 | `1 → 2 → 3` | Arrow notation |
|
|
94
|
+
| `.menu` | Vertical option list | ✅ | Arrow navigation | Same pattern |
|
|
95
|
+
| **Feedback** |
|
|
96
|
+
| `.alert` | Banner message | ✅ | Colored border + icon | Same layout |
|
|
97
|
+
| `.toast` | Temporary message | 🔄 | Bottom status line | Different position |
|
|
98
|
+
| `.notification` | Badge count | ✅ | `[3]` number indicator | Same format |
|
|
99
|
+
| `.loading` | Spinner + text | ✅ | Same spinner | Identical animation |
|
|
100
|
+
| `.skeleton` | `░░░░░` placeholder | 🔄 | Light block chars | Text-based |
|
|
101
|
+
| **Extensions** |
|
|
102
|
+
| `.accordion` | Collapsible section | 🔄 | `▼ Expanded` / `▶ Collapsed` | Arrow indicators |
|
|
103
|
+
| `.carousel` | N/A | 🌐 | N/A | Web-only (image slider) |
|
|
104
|
+
| `.lightbox` | N/A | 🌐 | N/A | Web-only (image viewer) |
|
|
105
|
+
| `.popover` | Inline message | 🔄 | Indented text | No floating UI |
|
|
106
|
+
| `.calendar` | N/A | 🌐 | N/A | Web-only (date picker) |
|
|
107
|
+
| `.chart` | ASCII bar chart | 🔄 | `▇▇▅▃` bars | Text-based visualization |
|
|
108
|
+
| `.timeline` | Vertical list with markers | 🔄 | `│─┬─┴` connectors | Unicode chars |
|
|
109
|
+
| `.rating` | Star count text | 🔄 | `★★★★☆ 4/5` | Star chars |
|
|
110
|
+
| `.video` | N/A | 🌐 | N/A | Web-only (video player) |
|
|
111
|
+
| `.audio` | N/A | 🌐 | N/A | Web-only (audio player) |
|
|
112
|
+
|
|
113
|
+
**Summary**:
|
|
114
|
+
- ✅ **30 components** with 1:1 equivalents (53%)
|
|
115
|
+
- 🔄 **18 components** adapted for platform (32%)
|
|
116
|
+
- 🌐 **8 components** web-only (14%)
|
|
117
|
+
- 💻 **0 components** CLI-only (CLI uses web equivalents)
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Container Components
|
|
122
|
+
|
|
123
|
+
### Glass Card
|
|
124
|
+
|
|
125
|
+
**Purpose**: Primary content container with glassmorphism effect
|
|
126
|
+
|
|
127
|
+
#### Web (`.glass-card`)
|
|
128
|
+
```html
|
|
129
|
+
<div class="glass-card">
|
|
130
|
+
<h2>US使AGE STAT統ISTICS</h2>
|
|
131
|
+
<p>Content here</p>
|
|
132
|
+
</div>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```css
|
|
136
|
+
.glass-card {
|
|
137
|
+
background: rgba(20, 12, 40, 0.7);
|
|
138
|
+
backdrop-filter: blur(15px);
|
|
139
|
+
border: 1px solid rgba(217, 79, 144, 0.3);
|
|
140
|
+
border-radius: 8px;
|
|
141
|
+
padding: 2rem;
|
|
142
|
+
box-shadow: 0 4px 16px rgba(217, 79, 144, 0.25);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### CLI (Dashboard Section)
|
|
147
|
+
```go
|
|
148
|
+
// Equivalent using Lip Gloss
|
|
149
|
+
style := lipgloss.NewStyle().
|
|
150
|
+
Border(lipgloss.RoundedBorder()).
|
|
151
|
+
BorderForeground(lipgloss.Color("#d94f90")).
|
|
152
|
+
Padding(1, 2).
|
|
153
|
+
Render("US使AGE STAT統ISTICS\n\nContent here")
|
|
154
|
+
|
|
155
|
+
// Output:
|
|
156
|
+
// ╭────────────────────────╮
|
|
157
|
+
// │ US使AGE STAT統ISTICS │
|
|
158
|
+
// │ │
|
|
159
|
+
// │ Content here │
|
|
160
|
+
// ╰────────────────────────╯
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Shared Attributes**:
|
|
164
|
+
- Pink border (`#d94f90`)
|
|
165
|
+
- Internal padding (2rem / 2 chars)
|
|
166
|
+
- Rounded corners (border-radius / unicode rounded borders)
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Interactive Components
|
|
171
|
+
|
|
172
|
+
### Button
|
|
173
|
+
|
|
174
|
+
**Purpose**: Primary action trigger
|
|
175
|
+
|
|
176
|
+
#### Web (`.btn`)
|
|
177
|
+
```html
|
|
178
|
+
<button class="btn btn-primary">
|
|
179
|
+
Confirm
|
|
180
|
+
</button>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```css
|
|
184
|
+
.btn-primary {
|
|
185
|
+
background: rgba(217, 79, 144, 0.2);
|
|
186
|
+
border: 1px solid rgba(217, 79, 144, 0.3);
|
|
187
|
+
color: #ffffff;
|
|
188
|
+
padding: 0.75rem 1.5rem;
|
|
189
|
+
transition: transform 0.15s ease;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.btn-primary:hover {
|
|
193
|
+
background: rgba(217, 79, 144, 0.3);
|
|
194
|
+
transform: scale(1.05);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### CLI (Selection Indicator)
|
|
199
|
+
```go
|
|
200
|
+
// Highlighted option with arrow
|
|
201
|
+
func RenderOption(label string, selected bool) string {
|
|
202
|
+
if selected {
|
|
203
|
+
return lipgloss.NewStyle().
|
|
204
|
+
Foreground(lipgloss.Color("#d94f90")).
|
|
205
|
+
Bold(true).
|
|
206
|
+
Render("[•] " + label) // Pink + bullet
|
|
207
|
+
}
|
|
208
|
+
return lipgloss.NewStyle().
|
|
209
|
+
Foreground(lipgloss.Color("#606060")).
|
|
210
|
+
Render("[ ] " + label) // Gray + empty bracket
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Output:
|
|
214
|
+
// [•] Confirm ← Selected (pink, bold)
|
|
215
|
+
// [ ] Cancel ← Not selected (gray)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Shared Attributes**:
|
|
219
|
+
- Accent color for selected state (`#d94f90`)
|
|
220
|
+
- Bold text for emphasis
|
|
221
|
+
- Visual indicator (border / bracket)
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Data Display Components
|
|
226
|
+
|
|
227
|
+
### Progress Bar
|
|
228
|
+
|
|
229
|
+
**Purpose**: Show completion percentage
|
|
230
|
+
|
|
231
|
+
#### Web (`.progress-bar`)
|
|
232
|
+
```html
|
|
233
|
+
<div class="progress-bar" data-percent="67">
|
|
234
|
+
<div class="progress-fill" style="width: 67%"></div>
|
|
235
|
+
</div>
|
|
236
|
+
<span class="progress-label">67%</span>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
```css
|
|
240
|
+
.progress-bar {
|
|
241
|
+
width: 100%;
|
|
242
|
+
height: 8px;
|
|
243
|
+
background: rgba(255, 255, 255, 0.1);
|
|
244
|
+
border-radius: 4px;
|
|
245
|
+
overflow: hidden;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.progress-fill {
|
|
249
|
+
height: 100%;
|
|
250
|
+
background: linear-gradient(90deg, #d94f90, #8b5cf6);
|
|
251
|
+
transition: width 0.3s ease;
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### CLI (Block Characters)
|
|
256
|
+
```go
|
|
257
|
+
// Block character progress bar
|
|
258
|
+
func RenderProgress(percent float64, width int) string {
|
|
259
|
+
filled := int(percent * float64(width))
|
|
260
|
+
bar := strings.Repeat("█", filled) // Full blocks
|
|
261
|
+
bar += strings.Repeat("░", width-filled) // Empty blocks
|
|
262
|
+
|
|
263
|
+
return lipgloss.NewStyle().
|
|
264
|
+
Foreground(lipgloss.Color("#d94f90")).
|
|
265
|
+
Render(fmt.Sprintf("[%s] %.0f%%", bar, percent*100))
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Output: [████████░░░░] 67%
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Shared Attributes**:
|
|
272
|
+
- Fill/empty visual ratio
|
|
273
|
+
- Accent color gradient (`#d94f90` → `#8b5cf6`)
|
|
274
|
+
- Percentage label
|
|
275
|
+
- 300ms update timing
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Feedback Components
|
|
280
|
+
|
|
281
|
+
### Alert
|
|
282
|
+
|
|
283
|
+
**Purpose**: Show important messages with severity levels
|
|
284
|
+
|
|
285
|
+
#### Web (`.alert`)
|
|
286
|
+
```html
|
|
287
|
+
<div class="alert alert-success">
|
|
288
|
+
✓ Successfully saved data
|
|
289
|
+
</div>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
```css
|
|
293
|
+
.alert {
|
|
294
|
+
background: rgba(20, 12, 40, 0.9);
|
|
295
|
+
border-left: 4px solid;
|
|
296
|
+
padding: 1rem;
|
|
297
|
+
border-radius: 4px;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.alert-success {
|
|
301
|
+
border-color: #10b981; /* Green */
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.alert-error {
|
|
305
|
+
border-color: #ef4444; /* Red */
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
#### CLI (Banner Message)
|
|
310
|
+
```go
|
|
311
|
+
// Alert banner with colored border
|
|
312
|
+
func RenderAlert(message string, severity string) string {
|
|
313
|
+
var color lipgloss.Color
|
|
314
|
+
|
|
315
|
+
switch severity {
|
|
316
|
+
case "success":
|
|
317
|
+
color = lipgloss.Color("#10b981") // Green
|
|
318
|
+
case "error":
|
|
319
|
+
color = lipgloss.Color("#ef4444") // Red
|
|
320
|
+
case "warning":
|
|
321
|
+
color = lipgloss.Color("#f59e0b") // Orange
|
|
322
|
+
default:
|
|
323
|
+
color = lipgloss.Color("#3b82f6") // Blue
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return lipgloss.NewStyle().
|
|
327
|
+
BorderStyle(lipgloss.RoundedBorder()).
|
|
328
|
+
BorderForeground(color).
|
|
329
|
+
BorderLeft(true).
|
|
330
|
+
Padding(0, 2).
|
|
331
|
+
Render(message)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Output:
|
|
335
|
+
// │ ✓ Successfully saved data
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Shared Attributes**:
|
|
339
|
+
- Colored left border indicating severity
|
|
340
|
+
- Same color palette (green/red/orange/blue)
|
|
341
|
+
- Padding around message
|
|
342
|
+
- Icon prefix (✓ ✗ ⚠ ℹ)
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Implementation Comparison
|
|
347
|
+
|
|
348
|
+
### Side-by-Side: Stat Card
|
|
349
|
+
|
|
350
|
+
#### Web Implementation
|
|
351
|
+
```html
|
|
352
|
+
<div class="glass-card stat-card">
|
|
353
|
+
<div class="stat-icon">📊</div>
|
|
354
|
+
<h3>US使AGE</h3>
|
|
355
|
+
<p class="stat-value">1,234</p>
|
|
356
|
+
<p class="stat-change">+12.5%</p>
|
|
357
|
+
</div>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
```css
|
|
361
|
+
.stat-card {
|
|
362
|
+
text-align: center;
|
|
363
|
+
padding: 2rem;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.stat-icon {
|
|
367
|
+
font-size: 3rem;
|
|
368
|
+
margin-bottom: 1rem;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.stat-value {
|
|
372
|
+
font-size: 2.5rem;
|
|
373
|
+
font-weight: 700;
|
|
374
|
+
color: #d94f90;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.stat-change {
|
|
378
|
+
color: #10b981; /* Green for positive */
|
|
379
|
+
font-size: 0.875rem;
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### CLI Implementation
|
|
384
|
+
```go
|
|
385
|
+
func RenderStatCard(label string, value int, change float64) string {
|
|
386
|
+
icon := "📊"
|
|
387
|
+
corruptedLabel := CorruptTextJapanese(label, 0.3)
|
|
388
|
+
|
|
389
|
+
valueStr := lipgloss.NewStyle().
|
|
390
|
+
Foreground(lipgloss.Color("#d94f90")).
|
|
391
|
+
Bold(true).
|
|
392
|
+
Render(fmt.Sprintf("%d", value))
|
|
393
|
+
|
|
394
|
+
changeColor := lipgloss.Color("#10b981") // Green
|
|
395
|
+
if change < 0 {
|
|
396
|
+
changeColor = lipgloss.Color("#ef4444") // Red
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
changeStr := lipgloss.NewStyle().
|
|
400
|
+
Foreground(changeColor).
|
|
401
|
+
Render(fmt.Sprintf("%+.1f%%", change))
|
|
402
|
+
|
|
403
|
+
content := fmt.Sprintf(
|
|
404
|
+
"%s\n\n%s\n%s\n%s",
|
|
405
|
+
icon,
|
|
406
|
+
corruptedLabel,
|
|
407
|
+
valueStr,
|
|
408
|
+
changeStr,
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
return lipgloss.NewStyle().
|
|
412
|
+
Border(lipgloss.RoundedBorder()).
|
|
413
|
+
BorderForeground(lipgloss.Color("#d94f90")).
|
|
414
|
+
Padding(1, 2).
|
|
415
|
+
Align(lipgloss.Center).
|
|
416
|
+
Width(24).
|
|
417
|
+
Render(content)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Output:
|
|
421
|
+
// ╭──────────────────────╮
|
|
422
|
+
// │ 📊 │
|
|
423
|
+
// │ │
|
|
424
|
+
// │ US使AGE │
|
|
425
|
+
// │ 1,234 │
|
|
426
|
+
// │ +12.5% │
|
|
427
|
+
// ╰──────────────────────╯
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Analysis**:
|
|
431
|
+
- ✅ **Identical layout**: Icon, label, value, change
|
|
432
|
+
- ✅ **Same colors**: Pink value, green/red change
|
|
433
|
+
- ✅ **Same corruption**: 30% intensity on label
|
|
434
|
+
- ✅ **Same spacing**: Center-aligned, padded
|
|
435
|
+
- 🔄 **Different size units**: rem (web) vs char count (CLI)
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## When to Diverge
|
|
440
|
+
|
|
441
|
+
### Platform-Specific Constraints
|
|
442
|
+
|
|
443
|
+
#### Web: Hover States
|
|
444
|
+
```css
|
|
445
|
+
/* Web supports hover (mouse input) */
|
|
446
|
+
.btn:hover {
|
|
447
|
+
transform: scale(1.05);
|
|
448
|
+
box-shadow: 0 0 20px rgba(217, 79, 144, 0.4);
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
```go
|
|
453
|
+
// CLI: No hover, use selection indicator instead
|
|
454
|
+
func RenderButton(label string, selected bool) string {
|
|
455
|
+
if selected {
|
|
456
|
+
return "[•] " + label // Selection indicator
|
|
457
|
+
}
|
|
458
|
+
return "[ ] " + label
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
#### CLI: Keyboard-Only Navigation
|
|
463
|
+
```go
|
|
464
|
+
// CLI uses keyboard shortcuts (no mouse)
|
|
465
|
+
const (
|
|
466
|
+
KeyUp = "↑"
|
|
467
|
+
KeyDown = "↓"
|
|
468
|
+
KeyEnter = "⏎"
|
|
469
|
+
KeyQuit = "q"
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
// Web uses full event system
|
|
473
|
+
document.addEventListener('click', handler);
|
|
474
|
+
document.addEventListener('keydown', handler);
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Performance Constraints
|
|
478
|
+
|
|
479
|
+
#### Web: Animation-Heavy
|
|
480
|
+
```css
|
|
481
|
+
/* Web can handle complex animations */
|
|
482
|
+
@keyframes glitch {
|
|
483
|
+
0%, 100% { transform: translate(0); }
|
|
484
|
+
20% { transform: translate(-2px, 2px); }
|
|
485
|
+
40% { transform: translate(2px, -2px); }
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.glitch {
|
|
489
|
+
animation: glitch 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55);
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
```go
|
|
494
|
+
// CLI: Limited to frame-based animations
|
|
495
|
+
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
496
|
+
case tickMsg:
|
|
497
|
+
m.frame++
|
|
498
|
+
// Update every 150ms (terminal refresh constraint)
|
|
499
|
+
return m, tick(150 * time.Millisecond)
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Visual Capabilities
|
|
504
|
+
|
|
505
|
+
#### Web: Backdrop-Filter
|
|
506
|
+
```css
|
|
507
|
+
/* Web: True glassmorphism with backdrop-filter */
|
|
508
|
+
.glass-card {
|
|
509
|
+
background: rgba(20, 12, 40, 0.7);
|
|
510
|
+
backdrop-filter: blur(15px);
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
```go
|
|
515
|
+
// CLI: Simulate with block characters
|
|
516
|
+
func RenderGlass() string {
|
|
517
|
+
// Use block chars to simulate blur
|
|
518
|
+
return strings.Repeat("░", width) // Light block pattern
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Decision Tree: When to Use Each Component
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
Need a container?
|
|
528
|
+
├─ Web: Use .glass-card (true glassmorphism)
|
|
529
|
+
└─ CLI: Use lipgloss.Border() with rounded corners
|
|
530
|
+
|
|
531
|
+
Need a button?
|
|
532
|
+
├─ Web: Use .btn with hover states
|
|
533
|
+
└─ CLI: Use [•] selection indicator
|
|
534
|
+
|
|
535
|
+
Need a progress bar?
|
|
536
|
+
├─ Web: Use .progress-bar with smooth animation
|
|
537
|
+
└─ CLI: Use ████▓▒░░ block characters (same visual)
|
|
538
|
+
|
|
539
|
+
Need an alert?
|
|
540
|
+
├─ Web: Use .alert with colored border
|
|
541
|
+
└─ CLI: Use banner with colored border (identical)
|
|
542
|
+
|
|
543
|
+
Need navigation?
|
|
544
|
+
├─ Web: Use .navbar (persistent header)
|
|
545
|
+
└─ CLI: Use status line (bottom, non-persistent)
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## Component Equivalence Matrix
|
|
551
|
+
|
|
552
|
+
| Feature | Web Support | CLI Support | Implementation Difference |
|
|
553
|
+
|---------|-------------|-------------|---------------------------|
|
|
554
|
+
| **Glassmorphism** | ✅ Native (backdrop-filter) | 🔄 Simulated (block chars) | Visual approximation |
|
|
555
|
+
| **Hover States** | ✅ Native (CSS :hover) | ❌ Not available | Use selection instead |
|
|
556
|
+
| **Smooth Animations** | ✅ 60fps CSS animations | ✅ 60fps frame-based | Same timing, different method |
|
|
557
|
+
| **Color Gradients** | ✅ Native (linear-gradient) | 🔄 Simulated (color steps) | Close approximation |
|
|
558
|
+
| **Images** | ✅ Full support | ❌ Not available | Use emoji/icons instead |
|
|
559
|
+
| **Mouse Input** | ✅ Full support | ⚠️ Limited (if enabled) | Keyboard-first design |
|
|
560
|
+
| **Keyboard Nav** | ✅ Supported | ✅ Primary input | Identical UX |
|
|
561
|
+
| **Screen Readers** | ✅ ARIA support | ⚠️ Limited | Text-based is accessible |
|
|
562
|
+
| **Responsive Design** | ✅ Media queries | ✅ Terminal size detection | Same breakpoint logic |
|
|
563
|
+
| **Typography** | ✅ Full control | ⚠️ Monospace only | Fixed-width constraint |
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## Related Documentation
|
|
568
|
+
|
|
569
|
+
- [COMPONENT_LIBRARY.md](../components/COMPONENT_LIBRARY.md) - Complete component inventory
|
|
570
|
+
- [WEB_IMPLEMENTATION.md](./WEB_IMPLEMENTATION.md) - Web-specific implementation
|
|
571
|
+
- [CLI_IMPLEMENTATION.md](./CLI_IMPLEMENTATION.md) - CLI-specific implementation
|
|
572
|
+
- [NPM_PACKAGE.md](./NPM_PACKAGE.md) - Package usage guide
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
**Last Updated**: 2025-12-13
|
|
577
|
+
**Version**: 1.0.0
|
|
578
|
+
**Maintainer**: Celeste Brand System
|
|
579
|
+
**Status**: ✅ Complete Cross-Platform Reference
|