@luster-ui/ui 1.0.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 (176) hide show
  1. package/PUBLISHING.md +469 -0
  2. package/README.md +423 -0
  3. package/dist/cjs/index-Couc0LVo.js +1571 -0
  4. package/dist/cjs/index.cjs.js +2 -0
  5. package/dist/cjs/loader.cjs.js +12 -0
  6. package/dist/cjs/luster-accordion_19.cjs.entry.js +555 -0
  7. package/dist/cjs/luster-card.cjs.entry.js +25 -0
  8. package/dist/cjs/luster.cjs.js +24 -0
  9. package/dist/collection/collection-manifest.json +32 -0
  10. package/dist/collection/components/luster-accordion/luster-accordion.css +76 -0
  11. package/dist/collection/components/luster-accordion/luster-accordion.js +160 -0
  12. package/dist/collection/components/luster-accordion/luster-accordion.stories.js +88 -0
  13. package/dist/collection/components/luster-activity-item/luster-activity-item.css +102 -0
  14. package/dist/collection/components/luster-activity-item/luster-activity-item.js +188 -0
  15. package/dist/collection/components/luster-activity-item/luster-activity-item.stories.js +94 -0
  16. package/dist/collection/components/luster-alert/luster-alert.css +71 -0
  17. package/dist/collection/components/luster-alert/luster-alert.js +171 -0
  18. package/dist/collection/components/luster-alert/luster-alert.stories.js +82 -0
  19. package/dist/collection/components/luster-article-card/luster-article-card.css +120 -0
  20. package/dist/collection/components/luster-article-card/luster-article-card.js +192 -0
  21. package/dist/collection/components/luster-article-card/luster-article-card.stories.js +82 -0
  22. package/dist/collection/components/luster-badge/luster-badge.css +38 -0
  23. package/dist/collection/components/luster-badge/luster-badge.js +87 -0
  24. package/dist/collection/components/luster-badge/luster-badge.stories.js +86 -0
  25. package/dist/collection/components/luster-button/luster-button.css +121 -0
  26. package/dist/collection/components/luster-button/luster-button.js +179 -0
  27. package/dist/collection/components/luster-button/luster-button.stories.js +103 -0
  28. package/dist/collection/components/luster-card/luster-card.css +29 -0
  29. package/dist/collection/components/luster-card/luster-card.js +92 -0
  30. package/dist/collection/components/luster-card/luster-card.stories.js +67 -0
  31. package/dist/collection/components/luster-checkbox/luster-checkbox.css +42 -0
  32. package/dist/collection/components/luster-checkbox/luster-checkbox.js +162 -0
  33. package/dist/collection/components/luster-checkbox/luster-checkbox.stories.js +78 -0
  34. package/dist/collection/components/luster-color-swatch/luster-color-swatch.css +33 -0
  35. package/dist/collection/components/luster-color-swatch/luster-color-swatch.js +108 -0
  36. package/dist/collection/components/luster-color-swatch/luster-color-swatch.stories.js +58 -0
  37. package/dist/collection/components/luster-feature-quote/luster-feature-quote.css +84 -0
  38. package/dist/collection/components/luster-feature-quote/luster-feature-quote.js +108 -0
  39. package/dist/collection/components/luster-feature-quote/luster-feature-quote.stories.js +52 -0
  40. package/dist/collection/components/luster-hero/luster-hero.css +119 -0
  41. package/dist/collection/components/luster-hero/luster-hero.js +129 -0
  42. package/dist/collection/components/luster-hero/luster-hero.stories.js +72 -0
  43. package/dist/collection/components/luster-input/luster-input.css +72 -0
  44. package/dist/collection/components/luster-input/luster-input.js +332 -0
  45. package/dist/collection/components/luster-input/luster-input.stories.js +106 -0
  46. package/dist/collection/components/luster-modal/luster-modal.css +103 -0
  47. package/dist/collection/components/luster-modal/luster-modal.js +215 -0
  48. package/dist/collection/components/luster-modal/luster-modal.stories.js +78 -0
  49. package/dist/collection/components/luster-navbar/luster-navbar.css +151 -0
  50. package/dist/collection/components/luster-navbar/luster-navbar.js +87 -0
  51. package/dist/collection/components/luster-navbar/luster-navbar.stories.js +41 -0
  52. package/dist/collection/components/luster-profile-card/luster-profile-card.css +89 -0
  53. package/dist/collection/components/luster-profile-card/luster-profile-card.js +194 -0
  54. package/dist/collection/components/luster-profile-card/luster-profile-card.stories.js +56 -0
  55. package/dist/collection/components/luster-resource-table/luster-resource-table.css +141 -0
  56. package/dist/collection/components/luster-resource-table/luster-resource-table.js +78 -0
  57. package/dist/collection/components/luster-resource-table/luster-resource-table.stories.js +44 -0
  58. package/dist/collection/components/luster-sidebar/luster-sidebar.css +152 -0
  59. package/dist/collection/components/luster-sidebar/luster-sidebar.js +78 -0
  60. package/dist/collection/components/luster-sidebar/luster-sidebar.stories.js +34 -0
  61. package/dist/collection/components/luster-stat-card/luster-stat-card.css +82 -0
  62. package/dist/collection/components/luster-stat-card/luster-stat-card.js +194 -0
  63. package/dist/collection/components/luster-stat-card/luster-stat-card.stories.js +75 -0
  64. package/dist/collection/components/luster-tabs/luster-tabs.css +35 -0
  65. package/dist/collection/components/luster-tabs/luster-tabs.js +116 -0
  66. package/dist/collection/components/luster-tabs/luster-tabs.stories.js +56 -0
  67. package/dist/collection/components/luster-toggle/luster-toggle.css +48 -0
  68. package/dist/collection/components/luster-toggle/luster-toggle.js +120 -0
  69. package/dist/collection/components/luster-toggle/luster-toggle.stories.js +66 -0
  70. package/dist/components/index.d.ts +33 -0
  71. package/dist/components/index.js +1 -0
  72. package/dist/components/luster-accordion.d.ts +11 -0
  73. package/dist/components/luster-accordion.js +1 -0
  74. package/dist/components/luster-activity-item.d.ts +11 -0
  75. package/dist/components/luster-activity-item.js +1 -0
  76. package/dist/components/luster-alert.d.ts +11 -0
  77. package/dist/components/luster-alert.js +1 -0
  78. package/dist/components/luster-article-card.d.ts +11 -0
  79. package/dist/components/luster-article-card.js +1 -0
  80. package/dist/components/luster-badge.d.ts +11 -0
  81. package/dist/components/luster-badge.js +1 -0
  82. package/dist/components/luster-badge2.js +1 -0
  83. package/dist/components/luster-button.d.ts +11 -0
  84. package/dist/components/luster-button.js +1 -0
  85. package/dist/components/luster-button2.js +1 -0
  86. package/dist/components/luster-card.d.ts +11 -0
  87. package/dist/components/luster-card.js +1 -0
  88. package/dist/components/luster-checkbox.d.ts +11 -0
  89. package/dist/components/luster-checkbox.js +1 -0
  90. package/dist/components/luster-color-swatch.d.ts +11 -0
  91. package/dist/components/luster-color-swatch.js +1 -0
  92. package/dist/components/luster-feature-quote.d.ts +11 -0
  93. package/dist/components/luster-feature-quote.js +1 -0
  94. package/dist/components/luster-hero.d.ts +11 -0
  95. package/dist/components/luster-hero.js +1 -0
  96. package/dist/components/luster-input.d.ts +11 -0
  97. package/dist/components/luster-input.js +1 -0
  98. package/dist/components/luster-modal.d.ts +11 -0
  99. package/dist/components/luster-modal.js +1 -0
  100. package/dist/components/luster-navbar.d.ts +11 -0
  101. package/dist/components/luster-navbar.js +1 -0
  102. package/dist/components/luster-profile-card.d.ts +11 -0
  103. package/dist/components/luster-profile-card.js +1 -0
  104. package/dist/components/luster-resource-table.d.ts +11 -0
  105. package/dist/components/luster-resource-table.js +1 -0
  106. package/dist/components/luster-sidebar.d.ts +11 -0
  107. package/dist/components/luster-sidebar.js +1 -0
  108. package/dist/components/luster-stat-card.d.ts +11 -0
  109. package/dist/components/luster-stat-card.js +1 -0
  110. package/dist/components/luster-tabs.d.ts +11 -0
  111. package/dist/components/luster-tabs.js +1 -0
  112. package/dist/components/luster-toggle.d.ts +11 -0
  113. package/dist/components/luster-toggle.js +1 -0
  114. package/dist/components/luster-toggle2.js +1 -0
  115. package/dist/esm/index-CeYIN8dN.js +1563 -0
  116. package/dist/esm/index.js +1 -0
  117. package/dist/esm/loader.js +10 -0
  118. package/dist/esm/luster-accordion_19.entry.js +535 -0
  119. package/dist/esm/luster-card.entry.js +23 -0
  120. package/dist/esm/luster.js +20 -0
  121. package/dist/index.cjs.js +1 -0
  122. package/dist/index.js +1 -0
  123. package/dist/luster/index.esm.js +0 -0
  124. package/dist/luster/luster.css +313 -0
  125. package/dist/luster/luster.esm.js +1 -0
  126. package/dist/luster/p-3c4ce897.entry.js +1 -0
  127. package/dist/luster/p-CeYIN8dN.js +2 -0
  128. package/dist/luster/p-e368ec08.entry.js +1 -0
  129. package/dist/types/.stencil/luster-accordion/luster-accordion.d.ts +13 -0
  130. package/dist/types/.stencil/luster-accordion/luster-accordion.stories.d.ts +10 -0
  131. package/dist/types/.stencil/luster-activity-item/luster-activity-item.d.ts +11 -0
  132. package/dist/types/.stencil/luster-activity-item/luster-activity-item.stories.d.ts +9 -0
  133. package/dist/types/.stencil/luster-alert/luster-alert.d.ts +13 -0
  134. package/dist/types/.stencil/luster-alert/luster-alert.stories.d.ts +10 -0
  135. package/dist/types/.stencil/luster-article-card/luster-article-card.d.ts +11 -0
  136. package/dist/types/.stencil/luster-article-card/luster-article-card.stories.d.ts +8 -0
  137. package/dist/types/.stencil/luster-badge/luster-badge.d.ts +6 -0
  138. package/dist/types/.stencil/luster-badge/luster-badge.stories.d.ts +12 -0
  139. package/dist/types/.stencil/luster-button/luster-button.d.ts +12 -0
  140. package/dist/types/.stencil/luster-button/luster-button.stories.d.ts +13 -0
  141. package/dist/types/.stencil/luster-card/luster-card.d.ts +6 -0
  142. package/dist/types/.stencil/luster-card/luster-card.stories.d.ts +10 -0
  143. package/dist/types/.stencil/luster-checkbox/luster-checkbox.d.ts +13 -0
  144. package/dist/types/.stencil/luster-checkbox/luster-checkbox.stories.d.ts +10 -0
  145. package/dist/types/.stencil/luster-color-swatch/luster-color-swatch.d.ts +7 -0
  146. package/dist/types/.stencil/luster-color-swatch/luster-color-swatch.stories.d.ts +8 -0
  147. package/dist/types/.stencil/luster-feature-quote/luster-feature-quote.d.ts +7 -0
  148. package/dist/types/.stencil/luster-feature-quote/luster-feature-quote.stories.d.ts +8 -0
  149. package/dist/types/.stencil/luster-hero/luster-hero.d.ts +8 -0
  150. package/dist/types/.stencil/luster-hero/luster-hero.stories.d.ts +8 -0
  151. package/dist/types/.stencil/luster-input/luster-input.d.ts +25 -0
  152. package/dist/types/.stencil/luster-input/luster-input.stories.d.ts +9 -0
  153. package/dist/types/.stencil/luster-modal/luster-modal.d.ts +17 -0
  154. package/dist/types/.stencil/luster-modal/luster-modal.stories.d.ts +8 -0
  155. package/dist/types/.stencil/luster-navbar/luster-navbar.d.ts +6 -0
  156. package/dist/types/.stencil/luster-navbar/luster-navbar.stories.d.ts +6 -0
  157. package/dist/types/.stencil/luster-profile-card/luster-profile-card.d.ts +11 -0
  158. package/dist/types/.stencil/luster-profile-card/luster-profile-card.stories.d.ts +7 -0
  159. package/dist/types/.stencil/luster-resource-table/luster-resource-table.d.ts +14 -0
  160. package/dist/types/.stencil/luster-resource-table/luster-resource-table.stories.d.ts +6 -0
  161. package/dist/types/.stencil/luster-sidebar/luster-sidebar.d.ts +9 -0
  162. package/dist/types/.stencil/luster-sidebar/luster-sidebar.stories.d.ts +8 -0
  163. package/dist/types/.stencil/luster-stat-card/luster-stat-card.d.ts +11 -0
  164. package/dist/types/.stencil/luster-stat-card/luster-stat-card.stories.d.ts +8 -0
  165. package/dist/types/.stencil/luster-tabs/luster-tabs.d.ts +15 -0
  166. package/dist/types/.stencil/luster-tabs/luster-tabs.stories.d.ts +7 -0
  167. package/dist/types/.stencil/luster-toggle/luster-toggle.d.ts +11 -0
  168. package/dist/types/.stencil/luster-toggle/luster-toggle.stories.d.ts +9 -0
  169. package/dist/types/components.d.ts +1355 -0
  170. package/dist/types/stencil-public-runtime.d.ts +1860 -0
  171. package/loader/cdn.js +1 -0
  172. package/loader/index.cjs.js +1 -0
  173. package/loader/index.d.ts +24 -0
  174. package/loader/index.es2017.js +1 -0
  175. package/loader/index.js +2 -0
  176. package/package.json +73 -0
package/PUBLISHING.md ADDED
@@ -0,0 +1,469 @@
1
+ # Publishing & Integration Guide — @yvstudio/luster-ui
2
+
3
+ This guide covers how to build, publish to npm, and integrate `@yvstudio/luster-ui` in any project or framework.
4
+
5
+ ---
6
+
7
+ ## Table of contents
8
+
9
+ 1. [Install in another project](#2-install-in-another-project)
10
+ 2. [Vanilla HTML](#3-vanilla-html)
11
+ 3. [React](#4-react)
12
+ 4. [Vue 3](#5-vue-3)
13
+ 5. [Angular](#6-angular)
14
+ 6. [Theming — any color in 3 lines](#7-theming--any-color-in-3-lines)
15
+ 7. [Light / dark mode](#8-light--dark-mode)
16
+ 8. [All design tokens reference](#9-all-design-tokens-reference)
17
+
18
+
19
+ ---
20
+
21
+ ## 3. Vanilla HTML
22
+
23
+ ### From npm (bundler / Vite / Webpack)
24
+
25
+ ```html
26
+ <!DOCTYPE html>
27
+ <html lang="en">
28
+ <head>
29
+ <meta charset="UTF-8" />
30
+ <title>My App</title>
31
+ </head>
32
+ <body>
33
+
34
+ <luster-button variant="primary">Get started</luster-button>
35
+ <luster-input label="Email" placeholder="you@example.com"></luster-input>
36
+ <luster-badge variant="success" dot>Active</luster-badge>
37
+
38
+ <script type="module">
39
+ import { defineCustomElements } from '@yvstudio/luster-ui/loader';
40
+ defineCustomElements();
41
+ </script>
42
+ </body>
43
+ </html>
44
+ ```
45
+
46
+ ### From CDN (no install needed)
47
+
48
+ ```html
49
+ <script
50
+ type="module"
51
+ src="https://unpkg.com/@yvstudio/luster-ui/dist/luster/luster.esm.js">
52
+ </script>
53
+
54
+ <luster-button variant="primary">Hello from CDN</luster-button>
55
+ ```
56
+
57
+ ---
58
+
59
+ ## 4. React
60
+
61
+ ### Setup (`main.tsx` or `index.tsx`)
62
+
63
+ ```tsx
64
+ import { defineCustomElements } from '@yvstudio/luster-ui/loader';
65
+ defineCustomElements();
66
+ ```
67
+
68
+ ### Component usage
69
+
70
+ ```tsx
71
+ // src/pages/Home.tsx
72
+ export function Home() {
73
+ return (
74
+ <section>
75
+ <luster-hero
76
+ heading="Welcome"
77
+ subtitle="Built with Luster design system"
78
+ section="HOME"
79
+ />
80
+
81
+ <luster-button
82
+ variant="primary"
83
+ onClick={() => console.log('clicked')}
84
+ >
85
+ Launch
86
+ </luster-button>
87
+
88
+ <luster-alert
89
+ variant="success"
90
+ heading="Saved!"
91
+ message="Your changes were published."
92
+ />
93
+ </section>
94
+ );
95
+ }
96
+ ```
97
+
98
+ ### TypeScript — silence unknown element warnings
99
+
100
+ Create `src/luster.d.ts`:
101
+
102
+ ```ts
103
+ import type { JSX as LusterJSX } from '@yvstudio/luster-ui/dist/types/components';
104
+
105
+ type LusterElements = {
106
+ [K in keyof LusterJSX.IntrinsicElements]: LusterJSX.IntrinsicElements[K];
107
+ };
108
+
109
+ declare global {
110
+ namespace JSX {
111
+ interface IntrinsicElements extends LusterElements {}
112
+ }
113
+ }
114
+ ```
115
+
116
+ ### Listening to custom events
117
+
118
+ ```tsx
119
+ import { useRef, useEffect } from 'react';
120
+
121
+ function MyModal() {
122
+ const modalRef = useRef<HTMLElement>(null);
123
+
124
+ useEffect(() => {
125
+ const el = modalRef.current;
126
+ const handler = () => console.log('modal closed');
127
+ el?.addEventListener('dcClose', handler);
128
+ return () => el?.removeEventListener('dcClose', handler);
129
+ }, []);
130
+
131
+ return (
132
+ <luster-modal
133
+ ref={modalRef}
134
+ open
135
+ heading="Confirm"
136
+ subtitle="Are you sure?"
137
+ />
138
+ );
139
+ }
140
+ ```
141
+
142
+ ---
143
+
144
+ ## 5. Vue 3
145
+
146
+ ### Setup (`main.ts`)
147
+
148
+ ```ts
149
+ import { createApp } from 'vue';
150
+ import App from './App.vue';
151
+ import { defineCustomElements } from '@yvstudio/luster-ui/loader';
152
+
153
+ defineCustomElements();
154
+
155
+ createApp(App).mount('#app');
156
+ ```
157
+
158
+ ### Tell Vue to ignore custom elements (`vite.config.ts`)
159
+
160
+ ```ts
161
+ import { defineConfig } from 'vite';
162
+ import vue from '@vitejs/plugin-vue';
163
+
164
+ export default defineConfig({
165
+ plugins: [
166
+ vue({
167
+ template: {
168
+ compilerOptions: {
169
+ // treat every tag starting with "luster-" as a custom element
170
+ isCustomElement: (tag) => tag.startsWith('luster-'),
171
+ },
172
+ },
173
+ }),
174
+ ],
175
+ });
176
+ ```
177
+
178
+ ### Component usage
179
+
180
+ ```vue
181
+ <script setup lang="ts">
182
+ import { ref } from 'vue';
183
+ const email = ref('');
184
+ </script>
185
+
186
+ <template>
187
+ <div>
188
+ <luster-navbar logo-title="My App" logo-sub="PLATFORM" />
189
+
190
+ <luster-input
191
+ label="Email"
192
+ placeholder="you@example.com"
193
+ :value="email"
194
+ @dc-input="(e: CustomEvent) => email = e.detail"
195
+ />
196
+
197
+ <luster-button variant="primary" @dc-click="submit">
198
+ Subscribe
199
+ </luster-button>
200
+ </div>
201
+ </template>
202
+ ```
203
+
204
+ ---
205
+
206
+ ## 6. Angular
207
+
208
+ ### `app.module.ts`
209
+
210
+ ```ts
211
+ import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
212
+ import { BrowserModule } from '@angular/platform-browser';
213
+ import { AppComponent } from './app.component';
214
+ import { defineCustomElements } from '@yvstudio/luster-ui/loader';
215
+
216
+ defineCustomElements();
217
+
218
+ @NgModule({
219
+ declarations: [AppComponent],
220
+ imports: [BrowserModule],
221
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
222
+ bootstrap: [AppComponent],
223
+ })
224
+ export class AppModule {}
225
+ ```
226
+
227
+ ### Component usage
228
+
229
+ ```html
230
+ <!-- app.component.html -->
231
+ <luster-navbar logo-title="My App" active-link="dashboard"></luster-navbar>
232
+
233
+ <luster-stat-card
234
+ heading="Users"
235
+ description="Active this month"
236
+ version="v2.1"
237
+ status="active"
238
+ users="12.4k"
239
+ [hasToggle]="true"
240
+ [toggleOn]="true"
241
+ ></luster-stat-card>
242
+
243
+ <luster-button variant="primary" (dcClick)="onAction()">
244
+ Create report
245
+ </luster-button>
246
+ ```
247
+
248
+ ---
249
+
250
+ ## 7. Theming — any color in 3 lines
251
+
252
+ All hover tints, shadows, focus rings, glass effects, and gradients are computed via `color-mix()` from three tokens. Override them anywhere in your CSS:
253
+
254
+ ```css
255
+ /* your-app.css — applied AFTER importing @yvstudio/luster-ui */
256
+ :root {
257
+ --dc-primary: #f97316; /* your brand color */
258
+ --dc-primary-dim: #ea580c; /* darker shade for gradients & shadows */
259
+ --dc-on-primary: #ffffff; /* text color on primary buttons */
260
+ }
261
+ ```
262
+
263
+ ### Examples
264
+
265
+ #### Emerald brand
266
+
267
+ ```css
268
+ :root {
269
+ --dc-primary: #10b981;
270
+ --dc-primary-dim: #059669;
271
+ --dc-on-primary: #ffffff;
272
+ }
273
+ ```
274
+
275
+ #### Rose / pink brand
276
+
277
+ ```css
278
+ :root {
279
+ --dc-primary: #f43f5e;
280
+ --dc-primary-dim: #e11d48;
281
+ --dc-on-primary: #ffffff;
282
+ }
283
+ ```
284
+
285
+ #### Gold / amber brand
286
+
287
+ ```css
288
+ :root {
289
+ --dc-primary: #f59e0b;
290
+ --dc-primary-dim: #d97706;
291
+ --dc-on-primary: #1c1200; /* dark text — amber is a light color */
292
+ }
293
+ ```
294
+
295
+ #### Sky blue brand
296
+
297
+ ```css
298
+ :root {
299
+ --dc-primary: #0ea5e9;
300
+ --dc-primary-dim: #0284c7;
301
+ --dc-on-primary: #ffffff;
302
+ }
303
+ ```
304
+
305
+ ### Scoped theming (per section / component)
306
+
307
+ You can scope a brand to a specific section of the page without affecting everything else:
308
+
309
+ ```css
310
+ .sidebar {
311
+ --dc-primary: #10b981;
312
+ --dc-primary-dim: #059669;
313
+ --dc-on-primary: #ffffff;
314
+ }
315
+ ```
316
+
317
+ ### Full surface override (custom dark shade)
318
+
319
+ ```css
320
+ :root {
321
+ --dc-primary: #f97316;
322
+ --dc-primary-dim: #ea580c;
323
+ --dc-on-primary: #ffffff;
324
+
325
+ /* Custom dark background instead of navy */
326
+ --dc-surface: #1a0500;
327
+ --dc-surface-container-low: #2a0d00;
328
+ --dc-surface-container: #331000;
329
+ --dc-surface-container-high: #3d1400;
330
+ --dc-surface-container-highest:#471800;
331
+ --dc-surface-bright: #5c2000;
332
+ }
333
+ ```
334
+
335
+ ---
336
+
337
+ ## 8. Light / dark mode
338
+
339
+ ### Via JavaScript (manual toggle)
340
+
341
+ ```js
342
+ const root = document.documentElement;
343
+
344
+ function setTheme(theme) {
345
+ root.setAttribute('data-theme', theme);
346
+ localStorage.setItem('theme', theme);
347
+ }
348
+
349
+ function toggleTheme() {
350
+ setTheme(root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
351
+ }
352
+
353
+ // Restore saved preference on load
354
+ const saved = localStorage.getItem('theme');
355
+ if (saved) setTheme(saved);
356
+ ```
357
+
358
+ ### Via OS preference (automatic — no JS needed)
359
+
360
+ Just import `@yvstudio/luster-ui` — it uses `@media (prefers-color-scheme: light)` out of the box. No configuration required.
361
+
362
+ ### In React with a hook
363
+
364
+ ```tsx
365
+ import { useEffect, useState } from 'react';
366
+
367
+ function useTheme() {
368
+ const [theme, setTheme] = useState<'dark' | 'light'>(() => {
369
+ return (localStorage.getItem('theme') as 'dark' | 'light') ?? 'dark';
370
+ });
371
+
372
+ useEffect(() => {
373
+ document.documentElement.setAttribute('data-theme', theme);
374
+ localStorage.setItem('theme', theme);
375
+ }, [theme]);
376
+
377
+ return { theme, toggle: () => setTheme(t => t === 'dark' ? 'light' : 'dark') };
378
+ }
379
+
380
+ // Usage
381
+ function ThemeToggle() {
382
+ const { theme, toggle } = useTheme();
383
+ return (
384
+ <luster-button variant="secondary" onClick={toggle}>
385
+ Switch to {theme === 'dark' ? 'Light' : 'Dark'}
386
+ </luster-button>
387
+ );
388
+ }
389
+ ```
390
+
391
+ ### In Vue with a composable
392
+
393
+ ```ts
394
+ // composables/useTheme.ts
395
+ import { ref, watchEffect } from 'vue';
396
+
397
+ export function useTheme() {
398
+ const theme = ref<'dark' | 'light'>(
399
+ (localStorage.getItem('theme') as 'dark' | 'light') ?? 'dark'
400
+ );
401
+
402
+ watchEffect(() => {
403
+ document.documentElement.setAttribute('data-theme', theme.value);
404
+ localStorage.setItem('theme', theme.value);
405
+ });
406
+
407
+ const toggle = () => {
408
+ theme.value = theme.value === 'dark' ? 'light' : 'dark';
409
+ };
410
+
411
+ return { theme, toggle };
412
+ }
413
+ ```
414
+
415
+ ---
416
+
417
+ ## 9. All design tokens reference
418
+
419
+ ### Override levels
420
+
421
+ | Level | How | Scope |
422
+ |---|---|---|
423
+ | Global rebrand | `:root { --dc-primary: ... }` | Entire app |
424
+ | Per section | `.sidebar { --dc-primary: ... }` | Section only |
425
+ | Per instance | `style="--dc-primary: ..."` on the element | One element |
426
+
427
+ ### Core brand tokens (most commonly overridden)
428
+
429
+ | Token | Dark default | Light default | Purpose |
430
+ |---|---|---|---|
431
+ | `--dc-primary` | `#a3a6ff` | `#4547ce` | Brand color — buttons, links, accents |
432
+ | `--dc-primary-dim` | `#6063ee` | `#3234b0` | Darker variant — gradients, shadows |
433
+ | `--dc-on-primary` | `#0a0040` | `#ffffff` | Text/icon on primary bg |
434
+
435
+ ### Surface tokens
436
+
437
+ | Token | Dark | Light |
438
+ |---|---|---|
439
+ | `--dc-surface` | `#060e20` | `#f5f7ff` |
440
+ | `--dc-surface-container-low` | `#091328` | `#eef0ff` |
441
+ | `--dc-surface-container-high` | `#141f38` | `#e0e3ff` |
442
+ | `--dc-on-surface` | `#dee5ff` | `#0d0f2d` |
443
+ | `--dc-on-surface-variant` | `#a3aac4` | `#3f4263` |
444
+
445
+ ### Semantic tokens
446
+
447
+ | Token | Dark | Light | Purpose |
448
+ |---|---|---|---|
449
+ | `--dc-error` | `#ffb4ab` | `#ba1a1a` | Destructive actions, error states |
450
+ | `--dc-success` | `#4cceac` | `#006c4c` | Success feedback |
451
+ | `--dc-warning` | `#ffd166` | `#7c5700` | Warning / caution |
452
+
453
+ ### Derived tokens (auto-computed — override only if needed)
454
+
455
+ These are computed via `color-mix()` and update automatically when you change the base tokens. You can still override them for fine-grained control.
456
+
457
+ | Token | Derived from | Use |
458
+ |---|---|---|
459
+ | `--dc-hover-tint` | `--dc-primary` @ 4% | Row/item hover |
460
+ | `--dc-hover-tint-strong` | `--dc-primary` @ 8% | Button hover fill |
461
+ | `--dc-icon-bg` | `--dc-primary` @ 10% | Icon backgrounds |
462
+ | `--dc-focus-ring` | `--dc-primary` @ 12% | Input/button focus |
463
+ | `--dc-border-faint` | `--dc-border-source` @ 20% | Subtle separators |
464
+ | `--dc-border-default` | `--dc-border-source` @ 30% | Card/modal borders |
465
+ | `--dc-glass-nav` | `--dc-surface-bright` @ 65% | Navbar blur effect |
466
+ | `--dc-overlay-modal` | `--dc-surface` @ 80% | Modal backdrop |
467
+ | `--dc-shadow-md` | `--dc-primary-dim` @ 12% | Card elevation |
468
+ | `--dc-error-border` | `--dc-error` @ 30% | Destructive button border |
469
+ | `--dc-error-bg` | `--dc-error` @ 10% | Destructive button hover |