rizzo-css 0.0.3 → 0.0.5
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 +508 -56
- package/dist/rizzo.min.css +1 -3
- package/package.json +1 -1
- package/scaffold/astro-app/astro.config.mjs +4 -0
- package/scaffold/astro-app/package.json +13 -0
- package/scaffold/astro-app/public/.gitkeep +0 -0
- package/scaffold/astro-app/src/layouts/Layout.astro +19 -0
- package/scaffold/astro-app/src/pages/index.astro +13 -0
- package/scaffold/astro-app/tsconfig.json +5 -0
- package/scaffold/svelte-app/package.json +17 -0
- package/scaffold/svelte-app/src/app.d.ts +13 -0
- package/scaffold/svelte-app/src/app.html +12 -0
- package/scaffold/svelte-app/src/routes/+layout.svelte +5 -0
- package/scaffold/svelte-app/src/routes/+page.svelte +12 -0
- package/scaffold/svelte-app/static/.gitkeep +0 -0
- package/scaffold/svelte-app/svelte.config.js +11 -0
- package/scaffold/svelte-app/tsconfig.json +15 -0
- package/scaffold/svelte-app/vite.config.ts +6 -0
- 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`
|
|
15
|
+
**Quick start (no install):** `npx rizzo-css init` — first choose **add to existing project** or **create new**. Existing: framework (auto-detect), themes, optional components. New: scaffold (Vanilla example, default Astro app, or default Svelte app; CLI colors: Vanilla = yellow, Astro = orange, Svelte = orange-red). All get the **same CSS and component styles**. To use the **official Svelte or Astro scaffold** plus Rizzo CSS, create the app with their CLI first, then run `npx rizzo-css add`:
|
|
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
|
|
67
|
-
add Copy Rizzo CSS into the current project
|
|
68
|
-
theme List available themes
|
|
262
|
+
init Add Rizzo to existing project or scaffold new one (first menu: existing vs new)
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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');
|
|
351
|
+
}
|
|
119
352
|
}
|
|
120
353
|
|
|
121
354
|
function getScaffoldSvelteDir() {
|
|
@@ -126,6 +359,18 @@ 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
|
+
|
|
366
|
+
function getScaffoldAstroAppDir() {
|
|
367
|
+
return join(getPackageRoot(), 'scaffold', 'astro-app');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function getScaffoldSvelteAppDir() {
|
|
371
|
+
return join(getPackageRoot(), 'scaffold', 'svelte-app');
|
|
372
|
+
}
|
|
373
|
+
|
|
129
374
|
function copyDirRecursive(src, dest) {
|
|
130
375
|
mkdirSync(dest, { recursive: true });
|
|
131
376
|
const entries = readdirSync(src, { withFileTypes: true });
|
|
@@ -140,6 +385,31 @@ function copyDirRecursive(src, dest) {
|
|
|
140
385
|
}
|
|
141
386
|
}
|
|
142
387
|
|
|
388
|
+
/** Copy directory recursively; in text files (utf-8), replace each key in replacements with its value. */
|
|
389
|
+
function copyDirRecursiveWithReplacements(src, dest, replacements) {
|
|
390
|
+
mkdirSync(dest, { recursive: true });
|
|
391
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
392
|
+
const textExtensions = new Set(['.html', '.astro', '.svelte', '.ts', '.js', '.mjs', '.json', '.css', '.md']);
|
|
393
|
+
for (const e of entries) {
|
|
394
|
+
const srcPath = join(src, e.name);
|
|
395
|
+
const destPath = join(dest, e.name);
|
|
396
|
+
if (e.isDirectory()) {
|
|
397
|
+
copyDirRecursiveWithReplacements(srcPath, destPath, replacements);
|
|
398
|
+
} else {
|
|
399
|
+
const ext = srcPath.slice(srcPath.lastIndexOf('.'));
|
|
400
|
+
if (textExtensions.has(ext)) {
|
|
401
|
+
let content = readFileSync(srcPath, 'utf8');
|
|
402
|
+
for (const [key, value] of Object.entries(replacements)) {
|
|
403
|
+
content = content.split(key).join(value);
|
|
404
|
+
}
|
|
405
|
+
writeFileSync(destPath, content, 'utf8');
|
|
406
|
+
} else {
|
|
407
|
+
copyFileSync(srcPath, destPath);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
143
413
|
function copySvelteComponents(projectDir, selectedNames) {
|
|
144
414
|
const scaffoldDir = getScaffoldSvelteDir();
|
|
145
415
|
if (!existsSync(scaffoldDir)) {
|
|
@@ -204,30 +474,149 @@ function copyAstroComponents(projectDir, selectedNames) {
|
|
|
204
474
|
}
|
|
205
475
|
}
|
|
206
476
|
|
|
477
|
+
/** Add Rizzo CSS (and optional components) to an existing project in cwd. */
|
|
478
|
+
async function runAddToExisting() {
|
|
479
|
+
const cwd = process.cwd();
|
|
480
|
+
const detected = detectFramework(cwd);
|
|
481
|
+
const frameworkOptions = [
|
|
482
|
+
{ value: 'vanilla', label: 'Vanilla JS (HTML + CSS)', color: C.vanilla },
|
|
483
|
+
{ value: 'astro', label: 'Astro', color: C.astro },
|
|
484
|
+
{ value: 'svelte', label: 'Svelte', color: C.svelte },
|
|
485
|
+
];
|
|
486
|
+
let frameworkPrompt = '? Framework';
|
|
487
|
+
if (detected) {
|
|
488
|
+
frameworkPrompt += ' (detected: ' + detected + ' — pick to confirm or choose another)';
|
|
489
|
+
}
|
|
490
|
+
const framework = await selectMenu(frameworkOptions, frameworkPrompt);
|
|
491
|
+
|
|
492
|
+
const selectedThemes = await multiSelectMenu(
|
|
493
|
+
THEMES.map((t) => ({ value: t, label: t })),
|
|
494
|
+
'? Themes (Space to toggle, Enter to confirm) — we\'ll suggest the first as default data-theme'
|
|
495
|
+
);
|
|
496
|
+
const themeList = selectedThemes.length > 0 ? selectedThemes : [THEMES[0]];
|
|
497
|
+
const suggestedTheme = THEMES.includes(themeList[0]) ? themeList[0] : THEMES[0];
|
|
498
|
+
|
|
499
|
+
let selectedComponents = [];
|
|
500
|
+
const componentList = framework === 'svelte' ? SVELTE_COMPONENTS : framework === 'astro' ? ASTRO_COMPONENTS : [];
|
|
501
|
+
if (componentList.length > 0) {
|
|
502
|
+
const includeLabel = framework === 'svelte' ? 'Svelte' : 'Astro';
|
|
503
|
+
const includeChoice = await selectMenu(
|
|
504
|
+
[
|
|
505
|
+
{ value: 'none', label: 'None' },
|
|
506
|
+
{ value: 'pick', label: 'Yes, pick ' + includeLabel + ' components' },
|
|
507
|
+
],
|
|
508
|
+
'? Include ' + includeLabel + ' components?'
|
|
509
|
+
);
|
|
510
|
+
if (includeChoice === 'pick') {
|
|
511
|
+
selectedComponents = await multiSelectMenu(
|
|
512
|
+
componentList.map((c) => ({ value: c, label: c })),
|
|
513
|
+
'? Components (Space to toggle, Enter to confirm)'
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const cssSource = getCssPath();
|
|
519
|
+
if (!existsSync(cssSource)) {
|
|
520
|
+
console.error('Error: Rizzo CSS build not found. Run from repo root: pnpm build:css');
|
|
521
|
+
process.exit(1);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const paths = getFrameworkCssPaths(framework);
|
|
525
|
+
const targetDir = join(cwd, paths.targetDir);
|
|
526
|
+
const cssTarget = join(targetDir, 'rizzo.min.css');
|
|
527
|
+
mkdirSync(targetDir, { recursive: true });
|
|
528
|
+
copyFileSync(cssSource, cssTarget);
|
|
529
|
+
|
|
530
|
+
if (framework === 'svelte' && selectedComponents.length > 0) {
|
|
531
|
+
copySvelteComponents(cwd, selectedComponents);
|
|
532
|
+
} else if (framework === 'astro' && selectedComponents.length > 0) {
|
|
533
|
+
copyAstroComponents(cwd, selectedComponents);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
const linkHref = paths.linkHref;
|
|
537
|
+
console.log('\n✓ Rizzo CSS added to your existing project');
|
|
538
|
+
console.log(' - ' + cssTarget);
|
|
539
|
+
if (framework === 'svelte') {
|
|
540
|
+
console.log('\nAdd to your root layout (e.g. src/app.html):');
|
|
541
|
+
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
542
|
+
console.log('\nSet a theme on <html>: data-theme="' + suggestedTheme + '" (see: npx rizzo-css theme)');
|
|
543
|
+
if (selectedComponents.length > 0) {
|
|
544
|
+
console.log(' Components are in src/lib/rizzo — import from \'$lib/rizzo\'.');
|
|
545
|
+
}
|
|
546
|
+
} else if (framework === 'astro') {
|
|
547
|
+
console.log('\nAdd to your layout (e.g. src/layouts/Layout.astro):');
|
|
548
|
+
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
549
|
+
console.log('\nSet a theme on <html>: data-theme="' + suggestedTheme + '" (see: npx rizzo-css theme)');
|
|
550
|
+
if (selectedComponents.length > 0) {
|
|
551
|
+
console.log(' Components are in src/components/rizzo — import from there.');
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
console.log('\nAdd to your HTML or layout:');
|
|
555
|
+
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
556
|
+
console.log('\nSet a theme on <html>: data-theme="' + suggestedTheme + '" (see: npx rizzo-css theme)');
|
|
557
|
+
}
|
|
558
|
+
console.log('\nDocs: https://rizzo-css.vercel.app\n');
|
|
559
|
+
}
|
|
560
|
+
|
|
207
561
|
async function cmdInit() {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
562
|
+
const initMode = await selectMenu(
|
|
563
|
+
[
|
|
564
|
+
{ value: 'existing', label: 'Add to existing project (current directory)' },
|
|
565
|
+
{ value: 'new', label: 'Create new project (scaffold)' },
|
|
566
|
+
],
|
|
567
|
+
'? Are you using an existing project or creating a new one?'
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
if (initMode === 'existing') {
|
|
571
|
+
await runAddToExisting();
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
212
574
|
|
|
213
|
-
const
|
|
575
|
+
const projectChoice = await selectMenu(
|
|
576
|
+
[
|
|
577
|
+
{ value: 'cwd', label: 'Current directory' },
|
|
578
|
+
{ value: 'name', label: 'Enter project name (new folder)' },
|
|
579
|
+
],
|
|
580
|
+
'? Project location'
|
|
581
|
+
);
|
|
582
|
+
const name = projectChoice === 'name' ? await question('Project name (folder name): ') : '';
|
|
583
|
+
|
|
584
|
+
const framework = await selectMenu(
|
|
585
|
+
[
|
|
586
|
+
{ value: 'vanilla', label: 'Vanilla JS (HTML + CSS + same styles & components)', color: C.vanilla },
|
|
587
|
+
{ value: 'astro', label: 'Astro', color: C.astro },
|
|
588
|
+
{ value: 'svelte', label: 'Svelte', color: C.svelte },
|
|
589
|
+
],
|
|
590
|
+
'? Framework (arrows, Enter to select) — all get the same CSS and component styles'
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
const selectedThemes = await multiSelectMenu(
|
|
594
|
+
THEMES.map((t) => ({ value: t, label: t })),
|
|
595
|
+
'? Themes (Space to toggle, Enter to confirm)'
|
|
596
|
+
);
|
|
597
|
+
const themeList = selectedThemes.length > 0 ? selectedThemes : [THEMES[0]];
|
|
598
|
+
const theme = THEMES.includes(themeList[0]) ? themeList[0] : THEMES[0];
|
|
214
599
|
|
|
215
600
|
let selectedComponents = [];
|
|
216
601
|
const componentList = framework === 'svelte' ? SVELTE_COMPONENTS : framework === 'astro' ? ASTRO_COMPONENTS : [];
|
|
217
602
|
if (componentList.length > 0) {
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
603
|
+
const includeLabel = framework === 'svelte' ? 'Svelte' : 'Astro';
|
|
604
|
+
const includeChoice = await selectMenu(
|
|
605
|
+
[
|
|
606
|
+
{ value: 'none', label: 'None' },
|
|
607
|
+
{ value: 'pick', label: 'Yes, pick ' + includeLabel + ' components' },
|
|
608
|
+
],
|
|
609
|
+
'? Include ' + includeLabel + ' components?'
|
|
610
|
+
);
|
|
611
|
+
if (includeChoice === 'pick') {
|
|
612
|
+
selectedComponents = await multiSelectMenu(
|
|
613
|
+
componentList.map((c) => ({ value: c, label: c })),
|
|
614
|
+
'? Components (Space to toggle, Enter to confirm)'
|
|
615
|
+
);
|
|
225
616
|
}
|
|
226
617
|
}
|
|
227
618
|
|
|
228
619
|
const projectDir = name ? join(process.cwd(), name) : process.cwd();
|
|
229
|
-
const cssDir = framework === 'astro' ? join(projectDir, 'public', 'css') : join(projectDir, 'css');
|
|
230
|
-
const cssTarget = join(cssDir, 'rizzo.min.css');
|
|
231
620
|
const cssSource = getCssPath();
|
|
232
621
|
|
|
233
622
|
if (!existsSync(cssSource)) {
|
|
@@ -235,12 +624,63 @@ async function cmdInit() {
|
|
|
235
624
|
process.exit(1);
|
|
236
625
|
}
|
|
237
626
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
627
|
+
const themeComment = themeList.length > 0
|
|
628
|
+
? '\n <!-- Selected themes: ' + themeList.join(', ') + ' -->'
|
|
629
|
+
: '';
|
|
630
|
+
const projectNamePkg = name
|
|
631
|
+
? name.replace(/\s+/g, '-').toLowerCase()
|
|
632
|
+
: (framework === 'astro' ? 'my-astro-app' : framework === 'svelte' ? 'my-svelte-app' : 'my-app');
|
|
633
|
+
const replacements = {
|
|
634
|
+
'{{DATA_THEME}}': theme,
|
|
635
|
+
'{{THEME_LIST_COMMENT}}': themeComment,
|
|
636
|
+
'{{TITLE}}': name || 'App',
|
|
637
|
+
'{{PROJECT_NAME}}': projectNamePkg,
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
const astroAppDir = getScaffoldAstroAppDir();
|
|
641
|
+
const svelteAppDir = getScaffoldSvelteAppDir();
|
|
642
|
+
|
|
643
|
+
let cssTarget;
|
|
644
|
+
let indexPath;
|
|
645
|
+
|
|
646
|
+
if (framework === 'astro' && existsSync(astroAppDir)) {
|
|
647
|
+
mkdirSync(projectDir, { recursive: true });
|
|
648
|
+
copyDirRecursiveWithReplacements(astroAppDir, projectDir, replacements);
|
|
649
|
+
mkdirSync(join(projectDir, 'public', 'css'), { recursive: true });
|
|
650
|
+
cssTarget = join(projectDir, 'public', 'css', 'rizzo.min.css');
|
|
651
|
+
copyFileSync(cssSource, cssTarget);
|
|
652
|
+
if (selectedComponents.length > 0) {
|
|
653
|
+
copyAstroComponents(projectDir, selectedComponents);
|
|
654
|
+
}
|
|
655
|
+
} else if (framework === 'svelte' && existsSync(svelteAppDir)) {
|
|
656
|
+
mkdirSync(projectDir, { recursive: true });
|
|
657
|
+
copyDirRecursiveWithReplacements(svelteAppDir, projectDir, replacements);
|
|
658
|
+
mkdirSync(join(projectDir, 'static', 'css'), { recursive: true });
|
|
659
|
+
cssTarget = join(projectDir, 'static', 'css', 'rizzo.min.css');
|
|
660
|
+
copyFileSync(cssSource, cssTarget);
|
|
661
|
+
if (selectedComponents.length > 0) {
|
|
662
|
+
copySvelteComponents(projectDir, selectedComponents);
|
|
663
|
+
}
|
|
664
|
+
} else {
|
|
665
|
+
const cssDir = framework === 'astro' ? join(projectDir, 'public', 'css') : join(projectDir, 'css');
|
|
666
|
+
cssTarget = join(cssDir, 'rizzo.min.css');
|
|
667
|
+
const linkHref = framework === 'astro' ? '/css/rizzo.min.css' : 'css/rizzo.min.css';
|
|
668
|
+
mkdirSync(cssDir, { recursive: true });
|
|
669
|
+
copyFileSync(cssSource, cssTarget);
|
|
670
|
+
|
|
671
|
+
const vanillaScaffoldPath = getScaffoldVanillaIndex();
|
|
672
|
+
indexPath = join(projectDir, 'index.html');
|
|
673
|
+
if (framework === 'vanilla' && existsSync(vanillaScaffoldPath)) {
|
|
674
|
+
let indexHtml = readFileSync(vanillaScaffoldPath, 'utf8');
|
|
675
|
+
indexHtml = indexHtml
|
|
676
|
+
.replace(/\{\{DATA_THEME\}\}/g, theme)
|
|
677
|
+
.replace(/\{\{THEME_LIST_COMMENT\}\}/g, themeComment)
|
|
678
|
+
.replace(/\{\{TITLE\}\}/g, name || 'App')
|
|
679
|
+
.replace(/\{\{LINK_HREF\}\}/g, linkHref);
|
|
680
|
+
writeFileSync(indexPath, indexHtml, 'utf8');
|
|
681
|
+
} else {
|
|
682
|
+
const indexHtml = `<!DOCTYPE html>
|
|
683
|
+
<html lang="en" data-theme="${theme}">${themeComment}
|
|
244
684
|
<head>
|
|
245
685
|
<meta charset="UTF-8" />
|
|
246
686
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
@@ -253,20 +693,32 @@ async function cmdInit() {
|
|
|
253
693
|
</body>
|
|
254
694
|
</html>
|
|
255
695
|
`;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
copyAstroComponents(projectDir, selectedComponents);
|
|
696
|
+
writeFileSync(indexPath, indexHtml, 'utf8');
|
|
697
|
+
}
|
|
698
|
+
if (framework === 'svelte' && selectedComponents.length > 0) {
|
|
699
|
+
copySvelteComponents(projectDir, selectedComponents);
|
|
700
|
+
} else if (framework === 'astro' && selectedComponents.length > 0) {
|
|
701
|
+
copyAstroComponents(projectDir, selectedComponents);
|
|
702
|
+
}
|
|
264
703
|
}
|
|
265
704
|
|
|
266
705
|
console.log('\n✓ Project ready at ' + projectDir);
|
|
267
706
|
console.log(' - ' + cssTarget);
|
|
268
|
-
console.log(' - ' + indexPath);
|
|
269
|
-
|
|
707
|
+
if (indexPath) console.log(' - ' + indexPath);
|
|
708
|
+
if (framework === 'vanilla') {
|
|
709
|
+
console.log(' - Vanilla JS: same CSS and component styles; index includes theme switcher and sample components.');
|
|
710
|
+
}
|
|
711
|
+
if (framework === 'astro' && existsSync(astroAppDir)) {
|
|
712
|
+
console.log(' - Default Astro project with Rizzo CSS. Run: pnpm install && pnpm dev');
|
|
713
|
+
}
|
|
714
|
+
if (framework === 'svelte' && existsSync(svelteAppDir)) {
|
|
715
|
+
console.log(' - Default SvelteKit project with Rizzo CSS. Run: pnpm install && pnpm dev');
|
|
716
|
+
}
|
|
717
|
+
if ((framework === 'svelte' || framework === 'astro') && !existsSync(framework === 'astro' ? astroAppDir : svelteAppDir)) {
|
|
718
|
+
const fw = framework === 'svelte' ? 'Svelte' : 'Astro';
|
|
719
|
+
console.log('\nTip: To use the official ' + fw + ' scaffold, create a project with their CLI (e.g. npm create ' + framework + '@latest my-app), then run npx rizzo-css add in that folder.');
|
|
720
|
+
}
|
|
721
|
+
console.log('\nDocs: https://rizzo-css.vercel.app\n');
|
|
270
722
|
}
|
|
271
723
|
|
|
272
724
|
function main() {
|
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
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
title?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { title = '{{TITLE}}' } = Astro.props;
|
|
7
|
+
---
|
|
8
|
+
<!doctype html>
|
|
9
|
+
<html lang="en" data-theme="{{DATA_THEME}}">{{THEME_LIST_COMMENT}}
|
|
10
|
+
<head>
|
|
11
|
+
<meta charset="UTF-8" />
|
|
12
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
13
|
+
<link rel="stylesheet" href="/css/rizzo.min.css" />
|
|
14
|
+
<title>{title}</title>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<slot />
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Layout from '../layouts/Layout.astro';
|
|
3
|
+
---
|
|
4
|
+
<Layout>
|
|
5
|
+
<main style="padding: var(--spacing-6); max-width: 65ch;">
|
|
6
|
+
<h1>Hello, Rizzo CSS</h1>
|
|
7
|
+
<p>Your Astro project is set up with Rizzo CSS. Same styles and components as Vanilla JS and Svelte.</p>
|
|
8
|
+
<p>
|
|
9
|
+
<a href="https://rizzo-css.vercel.app/docs/components">Component docs</a>
|
|
10
|
+
— Set theme via <code>data-theme</code> on <code><html></code> (e.g. <code>github-dark-classic</code>). Run <code>npx rizzo-css theme</code> to list themes.
|
|
11
|
+
</p>
|
|
12
|
+
</main>
|
|
13
|
+
</Layout>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite dev",
|
|
7
|
+
"build": "vite build",
|
|
8
|
+
"preview": "vite preview"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@sveltejs/adapter-auto": "^3.0.0",
|
|
12
|
+
"@sveltejs/kit": "^2.0.0",
|
|
13
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
|
14
|
+
"svelte": "^5.0.0",
|
|
15
|
+
"vite": "^6.0.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// See https://svelte.dev/docs/kit/types#app.d.ts
|
|
2
|
+
// for information about these interfaces
|
|
3
|
+
declare global {
|
|
4
|
+
namespace App {
|
|
5
|
+
// interface Error {}
|
|
6
|
+
// interface Locals {}
|
|
7
|
+
// interface PageData {}
|
|
8
|
+
// interface PageState {}
|
|
9
|
+
// interface Platform {}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
<link rel="stylesheet" href="/css/rizzo.min.css" />
|
|
7
|
+
%sveltekit.head%
|
|
8
|
+
</head>
|
|
9
|
+
<body data-sveltekit-preload-data="hover">
|
|
10
|
+
<div style="display: contents">%sveltekit.body%</div>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
// Welcome page
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<main style="padding: var(--spacing-6); max-width: 65ch;">
|
|
6
|
+
<h1>Hello, Rizzo CSS</h1>
|
|
7
|
+
<p>Your SvelteKit project is set up with Rizzo CSS. Same styles and components as Vanilla JS and Astro.</p>
|
|
8
|
+
<p>
|
|
9
|
+
<a href="https://rizzo-css.vercel.app/docs/components">Component docs</a>
|
|
10
|
+
— Set theme via <code>data-theme</code> on <code><html></code> (e.g. <code>github-dark-classic</code>). Run <code>npx rizzo-css theme</code> to list themes.
|
|
11
|
+
</p>
|
|
12
|
+
</main>
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./.svelte-kit/tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"allowJs": true,
|
|
5
|
+
"checkJs": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"forceConsistentCasingInFileNames": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"module": "ESNext",
|
|
13
|
+
"moduleResolution": "bundler"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -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>
|