{"_id":"@designesy/stylelint-plugin-dtcg-tokens","_rev":"5-34f2ab03c7eb342115fbcda888e30284","name":"@designesy/stylelint-plugin-dtcg-tokens","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"@designesy/stylelint-plugin-dtcg-tokens","version":"0.1.0","keywords":["stylelint","stylelint-plugin","postcss","postcss-plugin","design-tokens","dtcg","w3c","design-tokens-community-group","token-validation","design-system","lint","css","designesy"],"author":{"name":"Designesy","email":"hello@designesy.org"},"license":"MIT","_id":"@designesy/stylelint-plugin-dtcg-tokens@0.1.0","maintainers":[{"name":"designesy","email":"le@designesy.org"}],"homepage":"https://www.designesy.org/contracts/tokens","bugs":{"url":"https://github.com/LE-VAI/designesy-org/issues"},"dist":{"shasum":"356d36e791faec9662a8813d28385644e228e743","tarball":"https://registry.npmjs.org/@designesy/stylelint-plugin-dtcg-tokens/-/stylelint-plugin-dtcg-tokens-0.1.0.tgz","fileCount":10,"integrity":"sha512-82AUA4JcWmC6/fn9WMe/2s2WlLI2s7QQyyQh90VDUc20hhkL26LstxB8zNPJpAfy/eCD1DzqNozEP8/k5d/00Q==","signatures":[{"sig":"MEMCIDRGaFmkiKcrzPEE8kxshtcRawJV5cnxIXWKyTZviWw1Ah9rsrp+zJ/mf4I1uWF8KPR1aFrIDBDTI6cCgheBuUp0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":40520},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./tokens":{"types":"./dist/tokens.d.ts","import":"./dist/tokens.js"},"./postcss":{"types":"./dist/postcss-plugin.d.ts","import":"./dist/postcss-plugin.js"}},"gitHead":"21f6d47939895f2cdbc6ffcc64dfd6b57224c4b0","scripts":{"test":"node --test test/test.js","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"designesy","email":"le@designesy.org"},"repository":{"url":"git+https://github.com/LE-VAI/designesy-org.git","type":"git","directory":"packages/stylelint-plugin-dtcg-tokens"},"_npmVersion":"11.12.1","description":"stylelint + PostCSS plugin that enforces DTCG 2025.10 design token usage in CSS — no bare hex, no magic numbers, no undeclared var() references.","directories":{},"_nodeVersion":"24.15.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"postcss":"^8.4.0","typescript":"^5.7.0","@types/node":"^26.2.0"},"peerDependencies":{"postcss":">=8.0.0"},"peerDependenciesMeta":{"stylelint":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/stylelint-plugin-dtcg-tokens_0.1.0_1786810573212_0.3000550995311293","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@designesy/stylelint-plugin-dtcg-tokens","version":"0.1.1","keywords":["stylelint","stylelint-plugin","postcss","postcss-plugin","design-tokens","dtcg","w3c","design-tokens-community-group","token-validation","design-system","lint","css","designesy"],"author":{"name":"Designesy","email":"hello@designesy.org"},"license":"MIT","_id":"@designesy/stylelint-plugin-dtcg-tokens@0.1.1","maintainers":[{"name":"designesy","email":"le@designesy.org"}],"homepage":"https://www.designesy.org/contracts/tokens","bugs":{"url":"https://github.com/LE-VAI/designesy-org/issues"},"dist":{"shasum":"9c29d1a5d27c6cf4ce0cc1bd175bc5541280f326","tarball":"https://registry.npmjs.org/@designesy/stylelint-plugin-dtcg-tokens/-/stylelint-plugin-dtcg-tokens-0.1.1.tgz","fileCount":10,"integrity":"sha512-xCrd5t0VPlTzR9egxrz/EBPBEOuvB8tXMOuFeBxn2UWKKPshH43LERRSo947Dq37Ti8Lc0qjAdVUUu5gDBDDnw==","signatures":[{"sig":"MEQCIFD1mXcCH/98h1Ji+gKVVvq7pJR92dixMBj7fQh221SoAiB5Rwh4jWvIfWa+hwbAsDpYAWpzNGUGa9ep1OGYL/crkg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@designesy%2fstylelint-plugin-dtcg-tokens@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":40768},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./tokens":{"types":"./dist/tokens.d.ts","import":"./dist/tokens.js"},"./postcss":{"types":"./dist/postcss-plugin.d.ts","import":"./dist/postcss-plugin.js"}},"gitHead":"e5c1b4570a4b0de45f68ab27c041d4f2cf2083a6","scripts":{"test":"node --test test/test.js","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"designesy","email":"le@designesy.org"},"repository":{"url":"git+https://github.com/LE-VAI/designesy-org.git","type":"git","directory":"packages/stylelint-plugin-dtcg-tokens"},"_npmVersion":"10.9.8","description":"stylelint + PostCSS plugin that enforces DTCG 2025.10 design token usage in CSS — no bare hex, no magic numbers, no undeclared var() references.","directories":{},"_nodeVersion":"22.23.2","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"postcss":"^8.4.0","typescript":"^5.7.0","@types/node":"^26.2.0"},"peerDependencies":{"postcss":">=8.0.0"},"peerDependenciesMeta":{"stylelint":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/stylelint-plugin-dtcg-tokens_0.1.1_1786811503542_0.34481960290772995","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@designesy/stylelint-plugin-dtcg-tokens","version":"0.2.0","keywords":["stylelint","stylelint-plugin","postcss","postcss-plugin","design-tokens","dtcg","w3c","design-tokens-community-group","token-validation","design-system","lint","css","designesy"],"author":{"name":"Designesy","email":"hello@designesy.org"},"license":"MIT","_id":"@designesy/stylelint-plugin-dtcg-tokens@0.2.0","maintainers":[{"name":"designesy","email":"le@designesy.org"}],"homepage":"https://www.designesy.org/contracts/tokens","bugs":{"url":"https://github.com/LE-VAI/designesy-org/issues"},"dist":{"shasum":"3b4ccf2b9b428c8ecd89766266a338064771da73","tarball":"https://registry.npmjs.org/@designesy/stylelint-plugin-dtcg-tokens/-/stylelint-plugin-dtcg-tokens-0.2.0.tgz","fileCount":10,"integrity":"sha512-/GmyBJIISKzkh6CETPyF2Kq+eDD6stnx4/v7iZbDEPkCWmBkzzYDmv4OS0cM2axvdzHb+6wHAsRaM3mV9c4R/Q==","signatures":[{"sig":"MEQCIFsWFdTtjojsBcDeg/Gij34PxLXXOgQyk6Ke5/GcF005AiBAkJ7d4GYOZvdFlxaIQ9dWSIX+nFmxqQROcVJ2pEglmw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@designesy%2fstylelint-plugin-dtcg-tokens@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":58492},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./tokens":{"types":"./dist/tokens.d.ts","import":"./dist/tokens.js"},"./postcss":{"types":"./dist/postcss-plugin.d.ts","import":"./dist/postcss-plugin.js"}},"gitHead":"cae65a2a215036513bc96655c647ed0a46e2fadb","scripts":{"test":"node --test test/test.js","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"designesy","email":"le@designesy.org"},"repository":{"url":"git+https://github.com/LE-VAI/designesy-org.git","type":"git","directory":"packages/stylelint-plugin-dtcg-tokens"},"_npmVersion":"10.9.8","description":"stylelint + PostCSS plugin that enforces DTCG 2025.10 design token usage in CSS — no bare hex, no magic numbers, no undeclared var() references.","directories":{},"_nodeVersion":"22.23.2","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"postcss":"^8.4.0","stylelint":"^16.0.0","typescript":"^5.7.0","@types/node":"^26.2.0"},"peerDependencies":{"postcss":">=8.0.0","stylelint":">=16.0.0"},"peerDependenciesMeta":{"stylelint":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/stylelint-plugin-dtcg-tokens_0.2.0_1786812687432_0.6580855914088501","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@designesy/stylelint-plugin-dtcg-tokens","version":"0.2.1","keywords":["stylelint","stylelint-plugin","postcss","postcss-plugin","design-tokens","dtcg","w3c","design-tokens-community-group","token-validation","design-system","lint","css","designesy"],"author":{"name":"Designesy","email":"hello@designesy.org"},"license":"MIT","_id":"@designesy/stylelint-plugin-dtcg-tokens@0.2.1","maintainers":[{"name":"designesy","email":"le@designesy.org"}],"homepage":"https://www.designesy.org/contracts/tokens","bugs":{"url":"https://github.com/LE-VAI/designesy-org/issues"},"dist":{"shasum":"6a07bcbaa892b300a7d3cd28ce2afd467dff98b2","tarball":"https://registry.npmjs.org/@designesy/stylelint-plugin-dtcg-tokens/-/stylelint-plugin-dtcg-tokens-0.2.1.tgz","fileCount":10,"integrity":"sha512-VEFuc+eZtd+ZKLQrXFWcnc3tKk9BdrCP5we5VMH2GN67woNx8o4IJqgSBaxnL+J5ZW/5DPzuTlfo8l0R8hRmcw==","signatures":[{"sig":"MEUCIQDTJNQyBIZvRXsFNqliA9dqF+f6G0+ywxprFS8l92WaWAIgJttrEiI06kraqrBuU/Y9fdBwAPk2Bja8SMg1IPi16A0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@designesy%2fstylelint-plugin-dtcg-tokens@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":59957},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./tokens":{"types":"./dist/tokens.d.ts","import":"./dist/tokens.js"},"./postcss":{"types":"./dist/postcss-plugin.d.ts","import":"./dist/postcss-plugin.js"}},"gitHead":"d08f1a14c3d00102c51c8e0ab481fe80ace613c2","scripts":{"test":"node --test test/test.js","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"designesy","email":"le@designesy.org"},"repository":{"url":"git+https://github.com/LE-VAI/designesy-org.git","type":"git","directory":"packages/stylelint-plugin-dtcg-tokens"},"_npmVersion":"10.9.8","description":"stylelint + PostCSS plugin that enforces DTCG 2025.10 design token usage in CSS — no bare hex, no magic numbers, no undeclared var() references.","directories":{},"_nodeVersion":"22.23.2","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"postcss":"^8.4.0","stylelint":"^16.0.0","typescript":"^5.7.0","@types/node":"^26.2.0"},"peerDependencies":{"postcss":">=8.0.0","stylelint":">=16.0.0"},"peerDependenciesMeta":{"stylelint":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/stylelint-plugin-dtcg-tokens_0.2.1_1786813637992_0.7403890540527043","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@designesy/stylelint-plugin-dtcg-tokens","version":"0.2.2","description":"stylelint + PostCSS plugin that enforces DTCG 2025.10 design token usage in CSS — no bare hex, no magic numbers, no undeclared var() references.","license":"MIT","author":{"name":"Designesy","email":"hello@designesy.org"},"maintainers":[{"name":"designesy","email":"le@designesy.org"}],"homepage":"https://www.designesy.org/contracts/tokens","repository":{"type":"git","url":"git+https://github.com/LE-VAI/designesy-org.git","directory":"packages/stylelint-plugin-dtcg-tokens"},"bugs":{"url":"https://github.com/LE-VAI/designesy-org/issues"},"keywords":["stylelint","stylelint-plugin","postcss","postcss-plugin","design-tokens","dtcg","w3c","design-tokens-community-group","token-validation","design-system","lint","css","designesy"],"type":"module","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./postcss":{"import":"./dist/postcss-plugin.js","types":"./dist/postcss-plugin.d.ts"},"./tokens":{"import":"./dist/tokens.js","types":"./dist/tokens.d.ts"}},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"peerDependencies":{"postcss":">=8.0.0","stylelint":">=16.0.0"},"peerDependenciesMeta":{"stylelint":{"optional":true}},"devDependencies":{"@types/node":"^26.2.0","postcss":"^8.4.0","stylelint":"^16.0.0","typescript":"^5.7.0"},"dependencies":{},"scripts":{"build":"tsc -p tsconfig.json","test":"node --test test/test.js","pretest":"npm run build","prepublishOnly":"npm run build"},"_id":"@designesy/stylelint-plugin-dtcg-tokens@0.2.2","gitHead":"4a6b9b8512a85fa8bd21d37a056b6e3786a49ee0","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-eP/tLbp02564wn+qWkf8t/h/UEW+pqA4EV8m7K790q2cOonYxmMZCtwb2RjhojDPGFyJzpYRiaXYmUluiuJ/Rg==","shasum":"7f240bfa0db09d49f2f8f583aac45a2538dc7935","tarball":"https://registry.npmjs.org/@designesy/stylelint-plugin-dtcg-tokens/-/stylelint-plugin-dtcg-tokens-0.2.2.tgz","fileCount":10,"unpackedSize":59801,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@designesy%2fstylelint-plugin-dtcg-tokens@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCSzrcgm29QB+fyAykue3N4lwSpZ6lrK9CxBLl/q451oAIhAKiIGmSF9Y7OReEi7FOXUArBAcmoaKhDBj4HZIg5JWXf"}]},"_npmUser":{"name":"designesy","email":"le@designesy.org"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stylelint-plugin-dtcg-tokens_0.2.2_1786847090491_0.1359315344659755"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-15T16:16:13.020Z","modified":"2026-08-16T02:24:50.918Z","0.1.0":"2026-08-15T16:16:13.343Z","0.1.1":"2026-08-15T16:31:43.665Z","0.2.0":"2026-08-15T16:51:27.584Z","0.2.1":"2026-08-15T17:07:18.108Z","0.2.2":"2026-08-16T02:24:50.633Z"},"bugs":{"url":"https://github.com/LE-VAI/designesy-org/issues"},"author":{"name":"Designesy","email":"hello@designesy.org"},"license":"MIT","homepage":"https://www.designesy.org/contracts/tokens","keywords":["stylelint","stylelint-plugin","postcss","postcss-plugin","design-tokens","dtcg","w3c","design-tokens-community-group","token-validation","design-system","lint","css","designesy"],"repository":{"type":"git","url":"git+https://github.com/LE-VAI/designesy-org.git","directory":"packages/stylelint-plugin-dtcg-tokens"},"description":"stylelint + PostCSS plugin that enforces DTCG 2025.10 design token usage in CSS — no bare hex, no magic numbers, no undeclared var() references.","maintainers":[{"name":"designesy","email":"le@designesy.org"}],"readme":"# @designesy/stylelint-plugin-dtcg-tokens\n\n[![npm version](https://img.shields.io/npm/v/@designesy/stylelint-plugin-dtcg-tokens?color=blue&label=npm)](https://www.npmjs.com/package/@designesy/stylelint-plugin-dtcg-tokens)\n[![license](https://img.shields.io/npm/l/@designesy/stylelint-plugin-dtcg-tokens?color=green)](./LICENSE)\n[![CI](https://github.com/LE-VAI/designesy-org/actions/workflows/ci.yml/badge.svg)](https://github.com/LE-VAI/designesy-org/actions/workflows/ci.yml)\n[![dependencies](https://img.shields.io/badge/dependencies-0-blue)](./package.json)\n[![DTCG](https://img.shields.io/badge/DTCG-2025.10-blue)](https://www.designtokens.org/)\n[![Node](https://img.shields.io/badge/node-%3E%3D18-green)](./package.json)\n\nstylelint + PostCSS plugin that enforces DTCG 2025.10 design token usage in CSS. Catches bare hex colors, magic numbers, and undeclared `var()` references at lint time — before they reach production. Supports `--fix` to auto-replace unambiguous bare values with `var(--token)` references.\n\n## Why\n\nDesign tokens are the contract between design and code. But CSS is permissive — nothing stops a developer from writing `color: #ff0000` instead of `color: var(--color-danger)`. Over time, bare values accumulate, the token system erodes, and you get **token drift**: the gap between what your design system says and what your code actually does.\n\nThis plugin closes that gap at lint time, the same way `eslint` catches unused variables.\n\n## Install\n\n```bash\nnpm install --save-dev @designesy/stylelint-plugin-dtcg-tokens stylelint\n```\n\nFor PostCSS-only usage (no stylelint):\n\n```bash\nnpm install --save-dev @designesy/stylelint-plugin-dtcg-tokens postcss\n```\n\n## Rules\n\n### `designesy/no-bare-hex`\n\nFlags hex color values that should use `var(--token)` instead.\n\n```css\n/* ❌ Bad */\n.button { color: #ff0000; }\n\n/* ✅ Good */\n.button { color: var(--color-danger); }\n```\n\n### `designesy/no-magic-number`\n\nFlags bare `px`/`rem` values on token-enforced properties — the properties where design systems typically require tokens: `padding`, `margin`, `font-size`, `gap`, `border-radius`, `width`, `height`, `box-shadow`, etc.\n\n```css\n/* ❌ Bad */\n.card { padding: 12px; font-size: 18px; }\n\n/* ✅ Good */\n.card { padding: var(--space-sm); font-size: var(--font-size-lg); }\n```\n\n### `designesy/no-undeclared-var`\n\nFlags `var()` references to custom properties not declared in your DTCG token file or in any `:root` block. Catches typos like `var(--colr-primary)` and references to tokens that were removed.\n\n```css\n/* ❌ Bad — --color-unknown is not in the token file */\n.modal { color: var(--color-unknown); }\n\n/* ✅ Good — --color-primary is in the token file */\n.modal { color: var(--color-primary); }\n\n/* ✅ Good — --local-var is declared in CSS, even if not in the token file */\n:root { --local-var: 100px; }\n.sidebar { width: var(--local-var); }\n```\n\n## Usage\n\n### stylelint\n\n```json\n// .stylelintrc.json\n{\n  \"plugins\": [\"@designesy/stylelint-plugin-dtcg-tokens\"],\n  \"rules\": {\n    \"designesy/no-bare-hex\": [true, { \"tokensFile\": \"./design-tokens.json\" }],\n    \"designesy/no-magic-number\": [true, { \"tokensFile\": \"./design-tokens.json\" }],\n    \"designesy/no-undeclared-var\": [true, { \"tokensFile\": \"./design-tokens.json\" }]\n  }\n}\n```\n\nThe `tokensFile` option is a path to a DTCG 2025.10 token JSON file, resolved relative to `process.cwd()`.\n\n### PostCSS (standalone)\n\n```js\n// postcss.config.js\nimport dtcgTokenCheck from '@designesy/stylelint-plugin-dtcg-tokens/postcss';\n\nexport default {\n  plugins: [\n    dtcgTokenCheck({\n      tokensFile: './design-tokens.json',\n      rules: {\n        bareHex: true,\n        magicNumber: true,\n        undeclaredVar: true,\n      },\n    }),\n  ],\n};\n```\n\nWarnings are emitted via PostCSS's `node.warn()` — they appear in your build output and can be collected by downstream tools.\n\n## Auto-fix (`--fix`)\n\nBoth the stylelint plugin and the standalone PostCSS plugin support auto-fixing unambiguous violations:\n\n### stylelint\n\n```bash\nnpx stylelint --fix \"**/*.css\"\n```\n\n### PostCSS\n\n```js\ndtcgTokenCheck({\n  tokensFile: './design-tokens.json',\n  fix: true,  // ← auto-replace bare values in-place\n})\n```\n\n### What gets fixed\n\n| Rule | Auto-fixed? | How |\n|---|---|---|\n| no-bare-hex | ✅ When the hex maps to exactly 1 color token | `#3b82f6` → `var(--color-primary)` |\n| no-magic-number | ✅ When the value maps to exactly 1 token after property-semantic disambiguation | `16px` on `padding` → `var(--space-md)`, `16px` on `border-radius` → `var(--radius-lg)` |\n| no-undeclared-var | ❌ Never — can't infer what the author meant to reference |\n\n### Property-semantic disambiguation\n\nDimension values often collide across token groups — `16px` might be `--space-md`, `--radius-lg`, AND `--font-size-md`. The fix engine uses the CSS property name to pick the right group:\n\n- `padding: 16px` → space group → `var(--space-md)`\n- `border-radius: 16px` → radius group → `var(--radius-lg)`\n- `font-size: 16px` → font-size group → `var(--font-size-md)`\n\nWhen a value maps to multiple tokens even after disambiguation (e.g. `4px` on the `border` shorthand, which could be space or radius), the violation is **warned but not fixed** — you decide which token to use.\n\n### Framework integrations\n\n#### Tailwind CSS (PostCSS pipeline)\n\n```js\n// postcss.config.js\nimport dtcgTokenCheck from '@designesy/stylelint-plugin-dtcg-tokens/postcss';\n\nexport default {\n  plugins: [\n    dtcgTokenCheck({ tokensFile: './design-tokens.json' }),\n    // ... tailwindcss, autoprefixer, etc.\n  ],\n};\n```\n\n#### CSS Modules (webpack)\n\n```js\n// webpack.config.js\nimport dtcgTokenCheck from '@designesy/stylelint-plugin-dtcg-tokens/postcss';\n\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        test: /\\.module\\.css$/,\n        use: [\n          'style-loader',\n          { loader: 'css-loader', options: { modules: true } },\n          {\n            loader: 'postcss-loader',\n            options: {\n              postcssOptions: {\n                plugins: [\n                  dtcgTokenCheck({ tokensFile: './design-tokens.json' }),\n                ],\n              },\n            },\n          },\n        ],\n      },\n    ],\n  },\n};\n```\n\n#### Vite\n\n```js\n// vite.config.js\nimport dtcgTokenCheck from '@designesy/stylelint-plugin-dtcg-tokens/postcss';\n\nexport default {\n  css: {\n    postcss: {\n      plugins: [\n        dtcgTokenCheck({ tokensFile: './design-tokens.json' }),\n      ],\n    },\n  },\n};\n```\n\n#### Next.js\n\n```js\n// next.config.mjs\nimport dtcgTokenCheck from '@designesy/stylelint-plugin-dtcg-tokens/postcss';\n\nexport default {\n  webpack(config) {\n    config.module.rules.push({\n      test: /\\.css$/,\n      use: {\n        loader: 'postcss-loader',\n        options: {\n          postcssOptions: {\n            plugins: [\n              dtcgTokenCheck({ tokensFile: './design-tokens.json' }),\n            ],\n          },\n        },\n      },\n    });\n    return config;\n  },\n};\n```\n\n## Token File Format\n\nThe plugin expects a [DTCG 2025.10](https://www.designtokens.org/) token JSON file:\n\n```json\n{\n  \"$schema\": \"https://www.designtokens.org/schemas/2025.10/format.json\",\n  \"color\": {\n    \"primary\": { \"$type\": \"color\", \"$value\": \"#3b82f6\" },\n    \"danger\": { \"$type\": \"color\", \"$value\": \"#ef4444\" }\n  },\n  \"space\": {\n    \"sm\": { \"$type\": \"dimension\", \"$value\": \"8px\" },\n    \"md\": { \"$type\": \"dimension\", \"$value\": \"16px\" }\n  }\n}\n```\n\nDot-path groups become hyphenated CSS custom property names:\n- `color.primary` → `--color-primary`\n- `font.size.lg` → `--font-size-lg`\n\nBoth DTCG alias forms are supported:\n- `$ref: \"color.base.red\"` → resolved as `var(--color-base-red)`\n- `$value: \"{color.base.red}\"` → resolved as `var(--color-base-red)`\n\n## Programmatic API\n\n```typescript\nimport {\n  flattenTokens, extractVarRefs, isBareHex, isMagicNumber,\n  normalizeHex, buildReverseMap, resolveToken,\n} from '@designesy/stylelint-plugin-dtcg-tokens/tokens';\n\n// Flatten a DTCG token file into CSS custom property names\nconst tokens = flattenTokens(parsedTokenJson);\ntokens.get('--color-primary'); // { name, value, type, description, deprecated }\n\n// Extract var() references from a CSS value\nextractVarRefs('var(--space-md) var(--space-lg)'); // ['--space-md', '--space-lg']\n\n// Check if a CSS value is a bare hex color\nisBareHex('#ff0000'); // true\nisBareHex('var(--color-danger)'); // false\n\n// Check if a value is a magic number on an enforced property\nisMagicNumber('padding', '12px'); // true\nisMagicNumber('padding', 'var(--space-sm)'); // false\n\n// Build a reverse value→token map for auto-fix lookups\nconst reverseMap = buildReverseMap(tokens);\nreverseMap.get('#3b82f6'); // [FlattenedToken] — color tokens matching this hex\n\n// Resolve a CSS value to a single token using property-semantic disambiguation\nresolveToken('16px', 'padding', reverseMap, false); // { token: { name: '--space-md', ... } }\nresolveToken('16px', 'border-radius', reverseMap, false); // { token: { name: '--radius-lg', ... } }\nresolveToken('4px', 'border', reverseMap, false); // { ambiguous: [...] } — can't disambiguate\n\n// Normalize hex for lookup (lowercase + expand 3-digit to 6-digit)\nnormalizeHex('#FFF'); // '#ffffff'\n```\n\n## GitHub Actions\n\n```yaml\nname: Lint CSS\non: [pull_request]\npermissions:\n  contents: read\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7\n      - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7\n        with:\n          node-version: '22'\n      - run: npm ci\n      - run: npx stylelint \"**/*.css\"\n```\n\n## Spec Reference\n\n- [W3C Design Tokens Format Module 2025.10](https://www.designtokens.org/)\n- [DTCG JSON Schema](https://www.designtokens.org/schemas/2025.10/format.json)\n- [Designesy Tokens Contract](https://www.designesy.org/contracts/tokens)\n- [Designesy Tokens Validator](https://www.npmjs.com/package/@designesy/tokens) — companion CLI that validates the token file itself\n\n## License\n\nMIT © [Designesy](https://www.designesy.org)","readmeFilename":"README.md"}