@codeyam/codeyam-cli 0.1.28 → 0.1.29
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/analyzer-template/.build-info.json +6 -6
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +1 -1
- package/analyzer-template/packages/aws/package.json +5 -5
- package/codeyam-cli/src/commands/editor.js +213 -5
- package/codeyam-cli/src/commands/editor.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +136 -0
- package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js +398 -0
- package/codeyam-cli/src/utils/__tests__/editorRoadmap.test.js.map +1 -0
- package/codeyam-cli/src/utils/designSystemShowcase.js +810 -0
- package/codeyam-cli/src/utils/designSystemShowcase.js.map +1 -0
- package/codeyam-cli/src/utils/editorAudit.js +6 -1
- package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
- package/codeyam-cli/src/utils/editorRoadmap.js +301 -0
- package/codeyam-cli/src/utils/editorRoadmap.js.map +1 -0
- package/codeyam-cli/src/utils/editorScenarios.js +10 -0
- package/codeyam-cli/src/utils/editorScenarios.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js +1 -0
- package/codeyam-cli/src/webserver/__tests__/api.interactive-switch-scenario.test.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CLe80MMu.js → CopyButton-DTBZZfSk.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-Crt_KN_U.js → EntityItem-BxclONWq.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-CD7lGABo.js → EntityTypeIcon-BsnEOJZ_.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-CgTNOhnu.js → InlineSpinner-ByaELMbv.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-DtYTSPL2.js → InteractivePreview-6WjVfhxX.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-D3s1MFkb.js → LibraryFunctionPreview-ChX-Hp7W.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-CM5zg40N.js → LogViewer-C-9zQdXg.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{MiniClaudeChat-CQENLSrF.js → MiniClaudeChat-BusrvT2F.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-C2PLkej3.js → ReportIssueModal-DQsceHVv.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DanvyBPb.js → SafeScreenshot-DThcm_9M.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-CefgqbCr.js → ScenarioViewer-Cl4oOA3A.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{Spinner-Bc8BG-Lw.js → Spinner-CIil5-gb.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ViewportInspectBar-BA_Ry-rs.js → ViewportInspectBar-BqkA9zyZ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{_index-C1YkzTAV.js → _index-DnOgyseQ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-yH46LLUz.js → activity.(_tab)-DqM9hbNE.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{addon-web-links-CHx25PAe.js → addon-web-links-C58dYPwR.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{agent-transcripts-Bg3e7q4S.js → agent-transcripts-B8NCeOrm.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/api.editor-roadmap-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{book-open-CL-lMgHh.js → book-open-BFSIqZgO.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-GmAjGS9-.js → chevron-down-B9fDzFVh.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-UVKPFVEO-Bmq2apuh.js +43 -0
- package/codeyam-cli/src/webserver/build/client/assets/{circle-check-DFcQkN5j.js → circle-check-DLPObLUx.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{copy-C6iF61Xs.js → copy-DXEmO0TD.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-4ImjHTVC.js → createLucideIcon-BwyFiRot.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-CRepiabR.js → dev.empty-iRhRIFlp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor._tab-BZPBzV73.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-785deXbZ.js +147 -0
- package/codeyam-cli/src/webserver/build/client/assets/{editorPreview-CluPkvXJ.js → editorPreview-C6fEYHrh.js} +6 -6
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-DYJRGiDI.js → entity._sha._-Ce1s4OQ1.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-wdiwx5-Z.js → entity._sha.scenarios._scenarioId.dev-C8AyYgYT.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-BrkN-40Y.js → entity._sha.scenarios._scenarioId.fullscreen-DziaVQX1.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-DxfhekTZ.js → entity._sha_.create-scenario-BTcpgIpC.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CRXJWmpB.js → entity._sha_.edit._scenarioId-D_O_ajfZ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entry.client-SuW9syRS.js → entry.client-j1Vi0bco.js} +6 -6
- package/codeyam-cli/src/webserver/build/client/assets/{files-D-xGrg29.js → files-kuny2Q_s.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{git-Bq_fbXP5.js → git-DgCZPMie.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-Bt7TsgQz.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-Bp1l4hSv.js → index-BliGSSpl.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-DE3jI_dv.js → index-SqjQKTdH.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-CWV9XZiG.js → index-vyrZD2g4.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{labs-B_IX45ih.js → labs-c3yLxSEp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-De-7qQ2u.js → loader-circle-D-q28GLF.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-3d8cde80.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{memory-Cx2xEx7s.js → memory-CEWIUC4t.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{pause-CFxEKL1u.js → pause-BP6fitdh.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{root-dKFRTYcy.js → root-CVjDQwjJ.js} +6 -6
- package/codeyam-cli/src/webserver/build/client/assets/{search-BdBb5aqc.js → search-BooqacKS.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{settings-DdE-Untf.js → settings-BM0nbryO.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{simulations-DSCdE99u.js → simulations-ovy6FjRY.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{terminal-CrplD4b1.js → terminal-DHemCJIs.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-DqJ0j69l.js → triangle-alert-D87ekDl8.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-DhXHbEjP.js → useCustomSizes-Dk0Tciqg.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-D9QZKaLJ.js → useLastLogLine-C8QvIe05.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-Cy5Qg_UR.js → useReportContext-jkCytuYz.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-5HR2j9ZE.js → useToast-BgqkixU9.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{analysisRunner-OLsM110H.js → analysisRunner-CTJYMVFP.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{index-WHdB6WTN.js → index-CCth4Hgw.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{init-DbSiZoE6.js → init-UXl-3vVp.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{server-build-DZbLY6O_.js → server-build-DSW2mE30.js} +198 -147
- package/codeyam-cli/src/webserver/build/server/index.js +1 -1
- package/codeyam-cli/src/webserver/build-info.json +5 -5
- package/codeyam-cli/src/webserver/server.js +67 -0
- package/codeyam-cli/src/webserver/server.js.map +1 -1
- package/codeyam-cli/src/webserver/terminalServer.js +21 -0
- package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
- package/codeyam-cli/templates/editor-step-hook.py +4 -4
- package/package.json +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/chunk-JZWAC4HX-BAdwhyCx.js +0 -43
- package/codeyam-cli/src/webserver/build/client/assets/editor._tab-Gbk_i5Js.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/editor.entity.(_sha)-CRxPi2BB.js +0 -96
- package/codeyam-cli/src/webserver/build/client/assets/globals-BsGHu8WX.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-9032538f.js +0 -1
|
@@ -0,0 +1,810 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a self-contained HTML page that showcases standard UI components
|
|
3
|
+
* styled with CSS custom properties extracted from a design system markdown file.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
/**
|
|
8
|
+
* Extract all CSS code blocks from the design system markdown,
|
|
9
|
+
* preserving their selectors (or using :root as default).
|
|
10
|
+
*/
|
|
11
|
+
function extractCssFromMarkdown(markdown) {
|
|
12
|
+
const blocks = [];
|
|
13
|
+
const regex = /```css\n([\s\S]*?)```/g;
|
|
14
|
+
let match;
|
|
15
|
+
while ((match = regex.exec(markdown)) !== null) {
|
|
16
|
+
const raw = match[1].trim();
|
|
17
|
+
// Check if the block has a selector wrapper like [data-theme='light'] { ... }
|
|
18
|
+
const selectorMatch = raw.match(/^([^\n{]+?)\s*\{([\s\S]*)\}\s*$/);
|
|
19
|
+
if (selectorMatch) {
|
|
20
|
+
blocks.push({
|
|
21
|
+
selector: selectorMatch[1].trim(),
|
|
22
|
+
content: selectorMatch[2].trim(),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
// No selector wrapper — treat as :root declarations
|
|
27
|
+
// Only include lines that look like CSS variable declarations or comments
|
|
28
|
+
const cssLines = raw
|
|
29
|
+
.split('\n')
|
|
30
|
+
.filter((line) => line.trim().startsWith('--') ||
|
|
31
|
+
line.trim().startsWith('/*') ||
|
|
32
|
+
line.trim().startsWith('*'))
|
|
33
|
+
.join('\n');
|
|
34
|
+
if (cssLines.trim()) {
|
|
35
|
+
blocks.push({ selector: ':root', content: cssLines });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return blocks;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Extract the font stack from the markdown Typography section.
|
|
43
|
+
*/
|
|
44
|
+
function extractFontInfo(markdown) {
|
|
45
|
+
const fontMatch = markdown.match(/\*\*Font stack:\*\*\s*`([^`]+)`(?:[^`]*`([^`]+)`)?(?:[^`]*`([^`]+)`)?/);
|
|
46
|
+
if (!fontMatch)
|
|
47
|
+
return { fontFamilies: [], googleFontsUrl: null };
|
|
48
|
+
const allFamilies = [];
|
|
49
|
+
for (let i = 1; i <= 3; i++) {
|
|
50
|
+
if (fontMatch[i]) {
|
|
51
|
+
const name = fontMatch[i].split(',')[0].trim().replace(/'/g, '');
|
|
52
|
+
if (name && !isSystemFont(name)) {
|
|
53
|
+
allFamilies.push(name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Build Google Fonts URL for non-system fonts
|
|
58
|
+
const googleFonts = allFamilies.filter((f) => !isSystemFont(f));
|
|
59
|
+
const googleFontsUrl = googleFonts.length > 0
|
|
60
|
+
? `https://fonts.googleapis.com/css2?${googleFonts.map((f) => `family=${f.replace(/ /g, '+')}:ital,wght@0,300;0,400;0,500;0,600;0,700;0,900;1,400`).join('&')}&display=swap`
|
|
61
|
+
: null;
|
|
62
|
+
return { fontFamilies: allFamilies, googleFontsUrl };
|
|
63
|
+
}
|
|
64
|
+
function isSystemFont(name) {
|
|
65
|
+
const systemFonts = [
|
|
66
|
+
'sans-serif',
|
|
67
|
+
'serif',
|
|
68
|
+
'monospace',
|
|
69
|
+
'system-ui',
|
|
70
|
+
'-apple-system',
|
|
71
|
+
'Georgia',
|
|
72
|
+
'Courier',
|
|
73
|
+
'Courier New',
|
|
74
|
+
'Arial',
|
|
75
|
+
'Helvetica',
|
|
76
|
+
];
|
|
77
|
+
return systemFonts.includes(name);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if the design system has dark mode support.
|
|
81
|
+
*/
|
|
82
|
+
function hasDarkMode(markdown) {
|
|
83
|
+
return (markdown.includes("[data-theme='dark']") ||
|
|
84
|
+
markdown.includes('[data-theme="dark"]'));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Extract the design system name from the markdown.
|
|
88
|
+
*/
|
|
89
|
+
function extractName(markdown) {
|
|
90
|
+
const match = markdown.match(/^# (.+)$/m);
|
|
91
|
+
return match ? match[1].trim() : 'Design System';
|
|
92
|
+
}
|
|
93
|
+
// ── HTML Generation ────────────────────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Build the complete showcase HTML page from a design system markdown file.
|
|
96
|
+
*/
|
|
97
|
+
export function buildShowcaseHtml(markdown) {
|
|
98
|
+
const cssBlocks = extractCssFromMarkdown(markdown);
|
|
99
|
+
const { googleFontsUrl } = extractFontInfo(markdown);
|
|
100
|
+
const supportsDarkMode = hasDarkMode(markdown);
|
|
101
|
+
const name = extractName(markdown);
|
|
102
|
+
// Build CSS variable declarations
|
|
103
|
+
const cssVars = cssBlocks
|
|
104
|
+
.map((block) => `${block.selector} {\n ${block.content}\n}`)
|
|
105
|
+
.join('\n\n');
|
|
106
|
+
return `<!DOCTYPE html>
|
|
107
|
+
<html data-theme="light" lang="en">
|
|
108
|
+
<head>
|
|
109
|
+
<meta charset="UTF-8">
|
|
110
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
111
|
+
<title>${name} — Component Showcase</title>
|
|
112
|
+
${googleFontsUrl ? `<link rel="stylesheet" href="${googleFontsUrl}">` : ''}
|
|
113
|
+
<style>
|
|
114
|
+
/* Design System Tokens */
|
|
115
|
+
${cssVars}
|
|
116
|
+
|
|
117
|
+
/* Showcase Base Styles */
|
|
118
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
119
|
+
|
|
120
|
+
body {
|
|
121
|
+
background: var(--bg-base, #f7f8fa);
|
|
122
|
+
color: var(--text-primary, #1a1b25);
|
|
123
|
+
font-family: var(--font-body, system-ui, -apple-system, sans-serif);
|
|
124
|
+
font-size: 14px;
|
|
125
|
+
line-height: 1.6;
|
|
126
|
+
padding: 32px;
|
|
127
|
+
transition: background 0.2s, color 0.2s;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.showcase-header {
|
|
131
|
+
display: flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
justify-content: space-between;
|
|
134
|
+
margin-bottom: 40px;
|
|
135
|
+
padding-bottom: 20px;
|
|
136
|
+
border-bottom: 1px solid var(--border, #e8e9ed);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.showcase-title {
|
|
140
|
+
font-size: 24px;
|
|
141
|
+
font-weight: 600;
|
|
142
|
+
letter-spacing: -0.02em;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.theme-toggle {
|
|
146
|
+
display: flex;
|
|
147
|
+
gap: 4px;
|
|
148
|
+
background: var(--bg-muted, #f2f3f7);
|
|
149
|
+
border-radius: 8px;
|
|
150
|
+
padding: 3px;
|
|
151
|
+
border: 1px solid var(--border, #e8e9ed);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.theme-toggle button {
|
|
155
|
+
padding: 6px 14px;
|
|
156
|
+
border: none;
|
|
157
|
+
background: transparent;
|
|
158
|
+
border-radius: 6px;
|
|
159
|
+
font-size: 12px;
|
|
160
|
+
font-weight: 500;
|
|
161
|
+
cursor: pointer;
|
|
162
|
+
color: var(--text-secondary, #6b7280);
|
|
163
|
+
transition: all 0.15s ease;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.theme-toggle button.active {
|
|
167
|
+
background: var(--bg-surface, #ffffff);
|
|
168
|
+
color: var(--text-primary, #1a1b25);
|
|
169
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.showcase-section {
|
|
173
|
+
margin-bottom: 48px;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.section-label {
|
|
177
|
+
font-size: 10px;
|
|
178
|
+
font-weight: 600;
|
|
179
|
+
text-transform: uppercase;
|
|
180
|
+
letter-spacing: 0.12em;
|
|
181
|
+
color: var(--text-muted, var(--text-tertiary, #9ca3af));
|
|
182
|
+
margin-bottom: 16px;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Color Palette */
|
|
186
|
+
.color-grid {
|
|
187
|
+
display: grid;
|
|
188
|
+
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
|
189
|
+
gap: 12px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.color-swatch {
|
|
193
|
+
display: flex;
|
|
194
|
+
flex-direction: column;
|
|
195
|
+
gap: 6px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.color-swatch .swatch {
|
|
199
|
+
width: 100%;
|
|
200
|
+
height: 48px;
|
|
201
|
+
border-radius: var(--radius-md, 8px);
|
|
202
|
+
border: 1px solid var(--border, #e8e9ed);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.color-swatch .swatch-name {
|
|
206
|
+
font-size: 10px;
|
|
207
|
+
font-family: monospace;
|
|
208
|
+
color: var(--text-secondary, #6b7280);
|
|
209
|
+
word-break: break-all;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.color-swatch .swatch-value {
|
|
213
|
+
font-size: 10px;
|
|
214
|
+
font-family: monospace;
|
|
215
|
+
color: var(--text-muted, var(--text-tertiary, #9ca3af));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Typography */
|
|
219
|
+
.type-scale {
|
|
220
|
+
display: flex;
|
|
221
|
+
flex-direction: column;
|
|
222
|
+
gap: 16px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.type-sample {
|
|
226
|
+
padding: 12px 0;
|
|
227
|
+
border-bottom: 1px solid var(--border, #e8e9ed);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.type-sample .sample-text {
|
|
231
|
+
margin-bottom: 4px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.type-sample .sample-meta {
|
|
235
|
+
font-size: 11px;
|
|
236
|
+
font-family: monospace;
|
|
237
|
+
color: var(--text-muted, var(--text-tertiary, #9ca3af));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* Cards */
|
|
241
|
+
.card-grid {
|
|
242
|
+
display: grid;
|
|
243
|
+
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
|
244
|
+
gap: 16px;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.showcase-card {
|
|
248
|
+
background: var(--bg-surface, #ffffff);
|
|
249
|
+
border: 1px solid var(--border, #e8e9ed);
|
|
250
|
+
border-radius: var(--radius-lg, 12px);
|
|
251
|
+
padding: 20px 24px;
|
|
252
|
+
box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,0.06));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.showcase-card h3 {
|
|
256
|
+
font-size: 18px;
|
|
257
|
+
font-weight: 600;
|
|
258
|
+
margin-bottom: 8px;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.showcase-card p {
|
|
262
|
+
font-size: 14px;
|
|
263
|
+
color: var(--text-secondary, #6b7280);
|
|
264
|
+
line-height: 1.5;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* Value Cards */
|
|
268
|
+
.value-card {
|
|
269
|
+
background: var(--bg-surface, #ffffff);
|
|
270
|
+
border: 1px solid var(--border, #e8e9ed);
|
|
271
|
+
border-radius: var(--radius-lg, 12px);
|
|
272
|
+
padding: 20px 24px;
|
|
273
|
+
box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,0.06));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.value-card .value-label {
|
|
277
|
+
font-size: 12px;
|
|
278
|
+
font-weight: 500;
|
|
279
|
+
color: var(--text-secondary, #6b7280);
|
|
280
|
+
text-transform: uppercase;
|
|
281
|
+
letter-spacing: 0.06em;
|
|
282
|
+
margin-bottom: 8px;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.value-card .value-number {
|
|
286
|
+
font-size: 36px;
|
|
287
|
+
font-weight: 600;
|
|
288
|
+
letter-spacing: -0.02em;
|
|
289
|
+
line-height: 1;
|
|
290
|
+
margin-bottom: 8px;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.value-card .value-trend {
|
|
294
|
+
font-size: 13px;
|
|
295
|
+
font-weight: 500;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.value-card .value-trend.positive {
|
|
299
|
+
color: var(--green-a, var(--sage, var(--teal, var(--accent, #34d399))));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.value-card .value-trend.negative {
|
|
303
|
+
color: var(--red, var(--burgundy, var(--danger-text, #f87171)));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* Buttons */
|
|
307
|
+
.button-row {
|
|
308
|
+
display: flex;
|
|
309
|
+
gap: 12px;
|
|
310
|
+
flex-wrap: wrap;
|
|
311
|
+
align-items: center;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.btn {
|
|
315
|
+
padding: 8px 16px;
|
|
316
|
+
border-radius: var(--radius-md, 8px);
|
|
317
|
+
font-weight: 500;
|
|
318
|
+
font-size: 14px;
|
|
319
|
+
border: none;
|
|
320
|
+
cursor: pointer;
|
|
321
|
+
transition: all 0.15s ease;
|
|
322
|
+
text-decoration: none;
|
|
323
|
+
display: inline-flex;
|
|
324
|
+
align-items: center;
|
|
325
|
+
gap: 6px;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.btn-primary {
|
|
329
|
+
background: var(--text-primary, #1a1b25);
|
|
330
|
+
color: var(--bg-base, #f7f8fa);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.btn-secondary {
|
|
334
|
+
background: var(--bg-muted, #f2f3f7);
|
|
335
|
+
color: var(--text-primary, #1a1b25);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.btn-outline {
|
|
339
|
+
background: transparent;
|
|
340
|
+
color: var(--text-primary, #1a1b25);
|
|
341
|
+
border: 1px solid var(--border-strong, var(--border, #d1d3db));
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.btn-ghost {
|
|
345
|
+
background: transparent;
|
|
346
|
+
color: var(--text-secondary, #6b7280);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.btn-sm { padding: 6px 12px; font-size: 12px; }
|
|
350
|
+
.btn-lg { padding: 12px 24px; font-size: 16px; }
|
|
351
|
+
|
|
352
|
+
/* Badges */
|
|
353
|
+
.badge-row {
|
|
354
|
+
display: flex;
|
|
355
|
+
gap: 8px;
|
|
356
|
+
flex-wrap: wrap;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.badge {
|
|
360
|
+
padding: 3px 10px;
|
|
361
|
+
border-radius: var(--radius-sm, 6px);
|
|
362
|
+
font-size: 12px;
|
|
363
|
+
font-weight: 500;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.badge-default {
|
|
367
|
+
background: var(--bg-muted, #f2f3f7);
|
|
368
|
+
color: var(--text-secondary, #6b7280);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.badge-success {
|
|
372
|
+
background: var(--success-bg, var(--green-b, #d1fae5));
|
|
373
|
+
color: var(--success-text, #065f46);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.badge-danger {
|
|
377
|
+
background: var(--danger-bg, #fee2e2);
|
|
378
|
+
color: var(--danger-text, #991b1b);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.badge-warning {
|
|
382
|
+
background: var(--warning-bg, #fef9c3);
|
|
383
|
+
color: var(--warning-text, #854d0e);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.badge-pill {
|
|
387
|
+
border-radius: 999px;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/* Inputs */
|
|
391
|
+
.input-group {
|
|
392
|
+
display: flex;
|
|
393
|
+
flex-direction: column;
|
|
394
|
+
gap: 16px;
|
|
395
|
+
max-width: 400px;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.input-field {
|
|
399
|
+
display: flex;
|
|
400
|
+
flex-direction: column;
|
|
401
|
+
gap: 6px;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.input-field label {
|
|
405
|
+
font-size: 13px;
|
|
406
|
+
font-weight: 500;
|
|
407
|
+
color: var(--text-secondary, #6b7280);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.input-field input,
|
|
411
|
+
.input-field textarea {
|
|
412
|
+
padding: 10px 14px;
|
|
413
|
+
border: 1px solid var(--border, #e8e9ed);
|
|
414
|
+
border-radius: var(--radius-md, 8px);
|
|
415
|
+
font-size: 14px;
|
|
416
|
+
background: var(--bg-surface, #ffffff);
|
|
417
|
+
color: var(--text-primary, #1a1b25);
|
|
418
|
+
outline: none;
|
|
419
|
+
transition: border-color 0.15s ease;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.input-field input:focus,
|
|
423
|
+
.input-field textarea:focus {
|
|
424
|
+
border-color: var(--border-strong, var(--border, #d1d3db));
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.input-field input::placeholder {
|
|
428
|
+
color: var(--text-muted, var(--text-tertiary, #9ca3af));
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* Table */
|
|
432
|
+
.showcase-table {
|
|
433
|
+
width: 100%;
|
|
434
|
+
border-collapse: collapse;
|
|
435
|
+
background: var(--bg-surface, #ffffff);
|
|
436
|
+
border: 1px solid var(--border, #e8e9ed);
|
|
437
|
+
border-radius: var(--radius-lg, 12px);
|
|
438
|
+
overflow: hidden;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.showcase-table th {
|
|
442
|
+
text-align: left;
|
|
443
|
+
padding: 12px 16px;
|
|
444
|
+
font-size: 12px;
|
|
445
|
+
font-weight: 600;
|
|
446
|
+
text-transform: uppercase;
|
|
447
|
+
letter-spacing: 0.06em;
|
|
448
|
+
color: var(--text-secondary, #6b7280);
|
|
449
|
+
background: var(--bg-muted, #f2f3f7);
|
|
450
|
+
border-bottom: 1px solid var(--border, #e8e9ed);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.showcase-table td {
|
|
454
|
+
padding: 12px 16px;
|
|
455
|
+
font-size: 14px;
|
|
456
|
+
border-bottom: 1px solid var(--border, #e8e9ed);
|
|
457
|
+
color: var(--text-secondary, #6b7280);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.showcase-table tr:last-child td {
|
|
461
|
+
border-bottom: none;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.showcase-table td:first-child {
|
|
465
|
+
color: var(--text-primary, #1a1b25);
|
|
466
|
+
font-weight: 500;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/* Header / Nav Bar */
|
|
470
|
+
.showcase-navbar {
|
|
471
|
+
background: var(--bg-surface, #ffffff);
|
|
472
|
+
border: 1px solid var(--border, #e8e9ed);
|
|
473
|
+
border-radius: var(--radius-lg, 12px);
|
|
474
|
+
padding: 12px 20px;
|
|
475
|
+
display: flex;
|
|
476
|
+
align-items: center;
|
|
477
|
+
justify-content: space-between;
|
|
478
|
+
box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,0.06));
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.navbar-brand {
|
|
482
|
+
font-size: 16px;
|
|
483
|
+
font-weight: 700;
|
|
484
|
+
display: flex;
|
|
485
|
+
align-items: center;
|
|
486
|
+
gap: 8px;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.navbar-brand .brand-dot {
|
|
490
|
+
width: 10px;
|
|
491
|
+
height: 10px;
|
|
492
|
+
border-radius: 50%;
|
|
493
|
+
background: var(--green-a, var(--accent, var(--pink, var(--burgundy, #34d399))));
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.navbar-links {
|
|
497
|
+
display: flex;
|
|
498
|
+
gap: 4px;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.navbar-links a {
|
|
502
|
+
padding: 6px 14px;
|
|
503
|
+
border-radius: var(--radius-md, 8px);
|
|
504
|
+
font-size: 13px;
|
|
505
|
+
font-weight: 500;
|
|
506
|
+
color: var(--text-secondary, #6b7280);
|
|
507
|
+
text-decoration: none;
|
|
508
|
+
transition: all 0.15s ease;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.navbar-links a.active {
|
|
512
|
+
background: var(--bg-active, var(--bg-muted, #eef2ff));
|
|
513
|
+
color: var(--text-primary, #1a1b25);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/* Progress Bar */
|
|
517
|
+
.progress-track {
|
|
518
|
+
height: 8px;
|
|
519
|
+
background: var(--bg-muted, #f2f3f7);
|
|
520
|
+
border-radius: 999px;
|
|
521
|
+
overflow: hidden;
|
|
522
|
+
max-width: 300px;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.progress-fill {
|
|
526
|
+
height: 100%;
|
|
527
|
+
border-radius: 999px;
|
|
528
|
+
background: var(--green-a, var(--accent, var(--pink, #34d399)));
|
|
529
|
+
transition: width 0.6s ease;
|
|
530
|
+
}
|
|
531
|
+
</style>
|
|
532
|
+
</head>
|
|
533
|
+
<body>
|
|
534
|
+
<div class="showcase-header">
|
|
535
|
+
<div class="showcase-title">${name}</div>
|
|
536
|
+
${supportsDarkMode
|
|
537
|
+
? `<div class="theme-toggle">
|
|
538
|
+
<button class="active" onclick="setTheme('light')">Light</button>
|
|
539
|
+
<button onclick="setTheme('dark')">Dark</button>
|
|
540
|
+
</div>`
|
|
541
|
+
: ''}
|
|
542
|
+
</div>
|
|
543
|
+
|
|
544
|
+
<!-- Navigation Bar -->
|
|
545
|
+
<div class="showcase-section">
|
|
546
|
+
<div class="section-label">Navigation</div>
|
|
547
|
+
<div class="showcase-navbar">
|
|
548
|
+
<div class="navbar-brand">
|
|
549
|
+
<span class="brand-dot"></span>
|
|
550
|
+
Acme App
|
|
551
|
+
</div>
|
|
552
|
+
<div class="navbar-links">
|
|
553
|
+
<a href="#" class="active">Dashboard</a>
|
|
554
|
+
<a href="#">Projects</a>
|
|
555
|
+
<a href="#">Settings</a>
|
|
556
|
+
</div>
|
|
557
|
+
</div>
|
|
558
|
+
</div>
|
|
559
|
+
|
|
560
|
+
<!-- Value Cards -->
|
|
561
|
+
<div class="showcase-section">
|
|
562
|
+
<div class="section-label">Value Cards</div>
|
|
563
|
+
<div class="card-grid">
|
|
564
|
+
<div class="value-card">
|
|
565
|
+
<div class="value-label">Total Revenue</div>
|
|
566
|
+
<div class="value-number">$48,290</div>
|
|
567
|
+
<div class="value-trend positive">↗ +12.5% from last month</div>
|
|
568
|
+
</div>
|
|
569
|
+
<div class="value-card">
|
|
570
|
+
<div class="value-label">Active Users</div>
|
|
571
|
+
<div class="value-number">2,847</div>
|
|
572
|
+
<div class="value-trend positive">↗ +8.2% from last week</div>
|
|
573
|
+
</div>
|
|
574
|
+
<div class="value-card">
|
|
575
|
+
<div class="value-label">Bounce Rate</div>
|
|
576
|
+
<div class="value-number">24.3%</div>
|
|
577
|
+
<div class="value-trend negative">↘ -3.1% from yesterday</div>
|
|
578
|
+
</div>
|
|
579
|
+
</div>
|
|
580
|
+
</div>
|
|
581
|
+
|
|
582
|
+
<!-- Cards -->
|
|
583
|
+
<div class="showcase-section">
|
|
584
|
+
<div class="section-label">Cards</div>
|
|
585
|
+
<div class="card-grid">
|
|
586
|
+
<div class="showcase-card">
|
|
587
|
+
<h3>Project Alpha</h3>
|
|
588
|
+
<p>A dashboard for monitoring real-time analytics and performance metrics across distributed systems.</p>
|
|
589
|
+
</div>
|
|
590
|
+
<div class="showcase-card">
|
|
591
|
+
<h3>Design Tokens</h3>
|
|
592
|
+
<p>Centralized design token management with automatic code generation for multiple platforms.</p>
|
|
593
|
+
</div>
|
|
594
|
+
<div class="showcase-card">
|
|
595
|
+
<h3>API Gateway</h3>
|
|
596
|
+
<p>Unified API gateway with rate limiting, authentication, and request transformation.</p>
|
|
597
|
+
</div>
|
|
598
|
+
</div>
|
|
599
|
+
</div>
|
|
600
|
+
|
|
601
|
+
<!-- Buttons -->
|
|
602
|
+
<div class="showcase-section">
|
|
603
|
+
<div class="section-label">Buttons</div>
|
|
604
|
+
<div class="button-row" style="margin-bottom: 12px;">
|
|
605
|
+
<button class="btn btn-primary">Primary</button>
|
|
606
|
+
<button class="btn btn-secondary">Secondary</button>
|
|
607
|
+
<button class="btn btn-outline">Outline</button>
|
|
608
|
+
<button class="btn btn-ghost">Ghost</button>
|
|
609
|
+
</div>
|
|
610
|
+
<div class="button-row">
|
|
611
|
+
<button class="btn btn-primary btn-sm">Small</button>
|
|
612
|
+
<button class="btn btn-primary">Medium</button>
|
|
613
|
+
<button class="btn btn-primary btn-lg">Large</button>
|
|
614
|
+
</div>
|
|
615
|
+
</div>
|
|
616
|
+
|
|
617
|
+
<!-- Badges -->
|
|
618
|
+
<div class="showcase-section">
|
|
619
|
+
<div class="section-label">Badges</div>
|
|
620
|
+
<div class="badge-row" style="margin-bottom: 12px;">
|
|
621
|
+
<span class="badge badge-default">Default</span>
|
|
622
|
+
<span class="badge badge-success">Success</span>
|
|
623
|
+
<span class="badge badge-danger">Error</span>
|
|
624
|
+
<span class="badge badge-warning">Warning</span>
|
|
625
|
+
</div>
|
|
626
|
+
<div class="badge-row">
|
|
627
|
+
<span class="badge badge-default badge-pill">Default</span>
|
|
628
|
+
<span class="badge badge-success badge-pill">Active</span>
|
|
629
|
+
<span class="badge badge-danger badge-pill">Critical</span>
|
|
630
|
+
<span class="badge badge-warning badge-pill">Pending</span>
|
|
631
|
+
</div>
|
|
632
|
+
</div>
|
|
633
|
+
|
|
634
|
+
<!-- Form Inputs -->
|
|
635
|
+
<div class="showcase-section">
|
|
636
|
+
<div class="section-label">Form Inputs</div>
|
|
637
|
+
<div class="input-group">
|
|
638
|
+
<div class="input-field">
|
|
639
|
+
<label>Project Name</label>
|
|
640
|
+
<input type="text" placeholder="Enter project name..." value="Acme Dashboard">
|
|
641
|
+
</div>
|
|
642
|
+
<div class="input-field">
|
|
643
|
+
<label>Description</label>
|
|
644
|
+
<textarea rows="3" placeholder="Describe your project...">A modern analytics dashboard for tracking key metrics and user engagement.</textarea>
|
|
645
|
+
</div>
|
|
646
|
+
</div>
|
|
647
|
+
</div>
|
|
648
|
+
|
|
649
|
+
<!-- Table -->
|
|
650
|
+
<div class="showcase-section">
|
|
651
|
+
<div class="section-label">Data Table</div>
|
|
652
|
+
<table class="showcase-table">
|
|
653
|
+
<thead>
|
|
654
|
+
<tr>
|
|
655
|
+
<th>Name</th>
|
|
656
|
+
<th>Status</th>
|
|
657
|
+
<th>Role</th>
|
|
658
|
+
<th>Last Active</th>
|
|
659
|
+
</tr>
|
|
660
|
+
</thead>
|
|
661
|
+
<tbody>
|
|
662
|
+
<tr>
|
|
663
|
+
<td>Alice Chen</td>
|
|
664
|
+
<td><span class="badge badge-success">Active</span></td>
|
|
665
|
+
<td>Engineer</td>
|
|
666
|
+
<td>2 min ago</td>
|
|
667
|
+
</tr>
|
|
668
|
+
<tr>
|
|
669
|
+
<td>Bob Martinez</td>
|
|
670
|
+
<td><span class="badge badge-warning">Away</span></td>
|
|
671
|
+
<td>Designer</td>
|
|
672
|
+
<td>1 hour ago</td>
|
|
673
|
+
</tr>
|
|
674
|
+
<tr>
|
|
675
|
+
<td>Carol Davis</td>
|
|
676
|
+
<td><span class="badge badge-default">Offline</span></td>
|
|
677
|
+
<td>Product</td>
|
|
678
|
+
<td>Yesterday</td>
|
|
679
|
+
</tr>
|
|
680
|
+
<tr>
|
|
681
|
+
<td>Dave Kim</td>
|
|
682
|
+
<td><span class="badge badge-success">Active</span></td>
|
|
683
|
+
<td>Engineer</td>
|
|
684
|
+
<td>Just now</td>
|
|
685
|
+
</tr>
|
|
686
|
+
</tbody>
|
|
687
|
+
</table>
|
|
688
|
+
</div>
|
|
689
|
+
|
|
690
|
+
<!-- Typography Scale -->
|
|
691
|
+
<div class="showcase-section">
|
|
692
|
+
<div class="section-label">Typography</div>
|
|
693
|
+
<div class="type-scale">
|
|
694
|
+
<div class="type-sample">
|
|
695
|
+
<div class="sample-text" style="font-size: 36px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.1;">Display Heading</div>
|
|
696
|
+
<div class="sample-meta">Display — 36px / 600</div>
|
|
697
|
+
</div>
|
|
698
|
+
<div class="type-sample">
|
|
699
|
+
<div class="sample-text" style="font-size: 24px; font-weight: 600;">Section Heading</div>
|
|
700
|
+
<div class="sample-meta">2XL — 24px / 600</div>
|
|
701
|
+
</div>
|
|
702
|
+
<div class="type-sample">
|
|
703
|
+
<div class="sample-text" style="font-size: 18px; font-weight: 600;">Card Title</div>
|
|
704
|
+
<div class="sample-meta">LG — 18px / 600</div>
|
|
705
|
+
</div>
|
|
706
|
+
<div class="type-sample">
|
|
707
|
+
<div class="sample-text" style="font-size: 14px; font-weight: 400;">Body text for paragraphs and general content. This demonstrates the default reading experience with adequate line height.</div>
|
|
708
|
+
<div class="sample-meta">SM — 14px / 400</div>
|
|
709
|
+
</div>
|
|
710
|
+
<div class="type-sample">
|
|
711
|
+
<div class="sample-text" style="font-size: 12px; font-weight: 400; color: var(--text-secondary, #6b7280);">Caption text, timestamps, and secondary information</div>
|
|
712
|
+
<div class="sample-meta">XS — 12px / 400</div>
|
|
713
|
+
</div>
|
|
714
|
+
</div>
|
|
715
|
+
</div>
|
|
716
|
+
|
|
717
|
+
<!-- Progress -->
|
|
718
|
+
<div class="showcase-section">
|
|
719
|
+
<div class="section-label">Progress</div>
|
|
720
|
+
<div style="display: flex; flex-direction: column; gap: 12px;">
|
|
721
|
+
<div>
|
|
722
|
+
<div style="font-size: 13px; margin-bottom: 6px; color: var(--text-secondary, #6b7280);">Complete — 100%</div>
|
|
723
|
+
<div class="progress-track"><div class="progress-fill" style="width: 100%"></div></div>
|
|
724
|
+
</div>
|
|
725
|
+
<div>
|
|
726
|
+
<div style="font-size: 13px; margin-bottom: 6px; color: var(--text-secondary, #6b7280);">In Progress — 65%</div>
|
|
727
|
+
<div class="progress-track"><div class="progress-fill" style="width: 65%"></div></div>
|
|
728
|
+
</div>
|
|
729
|
+
<div>
|
|
730
|
+
<div style="font-size: 13px; margin-bottom: 6px; color: var(--text-secondary, #6b7280);">Starting — 15%</div>
|
|
731
|
+
<div class="progress-track"><div class="progress-fill" style="width: 15%"></div></div>
|
|
732
|
+
</div>
|
|
733
|
+
</div>
|
|
734
|
+
</div>
|
|
735
|
+
|
|
736
|
+
<!-- Color Palette -->
|
|
737
|
+
<div class="showcase-section">
|
|
738
|
+
<div class="section-label">Color Palette</div>
|
|
739
|
+
<div class="color-grid" id="colorPalette"></div>
|
|
740
|
+
</div>
|
|
741
|
+
|
|
742
|
+
<script>
|
|
743
|
+
// Theme toggle
|
|
744
|
+
function setTheme(theme) {
|
|
745
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
746
|
+
document.querySelectorAll('.theme-toggle button').forEach(btn => {
|
|
747
|
+
btn.classList.toggle('active', btn.textContent.trim().toLowerCase() === theme);
|
|
748
|
+
});
|
|
749
|
+
// Re-render palette with resolved colors
|
|
750
|
+
renderColorPalette();
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Render color palette by reading computed CSS variable values
|
|
754
|
+
function renderColorPalette() {
|
|
755
|
+
const grid = document.getElementById('colorPalette');
|
|
756
|
+
if (!grid) return;
|
|
757
|
+
grid.innerHTML = '';
|
|
758
|
+
|
|
759
|
+
const style = getComputedStyle(document.documentElement);
|
|
760
|
+
const vars = [
|
|
761
|
+
'bg-base', 'bg-surface', 'bg-muted', 'bg-overlay', 'bg-active', 'bg-inverse',
|
|
762
|
+
'text-primary', 'text-secondary', 'text-muted', 'text-tertiary', 'text-disabled', 'text-faint',
|
|
763
|
+
'border', 'border-strong', 'border-light', 'border-dashed',
|
|
764
|
+
];
|
|
765
|
+
|
|
766
|
+
// Also grab accent and palette colors
|
|
767
|
+
const accentVars = [
|
|
768
|
+
'green-a', 'green-b', 'red', 'purple-a', 'purple-b', 'blue-a', 'blue-b', 'yellow',
|
|
769
|
+
'pink', 'pink-light', 'teal', 'teal-light', 'teal-dark', 'orange',
|
|
770
|
+
'burgundy', 'burgundy-lt', 'sage', 'gold',
|
|
771
|
+
'accent', 'accent-soft', 'accent-dark',
|
|
772
|
+
'palette-1', 'palette-2', 'palette-3', 'palette-4', 'palette-5', 'palette-6',
|
|
773
|
+
];
|
|
774
|
+
|
|
775
|
+
const allVars = [...vars, ...accentVars];
|
|
776
|
+
|
|
777
|
+
for (const v of allVars) {
|
|
778
|
+
const value = style.getPropertyValue('--' + v).trim();
|
|
779
|
+
if (!value || value === 'none') continue;
|
|
780
|
+
// Skip non-color values (shadows, etc.)
|
|
781
|
+
if (value.includes('px') && !value.startsWith('#') && !value.startsWith('rgb')) continue;
|
|
782
|
+
|
|
783
|
+
const swatch = document.createElement('div');
|
|
784
|
+
swatch.className = 'color-swatch';
|
|
785
|
+
swatch.innerHTML =
|
|
786
|
+
'<div class="swatch" style="background:' + value + '"></div>' +
|
|
787
|
+
'<div class="swatch-name">--' + v + '</div>' +
|
|
788
|
+
'<div class="swatch-value">' + value + '</div>';
|
|
789
|
+
grid.appendChild(swatch);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// Initial render
|
|
794
|
+
renderColorPalette();
|
|
795
|
+
</script>
|
|
796
|
+
</body>
|
|
797
|
+
</html>`;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Read the design system file and generate the showcase HTML.
|
|
801
|
+
* Returns null if the design system file doesn't exist.
|
|
802
|
+
*/
|
|
803
|
+
export function generateShowcase(projectRoot) {
|
|
804
|
+
const dsPath = path.join(projectRoot, '.codeyam', 'design-system.md');
|
|
805
|
+
if (!fs.existsSync(dsPath))
|
|
806
|
+
return null;
|
|
807
|
+
const markdown = fs.readFileSync(dsPath, 'utf8');
|
|
808
|
+
return buildShowcaseHtml(markdown);
|
|
809
|
+
}
|
|
810
|
+
//# sourceMappingURL=designSystemShowcase.js.map
|