@lab206/ui 0.1.0

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 (327) hide show
  1. package/LICENSE +114 -0
  2. package/README.md +6 -0
  3. package/dist/components/Accordion.d.ts +25 -0
  4. package/dist/components/Accordion.d.ts.map +1 -0
  5. package/dist/components/Accordion.js +123 -0
  6. package/dist/components/Accordion.js.map +1 -0
  7. package/dist/components/Alert.d.ts +17 -0
  8. package/dist/components/Alert.d.ts.map +1 -0
  9. package/dist/components/Alert.js +59 -0
  10. package/dist/components/Alert.js.map +1 -0
  11. package/dist/components/AspectRatio.d.ts +13 -0
  12. package/dist/components/AspectRatio.d.ts.map +1 -0
  13. package/dist/components/AspectRatio.js +38 -0
  14. package/dist/components/AspectRatio.js.map +1 -0
  15. package/dist/components/Avatar.d.ts +17 -0
  16. package/dist/components/Avatar.d.ts.map +1 -0
  17. package/dist/components/Avatar.js +57 -0
  18. package/dist/components/Avatar.js.map +1 -0
  19. package/dist/components/Badge.d.ts +12 -0
  20. package/dist/components/Badge.d.ts.map +1 -0
  21. package/dist/components/Badge.js +62 -0
  22. package/dist/components/Badge.js.map +1 -0
  23. package/dist/components/Breadcrumb.d.ts +16 -0
  24. package/dist/components/Breadcrumb.d.ts.map +1 -0
  25. package/dist/components/Breadcrumb.js +76 -0
  26. package/dist/components/Breadcrumb.js.map +1 -0
  27. package/dist/components/Button.d.ts +28 -0
  28. package/dist/components/Button.d.ts.map +1 -0
  29. package/dist/components/Button.js +110 -0
  30. package/dist/components/Button.js.map +1 -0
  31. package/dist/components/Card.d.ts +18 -0
  32. package/dist/components/Card.d.ts.map +1 -0
  33. package/dist/components/Card.js +57 -0
  34. package/dist/components/Card.js.map +1 -0
  35. package/dist/components/Checkbox.d.ts +23 -0
  36. package/dist/components/Checkbox.d.ts.map +1 -0
  37. package/dist/components/Checkbox.js +107 -0
  38. package/dist/components/Checkbox.js.map +1 -0
  39. package/dist/components/Chip.d.ts +18 -0
  40. package/dist/components/Chip.d.ts.map +1 -0
  41. package/dist/components/Chip.js +103 -0
  42. package/dist/components/Chip.js.map +1 -0
  43. package/dist/components/Code.d.ts +12 -0
  44. package/dist/components/Code.d.ts.map +1 -0
  45. package/dist/components/Code.js +57 -0
  46. package/dist/components/Code.js.map +1 -0
  47. package/dist/components/Collapse.d.ts +15 -0
  48. package/dist/components/Collapse.d.ts.map +1 -0
  49. package/dist/components/Collapse.js +49 -0
  50. package/dist/components/Collapse.js.map +1 -0
  51. package/dist/components/Combobox.d.ts +47 -0
  52. package/dist/components/Combobox.d.ts.map +1 -0
  53. package/dist/components/Combobox.js +325 -0
  54. package/dist/components/Combobox.js.map +1 -0
  55. package/dist/components/Command.d.ts +42 -0
  56. package/dist/components/Command.d.ts.map +1 -0
  57. package/dist/components/Command.js +263 -0
  58. package/dist/components/Command.js.map +1 -0
  59. package/dist/components/Container.d.ts +11 -0
  60. package/dist/components/Container.d.ts.map +1 -0
  61. package/dist/components/Container.js +38 -0
  62. package/dist/components/Container.js.map +1 -0
  63. package/dist/components/Dialog.d.ts +26 -0
  64. package/dist/components/Dialog.d.ts.map +1 -0
  65. package/dist/components/Dialog.js +159 -0
  66. package/dist/components/Dialog.js.map +1 -0
  67. package/dist/components/Divider.d.ts +10 -0
  68. package/dist/components/Divider.d.ts.map +1 -0
  69. package/dist/components/Divider.js +52 -0
  70. package/dist/components/Divider.js.map +1 -0
  71. package/dist/components/Drawer.d.ts +19 -0
  72. package/dist/components/Drawer.d.ts.map +1 -0
  73. package/dist/components/Drawer.js +131 -0
  74. package/dist/components/Drawer.js.map +1 -0
  75. package/dist/components/Empty.d.ts +17 -0
  76. package/dist/components/Empty.d.ts.map +1 -0
  77. package/dist/components/Empty.js +51 -0
  78. package/dist/components/Empty.js.map +1 -0
  79. package/dist/components/Field.d.ts +27 -0
  80. package/dist/components/Field.d.ts.map +1 -0
  81. package/dist/components/Field.js +153 -0
  82. package/dist/components/Field.js.map +1 -0
  83. package/dist/components/Grid.d.ts +13 -0
  84. package/dist/components/Grid.d.ts.map +1 -0
  85. package/dist/components/Grid.js +44 -0
  86. package/dist/components/Grid.js.map +1 -0
  87. package/dist/components/Input.d.ts +55 -0
  88. package/dist/components/Input.d.ts.map +1 -0
  89. package/dist/components/Input.js +113 -0
  90. package/dist/components/Input.js.map +1 -0
  91. package/dist/components/Kbd.d.ts +10 -0
  92. package/dist/components/Kbd.d.ts.map +1 -0
  93. package/dist/components/Kbd.js +41 -0
  94. package/dist/components/Kbd.js.map +1 -0
  95. package/dist/components/Label.d.ts +13 -0
  96. package/dist/components/Label.d.ts.map +1 -0
  97. package/dist/components/Label.js +34 -0
  98. package/dist/components/Label.js.map +1 -0
  99. package/dist/components/Link.d.ts +18 -0
  100. package/dist/components/Link.d.ts.map +1 -0
  101. package/dist/components/Link.js +41 -0
  102. package/dist/components/Link.js.map +1 -0
  103. package/dist/components/List.d.ts +22 -0
  104. package/dist/components/List.d.ts.map +1 -0
  105. package/dist/components/List.js +157 -0
  106. package/dist/components/List.js.map +1 -0
  107. package/dist/components/Menu.d.ts +28 -0
  108. package/dist/components/Menu.d.ts.map +1 -0
  109. package/dist/components/Menu.js +126 -0
  110. package/dist/components/Menu.js.map +1 -0
  111. package/dist/components/NumberInput.d.ts +27 -0
  112. package/dist/components/NumberInput.d.ts.map +1 -0
  113. package/dist/components/NumberInput.js +92 -0
  114. package/dist/components/NumberInput.js.map +1 -0
  115. package/dist/components/Pagination.d.ts +13 -0
  116. package/dist/components/Pagination.d.ts.map +1 -0
  117. package/dist/components/Pagination.js +104 -0
  118. package/dist/components/Pagination.js.map +1 -0
  119. package/dist/components/Popover.d.ts +26 -0
  120. package/dist/components/Popover.d.ts.map +1 -0
  121. package/dist/components/Popover.js +165 -0
  122. package/dist/components/Popover.js.map +1 -0
  123. package/dist/components/Progress.d.ts +15 -0
  124. package/dist/components/Progress.d.ts.map +1 -0
  125. package/dist/components/Progress.js +63 -0
  126. package/dist/components/Progress.js.map +1 -0
  127. package/dist/components/Radio.d.ts +25 -0
  128. package/dist/components/Radio.d.ts.map +1 -0
  129. package/dist/components/Radio.js +95 -0
  130. package/dist/components/Radio.js.map +1 -0
  131. package/dist/components/ScrollArea.d.ts +13 -0
  132. package/dist/components/ScrollArea.d.ts.map +1 -0
  133. package/dist/components/ScrollArea.js +33 -0
  134. package/dist/components/ScrollArea.js.map +1 -0
  135. package/dist/components/Select.d.ts +34 -0
  136. package/dist/components/Select.d.ts.map +1 -0
  137. package/dist/components/Select.js +108 -0
  138. package/dist/components/Select.js.map +1 -0
  139. package/dist/components/Skeleton.d.ts +18 -0
  140. package/dist/components/Skeleton.d.ts.map +1 -0
  141. package/dist/components/Skeleton.js +86 -0
  142. package/dist/components/Skeleton.js.map +1 -0
  143. package/dist/components/Slider.d.ts +26 -0
  144. package/dist/components/Slider.d.ts.map +1 -0
  145. package/dist/components/Slider.js +113 -0
  146. package/dist/components/Slider.js.map +1 -0
  147. package/dist/components/Spinner.d.ts +12 -0
  148. package/dist/components/Spinner.d.ts.map +1 -0
  149. package/dist/components/Spinner.js +44 -0
  150. package/dist/components/Spinner.js.map +1 -0
  151. package/dist/components/Stack.d.ts +21 -0
  152. package/dist/components/Stack.d.ts.map +1 -0
  153. package/dist/components/Stack.js +48 -0
  154. package/dist/components/Stack.js.map +1 -0
  155. package/dist/components/Stat.d.ts +23 -0
  156. package/dist/components/Stat.d.ts.map +1 -0
  157. package/dist/components/Stat.js +115 -0
  158. package/dist/components/Stat.js.map +1 -0
  159. package/dist/components/Steps.d.ts +20 -0
  160. package/dist/components/Steps.d.ts.map +1 -0
  161. package/dist/components/Steps.js +126 -0
  162. package/dist/components/Steps.js.map +1 -0
  163. package/dist/components/Switch.d.ts +23 -0
  164. package/dist/components/Switch.d.ts.map +1 -0
  165. package/dist/components/Switch.js +108 -0
  166. package/dist/components/Switch.js.map +1 -0
  167. package/dist/components/Table.d.ts +27 -0
  168. package/dist/components/Table.d.ts.map +1 -0
  169. package/dist/components/Table.js +112 -0
  170. package/dist/components/Table.js.map +1 -0
  171. package/dist/components/Tabs.d.ts +27 -0
  172. package/dist/components/Tabs.d.ts.map +1 -0
  173. package/dist/components/Tabs.js +171 -0
  174. package/dist/components/Tabs.js.map +1 -0
  175. package/dist/components/Text.d.ts +17 -0
  176. package/dist/components/Text.d.ts.map +1 -0
  177. package/dist/components/Text.js +48 -0
  178. package/dist/components/Text.js.map +1 -0
  179. package/dist/components/Textarea.d.ts +32 -0
  180. package/dist/components/Textarea.d.ts.map +1 -0
  181. package/dist/components/Textarea.js +91 -0
  182. package/dist/components/Textarea.js.map +1 -0
  183. package/dist/components/Timeline.d.ts +17 -0
  184. package/dist/components/Timeline.d.ts.map +1 -0
  185. package/dist/components/Timeline.js +95 -0
  186. package/dist/components/Timeline.js.map +1 -0
  187. package/dist/components/Toast.d.ts +36 -0
  188. package/dist/components/Toast.d.ts.map +1 -0
  189. package/dist/components/Toast.js +143 -0
  190. package/dist/components/Toast.js.map +1 -0
  191. package/dist/components/ToggleGroup.d.ts +25 -0
  192. package/dist/components/ToggleGroup.d.ts.map +1 -0
  193. package/dist/components/ToggleGroup.js +103 -0
  194. package/dist/components/ToggleGroup.js.map +1 -0
  195. package/dist/components/Tooltip.d.ts +19 -0
  196. package/dist/components/Tooltip.d.ts.map +1 -0
  197. package/dist/components/Tooltip.js +141 -0
  198. package/dist/components/Tooltip.js.map +1 -0
  199. package/dist/components/Transition.d.ts +22 -0
  200. package/dist/components/Transition.d.ts.map +1 -0
  201. package/dist/components/Transition.js +139 -0
  202. package/dist/components/Transition.js.map +1 -0
  203. package/dist/density.d.ts +21 -0
  204. package/dist/density.d.ts.map +1 -0
  205. package/dist/density.js +31 -0
  206. package/dist/density.js.map +1 -0
  207. package/dist/dev.d.ts +27 -0
  208. package/dist/dev.d.ts.map +1 -0
  209. package/dist/dev.js +77 -0
  210. package/dist/dev.js.map +1 -0
  211. package/dist/focusTrap.d.ts +6 -0
  212. package/dist/focusTrap.d.ts.map +1 -0
  213. package/dist/focusTrap.js +55 -0
  214. package/dist/focusTrap.js.map +1 -0
  215. package/dist/form.d.ts +125 -0
  216. package/dist/form.d.ts.map +1 -0
  217. package/dist/form.js +192 -0
  218. package/dist/form.js.map +1 -0
  219. package/dist/index.d.ts +134 -0
  220. package/dist/index.d.ts.map +1 -0
  221. package/dist/index.js +85 -0
  222. package/dist/index.js.map +1 -0
  223. package/dist/motion.d.ts +29 -0
  224. package/dist/motion.d.ts.map +1 -0
  225. package/dist/motion.js +43 -0
  226. package/dist/motion.js.map +1 -0
  227. package/dist/overlay.d.ts +63 -0
  228. package/dist/overlay.d.ts.map +1 -0
  229. package/dist/overlay.js +172 -0
  230. package/dist/overlay.js.map +1 -0
  231. package/dist/palette.d.ts +20 -0
  232. package/dist/palette.d.ts.map +1 -0
  233. package/dist/palette.js +52 -0
  234. package/dist/palette.js.map +1 -0
  235. package/dist/reactive.d.ts +25 -0
  236. package/dist/reactive.d.ts.map +1 -0
  237. package/dist/reactive.js +43 -0
  238. package/dist/reactive.js.map +1 -0
  239. package/dist/rovingFocus.d.ts +36 -0
  240. package/dist/rovingFocus.d.ts.map +1 -0
  241. package/dist/rovingFocus.js +127 -0
  242. package/dist/rovingFocus.js.map +1 -0
  243. package/dist/size-entries/form-kit.d.ts +12 -0
  244. package/dist/size-entries/form-kit.d.ts.map +1 -0
  245. package/dist/size-entries/form-kit.js +12 -0
  246. package/dist/size-entries/form-kit.js.map +1 -0
  247. package/dist/styles.d.ts +29 -0
  248. package/dist/styles.d.ts.map +1 -0
  249. package/dist/styles.js +53 -0
  250. package/dist/styles.js.map +1 -0
  251. package/dist/theme.d.ts +22 -0
  252. package/dist/theme.d.ts.map +1 -0
  253. package/dist/theme.js +32 -0
  254. package/dist/theme.js.map +1 -0
  255. package/dist/utils.d.ts +5 -0
  256. package/dist/utils.d.ts.map +1 -0
  257. package/dist/utils.js +24 -0
  258. package/dist/utils.js.map +1 -0
  259. package/package.json +71 -0
  260. package/src/components/Accordion.tsx +194 -0
  261. package/src/components/Alert.tsx +88 -0
  262. package/src/components/AspectRatio.tsx +64 -0
  263. package/src/components/Avatar.tsx +89 -0
  264. package/src/components/Badge.tsx +84 -0
  265. package/src/components/Breadcrumb.tsx +116 -0
  266. package/src/components/Button.tsx +148 -0
  267. package/src/components/Card.tsx +92 -0
  268. package/src/components/Checkbox.tsx +143 -0
  269. package/src/components/Chip.tsx +153 -0
  270. package/src/components/Code.tsx +71 -0
  271. package/src/components/Collapse.tsx +76 -0
  272. package/src/components/Combobox.tsx +438 -0
  273. package/src/components/Command.tsx +380 -0
  274. package/src/components/Container.tsx +58 -0
  275. package/src/components/Dialog.tsx +226 -0
  276. package/src/components/Divider.tsx +72 -0
  277. package/src/components/Drawer.tsx +191 -0
  278. package/src/components/Empty.tsx +86 -0
  279. package/src/components/Field.tsx +184 -0
  280. package/src/components/Grid.tsx +67 -0
  281. package/src/components/Input.tsx +169 -0
  282. package/src/components/Kbd.tsx +57 -0
  283. package/src/components/Label.tsx +54 -0
  284. package/src/components/Link.tsx +87 -0
  285. package/src/components/List.tsx +236 -0
  286. package/src/components/Menu.tsx +195 -0
  287. package/src/components/NumberInput.tsx +158 -0
  288. package/src/components/Pagination.tsx +153 -0
  289. package/src/components/Popover.tsx +219 -0
  290. package/src/components/Progress.tsx +108 -0
  291. package/src/components/Radio.tsx +161 -0
  292. package/src/components/ScrollArea.tsx +58 -0
  293. package/src/components/Select.tsx +128 -0
  294. package/src/components/Skeleton.tsx +117 -0
  295. package/src/components/Slider.tsx +175 -0
  296. package/src/components/Spinner.tsx +70 -0
  297. package/src/components/Stack.tsx +79 -0
  298. package/src/components/Stat.tsx +169 -0
  299. package/src/components/Steps.tsx +191 -0
  300. package/src/components/Switch.tsx +146 -0
  301. package/src/components/Table.tsx +168 -0
  302. package/src/components/Tabs.tsx +246 -0
  303. package/src/components/Text.tsx +69 -0
  304. package/src/components/Textarea.tsx +128 -0
  305. package/src/components/Timeline.tsx +150 -0
  306. package/src/components/Toast.tsx +221 -0
  307. package/src/components/ToggleGroup.tsx +161 -0
  308. package/src/components/Tooltip.tsx +187 -0
  309. package/src/components/Transition.tsx +155 -0
  310. package/src/density.ts +46 -0
  311. package/src/dev.ts +87 -0
  312. package/src/focusTrap.ts +61 -0
  313. package/src/form.ts +269 -0
  314. package/src/index.ts +243 -0
  315. package/src/motion.ts +62 -0
  316. package/src/overlay.ts +232 -0
  317. package/src/palette.ts +70 -0
  318. package/src/reactive.ts +54 -0
  319. package/src/rovingFocus.ts +171 -0
  320. package/src/size-entries/form-kit.ts +11 -0
  321. package/src/styles/base.css +70 -0
  322. package/src/styles/theme.css +14 -0
  323. package/src/styles/tokens.css +377 -0
  324. package/src/styles/utilities.css +216 -0
  325. package/src/styles.ts +52 -0
  326. package/src/theme.ts +48 -0
  327. package/src/utils.ts +25 -0
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Roving tabindex helpers for Menu, Tabs, List, etc.
3
+ * @see https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex
4
+ */
5
+
6
+ export function listRovingItems(
7
+ root: HTMLElement,
8
+ selector: string,
9
+ ): HTMLElement[] {
10
+ return [...root.querySelectorAll<HTMLElement>(selector)].filter((el) => {
11
+ if (el.hasAttribute("disabled")) return false;
12
+ if (el.getAttribute("aria-disabled") === "true") return false;
13
+ // hidden from a11y tree
14
+ if (el.getAttribute("aria-hidden") === "true") return false;
15
+ return true;
16
+ });
17
+ }
18
+
19
+ /** Set tabindex so only `activeIndex` is in sequential tab order. */
20
+ export function applyRovingTabIndex(
21
+ items: HTMLElement[],
22
+ activeIndex: number,
23
+ ): void {
24
+ items.forEach((el, i) => {
25
+ el.tabIndex = i === activeIndex ? 0 : -1;
26
+ });
27
+ }
28
+
29
+ export function focusRovingItem(
30
+ items: HTMLElement[],
31
+ index: number,
32
+ ): HTMLElement | null {
33
+ if (items.length === 0) return null;
34
+ const i = Math.max(0, Math.min(items.length - 1, index));
35
+ applyRovingTabIndex(items, i);
36
+ const el = items[i]!;
37
+ el.focus();
38
+ return el;
39
+ }
40
+
41
+ export function indexOfFocused(
42
+ items: HTMLElement[],
43
+ active: Element | null,
44
+ ): number {
45
+ if (!active) return -1;
46
+ return items.findIndex((el) => el === active || el.contains(active));
47
+ }
48
+
49
+ export type RovingKeyOptions = {
50
+ orientation?: "horizontal" | "vertical" | "both";
51
+ loop?: boolean;
52
+ /** Home / End jump to ends (default true) */
53
+ homeEnd?: boolean;
54
+ /**
55
+ * Called when the focused item should activate (Enter / Space).
56
+ * Return true if the event was handled.
57
+ */
58
+ onActivate?: (el: HTMLElement, index: number) => boolean | void;
59
+ /**
60
+ * Called when focus moves via arrows/home/end.
61
+ * Return true to also activate (tabs pattern).
62
+ */
63
+ onMove?: (el: HTMLElement, index: number) => boolean | void;
64
+ };
65
+
66
+ /**
67
+ * Handle Arrow / Home / End / Enter / Space on a composite widget.
68
+ * Returns true when the event was consumed.
69
+ */
70
+ export function handleRovingKeydown(
71
+ e: KeyboardEvent,
72
+ root: HTMLElement,
73
+ selector: string,
74
+ options: RovingKeyOptions = {},
75
+ ): boolean {
76
+ const {
77
+ orientation = "vertical",
78
+ loop = true,
79
+ homeEnd = true,
80
+ onActivate,
81
+ onMove,
82
+ } = options;
83
+
84
+ const items = listRovingItems(root, selector);
85
+ if (items.length === 0) return false;
86
+
87
+ const doc = root.ownerDocument;
88
+ let idx = indexOfFocused(items, doc.activeElement);
89
+ if (idx < 0) idx = 0;
90
+
91
+ const key = e.key;
92
+ const vertical =
93
+ orientation === "vertical" || orientation === "both";
94
+ const horizontal =
95
+ orientation === "horizontal" || orientation === "both";
96
+
97
+ let next = idx;
98
+ let moved = false;
99
+
100
+ if (vertical && key === "ArrowDown") {
101
+ next = loop
102
+ ? (idx + 1) % items.length
103
+ : Math.min(items.length - 1, idx + 1);
104
+ moved = true;
105
+ } else if (vertical && key === "ArrowUp") {
106
+ next = loop
107
+ ? (idx - 1 + items.length) % items.length
108
+ : Math.max(0, idx - 1);
109
+ moved = true;
110
+ } else if (horizontal && key === "ArrowRight") {
111
+ next = loop
112
+ ? (idx + 1) % items.length
113
+ : Math.min(items.length - 1, idx + 1);
114
+ moved = true;
115
+ } else if (horizontal && key === "ArrowLeft") {
116
+ next = loop
117
+ ? (idx - 1 + items.length) % items.length
118
+ : Math.max(0, idx - 1);
119
+ moved = true;
120
+ } else if (homeEnd && key === "Home") {
121
+ next = 0;
122
+ moved = true;
123
+ } else if (homeEnd && key === "End") {
124
+ next = items.length - 1;
125
+ moved = true;
126
+ } else if (key === "Enter" || key === " ") {
127
+ e.preventDefault();
128
+ const el = items[idx]!;
129
+ onActivate?.(el, idx);
130
+ return true;
131
+ } else {
132
+ return false;
133
+ }
134
+
135
+ if (!moved || next === idx && key !== "Home" && key !== "End") {
136
+ // still prevent scroll for arrows even if clamped
137
+ if (
138
+ key === "ArrowDown" ||
139
+ key === "ArrowUp" ||
140
+ key === "ArrowLeft" ||
141
+ key === "ArrowRight" ||
142
+ key === "Home" ||
143
+ key === "End"
144
+ ) {
145
+ e.preventDefault();
146
+ return true;
147
+ }
148
+ return false;
149
+ }
150
+
151
+ e.preventDefault();
152
+ const el = focusRovingItem(items, next);
153
+ if (el) onMove?.(el, next);
154
+ return true;
155
+ }
156
+
157
+ /**
158
+ * Initial tabindex setup + focus first/selected item.
159
+ * Call when a menu opens or a list mounts.
160
+ */
161
+ export function initRovingFocus(
162
+ root: HTMLElement,
163
+ selector: string,
164
+ preferredIndex = 0,
165
+ ): number {
166
+ const items = listRovingItems(root, selector);
167
+ if (items.length === 0) return -1;
168
+ const i = Math.max(0, Math.min(items.length - 1, preferredIndex));
169
+ applyRovingTabIndex(items, i);
170
+ return i;
171
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Size entry: golden-path form surface only (tree-shake probe).
3
+ * Measured by scripts/size.ts — not a public export.
4
+ */
5
+ export { Button } from "../components/Button.js";
6
+ export { Input } from "../components/Input.js";
7
+ export { Field } from "../components/Field.js";
8
+ export { Stack } from "../components/Stack.js";
9
+ export { Text } from "../components/Text.js";
10
+ export { createTheme } from "../theme.js";
11
+ export { required, emailFormat, firstError } from "../form.js";
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Base reset + element defaults for Powers apps.
3
+ * Import after tokens.css.
4
+ */
5
+
6
+ *,
7
+ *::before,
8
+ *::after {
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ html {
13
+ color-scheme: light;
14
+ -webkit-text-size-adjust: 100%;
15
+ text-rendering: optimizeLegibility;
16
+ -webkit-font-smoothing: antialiased;
17
+ -moz-osx-font-smoothing: grayscale;
18
+ }
19
+
20
+ html[data-pu-theme="dark"] {
21
+ color-scheme: dark;
22
+ }
23
+
24
+ body {
25
+ margin: 0;
26
+ min-height: 100vh;
27
+ font-family: var(--pu-font-sans);
28
+ font-size: var(--pu-text-md);
29
+ line-height: var(--pu-leading);
30
+ background: var(--pu-color-bg);
31
+ color: var(--pu-color-text);
32
+ /* Soft navy / green atmosphere — clean, not noisy */
33
+ background-image:
34
+ radial-gradient(1000px 520px at 8% -12%, var(--pu-color-glow), transparent 55%),
35
+ radial-gradient(800px 460px at 96% 0%, var(--pu-color-glow-2), transparent 52%),
36
+ radial-gradient(600px 400px at 50% 110%, var(--pu-color-glow-holo), transparent 55%);
37
+ background-attachment: scroll;
38
+ }
39
+
40
+ ::selection {
41
+ background: var(--pu-color-selection);
42
+ color: var(--pu-color-text);
43
+ }
44
+
45
+ button,
46
+ input,
47
+ textarea,
48
+ select {
49
+ font: inherit;
50
+ color: inherit;
51
+ }
52
+
53
+ :focus {
54
+ outline: none;
55
+ }
56
+
57
+ :focus-visible {
58
+ outline: 2px solid color-mix(in srgb, var(--pu-color-focus) 80%, transparent);
59
+ outline-offset: 2px;
60
+ }
61
+
62
+ a {
63
+ color: inherit;
64
+ }
65
+
66
+ code,
67
+ pre,
68
+ kbd {
69
+ font-family: var(--pu-font-mono);
70
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Default Powers style entry (batteries included).
3
+ *
4
+ * Layers:
5
+ * 1. tokens — design contracts
6
+ * 2. base — document defaults
7
+ * 3. utilities — optional BEM-ish layout helpers (token-mapped)
8
+ *
9
+ * Component styles (pu-btn, etc.) are injected by primitives when used.
10
+ * For a minimal CSS footprint: import only tokens.css + base.css.
11
+ */
12
+ @import "./tokens.css";
13
+ @import "./base.css";
14
+ @import "./utilities.css";
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Powers design tokens — “instrument panel”
3
+ * -----------------------------------------
4
+ * Deep navy + green signal + cool slate neutrals (instrument).
5
+ * Thin edges, soft glows — dual electric overrides via data-pu-palette.
6
+ *
7
+ * Edit this file to rebrand the entire product.
8
+ */
9
+
10
+ :root {
11
+ /* ---- Brand navy scale ---- */
12
+ --pu-brand-50: #eef3f9;
13
+ --pu-brand-100: #d4e0ee;
14
+ --pu-brand-200: #9bb6d4;
15
+ --pu-brand-300: #5a86b5;
16
+ --pu-brand-400: #2f5f94;
17
+ --pu-brand-500: #0a2744; /* lifted navy — less chalk-black */
18
+ --pu-brand-600: #061c33;
19
+ --pu-brand-700: #041528;
20
+ --pu-brand-800: #030f1c;
21
+ --pu-brand-900: #020a14;
22
+
23
+ /* ---- Cool slate neutrals ---- */
24
+ --pu-gray-0: #fcfdff;
25
+ --pu-gray-50: #f4f6fa;
26
+ --pu-gray-100: #e8ecf3;
27
+ --pu-gray-200: #d2d9e5;
28
+ --pu-gray-300: #a8b2c2;
29
+ --pu-gray-400: #7c8799;
30
+ --pu-gray-500: #5a6578;
31
+ --pu-gray-600: #434c5d;
32
+ --pu-gray-700: #313846;
33
+ --pu-gray-800: #1f2530;
34
+ --pu-gray-900: #12161e;
35
+ --pu-gray-950: #090c11;
36
+
37
+ /* ---- Signal green (success / live — not primary chrome) ---- */
38
+ --pu-sage-300: #8fd44f;
39
+ --pu-sage-400: #7ac936;
40
+ --pu-sage-500: #69be28;
41
+ --pu-sage-600: #4f9a1c;
42
+ --pu-sage-700: #3a7214;
43
+ --pu-sage-800: #2a5410;
44
+
45
+ /* ---- Soft metal (optional; prefer not on surfaces) ---- */
46
+ --pu-brass-400: #c4c9d2;
47
+ --pu-brass-500: #9aa3b2;
48
+ --pu-brass-600: #6b7382;
49
+
50
+ /* ---- Precision cyan (focus / edge — restrained electric) ---- */
51
+ --pu-holo-cyan: #2eb8c9;
52
+ --pu-holo-teal: #1f8f9c;
53
+ --pu-holo-mix: color-mix(in srgb, var(--pu-holo-cyan) 40%, var(--pu-sage-400));
54
+
55
+ /* ---- Semantic surfaces ---- */
56
+ --pu-color-bg: var(--pu-gray-50);
57
+ --pu-color-surface: var(--pu-gray-0);
58
+ --pu-color-surface-2: var(--pu-gray-100);
59
+ --pu-color-surface-elevated: var(--pu-gray-0);
60
+ --pu-color-surface-sunken: color-mix(in srgb, var(--pu-gray-100) 88%, var(--pu-brand-500));
61
+ --pu-color-border: color-mix(in srgb, var(--pu-gray-200) 88%, var(--pu-brand-400));
62
+ --pu-color-border-strong: color-mix(in srgb, var(--pu-gray-300) 70%, var(--pu-brand-400));
63
+ /* Form controls / checkbox / switch — always clearer than hairline borders */
64
+ --pu-color-control-border: color-mix(in srgb, var(--pu-gray-300) 82%, var(--pu-brand-400));
65
+ --pu-color-text: var(--pu-brand-500);
66
+ --pu-color-text-muted: #4a5568; /* ~gray-600 — AA on surface/bg */
67
+ /* Primary actions: navy; green reserved for live/success signal */
68
+ --pu-color-accent: var(--pu-brand-500);
69
+ --pu-color-accent-hover: var(--pu-brand-600);
70
+ --pu-color-accent-fg: #f7fafc;
71
+ --pu-color-signal: var(--pu-sage-500);
72
+ --pu-color-danger: #b42318;
73
+ --pu-color-danger-fg: #fcfdff;
74
+ --pu-color-focus: var(--pu-holo-cyan);
75
+ --pu-color-selection: color-mix(in srgb, var(--pu-holo-cyan) 18%, transparent);
76
+ --pu-color-success: var(--pu-sage-600);
77
+ --pu-color-warning: #a67c3d;
78
+ --pu-color-warning-fg: #5c4018;
79
+ /* Soft / secondary actions (buttons, chips, active chrome) */
80
+ --pu-color-soft-bg: color-mix(in srgb, var(--pu-color-signal) 12%, var(--pu-color-surface));
81
+ --pu-color-soft-bg-hover: color-mix(in srgb, var(--pu-color-signal) 18%, var(--pu-color-surface));
82
+ --pu-color-soft-fg: #1f3d2e; /* dark green-navy — readable on soft wash */
83
+ --pu-color-soft-border: color-mix(in srgb, var(--pu-color-signal) 28%, var(--pu-color-border));
84
+
85
+ /* Thin glass — almost flat, slight frost */
86
+ --pu-glass-bg: color-mix(in srgb, var(--pu-color-surface) 86%, transparent);
87
+ --pu-glass-border: color-mix(
88
+ in srgb,
89
+ var(--pu-holo-cyan) 10%,
90
+ var(--pu-color-border)
91
+ );
92
+ --pu-glass-blur: 14px;
93
+
94
+ --pu-color-glow: color-mix(in srgb, var(--pu-brand-400) 10%, transparent);
95
+ --pu-color-glow-2: color-mix(in srgb, var(--pu-sage-500) 8%, transparent);
96
+ --pu-color-glow-holo: color-mix(in srgb, var(--pu-holo-cyan) 10%, transparent);
97
+
98
+ /* ---- Space ---- */
99
+ --pu-space-0: 0;
100
+ --pu-space-1: 0.25rem;
101
+ --pu-space-2: 0.5rem;
102
+ --pu-space-3: 0.75rem;
103
+ --pu-space-4: 1rem;
104
+ --pu-space-5: 1.25rem;
105
+ --pu-space-6: 1.5rem;
106
+ --pu-space-8: 2rem;
107
+ --pu-space-10: 2.5rem;
108
+ --pu-space-12: 3rem;
109
+
110
+ /* ---- Radius (technical, not bubbly) ---- */
111
+ --pu-radius-sm: 5px;
112
+ --pu-radius-md: 8px;
113
+ --pu-radius-lg: 12px;
114
+ --pu-radius-xl: 16px;
115
+ --pu-radius-full: 9999px;
116
+
117
+ /* ---- Typography ---- */
118
+ --pu-font-sans: "DM Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
119
+ --pu-font-display: "DM Sans", "Segoe UI", system-ui, sans-serif;
120
+ --pu-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
121
+ --pu-text-xs: 0.75rem;
122
+ --pu-text-sm: 0.875rem;
123
+ --pu-text-md: 1rem;
124
+ --pu-text-lg: 1.125rem;
125
+ --pu-text-xl: 1.375rem;
126
+ --pu-text-2xl: 1.75rem;
127
+ --pu-text-3xl: 2.35rem;
128
+ --pu-leading: 1.55;
129
+ --pu-leading-tight: 1.15;
130
+ --pu-tracking-tight: -0.025em;
131
+ --pu-tracking-display: -0.035em;
132
+ --pu-font-medium: 500;
133
+ --pu-font-semibold: 600;
134
+ --pu-font-bold: 700;
135
+
136
+ /* ---- Airy elevation (Linear-like, cool navy tint) ---- */
137
+ --pu-shadow-xs: 0 1px 1px rgba(10, 39, 68, 0.03);
138
+ --pu-shadow-sm:
139
+ 0 1px 2px rgba(10, 39, 68, 0.03),
140
+ 0 2px 6px rgba(10, 39, 68, 0.04);
141
+ --pu-shadow-md:
142
+ 0 2px 4px rgba(10, 39, 68, 0.03),
143
+ 0 8px 24px rgba(10, 39, 68, 0.06);
144
+ --pu-shadow-lg:
145
+ 0 4px 8px rgba(10, 39, 68, 0.03),
146
+ 0 16px 40px rgba(10, 39, 68, 0.08);
147
+ --pu-shadow-xl:
148
+ 0 8px 16px rgba(10, 39, 68, 0.04),
149
+ 0 24px 56px rgba(10, 39, 68, 0.1);
150
+ --pu-shadow-float:
151
+ 0 0 0 1px color-mix(in srgb, var(--pu-holo-cyan) 12%, var(--pu-color-border)),
152
+ 0 0 20px color-mix(in srgb, var(--pu-holo-cyan) 5%, transparent),
153
+ 0 12px 36px rgba(10, 39, 68, 0.1);
154
+
155
+ /* ---- Motion ---- */
156
+ --pu-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
157
+ --pu-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
158
+ --pu-ease-spring: cubic-bezier(0.34, 1.25, 0.64, 1);
159
+ --pu-duration-fast: 130ms;
160
+ --pu-duration: 220ms;
161
+ --pu-duration-slow: 380ms;
162
+
163
+ /* ---- Controls ---- */
164
+ --pu-control-h-sm: 2rem;
165
+ --pu-control-h-md: 2.5rem;
166
+ --pu-control-h-lg: 3rem;
167
+ --pu-control-px: 0.95rem;
168
+ --pu-field-gap: var(--pu-space-2);
169
+ --pu-label-size: var(--pu-text-sm);
170
+
171
+ --pu-z-overlay: 1000;
172
+ --pu-z-toast: 1100;
173
+ --pu-overlay-scrim: color-mix(in srgb, var(--pu-brand-500) 48%, transparent);
174
+ }
175
+
176
+ [data-pu-density="compact"] {
177
+ --pu-control-h-sm: 1.75rem;
178
+ --pu-control-h-md: 2rem;
179
+ --pu-control-h-lg: 2.35rem;
180
+ --pu-control-px: 0.7rem;
181
+ --pu-field-gap: var(--pu-space-1);
182
+ --pu-label-size: var(--pu-text-xs);
183
+ --pu-space-3: 0.5rem;
184
+ --pu-space-4: 0.75rem;
185
+ --pu-space-5: 1rem;
186
+ --pu-space-6: 1.15rem;
187
+ }
188
+
189
+ [data-pu-density="comfortable"] {
190
+ }
191
+
192
+ /* Dark — void navy; green as signal only; cyan focus edge */
193
+ [data-pu-theme="dark"] {
194
+ --pu-color-bg: #050a12;
195
+ --pu-color-surface: #0b1220;
196
+ --pu-color-surface-2: #121b2c;
197
+ --pu-color-surface-elevated: #172234;
198
+ --pu-color-surface-sunken: #03060c;
199
+ /* Borders must stay visible on navy surfaces (was ~12% — near-invisible) */
200
+ --pu-color-border: color-mix(in srgb, #9aa8bc 28%, transparent);
201
+ --pu-color-border-strong: color-mix(in srgb, var(--pu-holo-cyan) 36%, #6b7a90);
202
+ --pu-color-control-border: color-mix(in srgb, #b6c2d4 42%, transparent);
203
+ --pu-color-text: #e8eef8;
204
+ --pu-color-text-muted: #a8b4c8; /* brighter muted for AA on dark surfaces */
205
+ /* Primary CTA: medium blue + light label (never dark-on-dark) */
206
+ --pu-color-accent: #4a8fd4;
207
+ --pu-color-accent-hover: #6aa8e6;
208
+ --pu-color-accent-fg: #f7fafc;
209
+ --pu-color-signal: var(--pu-sage-400);
210
+ --pu-color-focus: var(--pu-holo-cyan);
211
+ --pu-color-danger: #f07178;
212
+ --pu-color-danger-fg: #1a0a0c;
213
+ --pu-color-success: var(--pu-sage-400);
214
+ --pu-color-warning: #e0b45c;
215
+ --pu-color-warning-fg: #1a1408;
216
+ --pu-color-selection: color-mix(in srgb, var(--pu-holo-cyan) 22%, transparent);
217
+ /* Soft chrome — light text on tinted dark wash */
218
+ --pu-color-soft-bg: color-mix(in srgb, var(--pu-color-accent) 18%, var(--pu-color-surface));
219
+ --pu-color-soft-bg-hover: color-mix(in srgb, var(--pu-color-accent) 26%, var(--pu-color-surface));
220
+ --pu-color-soft-fg: #c5ddf5;
221
+ --pu-color-soft-border: color-mix(in srgb, var(--pu-color-accent) 40%, transparent);
222
+ --pu-glass-bg: color-mix(in srgb, #0b1220 78%, transparent);
223
+ --pu-glass-border: color-mix(in srgb, var(--pu-holo-cyan) 18%, transparent);
224
+ --pu-color-glow: color-mix(in srgb, var(--pu-brand-300) 12%, transparent);
225
+ --pu-color-glow-2: color-mix(in srgb, var(--pu-sage-500) 8%, transparent);
226
+ --pu-color-glow-holo: color-mix(in srgb, var(--pu-holo-cyan) 10%, transparent);
227
+ --pu-overlay-scrim: color-mix(in srgb, #000 72%, transparent);
228
+ --pu-shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.4);
229
+ --pu-shadow-sm:
230
+ 0 1px 2px rgba(0, 0, 0, 0.35),
231
+ 0 2px 8px rgba(0, 0, 0, 0.28);
232
+ --pu-shadow-md:
233
+ 0 2px 4px rgba(0, 0, 0, 0.3),
234
+ 0 10px 28px rgba(0, 0, 0, 0.4);
235
+ --pu-shadow-lg:
236
+ 0 4px 8px rgba(0, 0, 0, 0.3),
237
+ 0 18px 44px rgba(0, 0, 0, 0.48);
238
+ --pu-shadow-xl:
239
+ 0 8px 16px rgba(0, 0, 0, 0.35),
240
+ 0 26px 60px rgba(0, 0, 0, 0.52);
241
+ --pu-shadow-float:
242
+ 0 0 0 1px color-mix(in srgb, var(--pu-holo-cyan) 18%, transparent),
243
+ 0 0 28px color-mix(in srgb, var(--pu-holo-cyan) 6%, transparent),
244
+ 0 14px 44px rgba(0, 0, 0, 0.55);
245
+ }
246
+
247
+ /**
248
+ * Palette: dual electric (preview / option 3)
249
+ * Navy primary + electric cyan secondary. Green = success/live only.
250
+ * Toggle via data-pu-palette="dual" | "instrument" (see createPalette).
251
+ * Default preview is dual; click “Instrument” in the nav to restore the prior look.
252
+ */
253
+ html[data-pu-palette="instrument"] {
254
+ /* explicit: :root values already = instrument */
255
+ }
256
+
257
+ html[data-pu-palette="dual"] {
258
+ /* Whiter canvas, clearer cyan — dual electric light (pushed) */
259
+ --pu-brand-50: #f4f9ff;
260
+ --pu-brand-100: #e3f0fc;
261
+ --pu-brand-200: #b6d4f5;
262
+ --pu-brand-300: #6ba3e0;
263
+ --pu-brand-400: #2f78c4;
264
+ --pu-brand-500: #0a1e38;
265
+ --pu-brand-600: #06152a;
266
+ --pu-brand-700: #040f1e;
267
+ --pu-brand-800: #030a14;
268
+ --pu-brand-900: #01060d;
269
+
270
+ --pu-gray-0: #ffffff;
271
+ --pu-gray-50: #f7f9fc;
272
+ --pu-gray-100: #eef2f8;
273
+ --pu-gray-200: #d8e0ec;
274
+ --pu-gray-300: #a8b4c8;
275
+ --pu-gray-400: #7a879e;
276
+ --pu-gray-500: #5a6780;
277
+ --pu-gray-600: #424d63;
278
+ --pu-gray-700: #303a4c;
279
+ --pu-gray-800: #1d2433;
280
+ --pu-gray-900: #111722;
281
+ --pu-gray-950: #080b12;
282
+
283
+ /* Electric cyan — stronger second brand voice */
284
+ --pu-holo-cyan: #06b6d4;
285
+ --pu-holo-teal: #0891b2;
286
+ --pu-holo-mix: color-mix(in srgb, var(--pu-holo-cyan) 60%, var(--pu-brand-300));
287
+
288
+ --pu-sage-500: #69be28;
289
+ --pu-sage-600: #4f9a1c;
290
+
291
+ --pu-color-bg: #f4f8fc;
292
+ --pu-color-surface: #ffffff;
293
+ --pu-color-surface-2: #e8f4f8;
294
+ --pu-color-surface-elevated: #ffffff;
295
+ --pu-color-surface-sunken: #dceef4;
296
+ --pu-color-border: color-mix(in srgb, #a8c4d4 62%, #06b6d4);
297
+ --pu-color-border-strong: color-mix(in srgb, #06b6d4 52%, #475569);
298
+ --pu-color-control-border: color-mix(in srgb, #7a9eb0 55%, #0891b2);
299
+ --pu-color-text: #0a1e38;
300
+ --pu-color-text-muted: #3d4f63; /* darker muted for AA on white/surface-2 */
301
+ --pu-color-accent: #0a1e38;
302
+ --pu-color-accent-hover: #06152a;
303
+ --pu-color-accent-fg: #ffffff;
304
+ --pu-color-signal: #69be28;
305
+ --pu-color-success: #3d7a16;
306
+ --pu-color-focus: #06b6d4;
307
+ --pu-color-selection: color-mix(in srgb, #06b6d4 32%, transparent);
308
+
309
+ /* Soft actions = cyan wash (readable dual electric) */
310
+ --pu-color-soft-bg: color-mix(in srgb, #06b6d4 16%, #ffffff);
311
+ --pu-color-soft-bg-hover: color-mix(in srgb, #06b6d4 24%, #ffffff);
312
+ --pu-color-soft-fg: #0a5f73; /* darker teal for AA on soft cyan wash */
313
+ --pu-color-soft-border: color-mix(in srgb, #06b6d4 45%, #94a3b8);
314
+
315
+ --pu-glass-bg: color-mix(in srgb, #ffffff 88%, #cffafe);
316
+ --pu-glass-border: color-mix(in srgb, #06b6d4 28%, #d0dae8);
317
+ --pu-glass-blur: 16px;
318
+ --pu-color-glow: color-mix(in srgb, #06b6d4 18%, transparent);
319
+ --pu-color-glow-2: color-mix(in srgb, #22d3ee 16%, transparent);
320
+ --pu-color-glow-holo: color-mix(in srgb, #06b6d4 20%, transparent);
321
+
322
+ --pu-shadow-xs: 0 1px 1px rgba(6, 182, 212, 0.06);
323
+ --pu-shadow-sm:
324
+ 0 1px 2px rgba(10, 30, 56, 0.03),
325
+ 0 2px 10px rgba(6, 182, 212, 0.1);
326
+ --pu-shadow-md:
327
+ 0 2px 4px rgba(10, 30, 56, 0.03),
328
+ 0 12px 32px rgba(6, 182, 212, 0.12);
329
+ --pu-shadow-lg:
330
+ 0 4px 8px rgba(10, 30, 56, 0.04),
331
+ 0 20px 48px rgba(6, 182, 212, 0.14);
332
+ --pu-shadow-float:
333
+ 0 0 0 1px color-mix(in srgb, #06b6d4 32%, transparent),
334
+ 0 0 40px color-mix(in srgb, #06b6d4 16%, transparent),
335
+ 0 16px 44px rgba(10, 30, 56, 0.1);
336
+ }
337
+
338
+ html[data-pu-palette="dual"][data-pu-theme="dark"] {
339
+ --pu-color-bg: #04080f;
340
+ --pu-color-surface: #0a101c;
341
+ --pu-color-surface-2: #111a2a;
342
+ --pu-color-surface-elevated: #162033;
343
+ --pu-color-surface-sunken: #02050a;
344
+ --pu-color-border: color-mix(in srgb, #94a3b8 26%, transparent);
345
+ --pu-color-border-strong: color-mix(in srgb, #22d3ee 38%, #64748b);
346
+ --pu-color-control-border: color-mix(in srgb, #a5b4c8 40%, transparent);
347
+ --pu-color-text: #eef3fb;
348
+ --pu-color-text-muted: #a8b6c9;
349
+ /* Soft electric primary for dark CTAs — dark ink on bright cyan */
350
+ --pu-color-accent: #38bdf8;
351
+ --pu-color-accent-hover: #7dd3fc;
352
+ --pu-color-accent-fg: #041018;
353
+ --pu-color-signal: #8fd44f;
354
+ --pu-color-success: #8fd44f;
355
+ --pu-color-focus: #22d3ee;
356
+ --pu-color-selection: color-mix(in srgb, #22d3ee 26%, transparent);
357
+ --pu-color-danger: #fb7185;
358
+ --pu-color-danger-fg: #1a080c;
359
+ --pu-color-warning: #f0c14d;
360
+ --pu-color-warning-fg: #1a1408;
361
+
362
+ --pu-color-soft-bg: color-mix(in srgb, #22d3ee 18%, #0a101c);
363
+ --pu-color-soft-bg-hover: color-mix(in srgb, #22d3ee 26%, #0a101c);
364
+ --pu-color-soft-fg: #a5f3fc; /* bright cyan text on dark soft wash */
365
+ --pu-color-soft-border: color-mix(in srgb, #22d3ee 42%, transparent);
366
+
367
+ --pu-glass-bg: color-mix(in srgb, #0a101c 80%, transparent);
368
+ --pu-glass-border: color-mix(in srgb, #22d3ee 18%, transparent);
369
+ --pu-color-glow: color-mix(in srgb, #38bdf8 14%, transparent);
370
+ --pu-color-glow-2: color-mix(in srgb, #69be28 8%, transparent);
371
+ --pu-color-glow-holo: color-mix(in srgb, #22d3ee 12%, transparent);
372
+
373
+ --pu-shadow-float:
374
+ 0 0 0 1px color-mix(in srgb, #22d3ee 24%, transparent),
375
+ 0 0 36px color-mix(in srgb, #22d3ee 10%, transparent),
376
+ 0 16px 48px rgba(0, 0, 0, 0.55);
377
+ }