@loidolt/theme-tokens 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,3 +14,15 @@ import { colors, semantic, spacing, tokens } from '@loidolt/theme-tokens';
14
14
  @import '@loidolt/theme-tokens/css';
15
15
  @import '@loidolt/theme-tokens/css/dark';
16
16
  ```
17
+
18
+ WCAG contrast arithmetic, for colours chosen at runtime:
19
+
20
+ ```ts
21
+ import { getContrastRatio, getContrastTextColor, meetsContrast } from '@loidolt/theme-tokens';
22
+
23
+ meetsContrast('#767676', '#ffffff'); // true — AA for body text
24
+ getContrastTextColor(userColour); // the theme ink that reads best on it
25
+ ```
26
+
27
+ Named media frames live in `aspectRatio` (`square`, `video`, `photo`, `portrait`, `wide`) and as
28
+ `--loidolt-aspect-*`.
@@ -36,6 +36,44 @@
36
36
  --loidolt-focus-ring: #f0895c;
37
37
  --loidolt-shadow-color: #000000;
38
38
  --loidolt-scrim: color-mix(in srgb, var(--loidolt-shadow-color) 78%, transparent);
39
+ --loidolt-chart-1: #e0672f;
40
+ --loidolt-chart-2: #6ea5bd;
41
+ --loidolt-chart-3: #93b287;
42
+ --loidolt-chart-4: #d9ab63;
43
+ --loidolt-chart-5: #c49ac0;
44
+ --loidolt-chart-6: #b8ad96;
45
+ --loidolt-chart-7: #6fb8a6;
46
+ --loidolt-chart-8: #c79a78;
47
+ --loidolt-chart-sequential-1: #3a2a1d;
48
+ --loidolt-chart-sequential-2: #6b4225;
49
+ --loidolt-chart-sequential-3: #a4602f;
50
+ --loidolt-chart-sequential-4: #d98a4d;
51
+ --loidolt-chart-sequential-5: #f2bd8a;
52
+ --loidolt-chart-diverging-1: #85b6ca;
53
+ --loidolt-chart-diverging-2: #5a8ea3;
54
+ --loidolt-chart-diverging-3: #35596a;
55
+ --loidolt-chart-diverging-4: #3a3d34;
56
+ --loidolt-chart-diverging-5: #7a4428;
57
+ --loidolt-chart-diverging-6: #bf6a3a;
58
+ --loidolt-chart-diverging-7: #f0895c;
59
+ --loidolt-chart-positive: #93b287;
60
+ --loidolt-chart-negative: #e88b81;
61
+ --loidolt-map-land: #161814;
62
+ --loidolt-map-water: #1d2b31;
63
+ --loidolt-map-park: #1f271c;
64
+ --loidolt-map-road: #2b2e26;
65
+ --loidolt-map-road-major: #3a3d34;
66
+ --loidolt-map-building: #24271f;
67
+ --loidolt-map-boundary: #787c6b;
68
+ --loidolt-map-label: #ebe7dc;
69
+ --loidolt-map-label-halo: #161814;
70
+ --loidolt-syntax-keyword: #a9441d;
71
+ --loidolt-syntax-string: #3f5139;
72
+ --loidolt-syntax-comment: #5f5b50;
73
+ --loidolt-syntax-constant: #7c4d17;
74
+ --loidolt-syntax-function: #265162;
75
+ --loidolt-syntax-parameter: #7a4a78;
76
+ --loidolt-syntax-punctuation: #474a42;
39
77
  }
40
78
 
41
79
  @media (prefers-color-scheme: dark) {
@@ -76,5 +114,43 @@
76
114
  --loidolt-focus-ring: #f0895c;
77
115
  --loidolt-shadow-color: #000000;
78
116
  --loidolt-scrim: color-mix(in srgb, var(--loidolt-shadow-color) 78%, transparent);
117
+ --loidolt-chart-1: #e0672f;
118
+ --loidolt-chart-2: #6ea5bd;
119
+ --loidolt-chart-3: #93b287;
120
+ --loidolt-chart-4: #d9ab63;
121
+ --loidolt-chart-5: #c49ac0;
122
+ --loidolt-chart-6: #b8ad96;
123
+ --loidolt-chart-7: #6fb8a6;
124
+ --loidolt-chart-8: #c79a78;
125
+ --loidolt-chart-sequential-1: #3a2a1d;
126
+ --loidolt-chart-sequential-2: #6b4225;
127
+ --loidolt-chart-sequential-3: #a4602f;
128
+ --loidolt-chart-sequential-4: #d98a4d;
129
+ --loidolt-chart-sequential-5: #f2bd8a;
130
+ --loidolt-chart-diverging-1: #85b6ca;
131
+ --loidolt-chart-diverging-2: #5a8ea3;
132
+ --loidolt-chart-diverging-3: #35596a;
133
+ --loidolt-chart-diverging-4: #3a3d34;
134
+ --loidolt-chart-diverging-5: #7a4428;
135
+ --loidolt-chart-diverging-6: #bf6a3a;
136
+ --loidolt-chart-diverging-7: #f0895c;
137
+ --loidolt-chart-positive: #93b287;
138
+ --loidolt-chart-negative: #e88b81;
139
+ --loidolt-map-land: #161814;
140
+ --loidolt-map-water: #1d2b31;
141
+ --loidolt-map-park: #1f271c;
142
+ --loidolt-map-road: #2b2e26;
143
+ --loidolt-map-road-major: #3a3d34;
144
+ --loidolt-map-building: #24271f;
145
+ --loidolt-map-boundary: #787c6b;
146
+ --loidolt-map-label: #ebe7dc;
147
+ --loidolt-map-label-halo: #161814;
148
+ --loidolt-syntax-keyword: #a9441d;
149
+ --loidolt-syntax-string: #3f5139;
150
+ --loidolt-syntax-comment: #5f5b50;
151
+ --loidolt-syntax-constant: #7c4d17;
152
+ --loidolt-syntax-function: #265162;
153
+ --loidolt-syntax-parameter: #7a4a78;
154
+ --loidolt-syntax-punctuation: #474a42;
79
155
  }
80
156
  }
package/dist/dark.css CHANGED
@@ -36,4 +36,42 @@
36
36
  --loidolt-focus-ring: #f0895c;
37
37
  --loidolt-shadow-color: #000000;
38
38
  --loidolt-scrim: color-mix(in srgb, var(--loidolt-shadow-color) 78%, transparent);
39
+ --loidolt-chart-1: #e0672f;
40
+ --loidolt-chart-2: #6ea5bd;
41
+ --loidolt-chart-3: #93b287;
42
+ --loidolt-chart-4: #d9ab63;
43
+ --loidolt-chart-5: #c49ac0;
44
+ --loidolt-chart-6: #b8ad96;
45
+ --loidolt-chart-7: #6fb8a6;
46
+ --loidolt-chart-8: #c79a78;
47
+ --loidolt-chart-sequential-1: #3a2a1d;
48
+ --loidolt-chart-sequential-2: #6b4225;
49
+ --loidolt-chart-sequential-3: #a4602f;
50
+ --loidolt-chart-sequential-4: #d98a4d;
51
+ --loidolt-chart-sequential-5: #f2bd8a;
52
+ --loidolt-chart-diverging-1: #85b6ca;
53
+ --loidolt-chart-diverging-2: #5a8ea3;
54
+ --loidolt-chart-diverging-3: #35596a;
55
+ --loidolt-chart-diverging-4: #3a3d34;
56
+ --loidolt-chart-diverging-5: #7a4428;
57
+ --loidolt-chart-diverging-6: #bf6a3a;
58
+ --loidolt-chart-diverging-7: #f0895c;
59
+ --loidolt-chart-positive: #93b287;
60
+ --loidolt-chart-negative: #e88b81;
61
+ --loidolt-map-land: #161814;
62
+ --loidolt-map-water: #1d2b31;
63
+ --loidolt-map-park: #1f271c;
64
+ --loidolt-map-road: #2b2e26;
65
+ --loidolt-map-road-major: #3a3d34;
66
+ --loidolt-map-building: #24271f;
67
+ --loidolt-map-boundary: #787c6b;
68
+ --loidolt-map-label: #ebe7dc;
69
+ --loidolt-map-label-halo: #161814;
70
+ --loidolt-syntax-keyword: #a9441d;
71
+ --loidolt-syntax-string: #3f5139;
72
+ --loidolt-syntax-comment: #5f5b50;
73
+ --loidolt-syntax-constant: #7c4d17;
74
+ --loidolt-syntax-function: #265162;
75
+ --loidolt-syntax-parameter: #7a4a78;
76
+ --loidolt-syntax-punctuation: #474a42;
39
77
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,53 @@
1
+ /**
2
+ * WCAG 2.x contrast arithmetic, shared by the token tests and by applications that need to pick
3
+ * or validate a colour at runtime (a user-chosen swatch, a generated label). Pure functions over
4
+ * hex strings, so they run anywhere — build scripts, servers, and the browser.
5
+ *
6
+ * @see https://www.w3.org/TR/WCAG22/#dfn-relative-luminance
7
+ */
8
+ type ContrastLevel = 'AA' | 'AAA';
9
+ type TextSize = 'normal' | 'large';
10
+ interface ContrastValidation {
11
+ ratio: number;
12
+ /** `ratio` to two decimals, e.g. `'4.52:1'`. */
13
+ ratioString: string;
14
+ passesAANormal: boolean;
15
+ passesAALarge: boolean;
16
+ passesAAANormal: boolean;
17
+ passesAAALarge: boolean;
18
+ }
19
+ /** Minimum ratio per level and text size. Large text is 18.66px bold or 24px regular and up. */
20
+ declare const contrastRequirements: {
21
+ readonly AA: {
22
+ readonly normal: 4.5;
23
+ readonly large: 3;
24
+ };
25
+ readonly AAA: {
26
+ readonly normal: 7;
27
+ readonly large: 4.5;
28
+ };
29
+ };
30
+ /** Relative luminance, from 0 (black) to 1 (white). Accepts `#rgb` and `#rrggbb`. */
31
+ declare function getLuminance(hex: string): number;
32
+ /** Contrast ratio between two colours, from 1 to 21. Order does not matter. */
33
+ declare function getContrastRatio(foreground: string, background: string): number;
34
+ /** Whether a pair clears the WCAG threshold for the given level and text size. */
35
+ declare function meetsContrast(foreground: string, background: string, { level, size }?: {
36
+ level?: ContrastLevel;
37
+ size?: TextSize;
38
+ }): boolean;
39
+ /** Every threshold at once, for reporting. */
40
+ declare function validateContrast(foreground: string, background: string): ContrastValidation;
41
+ /**
42
+ * Whichever of two inks reads better on `background` — by measured ratio, not a luminance
43
+ * cut-off, so it stays right for any pair you pass. Defaults to the theme's own deep ink and
44
+ * panel, rather than pure black and white.
45
+ */
46
+ declare function getContrastTextColor(background: string, { dark, light }?: {
47
+ dark?: string;
48
+ light?: string;
49
+ }): string;
50
+
1
51
  /**
2
52
  * Design tokens for Loidolt applications.
3
53
  *
@@ -11,7 +61,10 @@
11
61
  type TokenRef = {
12
62
  readonly $ref: string;
13
63
  };
14
- /** `['font', 'lineHeight', 'tight']` → `--loidolt-font-line-height-tight`. */
64
+ /**
65
+ * `['font', 'lineHeight', 'tight']` → `--loidolt-font-line-height-tight`; a trailing number is its
66
+ * own segment, so `chart1` → `--loidolt-chart-1`.
67
+ */
15
68
  declare const cssVarName: (path: readonly string[]) => string;
16
69
  declare const colors: {
17
70
  readonly paper: "#ebe7dc";
@@ -32,6 +85,59 @@ declare const colors: {
32
85
  readonly success: "#3f5139";
33
86
  readonly warning: "#7c4d17";
34
87
  readonly info: "#265162";
88
+ /**
89
+ * Categorical series for charts, in the order they are handed out. Earth tones that stay apart
90
+ * from each other and hold 3:1 against every surface, so a line or bar needs no outline.
91
+ */
92
+ readonly series: {
93
+ readonly 1: "#c65224";
94
+ readonly 2: "#2f6f8a";
95
+ readonly 3: "#5b7a3a";
96
+ readonly 4: "#9a6a12";
97
+ readonly 5: "#7a4a78";
98
+ readonly 6: "#4d5a6a";
99
+ readonly 7: "#2f7d6d";
100
+ readonly 8: "#8a5a3c";
101
+ };
102
+ /** One warm hue from little to most: heatmaps, choropleths, cluster sizes. */
103
+ readonly sequential: {
104
+ readonly 1: "#ecd3b8";
105
+ readonly 2: "#dea67a";
106
+ readonly 3: "#c97a45";
107
+ readonly 4: "#a4521f";
108
+ readonly 5: "#6e3314";
109
+ };
110
+ /** Below and above a midpoint: slate for below, orange for above, the neutral paper between. */
111
+ readonly diverging: {
112
+ readonly 1: "#265162";
113
+ readonly 2: "#4f8196";
114
+ readonly 3: "#9cbac3";
115
+ readonly 4: "#ddd7c9";
116
+ readonly 5: "#e0a986";
117
+ readonly 6: "#c96f3d";
118
+ readonly 7: "#9b3a17";
119
+ };
120
+ /**
121
+ * Code highlighting. Code sits on the inverse surface — dark in the light theme — so these are
122
+ * the light inks; the dark theme's code block is light, and takes dark ones.
123
+ */
124
+ readonly syntax: {
125
+ readonly keyword: "#f0895c";
126
+ readonly string: "#a3c197";
127
+ readonly comment: "#b5ae9c";
128
+ readonly constant: "#e2b56c";
129
+ readonly function: "#8fc0d4";
130
+ readonly parameter: "#d3a8cf";
131
+ readonly punctuation: "#d8d2c4";
132
+ };
133
+ /** Basemap fills. Quiet by design: the data drawn on top carries the colour. */
134
+ readonly map: {
135
+ readonly water: "#b9cdd3";
136
+ readonly park: "#d3d8bd";
137
+ readonly road: "#f5f2e9";
138
+ readonly roadMajor: "#ffffff";
139
+ readonly building: "#d8d3c7";
140
+ };
35
141
  };
36
142
  declare const typography: {
37
143
  readonly display: "\"Jost\", \"Avenir Next\", sans-serif";
@@ -120,6 +226,17 @@ declare const breakpoints: {
120
226
  readonly expanded: "1024px";
121
227
  readonly wide: "1400px";
122
228
  };
229
+ /**
230
+ * Named frames for media, as CSS `aspect-ratio` values. `Thumbnail`, `AspectRatio` and the media
231
+ * components accept these names so a gallery and its lightbox agree on shape.
232
+ */
233
+ declare const aspectRatio: {
234
+ readonly square: "1 / 1";
235
+ readonly video: "16 / 9";
236
+ readonly photo: "4 / 3";
237
+ readonly portrait: "3 / 4";
238
+ readonly wide: "21 / 9";
239
+ };
123
240
  /**
124
241
  * The role layer. Every value links to a primitive, so overriding a primitive propagates and
125
242
  * overriding a role restyles every component that plays it.
@@ -163,6 +280,45 @@ declare const semanticDefs: {
163
280
  readonly focusRing: TokenRef;
164
281
  readonly shadowColor: TokenRef;
165
282
  readonly scrim: "color-mix(in srgb, var(--loidolt-shadow-color) 72%, transparent)";
283
+ readonly chart1: TokenRef;
284
+ readonly chart2: TokenRef;
285
+ readonly chart3: TokenRef;
286
+ readonly chart4: TokenRef;
287
+ readonly chart5: TokenRef;
288
+ readonly chart6: TokenRef;
289
+ readonly chart7: TokenRef;
290
+ readonly chart8: TokenRef;
291
+ readonly chartSequential1: TokenRef;
292
+ readonly chartSequential2: TokenRef;
293
+ readonly chartSequential3: TokenRef;
294
+ readonly chartSequential4: TokenRef;
295
+ readonly chartSequential5: TokenRef;
296
+ readonly chartDiverging1: TokenRef;
297
+ readonly chartDiverging2: TokenRef;
298
+ readonly chartDiverging3: TokenRef;
299
+ readonly chartDiverging4: TokenRef;
300
+ readonly chartDiverging5: TokenRef;
301
+ readonly chartDiverging6: TokenRef;
302
+ readonly chartDiverging7: TokenRef;
303
+ /** Gains and losses: candlestick up/down, positive/negative bars. */
304
+ readonly chartPositive: TokenRef;
305
+ readonly chartNegative: TokenRef;
306
+ readonly mapLand: TokenRef;
307
+ readonly mapWater: TokenRef;
308
+ readonly mapPark: TokenRef;
309
+ readonly mapRoad: TokenRef;
310
+ readonly mapRoadMajor: TokenRef;
311
+ readonly mapBuilding: TokenRef;
312
+ readonly mapBoundary: TokenRef;
313
+ readonly mapLabel: TokenRef;
314
+ readonly mapLabelHalo: TokenRef;
315
+ readonly syntaxKeyword: TokenRef;
316
+ readonly syntaxString: TokenRef;
317
+ readonly syntaxComment: TokenRef;
318
+ readonly syntaxConstant: TokenRef;
319
+ readonly syntaxFunction: TokenRef;
320
+ readonly syntaxParameter: TokenRef;
321
+ readonly syntaxPunctuation: TokenRef;
166
322
  };
167
323
  /** Every custom property the package emits, in declaration order. */
168
324
  declare function flattenTokens(): Array<[string, string | TokenRef]>;
@@ -215,7 +371,121 @@ declare const darkSemantic: {
215
371
  readonly focusRing: "#f0895c";
216
372
  readonly shadowColor: "#000000";
217
373
  readonly scrim: "color-mix(in srgb, var(--loidolt-shadow-color) 78%, transparent)";
374
+ readonly chart1: "#e0672f";
375
+ readonly chart2: "#6ea5bd";
376
+ readonly chart3: "#93b287";
377
+ readonly chart4: "#d9ab63";
378
+ readonly chart5: "#c49ac0";
379
+ readonly chart6: "#b8ad96";
380
+ readonly chart7: "#6fb8a6";
381
+ readonly chart8: "#c79a78";
382
+ readonly chartSequential1: "#3a2a1d";
383
+ readonly chartSequential2: "#6b4225";
384
+ readonly chartSequential3: "#a4602f";
385
+ readonly chartSequential4: "#d98a4d";
386
+ readonly chartSequential5: "#f2bd8a";
387
+ readonly chartDiverging1: "#85b6ca";
388
+ readonly chartDiverging2: "#5a8ea3";
389
+ readonly chartDiverging3: "#35596a";
390
+ readonly chartDiverging4: "#3a3d34";
391
+ readonly chartDiverging5: "#7a4428";
392
+ readonly chartDiverging6: "#bf6a3a";
393
+ readonly chartDiverging7: "#f0895c";
394
+ readonly chartPositive: "#93b287";
395
+ readonly chartNegative: "#e88b81";
396
+ readonly mapLand: "#161814";
397
+ readonly mapWater: "#1d2b31";
398
+ readonly mapPark: "#1f271c";
399
+ readonly mapRoad: "#2b2e26";
400
+ readonly mapRoadMajor: "#3a3d34";
401
+ readonly mapBuilding: "#24271f";
402
+ readonly mapBoundary: "#787c6b";
403
+ readonly mapLabel: "#ebe7dc";
404
+ readonly mapLabelHalo: "#161814";
405
+ readonly syntaxKeyword: "#a9441d";
406
+ readonly syntaxString: "#3f5139";
407
+ readonly syntaxComment: "#5f5b50";
408
+ readonly syntaxConstant: "#7c4d17";
409
+ readonly syntaxFunction: "#265162";
410
+ readonly syntaxParameter: "#7a4a78";
411
+ readonly syntaxPunctuation: "#474a42";
218
412
  };
413
+ type ColorScheme = 'light' | 'dark';
414
+ type SemanticRole = keyof typeof semanticDefs;
415
+ /** The custom property a semantic role is published as: `chart1` → `--loidolt-chart-1`. */
416
+ declare const roleVar: (role: SemanticRole) => string;
417
+ /**
418
+ * A role's concrete value in the reference light or dark theme. Canvas and WebGL renderers cannot
419
+ * read `var()`, and neither can the server: this is what they fall back to when the live value
420
+ * cannot be read from the page.
421
+ */
422
+ declare const roleValue: (role: SemanticRole, scheme?: ColorScheme) => string;
423
+ /** Names roles — singly or as an ordered list — under keys a renderer understands. */
424
+ type RoleSpec = {
425
+ readonly [key: string]: SemanticRole | readonly SemanticRole[];
426
+ };
427
+ type ResolvedRoles<S extends RoleSpec> = {
428
+ -readonly [K in keyof S]: S[K] extends readonly SemanticRole[] ? string[] : string;
429
+ };
430
+ /**
431
+ * Resolves every role in `spec`. `read` defaults to the reference theme; a runtime passes one
432
+ * that reads the page, so a consumer's own theme reaches the canvas too.
433
+ */
434
+ declare function resolveRoles<S extends RoleSpec>(spec: S, scheme?: ColorScheme, read?: (role: SemanticRole) => string): ResolvedRoles<S>;
435
+ /** The roles a chart is painted with. */
436
+ declare const chartRoles: {
437
+ readonly categorical: readonly ["chart1", "chart2", "chart3", "chart4", "chart5", "chart6", "chart7", "chart8"];
438
+ readonly sequential: readonly ["chartSequential1", "chartSequential2", "chartSequential3", "chartSequential4", "chartSequential5"];
439
+ readonly diverging: readonly ["chartDiverging1", "chartDiverging2", "chartDiverging3", "chartDiverging4", "chartDiverging5", "chartDiverging6", "chartDiverging7"];
440
+ readonly positive: "chartPositive";
441
+ readonly negative: "chartNegative";
442
+ readonly text: "text";
443
+ readonly muted: "textMuted";
444
+ readonly axis: "border";
445
+ readonly grid: "borderSoft";
446
+ readonly surface: "surface";
447
+ readonly background: "background";
448
+ readonly accent: "accent";
449
+ };
450
+ /** The roles a basemap and map overlays are painted with. */
451
+ declare const mapRoles: {
452
+ readonly land: "mapLand";
453
+ readonly water: "mapWater";
454
+ readonly park: "mapPark";
455
+ readonly road: "mapRoad";
456
+ readonly roadMajor: "mapRoadMajor";
457
+ readonly building: "mapBuilding";
458
+ readonly boundary: "mapBoundary";
459
+ readonly label: "mapLabel";
460
+ readonly labelHalo: "mapLabelHalo";
461
+ readonly accent: "accent";
462
+ readonly text: "text";
463
+ readonly surface: "surface";
464
+ readonly focus: "focusRing";
465
+ readonly categorical: readonly ["chart1", "chart2", "chart3", "chart4", "chart5", "chart6", "chart7", "chart8"];
466
+ readonly sequential: readonly ["chartSequential1", "chartSequential2", "chartSequential3", "chartSequential4", "chartSequential5"];
467
+ };
468
+ /** The roles code is highlighted with, and the surface it sits on. */
469
+ declare const syntaxRoles: {
470
+ readonly background: "surfaceInverse";
471
+ readonly text: "textInverse";
472
+ readonly keyword: "syntaxKeyword";
473
+ readonly string: "syntaxString";
474
+ readonly comment: "syntaxComment";
475
+ readonly constant: "syntaxConstant";
476
+ readonly function: "syntaxFunction";
477
+ readonly parameter: "syntaxParameter";
478
+ readonly punctuation: "syntaxPunctuation";
479
+ };
480
+ type SyntaxColors = ResolvedRoles<typeof syntaxRoles>;
481
+ /** Syntax colours in the reference theme. */
482
+ declare const syntaxColors: (scheme?: ColorScheme) => SyntaxColors;
483
+ type ChartColors = ResolvedRoles<typeof chartRoles>;
484
+ type MapColors = ResolvedRoles<typeof mapRoles>;
485
+ /** Chart colours in the reference theme. */
486
+ declare const chartColors: (scheme?: ColorScheme) => ChartColors;
487
+ /** Map colours in the reference theme. */
488
+ declare const mapColors: (scheme?: ColorScheme) => MapColors;
219
489
  /**
220
490
  * Dark theme CSS. `scope` picks how it activates:
221
491
  * - `attribute` (default): `[data-theme='dark']` only — the app drives it.
@@ -243,6 +513,59 @@ declare const tokens: {
243
513
  readonly success: "#3f5139";
244
514
  readonly warning: "#7c4d17";
245
515
  readonly info: "#265162";
516
+ /**
517
+ * Categorical series for charts, in the order they are handed out. Earth tones that stay apart
518
+ * from each other and hold 3:1 against every surface, so a line or bar needs no outline.
519
+ */
520
+ readonly series: {
521
+ readonly 1: "#c65224";
522
+ readonly 2: "#2f6f8a";
523
+ readonly 3: "#5b7a3a";
524
+ readonly 4: "#9a6a12";
525
+ readonly 5: "#7a4a78";
526
+ readonly 6: "#4d5a6a";
527
+ readonly 7: "#2f7d6d";
528
+ readonly 8: "#8a5a3c";
529
+ };
530
+ /** One warm hue from little to most: heatmaps, choropleths, cluster sizes. */
531
+ readonly sequential: {
532
+ readonly 1: "#ecd3b8";
533
+ readonly 2: "#dea67a";
534
+ readonly 3: "#c97a45";
535
+ readonly 4: "#a4521f";
536
+ readonly 5: "#6e3314";
537
+ };
538
+ /** Below and above a midpoint: slate for below, orange for above, the neutral paper between. */
539
+ readonly diverging: {
540
+ readonly 1: "#265162";
541
+ readonly 2: "#4f8196";
542
+ readonly 3: "#9cbac3";
543
+ readonly 4: "#ddd7c9";
544
+ readonly 5: "#e0a986";
545
+ readonly 6: "#c96f3d";
546
+ readonly 7: "#9b3a17";
547
+ };
548
+ /**
549
+ * Code highlighting. Code sits on the inverse surface — dark in the light theme — so these are
550
+ * the light inks; the dark theme's code block is light, and takes dark ones.
551
+ */
552
+ readonly syntax: {
553
+ readonly keyword: "#f0895c";
554
+ readonly string: "#a3c197";
555
+ readonly comment: "#b5ae9c";
556
+ readonly constant: "#e2b56c";
557
+ readonly function: "#8fc0d4";
558
+ readonly parameter: "#d3a8cf";
559
+ readonly punctuation: "#d8d2c4";
560
+ };
561
+ /** Basemap fills. Quiet by design: the data drawn on top carries the colour. */
562
+ readonly map: {
563
+ readonly water: "#b9cdd3";
564
+ readonly park: "#d3d8bd";
565
+ readonly road: "#f5f2e9";
566
+ readonly roadMajor: "#ffffff";
567
+ readonly building: "#d8d3c7";
568
+ };
246
569
  };
247
570
  readonly typography: {
248
571
  readonly display: "\"Jost\", \"Avenir Next\", sans-serif";
@@ -322,6 +645,13 @@ declare const tokens: {
322
645
  readonly expanded: "1024px";
323
646
  readonly wide: "1400px";
324
647
  };
648
+ readonly aspectRatio: {
649
+ readonly square: "1 / 1";
650
+ readonly video: "16 / 9";
651
+ readonly photo: "4 / 3";
652
+ readonly portrait: "3 / 4";
653
+ readonly wide: "21 / 9";
654
+ };
325
655
  readonly semantic: {
326
656
  readonly background: string;
327
657
  readonly surface: string;
@@ -358,6 +688,44 @@ declare const tokens: {
358
688
  readonly focusRing: string;
359
689
  readonly shadowColor: string;
360
690
  readonly scrim: string;
691
+ readonly chart1: string;
692
+ readonly chart2: string;
693
+ readonly chart3: string;
694
+ readonly chart4: string;
695
+ readonly chart5: string;
696
+ readonly chart6: string;
697
+ readonly chart7: string;
698
+ readonly chart8: string;
699
+ readonly chartSequential1: string;
700
+ readonly chartSequential2: string;
701
+ readonly chartSequential3: string;
702
+ readonly chartSequential4: string;
703
+ readonly chartSequential5: string;
704
+ readonly chartDiverging1: string;
705
+ readonly chartDiverging2: string;
706
+ readonly chartDiverging3: string;
707
+ readonly chartDiverging4: string;
708
+ readonly chartDiverging5: string;
709
+ readonly chartDiverging6: string;
710
+ readonly chartDiverging7: string;
711
+ readonly chartPositive: string;
712
+ readonly chartNegative: string;
713
+ readonly mapLand: string;
714
+ readonly mapWater: string;
715
+ readonly mapPark: string;
716
+ readonly mapRoad: string;
717
+ readonly mapRoadMajor: string;
718
+ readonly mapBuilding: string;
719
+ readonly mapBoundary: string;
720
+ readonly mapLabel: string;
721
+ readonly mapLabelHalo: string;
722
+ readonly syntaxKeyword: string;
723
+ readonly syntaxString: string;
724
+ readonly syntaxComment: string;
725
+ readonly syntaxConstant: string;
726
+ readonly syntaxFunction: string;
727
+ readonly syntaxParameter: string;
728
+ readonly syntaxPunctuation: string;
361
729
  };
362
730
  readonly darkSemantic: {
363
731
  readonly background: "#161814";
@@ -395,8 +763,46 @@ declare const tokens: {
395
763
  readonly focusRing: "#f0895c";
396
764
  readonly shadowColor: "#000000";
397
765
  readonly scrim: "color-mix(in srgb, var(--loidolt-shadow-color) 78%, transparent)";
766
+ readonly chart1: "#e0672f";
767
+ readonly chart2: "#6ea5bd";
768
+ readonly chart3: "#93b287";
769
+ readonly chart4: "#d9ab63";
770
+ readonly chart5: "#c49ac0";
771
+ readonly chart6: "#b8ad96";
772
+ readonly chart7: "#6fb8a6";
773
+ readonly chart8: "#c79a78";
774
+ readonly chartSequential1: "#3a2a1d";
775
+ readonly chartSequential2: "#6b4225";
776
+ readonly chartSequential3: "#a4602f";
777
+ readonly chartSequential4: "#d98a4d";
778
+ readonly chartSequential5: "#f2bd8a";
779
+ readonly chartDiverging1: "#85b6ca";
780
+ readonly chartDiverging2: "#5a8ea3";
781
+ readonly chartDiverging3: "#35596a";
782
+ readonly chartDiverging4: "#3a3d34";
783
+ readonly chartDiverging5: "#7a4428";
784
+ readonly chartDiverging6: "#bf6a3a";
785
+ readonly chartDiverging7: "#f0895c";
786
+ readonly chartPositive: "#93b287";
787
+ readonly chartNegative: "#e88b81";
788
+ readonly mapLand: "#161814";
789
+ readonly mapWater: "#1d2b31";
790
+ readonly mapPark: "#1f271c";
791
+ readonly mapRoad: "#2b2e26";
792
+ readonly mapRoadMajor: "#3a3d34";
793
+ readonly mapBuilding: "#24271f";
794
+ readonly mapBoundary: "#787c6b";
795
+ readonly mapLabel: "#ebe7dc";
796
+ readonly mapLabelHalo: "#161814";
797
+ readonly syntaxKeyword: "#a9441d";
798
+ readonly syntaxString: "#3f5139";
799
+ readonly syntaxComment: "#5f5b50";
800
+ readonly syntaxConstant: "#7c4d17";
801
+ readonly syntaxFunction: "#265162";
802
+ readonly syntaxParameter: "#7a4a78";
803
+ readonly syntaxPunctuation: "#474a42";
398
804
  };
399
805
  };
400
806
  type ThemeTokens = typeof tokens;
401
807
 
402
- export { type ThemeTokens, type TokenRef, borders, breakpoints, colors, cssVarName, darkSemantic, tokens as default, flattenTokens, generateCss, generateDarkCss, motion, semantic, shadows, sizing, spacing, tokens, typography, zIndex };
808
+ export { type ChartColors, type ColorScheme, type ContrastLevel, type ContrastValidation, type MapColors, type ResolvedRoles, type RoleSpec, type SemanticRole, type SyntaxColors, type TextSize, type ThemeTokens, type TokenRef, aspectRatio, borders, breakpoints, chartColors, chartRoles, colors, contrastRequirements, cssVarName, darkSemantic, tokens as default, flattenTokens, generateCss, generateDarkCss, getContrastRatio, getContrastTextColor, getLuminance, mapColors, mapRoles, meetsContrast, motion, resolveRoles, roleValue, roleVar, semantic, shadows, sizing, spacing, syntaxColors, syntaxRoles, tokens, typography, validateContrast, zIndex };
package/dist/index.js CHANGED
@@ -1,7 +1,50 @@
1
+ // src/contrast.ts
2
+ var contrastRequirements = {
3
+ AA: { normal: 4.5, large: 3 },
4
+ AAA: { normal: 7, large: 4.5 }
5
+ };
6
+ var channels = (hex, caller) => {
7
+ const match = /^#?([\da-f]{3}|[\da-f]{6})$/i.exec(hex.trim());
8
+ if (!match) throw new RangeError(`${caller}: invalid hex colour ${JSON.stringify(hex)}`);
9
+ const digits = match[1].length === 3 ? [...match[1]].map((digit) => digit + digit).join("") : match[1];
10
+ return [0, 2, 4].map((index) => parseInt(digits.slice(index, index + 2), 16));
11
+ };
12
+ var luminanceOf = (hex, caller) => {
13
+ const [r, g, b] = channels(hex, caller).map((channel) => channel / 255).map((channel) => channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4);
14
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
15
+ };
16
+ function getLuminance(hex) {
17
+ return luminanceOf(hex, "getLuminance");
18
+ }
19
+ function getContrastRatio(foreground, background) {
20
+ const [high, low] = [
21
+ luminanceOf(foreground, "getContrastRatio"),
22
+ luminanceOf(background, "getContrastRatio")
23
+ ].sort((a, b) => b - a);
24
+ return (high + 0.05) / (low + 0.05);
25
+ }
26
+ function meetsContrast(foreground, background, { level = "AA", size = "normal" } = {}) {
27
+ return getContrastRatio(foreground, background) >= contrastRequirements[level][size];
28
+ }
29
+ function validateContrast(foreground, background) {
30
+ const ratio = getContrastRatio(foreground, background);
31
+ return {
32
+ ratio,
33
+ ratioString: `${ratio.toFixed(2)}:1`,
34
+ passesAANormal: ratio >= contrastRequirements.AA.normal,
35
+ passesAALarge: ratio >= contrastRequirements.AA.large,
36
+ passesAAANormal: ratio >= contrastRequirements.AAA.normal,
37
+ passesAAALarge: ratio >= contrastRequirements.AAA.large
38
+ };
39
+ }
40
+ function getContrastTextColor(background, { dark = "#20231d", light = "#f5f2e9" } = {}) {
41
+ return getContrastRatio(dark, background) >= getContrastRatio(light, background) ? dark : light;
42
+ }
43
+
1
44
  // src/index.ts
2
45
  var ref = (name) => ({ $ref: `--loidolt-${name}` });
3
46
  var isRef = (value) => typeof value === "object" && value !== null && "$ref" in value;
4
- var kebab = (value) => value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
47
+ var kebab = (value) => value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`).replace(/([a-z])(\d)/g, "$1-$2");
5
48
  var cssVarName = (path) => `--loidolt-${kebab(path.join("-"))}`;
6
49
  var colors = {
7
50
  paper: "#ebe7dc",
@@ -23,7 +66,60 @@ var colors = {
23
66
  errorDark: "#7f1f1a",
24
67
  success: "#3f5139",
25
68
  warning: "#7c4d17",
26
- info: "#265162"
69
+ info: "#265162",
70
+ /**
71
+ * Categorical series for charts, in the order they are handed out. Earth tones that stay apart
72
+ * from each other and hold 3:1 against every surface, so a line or bar needs no outline.
73
+ */
74
+ series: {
75
+ 1: "#c65224",
76
+ 2: "#2f6f8a",
77
+ 3: "#5b7a3a",
78
+ 4: "#9a6a12",
79
+ 5: "#7a4a78",
80
+ 6: "#4d5a6a",
81
+ 7: "#2f7d6d",
82
+ 8: "#8a5a3c"
83
+ },
84
+ /** One warm hue from little to most: heatmaps, choropleths, cluster sizes. */
85
+ sequential: {
86
+ 1: "#ecd3b8",
87
+ 2: "#dea67a",
88
+ 3: "#c97a45",
89
+ 4: "#a4521f",
90
+ 5: "#6e3314"
91
+ },
92
+ /** Below and above a midpoint: slate for below, orange for above, the neutral paper between. */
93
+ diverging: {
94
+ 1: "#265162",
95
+ 2: "#4f8196",
96
+ 3: "#9cbac3",
97
+ 4: "#ddd7c9",
98
+ 5: "#e0a986",
99
+ 6: "#c96f3d",
100
+ 7: "#9b3a17"
101
+ },
102
+ /**
103
+ * Code highlighting. Code sits on the inverse surface — dark in the light theme — so these are
104
+ * the light inks; the dark theme's code block is light, and takes dark ones.
105
+ */
106
+ syntax: {
107
+ keyword: "#f0895c",
108
+ string: "#a3c197",
109
+ comment: "#b5ae9c",
110
+ constant: "#e2b56c",
111
+ function: "#8fc0d4",
112
+ parameter: "#d3a8cf",
113
+ punctuation: "#d8d2c4"
114
+ },
115
+ /** Basemap fills. Quiet by design: the data drawn on top carries the colour. */
116
+ map: {
117
+ water: "#b9cdd3",
118
+ park: "#d3d8bd",
119
+ road: "#f5f2e9",
120
+ roadMajor: "#ffffff",
121
+ building: "#d8d3c7"
122
+ }
27
123
  };
28
124
  var typography = {
29
125
  display: '"Jost", "Avenir Next", sans-serif',
@@ -88,6 +184,13 @@ var zIndex = {
88
184
  skipLink: "1000"
89
185
  };
90
186
  var breakpoints = { compact: "760px", expanded: "1024px", wide: "1400px" };
187
+ var aspectRatio = {
188
+ square: "1 / 1",
189
+ video: "16 / 9",
190
+ photo: "4 / 3",
191
+ portrait: "3 / 4",
192
+ wide: "21 / 9"
193
+ };
91
194
  var semanticDefs = {
92
195
  background: ref("color-paper"),
93
196
  surface: ref("color-panel"),
@@ -131,7 +234,52 @@ var semanticDefs = {
131
234
  textInfo: ref("color-info"),
132
235
  focusRing: ref("color-orange"),
133
236
  shadowColor: ref("color-deep"),
134
- scrim: "color-mix(in srgb, var(--loidolt-shadow-color) 72%, transparent)"
237
+ scrim: "color-mix(in srgb, var(--loidolt-shadow-color) 72%, transparent)",
238
+ /*
239
+ * Data visualisation. `chart1`…`chart8` are categorical series; the ramps run from "least" (1)
240
+ * to "most" (last), whatever the theme; the diverging midpoint (4) is the neutral.
241
+ */
242
+ chart1: ref("color-series-1"),
243
+ chart2: ref("color-series-2"),
244
+ chart3: ref("color-series-3"),
245
+ chart4: ref("color-series-4"),
246
+ chart5: ref("color-series-5"),
247
+ chart6: ref("color-series-6"),
248
+ chart7: ref("color-series-7"),
249
+ chart8: ref("color-series-8"),
250
+ chartSequential1: ref("color-sequential-1"),
251
+ chartSequential2: ref("color-sequential-2"),
252
+ chartSequential3: ref("color-sequential-3"),
253
+ chartSequential4: ref("color-sequential-4"),
254
+ chartSequential5: ref("color-sequential-5"),
255
+ chartDiverging1: ref("color-diverging-1"),
256
+ chartDiverging2: ref("color-diverging-2"),
257
+ chartDiverging3: ref("color-diverging-3"),
258
+ chartDiverging4: ref("color-diverging-4"),
259
+ chartDiverging5: ref("color-diverging-5"),
260
+ chartDiverging6: ref("color-diverging-6"),
261
+ chartDiverging7: ref("color-diverging-7"),
262
+ /** Gains and losses: candlestick up/down, positive/negative bars. */
263
+ chartPositive: ref("color-success"),
264
+ chartNegative: ref("color-error"),
265
+ /* Basemap roles, read by the map style generator. */
266
+ mapLand: ref("color-paper"),
267
+ mapWater: ref("color-map-water"),
268
+ mapPark: ref("color-map-park"),
269
+ mapRoad: ref("color-map-road"),
270
+ mapRoadMajor: ref("color-map-road-major"),
271
+ mapBuilding: ref("color-map-building"),
272
+ mapBoundary: ref("color-line-strong"),
273
+ mapLabel: ref("color-deep"),
274
+ mapLabelHalo: ref("color-panel"),
275
+ /* Code highlighting, on the inverse surface where code blocks sit. */
276
+ syntaxKeyword: ref("color-syntax-keyword"),
277
+ syntaxString: ref("color-syntax-string"),
278
+ syntaxComment: ref("color-syntax-comment"),
279
+ syntaxConstant: ref("color-syntax-constant"),
280
+ syntaxFunction: ref("color-syntax-function"),
281
+ syntaxParameter: ref("color-syntax-parameter"),
282
+ syntaxPunctuation: ref("color-syntax-punctuation")
135
283
  };
136
284
  var PRIMITIVE_GROUPS = [
137
285
  ["color", colors],
@@ -141,7 +289,8 @@ var PRIMITIVE_GROUPS = [
141
289
  ["border", borders],
142
290
  ["shadow", shadows],
143
291
  ["motion", motion],
144
- ["z", zIndex]
292
+ ["z", zIndex],
293
+ ["aspect", aspectRatio]
145
294
  ];
146
295
  var flattenInto = (prefix, tree, out) => {
147
296
  for (const [key, value] of Object.entries(tree)) {
@@ -211,8 +360,115 @@ var darkSemantic = {
211
360
  textInfo: "#85b6ca",
212
361
  focusRing: "#f0895c",
213
362
  shadowColor: "#000000",
214
- scrim: "color-mix(in srgb, var(--loidolt-shadow-color) 78%, transparent)"
363
+ scrim: "color-mix(in srgb, var(--loidolt-shadow-color) 78%, transparent)",
364
+ chart1: "#e0672f",
365
+ chart2: "#6ea5bd",
366
+ chart3: "#93b287",
367
+ chart4: "#d9ab63",
368
+ chart5: "#c49ac0",
369
+ chart6: "#b8ad96",
370
+ chart7: "#6fb8a6",
371
+ chart8: "#c79a78",
372
+ chartSequential1: "#3a2a1d",
373
+ chartSequential2: "#6b4225",
374
+ chartSequential3: "#a4602f",
375
+ chartSequential4: "#d98a4d",
376
+ chartSequential5: "#f2bd8a",
377
+ chartDiverging1: "#85b6ca",
378
+ chartDiverging2: "#5a8ea3",
379
+ chartDiverging3: "#35596a",
380
+ chartDiverging4: "#3a3d34",
381
+ chartDiverging5: "#7a4428",
382
+ chartDiverging6: "#bf6a3a",
383
+ chartDiverging7: "#f0895c",
384
+ chartPositive: "#93b287",
385
+ chartNegative: "#e88b81",
386
+ mapLand: "#161814",
387
+ mapWater: "#1d2b31",
388
+ mapPark: "#1f271c",
389
+ mapRoad: "#2b2e26",
390
+ mapRoadMajor: "#3a3d34",
391
+ mapBuilding: "#24271f",
392
+ mapBoundary: "#787c6b",
393
+ mapLabel: "#ebe7dc",
394
+ mapLabelHalo: "#161814",
395
+ syntaxKeyword: "#a9441d",
396
+ syntaxString: "#3f5139",
397
+ syntaxComment: "#5f5b50",
398
+ syntaxConstant: "#7c4d17",
399
+ syntaxFunction: "#265162",
400
+ syntaxParameter: "#7a4a78",
401
+ syntaxPunctuation: "#474a42"
402
+ };
403
+ var roleVar = (role) => cssVarName([role]);
404
+ var roleValue = (role, scheme = "light") => scheme === "dark" ? darkSemantic[role] : semantic[role];
405
+ function resolveRoles(spec, scheme = "light", read = (role) => roleValue(role, scheme)) {
406
+ return Object.fromEntries(
407
+ Object.entries(spec).map(([key, value]) => [
408
+ key,
409
+ typeof value === "string" ? read(value) : value.map((role) => read(role))
410
+ ])
411
+ );
412
+ }
413
+ var chartRoles = {
414
+ categorical: ["chart1", "chart2", "chart3", "chart4", "chart5", "chart6", "chart7", "chart8"],
415
+ sequential: [
416
+ "chartSequential1",
417
+ "chartSequential2",
418
+ "chartSequential3",
419
+ "chartSequential4",
420
+ "chartSequential5"
421
+ ],
422
+ diverging: [
423
+ "chartDiverging1",
424
+ "chartDiverging2",
425
+ "chartDiverging3",
426
+ "chartDiverging4",
427
+ "chartDiverging5",
428
+ "chartDiverging6",
429
+ "chartDiverging7"
430
+ ],
431
+ positive: "chartPositive",
432
+ negative: "chartNegative",
433
+ text: "text",
434
+ muted: "textMuted",
435
+ axis: "border",
436
+ grid: "borderSoft",
437
+ surface: "surface",
438
+ background: "background",
439
+ accent: "accent"
440
+ };
441
+ var mapRoles = {
442
+ land: "mapLand",
443
+ water: "mapWater",
444
+ park: "mapPark",
445
+ road: "mapRoad",
446
+ roadMajor: "mapRoadMajor",
447
+ building: "mapBuilding",
448
+ boundary: "mapBoundary",
449
+ label: "mapLabel",
450
+ labelHalo: "mapLabelHalo",
451
+ accent: "accent",
452
+ text: "text",
453
+ surface: "surface",
454
+ focus: "focusRing",
455
+ categorical: chartRoles.categorical,
456
+ sequential: chartRoles.sequential
457
+ };
458
+ var syntaxRoles = {
459
+ background: "surfaceInverse",
460
+ text: "textInverse",
461
+ keyword: "syntaxKeyword",
462
+ string: "syntaxString",
463
+ comment: "syntaxComment",
464
+ constant: "syntaxConstant",
465
+ function: "syntaxFunction",
466
+ parameter: "syntaxParameter",
467
+ punctuation: "syntaxPunctuation"
215
468
  };
469
+ var syntaxColors = (scheme = "light") => resolveRoles(syntaxRoles, scheme);
470
+ var chartColors = (scheme = "light") => resolveRoles(chartRoles, scheme);
471
+ var mapColors = (scheme = "light") => resolveRoles(mapRoles, scheme);
216
472
  var darkDeclarations = () => Object.entries(darkSemantic).map(([name, value]) => ` ${cssVarName([name])}: ${value};`);
217
473
  function generateDarkCss(scope = "attribute") {
218
474
  const body = [" color-scheme: dark;", ...darkDeclarations()];
@@ -245,26 +501,43 @@ var tokens = {
245
501
  motion,
246
502
  zIndex,
247
503
  breakpoints,
504
+ aspectRatio,
248
505
  semantic,
249
506
  darkSemantic
250
507
  };
251
508
  var index_default = tokens;
252
509
  export {
510
+ aspectRatio,
253
511
  borders,
254
512
  breakpoints,
513
+ chartColors,
514
+ chartRoles,
255
515
  colors,
516
+ contrastRequirements,
256
517
  cssVarName,
257
518
  darkSemantic,
258
519
  index_default as default,
259
520
  flattenTokens,
260
521
  generateCss,
261
522
  generateDarkCss,
523
+ getContrastRatio,
524
+ getContrastTextColor,
525
+ getLuminance,
526
+ mapColors,
527
+ mapRoles,
528
+ meetsContrast,
262
529
  motion,
530
+ resolveRoles,
531
+ roleValue,
532
+ roleVar,
263
533
  semantic,
264
534
  shadows,
265
535
  sizing,
266
536
  spacing,
537
+ syntaxColors,
538
+ syntaxRoles,
267
539
  tokens,
268
540
  typography,
541
+ validateContrast,
269
542
  zIndex
270
543
  };
package/dist/tokens.css CHANGED
@@ -18,6 +18,38 @@
18
18
  --loidolt-color-success: #3f5139;
19
19
  --loidolt-color-warning: #7c4d17;
20
20
  --loidolt-color-info: #265162;
21
+ --loidolt-color-series-1: #c65224;
22
+ --loidolt-color-series-2: #2f6f8a;
23
+ --loidolt-color-series-3: #5b7a3a;
24
+ --loidolt-color-series-4: #9a6a12;
25
+ --loidolt-color-series-5: #7a4a78;
26
+ --loidolt-color-series-6: #4d5a6a;
27
+ --loidolt-color-series-7: #2f7d6d;
28
+ --loidolt-color-series-8: #8a5a3c;
29
+ --loidolt-color-sequential-1: #ecd3b8;
30
+ --loidolt-color-sequential-2: #dea67a;
31
+ --loidolt-color-sequential-3: #c97a45;
32
+ --loidolt-color-sequential-4: #a4521f;
33
+ --loidolt-color-sequential-5: #6e3314;
34
+ --loidolt-color-diverging-1: #265162;
35
+ --loidolt-color-diverging-2: #4f8196;
36
+ --loidolt-color-diverging-3: #9cbac3;
37
+ --loidolt-color-diverging-4: #ddd7c9;
38
+ --loidolt-color-diverging-5: #e0a986;
39
+ --loidolt-color-diverging-6: #c96f3d;
40
+ --loidolt-color-diverging-7: #9b3a17;
41
+ --loidolt-color-syntax-keyword: #f0895c;
42
+ --loidolt-color-syntax-string: #a3c197;
43
+ --loidolt-color-syntax-comment: #b5ae9c;
44
+ --loidolt-color-syntax-constant: #e2b56c;
45
+ --loidolt-color-syntax-function: #8fc0d4;
46
+ --loidolt-color-syntax-parameter: #d3a8cf;
47
+ --loidolt-color-syntax-punctuation: #d8d2c4;
48
+ --loidolt-color-map-water: #b9cdd3;
49
+ --loidolt-color-map-park: #d3d8bd;
50
+ --loidolt-color-map-road: #f5f2e9;
51
+ --loidolt-color-map-road-major: #ffffff;
52
+ --loidolt-color-map-building: #d8d3c7;
21
53
  --loidolt-font-display: "Jost", "Avenir Next", sans-serif;
22
54
  --loidolt-font-utility: "Archivo", "Helvetica Neue", sans-serif;
23
55
  --loidolt-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
@@ -71,6 +103,11 @@
71
103
  --loidolt-z-toast: 80;
72
104
  --loidolt-z-tooltip: 90;
73
105
  --loidolt-z-skip-link: 1000;
106
+ --loidolt-aspect-square: 1 / 1;
107
+ --loidolt-aspect-video: 16 / 9;
108
+ --loidolt-aspect-photo: 4 / 3;
109
+ --loidolt-aspect-portrait: 3 / 4;
110
+ --loidolt-aspect-wide: 21 / 9;
74
111
  --loidolt-background: var(--loidolt-color-paper);
75
112
  --loidolt-surface: var(--loidolt-color-panel);
76
113
  --loidolt-surface-alt: var(--loidolt-color-panel-alt);
@@ -106,4 +143,42 @@
106
143
  --loidolt-focus-ring: var(--loidolt-color-orange);
107
144
  --loidolt-shadow-color: var(--loidolt-color-deep);
108
145
  --loidolt-scrim: color-mix(in srgb, var(--loidolt-shadow-color) 72%, transparent);
146
+ --loidolt-chart-1: var(--loidolt-color-series-1);
147
+ --loidolt-chart-2: var(--loidolt-color-series-2);
148
+ --loidolt-chart-3: var(--loidolt-color-series-3);
149
+ --loidolt-chart-4: var(--loidolt-color-series-4);
150
+ --loidolt-chart-5: var(--loidolt-color-series-5);
151
+ --loidolt-chart-6: var(--loidolt-color-series-6);
152
+ --loidolt-chart-7: var(--loidolt-color-series-7);
153
+ --loidolt-chart-8: var(--loidolt-color-series-8);
154
+ --loidolt-chart-sequential-1: var(--loidolt-color-sequential-1);
155
+ --loidolt-chart-sequential-2: var(--loidolt-color-sequential-2);
156
+ --loidolt-chart-sequential-3: var(--loidolt-color-sequential-3);
157
+ --loidolt-chart-sequential-4: var(--loidolt-color-sequential-4);
158
+ --loidolt-chart-sequential-5: var(--loidolt-color-sequential-5);
159
+ --loidolt-chart-diverging-1: var(--loidolt-color-diverging-1);
160
+ --loidolt-chart-diverging-2: var(--loidolt-color-diverging-2);
161
+ --loidolt-chart-diverging-3: var(--loidolt-color-diverging-3);
162
+ --loidolt-chart-diverging-4: var(--loidolt-color-diverging-4);
163
+ --loidolt-chart-diverging-5: var(--loidolt-color-diverging-5);
164
+ --loidolt-chart-diverging-6: var(--loidolt-color-diverging-6);
165
+ --loidolt-chart-diverging-7: var(--loidolt-color-diverging-7);
166
+ --loidolt-chart-positive: var(--loidolt-color-success);
167
+ --loidolt-chart-negative: var(--loidolt-color-error);
168
+ --loidolt-map-land: var(--loidolt-color-paper);
169
+ --loidolt-map-water: var(--loidolt-color-map-water);
170
+ --loidolt-map-park: var(--loidolt-color-map-park);
171
+ --loidolt-map-road: var(--loidolt-color-map-road);
172
+ --loidolt-map-road-major: var(--loidolt-color-map-road-major);
173
+ --loidolt-map-building: var(--loidolt-color-map-building);
174
+ --loidolt-map-boundary: var(--loidolt-color-line-strong);
175
+ --loidolt-map-label: var(--loidolt-color-deep);
176
+ --loidolt-map-label-halo: var(--loidolt-color-panel);
177
+ --loidolt-syntax-keyword: var(--loidolt-color-syntax-keyword);
178
+ --loidolt-syntax-string: var(--loidolt-color-syntax-string);
179
+ --loidolt-syntax-comment: var(--loidolt-color-syntax-comment);
180
+ --loidolt-syntax-constant: var(--loidolt-color-syntax-constant);
181
+ --loidolt-syntax-function: var(--loidolt-color-syntax-function);
182
+ --loidolt-syntax-parameter: var(--loidolt-color-syntax-parameter);
183
+ --loidolt-syntax-punctuation: var(--loidolt-color-syntax-punctuation);
109
184
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loidolt/theme-tokens",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Typed design tokens for Loidolt applications",
5
5
  "license": "MIT",
6
6
  "type": "module",