@praxisui/core 10.0.0-rc.3 → 10.0.0-rc.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.
package/README.md CHANGED
@@ -211,7 +211,37 @@ Peer dependencies:
211
211
 
212
212
  ## Theme And Icons
213
213
 
214
- Import the theme bridge after Angular Material and CDK overlay styles.
214
+ ### Canonical SCSS Theming (Recommended)
215
+
216
+ Import the canonical theming mixins to bridge host design tokens (OKLCH, Material 3, Tailwind, etc.) to Praxis components:
217
+
218
+ ```scss
219
+ @use "@angular/cdk/overlay-prebuilt.css";
220
+ @use "@praxisui/core/theming" as praxis;
221
+
222
+ // Option A: Bundle light theme, dark mode overrides, widget shell, and tooltip enhancements
223
+ @include praxis.praxis-theme-bundle();
224
+
225
+ // Option B: Granular configuration with custom design tokens
226
+ :root {
227
+ @include praxis.define-praxis-theme((
228
+ 'primary': var(--primary),
229
+ 'surface': var(--card),
230
+ 'border': var(--border)
231
+ ));
232
+ }
233
+
234
+ .dark {
235
+ @include praxis.praxis-dark-theme-overrides();
236
+ }
237
+
238
+ @include praxis.praxis-shell-styles();
239
+ @include praxis.praxis-tooltip-styles();
240
+ ```
241
+
242
+ ### Static Theme Bridge (Legacy)
243
+
244
+ For simple or static setups, you can still import the prebuilt CSS bridge directly:
215
245
 
216
246
  ```scss
217
247
  @import "@angular/cdk/overlay-prebuilt.css";
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-07T02:07:06.204Z",
3
+ "generatedAt": "2026-10-07T11:07:08.250Z",
4
4
  "packageName": "@praxisui/core",
5
- "packageVersion": "10.0.0-rc.3",
5
+ "packageVersion": "10.0.0-rc.4",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 4,
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.4",
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
  },
@@ -41,11 +47,13 @@
41
47
  "core",
42
48
  "design-system",
43
49
  "tokens",
50
+ "theming",
44
51
  "widgets",
45
52
  "configuration"
46
53
  ],
47
54
  "sideEffects": [
48
- "./theme-bridge.css"
55
+ "./theme-bridge.css",
56
+ "./theming/**"
49
57
  ],
50
58
  "module": "fesm2022/praxisui-core.mjs",
51
59
  "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,465 @@
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
+ // 2. Praxis Core Bridge Tokens (--pdx-material-*, --pdx-overlay-*)
154
+ --pdx-material-surface: #{$surface};
155
+ --pdx-material-surface-high: #{$surface-container};
156
+ --pdx-material-on-surface: #{$foreground};
157
+ --pdx-material-on-surface-muted: #{$muted-foreground};
158
+ --pdx-material-outline: #{$border};
159
+ --pdx-material-focus-outline: #{$primary};
160
+
161
+ --pdx-overlay-surface: #{$popover};
162
+ --pdx-overlay-on-surface: #{$popover-foreground};
163
+ --pdx-overlay-on-surface-muted: #{$muted-foreground};
164
+ --pdx-overlay-state-layer: color-mix(in oklab, #{$primary} 10%, transparent);
165
+
166
+ // 3. Dynamic Widget Page & Widget Shell Tokens (--pdx-page-*, --pdx-shell-*)
167
+ --pdx-page-bg: transparent;
168
+ --pdx-page-surface: #{$surface};
169
+ --pdx-page-gap: 20px;
170
+ --pdx-page-card-radius: #{$radius-lg};
171
+ --pdx-page-card-shadow: #{$elevation-1};
172
+ --pdx-page-accent: #{$primary};
173
+
174
+ --pdx-shell-card-bg: color-mix(in oklab, #{$surface} 75%, transparent);
175
+ --pdx-shell-card-border: #{$border};
176
+ --pdx-shell-card-radius: #{$radius-lg};
177
+ --pdx-shell-card-shadow: #{$elevation-1};
178
+ --pdx-shell-card-backdrop-filter: blur(14px);
179
+ --pdx-shell-header-bg: transparent;
180
+ --pdx-shell-header-border: #{$border};
181
+ --pdx-shell-title-color: #{$foreground};
182
+ --pdx-shell-subtitle-color: #{$muted-foreground};
183
+ --pdx-shell-icon-color: #{$primary};
184
+ --pdx-shell-body-bg: transparent;
185
+ --pdx-shell-body-color: #{$foreground};
186
+ --pdx-shell-body-padding: 16px;
187
+
188
+ // 4. Praxis Rich Content Tokens (--prx-rich-*)
189
+ --prx-rich-card-tone-bg: color-mix(in oklab, #{$surface} 80%, transparent);
190
+ --prx-rich-content-inline-gap: 8px;
191
+
192
+ // 5. Legacy Praxis Component Bridge Tokens
193
+ --praxis-color-primary: #{$primary};
194
+ --praxis-color-surface: #{$surface};
195
+ --praxis-color-text: #{$foreground};
196
+ --praxis-color-border: #{$border};
197
+ --pdx-shell-fullscreen-bg: #{$surface};
198
+ }
199
+
200
+ /// Emits canonical dark theme token overrides.
201
+ ///
202
+ /// Can be included in `.dark`, `[data-theme="dark"]`, or `@media (prefers-color-scheme: dark)`.
203
+ ///
204
+ /// @param {Map} $config Optional overrides for dark theme tokens.
205
+ @mixin praxis-dark-theme-overrides($config: ()) {
206
+ $primary: _get-token($config, 'primary', var(--primary, #80d5d4));
207
+ $on-primary: _get-token($config, 'on-primary', var(--primary-foreground, #003737));
208
+ $secondary: _get-token($config, 'secondary', var(--secondary, #b1cccb));
209
+ $on-secondary: _get-token($config, 'on-secondary', var(--secondary-foreground, #1b3535));
210
+ $tertiary: _get-token($config, 'tertiary', var(--tertiary, var(--cobalt, #b2c8e8)));
211
+ $on-tertiary: _get-token($config, 'on-tertiary', var(--tertiary-foreground, #1a314b));
212
+ $error: _get-token($config, 'error', var(--destructive, var(--error, #ffb4ab)));
213
+ $on-error: _get-token($config, 'on-error', var(--destructive-foreground, var(--on-error, #690005)));
214
+
215
+ $surface: _get-token($config, 'surface', var(--card, var(--surface, #1e2222)));
216
+ $foreground: _get-token($config, 'foreground', var(--foreground, #e0e3e2));
217
+ $muted: _get-token($config, 'muted', var(--muted, #3f4948));
218
+ $muted-foreground: _get-token($config, 'muted-foreground', var(--muted-foreground, #bec9c7));
219
+ $border: _get-token($config, 'border', var(--border, #4a5453));
220
+
221
+ $popover: _get-token($config, 'popover', var(--popover, #{$surface}));
222
+ $popover-foreground: _get-token($config, 'popover-foreground', var(--popover-foreground, #{$foreground}));
223
+
224
+ $primary-container: _get-token($config, 'primary-container', color-mix(in oklab, #{$primary} 22%, #{$surface}));
225
+ $on-primary-container: _get-token($config, 'on-primary-container', #{$on-primary});
226
+
227
+ $secondary-container: _get-token($config, 'secondary-container', color-mix(in oklab, #{$secondary} 40%, #{$surface}));
228
+ $on-secondary-container: _get-token($config, 'on-secondary-container', #{$foreground});
229
+
230
+ $tertiary-container: _get-token($config, 'tertiary-container', color-mix(in oklab, #{$tertiary} 25%, #{$surface}));
231
+ $on-tertiary-container: _get-token($config, 'on-tertiary-container', #{$foreground});
232
+
233
+ $error-container: _get-token($config, 'error-container', color-mix(in oklab, #{$error} 25%, #{$surface}));
234
+ $on-error-container: _get-token($config, 'on-error-container', #{$on-error});
235
+
236
+ $surface-lowest: _get-token($config, 'surface-container-lowest', oklch(0.12 0.025 264));
237
+ $surface-low: _get-token($config, 'surface-container-low', oklch(0.15 0.03 260));
238
+ $surface-container: _get-token($config, 'surface-container', #{$surface});
239
+ $surface-high: _get-token($config, 'surface-container-high', oklch(0.22 0.035 260));
240
+ $surface-highest: _get-token($config, 'surface-container-highest', oklch(0.26 0.04 260));
241
+
242
+ $inverse-surface: _get-token($config, 'inverse-surface', oklch(0.24 0.035 260));
243
+ $inverse-on-surface: _get-token($config, 'inverse-on-surface', oklch(0.96 0.01 240));
244
+
245
+ $outline: _get-token($config, 'outline', #{$border});
246
+ $outline-variant: _get-token($config, 'outline-variant', color-mix(in oklab, #{$outline} 50%, transparent));
247
+
248
+ $shadow: _get-token($config, 'shadow', oklch(0.02 0.01 250 / 60%));
249
+ $scrim: _get-token($config, 'scrim', oklch(0.02 0.01 250 / 80%));
250
+
251
+ // 1. Dark Mode: Material Design 3 System Color Tokens
252
+ --md-sys-color-primary: #{$primary};
253
+ --md-sys-color-on-primary: #{$on-primary};
254
+ --md-sys-color-primary-container: #{$primary-container};
255
+ --md-sys-color-on-primary-container: #{$on-primary-container};
256
+
257
+ --md-sys-color-secondary: #{$secondary};
258
+ --md-sys-color-on-secondary: #{$on-secondary};
259
+ --md-sys-color-secondary-container: #{$secondary-container};
260
+ --md-sys-color-on-secondary-container: #{$on-secondary-container};
261
+
262
+ --md-sys-color-tertiary: #{$tertiary};
263
+ --md-sys-color-on-tertiary: #{$on-tertiary};
264
+ --md-sys-color-tertiary-container: #{$tertiary-container};
265
+ --md-sys-color-on-tertiary-container: #{$on-tertiary-container};
266
+
267
+ --md-sys-color-error: #{$error};
268
+ --md-sys-color-on-error: #{$on-error};
269
+ --md-sys-color-error-container: #{$error-container};
270
+ --md-sys-color-on-error-container: #{$on-error-container};
271
+
272
+ --md-sys-color-surface: #{$surface};
273
+ --md-sys-color-surface-container-lowest: #{$surface-lowest};
274
+ --md-sys-color-surface-container-low: #{$surface-low};
275
+ --md-sys-color-surface-container: #{$surface-container};
276
+ --md-sys-color-surface-container-high: #{$surface-high};
277
+ --md-sys-color-surface-container-highest: #{$surface-highest};
278
+ --md-sys-color-surface-variant: #{$muted};
279
+
280
+ --md-sys-color-on-surface: #{$foreground};
281
+ --md-sys-color-on-surface-variant: #{$muted-foreground};
282
+
283
+ --md-sys-color-inverse-surface: #{$inverse-surface};
284
+ --md-sys-color-inverse-on-surface: #{$inverse-on-surface};
285
+
286
+ --md-sys-color-outline: #{$outline};
287
+ --md-sys-color-outline-variant: #{$outline-variant};
288
+
289
+ --md-sys-color-shadow: #{$shadow};
290
+ --md-sys-color-scrim: #{$scrim};
291
+
292
+ // 1.1 Dark Mode: Angular Material M3 & Tooltip Tokens Bridge
293
+ --mat-sys-surface: #{$surface};
294
+ --mat-sys-on-surface: #{$foreground};
295
+ --mat-sys-surface-container: #{$surface-low};
296
+ --mat-sys-surface-container-high: #{$surface-high};
297
+ --mat-sys-surface-variant: #{$muted};
298
+ --mat-sys-on-surface-variant: #{$muted-foreground};
299
+ --mat-sys-outline: #{$outline};
300
+ --mat-sys-outline-variant: #{$outline-variant};
301
+ --mat-sys-primary: #{$primary};
302
+ --mat-sys-on-primary: #{$on-primary};
303
+ --mat-sys-inverse-surface: #{$inverse-surface};
304
+ --mat-sys-inverse-on-surface: #{$inverse-on-surface};
305
+
306
+ --mat-tooltip-container-color: var(--mat-sys-inverse-surface);
307
+ --mat-tooltip-supporting-text-color: var(--mat-sys-inverse-on-surface);
308
+
309
+ // 2. Dark Mode: Praxis Core Bridge Tokens
310
+ --pdx-material-surface: #{$surface};
311
+ --pdx-material-surface-high: #{$surface-high};
312
+ --pdx-material-on-surface: #{$foreground};
313
+ --pdx-material-on-surface-muted: #{$muted-foreground};
314
+ --pdx-material-outline: #{$border};
315
+ --pdx-material-focus-outline: #{$primary};
316
+
317
+ --pdx-overlay-surface: #{$popover};
318
+ --pdx-overlay-on-surface: #{$popover-foreground};
319
+ --pdx-overlay-on-surface-muted: #{$muted-foreground};
320
+ --pdx-overlay-state-layer: color-mix(in oklab, #{$primary} 15%, transparent);
321
+
322
+ // 3. Dark Mode: Dynamic Widget Page & Widget Shell Tokens
323
+ --pdx-page-bg: transparent;
324
+ --pdx-page-surface: #{$surface};
325
+ --pdx-page-accent: #{$primary};
326
+
327
+ --pdx-shell-card-bg: color-mix(in oklab, #{$surface} 60%, transparent);
328
+ --pdx-shell-card-border: #{$border};
329
+ --pdx-shell-card-backdrop-filter: blur(16px);
330
+ --pdx-shell-header-bg: transparent;
331
+ --pdx-shell-header-border: #{$border};
332
+ --pdx-shell-title-color: #{$foreground};
333
+ --pdx-shell-subtitle-color: #{$muted-foreground};
334
+ --pdx-shell-icon-color: #{$primary};
335
+ --pdx-shell-body-bg: transparent;
336
+ --pdx-shell-body-color: #{$foreground};
337
+
338
+ // 4. Dark Mode: Rich Content Tokens
339
+ --prx-rich-card-tone-bg: color-mix(in oklab, #{$surface} 65%, transparent);
340
+
341
+ // 5. Dark Mode: Legacy Praxis Component Bridge Tokens
342
+ --praxis-color-primary: #{$primary};
343
+ --praxis-color-surface: #{$surface};
344
+ --praxis-color-text: #{$foreground};
345
+ --praxis-color-border: #{$border};
346
+ --pdx-shell-fullscreen-bg: #{$surface};
347
+ }
348
+
349
+ /// Emits responsive and solid surface styling for Widget Shell expanded and fullscreen modes.
350
+ @mixin praxis-shell-styles() {
351
+ .pdx-shell-backdrop {
352
+ position: fixed !important;
353
+ inset: 0 !important;
354
+ z-index: 1280 !important;
355
+ background: color-mix(in oklab, var(--overlay, rgba(0, 0, 0, 0.6)) 85%, black) !important;
356
+ backdrop-filter: blur(14px) saturate(130%) !important;
357
+ -webkit-backdrop-filter: blur(14px) saturate(130%) !important;
358
+ }
359
+
360
+ .pdx-shell.fullscreen,
361
+ .pdx-shell.expanded {
362
+ background: var(--pdx-shell-fullscreen-bg, var(--card, #ffffff)) !important;
363
+ color: var(--pdx-shell-body-color, var(--foreground, inherit)) !important;
364
+ border: 1px solid var(--pdx-shell-card-border, var(--border, rgba(0, 0, 0, 0.12))) !important;
365
+ box-shadow: var(--shadow-command, var(--md-sys-elevation-level3, 0 4px 12px rgba(0, 0, 0, 0.18))) !important;
366
+ }
367
+
368
+ .pdx-shell.fullscreen {
369
+ inset: 24px !important;
370
+ width: auto !important;
371
+ height: auto !important;
372
+ border-radius: var(--radius-xl, 20px) !important;
373
+ overflow: hidden !important;
374
+ }
375
+
376
+ @media (max-width: 768px), (max-height: 800px) {
377
+ .pdx-shell.fullscreen {
378
+ inset: 12px !important;
379
+ border-radius: var(--radius-lg, 14px) !important;
380
+ }
381
+ }
382
+
383
+ .pdx-shell.fullscreen > .pdx-shell-header,
384
+ .pdx-shell.expanded > .pdx-shell-header {
385
+ padding: 16px 24px !important;
386
+ background: color-mix(in oklab, var(--pdx-shell-fullscreen-bg, var(--card, #ffffff)) 95%, var(--background, #f2f6f5)) !important;
387
+ border-bottom: 1px solid var(--pdx-shell-card-border, var(--border, rgba(0, 0, 0, 0.12))) !important;
388
+
389
+ .pdx-shell-title-text {
390
+ font-family: var(--font-display, inherit) !important;
391
+ font-size: 1.15rem !important;
392
+ font-weight: 700 !important;
393
+ }
394
+
395
+ .pdx-shell-subtitle {
396
+ font-size: 0.85rem !important;
397
+ color: var(--pdx-shell-subtitle-color, var(--muted-foreground, #666666)) !important;
398
+ }
399
+ }
400
+
401
+ @media (max-height: 800px) {
402
+ .pdx-shell.fullscreen > .pdx-shell-header,
403
+ .pdx-shell.expanded > .pdx-shell-header {
404
+ padding: 10px 18px !important;
405
+ }
406
+ }
407
+
408
+ .pdx-shell.fullscreen > .pdx-shell-body,
409
+ .pdx-shell.expanded > .pdx-shell-body {
410
+ padding: 24px 32px !important;
411
+ background: var(--pdx-shell-fullscreen-bg, var(--card, #ffffff)) !important;
412
+ }
413
+
414
+ @media (max-height: 800px) {
415
+ .pdx-shell.fullscreen > .pdx-shell-body,
416
+ .pdx-shell.expanded > .pdx-shell-body {
417
+ padding: 14px 20px !important;
418
+ }
419
+ }
420
+
421
+ .pdx-shell.fullscreen praxis-chart,
422
+ .pdx-shell.expanded praxis-chart {
423
+ width: 100% !important;
424
+ height: 100% !important;
425
+ display: block !important;
426
+ }
427
+ }
428
+
429
+ /// Emits solid surface and high-contrast refinements for Angular Material Tooltips.
430
+ @mixin praxis-tooltip-styles() {
431
+ .mat-mdc-tooltip-surface {
432
+ background-color: var(--mat-tooltip-container-color, var(--mat-sys-inverse-surface, oklch(0.24 0.03 260))) !important;
433
+ color: var(--mat-tooltip-supporting-text-color, var(--mat-sys-inverse-on-surface, oklch(0.98 0.005 240))) !important;
434
+ border-radius: var(--radius-sm, 8px) !important;
435
+ padding: 6px 12px !important;
436
+ box-shadow: 0 4px 18px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.12) !important;
437
+ border: 1px solid color-mix(in oklab, var(--border, rgba(255, 255, 255, 0.15)) 45%, transparent) !important;
438
+ font-family: var(--font-sans, inherit) !important;
439
+ font-size: 12px !important;
440
+ font-weight: 500 !important;
441
+ line-height: 1.35 !important;
442
+ letter-spacing: 0.01em !important;
443
+ backdrop-filter: blur(8px) !important;
444
+ -webkit-backdrop-filter: blur(8px) !important;
445
+ }
446
+ }
447
+
448
+ /// Convenience mixin that bundles all theme definitions, dark mode overrides,
449
+ /// widget shell rules, and tooltip enhancements.
450
+ ///
451
+ /// @param {Map} $config Optional overrides for root theme tokens.
452
+ /// @param {Map} $dark-config Optional overrides for dark theme tokens.
453
+ /// @param {String} $dark-selector Selector used for dark mode (defaults to '.dark').
454
+ @mixin praxis-theme-bundle($config: (), $dark-config: (), $dark-selector: '.dark') {
455
+ :root {
456
+ @include define-praxis-theme($config);
457
+ }
458
+
459
+ #{$dark-selector} {
460
+ @include praxis-dark-theme-overrides($dark-config);
461
+ }
462
+
463
+ @include praxis-shell-styles();
464
+ @include praxis-tooltip-styles();
465
+ }
@@ -0,0 +1 @@
1
+ @forward 'theming';
@@ -0,0 +1 @@
1
+ @forward 'theming';