@almadar/ui 6.29.0 → 6.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/{EntityBindingContext-UyeCfEBS.d.cts → EntityBindingContext-ChCONv2W.d.cts} +1 -50
  2. package/dist/{EntityBindingContext-UyeCfEBS.d.ts → EntityBindingContext-ChCONv2W.d.ts} +1 -50
  3. package/dist/avl/index.cjs +5 -6
  4. package/dist/avl/index.js +5 -6
  5. package/dist/components/index.cjs +4 -5
  6. package/dist/components/index.js +4 -5
  7. package/dist/context/index.cjs +135 -105
  8. package/dist/context/index.d.cts +2 -60
  9. package/dist/context/index.d.ts +2 -60
  10. package/dist/context/index.js +135 -105
  11. package/dist/lib/index.cjs +455 -0
  12. package/dist/lib/index.d.cts +42 -1
  13. package/dist/lib/index.d.ts +42 -1
  14. package/dist/lib/index.js +438 -1
  15. package/dist/marketing/index.cjs +4 -5
  16. package/dist/marketing/index.js +4 -5
  17. package/dist/providers/index.cjs +143 -116
  18. package/dist/providers/index.d.cts +1 -1
  19. package/dist/providers/index.d.ts +1 -1
  20. package/dist/providers/index.js +143 -116
  21. package/dist/runtime/index.cjs +5 -6
  22. package/dist/runtime/index.d.cts +2 -2
  23. package/dist/runtime/index.d.ts +2 -2
  24. package/dist/runtime/index.js +5 -6
  25. package/dist/themeTokens-DVRwufw8.d.cts +112 -0
  26. package/dist/themeTokens-DVRwufw8.d.ts +112 -0
  27. package/package.json +6 -5
  28. package/scripts/audit-tailwind-safelist.ts +4 -0
  29. package/tailwind-preset.cjs +155 -28
  30. package/themes/almadar-website.css +37 -107
  31. package/themes/almadar.css +37 -108
  32. package/themes/atelier.css +145 -240
  33. package/themes/bloomberg-dense.css +145 -252
  34. package/themes/clay.css +39 -137
  35. package/themes/comic.css +39 -145
  36. package/themes/corporate.css +39 -131
  37. package/themes/game-adventure.css +22 -87
  38. package/themes/game-rpg.css +22 -84
  39. package/themes/game-sci-fi.css +22 -88
  40. package/themes/game-ui-pack.css +22 -85
  41. package/themes/gazette.css +43 -135
  42. package/themes/glass.css +39 -148
  43. package/themes/kiosk.css +51 -146
  44. package/themes/linear-clean.css +145 -215
  45. package/themes/minimalist.css +39 -125
  46. package/themes/neon.css +39 -132
  47. package/themes/notion-editorial.css +145 -215
  48. package/themes/prism.css +37 -100
  49. package/themes/retro.css +39 -130
  50. package/themes/terminal.css +61 -152
  51. package/themes/trait-wars.css +121 -285
  52. package/themes/wireframe.css +41 -128
@@ -0,0 +1,112 @@
1
+ import { ThemeRef, ThemeDefinition, ThemeTokens, ThemeVariant, DensityTokens, ElevationTokens, GeometryTokens, IconographyTokens, MotionDurationKey, MotionEasingKey, MotionIntentMap, TypeScaleTokens, TypeIntentMap, TypeSizeKey } from '@almadar/core';
2
+
3
+ /**
4
+ * themeTokens — runtime mirror of the orbital compiler's theme codegen.
5
+ *
6
+ * The compile path (orbital-rust/crates/orbital-shell-typescript/src/codegen/theme.rs)
7
+ * reads `OrbitalDefinition.theme.tokens` and emits CSS custom-property
8
+ * declarations into a `[data-theme="<name>-<mode>"]` block. The runtime
9
+ * does not parse compiled CSS — it reads the same `tokens` object directly
10
+ * and produces the same `{ '--color-primary': '…', '--radius-md': '…' }` map
11
+ * that the compiler emits.
12
+ *
13
+ * Keeping the two paths byte-identical at the variable level is the contract:
14
+ * editing tokens via the Studio Design System tab must produce the exact
15
+ * same rendered result as editing them in source and running `orbital
16
+ * compile`. The mapping rules here mirror `generate_tokens_css` /
17
+ * `generate_tokens_css_dark` (theme.rs:122–351).
18
+ *
19
+ * Compile vs runtime difference (intentional):
20
+ * - Compile emits the FULL set: schema overrides on top of defaults. This is
21
+ * needed because the compiled CSS replaces the theme entirely.
22
+ * - Runtime emits ONLY the keys present in `tokens` (and `variants.dark`).
23
+ * Missing keys cascade from the parent `[data-theme]` rule on the document
24
+ * element. The provider scopes overrides to an orbital subtree without
25
+ * shadowing inherited defaults.
26
+ *
27
+ * The per-axis var tables below (`DENSITY_SPACING_VARS`, `TYPE_INTENT_VARS`, …)
28
+ * are the ONE mapping between a typed-axis field and its CSS variable name.
29
+ * `themeTokensToCssVars` reads them forward (token → CSS); `almadar-core`'s
30
+ * one-time `scripts/migrate-css-themes.ts` reads them in reverse (CSS →
31
+ * token) to build `packages/almadar-core/themes/*.json` from the checked-in
32
+ * preset CSS — see that script for the inverse direction.
33
+ *
34
+ * @packageDocumentation
35
+ */
36
+
37
+ /** Resolved color mode. Mirrors `ThemeContext.resolvedMode`. */
38
+ type ThemeMode = 'light' | 'dark';
39
+ /** The keys of `T` whose value is a plain (optional) string — excludes
40
+ * nested-object fields like `DensityTokens['spacing']` or
41
+ * `TypeScaleTokens['scale']`, which are never single CSS values. */
42
+ type StringValueKey<T> = {
43
+ [K in keyof T]-?: T[K] extends string | undefined ? K : never;
44
+ }[keyof T] & string;
45
+ /** One flat scalar field on an axis object and the CSS var name it maps to. */
46
+ interface FlatVarEntry<T> {
47
+ readonly cssVar: string;
48
+ readonly key: StringValueKey<T>;
49
+ }
50
+ /** Density axis — spacing scale steps (`density.spacing.space<N>` → `--space-<N>`). */
51
+ declare const DENSITY_SPACING_VARS: ReadonlyArray<FlatVarEntry<NonNullable<DensityTokens['spacing']>>>;
52
+ /** Density axis — per-element heights + paddings. */
53
+ declare const DENSITY_ELEMENT_VARS: ReadonlyArray<FlatVarEntry<DensityTokens>>;
54
+ /** Type axis — family triplet. */
55
+ declare const TYPE_FAMILY_VARS: ReadonlyArray<FlatVarEntry<TypeScaleTokens>>;
56
+ /** Type axis — size scale keys, ordered exactly as emitted. Each pairs `--text-<k>` / `--leading-<k>`. */
57
+ declare const TYPE_SIZE_KEYS: ReadonlyArray<TypeSizeKey>;
58
+ /** Type axis — intent names, ordered exactly as emitted. Each is 3 vars: `-size` / `-weight` / `-leading`. */
59
+ declare const TYPE_INTENT_VARS: ReadonlyArray<{
60
+ key: keyof TypeIntentMap & string;
61
+ cssName: string;
62
+ }>;
63
+ /** Motion axis — duration palette keys, ordered exactly as emitted. */
64
+ declare const MOTION_DURATION_KEYS: ReadonlyArray<MotionDurationKey>;
65
+ /** Motion axis — easing palette keys, ordered exactly as emitted. */
66
+ declare const MOTION_EASING_KEYS: ReadonlyArray<MotionEasingKey>;
67
+ /** Motion axis — intent names, ordered exactly as emitted. Each is 2 vars: `-duration` / `-easing`. */
68
+ declare const MOTION_INTENT_VARS: ReadonlyArray<{
69
+ key: keyof MotionIntentMap & string;
70
+ cssName: string;
71
+ }>;
72
+ /** Iconography axis — flat fields. */
73
+ declare const ICONOGRAPHY_VARS: ReadonlyArray<FlatVarEntry<IconographyTokens>>;
74
+ /** Elevation axis — flat fields. */
75
+ declare const ELEVATION_VARS: ReadonlyArray<FlatVarEntry<ElevationTokens>>;
76
+ /** Geometry axis — flat fields. */
77
+ declare const GEOMETRY_VARS: ReadonlyArray<FlatVarEntry<GeometryTokens>>;
78
+ /** Legacy free-form map prefixes (`ThemeTokens.colors`/`radii`/`spacing`/`shadows`). `typography` has no prefix — see below. */
79
+ declare const LEGACY_PREFIXES: {
80
+ readonly colors: "--color-";
81
+ readonly radii: "--radius-";
82
+ readonly spacing: "--space-";
83
+ readonly shadows: "--shadow-";
84
+ };
85
+ /**
86
+ * Convert `ThemeTokens` (+ optional dark variant) into a CSS custom-property
87
+ * map keyed by variable name (e.g. `--color-primary`).
88
+ *
89
+ * Mapping rules (mirror theme.rs):
90
+ * - `tokens.colors.<k>` → `--color-<k>`
91
+ * - `tokens.radii.<k>` → `--radius-<k>`
92
+ * - `tokens.spacing.<k>` → `--space-<k>`
93
+ * - `tokens.typography.<k>` → `--<k>` (keys already include their `font-`/
94
+ * `letter-`/`line-` prefix)
95
+ * - `tokens.shadows.<k>` → `--shadow-<k>` (schema key has no prefix)
96
+ *
97
+ * In `'dark'` mode, the `darkVariant` overrides are merged on top of the
98
+ * base tokens per category — same precedence the Rust compiler uses
99
+ * (`generate_tokens_css_dark`). Categories not present in `darkVariant` fall
100
+ * back to the base tokens.
101
+ */
102
+ declare function themeTokensToCssVars(tokens: ThemeTokens, mode?: ThemeMode, darkVariant?: ThemeVariant): Record<string, string>;
103
+ /**
104
+ * `ThemeRef` is `ThemeDefinition | string`. When it's a string, it's an
105
+ * unresolved import reference (e.g. `"Ocean.theme"`) that should have been
106
+ * inlined by the compiler's import phase before runtime. If we still see a
107
+ * string here, the upstream resolution path didn't run — return `undefined`
108
+ * rather than guess. `OrbitalThemeProvider` falls through to passthrough.
109
+ */
110
+ declare function resolveThemeForRuntime(theme: ThemeRef | undefined): ThemeDefinition | undefined;
111
+
112
+ export { DENSITY_ELEMENT_VARS as D, ELEVATION_VARS as E, type FlatVarEntry as F, GEOMETRY_VARS as G, ICONOGRAPHY_VARS as I, LEGACY_PREFIXES as L, MOTION_DURATION_KEYS as M, type StringValueKey as S, type ThemeMode as T, DENSITY_SPACING_VARS as a, MOTION_EASING_KEYS as b, MOTION_INTENT_VARS as c, TYPE_FAMILY_VARS as d, TYPE_INTENT_VARS as e, TYPE_SIZE_KEYS as f, resolveThemeForRuntime as r, themeTokensToCssVars as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "6.29.0",
3
+ "version": "6.30.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -118,11 +118,11 @@
118
118
  "access": "public"
119
119
  },
120
120
  "dependencies": {
121
- "@almadar/core": "^10.96.0",
121
+ "@almadar/core": "^10.99.0",
122
122
  "@almadar/evaluator": "^2.47.0",
123
123
  "@almadar/logger": "^1.12.0",
124
- "@almadar/runtime": "^6.83.0",
125
- "@almadar/std": "^16.220.0",
124
+ "@almadar/runtime": "^6.84.0",
125
+ "@almadar/std": "^16.223.0",
126
126
  "@almadar/syntax": "^1.17.0",
127
127
  "@dnd-kit/core": "^6.3.1",
128
128
  "@dnd-kit/sortable": "^10.0.0",
@@ -239,6 +239,7 @@
239
239
  "build:watch": "tsup --watch",
240
240
  "typecheck": "tsc --noEmit",
241
241
  "lint": "eslint --no-warn-ignored --max-warnings 0 .",
242
- "verify:themes": "node scripts/theme-contrast-audit.mjs"
242
+ "verify:themes": "node scripts/theme-contrast-audit.mjs",
243
+ "verify:safelist": "tsx scripts/audit-tailwind-safelist.ts"
243
244
  }
244
245
  }
@@ -234,4 +234,8 @@ if (fix) {
234
234
  } else {
235
235
  console.log();
236
236
  console.log('Run with --fix to add missing classes to the preset.');
237
+ // A missing entry here means a component ships a class Tailwind will silently
238
+ // drop CSS for (the Gantt bar defect: axis rendered, bars were invisible on
239
+ // every reload) — CI must fail so it is caught at merge, not in production.
240
+ process.exit(1);
237
241
  }
@@ -13,6 +13,18 @@
13
13
  * presets: [require('@almadar/ui/tailwind-preset')]
14
14
  */
15
15
 
16
+ // Tailwind can only apply an opacity modifier (`bg-primary/50`) to a color it
17
+ // can compute alpha for itself — a bare `var(--color-x)` string is opaque to
18
+ // it, so every semantic token below must resolve through this function or its
19
+ // `/NN` utilities silently generate no CSS rule at all (not even with the
20
+ // class safelisted — confirmed via a standalone `tailwindcss` CLI build).
21
+ function withOpacity(varName) {
22
+ return ({ opacityValue }) =>
23
+ opacityValue === undefined
24
+ ? `var(${varName})`
25
+ : `color-mix(in srgb, var(${varName}) calc(${opacityValue} * 100%), transparent)`;
26
+ }
27
+
16
28
  /** @type {import('tailwindcss').Config} */
17
29
  module.exports = {
18
30
  darkMode: 'class',
@@ -111,8 +123,7 @@ module.exports = {
111
123
  'animate-[shake_0.3s_ease-in-out]',
112
124
  'aspect-[3/4]',
113
125
  'bg-[radial-gradient(circle_at_center,rgba(34,197,94,0.2),transparent_70%)]',
114
- 'bg-[radial-gradient(ellipse_at_top,var(--color-primary)/0.08,transparent_60%),',
115
- 'radial-gradient(ellipse_at_bottom_right,var(--color-accent)/0.06,transparent_50%)]',
126
+ 'bg-[radial-gradient(ellipse_at_top,var(--color-primary)/0.08,transparent_60%),radial-gradient(ellipse_at_bottom_right,var(--color-accent)/0.06,transparent_50%)]',
116
127
  'bg-[var(--color-background)]',
117
128
  'bg-[var(--color-card)]',
118
129
  'bg-[var(--color-table-header)]',
@@ -264,6 +275,122 @@ module.exports = {
264
275
  'z-[1000]',
265
276
  'z-[1001]',
266
277
  'z-[60]',
278
+
279
+ // Auto-added by audit-tailwind-safelist.ts (2026-09-19)
280
+ 'bg-[var(--color-border)]',
281
+ 'bg-[var(--color-muted)]',
282
+ 'bg-[var(--color-primary)]',
283
+ 'bg-[var(--color-surface-subtle)]',
284
+ 'bg-[var(--color-surface)]',
285
+ 'bg-[var(--color-warning)]',
286
+ 'bg-accent/15',
287
+ 'bg-background/60',
288
+ 'bg-background/95',
289
+ 'bg-card/40',
290
+ 'bg-card/50',
291
+ 'bg-card/90',
292
+ 'bg-card/95',
293
+ 'bg-error/15',
294
+ 'bg-error/70',
295
+ 'bg-error/80',
296
+ 'bg-foreground/40',
297
+ 'bg-muted-foreground/50',
298
+ 'bg-muted/10',
299
+ 'bg-muted/40',
300
+ 'bg-primary/15',
301
+ 'bg-primary/80',
302
+ 'bg-secondary/10',
303
+ 'bg-success/15',
304
+ 'bg-success/80',
305
+ 'bg-warning/15',
306
+ 'bg-warning/80',
307
+ 'border-[length:var(--border-width-thick)]',
308
+ 'border-[var(--color-primary)]',
309
+ 'border-[var(--color-warning)]',
310
+ 'border-border/10',
311
+ 'border-border/20',
312
+ 'border-border/50',
313
+ 'border-error/40',
314
+ 'border-error/70',
315
+ 'border-info/70',
316
+ 'border-l-[length:var(--border-width-thin)]',
317
+ 'border-primary/20',
318
+ 'border-primary/40',
319
+ 'border-success/40',
320
+ 'border-success/50',
321
+ 'border-success/70',
322
+ 'border-warning/40',
323
+ 'border-warning/60',
324
+ 'border-y-[length:var(--border-width)]',
325
+ 'bottom-[15%]',
326
+ 'data-[empty=true]',
327
+ 'focus-visible:ring-[length:var(--focus-ring-width)]',
328
+ 'focus-visible:ring-offset-[length:var(--focus-ring-offset)]',
329
+ 'focus-within:border-[var(--color-primary)]',
330
+ 'from-primary/90',
331
+ 'group-hover:bg-[var(--color-surface-subtle)]',
332
+ 'h-[1.25rem]',
333
+ 'h-[1.5rem]',
334
+ 'hover:bg-[var(--color-card-hover,transparent)]',
335
+ 'hover:bg-[var(--color-muted)]',
336
+ 'hover:bg-[var(--color-surface-subtle)]',
337
+ 'hover:bg-[var(--color-surface)]',
338
+ 'hover:bg-foreground/10',
339
+ 'hover:bg-muted-foreground/70',
340
+ 'hover:bg-muted/30',
341
+ 'hover:bg-muted/40',
342
+ 'hover:bg-primary-foreground/15',
343
+ 'hover:bg-primary-foreground/20',
344
+ 'hover:text-[var(--color-foreground)]',
345
+ 'hover:text-info/80',
346
+ 'hover:translate-y-[var(--hover-translate-y)]',
347
+ 'left-[15%]',
348
+ 'max-h-[36rem]',
349
+ 'max-h-[60vh]',
350
+ 'max-w-[calc(100vw-1.5rem)]',
351
+ 'max-w-[calc(100vw-1rem)]',
352
+ 'max-w-[calc(100vw-2rem)]',
353
+ 'md:grid-cols-[var(--master-detail-cols)]',
354
+ 'md:max-w-[50%]',
355
+ 'md:min-w-[160px]',
356
+ 'md:min-w-[45%]',
357
+ 'min-h-[16rem]',
358
+ 'min-h-[3rem]',
359
+ 'min-h-[8rem]',
360
+ 'min-w-[10rem]',
361
+ 'min-w-[16rem]',
362
+ 'min-w-[2px]',
363
+ 'min-w-[400px]',
364
+ 'min-w-[520px]',
365
+ 'min-w-[600px]',
366
+ 'min-w-[700px]',
367
+ 'min-w-[8rem]',
368
+ 'pt-[10vh]',
369
+ 'py-[1px]',
370
+ 'right-[15%]',
371
+ 'ring-primary/40',
372
+ 'scale-[var(--hover-scale)]',
373
+ 'sm:min-w-[200px]',
374
+ 'sm:min-w-[300px]',
375
+ 'sm:w-[28rem]',
376
+ 'sm:w-[340px]',
377
+ 'sm:w-[480px]',
378
+ 'sm:w-[640px]',
379
+ 'text-[10px]',
380
+ 'text-[11px]',
381
+ 'text-[var(--color-danger)]',
382
+ 'text-[var(--color-primary)]',
383
+ 'text-[var(--color-success)]',
384
+ 'text-[var(--color-warning-foreground)]',
385
+ 'text-[var(--color-warning)]',
386
+ 'text-foreground/50',
387
+ 'top-[15%]',
388
+ 'translate-x-[1.25rem]',
389
+ 'w-[1.25rem]',
390
+ 'w-[2.75rem]',
391
+ 'w-[400px]',
392
+ 'z-[1]',
393
+ 'z-[45]',
267
394
  ],
268
395
  theme: {
269
396
  fontFamily: {
@@ -278,48 +405,48 @@ module.exports = {
278
405
  extend: {
279
406
  colors: {
280
407
  primary: {
281
- DEFAULT: 'var(--color-primary)',
282
- foreground: 'var(--color-primary-foreground)',
283
- hover: 'var(--color-primary-hover)',
408
+ DEFAULT: withOpacity('--color-primary'),
409
+ foreground: withOpacity('--color-primary-foreground'),
410
+ hover: withOpacity('--color-primary-hover'),
284
411
  },
285
412
  secondary: {
286
- DEFAULT: 'var(--color-secondary)',
287
- foreground: 'var(--color-secondary-foreground)',
288
- hover: 'var(--color-secondary-hover)',
413
+ DEFAULT: withOpacity('--color-secondary'),
414
+ foreground: withOpacity('--color-secondary-foreground'),
415
+ hover: withOpacity('--color-secondary-hover'),
289
416
  },
290
417
  muted: {
291
- DEFAULT: 'var(--color-muted)',
292
- foreground: 'var(--color-muted-foreground)',
418
+ DEFAULT: withOpacity('--color-muted'),
419
+ foreground: withOpacity('--color-muted-foreground'),
293
420
  },
294
421
  accent: {
295
- DEFAULT: 'var(--color-accent)',
296
- foreground: 'var(--color-accent-foreground)',
422
+ DEFAULT: withOpacity('--color-accent'),
423
+ foreground: withOpacity('--color-accent-foreground'),
297
424
  },
298
- background: 'var(--color-background)',
299
- foreground: 'var(--color-foreground)',
425
+ background: withOpacity('--color-background'),
426
+ foreground: withOpacity('--color-foreground'),
300
427
  card: {
301
- DEFAULT: 'var(--color-card)',
302
- foreground: 'var(--color-card-foreground)',
428
+ DEFAULT: withOpacity('--color-card'),
429
+ foreground: withOpacity('--color-card-foreground'),
303
430
  },
304
- surface: 'var(--color-surface)',
305
- border: 'var(--color-border)',
306
- input: 'var(--color-input)',
307
- ring: 'var(--color-ring)',
431
+ surface: withOpacity('--color-surface'),
432
+ border: withOpacity('--color-border'),
433
+ input: withOpacity('--color-input'),
434
+ ring: withOpacity('--color-ring'),
308
435
  error: {
309
- DEFAULT: 'var(--color-error)',
310
- foreground: 'var(--color-error-foreground)',
436
+ DEFAULT: withOpacity('--color-error'),
437
+ foreground: withOpacity('--color-error-foreground'),
311
438
  },
312
439
  success: {
313
- DEFAULT: 'var(--color-success)',
314
- foreground: 'var(--color-success-foreground)',
440
+ DEFAULT: withOpacity('--color-success'),
441
+ foreground: withOpacity('--color-success-foreground'),
315
442
  },
316
443
  warning: {
317
- DEFAULT: 'var(--color-warning)',
318
- foreground: 'var(--color-warning-foreground)',
444
+ DEFAULT: withOpacity('--color-warning'),
445
+ foreground: withOpacity('--color-warning-foreground'),
319
446
  },
320
447
  info: {
321
- DEFAULT: 'var(--color-info)',
322
- foreground: 'var(--color-info-foreground)',
448
+ DEFAULT: withOpacity('--color-info'),
449
+ foreground: withOpacity('--color-info-foreground'),
323
450
  },
324
451
  },
325
452
  borderRadius: {
@@ -1,52 +1,20 @@
1
1
  /**
2
- * Almadar Website Theme
3
- *
4
- * Brand-accurate theme for almadar.io based on Almadar Brand Guidelines.
5
- * Teal primary, Cyan accent, Sand Gold highlights, Plus Jakarta Sans typography.
6
- * Dark hero sections with light content sections (mixed mode).
2
+ * GENERATED do not edit by hand.
3
+ * Source: packages/almadar-core/themes/almadar-website.json
4
+ * Regenerate: node tools/almadar-pattern-sync/dist/index.js themes (or `almadar-sync themes`)
7
5
  */
8
6
 
9
- /* ==========================================================================
10
- * LIGHT MODE (content sections)
11
- * ========================================================================== */
12
7
  [data-theme="almadar-website-light"] {
13
- /* Shadows - neutral midnight-based (per brand) */
14
- --shadow-main: 0 4px 14px rgba(15, 23, 42, 0.1), 0 1px 3px rgba(15, 23, 42, 0.06);
15
- --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.08);
16
- --shadow-lg: 0 10px 15px rgba(15, 23, 42, 0.15);
17
- --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.05);
18
- --shadow-none: none;
19
- --shadow-hover: 0 12px 40px rgba(15, 23, 42, 0.15);
20
- --shadow-active: 0 2px 8px rgba(15, 23, 42, 0.1);
21
-
22
- /* Border radius - per brand (4/8/12/16) */
23
- --radius-none: 0px;
24
- --radius-sm: 4px;
25
- --radius-md: 8px;
26
- --radius-lg: 12px;
27
- --radius-xl: 16px;
28
- --radius-full: 9999px;
29
-
30
- /* Border width */
31
- --border-width: 1px;
32
- --border-width-thin: 1px;
33
- --border-width-thick: 2px;
34
-
35
- /* Colors - Teal on parchment */
36
8
  --color-primary: #0f766e;
37
9
  --color-primary-hover: #115e59;
38
10
  --color-primary-foreground: #ffffff;
39
-
40
11
  --color-secondary: #f1f5f9;
41
12
  --color-secondary-hover: #e2e8f0;
42
13
  --color-secondary-foreground: #0f172a;
43
-
44
14
  --color-accent: #c9a227;
45
15
  --color-accent-foreground: #0f172a;
46
-
47
16
  --color-muted: #f1f5f9;
48
17
  --color-muted-foreground: #5c6b80;
49
-
50
18
  --color-background: #ffffff;
51
19
  --color-foreground: #0f172a;
52
20
  --color-card: #ffffff;
@@ -55,10 +23,6 @@
55
23
  --color-border: #e2e8f0;
56
24
  --color-input: #e2e8f0;
57
25
  --color-ring: #14b8a6;
58
-
59
- /* Accent is gold in Almadar brand */
60
-
61
- /* Semantic colors */
62
26
  --color-error: #dc2626;
63
27
  --color-error-foreground: #ffffff;
64
28
  --color-success: #15803d;
@@ -67,100 +31,70 @@
67
31
  --color-warning-foreground: #000000;
68
32
  --color-info: #1d4ed8;
69
33
  --color-info-foreground: #ffffff;
70
-
71
- /* Icon styling */
72
- --icon-stroke-width: 1.75;
34
+ --radius-none: 0px;
35
+ --radius-sm: 4px;
36
+ --radius-md: 8px;
37
+ --radius-lg: 12px;
38
+ --radius-xl: 16px;
39
+ --radius-full: 9999px;
40
+ --border-width: 1px;
41
+ --border-width-thin: 1px;
42
+ --border-width-thick: 2px;
73
43
  --icon-color: #14b8a6;
74
-
75
- /* Transitions */
76
44
  --transition-fast: 150ms;
77
45
  --transition-normal: 250ms;
78
46
  --transition-slow: 400ms;
79
47
  --transition-timing: cubic-bezier(0.4, 0, 0.2, 1);
80
-
81
- /* Hover/Active */
82
48
  --hover-scale: 1.02;
83
49
  --hover-translate-y: -2px;
84
50
  --hover-translate-x: 0;
85
51
  --active-scale: 0.98;
86
52
  --active-translate-y: 0;
87
-
88
- /* Focus ring */
89
53
  --focus-ring-width: 2px;
90
54
  --focus-ring-offset: 2px;
91
55
  --focus-ring-color: #14b8a6;
92
-
93
- /* Layer 1 backfill (preserves current visual output, see themes/_contract.md) */
94
- /* Motion axis duration palette (aliases existing --transition-* for backward compat) */
56
+ --shadow-main: 0 4px 14px rgba(15, 23, 42, 0.1), 0 1px 3px rgba(15, 23, 42, 0.06);
57
+ --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.08);
58
+ --shadow-lg: 0 10px 15px rgba(15, 23, 42, 0.15);
59
+ --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.05);
60
+ --shadow-none: none;
61
+ --shadow-hover: 0 12px 40px rgba(15, 23, 42, 0.15);
62
+ --shadow-active: 0 2px 8px rgba(15, 23, 42, 0.1);
95
63
  --duration-instant: 0ms;
96
64
  --duration-fast: var(--transition-fast);
97
65
  --duration-normal: var(--transition-normal);
98
66
  --duration-slow: var(--transition-slow);
99
67
  --duration-dramatic: 600ms;
100
- /* Motion axis — easing palette (aliases existing --transition-timing for backward compat) */
101
68
  --easing-linear: linear;
102
69
  --easing-standard: var(--transition-timing);
103
70
  --easing-emphasized: cubic-bezier(0.2, 0, 0, 1);
104
71
  --easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
105
- /* Iconography axis */
106
72
  --icon-family: lucide;
73
+ --icon-stroke-width: 1.75;
107
74
  --icon-default-size: 16px;
108
- /* Elevation axis — per-layer mapping */
109
75
  --elevation-card: var(--shadow-sm);
110
76
  --elevation-popover: var(--shadow-main);
111
77
  --elevation-dialog: var(--shadow-lg);
112
78
  --elevation-toast: var(--shadow-main);
113
- /* Geometry axis — radius rhythm with intent */
114
79
  --radius-container: var(--radius-md);
115
80
  --radius-interactive: var(--radius-md);
116
81
  --radius-pill: var(--radius-full);
117
- /* Geometry axis — border-width rhythm */
118
82
  --border-hairline: 1px;
119
83
  --border-standard: var(--border-width);
120
84
  --border-heavy: var(--border-width-thick);
121
85
  }
122
86
 
123
- /* ==========================================================================
124
- * DARK MODE (hero sections, dark backgrounds)
125
- * ========================================================================== */
126
87
  [data-theme="almadar-website-dark"] {
127
- /* Shadows - dark mode, deeper (per brand) */
128
- --shadow-main: 0 4px 14px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
129
- --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
130
- --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5);
131
- --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.1);
132
- --shadow-none: none;
133
- --shadow-hover: 0 12px 40px rgba(0, 0, 0, 0.5);
134
- --shadow-active: 0 2px 8px rgba(0, 0, 0, 0.3);
135
-
136
- /* Border radius - per brand (4/8/12/16) */
137
- --radius-none: 0px;
138
- --radius-sm: 4px;
139
- --radius-md: 8px;
140
- --radius-lg: 12px;
141
- --radius-xl: 16px;
142
- --radius-full: 9999px;
143
-
144
- /* Border width */
145
- --border-width: 1px;
146
- --border-width-thin: 1px;
147
- --border-width-thick: 2px;
148
-
149
- /* Colors - Teal/Cyan on Midnight Blue */
150
88
  --color-primary: #14b8a6;
151
89
  --color-primary-hover: #2dd4bf;
152
90
  --color-primary-foreground: #042f2e;
153
-
154
91
  --color-secondary: #1e293b;
155
92
  --color-secondary-hover: #334155;
156
93
  --color-secondary-foreground: #f1f5f9;
157
-
158
94
  --color-accent: #d4b44a;
159
95
  --color-accent-foreground: #0f172a;
160
-
161
96
  --color-muted: #1e293b;
162
97
  --color-muted-foreground: #94a3b8;
163
-
164
98
  --color-background: #0f172a;
165
99
  --color-foreground: #f8fafc;
166
100
  --color-card: #1e293b;
@@ -169,14 +103,10 @@
169
103
  --color-border: #334155;
170
104
  --color-input: #334155;
171
105
  --color-ring: #14b8a6;
172
-
173
- /* Tertiary color (Gold in Almadar brand) */
174
106
  --color-tertiary: #c9a227;
175
107
  --color-tertiary-hover: #d4b44a;
176
108
  --color-tertiary-foreground: #0f172a;
177
109
  --color-tertiary-muted: rgba(201, 162, 39, 0.15);
178
-
179
- /* Semantic colors */
180
110
  --color-error: #f87171;
181
111
  --color-error-foreground: #000000;
182
112
  --color-success: #4ade80;
@@ -185,54 +115,54 @@
185
115
  --color-warning-foreground: #000000;
186
116
  --color-info: #38bdf8;
187
117
  --color-info-foreground: #000000;
188
-
189
- /* Icon styling */
190
- --icon-stroke-width: 1.75;
118
+ --radius-none: 0px;
119
+ --radius-sm: 4px;
120
+ --radius-md: 8px;
121
+ --radius-lg: 12px;
122
+ --radius-xl: 16px;
123
+ --radius-full: 9999px;
124
+ --border-width: 1px;
125
+ --border-width-thin: 1px;
126
+ --border-width-thick: 2px;
191
127
  --icon-color: #14b8a6;
192
-
193
- /* Transitions */
194
128
  --transition-fast: 150ms;
195
129
  --transition-normal: 250ms;
196
130
  --transition-slow: 400ms;
197
131
  --transition-timing: cubic-bezier(0.4, 0, 0.2, 1);
198
-
199
- /* Hover/Active */
200
132
  --hover-scale: 1.02;
201
133
  --hover-translate-y: -2px;
202
134
  --hover-translate-x: 0;
203
135
  --active-scale: 0.98;
204
136
  --active-translate-y: 0;
205
-
206
- /* Focus ring */
207
137
  --focus-ring-width: 2px;
208
138
  --focus-ring-offset: 2px;
209
139
  --focus-ring-color: #14b8a6;
210
-
211
- /* Layer 1 backfill (preserves current visual output, see themes/_contract.md) */
212
- /* Motion axis duration palette (aliases existing --transition-* for backward compat) */
140
+ --shadow-main: 0 4px 14px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);
141
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
142
+ --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5);
143
+ --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.1);
144
+ --shadow-none: none;
145
+ --shadow-hover: 0 12px 40px rgba(0, 0, 0, 0.5);
146
+ --shadow-active: 0 2px 8px rgba(0, 0, 0, 0.3);
213
147
  --duration-instant: 0ms;
214
148
  --duration-fast: var(--transition-fast);
215
149
  --duration-normal: var(--transition-normal);
216
150
  --duration-slow: var(--transition-slow);
217
151
  --duration-dramatic: 600ms;
218
- /* Motion axis — easing palette (aliases existing --transition-timing for backward compat) */
219
152
  --easing-linear: linear;
220
153
  --easing-standard: var(--transition-timing);
221
154
  --easing-emphasized: cubic-bezier(0.2, 0, 0, 1);
222
155
  --easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
223
- /* Iconography axis */
224
156
  --icon-family: lucide;
157
+ --icon-stroke-width: 1.75;
225
158
  --icon-default-size: 16px;
226
- /* Elevation axis — per-layer mapping */
227
159
  --elevation-card: var(--shadow-sm);
228
160
  --elevation-popover: var(--shadow-main);
229
161
  --elevation-dialog: var(--shadow-lg);
230
162
  --elevation-toast: var(--shadow-main);
231
- /* Geometry axis — radius rhythm with intent */
232
163
  --radius-container: var(--radius-md);
233
164
  --radius-interactive: var(--radius-md);
234
165
  --radius-pill: var(--radius-full);
235
- /* Geometry axis — border-width rhythm */
236
166
  --border-hairline: 1px;
237
167
  --border-standard: var(--border-width);
238
168
  --border-heavy: var(--border-width-thick);