xertica-ui 2.1.2 → 2.1.4

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 (181) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +1 -1
  3. package/bin/cli.ts +1 -1
  4. package/bin/generate-tokens.ts +13 -7
  5. package/components/assistant/xertica-assistant/index.ts +2 -0
  6. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +97 -0
  7. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -0
  8. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -0
  9. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +86 -0
  10. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +77 -0
  11. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +573 -0
  12. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +65 -0
  13. package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -0
  14. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +98 -0
  15. package/components/assistant/xertica-assistant/parts/index.ts +16 -0
  16. package/components/assistant/xertica-assistant/types.ts +139 -0
  17. package/components/assistant/xertica-assistant/use-assistant.ts +559 -0
  18. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +200 -0
  19. package/components/assistant/xertica-assistant/xertica-assistant.tsx +198 -1460
  20. package/components/brand/theme-toggle/ThemeToggle.tsx +8 -27
  21. package/components/hooks/index.ts +3 -0
  22. package/components/hooks/use-layout-shortcuts.ts +46 -0
  23. package/components/layout/sidebar/index.ts +2 -0
  24. package/components/layout/sidebar/sidebar.stories.tsx +160 -8
  25. package/components/layout/sidebar/sidebar.tsx +606 -497
  26. package/components/layout/sidebar/use-sidebar.ts +104 -0
  27. package/components/media/audio-player/AudioPlayer.tsx +131 -206
  28. package/components/media/audio-player/use-audio-player.ts +298 -0
  29. package/components/pages/home-page/HomePage.tsx +1 -1
  30. package/components/pages/template-content/TemplateContent.tsx +5 -5
  31. package/components/pages/template-page/TemplatePage.tsx +5 -5
  32. package/components/shared/CustomTooltipContent.tsx +52 -0
  33. package/components/shared/layout-constants.ts +1 -1
  34. package/components/ui/chart/chart.stories.tsx +966 -7
  35. package/components/ui/chart/chart.tsx +918 -45
  36. package/components/ui/file-upload/file-upload.stories.tsx +100 -0
  37. package/components/ui/file-upload/file-upload.tsx +14 -74
  38. package/components/ui/file-upload/index.ts +1 -0
  39. package/components/ui/file-upload/use-file-upload.ts +181 -0
  40. package/components/ui/pagination/index.ts +2 -0
  41. package/components/ui/pagination/pagination.stories.tsx +94 -0
  42. package/components/ui/pagination/use-pagination.ts +194 -0
  43. package/components/ui/rich-text-editor/index.ts +2 -0
  44. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +129 -1
  45. package/components/ui/rich-text-editor/rich-text-editor.tsx +86 -305
  46. package/components/ui/rich-text-editor/use-rich-text-editor.ts +439 -0
  47. package/components/ui/stepper/index.ts +3 -1
  48. package/components/ui/stepper/stepper.stories.tsx +116 -0
  49. package/components/ui/stepper/stepper.tsx +4 -4
  50. package/components/ui/stepper/use-stepper.ts +137 -0
  51. package/components/ui/tree-view/index.ts +4 -1
  52. package/components/ui/tree-view/tree-view.stories.tsx +110 -4
  53. package/components/ui/tree-view/tree-view.tsx +17 -125
  54. package/components/ui/tree-view/use-tree-view.ts +229 -0
  55. package/contexts/AssistenteContext.tsx +17 -54
  56. package/contexts/BrandColorsContext.tsx +6 -17
  57. package/contexts/LayoutContext.tsx +5 -31
  58. package/dist/AssistantChart-BAudAfne.cjs +3591 -0
  59. package/dist/AssistantChart-BP8upjMk.js +3565 -0
  60. package/dist/AudioPlayer-1ypwE2Wh.cjs +936 -0
  61. package/dist/AudioPlayer-DuKXrCfy.js +937 -0
  62. package/dist/CustomTooltipContent-DHjkY0ww.js +40 -0
  63. package/dist/CustomTooltipContent-c_K-DWRr.cjs +56 -0
  64. package/dist/LanguageContext-BwhwC3G2.js +657 -0
  65. package/dist/LanguageContext-DvUt5jBg.cjs +656 -0
  66. package/dist/LayoutContext-BDmcZfMH.cjs +84 -0
  67. package/dist/LayoutContext-dbQvdC4O.js +85 -0
  68. package/dist/ThemeContext-RTy1m2Uq.js +82 -0
  69. package/dist/ThemeContext-bSzuOit2.cjs +81 -0
  70. package/dist/VerifyEmailPage-C_ihbcth.js +2828 -0
  71. package/dist/VerifyEmailPage-Dt7zgA4w.cjs +2827 -0
  72. package/dist/XerticaProvider-CW9hpCdF.cjs +39 -0
  73. package/dist/XerticaProvider-siSt9uG2.js +40 -0
  74. package/dist/XerticaXLogo-D8jf0SNv.cjs +214 -0
  75. package/dist/XerticaXLogo-fAJMy3H4.js +215 -0
  76. package/dist/assistant.cjs.js +2 -1
  77. package/dist/assistant.es.js +3 -2
  78. package/dist/brand.cjs.js +2 -2
  79. package/dist/brand.es.js +2 -2
  80. package/dist/cli.js +14 -8
  81. package/dist/components/assistant/xertica-assistant/index.d.ts +2 -0
  82. package/dist/components/assistant/xertica-assistant/parts/AssistantCollapsedView.d.ts +13 -0
  83. package/dist/components/assistant/xertica-assistant/parts/AssistantConversationList.d.ts +16 -0
  84. package/dist/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.d.ts +17 -0
  85. package/dist/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.d.ts +19 -0
  86. package/dist/components/assistant/xertica-assistant/parts/AssistantHeader.d.ts +11 -0
  87. package/dist/components/assistant/xertica-assistant/parts/AssistantMessageBubble.d.ts +29 -0
  88. package/dist/components/assistant/xertica-assistant/parts/AssistantTabBar.d.ts +13 -0
  89. package/dist/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.d.ts +4 -0
  90. package/dist/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.d.ts +17 -0
  91. package/dist/components/assistant/xertica-assistant/parts/index.d.ts +16 -0
  92. package/dist/components/assistant/xertica-assistant/types.d.ts +106 -0
  93. package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +125 -0
  94. package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +8 -97
  95. package/dist/components/hooks/index.d.ts +3 -0
  96. package/dist/components/hooks/use-layout-shortcuts.d.ts +22 -0
  97. package/dist/components/layout/sidebar/index.d.ts +2 -0
  98. package/dist/components/layout/sidebar/sidebar.d.ts +80 -0
  99. package/dist/components/layout/sidebar/use-sidebar.d.ts +22 -0
  100. package/dist/components/media/audio-player/AudioPlayer.d.ts +4 -1
  101. package/dist/components/media/audio-player/use-audio-player.d.ts +72 -0
  102. package/dist/components/shared/CustomTooltipContent.d.ts +20 -0
  103. package/dist/components/shared/layout-constants.d.ts +1 -1
  104. package/dist/components/ui/alert/alert.d.ts +1 -1
  105. package/dist/components/ui/badge/badge.d.ts +1 -1
  106. package/dist/components/ui/button/button.d.ts +2 -2
  107. package/dist/components/ui/chart/chart.d.ts +162 -5
  108. package/dist/components/ui/file-upload/file-upload.d.ts +2 -0
  109. package/dist/components/ui/file-upload/index.d.ts +1 -0
  110. package/dist/components/ui/file-upload/use-file-upload.d.ts +49 -0
  111. package/dist/components/ui/pagination/index.d.ts +2 -0
  112. package/dist/components/ui/pagination/use-pagination.d.ts +78 -0
  113. package/dist/components/ui/rich-text-editor/index.d.ts +2 -0
  114. package/dist/components/ui/rich-text-editor/use-rich-text-editor.d.ts +107 -0
  115. package/dist/components/ui/stepper/index.d.ts +3 -1
  116. package/dist/components/ui/stepper/stepper.d.ts +2 -2
  117. package/dist/components/ui/stepper/use-stepper.d.ts +60 -0
  118. package/dist/components/ui/tree-view/index.d.ts +4 -1
  119. package/dist/components/ui/tree-view/tree-view.d.ts +4 -6
  120. package/dist/components/ui/tree-view/use-tree-view.d.ts +60 -0
  121. package/dist/contexts/AssistenteContext.d.ts +10 -49
  122. package/dist/hooks.cjs.js +30 -10
  123. package/dist/hooks.es.js +25 -4
  124. package/dist/index.cjs.js +20 -9
  125. package/dist/index.es.js +38 -27
  126. package/dist/layout.cjs.js +82 -1
  127. package/dist/layout.es.js +83 -2
  128. package/dist/media.cjs.js +1 -1
  129. package/dist/media.es.js +1 -1
  130. package/dist/pages.cjs.js +1 -1
  131. package/dist/pages.es.js +1 -1
  132. package/dist/rich-text-editor-BmsjY03B.js +2949 -0
  133. package/dist/rich-text-editor-GS2kpTAK.cjs +2966 -0
  134. package/dist/sidebar-CVUGHOS_.cjs +756 -0
  135. package/dist/sidebar-CmvwjnVb.js +757 -0
  136. package/dist/ui.cjs.js +12 -2
  137. package/dist/ui.es.js +24 -14
  138. package/dist/use-audio-player-Bkh23vQ3.js +177 -0
  139. package/dist/use-audio-player-Dn1NR9xN.cjs +176 -0
  140. package/dist/utils/color-utils.d.ts +51 -0
  141. package/dist/xertica-assistant-BMqdyRVi.js +2082 -0
  142. package/dist/xertica-assistant-Bj3vBCq_.cjs +2081 -0
  143. package/dist/xertica-ui.css +1 -1
  144. package/docs/ai-usage.md +28 -10
  145. package/docs/architecture-improvements.md +463 -0
  146. package/docs/architecture.md +77 -1
  147. package/docs/components/assistant-chart.md +1 -1
  148. package/docs/components/assistant.md +159 -0
  149. package/docs/components/audio-player.md +46 -0
  150. package/docs/components/branding.md +251 -0
  151. package/docs/components/chart.md +354 -39
  152. package/docs/components/code-block.md +108 -0
  153. package/docs/components/file-upload.md +119 -2
  154. package/docs/components/formatted-document.md +113 -0
  155. package/docs/components/hooks.md +430 -0
  156. package/docs/components/image-with-fallback.md +106 -0
  157. package/docs/components/map-layers.md +140 -0
  158. package/docs/components/modern-chat-input.md +163 -0
  159. package/docs/components/pages.md +351 -0
  160. package/docs/components/pagination.md +187 -0
  161. package/docs/components/rich-text-editor.md +164 -0
  162. package/docs/components/sidebar.md +153 -4
  163. package/docs/components/stepper.md +157 -12
  164. package/docs/components/tree-view.md +164 -6
  165. package/docs/doc-audit.md +223 -0
  166. package/docs/getting-started.md +155 -1
  167. package/docs/guidelines.md +14 -8
  168. package/docs/layout.md +2 -2
  169. package/docs/llms.md +29 -9
  170. package/docs/patterns/detail-page.md +276 -0
  171. package/docs/patterns/settings.md +346 -0
  172. package/docs/patterns/wizard.md +217 -0
  173. package/guidelines/Guidelines.md +5 -3
  174. package/llms.txt +1 -1
  175. package/package.json +10 -10
  176. package/styles/xertica/tokens.css +41 -12
  177. package/templates/CLAUDE.md +16 -6
  178. package/templates/guidelines/Guidelines.md +16 -4
  179. package/templates/package.json +3 -3
  180. package/templates/src/styles/xertica/tokens.css +39 -10
  181. package/utils/color-utils.ts +72 -0
@@ -40,8 +40,8 @@
40
40
  --success-foreground: rgba(250, 250, 250, 1);
41
41
  --info: rgba(29, 78, 216, 1);
42
42
  --info-foreground: rgba(250, 250, 250, 1);
43
- --warning: rgba(180, 83, 9, 1);
44
- --warning-foreground: rgba(250, 250, 250, 1);
43
+ --warning: rgba(234, 179, 8, 1);
44
+ --warning-foreground: rgba(28, 25, 23, 1);
45
45
 
46
46
  --border: rgba(228, 228, 231, 1);
47
47
  --input: rgba(244, 244, 245, 0.5);
@@ -58,12 +58,23 @@
58
58
  --sidebar-border: rgba(65, 61, 107, 1);
59
59
  --sidebar-ring: rgba(161, 161, 170, 1);
60
60
 
61
- /* Charts */
62
- --chart-1: rgba(44, 39, 91, 1);
63
- --chart-2: rgba(4, 120, 87, 1);
64
- --chart-3: rgba(180, 83, 9, 1);
65
- --chart-4: rgba(29, 78, 216, 1);
66
- --chart-5: rgba(185, 28, 28, 1);
61
+ /* Charts — vibrant, accessible, harmonious palette */
62
+ --chart-1: rgba(99, 91, 255, 1);
63
+ /* indigo-violet brand-adjacent */
64
+ --chart-2: rgba(16, 185, 129, 1);
65
+ /* emerald success-adjacent */
66
+ --chart-3: rgba(245, 158, 11, 1);
67
+ /* amber — warm accent */
68
+ --chart-4: rgba(59, 130, 246, 1);
69
+ /* blue — info-adjacent */
70
+ --chart-5: rgba(239, 68, 68, 1);
71
+ /* red — destructive-adjacent */
72
+ --chart-6: rgba(168, 85, 247, 1);
73
+ /* purple — extended palette */
74
+ --chart-7: rgba(20, 184, 166, 1);
75
+ /* teal — extended palette */
76
+ --chart-8: rgba(251, 113, 133, 1);
77
+ /* rose — extended palette */
67
78
 
68
79
  /* Gradients */
69
80
  --gradient-diagonal: linear-gradient(135deg, #FDB0F2 0%, #72CDFD 100%);
@@ -116,9 +127,9 @@
116
127
  --toast-success-border: rgba(5, 150, 105, 1);
117
128
  --toast-success-icon: rgba(5, 150, 105, 1);
118
129
  /* Toast - Warning */
119
- --toast-warning-bg: rgba(254, 243, 199, 1);
120
- --toast-warning-border: rgba(180, 83, 9, 1);
121
- --toast-warning-icon: rgba(180, 83, 9, 1);
130
+ --toast-warning-bg: rgba(254, 249, 195, 1);
131
+ --toast-warning-border: rgba(161, 98, 7, 1);
132
+ --toast-warning-icon: rgba(161, 98, 7, 1);
122
133
  /* Toast - Info */
123
134
  --toast-info-bg: rgba(219, 234, 254, 1);
124
135
  --toast-info-border: rgba(37, 99, 235, 1);
@@ -176,6 +187,24 @@
176
187
 
177
188
  --elevation-sm: 0px 0px 48px 0px rgba(0, 0, 0, 0.3);
178
189
 
190
+ /* Charts — dark mode: slightly lighter/more saturated for contrast on dark bg */
191
+ --chart-1: rgba(129, 122, 255, 1);
192
+ /* indigo-violet lighter */
193
+ --chart-2: rgba(52, 211, 153, 1);
194
+ /* emerald lighter */
195
+ --chart-3: rgba(251, 191, 36, 1);
196
+ /* amber lighter */
197
+ --chart-4: rgba(96, 165, 250, 1);
198
+ /* blue lighter */
199
+ --chart-5: rgba(248, 113, 113, 1);
200
+ /* red lighter */
201
+ --chart-6: rgba(196, 132, 252, 1);
202
+ /* purple lighter */
203
+ --chart-7: rgba(45, 212, 191, 1);
204
+ /* teal lighter */
205
+ --chart-8: rgba(253, 164, 175, 1);
206
+ /* rose lighter */
207
+
179
208
  /* Sidebar */
180
209
  --sidebar-foreground: rgba(250, 250, 250, 1);
181
210
  --sidebar-primary: rgba(255, 255, 255, 1);
@@ -204,4 +233,4 @@
204
233
  --toast-error-bg: rgba(127, 29, 29, 1);
205
234
  --toast-error-border: rgba(248, 113, 113, 1);
206
235
  --toast-error-icon: rgba(248, 113, 113, 1);
207
- }
236
+ }
@@ -44,12 +44,21 @@ import { Home, Settings, Plus, Trash2, ChevronRight } from 'lucide-react';
44
44
  | `<div class="card ...">` | `<Card>` from `xertica-ui/ui` |
45
45
  | custom scrollbar div | `<ScrollArea>` from `xertica-ui/ui` |
46
46
 
47
- ### Colors — never use raw values
48
- | ❌ Never | ✅ Always |
47
+ ### Colors — context-dependent rules
48
+
49
+ | ❌ Never (any context) | Reason |
49
50
  |---|---|
50
- | `bg-blue-500`, `text-gray-700` | `bg-primary`, `text-muted-foreground` |
51
- | `#3b82f6`, `rgb(...)` | `var(--primary)` |
52
- | `rounded-lg`, `rounded-xl` | `rounded-[var(--radius)]` |
51
+ | `#3b82f6`, `rgb(59,130,246)`, `hsl(...)` | Raw values — non-themeable |
52
+ | `style={{ color: '#...' }}` for theming | Non-themeable inline style |
53
+
54
+ | ❌ Wrong for semantic/status contexts | ✅ Required instead |
55
+ |---|---|
56
+ | `bg-red-500` for error states | `bg-destructive` |
57
+ | `text-red-500` for error text | `text-destructive` |
58
+ | `bg-green-500` for success states | `bg-success` |
59
+ | `bg-yellow-500` for warnings | `bg-warning` |
60
+
61
+ > For **layout, spacing, and general non-semantic UI** (custom components, decorative elements, Storybook stories where no semantic token applies), standard Tailwind color utilities like `bg-blue-500` or `text-gray-700` are acceptable.
53
62
 
54
63
  Semantic token reference:
55
64
  ```
@@ -57,7 +66,8 @@ bg-background / text-foreground → page background and primary text
57
66
  bg-card / text-card-foreground → card surfaces
58
67
  bg-muted / text-muted-foreground → subdued areas and secondary text
59
68
  bg-primary / text-primary-foreground → primary actions
60
- bg-destructive → danger states
69
+ bg-destructive → danger / error states
70
+ bg-success / bg-warning / bg-info → semantic status states
61
71
  bg-accent → hover states
62
72
  border-border → standard borders
63
73
  border-input → form field borders
@@ -181,12 +181,23 @@ import { Home, Settings, Plus, Trash2, ChevronRight } from 'lucide-react';
181
181
  | `<div class="card ...">` | `<Card>` from `xertica-ui/ui` |
182
182
  | custom scrollable div | `<ScrollArea>` from `xertica-ui/ui` |
183
183
 
184
- ### Colors — never use raw values
184
+ ### Colors — context-dependent rules
185
+
186
+ | ❌ Never (any context) | Reason |
187
+ |---|---|
188
+ | `#3b82f6`, `rgb(59, 130, 246)`, `hsl(...)` | Raw values — non-themeable |
189
+ | `style={{ color: '#...' }}` for theming | Non-themeable inline style |
190
+
191
+ | ❌ Wrong for semantic/status contexts | ✅ Required instead |
192
+ |---|---|
193
+ | `bg-red-500` / `text-red-500` for errors | `bg-destructive` / `text-destructive` |
194
+ | `bg-green-500` for success states | `bg-success` |
195
+ | `bg-yellow-500` for warnings | `bg-warning` |
196
+
197
+ > For **layout, spacing, and general non-semantic UI** (custom components, decorative elements where no semantic token applies), standard Tailwind color utilities like `bg-blue-500` or `text-gray-700` are acceptable.
185
198
 
186
199
  | ❌ Never | ✅ Always |
187
200
  |---|---|
188
- | `bg-blue-500`, `text-gray-700` | `bg-primary`, `text-muted-foreground` |
189
- | `#3b82f6`, `rgb(59, 130, 246)` | `var(--primary)` |
190
201
  | `rounded-lg`, `rounded-xl` | `rounded-[var(--radius)]` |
191
202
 
192
203
  ### Layout state — never hardcode
@@ -305,7 +316,8 @@ Before completing any feature:
305
316
  - [ ] Route registered in `src/app/components/AuthGuard.tsx`
306
317
  - [ ] Home navigation card added (if primary module)
307
318
  - [ ] Only `xertica-ui` components used — no raw HTML elements
308
- - [ ] Only semantic tokens no raw colors or hardcoded radii
319
+ - [ ] No raw hex/rgb values — semantic tokens for semantic/status contexts; Tailwind utilities acceptable for non-semantic layout
320
+ - [ ] No hardcoded radii — use `rounded-[var(--radius)]`
309
321
  - [ ] Icons from `lucide-react` only
310
322
  - [ ] Destructive actions wrapped in `<AlertDialog>`
311
323
  - [ ] Layout state from `useLayout()` — no hardcoded widths
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xertica-ui-template",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -17,7 +17,7 @@
17
17
  "react-dom": "^18.3.1",
18
18
  "react-router-dom": "^7.1.3",
19
19
  "sonner": "^1.7.3",
20
- "xertica-ui": "^2.1.2"
20
+ "xertica-ui": "^2.1.4"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@eslint/js": "^9.18.0",
@@ -57,4 +57,4 @@
57
57
  "vite": "6.3.5"
58
58
  }
59
59
  }
60
- }
60
+ }
@@ -40,8 +40,8 @@
40
40
  --success-foreground: rgba(250, 250, 250, 1);
41
41
  --info: rgba(37, 99, 235, 1);
42
42
  --info-foreground: rgba(250, 250, 250, 1);
43
- --warning: rgba(245, 158, 11, 1);
44
- --warning-foreground: rgba(24, 24, 27, 1);
43
+ --warning: rgba(234, 179, 8, 1);
44
+ --warning-foreground: rgba(28, 25, 23, 1);
45
45
 
46
46
  --border: rgba(228, 228, 231, 1);
47
47
  --input: rgba(244, 244, 245, 0.5);
@@ -58,12 +58,23 @@
58
58
  --sidebar-border: rgba(65, 61, 107, 1);
59
59
  --sidebar-ring: rgba(161, 161, 170, 1);
60
60
 
61
- /* Charts */
62
- --chart-1: rgba(44, 39, 91, 1);
63
- --chart-2: rgba(5, 150, 105, 1);
61
+ /* Charts — vibrant, accessible, harmonious palette */
62
+ --chart-1: rgba(99, 91, 255, 1);
63
+ /* indigo-violet brand-adjacent */
64
+ --chart-2: rgba(16, 185, 129, 1);
65
+ /* emerald — success-adjacent */
64
66
  --chart-3: rgba(245, 158, 11, 1);
65
- --chart-4: rgba(37, 99, 235, 1);
67
+ /* amber warm accent */
68
+ --chart-4: rgba(59, 130, 246, 1);
69
+ /* blue — info-adjacent */
66
70
  --chart-5: rgba(239, 68, 68, 1);
71
+ /* red — destructive-adjacent */
72
+ --chart-6: rgba(168, 85, 247, 1);
73
+ /* purple — extended palette */
74
+ --chart-7: rgba(20, 184, 166, 1);
75
+ /* teal — extended palette */
76
+ --chart-8: rgba(251, 113, 133, 1);
77
+ /* rose — extended palette */
67
78
 
68
79
  /* Gradients */
69
80
  --gradient-diagonal: linear-gradient(135deg, #FDB0F2 0%, #72CDFD 100%);
@@ -116,9 +127,9 @@
116
127
  --toast-success-border: rgba(5, 150, 105, 1);
117
128
  --toast-success-icon: rgba(5, 150, 105, 1);
118
129
  /* Toast - Warning */
119
- --toast-warning-bg: rgba(254, 243, 199, 1);
120
- --toast-warning-border: rgba(245, 158, 11, 1);
121
- --toast-warning-icon: rgba(245, 158, 11, 1);
130
+ --toast-warning-bg: rgba(254, 249, 195, 1);
131
+ --toast-warning-border: rgba(161, 98, 7, 1);
132
+ --toast-warning-icon: rgba(161, 98, 7, 1);
122
133
  /* Toast - Info */
123
134
  --toast-info-bg: rgba(219, 234, 254, 1);
124
135
  --toast-info-border: rgba(37, 99, 235, 1);
@@ -176,6 +187,24 @@
176
187
 
177
188
  --elevation-sm: 0px 0px 48px 0px rgba(0, 0, 0, 0.3);
178
189
 
190
+ /* Charts — dark mode: slightly lighter/more saturated for contrast on dark bg */
191
+ --chart-1: rgba(129, 122, 255, 1);
192
+ /* indigo-violet lighter */
193
+ --chart-2: rgba(52, 211, 153, 1);
194
+ /* emerald lighter */
195
+ --chart-3: rgba(251, 191, 36, 1);
196
+ /* amber lighter */
197
+ --chart-4: rgba(96, 165, 250, 1);
198
+ /* blue lighter */
199
+ --chart-5: rgba(248, 113, 113, 1);
200
+ /* red lighter */
201
+ --chart-6: rgba(196, 132, 252, 1);
202
+ /* purple lighter */
203
+ --chart-7: rgba(45, 212, 191, 1);
204
+ /* teal lighter */
205
+ --chart-8: rgba(253, 164, 175, 1);
206
+ /* rose lighter */
207
+
179
208
  /* Sidebar */
180
209
  --sidebar-foreground: rgba(250, 250, 250, 1);
181
210
  --sidebar-primary: rgba(255, 255, 255, 1);
@@ -204,4 +233,4 @@
204
233
  --toast-error-bg: rgba(127, 29, 29, 1);
205
234
  --toast-error-border: rgba(248, 113, 113, 1);
206
235
  --toast-error-icon: rgba(248, 113, 113, 1);
207
- }
236
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Color utility functions shared across the project.
3
+ * Extracted from BrandColorsContext to allow reuse and isolated testing.
4
+ */
5
+
6
+ /**
7
+ * Converts a hex color string to its RGB components.
8
+ * @param hex - Hex color string (with or without leading `#`)
9
+ * @returns Object with `r`, `g`, `b` values (0–255), or `null` if invalid
10
+ *
11
+ * @example
12
+ * hexToRgb('#3b82f6') // { r: 59, g: 130, b: 246 }
13
+ * hexToRgb('3b82f6') // { r: 59, g: 130, b: 246 }
14
+ * hexToRgb('invalid') // null
15
+ */
16
+ export function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
17
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
18
+ return result
19
+ ? {
20
+ r: parseInt(result[1], 16),
21
+ g: parseInt(result[2], 16),
22
+ b: parseInt(result[3], 16),
23
+ }
24
+ : null;
25
+ }
26
+
27
+ /**
28
+ * Converts RGB components to an `rgba()` CSS string.
29
+ * @param r - Red (0–255)
30
+ * @param g - Green (0–255)
31
+ * @param b - Blue (0–255)
32
+ * @param alpha - Alpha (0–1), defaults to 1
33
+ *
34
+ * @example
35
+ * rgbToRgba(59, 130, 246, 0.5) // 'rgba(59, 130, 246, 0.5)'
36
+ */
37
+ export function rgbToRgba(r: number, g: number, b: number, alpha = 1): string {
38
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
39
+ }
40
+
41
+ /**
42
+ * Converts a hex color to an `rgba()` CSS string.
43
+ * Returns `null` if the hex is invalid.
44
+ *
45
+ * @example
46
+ * hexToRgba('#3b82f6', 0.15) // 'rgba(59, 130, 246, 0.15)'
47
+ */
48
+ export function hexToRgba(hex: string, alpha = 1): string | null {
49
+ const rgb = hexToRgb(hex);
50
+ if (!rgb) return null;
51
+ return rgbToRgba(rgb.r, rgb.g, rgb.b, alpha);
52
+ }
53
+
54
+ /**
55
+ * Determines whether a hex color is considered "light" based on its luminance.
56
+ * Uses the W3C relative luminance formula.
57
+ *
58
+ * @param hex - Hex color string
59
+ * @returns `true` if the color is light, `false` if dark
60
+ *
61
+ * @example
62
+ * isLightColor('#ffffff') // true
63
+ * isLightColor('#000000') // false
64
+ * isLightColor('#3b82f6') // false
65
+ */
66
+ export function isLightColor(hex: string): boolean {
67
+ const rgb = hexToRgb(hex);
68
+ if (!rgb) return true;
69
+ // W3C relative luminance
70
+ const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
71
+ return luminance > 0.5;
72
+ }