rizzo-css 0.0.78 → 0.0.80

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.
Files changed (83) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/scaffold/react/base/package.json +1 -1
  4. package/scaffold/svelte/Navbar.svelte +1 -1
  5. package/scaffold/svelte/Search.svelte +3 -3
  6. package/scaffold/svelte/Settings.svelte +8 -6
  7. package/scaffold/svelte/variants/full/.svelte-kit/tsconfig.json +11 -0
  8. package/scaffold/svelte/variants/full/README-RIZZO.md +1 -0
  9. package/scaffold/svelte/variants/full/gitignore +2 -1
  10. package/scaffold/svelte/variants/full/src/config/componentCategories.ts +43 -0
  11. package/scaffold/svelte/variants/full/src/config/docsNav.ts +50 -0
  12. package/scaffold/svelte/variants/full/src/routes/+page.svelte +16 -22
  13. package/scaffold/svelte/variants/full/src/routes/blocks/+layout.svelte +119 -0
  14. package/scaffold/svelte/variants/full/src/routes/blocks/+page.svelte +107 -0
  15. package/scaffold/svelte/variants/full/src/routes/docs/+layout.svelte +135 -0
  16. package/scaffold/svelte/variants/full/src/routes/docs/+page.svelte +68 -0
  17. package/scaffold/svelte/variants/full/src/routes/docs/components/+page.svelte +116 -0
  18. package/scaffold/svelte/variants/full/src/routes/docs/getting-started/+page.svelte +48 -0
  19. package/scaffold/svelte/variants/full/src/routes/docs/overview/+page.svelte +5 -0
  20. package/scaffold/svelte/variants/full/src/routes/themes/+page.svelte +202 -0
  21. package/scaffold/svelte/variants/full/tsconfig.json +1 -0
  22. package/scaffold/vanilla/README-RIZZO.md +1 -1
  23. package/scaffold/vanilla/components/accordion.html +4 -0
  24. package/scaffold/vanilla/components/alert-dialog.html +4 -0
  25. package/scaffold/vanilla/components/alert.html +4 -0
  26. package/scaffold/vanilla/components/aspect-ratio.html +4 -0
  27. package/scaffold/vanilla/components/avatar.html +4 -0
  28. package/scaffold/vanilla/components/back-to-top.html +4 -0
  29. package/scaffold/vanilla/components/badge.html +4 -0
  30. package/scaffold/vanilla/components/breadcrumb.html +4 -0
  31. package/scaffold/vanilla/components/button-group.html +4 -0
  32. package/scaffold/vanilla/components/button.html +4 -0
  33. package/scaffold/vanilla/components/calendar.html +4 -0
  34. package/scaffold/vanilla/components/cards.html +4 -0
  35. package/scaffold/vanilla/components/carousel.html +4 -0
  36. package/scaffold/vanilla/components/chart.html +4 -0
  37. package/scaffold/vanilla/components/collapsible.html +4 -0
  38. package/scaffold/vanilla/components/command.html +4 -0
  39. package/scaffold/vanilla/components/context-menu.html +4 -0
  40. package/scaffold/vanilla/components/copy-to-clipboard.html +4 -0
  41. package/scaffold/vanilla/components/dashboard.html +4 -0
  42. package/scaffold/vanilla/components/direction.html +4 -0
  43. package/scaffold/vanilla/components/divider.html +4 -0
  44. package/scaffold/vanilla/components/docs-sidebar.html +4 -0
  45. package/scaffold/vanilla/components/dropdown.html +4 -0
  46. package/scaffold/vanilla/components/empty.html +4 -0
  47. package/scaffold/vanilla/components/font-switcher.html +4 -0
  48. package/scaffold/vanilla/components/footer.html +4 -0
  49. package/scaffold/vanilla/components/forms.html +4 -0
  50. package/scaffold/vanilla/components/hover-card.html +4 -0
  51. package/scaffold/vanilla/components/icons.html +4 -0
  52. package/scaffold/vanilla/components/index.html +4 -0
  53. package/scaffold/vanilla/components/input-group.html +4 -0
  54. package/scaffold/vanilla/components/input-otp.html +4 -0
  55. package/scaffold/vanilla/components/kbd.html +4 -0
  56. package/scaffold/vanilla/components/label.html +4 -0
  57. package/scaffold/vanilla/components/menubar.html +4 -0
  58. package/scaffold/vanilla/components/modal.html +4 -0
  59. package/scaffold/vanilla/components/navbar.html +4 -0
  60. package/scaffold/vanilla/components/pagination.html +4 -0
  61. package/scaffold/vanilla/components/popover.html +4 -0
  62. package/scaffold/vanilla/components/progress-bar.html +4 -0
  63. package/scaffold/vanilla/components/range-calendar.html +4 -0
  64. package/scaffold/vanilla/components/resizable.html +4 -0
  65. package/scaffold/vanilla/components/scroll-area.html +4 -0
  66. package/scaffold/vanilla/components/search.html +4 -0
  67. package/scaffold/vanilla/components/separator.html +4 -0
  68. package/scaffold/vanilla/components/settings.html +4 -0
  69. package/scaffold/vanilla/components/sheet.html +4 -0
  70. package/scaffold/vanilla/components/skeleton.html +4 -0
  71. package/scaffold/vanilla/components/slider.html +4 -0
  72. package/scaffold/vanilla/components/sound-effects.html +4 -0
  73. package/scaffold/vanilla/components/spinner.html +4 -0
  74. package/scaffold/vanilla/components/switch.html +4 -0
  75. package/scaffold/vanilla/components/table.html +4 -0
  76. package/scaffold/vanilla/components/tabs.html +4 -0
  77. package/scaffold/vanilla/components/theme-switcher.html +4 -0
  78. package/scaffold/vanilla/components/toast.html +4 -0
  79. package/scaffold/vanilla/components/toggle-group.html +4 -0
  80. package/scaffold/vanilla/components/toggle.html +4 -0
  81. package/scaffold/vanilla/components/tooltip.html +4 -0
  82. package/scaffold/vanilla/index.html +4 -0
  83. package/scaffold/vue/base/package.json +1 -1
package/README.md CHANGED
@@ -72,7 +72,7 @@ import 'rizzo-css';
72
72
  **Without a bundler (plain HTML):** Use a CDN. Both unpkg and jsDelivr resolve the package root to the built CSS (via the `unpkg` / `jsdelivr` fields in this package). For reliability or to pin a version, use the explicit path:
73
73
 
74
74
  ```html
75
- <!-- unpkg (pin version: replace @latest with @0.0.78 or any version) -->
75
+ <!-- unpkg (pin version: replace @latest with @0.0.80 or any version) -->
76
76
  <link rel="stylesheet" href="https://unpkg.com/rizzo-css@latest/dist/rizzo.min.css" />
77
77
 
78
78
  <!-- or jsDelivr -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rizzo-css",
3
- "version": "0.0.78",
3
+ "version": "0.0.80",
4
4
  "engines": {
5
5
  "node": ">=18"
6
6
  },
@@ -16,7 +16,7 @@
16
16
  "@types/react": "^18.3.12",
17
17
  "@types/react-dom": "^18.3.1",
18
18
  "@vitejs/plugin-react": "^4.3.3",
19
- "rizzo-css": "^0.0.78",
19
+ "rizzo-css": "^0.0.80",
20
20
  "typescript": "~5.6.2",
21
21
  "vite": "^6.0.1"
22
22
  }
@@ -45,7 +45,7 @@
45
45
  });
46
46
  </script>
47
47
 
48
- <nav class="navbar" role="navigation" aria-label="Main navigation">
48
+ <nav class="navbar" aria-label="Main navigation">
49
49
  <div class="navbar__container">
50
50
  <div class="navbar__brand">
51
51
  <a href="/" class="navbar__brand-link">
@@ -143,9 +143,9 @@
143
143
  <p class="search__empty-text">Start typing to search…</p>
144
144
  </div>
145
145
  <div class="search__results-list" role="group" aria-label="Sample results">
146
- <a href="#" class="search__result-item" tabindex={open ? 0 : -1}><div class="search__result-category">Docs</div><div class="search__result-title">Getting started</div></a>
147
- <a href="#" class="search__result-item" tabindex={open ? 0 : -1}><div class="search__result-category">Docs</div><div class="search__result-title">Components</div></a>
148
- <a href="#" class="search__result-item" tabindex={open ? 0 : -1}><div class="search__result-category">Docs</div><div class="search__result-title">Theming</div></a>
146
+ <a href="/docs/getting-started" class="search__result-item" tabindex={open ? 0 : -1}><div class="search__result-category">Docs</div><div class="search__result-title">Getting started</div></a>
147
+ <a href="/docs/components" class="search__result-item" tabindex={open ? 0 : -1}><div class="search__result-category">Docs</div><div class="search__result-title">Components</div></a>
148
+ <a href="/docs/theming" class="search__result-item" tabindex={open ? 0 : -1}><div class="search__result-category">Docs</div><div class="search__result-title">Theming</div></a>
149
149
  </div>
150
150
  </div>
151
151
  </div>
@@ -8,13 +8,14 @@
8
8
  let openInternal = $state(false);
9
9
  const open = $derived(openProp !== undefined ? openProp : openInternal);
10
10
 
11
+ const isBrowser = typeof window !== 'undefined' && typeof localStorage?.getItem === 'function';
11
12
  let fontSizeLabel = $state('100%');
12
13
  let fontSizeSlider = $state(1);
13
- let fontPairValue = $state(typeof localStorage !== 'undefined' ? localStorage.getItem('fontPair') || FONT_PAIR_DEFAULT : FONT_PAIR_DEFAULT);
14
- let soundEffects = $state(typeof localStorage !== 'undefined' && localStorage.getItem('soundEffects') === 'true');
15
- let reducedMotion = $state(typeof localStorage !== 'undefined' && localStorage.getItem('reducedMotion') === 'true');
16
- let highContrast = $state(typeof localStorage !== 'undefined' && localStorage.getItem('highContrast') === 'true');
17
- let scrollbarStyle = $state((typeof localStorage !== 'undefined' ? localStorage.getItem('scrollbarStyle') || 'thin' : 'thin') as 'thin' | 'thick' | 'hidden');
14
+ let fontPairValue = $state(isBrowser ? localStorage.getItem('fontPair') || FONT_PAIR_DEFAULT : FONT_PAIR_DEFAULT);
15
+ let soundEffects = $state(isBrowser && localStorage.getItem('soundEffects') === 'true');
16
+ let reducedMotion = $state(isBrowser && localStorage.getItem('reducedMotion') === 'true');
17
+ let highContrast = $state(isBrowser && localStorage.getItem('highContrast') === 'true');
18
+ let scrollbarStyle = $state((isBrowser ? localStorage.getItem('scrollbarStyle') || 'thin' : 'thin') as 'thin' | 'thick' | 'hidden');
18
19
 
19
20
  function applyFontSize(scale: number) {
20
21
  if (typeof document === 'undefined') return;
@@ -34,6 +35,7 @@
34
35
  }
35
36
 
36
37
  $effect(() => {
38
+ if (typeof window === 'undefined') return;
37
39
  (window as unknown as { openSettings?: () => void }).openSettings = () => {
38
40
  openInternal = true;
39
41
  };
@@ -45,7 +47,7 @@
45
47
  });
46
48
 
47
49
  $effect(() => {
48
- if (!open) return;
50
+ if (typeof document === 'undefined' || !open) return;
49
51
  const onEscape = (e: KeyboardEvent) => {
50
52
  if (e.key === 'Escape') openInternal = false;
51
53
  };
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "paths": {
5
+ "$lib": ["../src/lib"],
6
+ "$lib/*": ["../src/lib/*"]
7
+ },
8
+ "rootDir": ".."
9
+ },
10
+ "include": ["../src/**/*", "../*.config.js"]
11
+ }
@@ -39,6 +39,7 @@ SvelteKit project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you
39
39
 
40
40
  - `svelte.config.js` — SvelteKit configuration
41
41
  - `vite.config.js` — Vite config with SvelteKit plugin (required for `pnpm dev`)
42
+ - `tsconfig.json` — Extends `.svelte-kit/tsconfig.json`; a minimal fallback is committed so TypeScript and the IDE work before the first `pnpm dev`. Running `pnpm dev` or `svelte-kit sync` regenerates the full config.
42
43
  - `src/app.html` — HTML shell with Rizzo CSS and theme (edit `data-theme` for default)
43
44
  - `src/routes/+layout.svelte` — Root layout
44
45
  - `src/routes/+page.svelte` — Home page
@@ -2,7 +2,8 @@ node_modules
2
2
  .output
3
3
  .vercel
4
4
  .netlify
5
- /.svelte-kit
5
+ /.svelte-kit/*
6
+ !/.svelte-kit/tsconfig.json
6
7
  /build
7
8
  .DS_Store
8
9
  .env
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Minimal component categories for the full template components page.
3
+ * Same structure as main site for consistent layout.
4
+ */
5
+ export interface CategoryItem {
6
+ href: string;
7
+ title: string;
8
+ description: string;
9
+ }
10
+
11
+ export interface CategoryWithItems {
12
+ id: string;
13
+ label: string;
14
+ items: CategoryItem[];
15
+ }
16
+
17
+ function slugToTitle(slug: string): string {
18
+ return slug
19
+ .split('-')
20
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
21
+ .join(' ');
22
+ }
23
+
24
+ const CATEGORIES: { id: string; label: string; slugs: string[] }[] = [
25
+ { id: 'layout', label: 'Layout', slugs: ['navbar', 'docs-sidebar', 'dashboard', 'resizable', 'footer'] },
26
+ { id: 'forms', label: 'Forms & inputs', slugs: ['button', 'button-group', 'forms', 'switch', 'slider', 'toggle', 'toggle-group', 'divider', 'separator', 'label', 'kbd'] },
27
+ { id: 'data', label: 'Data display', slugs: ['cards', 'table', 'badge', 'pagination', 'aspect-ratio', 'empty', 'scroll-area', 'alert', 'skeleton', 'spinner', 'progress-bar', 'toast'] },
28
+ { id: 'overlay', label: 'Overlay', slugs: ['modal', 'sheet', 'popover', 'dropdown', 'tooltip', 'accordion', 'collapsible', 'tabs'] },
29
+ { id: 'other', label: 'Other', slugs: ['avatar', 'copy-to-clipboard', 'theme-switcher', 'font-switcher', 'settings', 'search', 'breadcrumb', 'back-to-top'] },
30
+ ];
31
+
32
+ export function getComponentsByCategory(): CategoryWithItems[] {
33
+ const pathPrefix = '/docs/components';
34
+ return CATEGORIES.map((cat) => ({
35
+ id: cat.id,
36
+ label: cat.label,
37
+ items: cat.slugs.map((slug) => ({
38
+ href: `${pathPrefix}/${slug}`,
39
+ title: slugToTitle(slug),
40
+ description: `Accessible, themeable ${slugToTitle(slug).toLowerCase()} component.`,
41
+ })),
42
+ }));
43
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Minimal docs nav for the full template. Matches DOCS_NAV structure so DocsSidebar works.
3
+ */
4
+ export interface DocsNavSection {
5
+ id: string;
6
+ label: string;
7
+ }
8
+
9
+ export interface DocsNavLink {
10
+ href: string;
11
+ label: string;
12
+ frameworkOnly?: boolean;
13
+ absolute?: boolean;
14
+ sections?: DocsNavSection[];
15
+ }
16
+
17
+ export interface DocsNavGroup {
18
+ label: string;
19
+ links: DocsNavLink[];
20
+ }
21
+
22
+ export const DOCS_NAV: DocsNavGroup[] = [
23
+ {
24
+ label: 'Introduction',
25
+ links: [
26
+ { href: 'overview', label: 'Overview', frameworkOnly: true },
27
+ { href: 'getting-started', label: 'Getting Started' },
28
+ ],
29
+ },
30
+ {
31
+ label: 'Components',
32
+ links: [{ href: 'components', label: 'Overview', frameworkOnly: true }],
33
+ },
34
+ {
35
+ label: 'Blocks',
36
+ links: [
37
+ { href: '/blocks', label: 'Blocks overview', absolute: true },
38
+ { href: '/blocks/landing-hero', label: 'Landing hero', absolute: true },
39
+ { href: '/blocks/pricing', label: 'Pricing cards', absolute: true },
40
+ { href: '/blocks/dashboard-01', label: 'Dashboard', absolute: true },
41
+ { href: '/blocks/docs-layout', label: 'Docs layout', absolute: true },
42
+ { href: '/blocks/login', label: 'Login', absolute: true },
43
+ { href: '/blocks/signup', label: 'Sign up', absolute: true },
44
+ ],
45
+ },
46
+ {
47
+ label: 'Themes',
48
+ links: [{ href: '/themes', label: 'Themes', absolute: true }],
49
+ },
50
+ ];
@@ -1,6 +1,5 @@
1
1
  <script lang="ts">
2
2
  import CopyToClipboard from '$lib/rizzo/CopyToClipboard.svelte';
3
- const DOCS_BASE = 'https://rizzo-css.vercel.app';
4
3
  const ADD_COMMAND = 'npx rizzo-css add <ComponentName>';
5
4
  </script>
6
5
 
@@ -11,8 +10,8 @@
11
10
  <h1 class="home__title">Rizzo CSS</h1>
12
11
  <p class="home__subtitle">A modern CSS design system with semantic theming, accessibility-first components, and one CLI for Vanilla, Astro, and Svelte. Start here then make it your own.</p>
13
12
  <div class="home__hero-ctas">
14
- <a href={DOCS_BASE + '/docs/getting-started'} class="btn btn-primary home__hero-cta" target="_blank" rel="noopener noreferrer">Get Started<span class="sr-only"> (opens in new tab)</span></a>
15
- <a href={DOCS_BASE + '/docs/components'} class="btn btn-outline home__hero-cta" target="_blank" rel="noopener noreferrer">View Components<span class="sr-only"> (opens in new tab)</span></a>
13
+ <a href="/docs/getting-started" class="btn btn-primary home__hero-cta">Get Started</a>
14
+ <a href="/docs/components" class="btn btn-outline home__hero-cta">View Components</a>
16
15
  </div>
17
16
  </header>
18
17
 
@@ -69,34 +68,29 @@
69
68
  <section class="home__docs">
70
69
  <h2 class="home__section-title">Documentation</h2>
71
70
  <div class="home__docs-grid">
72
- <a href={DOCS_BASE + '/docs/getting-started'} class="home__doc-card" target="_blank" rel="noopener noreferrer">
71
+ <a href="/docs/getting-started" class="home__doc-card">
73
72
  <h3>Getting Started</h3>
74
73
  <p>Installation, project structure, and quick start guide</p>
75
- <span class="sr-only"> (opens in new tab)</span>
76
74
  </a>
77
- <a href={DOCS_BASE + '/docs/components'} class="home__doc-card" target="_blank" rel="noopener noreferrer">
75
+ <a href="/docs/components" class="home__doc-card">
78
76
  <h3>Components</h3>
79
77
  <p>Component library with usage examples and live demos</p>
80
- <span class="sr-only"> (opens in new tab)</span>
81
78
  </a>
82
- <a href={DOCS_BASE + '/docs/theming'} class="home__doc-card" target="_blank" rel="noopener noreferrer">
83
- <h3>Theming</h3>
84
- <p>Theme system, custom themes, and color format guide</p>
85
- <span class="sr-only"> (opens in new tab)</span>
79
+ <a href="/themes" class="home__doc-card">
80
+ <h3>Themes</h3>
81
+ <p>Theme system, 14 themes, and live preview</p>
86
82
  </a>
87
- <a href={DOCS_BASE + '/docs/design-system'} class="home__doc-card" target="_blank" rel="noopener noreferrer">
88
- <h3>Design System</h3>
89
- <p>Semantic variables, typography, and design principles</p>
90
- <span class="sr-only"> (opens in new tab)</span>
83
+ <a href="/blocks" class="home__doc-card">
84
+ <h3>Blocks</h3>
85
+ <p>Pre-built layouts: landing, pricing, dashboard, docs, login, signup</p>
91
86
  </a>
92
- <a href={DOCS_BASE + '/docs/accessibility'} class="home__doc-card" target="_blank" rel="noopener noreferrer">
93
- <h3>Accessibility</h3>
94
- <p>Accessibility guidelines, utilities, and best practices</p>
95
- <span class="sr-only"> (opens in new tab)</span>
87
+ <a href="/docs" class="home__doc-card">
88
+ <h3>Docs Overview</h3>
89
+ <p>Condensed index of documentation and links</p>
96
90
  </a>
97
- <a href={DOCS_BASE + '/docs/colors'} class="home__doc-card" target="_blank" rel="noopener noreferrer">
98
- <h3>Colors</h3>
99
- <p>Interactive color reference with multiple format options</p>
91
+ <a href="https://rizzo-css.vercel.app/docs/theming" class="home__doc-card" target="_blank" rel="noopener noreferrer">
92
+ <h3>Theming (full docs)</h3>
93
+ <p>Custom themes, persistence, color format on main site</p>
100
94
  <span class="sr-only"> (opens in new tab)</span>
101
95
  </a>
102
96
  </div>
@@ -0,0 +1,119 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import { page } from '$app/stores';
4
+ import BackToTop from '$lib/rizzo/BackToTop.svelte';
5
+
6
+ const currentPath = $derived($page.url.pathname);
7
+ const BLOCKS_NAV = [
8
+ { href: '/blocks', label: 'Overview' },
9
+ { href: '/blocks/landing-hero', label: 'Landing hero' },
10
+ { href: '/blocks/pricing', label: 'Pricing cards' },
11
+ { href: '/blocks/dashboard-01', label: 'Dashboard with sidebar' },
12
+ { href: '/blocks/docs-layout', label: 'Docs layout with sidebar' },
13
+ { href: '/blocks/login', label: 'Login' },
14
+ { href: '/blocks/signup', label: 'Sign up' },
15
+ ];
16
+
17
+ onMount(() => {
18
+ const w = typeof window !== 'undefined' ? window.innerWidth : 1025;
19
+ document.documentElement.classList.add(w <= 1024 ? 'docs-sidebar-mobile' : 'docs-sidebar-desktop');
20
+
21
+ const container = document.getElementById('docs-sidebar-container');
22
+ if (!container) return;
23
+ const toggle = container.querySelector('[data-docs-sidebar-toggle]');
24
+ const overlay = container.querySelector('[data-docs-sidebar-overlay]');
25
+ const docs = document.querySelector('[data-docs]');
26
+ if (!toggle || !overlay || !docs) return;
27
+
28
+ function open() {
29
+ docs.classList.add('docs--sidebar-open');
30
+ toggle.setAttribute('aria-expanded', 'true');
31
+ overlay.setAttribute('aria-hidden', 'false');
32
+ }
33
+ function close() {
34
+ docs.classList.remove('docs--sidebar-open');
35
+ toggle.setAttribute('aria-expanded', 'false');
36
+ overlay.setAttribute('aria-hidden', 'true');
37
+ }
38
+ toggle.addEventListener('click', () => (docs.classList.contains('docs--sidebar-open') ? close() : open()));
39
+ overlay.addEventListener('click', close);
40
+
41
+ if (document.documentElement.classList.contains('docs-sidebar-mobile')) {
42
+ if (document.readyState === 'loading') {
43
+ document.addEventListener('DOMContentLoaded', () => container.remove());
44
+ } else {
45
+ container.remove();
46
+ }
47
+ }
48
+ });
49
+ </script>
50
+
51
+ <div class="docs" data-docs>
52
+ <div id="docs-sidebar-container">
53
+ <button
54
+ type="button"
55
+ class="docs__sidebar-toggle"
56
+ aria-label="Open blocks menu"
57
+ aria-expanded="false"
58
+ aria-controls="docs-sidebar"
59
+ data-docs-sidebar-toggle
60
+ >
61
+ <span class="docs__sidebar-toggle-icon" aria-hidden="true">
62
+ <span></span><span></span><span></span>
63
+ </span>
64
+ <span class="docs__sidebar-toggle-text">Blocks</span>
65
+ </button>
66
+ <div class="docs__sidebar-overlay" data-docs-sidebar-overlay aria-hidden="true"></div>
67
+ <aside id="docs-sidebar" class="docs-sidebar" aria-label="Blocks navigation" tabindex="0">
68
+ <nav class="docs-sidebar__nav">
69
+ <div class="docs-sidebar__group">
70
+ <h2 class="docs-sidebar__group-label">Blocks</h2>
71
+ <ul class="docs-sidebar__list">
72
+ {#each BLOCKS_NAV as item}
73
+ {@const isActive = currentPath === item.href || (item.href !== '/blocks' && currentPath.startsWith(item.href))}
74
+ <li class="docs-sidebar__item">
75
+ <a
76
+ href={item.href}
77
+ class="docs-sidebar__link"
78
+ class:docs-sidebar__link--active={isActive}
79
+ aria-current={isActive ? 'page' : undefined}
80
+ >
81
+ {item.label}
82
+ </a>
83
+ </li>
84
+ {/each}
85
+ </ul>
86
+ </div>
87
+ </nav>
88
+ </aside>
89
+ </div>
90
+ <div class="docs__main">
91
+ <div class="docs__container">
92
+ <div class="docs__content">
93
+ <slot />
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ <BackToTop threshold={300} />
99
+
100
+ <svelte:head>
101
+ <title>Blocks — Rizzo CSS</title>
102
+ </svelte:head>
103
+
104
+ <style>
105
+ :global(.docs__container) {
106
+ box-sizing: border-box;
107
+ width: 100%;
108
+ min-width: 0;
109
+ max-width: var(--container-default);
110
+ margin: 0 auto;
111
+ padding: 0 var(--content-padding-x);
112
+ }
113
+ :global(.docs__content) {
114
+ width: 100%;
115
+ min-width: 0;
116
+ color: var(--text);
117
+ line-height: var(--line-height-relaxed);
118
+ }
119
+ </style>
@@ -0,0 +1,107 @@
1
+ <script lang="ts">
2
+ import Card from '$lib/rizzo/Card.svelte';
3
+
4
+ const blocks = [
5
+ { href: '/blocks/landing-hero', title: 'Landing hero', desc: 'Marketing hero with headline, subtitle, and primary CTAs. Typography and button tokens.', meta: 'Hero · Buttons · Typography' },
6
+ { href: '/blocks/pricing', title: 'Pricing cards', desc: 'Three-tier pricing section using Card, Badge, and buttons. Theme-aware.', meta: 'Card · Badge · Buttons' },
7
+ { href: '/blocks/dashboard-01', title: 'Dashboard', desc: 'App dashboard with sidebar, stat cards, and data table. Uses Dashboard, Card, and Table components.', meta: 'Dashboard · Sidebar · Cards · Table' },
8
+ { href: '/blocks/docs-layout', title: 'Docs layout', desc: 'Documentation layout with a sidebar nav and main content area. Same pattern as this docs site.', meta: 'Docs Sidebar · Layout' },
9
+ { href: '/blocks/login', title: 'Login', desc: 'Centered login form on a muted background. Brand link, email/password fields, and footer links.', meta: 'Form · Button · Tokens' },
10
+ { href: '/blocks/signup', title: 'Sign up', desc: 'Centered sign-up form with name, email, password, and link to sign in. Same tokens as Login.', meta: 'Form · Button · Tokens' },
11
+ ];
12
+ const DOCS_BASE = 'https://rizzo-css.vercel.app';
13
+ </script>
14
+
15
+ <svelte:head>
16
+ <title>Blocks — Rizzo CSS</title>
17
+ </svelte:head>
18
+
19
+ <section class="blocks-index__browse">
20
+ <h1 class="docs__title">Blocks</h1>
21
+ <p class="blocks-index__browse-desc">
22
+ Pre-built layouts and patterns using Rizzo components and design tokens. Use them as starting points for dashboards, docs sites, auth screens, and app shells.
23
+ </p>
24
+ </section>
25
+
26
+ <section>
27
+ <h2 class="blocks-index__section-label">Featured</h2>
28
+ <div class="blocks-index__grid">
29
+ {#each blocks as block}
30
+ <a href="{DOCS_BASE}{block.href}" class="block-card-link" target="_blank" rel="noopener noreferrer">
31
+ <Card variant="elevated">
32
+ <div class="card__body">
33
+ <h3 style="margin: 0 0 var(--spacing-2) 0;">{block.title}</h3>
34
+ <p style="margin: 0; color: var(--text-dim); font-size: var(--font-size-sm);">{block.desc}</p>
35
+ <span class="block-card-meta" style="margin-top: var(--spacing-2); font-size: var(--font-size-xs); color: var(--text-dim);">{block.meta}</span>
36
+ </div>
37
+ </Card>
38
+ </a>
39
+ {/each}
40
+ </div>
41
+ </section>
42
+
43
+ <section>
44
+ <h2>Scaffold from CLI</h2>
45
+ <p>When you create a new project or add to existing, choose a <strong>template</strong>: <strong>CSS only</strong>, <strong>Landing</strong>, <strong>Docs</strong>, <strong>Dashboard</strong>, or <strong>Full</strong>. Full clones the entire docs site with home, docs, components, blocks, and themes.</p>
46
+ <pre><code>npx rizzo-css init
47
+ # → Choose framework (Vanilla, Astro, Svelte, React, Vue)
48
+ # → Choose template: CSS only | Landing | Docs | Dashboard | Full</code></pre>
49
+ </section>
50
+
51
+ <style>
52
+ .blocks-index__browse {
53
+ margin-bottom: var(--section-spacing);
54
+ }
55
+ .blocks-index__browse-desc {
56
+ margin: 0;
57
+ color: var(--text-dim);
58
+ font-size: var(--font-size-sm);
59
+ }
60
+ .blocks-index__section-label {
61
+ font-size: var(--text-lg);
62
+ font-weight: 600;
63
+ margin: 0 0 var(--page-header-margin-bottom);
64
+ color: var(--text);
65
+ }
66
+ .blocks-index__grid {
67
+ display: grid;
68
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
69
+ gap: var(--spacing-6);
70
+ margin: var(--page-header-margin-bottom) 0;
71
+ }
72
+ .block-card-link {
73
+ text-decoration: none;
74
+ color: inherit;
75
+ display: flex;
76
+ flex-direction: column;
77
+ height: 100%;
78
+ transition: transform var(--transition-base);
79
+ }
80
+ .block-card-link :global(.card) {
81
+ flex: 1;
82
+ display: flex;
83
+ flex-direction: column;
84
+ min-height: 0;
85
+ }
86
+ .block-card-link :global(.card .card__body) {
87
+ flex: 1;
88
+ }
89
+ .block-card-link:hover {
90
+ transform: translateY(calc(-1 * var(--spacing-0-125)));
91
+ }
92
+ .block-card-link:hover :global(.card__body h3) {
93
+ color: var(--accent-fg);
94
+ }
95
+ pre {
96
+ background: var(--background-alt);
97
+ border: 1px solid var(--border);
98
+ border-radius: var(--radius-lg);
99
+ padding: var(--spacing-4);
100
+ overflow-x: auto;
101
+ font-size: var(--font-size-sm);
102
+ }
103
+ pre code {
104
+ background: none;
105
+ padding: 0;
106
+ }
107
+ </style>
@@ -0,0 +1,135 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import { page } from '$app/stores';
4
+ import DocsSidebar from '$lib/rizzo/DocsSidebar.svelte';
5
+ import BackToTop from '$lib/rizzo/BackToTop.svelte';
6
+
7
+ const currentPath = $derived($page.url.pathname);
8
+
9
+ onMount(() => {
10
+ const w = typeof window !== 'undefined' ? window.innerWidth : 1025;
11
+ document.documentElement.classList.add(w <= 1024 ? 'docs-sidebar-mobile' : 'docs-sidebar-desktop');
12
+
13
+ const container = document.getElementById('docs-sidebar-container');
14
+ if (!container) return;
15
+ const toggle = container.querySelector('[data-docs-sidebar-toggle]');
16
+ const overlay = container.querySelector('[data-docs-sidebar-overlay]');
17
+ const docs = document.querySelector('[data-docs]');
18
+ if (!toggle || !overlay || !docs) return;
19
+
20
+ function open() {
21
+ docs.classList.add('docs--sidebar-open');
22
+ toggle.setAttribute('aria-expanded', 'true');
23
+ overlay.setAttribute('aria-hidden', 'false');
24
+ }
25
+ function close() {
26
+ docs.classList.remove('docs--sidebar-open');
27
+ toggle.setAttribute('aria-expanded', 'false');
28
+ overlay.setAttribute('aria-hidden', 'true');
29
+ }
30
+ toggle.addEventListener('click', () => (docs.classList.contains('docs--sidebar-open') ? close() : open()));
31
+ overlay.addEventListener('click', close);
32
+
33
+ if (document.documentElement.classList.contains('docs-sidebar-mobile')) {
34
+ if (document.readyState === 'loading') {
35
+ document.addEventListener('DOMContentLoaded', () => container.remove());
36
+ } else {
37
+ container.remove();
38
+ }
39
+ }
40
+
41
+ return () => {
42
+ toggle?.removeEventListener('click', close);
43
+ overlay?.removeEventListener('click', close);
44
+ };
45
+ });
46
+ </script>
47
+
48
+ <div class="docs" data-docs>
49
+ <div id="docs-sidebar-container">
50
+ <button
51
+ type="button"
52
+ class="docs__sidebar-toggle"
53
+ aria-label="Open documentation menu"
54
+ aria-expanded="false"
55
+ aria-controls="docs-sidebar"
56
+ data-docs-sidebar-toggle
57
+ >
58
+ <span class="docs__sidebar-toggle-icon" aria-hidden="true">
59
+ <span></span><span></span><span></span>
60
+ </span>
61
+ <span class="docs__sidebar-toggle-text">Docs</span>
62
+ </button>
63
+ <div class="docs__sidebar-overlay" data-docs-sidebar-overlay aria-hidden="true"></div>
64
+ <DocsSidebar currentPath={currentPath} pathPrefix="/docs" />
65
+ </div>
66
+ <div class="docs__main">
67
+ <div class="docs__container">
68
+ <div class="docs__content">
69
+ <slot />
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ <BackToTop threshold={300} />
75
+
76
+ <svelte:head>
77
+ <title>Docs — Rizzo CSS</title>
78
+ </svelte:head>
79
+
80
+ <style>
81
+ :global(.docs__container) {
82
+ box-sizing: border-box;
83
+ width: 100%;
84
+ min-width: 0;
85
+ max-width: var(--container-default);
86
+ margin: 0 auto;
87
+ padding: 0 var(--content-padding-x);
88
+ }
89
+ :global(.docs__content) {
90
+ width: 100%;
91
+ min-width: 0;
92
+ color: var(--text);
93
+ line-height: var(--line-height-relaxed);
94
+ }
95
+ :global(.docs__content h2) {
96
+ font-size: var(--font-size-4xl);
97
+ font-weight: var(--font-weight-bold);
98
+ margin-top: var(--section-spacing-lg);
99
+ margin-bottom: var(--spacing-6);
100
+ color: var(--text);
101
+ padding-bottom: var(--spacing-2);
102
+ border-bottom: 1px solid var(--border);
103
+ }
104
+ :global(.docs__content h3) {
105
+ font-size: var(--font-size-3xl);
106
+ font-weight: var(--font-weight-semibold);
107
+ margin-top: var(--spacing-8);
108
+ margin-bottom: var(--spacing-4);
109
+ color: var(--text);
110
+ }
111
+ :global(.docs__content p) {
112
+ font-size: var(--font-size-base);
113
+ margin-bottom: var(--spacing-5);
114
+ }
115
+ :global(.docs__content ul) {
116
+ margin-bottom: var(--spacing-5);
117
+ padding-left: var(--spacing-8);
118
+ }
119
+ :global(.docs__content a) {
120
+ color: var(--accent-fg);
121
+ text-decoration: underline;
122
+ text-underline-offset: 0.15em;
123
+ }
124
+ :global(.docs__content a:hover) {
125
+ color: var(--accent-fg-hover);
126
+ }
127
+ :global(.docs__content .component-card-link),
128
+ :global(.docs__content .block-card-link) {
129
+ text-decoration: none;
130
+ }
131
+ :global(.docs__content .component-card-link *),
132
+ :global(.docs__content .block-card-link *) {
133
+ text-decoration: none;
134
+ }
135
+ </style>