@happyvertical/smrt-ui 0.40.65 → 0.40.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/AGENTS.md +27 -4
  2. package/README.md +7 -2
  3. package/dist/themes/README.md +60 -15
  4. package/dist/themes/ThemeProvider.svelte +11 -0
  5. package/dist/themes/__tests__/happyvertical-theme.test.js +231 -0
  6. package/dist/themes/__tests__/token-aliases.test.js +1 -0
  7. package/dist/themes/components/ThemeSwitcher.svelte +1 -0
  8. package/dist/themes/components/ThemeSwitcher.svelte.d.ts.map +1 -1
  9. package/dist/themes/css-generator.d.ts.map +1 -1
  10. package/dist/themes/css-generator.js +12 -5
  11. package/dist/themes/fonts/LICENSE.md +4 -2
  12. package/dist/themes/fonts/archivo-latin-ext.woff2 +0 -0
  13. package/dist/themes/fonts/archivo-latin.woff2 +0 -0
  14. package/dist/themes/fonts/b612-bold-latin.woff2 +0 -0
  15. package/dist/themes/fonts/b612-latin.woff2 +0 -0
  16. package/dist/themes/fonts/b612-mono-latin.woff2 +0 -0
  17. package/dist/themes/happyvertical/index.d.ts +68 -0
  18. package/dist/themes/happyvertical/index.d.ts.map +1 -0
  19. package/dist/themes/happyvertical/index.js +402 -0
  20. package/dist/themes/index.d.ts +3 -1
  21. package/dist/themes/index.d.ts.map +1 -1
  22. package/dist/themes/index.js +3 -1
  23. package/dist/themes/registry.d.ts.map +1 -1
  24. package/dist/themes/registry.js +3 -0
  25. package/dist/themes/styles/all.css +6 -4
  26. package/dist/themes/styles/happyvertical-fonts.css +83 -0
  27. package/dist/themes/styles/happyvertical.css +561 -0
  28. package/dist/themes/styles/index.d.ts +3 -0
  29. package/dist/themes/styles/index.d.ts.map +1 -1
  30. package/dist/themes/styles/index.js +3 -0
  31. package/dist/themes/types.d.ts +10 -2
  32. package/dist/themes/types.d.ts.map +1 -1
  33. package/dist/themes/types.js +2 -1
  34. package/package.json +2 -2
@@ -0,0 +1,402 @@
1
+ /**
2
+ * HappyVertical Theme — "Day Shift"
3
+ *
4
+ * The HappyVertical brand identity (happyvertical/smrt#2318), signed off
5
+ * 2026-08-12. A calm instrument panel: a warm-grey enamel ground, raised
6
+ * faceplate panels separated by hairline bezels, graphite ink, and exactly one
7
+ * budgeted accent — a signal amber. The execution rule is the owner's, verbatim:
8
+ * **"calm is less for the brain to process, not theatre."** No decorative
9
+ * vocabulary, no glow, nothing animates unless it represents a state change.
10
+ *
11
+ * Unlike a generated dark scheme, **both schemes are hand-authored**. The dark
12
+ * scheme keeps a blue-graphite cast (rather than collapsing to near-black) and
13
+ * carries both accent hues — amber and green — at dark-surface strengths.
14
+ *
15
+ * Named roles (issue vocabulary → token slots):
16
+ *
17
+ * | role | light | dark | slots |
18
+ * |-------------|-----------|-----------|------------------------------------|
19
+ * | enamel | `#E8EBE9` | `#14181B` | `background`, the ground |
20
+ * | faceplate | `#F4F6F5` | `#1C2226` | `surface`, raised panels |
21
+ * | graphite | `#20272B` | `#E4E9E7` | `on-surface` / `on-background` |
22
+ * | etch | `#5A6660` | `#97A29C` | `on-surface-variant` |
23
+ * | bezel | `#C9CFCC` | `#2A3238` | `outline-variant`, hairlines |
24
+ * | amber | `#9C5300` | `#FFB454` | `primary`, incl. the focus ring |
25
+ * | green | `#1E7A4B` | `#53C989` | `success` |
26
+ *
27
+ * `background` is the enamel ground and `surface` is the raised faceplate, so a
28
+ * `Card` (which paints `--smrt-color-surface`) reads as a panel sitting on the
29
+ * ground exactly as in the sign-off mock. The `surface-container-*` ramp is
30
+ * anchored on those two — lightest at `lowest` in light, inverted in dark — and
31
+ * deliberately extends one hand-tuned step past each anchor (`lowest`/`bright`
32
+ * a shade above faceplate, `highest`/`dim` a shade below enamel). Confining all
33
+ * seven levels strictly between enamel and faceplate would compress them into a
34
+ * ~12-value band, and components that stack container levels (DataTable rows
35
+ * under a header, nested panels) would lose their separation entirely.
36
+ *
37
+ * **Green is never text.** It is a status lamp, marker, or container fill only;
38
+ * light `#1E7A4B` measures 4.44:1 on the enamel ground, just under AA. The
39
+ * accent-as-text contrast set in `__tests__/happyvertical-theme.test.ts`
40
+ * excludes `success` and a companion scan enforces that no component in this
41
+ * package paints text with it. Every other text/surface pairing in both schemes
42
+ * clears WCAG AA (4.5:1), and `outline` plus the amber focus ring clear 3:1
43
+ * non-text on every surface slot.
44
+ *
45
+ * `outline` and `outline-variant` are deliberately different strengths, and the
46
+ * distinction is the a11y contract: `outline` is the boundary token and is
47
+ * tuned to clear 3:1 on every surface, while `outline-variant` is the bezel —
48
+ * the decorative hairline between panels — which measures 1.25–1.54:1 in light
49
+ * and 1.03–1.43:1 in dark. That is the look the design signs off on and the
50
+ * same register every other preset here uses for its dividers. Never "fix" the
51
+ * bezel by raising its value; a structure that must be perceivable (a control
52
+ * boundary, a focus ring) should consume `outline` or `primary` instead.
53
+ *
54
+ * The dark bezel sits at the top of the surface ramp, so the ramp deliberately
55
+ * stops below it: `surfaceContainerHighest` and `surfaceBright` were originally
56
+ * authored AT `#2A3238` and a bezel-bordered panel on either was invisible at
57
+ * exactly 1.00:1. They are now distinct, and a test pins that no surface may
58
+ * ever equal `outline-variant` again. Separating them further would mean
59
+ * lifting the top of the ramp past the bezel, which drops `on-surface-variant`
60
+ * below AA on those surfaces — the wrong trade.
61
+ */
62
+ import { spacingScale } from '../shared.js';
63
+ /** Display family (headings, titles) — falls back when the fonts are absent. */
64
+ const DISPLAY_FONT = '"Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif';
65
+ /** Body/UI family. */
66
+ const BODY_FONT = '"B612", Verdana, "Segoe UI", system-ui, sans-serif';
67
+ /** Technical/monospace family (legends, readouts, code). */
68
+ const MONO_FONT = '"B612 Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace';
69
+ /**
70
+ * Day Shift light palette (canonical).
71
+ *
72
+ * Warm-grey enamel ground with faceplate panels. The amber is darkened to
73
+ * `#9C5300` so white-on-amber clears AA (5.75:1) and the accent still reads as
74
+ * a 3:1 non-text marker on every surface.
75
+ */
76
+ const lightColors = {
77
+ // Primary - Signal amber (the single budgeted accent; also the focus ring)
78
+ primary: '#9c5300',
79
+ onPrimary: '#ffffff',
80
+ primaryContainer: '#f7e3cc',
81
+ onPrimaryContainer: '#5e3200',
82
+ // Secondary - Graphite-green slate
83
+ secondary: '#4f5b55',
84
+ onSecondary: '#ffffff',
85
+ secondaryContainer: '#dce3df',
86
+ onSecondaryContainer: '#2a342f',
87
+ // Tertiary - Instrument blue, the quiet half of the blue-graphite cast
88
+ tertiary: '#3c5a68',
89
+ onTertiary: '#ffffff',
90
+ tertiaryContainer: '#d7e4ea',
91
+ onTertiaryContainer: '#1b333e',
92
+ // Error - Muted enamel-compatible red
93
+ error: '#9b3b32',
94
+ onError: '#ffffff',
95
+ errorContainer: '#f6dfdc',
96
+ onErrorContainer: '#5e1c16',
97
+ // Warning - Shares the amber family, pulled browner so it is not the accent
98
+ warning: '#8a4e08',
99
+ onWarning: '#ffffff',
100
+ warningContainer: '#f7e4c8',
101
+ onWarningContainer: '#533000',
102
+ // Success - Green. Status lamps, markers, and fills only; never text.
103
+ success: '#1e7a4b',
104
+ onSuccess: '#ffffff',
105
+ successContainer: '#d5e9df',
106
+ onSuccessContainer: '#0c3b24',
107
+ // Surface - Faceplate and the gradations down to the enamel ground
108
+ surface: '#f4f6f5',
109
+ onSurface: '#20272b',
110
+ surfaceVariant: '#e5eae7',
111
+ onSurfaceVariant: '#5a6660',
112
+ surfaceContainer: '#f1f4f2',
113
+ surfaceContainerLow: '#f7f9f8',
114
+ surfaceContainerHigh: '#eaeeec',
115
+ surfaceContainerHighest: '#e3e8e5',
116
+ surfaceContainerLowest: '#fbfcfb',
117
+ surfaceDim: '#e1e6e3',
118
+ surfaceBright: '#fbfcfb',
119
+ // Background - Enamel ground
120
+ background: '#e8ebe9',
121
+ onBackground: '#20272b',
122
+ // Outline - Etch family, tuned to clear 3:1 on every surface
123
+ outline: '#717d77',
124
+ outlineVariant: '#c9cfcc',
125
+ // Inverse
126
+ inverseSurface: '#20272b',
127
+ inverseOnSurface: '#edf0ee',
128
+ inversePrimary: '#ffb454',
129
+ // Effects
130
+ shadow: 'rgba(32, 39, 43, 0.2)',
131
+ scrim: 'rgba(20, 24, 27, 0.45)',
132
+ };
133
+ /**
134
+ * Day Shift dark palette ("night shift").
135
+ *
136
+ * Hand-authored, not derived. Surfaces keep a blue-graphite cast (`#14181B`
137
+ * ground, `#1C2226` faceplate, `#2A3238` bezel) instead of collapsing to
138
+ * near-black, and both accent hues survive: amber `#FFB454` at ~10:1 on the
139
+ * ground and green `#53C989` for lamps and fills.
140
+ */
141
+ const darkColors = {
142
+ // Primary - Signal amber at dark-surface strength
143
+ primary: '#ffb454',
144
+ onPrimary: '#14181b',
145
+ primaryContainer: '#3b2a12',
146
+ onPrimaryContainer: '#ffd7a1',
147
+ // Secondary - Graphite-green slate
148
+ secondary: '#a6b2ac',
149
+ onSecondary: '#14181b',
150
+ secondaryContainer: '#262e33',
151
+ onSecondaryContainer: '#dce3e0',
152
+ // Tertiary - Instrument blue
153
+ tertiary: '#9cbecc',
154
+ onTertiary: '#10262e',
155
+ tertiaryContainer: '#1e313a',
156
+ onTertiaryContainer: '#c6dee8',
157
+ // Error
158
+ error: '#e89b92',
159
+ onError: '#3b120d',
160
+ errorContainer: '#402019',
161
+ onErrorContainer: '#f7c9c3',
162
+ // Warning - Amber family, lifted off primary
163
+ warning: '#ffc46b',
164
+ onWarning: '#14181b',
165
+ warningContainer: '#3b2c12',
166
+ onWarningContainer: '#ffdca8',
167
+ // Success - Green. Status lamps, markers, and fills only; never text.
168
+ success: '#53c989',
169
+ onSuccess: '#06331e',
170
+ successContainer: '#14382a',
171
+ onSuccessContainer: '#a8e5c4',
172
+ // Surface - Blue-graphite faceplates over the night ground
173
+ surface: '#1c2226',
174
+ onSurface: '#e4e9e7',
175
+ surfaceVariant: '#232b30',
176
+ onSurfaceVariant: '#97a29c',
177
+ surfaceContainer: '#1c2226',
178
+ surfaceContainerLow: '#171c20',
179
+ surfaceContainerHigh: '#212930',
180
+ surfaceContainerHighest: '#252d33',
181
+ surfaceContainerLowest: '#0f1315',
182
+ surfaceDim: '#101416',
183
+ surfaceBright: '#283036',
184
+ // Background - Night enamel
185
+ background: '#14181b',
186
+ onBackground: '#e4e9e7',
187
+ // Outline - Etch family, tuned to clear 3:1 on every surface
188
+ outline: '#76827d',
189
+ outlineVariant: '#2a3238',
190
+ // Inverse
191
+ inverseSurface: '#e4e9e7',
192
+ inverseOnSurface: '#1c2226',
193
+ inversePrimary: '#9c5300',
194
+ // Effects
195
+ shadow: 'rgba(0, 0, 0, 0.6)',
196
+ scrim: 'rgba(0, 0, 0, 0.6)',
197
+ };
198
+ /**
199
+ * Day Shift typography.
200
+ *
201
+ * Archivo (500/600) sets display, headline, and title in sentence case with
202
+ * ~-0.01em tracking; B612 (400/700) carries body and label text at a 1.6 body
203
+ * line-height. Nothing is upper-cased by the scale — legends opt in through the
204
+ * `.hv-legend` utility instead.
205
+ */
206
+ const typography = {
207
+ displayLarge: {
208
+ size: '2.9rem',
209
+ lineHeight: '1.15',
210
+ weight: '600',
211
+ tracking: '-0.015em',
212
+ fontFamily: DISPLAY_FONT,
213
+ },
214
+ displayMedium: {
215
+ size: '2.4rem',
216
+ lineHeight: '1.15',
217
+ weight: '600',
218
+ tracking: '-0.015em',
219
+ fontFamily: DISPLAY_FONT,
220
+ },
221
+ displaySmall: {
222
+ size: '2rem',
223
+ lineHeight: '1.2',
224
+ weight: '600',
225
+ tracking: '-0.01em',
226
+ fontFamily: DISPLAY_FONT,
227
+ },
228
+ headlineLarge: {
229
+ size: '1.75rem',
230
+ lineHeight: '1.2',
231
+ weight: '600',
232
+ tracking: '-0.01em',
233
+ fontFamily: DISPLAY_FONT,
234
+ },
235
+ headlineMedium: {
236
+ size: '1.5rem',
237
+ lineHeight: '1.25',
238
+ weight: '600',
239
+ tracking: '-0.01em',
240
+ fontFamily: DISPLAY_FONT,
241
+ },
242
+ headlineSmall: {
243
+ size: '1.35rem',
244
+ lineHeight: '1.3',
245
+ weight: '600',
246
+ tracking: '-0.01em',
247
+ fontFamily: DISPLAY_FONT,
248
+ },
249
+ titleLarge: {
250
+ size: '1.15rem',
251
+ lineHeight: '1.35',
252
+ weight: '600',
253
+ tracking: '-0.01em',
254
+ fontFamily: DISPLAY_FONT,
255
+ },
256
+ titleMedium: {
257
+ size: '1rem',
258
+ lineHeight: '1.4',
259
+ weight: '500',
260
+ tracking: '-0.01em',
261
+ fontFamily: DISPLAY_FONT,
262
+ },
263
+ titleSmall: {
264
+ size: '0.9rem',
265
+ lineHeight: '1.4',
266
+ weight: '500',
267
+ tracking: '-0.01em',
268
+ fontFamily: DISPLAY_FONT,
269
+ },
270
+ bodyLarge: {
271
+ size: '1rem',
272
+ lineHeight: '1.6',
273
+ weight: '400',
274
+ tracking: '0',
275
+ fontFamily: 'var(--smrt-font-family)',
276
+ },
277
+ bodyMedium: {
278
+ size: '0.9375rem',
279
+ lineHeight: '1.6',
280
+ weight: '400',
281
+ tracking: '0',
282
+ fontFamily: 'var(--smrt-font-family)',
283
+ },
284
+ bodySmall: {
285
+ size: '0.875rem',
286
+ lineHeight: '1.55',
287
+ weight: '400',
288
+ tracking: '0',
289
+ fontFamily: 'var(--smrt-font-family)',
290
+ },
291
+ labelLarge: {
292
+ size: '0.9rem',
293
+ lineHeight: '1.4',
294
+ weight: '700',
295
+ tracking: '0',
296
+ fontFamily: 'var(--smrt-font-family)',
297
+ },
298
+ labelMedium: {
299
+ size: '0.8125rem',
300
+ lineHeight: '1.4',
301
+ weight: '700',
302
+ tracking: '0.02em',
303
+ fontFamily: 'var(--smrt-font-family)',
304
+ },
305
+ labelSmall: {
306
+ size: '0.75rem',
307
+ lineHeight: '1.4',
308
+ weight: '700',
309
+ tracking: '0.08em',
310
+ fontFamily: 'var(--smrt-font-family)',
311
+ },
312
+ };
313
+ /**
314
+ * Day Shift elevation (light) — flat with hairline bezels.
315
+ *
316
+ * Level 1 is the hairline itself; levels 2+ add the minimum soft shadow that
317
+ * still separates an overlay from the panel underneath. Closer to studio than
318
+ * to material — a raised faceplate, not a floating card.
319
+ */
320
+ const elevation = {
321
+ 0: 'none',
322
+ 1: 'inset 0 0 0 1px rgba(32, 39, 43, 0.1)',
323
+ 2: '0 1px 2px 0 rgba(32, 39, 43, 0.06)',
324
+ 3: '0 2px 6px -2px rgba(32, 39, 43, 0.1)',
325
+ 4: '0 6px 16px -6px rgba(32, 39, 43, 0.14)',
326
+ 5: '0 12px 28px -12px rgba(32, 39, 43, 0.18)',
327
+ };
328
+ /**
329
+ * Day Shift elevation (dark) — a white inset hairline over black drop shadows.
330
+ *
331
+ * Defined here (not only in `styles/happyvertical.css`) so the JS ThemeProvider
332
+ * output and the static dark CSS stay in lockstep (#1586).
333
+ */
334
+ const darkElevation = {
335
+ 0: 'none',
336
+ 1: 'inset 0 0 0 1px rgba(228, 233, 231, 0.08)',
337
+ 2: '0 1px 2px 0 rgba(0, 0, 0, 0.4)',
338
+ 3: '0 2px 6px -2px rgba(0, 0, 0, 0.5)',
339
+ 4: '0 6px 16px -6px rgba(0, 0, 0, 0.6)',
340
+ 5: '0 12px 28px -12px rgba(0, 0, 0, 0.7)',
341
+ };
342
+ /**
343
+ * Day Shift radii — the mock's restrained geometry: 6px controls, 8px panels.
344
+ */
345
+ const borderRadius = {
346
+ none: '0',
347
+ sm: '0.25rem',
348
+ md: '0.375rem',
349
+ lg: '0.5rem',
350
+ xl: '0.75rem',
351
+ '2xl': '1rem',
352
+ '3xl': '1.25rem',
353
+ full: '9999px',
354
+ };
355
+ /**
356
+ * Day Shift motion — ~120ms state transitions.
357
+ *
358
+ * `normal` is the 120ms the spec calls for; the rest of the scale stays tight
359
+ * around it, because nothing animates here unless it represents a state change.
360
+ * (The shared Material-3 `short1…long4` aliases from #1431 are emitted
361
+ * unchanged across every preset and are not part of this scale.)
362
+ */
363
+ const duration = {
364
+ instant: '0ms',
365
+ fast: '90ms',
366
+ normal: '120ms',
367
+ slow: '180ms',
368
+ slower: '260ms',
369
+ };
370
+ /**
371
+ * Day Shift easing — one calm curve everywhere.
372
+ *
373
+ * A single easing is the point: varying the curve per interaction is theatre,
374
+ * and the execution rule rejects it.
375
+ */
376
+ const calmEasing = {
377
+ standard: 'cubic-bezier(0.4, 0, 0.2, 1)',
378
+ standardDecelerate: 'cubic-bezier(0.4, 0, 0.2, 1)',
379
+ standardAccelerate: 'cubic-bezier(0.4, 0, 0.2, 1)',
380
+ emphasized: 'cubic-bezier(0.4, 0, 0.2, 1)',
381
+ emphasizedDecelerate: 'cubic-bezier(0.4, 0, 0.2, 1)',
382
+ emphasizedAccelerate: 'cubic-bezier(0.4, 0, 0.2, 1)',
383
+ };
384
+ /**
385
+ * HappyVertical "Day Shift" theme definition
386
+ */
387
+ export const happyverticalTheme = {
388
+ id: 'happyvertical',
389
+ name: 'Day Shift',
390
+ light: lightColors,
391
+ dark: darkColors,
392
+ typography,
393
+ elevation,
394
+ darkElevation,
395
+ spacing: spacingScale,
396
+ borderRadius,
397
+ duration,
398
+ easing: calmEasing,
399
+ fontFamily: BODY_FONT,
400
+ fontFamilyMono: MONO_FONT,
401
+ };
402
+ export default happyverticalTheme;
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * SMRT Svelte Themes
3
3
  *
4
- * Unified theme system with Material, Glass, Studio, and SMRT presets.
4
+ * Unified theme system with Material, Glass, Studio, SMRT, and HappyVertical
5
+ * ("Day Shift") presets.
5
6
  * Supports runtime theme switching, dark/light modes, and CSS custom properties.
6
7
  *
7
8
  * @example
@@ -21,6 +22,7 @@ export type { CreateThemeOptions } from './create-theme.js';
21
22
  export { createTheme, createThemeFromColor, getRegisteredTheme, isThemeRegistered, preloadThemeRegistry, registerTheme, } from './create-theme.js';
22
23
  export { generateAllThemesCSS, generateThemeCSS, generateThemeVariables, variablesToStyleString, } from './css-generator.js';
23
24
  export { glassTheme } from './glass/index.js';
25
+ export { happyverticalTheme } from './happyvertical/index.js';
24
26
  export { materialTheme } from './material/index.js';
25
27
  export { availablePresets, getAllThemes, getTheme, getThemeName, getThemeOptions, isValidPreset, themes, } from './registry.js';
26
28
  export { appleEasing, borderRadiusScale, durationScale, materialEasing, spacingScale, studioEasing, } from './shared.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,aAAa,EACb,MAAM,GACP,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,aAAa,EACb,MAAM,GACP,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * SMRT Svelte Themes
3
3
  *
4
- * Unified theme system with Material, Glass, Studio, and SMRT presets.
4
+ * Unified theme system with Material, Glass, Studio, SMRT, and HappyVertical
5
+ * ("Day Shift") presets.
5
6
  * Supports runtime theme switching, dark/light modes, and CSS custom properties.
6
7
  *
7
8
  * @example
@@ -24,6 +25,7 @@ export { createTheme, createThemeFromColor, getRegisteredTheme, isThemeRegistere
24
25
  // CSS generation
25
26
  export { generateAllThemesCSS, generateThemeCSS, generateThemeVariables, variablesToStyleString, } from './css-generator.js';
26
27
  export { glassTheme } from './glass/index.js';
28
+ export { happyverticalTheme } from './happyvertical/index.js';
27
29
  // Theme definitions
28
30
  export { materialTheme } from './material/index.js';
29
31
  // Registry
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/themes/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,CAK7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAKzC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAiBnD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,WAAW,CAInE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAMxD;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,KAAK,EAAE,CAEtC;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CASzE;AAOD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAEtD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAE5D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAElD"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/themes/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,CAM7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAMzC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAiBnD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,WAAW,CAInE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAMxD;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,KAAK,EAAE,CAEtC;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CASzE;AAOD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAEtD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAE5D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAElD"}
@@ -5,6 +5,7 @@
5
5
  * theme lookup, validation, and management.
6
6
  */
7
7
  import { glassTheme } from './glass/index.js';
8
+ import { happyverticalTheme } from './happyvertical/index.js';
8
9
  import { materialTheme } from './material/index.js';
9
10
  import { smrtTheme } from './smrt/index.js';
10
11
  import { studioTheme } from './studio/index.js';
@@ -16,6 +17,7 @@ export const themes = {
16
17
  glass: glassTheme,
17
18
  studio: studioTheme,
18
19
  smrt: smrtTheme,
20
+ happyvertical: happyverticalTheme,
19
21
  };
20
22
  /**
21
23
  * List of available theme presets (built-in only)
@@ -25,6 +27,7 @@ export const availablePresets = [
25
27
  'glass',
26
28
  'studio',
27
29
  'smrt',
30
+ 'happyvertical',
28
31
  ];
29
32
  /**
30
33
  * Get a theme by preset name
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * All Themes CSS
3
3
  *
4
- * Combined CSS file with all themes (Material, Glass, Studio, SMRT).
5
- * Use this if your app supports runtime theme switching.
4
+ * Combined CSS file with all themes (Material, Glass, Studio, SMRT,
5
+ * HappyVertical). Use this if your app supports runtime theme switching.
6
6
  *
7
- * Note: the SMRT theme's fonts are not imported here (they pull in woff2
8
- * binaries). Import './fonts.css' explicitly if you want the SMRT type stack.
7
+ * Note: the SMRT and HappyVertical fonts are not imported here (they pull in
8
+ * woff2 binaries). Import './fonts.css' or './happyvertical-fonts.css'
9
+ * explicitly if you want either type stack.
9
10
  *
10
11
  * @usage import '@happyvertical/smrt-ui/themes/styles/all.css';
11
12
  */
@@ -14,3 +15,4 @@
14
15
  @import './glass.css';
15
16
  @import './studio.css';
16
17
  @import './smrt.css';
18
+ @import './happyvertical.css';
@@ -0,0 +1,83 @@
1
+ /**
2
+ * HappyVertical Theme Fonts — "Day Shift"
3
+ *
4
+ * Self-hosted @font-face declarations for the Day Shift type stack:
5
+ * - Archivo — display / headline / title (variable, used at 500–600)
6
+ * - B612 — body / UI (400 and 700)
7
+ * - B612 Mono — legends, readouts, code (400)
8
+ *
9
+ * These are the Google Fonts woff2 instances (Archivo latin + latin-ext as the
10
+ * variable font; B612 and B612 Mono ship a latin subset only), bundled for
11
+ * privacy-first, CDN-free delivery. All three are licensed under the SIL Open
12
+ * Font License 1.1 — see ../fonts/LICENSE.md.
13
+ *
14
+ * Import alongside the theme tokens when you want the full brand look:
15
+ *
16
+ * import '@happyvertical/smrt-ui/themes/styles/happyvertical-fonts.css';
17
+ * import '@happyvertical/smrt-ui/themes/styles/happyvertical.css';
18
+ *
19
+ * Font files are resolved relative to this stylesheet (../fonts/*.woff2) by
20
+ * your bundler. If you can't bundle the fonts, the theme falls back to
21
+ * Helvetica / Verdana / ui-monospace stacks automatically.
22
+ */
23
+
24
+ /* Archivo — display / headline / title (variable weight) */
25
+ @font-face {
26
+ font-family: 'Archivo';
27
+ font-style: normal;
28
+ font-weight: 100 900;
29
+ font-display: swap;
30
+ src: url('../fonts/archivo-latin.woff2') format('woff2');
31
+ unicode-range:
32
+ U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
33
+ U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
34
+ U+2215, U+FEFF, U+FFFD;
35
+ }
36
+ @font-face {
37
+ font-family: 'Archivo';
38
+ font-style: normal;
39
+ font-weight: 100 900;
40
+ font-display: swap;
41
+ src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
42
+ unicode-range:
43
+ U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
44
+ U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
45
+ U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
46
+ }
47
+
48
+ /* B612 — body / UI */
49
+ @font-face {
50
+ font-family: 'B612';
51
+ font-style: normal;
52
+ font-weight: 400;
53
+ font-display: swap;
54
+ src: url('../fonts/b612-latin.woff2') format('woff2');
55
+ unicode-range:
56
+ U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
57
+ U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
58
+ U+2215, U+FEFF, U+FFFD;
59
+ }
60
+ @font-face {
61
+ font-family: 'B612';
62
+ font-style: normal;
63
+ font-weight: 700;
64
+ font-display: swap;
65
+ src: url('../fonts/b612-bold-latin.woff2') format('woff2');
66
+ unicode-range:
67
+ U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
68
+ U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
69
+ U+2215, U+FEFF, U+FFFD;
70
+ }
71
+
72
+ /* B612 Mono — legends / readouts / code */
73
+ @font-face {
74
+ font-family: 'B612 Mono';
75
+ font-style: normal;
76
+ font-weight: 400;
77
+ font-display: swap;
78
+ src: url('../fonts/b612-mono-latin.woff2') format('woff2');
79
+ unicode-range:
80
+ U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
81
+ U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
82
+ U+2215, U+FEFF, U+FFFD;
83
+ }