@asteby/metacore-theme 2.0.0 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/provider.d.ts +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/package.json +3 -2
- package/styles/glass.css +360 -0
- package/styles/index.css +21 -22
package/README.md
CHANGED
|
@@ -50,6 +50,22 @@ If you already have your own Tailwind entry and only want the tokens:
|
|
|
50
50
|
@import '@asteby/metacore-theme/tokens.css';
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
### Glass theme pack
|
|
54
|
+
|
|
55
|
+
A translucent skin (floating panels, blur + saturation, hairline rim, soft
|
|
56
|
+
layered shadows) activated with `<html data-ui-theme="glass">`. It styles the
|
|
57
|
+
`data-slot` primitives of `@asteby/metacore-ui` (sidebar, dialogs, sheets,
|
|
58
|
+
popovers, selects, inputs, tables) and only sets surfaces — the accent stays
|
|
59
|
+
the brand painted by `applyBranding`. Import it after your tokens:
|
|
60
|
+
|
|
61
|
+
```css
|
|
62
|
+
@import '@asteby/metacore-theme/tokens.css';
|
|
63
|
+
@import '@asteby/metacore-theme/glass.css';
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
It includes a near-opaque fallback for browsers without `backdrop-filter`
|
|
67
|
+
and for `prefers-reduced-transparency`.
|
|
68
|
+
|
|
53
69
|
## Usage from JS/TS
|
|
54
70
|
|
|
55
71
|
For programmatic access (Storybook, charts, PDF):
|
package/dist/provider.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type ThemeProviderState = {
|
|
|
12
12
|
setTheme: (theme: Theme) => void;
|
|
13
13
|
resetTheme: () => void;
|
|
14
14
|
};
|
|
15
|
-
export declare function ThemeProvider({ children, defaultTheme, storageKey, }: ThemeProviderProps): import("react
|
|
15
|
+
export declare function ThemeProvider({ children, defaultTheme, storageKey, }: ThemeProviderProps): import("react").JSX.Element;
|
|
16
16
|
export declare function useTheme(): ThemeProviderState;
|
|
17
17
|
export {};
|
|
18
18
|
//# sourceMappingURL=provider.d.ts.map
|
package/dist/provider.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AACxC,KAAK,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;AAM7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,KAAK,CAAA;IACnB,aAAa,EAAE,aAAa,CAAA;IAC5B,KAAK,EAAE,KAAK,CAAA;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,UAAU,EAAE,MAAM,IAAI,CAAA;CACvB,CAAA;AAgCD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAA4B,EAC5B,UAAgC,GACjC,EAAE,kBAAkB
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AACxC,KAAK,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;AAM7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,KAAK,CAAA;IACnB,aAAa,EAAE,aAAa,CAAA;IAC5B,KAAK,EAAE,KAAK,CAAA;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,UAAU,EAAE,MAAM,IAAI,CAAA;CACvB,CAAA;AAgCD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAA4B,EAC5B,UAAgC,GACjC,EAAE,kBAAkB,+BAuDpB;AAGD,wBAAgB,QAAQ,IAAI,kBAAkB,CAI7C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asteby/metacore-theme",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0",
|
|
4
4
|
"description": "Metacore design tokens + Tailwind 4 preset (oklch, shadows, fonts, dark mode)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"./tokens.css": "./styles/tokens.css",
|
|
25
25
|
"./index.css": "./styles/index.css",
|
|
26
|
+
"./glass.css": "./styles/glass.css",
|
|
26
27
|
"./fonts": {
|
|
27
28
|
"types": "./dist/fonts.d.ts",
|
|
28
29
|
"import": "./dist/fonts.js"
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"@types/react-dom": "^19.0.0",
|
|
46
47
|
"react": "^19.2.4",
|
|
47
48
|
"react-dom": "^19.2.4",
|
|
48
|
-
"typescript": "^
|
|
49
|
+
"typescript": "^6.0.0"
|
|
49
50
|
},
|
|
50
51
|
"publishConfig": {
|
|
51
52
|
"access": "public"
|
package/styles/glass.css
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Glass theme pack — translucent surfaces over a soft gradient, in the
|
|
3
|
+
* iOS / visionOS idiom: floating panels with a hairline rim, an inner top
|
|
4
|
+
* highlight, layered soft shadows and blur + saturation behind them.
|
|
5
|
+
*
|
|
6
|
+
* Activated with <html data-ui-theme="glass">. The pack only brings
|
|
7
|
+
* surfaces, borders, blur and shadows: it never sets --primary (nor ring /
|
|
8
|
+
* sidebar-primary). The accent is always the brand, painted by
|
|
9
|
+
* @asteby/metacore-app-providers' applyBranding.
|
|
10
|
+
*
|
|
11
|
+
* Targets the `data-slot` attributes of @asteby/metacore-ui primitives, so
|
|
12
|
+
* every app built on them (sidebar, dialogs, sheets, popovers, selects,
|
|
13
|
+
* inputs, tables) picks it up without per-component classes. Import it after
|
|
14
|
+
* the app's base tokens:
|
|
15
|
+
*
|
|
16
|
+
* @import '@asteby/metacore-theme/glass.css';
|
|
17
|
+
*
|
|
18
|
+
* Plain (unlayered) CSS on purpose: it must win over Tailwind utilities
|
|
19
|
+
* such as `bg-card` or `hover:bg-muted/50` in `@layer utilities`.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/* ─── Tokens ─── */
|
|
23
|
+
[data-ui-theme='glass'] {
|
|
24
|
+
--radius: 1.1rem;
|
|
25
|
+
--font-sans: Manrope, Inter, sans-serif;
|
|
26
|
+
|
|
27
|
+
--background: oklch(0.985 0.01 250 / 0.5);
|
|
28
|
+
--foreground: oklch(0.22 0.03 250);
|
|
29
|
+
--card: oklch(1 0 0 / 0.5);
|
|
30
|
+
--card-foreground: oklch(0.22 0.03 250);
|
|
31
|
+
--popover: oklch(0.995 0.004 250 / 0.74);
|
|
32
|
+
--popover-foreground: oklch(0.22 0.03 250);
|
|
33
|
+
--secondary: oklch(1 0 0 / 0.55);
|
|
34
|
+
--secondary-foreground: oklch(0.28 0.04 250);
|
|
35
|
+
--muted: oklch(0.95 0.015 250 / 0.6);
|
|
36
|
+
--muted-foreground: oklch(0.44 0.03 250);
|
|
37
|
+
--accent: oklch(1 0 0 / 0.6);
|
|
38
|
+
--accent-foreground: oklch(0.24 0.04 250);
|
|
39
|
+
/* Inner separators: a dark hairline reads on white glass, a white one doesn't. */
|
|
40
|
+
--border: oklch(0.35 0.03 250 / 0.12);
|
|
41
|
+
--input: oklch(0.35 0.03 250 / 0.14);
|
|
42
|
+
--sidebar: oklch(1 0 0 / 0.45);
|
|
43
|
+
--sidebar-foreground: oklch(0.26 0.03 250);
|
|
44
|
+
--sidebar-accent: oklch(1 0 0 / 0.6);
|
|
45
|
+
--sidebar-accent-foreground: oklch(0.22 0.04 250);
|
|
46
|
+
--sidebar-border: oklch(0.35 0.03 250 / 0.1);
|
|
47
|
+
|
|
48
|
+
--glass-blur: 24px;
|
|
49
|
+
--glass-saturate: 1.8;
|
|
50
|
+
--glass-radius: calc(var(--radius) + 4px);
|
|
51
|
+
/* Outer rim of a floating panel. */
|
|
52
|
+
--glass-rim: oklch(1 0 0 / 0.55);
|
|
53
|
+
--glass-highlight: inset 0 1px 0 0 oklch(1 0 0 / 0.75);
|
|
54
|
+
--glass-shadow:
|
|
55
|
+
0 1px 2px oklch(0.25 0.04 260 / 0.06),
|
|
56
|
+
0 8px 24px -8px oklch(0.25 0.04 260 / 0.14),
|
|
57
|
+
0 24px 56px -16px oklch(0.25 0.04 260 / 0.16);
|
|
58
|
+
--glass-shadow-float:
|
|
59
|
+
0 2px 6px oklch(0.25 0.04 260 / 0.08),
|
|
60
|
+
0 18px 48px -12px oklch(0.25 0.04 260 / 0.24),
|
|
61
|
+
0 48px 96px -24px oklch(0.25 0.04 260 / 0.22);
|
|
62
|
+
--glass-field: oklch(1 0 0 / 0.55);
|
|
63
|
+
--glass-field-hover: oklch(1 0 0 / 0.7);
|
|
64
|
+
--glass-overlay: oklch(0.3 0.03 260 / 0.16);
|
|
65
|
+
--glass-row-hover: oklch(1 0 0 / 0.4);
|
|
66
|
+
--glass-thead: oklch(1 0 0 / 0.62);
|
|
67
|
+
|
|
68
|
+
--shadow-md: var(--glass-shadow);
|
|
69
|
+
--ui-surface-blur: var(--glass-blur);
|
|
70
|
+
--ui-card-alpha: 0.5;
|
|
71
|
+
|
|
72
|
+
background-color: oklch(0.93 0.035 270);
|
|
73
|
+
background-image:
|
|
74
|
+
radial-gradient(48rem 34rem at 10% -8%, oklch(0.8 0.11 250 / 0.9), transparent 70%),
|
|
75
|
+
radial-gradient(40rem 30rem at 105% 20%, oklch(0.78 0.12 295 / 0.75), transparent 68%),
|
|
76
|
+
radial-gradient(38rem 28rem at 60% 115%, oklch(0.9 0.12 90 / 0.7), transparent 70%);
|
|
77
|
+
background-attachment: fixed;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.dark[data-ui-theme='glass'] {
|
|
81
|
+
--background: oklch(0.22 0.03 255 / 0.5);
|
|
82
|
+
--foreground: oklch(0.96 0.01 250);
|
|
83
|
+
--card: oklch(0.27 0.03 255 / 0.45);
|
|
84
|
+
--card-foreground: oklch(0.96 0.01 250);
|
|
85
|
+
--popover: oklch(0.23 0.03 255 / 0.78);
|
|
86
|
+
--popover-foreground: oklch(0.96 0.01 250);
|
|
87
|
+
--secondary: oklch(1 0 0 / 0.08);
|
|
88
|
+
--secondary-foreground: oklch(0.96 0.01 250);
|
|
89
|
+
--muted: oklch(1 0 0 / 0.06);
|
|
90
|
+
--muted-foreground: oklch(0.76 0.03 250);
|
|
91
|
+
--accent: oklch(1 0 0 / 0.1);
|
|
92
|
+
--accent-foreground: oklch(0.97 0.01 250);
|
|
93
|
+
--border: oklch(1 0 0 / 0.1);
|
|
94
|
+
--input: oklch(1 0 0 / 0.12);
|
|
95
|
+
--sidebar: oklch(0.2 0.03 255 / 0.5);
|
|
96
|
+
--sidebar-foreground: oklch(0.94 0.01 250);
|
|
97
|
+
--sidebar-accent: oklch(1 0 0 / 0.1);
|
|
98
|
+
--sidebar-accent-foreground: oklch(0.97 0.01 250);
|
|
99
|
+
--sidebar-border: oklch(1 0 0 / 0.08);
|
|
100
|
+
|
|
101
|
+
--glass-rim: oklch(1 0 0 / 0.1);
|
|
102
|
+
--glass-highlight: inset 0 1px 0 0 oklch(1 0 0 / 0.09);
|
|
103
|
+
--glass-shadow:
|
|
104
|
+
0 1px 2px oklch(0 0 0 / 0.3),
|
|
105
|
+
0 8px 24px -8px oklch(0 0 0 / 0.4),
|
|
106
|
+
0 24px 56px -16px oklch(0 0 0 / 0.45);
|
|
107
|
+
--glass-shadow-float:
|
|
108
|
+
0 2px 6px oklch(0 0 0 / 0.35),
|
|
109
|
+
0 18px 48px -12px oklch(0 0 0 / 0.55),
|
|
110
|
+
0 48px 96px -24px oklch(0 0 0 / 0.5);
|
|
111
|
+
--glass-field: oklch(1 0 0 / 0.06);
|
|
112
|
+
--glass-field-hover: oklch(1 0 0 / 0.1);
|
|
113
|
+
--glass-overlay: oklch(0.08 0.02 260 / 0.45);
|
|
114
|
+
--glass-row-hover: oklch(1 0 0 / 0.05);
|
|
115
|
+
--glass-thead: oklch(0.25 0.03 255 / 0.7);
|
|
116
|
+
|
|
117
|
+
background-color: oklch(0.16 0.03 260);
|
|
118
|
+
background-image:
|
|
119
|
+
radial-gradient(42rem 28rem at 8% -8%, oklch(0.45 0.16 250 / 0.7), transparent 70%),
|
|
120
|
+
radial-gradient(32rem 24rem at 100% 0%, oklch(0.4 0.12 200 / 0.55), transparent 68%),
|
|
121
|
+
radial-gradient(28rem 22rem at 70% 100%, oklch(0.42 0.14 300 / 0.45), transparent 70%);
|
|
122
|
+
background-attachment: fixed;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ─── Blur behind every translucent surface ─── */
|
|
126
|
+
[data-ui-theme='glass'] .bg-background,
|
|
127
|
+
[data-ui-theme='glass'] .bg-card,
|
|
128
|
+
[data-ui-theme='glass'] .bg-popover,
|
|
129
|
+
[data-ui-theme='glass'] .bg-sidebar,
|
|
130
|
+
[data-ui-theme='glass'] [data-slot='sidebar-inner'],
|
|
131
|
+
[data-ui-theme='glass'] [data-slot='popover-content'],
|
|
132
|
+
[data-ui-theme='glass'] [data-slot='select-content'],
|
|
133
|
+
[data-ui-theme='glass'] [data-slot='dropdown-menu-content'],
|
|
134
|
+
[data-ui-theme='glass'] [data-slot='dropdown-menu-sub-content'],
|
|
135
|
+
[data-ui-theme='glass'] [data-slot='context-menu-content'] {
|
|
136
|
+
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
137
|
+
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* Only the leaf surfaces are glass. body and the sidebar wrapper are pure
|
|
142
|
+
* layout, yet they also paint --background / --sidebar (inset variant):
|
|
143
|
+
* stacked under the panels those alphas compound to a flat fill.
|
|
144
|
+
*/
|
|
145
|
+
[data-ui-theme='glass'] body,
|
|
146
|
+
[data-ui-theme='glass'] [data-slot='sidebar-wrapper'] {
|
|
147
|
+
background-color: transparent;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* ─── Floating panels: sidebar + main inset ─── */
|
|
151
|
+
[data-ui-theme='glass'] [data-slot='sidebar-inner'],
|
|
152
|
+
[data-ui-theme='glass'] [data-slot='sidebar-inset'] {
|
|
153
|
+
border: 1px solid var(--glass-rim);
|
|
154
|
+
border-radius: var(--glass-radius);
|
|
155
|
+
box-shadow: var(--glass-highlight), var(--glass-shadow);
|
|
156
|
+
background-clip: padding-box;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
[data-ui-theme='glass'] [data-slot='sidebar-inner'] {
|
|
160
|
+
overflow: hidden;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/*
|
|
164
|
+
* The plain `sidebar` variant is flush to the viewport edge with a border:
|
|
165
|
+
* give it the same 0.5rem gutter the floating/inset variants have, and the
|
|
166
|
+
* icon-collapsed width room for that gutter.
|
|
167
|
+
*/
|
|
168
|
+
[data-ui-theme='glass'] [data-slot='sidebar'][data-variant='sidebar'] [data-slot='sidebar-container'] {
|
|
169
|
+
padding: 0.5rem;
|
|
170
|
+
border-inline: 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
[data-ui-theme='glass'] [data-slot='sidebar'][data-variant='sidebar'][data-collapsible='icon'] [data-slot='sidebar-container'] {
|
|
174
|
+
width: calc(var(--sidebar-width-icon) + 1rem + 2px);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
[data-ui-theme='glass'] [data-slot='sidebar'][data-variant='sidebar'][data-collapsible='icon'] [data-slot='sidebar-gap'] {
|
|
178
|
+
width: calc(var(--sidebar-width-icon) + 1rem);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@media (min-width: 768px) {
|
|
182
|
+
[data-ui-theme='glass'] [data-slot='sidebar'][data-variant='sidebar'] ~ [data-slot='sidebar-inset'] {
|
|
183
|
+
margin: 0.5rem;
|
|
184
|
+
margin-inline-start: 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@media (max-width: 767px) {
|
|
189
|
+
/* No sidebar panel beside it on phones: the inset is the whole screen. */
|
|
190
|
+
[data-ui-theme='glass'] [data-slot='sidebar-inset'] {
|
|
191
|
+
border: 0;
|
|
192
|
+
border-radius: 0;
|
|
193
|
+
box-shadow: none;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/*
|
|
198
|
+
* Mobile sidebar: a Sheet whose content carries data-slot="sidebar" +
|
|
199
|
+
* data-mobile="true" (not sheet-content). Float it as a card with the same
|
|
200
|
+
* gutter, over the dimmed overlay, so it takes the denser popover glass.
|
|
201
|
+
*/
|
|
202
|
+
[data-ui-theme='glass'] [data-mobile='true'][data-slot='sidebar'] {
|
|
203
|
+
inset-block: 0.5rem;
|
|
204
|
+
inset-inline-start: 0.5rem;
|
|
205
|
+
height: auto;
|
|
206
|
+
background-color: var(--popover);
|
|
207
|
+
border: 1px solid var(--glass-rim);
|
|
208
|
+
border-radius: var(--glass-radius);
|
|
209
|
+
box-shadow: var(--glass-highlight), var(--glass-shadow-float);
|
|
210
|
+
background-clip: padding-box;
|
|
211
|
+
overflow: hidden;
|
|
212
|
+
-webkit-backdrop-filter: blur(40px) saturate(var(--glass-saturate));
|
|
213
|
+
backdrop-filter: blur(40px) saturate(var(--glass-saturate));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* ─── Floating layers: dialogs, sheets, menus ─── */
|
|
217
|
+
[data-ui-theme='glass'] [data-slot='dialog-overlay'],
|
|
218
|
+
[data-ui-theme='glass'] [data-slot='alert-dialog-overlay'],
|
|
219
|
+
[data-ui-theme='glass'] [data-slot='sheet-overlay'] {
|
|
220
|
+
background-color: var(--glass-overlay);
|
|
221
|
+
-webkit-backdrop-filter: blur(6px) saturate(1.2);
|
|
222
|
+
backdrop-filter: blur(6px) saturate(1.2);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
[data-ui-theme='glass'] [data-slot='dialog-content'],
|
|
226
|
+
[data-ui-theme='glass'] [data-slot='alert-dialog-content'],
|
|
227
|
+
[data-ui-theme='glass'] [data-slot='sheet-content'] {
|
|
228
|
+
background-color: var(--popover);
|
|
229
|
+
color: var(--popover-foreground);
|
|
230
|
+
border: 1px solid var(--glass-rim);
|
|
231
|
+
box-shadow: var(--glass-highlight), var(--glass-shadow-float);
|
|
232
|
+
background-clip: padding-box;
|
|
233
|
+
-webkit-backdrop-filter: blur(40px) saturate(var(--glass-saturate));
|
|
234
|
+
backdrop-filter: blur(40px) saturate(var(--glass-saturate));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
[data-ui-theme='glass'] [data-slot='dialog-content'],
|
|
238
|
+
[data-ui-theme='glass'] [data-slot='alert-dialog-content'] {
|
|
239
|
+
border-radius: calc(var(--radius) + 6px);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
[data-ui-theme='glass'] [data-slot='dialog-footer'],
|
|
243
|
+
[data-ui-theme='glass'] [data-slot='sheet-footer'] {
|
|
244
|
+
border-color: var(--border);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* A footer bar that sits on a separator gets a faint frosted band. */
|
|
248
|
+
[data-ui-theme='glass'] [data-slot='dialog-footer'].border-t {
|
|
249
|
+
background-color: color-mix(in oklch, var(--popover) 55%, transparent);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
[data-ui-theme='glass'] [data-slot='popover-content'],
|
|
253
|
+
[data-ui-theme='glass'] [data-slot='select-content'],
|
|
254
|
+
[data-ui-theme='glass'] [data-slot='dropdown-menu-content'],
|
|
255
|
+
[data-ui-theme='glass'] [data-slot='dropdown-menu-sub-content'],
|
|
256
|
+
[data-ui-theme='glass'] [data-slot='context-menu-content'] {
|
|
257
|
+
background-color: var(--popover);
|
|
258
|
+
border-color: var(--glass-rim);
|
|
259
|
+
box-shadow: var(--glass-highlight), var(--glass-shadow);
|
|
260
|
+
background-clip: padding-box;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* ─── Fields ─── */
|
|
264
|
+
[data-ui-theme='glass'] [data-slot='input'],
|
|
265
|
+
[data-ui-theme='glass'] [data-slot='textarea'],
|
|
266
|
+
[data-ui-theme='glass'] [data-slot='select-trigger'],
|
|
267
|
+
[data-ui-theme='glass'] [data-slot='command-input-wrapper'] {
|
|
268
|
+
background-color: var(--glass-field);
|
|
269
|
+
border-color: var(--input);
|
|
270
|
+
box-shadow: var(--glass-highlight);
|
|
271
|
+
transition:
|
|
272
|
+
background-color 150ms ease,
|
|
273
|
+
border-color 150ms ease,
|
|
274
|
+
box-shadow 150ms ease;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
[data-ui-theme='glass'] [data-slot='input']:hover:not(:disabled),
|
|
278
|
+
[data-ui-theme='glass'] [data-slot='textarea']:hover:not(:disabled),
|
|
279
|
+
[data-ui-theme='glass'] [data-slot='select-trigger']:hover:not(:disabled) {
|
|
280
|
+
background-color: var(--glass-field-hover);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
[data-ui-theme='glass'] [data-slot='input']:focus-visible,
|
|
284
|
+
[data-ui-theme='glass'] [data-slot='textarea']:focus-visible,
|
|
285
|
+
[data-ui-theme='glass'] [data-slot='select-trigger']:focus-visible,
|
|
286
|
+
[data-ui-theme='glass'] [data-slot='select-trigger'][data-state='open'] {
|
|
287
|
+
background-color: var(--glass-field-hover);
|
|
288
|
+
border-color: var(--primary);
|
|
289
|
+
box-shadow:
|
|
290
|
+
var(--glass-highlight),
|
|
291
|
+
0 0 0 3px color-mix(in oklch, var(--primary) 28%, transparent);
|
|
292
|
+
outline: none;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* ─── Tables (DynamicTable and any metacore-ui <Table>) ─── */
|
|
296
|
+
[data-ui-theme='glass'] [data-slot='table-head'] {
|
|
297
|
+
background-color: var(--glass-thead);
|
|
298
|
+
border-bottom: 1px solid var(--border);
|
|
299
|
+
-webkit-backdrop-filter: blur(16px) saturate(var(--glass-saturate));
|
|
300
|
+
backdrop-filter: blur(16px) saturate(var(--glass-saturate));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
[data-ui-theme='glass'] [data-slot='table-row'] {
|
|
304
|
+
border-color: var(--border);
|
|
305
|
+
transition: background-color 120ms ease;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
[data-ui-theme='glass'] [data-slot='table-body'] [data-slot='table-row']:hover {
|
|
309
|
+
background-color: var(--glass-row-hover);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
[data-ui-theme='glass'] [data-slot='table-row'][data-state='selected'] {
|
|
313
|
+
background-color: color-mix(in oklch, var(--primary) 10%, transparent);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/* Sticky cells (actions column, totals footer) must not show rows through. */
|
|
317
|
+
[data-ui-theme='glass'] [data-slot='table-cell'].sticky {
|
|
318
|
+
background-color: var(--glass-thead);
|
|
319
|
+
-webkit-backdrop-filter: blur(16px) saturate(var(--glass-saturate));
|
|
320
|
+
backdrop-filter: blur(16px) saturate(var(--glass-saturate));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* ─── Without backdrop-filter translucency just muddies text ─── */
|
|
324
|
+
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
325
|
+
[data-ui-theme='glass'] {
|
|
326
|
+
--background: oklch(0.97 0.02 250 / 0.92);
|
|
327
|
+
--card: oklch(1 0 0 / 0.94);
|
|
328
|
+
--popover: oklch(1 0 0 / 0.98);
|
|
329
|
+
--sidebar: oklch(0.99 0.008 250 / 0.92);
|
|
330
|
+
--glass-thead: oklch(0.98 0.01 250);
|
|
331
|
+
--glass-field: oklch(1 0 0 / 0.9);
|
|
332
|
+
--glass-overlay: oklch(0.3 0.03 260 / 0.4);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.dark[data-ui-theme='glass'] {
|
|
336
|
+
--background: oklch(0.2 0.03 250 / 0.94);
|
|
337
|
+
--card: oklch(0.24 0.03 250 / 0.94);
|
|
338
|
+
--popover: oklch(0.22 0.03 250 / 0.98);
|
|
339
|
+
--sidebar: oklch(0.17 0.03 250 / 0.94);
|
|
340
|
+
--glass-thead: oklch(0.24 0.03 250);
|
|
341
|
+
--glass-field: oklch(0.26 0.03 250);
|
|
342
|
+
--glass-overlay: oklch(0.05 0.02 260 / 0.7);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
347
|
+
[data-ui-theme='glass'] {
|
|
348
|
+
--background: oklch(0.97 0.02 250 / 0.94);
|
|
349
|
+
--card: oklch(1 0 0 / 0.95);
|
|
350
|
+
--popover: oklch(1 0 0 / 0.98);
|
|
351
|
+
--sidebar: oklch(0.99 0.008 250 / 0.94);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.dark[data-ui-theme='glass'] {
|
|
355
|
+
--background: oklch(0.2 0.03 250 / 0.95);
|
|
356
|
+
--card: oklch(0.24 0.03 250 / 0.95);
|
|
357
|
+
--popover: oklch(0.22 0.03 250 / 0.98);
|
|
358
|
+
--sidebar: oklch(0.17 0.03 250 / 0.95);
|
|
359
|
+
}
|
|
360
|
+
}
|
package/styles/index.css
CHANGED
|
@@ -65,35 +65,34 @@
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/* styles.css */
|
|
68
|
+
/*
|
|
69
|
+
* Sidebar module groups are Radix <Collapsible defaultOpen>, so on mount they
|
|
70
|
+
* paint with data-state='open' immediately. A keyframe `animation` RUNS on that
|
|
71
|
+
* initial mount — and because Radix has not yet measured
|
|
72
|
+
* `--radix-collapsible-content-height` in the first frame, a `slideDown` from
|
|
73
|
+
* height:0 with `overflow:hidden` and no `animation-fill-mode` could settle the
|
|
74
|
+
* group at a wrong height, shoving the group below it up and making its items
|
|
75
|
+
* overlap. This surfaces specifically when returning from a full-screen route
|
|
76
|
+
* (e.g. the POS) that lives outside the authenticated shell: leaving it remounts
|
|
77
|
+
* the whole sidebar and re-triggers the mount animation.
|
|
78
|
+
*
|
|
79
|
+
* Fix: use a `transition` instead of a keyframe `animation`. A transition does
|
|
80
|
+
* NOT run on the initial render (there is no prior value to interpolate from),
|
|
81
|
+
* so a freshly-mounted defaultOpen group simply appears at its correct height —
|
|
82
|
+
* no measurement race — while genuine open/close toggles still animate.
|
|
83
|
+
*/
|
|
68
84
|
.CollapsibleContent {
|
|
69
85
|
overflow: hidden;
|
|
86
|
+
height: 0;
|
|
70
87
|
}
|
|
71
88
|
|
|
72
89
|
.CollapsibleContent[data-state='open'] {
|
|
73
|
-
|
|
90
|
+
height: var(--radix-collapsible-content-height);
|
|
74
91
|
}
|
|
75
92
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
@keyframes slideDown {
|
|
81
|
-
from {
|
|
82
|
-
height: 0;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
to {
|
|
86
|
-
height: var(--radix-collapsible-content-height);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@keyframes slideUp {
|
|
91
|
-
from {
|
|
92
|
-
height: var(--radix-collapsible-content-height);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
to {
|
|
96
|
-
height: 0;
|
|
93
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
94
|
+
.CollapsibleContent {
|
|
95
|
+
transition: height 300ms ease-out;
|
|
97
96
|
}
|
|
98
97
|
}
|
|
99
98
|
|