{"_id":"@cameronsjo/artificer","_rev":"12-926b47f34543cf8e651246d6afeac310","name":"@cameronsjo/artificer","dist-tags":{"latest":"0.27.0"},"versions":{"0.12.0":{"name":"@cameronsjo/artificer","version":"0.12.0","author":{"name":"Cameron Sjo","email":"csjo00@gmail.com"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.12.0","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"dist":{"shasum":"cb6842cfd5e80cd43aadb9ba0eb9655b4eec92dd","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.12.0.tgz","fileCount":30,"integrity":"sha512-lys+qXQCk2p8bjNkBfvT01ooLDqUJ3CXXDtBhBw916t4EFEyKoyQLS/8mOsNGS/U49DzOmCmA0r7nCk9FROImg==","signatures":[{"sig":"MEUCIEve+ZaBSl0vxHVBwjcdvF/O0R7kLzAw4ur1aQ/gx7V/AiEA8HTNcM9GJBS7LfoW3zPqUDDX/YLg0JmVovKs3wXI9ks=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":734621},"type":"module","style":"./src/artificer.css","exports":{"./tabs.js":"./src/artificer-tabs.js","./focus.js":"./src/artificer-focus.js","./icons.js":"./src/artificer-icons.js","./theme.js":"./src/artificer-theme.js","./print.css":"./src/print.css","./whimsy.js":"./src/artificer-whimsy.js","./whimsy.css":"./src/artificer-whimsy.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"e63f0a5df266c286acab733d20da96ef10ca72b5","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","build:themes":"node themes/build.mjs","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"cameronsjo","email":"cameron.sjo@outlook.com"},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"11.13.0","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"24.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/artificer_0.12.0_1780595390763_0.15981827041210717","host":"s3://npm-registry-packages-npm-production"}},"0.18.0":{"name":"@cameronsjo/artificer","version":"0.18.0","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.18.0","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"dist":{"shasum":"f5473a23a7677f975cbd565acd5e65d73953404e","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.18.0.tgz","fileCount":33,"integrity":"sha512-Ci+iyG/4kFCPE9Z9YvmDVEMripkijEEEX7e3ZC994juqjGibBSO8MsALIDIcwxGu0S0UBgDe9OaBWMvUjygGHw==","signatures":[{"sig":"MEQCIDVsuXCI2MDLwzKU5Xg5oNLpOU2yNMC+hAZo6ALQBAwAAiBpUKu6/X1edkC0+0cmdeKfzqAUm4tlWmlYS//1ytPryw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.18.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":809747},"type":"module","style":"./src/artificer.css","exports":{"./tabs.js":"./src/artificer-tabs.js","./tree.js":"./src/artificer-tree.js","./focus.js":"./src/artificer-focus.js","./icons.js":"./src/artificer-icons.js","./theme.js":"./src/artificer-theme.js","./print.css":"./src/print.css","./whimsy.js":"./src/artificer-whimsy.js","./options.js":"./src/artificer-options.js","./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"1ecf0ffdfaa3f810f0ffd9960328e4548b85393e","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","build:themes":"node themes/build.mjs","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"11.16.0","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/artificer_0.18.0_1781130305890_0.09058879716113633","host":"s3://npm-registry-packages-npm-production"}},"0.18.1":{"name":"@cameronsjo/artificer","version":"0.18.1","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.18.1","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"dist":{"shasum":"5add4250889e06add80715a9949470682ee33744","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.18.1.tgz","fileCount":33,"integrity":"sha512-YxJ5zZP4inwPidZ11fz7KMJpkFPiCvnaDkYFBTdCS9v42xLtLcTpHYe/22KQVZwtjK8syqbu0sJx6s69Ql6jaQ==","signatures":[{"sig":"MEUCICMCBSlrNVw4525rIz/1WRFL7UCBYaNZwgF7hTAV1kmUAiEAsjtZLLcLzVY2DPKLwktU2JZRywiyE+JEfI5UoURaFMI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.18.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":810575},"type":"module","style":"./src/artificer.css","exports":{"./tabs.js":"./src/artificer-tabs.js","./tree.js":"./src/artificer-tree.js","./focus.js":"./src/artificer-focus.js","./icons.js":"./src/artificer-icons.js","./theme.js":"./src/artificer-theme.js","./print.css":"./src/print.css","./whimsy.js":"./src/artificer-whimsy.js","./options.js":"./src/artificer-options.js","./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"19eaf4b0d4153f74644d57aa73ac7e07ff69aef1","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","build:themes":"node themes/build.mjs","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"11.16.0","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css"],"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/artificer_0.18.1_1781184187597_0.6486365402213223","host":"s3://npm-registry-packages-npm-production"}},"0.21.0":{"name":"@cameronsjo/artificer","version":"0.21.0","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.21.0","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"d20acf754dea020a5b3f4de979d2e395393fae8c","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.21.0.tgz","fileCount":37,"integrity":"sha512-VyO2GV+rgXgbqeCtwWzDw2fIzw6Zn/QkJivrexUMpiGvbEpEHN5kXyx+qArwJtWQBg6zWHBXge5j6cBW0Oc88w==","signatures":[{"sig":"MEQCIF0JYq5R8ikHTc/Ing8ZW6dh4B8oU9sdLFACcwenL/LsAiBbetkDMDNkL5YDf6uk4fnVcFkA82fOi32fkZkK86qPuQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.21.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":921583},"type":"module","style":"./src/artificer.css","exports":{"./tabs.js":"./src/artificer-tabs.js","./tree.js":"./src/artificer-tree.js","./focus.js":"./src/artificer-focus.js","./icons.js":"./src/artificer-icons.js","./theme.js":"./src/artificer-theme.js","./print.css":"./src/print.css","./whimsy.js":"./src/artificer-whimsy.js","./options.js":"./src/artificer-options.js","./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"c754bcd2bab641424b9d6bbee7b58354147f9392","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/artificer_0.21.0_1785694374637_0.31188945786647615","host":"s3://npm-registry-packages-npm-production"}},"0.22.0":{"name":"@cameronsjo/artificer","version":"0.22.0","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.22.0","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"13a641a76d556b91cf5e07ab5d97cae93053a5b4","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.22.0.tgz","fileCount":37,"integrity":"sha512-0P+8VZqYb+z6BGIAyEIsY2RqGQOHTI6S2waDseCxjUwL9tnsABJem03+Zwrcv3O6vYmP0xUP5KQd+E/Egx14Wg==","signatures":[{"sig":"MEYCIQD1rgpd+KbmrTDaiMMF8xN9NkyTCkHXW22xBY+Wch1ddwIhANhLUuN8V4OvrCtY1CCJS/dTLxcnh9O3sh4Rh958CgTT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.22.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":924472},"type":"module","style":"./src/artificer.css","exports":{"./tabs.js":"./src/artificer-tabs.js","./tree.js":"./src/artificer-tree.js","./focus.js":"./src/artificer-focus.js","./icons.js":"./src/artificer-icons.js","./theme.js":"./src/artificer-theme.js","./print.css":"./src/print.css","./whimsy.js":"./src/artificer-whimsy.js","./options.js":"./src/artificer-options.js","./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"38f9921288920c1d55de238039146b7a3d4fcc64","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/artificer_0.22.0_1785703825140_0.37899219764538916","host":"s3://npm-registry-packages-npm-production"}},"0.22.1":{"name":"@cameronsjo/artificer","version":"0.22.1","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.22.1","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"33f7dc05bce6cd48c8ccc4e91bc81237fb01daae","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.22.1.tgz","fileCount":37,"integrity":"sha512-dnTwN80LbpsZKGMgcKLOJYkIUNGQtVRAOXQjF9gPjPjQI7HqZEu7H9BJLCgfZkXiSnwE3/2ep+KBAfHP3Zt5OQ==","signatures":[{"sig":"MEYCIQDQo3yb7ohW4fp83h0XNmHiSQsW89Y2uejy7fH87jBBQQIhAP5IlvKMityB9uTWZ3tvRFCAP1GZgCw3dcJ1YC5hjsKW","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.22.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":926457},"type":"module","style":"./src/artificer.css","exports":{"./tabs.js":"./src/artificer-tabs.js","./tree.js":"./src/artificer-tree.js","./focus.js":"./src/artificer-focus.js","./icons.js":"./src/artificer-icons.js","./theme.js":"./src/artificer-theme.js","./print.css":"./src/print.css","./whimsy.js":"./src/artificer-whimsy.js","./options.js":"./src/artificer-options.js","./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"118c4be232b90b77bf7708a7081476d67981020c","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/artificer_0.22.1_1785710852831_0.7593024678596427","host":"s3://npm-registry-packages-npm-production"}},"0.23.0":{"name":"@cameronsjo/artificer","version":"0.23.0","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.23.0","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"7195303f659a093684e01169f0b2166540c727ba","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.23.0.tgz","fileCount":33,"integrity":"sha512-9KPFOIR7nHT0lY4Qs5xHPh0v5AV9WS9PFHjWGIaoPFnvWgLxHnrGg4sJfczoLN/YWfeRgxlARkOXvLK89AJjXA==","signatures":[{"sig":"MEUCIQD8u8dB7vAFa+GJKSTG0eQlXLSNs1Tq4aL9cJyszLiuOAIgbSfMf1pl4JHscYoyx9JSo1xglwcTXBwiJYPsr69IWpk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.23.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":778019},"type":"module","style":"./src/artificer.css","exports":{"./tabs.js":"./src/artificer-tabs.js","./tree.js":"./src/artificer-tree.js","./focus.js":"./src/artificer-focus.js","./icons.js":"./src/artificer-icons.js","./theme.js":"./src/artificer-theme.js","./print.css":"./src/print.css","./whimsy.js":"./src/artificer-whimsy.js","./options.js":"./src/artificer-options.js","./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"b7428b76bf754d76d5db3541a6f76185aafa6ded","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/artificer_0.23.0_1787162013707_0.9292246527845498","host":"s3://npm-registry-packages-npm-production"}},"0.24.0":{"name":"@cameronsjo/artificer","version":"0.24.0","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.24.0","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"5bde4211b384aaac8dd1e5434b59a004269e7f50","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.24.0.tgz","fileCount":40,"integrity":"sha512-yWYUmVNXoiMbMY3gJKH1ONVJm+xBRdWwic2R7/mJjLYzNICrL2DbXS2BmpRHnC2+vQ+a859tOEPtDqMSF4Cw6g==","signatures":[{"sig":"MEQCIEIhHKAZCxdUZmbYnSd+2dFKcpkLiSYRLUq5OoT8PNQBAiA8AwUF/OPdEuR4KIYfDRC20t7JRKuSAqUu2Kx2jEbbwg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.24.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":789733},"type":"module","style":"./src/artificer.css","exports":{"./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./tabs.js":{"types":"./types/tabs.d.ts","default":"./src/artificer-tabs.js"},"./tree.js":{"types":"./types/tree.d.ts","default":"./src/artificer-tree.js"},"./focus.js":{"types":"./types/focus.d.ts","default":"./src/artificer-focus.js"},"./icons.js":{"types":"./types/icons.d.ts","default":"./src/artificer-icons.js"},"./theme.js":{"types":"./types/theme.d.ts","default":"./src/artificer-theme.js"},"./print.css":"./src/print.css","./whimsy.js":{"types":"./types/whimsy.d.ts","default":"./src/artificer-whimsy.js"},"./options.js":{"types":"./types/options.d.ts","default":"./src/artificer-options.js"},"./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"3ecaeebf5b12b466126704c1352335da0d2c96ba","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/artificer_0.24.0_1787165261663_0.5529573245741641","host":"s3://npm-registry-packages-npm-production"}},"0.24.1":{"name":"@cameronsjo/artificer","version":"0.24.1","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.24.1","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"c91d52e89ea21e2385fec8021f7db72d9416e578","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.24.1.tgz","fileCount":52,"integrity":"sha512-DzxQosBYsR7/X1/tVdlcqYTAuhnJBHSrRxTKGYhmJ8Zr/BBnzfW6x7LF42OokGRADDqG5fytaCtwUpaSZ3LxNw==","signatures":[{"sig":"MEQCIDcgFabNYkU+VY0G1eNl5F49VedscskHWQYpHmD+a3lwAiAY5YyD/IHycEeoT7gs+AIk7oRwXXkasG1KEio8gqXunA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.24.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":828958},"type":"module","style":"./src/artificer.css","exports":{"./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./tabs.js":{"types":"./types/tabs.d.ts","default":"./src/artificer-tabs.js"},"./tree.js":{"types":"./types/tree.d.ts","default":"./src/artificer-tree.js"},"./focus.js":{"types":"./types/focus.d.ts","default":"./src/artificer-focus.js"},"./icons.js":{"types":"./types/icons.d.ts","default":"./src/artificer-icons.js"},"./theme.js":{"types":"./types/theme.d.ts","default":"./src/artificer-theme.js"},"./print.css":"./src/print.css","./whimsy.js":{"types":"./types/whimsy.d.ts","default":"./src/artificer-whimsy.js"},"./options.js":{"types":"./types/options.d.ts","default":"./src/artificer-options.js"},"./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"df88942144509a547412167d8e4cc9f6666f5cea","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/artificer_0.24.1_1787165948973_0.40240542574002625","host":"s3://npm-registry-packages-npm-production"}},"0.24.2":{"name":"@cameronsjo/artificer","version":"0.24.2","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.24.2","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"6b3902696aad3fbaeed55b6786ea7dea5be64c0a","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.24.2.tgz","fileCount":52,"integrity":"sha512-ChIOS+ktJk5BO1POMaLo13A+Mj89YYFe/XNy8PraiHOHiEtoQ8kXRY8LWCZclS8rr2dKS3EL5WICrCQ4dcdiRw==","signatures":[{"sig":"MEUCIQDP774DeqYUkDtcQ7KYyPbjEtdW7/bzFrmRvsxP2T7x6wIgDeO7xay6sfTZw1kJ5Zn+0cfifB0JKRR5r1hShpAkgoc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.24.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":828936},"type":"module","style":"./src/artificer.css","exports":{"./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./tabs.js":{"types":"./types/tabs.d.ts","default":"./src/artificer-tabs.js"},"./tree.js":{"types":"./types/tree.d.ts","default":"./src/artificer-tree.js"},"./focus.js":{"types":"./types/focus.d.ts","default":"./src/artificer-focus.js"},"./icons.js":{"types":"./types/icons.d.ts","default":"./src/artificer-icons.js"},"./theme.js":{"types":"./types/theme.d.ts","default":"./src/artificer-theme.js"},"./print.css":"./src/print.css","./whimsy.js":{"types":"./types/whimsy.d.ts","default":"./src/artificer-whimsy.js"},"./options.js":{"types":"./types/options.d.ts","default":"./src/artificer-options.js"},"./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"802583556c691f31082778b229f510bdc71635cd","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/artificer_0.24.2_1787170664269_0.9430930680009773","host":"s3://npm-registry-packages-npm-production"}},"0.25.0":{"name":"@cameronsjo/artificer","version":"0.25.0","author":{"name":"Cameron Sjo"},"license":"Apache-2.0","_id":"@cameronsjo/artificer@0.25.0","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"homepage":"https://github.com/cameronsjo/artificer#readme","bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"bin":{"artificer":"bin/artificer.mjs"},"dist":{"shasum":"6783efcbcf94001b26ccbb097b463df385ba1b14","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.25.0.tgz","fileCount":52,"integrity":"sha512-/VasUmAHKhPAS1ivteyk01vFI/e6VAGhk+rcOzEnf9eJ655ov0TiwIdpOYCv6eO6VwWB2dzyacEwnPse+gRwPQ==","signatures":[{"sig":"MEYCIQDQBnFWHVM+9spPEEbDSZi49mjVLw7XSY+VQWQvqtPXkgIhAOu7EYCMVnkUOo5OSSiZGmmxILPajHPpCy9bzsFcaDb5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.25.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":833530},"type":"module","style":"./src/artificer.css","exports":{"./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./tabs.js":{"types":"./types/tabs.d.ts","default":"./src/artificer-tabs.js"},"./tree.js":{"types":"./types/tree.d.ts","default":"./src/artificer-tree.js"},"./focus.js":{"types":"./types/focus.d.ts","default":"./src/artificer-focus.js"},"./icons.js":{"types":"./types/icons.d.ts","default":"./src/artificer-icons.js"},"./theme.js":{"types":"./types/theme.d.ts","default":"./src/artificer-theme.js"},"./print.css":"./src/print.css","./whimsy.js":{"types":"./types/whimsy.d.ts","default":"./src/artificer-whimsy.js"},"./options.js":{"types":"./types/options.d.ts","default":"./src/artificer-options.js"},"./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"2a8257242f2ccace643ae757a365ac2e193cd6e4","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","pack:browser":"node scripts/pack-browser.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check","pack:jetbrains":"node scripts/pack-jetbrains.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.0.2","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/artificer_0.25.0_1787970262644_0.5571699411925739","host":"s3://npm-registry-packages-npm-production"}},"0.27.0":{"_id":"@cameronsjo/artificer@0.27.0","bin":{"artificer":"bin/artificer.mjs"},"bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"dist":{"shasum":"6a6a6e19ff5599da567d6ae2acf83c16798b5034","tarball":"https://registry.npmjs.org/@cameronsjo/artificer/-/artificer-0.27.0.tgz","fileCount":55,"integrity":"sha512-zZ0Jidmup4x6AhOiLCGzBxSXOuQhxliNecZhG7EqPeZENEzQdqAQKOiq3atSwBq3OyC3bUTuNY2HyP6GzS++mw==","signatures":[{"sig":"MEQCIH0bAenegUosa31QmDmdS1873NPMVCOCmx6DnoNm8u9lAiAM4voF5+drPA4hXtWBlOMR2ce+3hw5Jp52umdp1+I1JA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDtwYHn0EQlg41umfPHf+M4GSZBWyT7p8bRppaLdjGFmAIgQmykmeEQtbnygunaYWqp9IMre+YHaUIuVNknlRrcgdc="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@cameronsjo%2fartificer@0.27.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":869547},"name":"@cameronsjo/artificer","type":"module","style":"./src/artificer.css","author":{"name":"Cameron Sjo"},"exports":{"./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./tabs.js":{"types":"./types/tabs.d.ts","default":"./src/artificer-tabs.js"},"./tree.js":{"types":"./types/tree.d.ts","default":"./src/artificer-tree.js"},"./focus.js":{"types":"./types/focus.d.ts","default":"./src/artificer-focus.js"},"./icons.js":{"types":"./types/icons.d.ts","default":"./src/artificer-icons.js"},"./theme.js":{"types":"./types/theme.d.ts","default":"./src/artificer-theme.js"},"./print.css":"./src/print.css","./whimsy.js":{"types":"./types/whimsy.d.ts","default":"./src/artificer-whimsy.js"},"./options.js":{"types":"./types/options.d.ts","default":"./src/artificer-options.js"},"./whimsy.css":"./src/artificer-whimsy.css","./texture.css":"./src/artificer-texture.css","./tokens.json":"./src/tokens.json","./package.json":"./package.json","./artificer.css":"./src/artificer.css","./editorial.css":"./src/artificer-editorial.css"},"gitHead":"75661fca7bb77ff952d74d3e857e9c58876c1da1","license":"Apache-2.0","scripts":{"sri":"node scripts/gen-sri.mjs","test":"node --test scripts/*.test.mjs","sync:tokens":"node scripts/sync-tokens.mjs","build:themes":"node themes/build.mjs","check:tokens":"node scripts/sync-tokens.mjs --check","lint:palette":"node scripts/lint-css-palette.mjs","pack:browser":"node scripts/pack-browser.mjs","sync:version":"node scripts/sync-version.mjs","check:version":"node scripts/sync-version.mjs --check","build:livespec":"node scripts/build-livespec.mjs","check:contrast":"node scripts/check-syntax-contrast.mjs","check:livespec":"node scripts/build-livespec.mjs --check","pack:jetbrains":"node scripts/pack-jetbrains.mjs"},"version":"0.27.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1efb57b3-db9e-441c-9c15-8112b71646be"}},"homepage":"https://github.com/cameronsjo/artificer#readme","repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"_npmVersion":"12.1.0","description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","directories":{},"maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"sideEffects":["*.css","src/artificer-*.js"],"_nodeVersion":"24.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/artificer_0.27.0_1790525467720_0.9848562694176319"}}},"time":{"created":"2026-06-04T17:49:50.642Z","modified":"2026-09-27T16:11:08.505Z","0.12.0":"2026-06-04T17:49:50.972Z","0.18.0":"2026-06-10T22:25:06.072Z","0.18.1":"2026-06-11T13:23:07.822Z","0.21.0":"2026-08-02T18:12:54.857Z","0.22.0":"2026-08-02T20:50:25.307Z","0.22.1":"2026-08-02T22:47:32.984Z","0.23.0":"2026-08-19T17:53:33.887Z","0.24.0":"2026-08-19T18:47:41.826Z","0.24.1":"2026-08-19T18:59:09.171Z","0.24.2":"2026-08-19T20:17:44.499Z","0.25.0":"2026-08-29T02:24:22.808Z","0.27.0":"2026-09-27T16:11:08.051Z"},"bugs":{"url":"https://github.com/cameronsjo/artificer/issues"},"author":{"name":"Cameron Sjo"},"license":"Apache-2.0","homepage":"https://github.com/cameronsjo/artificer#readme","repository":{"url":"git+https://github.com/cameronsjo/artificer.git","type":"git"},"description":"Cameron's personal design system — AuDHD-friendly, dark-first, for tools and dashboards. Apache-2.0 but Cameron-first: published for my own reuse, unsupported, no stability guarantees implied.","maintainers":[{"name":"cameronsjo","email":"cameron.sjo@outlook.com"}],"readme":"# Artificer · Design System Handoff\n\nCameron's personal design system, packaged for use in real codebases.\n**v0.27.0 · 2026** — new layout and doc-chrome primitives: `.container--page` for page padding, `.eyebrow`, `.subsection-title`, `.callout`, a `.kv--props` properties block, and an embed card on `.figure`. The shipped skills and reference drop stale guidance (AA contrast floor, current colour names, a boilerplate that follows the Hard rules), and every live-spec page now uses the system classes and tokens it used to hand-roll. See `CHANGELOG.md` for what changed.\n\n---\n\n## What this is\n\nA complete, self-contained design system you can drop into any project. Five files do the heavy lifting:\n\n| File | What it gives you |\n|---|---|\n| `src/artificer.css` | All tokens (color, type, space, radius, motion, z) + every component class. **Just add this stylesheet and you have the system.** |\n| `src/artificer-theme.js` | Persistent theme control — three modes (`dark` / `light` / `auto`), `auto` follows `prefers-color-scheme` live. Hydrates the empty canonical `.theme-toggle` button with the half-circle glyph. |\n| `src/artificer-focus.js` | `ArtificerFocus.trap(el, {onEscape})` — focus-trap helper for modals, dialogs, command palettes. |\n| `src/artificer-icons.js` | Lucide-rooted icon set, keyed by Lucide's canonical names (legacy names alias). Hydrates `<i data-icon=\"search\">` placeholders into inline SVG; unknown names render a dashed placeholder box. |\n| `src/tokens.json` | Machine-readable token export. For Tailwind, Figma, Style Dictionary, anything non-CSS. |\n\nPlus `src/print.css` (paper-mode for PDF/print) and two SVG assets (favicon, OG card).\n\nThe optional **Whimsy** layer (`src/artificer-whimsy.css` + `src/artificer-whimsy.js`) is the *one sanctioned exception* to the no-looping-decoration / no-raw-color rules — a flowing burnished rainbow on text, for **user-defined fun elements** and whimsical operations only. Opt-in; load it after `artificer.css`. It also ships `Whimsy.greeting()` — a seasonal footer line (`<span data-whimsy-greeting>`) that lights up for Pride every June. Full doctrine in `CLAUDE.md` § Whimsy; interactive reference + playground at `live-spec/whimsy.html`.\n\nThe full live spec for every component lives at the project URL (the HTML pages — `colors.html`, `typography.html`, `components.html`, etc). This bundle ships the source; visit the live system for the visual reference.\n\n---\n\n## What Artificer is for\n\n**Use it for** — internal tools, dashboards, IDE-adjacent UI, terminals, dev/devops products, configuration UIs, productivity apps targeting power users.\n\n**Don't use it for** — marketing sites, hero/landing pages, kid-facing UI, lifestyle/consumer-emotional brands. It's deliberately serious.\n\nIf you're not sure: Artificer treats the user as a peer with a job to do. If your audience is closer to \"delight me\" than \"stop wasting my time,\" reach for a different system.\n\n---\n\n## Install — three integration paths\n\n### Path A · Vanilla HTML / static site (zero build)\n\nCopy the `src/` folder into your project, then:\n\n```html\n<!doctype html>\n<html lang=\"en\" data-theme=\"dark\">\n<head>\n  <link rel=\"stylesheet\" href=\"/artificer/artificer.css\" />\n  <link rel=\"stylesheet\" href=\"/artificer/print.css\" media=\"print\" />\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"/artificer/favicon.svg\" />\n  <script src=\"/artificer/artificer-theme.js\" defer></script>\n  <script src=\"/artificer/artificer-icons.js\" defer></script>\n</head>\n<body>\n  <a href=\"#main\" class=\"skip-link\">Skip to content</a>\n  <button class=\"theme-toggle\" data-theme-toggle aria-label=\"Toggle theme\"></button>\n  <main id=\"main\" class=\"container container--md\">…</main>\n</body>\n</html>\n```\n\nThat's it. Use the utility classes (`.btn`, `.card`, `.stack`, `.cluster`, etc.).\n\n**Vendor it with one command.** Instead of copying `src/` by hand, run the\nbundled `vendor` bin — it globs the runtime (including `primitives.json`,\nthe machine-readable mint ledger) and stamps a provenance sidecar so you can\ntell later what version you're on and whether anything drifted:\n\n```bash\nnpx @cameronsjo/artificer vendor            # → public/artificer/\nnpx @cameronsjo/artificer vendor --dest static/artificer --fonts\n```\n\nIt copies `artificer*.css`, `artificer*.js`, `print.css`, `tokens.json`, and\n`primitives.json` (the mint ledger the upgrade skill consumes) into the dest,\nplus a `provenance.json` recording the source, the version, and a `sha256` for\neach file. (The interim `ARTIFICER-CHEATSHEET.md` ride-along is retired; an old\nvendored copy can be deleted.) Fonts are opt-in (`--fonts`) — off by default, since a bundler resolves\nthem for you. Re-run to update; a vendored file you hand-edited (or an untracked\nfile already sitting in the dest) is flagged, and `--strict` turns that into a\nnon-zero exit that refuses to overwrite. Re-vendoring adds and overwrites but\nnever removes — if a version bump relocates a file, delete the dest and re-run\nfor a clean tree. Bundler consumers on **Path B** don't need this — they import\nfrom `node_modules` directly.\n\n> The bin vendors the published `src/`. A minified `dist/` channel\n> (`--channel=min`) is a documented extension point, not yet shipped.\n\n**Keep your own CSS honest — `artificer lint`.** The same bin lints Hard rule #1\n(raw hex, on-scale spacing/radius px, near-scale `font-size` px that map to a\ntoken) over *your* CSS, so consumers hold the line the workshop holds:\n\n```bash\nnpx @cameronsjo/artificer lint \"src/**/*.css\"              # strict: exit 2 on a violation\nnpx @cameronsjo/artificer lint \"src/**/*.css\" --advisory   # report only, exit 0\n```\n\nIt reads the token inventory — the exact scale a violation is measured against —\nfrom the first of: `--tokens <path>`, then your vendored\n`public/artificer/tokens.json`, then the installed package's own\n`src/tokens.json` (version-locked to what you pinned), then a built-in fallback.\nThe chosen source is printed on every run, so the lint stays in lockstep with\nyour version. Custom-property definitions and lines marked `/* tuned */` are\nskipped. There is deliberately **no config file** — the discipline is the\nsystem's, not per-consumer.\n\n`lint` only reads files **within** the project — a glob whose base resolves\noutside the working directory is refused. Don't feed it attacker-controlled\nglobs in privileged CI.\n\nWire it into CI so drift can't merge. Add a script and a step:\n\n```jsonc\n// package.json\n\"scripts\": { \"lint:artificer\": \"artificer lint \\\"src/**/*.css\\\"\" }\n```\n\n```yaml\n# .github/workflows/ci.yml\n- run: npx @cameronsjo/artificer lint \"src/**/*.css\"\n```\n\n### Path B · Modern bundler (Vite / Webpack / Next / Nuxt)\n\n```bash\n# Drop src/ into your design system folder\ncp -r src/ packages/artificer/\n```\n\n```ts\n// In your app entry (e.g. src/main.ts, app/layout.tsx)\nimport 'artificer/artificer.css'      // tokens + .tabs .appbar .crumb .sidenav .split-pane …\nimport 'artificer/artificer-theme.js'\nimport 'artificer/artificer-focus.js' // only if using modals\nimport 'artificer/artificer-icons.js' // only if using <i data-icon>\nimport 'artificer/artificer-tabs.js'  // only if using .tabs (ships the APG keyboard model)\nimport 'artificer/artificer-options.js' // only if using .menu/.listbox/.palette (option navigation)\nimport 'artificer/artificer-tree.js'  // only if using .tree (ships the APG tree keyboard)\n```\n\nThe CSS uses CSS custom properties (variables) and `data-theme` attribute — no preprocessing needed.\n\n**Nav primitives.** `.tabs`, `.appbar`, `.crumb`, `.sidenav`, and `.split-pane` ship in `artificer.css`. The `.tabs` CSS is style-only — load `artificer-tabs.js` for the WAI-ARIA keyboard behavior (roving tabindex, arrows, Home/End). Full reference: `live-spec/navigation.html`.\n\n```html\n<div class=\"tabs\" data-tabs role=\"tablist\">\n  <button class=\"tabs__tab\" role=\"tab\" aria-controls=\"p1\">Overview</button>\n  <!-- … -->\n</div>\n```\n```ts\nArtificerTabs.observe(document) // wires APG keyboard for every [data-tabs]\n```\n\n### Path C · Tailwind / utility-first\n\nThe CSS already provides utility classes for layout (`.stack`, `.cluster`, `.grid-auto`, `.container`). For Tailwind shops, see `framework-adapters/tailwind.config.js` — it imports `tokens.json` so your Tailwind utilities use Artificer values.\n\n---\n\n## The non-negotiable rules\n\nThese came from research on AuDHD users; they are the system's spine. Don't refactor them away.\n\n1. **Dark is default.** Cream/light is a paper alternative. Never auto-switch on system theme without storing user preference.\n2. **One primary CTA per screen.** Always. If you need two equal-weight actions, you have a flow problem, not a design problem.\n3. **Lists ≤ 7 items.** Beyond that: progressive disclosure, search, or grouping. Default to 5.\n4. **Bold anchor words** in body copy — 3–5 per paragraph. They are the primary scan mechanism.\n5. **Tier notifications by *action required*, not severity.** A blocking error and a casual heads-up are not the same shape.\n6. **Active state is dramatic.** Inactive panes drop to 55% opacity + desaturated. Subtle differences fail the squint test.\n7. **Tabular numbers everywhere.** `font-variant-numeric: tabular-nums` on every numeric column.\n8. **Honor reduced-motion.** Already wired — durations collapse to 0ms. Don't re-introduce hard-coded transitions.\n9. **WCAG 2.2 AA floor, AAA on body text.** Every contrast pairing is pre-measured. Don't introduce new color combos without checking.\n10. **Pass the squint test.** If a visual hierarchy disappears at squint, the contrast is wrong.\n\n---\n\n## The decision recipe\n\nWhen you need to build something, find it here first instead of improvising:\n\n| You're building… | Reach for… |\n|---|---|\n| A page with sidebar + main | `.page-shell` + `.container--{sm,md,lg}` |\n| Stacking children vertically | `.stack` (with `--xs/sm/md/lg/xl/2xl`) |\n| Horizontal toolbar / chip row | `.cluster` |\n| Card grid | `.grid-auto` with `--min: 240px` |\n| Form field | `<div class=\"field\">` with `.field__label` + `.input` + `.field__hint` |\n| Validation error | `.field--invalid` + `aria-invalid=\"true\"` + `aria-describedby` |\n| Modal / dialog | `.scrim` + `.modal`, wire `ArtificerFocus.trap()` |\n| Tooltip (label) | `.tooltip` |\n| Popover (body content) | `.popover` |\n| Toast / notification | `.notif` + tier modifier (`--urgent`, `--attention`, `--info`, `--background`) |\n| Status pill | `.badge` + tier + `.dot` inside |\n| Table of data | `.table` (add `.table--zebra` for dense data) |\n| Headline number | Stat card pattern (see `data-display.html` in the live spec) |\n| Empty state | `.empty-state` + `.empty-state__title` + `.empty-state__body` |\n| Loading | Pick by *duration*: nothing → disabled label → `.skeleton` → `.progress` → background notification |\n| Icon | `<i data-icon=\"name\" aria-hidden=\"true\"></i>` |\n| Animation | `var(--dur-fast) var(--ease)`. Don't invent durations. |\n| z-index | Six rungs only: `--z-{base,raised,overlay,popover,modal,toast}` |\n| Print/PDF output | Add `<link rel=\"stylesheet\" href=\"print.css\" media=\"print\">` |\n\nFor the full surface area (every component, every variant, voice & tone, accessibility checklist) read the live system or `reference/SKILL.md`.\n\n---\n\n## Framework adapters\n\nThe `framework-adapters/` folder has minimal starting points:\n\n- `tailwind.config.js` — pulls `tokens.json` into Tailwind's theme. Use Artificer values via `bg-bg`, `text-fg`, `text-accent`, `font-mono`, `rounded-md`, etc.\n- `react-components.tsx` — typed React wrappers for the most common patterns (Button, Field, Stack, Cluster, Modal, Notification). Thin — they just emit the right classes.\n- `vue-components.vue` — same, for Vue 3 SFC.\n\nThese are starters, not the whole system. They cover the 80% case; for new patterns, write the markup directly and use the CSS classes.\n\n**Read [`framework-adapters/README.md`](framework-adapters/README.md) first** — the one rule for using Artificer's interactive behavior from a framework: the pure keyboard state machines (`ArtificerTabs.nextIndex`, `ArtificerOptions.nextOption`, `ArtificerTree.nextVisible`, …) are *imported* and you drive your own DOM; `enhance()`/`observe()` are for non-framework DOM. It also covers the SPA lifecycle (what auto-hydrates, and the imperative-vs-declarative Whimsy pattern) and the shared theme key (`window.ArtificerTheme.KEY`).\n\n---\n\n## Fonts\n\nArtificer ships three SIL OFL font faces (two typeface families), self-hosted as WOFF2 in `src/assets/fonts/`. **Pick the face by role** (see CLAUDE.md → \"First decision — what surface is this?\"):\n\n- **JetBrains Mono** (weights 400 / 500 / 700) — body face on **tool surfaces** (dashboards, consoles, terminals, settings panels, data tables). Always used for code, identifiers, file paths, and numerals — even in document surfaces.\n- **iA Writer Quattro V** — `--font-body`, the prose face on **document surfaces** (writeups, READMEs, reports, design docs). Ships 400 only (plus italic), so bold headlines synthesize faux-bold.\n- **iA Writer Quattro S** — `--font-interface`, the chrome face: labels, controls, badges, form fields, nav, tabular UI numerals — on **both** tool and document surfaces. Ships 400 / 700 with italics.\n\nBoth Quattro faces were designed by Bold Monday for iA Writer; humanist sans tuned to share rhythm with monospace. `--font-sans` remains resolvable as a legacy alias of `--font-body`.\n\nA useful rule of thumb: if the page has more than ~3 paragraphs of running prose, it's a document — set body in Quattro V. If it's mostly chrome around data, it's a tool — set body in JetBrains Mono. Mixing within a project is normal: the settings page is a tool, the README explaining it is a document.\n\nJetBrains Mono is on Google Fonts; Quattro is **not** — that's why we self-host. Each `@font-face` chain points at the bundled WOFF2 files and falls back through Iowan Old Style → Charter → Source Sans 3 → system-ui, so the page still renders if fonts haven't loaded yet.\n\nFull loading recipes, the weight-coverage table, and the Windows faux-bold disposition: **[`FONTS.md`](FONTS.md)**. Upstream source for both Quattro faces is [iaolo/iA-Fonts](https://github.com/iaolo/iA-Fonts).\n\n---\n\n## Accessibility — what's already wired\n\nYou don't need to reinvent any of this. Just don't undo it.\n\n- AAA contrast on all body text (12.8:1 dark, 11.4:1 cream)\n- Focus-visible outlines on every interactive element (2px `--accent`, 2px offset)\n- `:focus-visible` not `:focus` — no rings on mouse clicks\n- `prefers-reduced-motion: reduce` collapses all durations to 0ms\n- `prefers-color-scheme` honored on first load (overridable via toggle)\n- Skip-link styled, just include it on every page\n- `.sr-only` for screen-reader-only text\n- Custom checkbox/radio/toggle keyboard-navigable, focus-ringed\n- Selection color (`::selection`) themed\n- Scrollbar styled to match (Webkit + Firefox)\n\nThe `live-spec/a11y.html` page (in the live system) has the 13-point shipping checklist.\n\n---\n\n## Theming\n\n```html\n<html data-theme=\"dark\"> <!-- default; reads from localStorage -->\n<html data-theme=\"light\"> <!-- cream paper mode -->\n```\n\n`artificer-theme.js` handles persistence. To toggle programmatically:\n\n```js\ndocument.documentElement.setAttribute('data-theme', 'light');\nlocalStorage.setItem('artificer.theme', 'light');\n```\n\nTo read theme preference:\n\n```js\nconst theme = document.documentElement.getAttribute('data-theme'); // 'dark' | 'light'\n```\n\nThe CSS uses `color-scheme: dark` / `light` so form controls and scrollbars match without extra work.\n\n---\n\n## What's NOT in this bundle\n\n- **Live preview pages.** Open the project URL to see every component rendered, with code samples next to each.\n- **Logo files** in raster formats. Logo is `assets/cameron-logo.jpg` in the project; not included here because it's Cameron's personal mark, not a system component.\n- **Storybook config.** Add your own — Artificer is framework-agnostic.\n- **Tests.** Add your own — components are CSS classes, test what you build with them.\n\n---\n\n## Editor, terminal & browser themes\n\nArtificer also ships as themes for the surfaces where Cameron actually\nlives — same palette, every surface. The editors and agent CLIs:\n\n- **Claude Code** — `themes/claude-code/artificer-{dark,light}.json`\n- **VS Code / Cursor** — `themes/vscode/` (sideload or `vsce package`)\n- **Helix** — `themes/helix/artificer-{dark,light}.toml` (+ `-opaque` twins)\n- **Neovim** — `themes/neovim/colors/artificer.lua` (one file, both modes)\n- **Zed** — `themes/zed/artificer.json` (one theme family, both variants)\n- **JetBrains IDEs** — `themes/jetbrains/` (IntelliJ Platform theme plugin; `npm run pack:jetbrains` → install the jar from disk)\n- **Codex CLI** — `themes/codex/artificer-{dark,light}.tmTheme`\n- **Obsidian** — `themes/obsidian/Artificer/` (drop-in theme folder, hand-authored sister)\n\nAnd the browser:\n\n- **Chrome / Edge** — `themes/chromium/artificer-{dark,light}/` (one extension package per mode; Chromium's manifest takes only RGB arrays and has no dark/light switch)\n- **Firefox** — `themes/firefox/artificer/` (one package, both modes — the sibling `dark_theme` key follows the OS)\n\n`npm run pack:browser` builds the store zips; sideload straight from the\ndirectory without packing at all.\n\nPlus the terminal and TUI surfaces around them — Ghostty, WezTerm, tmux, gitmux, cmux,\nbat/delta, glamour, gum, fzf, eza, starship, yazi, lazygit, gh-dash, herdr, and\nflux. **`themes/README.md` carries the full list**; it is the one place that\nenumerates them, so this section never has to be counted again.\n\nEverything except Obsidian is generated from `themes/_palette.json`. To re-tune\nany color across every generated surface in lockstep:\n\n```bash\n# 1. Edit the hex in themes/_palette.json\n# 2. Regenerate every generated surface:\nnode themes/build.mjs\n# 3. Manually re-check obsidian/Artificer/theme.css (--art-* tokens at top)\n```\n\nObsidian is hand-authored because its aesthetic is intentionally distinct\n(gold-as-primary instead of steel, Ghostty-grey background instead of\nindigo-ink, dramatic 0.55/0.6 inactive-pane recession). The palette\ntokens stay in sync manually.\n\nSee `themes/README.md` for install instructions per surface.\n\n---\n\n## Quality gates — two test lanes\n\nMaintainer-facing. Both run in CI on every PR; consumers never need either.\n\n```bash\n# Lane 1 · data gates — zero dependencies, instant\nnpm test               # unit tests (node --test scripts/*.test.mjs)\nnpm run check:contrast # WCAG floors on $roles.syntax\nnpm run lint:palette   # every CSS hex is a palette value\nnpm run check:version  # all version stamps agree\nnpm run check:livespec # src/ <-> live-spec/ mirror parity\n\n# Lane 2 · browser trust layer — Playwright (devDependencies only)\nnpm install                             # once; then:\nnpx playwright install chromium webkit  # once; downloads engines\nnpm run test:browser                    # behavioral assertions on live-spec/\nnpm run test:browser:headed             # watch it run\nnpm run test:browser:ui                 # interactive debugging\n```\n\nThe browser lane loads `live-spec/` pages in **Chromium** (Chrome class) and\n**WebKit as iPhone 13** (Safari class — on iOS every browser is WebKit) and\nasserts behavior: no horizontal overflow, touch-target floors, a11y, keyboard\npatterns. The data gates check what the system *says*; the browser lane checks\nwhat it *does*.\n\n---\n\n## Where to ask\n\n- **Live system** — every page is a live spec. Read first, then code.\n- **`docs/STATE.md`** — the maturity baseline: where each layer of the system honestly sits (clay / materials / rooms / trust), known gaps, and the backlog policy. Re-assessed each minor version.\n- **`reference/SKILL.md`** — the AI-handoff version of these instructions, dense and machine-readable. If you're using Claude Code, point it at that file.\n- **`reference/CLAUDE.md`** — drop into your repo root; Claude Code reads it automatically and will follow Artificer's rules from then on.\n\n---\n\n## Versioning\n\n- **v0.1** · 2026 · personal use, no license required for Cameron's projects. For external use: Apache-2.0 (see LICENSE).\n- Any change to a token value is a **minor version bump**. Adding a new token or component is a **patch**. Removing a token is a **major** (breaking).\n\n---\n\n*This handoff package was generated from the Cameron Personal Design System project.*\n","readmeFilename":"README.md"}