@homepages/template-kit 0.1.0 → 0.3.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 (111) hide show
  1. package/CHANGELOG.md +220 -0
  2. package/README.md +70 -16
  3. package/dist/base.css +36 -48
  4. package/dist/cli/check/config.js +37 -0
  5. package/dist/cli/check/css.js +117 -0
  6. package/dist/cli/check/diagnostics.js +32 -0
  7. package/dist/cli/check/index.js +87 -0
  8. package/dist/cli/check/loader.js +142 -0
  9. package/dist/cli/check/paths.js +15 -0
  10. package/dist/cli/check/relativize.js +18 -0
  11. package/dist/cli/check/render-invariants.js +24 -0
  12. package/dist/cli/check/resolve-tool.js +38 -0
  13. package/dist/cli/check/stages/deps.js +337 -0
  14. package/dist/cli/check/stages/lint.js +46 -0
  15. package/dist/cli/check/stages/render.js +101 -0
  16. package/dist/cli/check/stages/size.js +158 -0
  17. package/dist/cli/check/stages/tree.js +207 -0
  18. package/dist/cli/check/stages/typecheck.js +46 -0
  19. package/dist/cli/check/stages/validate/catalog-exhaustiveness.js +18 -0
  20. package/dist/cli/check/stages/validate/facts.js +18 -0
  21. package/dist/cli/check/stages/validate/formatter-contract.js +14 -0
  22. package/dist/cli/check/stages/validate/group-contract.js +21 -0
  23. package/dist/cli/check/stages/validate/index.js +66 -0
  24. package/dist/cli/check/stages/validate/list-scalar-contract.js +22 -0
  25. package/dist/cli/check/stages/validate/nav-contract.js +93 -0
  26. package/dist/cli/check/stages/validate/nested-slot-contract.js +12 -0
  27. package/dist/cli/check/stages/validate/object-list-contract.js +31 -0
  28. package/dist/cli/check/stages/validate/orchestrator.js +241 -0
  29. package/dist/cli/check/stages/validate/produced-by-contract.js +18 -0
  30. package/dist/cli/check/stages/validate/row-contract.js +31 -0
  31. package/dist/cli/check/stages/validate/select-contract.js +13 -0
  32. package/dist/cli/check/stages/validate/source-contract.js +21 -0
  33. package/dist/cli/check/stages/validate/variant-contract.js +15 -0
  34. package/dist/cli/check/workspace.js +86 -0
  35. package/dist/cli/theme/generate.js +43 -0
  36. package/dist/cli/theme/index.js +33 -0
  37. package/dist/cli/theme/load-theme.js +69 -0
  38. package/dist/cli.js +22 -4
  39. package/dist/contracts/fill-treatments.js +47 -0
  40. package/dist/design-system/theme.d.ts +30 -299
  41. package/dist/design-system/theme.js +112 -83
  42. package/dist/eslint/rules/image-bare-needs-reason.js +6 -1
  43. package/dist/eslint/rules/no-client-directive-in-contract.js +6 -1
  44. package/dist/eslint/rules/no-client-runtime-in-server.js +5 -1
  45. package/dist/eslint/rules/no-css-import-from-render-path.js +8 -2
  46. package/dist/eslint/rules/no-hex.js +84 -7
  47. package/dist/eslint/rules/no-inline-style.js +5 -1
  48. package/dist/eslint/rules/no-nondeterminism.js +5 -1
  49. package/dist/eslint/rules/no-raw-element.js +6 -1
  50. package/dist/eslint/rules/props-from-schema.js +6 -1
  51. package/dist/eslint/rules/serializable-island-props.js +5 -1
  52. package/dist/eslint/rules/slot-marker-literal.js +6 -1
  53. package/dist/eslint.js +1 -1
  54. package/dist/index.d.ts +2 -2
  55. package/dist/index.js +2 -2
  56. package/dist/package.js +1 -1
  57. package/dist/primitives/Image.js +1 -1
  58. package/dist/rules/registry.js +16 -0
  59. package/dist/schema/fill-spec.d.ts +80 -590
  60. package/dist/schema/fixture-schema.d.ts +5 -81
  61. package/dist/schema/manifest.d.ts +39 -475
  62. package/dist/schema/resolve-section-ref.js +10 -0
  63. package/dist/schema/rows.js +10 -0
  64. package/dist/schema/section-nav.js +9 -0
  65. package/dist/schema/section-schema.d.ts +51 -437
  66. package/dist/schema/slot-types.d.ts +12 -16
  67. package/dist/styles.css +31 -88
  68. package/docs/INDEX.md +5 -3
  69. package/docs/check.md +121 -0
  70. package/docs/eslint.md +25 -50
  71. package/docs/llms.txt +26 -11
  72. package/docs/primitives.md +5 -0
  73. package/docs/rules/INDEX.md +65 -0
  74. package/docs/rules/audit-severity.md +91 -0
  75. package/docs/rules/bundle-binary-asset.md +102 -0
  76. package/docs/rules/bundle-incomplete.md +117 -0
  77. package/docs/rules/css-reason.md +94 -0
  78. package/docs/rules/determinism-drift.md +112 -0
  79. package/docs/rules/fixtures-invalid.md +96 -0
  80. package/docs/rules/image-bare-needs-reason.md +117 -0
  81. package/docs/rules/license-denied.md +114 -0
  82. package/docs/rules/lockfile-missing.md +68 -0
  83. package/docs/rules/lockfile-stale.md +88 -0
  84. package/docs/rules/manifest-invalid.md +99 -0
  85. package/docs/rules/missing-slot-marker.md +140 -0
  86. package/docs/rules/no-bare-css-import.md +128 -0
  87. package/docs/rules/no-client-directive-in-contract.md +111 -0
  88. package/docs/rules/no-client-runtime-in-server.md +143 -0
  89. package/docs/rules/no-css-import-from-render-path.md +118 -0
  90. package/docs/rules/no-hex.md +163 -0
  91. package/docs/rules/no-inline-style.md +121 -0
  92. package/docs/rules/no-nondeterminism.md +100 -0
  93. package/docs/rules/no-raw-element.md +100 -0
  94. package/docs/rules/no-templates.md +87 -0
  95. package/docs/rules/parse-error.md +76 -0
  96. package/docs/rules/props-from-schema.md +119 -0
  97. package/docs/rules/render-invariant.md +165 -0
  98. package/docs/rules/schema-invalid.md +96 -0
  99. package/docs/rules/serializable-island-props.md +146 -0
  100. package/docs/rules/server-vs-client.md +105 -0
  101. package/docs/rules/sidebar-order.md +109 -0
  102. package/docs/rules/single-react.md +97 -0
  103. package/docs/rules/size-renderer-bundle.md +109 -0
  104. package/docs/rules/size-section-css.md +95 -0
  105. package/docs/rules/slot-group-marker.md +127 -0
  106. package/docs/rules/slot-marker-literal.md +148 -0
  107. package/docs/rules/typecheck.md +103 -0
  108. package/docs/rules/unlayered-fence.md +113 -0
  109. package/docs/theme-and-css.md +193 -82
  110. package/package.json +4 -9
  111. package/tsconfig.json +1 -1
@@ -0,0 +1,43 @@
1
+ import { TokenThemeSchema, compileThemeToCss } from "../../design-system/theme.js";
2
+ import { loadTheme } from "./load-theme.js";
3
+ import { join } from "node:path";
4
+ import { writeFile } from "node:fs/promises";
5
+
6
+ //#region src/cli/theme/generate.ts
7
+ const OUT_FILE = "theme.css";
8
+ const HEADER = "/* Generated by `template-kit theme` from theme.ts — do not edit.\n Re-run `template-kit theme` after changing theme.ts. */\n";
9
+ /** theme.ts's `theme` export failed TokenThemeSchema; `issues` are `path: message` lines. */
10
+ var InvalidTheme = class extends Error {
11
+ path;
12
+ issues;
13
+ constructor(path, issues) {
14
+ super(`${path} is not a valid TokenTheme:\n${issues.map((i) => ` - ${i}`).join("\n")}`);
15
+ this.path = path;
16
+ this.issues = issues;
17
+ this.name = "InvalidTheme";
18
+ }
19
+ };
20
+ /**
21
+ * Compile `templates/<key>/theme.ts` to `templates/<key>/theme.css`. Throws
22
+ * MissingThemeFile / MissingThemeExport (load-theme.ts) or InvalidTheme.
23
+ */
24
+ async function generateTemplateTheme(root, template) {
25
+ const raw = await loadTheme(root, template);
26
+ const parsed = TokenThemeSchema.safeParse(raw);
27
+ if (!parsed.success) {
28
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`);
29
+ throw new InvalidTheme(join("templates", template.key, "theme.ts"), issues);
30
+ }
31
+ const theme = parsed.data;
32
+ const outPath = join(template.dir, OUT_FILE);
33
+ await writeFile(outPath, `${HEADER}${compileThemeToCss(theme)}`, "utf8");
34
+ const tokenCount = Object.keys(theme.colors).length + Object.keys(theme.fonts).length + Object.keys(theme.type).length + Object.keys(theme.radii).length + Object.keys(theme.shadows).length + Object.keys(theme.layout).length;
35
+ return {
36
+ outPath,
37
+ relPath: join("templates", template.key, OUT_FILE),
38
+ tokenCount
39
+ };
40
+ }
41
+
42
+ //#endregion
43
+ export { InvalidTheme, generateTemplateTheme };
@@ -0,0 +1,33 @@
1
+ import { findWorkspaceRoot, selectTemplates, templateFromCwd } from "../check/workspace.js";
2
+ import { generateTemplateTheme } from "./generate.js";
3
+ import { parseArgs } from "node:util";
4
+
5
+ //#region src/cli/theme/index.ts
6
+ async function runTheme(argv, cwd) {
7
+ const { values, positionals } = parseArgs({
8
+ args: argv,
9
+ options: { all: {
10
+ type: "boolean",
11
+ default: false
12
+ } },
13
+ allowPositionals: true
14
+ });
15
+ const root = await findWorkspaceRoot(cwd);
16
+ const selected = await selectTemplates(root, positionals[0] ?? (values.all ? void 0 : templateFromCwd(root, cwd)), values.all, "theme");
17
+ if (selected.length === 0) return {
18
+ code: 1,
19
+ output: "No template to generate theme CSS for: templates/ holds no template folder."
20
+ };
21
+ const lines = [];
22
+ for (const template of selected) {
23
+ const { relPath, tokenCount } = await generateTemplateTheme(root, template);
24
+ lines.push(` ${template.key} wrote ${relPath} (${tokenCount} tokens)`);
25
+ }
26
+ return {
27
+ code: 0,
28
+ output: `template-kit theme\n${lines.join("\n")}`
29
+ };
30
+ }
31
+
32
+ //#endregion
33
+ export { runTheme };
@@ -0,0 +1,69 @@
1
+ import { loadEsbuild } from "../check/resolve-tool.js";
2
+ import { join } from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { mkdir, readFile, rm, stat } from "node:fs/promises";
5
+ import { pathToFileURL } from "node:url";
6
+
7
+ //#region src/cli/theme/load-theme.ts
8
+ const THEME_FILE = "theme.ts";
9
+ const THEME_EXPORT = "theme";
10
+ /** A template has no theme.ts. `path` is workspace-relative. */
11
+ var MissingThemeFile = class extends Error {
12
+ path;
13
+ constructor(path) {
14
+ super(`${path} not found. A template's design tokens live in theme.ts — create it exporting \`${THEME_EXPORT}\` (a TokenTheme).`);
15
+ this.path = path;
16
+ this.name = "MissingThemeFile";
17
+ }
18
+ };
19
+ /** theme.ts built, but exports no `theme` binding. `path` is workspace-relative. */
20
+ var MissingThemeExport = class extends Error {
21
+ path;
22
+ constructor(path) {
23
+ super(`${path} does not export \`${THEME_EXPORT}\`. It must \`export const ${THEME_EXPORT}: TokenTheme = { … }\`.`);
24
+ this.path = path;
25
+ this.name = "MissingThemeExport";
26
+ }
27
+ };
28
+ const isFile = async (p) => {
29
+ try {
30
+ return (await stat(p)).isFile();
31
+ } catch {
32
+ return false;
33
+ }
34
+ };
35
+ /**
36
+ * Transpile + evaluate `templates/<key>/theme.ts` and return its `theme` export,
37
+ * unvalidated (the caller parses it with TokenThemeSchema). Throws MissingThemeFile
38
+ * when theme.ts is absent and MissingThemeExport when it builds without a `theme`
39
+ * binding.
40
+ */
41
+ async function loadTheme(root, template) {
42
+ const source = join(template.dir, THEME_FILE);
43
+ const rel = join("templates", template.key, THEME_FILE);
44
+ if (!await isFile(source)) throw new MissingThemeFile(rel);
45
+ const outdir = join(root, "node_modules", ".template-kit", "theme", createHash("sha256").update(template.dir).digest("hex").slice(0, 12));
46
+ await rm(outdir, {
47
+ recursive: true,
48
+ force: true
49
+ });
50
+ await mkdir(outdir, { recursive: true });
51
+ const { build } = await loadEsbuild(root);
52
+ await build({
53
+ entryPoints: [source],
54
+ outdir,
55
+ bundle: true,
56
+ format: "esm",
57
+ platform: "neutral",
58
+ packages: "external",
59
+ logLevel: "silent",
60
+ absWorkingDir: root
61
+ });
62
+ const version = createHash("sha256").update(await readFile(source)).digest("hex").slice(0, 12);
63
+ const value = (await import(`${pathToFileURL(join(outdir, "theme.js")).href}?v=${version}`))[THEME_EXPORT];
64
+ if (value === void 0) throw new MissingThemeExport(rel);
65
+ return value;
66
+ }
67
+
68
+ //#endregion
69
+ export { MissingThemeExport, MissingThemeFile, loadTheme };
package/dist/cli.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { KIT_VERSION } from "./index.js";
3
+ import { runCheck } from "./cli/check/index.js";
4
+ import { runTheme } from "./cli/theme/index.js";
3
5
 
4
6
  //#region src/cli/index.ts
5
7
  /**
@@ -10,7 +12,6 @@ import { KIT_VERSION } from "./index.js";
10
12
  */
11
13
  const NOT_IMPLEMENTED = /* @__PURE__ */ new Set([
12
14
  "dev",
13
- "check",
14
15
  "pack",
15
16
  "link",
16
17
  "unlink",
@@ -22,7 +23,8 @@ Usage: template-kit <command>
22
23
 
23
24
  Commands:
24
25
  dev Local preview server (not implemented yet)
25
- check Typecheck, lint, and validate (not implemented yet)
26
+ check Typecheck, lint, and validate a template
27
+ theme Generate a template's theme CSS from its theme.ts
26
28
  pack Build the submission artifact (not implemented yet)
27
29
  link Overlay a local kit build (not implemented yet)
28
30
  unlink Remove the overlay (not implemented yet)
@@ -32,7 +34,7 @@ Options:
32
34
  -v, --version Print the kit version
33
35
  -h, --help Print this message
34
36
  `;
35
- function main(argv) {
37
+ async function main(argv) {
36
38
  const cmd = argv[0];
37
39
  if (cmd === "--version" || cmd === "-v") {
38
40
  process.stdout.write(`${KIT_VERSION}\n`);
@@ -42,6 +44,22 @@ function main(argv) {
42
44
  process.stdout.write(USAGE);
43
45
  return 0;
44
46
  }
47
+ if (cmd === "check") try {
48
+ const { code, output } = await runCheck(argv.slice(1), process.cwd());
49
+ process.stdout.write(output.endsWith("\n") ? output : `${output}\n`);
50
+ return code;
51
+ } catch (cause) {
52
+ process.stderr.write(`template-kit check: ${cause instanceof Error ? cause.message : String(cause)}\n`);
53
+ return 1;
54
+ }
55
+ if (cmd === "theme") try {
56
+ const { code, output } = await runTheme(argv.slice(1), process.cwd());
57
+ process.stdout.write(output.endsWith("\n") ? output : `${output}\n`);
58
+ return code;
59
+ } catch (cause) {
60
+ process.stderr.write(`template-kit theme: ${cause instanceof Error ? cause.message : String(cause)}\n`);
61
+ return 1;
62
+ }
45
63
  if (NOT_IMPLEMENTED.has(cmd)) {
46
64
  process.stderr.write(`template-kit ${cmd}: not implemented yet.\nThis 0.0.x release ships the package skeleton only.\n`);
47
65
  return 1;
@@ -49,6 +67,6 @@ function main(argv) {
49
67
  process.stderr.write(`template-kit: unknown command '${cmd}'\n\n${USAGE}`);
50
68
  return 1;
51
69
  }
52
- process.exit(main(process.argv.slice(2)));
70
+ process.exit(await main(process.argv.slice(2)));
53
71
 
54
72
  //#endregion
@@ -0,0 +1,47 @@
1
+ //#region src/contracts/fill-treatments.ts
2
+ const GENERATED_KINDS = ["text", "list<text>"];
3
+ const COMPUTED_FNS = ["haversine_miles", "mint_id"];
4
+ const CATALOG_FIELDS = [
5
+ "key",
6
+ "label",
7
+ "icon",
8
+ "slot"
9
+ ];
10
+ function parseTreatment(raw) {
11
+ if (raw === "source") return {
12
+ kind: "source",
13
+ path: null
14
+ };
15
+ if (raw.startsWith("source:")) {
16
+ const path = raw.slice(7);
17
+ return path ? {
18
+ kind: "source",
19
+ path
20
+ } : null;
21
+ }
22
+ if (raw.startsWith("computed:")) {
23
+ const fn = raw.slice(9);
24
+ return COMPUTED_FNS.includes(fn) ? {
25
+ kind: "computed",
26
+ fn
27
+ } : null;
28
+ }
29
+ if (raw.startsWith("catalog:")) {
30
+ const field = raw.slice(8);
31
+ return CATALOG_FIELDS.includes(field) ? {
32
+ kind: "catalog",
33
+ field
34
+ } : null;
35
+ }
36
+ if (raw.startsWith("generated:")) {
37
+ const outKind = raw.slice(10);
38
+ return GENERATED_KINDS.includes(outKind) ? {
39
+ kind: "generated",
40
+ outKind
41
+ } : null;
42
+ }
43
+ return null;
44
+ }
45
+
46
+ //#endregion
47
+ export { CATALOG_FIELDS, COMPUTED_FNS, GENERATED_KINDS, parseTreatment };
@@ -1,307 +1,38 @@
1
1
  import { z } from "zod";
2
2
  //#region src/design-system/theme.d.ts
3
- declare const COLOR_ROLE_VARS: {
4
- readonly ink: "--tr-color-ink";
5
- readonly inkSoft: "--tr-color-ink-soft";
6
- readonly inkMute: "--tr-color-ink-mute";
7
- readonly background: "--tr-color-background";
8
- readonly surface: "--tr-color-surface";
9
- readonly surfaceAlt: "--tr-color-surface-alt";
10
- readonly border: "--tr-color-border";
11
- readonly borderStrong: "--tr-color-border-strong";
12
- readonly primary: "--tr-color-primary";
13
- readonly primaryFg: "--tr-color-primary-fg";
14
- readonly primaryStrong: "--tr-color-primary-darker";
15
- readonly accent: "--tr-color-accent";
16
- readonly accentFg: "--tr-color-accent-contrast";
17
- readonly accentStrong: "--tr-color-accent-strong";
18
- readonly overlay: "--tr-color-overlay";
19
- readonly overlayStrong: "--tr-color-overlay-strong";
20
- readonly overlayLight: "--tr-color-overlay-light";
21
- readonly darkBg: "--tr-color-footer-bg";
22
- readonly darkFg: "--tr-color-footer-fg";
23
- readonly darkFgMute: "--tr-color-footer-fg-mute";
24
- readonly darkBorder: "--tr-color-footer-divider";
25
- };
26
- type ColorRole = keyof typeof COLOR_ROLE_VARS;
27
- declare const FONT_ROLE_VARS: {
28
- readonly body: "--tr-font-sans";
29
- readonly heading: "--tr-font-serif";
30
- readonly numeric: "--tr-font-num";
31
- readonly label: "--tr-font-label";
32
- };
33
- declare const TYPE_STEP_VARS: {
34
- readonly xs: "--tr-text-xs";
35
- readonly sm: "--tr-text-sm";
36
- readonly base: "--tr-text-base";
37
- readonly lg: "--tr-text-lg";
38
- readonly xl: "--tr-text-xl";
39
- readonly "2xl": "--tr-text-2xl";
40
- readonly "3xl": "--tr-text-3xl";
41
- readonly "4xl": "--tr-text-4xl";
42
- readonly "5xl": "--tr-text-5xl";
43
- readonly display: "--tr-text-display";
44
- };
45
- declare const RADIUS_VARS: {
46
- readonly sm: "--tr-radius-sm";
47
- readonly md: "--tr-radius-md";
48
- readonly lg: "--tr-radius-lg";
49
- readonly full: "--tr-radius-full";
50
- };
51
- declare const SHADOW_VARS: {
52
- readonly sm: "--tr-shadow-sm";
53
- readonly md: "--tr-shadow-md";
54
- readonly lg: "--tr-shadow-lg";
55
- };
56
- declare const LAYOUT_VARS: {
57
- readonly containerMax: "--tr-container-max";
58
- readonly containerPad: "--tr-container-pad";
59
- readonly headerHeight: "--tr-header-height";
60
- };
3
+ declare const TokenNameSchema: z.ZodString;
61
4
  declare const TokenThemeSchema: z.ZodObject<{
62
- colors: z.ZodObject<Record<"ink" | "inkSoft" | "inkMute" | "background" | "surface" | "surfaceAlt" | "border" | "borderStrong" | "primary" | "primaryFg" | "primaryStrong" | "accent" | "accentFg" | "accentStrong" | "overlay" | "overlayStrong" | "overlayLight" | "darkBg" | "darkFg" | "darkFgMute" | "darkBorder", z.ZodString>, "strip", z.ZodTypeAny, {
63
- ink: string;
64
- inkSoft: string;
65
- inkMute: string;
66
- background: string;
67
- surface: string;
68
- surfaceAlt: string;
69
- border: string;
70
- borderStrong: string;
71
- primary: string;
72
- primaryFg: string;
73
- primaryStrong: string;
74
- accent: string;
75
- accentFg: string;
76
- accentStrong: string;
77
- overlay: string;
78
- overlayStrong: string;
79
- overlayLight: string;
80
- darkBg: string;
81
- darkFg: string;
82
- darkFgMute: string;
83
- darkBorder: string;
84
- }, {
85
- ink: string;
86
- inkSoft: string;
87
- inkMute: string;
88
- background: string;
89
- surface: string;
90
- surfaceAlt: string;
91
- border: string;
92
- borderStrong: string;
93
- primary: string;
94
- primaryFg: string;
95
- primaryStrong: string;
96
- accent: string;
97
- accentFg: string;
98
- accentStrong: string;
99
- overlay: string;
100
- overlayStrong: string;
101
- overlayLight: string;
102
- darkBg: string;
103
- darkFg: string;
104
- darkFgMute: string;
105
- darkBorder: string;
106
- }>;
107
- /** Optional open brand palette → `--tr-color-<name>` (the escape hatch). */
108
- palette: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
109
- fonts: z.ZodObject<Record<"body" | "heading" | "numeric" | "label", z.ZodString> & {
110
- /** Font-loading block (@import / @font-face) emitted before :root. */
111
- fontFaces: z.ZodOptional<z.ZodString>;
112
- }, "strip", z.ZodTypeAny, {
113
- body: string;
114
- heading: string;
115
- numeric: string;
116
- label: string;
117
- fontFaces?: string | undefined;
118
- }, {
119
- body: string;
120
- heading: string;
121
- numeric: string;
122
- label: string;
123
- fontFaces?: string | undefined;
124
- }>;
125
- type: z.ZodObject<Record<"xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "display", z.ZodString>, "strip", z.ZodTypeAny, {
126
- xs: string;
127
- sm: string;
128
- base: string;
129
- lg: string;
130
- xl: string;
131
- "2xl": string;
132
- "3xl": string;
133
- "4xl": string;
134
- "5xl": string;
135
- display: string;
136
- }, {
137
- xs: string;
138
- sm: string;
139
- base: string;
140
- lg: string;
141
- xl: string;
142
- "2xl": string;
143
- "3xl": string;
144
- "4xl": string;
145
- "5xl": string;
146
- display: string;
147
- }>;
148
- radii: z.ZodObject<Record<"sm" | "lg" | "md" | "full", z.ZodString>, "strip", z.ZodTypeAny, {
149
- sm: string;
150
- lg: string;
151
- md: string;
152
- full: string;
153
- }, {
154
- sm: string;
155
- lg: string;
156
- md: string;
157
- full: string;
158
- }>;
159
- shadows: z.ZodObject<Record<"sm" | "lg" | "md", z.ZodString>, "strip", z.ZodTypeAny, {
160
- sm: string;
161
- lg: string;
162
- md: string;
163
- }, {
164
- sm: string;
165
- lg: string;
166
- md: string;
167
- }>;
168
- layout: z.ZodObject<Record<"containerMax" | "containerPad" | "headerHeight", z.ZodString>, "strip", z.ZodTypeAny, {
169
- containerMax: string;
170
- containerPad: string;
171
- headerHeight: string;
172
- }, {
173
- containerMax: string;
174
- containerPad: string;
175
- headerHeight: string;
176
- }>;
177
- }, "strict", z.ZodTypeAny, {
178
- type: {
179
- xs: string;
180
- sm: string;
181
- base: string;
182
- lg: string;
183
- xl: string;
184
- "2xl": string;
185
- "3xl": string;
186
- "4xl": string;
187
- "5xl": string;
188
- display: string;
189
- };
190
- colors: {
191
- ink: string;
192
- inkSoft: string;
193
- inkMute: string;
194
- background: string;
195
- surface: string;
196
- surfaceAlt: string;
197
- border: string;
198
- borderStrong: string;
199
- primary: string;
200
- primaryFg: string;
201
- primaryStrong: string;
202
- accent: string;
203
- accentFg: string;
204
- accentStrong: string;
205
- overlay: string;
206
- overlayStrong: string;
207
- overlayLight: string;
208
- darkBg: string;
209
- darkFg: string;
210
- darkFgMute: string;
211
- darkBorder: string;
212
- };
213
- fonts: {
214
- body: string;
215
- heading: string;
216
- numeric: string;
217
- label: string;
218
- fontFaces?: string | undefined;
219
- };
220
- radii: {
221
- sm: string;
222
- lg: string;
223
- md: string;
224
- full: string;
225
- };
226
- shadows: {
227
- sm: string;
228
- lg: string;
229
- md: string;
230
- };
231
- layout: {
232
- containerMax: string;
233
- containerPad: string;
234
- headerHeight: string;
235
- };
236
- palette?: Record<string, string> | undefined;
237
- }, {
238
- type: {
239
- xs: string;
240
- sm: string;
241
- base: string;
242
- lg: string;
243
- xl: string;
244
- "2xl": string;
245
- "3xl": string;
246
- "4xl": string;
247
- "5xl": string;
248
- display: string;
249
- };
250
- colors: {
251
- ink: string;
252
- inkSoft: string;
253
- inkMute: string;
254
- background: string;
255
- surface: string;
256
- surfaceAlt: string;
257
- border: string;
258
- borderStrong: string;
259
- primary: string;
260
- primaryFg: string;
261
- primaryStrong: string;
262
- accent: string;
263
- accentFg: string;
264
- accentStrong: string;
265
- overlay: string;
266
- overlayStrong: string;
267
- overlayLight: string;
268
- darkBg: string;
269
- darkFg: string;
270
- darkFgMute: string;
271
- darkBorder: string;
272
- };
273
- fonts: {
274
- body: string;
275
- heading: string;
276
- numeric: string;
277
- label: string;
278
- fontFaces?: string | undefined;
279
- };
280
- radii: {
281
- sm: string;
282
- lg: string;
283
- md: string;
284
- full: string;
285
- };
286
- shadows: {
287
- sm: string;
288
- lg: string;
289
- md: string;
290
- };
291
- layout: {
292
- containerMax: string;
293
- containerPad: string;
294
- headerHeight: string;
295
- };
296
- palette?: Record<string, string> | undefined;
297
- }>;
5
+ colors: z.ZodRecord<z.ZodString, z.ZodString>;
6
+ fonts: z.ZodRecord<z.ZodString, z.ZodString>;
7
+ type: z.ZodRecord<z.ZodString, z.ZodString>;
8
+ radii: z.ZodRecord<z.ZodString, z.ZodString>;
9
+ shadows: z.ZodRecord<z.ZodString, z.ZodString>;
10
+ layout: z.ZodRecord<z.ZodString, z.ZodString>;
11
+ fontFaces: z.ZodOptional<z.ZodString>;
12
+ document: z.ZodObject<{
13
+ font: z.ZodString;
14
+ color: z.ZodString;
15
+ background: z.ZodString;
16
+ fontSize: z.ZodString;
17
+ }, z.core.$strict>;
18
+ }, z.core.$strict>;
298
19
  type TokenTheme = z.infer<typeof TokenThemeSchema>;
299
20
  /**
300
- * Compile a `TokenTheme` into the CSS a template's bundle ships: an optional
301
- * font-loading block followed by a single `:root { --tr-*: … }` declaration.
302
- * Deterministic (stable key order; palette keys sorted) so the same theme
303
- * always content-hashes identically.
21
+ * Compile a `TokenTheme` into the CSS a template's bundle ships:
22
+ *
23
+ * 1. the optional font-loading block;
24
+ * 2. `@theme inline { --color-<name>: var(--tr-color-<name>); … }` — the Tailwind
25
+ * alias layer, which is what brings the token utilities into existence;
26
+ * 3. `:root { --tr-color-<name>: <value>; … }` — the values behind those aliases;
27
+ * 4. `body { … }` — the document defaults, as `var()` indirections so that a runtime
28
+ * `:root` override still cascades to the page.
29
+ *
30
+ * The output MUST be compiled INSIDE the Tailwind build graph: `@theme` is a Tailwind
31
+ * directive, and anywhere else it is inert — silently, yielding a stylesheet with no
32
+ * token utilities and no error to explain why.
33
+ *
34
+ * Deterministic: keys are sorted, so the same theme always content-hashes identically.
304
35
  */
305
36
  declare function compileThemeToCss(theme: TokenTheme): string;
306
37
  //#endregion
307
- export { COLOR_ROLE_VARS, ColorRole, FONT_ROLE_VARS, LAYOUT_VARS, RADIUS_VARS, SHADOW_VARS, TYPE_STEP_VARS, TokenTheme, TokenThemeSchema, compileThemeToCss };
38
+ export { TokenNameSchema, TokenTheme, TokenThemeSchema, compileThemeToCss };