@crewlethq/tokens 0.12.0 → 0.13.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/dist/themes.js CHANGED
@@ -27,9 +27,12 @@ export const themes = {
27
27
  "text": {
28
28
  "primary": "#121625",
29
29
  "secondary": "#3e4459",
30
+ "linkQuiet": "#484e99",
30
31
  "tertiary": "#585e73",
31
32
  "muted": "#878d9f",
32
33
  "onAccent": "#ffffff",
34
+ "onDanger": "#ffffff",
35
+ "onScrim": "#ffffff",
33
36
  "inverse": "#f6f7fb"
34
37
  },
35
38
  "brand": {
@@ -144,9 +147,12 @@ export const themes = {
144
147
  "text": {
145
148
  "primary": "#e7eaf3",
146
149
  "secondary": "#a9b0c3",
150
+ "linkQuiet": "#a9b0ea",
147
151
  "tertiary": "#9fa7bc",
148
152
  "muted": "#5a6176",
149
153
  "onAccent": "#ffffff",
154
+ "onDanger": "#ffffff",
155
+ "onScrim": "#ffffff",
150
156
  "inverse": "#07080d"
151
157
  },
152
158
  "brand": {
@@ -244,3 +250,470 @@ export const themes = {
244
250
  }
245
251
  }
246
252
  };
253
+ /** The groups a theme picker lists the themes under, in order. */
254
+ export const themeGroups = [
255
+ {
256
+ "id": "crewlet",
257
+ "name": "Crewlet",
258
+ "description": "The brand's own palettes."
259
+ },
260
+ {
261
+ "id": "purple",
262
+ "name": "Purple",
263
+ "description": "Grounds anchored on #090019."
264
+ },
265
+ {
266
+ "id": "cool",
267
+ "name": "Cool",
268
+ "description": "Blue-black grounds."
269
+ },
270
+ {
271
+ "id": "warm",
272
+ "name": "Warm",
273
+ "description": "Warm stone grounds."
274
+ },
275
+ {
276
+ "id": "high-contrast",
277
+ "name": "High contrast",
278
+ "description": "For readers who need more contrast than the defaults give."
279
+ }
280
+ ];
281
+ /**
282
+ * Every theme, in the order a picker lists them. `id` is the value of the
283
+ * data-palette attribute that paints it (the default paints with none),
284
+ * `swatch` the colours a picker draws its thumbnail with in each mode, and
285
+ * `tint` and `contrast` the profile the palette suite measures it under.
286
+ */
287
+ export const themeRegistry = [
288
+ {
289
+ "id": "crewlet",
290
+ "name": "Crewlet",
291
+ "group": "crewlet",
292
+ "tag": "Default",
293
+ "description": "Blue-black neutrals with a violet accent and a cyan working state.",
294
+ "tint": null,
295
+ "contrast": "standard",
296
+ "swatch": {
297
+ "dark": {
298
+ "frame": "#07080d",
299
+ "sheet": "#0c0e16",
300
+ "card": "#11141d",
301
+ "raised": "#242833",
302
+ "hairline": "#191b20",
303
+ "text": "#e7eaf3",
304
+ "muted": "#5a6176",
305
+ "accent": "#725be6",
306
+ "onAccent": "#ffffff",
307
+ "info": "#61d0ff",
308
+ "warning": "#f0b425",
309
+ "danger": "#d73756",
310
+ "success": "#34c98b"
311
+ },
312
+ "light": {
313
+ "frame": "#e9ecf3",
314
+ "sheet": "#f6f7fb",
315
+ "card": "#fcfcfc",
316
+ "raised": "#f1f2f6",
317
+ "hairline": "#e7e8ec",
318
+ "text": "#121625",
319
+ "muted": "#878d9f",
320
+ "accent": "#735af2",
321
+ "onAccent": "#ffffff",
322
+ "info": "#2f92b4",
323
+ "warning": "#c17300",
324
+ "danger": "#b9112c",
325
+ "success": "#0b9a74"
326
+ }
327
+ }
328
+ },
329
+ {
330
+ "id": "violet",
331
+ "name": "Violet",
332
+ "group": "crewlet",
333
+ "tag": "Zinc and violet",
334
+ "description": "Zinc neutrals with a saturated violet accent.",
335
+ "tint": null,
336
+ "contrast": "standard",
337
+ "swatch": {
338
+ "dark": {
339
+ "frame": "#09090b",
340
+ "sheet": "#101013",
341
+ "card": "#141418",
342
+ "raised": "#1b1b20",
343
+ "hairline": "#232329",
344
+ "text": "#ededf0",
345
+ "muted": "#5f5f68",
346
+ "accent": "#7c56ff",
347
+ "onAccent": "#ffffff",
348
+ "info": "#4c9dff",
349
+ "warning": "#f4b221",
350
+ "danger": "#e50055",
351
+ "success": "#3ecf8f"
352
+ },
353
+ "light": {
354
+ "frame": "#ededea",
355
+ "sheet": "#f9f9f8",
356
+ "card": "#ffffff",
357
+ "raised": "#f3f3f1",
358
+ "hairline": "#e4e4e0",
359
+ "text": "#17171a",
360
+ "muted": "#8d8d94",
361
+ "accent": "#6b45f0",
362
+ "onAccent": "#ffffff",
363
+ "info": "#3081de",
364
+ "warning": "#c57600",
365
+ "danger": "#c01d32",
366
+ "success": "#009b74"
367
+ }
368
+ }
369
+ },
370
+ {
371
+ "id": "origin",
372
+ "name": "Origin",
373
+ "group": "crewlet",
374
+ "tag": "Purple on charcoal",
375
+ "description": "Charcoal and near-black grounds, graphite cards and hairlines, and a #5469d4 purple on the primary button, links and focus.",
376
+ "tint": null,
377
+ "contrast": "standard",
378
+ "swatch": {
379
+ "dark": {
380
+ "frame": "#15171c",
381
+ "sheet": "#0e0f13",
382
+ "card": "#1c1e24",
383
+ "raised": "#23262c",
384
+ "hairline": "#3f4145",
385
+ "text": "#ececee",
386
+ "muted": "#60646b",
387
+ "accent": "#5469d4",
388
+ "onAccent": "#ffffff",
389
+ "info": "#3a8ff4",
390
+ "warning": "#f59e0b",
391
+ "danger": "#d6364c",
392
+ "success": "#3eba82"
393
+ },
394
+ "light": {
395
+ "frame": "#f4f4f5",
396
+ "sheet": "#ffffff",
397
+ "card": "#f7f7f8",
398
+ "raised": "#ececef",
399
+ "hairline": "#e2e2e5",
400
+ "text": "#09090b",
401
+ "muted": "#929294",
402
+ "accent": "#5469d4",
403
+ "onAccent": "#ffffff",
404
+ "info": "#3190c5",
405
+ "warning": "#c57500",
406
+ "danger": "#b9112c",
407
+ "success": "#0f9a73"
408
+ }
409
+ }
410
+ },
411
+ {
412
+ "id": "abyss",
413
+ "name": "Abyss",
414
+ "group": "purple",
415
+ "tag": "Vivid violet",
416
+ "description": "Ink-violet grounds on #090019 with an electric violet accent.",
417
+ "tint": {
418
+ "hue": 298,
419
+ "chroma": 7
420
+ },
421
+ "contrast": "standard",
422
+ "swatch": {
423
+ "dark": {
424
+ "frame": "#090019",
425
+ "sheet": "#120425",
426
+ "card": "#180b2c",
427
+ "raised": "#1e1430",
428
+ "hairline": "#2b1f41",
429
+ "text": "#ebe6f8",
430
+ "muted": "#62577c",
431
+ "accent": "#8633fe",
432
+ "onAccent": "#ffffff",
433
+ "info": "#1281c3",
434
+ "warning": "#ffb22f",
435
+ "danger": "#dd2c5b",
436
+ "success": "#16d297"
437
+ },
438
+ "light": {
439
+ "frame": "#e8e3f3",
440
+ "sheet": "#f8f6fd",
441
+ "card": "#fdfcff",
442
+ "raised": "#edeaf7",
443
+ "hairline": "#dfd9eb",
444
+ "text": "#1d132f",
445
+ "muted": "#8d83a2",
446
+ "accent": "#6b11da",
447
+ "onAccent": "#ffffff",
448
+ "info": "#287ac2",
449
+ "warning": "#c16f00",
450
+ "danger": "#9a0028",
451
+ "success": "#019472"
452
+ }
453
+ }
454
+ },
455
+ {
456
+ "id": "iris",
457
+ "name": "Iris",
458
+ "group": "purple",
459
+ "tag": "Periwinkle",
460
+ "description": "Cool violet grounds with a periwinkle accent that carries a dark label at night.",
461
+ "tint": {
462
+ "hue": 296,
463
+ "chroma": 7.5
464
+ },
465
+ "contrast": "standard",
466
+ "swatch": {
467
+ "dark": {
468
+ "frame": "#09011a",
469
+ "sheet": "#110b1e",
470
+ "card": "#141021",
471
+ "raised": "#1c0f34",
472
+ "hairline": "#292339",
473
+ "text": "#eae7f7",
474
+ "muted": "#645d76",
475
+ "accent": "#9584ff",
476
+ "onAccent": "#09011a",
477
+ "info": "#0279a9",
478
+ "warning": "#f9ad26",
479
+ "danger": "#db3845",
480
+ "success": "#27cf9b"
481
+ },
482
+ "light": {
483
+ "frame": "#e8e4f6",
484
+ "sheet": "#f8f6fd",
485
+ "card": "#ffffff",
486
+ "raised": "#efecf9",
487
+ "hairline": "#dddaea",
488
+ "text": "#181128",
489
+ "muted": "#8b859d",
490
+ "accent": "#4a2abd",
491
+ "onAccent": "#ffffff",
492
+ "info": "#0585b9",
493
+ "warning": "#be6e02",
494
+ "danger": "#9a0b35",
495
+ "success": "#039571"
496
+ }
497
+ }
498
+ },
499
+ {
500
+ "id": "dusk",
501
+ "name": "Dusk",
502
+ "group": "purple",
503
+ "tag": "Soft lavender",
504
+ "description": "Muted violet-grey grounds with a soft lavender accent. The calmest option, built for long sessions.",
505
+ "tint": {
506
+ "hue": 305,
507
+ "chroma": 4
508
+ },
509
+ "contrast": "standard",
510
+ "swatch": {
511
+ "dark": {
512
+ "frame": "#090311",
513
+ "sheet": "#110c18",
514
+ "card": "#17111d",
515
+ "raised": "#1f1827",
516
+ "hairline": "#282031",
517
+ "text": "#e6e2ec",
518
+ "muted": "#66606f",
519
+ "accent": "#d6b7fc",
520
+ "onAccent": "#090019",
521
+ "info": "#3185b8",
522
+ "warning": "#f4b73b",
523
+ "danger": "#ca4d48",
524
+ "success": "#8ec899"
525
+ },
526
+ "light": {
527
+ "frame": "#e9e5f0",
528
+ "sheet": "#f4f1f8",
529
+ "card": "#faf8fc",
530
+ "raised": "#efebf4",
531
+ "hairline": "#e0dbe6",
532
+ "text": "#221a2a",
533
+ "muted": "#8d8697",
534
+ "accent": "#4e247e",
535
+ "onAccent": "#ffffff",
536
+ "info": "#1b86bf",
537
+ "warning": "#af6901",
538
+ "danger": "#8a0d15",
539
+ "success": "#527b67"
540
+ }
541
+ }
542
+ },
543
+ {
544
+ "id": "nocturne",
545
+ "name": "Nocturne",
546
+ "group": "cool",
547
+ "tag": "Indigo",
548
+ "description": "Blue-black grounds with an indigo accent. Calm and technical.",
549
+ "tint": {
550
+ "hue": 272,
551
+ "chroma": 3
552
+ },
553
+ "contrast": "standard",
554
+ "swatch": {
555
+ "dark": {
556
+ "frame": "#07080d",
557
+ "sheet": "#0c0e16",
558
+ "card": "#11141d",
559
+ "raised": "#181c28",
560
+ "hairline": "#1f2433",
561
+ "text": "#e6e9f2",
562
+ "muted": "#5a6176",
563
+ "accent": "#5a62f0",
564
+ "onAccent": "#ffffff",
565
+ "info": "#38bdf8",
566
+ "warning": "#f0b425",
567
+ "danger": "#de2f5b",
568
+ "success": "#34c98b"
569
+ },
570
+ "light": {
571
+ "frame": "#e9ecf3",
572
+ "sheet": "#f6f7fb",
573
+ "card": "#ffffff",
574
+ "raised": "#eff1f7",
575
+ "hairline": "#dde1ea",
576
+ "text": "#121625",
577
+ "muted": "#878d9f",
578
+ "accent": "#4c55e6",
579
+ "onAccent": "#ffffff",
580
+ "info": "#0b84c6",
581
+ "warning": "#b86e00",
582
+ "danger": "#b8002e",
583
+ "success": "#00916f"
584
+ }
585
+ }
586
+ },
587
+ {
588
+ "id": "nightshade",
589
+ "name": "Nightshade",
590
+ "group": "cool",
591
+ "tag": "Iris at night",
592
+ "description": "Nocturne's blue-black grounds with Iris's periwinkle accent, states and charts.",
593
+ "tint": {
594
+ "hue": 272,
595
+ "chroma": 3
596
+ },
597
+ "contrast": "standard",
598
+ "swatch": {
599
+ "dark": {
600
+ "frame": "#07080d",
601
+ "sheet": "#0d0f16",
602
+ "card": "#11141d",
603
+ "raised": "#171b27",
604
+ "hairline": "#1f2433",
605
+ "text": "#e8ebf4",
606
+ "muted": "#5a6176",
607
+ "accent": "#9584ff",
608
+ "onAccent": "#07080d",
609
+ "info": "#0279a9",
610
+ "warning": "#f9ad26",
611
+ "danger": "#db3845",
612
+ "success": "#20cc98"
613
+ },
614
+ "light": {
615
+ "frame": "#e7eaf1",
616
+ "sheet": "#f6f7fb",
617
+ "card": "#ffffff",
618
+ "raised": "#eef0f6",
619
+ "hairline": "#dde1ea",
620
+ "text": "#121625",
621
+ "muted": "#878a9d",
622
+ "accent": "#4a2abd",
623
+ "onAccent": "#ffffff",
624
+ "info": "#0585b9",
625
+ "warning": "#be6e02",
626
+ "danger": "#9a0b35",
627
+ "success": "#039571"
628
+ }
629
+ }
630
+ },
631
+ {
632
+ "id": "ledger",
633
+ "name": "Ledger",
634
+ "group": "warm",
635
+ "tag": "Cobalt on stone",
636
+ "description": "Warm stone grounds with a cobalt accent. Reads like printed paper in light.",
637
+ "tint": null,
638
+ "contrast": "standard",
639
+ "swatch": {
640
+ "dark": {
641
+ "frame": "#0d0c0a",
642
+ "sheet": "#141310",
643
+ "card": "#191814",
644
+ "raised": "#211f1b",
645
+ "hairline": "#2a2823",
646
+ "text": "#ece8df",
647
+ "muted": "#67625a",
648
+ "accent": "#4d6bef",
649
+ "onAccent": "#ffffff",
650
+ "info": "#2fb3b0",
651
+ "warning": "#e2a132",
652
+ "danger": "#d6403d",
653
+ "success": "#53cc8f"
654
+ },
655
+ "light": {
656
+ "frame": "#ebe8e1",
657
+ "sheet": "#f6f5f1",
658
+ "card": "#fffefb",
659
+ "raised": "#f0ede6",
660
+ "hairline": "#e0dbd0",
661
+ "text": "#1c1a16",
662
+ "muted": "#908a7e",
663
+ "accent": "#2f50d8",
664
+ "onAccent": "#ffffff",
665
+ "info": "#007883",
666
+ "warning": "#a86900",
667
+ "danger": "#9c332b",
668
+ "success": "#1a9368"
669
+ }
670
+ }
671
+ },
672
+ {
673
+ "id": "high-contrast",
674
+ "name": "High contrast",
675
+ "group": "high-contrast",
676
+ "tag": "AAA text",
677
+ "description": "Every word at 7:1 or more, hairlines a reader can find, and a muted step that reads rather than decorates.",
678
+ "tint": null,
679
+ "contrast": "high",
680
+ "swatch": {
681
+ "dark": {
682
+ "frame": "#000000",
683
+ "sheet": "#0b0b10",
684
+ "card": "#0f0f16",
685
+ "raised": "#16161d",
686
+ "hairline": "#7c7c90",
687
+ "text": "#f8f8fb",
688
+ "muted": "#9696a6",
689
+ "accent": "#6c55e6",
690
+ "onAccent": "#ffffff",
691
+ "info": "#61d0ff",
692
+ "warning": "#f0b425",
693
+ "danger": "#d73756",
694
+ "success": "#34c98b"
695
+ },
696
+ "light": {
697
+ "frame": "#e9ecf3",
698
+ "sheet": "#f6f7fb",
699
+ "card": "#fcfcfc",
700
+ "raised": "#f1f2f6",
701
+ "hairline": "#6f6f82",
702
+ "text": "#000000",
703
+ "muted": "#5b5b69",
704
+ "accent": "#4424c4",
705
+ "onAccent": "#ffffff",
706
+ "info": "#2f92b4",
707
+ "warning": "#c17300",
708
+ "danger": "#b9112c",
709
+ "success": "#0b9a74"
710
+ }
711
+ }
712
+ }
713
+ ];
714
+ /** The theme a document that names none gets: it paints the bare root. */
715
+ export const DEFAULT_THEME_ID = 'crewlet';
716
+ /** Whether a stored or typed value names a theme this build ships. */
717
+ export function isThemeId(value) {
718
+ return typeof value === 'string' && themeRegistry.some((theme) => theme.id === value);
719
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewlethq/tokens",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Crewlet design tokens. Single JSON source compiled to CSS variables and typed JS modules.",
5
5
  "license": "MIT AND OFL-1.1",
6
6
  "repository": {
@@ -32,6 +32,7 @@
32
32
  "./css/legacy": "./dist/css/legacy.css",
33
33
  "./css/material-symbols": "./dist/css/material-symbols.css",
34
34
  "./css/themes": "./dist/css/themes.css",
35
+ "./css/themes/*": "./dist/css/themes/*.css",
35
36
  "./fonts/*": "./fonts/*",
36
37
  "./test/palette": {
37
38
  "types": "./test/palette.d.mts",
package/test/color.mjs CHANGED
@@ -190,6 +190,12 @@ export function deltaE(x, y) {
190
190
  return Math.hypot(a.L - b.L, a.a - b.a, a.b - b.b) * 100;
191
191
  }
192
192
 
193
+ /** The OKLCh hue of a colour, in degrees from 0 to under 360. */
194
+ export function hue(c) {
195
+ const { a, b } = toOklab(c);
196
+ return ((Math.atan2(b, a) * 180) / Math.PI + 360) % 360;
197
+ }
198
+
193
199
  export function chroma(c) {
194
200
  const { a, b } = toOklab(c);
195
201
  return Math.hypot(a, b) * 100;
@@ -33,8 +33,17 @@ export interface PaletteCheck {
33
33
  export interface PaletteSources {
34
34
  /** The text of the built tokens.css. */
35
35
  tokens: string;
36
- /** The text of the built themes.css. */
36
+ /**
37
+ * The text of the built themes.css, followed by the sheet of a named theme
38
+ * (css/themes/<id>.css, or css/themes/all.css) when `palette` names one.
39
+ */
37
40
  themes: string;
41
+ /** A named theme's id, measured under its data-palette blocks; absent for the default. */
42
+ palette?: string | null;
43
+ /** The tint a theme declares for its grounds, measured in place of the neutral cap. */
44
+ tint?: { hue: number; chroma: number } | null;
45
+ /** 'high' holds the theme to the high-contrast floors as well. */
46
+ contrast?: 'standard' | 'high';
38
47
  }
39
48
 
40
49
  export interface PaletteResult {
@@ -55,6 +64,18 @@ export function runPalette(sources: PaletteSources): PaletteResult;
55
64
  */
56
65
  export function paletteStates(sources: PaletteSources): Record<string, Map<string, string>>;
57
66
 
67
+ /** The three selectors that paint a theme: the default on the bare root, a named one under data-palette. */
68
+ export function paletteSelectors(palette: string | null | undefined): { dark: string; lightMedia: string; lightAttribute: string };
69
+
70
+ /** The chroma under which a ground reads as neutral, and the cap an untinted theme's rungs keep. */
71
+ export const NEUTRAL_CHROMA: number;
72
+ /** How far, in OKLCh degrees, a tinted rung's hue may sit from its theme's declared tint. */
73
+ export const TINT_HUE_RANGE: number;
74
+ /** How many times the most tinted rung's chroma the accent carries. */
75
+ export const ACCENT_OVER_TINT: number;
76
+ /** The floors a high-contrast theme is held to on top of the table. */
77
+ export const HIGH_CONTRAST: { readonly text: number; readonly ink: number; readonly muted: number; readonly hairline: number };
78
+
58
79
  /** One line per failing check, for an assertion message. */
59
80
  export function describeFailure(check: PaletteCheck): string;
60
81
 
@@ -164,6 +185,10 @@ export const ACTION_STEPS: readonly (readonly [string, string, string])[];
164
185
  */
165
186
  export const MARK_ON_FILL: readonly (readonly [string, string])[];
166
187
  export const ACTION_LABEL: string;
188
+ /** The destructive action's label, which each step of the danger fill moves away from. */
189
+ export const DESTRUCTIVE_LABEL: string;
190
+ /** The label drawn on the scrim and on a seeded tint, white in every palette. */
191
+ export const SCRIM_LABEL: string;
167
192
  export const ACTION_DE: number;
168
193
 
169
194
  /** The token name of the modal veil. */