@kanzo-tech/theme 0.0.1-alpha

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 (44) hide show
  1. package/README.md +130 -0
  2. package/dist/index.d.ts +427 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +269 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/ink.d.ts +52 -0
  7. package/dist/ink.d.ts.map +1 -0
  8. package/dist/obligations.d.ts +45 -0
  9. package/dist/obligations.d.ts.map +1 -0
  10. package/dist/sections.d.ts +304 -0
  11. package/dist/sections.d.ts.map +1 -0
  12. package/package.json +43 -0
  13. package/theme-data.json +311 -0
  14. package/themes/acid.css +54 -0
  15. package/themes/bank-dark.css +64 -0
  16. package/themes/bank-private-dark.css +64 -0
  17. package/themes/bank-private.css +63 -0
  18. package/themes/bank.css +63 -0
  19. package/themes/catppuccin-latte-dark.css +64 -0
  20. package/themes/catppuccin-latte.css +63 -0
  21. package/themes/catppuccin-mocha-dark.css +64 -0
  22. package/themes/catppuccin-mocha.css +63 -0
  23. package/themes/cmyk.css +54 -0
  24. package/themes/coffee.css +54 -0
  25. package/themes/cyberpunk.css +54 -0
  26. package/themes/dim.css +54 -0
  27. package/themes/dracula-dark.css +64 -0
  28. package/themes/dracula.css +63 -0
  29. package/themes/forest.css +54 -0
  30. package/themes/kanzo-dark.css +73 -0
  31. package/themes/kanzo.css +70 -0
  32. package/themes/lemonade.css +54 -0
  33. package/themes/lofi.css +54 -0
  34. package/themes/luxury.css +54 -0
  35. package/themes/monochrome-dark.css +64 -0
  36. package/themes/monochrome.css +63 -0
  37. package/themes/night.css +54 -0
  38. package/themes/nord-dark.css +64 -0
  39. package/themes/nord.css +63 -0
  40. package/themes/sunset.css +54 -0
  41. package/themes/synthwave.css +54 -0
  42. package/themes/wireframe.css +54 -0
  43. package/themes.css +92 -0
  44. package/tokens.css +311 -0
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Sections: appearance vocabulary contributed by the package that owns it.
3
+ *
4
+ * The core never learns that a section exists. It stores sections **opaquely**, resolves a token by
5
+ * hierarchical fallback, and validates against a manifest the owning package hands it. Contributing
6
+ * is *using* a name, not registering a type here — which is what keeps the one-way door shut
7
+ * structurally rather than by discipline: `@kanzo-tech/theme` gains no reference to
8
+ * `@kanzo-tech/graph`, and `boundary.test.ts` keeps passing because there is nothing to import.
9
+ *
10
+ * ## Resolution is Neovim's, validation is not
11
+ *
12
+ * A dotted name falls back to its parent: `--graph-point-size-min` → `--point-size-min` → the
13
+ * default the manifest declared. Neovim's highlight groups work exactly this way
14
+ * (`@foo.bar.lang → @foo.bar → @foo`) and it is why a section costs the core nothing.
15
+ *
16
+ * **Neovim pays a price we do not: there, a typo degrades silently to the parent.** Here the
17
+ * manifest *declares* its tokens, so resolution goes by fallback and validation goes against the
18
+ * declaration. That combination — contribute *and* validate — is the part no surveyed system does:
19
+ * VS Code's `contributes.colors` and Emacs contribute without validating the namespace, Vanilla
20
+ * Extract validates completely and therefore cannot have optional sections at all, and StyleX
21
+ * retracted that shape. This is unmapped ground, and `sections.test.ts` says what it cannot prove.
22
+ *
23
+ * ## A default may be derived, and that is what makes white-label flow
24
+ *
25
+ * VS Code spells derived defaults as imperative transforms (`darken`, `transparent`, `oneOf`). Ours
26
+ * is a **CSS value**, which is the same idea with nothing between it and the browser:
27
+ * `var(--primary)` points at what the theme publishes, and `color-mix(in oklab, var(--primary) 20%,
28
+ * transparent)` derives from it. A bank changing its theme moves both — **without the core knowing
29
+ * what a graph is**, and without anyone copying a hex.
30
+ *
31
+ * **It was an object with three shapes** — `{kind:"step"|"alpha", ramp, step}` and
32
+ * `{kind:"role", token}` — declarative against the tenant's *ramps*. Two of the three named a
33
+ * reference tier that no longer exists, and the third was `var()` wearing a wrapper. Collapsing them
34
+ * removed a type that had to be declared structurally in two packages at once, so it also removed
35
+ * the drift between the two declarations.
36
+ *
37
+ * That is why this is not the thing that was refused earlier. Minting a *role* in the core's
38
+ * vocabulary for one consumer is how seventeen level-names happened. A section token lives in the
39
+ * owner's namespace, is declared by the owner, and costs nothing to whoever never installs it.
40
+ */
41
+ export interface SectionTokenDecl {
42
+ /**
43
+ * A CSS value. A literal, a `var()` at what the theme publishes, or a `color-mix()` derived from
44
+ * one — and nothing needs to resolve it but the browser.
45
+ */
46
+ default: string;
47
+ /** What the token is for, in one line. Shown by a panel that lists a section's vocabulary. */
48
+ doc: string;
49
+ }
50
+ /** What every declaration carries, whatever its kind. */
51
+ interface PrefCommon {
52
+ /** The value when nothing else answers. Always a string — see {@link SectionPrefDecl}. */
53
+ default: string;
54
+ /** What the preference does, in one line. Shown by a surface beside the control. */
55
+ doc: string;
56
+ /**
57
+ * What a surface CALLS it. Falls back to the key, which is what every surface used to draw.
58
+ *
59
+ * The options carried labels and the preference did not, so a generic control had a key for a
60
+ * legend: a dock offering the force coefficients announced `link-spring`. A name is authored where
61
+ * the values are, like everything else here — and it is not the `doc`, which is a sentence about
62
+ * what the thing does rather than the two words a control is titled with.
63
+ */
64
+ label?: string;
65
+ /**
66
+ * The stored value is a map keyed by the resolved appearance, not a plain string.
67
+ *
68
+ * One field on the declaration rather than a second table beside it. It is only expressible
69
+ * because appearance resolves *first* — the pre-hydration script has to resolve it to write
70
+ * `.dark` — so by the time anything reads this, the side to index by is known.
71
+ */
72
+ byAppearance?: true;
73
+ /**
74
+ * The attribute to write on `<html>` — **only where CSS has to react.**
75
+ *
76
+ * Most contributed preferences have none. The graph's look is read by JS and pushed into a
77
+ * renderer's config; an editor's font size would want one. Leaving it out is what keeps the
78
+ * pre-hydration script from growing by a line for every optional package a host installs, which is
79
+ * the cost the four core axes pay for having attributes at all.
80
+ */
81
+ attr?: string;
82
+ }
83
+ /** One thing a `choice` may offer. `value` is what is stored; `label` is what a person reads. */
84
+ export interface PrefOption {
85
+ value: string;
86
+ label: string;
87
+ }
88
+ /**
89
+ * Where a choice's options come from, when an author cannot list them.
90
+ *
91
+ * The one thing a TENANT publishes that nobody can know at authoring time: the themes they wrote.
92
+ * Closed on purpose — a source is something the provider already receives and can hand to a
93
+ * resolver, not a hook for a package to fetch from.
94
+ *
95
+ * It was two, `"palettes"` and `"identities"`, while a palette contained brands and a control had to
96
+ * ask which level it was filling. A brand is a theme, so there is one level and one list.
97
+ */
98
+ export type PrefSource = "themes";
99
+ /**
100
+ * A list, or the name of the list's owner.
101
+ *
102
+ * This is the same move {@link SectionTokenDecl} already makes for colour — a **binding** instead of
103
+ * a value — so the vocabulary stays one. It is what `theme` needs: its options are
104
+ * a client's brands, and an author who typed them would be authoring the client's product.
105
+ */
106
+ export type PrefOptions = readonly PrefOption[] | {
107
+ from: PrefSource;
108
+ };
109
+ /** What the host publishes, for the declarations that name a source. */
110
+ export type PrefSources = Partial<Record<PrefSource, readonly PrefOption[]>>;
111
+ /**
112
+ * The options a declaration offers — `null` when it names a source nobody has answered yet.
113
+ *
114
+ * `null` rather than `[]`, and the distinction is load-bearing: "this tenant published nothing",
115
+ * "the host has not wired the prop" and "the document is still being fetched" are indistinguishable
116
+ * from here, and every one of them must leave a stored value alone. An empty list would read as
117
+ * *nothing is legal* and quietly reset a user's brand on the first render before the fetch lands —
118
+ * which is the failure `useRetirement` guards with `options.length > 0` one layer up.
119
+ */
120
+ export declare function prefOptions(decl: SectionPrefDecl, sources?: PrefSources): readonly PrefOption[] | null;
121
+ /**
122
+ * One preference a section offers its user — the half of a manifest the person on the screen decides.
123
+ *
124
+ * **Three kinds, and the set is closed.** A section may offer a value it has measured; it may not
125
+ * offer a text field, and there is deliberately no `custom` escape. That is the same line the colour
126
+ * layer holds one level up — choose among what somebody validated, never author — and it is what
127
+ * lets any surface render any section without knowing which package wrote it.
128
+ *
129
+ * The three arrived together with their call sites rather than ahead of them. `choice` shipped
130
+ * alone and covered the graph's look; the eleven controls it could not express are what asked for
131
+ * the other two — three toggles and two scalars in the graph's Display, six coefficients in its
132
+ * simulation dock, every one of them hand-rolled with its own wiring.
133
+ *
134
+ * **"Follow the system" is an option and not a fourth kind.** It is the option whose value is `""`,
135
+ * and the convention is already load-bearing here: `identity` and `palette` default to `""`, and the
136
+ * write rule removes the attribute at the default — which is exactly what *the OS decides* means in
137
+ * CSS, where there is no third keyword either. Declared as `{ value: "", label: "System" }` it is a
138
+ * thing a control can offer, so getting back to it stops being the panel's `Reset` button's private
139
+ * power.
140
+ *
141
+ * **A value is a string in all three**, and that is a decision rather than an oversight. One storage
142
+ * shape means an unrecognised namespace rides through a write untouched without the core parsing
143
+ * it; and a value that can be written to a `data-*` attribute needs no second spelling on its way
144
+ * out. A renderer parses what its own kind means — `"true"`, `"0.42"` — and the parsing is one
145
+ * place, {@link prefNumber} and {@link prefBoolean}.
146
+ */
147
+ export type SectionPrefDecl =
148
+ /** Pick one of a closed list — or of a list only the tenant can write. */
149
+ (PrefCommon & {
150
+ kind: "choice";
151
+ /** Everything a control may offer, in order. Order is the section's, and a surface keeps it. */
152
+ options: PrefOptions;
153
+ })
154
+ /** On or off. Stored as `"true"` / `"false"`. */
155
+ | (PrefCommon & {
156
+ kind: "toggle";
157
+ })
158
+ /**
159
+ * A number within declared bounds.
160
+ *
161
+ * The bounds are the section's own claim about what it will honour, so a stored value outside them
162
+ * is declined the same way a retired option is: a slider that used to run to 5 and now stops at 3
163
+ * must not paint 5 because storage remembers it.
164
+ */
165
+ | (PrefCommon & {
166
+ kind: "range";
167
+ min: number;
168
+ max: number;
169
+ step: number;
170
+ });
171
+ /** Read a `toggle`'s value. Anything that is not exactly `"true"` is off. */
172
+ export declare const prefBoolean: (value: string) => boolean;
173
+ /** Read a `range`'s value. `NaN` never escapes: a corrupt string answers the declared minimum. */
174
+ export declare function prefNumber(value: string, decl: {
175
+ min: number;
176
+ }): number;
177
+ /**
178
+ * What a tenant may say about a section's choice — **selection, never authorship.**
179
+ *
180
+ * A document may fix a choice or withhold it; it may not invent a value for it. The options are the
181
+ * ones the owning package declared and measured, and a policy picks among them or removes the
182
+ * control. That is the same line the colour half holds — a user chooses among colours somebody
183
+ * validated and never authors one — and it is what stops this field becoming the runtime palette
184
+ * authoring the retired axes exist to prevent.
185
+ */
186
+ export interface SectionPrefPolicy {
187
+ /** Fixed to this value. No control is offered and a stored preference does not apply. */
188
+ pinned?: string;
189
+ /** Not offered. The default applies, and a stored preference is kept but does not apply. */
190
+ hidden?: boolean;
191
+ /** Offered, but starting somewhere other than the manifest says. */
192
+ default?: string;
193
+ }
194
+ /**
195
+ * What a package publishes to contribute a section. Reached by subpath, never imported here.
196
+ *
197
+ * **One manifest carries both halves**, and they are both optional. A package may contribute tokens
198
+ * without preferences (a vocabulary a document decides), preferences without tokens (a choice that
199
+ * paints nothing of its own), or both. Two exports would let a namespace and a version drift apart
200
+ * while describing the same section, and the namespace is the whole of the contract.
201
+ */
202
+ export interface SectionManifest {
203
+ /** The namespace segment. `"graph"` produces `--graph-*`. */
204
+ namespace: string;
205
+ version: number;
206
+ /** Keys are token names **without** the namespace: `"marquee"`, `"point-size-min"`. */
207
+ tokens?: Readonly<Record<string, SectionTokenDecl>>;
208
+ /** Keys are preference names, unqualified: `"look"`. */
209
+ prefs?: Readonly<Record<string, SectionPrefDecl>>;
210
+ }
211
+ /** A tenant's policy for one section, keyed by preference name. */
212
+ export type SectionPolicy = Readonly<Record<string, SectionPrefPolicy>>;
213
+ /** Where a resolved preference came from — a panel says so, and a test asserts on it. */
214
+ export type PrefOrigin = "pinned" | "stored" | "policy" | "default";
215
+ export interface ResolvedPref {
216
+ value: string;
217
+ via: PrefOrigin;
218
+ /** Whether a control should be drawn at all. `false` for pinned and for withheld. */
219
+ offered: boolean;
220
+ }
221
+ /**
222
+ * One chain, most specific first — the sibling of {@link resolveSectionToken}.
223
+ *
224
+ * Writing it as a chain is not decoration: the token half already answers *the first member that
225
+ * answers, and says which one it used*, and a preference resolved by some other order would be a
226
+ * second mechanism wearing the first one's vocabulary.
227
+ *
228
+ * A stored value that is not in `options` is ignored rather than applied. A section's options are
229
+ * the values it has measured; a stale one from a version the package no longer ships is exactly the
230
+ * case where falling back beats honouring what storage happens to hold.
231
+ */
232
+ export declare function resolvePref(decl: SectionPrefDecl, stored: string | undefined, policy?: SectionPrefPolicy,
233
+ /** What the tenant published, for a choice whose options name a source rather than listing them. */
234
+ sources?: PrefSources): ResolvedPref;
235
+ /**
236
+ * Check a section's stored preferences against the manifest that owns it.
237
+ *
238
+ * The preference sibling of {@link validateSection}, and the same argument: a name the manifest
239
+ * never declared is reported rather than resolving to something plausible. What differs is that a
240
+ * preference also has a closed set of legal *values*, so a stored value outside `options` is
241
+ * reported too — `resolvePref` already refuses to apply it, and this is what says so out loud.
242
+ */
243
+ export declare function validatePrefs(manifest: SectionManifest, stored: Readonly<Record<string, string>>,
244
+ /** As {@link resolvePref}'s. A choice whose source is unanswered is not judged, and not reported. */
245
+ sources?: PrefSources): Problem[];
246
+ /** A stored appearance document. `sections` is opaque: the core never parses a section's payload. */
247
+ export interface LookDocument {
248
+ id: string;
249
+ label: string;
250
+ version: number;
251
+ /**
252
+ * Keyed by namespace. **Unknown sections are legal and are preserved**, which is a product
253
+ * requirement rather than politeness: a client signs their document before they buy the graph,
254
+ * and the section a later package adds must survive every load and save in between.
255
+ */
256
+ sections: Readonly<Record<string, Readonly<Record<string, string>>>>;
257
+ }
258
+ /**
259
+ * The fallback chain for a dotted token, most specific first.
260
+ *
261
+ * `--graph-point-size-min` → `--point-size-min`. One segment is dropped at a time from the left,
262
+ * because the namespace is the qualifier: a section asks for its own value and inherits the shared
263
+ * one when it has none of its own.
264
+ */
265
+ export declare function fallbackChain(token: string): string[];
266
+ /**
267
+ * Resolve a section token against a document, then against the manifest's default.
268
+ *
269
+ * `declared` is what the cascade or the document already provides, keyed by full token name. The
270
+ * first member of the chain it answers wins; if none does, the manifest's default is returned —
271
+ * and a default is returned as written, because it is already a CSS value: the browser is what
272
+ * resolves it, on the element that uses it.
273
+ */
274
+ export declare function resolveSectionToken(token: string, declared: Readonly<Record<string, string>>, manifest: SectionManifest): {
275
+ value: string;
276
+ via: string;
277
+ } | null;
278
+ export interface Problem {
279
+ token: string;
280
+ /** `unknown` — not declared by the manifest. `shadowed` — would silently fall back to a parent. */
281
+ kind: "unknown" | "shadowed";
282
+ detail: string;
283
+ }
284
+ /**
285
+ * Check a section's stored payload against the manifest that owns it.
286
+ *
287
+ * This is the half Neovim does not have, and it is why a typo cannot degrade in silence: a name the
288
+ * manifest never declared is reported rather than quietly resolving to whatever parent happens to
289
+ * exist. Validation is **per section**, so a document carrying a section for an absent package is
290
+ * simply not validated — it is not an error, and `sections.test.ts` pins that.
291
+ */
292
+ export declare function validateSection(manifest: SectionManifest, stored: Readonly<Record<string, string>>): Problem[];
293
+ /** Read a section's payload. Absent, or a package you do not have, answers an empty record. */
294
+ export declare function sectionOf(doc: LookDocument, namespace: string): Readonly<Record<string, string>>;
295
+ /**
296
+ * Write a section back, preserving every other section byte for byte.
297
+ *
298
+ * The preservation is the point: a host that never installed `@kanzo-tech/graph` still round-trips
299
+ * a document containing a graph section, because the core treats the payload as opaque data rather
300
+ * than as something to parse into a type it knows.
301
+ */
302
+ export declare function withSection(doc: LookDocument, namespace: string, tokens: Readonly<Record<string, string>>): LookDocument;
303
+ export {};
304
+ //# sourceMappingURL=sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../src/sections.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@kanzo-tech/theme",
3
+ "version": "0.0.1-alpha",
4
+ "description": "Kanzo design tokens — a catalogue of themes, each one flat block of CSS, plus the non-colour axes (radius / font / mono font / density) a user layers over them, driven by data-* attributes on <html>.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "sideEffects": [
8
+ "**/*.css"
9
+ ],
10
+ "files": [
11
+ "dist",
12
+ "themes",
13
+ "tokens.css",
14
+ "themes.css",
15
+ "theme-data.json",
16
+ "README.md"
17
+ ],
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js"
24
+ },
25
+ "./tokens.css": "./tokens.css",
26
+ "./themes.css": "./themes.css",
27
+ "./theme-data.json": "./theme-data.json",
28
+ "./package.json": "./package.json",
29
+ "./themes/*.css": "./themes/*.css"
30
+ },
31
+ "//deps": "No React peer and no derivation dependency: this package ships CSS, the axis table and types. The provider that consumes them lives in @kanzo-tech/ui. A theme is source, not output — there is nothing to derive it from.",
32
+ "devDependencies": {
33
+ "tailwindcss": "4"
34
+ },
35
+ "//gen": "One step now: the non-colour axes and the theme catalogue. There is no colour generation — a theme is themes/<name>.css, hand-written source. scripts/extract-themes.mjs was the one-way migration that produced the first sixteen and does not run again.",
36
+ "scripts": {
37
+ "build": "vite build",
38
+ "//gen": "Three steps, in this order: the derivation made runnable from plain Node (its own tables, then its build), the four non-colour axes, and the default tenant's document compiled into tokens.css.",
39
+ "gen": "node scripts/gen-theme.mjs",
40
+ "typecheck": "tsc --noEmit",
41
+ "test": "vitest run"
42
+ }
43
+ }
@@ -0,0 +1,311 @@
1
+ {
2
+ "radii": {
3
+ "none": "0rem",
4
+ "xs": "0.125rem",
5
+ "sm": "0.25rem",
6
+ "md": "0.5rem",
7
+ "lg": "0.625rem"
8
+ },
9
+ "fonts": {
10
+ "system": "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif",
11
+ "geist": "var(--font-geist-sans, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif)",
12
+ "inter": "var(--font-inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif)"
13
+ },
14
+ "monoFonts": {
15
+ "system": "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
16
+ "geist-mono": "var(--font-geist-mono, ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace)",
17
+ "jetbrains-mono": "var(--font-jetbrains-mono, ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace)"
18
+ },
19
+ "densities": {
20
+ "default": "16px",
21
+ "compact": "14px",
22
+ "comfortable": "18px"
23
+ },
24
+ "themes": [
25
+ {
26
+ "name": "acid",
27
+ "dark": false
28
+ },
29
+ {
30
+ "name": "bank-dark",
31
+ "dark": true
32
+ },
33
+ {
34
+ "name": "bank-private-dark",
35
+ "dark": true
36
+ },
37
+ {
38
+ "name": "bank-private",
39
+ "dark": false
40
+ },
41
+ {
42
+ "name": "bank",
43
+ "dark": false
44
+ },
45
+ {
46
+ "name": "catppuccin-latte-dark",
47
+ "dark": true
48
+ },
49
+ {
50
+ "name": "catppuccin-latte",
51
+ "dark": false
52
+ },
53
+ {
54
+ "name": "catppuccin-mocha-dark",
55
+ "dark": true
56
+ },
57
+ {
58
+ "name": "catppuccin-mocha",
59
+ "dark": false
60
+ },
61
+ {
62
+ "name": "cmyk",
63
+ "dark": false
64
+ },
65
+ {
66
+ "name": "coffee",
67
+ "dark": true
68
+ },
69
+ {
70
+ "name": "cyberpunk",
71
+ "dark": false
72
+ },
73
+ {
74
+ "name": "dim",
75
+ "dark": true
76
+ },
77
+ {
78
+ "name": "dracula-dark",
79
+ "dark": true
80
+ },
81
+ {
82
+ "name": "dracula",
83
+ "dark": false
84
+ },
85
+ {
86
+ "name": "forest",
87
+ "dark": true
88
+ },
89
+ {
90
+ "name": "kanzo-dark",
91
+ "dark": true
92
+ },
93
+ {
94
+ "name": "kanzo",
95
+ "dark": false
96
+ },
97
+ {
98
+ "name": "lemonade",
99
+ "dark": false
100
+ },
101
+ {
102
+ "name": "lofi",
103
+ "dark": false
104
+ },
105
+ {
106
+ "name": "luxury",
107
+ "dark": true
108
+ },
109
+ {
110
+ "name": "monochrome-dark",
111
+ "dark": true
112
+ },
113
+ {
114
+ "name": "monochrome",
115
+ "dark": false
116
+ },
117
+ {
118
+ "name": "night",
119
+ "dark": true
120
+ },
121
+ {
122
+ "name": "nord-dark",
123
+ "dark": true
124
+ },
125
+ {
126
+ "name": "nord",
127
+ "dark": false
128
+ },
129
+ {
130
+ "name": "sunset",
131
+ "dark": true
132
+ },
133
+ {
134
+ "name": "synthwave",
135
+ "dark": true
136
+ },
137
+ {
138
+ "name": "wireframe",
139
+ "dark": false
140
+ }
141
+ ],
142
+ "prefs": {
143
+ "appearance": {
144
+ "kind": "choice",
145
+ "options": [
146
+ {
147
+ "value": "",
148
+ "label": "System"
149
+ },
150
+ {
151
+ "value": "light",
152
+ "label": "Light"
153
+ },
154
+ {
155
+ "value": "dark",
156
+ "label": "Dark"
157
+ }
158
+ ],
159
+ "default": "",
160
+ "label": "Appearance",
161
+ "doc": "which side of the document is worn"
162
+ },
163
+ "radius": {
164
+ "kind": "choice",
165
+ "options": [
166
+ {
167
+ "value": "none",
168
+ "label": "none"
169
+ },
170
+ {
171
+ "value": "xs",
172
+ "label": "xs"
173
+ },
174
+ {
175
+ "value": "sm",
176
+ "label": "sm"
177
+ },
178
+ {
179
+ "value": "md",
180
+ "label": "md"
181
+ },
182
+ {
183
+ "value": "lg",
184
+ "label": "lg"
185
+ }
186
+ ],
187
+ "default": "md",
188
+ "attr": "data-radius",
189
+ "source": "themes",
190
+ "label": "Radius",
191
+ "doc": "how round a corner is"
192
+ },
193
+ "font": {
194
+ "kind": "choice",
195
+ "options": [
196
+ {
197
+ "value": "system",
198
+ "label": "System"
199
+ },
200
+ {
201
+ "value": "geist",
202
+ "label": "Geist"
203
+ },
204
+ {
205
+ "value": "inter",
206
+ "label": "Inter"
207
+ }
208
+ ],
209
+ "default": "system",
210
+ "attr": "data-font",
211
+ "source": "themes",
212
+ "label": "Font",
213
+ "doc": "the face body text is set in"
214
+ },
215
+ "monoFont": {
216
+ "kind": "choice",
217
+ "options": [
218
+ {
219
+ "value": "system",
220
+ "label": "System"
221
+ },
222
+ {
223
+ "value": "geist-mono",
224
+ "label": "Geist Mono"
225
+ },
226
+ {
227
+ "value": "jetbrains-mono",
228
+ "label": "JetBrains"
229
+ }
230
+ ],
231
+ "default": "system",
232
+ "attr": "data-mono-font",
233
+ "source": "themes",
234
+ "label": "Mono font",
235
+ "doc": "the face code is set in"
236
+ },
237
+ "density": {
238
+ "kind": "choice",
239
+ "options": [
240
+ {
241
+ "value": "default",
242
+ "label": "Default"
243
+ },
244
+ {
245
+ "value": "compact",
246
+ "label": "Compact"
247
+ },
248
+ {
249
+ "value": "comfortable",
250
+ "label": "Cozy"
251
+ }
252
+ ],
253
+ "default": "default",
254
+ "attr": "data-font-size",
255
+ "source": "themes",
256
+ "label": "Density",
257
+ "doc": "the root size everything scales from"
258
+ },
259
+ "themeByAppearance": {
260
+ "kind": "choice",
261
+ "options": {
262
+ "from": "themes"
263
+ },
264
+ "default": "",
265
+ "attr": "data-theme",
266
+ "source": "document",
267
+ "byAppearance": true,
268
+ "label": "Theme",
269
+ "doc": "which theme is worn on this side"
270
+ }
271
+ },
272
+ "fallbacks": {
273
+ "--secondary-foreground": [
274
+ "--foreground"
275
+ ],
276
+ "--accent-foreground": [
277
+ "--foreground"
278
+ ],
279
+ "--popover": [
280
+ "--card"
281
+ ],
282
+ "--input": [
283
+ "--border"
284
+ ],
285
+ "--field": [
286
+ "--muted"
287
+ ],
288
+ "--faint": [
289
+ "--muted-foreground"
290
+ ],
291
+ "--destructive-foreground": [
292
+ "--destructive"
293
+ ],
294
+ "--info-foreground": [
295
+ "--info"
296
+ ],
297
+ "--success-foreground": [
298
+ "--success"
299
+ ],
300
+ "--warning-foreground": [
301
+ "--warning"
302
+ ],
303
+ "--sidebar": [
304
+ "--popover",
305
+ "--card"
306
+ ],
307
+ "--sidebar-foreground": [
308
+ "--muted-foreground"
309
+ ]
310
+ }
311
+ }