@nurix/etna 0.18.20 → 0.18.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/CLAUDE.md +3 -3
- package/data/harnesses/code/agents/brainstorm.md +1 -1
- package/data/harnesses/code/agents/maintenance.md +8 -7
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/rules/database.md +38 -0
- package/data/harnesses/code/rules/express.md +28 -0
- package/data/harnesses/code/rules/frontend.md +14 -0
- package/data/harnesses/code/rules/general.md +2 -40
- package/data/harnesses/code/rules/nomenclature.md +1 -8
- package/data/harnesses/code/rules/nustack.md +150 -0
- package/data/harnesses/code/skills/brainstorm/README.md +4 -4
- package/data/harnesses/code/skills/brainstorm/SKILL.md +5 -3
- package/data/harnesses/code/skills/brainstorm/exit-artifacts.md +15 -11
- package/data/harnesses/code/skills/brainstorm/templates/source-of-truth.md +5 -5
- package/data/harnesses/code/skills/design/SKILL.md +14 -11
- package/data/harnesses/code/skills/design/data/catalog/rules.csv +4 -4
- package/data/harnesses/code/skills/design/data/combinations/Readme.md +29 -0
- package/data/harnesses/code/skills/design/data/combinations/charts.csv +33 -0
- package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +437 -0
- package/data/harnesses/code/skills/design/data/combinations/icons.csv +157 -0
- package/data/harnesses/code/skills/design/data/combinations/landing.csv +38 -0
- package/data/harnesses/code/skills/design/data/combinations/lucide-names.json +2001 -0
- package/data/harnesses/code/skills/design/data/combinations/manifest.json +283 -0
- package/data/harnesses/code/skills/design/data/combinations/palettes.csv +49 -0
- package/data/harnesses/code/skills/design/data/combinations/product-router.csv +80 -0
- package/data/harnesses/code/skills/design/data/combinations/styles.csv +54 -0
- package/data/harnesses/code/skills/design/data/combinations/typography.csv +61 -0
- package/data/harnesses/code/skills/design/data/design-md/SCHEMA.md +27 -238
- package/data/harnesses/code/skills/design/data/design-md/library/airbnb.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/airtable.md +1 -82
- package/data/harnesses/code/skills/design/data/design-md/library/anthropic-claude.md +4 -85
- package/data/harnesses/code/skills/design/data/design-md/library/apple.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/binance.md +4 -87
- package/data/harnesses/code/skills/design/data/design-md/library/bmw.md +7 -86
- package/data/harnesses/code/skills/design/data/design-md/library/cal.md +4 -84
- package/data/harnesses/code/skills/design/data/design-md/library/clay.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/clickhouse.md +3 -84
- package/data/harnesses/code/skills/design/data/design-md/library/cohere.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/coinbase.md +10 -91
- package/data/harnesses/code/skills/design/data/design-md/library/composio.md +2 -84
- package/data/harnesses/code/skills/design/data/design-md/library/cursor.md +3 -85
- package/data/harnesses/code/skills/design/data/design-md/library/elevenlabs.md +7 -90
- package/data/harnesses/code/skills/design/data/design-md/library/expo.md +0 -80
- package/data/harnesses/code/skills/design/data/design-md/library/figma.md +0 -80
- package/data/harnesses/code/skills/design/data/design-md/library/framer.md +5 -85
- package/data/harnesses/code/skills/design/data/design-md/library/hashicorp.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/ibm.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/intercom.md +9 -91
- package/data/harnesses/code/skills/design/data/design-md/library/kraken.md +9 -89
- package/data/harnesses/code/skills/design/data/design-md/library/linear-app.md +0 -115
- package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +5 -85
- package/data/harnesses/code/skills/design/data/design-md/library/meta.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +3 -84
- package/data/harnesses/code/skills/design/data/design-md/library/mintlify.md +4 -85
- package/data/harnesses/code/skills/design/data/design-md/library/miro.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/mistral-ai.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/mongodb.md +4 -85
- package/data/harnesses/code/skills/design/data/design-md/library/notion.md +4 -84
- package/data/harnesses/code/skills/design/data/design-md/library/nvidia.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/ollama.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/opencode-ai.md +6 -87
- package/data/harnesses/code/skills/design/data/design-md/library/posthog.md +9 -91
- package/data/harnesses/code/skills/design/data/design-md/library/raycast.md +5 -88
- package/data/harnesses/code/skills/design/data/design-md/library/replicate.md +9 -89
- package/data/harnesses/code/skills/design/data/design-md/library/resend.md +4 -119
- package/data/harnesses/code/skills/design/data/design-md/library/revolut.md +4 -84
- package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +0 -82
- package/data/harnesses/code/skills/design/data/design-md/library/sanity.md +3 -86
- package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +13 -94
- package/data/harnesses/code/skills/design/data/design-md/library/shopify.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/slack.md +6 -88
- package/data/harnesses/code/skills/design/data/design-md/library/spacex.md +13 -94
- package/data/harnesses/code/skills/design/data/design-md/library/spotify.md +4 -86
- package/data/harnesses/code/skills/design/data/design-md/library/stripe.md +7 -88
- package/data/harnesses/code/skills/design/data/design-md/library/supabase.md +6 -88
- package/data/harnesses/code/skills/design/data/design-md/library/superhuman.md +5 -86
- package/data/harnesses/code/skills/design/data/design-md/library/tesla.md +6 -86
- package/data/harnesses/code/skills/design/data/design-md/library/theverge.md +12 -93
- package/data/harnesses/code/skills/design/data/design-md/library/together-ai.md +11 -91
- package/data/harnesses/code/skills/design/data/design-md/library/uber.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/vercel.md +2 -82
- package/data/harnesses/code/skills/design/data/design-md/library/voltagent.md +11 -126
- package/data/harnesses/code/skills/design/data/design-md/library/warp.md +8 -88
- package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +3 -83
- package/data/harnesses/code/skills/design/data/design-md/library/wired.md +10 -91
- package/data/harnesses/code/skills/design/data/design-md/library/wise.md +7 -90
- package/data/harnesses/code/skills/design/data/design-md/library/x-ai.md +6 -88
- package/data/harnesses/code/skills/design/data/design-md/library/zapier.md +9 -89
- package/data/harnesses/code/skills/design/data/design-md/nurix.md +4 -87
- package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +580 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +965 -0
- package/data/harnesses/code/skills/design/data/design-tokens/apple/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +954 -0
- package/data/harnesses/code/skills/design/data/design-tokens/binance/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +949 -0
- package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +962 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cal/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clay/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +953 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +973 -0
- package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +954 -0
- package/data/harnesses/code/skills/design/data/design-tokens/composio/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +963 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +968 -0
- package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +981 -0
- package/data/harnesses/code/skills/design/data/design-tokens/expo/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +962 -0
- package/data/harnesses/code/skills/design/data/design-tokens/figma/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/framer/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +959 -0
- package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +251 -0
- package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +965 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +978 -0
- package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +982 -0
- package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +23 -0
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +589 -0
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +955 -0
- package/data/harnesses/code/skills/design/data/design-tokens/meta/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +977 -0
- package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +950 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +976 -0
- package/data/harnesses/code/skills/design/data/design-tokens/miro/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +955 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/notion/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +953 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +904 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +957 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +945 -0
- package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +953 -0
- package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +955 -0
- package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +23 -0
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +613 -0
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +968 -0
- package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +956 -0
- package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +958 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +980 -0
- package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +964 -0
- package/data/harnesses/code/skills/design/data/design-tokens/slack/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +957 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +974 -0
- package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +973 -0
- package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +966 -0
- package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +961 -0
- package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +977 -0
- package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +991 -0
- package/data/harnesses/code/skills/design/data/design-tokens/uber/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +966 -0
- package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +988 -0
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +23 -0
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +602 -0
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +974 -0
- package/data/harnesses/code/skills/design/data/design-tokens/warp/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +979 -0
- package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +960 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wired/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +968 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wise/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +965 -0
- package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +988 -0
- package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.resolver.json +20 -0
- package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +978 -0
- package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +1 -1
- package/data/harnesses/code/skills/design/references/create.md +14 -9
- package/data/harnesses/code/skills/design/references/diagnosis.md +1 -1
- package/data/harnesses/code/skills/design/references/hard-rules.md +4 -4
- package/data/harnesses/code/skills/design/references/improve.md +11 -9
- package/data/harnesses/code/skills/design/references/introspect.md +1 -1
- package/data/harnesses/code/skills/design/references/personality.md +337 -413
- package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +1032 -0
- package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +596 -296
- package/data/harnesses/code/skills/design/scripts/{detector.mjs → lib/checks.mjs} +145 -140
- package/data/harnesses/code/skills/design/scripts/lib/golden.mjs +26 -0
- package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +105 -37
- package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +60 -73
- package/data/harnesses/code/skills/design/scripts/render-rung.mjs +1 -1
- package/data/harnesses/code/skills/design/scripts/scaffold.mjs +1 -1
- package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +205 -37
- package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +68 -0
- package/data/harnesses/code/skills/design/scripts/validate-combinations.mjs +314 -0
- package/data/harnesses/code/skills/documentation/SKILL.md +61 -17
- package/data/harnesses/code/skills/documentation/references/examples.md +41 -0
- package/data/harnesses/code/skills/documentation/references/style-guide.md +14 -9
- package/data/harnesses/code/skills/documentation/references/templates.md +306 -52
- package/data/harnesses/etna/CLAUDE.md +3 -3
- package/data/harnesses/etna/agents/brainstorm.md +1 -1
- package/data/harnesses/etna/agents/maintenance.md +8 -7
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/rules/general.md +2 -40
- package/data/harnesses/etna/rules/nomenclature.md +1 -8
- package/data/harnesses/etna/skills/brainstorm/README.md +4 -4
- package/data/harnesses/etna/skills/brainstorm/SKILL.md +5 -3
- package/data/harnesses/etna/skills/brainstorm/exit-artifacts.md +15 -11
- package/data/harnesses/etna/skills/brainstorm/templates/source-of-truth.md +5 -5
- package/data/harnesses/etna/skills/documentation/SKILL.md +61 -17
- package/data/harnesses/etna/skills/documentation/references/examples.md +41 -0
- package/data/harnesses/etna/skills/documentation/references/style-guide.md +14 -9
- package/data/harnesses/etna/skills/documentation/references/templates.md +306 -52
- package/data/harnesses/mobile/CLAUDE.md +3 -3
- package/data/harnesses/mobile/agents/brainstorm.md +1 -1
- package/data/harnesses/mobile/agents/maintenance.md +8 -7
- package/data/harnesses/mobile/harness.json +2 -2
- package/data/harnesses/mobile/rules/database.md +38 -0
- package/data/harnesses/mobile/rules/general.md +2 -40
- package/data/harnesses/mobile/rules/nomenclature.md +1 -8
- package/data/harnesses/mobile/rules/nustack.md +150 -0
- package/data/harnesses/mobile/skills/brainstorm/README.md +4 -4
- package/data/harnesses/mobile/skills/brainstorm/SKILL.md +5 -3
- package/data/harnesses/mobile/skills/brainstorm/exit-artifacts.md +15 -11
- package/data/harnesses/mobile/skills/brainstorm/templates/source-of-truth.md +5 -5
- package/data/harnesses/mobile/skills/documentation/SKILL.md +61 -17
- package/data/harnesses/mobile/skills/documentation/references/examples.md +41 -0
- package/data/harnesses/mobile/skills/documentation/references/style-guide.md +14 -9
- package/data/harnesses/mobile/skills/documentation/references/templates.md +306 -52
- package/package.json +1 -1
- package/data/harnesses/code/skills/design/scripts/hook-config.json +0 -11
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
# design-tokens — schema `design-tokens/v1`
|
|
2
|
+
|
|
3
|
+
A look travels as a **design-tokens artifact**: three JSON files in the pinned **DTCG 2025.10 Stable**
|
|
4
|
+
grammar (W3C Design Tokens Community Group — the dated snapshot; the live drafts carry the spec's own
|
|
5
|
+
"do not implement" warning). The artifact is exact, queryable, and diffable — no consumer interprets
|
|
6
|
+
prose. [`derive-personality.mjs`](../../scripts/derive-personality.mjs) is the reference consumer:
|
|
7
|
+
`--check` is the coverage gate, `--emit` writes `personality.css` / `globals.css` / the `<html>`
|
|
8
|
+
attributes. The check engine ([`lib/checks.mjs`](../../scripts/lib/checks.mjs), fired at the phase
|
|
9
|
+
gates and the verify/pre-ship sweeps) reads the lever manifest from the artifact's `$extensions` payload.
|
|
10
|
+
|
|
11
|
+
The token files are a project's **canonical look state**. Create writes them, improve rewrites them,
|
|
12
|
+
extraction on a foreign UI recovers them. No readable design.md view is generated from the token
|
|
13
|
+
files — the nine-section [design.md format](../design-md/SCHEMA.md) serves only as the library's
|
|
14
|
+
documentation format.
|
|
15
|
+
|
|
16
|
+
**One schema, every origin.** A project's own artifact, an extracted artifact, a shipped library
|
|
17
|
+
entry, and the Nurix default all use this identical shape; only the payload's `provenance` varies.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## The three files
|
|
22
|
+
|
|
23
|
+
| File | Ships | Contents |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `design.tokens.json` | always | The base/light set: the 26 visual primitives, the 34 color roles, the typography composites, and the file-level `$extensions["com.nurix.design"]` payload. The base set **is** the light rendering — light is never omitted. |
|
|
26
|
+
| `design.tokens.dark.json` | only when the look has dark values | The dark modifier set: the `color` group remapped, nothing else. |
|
|
27
|
+
| `design.resolver.json` | always | Sets, modifiers, and resolution order. Light-first. |
|
|
28
|
+
|
|
29
|
+
The three files sit together in one directory: a project's artifact lives at the repo root; a library
|
|
30
|
+
entry lives at `data/design-tokens/<product-slug>/`; the Nurix default at `data/design-tokens/nurix/`.
|
|
31
|
+
|
|
32
|
+
Look resolution is project-first — `project`/`extracted` artifacts win outright; a `library` entry
|
|
33
|
+
serves only on confirmed match; the `default` serves when nothing else does. The origin is recorded in
|
|
34
|
+
the payload's `provenance` field:
|
|
35
|
+
|
|
36
|
+
| `provenance` | Origin | Precedence |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `project` | The project's own artifact, written by a create run. | Wins outright when present. |
|
|
39
|
+
| `extracted` | Recovered from a UI this skill did not build. | Same tier as `project`. |
|
|
40
|
+
| `library` | A shipped library entry. | Serves only when the brief names or resembles the product and the user confirms. |
|
|
41
|
+
| `default` | The Nurix default. | Worn when there is no project artifact and no confirmed library match. |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## DTCG grammar in this artifact
|
|
46
|
+
|
|
47
|
+
A token is an object with `$type` and `$value`, plus optional `$description` and `$extensions`.
|
|
48
|
+
Groups nest; the file root is a group and carries the file-level `$extensions`. An alias is the
|
|
49
|
+
string `"{path.to.token}"` and may appear anywhere a value of the target's type is legal, including
|
|
50
|
+
composite sub-values; alias chains are legal, cycles are not. Exactly eight `$type` values appear —
|
|
51
|
+
**never invent a custom `$type`**:
|
|
52
|
+
|
|
53
|
+
| `$type` | `$value` shape | Used by |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| `color` | `{ "colorSpace": "oklch"\|"srgb", "components": [n, n, n], "alpha"?: n, "hex"?: "#rrggbb" }` | the 34 color roles |
|
|
56
|
+
| `dimension` | `{ "value": n, "unit": "px" }` (`px`\|`rem` per spec; this artifact always writes `px`) | `radius`, `border-weight`, `icon-size-base`, the 8 layout primitives, ramp `fontSize` |
|
|
57
|
+
| `duration` | `{ "value": n, "unit": "ms" }` | the 4 duration primitives |
|
|
58
|
+
| `cubicBezier` | `[x1, y1, x2, y2]` (numbers; x in 0–1) | `ease-default` |
|
|
59
|
+
| `fontFamily` | array of family-name strings | `font-sans`, `font-mono`, `typography.family.*` |
|
|
60
|
+
| `fontWeight` | number 100–900 | `font-weight-normal`, `font-weight-strong`, ramp `fontWeight` |
|
|
61
|
+
| `number` | plain JSON number | `shadow-intensity`, `density-gap`, `density-inset`, `heading-tracking`, `contrast-boost`, `icon-stroke`, ramp `lineHeight` / `letterSpacing` |
|
|
62
|
+
| `typography` | composite `{ fontFamily, fontSize, fontWeight, letterSpacing, lineHeight }` | the 6 ramp steps |
|
|
63
|
+
|
|
64
|
+
Color rules: an oklch source stays `"colorSpace": "oklch"` with `components` carrying the literal
|
|
65
|
+
`[L, C, H]` numbers from the source string; a hex/rgba (or any other CSS color) source becomes
|
|
66
|
+
`"colorSpace": "srgb"` with `components` as `[r, g, b]` in 0–1 (at most 5 decimals), the `hex`
|
|
67
|
+
fallback field, and `alpha` when the source carries one:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"$type": "color",
|
|
72
|
+
"$value": { "colorSpace": "srgb", "components": [0.3098, 0.2745, 0.898], "alpha": 1, "hex": "#4f46e5" },
|
|
73
|
+
"$extensions": { "com.nurix.design": { "css": "#4f46e5" } }
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**One documented deviation.** The spec's `dimension` carries only `px`|`rem`, so an `em` tracking
|
|
78
|
+
value cannot be a dimension. `heading-tracking` is therefore a `number` token (an em multiplier) with
|
|
79
|
+
its exact source string preserved (the preserved-css pattern, below), and a typography composite's
|
|
80
|
+
`letterSpacing` sub-value is a number (em multiplier) or an alias to one — not a spec dimension.
|
|
81
|
+
Everything else in the artifact is spec-shaped.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## The file-level payload — `$extensions["com.nurix.design"]`
|
|
86
|
+
|
|
87
|
+
One vendor namespace, reverse-domain, on the **base file's root group only** (the dark file carries no
|
|
88
|
+
payload; the resolver has no `$extensions`). It holds everything the look needs that is not a design
|
|
89
|
+
token:
|
|
90
|
+
|
|
91
|
+
| Key | Type | Legal values / shape |
|
|
92
|
+
| --- | --- | --- |
|
|
93
|
+
| `schema` | string | Literal `design-tokens/v1`. A parser refuses an unknown value. |
|
|
94
|
+
| `dtcg` | string | Literal `2025.10` — the pinned DTCG snapshot this artifact conforms to. |
|
|
95
|
+
| `product` | string | The product name; slugified (lowercase, non-alphanumeric runs → `-`) it becomes the `data-style` value. |
|
|
96
|
+
| `provenance` | enum | `project` \| `extracted` \| `library` \| `default` |
|
|
97
|
+
| `sourced` | string | ISO date the artifact was authored, extracted, or last re-sourced. |
|
|
98
|
+
| `verbosity` | enum | `full` \| `default` \| `compact` \| `expert` — emits `data-verbosity` on `<html>`. |
|
|
99
|
+
| `feedback` | enum | `subtle` \| `minimal` — emits `data-feedback`. |
|
|
100
|
+
| `density-tier` | enum | `spacious` \| `standard` \| `dense` — emits `data-density`; drives the density base multipliers. |
|
|
101
|
+
| `product-traits` | array | Non-empty list of product-type trait slugs the front gate reads — e.g. `["review-queue", "case-detail", "fintech"]`. Never emitted to CSS. |
|
|
102
|
+
| `lever-manifest` | object | The drift-check allowlist (below). |
|
|
103
|
+
|
|
104
|
+
Payload fields are always concrete — the hint mechanism (below) exists only on tokens.
|
|
105
|
+
|
|
106
|
+
### The lever manifest
|
|
107
|
+
|
|
108
|
+
The machine-readable allowlist the drift check reads: the check engine flags any emitted value outside
|
|
109
|
+
this vocabulary — a radius not on `radius-scale`, a spacing off `spacing-scale`, a motion duration off
|
|
110
|
+
`motion.durations`.
|
|
111
|
+
|
|
112
|
+
| Key | Shape | Rule |
|
|
113
|
+
| --- | --- | --- |
|
|
114
|
+
| `spacing-scale` | number[] (px) | Non-empty, ascending — on-scale values only. |
|
|
115
|
+
| `radius-scale` | number[] (px) | Non-empty, ascending. |
|
|
116
|
+
| `shadow-levels` | string[] | Non-empty; names drawn from `none` `2xs` `xs` `sm` `md` `lg` `xl` `2xl`, ordered by strictly increasing intensity. |
|
|
117
|
+
| `motion` | `{ "durations": number[], "easings": string[] }` | Durations in ms, non-empty, ascending; easings non-empty CSS easing strings. |
|
|
118
|
+
| `icons` | `{ "family": string }` | The icon family, e.g. `lucide`. |
|
|
119
|
+
| `accent-count` | number | ≥ 1. |
|
|
120
|
+
|
|
121
|
+
The manifest carries only vocabulary that is not already a token — **it never restates a token
|
|
122
|
+
value**. The allowlists that are tokens are read from the tokens: the 34 color values from the
|
|
123
|
+
`color` group, the font stacks from `primitive.font-sans` / `primitive.font-mono`, the icon stroke
|
|
124
|
+
from `primitive.icon-stroke`.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## `primitive.*` — the 26 visual primitives
|
|
129
|
+
|
|
130
|
+
One group, `primitive`, holding all 26 (leaf names are law — they map 1:1 to the emitted CSS
|
|
131
|
+
variables, without the leading `--`). Every token is either concrete or hinted.
|
|
132
|
+
|
|
133
|
+
| Family | Token (`primitive.…`) | `$type` | Notes | Example (source form) |
|
|
134
|
+
| --- | --- | --- | --- | --- |
|
|
135
|
+
| geometric | `radius` | `dimension` | | `6px` |
|
|
136
|
+
| | `shadow-intensity` | `number` | 0–1 multiplier on the emitted `--shadow-*` alpha | `0.4` |
|
|
137
|
+
| | `border-weight` | `dimension` | | `1px` |
|
|
138
|
+
| | `density-gap` | `number` | multiplier on the `0.25rem` spacing base | `1` |
|
|
139
|
+
| | `density-inset` | `number` | multiplier on component insets | `1` |
|
|
140
|
+
| typographic | `font-sans` | `fontFamily` | carries `.css` | `Inter, system-ui, sans-serif` |
|
|
141
|
+
| | `font-mono` | `fontFamily` | carries `.css` | `Geist Mono, ui-monospace, SFMono-Regular, monospace` |
|
|
142
|
+
| | `font-weight-normal` | `fontWeight` | | `400` |
|
|
143
|
+
| | `font-weight-strong` | `fontWeight` | | `600` |
|
|
144
|
+
| | `heading-tracking` | `number` | em multiplier; carries `.css` | `-0.01em` |
|
|
145
|
+
| temporal | `duration-unit` | `duration` | the tempo base | `50ms` |
|
|
146
|
+
| | `duration-fast` | `duration` | | `100ms` |
|
|
147
|
+
| | `duration-normal` | `duration` | | `150ms` |
|
|
148
|
+
| | `duration-slow` | `duration` | | `250ms` |
|
|
149
|
+
| | `ease-default` | `cubicBezier` | carries `.css` | `cubic-bezier(0.4,0,0.2,1)` |
|
|
150
|
+
| surface | `contrast-boost` | `number` | multiplier, 1 = default | `1` |
|
|
151
|
+
| iconography | `icon-stroke` | `number` | px stroke-width | `1.75` |
|
|
152
|
+
| | `icon-size-base` | `dimension` | | `16px` |
|
|
153
|
+
| layout | `sidebar-width-expanded` | `dimension` | | `248px` |
|
|
154
|
+
| | `sidebar-width-collapsed` | `dimension` | | `56px` |
|
|
155
|
+
| | `topbar-height` | `dimension` | | `52px` |
|
|
156
|
+
| | `side-panel-width` | `dimension` | | `420px` |
|
|
157
|
+
| | `side-panel-width-rich` | `dimension` | | `640px` |
|
|
158
|
+
| | `modal-width-max` | `dimension` | | `560px` |
|
|
159
|
+
| | `form-max-width` | `dimension` | | `640px` |
|
|
160
|
+
| | `table-row-height` | `dimension` | | `40px` |
|
|
161
|
+
|
|
162
|
+
**Derived, never stored.** Emission computes `--ease-enter`, `--ease-exit`, and `--stagger-delay`
|
|
163
|
+
from `ease-default` and `duration-unit`. They are not tokens, not authored, and not part of the
|
|
164
|
+
coverage gate. Do not add them.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## `color.*` — the 34 color roles
|
|
169
|
+
|
|
170
|
+
One flat group, `color`, holding all 34 (leaf names map 1:1 to the emitted `--<name>` variables).
|
|
171
|
+
Every token is `$type: "color"` with a typed `$value` **and** mandatory preserved `.css`.
|
|
172
|
+
|
|
173
|
+
- **Semantic (17):** `background` · `foreground` · `card` · `card-foreground` · `muted` ·
|
|
174
|
+
`muted-foreground` · `border` · `input` · `ring` · `primary` · `primary-foreground` · `accent` ·
|
|
175
|
+
`accent-foreground` · `destructive` · `destructive-foreground` · `success` · `warning`.
|
|
176
|
+
- **Substrate (17):** `popover` · `popover-foreground` · `secondary` · `secondary-foreground` ·
|
|
177
|
+
`chart-1` · `chart-2` · `chart-3` · `chart-4` · `chart-5` · `sidebar` · `sidebar-foreground` ·
|
|
178
|
+
`sidebar-primary` · `sidebar-primary-foreground` · `sidebar-accent` · `sidebar-accent-foreground` ·
|
|
179
|
+
`sidebar-border` · `sidebar-ring`.
|
|
180
|
+
|
|
181
|
+
No consumed token falls back to a shadcn-gray default: emission sets all 34. A color token may alias
|
|
182
|
+
another (`"$value": "{color.primary}"`), in which case it takes the target's `.css`; mechanical
|
|
183
|
+
conversion writes literals, aliases are for authored files.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## `typography.*` — families and the ramp
|
|
188
|
+
|
|
189
|
+
The first-class machine form of the type scale, in two subgroups. It reaches CSS variables only
|
|
190
|
+
through the primitives it aliases; emitters and exemplars read the ramp as data (size, line-height,
|
|
191
|
+
weight, tracking per step).
|
|
192
|
+
|
|
193
|
+
**`typography.family.*`** — the heading/body pairing plus mono, all `$type: "fontFamily"`:
|
|
194
|
+
|
|
195
|
+
| Token | Value |
|
|
196
|
+
| --- | --- |
|
|
197
|
+
| `typography.family.heading` | `"{primitive.font-sans}"` — or its own stack when the look pairs a distinct heading family. |
|
|
198
|
+
| `typography.family.body` | `"{primitive.font-sans}"` |
|
|
199
|
+
| `typography.family.mono` | `"{primitive.font-mono}"` |
|
|
200
|
+
|
|
201
|
+
**`typography.ramp.*`** — six fixed step names, each `$type: "typography"` carrying all five
|
|
202
|
+
sub-values:
|
|
203
|
+
|
|
204
|
+
| Step | Role |
|
|
205
|
+
| --- | --- |
|
|
206
|
+
| `h1` | page title |
|
|
207
|
+
| `h2` | section head |
|
|
208
|
+
| `h3` | card / group head |
|
|
209
|
+
| `body` | UI + prose |
|
|
210
|
+
| `small` | labels, meta, dense table |
|
|
211
|
+
| `caption` | uppercase eyebrow (text case is a usage rule; the composite carries no case slot) |
|
|
212
|
+
|
|
213
|
+
| Sub-value | Shape |
|
|
214
|
+
| --- | --- |
|
|
215
|
+
| `fontFamily` | alias to a `typography.family.*` token |
|
|
216
|
+
| `fontSize` | `dimension` (px) |
|
|
217
|
+
| `lineHeight` | number (unitless multiplier) |
|
|
218
|
+
| `fontWeight` | alias to `primitive.font-weight-strong` / `primitive.font-weight-normal`, or a number |
|
|
219
|
+
| `letterSpacing` | number (em multiplier) or alias to `primitive.heading-tracking` — the documented deviation |
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## The preserved-css pattern
|
|
224
|
+
|
|
225
|
+
Every formatting-sensitive value carries **two forms that must agree**: the typed `$value` (the
|
|
226
|
+
queryable semantic) and `$extensions["com.nurix.design"].css` — the exact source CSS string.
|
|
227
|
+
Emitters prefer the preserved string, so output is byte-stable across convert/emit round trips.
|
|
228
|
+
|
|
229
|
+
- **Mandatory `.css`:** every `color` token; `heading-tracking` (sources vary — `0`, `0em`,
|
|
230
|
+
`-0.015em`); `ease-default`; any `fontFamily` token carrying its own stack.
|
|
231
|
+
- **Omitted where serialization is deterministic:** `dimension` and `duration` serialize as
|
|
232
|
+
`<value><unit>`; `number` and `fontWeight` as the plain number; `cubicBezier` (absent `.css`) as
|
|
233
|
+
`cubic-bezier(x1, y1, x2, y2)`; `fontFamily` (absent `.css`) as the families joined with `", "`,
|
|
234
|
+
multi-word names double-quoted.
|
|
235
|
+
- **On a composite token**, `.css` is an object keyed by sub-value name, present for
|
|
236
|
+
formatting-sensitive inline sub-values (e.g. `{ "letterSpacing": "0.02em" }`); an aliased sub-value
|
|
237
|
+
takes its `.css` from the alias target.
|
|
238
|
+
- **Parse-back verification is a converter requirement:** whatever writes a token must verify that
|
|
239
|
+
parsing `.css` reproduces `$value` exactly, and that re-serializing `$value` reproduces the byte
|
|
240
|
+
form — oklch components are the literal source numbers; srgb components round-trip through the
|
|
241
|
+
`hex` field. The gate re-verifies.
|
|
242
|
+
|
|
243
|
+
## Hints and the coverage tri-state
|
|
244
|
+
|
|
245
|
+
DTCG has no hint concept; this is the convention. Where a value needs judgment, the token carries a
|
|
246
|
+
**valid provisional `$value`** plus `$extensions["com.nurix.design"].hint` — the intent in plain
|
|
247
|
+
words. Every gated token is in exactly one state:
|
|
248
|
+
|
|
249
|
+
| State | Marker | `--check` | `--emit` |
|
|
250
|
+
| --- | --- | --- | --- |
|
|
251
|
+
| **assigned** | real value, no `hint` key | passes | emits |
|
|
252
|
+
| **hinted** | `hint` key present | passes | **refuses**, naming every hinted path |
|
|
253
|
+
| **missing** | token absent | fails, naming the key | — |
|
|
254
|
+
|
|
255
|
+
Resolving a hint deletes the `hint` key and records the rationale in the token's `$description`, so
|
|
256
|
+
the resolved artifact is self-explaining and re-derivable. Judgment is recorded, never silent.
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{
|
|
260
|
+
"$type": "number",
|
|
261
|
+
"$value": 1,
|
|
262
|
+
"$extensions": { "com.nurix.design": { "hint": "nudge borders up a step so the dense table grid reads as a grid" } }
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
resolves to:
|
|
267
|
+
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"$type": "number",
|
|
271
|
+
"$value": 1.1,
|
|
272
|
+
"$description": "derived: dense-grid brief, one step up (was hint)"
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Per-value provenance
|
|
277
|
+
|
|
278
|
+
A value's provenance rationale — why it diverges from a brand default, what judgment resolved its
|
|
279
|
+
hint — lives in the token's `$description`. Mechanical conversion moves source comments here.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## The dark set — `design.tokens.dark.json`
|
|
284
|
+
|
|
285
|
+
Ships **only when the look has dark values**; light is never omitted — the base set is the light
|
|
286
|
+
rendering. When it ships:
|
|
287
|
+
|
|
288
|
+
- It carries exactly the `color` group, all 34 roles, same shape rules (typed `$value` + `.css`) —
|
|
289
|
+
and nothing else: no primitives, no typography, no payload (the base file is the payload's single
|
|
290
|
+
carrier).
|
|
291
|
+
- Emission targets `[data-theme="dark"]`, remapping all 34; when the file is absent, no dark block is
|
|
292
|
+
emitted and the project is light-only.
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"color": {
|
|
297
|
+
"background": { "$type": "color", "$value": { "colorSpace": "oklch", "components": [0.2077, 0.0398, 265.75] }, "$extensions": { "com.nurix.design": { "css": "oklch(0.2077 0.0398 265.75)" } } },
|
|
298
|
+
"foreground": { "$type": "color", "$value": { "colorSpace": "oklch", "components": [0.9842, 0.0034, 247.86] }, "$extensions": { "com.nurix.design": { "css": "oklch(0.9842 0.0034 247.86)" } } }
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
(Fragment — a real dark file carries all 34.)
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## The resolver — `design.resolver.json`
|
|
308
|
+
|
|
309
|
+
The DTCG resolver document has no stable snapshot, so this shape is **ours-until-standardized** — the
|
|
310
|
+
exact minimal shape the scripts implement, confined to this file so a future spec shift lands in one
|
|
311
|
+
place.
|
|
312
|
+
|
|
313
|
+
| Key | Shape |
|
|
314
|
+
| --- | --- |
|
|
315
|
+
| `schema` | Literal `design-resolver/v1`. |
|
|
316
|
+
| `sets` | Array of `{ "name": string, "values": [file, …] }` — the base token files, in load order. |
|
|
317
|
+
| `modifiers` | Array of `{ "name": string, "default": string, "contexts": { <context>: [file, …] } }`. Exactly one modifier today: `theme`. |
|
|
318
|
+
|
|
319
|
+
**Resolution order (deterministic):** concatenate the set files in array order; select one context
|
|
320
|
+
per modifier (the `default` when unstated); overlay the context's files in order — a later file
|
|
321
|
+
overrides an earlier one per token path, and an overlay may only override paths that exist in the
|
|
322
|
+
base, never introduce new ones. Aliases resolve after overlay. **Light-first:** `theme.default` is
|
|
323
|
+
always `light`, and the `light` context is always the empty overlay `[]` — the base set is the light
|
|
324
|
+
rendering. A light-only look carries only the `light` context; a look with dark adds
|
|
325
|
+
`"dark": ["design.tokens.dark.json"]`:
|
|
326
|
+
|
|
327
|
+
```json
|
|
328
|
+
{
|
|
329
|
+
"schema": "design-resolver/v1",
|
|
330
|
+
"sets": [{ "name": "base", "values": ["design.tokens.json"] }],
|
|
331
|
+
"modifiers": [
|
|
332
|
+
{ "name": "theme", "default": "light", "contexts": { "light": [], "dark": ["design.tokens.dark.json"] } }
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Emission mapping
|
|
340
|
+
|
|
341
|
+
The slug is the payload's `product`, slugified. Emission order is this document's enumeration order
|
|
342
|
+
(mirrored by the consumer's arrays); JSON key order carries no meaning.
|
|
343
|
+
|
|
344
|
+
| Source | Emitted target |
|
|
345
|
+
| --- | --- |
|
|
346
|
+
| `primitive.<name>` (24 static) | `[data-style="<slug>"] { --<name>: … }` — 1:1 by leaf name |
|
|
347
|
+
| `primitive.density-gap` / `density-inset` | governed refs (`var(--density-base-gap/inset)`); the tier writes the base |
|
|
348
|
+
| `color.<name>` (34) | `:root, :root[data-theme="light"] { --<name>: … }` |
|
|
349
|
+
| dark set `color.<name>` | `[data-theme="dark"] { --<name>: … }` — only when the dark file ships |
|
|
350
|
+
| `verbosity` / `feedback` / `density-tier` | `<html data-verbosity / data-feedback / data-density>` |
|
|
351
|
+
| `product` | `<html data-style="<slug>">` |
|
|
352
|
+
| `product-traits` | read by the front gate; never emitted |
|
|
353
|
+
| `typography.family.*` / `typography.ramp.*` | data for emitters and exemplars; reaches CSS only through the primitives it aliases |
|
|
354
|
+
| — (derived at emit) | `--ease-enter`, `--ease-exit`, `--stagger-delay` from `ease-default` + `duration-unit` |
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Validation — what `--check` enforces
|
|
359
|
+
|
|
360
|
+
The coverage gate. It exits non-zero and **names every offending path** so the fix is mechanical; an
|
|
361
|
+
artifact that passes is guaranteed derivable.
|
|
362
|
+
|
|
363
|
+
1. **Files** — `design.tokens.json` and `design.resolver.json` present and parse as JSON; every file
|
|
364
|
+
the resolver references exists beside it; `design.tokens.dark.json` exists exactly when the
|
|
365
|
+
resolver's `dark` context names it.
|
|
366
|
+
2. **Payload** — the base file's root `$extensions["com.nurix.design"]` present with: `schema` literal
|
|
367
|
+
`design-tokens/v1`; `dtcg` literal `2025.10`; `product` non-empty; `provenance` legal; `sourced` an
|
|
368
|
+
ISO date; `verbosity` / `feedback` / `density-tier` legal enum values (never hinted);
|
|
369
|
+
`product-traits` a non-empty array; `lever-manifest` carrying all six keys.
|
|
370
|
+
3. **Primitive coverage** — all 26 `primitive.*` tokens present with the exact `$type` this schema
|
|
371
|
+
assigns, each assigned or hinted; fails naming every absent, empty, or mistyped key.
|
|
372
|
+
4. **Color coverage** — all 34 `color.*` tokens present, `$type: "color"`, `colorSpace` one of
|
|
373
|
+
`oklch` | `srgb`, `.css` present, each assigned or hinted; fails naming every missing token.
|
|
374
|
+
5. **Typography coverage** — `typography.family.heading|body|mono` present (`fontFamily`);
|
|
375
|
+
`typography.ramp.h1|h2|h3|body|small|caption` present (`typography`), each composite carrying all
|
|
376
|
+
five sub-values.
|
|
377
|
+
6. **Alias integrity** — every `{path}` reference resolves within the artifact to a token of the
|
|
378
|
+
required type; no cycles.
|
|
379
|
+
7. **Manifest scales** — `spacing-scale`, `radius-scale`, `motion.durations` non-empty and ascending;
|
|
380
|
+
`motion.easings` non-empty; `shadow-levels` non-empty, drawn from the legal vocabulary, strictly
|
|
381
|
+
increasing in intensity; `icons.family` non-empty; `accent-count` ≥ 1.
|
|
382
|
+
8. **Manifest consistency** — the look's own base values sit on its own allowlist: `radius` ∈
|
|
383
|
+
`radius-scale`; `duration-fast` / `duration-normal` / `duration-slow` ∈ `motion.durations`;
|
|
384
|
+
`ease-default`'s serialization ∈ `motion.easings`.
|
|
385
|
+
9. **Parse-back** — for every token carrying `.css`, parsing the string reproduces `$value` and
|
|
386
|
+
re-serializing `$value` reproduces the byte form.
|
|
387
|
+
10. **Dark completeness** — the dark file, when present, carries exactly the `color` group with all
|
|
388
|
+
34 roles under the same shape rules, and nothing else.
|
|
389
|
+
11. **Spec conformance** — only the eight `$type` values this schema uses appear; no invented
|
|
390
|
+
`$type`; unknown `$extensions` namespaces are preserved, never authored.
|
|
391
|
+
12. **Emission precondition** — `--emit` runs only over a passing artifact and refuses while any
|
|
392
|
+
token carries a `hint`, naming every hinted path.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Worked example — the Nurix default (abbreviated)
|
|
397
|
+
|
|
398
|
+
`data/design-tokens/nurix/design.tokens.json`, abbreviated to a representative subset of each token
|
|
399
|
+
family — the real file carries all 26 primitives, all 34 color roles, and the full six-step ramp.
|
|
400
|
+
Nurix ships no dark set, so `design.tokens.dark.json` is absent and the resolver carries only the
|
|
401
|
+
`light` context.
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
{
|
|
405
|
+
"$description": "Nurix default — the look a zero-input project wears. Abbreviated here; the shipped file is complete.",
|
|
406
|
+
"$extensions": {
|
|
407
|
+
"com.nurix.design": {
|
|
408
|
+
"schema": "design-tokens/v1",
|
|
409
|
+
"dtcg": "2025.10",
|
|
410
|
+
"product": "Nurix",
|
|
411
|
+
"provenance": "default",
|
|
412
|
+
"sourced": "2026-07-04",
|
|
413
|
+
"product-traits": ["operator-console", "crm", "queue", "dashboard", "admin"],
|
|
414
|
+
"verbosity": "default",
|
|
415
|
+
"feedback": "subtle",
|
|
416
|
+
"density-tier": "standard",
|
|
417
|
+
"lever-manifest": {
|
|
418
|
+
"spacing-scale": [2, 4, 8, 12, 16, 24, 32, 48, 64],
|
|
419
|
+
"radius-scale": [0, 4, 6, 12, 9999],
|
|
420
|
+
"shadow-levels": ["none", "sm", "md"],
|
|
421
|
+
"motion": { "durations": [100, 150, 250], "easings": ["cubic-bezier(0.4,0,0.2,1)"] },
|
|
422
|
+
"icons": { "family": "lucide" },
|
|
423
|
+
"accent-count": 1
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
"primitive": {
|
|
428
|
+
"radius": {
|
|
429
|
+
"$type": "dimension",
|
|
430
|
+
"$value": { "value": 6, "unit": "px" },
|
|
431
|
+
"$description": "brand default 12px is marketing-surface soft; operator default tightens for a denser, engineered read"
|
|
432
|
+
},
|
|
433
|
+
"shadow-intensity": {
|
|
434
|
+
"$type": "number",
|
|
435
|
+
"$value": 0.4,
|
|
436
|
+
"$description": "brand is predominantly flat; shadow only lifts true overlays"
|
|
437
|
+
},
|
|
438
|
+
"border-weight": { "$type": "dimension", "$value": { "value": 1, "unit": "px" } },
|
|
439
|
+
"density-gap": { "$type": "number", "$value": 1 },
|
|
440
|
+
"font-sans": {
|
|
441
|
+
"$type": "fontFamily",
|
|
442
|
+
"$value": ["Inter", "system-ui", "sans-serif"],
|
|
443
|
+
"$description": "brand's body font; the single sans slot serves dense body/table chrome",
|
|
444
|
+
"$extensions": { "com.nurix.design": { "css": "Inter, system-ui, sans-serif" } }
|
|
445
|
+
},
|
|
446
|
+
"font-mono": {
|
|
447
|
+
"$type": "fontFamily",
|
|
448
|
+
"$value": ["Geist Mono", "ui-monospace", "SFMono-Regular", "monospace"],
|
|
449
|
+
"$description": "Geist monospace sibling — IDs, codes, log lines",
|
|
450
|
+
"$extensions": { "com.nurix.design": { "css": "Geist Mono, ui-monospace, SFMono-Regular, monospace" } }
|
|
451
|
+
},
|
|
452
|
+
"font-weight-normal": {
|
|
453
|
+
"$type": "fontWeight",
|
|
454
|
+
"$value": 400,
|
|
455
|
+
"$description": "brand base 500 is display-tuned; dense operator body reads cleaner at 400"
|
|
456
|
+
},
|
|
457
|
+
"font-weight-strong": { "$type": "fontWeight", "$value": 600 },
|
|
458
|
+
"heading-tracking": {
|
|
459
|
+
"$type": "number",
|
|
460
|
+
"$value": -0.01,
|
|
461
|
+
"$description": "em multiplier; brand display tracks 0 — at operator heading sizes Inter reads tighter",
|
|
462
|
+
"$extensions": { "com.nurix.design": { "css": "-0.01em" } }
|
|
463
|
+
},
|
|
464
|
+
"duration-unit": { "$type": "duration", "$value": { "value": 50, "unit": "ms" } },
|
|
465
|
+
"ease-default": {
|
|
466
|
+
"$type": "cubicBezier",
|
|
467
|
+
"$value": [0.4, 0, 0.2, 1],
|
|
468
|
+
"$extensions": { "com.nurix.design": { "css": "cubic-bezier(0.4,0,0.2,1)" } }
|
|
469
|
+
},
|
|
470
|
+
"icon-stroke": {
|
|
471
|
+
"$type": "number",
|
|
472
|
+
"$value": 1.75,
|
|
473
|
+
"$description": "one step under lucide's 2 for a refined operator stroke"
|
|
474
|
+
},
|
|
475
|
+
"sidebar-width-expanded": { "$type": "dimension", "$value": { "value": 248, "unit": "px" } },
|
|
476
|
+
"table-row-height": {
|
|
477
|
+
"$type": "dimension",
|
|
478
|
+
"$value": { "value": 40, "unit": "px" },
|
|
479
|
+
"$description": "comfortable at standard density; dense archetypes step down via the surface catalog"
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
"color": {
|
|
483
|
+
"background": {
|
|
484
|
+
"$type": "color",
|
|
485
|
+
"$value": { "colorSpace": "oklch", "components": [1, 0, 0] },
|
|
486
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(1 0 0)" } }
|
|
487
|
+
},
|
|
488
|
+
"foreground": {
|
|
489
|
+
"$type": "color",
|
|
490
|
+
"$value": { "colorSpace": "oklch", "components": [0.2077, 0.0398, 265.75] },
|
|
491
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(0.2077 0.0398 265.75)" } }
|
|
492
|
+
},
|
|
493
|
+
"border": {
|
|
494
|
+
"$type": "color",
|
|
495
|
+
"$value": { "colorSpace": "oklch", "components": [0.9288, 0.0126, 255.51] },
|
|
496
|
+
"$description": "brand #E2E8F0 — every separator, grid line, and field edge",
|
|
497
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(0.9288 0.0126 255.51)" } }
|
|
498
|
+
},
|
|
499
|
+
"primary": {
|
|
500
|
+
"$type": "color",
|
|
501
|
+
"$value": { "colorSpace": "oklch", "components": [0.5211, 0.2145, 263.89] },
|
|
502
|
+
"$description": "brand #245AE2 — the one accent",
|
|
503
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(0.5211 0.2145 263.89)" } }
|
|
504
|
+
},
|
|
505
|
+
"primary-foreground": {
|
|
506
|
+
"$type": "color",
|
|
507
|
+
"$value": { "colorSpace": "oklch", "components": [1, 0, 0] },
|
|
508
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(1 0 0)" } }
|
|
509
|
+
},
|
|
510
|
+
"warning": {
|
|
511
|
+
"$type": "color",
|
|
512
|
+
"$value": { "colorSpace": "oklch", "components": [0.6658, 0.1574, 58.32] },
|
|
513
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(0.6658 0.1574 58.32)" } }
|
|
514
|
+
},
|
|
515
|
+
"chart-2": {
|
|
516
|
+
"$type": "color",
|
|
517
|
+
"$value": { "colorSpace": "oklch", "components": [0.6089, 0.1109, 221.72] },
|
|
518
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(0.6089 0.1109 221.72)" } }
|
|
519
|
+
},
|
|
520
|
+
"sidebar": {
|
|
521
|
+
"$type": "color",
|
|
522
|
+
"$value": { "colorSpace": "oklch", "components": [0.9842, 0.0034, 247.86] },
|
|
523
|
+
"$extensions": { "com.nurix.design": { "css": "oklch(0.9842 0.0034 247.86)" } }
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
"typography": {
|
|
527
|
+
"family": {
|
|
528
|
+
"heading": { "$type": "fontFamily", "$value": "{primitive.font-sans}" },
|
|
529
|
+
"body": { "$type": "fontFamily", "$value": "{primitive.font-sans}" },
|
|
530
|
+
"mono": { "$type": "fontFamily", "$value": "{primitive.font-mono}" }
|
|
531
|
+
},
|
|
532
|
+
"ramp": {
|
|
533
|
+
"h1": {
|
|
534
|
+
"$type": "typography",
|
|
535
|
+
"$value": {
|
|
536
|
+
"fontFamily": "{typography.family.heading}",
|
|
537
|
+
"fontSize": { "value": 24, "unit": "px" },
|
|
538
|
+
"lineHeight": 1.25,
|
|
539
|
+
"fontWeight": "{primitive.font-weight-strong}",
|
|
540
|
+
"letterSpacing": "{primitive.heading-tracking}"
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
"body": {
|
|
544
|
+
"$type": "typography",
|
|
545
|
+
"$value": {
|
|
546
|
+
"fontFamily": "{typography.family.body}",
|
|
547
|
+
"fontSize": { "value": 14, "unit": "px" },
|
|
548
|
+
"lineHeight": 1.45,
|
|
549
|
+
"fontWeight": "{primitive.font-weight-normal}",
|
|
550
|
+
"letterSpacing": 0
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
"caption": {
|
|
554
|
+
"$type": "typography",
|
|
555
|
+
"$value": {
|
|
556
|
+
"fontFamily": "{typography.family.body}",
|
|
557
|
+
"fontSize": { "value": 12, "unit": "px" },
|
|
558
|
+
"lineHeight": 1.2,
|
|
559
|
+
"fontWeight": "{primitive.font-weight-strong}",
|
|
560
|
+
"letterSpacing": 0.02
|
|
561
|
+
},
|
|
562
|
+
"$description": "uppercase eyebrow — text case is a usage rule; the composite carries no case slot",
|
|
563
|
+
"$extensions": { "com.nurix.design": { "css": { "letterSpacing": "0.02em" } } }
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
`data/design-tokens/nurix/design.resolver.json`:
|
|
571
|
+
|
|
572
|
+
```json
|
|
573
|
+
{
|
|
574
|
+
"schema": "design-resolver/v1",
|
|
575
|
+
"sets": [{ "name": "base", "values": ["design.tokens.json"] }],
|
|
576
|
+
"modifiers": [
|
|
577
|
+
{ "name": "theme", "default": "light", "contexts": { "light": [] } }
|
|
578
|
+
]
|
|
579
|
+
}
|
|
580
|
+
```
|