@dvcol/neo-svelte 0.1.1 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.1.2](https://github.com/dvcol/neo-svelte/compare/v0.1.1...v0.1.2) (2024-11-25)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **selector:** prevent $effect loop when provider props change ([2d9f6b1](https://github.com/dvcol/neo-svelte/commit/2d9f6b150ea69e6e66b111bf0b3ac4baea83c8d5))
11
+ * **style:** bundle theme scss with component & make reset optional ([1712a25](https://github.com/dvcol/neo-svelte/commit/1712a25ad42b3528783f09da1f8cd9fecc54f20f))
12
+
5
13
  ### 0.1.1 (2024-11-25)
6
14
 
7
15
 
@@ -1,7 +1,4 @@
1
1
  <script lang="ts">
2
- import '~/styles/reset.scss';
3
- import '~/styles/theme.scss';
4
-
5
2
  import { onDestroy } from 'svelte';
6
3
 
7
4
  import { setNeoThemeContext } from './neo-theme-provider-context.svelte.js';
@@ -13,16 +10,619 @@
13
10
  children,
14
11
 
15
12
  // States
16
- theme = $bindable(),
17
- source = $bindable(),
18
- remember = $bindable(),
13
+ reset,
14
+ theme,
15
+ source,
16
+ remember,
19
17
  target,
20
18
  }: NeoThemeProviderProps = $props();
21
19
  /* eslint-enable prefer-const */
22
20
 
23
- const context = setNeoThemeContext({ theme, source, remember, root: target });
24
- $effect(() => context.update({ theme, source, remember, root: target }));
21
+ const context = setNeoThemeContext({ reset, theme, source, remember, root: target });
22
+ $effect(() => context.update({ reset, theme, source, remember, root: target }));
25
23
  onDestroy(() => context.destroy());
26
24
  </script>
27
25
 
28
26
  {@render children?.(context.state)}
27
+
28
+ <style global>[neo-reset] {
29
+ /*
30
+ Use a more-intuitive box-sizing model.
31
+ */
32
+ /* Remove default */
33
+ /* Global defaults */
34
+ /*
35
+ Typographic tweaks!
36
+ - Add accessible line-height
37
+ - Improve text rendering
38
+ */
39
+ /* Improve media defaults */
40
+ /* Avoid ugly unbalanced word wrap */
41
+ /* Avoid ugly orphan word wrap */
42
+ /* Declare as container for container queries */
43
+ }
44
+ [neo-reset] *,
45
+ [neo-reset] *::before,
46
+ [neo-reset] *::after {
47
+ box-sizing: border-box;
48
+ }
49
+ [neo-reset] * {
50
+ margin: 0;
51
+ padding: 0;
52
+ font: inherit;
53
+ }
54
+ [neo-reset] :host,
55
+ [neo-reset] html {
56
+ /* Default to dark mode */
57
+ color-scheme: dark light;
58
+ hanging-punctuation: first last;
59
+ }
60
+ [neo-reset] :host,
61
+ [neo-reset] body {
62
+ min-height: 100svh;
63
+ line-height: 1.5rem;
64
+ -webkit-font-smoothing: antialiased;
65
+ transition-behavior: allow-discrete;
66
+ interpolate-size: allow-keywords;
67
+ }
68
+ [neo-reset] img,
69
+ [neo-reset] picture,
70
+ [neo-reset] video,
71
+ [neo-reset] canvas,
72
+ [neo-reset] svg {
73
+ display: block;
74
+ max-width: 100%;
75
+ }
76
+ [neo-reset] h1,
77
+ [neo-reset] h2,
78
+ [neo-reset] h3,
79
+ [neo-reset] h4,
80
+ [neo-reset] h5,
81
+ [neo-reset] h6 {
82
+ text-wrap: balance;
83
+ }
84
+ [neo-reset] p,
85
+ [neo-reset] li,
86
+ [neo-reset] figcaption {
87
+ max-width: 80ch;
88
+ text-wrap: pretty;
89
+ }
90
+ [neo-reset] :host > :is(header, main, footer),
91
+ [neo-reset] body > :is(header, main, footer),
92
+ [neo-reset] section,
93
+ [neo-reset] article {
94
+ container-type: inline-size;
95
+ }
96
+ @media (prefers-reduced-motion: reduce) {
97
+ [neo-reset] :has(:target) {
98
+ scroll-behavior: smooth;
99
+ scroll-padding-top: 3rem;
100
+ }
101
+ }
102
+
103
+ [neo-theme-root] {
104
+ --neo-z-index-behind: -1;
105
+ --neo-z-index-default: 0;
106
+ --neo-z-index-in-front: 1;
107
+ --neo-z-index-layer-1: 10;
108
+ --neo-z-index-layer-2: 100;
109
+ --neo-z-index-layer-3: 200;
110
+ --neo-z-index-layer-4: 300;
111
+ --neo-z-index-layer-5: 400;
112
+ --neo-z-index-layer-ui: 1000;
113
+ --neo-z-index-layer-max: 2147483647;
114
+ }
115
+
116
+ [neo-theme-root] {
117
+ /* ui color variables */
118
+ --neo-white: oklch(100% 0 0deg);
119
+ --neo-white-soft-light: oklch(from var(--neo-white-soft) calc(l + 0.05) c h);
120
+ --neo-white-soft-light-50: oklch(from var(--neo-white-soft-light) l c h / 50%);
121
+ --neo-white-soft: oklch(92.9% 0.009 279.682deg);
122
+ --neo-white-soft-10: oklch(from var(--neo-white-soft) l c h / 10%);
123
+ --neo-white-soft-15: oklch(from var(--neo-white-soft) l c h / 15%);
124
+ --neo-white-soft-20: oklch(from var(--neo-white-soft) l c h / 20%);
125
+ --neo-white-soft-dark: oklch(from var(--neo-white-soft) calc(l - 0.075) c h);
126
+ --neo-white-soft-dark-80: oklch(from var(--neo-white-soft-dark) l c h / 80%);
127
+ --neo-black: oklch(0% 0 0deg);
128
+ --neo-black-5: oklch(from var(--neo-black) l c h / 5%);
129
+ --neo-black-lighter-50: oklch(from var(--neo-black-lighter) l c h / 50%);
130
+ --neo-black-lighter: oklch(from var(--neo-black-soft) calc(l + 0.1) c h);
131
+ --neo-black-light: oklch(from var(--neo-black-soft) calc(l + 0.05) c h);
132
+ --neo-black-soft: oklch(33% 0 264.416deg);
133
+ --neo-black-soft-10: oklch(from var(--neo-black-soft) l c h / 10%);
134
+ --neo-black-soft-dark: oklch(from var(--neo-black-soft) calc(l - 0.05) c h);
135
+ --neo-black-soft-dark-50: oklch(from var(--neo-black-soft-dark) l c h / 50%);
136
+ --neo-grey: oklch(from var(--neo-black-soft) calc(l + 0.612) c h);
137
+ --neo-grey-soft: oklch(from var(--neo-grey) calc(l - 0.15) c h);
138
+ --neo-grey-soft-5: oklch(from var(--neo-grey-soft) l c h / 5%);
139
+ --neo-grey-soft-10: oklch(from var(--neo-grey-soft) l c h / 10%);
140
+ --neo-grey-soft-12: oklch(from var(--neo-grey-soft) l c h / 12%);
141
+ --neo-grey-soft-20: oklch(from var(--neo-grey-soft) l c h / 20%);
142
+ --neo-grey-soft-30: oklch(from var(--neo-grey-soft) l c h / 30%);
143
+ --neo-grey-soft-60: oklch(from var(--neo-grey-soft) l c h / 60%);
144
+ --neo-grey-strong: oklch(from var(--neo-grey) calc(l - 0.4) c h);
145
+ --neo-grey-strong-5: oklch(from var(--neo-grey-strong) l c h / 5%);
146
+ --neo-grey-strong-8: oklch(from var(--neo-grey-strong) l c h / 8%);
147
+ --neo-grey-strong-10: oklch(from var(--neo-grey-strong) l c h / 10%);
148
+ --neo-grey-strong-12: oklch(from var(--neo-grey-strong) l c h / 12%);
149
+ --neo-grey-strong-20: oklch(from var(--neo-grey-strong) l c h / 20%);
150
+ --neo-grey-strong-60: oklch(from var(--neo-grey-strong) l c h / 60%);
151
+ --neo-grey-strong-80: oklch(from var(--neo-grey-strong) l c h / 80%);
152
+ --neo-grey-dark: oklch(from var(--neo-grey-strong) calc(l - 0.1) c h);
153
+ --neo-grey-dark-80: oklch(from var(--neo-grey-dark) l c h / 80%);
154
+ --neo-blue: oklch(50% 0.302 264.206deg);
155
+ --neo-blue-50: oklch(from var(--neo-blue) l c h / 50%);
156
+ --neo-blue-80: oklch(from var(--neo-blue) l c h / 80%);
157
+ --neo-blue-soft: oklch(from var(--neo-blue) calc(l + 0.4) c h);
158
+ --neo-blue-soft-50: oklch(from var(--neo-blue-soft) l c h / 50%);
159
+ --neo-blue-soft-80: oklch(from var(--neo-blue-soft) l c h / 80%);
160
+ --neo-red-light: oklch(from var(--neo-red) calc(l + 0.25) c h);
161
+ --neo-red-light-5: oklch(from var(--neo-red-light) l c h / 5%);
162
+ --neo-red-light-10: oklch(from var(--neo-red-light) l c h / 10%);
163
+ --neo-red-light-50: oklch(from var(--neo-red-light) l c h / 50%);
164
+ --neo-red-light-75: oklch(from var(--neo-red-light) l c h / 75%);
165
+ --neo-red: oklch(50% 0.302 26.206deg);
166
+ --neo-red-5: oklch(from var(--neo-red) l c h / 5%);
167
+ --neo-red-10: oklch(from var(--neo-red) l c h / 10%);
168
+ --neo-red-50: oklch(from var(--neo-red) l c h / 50%);
169
+ --neo-red-75: oklch(from var(--neo-red) l c h / 75%);
170
+ --neo-green-light: oklch(from var(--neo-green) calc(l + 0.25) c h);
171
+ --neo-green-light-50: oklch(from var(--neo-green-light) l c h / 50%);
172
+ --neo-green: oklch(52% 0.177 142.495deg);
173
+ --neo-green-50: oklch(from var(--neo-green) l c h / 50%);
174
+ /** primary colors */
175
+ --neo-color-primary: var(--neo-blue);
176
+ --neo-color-primary-50: var(--neo-blue-50);
177
+ --neo-color-primary-80: var(--neo-blue-80);
178
+ --neo-color-error: var(--neo-red);
179
+ --neo-color-error-5: var(--neo-red-5);
180
+ --neo-color-error-10: var(--neo-red-10);
181
+ --neo-color-error-50: var(--neo-red-50);
182
+ --neo-color-error-75: var(--neo-red-75);
183
+ --neo-color-success: var(--neo-green);
184
+ --neo-color-success-50: var(--neo-green-50);
185
+ /** semantic colors */
186
+ --neo-text-color: var(--neo-grey-strong);
187
+ --neo-text-color-active: color-mix(in srgb, currentcolor, white 10%);
188
+ --neo-text-color-focused: var(--neo-color-primary-50);
189
+ --neo-text-color-focused-active: color-mix(in srgb, var(--neo-text-color-focused), white 10%);
190
+ --neo-text-color-hover: var(--neo-color-primary-80);
191
+ --neo-text-color-hover-active: color-mix(in srgb, var(--neo-text-color-hover), white 20%);
192
+ --neo-text-color-disabled: var(--neo-grey-strong-60);
193
+ --neo-text-highlight-color: var(--neo-grey-soft-30);
194
+ --neo-border-color: var(--neo-grey-soft);
195
+ --neo-border-color-focused: var(--neo-color-primary-50);
196
+ --neo-border-color-primary: var(--neo-color-primary-80);
197
+ --neo-border-color-disabled: var(--neo-grey-soft-60);
198
+ --neo-background-color: var(--neo-white-soft);
199
+ --neo-background-color-lighter: color-mix(in srgb, var(--neo-background-color), white 5%);
200
+ --neo-background-color-darker: color-mix(in srgb, var(--neo-background-color, transparent), black 5%);
201
+ --neo-shadow-color-light: var(--neo-white-soft-light);
202
+ --neo-shadow-color-dark: var(--neo-white-soft-dark);
203
+ --neo-skeleton-color: var(--neo-grey-soft);
204
+ --neo-skeleton-color-step: 0.1;
205
+ --neo-close-color: var(--neo-color-error);
206
+ --neo-close-color-hover: var(--neo-color-error-75);
207
+ --neo-close-color-focused: var(--neo-color-error-50);
208
+ --neo-close-bg-color-hover: var(--neo-color-error-10);
209
+ --neo-close-bg-color-focused: var(--neo-color-error-5);
210
+ --neo-scrollbar-color: var(--neo-grey-soft-60);
211
+ /** glass colors */
212
+ --neo-glass-background-color: var(--neo-white-soft-20);
213
+ --neo-glass-background-color-focus: var(--neo-white-soft-15);
214
+ --neo-glass-background-color-hover: var(--neo-white-soft-10);
215
+ --neo-glass-shadow-color: var(--neo-black-soft-10);
216
+ --neo-glass-border-color: var(--neo-white-soft-light-50);
217
+ --neo-glass-border-color-hover: var(--neo-glass-background-color);
218
+ --neo-glass-skeleton-color: var(--neo-grey-soft-60);
219
+ /** dark primary colors */
220
+ --neo-dark-color-primary: var(--neo-blue-soft);
221
+ --neo-dark-color-primary-50: var(--neo-blue-soft-50);
222
+ --neo-dark-color-primary-80: var(--neo-blue-soft-80);
223
+ --neo-dark-color-error: var(--neo-red-light);
224
+ --neo-dark-color-error-5: var(--neo-red-light-5);
225
+ --neo-dark-color-error-10: var(--neo-red-light-10);
226
+ --neo-dark-color-error-50: var(--neo-red-light-50);
227
+ --neo-dark-color-error-75: var(--neo-red-light-75);
228
+ --neo-dark-color-success: var(--neo-green-light);
229
+ --neo-dark-color-success-50: var(--neo-green-light-50);
230
+ /** dark mode semantic colors */
231
+ --neo-dark-text-color: var(--neo-white-soft-dark);
232
+ --neo-dark-text-color-active: color-mix(in srgb, currentcolor, black 10%);
233
+ --neo-dark-text-color-focused: var(--neo-dark-color-primary-50);
234
+ --neo-dark-text-color-focused-active: color-mix(in srgb, var(--neo-dark-text-color-focused), black 10%);
235
+ --neo-dark-text-color-hover: var(--neo-dark-color-primary-80);
236
+ --neo-dark-text-color-hover-active: color-mix(in srgb, var(--neo-dark-text-color-hover), black 20%);
237
+ --neo-dark-text-color-disabled: var(--neo-white-soft-dark-80);
238
+ --neo-dark-text-highlight-color: var(--neo-grey-soft-20);
239
+ --neo-dark-border-color: var(--neo-grey-dark);
240
+ --neo-dark-border-color-focused: var(--neo-dark-color-primary-50);
241
+ --neo-dark-border-color-primary: var(--neo-dark-color-primary-80);
242
+ --neo-dark-border-color-disabled: var(--neo-grey-dark-80);
243
+ --neo-dark-background-color: var(--neo-black-soft);
244
+ --neo-dark-background-color-lighter: color-mix(in srgb, var(--neo-background-color), black 5%);
245
+ --neo-dark-background-color-darker: color-mix(in srgb, var(--neo-background-color, transparent), white 5%);
246
+ --neo-dark-shadow-color-light: var(--neo-black-light);
247
+ --neo-dark-shadow-color-dark: var(--neo-black-soft-dark);
248
+ --neo-dark-skeleton-color: var(--neo-grey-dark);
249
+ --neo-dark-skeleton-color-step: 0.05;
250
+ --neo-dark-close-color: var(--neo-dark-color-error);
251
+ --neo-dark-close-color-hover: var(--neo-dark-color-error-75);
252
+ --neo-dark-close-color-focused: var(--neo-dark-color-error-50);
253
+ --neo-dark-close-bg-color-hover: var(--neo-dark-color-error-10);
254
+ --neo-dark-close-bg-color-focused: var(--neo-dark-color-error-5);
255
+ --neo-dark-scrollbar-color: var(--neo-grey-dark-80);
256
+ /** dark mode glass colors */
257
+ --neo-dark-glass-background-color: var(--neo-grey-strong-8);
258
+ --neo-dark-glass-background-color-focus: var(--neo-grey-strong-10);
259
+ --neo-dark-glass-background-color-hover: var(--neo-grey-strong-12);
260
+ --neo-dark-glass-shadow-color: var(--neo-black-soft-dark-50);
261
+ --neo-dark-glass-border-color: var(--neo-black-lighter-50);
262
+ --neo-dark-glass-border-color-hover: var(--neo-dark-glass-background-color);
263
+ --neo-dark-glass-skeleton-color: var(--neo-grey-dark-80);
264
+ /* override semantic color if dark mode is enabled */
265
+ /* apply dark mode if not overridden */
266
+ }
267
+ [neo-theme-root][neo-theme=dark] {
268
+ /** primary colors */
269
+ --neo-color-primary: var(--neo-dark-color-primary);
270
+ --neo-color-primary-50: var(--neo-dark-color-primary-50);
271
+ --neo-color-primary-80: var(--neo-dark-color-primary-80);
272
+ --neo-color-error: var(--neo-dark-color-error);
273
+ --neo-color-error-5: var(--neo-dark-color-error-5);
274
+ --neo-color-error-10: var(--neo-dark-color-error-10);
275
+ --neo-color-error-50: var(--neo-dark-color-error-50);
276
+ --neo-color-error-75: var(--neo-dark-color-error-75);
277
+ --neo-color-success: var(--neo-dark-color-success);
278
+ --neo-color-success-50: var(--neo-dark-color-success-50);
279
+ /** semantic colors */
280
+ --neo-text-color: var(--neo-dark-text-color);
281
+ --neo-text-color-active: var(--neo-dark-text-color-active);
282
+ --neo-text-color-focused: var(--neo-dark-text-color-focused);
283
+ --neo-text-color-focused-active: var(--neo-dark-text-color-focused-active);
284
+ --neo-text-color-hover: var(--neo-dark-text-color-hover);
285
+ --neo-text-color-hover-active: var(--neo-dark-text-color-hover-active);
286
+ --neo-text-color-disabled: var(--neo-dark-text-color-disabled);
287
+ --neo-text-highlight-color: var(--neo-dark-text-highlight-color);
288
+ --neo-border-color: var(--neo-dark-border-color);
289
+ --neo-border-color-focused: var(--neo-dark-border-color-focused);
290
+ --neo-border-color-primary: var(--neo-dark-border-color-primary);
291
+ --neo-border-color-disabled: var(--neo-dark-border-color-disabled);
292
+ --neo-background-color: var(--neo-dark-background-color);
293
+ --neo-background-color-lighter: var(--neo-dark-background-color-lighter);
294
+ --neo-background-color-darker: var(--neo-dark-background-color-darker);
295
+ --neo-shadow-color-light: var(--neo-dark-shadow-color-light);
296
+ --neo-shadow-color-dark: var(--neo-dark-shadow-color-dark);
297
+ --neo-skeleton-color: var(--neo-dark-skeleton-color);
298
+ --neo-skeleton-color-step: var(--neo-dark-skeleton-color-step);
299
+ --neo-close-color: var(--neo-dark-close-color);
300
+ --neo-close-color-hover: var(--neo-dark-close-color-hover);
301
+ --neo-close-color-focused: var(--neo-dark-close-color-focused);
302
+ --neo-close-bg-color-hover: var(--neo-dark-close-bg-color-hover);
303
+ --neo-close-bg-color-focused: var(--neo-dark-close-bg-color-focused);
304
+ --neo-scrollbar-color: var(--neo-dark-scrollbar-color);
305
+ /** glass colors */
306
+ --neo-glass-background-color: var(--neo-dark-glass-background-color);
307
+ --neo-glass-background-color-focus: var(--neo-dark-glass-background-color-focus);
308
+ --neo-glass-background-color-hover: var(--neo-dark-glass-background-color-hover);
309
+ --neo-glass-shadow-color: var(--neo-dark-glass-shadow-color);
310
+ --neo-glass-border-color: var(--neo-dark-glass-border-color);
311
+ --neo-glass-border-color-hover: var(--neo-dark-glass-border-color-hover);
312
+ --neo-glass-skeleton-color: var(--neo-dark-glass-skeleton-color);
313
+ }
314
+ @media (prefers-color-scheme: dark) {
315
+ [neo-theme-root]:not([neo-theme=light]) {
316
+ /** primary colors */
317
+ --neo-color-primary: var(--neo-dark-color-primary);
318
+ --neo-color-primary-50: var(--neo-dark-color-primary-50);
319
+ --neo-color-primary-80: var(--neo-dark-color-primary-80);
320
+ --neo-color-error: var(--neo-dark-color-error);
321
+ --neo-color-error-5: var(--neo-dark-color-error-5);
322
+ --neo-color-error-10: var(--neo-dark-color-error-10);
323
+ --neo-color-error-50: var(--neo-dark-color-error-50);
324
+ --neo-color-error-75: var(--neo-dark-color-error-75);
325
+ --neo-color-success: var(--neo-dark-color-success);
326
+ --neo-color-success-50: var(--neo-dark-color-success-50);
327
+ /** semantic colors */
328
+ --neo-text-color: var(--neo-dark-text-color);
329
+ --neo-text-color-active: var(--neo-dark-text-color-active);
330
+ --neo-text-color-focused: var(--neo-dark-text-color-focused);
331
+ --neo-text-color-focused-active: var(--neo-dark-text-color-focused-active);
332
+ --neo-text-color-hover: var(--neo-dark-text-color-hover);
333
+ --neo-text-color-hover-active: var(--neo-dark-text-color-hover-active);
334
+ --neo-text-color-disabled: var(--neo-dark-text-color-disabled);
335
+ --neo-text-highlight-color: var(--neo-dark-text-highlight-color);
336
+ --neo-border-color: var(--neo-dark-border-color);
337
+ --neo-border-color-focused: var(--neo-dark-border-color-focused);
338
+ --neo-border-color-primary: var(--neo-dark-border-color-primary);
339
+ --neo-border-color-disabled: var(--neo-dark-border-color-disabled);
340
+ --neo-background-color: var(--neo-dark-background-color);
341
+ --neo-background-color-lighter: var(--neo-dark-background-color-lighter);
342
+ --neo-background-color-darker: var(--neo-dark-background-color-darker);
343
+ --neo-shadow-color-light: var(--neo-dark-shadow-color-light);
344
+ --neo-shadow-color-dark: var(--neo-dark-shadow-color-dark);
345
+ --neo-skeleton-color: var(--neo-dark-skeleton-color);
346
+ --neo-skeleton-color-step: var(--neo-dark-skeleton-color-step);
347
+ --neo-close-color: var(--neo-dark-close-color);
348
+ --neo-close-color-hover: var(--neo-dark-close-color-hover);
349
+ --neo-close-color-focused: var(--neo-dark-close-color-focused);
350
+ --neo-close-bg-color-hover: var(--neo-dark-close-bg-color-hover);
351
+ --neo-close-bg-color-focused: var(--neo-dark-close-bg-color-focused);
352
+ --neo-scrollbar-color: var(--neo-dark-scrollbar-color);
353
+ /** glass colors */
354
+ --neo-glass-background-color: var(--neo-dark-glass-background-color);
355
+ --neo-glass-background-color-focus: var(--neo-dark-glass-background-color-focus);
356
+ --neo-glass-background-color-hover: var(--neo-dark-glass-background-color-hover);
357
+ --neo-glass-shadow-color: var(--neo-dark-glass-shadow-color);
358
+ --neo-glass-border-color: var(--neo-dark-glass-border-color);
359
+ --neo-glass-border-color-hover: var(--neo-dark-glass-border-color-hover);
360
+ --neo-glass-skeleton-color: var(--neo-dark-glass-skeleton-color);
361
+ }
362
+ }
363
+
364
+ [neo-theme-root] {
365
+ /* Default font stack */
366
+ --neo-font-family: "Nunito Sans", ui-rounded, sans-serif;
367
+ /* font variables */
368
+ --neo-font-size-xxs: 0.625rem;
369
+ --neo-font-size-xs: 0.75rem;
370
+ --neo-font-size-sm: 0.875rem;
371
+ --neo-font-size: 1rem;
372
+ --neo-font-size-md: 1.125rem;
373
+ --neo-font-size-lg: 1.25rem;
374
+ --neo-font-size-xl: 1.5rem;
375
+ }
376
+
377
+ [neo-theme-root] {
378
+ /* Blurs */
379
+ --neo-blur-0: blur(0);
380
+ --neo-blur-1: blur(1px);
381
+ --neo-blur-2: blur(2px);
382
+ --neo-blur-3: blur(3px);
383
+ --neo-blur-4: blur(4px);
384
+ --neo-blur-5: blur(8px);
385
+ /* Saturation */
386
+ --neo-saturate: saturate(1);
387
+ --neo-saturate-1: saturate(1.125);
388
+ --neo-saturate-2: saturate(1.25);
389
+ --neo-saturate-3: saturate(1.5);
390
+ --neo-saturate-4: saturate(1.75);
391
+ --neo-saturate-5: saturate(2);
392
+ /* Base shadows flat */
393
+ /* Base shadows raised top left */
394
+ /** Base shadows inset top left */
395
+ /** Glass shadows */
396
+ /** glass border-color */
397
+ /* Box shadows top left */
398
+ /* Base shadows raised top left */
399
+ /** Base shadows inset top left */
400
+ /** Glass shadows */
401
+ /** glass border-color */
402
+ /** Base shadows flat */
403
+ --neo-box-shadow-flat: none;
404
+ /* Box shadows raised top left */
405
+ --neo-box-shadow-raised-1: 0.08rem 0.08rem 0.2rem var(--neo-shadow-color-dark), -0.08rem -0.08rem 0.1rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
406
+ --neo-box-shadow-raised-2: 0.1rem 0.1rem 0.3rem var(--neo-shadow-color-dark), -0.1rem -0.1rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
407
+ --neo-box-shadow-raised-3: 0.3rem 0.3rem 0.3rem var(--neo-shadow-color-dark), -0.2rem -0.2rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
408
+ --neo-box-shadow-raised-4: 0.5rem 0.5rem 0.6rem var(--neo-shadow-color-dark), -0.35rem -0.35rem 0.4rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
409
+ --neo-box-shadow-raised-5: 0.7rem 0.7rem 0.7rem var(--neo-shadow-color-dark), -0.55rem -0.55rem 0.7rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
410
+ /** Base shadows inset top left */
411
+ --neo-box-shadow-inset-1: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.08rem 0.08rem 0.2rem var(--neo-shadow-color-dark), inset -0.08rem -0.08rem 0.1rem var(--neo-shadow-color-light);
412
+ --neo-box-shadow-inset-2: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.15rem 0.15rem 0.3rem var(--neo-shadow-color-dark), inset -0.15rem -0.15rem 0.2rem var(--neo-shadow-color-light);
413
+ --neo-box-shadow-inset-3: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.3rem 0.3rem 0.4rem var(--neo-shadow-color-dark), inset -0.2rem -0.2rem 0.3rem var(--neo-shadow-color-light);
414
+ --neo-box-shadow-inset-4: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.5rem 0.5rem 0.6rem var(--neo-shadow-color-dark), inset -0.35rem -0.35rem 0.4rem var(--neo-shadow-color-light);
415
+ --neo-box-shadow-inset-5: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.8rem 0.8rem 0.7rem var(--neo-shadow-color-dark), inset -0.6rem -0.6rem 0.8rem var(--neo-shadow-color-light);
416
+ /* Glass box shadows raised */
417
+ --neo-glass-box-shadow-raised-1: 0.08rem 0.08rem 0.2rem var(--neo-glass-shadow-color);
418
+ --neo-glass-box-shadow-raised-2: 0.1rem 0.1rem 0.3rem var(--neo-glass-shadow-color);
419
+ --neo-glass-box-shadow-raised-3: 0.3rem 0.3rem 0.3rem var(--neo-glass-shadow-color);
420
+ --neo-glass-box-shadow-raised-4: 0.5rem 0.5rem 0.6rem var(--neo-glass-shadow-color);
421
+ --neo-glass-box-shadow-raised-5: 0.8rem 0.8rem 0.7rem var(--neo-glass-shadow-color);
422
+ /* Glass box shadows inset */
423
+ --neo-glass-box-shadow-inset-1: var(--neo-box-shadow-inset-1);
424
+ --neo-glass-box-shadow-inset-2: var(--neo-box-shadow-inset-2);
425
+ --neo-glass-box-shadow-inset-3: var(--neo-box-shadow-inset-3);
426
+ --neo-glass-box-shadow-inset-4: var(--neo-box-shadow-inset-4);
427
+ --neo-glass-box-shadow-inset-5: var(--neo-box-shadow-inset-5);
428
+ /** glass border-color */
429
+ --neo-glass-top-border-color: var(--neo-glass-border-color);
430
+ --neo-glass-right-border-color: transparent;
431
+ --neo-glass-left-border-color: var(--neo-glass-border-color);
432
+ --neo-glass-bottom-border-color: transparent;
433
+ }
434
+ [neo-theme-root][neo-source=bottom-right] {
435
+ /* Base shadows flat */
436
+ /* Base shadows raised top left */
437
+ /** Base shadows inset top left */
438
+ /** Glass shadows */
439
+ /** glass border-color */
440
+ /* Box shadows top left */
441
+ /* Box shadows raised */
442
+ /* Box shadows inset */
443
+ /** Glass shadows */
444
+ /** glass border-color */
445
+ /** Base shadows flat */
446
+ --neo-box-shadow-flat: none;
447
+ /* Box shadows raised top left */
448
+ --neo-box-shadow-raised-1: -0.08rem -0.08rem 0.2rem var(--neo-shadow-color-dark), 0.08rem 0.08rem 0.1rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
449
+ --neo-box-shadow-raised-2: -0.1rem -0.1rem 0.3rem var(--neo-shadow-color-dark), 0.1rem 0.1rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
450
+ --neo-box-shadow-raised-3: -0.3rem -0.3rem 0.3rem var(--neo-shadow-color-dark), 0.2rem 0.2rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
451
+ --neo-box-shadow-raised-4: -0.5rem -0.5rem 0.6rem var(--neo-shadow-color-dark), 0.35rem 0.35rem 0.4rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
452
+ --neo-box-shadow-raised-5: -0.7rem -0.7rem 0.7rem var(--neo-shadow-color-dark), 0.55rem 0.55rem 0.7rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
453
+ /** Base shadows inset top left */
454
+ --neo-box-shadow-inset-1: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.08rem -0.08rem 0.2rem var(--neo-shadow-color-dark), inset 0.08rem 0.08rem 0.1rem var(--neo-shadow-color-light);
455
+ --neo-box-shadow-inset-2: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.15rem -0.15rem 0.3rem var(--neo-shadow-color-dark), inset 0.15rem 0.15rem 0.2rem var(--neo-shadow-color-light);
456
+ --neo-box-shadow-inset-3: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.3rem -0.3rem 0.4rem var(--neo-shadow-color-dark), inset 0.2rem 0.2rem 0.3rem var(--neo-shadow-color-light);
457
+ --neo-box-shadow-inset-4: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.5rem -0.5rem 0.6rem var(--neo-shadow-color-dark), inset 0.35rem 0.35rem 0.4rem var(--neo-shadow-color-light);
458
+ --neo-box-shadow-inset-5: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.8rem -0.8rem 0.7rem var(--neo-shadow-color-dark), inset 0.6rem 0.6rem 0.8rem var(--neo-shadow-color-light);
459
+ /* Glass box shadows raised */
460
+ --neo-glass-box-shadow-raised-1: -0.08rem -0.08rem 0.2rem var(--neo-glass-shadow-color);
461
+ --neo-glass-box-shadow-raised-2: -0.1rem -0.1rem 0.3rem var(--neo-glass-shadow-color);
462
+ --neo-glass-box-shadow-raised-3: -0.3rem -0.3rem 0.3rem var(--neo-glass-shadow-color);
463
+ --neo-glass-box-shadow-raised-4: -0.5rem -0.5rem 0.6rem var(--neo-glass-shadow-color);
464
+ --neo-glass-box-shadow-raised-5: -0.8rem -0.8rem 0.7rem var(--neo-glass-shadow-color);
465
+ /* Glass box shadows inset */
466
+ --neo-glass-box-shadow-inset-1: var(--neo-box-shadow-inset-1);
467
+ --neo-glass-box-shadow-inset-2: var(--neo-box-shadow-inset-2);
468
+ --neo-glass-box-shadow-inset-3: var(--neo-box-shadow-inset-3);
469
+ --neo-glass-box-shadow-inset-4: var(--neo-box-shadow-inset-4);
470
+ --neo-glass-box-shadow-inset-5: var(--neo-box-shadow-inset-5);
471
+ /** glass border-color */
472
+ --neo-glass-top-border-color: transparent;
473
+ --neo-glass-right-border-color: var(--neo-glass-border-color);
474
+ --neo-glass-left-border-color: transparent;
475
+ --neo-glass-bottom-border-color: var(--neo-glass-border-color);
476
+ }
477
+ [neo-theme-root][neo-source=top-right] {
478
+ /* Base shadows flat */
479
+ /* Base shadows raised top left */
480
+ /** Base shadows inset top left */
481
+ /** Glass shadows */
482
+ /** glass border-color */
483
+ /* Box shadows top left */
484
+ /* Box shadows raised */
485
+ /* Box shadows inset */
486
+ /** Glass shadows */
487
+ /** glass border-color */
488
+ /** Base shadows flat */
489
+ --neo-box-shadow-flat: none;
490
+ /* Box shadows raised top left */
491
+ --neo-box-shadow-raised-1: -0.08rem 0.08rem 0.2rem var(--neo-shadow-color-dark), 0.08rem -0.08rem 0.1rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
492
+ --neo-box-shadow-raised-2: -0.1rem 0.1rem 0.3rem var(--neo-shadow-color-dark), 0.1rem -0.1rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
493
+ --neo-box-shadow-raised-3: -0.3rem 0.3rem 0.3rem var(--neo-shadow-color-dark), 0.2rem -0.2rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
494
+ --neo-box-shadow-raised-4: -0.5rem 0.5rem 0.6rem var(--neo-shadow-color-dark), 0.35rem -0.35rem 0.4rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
495
+ --neo-box-shadow-raised-5: -0.7rem 0.7rem 0.7rem var(--neo-shadow-color-dark), 0.55rem -0.55rem 0.7rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
496
+ /** Base shadows inset top left */
497
+ --neo-box-shadow-inset-1: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.08rem 0.08rem 0.2rem var(--neo-shadow-color-dark), inset 0.08rem -0.08rem 0.1rem var(--neo-shadow-color-light);
498
+ --neo-box-shadow-inset-2: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.15rem 0.15rem 0.3rem var(--neo-shadow-color-dark), inset 0.15rem -0.15rem 0.2rem var(--neo-shadow-color-light);
499
+ --neo-box-shadow-inset-3: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.3rem 0.3rem 0.4rem var(--neo-shadow-color-dark), inset 0.2rem -0.2rem 0.3rem var(--neo-shadow-color-light);
500
+ --neo-box-shadow-inset-4: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.5rem 0.5rem 0.6rem var(--neo-shadow-color-dark), inset 0.35rem -0.35rem 0.4rem var(--neo-shadow-color-light);
501
+ --neo-box-shadow-inset-5: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset -0.8rem 0.8rem 0.7rem var(--neo-shadow-color-dark), inset 0.6rem -0.6rem 0.8rem var(--neo-shadow-color-light);
502
+ /* Glass box shadows raised */
503
+ --neo-glass-box-shadow-raised-1: -0.08rem 0.08rem 0.2rem var(--neo-glass-shadow-color);
504
+ --neo-glass-box-shadow-raised-2: -0.1rem 0.1rem 0.3rem var(--neo-glass-shadow-color);
505
+ --neo-glass-box-shadow-raised-3: -0.3rem 0.3rem 0.3rem var(--neo-glass-shadow-color);
506
+ --neo-glass-box-shadow-raised-4: -0.5rem 0.5rem 0.6rem var(--neo-glass-shadow-color);
507
+ --neo-glass-box-shadow-raised-5: -0.8rem 0.8rem 0.7rem var(--neo-glass-shadow-color);
508
+ /* Glass box shadows inset */
509
+ --neo-glass-box-shadow-inset-1: var(--neo-box-shadow-inset-1);
510
+ --neo-glass-box-shadow-inset-2: var(--neo-box-shadow-inset-2);
511
+ --neo-glass-box-shadow-inset-3: var(--neo-box-shadow-inset-3);
512
+ --neo-glass-box-shadow-inset-4: var(--neo-box-shadow-inset-4);
513
+ --neo-glass-box-shadow-inset-5: var(--neo-box-shadow-inset-5);
514
+ /** glass border-color */
515
+ --neo-glass-top-border-color: var(--neo-glass-border-color);
516
+ --neo-glass-right-border-color: var(--neo-glass-border-color);
517
+ --neo-glass-left-border-color: transparent;
518
+ --neo-glass-bottom-border-color: transparent;
519
+ }
520
+ [neo-theme-root][neo-source=bottom-left] {
521
+ /* Base shadows flat */
522
+ /* Base shadows raised top left */
523
+ /** Base shadows inset top left */
524
+ /** Glass shadows */
525
+ /** glass border-color */
526
+ /* Box shadows top left */
527
+ /* Base shadows raised top left */
528
+ /** Base shadows inset top left */
529
+ /** Glass shadows */
530
+ /** glass border-color */
531
+ /** Base shadows flat */
532
+ --neo-box-shadow-flat: none;
533
+ /* Box shadows raised top left */
534
+ --neo-box-shadow-raised-1: 0.08rem -0.08rem 0.2rem var(--neo-shadow-color-dark), -0.08rem 0.08rem 0.1rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
535
+ --neo-box-shadow-raised-2: 0.1rem -0.1rem 0.3rem var(--neo-shadow-color-dark), -0.1rem 0.1rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
536
+ --neo-box-shadow-raised-3: 0.3rem -0.3rem 0.3rem var(--neo-shadow-color-dark), -0.2rem 0.2rem 0.2rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
537
+ --neo-box-shadow-raised-4: 0.5rem -0.5rem 0.6rem var(--neo-shadow-color-dark), -0.35rem 0.35rem 0.4rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
538
+ --neo-box-shadow-raised-5: 0.7rem -0.7rem 0.7rem var(--neo-shadow-color-dark), -0.55rem 0.55rem 0.7rem var(--neo-shadow-color-light), inset 0 0 0 0 var(--neo-shadow-color-dark), inset 0 0 0 0 var(--neo-shadow-color-light);
539
+ /** Base shadows inset top left */
540
+ --neo-box-shadow-inset-1: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.08rem -0.08rem 0.2rem var(--neo-shadow-color-dark), inset -0.08rem 0.08rem 0.1rem var(--neo-shadow-color-light);
541
+ --neo-box-shadow-inset-2: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.15rem -0.15rem 0.3rem var(--neo-shadow-color-dark), inset -0.15rem 0.15rem 0.2rem var(--neo-shadow-color-light);
542
+ --neo-box-shadow-inset-3: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.3rem -0.3rem 0.4rem var(--neo-shadow-color-dark), inset -0.2rem 0.2rem 0.3rem var(--neo-shadow-color-light);
543
+ --neo-box-shadow-inset-4: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.5rem -0.5rem 0.6rem var(--neo-shadow-color-dark), inset -0.35rem 0.35rem 0.4rem var(--neo-shadow-color-light);
544
+ --neo-box-shadow-inset-5: 0 0 0 0 var(--neo-shadow-color-dark), 0 0 0 0 var(--neo-shadow-color-light), inset 0.8rem -0.8rem 0.7rem var(--neo-shadow-color-dark), inset -0.6rem 0.6rem 0.8rem var(--neo-shadow-color-light);
545
+ /* Glass box shadows raised */
546
+ --neo-glass-box-shadow-raised-1: 0.08rem -0.08rem 0.2rem var(--neo-glass-shadow-color);
547
+ --neo-glass-box-shadow-raised-2: 0.1rem -0.1rem 0.3rem var(--neo-glass-shadow-color);
548
+ --neo-glass-box-shadow-raised-3: 0.3rem -0.3rem 0.3rem var(--neo-glass-shadow-color);
549
+ --neo-glass-box-shadow-raised-4: 0.5rem -0.5rem 0.6rem var(--neo-glass-shadow-color);
550
+ --neo-glass-box-shadow-raised-5: 0.8rem -0.8rem 0.7rem var(--neo-glass-shadow-color);
551
+ /* Glass box shadows inset */
552
+ --neo-glass-box-shadow-inset-1: var(--neo-box-shadow-inset-1);
553
+ --neo-glass-box-shadow-inset-2: var(--neo-box-shadow-inset-2);
554
+ --neo-glass-box-shadow-inset-3: var(--neo-box-shadow-inset-3);
555
+ --neo-glass-box-shadow-inset-4: var(--neo-box-shadow-inset-4);
556
+ --neo-glass-box-shadow-inset-5: var(--neo-box-shadow-inset-5);
557
+ /** glass border-color */
558
+ --neo-glass-top-border-color: transparent;
559
+ --neo-glass-right-border-color: transparent;
560
+ --neo-glass-left-border-color: var(--neo-glass-border-color);
561
+ --neo-glass-bottom-border-color: var(--neo-glass-border-color);
562
+ }
563
+
564
+ [neo-theme-root] {
565
+ /* Borders */
566
+ --neo-border-width: 1px;
567
+ --neo-border-radius: 0.5rem;
568
+ --neo-border-radius-md: 1rem;
569
+ --neo-border-radius-lg: 2rem;
570
+ /* Gap */
571
+ --neo-gap-xxs: 0.5rem;
572
+ --neo-gap-xs: 0.615rem;
573
+ --neo-gap-sm: 0.75rem;
574
+ --neo-gap: 1rem;
575
+ --neo-gap-md: 1.25rem;
576
+ --neo-gap-lg: 2rem;
577
+ --neo-gap-xl: 3rem;
578
+ --neo-gap-xxl: 5rem;
579
+ /* Line height */
580
+ --neo-line-height-xxs: 0.75rem;
581
+ --neo-line-height-xs: 1rem;
582
+ --neo-line-height-sm: 1.25rem;
583
+ --neo-line-height: 1.5rem;
584
+ /* Margin */
585
+ --neo-shadow-margin: 0.6rem;
586
+ --neo-shadow-margin-lg: 1.125rem;
587
+ }
588
+
589
+ [neo-theme-root] {
590
+ /* Transforms */
591
+ --neo-transition-bezier: cubic-bezier(0.4, 0, 0.2, 1);
592
+ --neo-transition-skeleton: cubic-bezier(0.4, 0, 0.6, 1);
593
+ /* Opacity */
594
+ --neo-opacity-disabled: 0.8;
595
+ }
596
+
597
+ @property --neo-angle {
598
+ syntax: "<angle>";
599
+ initial-value: 0deg;
600
+ inherits: false;
601
+ }
602
+ @property --neo-progress {
603
+ syntax: "<percentage>";
604
+ inherits: true;
605
+ initial-value: 0%;
606
+ }
607
+ @property --neo-source-color {
608
+ syntax: "<color>";
609
+ initial-value: transparent;
610
+ inherits: false;
611
+ }
612
+ @property --neo-target-color {
613
+ syntax: "<color>";
614
+ initial-value: transparent;
615
+ inherits: false;
616
+ }
617
+ [neo-theme-root] {
618
+ color: var(--neo-text-color);
619
+ font-family: var(--neo-font-family), sans-serif;
620
+ line-height: var(--neo-line-height);
621
+ background-color: var(--neo-background-color);
622
+ /* touch highlight */
623
+ -webkit-tap-highlight-color: transparent;
624
+ /* cursor highlight */
625
+ }
626
+ [neo-theme-root] *::selection {
627
+ background-color: var(--neo-text-highlight-color);
628
+ }</style>
@@ -1,5 +1,3 @@
1
- import '~/styles/reset.scss';
2
- import '~/styles/theme.scss';
3
1
  import { type NeoThemeProviderProps } from './neo-theme-provider.model.js';
4
2
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
5
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -16,6 +14,6 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
16
14
  }
17
15
  declare const NeoThemeProvider: $$__sveltets_2_IsomorphicComponent<NeoThemeProviderProps, {
18
16
  [evt: string]: CustomEvent<any>;
19
- }, {}, {}, "source" | "theme" | "remember">;
17
+ }, {}, {}, "">;
20
18
  type NeoThemeProvider = InstanceType<typeof NeoThemeProvider>;
21
19
  export default NeoThemeProvider;
@@ -3,6 +3,7 @@
3
3
 
4
4
  import NeoButton from '../buttons/NeoButton.svelte';
5
5
  import NeoButtonGroup from '../buttons/NeoButtonGroup.svelte';
6
+ import IconImage from '../icons/IconImage.svelte';
6
7
  import IconMoon from '../icons/IconMoon.svelte';
7
8
  import IconSave from '../icons/IconSave.svelte';
8
9
  import IconSaveOff from '../icons/IconSaveOff.svelte';
@@ -11,15 +12,30 @@
11
12
  import { useNeoThemeContext } from './neo-theme-provider-context.svelte.js';
12
13
  import { NeoSource, NeoTheme } from './neo-theme-provider.model.js';
13
14
 
14
- const { children, ...rest }: NeoThemeSelectorProps = $props();
15
+ const {
16
+ // Snippet
17
+ children,
15
18
 
16
- const context = useNeoThemeContext();
19
+ // state
20
+ remember: showRemember = true,
21
+ source: showSource = true,
22
+ theme: showTheme = true,
23
+ reset: showReset,
24
+
25
+ // Other props
26
+ rememberProps,
27
+ sourceProps,
28
+ themeProps,
29
+ resetProps,
30
+ ...rest
31
+ }: NeoThemeSelectorProps = $props();
17
32
 
18
- let dark = $state(context.theme === NeoTheme.Dark);
19
- const theme = $derived(dark ? NeoTheme.Dark : NeoTheme.Light);
33
+ const context = useNeoThemeContext();
20
34
 
21
- let source = $state(context.source);
22
- let remember = $state(context.remember);
35
+ const reset = $derived(context.reset);
36
+ const dark = $derived(context.theme === NeoTheme.Dark);
37
+ const source = $derived(context.source);
38
+ const remember = $derived(context.remember);
23
39
 
24
40
  const sources = Object.values(NeoSource);
25
41
  const sourceMap = { ...sources };
@@ -27,42 +43,70 @@
27
43
 
28
44
  let angle = $state(sourceIndexMap[context.source] * 90);
29
45
  const onCycleSource = () => {
30
- source = sourceMap[(sourceIndexMap[source] + 1) % sources.length];
31
46
  angle += 90;
47
+ context.update({ source: sourceMap[(sourceIndexMap[source] + 1) % sources.length] });
32
48
  };
33
49
 
34
- $effect(() => context.update({ theme, source, remember }));
50
+ const onTheme = () => context.update({ theme: dark ? NeoTheme.Light : NeoTheme.Dark });
51
+ const onReset = () => context.update({ reset: !reset });
52
+ const onRemember = () => context.update({ remember: !remember });
35
53
  </script>
36
54
 
37
55
  <NeoButtonGroup {...rest}>
38
- <NeoButton aria-label="Cycle light source origin" title="Cycle light source origin" checked onclick={onCycleSource}>
39
- {#snippet icon()}
40
- <span class="source-icon" style:--neo-source-rotate={`${angle}deg`}>
41
- <IconSunrise />
42
- </span>
43
- {/snippet}
44
- <span>Source</span>
45
- </NeoButton>
46
- <NeoButton aria-label={`Toggle ${dark ? 'light' : 'dark'} theme`} title={`Toggle ${dark ? 'light' : 'dark'} theme`} toggle bind:checked={dark}>
47
- {#snippet icon()}
48
- {#if dark}
49
- <IconMoon />
50
- {:else}
51
- <IconSun />
52
- {/if}
53
- {/snippet}
54
- <span>Theme</span>
55
- </NeoButton>
56
-
57
- <NeoButton aria-label="Remember theme settings" title="Remember theme settings" toggle bind:checked={remember}>
58
- {#snippet icon()}
59
- {#if remember}
60
- <IconSave />
61
- {:else}
62
- <IconSaveOff />
63
- {/if}
64
- {/snippet}
65
- </NeoButton>
56
+ {#if showSource}
57
+ <NeoButton aria-label="Cycle light source origin" title="Cycle light source origin" checked onclick={onCycleSource} {...sourceProps}>
58
+ {#snippet icon()}
59
+ <span class="source-icon" style:--neo-source-rotate={`${angle}deg`}>
60
+ <IconSunrise />
61
+ </span>
62
+ {/snippet}
63
+ <span>Source</span>
64
+ </NeoButton>
65
+ {/if}
66
+ {#if showTheme}
67
+ <NeoButton
68
+ aria-label={`Toggle ${dark ? 'light' : 'dark'} theme`}
69
+ title={`Toggle ${dark ? 'light' : 'dark'} theme`}
70
+ toggle
71
+ checked={dark}
72
+ onclick={onTheme}
73
+ {...themeProps}
74
+ >
75
+ {#snippet icon()}
76
+ {#if dark}
77
+ <IconMoon />
78
+ {:else}
79
+ <IconSun />
80
+ {/if}
81
+ {/snippet}
82
+ <span>Theme</span>
83
+ </NeoButton>
84
+ {/if}
85
+ {#if showReset}
86
+ <NeoButton
87
+ aria-label={`Toggle ${reset ? 'off' : 'on'} style reset`}
88
+ title={`Toggle ${reset ? 'off' : 'on'} style reset`}
89
+ toggle
90
+ checked={reset}
91
+ onclick={onReset}
92
+ {...resetProps}
93
+ >
94
+ {#snippet icon()}
95
+ <IconImage />
96
+ {/snippet}
97
+ </NeoButton>
98
+ {/if}
99
+ {#if showRemember}
100
+ <NeoButton aria-label="Remember theme settings" title="Remember theme settings" toggle checked={remember} onclick={onRemember} {...rememberProps}>
101
+ {#snippet icon()}
102
+ {#if remember}
103
+ <IconSave />
104
+ {:else}
105
+ <IconSaveOff />
106
+ {/if}
107
+ {/snippet}
108
+ </NeoButton>
109
+ {/if}
66
110
  {@render children?.(context.state)}
67
111
  </NeoButtonGroup>
68
112
 
@@ -5,17 +5,19 @@ export type NeoThemeProviderContextState = Partial<Omit<INeoThemeProviderContext
5
5
  };
6
6
  export declare class NeoThemeProviderContext implements INeoThemeProviderContext {
7
7
  #private;
8
+ get reset(): boolean | undefined;
8
9
  get theme(): import("./neo-theme-provider.model.js").NeoThemes;
9
10
  get source(): import("./neo-theme-provider.model.js").NeoSources;
10
11
  get remember(): boolean;
11
12
  get root(): HTMLElement | ShadowRoot | undefined;
12
13
  get state(): {
14
+ reset: boolean | undefined;
13
15
  theme: import("./neo-theme-provider.model.js").NeoThemes;
14
16
  source: import("./neo-theme-provider.model.js").NeoSources;
15
17
  remember: boolean;
16
18
  root: HTMLElement | ShadowRoot | undefined;
17
19
  };
18
- constructor({ theme, source, remember, root }: NeoThemeProviderContextState);
20
+ constructor({ reset, theme, source, remember, root }: NeoThemeProviderContextState);
19
21
  update(partial: Partial<NeoThemeProviderContextState>): void;
20
22
  sync(): void;
21
23
  destroy(): void;
@@ -1,11 +1,15 @@
1
- import { getContext, setContext } from 'svelte';
2
- import { getSource, getTheme, hasSaved, NeoSourceKey, NeoThemeKey, NeoThemeRoot, } from './neo-theme-provider.model.js';
1
+ import { getContext, setContext, untrack } from 'svelte';
2
+ import { getReset, getSource, getTheme, hasSaved, NeoSourceKey, NeoThemeKey, NeoThemeReset, NeoThemeRoot, } from './neo-theme-provider.model.js';
3
3
  import { NeoErrorThemeContextNotFound, NeoErrorThemeInvalidTarget, NeoErrorThemeTargetNotFound } from '../utils/error.utils.js';
4
4
  export class NeoThemeProviderContext {
5
+ #reset = $state(getReset());
5
6
  #theme = $state(getTheme());
6
7
  #source = $state(getSource());
7
8
  #remember = $state(hasSaved());
8
9
  #root = $state(document?.documentElement);
10
+ get reset() {
11
+ return this.#reset;
12
+ }
9
13
  get theme() {
10
14
  return this.#theme;
11
15
  }
@@ -20,13 +24,15 @@ export class NeoThemeProviderContext {
20
24
  }
21
25
  get state() {
22
26
  return {
27
+ reset: this.reset,
23
28
  theme: this.theme,
24
29
  source: this.source,
25
30
  remember: this.remember,
26
31
  root: this.root,
27
32
  };
28
33
  }
29
- constructor({ theme, source, remember, root }) {
34
+ constructor({ reset, theme, source, remember, root }) {
35
+ this.#reset = reset ?? this.reset;
30
36
  this.#theme = theme ?? this.theme;
31
37
  this.#source = source ?? this.source;
32
38
  this.#remember = remember ?? this.remember;
@@ -34,11 +40,19 @@ export class NeoThemeProviderContext {
34
40
  this.sync();
35
41
  }
36
42
  update(partial) {
37
- this.#theme = partial.theme ?? this.#theme;
38
- this.#source = partial.source ?? this.#source;
39
- this.#remember = partial.remember ?? this.#remember;
40
- this.#root = partial.root ?? this.#root;
41
- this.sync();
43
+ untrack(() => {
44
+ if (partial.reset !== undefined)
45
+ this.#reset = partial.reset;
46
+ if (partial.theme !== undefined)
47
+ this.#theme = partial.theme;
48
+ if (partial.source !== undefined)
49
+ this.#source = partial.source;
50
+ if (partial.remember !== undefined)
51
+ this.#remember = partial.remember;
52
+ if (partial.root !== undefined)
53
+ this.#root = partial.root;
54
+ this.sync();
55
+ });
42
56
  }
43
57
  sync() {
44
58
  if (!this.root)
@@ -48,11 +62,19 @@ export class NeoThemeProviderContext {
48
62
  this.root.setAttribute(NeoThemeRoot, '');
49
63
  this.root.setAttribute(NeoThemeKey, this.theme);
50
64
  this.root.setAttribute(NeoSourceKey, this.source);
65
+ if (this.reset)
66
+ this.root.setAttribute(NeoThemeReset, '');
67
+ else
68
+ this.root.removeAttribute(NeoThemeReset);
69
+ if (!localStorage)
70
+ return;
51
71
  if (this.remember) {
72
+ localStorage.setItem(NeoThemeReset, Boolean(this.reset).toString());
52
73
  localStorage.setItem(NeoThemeKey, this.theme);
53
74
  localStorage.setItem(NeoSourceKey, this.source);
54
75
  }
55
76
  else {
77
+ localStorage.removeItem(NeoThemeReset);
56
78
  localStorage.removeItem(NeoThemeKey);
57
79
  localStorage.removeItem(NeoSourceKey);
58
80
  }
@@ -63,6 +85,7 @@ export class NeoThemeProviderContext {
63
85
  if (!('removeAttribute' in this.root))
64
86
  return;
65
87
  this.root.removeAttribute(NeoThemeRoot);
88
+ this.root.removeAttribute(NeoThemeReset);
66
89
  this.root.removeAttribute(NeoThemeKey);
67
90
  this.root.removeAttribute(NeoSourceKey);
68
91
  }
@@ -1,9 +1,15 @@
1
1
  import { type Snippet } from 'svelte';
2
+ /**
3
+ * The active theme (`dark` or `light`)
4
+ */
2
5
  export declare const NeoTheme: {
3
6
  readonly Light: "light";
4
7
  readonly Dark: "dark";
5
8
  };
6
9
  export type NeoThemes = (typeof NeoTheme)[keyof typeof NeoTheme];
10
+ /**
11
+ * The light source to simulate shadows
12
+ */
7
13
  export declare const NeoSource: {
8
14
  readonly TopLeft: "top-left";
9
15
  readonly TopRight: "top-right";
@@ -12,19 +18,63 @@ export declare const NeoSource: {
12
18
  };
13
19
  export type NeoSources = (typeof NeoSource)[keyof typeof NeoSource];
14
20
  export type INeoThemeProviderContext = {
21
+ /**
22
+ * If a style reset is applied.
23
+ */
24
+ readonly reset?: boolean;
25
+ /**
26
+ * The active theme (`dark` or `light`)
27
+ */
15
28
  readonly theme: NeoThemes;
29
+ /**
30
+ * The active light source to simulate shadows
31
+ */
16
32
  readonly source: NeoSources;
33
+ /**
34
+ * If the reset, theme and source are stored in local-storage
35
+ */
17
36
  readonly remember: boolean;
37
+ /**
38
+ * The target to which scope the theme variables
39
+ */
18
40
  readonly root?: HTMLElement | ShadowRoot;
19
41
  };
20
42
  export type NeoThemeProviderProps = {
43
+ /**
44
+ * Child element to wrap in the theme context.
45
+ */
21
46
  children?: Snippet<[INeoThemeProviderContext]>;
47
+ /**
48
+ * If `true`, injects a css reset for common styling.
49
+ */
50
+ reset?: boolean;
51
+ /**
52
+ * Enforce `dark` or `light` theme.
53
+ *
54
+ * @default prefers-color-scheme
55
+ */
22
56
  theme?: NeoThemes;
57
+ /**
58
+ * The light source to simulate shadows
59
+ *
60
+ * @default top-left
61
+ */
23
62
  source?: NeoSources;
63
+ /**
64
+ * To store the last used reset & theme & source in local storage (if available)
65
+ *
66
+ * @default false
67
+ */
24
68
  remember?: boolean;
69
+ /**
70
+ * The target to which scope the theme variables
71
+ *
72
+ * @default document.documentElement
73
+ */
25
74
  target?: HTMLElement | ShadowRoot | (() => HTMLElement | ShadowRoot);
26
75
  };
27
76
  export declare const NeoThemeRoot = "neo-theme-root";
77
+ export declare const NeoThemeReset = "neo-reset";
28
78
  export declare const NeoThemeKey = "neo-theme";
29
79
  export declare const NeoSourceKey = "neo-source";
30
80
  export declare const getSavedTheme: () => NeoThemes | null;
@@ -32,4 +82,6 @@ export declare const getPreferTheme: () => NeoThemes;
32
82
  export declare const getTheme: () => NeoThemes;
33
83
  export declare const getSavedSource: () => NeoSources | null;
34
84
  export declare const getSource: () => NeoSources;
85
+ export declare const getSavedReset: () => string | null;
86
+ export declare const getReset: () => boolean | undefined;
35
87
  export declare const hasSaved: () => boolean;
@@ -1,8 +1,14 @@
1
1
  import {} from 'svelte';
2
+ /**
3
+ * The active theme (`dark` or `light`)
4
+ */
2
5
  export const NeoTheme = {
3
6
  Light: 'light',
4
7
  Dark: 'dark',
5
8
  };
9
+ /**
10
+ * The light source to simulate shadows
11
+ */
6
12
  export const NeoSource = {
7
13
  TopLeft: 'top-left',
8
14
  TopRight: 'top-right',
@@ -10,6 +16,7 @@ export const NeoSource = {
10
16
  BottomLeft: 'bottom-left',
11
17
  };
12
18
  export const NeoThemeRoot = 'neo-theme-root';
19
+ export const NeoThemeReset = 'neo-reset';
13
20
  export const NeoThemeKey = 'neo-theme';
14
21
  export const NeoSourceKey = 'neo-source';
15
22
  export const getSavedTheme = () => localStorage?.getItem(NeoThemeKey);
@@ -17,4 +24,11 @@ export const getPreferTheme = () => (window.matchMedia('(prefers-color-scheme: d
17
24
  export const getTheme = () => getSavedTheme() ?? getPreferTheme();
18
25
  export const getSavedSource = () => localStorage?.getItem(NeoSourceKey);
19
26
  export const getSource = () => getSavedSource() ?? NeoSource.TopLeft;
20
- export const hasSaved = () => !!getSavedTheme() || !!getSavedSource();
27
+ export const getSavedReset = () => localStorage?.getItem(NeoThemeReset);
28
+ export const getReset = () => {
29
+ const reset = getSavedReset();
30
+ if (!reset)
31
+ return;
32
+ return reset === 'true';
33
+ };
34
+ export const hasSaved = () => !!getSavedTheme() || !!getSavedSource() || !!getSavedReset();
@@ -1,6 +1,39 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { NeoButtonProps } from '../buttons/index.js';
2
3
  import type { NeoButtonGroupProps } from '../buttons/neo-button-group.model.js';
3
4
  import type { INeoThemeProviderContext } from './neo-theme-provider.model.js';
4
5
  export type NeoThemeSelectorProps = {
5
6
  children: Snippet<[INeoThemeProviderContext]>;
7
+ /**
8
+ * Whether to show the reset style button or not.
9
+ */
10
+ reset?: boolean;
11
+ /**
12
+ * Whether to show the dark/light theme button or not.
13
+ */
14
+ theme?: boolean;
15
+ /**
16
+ * Whether to show the light source button or not.
17
+ */
18
+ source?: boolean;
19
+ /**
20
+ * Whether to show the remember button or not.
21
+ */
22
+ remember?: boolean;
23
+ /**
24
+ * The props to pass to the reset button.
25
+ */
26
+ resetProps?: NeoButtonProps;
27
+ /**
28
+ * The props to pass to the theme button.
29
+ */
30
+ themeProps?: NeoButtonProps;
31
+ /**
32
+ * The props to pass to the source button.
33
+ */
34
+ sourceProps?: NeoButtonProps;
35
+ /**
36
+ * The props to pass to the remember button.
37
+ */
38
+ rememberProps?: NeoButtonProps;
6
39
  } & Omit<NeoButtonGroupProps, 'children'>;
@@ -1,81 +1,83 @@
1
- /*
2
- Use a more-intuitive box-sizing model.
3
- */
4
- *,
5
- *::before,
6
- *::after {
7
- box-sizing: border-box;
8
- }
1
+ [neo-reset] {
2
+ /*
3
+ Use a more-intuitive box-sizing model.
4
+ */
5
+ *,
6
+ *::before,
7
+ *::after {
8
+ box-sizing: border-box;
9
+ }
9
10
 
10
- /* Remove default */
11
- * {
12
- margin: 0;
13
- padding: 0;
14
- font: inherit;
15
- }
11
+ /* Remove default */
12
+ * {
13
+ margin: 0;
14
+ padding: 0;
15
+ font: inherit;
16
+ }
16
17
 
17
- /* Global defaults */
18
- :host,
19
- html {
20
- /* Default to dark mode */
21
- color-scheme: dark light;
22
- hanging-punctuation: first last;
23
- }
18
+ /* Global defaults */
19
+ :host,
20
+ html {
21
+ /* Default to dark mode */
22
+ color-scheme: dark light;
23
+ hanging-punctuation: first last;
24
+ }
24
25
 
25
- /*
26
- Typographic tweaks!
27
- - Add accessible line-height
28
- - Improve text rendering
29
- */
30
- :host,
31
- body {
32
- min-height: 100svh;
33
- line-height: 1.5rem;
34
- -webkit-font-smoothing: antialiased;
35
- transition-behavior: allow-discrete;
36
- // stylelint-disable-next-line property-no-unknown -- @see https://caniuse.com/mdn-css_properties_interpolate-size_allow-keywords
37
- interpolate-size: allow-keywords;
38
- }
26
+ /*
27
+ Typographic tweaks!
28
+ - Add accessible line-height
29
+ - Improve text rendering
30
+ */
31
+ :host,
32
+ body {
33
+ min-height: 100svh;
34
+ line-height: 1.5rem;
35
+ -webkit-font-smoothing: antialiased;
36
+ transition-behavior: allow-discrete;
37
+ // stylelint-disable-next-line property-no-unknown -- @see https://caniuse.com/mdn-css_properties_interpolate-size_allow-keywords
38
+ interpolate-size: allow-keywords;
39
+ }
39
40
 
40
- /* Improve media defaults */
41
- img,
42
- picture,
43
- video,
44
- canvas,
45
- svg {
46
- display: block;
47
- max-width: 100%;
48
- }
41
+ /* Improve media defaults */
42
+ img,
43
+ picture,
44
+ video,
45
+ canvas,
46
+ svg {
47
+ display: block;
48
+ max-width: 100%;
49
+ }
49
50
 
50
- /* Avoid ugly unbalanced word wrap */
51
- h1,
52
- h2,
53
- h3,
54
- h4,
55
- h5,
56
- h6 {
57
- text-wrap: balance;
58
- }
51
+ /* Avoid ugly unbalanced word wrap */
52
+ h1,
53
+ h2,
54
+ h3,
55
+ h4,
56
+ h5,
57
+ h6 {
58
+ text-wrap: balance;
59
+ }
59
60
 
60
- /* Avoid ugly orphan word wrap */
61
- p,
62
- li,
63
- figcaption {
64
- max-width: 80ch;
65
- text-wrap: pretty;
66
- }
61
+ /* Avoid ugly orphan word wrap */
62
+ p,
63
+ li,
64
+ figcaption {
65
+ max-width: 80ch;
66
+ text-wrap: pretty;
67
+ }
67
68
 
68
- /* Declare as container for container queries */
69
- :host > :is(header, main, footer),
70
- body > :is(header, main, footer),
71
- section,
72
- article {
73
- container-type: inline-size;
74
- }
69
+ /* Declare as container for container queries */
70
+ :host > :is(header, main, footer),
71
+ body > :is(header, main, footer),
72
+ section,
73
+ article {
74
+ container-type: inline-size;
75
+ }
75
76
 
76
- @media (prefers-reduced-motion: reduce) {
77
- :has(:target) {
78
- scroll-behavior: smooth;
79
- scroll-padding-top: 3rem;
77
+ @media (prefers-reduced-motion: reduce) {
78
+ :has(:target) {
79
+ scroll-behavior: smooth;
80
+ scroll-padding-top: 3rem;
81
+ }
80
82
  }
81
83
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dvcol/neo-svelte",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.1.2",
5
5
  "description": "Neomorphic ui library for svelte 5",
6
6
  "homepage": "https://github.com/dvcol/neo-svelte",
7
7
  "bugs": "https://github.com/dvcol/neo-svelte/issues",