rizzo-css 0.0.54 → 0.0.55

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 (250) hide show
  1. package/README.md +11 -7
  2. package/bin/rizzo-css.js +273 -118
  3. package/dist/rizzo.min.css +40 -16
  4. package/package.json +6 -6
  5. package/scaffold/astro/AlertDialog.astro +86 -0
  6. package/scaffold/astro/AspectRatio.astro +22 -0
  7. package/scaffold/astro/ButtonGroup.astro +16 -0
  8. package/scaffold/astro/Collapsible.astro +69 -0
  9. package/scaffold/astro/ContextMenu.astro +58 -0
  10. package/scaffold/astro/CopyToClipboard.astro +4 -0
  11. package/scaffold/astro/Dashboard.astro +74 -0
  12. package/scaffold/astro/Empty.astro +23 -0
  13. package/scaffold/astro/HoverCard.astro +64 -0
  14. package/scaffold/astro/Kbd.astro +14 -0
  15. package/scaffold/astro/Label.astro +24 -0
  16. package/scaffold/astro/Modal.astro +17 -2
  17. package/scaffold/astro/Popover.astro +62 -0
  18. package/scaffold/astro/ResizableHandle.astro +16 -0
  19. package/scaffold/astro/ResizablePane.astro +20 -0
  20. package/scaffold/astro/ResizablePaneGroup.astro +84 -0
  21. package/scaffold/astro/ScrollArea.astro +19 -0
  22. package/scaffold/astro/Separator.astro +18 -0
  23. package/scaffold/astro/Settings.astro +10 -2
  24. package/scaffold/astro/Sheet.astro +90 -0
  25. package/scaffold/astro/Skeleton.astro +16 -0
  26. package/scaffold/astro/Slider.astro +75 -0
  27. package/scaffold/astro/SoundEffects.astro +1 -0
  28. package/scaffold/astro/Switch.astro +37 -0
  29. package/scaffold/astro/Tabs.astro +1 -1
  30. package/scaffold/astro/ThemeSwitcher.astro +11 -4
  31. package/scaffold/astro/Toggle.astro +35 -0
  32. package/scaffold/astro/ToggleGroup.astro +24 -0
  33. package/scaffold/astro/base/README-RIZZO.md +55 -0
  34. package/scaffold/{astro-core → astro/base}/src/pages/index.astro +1 -1
  35. package/scaffold/astro/variants/dashboard/src/layouts/Layout.astro +85 -0
  36. package/scaffold/astro/variants/dashboard/src/pages/index.astro +110 -0
  37. package/scaffold/astro/variants/docs/src/layouts/Layout.astro +81 -0
  38. package/scaffold/astro/variants/docs/src/pages/docs/getting-started.astro +36 -0
  39. package/scaffold/astro/variants/docs/src/pages/index.astro +38 -0
  40. package/scaffold/{astro-core → astro/variants/full}/README-RIZZO.md +2 -1
  41. package/scaffold/astro/variants/full/astro.config.mjs +5 -0
  42. package/scaffold/astro/variants/full/dist/_noop-middleware.mjs +3 -0
  43. package/scaffold/astro/variants/full/dist/chunks/astro/server_9Mzx7luy.mjs +6023 -0
  44. package/scaffold/astro/variants/full/dist/chunks/astro_BOYUKg7r.mjs +1 -0
  45. package/scaffold/astro/variants/full/dist/favicon.svg +18 -0
  46. package/scaffold/astro/variants/full/dist/manifest_DXpJmqSX.mjs +154 -0
  47. package/scaffold/astro/variants/full/dist/noop-entrypoint.mjs +3 -0
  48. package/scaffold/astro/variants/full/dist/pages/index.astro.mjs +87 -0
  49. package/scaffold/astro/variants/full/dist/renderers.mjs +3 -0
  50. package/scaffold/astro/variants/full/gitignore +24 -0
  51. package/scaffold/astro/variants/full/node_modules/.astro/data-store.json +1 -0
  52. package/scaffold/astro/variants/full/node_modules/.vite/deps/_metadata.json +31 -0
  53. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___aria-query.js +6776 -0
  54. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___aria-query.js.map +7 -0
  55. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___axobject-query.js +3754 -0
  56. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___axobject-query.js.map +7 -0
  57. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___cssesc.js +99 -0
  58. package/scaffold/astro/variants/full/node_modules/.vite/deps/astro___cssesc.js.map +7 -0
  59. package/scaffold/astro/variants/full/node_modules/.vite/deps/chunk-BUSYA2B4.js +8 -0
  60. package/scaffold/astro/variants/full/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +7 -0
  61. package/scaffold/astro/variants/full/node_modules/.vite/deps/package.json +3 -0
  62. package/scaffold/astro/variants/full/package.json +13 -0
  63. package/scaffold/astro/variants/full/public/.gitkeep +0 -0
  64. package/scaffold/astro/variants/full/public/favicon.svg +18 -0
  65. package/scaffold/astro/variants/full/src/components/rizzo/CopyToClipboard.astro +157 -0
  66. package/scaffold/astro/variants/full/src/components/rizzo/icons/Check.astro +29 -0
  67. package/scaffold/astro/variants/full/src/components/rizzo/icons/Copy.astro +30 -0
  68. package/scaffold/astro/variants/full/src/layouts/Layout.astro +34 -0
  69. package/scaffold/astro/variants/full/src/pages/index.astro +107 -0
  70. package/scaffold/astro/variants/full/tsconfig.json +5 -0
  71. package/scaffold/landing/index.html +13 -0
  72. package/scaffold/shared/navbar-vanilla.html +59 -0
  73. package/scaffold/shared/sound-effects-inline.js +6 -1
  74. package/scaffold/svelte/AlertDialog.svelte +55 -0
  75. package/scaffold/svelte/AspectRatio.svelte +21 -0
  76. package/scaffold/svelte/BackToTop.svelte +1 -0
  77. package/scaffold/svelte/ButtonGroup.svelte +16 -0
  78. package/scaffold/svelte/Collapsible.svelte +57 -0
  79. package/scaffold/svelte/ContextMenu.svelte +60 -0
  80. package/scaffold/svelte/Dashboard.svelte +87 -0
  81. package/scaffold/svelte/Empty.svelte +36 -0
  82. package/scaffold/svelte/HoverCard.svelte +55 -0
  83. package/scaffold/svelte/Kbd.svelte +13 -0
  84. package/scaffold/svelte/Label.svelte +19 -0
  85. package/scaffold/svelte/Popover.svelte +59 -0
  86. package/scaffold/svelte/ResizableHandle.svelte +13 -0
  87. package/scaffold/svelte/ResizablePane.svelte +16 -0
  88. package/scaffold/svelte/ResizablePaneGroup.svelte +92 -0
  89. package/scaffold/svelte/ScrollArea.svelte +18 -0
  90. package/scaffold/svelte/Separator.svelte +14 -0
  91. package/scaffold/svelte/Sheet.svelte +62 -0
  92. package/scaffold/svelte/Skeleton.svelte +19 -0
  93. package/scaffold/svelte/Slider.svelte +57 -0
  94. package/scaffold/svelte/SoundEffects.svelte +3 -0
  95. package/scaffold/svelte/Switch.svelte +35 -0
  96. package/scaffold/svelte/Tabs.svelte +1 -1
  97. package/scaffold/svelte/Toggle.svelte +41 -0
  98. package/scaffold/svelte/ToggleGroup.svelte +30 -0
  99. package/scaffold/svelte/base/README-RIZZO.md +55 -0
  100. package/scaffold/{svelte-core → svelte/base}/src/routes/+page.svelte +1 -1
  101. package/scaffold/svelte/base/static/.gitkeep +0 -0
  102. package/scaffold/svelte/index.ts +21 -0
  103. package/scaffold/svelte/variants/dashboard/src/routes/+layout.svelte +64 -0
  104. package/scaffold/svelte/variants/dashboard/src/routes/+page.svelte +104 -0
  105. package/scaffold/svelte/variants/docs/src/routes/+layout.svelte +60 -0
  106. package/scaffold/svelte/variants/docs/src/routes/+page.svelte +34 -0
  107. package/scaffold/svelte/variants/docs/src/routes/docs/getting-started/+page.svelte +31 -0
  108. package/scaffold/{svelte-core → svelte/variants/full}/README-RIZZO.md +2 -1
  109. package/scaffold/svelte/variants/full/gitignore +10 -0
  110. package/scaffold/svelte/variants/full/package.json +20 -0
  111. package/scaffold/svelte/variants/full/src/app.d.ts +11 -0
  112. package/scaffold/svelte/variants/full/src/app.html +16 -0
  113. package/scaffold/svelte/variants/full/src/routes/+layout.svelte +1 -0
  114. package/scaffold/svelte/variants/full/src/routes/+page.svelte +105 -0
  115. package/scaffold/svelte/variants/full/static/.gitkeep +0 -0
  116. package/scaffold/svelte/variants/full/svelte.config.js +10 -0
  117. package/scaffold/svelte/variants/full/tsconfig.json +11 -0
  118. package/scaffold/vanilla/README-RIZZO.md +6 -5
  119. package/scaffold/vanilla/components/accordion.html +59 -64
  120. package/scaffold/vanilla/components/alert-dialog.html +640 -0
  121. package/scaffold/vanilla/components/alert.html +59 -64
  122. package/scaffold/vanilla/components/aspect-ratio.html +640 -0
  123. package/scaffold/vanilla/components/avatar.html +59 -64
  124. package/scaffold/vanilla/components/back-to-top.html +59 -64
  125. package/scaffold/vanilla/components/badge.html +59 -64
  126. package/scaffold/vanilla/components/breadcrumb.html +59 -64
  127. package/scaffold/vanilla/components/button-group.html +640 -0
  128. package/scaffold/vanilla/components/button.html +59 -64
  129. package/scaffold/vanilla/components/cards.html +59 -64
  130. package/scaffold/vanilla/components/collapsible.html +640 -0
  131. package/scaffold/vanilla/components/context-menu.html +640 -0
  132. package/scaffold/vanilla/components/copy-to-clipboard.html +59 -64
  133. package/scaffold/vanilla/components/dashboard.html +640 -0
  134. package/scaffold/vanilla/components/divider.html +59 -64
  135. package/scaffold/vanilla/components/docs-sidebar.html +59 -64
  136. package/scaffold/vanilla/components/dropdown.html +59 -64
  137. package/scaffold/vanilla/components/empty.html +640 -0
  138. package/scaffold/vanilla/components/font-switcher.html +59 -64
  139. package/scaffold/vanilla/components/footer.html +59 -64
  140. package/scaffold/vanilla/components/forms.html +59 -64
  141. package/scaffold/vanilla/components/hover-card.html +640 -0
  142. package/scaffold/vanilla/components/icons.html +59 -64
  143. package/scaffold/vanilla/components/index.html +79 -64
  144. package/scaffold/vanilla/components/kbd.html +640 -0
  145. package/scaffold/vanilla/components/label.html +640 -0
  146. package/scaffold/vanilla/components/modal.html +59 -64
  147. package/scaffold/vanilla/components/navbar.html +59 -64
  148. package/scaffold/vanilla/components/pagination.html +59 -64
  149. package/scaffold/vanilla/components/popover.html +640 -0
  150. package/scaffold/vanilla/components/progress-bar.html +59 -64
  151. package/scaffold/vanilla/components/resizable.html +640 -0
  152. package/scaffold/vanilla/components/scroll-area.html +640 -0
  153. package/scaffold/vanilla/components/search.html +59 -64
  154. package/scaffold/vanilla/components/separator.html +640 -0
  155. package/scaffold/vanilla/components/settings.html +59 -64
  156. package/scaffold/vanilla/components/sheet.html +640 -0
  157. package/scaffold/vanilla/components/skeleton.html +640 -0
  158. package/scaffold/vanilla/components/slider.html +640 -0
  159. package/scaffold/vanilla/components/sound-effects.html +59 -64
  160. package/scaffold/vanilla/components/spinner.html +59 -64
  161. package/scaffold/vanilla/components/switch.html +640 -0
  162. package/scaffold/vanilla/components/table.html +59 -64
  163. package/scaffold/vanilla/components/tabs.html +59 -64
  164. package/scaffold/vanilla/components/theme-switcher.html +59 -64
  165. package/scaffold/vanilla/components/toast.html +59 -64
  166. package/scaffold/vanilla/components/toggle-group.html +640 -0
  167. package/scaffold/vanilla/components/toggle.html +640 -0
  168. package/scaffold/vanilla/components/tooltip.html +59 -64
  169. package/scaffold/vanilla/index.html +61 -66
  170. package/scaffold/vanilla/variants/dashboard/index.html +45 -0
  171. package/scaffold/vanilla/variants/docs/index.html +36 -0
  172. package/scaffold/vanilla/variants/full/components/accordion.html +592 -0
  173. package/scaffold/vanilla/variants/full/components/alert.html +592 -0
  174. package/scaffold/vanilla/variants/full/components/avatar.html +592 -0
  175. package/scaffold/vanilla/variants/full/components/back-to-top.html +592 -0
  176. package/scaffold/vanilla/variants/full/components/badge.html +592 -0
  177. package/scaffold/vanilla/variants/full/components/breadcrumb.html +592 -0
  178. package/scaffold/vanilla/variants/full/components/button.html +592 -0
  179. package/scaffold/vanilla/variants/full/components/cards.html +592 -0
  180. package/scaffold/vanilla/variants/full/components/copy-to-clipboard.html +592 -0
  181. package/scaffold/vanilla/variants/full/components/dashboard.html +592 -0
  182. package/scaffold/vanilla/variants/full/components/divider.html +592 -0
  183. package/scaffold/vanilla/variants/full/components/docs-sidebar.html +592 -0
  184. package/scaffold/vanilla/variants/full/components/dropdown.html +592 -0
  185. package/scaffold/vanilla/variants/full/components/font-switcher.html +592 -0
  186. package/scaffold/vanilla/variants/full/components/footer.html +592 -0
  187. package/scaffold/vanilla/variants/full/components/forms.html +592 -0
  188. package/scaffold/vanilla/variants/full/components/icons.html +592 -0
  189. package/scaffold/vanilla/variants/full/components/index.html +625 -0
  190. package/scaffold/vanilla/variants/full/components/modal.html +592 -0
  191. package/scaffold/vanilla/variants/full/components/navbar.html +592 -0
  192. package/scaffold/vanilla/variants/full/components/pagination.html +592 -0
  193. package/scaffold/vanilla/variants/full/components/progress-bar.html +592 -0
  194. package/scaffold/vanilla/variants/full/components/search.html +592 -0
  195. package/scaffold/vanilla/variants/full/components/settings.html +592 -0
  196. package/scaffold/vanilla/variants/full/components/skeleton.html +592 -0
  197. package/scaffold/vanilla/variants/full/components/sound-effects.html +592 -0
  198. package/scaffold/vanilla/variants/full/components/spinner.html +592 -0
  199. package/scaffold/vanilla/variants/full/components/switch.html +592 -0
  200. package/scaffold/vanilla/variants/full/components/table.html +592 -0
  201. package/scaffold/vanilla/variants/full/components/tabs.html +592 -0
  202. package/scaffold/vanilla/variants/full/components/theme-switcher.html +592 -0
  203. package/scaffold/vanilla/variants/full/components/toast.html +592 -0
  204. package/scaffold/vanilla/variants/full/components/tooltip.html +592 -0
  205. package/scaffold/vanilla/variants/full/index.html +682 -0
  206. package/scaffold/vanilla/variants/full/js/main.js +989 -0
  207. package/scaffold/astro-core/.astro/content-assets.mjs +0 -1
  208. package/scaffold/astro-core/.astro/content-modules.mjs +0 -1
  209. package/scaffold/astro-core/.astro/content.d.ts +0 -199
  210. package/scaffold/astro-core/.astro/types.d.ts +0 -2
  211. package/scaffold/astro-core/.env.example +0 -3
  212. package/scaffold/svelte-core/.env.example +0 -3
  213. /package/scaffold/{astro-core → astro/base}/astro.config.mjs +0 -0
  214. /package/scaffold/{astro-core → astro/base}/dist/.gitkeep +0 -0
  215. /package/scaffold/{astro-core → astro/base}/dist/_noop-middleware.mjs +0 -0
  216. /package/scaffold/{astro-core → astro/base}/dist/chunks/astro/server_9Mzx7luy.mjs +0 -0
  217. /package/scaffold/{astro-core → astro/base}/dist/chunks/astro_BOYUKg7r.mjs +0 -0
  218. /package/scaffold/{astro-core → astro/base}/dist/favicon.svg +0 -0
  219. /package/scaffold/{astro-core → astro/base}/dist/manifest_DXpJmqSX.mjs +0 -0
  220. /package/scaffold/{astro-core → astro/base}/dist/noop-entrypoint.mjs +0 -0
  221. /package/scaffold/{astro-core → astro/base}/dist/pages/index.astro.mjs +0 -0
  222. /package/scaffold/{astro-core → astro/base}/dist/renderers.mjs +0 -0
  223. /package/scaffold/{astro-core → astro/base}/gitignore +0 -0
  224. /package/scaffold/{astro-core → astro/base}/node_modules/.astro/data-store.json +0 -0
  225. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/_metadata.json +0 -0
  226. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___aria-query.js +0 -0
  227. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___aria-query.js.map +0 -0
  228. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___axobject-query.js +0 -0
  229. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___axobject-query.js.map +0 -0
  230. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___cssesc.js +0 -0
  231. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/astro___cssesc.js.map +0 -0
  232. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/chunk-BUSYA2B4.js +0 -0
  233. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +0 -0
  234. /package/scaffold/{astro-core → astro/base}/node_modules/.vite/deps/package.json +0 -0
  235. /package/scaffold/{astro-core → astro/base}/package.json +0 -0
  236. /package/scaffold/{astro-core → astro/base}/public/.gitkeep +0 -0
  237. /package/scaffold/{astro-core → astro/base}/public/favicon.svg +0 -0
  238. /package/scaffold/{astro-core → astro/base}/src/components/rizzo/CopyToClipboard.astro +0 -0
  239. /package/scaffold/{astro-core → astro/base}/src/components/rizzo/icons/Check.astro +0 -0
  240. /package/scaffold/{astro-core → astro/base}/src/components/rizzo/icons/Copy.astro +0 -0
  241. /package/scaffold/{astro-core → astro/base}/src/layouts/Layout.astro +0 -0
  242. /package/scaffold/{astro-core → astro/base}/tsconfig.json +0 -0
  243. /package/scaffold/{svelte-core/static → astro/variants/full/dist}/.gitkeep +0 -0
  244. /package/scaffold/{svelte-core → svelte/base}/gitignore +0 -0
  245. /package/scaffold/{svelte-core → svelte/base}/package.json +0 -0
  246. /package/scaffold/{svelte-core → svelte/base}/src/app.d.ts +0 -0
  247. /package/scaffold/{svelte-core → svelte/base}/src/app.html +0 -0
  248. /package/scaffold/{svelte-core → svelte/base}/src/routes/+layout.svelte +0 -0
  249. /package/scaffold/{svelte-core → svelte/base}/svelte.config.js +0 -0
  250. /package/scaffold/{svelte-core → svelte/base}/tsconfig.json +0 -0
@@ -0,0 +1,157 @@
1
+ ---
2
+ import Copy from './icons/Copy.astro';
3
+ import Check from './icons/Check.astro';
4
+
5
+ interface Props {
6
+ value: string;
7
+ label?: string;
8
+ format?: string;
9
+ /** When true, only the copy/check icons are shown (e.g. in code blocks). */
10
+ iconOnly?: boolean;
11
+ /** For icon-only: accessible label for the hidden text (e.g. "Copy code"). */
12
+ buttonLabel?: string;
13
+ class?: string;
14
+ id?: string;
15
+ }
16
+
17
+ const {
18
+ value,
19
+ label,
20
+ format,
21
+ iconOnly = false,
22
+ buttonLabel,
23
+ class: className = '',
24
+ id,
25
+ } = Astro.props;
26
+
27
+ const buttonId = id || `copy-btn-${Math.random().toString(36).substr(2, 9)}`;
28
+ const defaultTooltip = label || (iconOnly ? (buttonLabel || 'Copy') : 'Copy to clipboard');
29
+ const ariaLabel = label || (iconOnly ? (buttonLabel || 'Copy to clipboard') : `Copy ${value} to clipboard`);
30
+ const displayText = iconOnly ? (buttonLabel || 'Copy') : value;
31
+ const buttonClass = ['copy-to-clipboard', iconOnly ? 'copy-to-clipboard--icon-only' : '', className].filter(Boolean).join(' ').trim();
32
+ ---
33
+
34
+ <span class="tooltip-host" data-tooltip={defaultTooltip}>
35
+ <button
36
+ type="button"
37
+ class={buttonClass}
38
+ data-copy-value={value}
39
+ data-copy-format={format}
40
+ aria-label={ariaLabel}
41
+ id={buttonId}
42
+ data-copy-icon-only={iconOnly ? 'true' : undefined}
43
+ data-copy-button-label={iconOnly ? (buttonLabel || 'Copy') : undefined}
44
+ >
45
+ <span class="copy-to-clipboard__text">{displayText}</span>
46
+ <span class="copy-to-clipboard__icon copy-to-clipboard__icon--copy" aria-hidden="true">
47
+ <Copy width={16} height={16} />
48
+ </span>
49
+ <span class="copy-to-clipboard__icon copy-to-clipboard__icon--check" aria-hidden="true">
50
+ <Check width={16} height={16} />
51
+ </span>
52
+ <span class="copy-to-clipboard__feedback" aria-live="polite"></span>
53
+ </button>
54
+ </span>
55
+
56
+ <script>
57
+ (function initCopyToClipboard() {
58
+ const init = () => {
59
+ const buttons = document.querySelectorAll('.copy-to-clipboard');
60
+ buttons.forEach((button) => {
61
+ if (button.hasAttribute('data-copy-initialized')) return;
62
+ button.setAttribute('data-copy-initialized', 'true');
63
+ const tooltipHost = button.closest('.tooltip-host');
64
+ const defaultTooltip = tooltipHost ? (tooltipHost.getAttribute('data-tooltip') || 'Copy to clipboard') : 'Copy to clipboard';
65
+ const defaultAriaLabel = button.getAttribute('aria-label') || 'Copy to clipboard';
66
+ if (tooltipHost) tooltipHost.setAttribute('data-tooltip', defaultTooltip);
67
+ button.setAttribute('data-copy-aria-label', defaultAriaLabel);
68
+ if (tooltipHost) tooltipHost.setAttribute('data-copy-default-tooltip', defaultTooltip);
69
+ const getValue = () => button.getAttribute('data-copy-value') || '';
70
+ const getFormat = () => button.getAttribute('data-copy-format') || '';
71
+ const feedback = button.querySelector('.copy-to-clipboard__feedback');
72
+ const copyIcon = button.querySelector('.copy-to-clipboard__icon--copy');
73
+ const checkIcon = button.querySelector('.copy-to-clipboard__icon--check');
74
+ const textSpan = button.querySelector('.copy-to-clipboard__text');
75
+ const updateDisplay = () => {
76
+ if (button.hasAttribute('data-copy-icon-only')) {
77
+ if (textSpan) textSpan.textContent = button.getAttribute('data-copy-button-label') || 'Copy';
78
+ return;
79
+ }
80
+ const value = getValue();
81
+ if (textSpan) textSpan.textContent = value || '';
82
+ };
83
+ updateDisplay();
84
+ const observer = new MutationObserver((mutations) => {
85
+ let shouldUpdate = false;
86
+ mutations.forEach((mutation) => {
87
+ if (mutation.type === 'attributes' && (mutation.attributeName === 'data-copy-value' || mutation.attributeName === 'data-copy-format')) shouldUpdate = true;
88
+ });
89
+ if (shouldUpdate) requestAnimationFrame(updateDisplay);
90
+ });
91
+ observer.observe(button, { attributes: true, attributeFilter: ['data-copy-value', 'data-copy-format'], attributeOldValue: false });
92
+ button.addEventListener('value-updated', () => updateDisplay());
93
+ let lastValue = getValue();
94
+ const intervalId = setInterval(() => {
95
+ const currentValue = getValue();
96
+ if (currentValue !== lastValue) { lastValue = currentValue; updateDisplay(); }
97
+ }, 300);
98
+ button.setAttribute('data-copy-interval-id', intervalId.toString());
99
+ const copyToClipboard = async () => {
100
+ let value = getValue();
101
+ const format = getFormat();
102
+ if (!value && textSpan) value = textSpan.textContent || '';
103
+ if (!value) return;
104
+ try {
105
+ await navigator.clipboard.writeText(value);
106
+ if (copyIcon) copyIcon.classList.add('copy-to-clipboard__icon--hidden');
107
+ if (checkIcon) checkIcon.classList.remove('copy-to-clipboard__icon--hidden');
108
+ if (feedback) feedback.textContent = format ? `Copied ${format}!` : 'Copied!';
109
+ const th = button.closest('.tooltip-host');
110
+ if (th) th.setAttribute('data-tooltip', format ? `Copied ${format}!` : 'Copied!');
111
+ button.setAttribute('aria-label', format ? `Copied ${format}!` : 'Copied!');
112
+ setTimeout(() => {
113
+ if (copyIcon) copyIcon.classList.remove('copy-to-clipboard__icon--hidden');
114
+ if (checkIcon) checkIcon.classList.add('copy-to-clipboard__icon--hidden');
115
+ if (feedback) feedback.textContent = '';
116
+ if (th) th.setAttribute('data-tooltip', th.getAttribute('data-copy-default-tooltip') || defaultTooltip);
117
+ button.setAttribute('aria-label', defaultAriaLabel);
118
+ }, 2000);
119
+ } catch (err) {
120
+ const textArea = document.createElement('textarea');
121
+ textArea.value = value;
122
+ textArea.style.position = 'fixed';
123
+ textArea.style.left = '-999999px';
124
+ document.body.appendChild(textArea);
125
+ textArea.focus();
126
+ textArea.select();
127
+ try {
128
+ document.execCommand('copy');
129
+ if (copyIcon) copyIcon.classList.add('copy-to-clipboard__icon--hidden');
130
+ if (checkIcon) checkIcon.classList.remove('copy-to-clipboard__icon--hidden');
131
+ if (feedback) feedback.textContent = format ? `Copied ${format}!` : 'Copied!';
132
+ const thf = button.closest('.tooltip-host');
133
+ if (thf) thf.setAttribute('data-tooltip', format ? `Copied ${format}!` : 'Copied!');
134
+ button.setAttribute('aria-label', format ? `Copied ${format}!` : 'Copied!');
135
+ setTimeout(() => {
136
+ if (copyIcon) copyIcon.classList.remove('copy-to-clipboard__icon--hidden');
137
+ if (checkIcon) checkIcon.classList.add('copy-to-clipboard__icon--hidden');
138
+ if (feedback) feedback.textContent = '';
139
+ if (thf) thf.setAttribute('data-tooltip', thf.getAttribute('data-copy-default-tooltip') || defaultTooltip);
140
+ button.setAttribute('aria-label', defaultAriaLabel);
141
+ }, 2000);
142
+ } catch (fallbackErr) {
143
+ if (feedback) feedback.textContent = 'Failed to copy';
144
+ }
145
+ document.body.removeChild(textArea);
146
+ }
147
+ };
148
+ button.addEventListener('click', copyToClipboard);
149
+ button.addEventListener('keydown', (e) => {
150
+ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); copyToClipboard(); }
151
+ });
152
+ });
153
+ };
154
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
155
+ else init();
156
+ })();
157
+ </script>
@@ -0,0 +1,29 @@
1
+ ---
2
+ // Tabler Icons - Check
3
+ // Source: https://tabler.io/icons/icon/check
4
+ // License: MIT
5
+
6
+ interface Props {
7
+ width?: number;
8
+ height?: number;
9
+ class?: string;
10
+ }
11
+
12
+ const { width = 16, height = 16, class: className = '' } = Astro.props;
13
+ ---
14
+
15
+ <svg
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ width={width}
18
+ height={height}
19
+ viewBox="0 0 24 24"
20
+ fill="none"
21
+ stroke="currentColor"
22
+ stroke-width="2"
23
+ stroke-linecap="round"
24
+ stroke-linejoin="round"
25
+ class={`icon ${className}`.trim()}
26
+ aria-hidden="true"
27
+ >
28
+ <path d="M20 6L9 17l-5-5" />
29
+ </svg>
@@ -0,0 +1,30 @@
1
+ ---
2
+ // Tabler Icons - Copy
3
+ // Source: https://tabler.io/icons/icon/copy
4
+ // License: MIT
5
+
6
+ interface Props {
7
+ width?: number;
8
+ height?: number;
9
+ class?: string;
10
+ }
11
+
12
+ const { width = 16, height = 16, class: className = '' } = Astro.props;
13
+ ---
14
+
15
+ <svg
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ width={width}
18
+ height={height}
19
+ viewBox="0 0 24 24"
20
+ fill="none"
21
+ stroke="currentColor"
22
+ stroke-width="2"
23
+ stroke-linecap="round"
24
+ stroke-linejoin="round"
25
+ class={`icon ${className}`.trim()}
26
+ aria-hidden="true"
27
+ >
28
+ <rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
29
+ <path d="M4 16c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2h8c1.1 0 2 .9 2 2" />
30
+ </svg>
@@ -0,0 +1,34 @@
1
+ ---
2
+ /* Placeholders replaced by rizzo-css CLI when scaffolding */
3
+ /* {{THEME_LIST_COMMENT}} */
4
+ const DATA_THEME = '{{DATA_THEME}}';
5
+ /** @type {{ title?: string }} */
6
+ const { title = '{{TITLE}}' } = Astro.props;
7
+ {{RIZZO_LAYOUT_IMPORTS}}
8
+ ---
9
+ <!doctype html>
10
+ <html lang="en" data-theme={DATA_THEME}>
11
+ <head>
12
+ <meta charset="UTF-8" />
13
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
14
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
15
+ <script is:inline>
16
+ (function(){try{
17
+ var s=localStorage.getItem('theme');var d='{{DEFAULT_DARK}}';var l='{{DEFAULT_LIGHT}}';var initial=document.documentElement.getAttribute('data-theme');var r=!s?((initial&&initial!=='system')?initial:(matchMedia('(prefers-color-scheme: dark)').matches?d:l)):s==='system'?(matchMedia('(prefers-color-scheme: dark)').matches?d:l):s;document.documentElement.setAttribute('data-theme',r);
18
+ var fs=localStorage.getItem('fontSizeScale');if(fs)document.documentElement.style.setProperty('--font-size-scale',fs);
19
+ var fp=localStorage.getItem('fontPair')||'geist';if(fp==='geist'){document.documentElement.style.setProperty('--font-family','var(--font-family-geist-sans)');document.documentElement.style.setProperty('--font-family-mono','var(--font-family-geist-mono)');}else if(fp==='inter-jetbrains'){document.documentElement.style.setProperty('--font-family','var(--font-family-inter)');document.documentElement.style.setProperty('--font-family-mono','var(--font-family-jetbrains-mono)');}else if(fp==='ibm-plex'){document.documentElement.style.setProperty('--font-family','var(--font-family-ibm-plex-sans)');document.documentElement.style.setProperty('--font-family-mono','var(--font-family-ibm-plex-mono)');}else if(fp==='source'){document.documentElement.style.setProperty('--font-family','var(--font-family-source-sans-3)');document.documentElement.style.setProperty('--font-family-mono','var(--font-family-source-code-pro)');}else if(fp==='dm'){document.documentElement.style.setProperty('--font-family','var(--font-family-dm-sans)');document.documentElement.style.setProperty('--font-family-mono','var(--font-family-dm-mono)');}else if(fp==='outfit-jetbrains'){document.documentElement.style.setProperty('--font-family','var(--font-family-outfit)');document.documentElement.style.setProperty('--font-family-mono','var(--font-family-jetbrains-mono)');}
20
+ }catch(e){}})();
21
+ </script>
22
+ <link rel="stylesheet" href="/css/rizzo.min.css" />
23
+ {{RIZZO_SOUND_SCRIPT}}
24
+ <title>{title}</title>
25
+ </head>
26
+ <body>
27
+ <a href="#main-content" class="skip-link">Skip to main content</a>
28
+ {{RIZZO_LAYOUT_BODY_TOP}}
29
+ <main id="main-content">
30
+ <slot />
31
+ </main>
32
+ {{RIZZO_LAYOUT_BODY_BOTTOM}}
33
+ </body>
34
+ </html>
@@ -0,0 +1,107 @@
1
+ ---
2
+ import Layout from '../layouts/Layout.astro';
3
+ import CopyToClipboard from '../components/rizzo/CopyToClipboard.astro';
4
+ const TITLE = '{{TITLE}}';
5
+ const DOCS_BASE = 'https://rizzo-css.vercel.app';
6
+ const ADD_COMMAND = 'npx rizzo-css add <ComponentName>';
7
+ ---
8
+ <Layout title={TITLE}>
9
+ <div class="home">
10
+ <div class="home__container">
11
+ <header class="home__hero">
12
+ <h1 class="home__title">Rizzo CSS</h1>
13
+ <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>
14
+ <div class="home__hero-ctas">
15
+ <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>
16
+ <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>
17
+ </div>
18
+ </header>
19
+
20
+ <section class="home__features" aria-labelledby="home-features-heading">
21
+ <h2 id="home-features-heading" class="home__section-title">Features</h2>
22
+ <p class="home__features-intro">A complete design system that works across Vanilla, Astro, and Svelte — same CSS, same components, zero lock-in.</p>
23
+ <div class="home__features-featured">
24
+ <div class="home__card home__card--featured">
25
+ <span class="home__card-icon" aria-hidden="true">Themes</span>
26
+ <h3>14 beautiful themes</h3>
27
+ <p>7 dark and 7 light with OKLCH for perceptual uniformity. System preference, persistence, and a unique icon per theme.</p>
28
+ </div>
29
+ <div class="home__card home__card--featured">
30
+ <span class="home__card-icon" aria-hidden="true">A11y</span>
31
+ <h3>Accessibility first</h3>
32
+ <p>WCAG AA compliant with full keyboard navigation, ARIA, focus management, and screen reader support.</p>
33
+ </div>
34
+ <div class="home__card home__card--featured">
35
+ <span class="home__card-icon" aria-hidden="true">Components</span>
36
+ <h3>All components</h3>
37
+ <p>Navbar, Settings, Theme Switcher, Font Switcher, Modal, Dropdown, Tabs, Forms, and more — all accessible and themeable.</p>
38
+ </div>
39
+ </div>
40
+ <h3 class="home__features-supporting-label">And more</h3>
41
+ <div class="home__grid home__grid--supporting">
42
+ <div class="home__card home__card--supporting">
43
+ <h3>Semantic variables</h3>
44
+ <p>CSS variables that adapt to themes. No hardcoded colors; override once, update everywhere.</p>
45
+ </div>
46
+ <div class="home__card home__card--supporting">
47
+ <h3>PostCSS powered</h3>
48
+ <p>Imports, autoprefixing, and production minification. Fits into any build pipeline.</p>
49
+ </div>
50
+ <div class="home__card home__card--supporting">
51
+ <h3>Typography & spacing</h3>
52
+ <p>Scaling font sizes, weights, line heights, and a consistent spacing scale (0–24).</p>
53
+ </div>
54
+ <div class="home__card home__card--supporting">
55
+ <h3>Responsive & utilities</h3>
56
+ <p>Mobile-first breakpoints and utility classes for layout, display, and flexbox.</p>
57
+ </div>
58
+ </div>
59
+ </section>
60
+
61
+ <section class="home__add-command" aria-labelledby="home-add-command-heading">
62
+ <h2 id="home-add-command-heading" class="home__section-title">Add a component</h2>
63
+ <p class="home__features-intro" style="margin-bottom: var(--spacing-4);">Add any component from the CLI:</p>
64
+ <div class="home__add-command-block">
65
+ <pre><code>npx rizzo-css add &lt;ComponentName&gt;</code></pre>
66
+ <CopyToClipboard value={ADD_COMMAND} iconOnly buttonLabel="Copy" format="command" label="Copy command" class="home__add-command-copy" />
67
+ </div>
68
+ </section>
69
+
70
+ <section class="home__docs">
71
+ <h2 class="home__section-title">Documentation</h2>
72
+ <div class="home__docs-grid">
73
+ <a href={`${DOCS_BASE}/docs/getting-started`} class="home__doc-card" target="_blank" rel="noopener noreferrer">
74
+ <h3>Getting Started</h3>
75
+ <p>Installation, project structure, and quick start guide</p>
76
+ <span class="sr-only"> (opens in new tab)</span>
77
+ </a>
78
+ <a href={`${DOCS_BASE}/docs/components`} class="home__doc-card" target="_blank" rel="noopener noreferrer">
79
+ <h3>Components</h3>
80
+ <p>Component library with usage examples and live demos</p>
81
+ <span class="sr-only"> (opens in new tab)</span>
82
+ </a>
83
+ <a href={`${DOCS_BASE}/docs/theming`} class="home__doc-card" target="_blank" rel="noopener noreferrer">
84
+ <h3>Theming</h3>
85
+ <p>Theme system, custom themes, and color format guide</p>
86
+ <span class="sr-only"> (opens in new tab)</span>
87
+ </a>
88
+ <a href={`${DOCS_BASE}/docs/design-system`} class="home__doc-card" target="_blank" rel="noopener noreferrer">
89
+ <h3>Design System</h3>
90
+ <p>Semantic variables, typography, and design principles</p>
91
+ <span class="sr-only"> (opens in new tab)</span>
92
+ </a>
93
+ <a href={`${DOCS_BASE}/docs/accessibility`} class="home__doc-card" target="_blank" rel="noopener noreferrer">
94
+ <h3>Accessibility</h3>
95
+ <p>Accessibility guidelines, utilities, and best practices</p>
96
+ <span class="sr-only"> (opens in new tab)</span>
97
+ </a>
98
+ <a href={`${DOCS_BASE}/docs/colors`} class="home__doc-card" target="_blank" rel="noopener noreferrer">
99
+ <h3>Colors</h3>
100
+ <p>Interactive color reference with multiple format options</p>
101
+ <span class="sr-only"> (opens in new tab)</span>
102
+ </a>
103
+ </div>
104
+ </section>
105
+ </div>
106
+ </div>
107
+ </Layout>
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "astro/tsconfigs/strict",
3
+ "include": [".astro/types.d.ts", "**/*"],
4
+ "exclude": ["dist"]
5
+ }
@@ -0,0 +1,13 @@
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
+ <h1>Hello, Rizzo CSS</h1>
11
+ <p>Edit this file and add components. Docs: <a href="https://rizzo-css.vercel.app">rizzo-css.vercel.app</a></p>
12
+ </body>
13
+ </html>
@@ -0,0 +1,59 @@
1
+ <!-- Same structure as Astro/Svelte Navbar: flat links (Docs, Components, Blocks, Themes, Colors), Search, Settings, mobile toggle. Use {{TITLE}} and {{NAVBAR_BRAND_HREF}} when injecting. -->
2
+ <nav class="navbar" role="navigation" aria-label="Main navigation">
3
+ <div class="navbar__container">
4
+ <div class="navbar__brand">
5
+ <a href="{{NAVBAR_BRAND_HREF}}" class="navbar__brand-link">
6
+ <svg class="navbar__logo" width="32" height="32" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path d="M9.606 5.563c.766 0 .914-.157 2.394-.157s1.628.157 2.394.157c.638 0 2.554-1.563 3.511-1.563s2.075.563 2.075 2.188v1.875c-.002.492-.18 2-.88 1.597c1.111 1.314.88 2.922.88 4.34c0 3.906-5.267 5-7.98 5s-7.98-1.094-7.98-5c0-1.418-.231-3.026.88-4.34c-.7.403-.878-1.105-.88-1.598V6.188C4.02 4.563 5.137 4 6.095 4c.957 0 2.873 1.563 3.511 1.563" opacity="0.5"/><path d="M9.016 11.063c-.489 0-.815.317-.98.583a1.8 1.8 0 0 0-.254.948c0 .332.082.67.254.947c.165.266.491.584.98.584c.49 0 .815-.318.98-.584c.172-.278.254-.615.254-.947c0-.333-.082-.67-.254-.948c-.165-.266-.49-.584-.98-.584m5.021.584c.164-.266.49-.584.98-.584c.488 0 .814.318.979.584c.172.278.254.615.254.948s-.082.67-.254.947c-.165.266-.49.584-.98.584c-.489 0-.815-.318-.98-.584a1.8 1.8 0 0 1-.254-.947c0-.333.082-.67.255-.948"/><path fill-rule="evenodd" d="M11.178 14.08a2.4 2.4 0 0 1 .841-.143c.292 0 .59.045.842.143a1.3 1.3 0 0 1 .408.245c.134.123.307.35.307.675a.92.92 0 0 1-.307.675a1.3 1.3 0 0 1-.408.245c-.253.098-.55.143-.842.143c-.29 0-.588-.045-.84-.143a1.3 1.3 0 0 1-.41-.245a.92.92 0 0 1-.306-.675c0-.325.173-.552.307-.675a1.3 1.3 0 0 1 .408-.245" clip-rule="evenodd"/><path d="M17.863 13.375a.75.75 0 0 1 .75-.75c.296 0 .65.067.981.149c.345.085.72.199 1.076.321c.684.234 1.41.532 1.737.744a.75.75 0 0 1-.813 1.26c-.157-.101-.722-.35-1.409-.585a12 12 0 0 0-.95-.284a3 3 0 0 0-.622-.105a.75.75 0 0 1-.75-.75m.105 1.75a.75.75 0 1 0 0 1.5c.206 0 .55.115.98.343c.342.18.656.385.901.545l.131.086a.75.75 0 0 0 .814-1.26l-.113-.074a13 13 0 0 0-1.032-.623c-.457-.242-1.08-.517-1.681-.517m-14.153-.611c-.687.235-1.252.484-1.408.585a.75.75 0 0 1-.814-1.26c.328-.212 1.053-.51 1.737-.744c.357-.122.732-.237 1.077-.321c.33-.082.684-.149.98-.149a.75.75 0 0 1 0 1.5c-.107 0-.317.03-.622.105c-.29.072-.621.172-.95.284m.205 3.085l.131-.086c.246-.16.56-.365.901-.545c.431-.228.775-.343.98-.343a.75.75 0 0 0 0-1.5c-.6 0-1.224.275-1.68.517c-.41.216-.79.465-1.033.623l-.113.074a.75.75 0 0 0 .814 1.26"/></svg>
7
+ {{TITLE}}
8
+ </a>
9
+ </div>
10
+ <div class="navbar__actions-desktop">
11
+ <div class="search" data-search>
12
+ <div class="search__trigger-wrapper">
13
+ <button type="button" class="search__trigger" aria-label="Open search" aria-expanded="false" aria-controls="search-navbar-panel" data-search-trigger>
14
+ <svg class="search__icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
15
+ <span class="search__trigger-text">Search</span>
16
+ <kbd class="search__kbd" aria-hidden="true"><span class="search__kbd-modifier">⌘</span><kbd>K</kbd></kbd>
17
+ </button>
18
+ </div>
19
+ <div class="search__overlay" id="search-navbar-panel" aria-hidden="true" role="dialog" aria-modal="true" data-search-overlay>
20
+ <div class="search__panel" role="dialog" aria-modal="true" aria-labelledby="search-navbar-title" aria-hidden="true" tabindex="-1">
21
+ <h2 id="search-navbar-title" class="sr-only">Search</h2>
22
+ <div class="search__header">
23
+ <div class="search__input-wrapper">
24
+ <svg class="search__input-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
25
+ <input type="search" class="search__input" placeholder="Search…" aria-label="Search" />
26
+ </div>
27
+ <button type="button" class="search__close-btn" aria-label="Close search" data-search-close>
28
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M18 6L6 18"/><path d="M6 6l12 12"/></svg>
29
+ </button>
30
+ </div>
31
+ <div class="search__results" role="listbox" aria-label="Search results">
32
+ <div class="search__empty"><p class="search__empty-text">Start typing to search…</p></div>
33
+ <div class="search__results-list" role="group" aria-label="Sample results">
34
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Getting started</div></a>
35
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Components</div></a>
36
+ <a href="#" class="search__result-item" tabindex="-1"><div class="search__result-category">Docs</div><div class="search__result-title">Theming</div></a>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ <button type="button" class="navbar__settings-btn" aria-label="Open settings" onclick="window.openSettings && window.openSettings()">
43
+ <svg class="navbar__settings-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
44
+ <span class="navbar__settings-label">Settings</span>
45
+ </button>
46
+ </div>
47
+ <button type="button" class="navbar__toggle" id="navbar-toggle" aria-label="Toggle navigation menu" aria-expanded="false" aria-controls="navbar-menu">
48
+ <span class="sr-only">Menu</span>
49
+ <span class="navbar__toggle-icon" aria-hidden="true"><span></span><span></span><span></span></span>
50
+ </button>
51
+ <div class="navbar__menu" id="navbar-menu" role="menu" aria-hidden="true">
52
+ <a href="/docs" class="navbar__link">Docs</a>
53
+ <a href="/components" class="navbar__link">Components</a>
54
+ <a href="/blocks" class="navbar__link">Blocks</a>
55
+ <a href="/themes" class="navbar__link">Themes</a>
56
+ <a href="/colors" class="navbar__link">Colors</a>
57
+ </div>
58
+ </div>
59
+ </nav>
@@ -2,7 +2,7 @@
2
2
  (function() {
3
3
  var SOUND_KEY = 'soundEffects';
4
4
  var THROTTLE_MS = 120;
5
- var clickableSelector = 'a[href], area[href], button, input[type="submit"], input[type="button"], input[type="checkbox"], input[type="radio"], input[type="reset"], select, summary, [role="button"], [role="link"], [role="menuitem"], [role="menuitemradio"], [role="tab"], [role="option"], [role="switch"], .btn, .tabs__tab, .dropdown__trigger, .accordion__trigger, [data-accordion-trigger], .navbar__link, .navbar__brand-link, .pagination__link, .breadcrumb__link, .search__trigger, .theme-switcher__option, .font-switcher__option, .framework-switcher__segment, .modal__close, .alert__close, .copy-btn, [data-copy-btn], [data-sound-on-click]';
5
+ var clickableSelector = 'a[href], area[href], button, input[type="submit"], input[type="button"], input[type="checkbox"], input[type="radio"], input[type="reset"], select, summary, [role="button"], [role="link"], [role="menuitem"], [role="menuitemradio"], [role="tab"], [role="option"], [role="switch"], .btn, .tabs__tab, .dropdown__trigger, .accordion__trigger, [data-accordion-trigger], .navbar__link, .navbar__brand-link, .pagination__link, .breadcrumb__link, .search__trigger, .theme-switcher__option, .font-switcher__option, .framework-switcher__segment, .modal__close, .alert__close, .copy-btn, .copy-to-clipboard, [data-copy-btn], .docs-sidebar__link, .docs-sidebar__sublink, .docs__sidebar-toggle, .home__announcement, .home__example-pill, .block-card-link, .component-card-link, .home__doc-card, .skip-link, [data-sound-on-click]';
6
6
  var audioContext = null;
7
7
  var soundBase = '/assets/sfx';
8
8
  var soundUrls = [soundBase + '/click.mp3', soundBase + '/click.wav'];
@@ -98,9 +98,14 @@
98
98
  }
99
99
  if (localStorage.getItem(SOUND_KEY) === 'true') tryLoadAssetSound();
100
100
  }
101
+ // When user turns sound on (e.g. in Settings), preload so next click plays immediately
102
+ function onSoundEffectsChange() {
103
+ if (localStorage.getItem(SOUND_KEY) === 'true') tryLoadAssetSound();
104
+ }
101
105
  if (document.readyState === 'loading') {
102
106
  document.addEventListener('DOMContentLoaded', initSound);
103
107
  } else {
104
108
  initSound();
105
109
  }
110
+ window.addEventListener('rizzo-sound-effects-change', onSoundEffectsChange);
106
111
  })();
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ id?: string;
6
+ title?: string;
7
+ description?: string;
8
+ open?: boolean;
9
+ class?: string;
10
+ children?: Snippet;
11
+ actions?: Snippet;
12
+ }
13
+
14
+ let {
15
+ id: dialogId,
16
+ title = 'Are you sure?',
17
+ description,
18
+ open = $bindable(false),
19
+ class: className = '',
20
+ children,
21
+ actions,
22
+ }: Props = $props();
23
+
24
+ const id = $derived(dialogId ?? `alert-dialog-${Math.random().toString(36).slice(2, 9)}`);
25
+ </script>
26
+
27
+ <div
28
+ class="alert-dialog__overlay {open ? 'alert-dialog__overlay--open' : ''}"
29
+ data-alert-dialog-overlay
30
+ aria-hidden={!open}
31
+ id={`${id}-overlay`}
32
+ onclick={() => (open = false)}
33
+ role="presentation"
34
+ ></div>
35
+ <div
36
+ class="alert-dialog {className}"
37
+ role="alertdialog"
38
+ aria-modal="true"
39
+ aria-labelledby={`${id}-title`}
40
+ aria-describedby={description ? `${id}-desc` : undefined}
41
+ aria-hidden={!open}
42
+ id={id}
43
+ data-alert-dialog
44
+ hidden={!open}
45
+ >
46
+ <div class="alert-dialog__content">
47
+ <h2 id={`${id}-title`} class="alert-dialog__title">{title}</h2>
48
+ {#if description}
49
+ <p id={`${id}-desc`} class="alert-dialog__description">{description}</p>
50
+ {/if}
51
+ <div class="alert-dialog__actions">
52
+ {@render actions?.()}
53
+ </div>
54
+ </div>
55
+ </div>
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ ratio?: number;
6
+ class?: string;
7
+ children?: Snippet;
8
+ }
9
+
10
+ let { ratio = 16 / 9, class: className = '', children }: Props = $props();
11
+ const paddingPercent = $derived((1 / ratio) * 100);
12
+ </script>
13
+
14
+ <div
15
+ class="aspect-ratio {className}"
16
+ style="--aspect-ratio: {ratio}; --aspect-ratio-padding: {paddingPercent}%;"
17
+ >
18
+ <div class="aspect-ratio__inner">
19
+ {@render children?.()}
20
+ </div>
21
+ </div>
@@ -45,6 +45,7 @@
45
45
  stroke-linecap="round"
46
46
  stroke-linejoin="round"
47
47
  class="icon"
48
+ aria-hidden="true"
48
49
  >
49
50
  <path d="m18 15-6-6-6 6" />
50
51
  </svg>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ orientation?: 'horizontal' | 'vertical';
6
+ class?: string;
7
+ children?: Snippet;
8
+ }
9
+
10
+ let { orientation = 'horizontal', class: className = '', children }: Props = $props();
11
+ const orientationClass = $derived(orientation === 'vertical' ? 'button-group--vertical' : '');
12
+ </script>
13
+
14
+ <div class="button-group {orientationClass} {className}" role="group">
15
+ {@render children?.()}
16
+ </div>
@@ -0,0 +1,57 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import ChevronDown from './icons/ChevronDown.svelte';
4
+
5
+ interface Props {
6
+ id?: string;
7
+ defaultOpen?: boolean;
8
+ triggerLabel?: string;
9
+ class?: string;
10
+ children?: Snippet;
11
+ }
12
+
13
+ let {
14
+ id: collapsibleId,
15
+ defaultOpen = false,
16
+ triggerLabel = 'Toggle',
17
+ class: className = '',
18
+ children,
19
+ }: Props = $props();
20
+
21
+ const id = $derived(collapsibleId ?? `collapsible-${Math.random().toString(36).slice(2, 9)}`);
22
+ const triggerId = $derived(`${id}-trigger`);
23
+ const panelId = $derived(`${id}-panel`);
24
+ let open = $state(defaultOpen);
25
+
26
+ function toggle() {
27
+ open = !open;
28
+ }
29
+
30
+ const triggerClasses = $derived(['collapsible__trigger', open ? 'collapsible__trigger--open' : ''].filter(Boolean).join(' '));
31
+ const panelClasses = $derived(['collapsible__panel', open ? 'collapsible__panel--open' : ''].filter(Boolean).join(' '));
32
+ </script>
33
+
34
+ <div class="collapsible {className}" data-collapsible id={id}>
35
+ <button
36
+ type="button"
37
+ class={triggerClasses}
38
+ id={triggerId}
39
+ aria-expanded={open}
40
+ aria-controls={panelId}
41
+ onclick={toggle}
42
+ >
43
+ <span class="collapsible__trigger-label">{triggerLabel}</span>
44
+ <ChevronDown class="collapsible__icon" width={16} height={16} aria-hidden="true" />
45
+ </button>
46
+ <div
47
+ class={panelClasses}
48
+ id={panelId}
49
+ role="region"
50
+ aria-labelledby={triggerId}
51
+ hidden={!open}
52
+ >
53
+ <div class="collapsible__panel-inner">
54
+ {@render children?.()}
55
+ </div>
56
+ </div>
57
+ </div>