feat(tokens): STYLE-001 MVP complete - 10 default tokens system

- Implemented StyleTokensModel for managing design tokens
- Added StyleTokensInjector to inject tokens into viewer preview
- 10 essential default tokens (primary, background, foreground, border, spacing, radius, shadows)
- Token storage in project metadata (styleTokens field)
- Real-time CSS variable injection in preview
- Fixed bug: tokens now inject for legacy projects without styleTokens field
- Tested and validated (see TEST-REPORT.md)

MVP does NOT include:
- UI panel for editing tokens
- Token picker component
- Import/export functionality
- Full token set (only 10 essentials)

These features are planned for STYLE-001 Full implementation.
This commit is contained in:
Tara West
2026-01-15 10:04:27 +01:00
parent aa814e17b9
commit 505de200ce
5 changed files with 552 additions and 108 deletions

142
package-lock.json generated
View File

@@ -40,13 +40,13 @@
"license": "MIT"
},
"node_modules/@ai-sdk/gateway": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.18.tgz",
"integrity": "sha512-sDQcW+6ck2m0pTIHW6BPHD7S125WD3qNkx/B8sEzJp/hurocmJ5Cni0ybExg6sQMGo+fr/GWOwpHF1cmCdg5rQ==",
"version": "2.0.25",
"resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.25.tgz",
"integrity": "sha512-Rq+FX55ne7lMiqai7NcvvDZj4HLsr+hg77WayqmySqc6zhw3tIOLxd4Ty6OpwNj0C0bVMi3iCl2zvJIEirh9XA==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider-utils": "3.0.18",
"@ai-sdk/provider": "2.0.1",
"@ai-sdk/provider-utils": "3.0.20",
"@vercel/oidc": "3.0.5"
},
"engines": {
@@ -57,9 +57,9 @@
}
},
"node_modules/@ai-sdk/provider": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz",
"integrity": "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.1.tgz",
"integrity": "sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng==",
"license": "Apache-2.0",
"dependencies": {
"json-schema": "^0.4.0"
@@ -69,12 +69,12 @@
}
},
"node_modules/@ai-sdk/provider-utils": {
"version": "3.0.18",
"resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz",
"integrity": "sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ==",
"version": "3.0.20",
"resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.20.tgz",
"integrity": "sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider": "2.0.1",
"@standard-schema/spec": "^1.0.0",
"eventsource-parser": "^3.0.6"
},
@@ -6207,9 +6207,9 @@
}
},
"node_modules/@standard-schema/spec": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
"license": "MIT"
},
"node_modules/@storybook/addon-actions": {
@@ -6579,13 +6579,13 @@
}
},
"node_modules/@storybook/core": {
"version": "8.6.14",
"resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.14.tgz",
"integrity": "sha512-1P/w4FSNRqP8j3JQBOi3yGt8PVOgSRbP66Ok520T78eJBeqx9ukCfl912PQZ7SPbW3TIunBwLXMZOjZwBB/JmA==",
"version": "8.6.15",
"resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.15.tgz",
"integrity": "sha512-VFpKcphNurJpSC4fpUfKL3GTXVoL53oytghGR30QIw5jKWwaT50HVbTyb41BLOUuZjmMhUQA8weiQEew6RX0gw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/theming": "8.6.14",
"@storybook/theming": "8.6.15",
"better-opn": "^3.0.2",
"browser-assert": "^1.2.1",
"esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0",
@@ -6627,6 +6627,20 @@
"storybook": "^8.6.14"
}
},
"node_modules/@storybook/core/node_modules/@storybook/theming": {
"version": "8.6.15",
"resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.15.tgz",
"integrity": "sha512-dAbL0XOekyT6XsF49R6Etj3WxQ/LpdJDIswUUeHgVJ6/yd2opZOGbPxnwA3zlmAh1c0tvpPyhSDXxSG79u8e4Q==",
"dev": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
}
},
"node_modules/@storybook/core/node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
@@ -8974,14 +8988,14 @@
}
},
"node_modules/ai": {
"version": "5.0.108",
"resolved": "https://registry.npmjs.org/ai/-/ai-5.0.108.tgz",
"integrity": "sha512-Jex3Lb7V41NNpuqJHKgrwoU6BCLHdI1Pg4qb4GJH4jRIDRXUBySJErHjyN4oTCwbiYCeb/8II9EnqSRPq9EifA==",
"version": "5.0.119",
"resolved": "https://registry.npmjs.org/ai/-/ai-5.0.119.tgz",
"integrity": "sha512-HUOwhc17fl2SZTJGZyA/99aNu706qKfXaUBCy9vgZiXBwrxg2eTzn2BCz7kmYDsfx6Fg2ACBy2icm41bsDXCTw==",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/gateway": "2.0.18",
"@ai-sdk/provider": "2.0.0",
"@ai-sdk/provider-utils": "3.0.18",
"@ai-sdk/gateway": "2.0.25",
"@ai-sdk/provider": "2.0.1",
"@ai-sdk/provider-utils": "3.0.20",
"@opentelemetry/api": "1.9.0"
},
"engines": {
@@ -9083,9 +9097,9 @@
}
},
"node_modules/algoliasearch-helper": {
"version": "3.26.1",
"resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.26.1.tgz",
"integrity": "sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw==",
"version": "3.27.0",
"resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.27.0.tgz",
"integrity": "sha512-eNYchRerbsvk2doHOMfdS1/B6Tm70oGtu8mzQlrNzbCeQ8p1MjCW8t/BL6iZ5PD+cL5NNMgTMyMnmiXZ1sgmNw==",
"license": "MIT",
"dependencies": {
"@algolia/events": "^4.0.1"
@@ -16613,9 +16627,9 @@
}
},
"node_modules/instantsearch-ui-components": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/instantsearch-ui-components/-/instantsearch-ui-components-0.15.1.tgz",
"integrity": "sha512-IpBtPYt4HHAd8lCPziMIqfvcAIeSQD8teZxhGfzCj6520GHwucYr37fMWjUPlLs/bygS+2a6zwQf3amfeekaag==",
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/instantsearch-ui-components/-/instantsearch-ui-components-0.16.0.tgz",
"integrity": "sha512-3CoUlEqiFgQ1cd/y90aPi355JVMY757XSrpojC1m8blLPW0nokx4AwH723dHUGU2MtvI0U49dB2F5EGUS0FZkA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6",
@@ -16626,9 +16640,9 @@
}
},
"node_modules/instantsearch.js": {
"version": "4.85.0",
"resolved": "https://registry.npmjs.org/instantsearch.js/-/instantsearch.js-4.85.0.tgz",
"integrity": "sha512-46WIVx5A6nFnRKpGiXidJS7NUFbB6TFK21h9z7sRu9YltnZw/RsUwtHwb/TVzAUnSgjqACM4pRAgqNvidGvydg==",
"version": "4.86.1",
"resolved": "https://registry.npmjs.org/instantsearch.js/-/instantsearch.js-4.86.1.tgz",
"integrity": "sha512-ETazkxnWj3aOsHgQem1JQ4roqhfpkA32CZEW+ccP+rQqSbO4sCEEMJTy1A1BMiTD1iCoBFWD+x+8Bx73DOm/Gg==",
"license": "MIT",
"dependencies": {
"@algolia/events": "^4.0.1",
@@ -16637,12 +16651,12 @@
"@types/hogan.js": "^3.0.0",
"@types/qs": "^6.5.3",
"ai": "^5.0.18",
"algoliasearch-helper": "3.26.1",
"algoliasearch-helper": "3.27.0",
"hogan.js": "^3.0.2",
"htm": "^3.0.0",
"instantsearch-ui-components": "0.15.1",
"instantsearch-ui-components": "0.16.0",
"preact": "^10.10.0",
"qs": "^6.5.1 < 6.10",
"qs": "^6.5.1",
"react": ">= 0.14.0",
"search-insights": "^2.17.2",
"zod": "^3.25.76 || ^4",
@@ -16652,18 +16666,6 @@
"algoliasearch": ">= 3.1 < 6"
}
},
"node_modules/instantsearch.js/node_modules/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz",
"integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
@@ -23064,9 +23066,9 @@
"license": "MIT"
},
"node_modules/preact": {
"version": "10.28.0",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.28.0.tgz",
"integrity": "sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==",
"version": "10.28.2",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.28.2.tgz",
"integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==",
"license": "MIT",
"funding": {
"type": "opencollective",
@@ -23510,9 +23512,9 @@
"license": "MIT"
},
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"version": "6.14.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
@@ -23769,15 +23771,15 @@
}
},
"node_modules/react-instantsearch": {
"version": "7.20.1",
"resolved": "https://registry.npmjs.org/react-instantsearch/-/react-instantsearch-7.20.1.tgz",
"integrity": "sha512-AiK7cyNhAdsduDnmiKa/16dTbC7aJGG86CLF/A7Nj+hiNFDm0ELUxu120cfeHOPw8WZFKkTUmnI6Og0x4S56yg==",
"version": "7.22.1",
"resolved": "https://registry.npmjs.org/react-instantsearch/-/react-instantsearch-7.22.1.tgz",
"integrity": "sha512-sTZ8z2JcSyveP0RmClmP9KFkJMQ9ZZmZKI05uSmfx7fP21N8Ry9CCyn2EvalGFm2gTPaB7VMFZrC9q7HXvG9wA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6",
"instantsearch-ui-components": "0.15.1",
"instantsearch.js": "4.85.0",
"react-instantsearch-core": "7.20.1"
"instantsearch-ui-components": "0.16.0",
"instantsearch.js": "4.86.1",
"react-instantsearch-core": "7.22.1"
},
"peerDependencies": {
"algoliasearch": ">= 3.1 < 6",
@@ -23786,15 +23788,15 @@
}
},
"node_modules/react-instantsearch-core": {
"version": "7.20.1",
"resolved": "https://registry.npmjs.org/react-instantsearch-core/-/react-instantsearch-core-7.20.1.tgz",
"integrity": "sha512-GMC/F2RldOKyiWP5Sie00W+eC8lvE/CiNZ0tYJoChr9vbSzzpA88zhRl+j9LTnMMsaq4vM13/R/1ENA7/AXgdQ==",
"version": "7.22.1",
"resolved": "https://registry.npmjs.org/react-instantsearch-core/-/react-instantsearch-core-7.22.1.tgz",
"integrity": "sha512-fumuQbLKzEnZ3pX9LHXCbxfol8OiStWa63ujDin9SMb2k6cCMXbkuRC/eRe1EDLYPSfkVAKV+r6elOwT6fTVYQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.6",
"ai": "^5.0.18",
"algoliasearch-helper": "3.26.1",
"instantsearch.js": "4.85.0",
"algoliasearch-helper": "3.27.0",
"instantsearch.js": "4.86.1",
"use-sync-external-store": "^1.0.0",
"zod": "^3.25.76 || ^4",
"zod-to-json-schema": "3.24.6"
@@ -26444,13 +26446,13 @@
}
},
"node_modules/storybook": {
"version": "8.6.14",
"resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.14.tgz",
"integrity": "sha512-sVKbCj/OTx67jhmauhxc2dcr1P+yOgz/x3h0krwjyMgdc5Oubvxyg4NYDZmzAw+ym36g/lzH8N0Ccp4dwtdfxw==",
"version": "8.6.15",
"resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.15.tgz",
"integrity": "sha512-Ob7DMlwWx8s7dMvcQ3xPc02TvUeralb+xX3oaPRk9wY9Hc6M1IBC/7cEoITkSmRS2v38DHubC+mtEKNc1u2gQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/core": "8.6.14"
"@storybook/core": "8.6.15"
},
"bin": {
"getstorybook": "bin/index.cjs",