@ojiepermana/angular-theme 22.0.35 → 22.0.41

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 (64) hide show
  1. package/README.md +54 -22
  2. package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +74 -20
  3. package/fesm2022/ojiepermana-angular-theme-layout.mjs +14 -2
  4. package/fesm2022/ojiepermana-angular-theme-page.mjs +251 -101
  5. package/fesm2022/ojiepermana-angular-theme-styles.mjs +375 -53
  6. package/layout/README.md +21 -19
  7. package/package.json +3 -3
  8. package/page/README.md +53 -15
  9. package/styles/README.md +18 -3
  10. package/styles/css/{seasonal/base → base}/tailwind.css +9 -5
  11. package/styles/css/{seasonal/base → base}/theme.css +27 -52
  12. package/styles/css/{seasonal/base → base}/tokens.css +62 -44
  13. package/styles/css/color/amber.css +52 -0
  14. package/styles/css/color/blue.css +52 -0
  15. package/styles/css/color/brand.css +16 -0
  16. package/styles/css/color/cyan.css +52 -0
  17. package/styles/css/color/emerald.css +52 -0
  18. package/styles/css/color/fuchsia.css +52 -0
  19. package/styles/css/color/green.css +52 -0
  20. package/styles/css/color/index.css +19 -0
  21. package/styles/css/color/indigo.css +52 -0
  22. package/styles/css/color/lime.css +52 -0
  23. package/styles/css/color/orange.css +52 -0
  24. package/styles/css/color/pink.css +52 -0
  25. package/styles/css/color/purple.css +52 -0
  26. package/styles/css/color/red.css +52 -0
  27. package/styles/css/color/rose.css +52 -0
  28. package/styles/css/color/sky.css +52 -0
  29. package/styles/css/color/teal.css +52 -0
  30. package/styles/css/color/violet.css +52 -0
  31. package/styles/css/color/yellow.css +52 -0
  32. package/styles/css/index.css +15 -6
  33. package/styles/css/neutral/gray.css +36 -0
  34. package/styles/css/neutral/index.css +11 -0
  35. package/styles/css/neutral/mauve.css +36 -0
  36. package/styles/css/neutral/mist.css +36 -0
  37. package/styles/css/neutral/neutral.css +36 -0
  38. package/styles/css/neutral/olive.css +36 -0
  39. package/styles/css/neutral/slate.css +36 -0
  40. package/styles/css/neutral/stone.css +36 -0
  41. package/styles/css/neutral/taupe.css +36 -0
  42. package/styles/css/neutral/zinc.css +36 -0
  43. package/styles/css/radius/index.css +29 -0
  44. package/styles/css/space/index.css +24 -0
  45. package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +43 -10
  46. package/types/ojiepermana-angular-theme-layout.d.ts +1 -0
  47. package/types/ojiepermana-angular-theme-page.d.ts +88 -36
  48. package/types/ojiepermana-angular-theme-styles.d.ts +169 -37
  49. package/styles/css/seasonal/ied/package.css +0 -4
  50. package/styles/css/seasonal/ied/theme.css +0 -78
  51. package/styles/css/seasonal/imlek/components.css +0 -87
  52. package/styles/css/seasonal/imlek/package.css +0 -6
  53. package/styles/css/seasonal/imlek/tailwind.css +0 -144
  54. package/styles/css/seasonal/imlek/theme.css +0 -95
  55. package/styles/css/seasonal/imlek/tokens.css +0 -152
  56. package/styles/css/seasonal/index.css +0 -6
  57. package/styles/css/seasonal/natal/package.css +0 -4
  58. package/styles/css/seasonal/natal/theme.css +0 -78
  59. package/styles/css/seasonal/new-year/package.css +0 -4
  60. package/styles/css/seasonal/new-year/theme.css +0 -78
  61. package/styles/css/seasonal/ramadhan/package.css +0 -4
  62. package/styles/css/seasonal/ramadhan/theme.css +0 -78
  63. /package/styles/css/{seasonal/base → base}/components.css +0 -0
  64. /package/styles/css/{seasonal/base → base}/package.css +0 -0
package/page/README.md CHANGED
@@ -21,22 +21,48 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
21
21
 
22
22
  ### `Page`
23
23
 
24
- | Input | Type | Default | Keterangan |
25
- | ----------- | ----------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------- |
26
- | `variant` | `'stacked' \| 'side'` | `'stacked'` | Menentukan struktur utama page shell. |
27
- | `scroll` | `'content' \| 'Page'` | `'content'` | Menentukan apakah body slot scroll sendiri atau seluruh root `Page` scroll bersama. |
28
- | `height` | `'auto' \| 'fix'` | `'auto'` | Mengontrol tinggi `PageHeader` dan `PageFooter`. |
29
- | `position` | `'left' \| 'right'` | `'left'` | Posisi default untuk `PageSide` jika side tidak memberi override sendiri. |
30
- | `sideMode` | `'sticky' \| 'drawer' \| 'overlay'` | `'sticky'` | Mode default untuk `PageSide` jika side tidak memberi override sendiri. |
31
- | `sideWidth` | `string` | `'16rem'` | Lebar default side rail; dipakai juga untuk drawer dan overlay. |
32
- | `sideOpen` | `boolean \| null` | `null` | Saat `null`, state side tidak dikontrol dari parent. Saat `true/false`, komponen masuk controlled mode. |
33
- | `class` | `string` | `''` | Class tambahan pada host `Page`. |
24
+ | Input | Type | Default | Keterangan |
25
+ | ------------ | ----------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------- |
26
+ | `variant` | `'stacked' \| 'side'` | `'stacked'` | Menentukan struktur utama page shell. |
27
+ | `scroll` | `'content' \| 'page'` | `'content'` | Menentukan apakah body slot scroll sendiri atau seluruh root `Page` scroll bersama. |
28
+ | `height` | `'auto' \| 'fix'` | `'auto'` | Mengontrol tinggi `PageHeader` dan `PageFooter`. |
29
+ | `appearance` | `'flat' \| 'border-rail'` | `'flat'` | Appearance visual yang dibagi dengan layout/navigation; menyeragamkan border header/footer (`border-rail` = 1.5px). |
30
+ | `position` | `'left' \| 'right'` | `'left'` | Posisi default untuk `PageSide` jika side tidak memberi override sendiri. |
31
+ | `sideMode` | `'sticky' \| 'drawer' \| 'overlay'` | `'sticky'` | Mode default untuk `PageSide` jika side tidak memberi override sendiri. |
32
+ | `sideWidth` | `string` | `'16rem'` | Lebar default side rail; dipakai juga untuk drawer dan overlay. |
33
+ | `sideOpen` | `boolean \| null` | `null` | Saat `null`, state side tidak dikontrol dari parent. Saat `true/false`, komponen masuk controlled mode. |
34
+ | `class` | `string` | `''` | Class tambahan pada host `Page`. |
34
35
 
35
36
  | Output | Payload | Keterangan |
36
37
  | ---------------- | --------- | -------------------------------------------------------------------------------------------- |
37
38
  | `sideOpenChange` | `boolean` | Emit setiap ada permintaan buka/tutup side, baik dari toggle, backdrop, maupun tombol `Esc`. |
38
39
 
39
- `Page` juga menambahkan atribut host `data-page-variant`, `data-page-height`, `data-page-scroll`, `data-page-position`, `data-page-side-mode`, dan `data-page-side-open` untuk styling atau inspeksi.
40
+ `Page` juga menambahkan atribut host `data-page-variant`, `data-page-height`, `data-page-scroll`, `data-page-appearance`, `data-page-position`, `data-page-side-mode`, dan `data-page-side-open` untuk styling atau inspeksi.
41
+
42
+ ### Apps launcher (layout `empty`)
43
+
44
+ Saat `Page` dirender di dalam layout `empty`, sebuah tombol icon-only tanpa border (ikon `apps`) muncul **otomatis** di pojok kanan-atas dan membuka **main navigation** (`id="main"`) sebagai flyout. Penempatannya menyesuaikan struktur `Page`:
45
+
46
+ - Ada `PageHeader` → tombol menyatu di kanan header.
47
+ - Tanpa `PageHeader` (mis. hanya `PageDashboard`) → tombol mengambang di atas konten.
48
+
49
+ Tombol hanya muncul ketika layout aktif `empty` dan nav target punya data. Di layout lain (`vertical`/`horizontal`/`fluid`) tombol tidak dirender karena navigasi utama sudah terlihat.
50
+
51
+ | Input | Type | Default | Keterangan |
52
+ | -------------- | --------- | ------------------- | ------------------------------------------------------------ |
53
+ | `appsLauncher` | `boolean` | `true` | Aktif/nonaktifkan apps-launcher pada layout `empty`. |
54
+ | `appsNavId` | `string` | `'main'` | Id navigasi yang disurface oleh apps-launcher. |
55
+ | `appsIcon` | `string` | `'apps'` | Nama ikon Material untuk tombol. |
56
+ | `appsLabel` | `string` | `'Open navigation'` | Label/aria-label tombol icon-only (untuk aksesibilitas AXE). |
57
+
58
+ ```html
59
+ <!-- Dashboard tanpa header: tombol apps mengambang di kanan-atas saat layout empty. -->
60
+ <Page variant="stacked">
61
+ <PageDashboard>
62
+ <p>Konten dashboard.</p>
63
+ </PageDashboard>
64
+ </Page>
65
+ ```
40
66
 
41
67
  ## Slot API
42
68
 
@@ -63,7 +89,7 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
63
89
 
64
90
  | Input / Output | Type | Default | Keterangan |
65
91
  | -------------- | --------- | -------------------- | ----------------------------------------------------------- |
66
- | `ariaLabel` | `string` | `'Toggle Page side'` | Label aksesibilitas untuk tombol toggle. |
92
+ | `ariaLabel` | `string` | `'Toggle page side'` | Label aksesibilitas untuk tombol toggle. |
67
93
  | `class` | `string` | `''` | Class tambahan pada host toggle. |
68
94
  | `toggled` | `boolean` | - | Emit nilai open state terbaru setelah tombol toggle diklik. |
69
95
 
@@ -75,7 +101,7 @@ Dokumentasi ini mengikuti API publik terbaru dari `@ojiepermana/angular-theme/pa
75
101
  ## Scroll Modes
76
102
 
77
103
  - `content` (default): `PageContent` atau `PageDashboard` menjadi area scroll. Pada variant `side`, `PageSide` dan body slot yang dipakai sama-sama stretch ke parent dan masing-masing punya scroll sendiri.
78
- - `Page`: seluruh isi `Page` menjadi area scroll. Header, content, footer, dan pada variant `side` juga `PageSide` akan mengikuti tinggi content induk tanpa scroll internal.
104
+ - `page`: seluruh isi `Page` menjadi area scroll. Header, content, footer, dan pada variant `side` juga `PageSide` akan mengikuti tinggi content induk tanpa scroll internal.
79
105
 
80
106
  ## Height Modes
81
107
 
@@ -86,7 +112,7 @@ Dalam mode `fix`, pastikan isi header/footer memang dirancang sebagai rail ringk
86
112
 
87
113
  ## Behavior Summary
88
114
 
89
- | Variant | `scroll="content"` | `scroll="Page"` |
115
+ | Variant | `scroll="content"` | `scroll="page"` |
90
116
  | --------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
91
117
  | `stacked` | `PageContent` atau `PageDashboard` stretch ke tinggi yang tersedia dan menjadi area scroll | seluruh `Page` scroll bersama; header, content, footer ikut satu kanvas |
92
118
  | `side` | `PageSide` dan body slot (`PageContent`/`PageDashboard`) sama-sama stretch ke parent dan punya scroll sendiri | `PageSide` dan body slot mengikuti tinggi content induk tanpa scroll internal |
@@ -126,6 +152,18 @@ Saat memakai `height="fix"`, slot berikut tidak boleh melebihi tinggi tetap yang
126
152
 
127
153
  ### Stacked dashboard surface
128
154
 
155
+ `PageDashboard` berdiri sendiri — tidak memerlukan `PageHeader` maupun `PageFooter`. Gunakan slot ini ketika area utama secara semantik adalah dashboard atau board analitik.
156
+
157
+ ```html
158
+ <Page variant="stacked">
159
+ <PageDashboard>
160
+ <p>Gunakan slot ini ketika area utama secara semantik adalah dashboard atau board analitik.</p>
161
+ </PageDashboard>
162
+ </Page>
163
+ ```
164
+
165
+ `PageHeader` dan `PageFooter` tetap opsional bila memang dibutuhkan:
166
+
129
167
  ```html
130
168
  <Page variant="stacked">
131
169
  <PageHeader>
@@ -133,7 +171,7 @@ Saat memakai `height="fix"`, slot berikut tidak boleh melebihi tinggi tetap yang
133
171
  </PageHeader>
134
172
 
135
173
  <PageDashboard>
136
- <p>Gunakan slot ini ketika area utama secara semantik adalah dashboard atau board analitik.</p>
174
+ <p>Dashboard dengan header dan footer eksplisit.</p>
137
175
  </PageDashboard>
138
176
 
139
177
  <PageFooter>
package/styles/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Theme
2
2
 
3
- `@ojiepermana/angular-theme/styles` menyediakan provider untuk mode, season, dan preload aset tema global.
3
+ `@ojiepermana/angular-theme/styles` menyediakan provider untuk mode, warna (accent +
4
+ neutral, gaya FluxUI), brand color, dan preload aset tema global.
4
5
 
5
6
  ```ts
6
7
  import { provideUiTheme } from '@ojiepermana/angular-theme/styles';
@@ -9,7 +10,11 @@ export const appConfig = {
9
10
  providers: [
10
11
  provideUiTheme({
11
12
  mode: 'light',
12
- season: 'base',
13
+ color: 'base', // accent: base, red…rose, brand
14
+ neutral: 'base', // gray family: base, slate, gray, zinc, …
15
+ radius: 'md', // corner radius: none, sm, md, lg, xl, full
16
+ space: 'normal', // spacing density: compact, normal, relaxed, spacious
17
+ brand: '221 83% 53%', // warna brand consumer (HSL triplet, atau { color, foreground })
13
18
  }),
14
19
  ],
15
20
  };
@@ -18,8 +23,18 @@ export const appConfig = {
18
23
  ## API Notes
19
24
 
20
25
  - `mode` mem-bootstrap `ThemeModeService` dan default mode yang disimpan di storage.
21
- - `season` mem-bootstrap `ThemeSeasonService` dan default season yang disimpan di storage.
26
+ - `color` mem-bootstrap `ThemeColorService`; accent palette awal (`<html theme-color>`).
27
+ - `neutral` keluarga neutral awal (`<html theme-neutral>`); berkomposisi dengan accent.
28
+ - `radius` mem-bootstrap `ThemeRadiusService`; preset corner radius awal (`<html theme-radius>`).
29
+ Menggerakkan knob `--radius-base` sehingga seluruh skala `--radius-*` dan utility `rounded-*` ikut.
30
+ - `space` mem-bootstrap `ThemeSpaceService`; preset spacing density awal (`<html theme-space>`).
31
+ Menggerakkan knob `--spacing-base` sehingga setiap utility `p-*`/`m-*`/`gap-*`/`w-*`/`h-*` ikut.
32
+ - `brand` mem-bootstrap `ThemeBrandService`; set `--brand` / utility `bg-brand` dan preset
33
+ accent `theme-color='brand'`. Menerima string HSL triplet atau `{ color, foreground }`.
34
+ Bisa diubah runtime via `setBrand()`, persist di storage.
22
35
  - `icons.materialSymbols` mengontrol preload stylesheet Material Symbols pada bootstrap aplikasi.
36
+ - Pilihan yang dipersist (`theme-color` / `theme-neutral` / `theme-radius` / `theme-space` /
37
+ `theme-brand`) menang atas default.
23
38
 
24
39
  ## Default Behavior
25
40
 
@@ -6,7 +6,7 @@
6
6
  * Usage (styles.css):
7
7
  * @import '@ojiepermana/angular-theme/theme.css';
8
8
  * @import 'tailwindcss';
9
- * @import '@ojiepermana/angular-theme/styles/css/seasonal/base/tailwind.css';
9
+ * @import '@ojiepermana/angular-theme/styles/css/base/tailwind.css';
10
10
  *
11
11
  * Maps the 3-layer HSL CSS variables onto Tailwind v4 design tokens so
12
12
  * utilities like `bg-primary`, `text-foreground`, `rounded-md`, and
@@ -27,6 +27,9 @@
27
27
  --color-primary: hsl(var(--primary));
28
28
  --color-primary-foreground: hsl(var(--primary-foreground));
29
29
 
30
+ --color-brand: hsl(var(--brand));
31
+ --color-brand-foreground: hsl(var(--brand-foreground));
32
+
30
33
  --color-secondary: hsl(var(--secondary));
31
34
  --color-secondary-foreground: hsl(var(--secondary-foreground));
32
35
 
@@ -123,6 +126,11 @@
123
126
  --leading-relaxed: var(--line-height-relaxed);
124
127
  --leading-loose: var(--line-height-loose);
125
128
 
129
+ /* Global spacing unit — Tailwind derives every padding, margin, gap, width and
130
+ * height utility from this. Wired to --spacing-base so the theme-space density
131
+ * axis rescales all spacing at runtime (default 0.25rem = unchanged). */
132
+ --spacing: var(--spacing-base);
133
+
126
134
  --spacing-control-xs: var(--control-height-xs);
127
135
  --spacing-control-sm: var(--control-height-sm);
128
136
  --spacing-control-md: var(--control-height-md);
@@ -138,7 +146,3 @@
138
146
  --font-sans: var(--theme-font-sans);
139
147
  --font-mono: var(--theme-font-mono);
140
148
  }
141
-
142
- @utility rounded-base {
143
- border-radius: var(--rounded-base);
144
- }
@@ -5,9 +5,8 @@
5
5
 
6
6
  @layer tokens {
7
7
  :root {
8
- --radius-base: var(--theme-radius-base, 0.625rem);
8
+ --radius-base: 0.625rem;
9
9
  --radius-none: 0px;
10
- --rounded-base: var(--radius-none);
11
10
  --scrollbar-size: 0.5rem;
12
11
  --scrollbar-radius: 9999px;
13
12
  --scrollbar-track: var(--primary) / var(--opacity-10);
@@ -20,7 +19,7 @@
20
19
 
21
20
  --border-width-base: 1px;
22
21
 
23
- --shadow-base: 0 1px 2px hsl(240 10% 3.9% / 0.08);
22
+ --shadow-base: 0 1px 2px hsl(0 0% 3.9% / 0.08);
24
23
 
25
24
  --duration-base: 200ms;
26
25
  --ease-base: cubic-bezier(0.4, 0, 0.2, 1);
@@ -83,10 +82,10 @@
83
82
  * re-emitted by the Tailwind @theme mapping as var(--theme-shadow-*) in the
84
83
  * later `theme` layer, so pointing either alias back at --shadow-* would
85
84
  * create a var() cycle that invalidates the whole chain. */
86
- --shadow-xs-base: 0 1px 1px hsl(240 10% 3.9% / 0.05);
87
- --shadow-md-base: 0 4px 6px hsl(240 10% 3.9% / 0.08);
88
- --shadow-lg-base: 0 10px 15px hsl(240 10% 3.9% / 0.1);
89
- --shadow-xl-base: 0 20px 25px hsl(240 10% 3.9% / 0.12);
85
+ --shadow-xs-base: 0 1px 1px hsl(0 0% 3.9% / 0.05);
86
+ --shadow-md-base: 0 4px 6px hsl(0 0% 3.9% / 0.08);
87
+ --shadow-lg-base: 0 10px 15px hsl(0 0% 3.9% / 0.1);
88
+ --shadow-xl-base: 0 20px 25px hsl(0 0% 3.9% / 0.12);
90
89
  --shadow-xs: var(--shadow-xs-base);
91
90
  --shadow-sm: var(--shadow-base);
92
91
  --shadow-md: var(--shadow-md-base);
@@ -158,12 +157,15 @@
158
157
  --timeline-indicator-rose: 349 89% 60%;
159
158
  --timeline-indicator-rose-foreground: 0 0% 100%;
160
159
 
161
- --layout-grid-line: var(--border);
160
+ /* --layout-grid-line is defined per-mode in base/tokens.css and per-neutral
161
+ * by the generated theme-neutral CSS, so the surface grid keeps constant
162
+ * contrast across every neutral — not just base. Opacity is the global
163
+ * subtlety knob shared by all grid surfaces (grid / honeycome / line-*). */
162
164
  --layout-grid-line-opacity: 0.18;
163
165
  --layout-grid-dot-opacity: 0.22;
164
166
 
165
- --overlay-backdrop: 240 10% 3.9% / 0.5;
166
- --overlay-backdrop-strong: 240 10% 3.9% / 0.4;
167
+ --overlay-backdrop: 0 0% 3.9% / 0.5;
168
+ --overlay-backdrop-strong: 0 0% 3.9% / 0.4;
167
169
 
168
170
  --editor-highlight: 48 96% 80%;
169
171
 
@@ -177,10 +179,6 @@
177
179
  * @theme mapping re-emits --shadow-*: var(--theme-shadow-*), so an alias
178
180
  * back to --shadow-* forms a var() cycle. */
179
181
  --theme-shadow-xs: var(--shadow-xs-base);
180
- --theme-radius-xs: var(--radius-xs);
181
- --theme-radius-sm: var(--radius-sm);
182
- --theme-radius-md: var(--radius-base);
183
- --theme-radius-lg: var(--radius-xl);
184
182
  --border-width: var(--border-width-base);
185
183
  --theme-shadow-sm: var(--shadow-base);
186
184
  --theme-shadow: var(--shadow-base);
@@ -192,40 +190,10 @@
192
190
  :root,
193
191
  [data-mode='light'] {
194
192
  color-scheme: light;
195
-
196
- --background: 0 0% 100%;
197
- --foreground: 240 10% 3.9%;
198
-
199
- --card: 0 0% 100%;
200
- --card-foreground: 240 10% 3.9%;
201
-
202
- --popover: 0 0% 100%;
203
- --popover-foreground: 240 10% 3.9%;
204
-
205
- --muted: 240 4.8% 95.9%;
206
- --muted-foreground: 240 3.8% 46.1%;
207
-
208
- --border: 240 5.9% 90%;
209
- --input: 240 5.9% 90%;
210
193
  }
211
194
 
212
195
  [data-mode='dark'] {
213
196
  color-scheme: dark;
214
-
215
- --background: 240 10% 3.9%;
216
- --foreground: 0 0% 98%;
217
-
218
- --card: 240 10% 3.9%;
219
- --card-foreground: 0 0% 98%;
220
-
221
- --popover: 240 10% 3.9%;
222
- --popover-foreground: 0 0% 98%;
223
-
224
- --muted: 240 3.7% 15.9%;
225
- --muted-foreground: 240 5% 64.9%;
226
-
227
- --border: 240 3.7% 15.9%;
228
- --input: 240 3.7% 15.9%;
229
197
  }
230
198
  }
231
199
 
@@ -243,11 +211,17 @@
243
211
  --info: 217 91% 60%;
244
212
  --info-foreground: 0 0% 100%;
245
213
 
214
+ /*
215
+ * Chart series palette. --chart-1 follows the selected accent (--primary)
216
+ * so the primary series always reflects the picked theme color; --chart-2..5
217
+ * mirror the shadcn/ui chart palette for distinguishable supporting series.
218
+ * Each stays overridable per-theme via the --theme-chart-* hook.
219
+ */
246
220
  --chart-1: var(--theme-chart-1, var(--primary));
247
- --chart-2: var(--theme-chart-2, var(--accent-foreground));
248
- --chart-3: var(--theme-chart-3, 271 81% 56%);
249
- --chart-4: var(--theme-chart-4, 38 92% 50%);
250
- --chart-5: var(--theme-chart-5, 355 78% 56%);
221
+ --chart-2: var(--theme-chart-2, 173 58% 39%);
222
+ --chart-3: var(--theme-chart-3, 197 37% 24%);
223
+ --chart-4: var(--theme-chart-4, 43 74% 66%);
224
+ --chart-5: var(--theme-chart-5, 27 87% 67%);
251
225
 
252
226
  --sidebar: var(--card);
253
227
  --sidebar-background: var(--sidebar);
@@ -278,10 +252,11 @@
278
252
 
279
253
  --editor-highlight: 48 70% 30%;
280
254
 
255
+ /* Chart palette (dark) — --chart-1 follows --primary; rest track shadcn/ui. */
281
256
  --chart-1: var(--theme-chart-1, var(--primary));
282
- --chart-2: var(--theme-chart-2, var(--accent-foreground));
283
- --chart-3: var(--theme-chart-3, 271 85% 70%);
284
- --chart-4: var(--theme-chart-4, 38 96% 62%);
285
- --chart-5: var(--theme-chart-5, 355 82% 68%);
257
+ --chart-2: var(--theme-chart-2, 160 60% 45%);
258
+ --chart-3: var(--theme-chart-3, 30 80% 55%);
259
+ --chart-4: var(--theme-chart-4, 280 65% 60%);
260
+ --chart-5: var(--theme-chart-5, 340 75% 55%);
286
261
  }
287
262
  }
@@ -7,41 +7,49 @@
7
7
  --highlight-border-alpha: 0.7;
8
8
  --highlight-background-alpha: 0.7;
9
9
 
10
- --background: 210 38% 98%;
10
+ --background: 0 0% 98%;
11
11
  --surface: 0 0% 89.8%;
12
- --surface-foreground: 211 56% 12%;
13
- --foreground: 211 56% 12%;
12
+ --surface-foreground: 0 0% 12%;
13
+ --foreground: 0 0% 12%;
14
14
 
15
15
  --card: 0 0% 100%;
16
- --card-foreground: 211 56% 12%;
16
+ --card-foreground: 0 0% 12%;
17
17
 
18
18
  --popover: 0 0% 100%;
19
- --popover-foreground: 211 56% 12%;
19
+ --popover-foreground: 0 0% 12%;
20
20
 
21
- --muted: 211 34% 94%;
22
- --muted-foreground: 211 24% 38%;
21
+ --muted: 0 0% 94%;
22
+ --muted-foreground: 0 0% 38%;
23
23
 
24
- --border: 211 28% 82%;
25
- --input: 211 28% 82%;
24
+ --border: 0 0% 82%;
25
+ --input: 0 0% 82%;
26
26
 
27
- --primary: 211 95% 29%;
27
+ /* Surface-grid line for the base neutral. Explicit (not var(--border)) so the
28
+ * grid keeps the same ~16-point lightness gap vs --background that every
29
+ * generated neutral targets — base is no longer a special case. */
30
+ --layout-grid-line: 0 0% 82%;
31
+
32
+ /* Base accent = near-black neutral (FluxUI "base"); inverts to near-white in
33
+ * dark mode (see :root[data-mode='dark'] below). Accent palettes
34
+ * (theme-color) override these at higher specificity. */
35
+ --primary: 0 0% 10%;
28
36
  --primary-foreground: 0 0% 100%;
29
- --accent: 211 95% 96%;
30
- --accent-foreground: 211 95% 22%;
31
- --secondary: 211 24% 95%;
32
- --secondary-foreground: 211 75% 24%;
33
- --ring: 211 95% 29%;
37
+ --accent: 0 0% 95%;
38
+ --accent-foreground: 0 0% 14%;
39
+ --secondary: 0 0% 95%;
40
+ --secondary-foreground: 0 0% 18%;
41
+ --ring: 0 0% 16%;
42
+
43
+ /* Brand identity color — set by the consumer via ThemeBrandService
44
+ * (provideUiTheme({ brand }) or setBrand()). Concrete (not var(--primary))
45
+ * so the theme-color='brand' preset never forms a var() cycle. Defaults to
46
+ * the base accent and inverts in dark mode. */
47
+ --brand: 0 0% 10%;
48
+ --brand-foreground: 0 0% 100%;
34
49
 
35
50
  --radius-base: 0.625rem;
36
51
  --radius: var(--radius-base);
37
52
 
38
- /* Deprecated: use the --radius-* tokens directly. */
39
- --theme-radius-base: var(--radius-base);
40
- --theme-radius-xs: var(--radius-xs);
41
- --theme-radius-sm: var(--radius-sm);
42
- --theme-radius-md: var(--radius-base);
43
- --theme-radius-lg: var(--radius-base);
44
-
45
53
  --border-width-base: 1px;
46
54
  --border-width: var(--border-width-base);
47
55
 
@@ -50,17 +58,17 @@
50
58
  * --shadow-* — the Tailwind @theme mapping re-emits
51
59
  * --shadow-*: var(--theme-shadow-*) in the later `theme` layer, which
52
60
  * turns that into a var() cycle and invalidates both tokens. */
53
- --shadow-base: 0 1px 0 0 hsl(211 95% 12% / 0.08);
54
- --shadow-md-base: 0 8px 18px -14px hsl(211 95% 12% / 0.24);
55
- --shadow-lg-base: 0 18px 36px -28px hsl(211 95% 12% / 0.34);
56
- --shadow-xl-base: 0 24px 48px -36px hsl(211 95% 12% / 0.4);
61
+ --shadow-base: 0 1px 0 0 hsl(0 0% 12% / 0.08);
62
+ --shadow-md-base: 0 8px 18px -14px hsl(0 0% 12% / 0.24);
63
+ --shadow-lg-base: 0 18px 36px -28px hsl(0 0% 12% / 0.34);
64
+ --shadow-xl-base: 0 24px 48px -36px hsl(0 0% 12% / 0.4);
57
65
  --shadow-sm: var(--shadow-base);
58
66
  --shadow-md: var(--shadow-md-base);
59
67
  --shadow-lg: var(--shadow-lg-base);
60
68
  --shadow-xl: var(--shadow-xl-base);
61
69
 
62
70
  --theme-shadow-sm: var(--shadow-base);
63
- --theme-shadow: 0 2px 4px -2px hsl(211 95% 12% / 0.14);
71
+ --theme-shadow: 0 2px 4px -2px hsl(0 0% 12% / 0.14);
64
72
  --theme-shadow-md: var(--shadow-md-base);
65
73
  --theme-shadow-lg: var(--shadow-lg-base);
66
74
  --theme-shadow-xl: var(--shadow-xl-base);
@@ -111,29 +119,39 @@
111
119
  --highlight-border-alpha: 0.45;
112
120
  --highlight-background-alpha: 0.55;
113
121
 
114
- --background: 211 38% 9%;
115
- --surface: 211 22% 18%;
116
- --surface-foreground: 210 40% 96%;
117
- --foreground: 210 40% 96%;
122
+ --background: 0 0% 9%;
123
+ --surface: 0 0% 18%;
124
+ --surface-foreground: 0 0% 96%;
125
+ --foreground: 0 0% 96%;
126
+
127
+ --card: 0 0% 11%;
128
+ --card-foreground: 0 0% 96%;
129
+
130
+ --popover: 0 0% 11%;
131
+ --popover-foreground: 0 0% 96%;
118
132
 
119
- --card: 211 34% 11%;
120
- --card-foreground: 210 40% 96%;
133
+ --muted: 0 0% 18%;
134
+ --muted-foreground: 0 0% 70%;
121
135
 
122
- --popover: 211 34% 11%;
123
- --popover-foreground: 210 40% 96%;
136
+ --border: 0 0% 24%;
137
+ --input: 0 0% 24%;
124
138
 
125
- --muted: 211 22% 18%;
126
- --muted-foreground: 211 18% 70%;
139
+ /* Surface-grid line for the base neutral (dark). See light block. */
140
+ --layout-grid-line: 0 0% 24%;
127
141
 
128
- --border: 211 24% 24%;
129
- --input: 211 24% 24%;
142
+ /* Base accent inverts: near-white primary on dark. */
143
+ --primary: 0 0% 98%;
144
+ --primary-foreground: 0 0% 12%;
145
+ --accent: 0 0% 16%;
146
+ --accent-foreground: 0 0% 98%;
147
+ --secondary: 0 0% 18%;
148
+ --secondary-foreground: 0 0% 96%;
149
+ --ring: 0 0% 85%;
130
150
 
131
- --accent: 211 58% 18%;
132
- --accent-foreground: 211 90% 84%;
133
- --secondary: 211 24% 18%;
134
- --secondary-foreground: 211 82% 84%;
151
+ --brand: 0 0% 98%;
152
+ --brand-foreground: 0 0% 12%;
135
153
 
136
- --shadow-base: 0 1px 0 0 hsl(210 40% 96% / 0.08);
154
+ --shadow-base: 0 1px 0 0 hsl(0 0% 96% / 0.08);
137
155
  --shadow-sm: var(--shadow-base);
138
156
  --theme-shadow-sm: var(--shadow-base);
139
157
 
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Accent theme: amber. Generated by scripts/gen-theme-colors.mjs — do not edit.
3
+ */
4
+ @layer tokens {
5
+ html[theme-color='amber'][data-mode='light'] {
6
+ --background: 38 28% 98%;
7
+ --foreground: 38 31% 16%;
8
+ --surface: 38 32% 95%;
9
+ --surface-foreground: 38 31% 16%;
10
+ --card: 0 0% 100%;
11
+ --card-foreground: 38 31% 16%;
12
+ --popover: 0 0% 100%;
13
+ --popover-foreground: 38 31% 16%;
14
+ --muted: 38 28% 95%;
15
+ --muted-foreground: 38 18% 40%;
16
+ --border: 38 28% 87%;
17
+ --input: 38 28% 87%;
18
+ --layout-grid-line: 38 28% 82%;
19
+ --primary: 38 92% 48%;
20
+ --primary-foreground: 0 0% 12%;
21
+ --accent: 38 55% 94%;
22
+ --accent-foreground: 38 92% 32%;
23
+ --secondary: 38 37% 93%;
24
+ --secondary-foreground: 38 92% 28%;
25
+ --ring: 38 92% 48%;
26
+ --highlight: 38 92% 64%;
27
+ }
28
+
29
+ html[theme-color='amber'][data-mode='dark'] {
30
+ --background: 38 28% 8%;
31
+ --foreground: 38 14% 96%;
32
+ --surface: 38 23% 12%;
33
+ --surface-foreground: 38 14% 96%;
34
+ --card: 38 28% 9%;
35
+ --card-foreground: 38 14% 96%;
36
+ --popover: 38 28% 9%;
37
+ --popover-foreground: 38 14% 96%;
38
+ --muted: 38 23% 16%;
39
+ --muted-foreground: 38 18% 64%;
40
+ --border: 38 23% 18%;
41
+ --input: 38 23% 18%;
42
+ --layout-grid-line: 38 23% 23%;
43
+ --primary: 38 92% 58%;
44
+ --primary-foreground: 0 0% 10%;
45
+ --accent: 38 46% 18%;
46
+ --accent-foreground: 38 74% 80%;
47
+ --secondary: 38 37% 18%;
48
+ --secondary-foreground: 38 64% 82%;
49
+ --ring: 38 92% 58%;
50
+ --highlight: 38 92% 58%;
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Accent theme: blue. Generated by scripts/gen-theme-colors.mjs — do not edit.
3
+ */
4
+ @layer tokens {
5
+ html[theme-color='blue'][data-mode='light'] {
6
+ --background: 221 25% 98%;
7
+ --foreground: 221 29% 16%;
8
+ --surface: 221 29% 95%;
9
+ --surface-foreground: 221 29% 16%;
10
+ --card: 0 0% 100%;
11
+ --card-foreground: 221 29% 16%;
12
+ --popover: 0 0% 100%;
13
+ --popover-foreground: 221 29% 16%;
14
+ --muted: 221 25% 95%;
15
+ --muted-foreground: 221 17% 40%;
16
+ --border: 221 25% 87%;
17
+ --input: 221 25% 87%;
18
+ --layout-grid-line: 221 25% 82%;
19
+ --primary: 221 83% 48%;
20
+ --primary-foreground: 0 0% 100%;
21
+ --accent: 221 50% 94%;
22
+ --accent-foreground: 221 83% 32%;
23
+ --secondary: 221 33% 93%;
24
+ --secondary-foreground: 221 83% 28%;
25
+ --ring: 221 83% 48%;
26
+ --highlight: 221 83% 64%;
27
+ }
28
+
29
+ html[theme-color='blue'][data-mode='dark'] {
30
+ --background: 221 25% 8%;
31
+ --foreground: 221 12% 96%;
32
+ --surface: 221 21% 12%;
33
+ --surface-foreground: 221 12% 96%;
34
+ --card: 221 25% 9%;
35
+ --card-foreground: 221 12% 96%;
36
+ --popover: 221 25% 9%;
37
+ --popover-foreground: 221 12% 96%;
38
+ --muted: 221 21% 16%;
39
+ --muted-foreground: 221 17% 64%;
40
+ --border: 221 21% 18%;
41
+ --input: 221 21% 18%;
42
+ --layout-grid-line: 221 21% 23%;
43
+ --primary: 221 83% 58%;
44
+ --primary-foreground: 0 0% 100%;
45
+ --accent: 221 42% 18%;
46
+ --accent-foreground: 221 66% 80%;
47
+ --secondary: 221 33% 18%;
48
+ --secondary-foreground: 221 58% 82%;
49
+ --ring: 221 83% 58%;
50
+ --highlight: 221 83% 58%;
51
+ }
52
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Accent theme: brand. Maps the chromatic accent tokens to the consumer's
3
+ * --brand / --brand-foreground (set by ThemeBrandService). Neutrals are left to
4
+ * the base/neutral axis. Hand-written — not emitted by the generated index.
5
+ */
6
+ @layer tokens {
7
+ html[theme-color='brand'][data-mode='light'],
8
+ html[theme-color='brand'][data-mode='dark'] {
9
+ --primary: var(--brand);
10
+ --primary-foreground: var(--brand-foreground);
11
+ --ring: var(--brand);
12
+ --accent-foreground: var(--brand);
13
+ --secondary-foreground: var(--brand);
14
+ --highlight: var(--brand);
15
+ }
16
+ }