unholy-design-tokens 1.0.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/.github/workflows/lint-format-build.yml +35 -0
  2. package/.github/workflows/publish_release.yml +18 -0
  3. package/.prettierrc +9 -0
  4. package/ANALOGY_HOUSE.md +139 -0
  5. package/ANALOGY_I18NEXT.md +160 -0
  6. package/LICENSE +201 -0
  7. package/README.md +90 -0
  8. package/WHY_THIS_EXISTS.md +74 -0
  9. package/bin/build-tokens.ts +34 -0
  10. package/build/css/bg/bg.css +60 -0
  11. package/build/css/border/border.css +51 -0
  12. package/build/css/colors.css +204 -0
  13. package/build/css/conditional.css +8 -0
  14. package/build/css/cube/cube.block.css +18 -0
  15. package/build/css/cube/cube.composition.css +16 -0
  16. package/build/css/cube/cube.utility.css +185 -0
  17. package/build/css/font/font.css +24 -0
  18. package/build/css/space.css +20 -0
  19. package/build/css/text/text.css +48 -0
  20. package/build/css/themes/private-theme.css +228 -0
  21. package/build/css/themes/public-theme.css +228 -0
  22. package/build/css/variant/variant.css +42 -0
  23. package/build/css/variants.css +167 -0
  24. package/build/types/theme.d.ts +932 -0
  25. package/build/types/tokens.ts +653 -0
  26. package/dist/bin/build-tokens.js +27 -0
  27. package/dist/scripts/build-style-dictionary.js +32 -0
  28. package/dist/scripts/generate-typography-tokens.js +125 -0
  29. package/dist/src/colors/color.config.js +45 -0
  30. package/dist/src/colors/color.filter.js +19 -0
  31. package/dist/src/colors/color.formatter.js +25 -0
  32. package/dist/src/colors/index.js +2 -0
  33. package/dist/src/cube-css/cube.config.js +42 -0
  34. package/dist/src/cube-css/cube.formatter.js +89 -0
  35. package/dist/src/style-dictionary.config.js +143 -0
  36. package/dist/src/type-declarations/type-declarations.config.js +29 -0
  37. package/dist/src/type-declarations/type-declarations.formatter.js +111 -0
  38. package/dist/src/utils/helpers.js +9 -0
  39. package/dist/src/utils/index.js +4 -0
  40. package/dist/src/utils/template.js +83 -0
  41. package/dist/src/utils/tokens.js +80 -0
  42. package/dist/src/utils/utopia.js +19 -0
  43. package/eslint.config.js +67 -0
  44. package/package.json +60 -0
  45. package/scripts/build-style-dictionary.ts +44 -0
  46. package/scripts/generate-typography-tokens.ts +138 -0
  47. package/src/LICENSE +201 -0
  48. package/src/README.md +88 -0
  49. package/src/colors/color.config.ts +48 -0
  50. package/src/colors/color.filter.ts +28 -0
  51. package/src/colors/color.formatter.ts +43 -0
  52. package/src/colors/index.ts +6 -0
  53. package/src/cube-css/cube.config.ts +50 -0
  54. package/src/cube-css/cube.formatter.ts +104 -0
  55. package/src/formatters/spacing.js +95 -0
  56. package/src/style-dictionary.config.ts +151 -0
  57. package/src/theme/README.md +256 -0
  58. package/src/theme/cube-theme-addon.js +44 -0
  59. package/src/theme/helper.js +38 -0
  60. package/src/theme/index.js +6 -0
  61. package/src/theme/theme.config.js +42 -0
  62. package/src/theme/theme.filter.js +42 -0
  63. package/src/theme/theme.formatter.js +71 -0
  64. package/src/tokens/1 - primitives/README.md +58 -0
  65. package/src/tokens/1 - primitives/border.json +54 -0
  66. package/src/tokens/1 - primitives/breakpoint.json +10 -0
  67. package/src/tokens/1 - primitives/color-pool.json +266 -0
  68. package/src/tokens/1 - primitives/color.json +266 -0
  69. package/src/tokens/1 - primitives/font-scale.json +27 -0
  70. package/src/tokens/1 - primitives/font.json +23 -0
  71. package/src/tokens/1 - primitives/shadow.json +26 -0
  72. package/src/tokens/1 - primitives/space.json +27 -0
  73. package/src/tokens/2 - semantic/README.md +49 -0
  74. package/src/tokens/2 - semantic/border.json +27 -0
  75. package/src/tokens/2 - semantic/color.json +263 -0
  76. package/src/tokens/2 - semantic/details.md +1 -0
  77. package/src/tokens/2 - semantic/layout.json +52 -0
  78. package/src/tokens/2 - semantic/radius.json +13 -0
  79. package/src/tokens/2 - semantic/shadow.json +19 -0
  80. package/src/tokens/2 - semantic/spacing.json +25 -0
  81. package/src/tokens/3 - intent/README.md +43 -0
  82. package/src/tokens/3 - intent/background.json +135 -0
  83. package/src/tokens/3 - intent/color.json +265 -0
  84. package/src/tokens/3 - intent/font.json +61 -0
  85. package/src/tokens/3 - intent/text +67 -0
  86. package/src/tokens/README.md +176 -0
  87. package/src/tokens/color/brand.json +316 -0
  88. package/src/tokens/component/theming.json +69 -0
  89. package/src/tokens/conditional.json +40 -0
  90. package/src/tokens/custom/4 - (OPTIONAL) cube css/README.md +38 -0
  91. package/src/tokens/custom/4 - (OPTIONAL) cube css/block.json +24 -0
  92. package/src/tokens/custom/4 - (OPTIONAL) cube css/composition.json +26 -0
  93. package/src/tokens/custom/4 - (OPTIONAL) cube css/global.json +15 -0
  94. package/src/tokens/custom/4 - (OPTIONAL) cube css/utility.json +224 -0
  95. package/src/tokens/custom/OKlch/color.json +61 -0
  96. package/src/tokens/custom/OKlch/state.json +107 -0
  97. package/src/tokens/custom/OKlch/theme-color.json +34 -0
  98. package/src/tokens/custom/OKlch/variant.json +67 -0
  99. package/src/tokens/custom/components/highlighted.json +16 -0
  100. package/src/tokens/state.js +29 -0
  101. package/src/tokens/theme-color.json +34 -0
  102. package/src/type-declarations/type-declarations.config.ts +34 -0
  103. package/src/type-declarations/type-declarations.formatter.ts +122 -0
  104. package/src/utils/helpers.ts +11 -0
  105. package/src/utils/index.ts +4 -0
  106. package/src/utils/template.ts +110 -0
  107. package/src/utils/tokens.ts +95 -0
  108. package/src/utils/utopia.ts +36 -0
  109. package/tailwind.md +720 -0
  110. package/tsconfig.json +19 -0
  111. package/turbowatch.ts +14 -0
@@ -0,0 +1,4 @@
1
+ export * from './helpers';
2
+ export * from './template';
3
+ export * from './tokens';
4
+ export * from './utopia';
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Utility functions for template generation.
3
+ * https://styledictionary.com/reference/hooks/formats/#using-a-template--templating-engine-to-create-a-format
4
+ */
5
+ import { capitalizeFirstLetter } from "./helpers.js";
6
+ export { generateHeader, generateSubheader, formatInLayer, generateFigmaHeaderReference, };
7
+ const startComment = "/* ";
8
+ const endComment = " */";
9
+ const headerLength = 60;
10
+ const subheaderLength = 20;
11
+ const separatorChar = "-";
12
+ const headerSeparator = " ";
13
+ function generateSeparator(length) {
14
+ return `${startComment}${separatorChar.repeat(length)}${endComment}`;
15
+ }
16
+ /**
17
+ * Will generate a comment block like this:
18
+ /* ------------------------------------------------------------ *\/
19
+ /* Title *\/
20
+ /* ------------------------------------------------------------ *\/
21
+ *
22
+ */
23
+ function generateCommentBlock(title, totalLength, separatorChar, indent = "") {
24
+ let titleTotalLength = totalLength - title.length;
25
+ let halfLength = Math.floor(titleTotalLength / 2);
26
+ let titleSeparator = headerSeparator.repeat(halfLength);
27
+ if (totalLength % 2 !== 0) {
28
+ titleSeparator += separatorChar;
29
+ }
30
+ return (`\n${indent}${generateSeparator(totalLength)}` +
31
+ `\n${indent}${startComment}${titleSeparator}${title}${titleSeparator}${endComment}` +
32
+ `\n${indent}${generateSeparator(totalLength)}\n`);
33
+ }
34
+ /**
35
+ * Generates a header comment block for a given header string.
36
+ * /* ------------------------------------------------------------ *\/
37
+ * /* Header *\/
38
+ * /* ------------------------------------------------------------ *\/
39
+ */
40
+ function generateHeader(header) {
41
+ if (!header)
42
+ return "";
43
+ return generateCommentBlock(capitalizeFirstLetter(header), headerLength, separatorChar, "");
44
+ }
45
+ /**
46
+ * Generates a subheader comment block for a given subheader string.
47
+ * /* ---------------------- \/*
48
+ * /* Subheader *\/
49
+ * /* ---------------------- *\/
50
+ */
51
+ function generateSubheader(subheader) {
52
+ if (!subheader)
53
+ return "";
54
+ return generateCommentBlock(capitalizeFirstLetter(subheader), subheaderLength, separatorChar, " ");
55
+ }
56
+ /**
57
+ * Formats content within a CSS layer block.
58
+ * @layer name {
59
+ * :root {
60
+ * --variable: value;
61
+ * }
62
+ * }
63
+ */
64
+ function formatInLayer(name, content) {
65
+ let result = `@layer ${name} {`;
66
+ result += `\n`;
67
+ result += ` :root {`;
68
+ result += `\n`;
69
+ result += `${content}`;
70
+ result += ` }\n`;
71
+ result += `}\n`;
72
+ return result;
73
+ }
74
+ /**
75
+ * Generates a Figma header reference comment block
76
+ * /* Collection name: <collectionName> *\/
77
+ * /* Mode: <mode> *\/
78
+ *
79
+ * See https://www.figma.com/community/plugin/1470777269812001046/css-variables-import-export
80
+ */
81
+ function generateFigmaHeaderReference(collectionName, mode = "Light") {
82
+ return `/* Collection name: ${collectionName} */\n/* Mode: ${mode} */`;
83
+ }
@@ -0,0 +1,80 @@
1
+ import { getReferences, usesReferences } from 'style-dictionary/utils';
2
+ import { toKebab } from './helpers.js';
3
+ export function tokenName(token) {
4
+ const attrs = token.attributes;
5
+ const path = attrs?.item ? [attrs.category, attrs.type, attrs.item] : token.path;
6
+ return path.join('-');
7
+ }
8
+ // TODO:
9
+ export function resolveTokenReferences(token, options, dictionary, privateVar = false) {
10
+ const originalValue = token.original?.value;
11
+ // if (!shouldOutputReferences(token, options, dictionary)) {
12
+ // return originalValue != null
13
+ // ? cssValue(originalValue)
14
+ // : cssValue(token.value);
15
+ // }
16
+ if (!originalValue)
17
+ return cssValue(token.value);
18
+ // if (
19
+ // (originalValueParsed && originalValueParsed.startsWith("var(--")) ||
20
+ // originalValueParsed.startsWith("calc") ||
21
+ // originalValueParsed.startsWith("clamp")
22
+ // ) {
23
+ // ("📟 - cssValue(originalValue) → ", cssValue(originalValue));
24
+ // return originalValue;
25
+ // }
26
+ if (!usesReferences(originalValue))
27
+ return cssValue(token.value);
28
+ if (!shouldOutputReferences(token, options, dictionary)) {
29
+ return rewriteOriginalRefs(originalValue, dictionary.tokens, privateVar);
30
+ }
31
+ else {
32
+ return cssValue(originalValue);
33
+ }
34
+ }
35
+ export function refToTokenRefString(ref) {
36
+ // Verify if the ref is a style-dictionary reference object pattern or a direct var(--...) string
37
+ const refPath = ref.ref ?? ref.path;
38
+ return `{${refPath.join('.')}}`;
39
+ }
40
+ export function refToCssVar(ref, privateVar) {
41
+ return `var(--${privateVar ? '_' : ''}${toKebab(ref.name)})`;
42
+ }
43
+ const cssValue = (v) => {
44
+ if (v == null)
45
+ return '';
46
+ if (typeof v === 'string')
47
+ return v;
48
+ if (typeof v === 'number')
49
+ return String(v);
50
+ if (typeof v === 'boolean')
51
+ return v ? 'true' : 'false';
52
+ if (Array.isArray(v))
53
+ return v.join(',');
54
+ return JSON.stringify(v);
55
+ };
56
+ export function rewriteOriginalRefs(originalValue, dictionaryTokens, privateVar) {
57
+ if (typeof originalValue !== 'string' || !usesReferences(originalValue))
58
+ return null;
59
+ const refs = getReferences(originalValue, dictionaryTokens);
60
+ let out = originalValue;
61
+ for (const ref of refs) {
62
+ out = out.replaceAll(refToTokenRefString(ref), refToCssVar(ref, privateVar));
63
+ }
64
+ return out;
65
+ }
66
+ export function shouldOutputReferences(token, options, dictionary) {
67
+ const originalValue = token.original?.value;
68
+ if (!usesReferences(originalValue))
69
+ return false;
70
+ const originalValueParsed = cssValue(originalValue);
71
+ if ((originalValueParsed && originalValueParsed.startsWith('var(--')) ||
72
+ originalValueParsed.startsWith('calc') ||
73
+ originalValueParsed.startsWith('clamp')) {
74
+ return false;
75
+ }
76
+ const { usesDtcg, outputReferences } = options ?? {};
77
+ return typeof outputReferences === 'function'
78
+ ? outputReferences(token, { dictionary, usesDtcg })
79
+ : Boolean(outputReferences);
80
+ }
@@ -0,0 +1,19 @@
1
+ // src/utils/utopia.js
2
+ /**
3
+ * Generate a Utopia fluid type scale.
4
+ *
5
+ * Based on https://utopia.fyi/type/calculator/
6
+ * by James Gilyead & Trys Mudford
7
+ */
8
+ export function generateUtopiaScale({ minViewport = 360, maxViewport = 1280, minFont = 16, maxFont = 20, scaleMin = 1.2, scaleMax = 1.25, steps = [-2, -1, 0, 1, 2, 3, 4], } = {}) {
9
+ const results = {};
10
+ steps.forEach((step) => {
11
+ const minSize = minFont * scaleMin ** step;
12
+ const maxSize = maxFont * scaleMax ** step;
13
+ const slope = ((maxSize - minSize) / (maxViewport - minViewport)) * 100;
14
+ const intercept = minSize - (slope / 100) * minViewport;
15
+ const clampValue = `clamp(${minSize / 16}rem, ${intercept / 16}rem + ${slope}vw, ${maxSize / 16}rem)`;
16
+ results[step] = clampValue;
17
+ });
18
+ return results;
19
+ }
@@ -0,0 +1,67 @@
1
+ import css from '@eslint/css'
2
+ import js from '@eslint/js'
3
+ import json from '@eslint/json'
4
+ import markdown from '@eslint/markdown'
5
+ import { defineConfig } from 'eslint/config'
6
+ import globals from 'globals'
7
+
8
+ export default defineConfig([
9
+ {
10
+ ignores: [
11
+ 'dist/**',
12
+ 'build/**',
13
+ 'node_modules/**',
14
+ '**/package-lock.json',
15
+ '**/yarn.lock',
16
+ '**/pnpm-lock.yaml',
17
+ ],
18
+ },
19
+ {
20
+ files: ['**/*.{js,mjs,cjs, ts, mts}'],
21
+ plugins: { js },
22
+ extends: ['js/recommended'],
23
+ languageOptions: { globals: { ...globals.browser, ...globals.node } },
24
+ rules: {
25
+ 'no-console': 'error',
26
+ },
27
+ },
28
+ {
29
+ files: ['**/*.json'],
30
+ ignores: ['**/tokens/**/*.json'],
31
+ plugins: { json },
32
+ language: 'json/json',
33
+ extends: ['json/recommended'],
34
+ },
35
+ {
36
+ files: ['**/tokens/**/*.json'],
37
+ plugins: { json },
38
+ language: 'json/json5',
39
+ extends: ['json/recommended'],
40
+ },
41
+ {
42
+ files: ['**/*.json5'],
43
+ plugins: { json },
44
+ language: 'json/json5',
45
+ extends: ['json/recommended'],
46
+ },
47
+ {
48
+ files: ['**/*.md'],
49
+ plugins: { markdown },
50
+ language: 'markdown/commonmark',
51
+ extends: ['markdown/recommended'],
52
+ },
53
+ {
54
+ files: ['**/*.css'],
55
+ plugins: { css },
56
+ language: 'css/css',
57
+ extends: ['css/recommended'],
58
+ rules: {
59
+ 'css/no-invalid-properties': [
60
+ 'error',
61
+ {
62
+ allowUnknownVariables: true,
63
+ },
64
+ ],
65
+ },
66
+ },
67
+ ])
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "unholy-design-tokens",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "dist/build-tokens.js",
6
+ "module": "dist/build-tokens.js",
7
+ "types": "dist/build-tokens.d.ts",
8
+ "exports": {
9
+ "package.json": "./dist/package.json",
10
+ ".": {
11
+ "import": "./dist/build-tokens.js",
12
+ "require": "./dist/build-tokens.js"
13
+ }
14
+ },
15
+ "type": "module",
16
+ "scripts": {
17
+ "clean": "rm -rf build",
18
+ "tokens:typography": "node scripts/generate-typography-tokens.js",
19
+ "build:ts": "tsc",
20
+ "build": "pnpm run build:ts",
21
+ "prepack": "pnpm run build",
22
+ "build-tokens": "node scripts/generate-typography-tokens.js && pnpm run build:ts && node dist/build-tokens.js",
23
+ "build-tokens:verbose": "node scripts/generate-typography-tokens.js && pnpm run build:ts && node dist/build-tokens.js --verbose",
24
+ "build:verbose": "pnpm exec build-tokens -- --verbose",
25
+ "build-TODO:": "build-tokens -- --buildPath=./build/ --source=./src/tokens/ --destination=./build/ --test",
26
+ "lint": "eslint .",
27
+ "format": "prettier --write src/**/*.ts src/**/*.js",
28
+ "test": "echo \"Error: no test specified\" && exit 1"
29
+ },
30
+ "author": "",
31
+ "license": "Apache-2.0",
32
+ "devDependencies": {
33
+ "@eslint/css": "^0.14.1",
34
+ "@eslint/js": "^9.39.2",
35
+ "@eslint/json": "^0.14.0",
36
+ "@eslint/markdown": "^7.5.1",
37
+ "@types/node": "24.5.1",
38
+ "@types/tinycolor2": "1.4.6",
39
+ "eslint": "^9.39.2",
40
+ "eslint-config-prettier": "^10.1.8",
41
+ "globals": "^16.5.0",
42
+ "prettier": "3.7.4",
43
+ "style-dictionary": "^4.0.0-prerelease.30",
44
+ "tinycolor2": "1.6.0",
45
+ "prettier-plugin-organize-imports": "4.1.0",
46
+ "ts-node": "^10.9.2",
47
+ "tslib": "^2.8.1",
48
+ "tsx": "^4.21.0",
49
+ "typescript": "5.9.3",
50
+ "typescript-eslint": "^8.50.0"
51
+ },
52
+ "bin": {
53
+ "build-tokens": "./dist/bin/build-tokens.js"
54
+ },
55
+ "dependencies": {
56
+ "commander": "^14.0.2",
57
+ "install": "^0.13.0",
58
+ "turbowatch": "^2.29.4"
59
+ }
60
+ }
@@ -0,0 +1,44 @@
1
+ import path from 'node:path'
2
+ import StyleDictionary from 'style-dictionary'
3
+ import { logVerbosityLevels } from 'style-dictionary/enums'
4
+ import styleDictionaryConfig from '../src/style-dictionary.config'
5
+ import {
6
+ tokensDeclarationFormatter,
7
+ typesDeclarationFormatter,
8
+ } from '../src/type-declarations/type-declarations.formatter.js'
9
+ import { generateTypographyTokens } from './generate-typography-tokens'
10
+
11
+ function ensureTrailingSlash(p: string): string {
12
+ // Style Dictionary wants POSIX-ish trailing slash, even on Windows it accepts `/`
13
+ return p.endsWith(path.sep) ? p : p + path.sep
14
+ }
15
+
16
+ export async function buildStyleDictionary(outDir: string) {
17
+ // 1️⃣ Generate typography tokens FIRST
18
+ generateTypographyTokens()
19
+
20
+ // clone config so we can override buildPath safely
21
+ const config = {
22
+ ...styleDictionaryConfig,
23
+ platforms: Object.fromEntries(
24
+ Object.entries(styleDictionaryConfig.platforms).map(([name, platform]) => [
25
+ name,
26
+ { ...platform },
27
+ ]),
28
+ ),
29
+ }
30
+
31
+ for (const platform of Object.values(config.platforms)) {
32
+ platform.buildPath = ensureTrailingSlash(path.resolve(outDir, platform.buildPath ?? './build/'))
33
+ }
34
+
35
+ let sd = new StyleDictionary(config, {
36
+ verbosity: logVerbosityLevels.verbose,
37
+ })
38
+
39
+ // Types formatters
40
+ StyleDictionary.registerFormat(typesDeclarationFormatter)
41
+ StyleDictionary.registerFormat(tokensDeclarationFormatter)
42
+
43
+ await sd.buildAllPlatforms()
44
+ }
@@ -0,0 +1,138 @@
1
+ // scripts/generate-typography-tokens.js
2
+ // ---------------------------------------------------------
3
+ // Generate ALL typography tokens from primitives/font.json
4
+ // ---------------------------------------------------------
5
+
6
+ import fs from 'fs'
7
+ import path from 'path'
8
+ import { fileURLToPath } from 'url'
9
+ import { generateUtopiaScale } from '../src/utils'
10
+
11
+ const __filename = fileURLToPath(import.meta.url)
12
+ const __dirname = path.dirname(__filename)
13
+
14
+ const INPUT_FILE = path.join(__dirname, `../src/tokens/1 - primitives/font.json`)
15
+ const PRIMITIVES_OUT = path.join(__dirname, `../src/tokens/1 - primitives/font-scale.json`)
16
+ const INTENT_OUT = path.join(__dirname, '../src/tokens/3 - intent/font.json')
17
+
18
+ // -----------------------------------
19
+ // Load primitive inputs for typography
20
+ // -----------------------------------
21
+ export function generateTypographyTokens() {
22
+ if (!fs.existsSync(INPUT_FILE)) {
23
+ process.exit(1)
24
+ }
25
+
26
+ let configToken
27
+ try {
28
+ configToken = JSON.parse(fs.readFileSync(INPUT_FILE, 'utf8')).font
29
+ } catch {
30
+ process.exit(1)
31
+ }
32
+
33
+ const config = {
34
+ minFont: configToken.minFont?.value ?? 16,
35
+ maxFont: configToken.maxFont?.value ?? 20,
36
+ minViewport: configToken.minViewport?.value ?? 360,
37
+ maxViewport: configToken.maxViewport?.value ?? 1280,
38
+ scaleMin: configToken.scaleMin?.value ?? 1.2,
39
+ scaleMax: configToken.scaleMax?.value ?? 1.25,
40
+ steps: configToken.steps?.value ?? [0, 1, 2, 3, 4, 5, 6],
41
+ }
42
+
43
+ // -----------------------------------
44
+ // Build Utopia scale
45
+ // -----------------------------------
46
+
47
+ const scale = generateUtopiaScale(config)
48
+
49
+ // -----------------------------------
50
+ // Output primitive scale tokens
51
+ // -----------------------------------
52
+
53
+ const primitives = {
54
+ font: {
55
+ scale: Object.fromEntries(Object.entries(scale).map(([step, value]) => [step, { value }])),
56
+ },
57
+ }
58
+
59
+ // -----------------------------------
60
+ // Define intent tokens
61
+ // -----------------------------------
62
+
63
+ const intent = {
64
+ text: {
65
+ body: {
66
+ size: {
67
+ value: 'var(--font-scale-0)',
68
+ },
69
+ lineHeight: {
70
+ value: '1.5',
71
+ },
72
+ weight: {
73
+ value: 'var(--font-weight-regular)',
74
+ },
75
+ },
76
+ caption: {
77
+ size: {
78
+ value: 'var(--font-scale--2)',
79
+ },
80
+ lineHeight: {
81
+ value: '1.4',
82
+ },
83
+ weight: {
84
+ value: 'var(--font-weight-regular)',
85
+ },
86
+ },
87
+ small: {
88
+ size: {
89
+ value: 'var(--font-scale--1)',
90
+ },
91
+ lineHeight: {
92
+ value: '1.4',
93
+ },
94
+ weight: {
95
+ value: 'var(--font-weight-regular)',
96
+ },
97
+ },
98
+ },
99
+ heading: {
100
+ h1: {
101
+ size: {
102
+ value: 'var(--font-scale-4)',
103
+ },
104
+ lineHeight: {
105
+ value: '1.1',
106
+ },
107
+ weight: {
108
+ value: 'var(--font-weight-bold)',
109
+ },
110
+ },
111
+ h2: {
112
+ size: {
113
+ value: 'var(--font-scale-3)',
114
+ },
115
+ lineHeight: {
116
+ value: '1.15',
117
+ },
118
+ weight: {
119
+ value: 'var(--font-weight-bold)',
120
+ },
121
+ },
122
+ },
123
+ }
124
+
125
+ // -----------------------------------
126
+ // Write JSON files
127
+ // -----------------------------------
128
+
129
+ function writeJSON(file: string, data: unknown) {
130
+ const dir = path.dirname(file)
131
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
132
+ fs.writeFileSync(file, JSON.stringify(data, null, 2))
133
+ }
134
+
135
+ writeJSON(PRIMITIVES_OUT, primitives)
136
+ // writeJSON(SEMANTIC_OUT, semantic);
137
+ writeJSON(INTENT_OUT, intent)
138
+ }