@adea-ai/themes 0.4.0 → 0.4.1

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 (69) hide show
  1. package/dist/accents.d.ts +150 -0
  2. package/dist/accents.d.ts.map +1 -0
  3. package/dist/accents.js +205 -0
  4. package/dist/accents.js.map +1 -0
  5. package/dist/adapters/base24.d.ts +117 -0
  6. package/dist/adapters/base24.d.ts.map +1 -0
  7. package/dist/adapters/base24.js +313 -0
  8. package/dist/adapters/base24.js.map +1 -0
  9. package/dist/adapters/css.d.ts +68 -0
  10. package/dist/adapters/css.d.ts.map +1 -0
  11. package/dist/adapters/css.js +107 -0
  12. package/dist/adapters/css.js.map +1 -0
  13. package/dist/adapters/shadcn.d.ts +51 -0
  14. package/dist/adapters/shadcn.d.ts.map +1 -0
  15. package/dist/adapters/shadcn.js +120 -0
  16. package/dist/adapters/shadcn.js.map +1 -0
  17. package/dist/adapters/shiki.d.ts +60 -0
  18. package/dist/adapters/shiki.d.ts.map +1 -0
  19. package/dist/adapters/shiki.js +139 -0
  20. package/dist/adapters/shiki.js.map +1 -0
  21. package/dist/adapters/tailwind.d.ts +35 -0
  22. package/dist/adapters/tailwind.d.ts.map +1 -0
  23. package/dist/adapters/tailwind.js +58 -0
  24. package/dist/adapters/tailwind.js.map +1 -0
  25. package/dist/adapters/xterm.d.ts +64 -0
  26. package/dist/adapters/xterm.d.ts.map +1 -0
  27. package/dist/adapters/xterm.js +112 -0
  28. package/dist/adapters/xterm.js.map +1 -0
  29. package/dist/catalogue.d.ts +66 -0
  30. package/dist/catalogue.d.ts.map +1 -0
  31. package/dist/catalogue.js +110 -0
  32. package/dist/catalogue.js.map +1 -0
  33. package/dist/derive.d.ts +89 -0
  34. package/dist/derive.d.ts.map +1 -0
  35. package/dist/derive.js +172 -0
  36. package/dist/derive.js.map +1 -0
  37. package/dist/generated/schemes.d.ts +16 -0
  38. package/dist/generated/schemes.d.ts.map +1 -0
  39. package/dist/generated/schemes.js +880 -0
  40. package/dist/generated/schemes.js.map +1 -0
  41. package/dist/generated/themes.d.ts +11 -0
  42. package/dist/generated/themes.d.ts.map +1 -0
  43. package/dist/generated/themes.js +1658 -0
  44. package/dist/generated/themes.js.map +1 -0
  45. package/dist/index.d.ts +69 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +59 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/normalize.d.ts +192 -0
  50. package/dist/normalize.d.ts.map +1 -0
  51. package/dist/normalize.js +958 -0
  52. package/dist/normalize.js.map +1 -0
  53. package/dist/oklch.d.ts +141 -0
  54. package/dist/oklch.d.ts.map +1 -0
  55. package/dist/oklch.js +311 -0
  56. package/dist/oklch.js.map +1 -0
  57. package/dist/schema.d.ts +178 -0
  58. package/dist/schema.d.ts.map +1 -0
  59. package/dist/schema.js +69 -0
  60. package/dist/schema.js.map +1 -0
  61. package/dist/sources.d.ts +296 -0
  62. package/dist/sources.d.ts.map +1 -0
  63. package/dist/sources.js +634 -0
  64. package/dist/sources.js.map +1 -0
  65. package/dist/validate.d.ts +121 -0
  66. package/dist/validate.d.ts.map +1 -0
  67. package/dist/validate.js +255 -0
  68. package/dist/validate.js.map +1 -0
  69. package/package.json +2 -1
@@ -0,0 +1,150 @@
1
+ /**
2
+ * The accent axis.
3
+ *
4
+ * A theme has one interactive colour — its primary — and the accent axis lets a
5
+ * user replace it without changing the theme. That is a different question from
6
+ * "which palette do you want": a user may like Catppuccin's surfaces and still want
7
+ * a violet primary, and a product may ship a brand colour that has to survive every
8
+ * theme in the catalogue.
9
+ *
10
+ * ## Why the presets live here
11
+ *
12
+ * They are colour data with a light/dark pair per preset — structurally the same
13
+ * thing as a theme's primary, and the last colour a consumer should have to author
14
+ * itself. Keeping them in a consumer meant two things that must agree lived in two
15
+ * places: the preset list, and the CSS blocks generated from it. They were written
16
+ * by hand in both, and they drifted — the generated default moved its hover *toward*
17
+ * the canvas while every hand-written accent moved *away*, so the default primary
18
+ * button hovered backwards and picking any accent silently fixed it.
19
+ *
20
+ * Here the values and the derivation are one module, so a consumer emits both from
21
+ * the same rule and cannot produce that disagreement.
22
+ *
23
+ * ## The hover rule
24
+ *
25
+ * A hovered primary moves **away from the canvas**, which is what makes it read as
26
+ * hovered rather than as a second, slightly different colour.
27
+ *
28
+ * Two rules were tried here before this one, and both are worth recording because
29
+ * each looks right until it is measured:
30
+ *
31
+ * - **Toward `--background`** — what the consumer used to do. Inverted in both
32
+ * appearances: it moves the button toward the page it sits on, so a hovered button
33
+ * recedes.
34
+ * - **Toward `--foreground`** — correct in principle, since the foreground is
35
+ * normally away from the canvas, and wrong in practice: a dark theme's foreground
36
+ * is mid-lightness (`0.79` in the default), so an accent lighter than that — the
37
+ * dark green is `0.80` — moves *toward* the canvas by a hair.
38
+ * - **Toward white or black** — always the right direction, but a *proportional*
39
+ * step: a mid-lightness light accent moves ~0.10 and a pale dark accent ~0.03, so
40
+ * the same rule gives one appearance a hover twice as strong as the other's.
41
+ *
42
+ * A uniform step needs a resolved value, which is why {@link primaryHover} returns
43
+ * one and why the tint below can stay an expression. `shiftLightness` is what keeps
44
+ * the step uniform *and* the hue intact — a mix toward a neutral cannot do both.
45
+ */
46
+ import type { ThemeAppearance } from './schema';
47
+ /** One accent preset: a named primary, per appearance. */
48
+ export type AccentPreset = {
49
+ /** The `data-accent` value. */
50
+ id: string;
51
+ label: string;
52
+ /** What the preset is for, in a gallery or a picker. */
53
+ description: string;
54
+ /** The accent as it appears on a light theme. */
55
+ light: string;
56
+ /** The accent as it appears on a dark theme. */
57
+ dark: string;
58
+ };
59
+ /**
60
+ * The presets.
61
+ *
62
+ * Each is a pair rather than one colour, because the same accent cannot be one
63
+ * value across both appearances: a violet that reads as vivid on a dark canvas is
64
+ * muddy on a light one, and the deep form that works on light is dull on dark. The
65
+ * pairs below are chosen so each appearance gets the vibrancy the other's value
66
+ * would lose.
67
+ */
68
+ export declare const ACCENTS: readonly AccentPreset[];
69
+ /** The accent ids, for validating a stored preference without loading the data. */
70
+ export declare const ACCENT_IDS: readonly string[];
71
+ /** Look a preset up by id. */
72
+ export declare function getAccent(id: string): AccentPreset | undefined;
73
+ /** The accent's value for one appearance. */
74
+ export declare function accentValue(preset: AccentPreset, appearance: ThemeAppearance): string;
75
+ /**
76
+ * The label to draw on an accent fill: black or white, whichever wins on contrast.
77
+ *
78
+ * Measured rather than conventional. The usual convention is "white on a coloured
79
+ * fill", which is wrong for the bright half of this set — white on `#a78bfa` is
80
+ * about 2.1:1, and black on it is about 9.9:1. That is why the same accent carries a
81
+ * black label in dark mode and a white one in light: the pair is designed so the
82
+ * polarity flips, and the label has to flip with it.
83
+ */
84
+ export declare function accentForeground(accent: string): string;
85
+ /** The contrast the chosen label achieves, for validation and reporting. */
86
+ export declare function accentForegroundContrast(accent: string): number;
87
+ /**
88
+ * How far a hovered primary moves along lightness.
89
+ *
90
+ * A **uniform step**, not a proportional one, and the difference matters. Mixing a
91
+ * fixed share toward white or black moves an accent by a share of its headroom, so
92
+ * the same rule gives a mid-lightness light accent a step of ~0.10 and a pale dark
93
+ * accent one of ~0.03 — a hover that feels twice as strong in one appearance as the
94
+ * other, and nearly invisible on the palest accent.
95
+ *
96
+ * 0.05 is the step this system's accents were already hand-written with, so the
97
+ * accents keep the appearance they had while the rule becomes one value.
98
+ */
99
+ export declare const ACCENT_HOVER_STEP = 0.05;
100
+ /**
101
+ * The hovered primary, as a resolved colour.
102
+ *
103
+ * Resolved rather than expressed as a `color-mix()`, because a uniform step cannot
104
+ * be written as a mix — see {@link ACCENT_HOVER_STEP}. That means it does **not**
105
+ * follow `--primary` on its own, so a consumer that applies themes at runtime has to
106
+ * write this token too; the alternative is a hover left over from the previous
107
+ * theme's primary. `themeCssVariables` includes it for that reason.
108
+ *
109
+ * The direction is away from the canvas: darker on a light theme, lighter on a dark
110
+ * one. `shiftLightness` keeps chroma and hue and damps chroma near the extremes, so a
111
+ * hovered accent stays the same colour rather than washing out toward grey.
112
+ */
113
+ export declare function primaryHover(primary: string, appearance: ThemeAppearance): string;
114
+ /**
115
+ * How much of the primary a tint carries, per appearance.
116
+ *
117
+ * Not one value, because a tint's visibility depends on what it is tinted onto: the
118
+ * same alpha over a near-black surface reads as nothing, and over a near-white one
119
+ * reads as a wash. The dark value is the larger for exactly that reason.
120
+ *
121
+ * This one *is* a `color-mix()`, because a tint is a share of the primary by nature
122
+ * and follows `--primary` correctly at runtime.
123
+ */
124
+ export declare const ACCENT_SUBTLE_ALPHA: Readonly<Record<ThemeAppearance, number>>;
125
+ /**
126
+ * The tint expression, for any primary.
127
+ *
128
+ * Takes the appearance because the alpha is appearance-dependent — see
129
+ * {@link ACCENT_SUBTLE_ALPHA}.
130
+ */
131
+ export declare function primarySubtleCss(appearance: ThemeAppearance, primaryVariable?: string): string;
132
+ /**
133
+ * The five declarations an accent sets, as CSS values.
134
+ *
135
+ * `primary`, `primaryForeground` and `ring` are resolved colours; `primaryHover` and
136
+ * `primarySubtle` are expressions, for the reason in the module comment. A consumer
137
+ * writes them as custom properties and the rules hold for every theme and every
138
+ * accent at once.
139
+ */
140
+ export type AccentRoles = {
141
+ primary: string;
142
+ primaryForeground: string;
143
+ primaryHover: string;
144
+ primarySubtle: string;
145
+ ring: string;
146
+ };
147
+ export declare function accentRoles(preset: AccentPreset, appearance: ThemeAppearance,
148
+ /** The property the subtle tint is built from. A consumer may pass its own alias. */
149
+ primaryVariable?: string): AccentRoles;
150
+ //# sourceMappingURL=accents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accents.d.ts","sourceRoot":"","sources":["../src/accents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI/C,0DAA0D;AAC1D,MAAM,MAAM,YAAY,GAAG;IACzB,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAA;IACnB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,EAAE,SAAS,YAAY,EA2CzC,CAAA;AAEF,mFAAmF;AACnF,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAAsD,CAAA;AAE9F,8BAA8B;AAC9B,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE9D;AAED,6CAA6C;AAC7C,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,GAAG,MAAM,CAErF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED,4EAA4E;AAC5E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,GAAG,MAAM,CAKjF;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAGxE,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,eAAe,EAAE,eAAe,SAAc,GAAG,MAAM,CAEnG;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,eAAe;AAC3B,qFAAqF;AACrF,eAAe,SAAc,GAC5B,WAAW,CAYb"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * The accent axis.
3
+ *
4
+ * A theme has one interactive colour — its primary — and the accent axis lets a
5
+ * user replace it without changing the theme. That is a different question from
6
+ * "which palette do you want": a user may like Catppuccin's surfaces and still want
7
+ * a violet primary, and a product may ship a brand colour that has to survive every
8
+ * theme in the catalogue.
9
+ *
10
+ * ## Why the presets live here
11
+ *
12
+ * They are colour data with a light/dark pair per preset — structurally the same
13
+ * thing as a theme's primary, and the last colour a consumer should have to author
14
+ * itself. Keeping them in a consumer meant two things that must agree lived in two
15
+ * places: the preset list, and the CSS blocks generated from it. They were written
16
+ * by hand in both, and they drifted — the generated default moved its hover *toward*
17
+ * the canvas while every hand-written accent moved *away*, so the default primary
18
+ * button hovered backwards and picking any accent silently fixed it.
19
+ *
20
+ * Here the values and the derivation are one module, so a consumer emits both from
21
+ * the same rule and cannot produce that disagreement.
22
+ *
23
+ * ## The hover rule
24
+ *
25
+ * A hovered primary moves **away from the canvas**, which is what makes it read as
26
+ * hovered rather than as a second, slightly different colour.
27
+ *
28
+ * Two rules were tried here before this one, and both are worth recording because
29
+ * each looks right until it is measured:
30
+ *
31
+ * - **Toward `--background`** — what the consumer used to do. Inverted in both
32
+ * appearances: it moves the button toward the page it sits on, so a hovered button
33
+ * recedes.
34
+ * - **Toward `--foreground`** — correct in principle, since the foreground is
35
+ * normally away from the canvas, and wrong in practice: a dark theme's foreground
36
+ * is mid-lightness (`0.79` in the default), so an accent lighter than that — the
37
+ * dark green is `0.80` — moves *toward* the canvas by a hair.
38
+ * - **Toward white or black** — always the right direction, but a *proportional*
39
+ * step: a mid-lightness light accent moves ~0.10 and a pale dark accent ~0.03, so
40
+ * the same rule gives one appearance a hover twice as strong as the other's.
41
+ *
42
+ * A uniform step needs a resolved value, which is why {@link primaryHover} returns
43
+ * one and why the tint below can stay an expression. `shiftLightness` is what keeps
44
+ * the step uniform *and* the hue intact — a mix toward a neutral cannot do both.
45
+ */
46
+ import { contrastRatio, formatOklch, parseColor, shiftLightness } from './oklch';
47
+ /**
48
+ * The presets.
49
+ *
50
+ * Each is a pair rather than one colour, because the same accent cannot be one
51
+ * value across both appearances: a violet that reads as vivid on a dark canvas is
52
+ * muddy on a light one, and the deep form that works on light is dull on dark. The
53
+ * pairs below are chosen so each appearance gets the vibrancy the other's value
54
+ * would lose.
55
+ */
56
+ export const ACCENTS = Object.freeze([
57
+ {
58
+ id: 'violet',
59
+ label: 'Violet',
60
+ description: 'The default brand accent.',
61
+ light: '#6d28d9',
62
+ dark: '#a78bfa',
63
+ },
64
+ {
65
+ id: 'blue',
66
+ label: 'Blue',
67
+ description: 'Cool and conventional. Reads as informational.',
68
+ light: '#2563eb',
69
+ dark: '#60a5fa',
70
+ },
71
+ {
72
+ id: 'green',
73
+ label: 'Green',
74
+ description: 'Reads as confirmatory, which competes with the success status.',
75
+ light: '#15803d',
76
+ dark: '#4ade80',
77
+ },
78
+ {
79
+ id: 'amber',
80
+ label: 'Amber',
81
+ description: 'Warm and attention-drawing. Competes with the warning status.',
82
+ light: '#b45309',
83
+ dark: '#fbbf24',
84
+ },
85
+ {
86
+ id: 'cyan',
87
+ label: 'Cyan',
88
+ description: 'Quiet and technical. The least saturated of the set.',
89
+ light: '#0e7490',
90
+ dark: '#22d3ee',
91
+ },
92
+ {
93
+ id: 'pink',
94
+ label: 'Pink',
95
+ description: 'The loudest of the set. Use where the accent is decorative.',
96
+ light: '#be185d',
97
+ dark: '#f472b6',
98
+ },
99
+ ]);
100
+ /** The accent ids, for validating a stored preference without loading the data. */
101
+ export const ACCENT_IDS = Object.freeze(ACCENTS.map((accent) => accent.id));
102
+ /** Look a preset up by id. */
103
+ export function getAccent(id) {
104
+ return ACCENTS.find((accent) => accent.id === id);
105
+ }
106
+ /** The accent's value for one appearance. */
107
+ export function accentValue(preset, appearance) {
108
+ return appearance === 'light' ? preset.light : preset.dark;
109
+ }
110
+ /**
111
+ * The label to draw on an accent fill: black or white, whichever wins on contrast.
112
+ *
113
+ * Measured rather than conventional. The usual convention is "white on a coloured
114
+ * fill", which is wrong for the bright half of this set — white on `#a78bfa` is
115
+ * about 2.1:1, and black on it is about 9.9:1. That is why the same accent carries a
116
+ * black label in dark mode and a white one in light: the pair is designed so the
117
+ * polarity flips, and the label has to flip with it.
118
+ */
119
+ export function accentForeground(accent) {
120
+ const fill = parseColor(accent);
121
+ if (!fill)
122
+ return 'oklch(1 0 0)';
123
+ const black = { l: 0, c: 0, h: 0 };
124
+ const white = { l: 1, c: 0, h: 0 };
125
+ const best = contrastRatio(black, fill) >= contrastRatio(white, fill) ? black : white;
126
+ return formatOklch(best);
127
+ }
128
+ /** The contrast the chosen label achieves, for validation and reporting. */
129
+ export function accentForegroundContrast(accent) {
130
+ const fill = parseColor(accent);
131
+ if (!fill)
132
+ return 0;
133
+ return contrastRatio(parseColor(accentForeground(accent)), fill);
134
+ }
135
+ /**
136
+ * How far a hovered primary moves along lightness.
137
+ *
138
+ * A **uniform step**, not a proportional one, and the difference matters. Mixing a
139
+ * fixed share toward white or black moves an accent by a share of its headroom, so
140
+ * the same rule gives a mid-lightness light accent a step of ~0.10 and a pale dark
141
+ * accent one of ~0.03 — a hover that feels twice as strong in one appearance as the
142
+ * other, and nearly invisible on the palest accent.
143
+ *
144
+ * 0.05 is the step this system's accents were already hand-written with, so the
145
+ * accents keep the appearance they had while the rule becomes one value.
146
+ */
147
+ export const ACCENT_HOVER_STEP = 0.05;
148
+ /**
149
+ * The hovered primary, as a resolved colour.
150
+ *
151
+ * Resolved rather than expressed as a `color-mix()`, because a uniform step cannot
152
+ * be written as a mix — see {@link ACCENT_HOVER_STEP}. That means it does **not**
153
+ * follow `--primary` on its own, so a consumer that applies themes at runtime has to
154
+ * write this token too; the alternative is a hover left over from the previous
155
+ * theme's primary. `themeCssVariables` includes it for that reason.
156
+ *
157
+ * The direction is away from the canvas: darker on a light theme, lighter on a dark
158
+ * one. `shiftLightness` keeps chroma and hue and damps chroma near the extremes, so a
159
+ * hovered accent stays the same colour rather than washing out toward grey.
160
+ */
161
+ export function primaryHover(primary, appearance) {
162
+ const parsed = parseColor(primary);
163
+ if (!parsed)
164
+ return primary;
165
+ const delta = appearance === 'light' ? -ACCENT_HOVER_STEP : ACCENT_HOVER_STEP;
166
+ return formatOklch(shiftLightness(parsed, delta));
167
+ }
168
+ /**
169
+ * How much of the primary a tint carries, per appearance.
170
+ *
171
+ * Not one value, because a tint's visibility depends on what it is tinted onto: the
172
+ * same alpha over a near-black surface reads as nothing, and over a near-white one
173
+ * reads as a wash. The dark value is the larger for exactly that reason.
174
+ *
175
+ * This one *is* a `color-mix()`, because a tint is a share of the primary by nature
176
+ * and follows `--primary` correctly at runtime.
177
+ */
178
+ export const ACCENT_SUBTLE_ALPHA = Object.freeze({
179
+ light: 10,
180
+ dark: 16,
181
+ });
182
+ /**
183
+ * The tint expression, for any primary.
184
+ *
185
+ * Takes the appearance because the alpha is appearance-dependent — see
186
+ * {@link ACCENT_SUBTLE_ALPHA}.
187
+ */
188
+ export function primarySubtleCss(appearance, primaryVariable = '--primary') {
189
+ return `color-mix(in oklch, var(${primaryVariable}) ${ACCENT_SUBTLE_ALPHA[appearance]}%, transparent)`;
190
+ }
191
+ export function accentRoles(preset, appearance,
192
+ /** The property the subtle tint is built from. A consumer may pass its own alias. */
193
+ primaryVariable = '--primary') {
194
+ const value = accentValue(preset, appearance);
195
+ const parsed = parseColor(value);
196
+ const primary = parsed ? formatOklch(parsed) : value;
197
+ return {
198
+ primary,
199
+ primaryForeground: accentForeground(value),
200
+ primaryHover: primaryHover(value, appearance),
201
+ primarySubtle: primarySubtleCss(appearance, primaryVariable),
202
+ ring: primary,
203
+ };
204
+ }
205
+ //# sourceMappingURL=accents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accents.js","sourceRoot":"","sources":["../src/accents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The Base24 bridge.
3
+ *
4
+ * Base24 is the interchange format this package speaks to the outside world, in
5
+ * both directions. Importing is the normalizer's first step for every theme that
6
+ * is not authored here ({@link "./normalize"}); exporting is how a theme reaches a
7
+ * terminal, a tmux theme, or another tool that has never heard of Adea.
8
+ *
9
+ * ## The slot order is not the ANSI order
10
+ *
11
+ * Base24's `base12`–`base17` are *bright red, bright yellow, bright green, bright
12
+ * cyan, bright blue, bright magenta* — the order Base16 needed to keep its ramps
13
+ * monotonic, not the ANSI order of yellow before green. Reading them positionally
14
+ * as ANSI 1–6 silently swaps green and yellow and blue and cyan, which is the kind
15
+ * of mistake that survives review because the theme still *looks* like itself.
16
+ * {@link BASE24_TO_ANSI} names the mapping explicitly so it cannot be inferred
17
+ * wrongly.
18
+ *
19
+ * ## The two slots with no Adea role
20
+ *
21
+ * `base09` (orange) and `base0F` (brown) have no counterpart in the canonical
22
+ * schema: Adea has no "constant" or "deprecated" role, because a UI does not. On
23
+ * export they are re-derived from `red` and `yellow` by a fixed rotation, and
24
+ * {@link AdeaThemeRecord} carries the vendored schemes separately for callers who
25
+ * need the originals byte-for-byte. Round-tripping is therefore lossless for every
26
+ * role Adea models, and explicitly approximate for the two it does not — rather
27
+ * than silently lossy, which is what an unnamed slot would have been.
28
+ */
29
+ import type { AdeaTheme, AdeaThemeColors } from '../schema';
30
+ import type { Oklch } from '../oklch';
31
+ /** The twenty-four Base24 slots, in the order the specification lists them. */
32
+ export declare const BASE24_SLOTS: readonly ["base00", "base01", "base02", "base03", "base04", "base05", "base06", "base07", "base08", "base09", "base0A", "base0B", "base0C", "base0D", "base0E", "base0F", "base10", "base11", "base12", "base13", "base14", "base15", "base16", "base17"];
33
+ export type Base24Slot = (typeof BASE24_SLOTS)[number];
34
+ /** A Base24 palette. Values are colours in any notation {@link parseColor} accepts. */
35
+ export type Base24Palette = Readonly<Record<Base24Slot, string>>;
36
+ /** A Base24 scheme: the palette plus the metadata the specification defines. */
37
+ export interface Base24Scheme {
38
+ system: 'base24';
39
+ name: string;
40
+ author: string;
41
+ variant: 'dark' | 'light';
42
+ palette: Base24Palette;
43
+ }
44
+ /**
45
+ * What each slot means, in the specification's own terms.
46
+ *
47
+ * Kept as data because the normalizer reads it rather than hard-coding slot names
48
+ * in its logic, and because it is the documentation a reader needs to check that
49
+ * the mapping is right.
50
+ */
51
+ export declare const BASE24_SLOT_MEANING: Readonly<Record<Base24Slot, string>>;
52
+ /**
53
+ * Base24 slot → ANSI role.
54
+ *
55
+ * `black`, `white` and `brightBlack` are absent because Base24 does not name them:
56
+ * the background and foreground slots do double duty. The normalizer decides those
57
+ * three; see its `ANSI_FROM_BASE24` note for why the choice is the one it is.
58
+ */
59
+ export declare const BASE24_TO_ANSI: Readonly<{
60
+ readonly red: "base08";
61
+ readonly yellow: "base0A";
62
+ readonly green: "base0B";
63
+ readonly cyan: "base0C";
64
+ readonly blue: "base0D";
65
+ readonly magenta: "base0E";
66
+ readonly brightRed: "base12";
67
+ readonly brightYellow: "base13";
68
+ readonly brightGreen: "base14";
69
+ readonly brightCyan: "base15";
70
+ readonly brightBlue: "base16";
71
+ readonly brightMagenta: "base17";
72
+ }>;
73
+ /** The inverse of {@link BASE24_TO_ANSI}, for export. */
74
+ export declare const ANSI_TO_BASE24: Readonly<Record<string, Base24Slot>>;
75
+ /**
76
+ * How each semantic role is written back to a Base24 slot on export.
77
+ *
78
+ * The choices are not arbitrary. `base01` receives `black` rather than the
79
+ * background because an ANSI black that equals the background is invisible as
80
+ * foreground text — which is precisely the defect the import side documents. The
81
+ * surface ladder has no Base24 slot at all, so it is deliberately absent here:
82
+ * Base24 cannot express it, and pretending otherwise by packing four rungs into
83
+ * `base01`/`base02` would make the export lie about what it preserves.
84
+ */
85
+ export declare const THEME_TO_BASE24: Readonly<Record<keyof AdeaThemeColors, Base24Slot | undefined>>;
86
+ /** Thrown when a palette is missing a slot or holds an unparseable colour. */
87
+ export declare class Base24ParseError extends Error {
88
+ readonly slot: string;
89
+ constructor(message: string, slot: string);
90
+ }
91
+ /** Parses every slot of a palette into OKLCH, or throws naming the offending slot. */
92
+ export declare function parseBase24Palette(palette: Base24Palette): Record<Base24Slot, Oklch>;
93
+ /**
94
+ * Writes a theme back to Base24.
95
+ *
96
+ * `base09` and `base0F` are synthesised — see this module's header. `base10` and
97
+ * `base11` are the two rungs below `base00`, which is what the specification
98
+ * defines them as and what a terminal needs in order to draw a black that is
99
+ * darker than the background.
100
+ */
101
+ export declare function toBase24(theme: AdeaTheme, options?: {
102
+ author?: string;
103
+ name?: string;
104
+ }): Base24Scheme;
105
+ /** Serialises a scheme to the YAML dialect Base24 schemes are published in. */
106
+ export declare function formatBase24Scheme(scheme: Base24Scheme): string;
107
+ /**
108
+ * Reads the YAML dialect Base24 schemes are published in.
109
+ *
110
+ * Hand-written rather than pulled from a YAML library: the format is a fixed set
111
+ * of scalar keys, the package has no runtime dependencies and no build-time
112
+ * dependencies beyond the TypeScript compiler, and a general parser would accept
113
+ * documents this bridge cannot actually honour. Anything outside the specification
114
+ * is rejected loudly instead of being parsed into a half-scheme.
115
+ */
116
+ export declare function parseBase24Scheme(source: string): Base24Scheme;
117
+ //# sourceMappingURL=base24.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base24.d.ts","sourceRoot":"","sources":["../../src/adapters/base24.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAY,SAAS,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAGrC,+EAA+E;AAC/E,eAAO,MAAM,YAAY,2PAyBf,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtD,uFAAuF;AACvF,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;AAEhE,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,QAAQ,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;IACzB,OAAO,EAAE,aAAa,CAAA;CACvB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAyBnE,CAAA;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;EAasC,CAAA;AAEjE,yDAAyD;AACzD,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAI/D,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,eAAe,EAAE,UAAU,GAAG,SAAS,CAAC,CAmBxF,CAAA;AAEJ,8EAA8E;AAC9E,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBADrB,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,MAAM;CAKxB;AAED,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAcpF;AAcD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,YAAY,CAgDd;AAQD,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAU/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAwD9D"}