@skdx/tokens 0.26.0 → 0.28.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 (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -57
  3. package/dist/themes/AntDark.d.cts +3 -7
  4. package/dist/themes/AntDark.d.ts +3 -7
  5. package/dist/themes/ChakraDark.d.cts +3 -7
  6. package/dist/themes/ChakraDark.d.ts +3 -7
  7. package/dist/themes/DefaultTheme.d.cts +1 -2
  8. package/dist/themes/DefaultTheme.d.ts +1 -2
  9. package/dist/themes/DraculaLight.d.cts +1 -9
  10. package/dist/themes/DraculaLight.d.ts +1 -9
  11. package/dist/themes/EverforestDark.d.cts +1 -2
  12. package/dist/themes/EverforestDark.d.ts +1 -2
  13. package/dist/themes/EverforestLight.d.cts +4 -8
  14. package/dist/themes/EverforestLight.d.ts +4 -8
  15. package/dist/themes/FluentDark.d.cts +2 -6
  16. package/dist/themes/FluentDark.d.ts +2 -6
  17. package/dist/themes/GruvboxLight.d.cts +1 -2
  18. package/dist/themes/GruvboxLight.d.ts +1 -2
  19. package/dist/themes/MaterialBrand.d.cts +1 -1
  20. package/dist/themes/MaterialBrand.d.ts +1 -1
  21. package/dist/themes/MaterialDark.d.cts +3 -7
  22. package/dist/themes/MaterialDark.d.ts +3 -7
  23. package/dist/themes/MidnightBrand.d.cts +2 -5
  24. package/dist/themes/MidnightBrand.d.ts +2 -5
  25. package/dist/themes/MidnightLight.d.cts +2 -5
  26. package/dist/themes/MidnightLight.d.ts +2 -5
  27. package/dist/themes/NordLight.d.cts +1 -2
  28. package/dist/themes/NordLight.d.ts +1 -2
  29. package/dist/themes/OneLight.d.cts +4 -8
  30. package/dist/themes/OneLight.d.ts +4 -8
  31. package/dist/themes/PrimerDark.d.cts +0 -1
  32. package/dist/themes/PrimerDark.d.ts +0 -1
  33. package/dist/themes/RosePineDawn.d.cts +4 -8
  34. package/dist/themes/RosePineDawn.d.ts +4 -8
  35. package/dist/themes/SkandaDark.d.cts +3 -7
  36. package/dist/themes/SkandaDark.d.ts +3 -7
  37. package/dist/themes/SynthwaveLight.d.cts +3 -7
  38. package/dist/themes/SynthwaveLight.d.ts +3 -7
  39. package/dist/themes/brands.d.cts +7 -14
  40. package/dist/themes/brands.d.ts +7 -14
  41. package/dist/themes/createBrandTheme.d.cts +13 -21
  42. package/dist/themes/createBrandTheme.d.ts +13 -21
  43. package/dist/utils/aliases.d.cts +22 -92
  44. package/dist/utils/aliases.d.ts +22 -92
  45. package/dist/utils/contrast.d.cts +2 -17
  46. package/dist/utils/contrast.d.ts +2 -17
  47. package/dist/utils/cssVars.d.cts +7 -29
  48. package/dist/utils/cssVars.d.ts +7 -29
  49. package/dist/utils/foundation.d.cts +47 -143
  50. package/dist/utils/foundation.d.ts +47 -143
  51. package/dist/utils/mode.d.cts +31 -43
  52. package/dist/utils/mode.d.ts +31 -43
  53. package/dist/utils/theme.d.cts +83 -240
  54. package/dist/utils/theme.d.ts +83 -240
  55. package/dist/utils/toCss.d.cts +18 -57
  56. package/dist/utils/toCss.d.ts +18 -57
  57. package/package.json +1 -1
@@ -1,12 +1,8 @@
1
1
  /**
2
- * Light counterpart of `one-dark`, following Atom's One Light scheme
3
- * (#fafafa background, #383a42 text). Palette source: atom/one-light-syntax
4
- * (MIT).
5
- *
6
- * `primary-500` is One Light's own blue (#4078f2), not a lightened One Dark
7
- * blue — the two schemes pick genuinely different blues, and 500 is the slot
8
- * consumers read for a plain accent. 600 is that blue darkened, since
9
- * #4078f2 carries only 4.05:1 under white label text.
2
+ * Light counterpart of `one-dark`, following One Light's scheme
3
+ * (#fafafa background, #383a42 text). Uses One Light's own blue (#4078f2);
4
+ * the two schemes specify different blues. At 500 it reaches only 4.05:1
5
+ * contrast; 600 darkens it for white text.
10
6
  *
11
7
  * @public
12
8
  */
@@ -1,12 +1,8 @@
1
1
  /**
2
- * Light counterpart of `one-dark`, following Atom's One Light scheme
3
- * (#fafafa background, #383a42 text). Palette source: atom/one-light-syntax
4
- * (MIT).
5
- *
6
- * `primary-500` is One Light's own blue (#4078f2), not a lightened One Dark
7
- * blue — the two schemes pick genuinely different blues, and 500 is the slot
8
- * consumers read for a plain accent. 600 is that blue darkened, since
9
- * #4078f2 carries only 4.05:1 under white label text.
2
+ * Light counterpart of `one-dark`, following One Light's scheme
3
+ * (#fafafa background, #383a42 text). Uses One Light's own blue (#4078f2);
4
+ * the two schemes specify different blues. At 500 it reaches only 4.05:1
5
+ * contrast; 600 darkens it for white text.
10
6
  *
11
7
  * @public
12
8
  */
@@ -2,7 +2,6 @@ import type { Theme } from '../utils/theme.cjs';
2
2
  /**
3
3
  * Primer Dark inspired theme: GitHub's dark mode — `#0d1117` canvas,
4
4
  * `#1f6feb` accent blue, and the Primer dark green/yellow/red scales.
5
- * Palette source: primer/primitives (MIT).
6
5
  *
7
6
  * @public
8
7
  */
@@ -2,7 +2,6 @@ import type { Theme } from '../utils/theme.js';
2
2
  /**
3
3
  * Primer Dark inspired theme: GitHub's dark mode — `#0d1117` canvas,
4
4
  * `#1f6feb` accent blue, and the Primer dark green/yellow/red scales.
5
- * Palette source: primer/primitives (MIT).
6
5
  *
7
6
  * @public
8
7
  */
@@ -1,12 +1,8 @@
1
1
  /**
2
- * Light counterpart of `rose-pine`, built on the Rosé Pine Dawn variant
3
- * (#faf4ed base, #575279 text). Palette source: rose-pine/rose-pine-theme
4
- * (MIT).
5
- *
6
- * `primary-500` is Dawn's own iris (#907aa9) — Dawn restates every role
7
- * rather than lightening Main's, and its iris is markedly softer than
8
- * Main's #c4a7e7. 600 is that iris darkened, since #907aa9 carries only
9
- * 3.79:1 under white label text.
2
+ * Light counterpart of `rose-pine`, built on Rosé Pine Dawn
3
+ * (#faf4ed base, #575279 text). Uses Dawn's iris (#907aa9), which is softer
4
+ * than the dark palette's #c4a7e7. At 500 it reaches only 3.79:1 contrast;
5
+ * 600 darkens it for white text.
10
6
  *
11
7
  * @public
12
8
  */
@@ -1,12 +1,8 @@
1
1
  /**
2
- * Light counterpart of `rose-pine`, built on the Rosé Pine Dawn variant
3
- * (#faf4ed base, #575279 text). Palette source: rose-pine/rose-pine-theme
4
- * (MIT).
5
- *
6
- * `primary-500` is Dawn's own iris (#907aa9) — Dawn restates every role
7
- * rather than lightening Main's, and its iris is markedly softer than
8
- * Main's #c4a7e7. 600 is that iris darkened, since #907aa9 carries only
9
- * 3.79:1 under white label text.
2
+ * Light counterpart of `rose-pine`, built on Rosé Pine Dawn
3
+ * (#faf4ed base, #575279 text). Uses Dawn's iris (#907aa9), which is softer
4
+ * than the dark palette's #c4a7e7. At 500 it reaches only 3.79:1 contrast;
5
+ * 600 darkens it for white text.
10
6
  *
11
7
  * @public
12
8
  */
@@ -1,11 +1,7 @@
1
1
  /**
2
- * Dark counterpart of `skanda-light` — the Skanda blue on deep slate
3
- * surfaces. Together they form the `skanda` brand's light/dark pair (see
4
- * `brands`).
5
- *
6
- * The ramp is centred one step lighter than the light theme's: `primary-600`
7
- * is the filled-action slot in both modes, and a mid-blue tuned to sit on
8
- * white is too dark to read as an accent on `#0f172a`.
2
+ * Dark counterpart of `skanda-light` — Skanda blue on deep slate.
3
+ * The ramp is shifted one step lighter; mid-blue tuned for white becomes
4
+ * too dark as an accent on `#0f172a`.
9
5
  *
10
6
  * @public
11
7
  */
@@ -1,11 +1,7 @@
1
1
  /**
2
- * Dark counterpart of `skanda-light` — the Skanda blue on deep slate
3
- * surfaces. Together they form the `skanda` brand's light/dark pair (see
4
- * `brands`).
5
- *
6
- * The ramp is centred one step lighter than the light theme's: `primary-600`
7
- * is the filled-action slot in both modes, and a mid-blue tuned to sit on
8
- * white is too dark to read as an accent on `#0f172a`.
2
+ * Dark counterpart of `skanda-light` — Skanda blue on deep slate.
3
+ * The ramp is shifted one step lighter; mid-blue tuned for white becomes
4
+ * too dark as an accent on `#0f172a`.
9
5
  *
10
6
  * @public
11
7
  */
@@ -1,11 +1,7 @@
1
1
  /**
2
- * Light counterpart of `synthwave-dark` — the neon pink primary on pale
3
- * lavender surfaces.
4
- *
5
- * Synthwave '84 is a dark-only scheme upstream, so unlike the other bundled
6
- * pairs this light mode has no published palette to match; it is a
7
- * deliberate derivation, holding the neon's hue while dropping lightness far
8
- * enough to survive on paper. The dark mode takes the real #ff7edb.
2
+ * Light counterpart of `synthwave-dark` — neon pink primary on pale lavender.
3
+ * This light mode is a deliberate derivation: the dark theme uses the real
4
+ * neon pink (#ff7edb), but dropped here to survive on paper.
9
5
  *
10
6
  * @public
11
7
  */
@@ -1,11 +1,7 @@
1
1
  /**
2
- * Light counterpart of `synthwave-dark` — the neon pink primary on pale
3
- * lavender surfaces.
4
- *
5
- * Synthwave '84 is a dark-only scheme upstream, so unlike the other bundled
6
- * pairs this light mode has no published palette to match; it is a
7
- * deliberate derivation, holding the neon's hue while dropping lightness far
8
- * enough to survive on paper. The dark mode takes the real #ff7edb.
2
+ * Light counterpart of `synthwave-dark` — neon pink primary on pale lavender.
3
+ * This light mode is a deliberate derivation: the dark theme uses the real
4
+ * neon pink (#ff7edb), but dropped here to survive on paper.
9
5
  *
10
6
  * @public
11
7
  */
@@ -1,11 +1,8 @@
1
1
  import type { Theme, ThemeColorMode } from '../utils/theme.cjs';
2
2
  /**
3
3
  * A brand is one visual identity with a complete {@link Theme} per color
4
- * mode. The brand decides identity (palette hues, type, radii, motion); the
5
- * mode decides light or dark appearance. Consumers resolve a user's brand
6
- * preference plus color-mode preference to `brand.themes[mode]` and hand
7
- * that theme to the existing `themeToCss`/`applyTheme` pipeline — the
8
- * resolved theme is an ordinary `Theme`, so nothing downstream changes.
4
+ * mode the brand decides identity (palette, type, radii, motion), the
5
+ * mode decides light or dark appearance.
9
6
  *
10
7
  * @public
11
8
  */
@@ -18,23 +15,19 @@ export interface Brand {
18
15
  themes: Record<ThemeColorMode, Theme>;
19
16
  }
20
17
  /**
21
- * Every bundled brand with its light/dark theme pair, in the same order the
22
- * pre-brand `themes` array introduced them. This array is the authoritative
23
- * brand registry — tests derive the brand-and-mode support matrix from it,
24
- * so a brand missing either mode fails validation rather than falling back
25
- * to another brand's values.
18
+ * Every bundled brand with its light/dark theme pair in stable order
19
+ * the authoritative brand registry for the brand-and-mode support matrix.
26
20
  *
27
21
  * @public
28
22
  */
29
23
  export declare const brands: Brand[];
30
- /** The default brand `skanda`, whose light theme is `defaultTheme`/`skanda-light`. @public */
24
+ /** Default brand (`skanda-light`). @public */
31
25
  export declare const defaultBrand: Brand;
32
- /** Looks up a brand by its stable identifier; `undefined` for unknown names so callers can apply their own fallback. @public */
26
+ /** Looks up a brand by its stable identifier; `undefined` if not found. @public */
33
27
  export declare function getBrand(name: string): Brand | undefined;
34
28
  /**
35
29
  * Looks up the brand that owns a theme name (either mode) — e.g.
36
- * `'one-dark'` → the `one` brand. Useful for migrating persisted
37
- * pre-brand theme-name preferences to a brand preference.
30
+ * `'one-dark'` → the `one` brand.
38
31
  *
39
32
  * @public
40
33
  */
@@ -1,11 +1,8 @@
1
1
  import type { Theme, ThemeColorMode } from '../utils/theme.js';
2
2
  /**
3
3
  * A brand is one visual identity with a complete {@link Theme} per color
4
- * mode. The brand decides identity (palette hues, type, radii, motion); the
5
- * mode decides light or dark appearance. Consumers resolve a user's brand
6
- * preference plus color-mode preference to `brand.themes[mode]` and hand
7
- * that theme to the existing `themeToCss`/`applyTheme` pipeline — the
8
- * resolved theme is an ordinary `Theme`, so nothing downstream changes.
4
+ * mode the brand decides identity (palette, type, radii, motion), the
5
+ * mode decides light or dark appearance.
9
6
  *
10
7
  * @public
11
8
  */
@@ -18,23 +15,19 @@ export interface Brand {
18
15
  themes: Record<ThemeColorMode, Theme>;
19
16
  }
20
17
  /**
21
- * Every bundled brand with its light/dark theme pair, in the same order the
22
- * pre-brand `themes` array introduced them. This array is the authoritative
23
- * brand registry — tests derive the brand-and-mode support matrix from it,
24
- * so a brand missing either mode fails validation rather than falling back
25
- * to another brand's values.
18
+ * Every bundled brand with its light/dark theme pair in stable order
19
+ * the authoritative brand registry for the brand-and-mode support matrix.
26
20
  *
27
21
  * @public
28
22
  */
29
23
  export declare const brands: Brand[];
30
- /** The default brand `skanda`, whose light theme is `defaultTheme`/`skanda-light`. @public */
24
+ /** Default brand (`skanda-light`). @public */
31
25
  export declare const defaultBrand: Brand;
32
- /** Looks up a brand by its stable identifier; `undefined` for unknown names so callers can apply their own fallback. @public */
26
+ /** Looks up a brand by its stable identifier; `undefined` if not found. @public */
33
27
  export declare function getBrand(name: string): Brand | undefined;
34
28
  /**
35
29
  * Looks up the brand that owns a theme name (either mode) — e.g.
36
- * `'one-dark'` → the `one` brand. Useful for migrating persisted
37
- * pre-brand theme-name preferences to a brand preference.
30
+ * `'one-dark'` → the `one` brand.
38
31
  *
39
32
  * @public
40
33
  */
@@ -1,44 +1,36 @@
1
1
  import type { Theme, ThemeColorMode, ThemeOverride } from '../utils/theme.cjs';
2
2
  /**
3
- * Internal seed for {@link createBrandTheme} the handful of decisions that
4
- * actually define a brand's palette. Everything else (ramp shape, semantic
5
- * role assignment, contrast enforcement) is derived.
3
+ * Seed for {@link createBrandTheme}: brand hues and chroma. Ramp shape,
4
+ * semantic roles, contrast enforcement are derived.
6
5
  */
7
6
  export interface BrandSeed {
8
- /** Theme name, e.g. `'midnight-light'`. Becomes `theme.name`. */
7
+ /** Theme name (e.g. `'midnight-light'`); becomes `theme.name`. */
9
8
  name: string;
10
- /** Which mode's semantic roles to derive — the ramps themselves are mode-independent. */
9
+ /** Which mode's semantic roles to derive (ramps are mode-independent). */
11
10
  mode: ThemeColorMode;
12
11
  /** Primary hue in degrees, 0–360 (e.g. 272 for violet). */
13
12
  primaryHue: number;
14
- /** Saturation of the primary ramp, 0–100. Lower it toward 0 for a monochrome brand. @default 75 */
13
+ /** Primary ramp saturation, 0–100. Toward 0 for monochrome. @default 75 */
15
14
  primaryChroma?: number;
16
- /** Hue the grays are tinted toward. @default primaryHue */
15
+ /** Gray tint hue. @default primaryHue */
17
16
  neutralHue?: number;
18
- /** How much tint the grays carry, 0–100. @default 8 */
17
+ /** Gray tint amount, 0–100. @default 8 */
19
18
  neutralChroma?: number;
20
- /** Hues for the intent ramps. @default { success: 145, warning: 40, danger: 0 } */
19
+ /** Intent ramp hues. @default { success: 145, warning: 40, danger: 0 } */
21
20
  intentHues?: {
22
21
  success?: number;
23
22
  warning?: number;
24
23
  danger?: number;
25
24
  };
26
- /** Saturation of the intent ramps, 0–100. @default 70 */
25
+ /** Intent ramp saturation, 0–100. @default 70 */
27
26
  intentChroma?: number;
28
- /** Merged last, so a brand can still hand-pick anything the seed derives — in practice the shadow tint, which isn't derivable from hue. */
27
+ /** Hand-picked overrides merged last (typically shadow tint). */
29
28
  override?: ThemeOverride;
30
29
  }
31
30
  /**
32
- * Generates a complete {@link Theme} from a {@link BrandSeed}: three-plus
33
- * ramps built from the seed's hues, semantic roles assigned per mode, and
34
- * every WCAG AA pair the contrast test checks (body text 4.5:1, muted text
35
- * and focus ring 3:1 against the page background, inverted text 4.5:1 against
36
- * `primary-600`) driven to threshold by adjusting lightness rather than being
37
- * hand-tuned and hoped for.
38
- *
39
- * Internal on purpose: it is the seam a visual theme builder will call, not a
40
- * public token API — brands that ship today are hand-written theme objects,
41
- * and only `midnight` is generated so far (see `MidnightBrand.ts`).
31
+ * Generate {@link Theme} from {@link BrandSeed}: ramps from hues, semantic
32
+ * roles per mode, WCAG AA pairs enforced to threshold via lightness walk.
33
+ * Internal: visual theme builders call this; hand-written themes are the public API.
42
34
  *
43
35
  * @example
44
36
  * ```ts
@@ -1,44 +1,36 @@
1
1
  import type { Theme, ThemeColorMode, ThemeOverride } from '../utils/theme.js';
2
2
  /**
3
- * Internal seed for {@link createBrandTheme} the handful of decisions that
4
- * actually define a brand's palette. Everything else (ramp shape, semantic
5
- * role assignment, contrast enforcement) is derived.
3
+ * Seed for {@link createBrandTheme}: brand hues and chroma. Ramp shape,
4
+ * semantic roles, contrast enforcement are derived.
6
5
  */
7
6
  export interface BrandSeed {
8
- /** Theme name, e.g. `'midnight-light'`. Becomes `theme.name`. */
7
+ /** Theme name (e.g. `'midnight-light'`); becomes `theme.name`. */
9
8
  name: string;
10
- /** Which mode's semantic roles to derive — the ramps themselves are mode-independent. */
9
+ /** Which mode's semantic roles to derive (ramps are mode-independent). */
11
10
  mode: ThemeColorMode;
12
11
  /** Primary hue in degrees, 0–360 (e.g. 272 for violet). */
13
12
  primaryHue: number;
14
- /** Saturation of the primary ramp, 0–100. Lower it toward 0 for a monochrome brand. @default 75 */
13
+ /** Primary ramp saturation, 0–100. Toward 0 for monochrome. @default 75 */
15
14
  primaryChroma?: number;
16
- /** Hue the grays are tinted toward. @default primaryHue */
15
+ /** Gray tint hue. @default primaryHue */
17
16
  neutralHue?: number;
18
- /** How much tint the grays carry, 0–100. @default 8 */
17
+ /** Gray tint amount, 0–100. @default 8 */
19
18
  neutralChroma?: number;
20
- /** Hues for the intent ramps. @default { success: 145, warning: 40, danger: 0 } */
19
+ /** Intent ramp hues. @default { success: 145, warning: 40, danger: 0 } */
21
20
  intentHues?: {
22
21
  success?: number;
23
22
  warning?: number;
24
23
  danger?: number;
25
24
  };
26
- /** Saturation of the intent ramps, 0–100. @default 70 */
25
+ /** Intent ramp saturation, 0–100. @default 70 */
27
26
  intentChroma?: number;
28
- /** Merged last, so a brand can still hand-pick anything the seed derives — in practice the shadow tint, which isn't derivable from hue. */
27
+ /** Hand-picked overrides merged last (typically shadow tint). */
29
28
  override?: ThemeOverride;
30
29
  }
31
30
  /**
32
- * Generates a complete {@link Theme} from a {@link BrandSeed}: three-plus
33
- * ramps built from the seed's hues, semantic roles assigned per mode, and
34
- * every WCAG AA pair the contrast test checks (body text 4.5:1, muted text
35
- * and focus ring 3:1 against the page background, inverted text 4.5:1 against
36
- * `primary-600`) driven to threshold by adjusting lightness rather than being
37
- * hand-tuned and hoped for.
38
- *
39
- * Internal on purpose: it is the seam a visual theme builder will call, not a
40
- * public token API — brands that ship today are hand-written theme objects,
41
- * and only `midnight` is generated so far (see `MidnightBrand.ts`).
31
+ * Generate {@link Theme} from {@link BrandSeed}: ramps from hues, semantic
32
+ * roles per mode, WCAG AA pairs enforced to threshold via lightness walk.
33
+ * Internal: visual theme builders call this; hand-written themes are the public API.
42
34
  *
43
35
  * @example
44
36
  * ```ts
@@ -1,121 +1,51 @@
1
1
  /**
2
- * The semantic alias layer: the vocabulary component skins are allowed to name.
2
+ * The semantic alias layer: `var()` indirection for component skins.
3
3
  *
4
- * Why this file exists
5
- * -------------------
6
- * `@skdx/skins` is forbidden from containing a colour literal every colour
7
- * it declares must resolve through a token. But the surface a theme actually
8
- * defines is small: five ramps (`primary`, `neutral`, `success`, `warning`,
9
- * `danger`) and ten `semantic` entries. A button skin needs more than that. It
10
- * needs to say "the background of a pressed primary action" and "the border of
11
- * an invalid field", and neither exists as a theme-authored token.
4
+ * Aliases point at ramp steps and semantic entries themes already define. A
5
+ * theme redeclaring `--skdx-color-primary-600` makes every alias pointing
6
+ * there re-resolve, so adding a theme costs one line per alias, not 38.
12
7
  *
13
- * The naive fix is to add those names to `SemanticColors` and set them in all
14
- * 38 themes. That is 38 files edited per alias added, and every one of those
15
- * edits is a chance for a theme to drift out of step with the others.
8
+ * Aliases are emitted at `:root`, below theme declarations in the cascade,
9
+ * letting a theme override an alias when the derivation is mode-dependent.
10
+ * {@link darkColorAliases} uses this escape hatch for aliases that put ink
11
+ * directly on the page and need opposite ends of the ramp in dark mode.
16
12
  *
17
- * This layer takes the other option: aliases are **pure `var()` indirection**,
18
- * declared once at `:root`, pointing at ramp steps and semantic entries the
19
- * themes already define. No alias holds a colour — it holds the *name of* a
20
- * colour. So when `[data-skdx-theme="nord-dark"]` redeclares
21
- * `--skdx-color-primary-600` at its own higher-specificity selector, every alias
22
- * pointing at that step re-resolves to Nord's value automatically. Adding a
23
- * theme costs nothing here, and adding an alias costs one line rather than 38.
24
- *
25
- * This is also why the aliases are emitted at `:root` rather than inside each
26
- * theme block: they must sit *below* the theme declarations in the cascade so a
27
- * theme can still override an alias outright when the derivation is wrong for
28
- * it. {@link darkColorAliases} is exactly that escape hatch in use: a ramp runs
29
- * light-to-dark in every theme, so the aliases that put ink directly on the
30
- * page need the opposite end in dark mode.
31
- *
32
- * Choosing the ramp step
33
- * ----------------------
34
- * A dark theme's ramp is authored for dark — `NordDark`'s `primary-600` is
35
- * already a step that works as a filled background on a dark surface, the same
36
- * way `DefaultTheme`'s is on a light one. So a single step choice per alias is
37
- * correct in both modes for the *filled* aliases. It does not hold for aliases
38
- * that put ink or a wash directly on the page — see {@link darkColorAliases},
39
- * which was written after measuring 22 of 38 themes failing WCAG contrast.
40
- *
41
- * @see docs/architecture/skin-token-map.md for the per-property mapping table.
13
+ * @see packages/skins/README.md for how a skin consumes these aliases.
42
14
  */
43
15
  /**
44
- * Every alias, as `[name, value]` pairs where `value` is always a `var()`
45
- * reference never a literal. Grouped by the question a skin author asks.
46
- *
47
- * Kept as data rather than a hand-written CSS string so
48
- * `aliases.test.ts` can assert the no-literal rule mechanically over the whole
49
- * set, which is the only thing standing between this file and the exact class
50
- * of drift the skins package's Stylelint rule exists to prevent.
16
+ * Alias entries as `[name, value]` pairs, where `value` is always a `var()` reference.
17
+ * Kept as data so `aliases.test.ts` can assert the no-literal rule.
51
18
  */
52
19
  export declare const colorAliases: ReadonlyArray<readonly [string, string]>;
53
20
  /**
54
- * The aliases a dark theme re-points, and what it re-points them to.
55
- *
56
- * Why this exists
57
- * ---------------
58
- * The base table above picks one ramp step per alias and claims that is correct
59
- * in both modes. For most aliases it is: a theme authors its ramp for its own
60
- * mode, so `primary-600` is a usable filled background whichever way the page
61
- * faces.
62
- *
63
- * It is *not* true for the aliases that put ink directly on the page. A ramp
64
- * runs light at 50 to dark at 950 in every theme, dark ones included — that is
65
- * what makes a ramp a ramp. So `--skdx-color-text-danger: danger-700` is dark
66
- * red: correct on a white page, and nearly invisible on a charcoal one. The
67
- * same applies to every "wash + dark ink" status pairing, and to the neutral
68
- * fills (`surface-sunken`, `track`, `skeleton`) that assume the page is lighter
69
- * than they are.
70
- *
71
- * Measured before writing this: 22 of the 38 themes had at least one contrast
72
- * failure, every one of them a dark theme, and every failure in this list.
73
- * Input text sat at 1.07:1 and the tooltip at 1.00:1.
74
- *
75
- * The fix uses the escape hatch the base table was designed around — a theme
76
- * may override an alias, because `[data-skdx-theme="…"]` outranks `:root`. These
77
- * overrides are emitted automatically for every theme whose `mode` is `'dark'`,
78
- * so the cost stays "one line per alias" rather than "one edit per theme", and
79
- * a new dark theme is correct the day it lands without anyone remembering this
80
- * file exists.
81
- *
82
- * Steps mirror around the middle of the ramp: 700 → 300, 800 → 200, 50 → 950.
83
- * That keeps the light and dark treatments the same *distance* from their
84
- * background rather than merely both legible.
21
+ * Dark-mode alias overrides. Base table picks one ramp step per alias; it fails
22
+ * for aliases putting ink directly on the page (ramp runs 50–950 in all themes,
23
+ * so dark-page inks become invisible). These overrides automatically emit for
24
+ * themes where `mode` is `'dark'`. Steps mirror around ramp center: 700 → 300,
25
+ * keeping equal distance from background.
85
26
  */
86
27
  export declare const darkColorAliases: ReadonlyArray<readonly [string, string]>;
87
28
  /**
88
- * Renders {@link darkColorAliases} at `selector`, for a theme whose mode is dark.
89
- *
90
- * @param selector - The theme's own selector, e.g. `'[data-skdx-theme="nord-dark"]'`.
29
+ * Renders {@link darkColorAliases} at the theme selector.
30
+ * @param selector - Theme selector, e.g. `'[data-skdx-theme="nord-dark"]'`.
91
31
  * @public
92
32
  */
93
33
  export declare function darkAliasesToCss(selector: string): string;
94
34
  /**
95
- * Renders {@link colorAliases} as a `:root` rule block.
96
- *
97
- * Emitted *after* `foundationToCss()` and *before* the theme blocks in
98
- * `@skdx/tokens/css`. Order matters in one direction only: an alias must be
99
- * able to be overridden by a theme, and `:root` loses to
100
- * `[data-skdx-theme="…"]` on specificity regardless of source order, so the
101
- * position here is for readability rather than correctness.
102
- *
103
- * @returns A CSS string, e.g. `':root {\n --skdx-color-action-primary-bg: var(--skdx-color-primary-600);\n …\n}\n'`.
35
+ * Renders {@link colorAliases} as a `:root` rule block. `:root` always loses
36
+ * to `[data-skdx-theme="…"]` on specificity.
104
37
  *
38
+ * @returns CSS string; emitted after `foundationToCss()` and before theme blocks.
105
39
  * @example
106
40
  * ```ts
107
41
  * import { foundationToCss, aliasesToCss } from '@skdx/tokens';
108
- *
109
42
  * fs.writeFileSync('tokens.css', foundationToCss() + aliasesToCss());
110
43
  * ```
111
- *
112
44
  * @public
113
45
  */
114
46
  export declare function aliasesToCss(): string;
115
47
  /**
116
- * {@link colorAliases} as a plain object, for consumers applying tokens through
117
- * JS rather than a stylesheet (the alias counterpart to `themeToCssVars`).
118
- *
48
+ * {@link colorAliases} as a plain object for JS consumers (counterpart to `themeToCssVars`).
119
49
  * @public
120
50
  */
121
51
  export declare function aliasesToCssVars(): Record<string, string>;