@bergetai/ui 0.1.78

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.
@@ -0,0 +1,919 @@
1
+ /* =====================================================================
2
+ Section A — Brand primitives
3
+ ----------------------------------------------------------------------
4
+ OKLCH-authored palette scales, 50→950 per colour family.
5
+ Rules:
6
+ - Palette scales are the source of truth for all colour values.
7
+ - No single-value HSL aliases. Use numbered scales or semantic tokens.
8
+ ===================================================================== */
9
+
10
+ :root {
11
+ /* ────────────────────────────
12
+ GRANITE — neutral stone
13
+ 950 = Bedrock (base bg), 900 = Slate (surface)
14
+ ──────────────────────────── */
15
+ --berget-brand-granite-50: #f3f1ef;
16
+ --berget-brand-granite-100: #e3e1de;
17
+ --berget-brand-granite-200: #d0cdca;
18
+ --berget-brand-granite-300: #b4b0ad;
19
+ --berget-brand-granite-400: #95928e;
20
+ --berget-brand-granite-500: #74716e;
21
+ --berget-brand-granite-600: #545250;
22
+ --berget-brand-granite-700: #393836;
23
+ --berget-brand-granite-800: #262524;
24
+ --berget-brand-granite-900: #1a1a1a; /* Slate */
25
+ --berget-brand-granite-950: #0a0a0a; /* Bedrock/base */
26
+
27
+ /* ────────────────────────────
28
+ SANDSTONE — warm stone
29
+ 100 = primary text warmth
30
+ ──────────────────────────── */
31
+ --berget-brand-sandstone-50: #f4f1ee;
32
+ --berget-brand-sandstone-100: #e7e0d9;
33
+ --berget-brand-sandstone-200: #d8cbbf;
34
+ --berget-brand-sandstone-300: #c0ae9b;
35
+ --berget-brand-sandstone-400: #a48e76;
36
+ --berget-brand-sandstone-500: #856c52;
37
+ --berget-brand-sandstone-600: #664d33;
38
+ --berget-brand-sandstone-700: #49331b;
39
+ --berget-brand-sandstone-800: #32210e;
40
+ --berget-brand-sandstone-900: #211407;
41
+ --berget-brand-sandstone-950: #100802;
42
+
43
+ /* ────────────────────────────
44
+ FJORD — petrol blue
45
+ 700 = deep fjord accent
46
+ ──────────────────────────── */
47
+ --berget-brand-fjord-50: #ecf3f8;
48
+ --berget-brand-fjord-100: #d4e4ef;
49
+ --berget-brand-fjord-200: #b4d3e7;
50
+ --berget-brand-fjord-300: #88b8d7;
51
+ --berget-brand-fjord-400: #5b9ac1;
52
+ --berget-brand-fjord-500: #2c79a4;
53
+ --berget-brand-fjord-600: #005985;
54
+ --berget-brand-fjord-700: #003d63;
55
+ --berget-brand-fjord-800: #002947;
56
+ --berget-brand-fjord-900: #001a30;
57
+ --berget-brand-fjord-950: #000c1b;
58
+
59
+ /* ────────────────────────────
60
+ MOSS — green (slopes)
61
+ 300 = Lichen, 400 = Moss, 600 = Spruce
62
+ ──────────────────────────── */
63
+ --berget-brand-moss-50: #ebf4ef;
64
+ --berget-brand-moss-100: #d3e7dc;
65
+ --berget-brand-moss-200: #b3d8c3;
66
+ --berget-brand-moss-300: #86c0a2; /* Lichen */
67
+ --berget-brand-moss-400: #57a57f; /* Moss (primary action) */
68
+ --berget-brand-moss-500: #21855c;
69
+ --berget-brand-moss-600: #00653c; /* Spruce */
70
+ --berget-brand-moss-700: #004726;
71
+ --berget-brand-moss-800: #003117;
72
+ --berget-brand-moss-900: #00200c;
73
+ --berget-brand-moss-950: #001004;
74
+
75
+ /* ────────────────────────────
76
+ MUSCARIA — red (forest floor)
77
+ 500 = brand red #D1392E (pinned)
78
+ ──────────────────────────── */
79
+ --berget-brand-muscaria-50: #ffedea;
80
+ --berget-brand-muscaria-100: #fed7d1;
81
+ --berget-brand-muscaria-200: #ffb9af;
82
+ --berget-brand-muscaria-300: #f89082;
83
+ --berget-brand-muscaria-400: #e66354;
84
+ --berget-brand-muscaria-500: #d1392e; /* pinned brand */
85
+ --berget-brand-muscaria-600: #a50000;
86
+ --berget-brand-muscaria-700: #750000;
87
+ --berget-brand-muscaria-800: #530000;
88
+ --berget-brand-muscaria-900: #3a0000;
89
+ --berget-brand-muscaria-950: #220000;
90
+
91
+ /* ────────────────────────────
92
+ CHANTERELLE — amber (forest floor)
93
+ ──────────────────────────── */
94
+ --berget-brand-chanterelle-50: #ffeeb7;
95
+ --berget-brand-chanterelle-100: #ffd976;
96
+ --berget-brand-chanterelle-200: #ffc11e;
97
+ --berget-brand-chanterelle-300: #e3a500;
98
+ --berget-brand-chanterelle-400: #bc8800;
99
+ --berget-brand-chanterelle-500: #926a04;
100
+ --berget-brand-chanterelle-600: #6b4d05;
101
+ --berget-brand-chanterelle-700: #493403;
102
+ --berget-brand-chanterelle-800: #322202;
103
+ --berget-brand-chanterelle-900: #201501;
104
+ --berget-brand-chanterelle-950: #100900;
105
+
106
+ /* (No backward-compatibility aliases) */
107
+ }
108
+
109
+ /*
110
+ * B. Semantic Berget tokens
111
+ *
112
+ * Composed from the palette scales. All values resolve through
113
+ * colour-mix() or direct palette references for maintainability.
114
+ * These are what Berget components consume via Tailwind utilities.
115
+ */
116
+ :root {
117
+ /* ── Surfaces ───────────────────────────────────────────────────── */
118
+ --berget-background: var(--berget-brand-granite-950); /* Bedrock · page bg */
119
+ --berget-foreground: var(--berget-brand-sandstone-100); /* warm white · primary text */
120
+ --berget-foreground-alt: color-mix(in oklch, var(--berget-brand-sandstone-100) 80%, transparent);
121
+ --berget-body-background: color-mix(in oklch, var(--berget-brand-sandstone-100) 80%, transparent);
122
+ --berget-mid-alt: var(--berget-brand-granite-950);
123
+
124
+ /* ── Core surface + text aliases ────────────────────────────────── */
125
+ --berget-surface-01: var(--berget-brand-granite-900);
126
+ --berget-surface-02: var(--berget-brand-granite-800);
127
+ --berget-surface-subtlest: color-mix(in oklch, var(--berget-brand-sandstone-100) 3%, transparent);
128
+ --berget-text-inverse: var(--berget-brand-granite-950);
129
+
130
+ /* ── Cards / containers ─────────────────────────────────────────── */
131
+ --berget-card: color-mix(in oklch, var(--berget-brand-granite-900) 40%, transparent);
132
+ --berget-card-foreground: var(--berget-brand-sandstone-100);
133
+ --berget-popover: var(--berget-brand-granite-900);
134
+ --berget-popover-foreground: var(--berget-brand-sandstone-100);
135
+ --berget-muted: var(--berget-brand-granite-950);
136
+ --berget-muted-foreground: color-mix(
137
+ in oklch,
138
+ var(--berget-brand-sandstone-100) 80%,
139
+ transparent
140
+ );
141
+
142
+ /* ── Surface semantic aliases ────────────────────────────────────── */
143
+ --berget-primary: var(--berget-brand-sandstone-100); /* primary CTA / action */
144
+ --berget-primary-foreground: var(--berget-brand-sandstone-100);
145
+ --berget-primary-hover: var(--berget-brand-granite-950);
146
+ --berget-secondary: var(--berget-brand-moss-400); /* moss = action */
147
+ --berget-secondary-foreground: var(--berget-brand-sandstone-100);
148
+ --berget-secondary-hover: color-mix(in oklch, var(--berget-brand-moss-400) 40%, transparent);
149
+
150
+ /* ── Accent ──────────────────────────────────────────────────────── */
151
+ --berget-accent: var(--berget-brand-moss-300); /* lichen · tertiary accent */
152
+ --berget-accent-foreground: var(--berget-brand-granite-900);
153
+ --berget-accent-2: var(--berget-brand-chanterelle-300); /* warning tint */
154
+ --berget-accent-3: var(--berget-brand-fjord-700); /* fjord depth */
155
+
156
+ /* ── Ghost ───────────────────────────────────────────────────────·─ */
157
+ --berget-ghost: color-mix(in oklch, var(--berget-brand-granite-900) 40%, transparent);
158
+ --berget-ghost-hover: color-mix(in oklch, var(--berget-brand-granite-900) 80%, transparent);
159
+ --berget-ghost-foreground: var(--berget-brand-sandstone-100);
160
+
161
+ /* ── Outline ────────────────────────────────────────────────────── */
162
+ --berget-outline: var(--berget-brand-moss-300); /* Lichen */
163
+ --berget-outline-hover: color-mix(in oklch, var(--berget-brand-sandstone-100) 5%, transparent);
164
+ --berget-outline-active: color-mix(in oklch, var(--berget-brand-sandstone-100) 15%, transparent);
165
+
166
+ /* ── Borders / inputs ───────────────────────────────────────────── */
167
+ --berget-border: var(--berget-brand-granite-700);
168
+ --berget-input: var(--berget-brand-granite-700);
169
+ --berget-ring: var(--berget-brand-moss-300); /* Lichen · focus ring */
170
+ --berget-ring-error: var(--berget-brand-muscaria-400); /* error ring */
171
+
172
+ /* ── Destructive ────────────────────────────────────────────────── */
173
+ --berget-destructive: color-mix(in oklch, var(--berget-brand-muscaria-400) 20%, transparent);
174
+ --berget-destructive-border: var(--berget-brand-muscaria-400);
175
+ --berget-destructive-foreground: var(--berget-brand-muscaria-400);
176
+
177
+ /* ── Sidebar ────────────────────────────────────────────────────── */
178
+ --berget-sidebar: color-mix(in oklch, var(--berget-brand-granite-900) 40%, transparent);
179
+ --berget-sidebar-foreground: color-mix(
180
+ in oklch,
181
+ var(--berget-brand-sandstone-100) 80%,
182
+ transparent
183
+ );
184
+ --berget-sidebar-accent: var(--berget-brand-moss-400);
185
+ --berget-sidebar-accent-foreground: var(--berget-brand-sandstone-100);
186
+ --berget-sidebar-border: color-mix(in oklch, var(--berget-brand-sandstone-100) 5%, transparent);
187
+ --berget-sidebar-ring: var(--berget-brand-moss-300);
188
+
189
+ /* ── Utility ──────────────────────────────────────────────────────── */
190
+ --berget-backdrop: color-mix(in oklch, var(--berget-brand-granite-900) 80%, transparent);
191
+
192
+ /* ── Interactive surface tints ──────────────────────────────────── */
193
+ --berget-surface-hover: color-mix(in oklch, var(--berget-brand-sandstone-100) 2%, transparent);
194
+ --berget-surface-subtle: color-mix(in oklch, var(--berget-brand-sandstone-100) 5%, transparent);
195
+ --berget-surface-raised: color-mix(in oklch, var(--berget-brand-sandstone-100) 10%, transparent);
196
+
197
+ /* ── Subtle borders ──────────────────────────────────────────────── */
198
+ --berget-border-subtle: color-mix(in oklch, var(--berget-brand-sandstone-100) 10%, transparent);
199
+ --berget-border-interactive: color-mix(
200
+ in oklch,
201
+ var(--berget-brand-sandstone-100) 20%,
202
+ transparent
203
+ );
204
+ --berget-border-interactive-elevated: color-mix(
205
+ in oklch,
206
+ var(--berget-brand-sandstone-100) 30%,
207
+ transparent
208
+ );
209
+
210
+ /* ── Primary tint surfaces (for active/selected/focused states) ───── */
211
+ --berget-primary-tint: color-mix(in oklch, var(--berget-brand-moss-400) 10%, transparent);
212
+ --berget-primary-tint-hover: color-mix(in oklch, var(--berget-brand-moss-400) 20%, transparent);
213
+ --berget-primary-border: color-mix(in oklch, var(--berget-brand-moss-400) 50%, transparent);
214
+
215
+ /* ── Focus-visible ring on form controls ───────────────────────── */
216
+ --berget-form-focus-border: color-mix(in oklch, var(--berget-brand-moss-400) 40%, transparent);
217
+
218
+ /* ── Dark surface hover (for elements on dark backgrounds) ───────── */
219
+ --berget-surface-hover-dark: color-mix(
220
+ in oklch,
221
+ var(--berget-brand-granite-900) 20%,
222
+ transparent
223
+ );
224
+
225
+ /* ── Separator / icon tint ──────────────────────────────────────── */
226
+ --berget-separator: color-mix(in oklch, var(--berget-brand-sandstone-100) 10%, transparent);
227
+ --berget-separator-subtle: color-mix(in oklch, var(--berget-brand-sandstone-100) 5%, transparent);
228
+ --berget-icon-muted: color-mix(in oklch, var(--berget-brand-sandstone-100) 60%, transparent);
229
+
230
+ /* ── Status ─────────────────────────────────────────────────────── */
231
+ --berget-info: color-mix(in oklch, var(--berget-brand-fjord-400) 20%, transparent);
232
+ --berget-info-foreground: var(--berget-brand-fjord-400);
233
+ --berget-info-border: var(--berget-brand-fjord-400);
234
+ --berget-success: color-mix(in oklch, var(--berget-brand-moss-400) 20%, transparent);
235
+ --berget-success-foreground: var(--berget-brand-moss-400);
236
+ --berget-success-border: var(--berget-brand-moss-400);
237
+ --berget-warning: color-mix(in oklch, var(--berget-brand-chanterelle-300) 20%, transparent);
238
+ --berget-warning-foreground: var(--berget-brand-chanterelle-300);
239
+ --berget-warning-border: var(--berget-brand-chanterelle-300);
240
+
241
+ /* ── Card component-scoped tokens ───────────────────────────────── */
242
+ --berget-card-filled-bg: var(--berget-surface-01);
243
+
244
+ /* ── CodeBlock component-scoped tokens ──────────────────────────── */
245
+ --berget-codeblock-bg: var(--berget-surface-01);
246
+ --berget-codeblock-header-bg: color-mix(in oklch, var(--berget-surface-02) 40%, transparent);
247
+
248
+ /* ── Badge component-scoped tokens ──────────────────────────────── */
249
+ --berget-badge-default-bg: var(--berget-brand-moss-600);
250
+ --berget-badge-default-fg: var(--berget-foreground);
251
+ --berget-badge-active-bg: var(--berget-brand-moss-600);
252
+ --berget-badge-active-fg: var(--berget-foreground-alt);
253
+ --berget-badge-tag-default-bg: var(--berget-primary);
254
+ --berget-badge-tag-default-fg: color-mix(in oklch, var(--berget-text-inverse) 80%, transparent);
255
+ --berget-badge-tag-active-bg: var(--berget-surface-01);
256
+ --berget-badge-tag-active-fg: var(--berget-foreground);
257
+ --berget-badge-tag-ghost-bg: color-mix(in oklch, var(--berget-primary) 30%, transparent);
258
+ --berget-badge-tag-ghost-fg: color-mix(in oklch, var(--berget-text-inverse) 60%, transparent);
259
+
260
+ /* ── Switch component-scoped tokens ─────────────────────────────── */
261
+ --berget-switch-primary-checked: var(--berget-brand-moss-400);
262
+ --berget-switch-subtle-checked: var(--berget-brand-moss-300);
263
+
264
+ /* ── FeatureCards component-scoped tokens ─────────────────────── */
265
+ --berget-feature-card-badge-bg: var(--berget-brand-moss-600);
266
+ --berget-feature-card-badge-fg: var(--berget-foreground);
267
+
268
+ /* ── Logo tokens ──────────────────────────────────────────────── */
269
+ --berget-logo-light: var(--berget-brand-sandstone-100);
270
+ --berget-logo-dark: var(--berget-brand-granite-950);
271
+
272
+ /* ── Section component-scoped tokens ────────────────────────────── */
273
+ --berget-section-muted-bg: var(--berget-surface-subtlest);
274
+
275
+ /* ── Button component-scoped tokens ─────────────────────────────── */
276
+ /* default (sandstone-100 bg, granite-900 text) */
277
+ --berget-button-default-bg: var(--berget-brand-sandstone-100);
278
+ --berget-button-default-fg: var(--berget-brand-granite-900);
279
+ /* primary (moss-400 bg, granite-950 text) */
280
+ --berget-button-primary-bg: var(--berget-brand-moss-400);
281
+ --berget-button-primary-fg: var(--berget-brand-granite-950);
282
+ /* secondary / accent (lichen-300 bg, granite-950 text) */
283
+ --berget-button-secondary-bg: var(--berget-brand-moss-300);
284
+ --berget-button-secondary-fg: var(--berget-brand-granite-950);
285
+ /* destructive (muscaria-400 bg, sandstone-100 text) */
286
+ --berget-button-destructive-bg: var(--berget-brand-muscaria-400);
287
+ --berget-button-destructive-fg: var(--berget-brand-sandstone-100);
288
+ /* link */
289
+ --berget-button-link-fg: var(--berget-brand-moss-400);
290
+
291
+ /* ── WCAG 1.4.8 Visual Presentation — Line heights ──────────────── */
292
+ --berget-heading-leading: 1.5;
293
+ --berget-body-leading: 1.6;
294
+
295
+ /* ── WCAG 1.4.12 Text Spacing ──────────────────────────────────── */
296
+ --berget-heading-spacing: -0.01em;
297
+ --berget-body-spacing: 0;
298
+
299
+ /* ── WCAG 1.4.12 Paragraph spacing ──────────────────────────────── */
300
+ --berget-paragraph-spacing: 1.5em;
301
+
302
+ /* ── WCAG 2.4.7 Focus Visible ──────────────────────────────────── */
303
+ --berget-focus-ring: var(--berget-brand-moss-300); /* Lichen · full opacity */
304
+ --berget-focus-ring-offset: 2px;
305
+ --berget-focus-ring-width: 2px;
306
+
307
+ /* ── Shadows ─────────────────────────────────────────────────────·─ */
308
+ --berget-shadow-sm: 0 4px 4px color-mix(in oklch, var(--berget-brand-granite-900) 5%, transparent);
309
+ --berget-shadow-md: 0 8px 8px 4px
310
+ color-mix(in oklch, var(--berget-brand-granite-900) 5%, transparent);
311
+ --berget-shadow-lg: 0 8px 12px
312
+ color-mix(in oklch, var(--berget-brand-granite-900) 40%, transparent);
313
+
314
+ /* ── Chart ──────────────────────────────────────────────────────── */
315
+ --berget-chart-1: var(--berget-brand-chanterelle-300);
316
+ --berget-chart-2: var(--berget-brand-moss-400);
317
+ --berget-chart-3: var(--berget-brand-moss-400);
318
+ --berget-chart-4: var(--berget-brand-moss-600);
319
+ --berget-chart-5: var(--berget-brand-fjord-700);
320
+
321
+ /* ── Border radii ─────────────────────────────────────────────────·─ */
322
+ --berget-radius-none: 0px;
323
+ --berget-radius-xs: 12px;
324
+ --berget-radius-sm: 16px;
325
+ --berget-radius-md: 24px;
326
+ --berget-radius-lg: 32px;
327
+ --berget-radius-full: 9999px;
328
+
329
+ /* ── Typography ───────────────────────────────────────────────────·─ */
330
+ --berget-font-sans: 'DM Sans', sans-serif;
331
+ --berget-font-serif: 'Ovo', serif;
332
+ --berget-font-mono: 'DM Mono', monospace;
333
+ }
334
+
335
+ /*
336
+ * B.2 Tint system
337
+ *
338
+ * Unified tinted container styles for alerts, badges, and other
339
+ * status-driven components. Uses OKLCH for perceptually uniform
340
+ * tints with a single hue override per status.
341
+ */
342
+
343
+ :root {
344
+ /* the whole tint plane, as four numbers you can tune */
345
+ --berget-tint-l: 25%;
346
+ --berget-tint-c: 0.046;
347
+ --berget-tint-border-l: 30%;
348
+ --berget-tint-border-c: 0.056;
349
+
350
+ /* the only per-status data: a hue */
351
+ --berget-tint-hue-info: 246;
352
+ --berget-tint-hue-success: 153;
353
+ --berget-tint-hue-warning: 82;
354
+ --berget-tint-hue-error: 29;
355
+ }
356
+
357
+ /* one rule for any tinted container, whatever the component */
358
+ .berget-tint {
359
+ background: oklch(var(--berget-tint-l) var(--berget-tint-c) var(--berget-tint-h));
360
+ border: 1px solid
361
+ oklch(var(--berget-tint-border-l) var(--berget-tint-border-c) var(--berget-tint-h));
362
+ color: var(--berget-tint-accent);
363
+ }
364
+ .berget-tint > svg {
365
+ color: var(--berget-tint-accent);
366
+ }
367
+
368
+ .berget-tint-info {
369
+ --berget-tint-h: var(--berget-tint-hue-info);
370
+ --berget-tint-accent: var(--berget-brand-fjord-300);
371
+ }
372
+ .berget-tint-success {
373
+ --berget-tint-h: var(--berget-tint-hue-success);
374
+ --berget-tint-accent: var(--berget-brand-moss-300);
375
+ }
376
+ .berget-tint-warning {
377
+ --berget-tint-h: var(--berget-tint-hue-warning);
378
+ --berget-tint-accent: var(--berget-brand-chanterelle-300);
379
+ }
380
+ .berget-tint-error {
381
+ --berget-tint-h: var(--berget-tint-hue-error);
382
+ --berget-tint-accent: var(--berget-brand-muscaria-300);
383
+ }
384
+
385
+ /*
386
+ * C. shadcn bridge
387
+ *
388
+ * Maps the upstream shadcn/ui CSS variable names (--primary, --border, …)
389
+ * to Berget brand primitives so that shadcn primitive components render
390
+ * correctly without modification.
391
+ *
392
+ * Rules:
393
+ * - These vars are for shadcn primitives only (packages/ui/src/primitives/).
394
+ * - Never use --primary, --border, etc. in Berget wrapper components
395
+ * (packages/ui/src/components/). Use --berget-* tokens instead.
396
+ * - Do not add new entries here unless adding a new shadcn primitive.
397
+ */
398
+ @layer base {
399
+ :root {
400
+ --background: var(--berget-brand-granite-950); /* Bedrock */
401
+ --foreground: var(--berget-brand-sandstone-100); /* warm primary text */
402
+ --primary: var(--berget-brand-sandstone-100); /* warm text (surfaces) */
403
+ --primary-foreground: var(--berget-brand-granite-950);
404
+ --secondary: var(--berget-brand-moss-400); /* moss action */
405
+ --secondary-foreground: var(--berget-brand-sandstone-100);
406
+ --accent: var(--berget-brand-moss-300); /* lichen */
407
+ --accent-foreground: var(--berget-brand-granite-900);
408
+ --muted: var(--berget-brand-granite-950);
409
+ --muted-foreground: var(--berget-brand-sandstone-100);
410
+ --card: var(--berget-brand-granite-900); /* Slate */
411
+ --card-foreground: var(--berget-brand-sandstone-100);
412
+ --popover: var(--berget-brand-granite-900);
413
+ --popover-foreground: var(--berget-brand-sandstone-100);
414
+ --input: var(--berget-brand-granite-700);
415
+ --border: var(--berget-brand-granite-700);
416
+ --ring: var(--berget-brand-moss-300); /* Lichen */
417
+ --destructive: var(--berget-brand-muscaria-400);
418
+ --destructive-foreground: var(--berget-brand-sandstone-100);
419
+ --radius: 0.5rem;
420
+ }
421
+
422
+ body {
423
+ color: var(--foreground);
424
+ }
425
+
426
+ p,
427
+ h1,
428
+ h2,
429
+ h3,
430
+ h4,
431
+ h5,
432
+ h6,
433
+ li,
434
+ span {
435
+ orphans: 2;
436
+ widows: 2;
437
+ }
438
+
439
+ @media (prefers-reduced-motion: reduce) {
440
+ *,
441
+ *::before,
442
+ *::after {
443
+ animation-duration: 0.01ms !important;
444
+ animation-iteration-count: 1 !important;
445
+ transition-duration: 0.01ms !important;
446
+ scroll-behavior: auto !important;
447
+ transition-property: none !important;
448
+ }
449
+ }
450
+ }
451
+
452
+ /*
453
+ * D. @theme block
454
+ *
455
+ * Registers all tokens into Tailwind v4's design system so they are
456
+ * available as utility classes (bg-*, text-*, shadow-*, etc.).
457
+ *
458
+ * Two patterns used here:
459
+ * - Brand primitives: `hsl(var(--berget-brand-*))` — wrapping the raw HSL
460
+ * channel in hsl() is what enables Tailwind opacity modifiers (/20, /90).
461
+ * - Semantic tokens: bare `var(--berget-*)` — already full hsl() values from
462
+ * section B, so no extra wrapper needed. Opacity modifiers do not work on
463
+ * these; bake opacity into the section B definition instead.
464
+ *
465
+ * Rules:
466
+ * - Every --berget-* token in section B must have a corresponding alias here.
467
+ * - Button component-scoped tokens use hsl(var(--berget-brand-*)) directly
468
+ * (not via section B) so that hover opacity modifiers (/90, /80) work.
469
+ * - Do not add arbitrary values here; derive from section A or B.
470
+ */
471
+ @theme {
472
+ /* Existing shadcn aliases */
473
+ --color-primary: hsl(var(--primary));
474
+ --color-primary-foreground: hsl(var(--primary-foreground));
475
+ --color-secondary: hsl(var(--secondary));
476
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
477
+ --color-accent: hsl(var(--accent));
478
+ --color-accent-foreground: hsl(var(--accent-foreground));
479
+ --color-destructive: hsl(var(--destructive));
480
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
481
+ --color-muted: hsl(var(--muted));
482
+ --color-muted-foreground: hsl(var(--muted-foreground));
483
+ --color-card: hsl(var(--card));
484
+ --color-card-foreground: hsl(var(--card-foreground));
485
+ --color-input: hsl(var(--input));
486
+ --color-border: hsl(var(--border));
487
+ --color-ring: hsl(var(--ring));
488
+ --color-background: hsl(var(--background));
489
+ --color-foreground: hsl(var(--foreground));
490
+
491
+ /* Feature card tokens */
492
+ --spacing-feature-card-padding-vertical: 48px;
493
+ --spacing-feature-card-padding-horizontal: 40px;
494
+ --spacing-feature-card-gap: 32px;
495
+ --font-size-feature-title: 40px;
496
+ --line-height-feature-title: 56px;
497
+ --letter-spacing-feature-title: -0.03em;
498
+ --font-size-feature-description: 16px;
499
+ --line-height-feature-description: 24px;
500
+
501
+ /* Float animations for GrainyGradientBackground */
502
+ --animate-float-slow: float-slow 20s ease-in-out infinite;
503
+ --animate-float-medium: float-medium 14s ease-in-out infinite;
504
+ --animate-float-fast: float-fast 8s ease-in-out infinite;
505
+
506
+ /* Gradient tokens */
507
+ --bg-image-gradient-fjord-slate: linear-gradient(
508
+ to right,
509
+ var(--berget-brand-fjord-700),
510
+ var(--berget-brand-granite-900)
511
+ );
512
+ --bg-image-gradient-slate-night: linear-gradient(
513
+ to right,
514
+ var(--berget-brand-granite-900),
515
+ var(--berget-brand-granite-950)
516
+ );
517
+ --bg-image-gradient-spruce-fjord: linear-gradient(
518
+ to right,
519
+ var(--berget-brand-moss-600),
520
+ var(--berget-brand-fjord-700)
521
+ );
522
+ --bg-image-gradient-spruce-slate: linear-gradient(
523
+ to right,
524
+ var(--berget-brand-moss-600),
525
+ var(--berget-brand-granite-900)
526
+ );
527
+ --bg-image-gradient-spruce-night: linear-gradient(
528
+ to right,
529
+ var(--berget-brand-moss-600),
530
+ var(--berget-brand-granite-950)
531
+ );
532
+ --bg-image-gradient-moss-lichen: linear-gradient(
533
+ to right,
534
+ var(--berget-brand-moss-400),
535
+ var(--berget-brand-moss-300)
536
+ );
537
+ --bg-image-gradient-moss-spruce: linear-gradient(
538
+ to right,
539
+ var(--berget-brand-moss-400),
540
+ var(--berget-brand-moss-600)
541
+ );
542
+ --bg-image-gradient-lichen-sandstone: linear-gradient(
543
+ to right,
544
+ var(--berget-brand-moss-300),
545
+ var(--berget-brand-sandstone-100)
546
+ );
547
+
548
+ /* Full Granite scale (11 step) */
549
+ --color-berget-brand-granite-50: #f3f1ef;
550
+ --color-berget-brand-granite-100: #e3e1de;
551
+ --color-berget-brand-granite-200: #d0cdca;
552
+ --color-berget-brand-granite-300: #b4b0ad;
553
+ --color-berget-brand-granite-400: #95928e;
554
+ --color-berget-brand-granite-500: #74716e;
555
+ --color-berget-brand-granite-600: #545250;
556
+ --color-berget-brand-granite-700: #393836;
557
+ --color-berget-brand-granite-800: #262524;
558
+ --color-berget-brand-granite-900: #1a1a1a;
559
+ --color-berget-brand-granite-950: #0a0a0a;
560
+
561
+ /* Full Sandstone scale (11 step) */
562
+ --color-berget-brand-sandstone-50: #f4f1ee;
563
+ --color-berget-brand-sandstone-100: #e7e0d9;
564
+ --color-berget-brand-sandstone-200: #d8cbbf;
565
+ --color-berget-brand-sandstone-300: #c0ae9b;
566
+ --color-berget-brand-sandstone-400: #a48e76;
567
+ --color-berget-brand-sandstone-500: #856c52;
568
+ --color-berget-brand-sandstone-600: #664d33;
569
+ --color-berget-brand-sandstone-700: #49331b;
570
+ --color-berget-brand-sandstone-800: #32210e;
571
+ --color-berget-brand-sandstone-900: #211407;
572
+ --color-berget-brand-sandstone-950: #100802;
573
+
574
+ /* Full Fjord scale (11 step) */
575
+ --color-berget-brand-fjord-50: #ecf3f8;
576
+ --color-berget-brand-fjord-100: #d4e4ef;
577
+ --color-berget-brand-fjord-200: #b4d3e7;
578
+ --color-berget-brand-fjord-300: #88b8d7;
579
+ --color-berget-brand-fjord-400: #5b9ac1;
580
+ --color-berget-brand-fjord-500: #2c79a4;
581
+ --color-berget-brand-fjord-600: #005985;
582
+ --color-berget-brand-fjord-700: #003d63;
583
+ --color-berget-brand-fjord-800: #002947;
584
+ --color-berget-brand-fjord-900: #001a30;
585
+ --color-berget-brand-fjord-950: #000c1b;
586
+
587
+ /* Full Moss scale (11 step) */
588
+ --color-berget-brand-moss-50: #ebf4ef;
589
+ --color-berget-brand-moss-100: #d3e7dc;
590
+ --color-berget-brand-moss-200: #b3d8c3;
591
+ --color-berget-brand-moss-300: #86c0a2;
592
+ --color-berget-brand-moss-400: #57a57f;
593
+ --color-berget-brand-moss-500: #21855c;
594
+ --color-berget-brand-moss-600: #00653c;
595
+ --color-berget-brand-moss-700: #004726;
596
+ --color-berget-brand-moss-800: #003117;
597
+ --color-berget-brand-moss-900: #00200c;
598
+ --color-berget-brand-moss-950: #001004;
599
+
600
+ /* Full Muscaria scale (11 step) */
601
+ --color-berget-brand-muscaria-50: #ffedea;
602
+ --color-berget-brand-muscaria-100: #fed7d1;
603
+ --color-berget-brand-muscaria-200: #ffb9af;
604
+ --color-berget-brand-muscaria-300: #f89082;
605
+ --color-berget-brand-muscaria-400: #e66354;
606
+ --color-berget-brand-muscaria-500: #d1392e;
607
+ --color-berget-brand-muscaria-600: #a50000;
608
+ --color-berget-brand-muscaria-700: #750000;
609
+ --color-berget-brand-muscaria-800: #530000;
610
+ --color-berget-brand-muscaria-900: #3a0000;
611
+ --color-berget-brand-muscaria-950: #220000;
612
+
613
+ /* Full Chanterelle scale (11 step) */
614
+ --color-berget-brand-chanterelle-50: #ffeeb7;
615
+ --color-berget-brand-chanterelle-100: #ffd976;
616
+ --color-berget-brand-chanterelle-200: #ffc11e;
617
+ --color-berget-brand-chanterelle-300: #e3a500;
618
+ --color-berget-brand-chanterelle-400: #bc8800;
619
+ --color-berget-brand-chanterelle-500: #926a04;
620
+ --color-berget-brand-chanterelle-600: #6b4d05;
621
+ --color-berget-brand-chanterelle-700: #493403;
622
+ --color-berget-brand-chanterelle-800: #322202;
623
+ --color-berget-brand-chanterelle-900: #201501;
624
+ --color-berget-brand-chanterelle-950: #100900;
625
+
626
+ /* (No legacy single-value aliases) */
627
+
628
+ /* Semantic surface aliases */
629
+ --color-berget-background: var(--berget-background);
630
+ --color-berget-foreground: var(--berget-foreground);
631
+ --color-berget-foreground-alt: var(--berget-foreground-alt);
632
+ --color-berget-body-background: var(--berget-body-background);
633
+ --color-berget-mid-alt: var(--berget-mid-alt);
634
+ --color-berget-card: var(--berget-card);
635
+ --color-berget-card-foreground: var(--berget-card-foreground);
636
+ --color-berget-popover: var(--berget-popover);
637
+ --color-berget-popover-foreground: var(--berget-popover-foreground);
638
+ --color-berget-muted: var(--berget-muted);
639
+ --color-berget-muted-foreground: var(--berget-muted-foreground);
640
+ --color-berget-primary: var(--berget-primary);
641
+ --color-berget-primary-foreground: var(--berget-primary-foreground);
642
+ --color-berget-primary-hover: var(--berget-primary-hover);
643
+ --color-berget-secondary: var(--berget-secondary);
644
+ --color-berget-secondary-foreground: var(--berget-secondary-foreground);
645
+ --color-berget-secondary-hover: var(--berget-secondary-hover);
646
+ --color-berget-accent: var(--berget-accent);
647
+ --color-berget-accent-foreground: var(--berget-accent-foreground);
648
+ --color-berget-accent-2: var(--berget-accent-2);
649
+ --color-berget-accent-3: var(--berget-accent-3);
650
+ --color-berget-ghost: var(--berget-ghost);
651
+ --color-berget-ghost-hover: var(--berget-ghost-hover);
652
+ --color-berget-ghost-foreground: var(--berget-ghost-foreground);
653
+ --color-berget-outline: var(--berget-outline);
654
+ --color-berget-outline-hover: var(--berget-outline-hover);
655
+ --color-berget-outline-active: var(--berget-outline-active);
656
+ --color-berget-border: var(--berget-border);
657
+ --color-berget-input: var(--berget-input);
658
+ --color-berget-ring: var(--berget-focus-ring);
659
+ --color-berget-ring-error: var(--berget-ring-error);
660
+ --color-berget-destructive: var(--berget-destructive);
661
+ --color-berget-destructive-foreground: var(--berget-destructive-foreground);
662
+ --color-berget-destructive-border: var(--berget-destructive-border);
663
+ --color-berget-backdrop: var(--berget-backdrop);
664
+
665
+ /* Interactive surface + subtle border aliases */
666
+ --color-berget-surface-hover: var(--berget-surface-hover);
667
+ --color-berget-surface-subtle: var(--berget-surface-subtle);
668
+ --color-berget-surface-raised: var(--berget-surface-raised);
669
+ --color-berget-border-subtle: var(--berget-border-subtle);
670
+ --color-berget-border-interactive: var(--berget-border-interactive);
671
+ --color-berget-border-interactive-elevated: var(--berget-border-interactive-elevated);
672
+ --color-berget-separator: var(--berget-separator);
673
+ --color-berget-separator-subtle: var(--berget-separator-subtle);
674
+ --color-berget-icon-muted: var(--berget-icon-muted);
675
+
676
+ /* Primary tint + focus + dark-surface aliases */
677
+ --color-berget-primary-tint: var(--berget-primary-tint);
678
+ --color-berget-primary-tint-hover: var(--berget-primary-tint-hover);
679
+ --color-berget-primary-border: var(--berget-primary-border);
680
+ --color-berget-form-focus-border: var(--berget-form-focus-border);
681
+ --color-berget-surface-hover-dark: var(--berget-surface-hover-dark);
682
+
683
+ /* Status aliases */
684
+ --color-berget-info: var(--berget-info);
685
+ --color-berget-info-foreground: var(--berget-info-foreground);
686
+ --color-berget-info-border: var(--berget-info-border);
687
+ --color-berget-success: var(--berget-success);
688
+ --color-berget-success-foreground: var(--berget-success-foreground);
689
+ --color-berget-success-border: var(--berget-success-border);
690
+ --color-berget-warning: var(--berget-warning);
691
+ --color-berget-warning-foreground: var(--berget-warning-foreground);
692
+ --color-berget-warning-border: var(--berget-warning-border);
693
+
694
+ /* Button component-scoped aliases — must use bare var(--berget-button-*) so
695
+ Tailwind opacity modifiers (e.g. /90) work. Values are full colours from
696
+ Section B; the /90 modifier darkens the token via oklch mixing. */
697
+ --color-berget-button-default-bg: var(--berget-button-default-bg);
698
+ --color-berget-button-default-fg: var(--berget-button-default-fg);
699
+ --color-berget-button-primary-bg: var(--berget-button-primary-bg);
700
+ --color-berget-button-primary-fg: var(--berget-button-primary-fg);
701
+ --color-berget-button-secondary-bg: var(--berget-button-secondary-bg);
702
+ --color-berget-button-secondary-fg: var(--berget-button-secondary-fg);
703
+ --color-berget-button-destructive-bg: var(--berget-button-destructive-bg);
704
+ --color-berget-button-destructive-fg: var(--berget-button-destructive-fg);
705
+ --color-berget-button-link-fg: var(--berget-button-link-fg);
706
+
707
+ /* Core surface + text aliases */
708
+ --color-berget-surface-01: var(--berget-surface-01);
709
+ --color-berget-surface-02: var(--berget-surface-02);
710
+ --color-berget-surface-subtlest: var(--berget-surface-subtlest);
711
+ --color-berget-text-inverse: var(--berget-text-inverse);
712
+
713
+ /* Card component-scoped aliases */
714
+ --color-berget-card-filled-bg: var(--berget-card-filled-bg);
715
+
716
+ /* CodeBlock component-scoped aliases */
717
+ --color-berget-codeblock-bg: var(--berget-codeblock-bg);
718
+ --color-berget-codeblock-header-bg: var(--berget-codeblock-header-bg);
719
+
720
+ /* Badge component-scoped aliases */
721
+ --color-berget-badge-default-bg: var(--berget-badge-default-bg);
722
+ --color-berget-badge-default-fg: var(--berget-badge-default-fg);
723
+ --color-berget-badge-active-bg: var(--berget-badge-active-bg);
724
+ --color-berget-badge-active-fg: var(--berget-badge-active-fg);
725
+ --color-berget-badge-tag-default-bg: var(--berget-badge-tag-default-bg);
726
+ --color-berget-badge-tag-default-fg: var(--berget-badge-tag-default-fg);
727
+ --color-berget-badge-tag-active-bg: var(--berget-badge-tag-active-bg);
728
+ --color-berget-badge-tag-active-fg: var(--berget-badge-tag-active-fg);
729
+ --color-berget-badge-tag-ghost-bg: var(--berget-badge-tag-ghost-bg);
730
+ --color-berget-badge-tag-ghost-fg: var(--berget-badge-tag-ghost-fg);
731
+
732
+ /* Switch component-scoped aliases */
733
+ --color-berget-switch-primary-checked: var(--berget-switch-primary-checked);
734
+ --color-berget-switch-subtle-checked: var(--berget-switch-subtle-checked);
735
+
736
+ /* Logo tokens */
737
+ --color-berget-logo-light: var(--berget-logo-light);
738
+ --color-berget-logo-dark: var(--berget-logo-dark);
739
+
740
+ /* FeatureCards component-scoped aliases */
741
+ --color-berget-feature-card-badge-bg: var(--berget-feature-card-badge-bg);
742
+ --color-berget-feature-card-badge-fg: var(--berget-feature-card-badge-fg);
743
+
744
+ /* Section component-scoped aliases */
745
+ --color-berget-section-muted-bg: var(--berget-section-muted-bg);
746
+
747
+ /* Sidebar aliases */
748
+ --color-berget-sidebar: var(--berget-sidebar);
749
+ --color-berget-sidebar-foreground: var(--berget-sidebar-foreground);
750
+ --color-berget-sidebar-accent: var(--berget-sidebar-accent);
751
+ --color-berget-sidebar-accent-foreground: var(--berget-sidebar-accent-foreground);
752
+ --color-berget-sidebar-border: var(--berget-sidebar-border);
753
+ --color-berget-sidebar-ring: var(--berget-sidebar-ring);
754
+
755
+ /* Chart */
756
+ --color-berget-chart-1: var(--berget-chart-1);
757
+ --color-berget-chart-2: var(--berget-chart-2);
758
+ --color-berget-chart-3: var(--berget-chart-3);
759
+ --color-berget-chart-4: var(--berget-chart-4);
760
+ --color-berget-chart-5: var(--berget-chart-5);
761
+
762
+ /* Shadows */
763
+ --shadow-berget-sm: var(--berget-shadow-sm);
764
+ --shadow-berget-md: var(--berget-shadow-md);
765
+ --shadow-berget-lg: var(--berget-shadow-lg);
766
+
767
+ /* Border radii */
768
+ --radius-berget-none: var(--berget-radius-none);
769
+ --radius-berget-xs: var(--berget-radius-xs);
770
+ --radius-berget-sm: var(--berget-radius-sm);
771
+ --radius-berget-md: var(--berget-radius-md);
772
+ --radius-berget-lg: var(--berget-radius-lg);
773
+ --radius-berget-full: var(--berget-radius-full);
774
+
775
+ /* Icon stroke widths */
776
+ --stroke-icon-sm: 1.4px;
777
+ --stroke-icon-md: 1.6px;
778
+ --stroke-icon-lg: 1.8px;
779
+
780
+ /* Typography scale - fluid */
781
+ /* Heading 1 (Ovo, Serif) */
782
+ --text-h1: clamp(1.875rem, 0.714rem + 4.76vw, 5rem);
783
+ --leading-h1: var(--berget-heading-leading);
784
+ --tracking-h1: var(--berget-heading-spacing);
785
+ --font-h1: 'Ovo', serif;
786
+
787
+ /* Heading 2 (Ovo, Serif) */
788
+ --text-h2: clamp(1.75rem, 1.47rem + 1.14vw, 2.5rem);
789
+ --leading-h2: var(--berget-heading-leading);
790
+ --tracking-h2: var(--berget-heading-spacing);
791
+ --font-h2: 'Ovo', serif;
792
+
793
+ /* Heading 3 (DM Sans, Sans) */
794
+ --text-h3: clamp(1.25rem, 1.16rem + 0.38vw, 1.5rem);
795
+ --leading-h3: var(--berget-heading-leading);
796
+ --tracking-h3: var(--berget-body-spacing);
797
+ --font-h3: 'DM Sans', sans-serif;
798
+
799
+ /* Heading 4 (Ovo, Serif) */
800
+ --text-h4: clamp(1.25rem, 1.16rem + 0.38vw, 1.5rem);
801
+ --leading-h4: var(--berget-heading-leading);
802
+ --tracking-h4: var(--berget-body-spacing);
803
+ --font-h4: 'Ovo', serif;
804
+
805
+ /* Paragraph (DM Sans, Sans) */
806
+ --text-p: 1rem;
807
+ --leading-p: var(--berget-body-leading);
808
+ --font-p: 'DM Sans', sans-serif;
809
+
810
+ /* Large body text (DM Sans, Sans) */
811
+ --text-lg: 1.125rem;
812
+ --leading-lg: var(--berget-body-leading);
813
+ --font-lg: 'DM Sans', sans-serif;
814
+ --tracking-lg: var(--berget-body-spacing);
815
+
816
+ /* Small body text (DM Sans, Sans) */
817
+ --text-sm: 0.875rem;
818
+ --leading-sm: var(--berget-body-leading);
819
+ --font-sm: 'DM Sans', sans-serif;
820
+ --tracking-sm: var(--berget-body-spacing);
821
+
822
+ /* Extra small body text (DM Sans, Sans) */
823
+ --text-xs: 0.75rem;
824
+ --leading-xs: var(--berget-body-leading);
825
+ --font-xs: 'DM Sans', sans-serif;
826
+ --tracking-xs: var(--berget-body-spacing);
827
+
828
+ /* Heading 5 (DM Sans, Sans) */
829
+ --text-xl: 1.25rem;
830
+ --leading-xl: var(--berget-heading-leading);
831
+ --font-xl: 'DM Sans', sans-serif;
832
+ --tracking-xl: var(--berget-body-spacing);
833
+
834
+ /* Monospaced (DM Mono, Monospace) */
835
+ --text-mono: 1rem;
836
+ --leading-mono: var(--berget-body-leading);
837
+ --font-mono: 'DM Mono', monospace;
838
+
839
+ /* Fluid Spacing Scale (Base 16px) */
840
+ /* Viewport range: 390px → 1440px */
841
+ --spacing-fluid-xs: clamp(0.5rem, 0.41rem + 0.38vw, 0.75rem);
842
+ --spacing-fluid-sm: clamp(0.75rem, 0.66rem + 0.38vw, 1rem);
843
+ --spacing-fluid-md: clamp(1rem, 0.82rem + 0.76vw, 1.5rem);
844
+ --spacing-fluid-lg: clamp(1.5rem, 1.14rem + 1.52vw, 2.5rem);
845
+ --spacing-fluid-xl: clamp(2.5rem, 1.96rem + 2.29vw, 4rem);
846
+ --spacing-fluid-2xl: clamp(4rem, 2.93rem + 4.38vw, 6.875rem);
847
+
848
+ /* Semantiska Layout-alias */
849
+ --spacing-container-px: var(--spacing-fluid-md);
850
+ --spacing-section-py: var(--spacing-fluid-xl);
851
+ --spacing-gutter: var(--spacing-fluid-lg);
852
+ }
853
+
854
+ @keyframes float-slow {
855
+ 0%,
856
+ 100% {
857
+ transform: translateY(0) translateX(0);
858
+ }
859
+ 33% {
860
+ transform: translateY(-8px) translateX(4px);
861
+ }
862
+ 66% {
863
+ transform: translateY(4px) translateX(-6px);
864
+ }
865
+ }
866
+
867
+ @keyframes float-medium {
868
+ 0%,
869
+ 100% {
870
+ transform: translateY(0) translateX(0);
871
+ }
872
+ 25% {
873
+ transform: translateY(-12px) translateX(6px);
874
+ }
875
+ 50% {
876
+ transform: translateY(6px) translateX(-8px);
877
+ }
878
+ 75% {
879
+ transform: translateY(-4px) translateX(10px);
880
+ }
881
+ }
882
+
883
+ @keyframes float-fast {
884
+ 0%,
885
+ 100% {
886
+ transform: translateY(0) translateX(0);
887
+ }
888
+ 20% {
889
+ transform: translateY(-10px) translateX(8px);
890
+ }
891
+ 40% {
892
+ transform: translateY(8px) translateX(-6px);
893
+ }
894
+ 60% {
895
+ transform: translateY(-6px) translateX(12px);
896
+ }
897
+ 80% {
898
+ transform: translateY(4px) translateX(-10px);
899
+ }
900
+ }
901
+
902
+ @keyframes fadeIn {
903
+ from {
904
+ opacity: 0;
905
+ transform: translateY(10px);
906
+ }
907
+ to {
908
+ opacity: 1;
909
+ transform: translateY(0);
910
+ }
911
+ }
912
+
913
+ @utility header-backdrop {
914
+ background: linear-gradient(
915
+ 180deg,
916
+ var(--color-background) 0,
917
+ color-mix(in oklab, var(--color-background) 80%, transparent) 100%
918
+ );
919
+ }