rizzo-css 0.0.3 → 0.0.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/README.md +10 -3
- package/bin/rizzo-css.js +324 -43
- package/dist/rizzo.min.css +1 -3
- package/package.json +1 -1
- package/scaffold/vanilla/index.html +77 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# rizzo-css
|
|
2
2
|
|
|
3
|
-
A modern CSS design system with semantic theming, 14 built-in themes, and accessible components (BEM). Framework-agnostic: use with
|
|
3
|
+
A modern CSS design system with semantic theming, 14 built-in themes, and accessible components (BEM). **The same CSS and component styles** ship for every option: **Vanilla JS**, Astro, and Svelte. Framework-agnostic: use with any stack or plain HTML.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -12,7 +12,14 @@ pnpm add rizzo-css
|
|
|
12
12
|
yarn add rizzo-css
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
**Quick start (no install):** `npx rizzo-css init` scaffolds a project (
|
|
15
|
+
**Quick start (no install):** `npx rizzo-css init` scaffolds a project. Choose **Vanilla JS** (yellow in the CLI), **Astro** (orange), or **Svelte** (orange-red). All options get the **same CSS and component styles**. Vanilla JS gets an example page with theme switcher and sample components; Astro/Svelte can optionally add component files. To use the **official Svelte or Astro scaffold** plus Rizzo CSS, create the app with their CLI first, then add our CSS:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm create svelte@latest my-app && cd my-app && npx rizzo-css add
|
|
19
|
+
npm create astro@latest my-app && cd my-app && npx rizzo-css add
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`add` auto-detects Svelte/Astro and copies CSS to the right place (`static/css` or `public/css`). `npx rizzo-css theme` lists themes.
|
|
16
23
|
|
|
17
24
|
## Use
|
|
18
25
|
|
|
@@ -34,7 +41,7 @@ import 'rizzo-css';
|
|
|
34
41
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rizzo-css@latest" />
|
|
35
42
|
```
|
|
36
43
|
|
|
37
|
-
Use the same class names and HTML structure as in the [component docs](https://rizzo-css.vercel.app/docs/components).
|
|
44
|
+
Use the same class names and HTML structure as in the [component docs](https://rizzo-css.vercel.app/docs/components). **Vanilla JS**, Astro, and Svelte all use the same CSS and BEM markup; Astro/Svelte add framework component files for convenience.
|
|
38
45
|
|
|
39
46
|
## Themes
|
|
40
47
|
|
package/bin/rizzo-css.js
CHANGED
|
@@ -36,6 +36,19 @@ const ASTRO_COMPONENTS = [
|
|
|
36
36
|
'Modal', 'Toast', 'Table',
|
|
37
37
|
];
|
|
38
38
|
|
|
39
|
+
// ANSI colors for CLI (framework logo colors)
|
|
40
|
+
const C = {
|
|
41
|
+
reset: '\u001b[0m',
|
|
42
|
+
dim: '\u001b[90m',
|
|
43
|
+
cyan: '\u001b[36m',
|
|
44
|
+
vanilla: '\u001b[38;5;226m', // Vanilla JS yellow
|
|
45
|
+
astro: '\u001b[38;5;208m', // Astro orange #ff5d01
|
|
46
|
+
svelte: '\u001b[38;5;202m', // Svelte orange #ff3e00
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const CIRCLE_EMPTY = '\u25CB '; // ○
|
|
50
|
+
const CIRCLE_FILLED = '\u25CF '; // ●
|
|
51
|
+
|
|
39
52
|
// Resolve path to this package (works when run via npx or from repo)
|
|
40
53
|
function getPackageRoot() {
|
|
41
54
|
return dirname(require.resolve('../package.json'));
|
|
@@ -55,6 +68,189 @@ function question(prompt) {
|
|
|
55
68
|
});
|
|
56
69
|
}
|
|
57
70
|
|
|
71
|
+
/** Format label with optional ANSI color (item.color). */
|
|
72
|
+
function formatLabel(item) {
|
|
73
|
+
const text = item.label || item.value;
|
|
74
|
+
return item.color ? item.color + text + C.reset : text;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Single-select menu with circles. options: array of { value, label, color? }. Returns selected value. */
|
|
78
|
+
function selectMenu(options, title) {
|
|
79
|
+
const items = options.map((o) => (typeof o === 'string' ? { value: o, label: o } : o));
|
|
80
|
+
const isTty = process.stdin.isTTY && process.stdout.isTTY;
|
|
81
|
+
|
|
82
|
+
if (!isTty) {
|
|
83
|
+
console.log('\n' + (title || 'Choose one') + ':');
|
|
84
|
+
items.forEach((item, i) => console.log(' ' + (i + 1) + '. ' + (item.label || item.value)));
|
|
85
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
86
|
+
return new Promise((resolve) => {
|
|
87
|
+
rl.question('\nEnter number [1]: ', (answer) => {
|
|
88
|
+
rl.close();
|
|
89
|
+
const n = parseInt((answer || '1').trim(), 10);
|
|
90
|
+
const idx = n >= 1 && n <= items.length ? n - 1 : 0;
|
|
91
|
+
resolve(items[idx].value);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return new Promise((resolve) => {
|
|
97
|
+
let index = 0;
|
|
98
|
+
const lineCount = (title ? 1 : 0) + items.length + 1;
|
|
99
|
+
|
|
100
|
+
const render = (first) => {
|
|
101
|
+
const lines = (title ? [title] : []).concat(
|
|
102
|
+
items.map((item, i) => {
|
|
103
|
+
const circle = i === index ? CIRCLE_FILLED : CIRCLE_EMPTY;
|
|
104
|
+
const prefix = i === index ? C.cyan + '>' + C.reset + ' ' : ' ';
|
|
105
|
+
return prefix + circle + formatLabel(item);
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
if (!first) {
|
|
109
|
+
process.stdout.write('\u001b[' + lineCount + 'A');
|
|
110
|
+
}
|
|
111
|
+
process.stdout.write('\u001b[?25l');
|
|
112
|
+
process.stdout.write(lines.join('\n') + '\n\n');
|
|
113
|
+
process.stdout.write('\u001b[?25h');
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
process.stdin.setRawMode(true);
|
|
117
|
+
process.stdin.resume();
|
|
118
|
+
process.stdin.setEncoding('utf8');
|
|
119
|
+
|
|
120
|
+
render(true);
|
|
121
|
+
|
|
122
|
+
let buf = '';
|
|
123
|
+
const onData = (ch) => {
|
|
124
|
+
if (ch === '\u0003') {
|
|
125
|
+
process.stdin.setRawMode(false);
|
|
126
|
+
process.stdin.removeListener('data', onData);
|
|
127
|
+
process.stdout.write('\n');
|
|
128
|
+
process.exit(130);
|
|
129
|
+
}
|
|
130
|
+
if (ch === '\r' || ch === '\n') {
|
|
131
|
+
process.stdin.setRawMode(false);
|
|
132
|
+
process.stdin.removeListener('data', onData);
|
|
133
|
+
process.stdin.pause();
|
|
134
|
+
process.stdout.write('\n');
|
|
135
|
+
resolve(items[index].value);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
buf += ch;
|
|
139
|
+
const isUp = buf === '\u001b[A' || buf === '\u001bOA' || (buf.length >= 2 && buf.endsWith('A') && buf.startsWith('\u001b'));
|
|
140
|
+
const isDown = buf === '\u001b[B' || buf === '\u001bOB' || (buf.length >= 2 && buf.endsWith('B') && buf.startsWith('\u001b'));
|
|
141
|
+
if (isUp) {
|
|
142
|
+
buf = '';
|
|
143
|
+
index = index <= 0 ? items.length - 1 : index - 1;
|
|
144
|
+
render(false);
|
|
145
|
+
} else if (isDown) {
|
|
146
|
+
buf = '';
|
|
147
|
+
index = index >= items.length - 1 ? 0 : index + 1;
|
|
148
|
+
render(false);
|
|
149
|
+
} else if (buf.length > 12 || (buf.length === 1 && ch !== '\u001b')) {
|
|
150
|
+
buf = '';
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
process.stdin.on('data', onData);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Multi-select menu: circles ○/●, Space toggles, Enter confirms. Returns array of selected values. */
|
|
158
|
+
function multiSelectMenu(options, title) {
|
|
159
|
+
const items = options.map((o) => (typeof o === 'string' ? { value: o, label: o } : o));
|
|
160
|
+
const isTty = process.stdin.isTTY && process.stdout.isTTY;
|
|
161
|
+
|
|
162
|
+
if (!isTty) {
|
|
163
|
+
console.log('\n' + (title || 'Choose (space to toggle, enter when done') + ':');
|
|
164
|
+
items.forEach((item, i) => console.log(' ' + (i + 1) + '. ' + (item.label || item.value)));
|
|
165
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
166
|
+
return new Promise((resolve) => {
|
|
167
|
+
rl.question('\nEnter numbers to include (e.g. 1 3 5 or all): ', (answer) => {
|
|
168
|
+
rl.close();
|
|
169
|
+
const s = (answer || '').trim().toLowerCase();
|
|
170
|
+
if (s === 'all' || s === 'a') {
|
|
171
|
+
resolve(items.map((i) => i.value));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const parts = s.split(/[\s,]+/).filter(Boolean);
|
|
175
|
+
const indices = new Set();
|
|
176
|
+
for (const p of parts) {
|
|
177
|
+
const n = parseInt(p, 10);
|
|
178
|
+
if (n >= 1 && n <= items.length) indices.add(n - 1);
|
|
179
|
+
}
|
|
180
|
+
resolve(Array.from(indices).sort((a, b) => a - b).map((i) => items[i].value));
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return new Promise((resolve) => {
|
|
186
|
+
let index = 0;
|
|
187
|
+
const selected = new Set();
|
|
188
|
+
const lineCount = (title ? 1 : 0) + items.length + 1;
|
|
189
|
+
|
|
190
|
+
const render = (first) => {
|
|
191
|
+
const lines = (title ? [title] : []).concat(
|
|
192
|
+
items.map((item, i) => {
|
|
193
|
+
const circle = selected.has(i) ? CIRCLE_FILLED : CIRCLE_EMPTY;
|
|
194
|
+
const prefix = i === index ? C.cyan + '>' + C.reset + ' ' : ' ';
|
|
195
|
+
return prefix + circle + formatLabel(item);
|
|
196
|
+
})
|
|
197
|
+
);
|
|
198
|
+
if (!first) {
|
|
199
|
+
process.stdout.write('\u001b[' + lineCount + 'A');
|
|
200
|
+
}
|
|
201
|
+
process.stdout.write('\u001b[?25l');
|
|
202
|
+
process.stdout.write(lines.join('\n') + '\n\n');
|
|
203
|
+
process.stdout.write('\u001b[?25h');
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
process.stdin.setRawMode(true);
|
|
207
|
+
process.stdin.resume();
|
|
208
|
+
process.stdin.setEncoding('utf8');
|
|
209
|
+
|
|
210
|
+
render(true);
|
|
211
|
+
|
|
212
|
+
let buf = '';
|
|
213
|
+
const onData = (ch) => {
|
|
214
|
+
if (ch === '\u0003') {
|
|
215
|
+
process.stdin.setRawMode(false);
|
|
216
|
+
process.stdin.removeListener('data', onData);
|
|
217
|
+
process.stdout.write('\n');
|
|
218
|
+
process.exit(130);
|
|
219
|
+
}
|
|
220
|
+
if (ch === '\r' || ch === '\n') {
|
|
221
|
+
process.stdin.setRawMode(false);
|
|
222
|
+
process.stdin.removeListener('data', onData);
|
|
223
|
+
process.stdin.pause();
|
|
224
|
+
process.stdout.write('\n');
|
|
225
|
+
resolve(Array.from(selected).sort((a, b) => a - b).map((i) => items[i].value));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (ch === ' ') {
|
|
229
|
+
buf = '';
|
|
230
|
+
if (selected.has(index)) selected.delete(index);
|
|
231
|
+
else selected.add(index);
|
|
232
|
+
render(false);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
buf += ch;
|
|
236
|
+
const isUp = buf === '\u001b[A' || buf === '\u001bOA' || (buf.length >= 2 && buf.endsWith('A') && buf.startsWith('\u001b'));
|
|
237
|
+
const isDown = buf === '\u001b[B' || buf === '\u001bOB' || (buf.length >= 2 && buf.endsWith('B') && buf.startsWith('\u001b'));
|
|
238
|
+
if (isUp) {
|
|
239
|
+
buf = '';
|
|
240
|
+
index = index <= 0 ? items.length - 1 : index - 1;
|
|
241
|
+
render(false);
|
|
242
|
+
} else if (isDown) {
|
|
243
|
+
buf = '';
|
|
244
|
+
index = index >= items.length - 1 ? 0 : index + 1;
|
|
245
|
+
render(false);
|
|
246
|
+
} else if (buf.length > 12 || (buf.length === 1 && ch !== '\u001b')) {
|
|
247
|
+
buf = '';
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
process.stdin.on('data', onData);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
58
254
|
function printHelp() {
|
|
59
255
|
console.log(`
|
|
60
256
|
rizzo-css CLI — Add Rizzo CSS to your project
|
|
@@ -63,15 +259,23 @@ Usage:
|
|
|
63
259
|
npx rizzo-css <command> [options]
|
|
64
260
|
|
|
65
261
|
Commands:
|
|
66
|
-
init Scaffold a
|
|
67
|
-
add Copy Rizzo CSS into the current project
|
|
68
|
-
theme List available themes
|
|
262
|
+
init Scaffold a minimal project (menus: location, framework, themes, components)
|
|
263
|
+
add Copy Rizzo CSS into the current project (auto-detects Svelte/Astro)
|
|
264
|
+
theme List all available themes (use in init or set data-theme on <html>)
|
|
69
265
|
help Show this help
|
|
70
266
|
|
|
267
|
+
Use framework CLI first, then add Rizzo CSS:
|
|
268
|
+
npm create svelte@latest my-app
|
|
269
|
+
cd my-app && npx rizzo-css add
|
|
270
|
+
|
|
271
|
+
npm create astro@latest my-app
|
|
272
|
+
cd my-app && npx rizzo-css add
|
|
273
|
+
|
|
71
274
|
Examples:
|
|
72
275
|
npx rizzo-css init
|
|
73
276
|
npx rizzo-css add
|
|
74
277
|
npx rizzo-css add --path public/css
|
|
278
|
+
npx rizzo-css add --framework svelte
|
|
75
279
|
npx rizzo-css theme
|
|
76
280
|
|
|
77
281
|
Docs: https://rizzo-css.vercel.app
|
|
@@ -79,16 +283,44 @@ Docs: https://rizzo-css.vercel.app
|
|
|
79
283
|
}
|
|
80
284
|
|
|
81
285
|
function cmdTheme() {
|
|
82
|
-
|
|
83
|
-
THEMES.forEach((t) =>
|
|
84
|
-
|
|
286
|
+
process.stdout.write('\nAvailable themes (set data-theme on <html>):\n\n');
|
|
287
|
+
THEMES.forEach((t) => process.stdout.write(' ' + t + '\n'));
|
|
288
|
+
process.stdout.write('\nExample: <html lang="en" data-theme="github-dark-classic">\n\n');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** Detect framework from cwd: "svelte" | "astro" | null. */
|
|
292
|
+
function detectFramework(cwd) {
|
|
293
|
+
if (existsSync(join(cwd, 'svelte.config.js')) || existsSync(join(cwd, 'svelte.config.ts'))) return 'svelte';
|
|
294
|
+
if (existsSync(join(cwd, 'astro.config.mjs')) || existsSync(join(cwd, 'astro.config.mts')) || existsSync(join(cwd, 'astro.config.js'))) return 'astro';
|
|
295
|
+
try {
|
|
296
|
+
const pkg = readFileSync(join(cwd, 'package.json'), 'utf8');
|
|
297
|
+
const json = JSON.parse(pkg);
|
|
298
|
+
const deps = { ...json.dependencies, ...(json.devDependencies || {}) };
|
|
299
|
+
if (deps['@sveltejs/kit'] || deps['svelte']) return 'svelte';
|
|
300
|
+
if (deps['astro']) return 'astro';
|
|
301
|
+
} catch (_) { /* ignore */ }
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/** Default CSS directory and link href for a framework (for add command). */
|
|
306
|
+
function getFrameworkCssPaths(framework) {
|
|
307
|
+
if (framework === 'svelte') return { targetDir: 'static/css', linkHref: '/css/rizzo.min.css' };
|
|
308
|
+
if (framework === 'astro') return { targetDir: 'public/css', linkHref: '/css/rizzo.min.css' };
|
|
309
|
+
return { targetDir: 'css', linkHref: 'css/rizzo.min.css' };
|
|
85
310
|
}
|
|
86
311
|
|
|
87
312
|
function cmdAdd(argv) {
|
|
88
313
|
const pathIdx = argv.indexOf('--path');
|
|
89
314
|
const customPath = pathIdx !== -1 && argv[pathIdx + 1] ? argv[pathIdx + 1] : null;
|
|
90
|
-
const
|
|
91
|
-
const
|
|
315
|
+
const frameworkIdx = argv.indexOf('--framework');
|
|
316
|
+
const explicitFramework = frameworkIdx !== -1 && argv[frameworkIdx + 1] ? argv[frameworkIdx + 1].toLowerCase() : null;
|
|
317
|
+
const cwd = process.cwd();
|
|
318
|
+
const framework = explicitFramework && FRAMEWORKS.includes(explicitFramework)
|
|
319
|
+
? explicitFramework
|
|
320
|
+
: (explicitFramework === null ? detectFramework(cwd) : null);
|
|
321
|
+
const paths = getFrameworkCssPaths(framework);
|
|
322
|
+
const targetDir = customPath || paths.targetDir;
|
|
323
|
+
const targetFile = join(cwd, targetDir, 'rizzo.min.css');
|
|
92
324
|
const cssSource = getCssPath();
|
|
93
325
|
|
|
94
326
|
if (!existsSync(cssSource)) {
|
|
@@ -96,26 +328,27 @@ function cmdAdd(argv) {
|
|
|
96
328
|
process.exit(1);
|
|
97
329
|
}
|
|
98
330
|
|
|
99
|
-
mkdirSync(join(
|
|
331
|
+
mkdirSync(join(cwd, targetDir), { recursive: true });
|
|
100
332
|
copyFileSync(cssSource, targetFile);
|
|
101
|
-
const
|
|
333
|
+
const linkHref = customPath ? customPath + '/rizzo.min.css' : paths.linkHref;
|
|
102
334
|
console.log('\n✓ Rizzo CSS copied to ' + targetFile);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
335
|
+
if (framework === 'svelte') {
|
|
336
|
+
console.log('\nDetected Svelte/SvelteKit. Add to your root layout (e.g. src/app.html):\n');
|
|
337
|
+
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
338
|
+
console.log('\nSet a theme on <html>: data-theme="github-dark-classic" (see: npx rizzo-css theme)');
|
|
339
|
+
console.log('\nTo add Rizzo Svelte components later: copy from this package\'s scaffold or run npx rizzo-css init and pick Svelte + components in an empty folder, then copy the generated files.\n');
|
|
340
|
+
} else if (framework === 'astro') {
|
|
341
|
+
console.log('\nDetected Astro. Add to your layout (e.g. src/layouts/Layout.astro):\n');
|
|
342
|
+
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
343
|
+
console.log('\nSet a theme on <html>: data-theme="github-dark-classic" (see: npx rizzo-css theme)\n');
|
|
344
|
+
} else {
|
|
345
|
+
console.log('\nAdd to your HTML or layout:\n');
|
|
346
|
+
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
347
|
+
if (framework === 'vanilla') {
|
|
348
|
+
console.log('\nVanilla JS: same CSS and component classes as Astro/Svelte. Use the same BEM markup from the docs.');
|
|
349
|
+
}
|
|
350
|
+
console.log('\nSet a theme on <html>: data-theme="github-dark-classic" (see: npx rizzo-css theme)\n');
|
|
117
351
|
}
|
|
118
|
-
return indices.size === 0 ? [] : Array.from(indices).sort((a, b) => a - b).map((i) => componentList[i]);
|
|
119
352
|
}
|
|
120
353
|
|
|
121
354
|
function getScaffoldSvelteDir() {
|
|
@@ -126,6 +359,10 @@ function getScaffoldAstroDir() {
|
|
|
126
359
|
return join(getPackageRoot(), 'scaffold', 'astro');
|
|
127
360
|
}
|
|
128
361
|
|
|
362
|
+
function getScaffoldVanillaIndex() {
|
|
363
|
+
return join(getPackageRoot(), 'scaffold', 'vanilla', 'index.html');
|
|
364
|
+
}
|
|
365
|
+
|
|
129
366
|
function copyDirRecursive(src, dest) {
|
|
130
367
|
mkdirSync(dest, { recursive: true });
|
|
131
368
|
const entries = readdirSync(src, { withFileTypes: true });
|
|
@@ -205,23 +442,47 @@ function copyAstroComponents(projectDir, selectedNames) {
|
|
|
205
442
|
}
|
|
206
443
|
|
|
207
444
|
async function cmdInit() {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
445
|
+
const projectChoice = await selectMenu(
|
|
446
|
+
[
|
|
447
|
+
{ value: 'cwd', label: 'Current directory' },
|
|
448
|
+
{ value: 'name', label: 'Enter project name (new folder)' },
|
|
449
|
+
],
|
|
450
|
+
'? Project location'
|
|
451
|
+
);
|
|
452
|
+
const name = projectChoice === 'name' ? await question('Project name (folder name): ') : '';
|
|
453
|
+
|
|
454
|
+
const framework = await selectMenu(
|
|
455
|
+
[
|
|
456
|
+
{ value: 'vanilla', label: 'Vanilla JS (HTML + CSS + same styles & components)', color: C.vanilla },
|
|
457
|
+
{ value: 'astro', label: 'Astro', color: C.astro },
|
|
458
|
+
{ value: 'svelte', label: 'Svelte', color: C.svelte },
|
|
459
|
+
],
|
|
460
|
+
'? Framework (arrows, Enter to select) — all get the same CSS and component styles'
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
const selectedThemes = await multiSelectMenu(
|
|
464
|
+
THEMES.map((t) => ({ value: t, label: t })),
|
|
465
|
+
'? Themes (Space to toggle, Enter to confirm)'
|
|
466
|
+
);
|
|
467
|
+
const themeList = selectedThemes.length > 0 ? selectedThemes : [THEMES[0]];
|
|
468
|
+
const theme = THEMES.includes(themeList[0]) ? themeList[0] : THEMES[0];
|
|
214
469
|
|
|
215
470
|
let selectedComponents = [];
|
|
216
471
|
const componentList = framework === 'svelte' ? SVELTE_COMPONENTS : framework === 'astro' ? ASTRO_COMPONENTS : [];
|
|
217
472
|
if (componentList.length > 0) {
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
473
|
+
const includeLabel = framework === 'svelte' ? 'Svelte' : 'Astro';
|
|
474
|
+
const includeChoice = await selectMenu(
|
|
475
|
+
[
|
|
476
|
+
{ value: 'none', label: 'None' },
|
|
477
|
+
{ value: 'pick', label: 'Yes, pick ' + includeLabel + ' components' },
|
|
478
|
+
],
|
|
479
|
+
'? Include ' + includeLabel + ' components?'
|
|
480
|
+
);
|
|
481
|
+
if (includeChoice === 'pick') {
|
|
482
|
+
selectedComponents = await multiSelectMenu(
|
|
483
|
+
componentList.map((c) => ({ value: c, label: c })),
|
|
484
|
+
'? Components (Space to toggle, Enter to confirm)'
|
|
485
|
+
);
|
|
225
486
|
}
|
|
226
487
|
}
|
|
227
488
|
|
|
@@ -239,8 +500,22 @@ async function cmdInit() {
|
|
|
239
500
|
copyFileSync(cssSource, cssTarget);
|
|
240
501
|
|
|
241
502
|
const linkHref = framework === 'astro' ? '/css/rizzo.min.css' : 'css/rizzo.min.css';
|
|
242
|
-
const
|
|
243
|
-
|
|
503
|
+
const themeComment = themeList.length > 0
|
|
504
|
+
? '\n <!-- Selected themes: ' + themeList.join(', ') + ' -->'
|
|
505
|
+
: '';
|
|
506
|
+
const indexPath = join(projectDir, 'index.html');
|
|
507
|
+
const vanillaScaffoldPath = getScaffoldVanillaIndex();
|
|
508
|
+
if (framework === 'vanilla' && existsSync(vanillaScaffoldPath)) {
|
|
509
|
+
let indexHtml = readFileSync(vanillaScaffoldPath, 'utf8');
|
|
510
|
+
indexHtml = indexHtml
|
|
511
|
+
.replace(/\{\{DATA_THEME\}\}/g, theme)
|
|
512
|
+
.replace(/\{\{THEME_LIST_COMMENT\}\}/g, themeComment)
|
|
513
|
+
.replace(/\{\{TITLE\}\}/g, name || 'App')
|
|
514
|
+
.replace(/\{\{LINK_HREF\}\}/g, linkHref);
|
|
515
|
+
writeFileSync(indexPath, indexHtml, 'utf8');
|
|
516
|
+
} else {
|
|
517
|
+
const indexHtml = `<!DOCTYPE html>
|
|
518
|
+
<html lang="en" data-theme="${theme}">${themeComment}
|
|
244
519
|
<head>
|
|
245
520
|
<meta charset="UTF-8" />
|
|
246
521
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
@@ -253,9 +528,8 @@ async function cmdInit() {
|
|
|
253
528
|
</body>
|
|
254
529
|
</html>
|
|
255
530
|
`;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
writeFileSync(indexPath, indexHtml, 'utf8');
|
|
531
|
+
writeFileSync(indexPath, indexHtml, 'utf8');
|
|
532
|
+
}
|
|
259
533
|
|
|
260
534
|
if (framework === 'svelte' && selectedComponents.length > 0) {
|
|
261
535
|
copySvelteComponents(projectDir, selectedComponents);
|
|
@@ -266,6 +540,13 @@ async function cmdInit() {
|
|
|
266
540
|
console.log('\n✓ Project ready at ' + projectDir);
|
|
267
541
|
console.log(' - ' + cssTarget);
|
|
268
542
|
console.log(' - ' + indexPath);
|
|
543
|
+
if (framework === 'vanilla') {
|
|
544
|
+
console.log(' - Vanilla JS: same CSS and component styles as Astro/Svelte; index includes theme switcher and sample components.');
|
|
545
|
+
}
|
|
546
|
+
if (framework === 'svelte' || framework === 'astro') {
|
|
547
|
+
const fw = framework === 'svelte' ? 'Svelte' : 'Astro';
|
|
548
|
+
console.log('\nTip: To use the official ' + fw + ' scaffold instead, create a project with their CLI (e.g. npm create ' + framework + '@latest my-app), then run npx rizzo-css add in that folder.');
|
|
549
|
+
}
|
|
269
550
|
console.log('\nRun a local server (e.g. npx serve .) or open index.html. Docs: https://rizzo-css.vercel.app\n');
|
|
270
551
|
}
|
|
271
552
|
|
package/dist/rizzo.min.css
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
:root{--primary-color:oklch(45.2% 0.198 250.1deg);--secondary-color:oklch(25.1% 0 0deg);--font-family-sans:system-ui,-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif;--font-family-serif:georgia,"Times New Roman",times,serif;--font-family-mono:"SF Mono",monaco,"Cascadia Code","Roboto Mono",consolas,"Courier New",monospace;--font-family:var(--font-family-sans);--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-size-scale:1;--font-size-xs:calc(0.75rem*var(--font-size-scale));--font-size-sm:calc(0.875rem*var(--font-size-scale));--font-size-base:calc(1rem*var(--font-size-scale));--font-size-lg:calc(1.125rem*var(--font-size-scale));--font-size-xl:calc(1.25rem*var(--font-size-scale));--font-size-2xl:calc(1.5rem*var(--font-size-scale));--font-size-3xl:calc(1.875rem*var(--font-size-scale));--font-size-4xl:calc(2.25rem*var(--font-size-scale));--font-size-5xl:calc(3rem*var(--font-size-scale));--font-size-6xl:calc(3.75rem*var(--font-size-scale));--line-height-tight:1.25;--line-height-snug:1.375;--line-height-normal:1.5;--line-height-relaxed:1.625;--line-height-loose:2;--letter-spacing-tighter:-0.05em;--letter-spacing-tight:-0.025em;--letter-spacing-normal:0;--letter-spacing-wide:0.025em;--letter-spacing-wider:0.05em;--letter-spacing-widest:0.1em;--spacing-0:0;--spacing-1:0.25rem;--spacing-2:0.5rem;--spacing-3:0.75rem;--spacing-4:1rem;--spacing-5:1.25rem;--spacing-6:1.5rem;--spacing-8:2rem;--spacing-10:2.5rem;--spacing-12:3rem;--spacing-16:4rem;--spacing-20:5rem;--spacing-24:6rem;--spacing-0-125:0.125rem;--spacing-0-375:0.375rem;--spacing-0-625:0.625rem;--spacing-0-875:0.875rem;--spacing-28:7rem;--spacing-32:8rem;--spacing-36:9rem;--spacing-40:10rem;--spacing-48:12rem;--spacing-56:14rem;--spacing-64:16rem;--spacing-72:18rem;--spacing-80:20rem;--spacing-96:24rem;--spacing-50:12.5rem;--spacing-100:25rem;--spacing-150:37.5rem;--spacing-14:3.5rem;--spacing-15:3.75rem;--spacing-75:18.75rem;--spacing-175:43.75rem;--spacing-70:17.5rem;--spacing-105:26.25rem;--spacing-2500:2500rem;--radius-none:0;--radius-sm:0.125rem;--radius:0.25rem;--radius-md:0.375rem;--radius-lg:0.5rem;--radius-xl:0.75rem;--radius-2xl:1rem;--radius-3xl:1.5rem;--radius-full:9999px;--radius-circle:50%;--z-base:0;--z-1:1;--z-2:2;--z-3:3;--z-10:10;--z-dropdown:10;--z-dropdown-submenu:11;--z-sticky:50;--z-fixed:100;--z-search-overlay:98;--z-search-panel:99;--z-modal-backdrop:1999;--z-modal:2000;--z-tooltip:3000;--z-toast:4000;--z-settings:10000;--z-navbar:5000;--z-navbar-mobile-menu-open:5100;--z-skip-link:10001;--z-navbar-mobile-menu:101;--z-navbar-search-overlay:98;--z-navbar-search-panel:99;--z-navbar-mobile-search-overlay:101;--z-navbar-mobile-search-panel:102;--transition-fast:150ms;--transition-base:200ms;--transition-slow:300ms;--transition-slower:350ms;--transition-slowest:400ms;--transition-ease-out:300ms ease-out;--transition-ease-in:300ms ease-in;--theme-transition-duration:0.2s;--blur-sm:4px;--blur:8px;--blur-md:12px;--blur-lg:16px;--outline-width:2px;--outline-offset:2px;--container-sm:640px;--container-md:768px;--container-lg:1024px;--container-xl:1280px;--container-2xl:1536px;--container-default:1200px;--vh-70:70vh;--vh-80:80vh;--vh-90:90vh;--touch-target-min:3rem;--max-height-dropdown:600px;--max-height-modal:32rem;--max-height-navbar-submenu:2000px;--ease-in-out-cubic:cubic-bezier(0.4,0,0.2,1);--scale-80:0.8;--scale-95:0.95;--scale-100:1;--scale-110:1.1;--border-width:1px;--border-width-2:2px;--border-width-3:3px;--border-width-4:4px;--border-width-arrow:6px;--border-width-accent:3px;--opacity-0:0;--opacity-50:0.5;--opacity-60:0.6;--opacity-70:0.7;--opacity-80:0.8;--opacity-90:0.9;--opacity-100:1;--background:oklch(100% 0 0deg);--background-alt:oklch(96.9% 0 0deg);--text:oklch(25.1% 0 0deg);--text-dim:oklch(50.2% 0 0deg);--icon:var(--text);--icon-dim:var(--text-dim);--border:oklch(90.2% 0 0deg);--accent:oklch(45.2% 0.198 250.1deg);--accent-hover:oklch(40.2% 0.198 250.1deg);--accent-text:oklch(100% 0 0deg);--accent-text-on-hover:var(--accent-text);--success:oklch(60.2% 0.182 145.1deg);--success-hover:oklch(70% 0.16 145deg);--success-text:oklch(20% 0 0deg);--success-text-on-solid:var(--success-text);--warning:oklch(80.2% 0.152 90.1deg);--warning-hover:oklch(88% 0.12 90deg);--warning-text:oklch(100% 0 0deg);--warning-text-on-solid:oklch(22% 0.02 90deg);--text-on-solid-hover:oklch(22% 0.02 0deg);--error:oklch(55.2% 0.218 25.1deg);--error-hover:oklch(65% 0.18 25deg);--error-text:oklch(100% 0 0deg);--error-text-on-solid:var(--error-text);--info:oklch(60.2% 0.118 210.1deg);--info-hover:oklch(70% 0.1 210deg);--info-text:oklch(20% 0 0deg);--info-text-on-solid:var(--info-text);--selection:oklch(70% 0.15 250deg);--shadow-color:oklch(0% 0 0deg);--shadow-sm:0 1px 2px 0 oklch(from var(--shadow-color) l c h/5%);--shadow:0 1px 3px 0 oklch(from var(--shadow-color) l c h/10%),0 1px 2px -1px oklch(from var(--shadow-color) l c h/10%);--shadow-md:0 4px 6px -1px oklch(from var(--shadow-color) l c h/10%),0 2px 4px -2px oklch(from var(--shadow-color) l c h/6%);--shadow-lg:0 10px 15px -3px oklch(from var(--shadow-color) l c h/10%),0 4px 6px -4px oklch(from var(--shadow-color) l c h/5%);--shadow-xl:0 20px 25px -5px oklch(from var(--shadow-color) l c h/10%),0 8px 10px -6px oklch(from var(--shadow-color) l c h/4%);--overlay:oklch(from var(--shadow-color) l c h/50%);--shadow-inset-sm:inset 0 var(--spacing-0-125) var(--spacing-0-125) oklch(from var(--shadow-color) l c h/10%);--shadow-inset:inset 0 var(--spacing-0-125) var(--spacing-0-125) oklch(from var(--shadow-color) l c h/10%)}*,
|
|
2
|
-
*::after,
|
|
3
|
-
*::before{box-sizing:border-box}html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;margin:0;padding:0} blockquote,body, dd, dl,
|
|
1
|
+
:root{--primary-color:oklch(45.2% 0.198 250.1deg);--secondary-color:oklch(25.1% 0 0deg);--font-family-sans:system-ui,-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif;--font-family-serif:georgia,"Times New Roman",times,serif;--font-family-mono:"SF Mono",monaco,"Cascadia Code","Roboto Mono",consolas,"Courier New",monospace;--font-family:var(--font-family-sans);--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-size-scale:1;--font-size-xs:calc(0.75rem*var(--font-size-scale));--font-size-sm:calc(0.875rem*var(--font-size-scale));--font-size-base:calc(1rem*var(--font-size-scale));--font-size-lg:calc(1.125rem*var(--font-size-scale));--font-size-xl:calc(1.25rem*var(--font-size-scale));--font-size-2xl:calc(1.5rem*var(--font-size-scale));--font-size-3xl:calc(1.875rem*var(--font-size-scale));--font-size-4xl:calc(2.25rem*var(--font-size-scale));--font-size-5xl:calc(3rem*var(--font-size-scale));--font-size-6xl:calc(3.75rem*var(--font-size-scale));--line-height-tight:1.25;--line-height-snug:1.375;--line-height-normal:1.5;--line-height-relaxed:1.625;--line-height-loose:2;--letter-spacing-tighter:-0.05em;--letter-spacing-tight:-0.025em;--letter-spacing-normal:0;--letter-spacing-wide:0.025em;--letter-spacing-wider:0.05em;--letter-spacing-widest:0.1em;--spacing-0:0;--spacing-1:0.25rem;--spacing-2:0.5rem;--spacing-3:0.75rem;--spacing-4:1rem;--spacing-5:1.25rem;--spacing-6:1.5rem;--spacing-8:2rem;--spacing-10:2.5rem;--spacing-12:3rem;--spacing-16:4rem;--spacing-20:5rem;--spacing-24:6rem;--spacing-0-125:0.125rem;--spacing-0-375:0.375rem;--spacing-0-625:0.625rem;--spacing-0-875:0.875rem;--spacing-28:7rem;--spacing-32:8rem;--spacing-36:9rem;--spacing-40:10rem;--spacing-48:12rem;--spacing-56:14rem;--spacing-64:16rem;--spacing-72:18rem;--spacing-80:20rem;--spacing-96:24rem;--spacing-50:12.5rem;--spacing-100:25rem;--spacing-150:37.5rem;--spacing-14:3.5rem;--spacing-15:3.75rem;--spacing-75:18.75rem;--spacing-175:43.75rem;--spacing-70:17.5rem;--spacing-105:26.25rem;--spacing-2500:2500rem;--radius-none:0;--radius-sm:0.125rem;--radius:0.25rem;--radius-md:0.375rem;--radius-lg:0.5rem;--radius-xl:0.75rem;--radius-2xl:1rem;--radius-3xl:1.5rem;--radius-full:9999px;--radius-circle:50%;--z-base:0;--z-1:1;--z-2:2;--z-3:3;--z-10:10;--z-dropdown:10;--z-dropdown-submenu:11;--z-sticky:50;--z-fixed:100;--z-search-overlay:98;--z-search-panel:99;--z-modal-backdrop:1999;--z-modal:2000;--z-tooltip:3000;--z-toast:4000;--z-settings:10000;--z-navbar:5000;--z-navbar-mobile-menu-open:5100;--z-skip-link:10001;--z-navbar-mobile-menu:101;--z-navbar-search-overlay:98;--z-navbar-search-panel:99;--z-navbar-mobile-search-overlay:101;--z-navbar-mobile-search-panel:102;--transition-fast:150ms;--transition-base:200ms;--transition-slow:300ms;--transition-slower:350ms;--transition-slowest:400ms;--transition-ease-out:300ms ease-out;--transition-ease-in:300ms ease-in;--theme-transition-duration:0.2s;--blur-sm:4px;--blur:8px;--blur-md:12px;--blur-lg:16px;--outline-width:2px;--outline-offset:2px;--container-sm:640px;--container-md:768px;--container-lg:1024px;--container-xl:1280px;--container-2xl:1536px;--container-default:1200px;--vh-70:70vh;--vh-80:80vh;--vh-90:90vh;--touch-target-min:3rem;--max-height-dropdown:600px;--max-height-modal:32rem;--max-height-navbar-submenu:2000px;--ease-in-out-cubic:cubic-bezier(0.4,0,0.2,1);--scale-80:0.8;--scale-95:0.95;--scale-100:1;--scale-110:1.1;--border-width:1px;--border-width-2:2px;--border-width-3:3px;--border-width-4:4px;--border-width-arrow:6px;--border-width-accent:3px;--opacity-0:0;--opacity-50:0.5;--opacity-60:0.6;--opacity-70:0.7;--opacity-80:0.8;--opacity-90:0.9;--opacity-100:1;--background:oklch(100% 0 0deg);--background-alt:oklch(96.9% 0 0deg);--text:oklch(25.1% 0 0deg);--text-dim:oklch(50.2% 0 0deg);--icon:var(--text);--icon-dim:var(--text-dim);--border:oklch(90.2% 0 0deg);--accent:oklch(45.2% 0.198 250.1deg);--accent-hover:oklch(40.2% 0.198 250.1deg);--accent-text:oklch(100% 0 0deg);--accent-text-on-hover:var(--accent-text);--success:oklch(60.2% 0.182 145.1deg);--success-hover:oklch(70% 0.16 145deg);--success-text:oklch(20% 0 0deg);--success-text-on-solid:var(--success-text);--warning:oklch(80.2% 0.152 90.1deg);--warning-hover:oklch(88% 0.12 90deg);--warning-text:oklch(100% 0 0deg);--warning-text-on-solid:oklch(22% 0.02 90deg);--text-on-solid-hover:oklch(22% 0.02 0deg);--error:oklch(55.2% 0.218 25.1deg);--error-hover:oklch(65% 0.18 25deg);--error-text:oklch(100% 0 0deg);--error-text-on-solid:var(--error-text);--info:oklch(60.2% 0.118 210.1deg);--info-hover:oklch(70% 0.1 210deg);--info-text:oklch(20% 0 0deg);--info-text-on-solid:var(--info-text);--selection:oklch(70% 0.15 250deg);--shadow-color:oklch(0% 0 0deg);--shadow-sm:0 1px 2px 0 oklch(from var(--shadow-color) l c h/5%);--shadow:0 1px 3px 0 oklch(from var(--shadow-color) l c h/10%),0 1px 2px -1px oklch(from var(--shadow-color) l c h/10%);--shadow-md:0 4px 6px -1px oklch(from var(--shadow-color) l c h/10%),0 2px 4px -2px oklch(from var(--shadow-color) l c h/6%);--shadow-lg:0 10px 15px -3px oklch(from var(--shadow-color) l c h/10%),0 4px 6px -4px oklch(from var(--shadow-color) l c h/5%);--shadow-xl:0 20px 25px -5px oklch(from var(--shadow-color) l c h/10%),0 8px 10px -6px oklch(from var(--shadow-color) l c h/4%);--overlay:oklch(from var(--shadow-color) l c h/50%);--shadow-inset-sm:inset 0 var(--spacing-0-125) var(--spacing-0-125) oklch(from var(--shadow-color) l c h/10%);--shadow-inset:inset 0 var(--spacing-0-125) var(--spacing-0-125) oklch(from var(--shadow-color) l c h/10%)}*, *::after, *::before{box-sizing:border-box;margin:0;padding:0}html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;margin:0;padding:0} blockquote,body, dd, dl,
|
|
4
2
|
figure, h1, h2, h3, h4, h5, h6, p{margin-block-end:0}
|
|
5
3
|
ol[role="list"],ul[role="list"]{list-style:none}body{line-height:1.5;margin:0;min-height:100vh;padding:0}
|
|
6
4
|
button,h1, h2, h3, h4, h5, h6, input, label{line-height:1.1}h1, h2, h3, h4, h5, h6{text-wrap:balance}a:not([class]){-webkit-text-decoration-skip:ink;color:currentcolor;text-decoration-skip-ink:auto}img,
|
package/package.json
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="{{DATA_THEME}}">{{THEME_LIST_COMMENT}}
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>{{TITLE}}</title>
|
|
7
|
+
<link rel="stylesheet" href="{{LINK_HREF}}" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header style="margin-bottom: var(--spacing-6);">
|
|
11
|
+
<h1>Hello, Rizzo CSS</h1>
|
|
12
|
+
<p>Vanilla JS — same styles and components as Astro/Svelte. Use the same BEM classes; see <a href="https://rizzo-css.vercel.app/docs/components">docs</a>.</p>
|
|
13
|
+
<div style="display: flex; align-items: center; gap: var(--spacing-3); flex-wrap: wrap; margin-top: var(--spacing-3);">
|
|
14
|
+
<label for="theme-select">Theme:</label>
|
|
15
|
+
<select id="theme-select" style="width: auto; min-width: 12rem;">
|
|
16
|
+
<option value="github-dark-classic">github-dark-classic</option>
|
|
17
|
+
<option value="github-light">github-light</option>
|
|
18
|
+
<option value="shades-of-purple">shades-of-purple</option>
|
|
19
|
+
<option value="sandstorm-classic">sandstorm-classic</option>
|
|
20
|
+
<option value="rocky-blood-orange">rocky-blood-orange</option>
|
|
21
|
+
<option value="minimal-dark-neon-yellow">minimal-dark-neon-yellow</option>
|
|
22
|
+
<option value="hack-the-box">hack-the-box</option>
|
|
23
|
+
<option value="pink-cat-boo">pink-cat-boo</option>
|
|
24
|
+
<option value="red-velvet-cupcake">red-velvet-cupcake</option>
|
|
25
|
+
<option value="orangy-one-light">orangy-one-light</option>
|
|
26
|
+
<option value="sunflower">sunflower</option>
|
|
27
|
+
<option value="green-breeze-light">green-breeze-light</option>
|
|
28
|
+
<option value="cute-pink">cute-pink</option>
|
|
29
|
+
<option value="semi-light-purple">semi-light-purple</option>
|
|
30
|
+
</select>
|
|
31
|
+
</div>
|
|
32
|
+
</header>
|
|
33
|
+
|
|
34
|
+
<section style="margin-bottom: var(--spacing-6);">
|
|
35
|
+
<h2>Buttons</h2>
|
|
36
|
+
<div style="display: flex; flex-wrap: wrap; gap: var(--spacing-3);">
|
|
37
|
+
<button type="button" class="btn">Default</button>
|
|
38
|
+
<button type="button" class="btn btn-primary">Primary</button>
|
|
39
|
+
<button type="button" class="btn btn-success">Success</button>
|
|
40
|
+
<button type="button" class="btn btn-warning">Warning</button>
|
|
41
|
+
<button type="button" class="btn btn-error">Error</button>
|
|
42
|
+
<button type="button" class="btn btn-outline">Outline</button>
|
|
43
|
+
</div>
|
|
44
|
+
</section>
|
|
45
|
+
|
|
46
|
+
<section style="margin-bottom: var(--spacing-6);">
|
|
47
|
+
<h2>Card & Badge</h2>
|
|
48
|
+
<div class="card" style="max-width: 20rem;">
|
|
49
|
+
<div class="card__body">
|
|
50
|
+
<h3 class="card__title">Card title</h3>
|
|
51
|
+
<p>Same component styles as Astro and Svelte. Use class names from the <a href="https://rizzo-css.vercel.app/docs/components">component docs</a>.</p>
|
|
52
|
+
<span class="badge badge--primary">Badge</span>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</section>
|
|
56
|
+
|
|
57
|
+
<p><small>All themes and component styles are included. Run <code>npx rizzo-css theme</code> to list themes.</small></p>
|
|
58
|
+
|
|
59
|
+
<script>
|
|
60
|
+
(function () {
|
|
61
|
+
var select = document.getElementById('theme-select');
|
|
62
|
+
var html = document.documentElement;
|
|
63
|
+
var key = 'rizzo-theme';
|
|
64
|
+
function applyTheme(value) {
|
|
65
|
+
html.setAttribute('data-theme', value);
|
|
66
|
+
try { localStorage.setItem(key, value); } catch (e) {}
|
|
67
|
+
select.value = value;
|
|
68
|
+
}
|
|
69
|
+
var stored = null;
|
|
70
|
+
try { stored = localStorage.getItem(key); } catch (e) {}
|
|
71
|
+
var initial = stored || html.getAttribute('data-theme') || 'github-dark-classic';
|
|
72
|
+
applyTheme(initial);
|
|
73
|
+
select.addEventListener('change', function () { applyTheme(select.value); });
|
|
74
|
+
})();
|
|
75
|
+
</script>
|
|
76
|
+
</body>
|
|
77
|
+
</html>
|