@praxisui/core 10.0.0-rc.3 → 10.0.0-rc.30

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/core",
3
- "version": "10.0.0-rc.3",
3
+ "version": "10.0.0-rc.30",
4
4
  "description": "Core library for Praxis UI Workspace: types, tokens, services and utilities shared across @praxisui/* packages.",
5
5
  "peerDependencies": {
6
6
  "@angular/cdk": "^21.0.0",
@@ -19,6 +19,12 @@
19
19
  "license": "Apache-2.0",
20
20
  "exports": {
21
21
  "./theme-bridge.css": "./theme-bridge.css",
22
+ "./theming": {
23
+ "sass": "./theming/_theming.scss",
24
+ "style": "./theming/_theming.scss",
25
+ "default": "./theming/_theming.scss"
26
+ },
27
+ "./theming/*": "./theming/*",
22
28
  "./package.json": {
23
29
  "default": "./package.json"
24
30
  },
@@ -26,6 +32,10 @@
26
32
  "types": "./types/praxisui-core.d.ts",
27
33
  "default": "./fesm2022/praxisui-core.mjs"
28
34
  },
35
+ "./schema": {
36
+ "types": "./types/praxisui-core-schema.d.ts",
37
+ "default": "./fesm2022/praxisui-core-schema.mjs"
38
+ },
29
39
  "./ai/component-registry.json": {
30
40
  "default": "./ai/component-registry.json"
31
41
  }
@@ -41,11 +51,13 @@
41
51
  "core",
42
52
  "design-system",
43
53
  "tokens",
54
+ "theming",
44
55
  "widgets",
45
56
  "configuration"
46
57
  ],
47
58
  "sideEffects": [
48
- "./theme-bridge.css"
59
+ "./theme-bridge.css",
60
+ "./theming/**"
49
61
  ],
50
62
  "module": "fesm2022/praxisui-core.mjs",
51
63
  "typings": "types/praxisui-core.d.ts",
@@ -0,0 +1,63 @@
1
+ # @praxisui/core - Canonical SCSS Theming & Design Token Bridge
2
+
3
+ This module provides the official Sass mixins and design token bridge for integrating Praxis UI with host applications, design systems (Material Design 3, Tailwind, shadcn/ui, OKLCH tokens), and custom enterprise palettes.
4
+
5
+ ## Features
6
+
7
+ - **Material Design 3 & Angular Material M3 Bridge**: Automatically derives `--md-sys-color-*` and `--mat-sys-*` tokens.
8
+ - **Praxis Platform Tokens**: Full bridge for `--pdx-material-*`, `--pdx-overlay-*`, `--pdx-page-*`, `--pdx-shell-*`, and `--prx-rich-*`.
9
+ - **Dynamic Color Mixing**: Utilizes modern native CSS `color-mix(in oklab, ...)` for predictable perceptual container/state tinting.
10
+ - **Enterprise Dark Mode**: Declarative `@mixin praxis-dark-theme-overrides` for high-contrast, polished dark surfaces.
11
+ - **Widget Shell & Tooltip Refinements**: Built-in responsive full-screen UX behaviors, solid non-bleeding surfaces, and enterprise-grade tooltip styling.
12
+
13
+ ## Quick Start
14
+
15
+ ### 1. Bundle (All-in-One)
16
+
17
+ In your global styles (`styles.scss`):
18
+
19
+ ```scss
20
+ @use '@praxisui/core/theming' as praxis;
21
+
22
+ @include praxis.praxis-theme-bundle();
23
+ ```
24
+
25
+ ### 2. Granular / Custom Configuration
26
+
27
+ If your host defines custom CSS variables or design tokens:
28
+
29
+ ```scss
30
+ @use '@praxisui/core/theming' as praxis;
31
+
32
+ :root {
33
+ @include praxis.define-praxis-theme((
34
+ 'primary': var(--primary),
35
+ 'secondary': var(--secondary),
36
+ 'surface': var(--card),
37
+ 'background': var(--background),
38
+ 'foreground': var(--foreground),
39
+ 'border': var(--border),
40
+ 'radius-lg': var(--radius-lg, 12px)
41
+ ));
42
+ }
43
+
44
+ .dark {
45
+ @include praxis.praxis-dark-theme-overrides((
46
+ 'primary': var(--primary),
47
+ 'surface': var(--card),
48
+ 'border': var(--border)
49
+ ));
50
+ }
51
+
52
+ // Include UX enhancements for shell dialogs and Material tooltips:
53
+ @include praxis.praxis-shell-styles();
54
+ @include praxis.praxis-tooltip-styles();
55
+ ```
56
+
57
+ ## Available Mixins
58
+
59
+ - `define-praxis-theme($config: ())`: Emits root / light CSS variables.
60
+ - `praxis-dark-theme-overrides($config: ())`: Emits dark mode CSS variable overrides.
61
+ - `praxis-shell-styles()`: Emits fullscreen, backdrop, and expanded widget shell rules.
62
+ - `praxis-tooltip-styles()`: Emits solid surface and high-contrast refinements for Angular Material tooltips.
63
+ - `praxis-theme-bundle($config: (), $dark-config: (), $dark-selector: '.dark')`: Bundles all the above in one declaration.
@@ -0,0 +1,543 @@
1
+ @use 'sass:map';
2
+
3
+ // =============================================================================
4
+ // Praxis Platform - Canonical SCSS Theming & Design Token Bridge
5
+ // =============================================================================
6
+
7
+ /// Helper function to retrieve a key from a config map with fallback.
8
+ @function _get-token($config, $key, $fallback) {
9
+ @if map.has-key($config, $key) {
10
+ @return map.get($config, $key);
11
+ }
12
+ @return $fallback;
13
+ }
14
+
15
+ /// Emits the canonical Praxis UI tokens for a light or standard theme.
16
+ ///
17
+ /// Can be included in `:root`, inside a theme selector (e.g. `.theme-light`),
18
+ /// or at a component container boundary.
19
+ ///
20
+ /// @param {Map} $config Optional overrides for theme tokens.
21
+ @mixin define-praxis-theme($config: ()) {
22
+ $primary: _get-token($config, 'primary', var(--primary, #006a6a));
23
+ $on-primary: _get-token($config, 'on-primary', var(--primary-foreground, #ffffff));
24
+ $secondary: _get-token($config, 'secondary', var(--secondary, #4a6363));
25
+ $on-secondary: _get-token($config, 'on-secondary', var(--secondary-foreground, #ffffff));
26
+ $tertiary: _get-token($config, 'tertiary', var(--tertiary, var(--cobalt, #4b607c)));
27
+ $on-tertiary: _get-token($config, 'on-tertiary', var(--tertiary-foreground, #ffffff));
28
+ $error: _get-token($config, 'error', var(--destructive, var(--error, #ba1a1a)));
29
+ $on-error: _get-token($config, 'on-error', var(--destructive-foreground, var(--on-error, #ffffff)));
30
+
31
+ $surface: _get-token($config, 'surface', var(--card, var(--surface, #fbfcfc)));
32
+ $background: _get-token($config, 'background', var(--background, #f2f6f5));
33
+ $foreground: _get-token($config, 'foreground', var(--foreground, #191c1c));
34
+ $muted: _get-token($config, 'muted', var(--muted, #dae5e3));
35
+ $muted-foreground: _get-token($config, 'muted-foreground', var(--muted-foreground, #3f4948));
36
+ $border: _get-token($config, 'border', var(--border, #6f7978));
37
+
38
+ $popover: _get-token($config, 'popover', var(--popover, #{$surface}));
39
+ $popover-foreground: _get-token($config, 'popover-foreground', var(--popover-foreground, #{$foreground}));
40
+
41
+ $primary-container: _get-token($config, 'primary-container', color-mix(in oklab, #{$primary} 16%, #{$surface}));
42
+ $on-primary-container: _get-token($config, 'on-primary-container', #{$primary});
43
+
44
+ $secondary-container: _get-token($config, 'secondary-container', color-mix(in oklab, #{$secondary} 30%, #{$surface}));
45
+ $on-secondary-container: _get-token($config, 'on-secondary-container', #{$foreground});
46
+
47
+ $tertiary-container: _get-token($config, 'tertiary-container', color-mix(in oklab, #{$tertiary} 18%, #{$surface}));
48
+ $on-tertiary-container: _get-token($config, 'on-tertiary-container', #{$tertiary});
49
+
50
+ $error-container: _get-token($config, 'error-container', color-mix(in oklab, #{$error} 18%, #{$surface}));
51
+ $on-error-container: _get-token($config, 'on-error-container', #{$error});
52
+
53
+ $surface-lowest: _get-token($config, 'surface-container-lowest', #{$surface});
54
+ $surface-low: _get-token($config, 'surface-container-low', color-mix(in oklab, #{$surface} 95%, #{$background}));
55
+ $surface-container: _get-token($config, 'surface-container', color-mix(in oklab, #{$surface} 90%, #{$background}));
56
+ $surface-high: _get-token($config, 'surface-container-high', color-mix(in oklab, #{$surface} 85%, #{$background}));
57
+ $surface-highest: _get-token($config, 'surface-container-highest', color-mix(in oklab, #{$surface} 80%, #{$background}));
58
+
59
+ $inverse-surface: _get-token($config, 'inverse-surface', oklch(0.24 0.03 260));
60
+ $inverse-on-surface: _get-token($config, 'inverse-on-surface', oklch(0.98 0.005 240));
61
+
62
+ $outline: _get-token($config, 'outline', #{$border});
63
+ $outline-variant: _get-token($config, 'outline-variant', color-mix(in oklab, #{$outline} 60%, transparent));
64
+
65
+ $shadow: _get-token($config, 'shadow', oklch(0.1 0.02 240 / 12%));
66
+ $scrim: _get-token($config, 'scrim', oklch(0.05 0.01 240 / 45%));
67
+
68
+ $elevation-1: _get-token($config, 'elevation-1', var(--shadow-panel, var(--mat-app-elevation-shadow-level1, 0 1px 2px rgba(0, 0, 0, 0.14))));
69
+ $elevation-2: _get-token($config, 'elevation-2', var(--shadow-panel, var(--mat-app-elevation-shadow-level2, 0 2px 6px rgba(0, 0, 0, 0.16))));
70
+ $elevation-3: _get-token($config, 'elevation-3', var(--shadow-command, var(--mat-app-elevation-shadow-level3, 0 4px 12px rgba(0, 0, 0, 0.18))));
71
+
72
+ $radius-sm: _get-token($config, 'radius-sm', var(--radius-sm, 6px));
73
+ $radius-lg: _get-token($config, 'radius-lg', var(--radius-lg, 12px));
74
+ $radius-xl: _get-token($config, 'radius-xl', var(--radius-xl, 20px));
75
+
76
+ $font-sans: _get-token($config, 'font-sans', var(--font-sans, inherit));
77
+ $font-display: _get-token($config, 'font-display', var(--font-display, inherit));
78
+
79
+ // 1. Material Design 3 System Color Tokens (--md-sys-color-*)
80
+ --md-sys-color-primary: #{$primary};
81
+ --md-sys-color-on-primary: #{$on-primary};
82
+ --md-sys-color-primary-container: #{$primary-container};
83
+ --md-sys-color-on-primary-container: #{$on-primary-container};
84
+
85
+ --md-sys-color-secondary: #{$secondary};
86
+ --md-sys-color-on-secondary: #{$on-secondary};
87
+ --md-sys-color-secondary-container: #{$secondary-container};
88
+ --md-sys-color-on-secondary-container: #{$on-secondary-container};
89
+
90
+ --md-sys-color-tertiary: #{$tertiary};
91
+ --md-sys-color-on-tertiary: #{$on-tertiary};
92
+ --md-sys-color-tertiary-container: #{$tertiary-container};
93
+ --md-sys-color-on-tertiary-container: #{$on-tertiary-container};
94
+
95
+ --md-sys-color-error: #{$error};
96
+ --md-sys-color-on-error: #{$on-error};
97
+ --md-sys-color-error-container: #{$error-container};
98
+ --md-sys-color-on-error-container: #{$on-error-container};
99
+
100
+ --md-sys-color-surface: #{$surface};
101
+ --md-sys-color-surface-container-lowest: #{$surface-lowest};
102
+ --md-sys-color-surface-container-low: #{$surface-low};
103
+ --md-sys-color-surface-container: #{$surface-container};
104
+ --md-sys-color-surface-container-high: #{$surface-high};
105
+ --md-sys-color-surface-container-highest: #{$surface-highest};
106
+ --md-sys-color-surface-variant: #{$muted};
107
+
108
+ --md-sys-color-on-surface: #{$foreground};
109
+ --md-sys-color-on-surface-variant: #{$muted-foreground};
110
+
111
+ --md-sys-color-inverse-surface: #{$inverse-surface};
112
+ --md-sys-color-inverse-on-surface: #{$inverse-on-surface};
113
+
114
+ --md-sys-color-outline: #{$outline};
115
+ --md-sys-color-outline-variant: #{$outline-variant};
116
+
117
+ --md-sys-color-shadow: #{$shadow};
118
+ --md-sys-color-scrim: #{$scrim};
119
+
120
+ --md-sys-elevation-level1: #{$elevation-1};
121
+ --md-sys-elevation-level2: #{$elevation-2};
122
+ --md-sys-elevation-level3: #{$elevation-3};
123
+
124
+ // 1.1 Angular Material M3 & Tooltip Tokens Bridge (--mat-sys-*, --mat-tooltip-*)
125
+ --mat-sys-surface: #{$surface};
126
+ --mat-sys-on-surface: #{$foreground};
127
+ --mat-sys-surface-container: #{$surface-container};
128
+ --mat-sys-surface-container-high: #{$surface-high};
129
+ --mat-sys-surface-variant: #{$muted};
130
+ --mat-sys-on-surface-variant: #{$muted-foreground};
131
+ --mat-sys-outline: #{$outline};
132
+ --mat-sys-outline-variant: #{$outline-variant};
133
+ --mat-sys-primary: #{$primary};
134
+ --mat-sys-on-primary: #{$on-primary};
135
+ --mat-sys-inverse-surface: #{$inverse-surface};
136
+ --mat-sys-inverse-on-surface: #{$inverse-on-surface};
137
+ --mat-sys-corner-extra-small: #{$radius-sm};
138
+ --mat-sys-body-small-font: #{$font-sans};
139
+ --mat-sys-body-small-size: 12px;
140
+ --mat-sys-body-small-weight: 500;
141
+ --mat-sys-body-small-line-height: 16px;
142
+ --mat-sys-body-small-tracking: 0.01em;
143
+
144
+ --mat-tooltip-container-color: var(--mat-sys-inverse-surface);
145
+ --mat-tooltip-supporting-text-color: var(--mat-sys-inverse-on-surface);
146
+ --mat-tooltip-container-shape: #{$radius-sm};
147
+ --mat-tooltip-supporting-text-font: #{$font-sans};
148
+ --mat-tooltip-supporting-text-size: 12px;
149
+ --mat-tooltip-supporting-text-weight: 500;
150
+ --mat-tooltip-supporting-text-line-height: 16px;
151
+ --mat-tooltip-supporting-text-tracking: 0.01em;
152
+
153
+ // 1.2 Angular Material M3 Menu Tokens Bridge (--mat-menu-*)
154
+ --mat-menu-container-color: var(--card, var(--surface, #{$surface}));
155
+ --mat-menu-container-shape: var(--radius-md, var(--radius-lg, 14px));
156
+ --mat-menu-item-label-text-color: #{$foreground};
157
+ --mat-menu-item-icon-color: #{$muted-foreground};
158
+ --mat-menu-item-hover-state-layer-color: color-mix(in oklab, #{$primary} 12%, transparent);
159
+ --mat-menu-item-focus-state-layer-color: color-mix(in oklab, #{$primary} 18%, transparent);
160
+
161
+ // 2. Praxis Core Bridge Tokens (--pdx-material-*, --pdx-overlay-*)
162
+ --pdx-material-surface: #{$surface};
163
+ --pdx-material-surface-high: #{$surface-container};
164
+ --pdx-material-on-surface: #{$foreground};
165
+ --pdx-material-on-surface-muted: #{$muted-foreground};
166
+ --pdx-material-outline: #{$border};
167
+ --pdx-material-focus-outline: #{$primary};
168
+
169
+ --pdx-overlay-surface: #{$popover};
170
+ --pdx-overlay-on-surface: #{$popover-foreground};
171
+ --pdx-overlay-on-surface-muted: #{$muted-foreground};
172
+ --pdx-overlay-state-layer: color-mix(in oklab, #{$primary} 10%, transparent);
173
+
174
+ // 3. Dynamic Widget Page & Widget Shell Tokens (--pdx-page-*, --pdx-shell-*)
175
+ --pdx-page-bg: transparent;
176
+ --pdx-page-surface: #{$surface};
177
+ --pdx-page-gap: 20px;
178
+ --pdx-page-card-radius: #{$radius-lg};
179
+ --pdx-page-card-shadow: #{$elevation-1};
180
+ --pdx-page-accent: #{$primary};
181
+
182
+ --pdx-shell-card-bg: color-mix(in oklab, #{$surface} 75%, transparent);
183
+ --pdx-shell-card-border: #{$border};
184
+ --pdx-shell-card-radius: #{$radius-lg};
185
+ --pdx-shell-card-shadow: #{$elevation-1};
186
+ --pdx-shell-card-backdrop-filter: blur(14px);
187
+ --pdx-shell-header-bg: transparent;
188
+ --pdx-shell-header-border: #{$border};
189
+ --pdx-shell-title-color: #{$foreground};
190
+ --pdx-shell-subtitle-color: #{$muted-foreground};
191
+ --pdx-shell-icon-color: #{$primary};
192
+ --pdx-shell-body-bg: transparent;
193
+ --pdx-shell-body-color: #{$foreground};
194
+ --pdx-shell-body-padding: 16px;
195
+
196
+ // 4. Praxis Rich Content Tokens (--prx-rich-*)
197
+ --prx-rich-card-tone-bg: color-mix(in oklab, #{$surface} 80%, transparent);
198
+ --prx-rich-content-inline-gap: 8px;
199
+
200
+ // 5. Legacy Praxis Component Bridge Tokens
201
+ --praxis-color-primary: #{$primary};
202
+ --praxis-color-surface: #{$surface};
203
+ --praxis-color-text: #{$foreground};
204
+ --praxis-color-border: #{$border};
205
+ --pdx-shell-fullscreen-bg: #{$surface};
206
+ }
207
+
208
+ /// Emits canonical dark theme token overrides.
209
+ ///
210
+ /// Can be included in `.dark`, `[data-theme="dark"]`, or `@media (prefers-color-scheme: dark)`.
211
+ ///
212
+ /// @param {Map} $config Optional overrides for dark theme tokens.
213
+ @mixin praxis-dark-theme-overrides($config: ()) {
214
+ $primary: _get-token($config, 'primary', var(--primary, #80d5d4));
215
+ $on-primary: _get-token($config, 'on-primary', var(--primary-foreground, #003737));
216
+ $secondary: _get-token($config, 'secondary', var(--secondary, #b1cccb));
217
+ $on-secondary: _get-token($config, 'on-secondary', var(--secondary-foreground, #1b3535));
218
+ $tertiary: _get-token($config, 'tertiary', var(--tertiary, var(--cobalt, #b2c8e8)));
219
+ $on-tertiary: _get-token($config, 'on-tertiary', var(--tertiary-foreground, #1a314b));
220
+ $error: _get-token($config, 'error', var(--destructive, var(--error, #ffb4ab)));
221
+ $on-error: _get-token($config, 'on-error', var(--destructive-foreground, var(--on-error, #690005)));
222
+
223
+ $surface: _get-token($config, 'surface', var(--card, var(--surface, #1e2222)));
224
+ $foreground: _get-token($config, 'foreground', var(--foreground, #e0e3e2));
225
+ $muted: _get-token($config, 'muted', var(--muted, #3f4948));
226
+ $muted-foreground: _get-token($config, 'muted-foreground', var(--muted-foreground, #bec9c7));
227
+ $border: _get-token($config, 'border', var(--border, #4a5453));
228
+
229
+ $popover: _get-token($config, 'popover', var(--popover, #{$surface}));
230
+ $popover-foreground: _get-token($config, 'popover-foreground', var(--popover-foreground, #{$foreground}));
231
+
232
+ $primary-container: _get-token($config, 'primary-container', color-mix(in oklab, #{$primary} 22%, #{$surface}));
233
+ $on-primary-container: _get-token($config, 'on-primary-container', #{$on-primary});
234
+
235
+ $secondary-container: _get-token($config, 'secondary-container', color-mix(in oklab, #{$secondary} 40%, #{$surface}));
236
+ $on-secondary-container: _get-token($config, 'on-secondary-container', #{$foreground});
237
+
238
+ $tertiary-container: _get-token($config, 'tertiary-container', color-mix(in oklab, #{$tertiary} 25%, #{$surface}));
239
+ $on-tertiary-container: _get-token($config, 'on-tertiary-container', #{$foreground});
240
+
241
+ $error-container: _get-token($config, 'error-container', color-mix(in oklab, #{$error} 25%, #{$surface}));
242
+ $on-error-container: _get-token($config, 'on-error-container', #{$on-error});
243
+
244
+ $surface-lowest: _get-token($config, 'surface-container-lowest', oklch(0.12 0.025 264));
245
+ $surface-low: _get-token($config, 'surface-container-low', oklch(0.15 0.03 260));
246
+ $surface-container: _get-token($config, 'surface-container', #{$surface});
247
+ $surface-high: _get-token($config, 'surface-container-high', oklch(0.22 0.035 260));
248
+ $surface-highest: _get-token($config, 'surface-container-highest', oklch(0.26 0.04 260));
249
+
250
+ $inverse-surface: _get-token($config, 'inverse-surface', oklch(0.24 0.035 260));
251
+ $inverse-on-surface: _get-token($config, 'inverse-on-surface', oklch(0.96 0.01 240));
252
+
253
+ $outline: _get-token($config, 'outline', #{$border});
254
+ $outline-variant: _get-token($config, 'outline-variant', color-mix(in oklab, #{$outline} 50%, transparent));
255
+
256
+ $shadow: _get-token($config, 'shadow', oklch(0.02 0.01 250 / 60%));
257
+ $scrim: _get-token($config, 'scrim', oklch(0.02 0.01 250 / 80%));
258
+
259
+ // 1. Dark Mode: Material Design 3 System Color Tokens
260
+ --md-sys-color-primary: #{$primary};
261
+ --md-sys-color-on-primary: #{$on-primary};
262
+ --md-sys-color-primary-container: #{$primary-container};
263
+ --md-sys-color-on-primary-container: #{$on-primary-container};
264
+
265
+ --md-sys-color-secondary: #{$secondary};
266
+ --md-sys-color-on-secondary: #{$on-secondary};
267
+ --md-sys-color-secondary-container: #{$secondary-container};
268
+ --md-sys-color-on-secondary-container: #{$on-secondary-container};
269
+
270
+ --md-sys-color-tertiary: #{$tertiary};
271
+ --md-sys-color-on-tertiary: #{$on-tertiary};
272
+ --md-sys-color-tertiary-container: #{$tertiary-container};
273
+ --md-sys-color-on-tertiary-container: #{$on-tertiary-container};
274
+
275
+ --md-sys-color-error: #{$error};
276
+ --md-sys-color-on-error: #{$on-error};
277
+ --md-sys-color-error-container: #{$error-container};
278
+ --md-sys-color-on-error-container: #{$on-error-container};
279
+
280
+ --md-sys-color-surface: #{$surface};
281
+ --md-sys-color-surface-container-lowest: #{$surface-lowest};
282
+ --md-sys-color-surface-container-low: #{$surface-low};
283
+ --md-sys-color-surface-container: #{$surface-container};
284
+ --md-sys-color-surface-container-high: #{$surface-high};
285
+ --md-sys-color-surface-container-highest: #{$surface-highest};
286
+ --md-sys-color-surface-variant: #{$muted};
287
+
288
+ --md-sys-color-on-surface: #{$foreground};
289
+ --md-sys-color-on-surface-variant: #{$muted-foreground};
290
+
291
+ --md-sys-color-inverse-surface: #{$inverse-surface};
292
+ --md-sys-color-inverse-on-surface: #{$inverse-on-surface};
293
+
294
+ --md-sys-color-outline: #{$outline};
295
+ --md-sys-color-outline-variant: #{$outline-variant};
296
+
297
+ --md-sys-color-shadow: #{$shadow};
298
+ --md-sys-color-scrim: #{$scrim};
299
+
300
+ // 1.1 Dark Mode: Angular Material M3 & Tooltip Tokens Bridge
301
+ --mat-sys-surface: #{$surface};
302
+ --mat-sys-on-surface: #{$foreground};
303
+ --mat-sys-surface-container: #{$surface-low};
304
+ --mat-sys-surface-container-high: #{$surface-high};
305
+ --mat-sys-surface-variant: #{$muted};
306
+ --mat-sys-on-surface-variant: #{$muted-foreground};
307
+ --mat-sys-outline: #{$outline};
308
+ --mat-sys-outline-variant: #{$outline-variant};
309
+ --mat-sys-primary: #{$primary};
310
+ --mat-sys-on-primary: #{$on-primary};
311
+ --mat-sys-inverse-surface: #{$inverse-surface};
312
+ --mat-sys-inverse-on-surface: #{$inverse-on-surface};
313
+
314
+ --mat-tooltip-container-color: var(--mat-sys-inverse-surface);
315
+ --mat-tooltip-supporting-text-color: var(--mat-sys-inverse-on-surface);
316
+
317
+ // 1.2 Dark Mode: Angular Material M3 Menu Tokens Bridge
318
+ --mat-menu-container-color: var(--card, var(--surface, #{$surface}));
319
+ --mat-menu-container-shape: var(--radius-md, var(--radius-lg, 14px));
320
+ --mat-menu-item-label-text-color: #{$foreground};
321
+ --mat-menu-item-icon-color: #{$muted-foreground};
322
+ --mat-menu-item-hover-state-layer-color: color-mix(in oklab, #{$primary} 18%, transparent);
323
+ --mat-menu-item-focus-state-layer-color: color-mix(in oklab, #{$primary} 24%, transparent);
324
+
325
+ // 2. Dark Mode: Praxis Core Bridge Tokens
326
+ --pdx-material-surface: #{$surface};
327
+ --pdx-material-surface-high: #{$surface-high};
328
+ --pdx-material-on-surface: #{$foreground};
329
+ --pdx-material-on-surface-muted: #{$muted-foreground};
330
+ --pdx-material-outline: #{$border};
331
+ --pdx-material-focus-outline: #{$primary};
332
+
333
+ --pdx-overlay-surface: #{$popover};
334
+ --pdx-overlay-on-surface: #{$popover-foreground};
335
+ --pdx-overlay-on-surface-muted: #{$muted-foreground};
336
+ --pdx-overlay-state-layer: color-mix(in oklab, #{$primary} 15%, transparent);
337
+
338
+ // 3. Dark Mode: Dynamic Widget Page & Widget Shell Tokens
339
+ --pdx-page-bg: transparent;
340
+ --pdx-page-surface: #{$surface};
341
+ --pdx-page-accent: #{$primary};
342
+
343
+ --pdx-shell-card-bg: color-mix(in oklab, #{$surface} 60%, transparent);
344
+ --pdx-shell-card-border: #{$border};
345
+ --pdx-shell-card-backdrop-filter: blur(16px);
346
+ --pdx-shell-header-bg: transparent;
347
+ --pdx-shell-header-border: #{$border};
348
+ --pdx-shell-title-color: #{$foreground};
349
+ --pdx-shell-subtitle-color: #{$muted-foreground};
350
+ --pdx-shell-icon-color: #{$primary};
351
+ --pdx-shell-body-bg: transparent;
352
+ --pdx-shell-body-color: #{$foreground};
353
+
354
+ // 4. Dark Mode: Rich Content Tokens
355
+ --prx-rich-card-tone-bg: color-mix(in oklab, #{$surface} 65%, transparent);
356
+
357
+ // 5. Dark Mode: Legacy Praxis Component Bridge Tokens
358
+ --praxis-color-primary: #{$primary};
359
+ --praxis-color-surface: #{$surface};
360
+ --praxis-color-text: #{$foreground};
361
+ --praxis-color-border: #{$border};
362
+ --pdx-shell-fullscreen-bg: #{$surface};
363
+ }
364
+
365
+ /// Emits responsive and solid surface styling for Widget Shell expanded and fullscreen modes.
366
+ @mixin praxis-shell-styles() {
367
+ .pdx-shell-backdrop {
368
+ position: fixed !important;
369
+ inset: 0 !important;
370
+ z-index: 1280 !important;
371
+ background: color-mix(in oklab, var(--overlay, rgba(0, 0, 0, 0.6)) 85%, black) !important;
372
+ backdrop-filter: blur(14px) saturate(130%) !important;
373
+ -webkit-backdrop-filter: blur(14px) saturate(130%) !important;
374
+ }
375
+
376
+ .pdx-shell.fullscreen,
377
+ .pdx-shell.expanded {
378
+ background: var(--pdx-shell-fullscreen-bg, var(--card, #ffffff)) !important;
379
+ color: var(--pdx-shell-body-color, var(--foreground, inherit)) !important;
380
+ border: 1px solid var(--pdx-shell-card-border, var(--border, rgba(0, 0, 0, 0.12))) !important;
381
+ box-shadow: var(--shadow-command, var(--md-sys-elevation-level3, 0 4px 12px rgba(0, 0, 0, 0.18))) !important;
382
+ }
383
+
384
+ .pdx-shell.fullscreen {
385
+ inset: 24px !important;
386
+ width: auto !important;
387
+ height: auto !important;
388
+ border-radius: var(--radius-xl, 20px) !important;
389
+ overflow: hidden !important;
390
+ }
391
+
392
+ @media (max-width: 768px), (max-height: 800px) {
393
+ .pdx-shell.fullscreen {
394
+ inset: 12px !important;
395
+ border-radius: var(--radius-lg, 14px) !important;
396
+ }
397
+ }
398
+
399
+ .pdx-shell.fullscreen > .pdx-shell-header,
400
+ .pdx-shell.expanded > .pdx-shell-header {
401
+ padding: 16px 24px !important;
402
+ background: color-mix(in oklab, var(--pdx-shell-fullscreen-bg, var(--card, #ffffff)) 95%, var(--background, #f2f6f5)) !important;
403
+ border-bottom: 1px solid var(--pdx-shell-card-border, var(--border, rgba(0, 0, 0, 0.12))) !important;
404
+
405
+ .pdx-shell-title-text {
406
+ font-family: var(--font-display, inherit) !important;
407
+ font-size: 1.15rem !important;
408
+ font-weight: 700 !important;
409
+ }
410
+
411
+ .pdx-shell-subtitle {
412
+ font-size: 0.85rem !important;
413
+ color: var(--pdx-shell-subtitle-color, var(--muted-foreground, #666666)) !important;
414
+ }
415
+ }
416
+
417
+ @media (max-height: 800px) {
418
+ .pdx-shell.fullscreen > .pdx-shell-header,
419
+ .pdx-shell.expanded > .pdx-shell-header {
420
+ padding: 10px 18px !important;
421
+ }
422
+ }
423
+
424
+ .pdx-shell.fullscreen > .pdx-shell-body,
425
+ .pdx-shell.expanded > .pdx-shell-body {
426
+ padding: 24px 32px !important;
427
+ background: var(--pdx-shell-fullscreen-bg, var(--card, #ffffff)) !important;
428
+ }
429
+
430
+ @media (max-height: 800px) {
431
+ .pdx-shell.fullscreen > .pdx-shell-body,
432
+ .pdx-shell.expanded > .pdx-shell-body {
433
+ padding: 14px 20px !important;
434
+ }
435
+ }
436
+
437
+ .pdx-shell.fullscreen praxis-chart,
438
+ .pdx-shell.expanded praxis-chart {
439
+ width: 100% !important;
440
+ height: 100% !important;
441
+ display: block !important;
442
+ }
443
+ }
444
+
445
+ /// Emits solid surface and high-contrast refinements for Angular Material Tooltips.
446
+ @mixin praxis-tooltip-styles() {
447
+ .mat-mdc-tooltip-surface {
448
+ background-color: var(--mat-tooltip-container-color, var(--mat-sys-inverse-surface, oklch(0.24 0.03 260))) !important;
449
+ color: var(--mat-tooltip-supporting-text-color, var(--mat-sys-inverse-on-surface, oklch(0.98 0.005 240))) !important;
450
+ border-radius: var(--radius-sm, 8px) !important;
451
+ padding: 6px 12px !important;
452
+ box-shadow: 0 4px 18px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.12) !important;
453
+ border: 1px solid color-mix(in oklab, var(--border, rgba(255, 255, 255, 0.15)) 45%, transparent) !important;
454
+ font-family: var(--font-sans, inherit) !important;
455
+ font-size: 12px !important;
456
+ font-weight: 500 !important;
457
+ line-height: 1.35 !important;
458
+ letter-spacing: 0.01em !important;
459
+ backdrop-filter: blur(8px) !important;
460
+ -webkit-backdrop-filter: blur(8px) !important;
461
+ }
462
+ }
463
+
464
+ /// Emits refined surface styling, command shadow, backdrop filter,
465
+ /// and state layer hover animations for Angular Material Menus.
466
+ @mixin praxis-menu-styles() {
467
+ .mat-mdc-menu-panel {
468
+ border-radius: var(--radius-md, 14px) !important;
469
+ background: color-mix(in oklab, var(--mat-menu-container-color, var(--card, var(--surface, #ffffff))) 92%, var(--background, #f2f6f5)) !important;
470
+ border: 1px solid var(--border, var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.12))) !important;
471
+ box-shadow: var(--shadow-command, var(--md-sys-elevation-level3, 0 4px 12px rgba(0, 0, 0, 0.18))), 0 12px 32px rgba(0, 0, 0, 0.18) !important;
472
+ backdrop-filter: blur(18px) saturate(140%) !important;
473
+ -webkit-backdrop-filter: blur(18px) saturate(140%) !important;
474
+ padding: 6px !important;
475
+ overflow: hidden !important;
476
+ }
477
+
478
+ .mat-mdc-menu-item {
479
+ min-height: 40px !important;
480
+ border-radius: var(--radius-sm, 10px) !important;
481
+ margin: 2px 0 !important;
482
+ padding: 0 14px !important;
483
+ font-family: var(--font-sans, inherit) !important;
484
+ font-size: 0.85rem !important;
485
+ font-weight: 500 !important;
486
+ color: var(--mat-menu-item-label-text-color, var(--foreground, inherit)) !important;
487
+ transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease !important;
488
+
489
+ .mat-icon {
490
+ margin-right: 12px !important;
491
+ color: var(--mat-menu-item-icon-color, var(--muted-foreground, inherit)) !important;
492
+ font-size: 20px !important;
493
+ width: 20px !important;
494
+ height: 20px !important;
495
+ transition: color 0.15s ease, transform 0.15s ease !important;
496
+ }
497
+
498
+ &:hover:not([disabled]) {
499
+ background-color: var(--mat-menu-item-hover-state-layer-color, color-mix(in oklab, var(--primary) 12%, transparent)) !important;
500
+ color: var(--foreground, inherit) !important;
501
+ transform: translateX(3px);
502
+
503
+ .mat-icon {
504
+ color: var(--primary, var(--md-sys-color-primary)) !important;
505
+ transform: scale(1.08);
506
+ }
507
+ }
508
+
509
+ &:focus-visible:not([disabled]),
510
+ &.cdk-program-focused:not([disabled]) {
511
+ background-color: var(--mat-menu-item-focus-state-layer-color, color-mix(in oklab, var(--primary) 18%, transparent)) !important;
512
+ outline: 2px solid var(--primary, var(--md-sys-color-primary)) !important;
513
+ outline-offset: -2px;
514
+ }
515
+
516
+ &[disabled] {
517
+ opacity: 0.42 !important;
518
+ cursor: not-allowed !important;
519
+ pointer-events: none !important;
520
+ transform: none !important;
521
+ }
522
+ }
523
+ }
524
+
525
+ /// Convenience mixin that bundles all theme definitions, dark mode overrides,
526
+ /// widget shell rules, tooltip enhancements, and menu state layer styles.
527
+ ///
528
+ /// @param {Map} $config Optional overrides for root theme tokens.
529
+ /// @param {Map} $dark-config Optional overrides for dark theme tokens.
530
+ /// @param {String} $dark-selector Selector used for dark mode (defaults to '.dark').
531
+ @mixin praxis-theme-bundle($config: (), $dark-config: (), $dark-selector: '.dark') {
532
+ :root {
533
+ @include define-praxis-theme($config);
534
+ }
535
+
536
+ #{$dark-selector} {
537
+ @include praxis-dark-theme-overrides($dark-config);
538
+ }
539
+
540
+ @include praxis-shell-styles();
541
+ @include praxis-tooltip-styles();
542
+ @include praxis-menu-styles();
543
+ }
@@ -0,0 +1 @@
1
+ @forward 'theming';
@@ -0,0 +1 @@
1
+ @forward 'theming';