@aziontech/theme 1.12.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +1 -1
  2. package/package.json +19 -21
  3. package/src/scripts/build-tokens.mjs +391 -0
  4. package/src/scripts/compile-primitives.js +165 -0
  5. package/src/scripts/compile-theme.js +117 -0
  6. package/src/{tokens/build → scripts}/css-vars.js +10 -9
  7. package/src/{tokens/build → scripts}/resolve.js +2 -0
  8. package/src/tests/primitives.html +293 -0
  9. package/src/tests/theme.html +310 -0
  10. package/src/tests/tokens.html +84 -0
  11. package/src/tokens/README.md +306 -272
  12. package/src/tokens/index.js +4 -12
  13. package/src/tokens/primitives/animations/animate.js +8 -0
  14. package/src/tokens/primitives/animations/ease.js +7 -0
  15. package/src/tokens/primitives/border-widths.js +9 -0
  16. package/src/tokens/primitives/breakpoints.js +9 -0
  17. package/src/tokens/primitives/colors/alpha.js +104 -0
  18. package/src/tokens/primitives/colors/brand.js +40 -0
  19. package/src/tokens/primitives/colors/colors.js +142 -0
  20. package/src/tokens/primitives/effects/blur.js +11 -0
  21. package/src/tokens/primitives/effects/drop-shadow.js +10 -0
  22. package/src/tokens/primitives/effects/inset-shadow.js +7 -0
  23. package/src/tokens/primitives/effects/opacity.js +8 -0
  24. package/src/tokens/primitives/effects/perspective.js +9 -0
  25. package/src/tokens/primitives/effects/shadow.js +11 -0
  26. package/src/tokens/primitives/ring-offset.js +5 -0
  27. package/src/tokens/primitives/shape/aspect-video.js +3 -0
  28. package/src/tokens/primitives/shape/container.js +17 -0
  29. package/src/tokens/primitives/shape/height.js +32 -0
  30. package/src/tokens/primitives/shape/radius.js +13 -0
  31. package/src/tokens/primitives/shape/shape.js +12 -0
  32. package/src/tokens/primitives/shape/size.js +32 -0
  33. package/src/tokens/primitives/shape/spacing.js +33 -0
  34. package/src/tokens/primitives/shape/width.js +19 -0
  35. package/src/tokens/primitives/typography/font-family.js +7 -0
  36. package/src/tokens/primitives/typography/font-size.js +30 -0
  37. package/src/tokens/primitives/typography/font-weight.js +13 -0
  38. package/src/tokens/primitives/typography/leading.js +9 -0
  39. package/src/tokens/primitives/typography/line-height.js +13 -0
  40. package/src/tokens/primitives/typography/tracking.js +10 -0
  41. package/src/{tailwind/semantic-animations-plugin.js → tokens/semantic/animations.js} +3 -21
  42. package/src/tokens/semantic/colors.js +138 -0
  43. package/src/tokens/semantic/containers.data.js +18 -0
  44. package/src/tokens/semantic/containers.js +70 -0
  45. package/src/tokens/semantic/spacings.data.js +18 -0
  46. package/src/tokens/semantic/spacings.js +163 -0
  47. package/src/tokens/semantic/texts.data.js +103 -0
  48. package/src/{tailwind/semantic-texts-plugin.js → tokens/semantic/texts.js} +91 -70
  49. package/src/tokens/theme/accent.js +18 -0
  50. package/src/tokens/theme/background.js +32 -0
  51. package/src/tokens/theme/border.js +18 -0
  52. package/src/tokens/theme/feedback/danger.js +16 -0
  53. package/src/tokens/theme/feedback/info.js +16 -0
  54. package/src/tokens/theme/feedback/success.js +16 -0
  55. package/src/tokens/theme/feedback/warning.js +16 -0
  56. package/src/tokens/theme/primary.js +18 -0
  57. package/src/tokens/theme/ring.js +12 -0
  58. package/src/tokens/theme/secondary.js +18 -0
  59. package/src/tokens/theme/surfaces.js +23 -0
  60. package/src/tokens/theme/text.js +18 -0
  61. package/src/tokens/theme.js +32 -0
  62. package/colors-brand.js +0 -24
  63. package/src/tailwind/semantic-colors-plugin.js +0 -91
  64. package/src/tailwind/semantic-spacing-plugin.js +0 -151
  65. package/src/tailwind/tailwind-theme.js +0 -54
  66. package/src/tokens/build/preset.js +0 -62
  67. package/src/tokens/build/tailwind-flat-colors.js +0 -75
  68. package/src/tokens/build/tailwind-helper.js +0 -12
  69. package/src/tokens/build/tailwind-plugin.js +0 -175
  70. package/src/tokens/colors-brand.js +0 -24
  71. package/src/tokens/primitives/brand.js +0 -69
  72. package/src/tokens/primitives/colors.js +0 -144
  73. package/src/tokens/semantic/backgrounds.js +0 -46
  74. package/src/tokens/semantic/borders.js +0 -44
  75. package/src/tokens/semantic/text.js +0 -48
  76. /package/src/{tokens/build → scripts}/refs.js +0 -0
@@ -1,345 +1,379 @@
1
+ <h1 align="center">azion-theme · tokens</h1>
1
2
 
2
- <h1 align="center">azion-theme</h1>
3
+ Design tokens organized as JavaScript modules, compiled into CSS custom properties and a Tailwind config. The pipeline emits **two parallel targets** from the same source:
3
4
 
4
- ![production](https://github.com/aziontech/azion-theme/actions/workflows/release.yml/badge.svg)
5
+ - **`dist/v3/`** — Tailwind v3 preset (`tailwind-preset.js` / `tailwind.config.js`) + a self-contained `globals.css` with `@tailwind` directives, `:root` / `[data-theme=dark]` blocks, responsive `@media` overrides, and the component classes.
6
+ - **`dist/v4/`** — Tailwind v4 CSS-first output: `globals.css` with `@import "tailwindcss"` + `@theme { … }` + plain `:root` for shape/typography semantics + `@layer components`.
5
7
 
6
- <p align="center">
7
- <img
8
- src="./doc/cover-image.png"
9
- width="1200px"
10
- />
11
- </p>
8
+ Tokens live in JS as the source-of-truth and are compiled at package build time, not in the browser.
12
9
 
13
- The Azion Theme repository is focused on sharing our style kit across interfaces and should be used in all company projects, including Azion Console Kit, Azion Site, Landing Pages, and all user interactions with Azion.
10
+ ## 📋 Table of contents
14
11
 
15
- ## 📋 Table of Contents
12
+ - [Architecture overview](#-architecture-overview)
13
+ - [File structure](#-file-structure)
14
+ - [Token types](#-token-types)
15
+ - [Building & consuming](#-building--consuming)
16
+ - [How to add a new token](#-how-to-add-a-new-token)
17
+ - [Token references (`tokenRef`)](#-token-references-tokenref)
18
+ - [Test pages](#-test-pages)
19
+ - [Theme switching](#-theme-switching)
16
20
 
17
- - [Installation](#-installation)
18
- - [Usage](#-usage)
19
- - [Development](#-development)
20
- - [Design Tokens](#-design-tokens)
21
- - [Links](#-links)
21
+ ---
22
22
 
23
- ## 🚀 Installation
23
+ ## 🏗 Architecture overview
24
24
 
25
- To install the `azion-theme` project, you need to follow the command. Choose one of your preferences: npm or yarn:
25
+ Three layers:
26
26
 
27
- ```bash
28
- npm install azion-theme --save
29
- # or
30
- yarn add azion-theme
31
- ```
27
+ 1. **Primitives** — raw, theme-invariant values (color hexes, px sizes, font sizes, durations).
28
+ 2. **Semantic / theme** — light/dark variants and responsive (per-breakpoint) tokens that **reference** primitives via `tokenRef(...)`.
29
+ 3. **Output bundles** — `dist/v3/` and `dist/v4/` artifacts emitted by `scripts/build-tokens.mjs`.
32
30
 
33
- Alternatively, you can configure the `package.json` file by adding the dependency:
31
+ Compile pipeline:
34
32
 
35
- ```json
36
- {
37
- "dependencies": {
38
- "azion-theme": "^1.4.0"
39
- }
40
- }
33
+ ```
34
+ tokens/primitives/** ─┐
35
+ │
36
+ tokens/semantic/colors.js ─┤
37
+ tokens/semantic/*.data.js ─┼──► scripts/build-tokens.mjs ──► dist/v3/{globals.css,tailwind-preset.js,tailwind.config.js}
38
+ tokens/theme/** ─┤ dist/v4/globals.css
39
+ │
40
+ scripts/{compile-primitives, ─┘
41
+ compile-theme,
42
+ resolve,
43
+ css-vars,
44
+ refs}.js (building blocks used by build-tokens.mjs)
41
45
  ```
42
46
 
43
- After updating the `package.json` file, run `npm install` in the root of your project to install the Azion Theme.
47
+ - Primitives emit a single block (values don't change between themes).
48
+ - Semantic colors flip between `:root, [data-theme=light]` and `[data-theme=dark], .dark, .azion.azion-dark`.
49
+ - Responsive semantic tokens (containers, spacings, texts) emit `@media (min-width: …)` overrides.
44
50
 
45
- ### 🔗 Integration with Front-End Project
51
+ ---
46
52
 
47
- To integrate the Azion Theme into your front-end project, you need to import the theme files in your project's entry point file (App.vue, main.js, index.js, etc.):
53
+ ## 📂 File structure
48
54
 
49
- ```javascript
50
- import 'azion-theme/dark';
51
- import 'azion-theme/light';
55
+ ```
56
+ src/
57
+ ├── tokens/
58
+ │ ├── primitives/
59
+ │ │ ├── colors/
60
+ │ │ │ ├── colors.js # base, blue, gray, violet, orange, slate, yellow,
61
+ │ │ │ │ # green, red + surface palettes + brand re-export
62
+ │ │ │ ├── brand.js # primary, accent, surfaces, absolute
63
+ │ │ │ └── alpha.js # alpha variants for each palette
64
+ │ │ ├── shape/
65
+ │ │ │ ├── aspect-video.js
66
+ │ │ │ ├── container.js # container-3xs … container-7xl
67
+ │ │ │ ├── height.js # h-2 … h-96
68
+ │ │ │ ├── radius.js # none, sm, DEFAULT, md, lg, xl, 2xl, 3xl, full
69
+ │ │ │ ├── shape.js # shape aliases (`max-w-*`, etc.)
70
+ │ │ │ ├── size.js # size-2 … size-96
71
+ │ │ │ ├── spacing.js # spacing-1 … spacing-96
72
+ │ │ │ └── width.js # w-3xs … w-7xl (alias → container.X)
73
+ │ │ ├── typography/
74
+ │ │ │ ├── font-family.js # sans, mono, code
75
+ │ │ │ ├── font-size.js # text-xs … text-9xl
76
+ │ │ │ ├── font-weight.js # 100 … 900
77
+ │ │ │ ├── leading.js # leading-3 … leading-10
78
+ │ │ │ ├── line-height.js # line-height-none … line-height-loose
79
+ │ │ │ └── tracking.js # tracking-tighter … tracking-widest
80
+ │ │ ├── effects/
81
+ │ │ │ ├── blur.js # blur-xs … blur-3xl
82
+ │ │ │ ├── drop-shadow.js
83
+ │ │ │ ├── inset-shadow.js
84
+ │ │ │ ├── opacity.js # opacity-0 … opacity-100
85
+ │ │ │ ├── perspective.js
86
+ │ │ │ └── shadow.js # box-shadow scale
87
+ │ │ ├── animations/
88
+ │ │ │ ├── animate.js # named keyframe animations
89
+ │ │ │ └── ease.js # easing curves
90
+ │ │ ├── border-widths.js # border-0 … border-4
91
+ │ │ ├── breakpoints.js # sm, md, lg, xl, 2xl
92
+ │ │ └── ring-offset.js
93
+ │ ├── theme/
94
+ │ │ ├── primary.js # primary, primary-mask/hover/contrast
95
+ │ │ ├── secondary.js
96
+ │ │ ├── accent.js
97
+ │ │ ├── surfaces.js # surface-0 … surface-950 (alias for gray)
98
+ │ │ ├── background.js # bg-canvas, bg-surface, bg-mask, …
99
+ │ │ ├── border.js # border-default/muted/strong/selected
100
+ │ │ ├── text.js # text-default, text-muted
101
+ │ │ ├── ring.js # ring-color
102
+ │ │ └── feedback/
103
+ │ │ ├── success.js
104
+ │ │ ├── warning.js
105
+ │ │ ├── danger.js
106
+ │ │ └── info.js
107
+ │ ├── semantic/
108
+ │ │ ├── colors.js # text/background/border semantic refs (consumed by v3 preset)
109
+ │ │ ├── containers.js # static + responsive container tokens
110
+ │ │ ├── containers.data.js # `{ key: { sm, md, lg, … } }` data table
111
+ │ │ ├── spacings.js
112
+ │ │ ├── spacings.data.js
113
+ │ │ ├── texts.js
114
+ │ │ ├── texts.data.js # font-size + line-height + letter-spacing bundles
115
+ │ │ └── animations.js
116
+ │ ├── theme.js # Tailwind theme.extend (colors + semantic mappings)
117
+ │ └── index.js # public re-exports
118
+ ├── scripts/
119
+ │ ├── refs.js # tokenRef helper + isTokenRef guard
120
+ │ ├── resolve.js # resolves `tokenRef` paths to literal values
121
+ │ ├── css-vars.js # builds light/dark CSS var maps from semantic refs
122
+ │ ├── compile-primitives.js # flattens primitive trees into CSS vars
123
+ │ ├── compile-theme.js # legacy theme compiler (used by the harness pages)
124
+ │ └── build-tokens.mjs # main entrypoint: emits dist/v3 and dist/v4 bundles
125
+ └── tests/
126
+ ├── primitives.html # visual harness for all primitives
127
+ ├── theme.html # semantic tokens with light/dark toggle
128
+ └── tokens.html # combined view
52
129
  ```
53
130
 
54
- Make sure to include these imports at the top of your entry point file to ensure the styles are applied correctly throughout your application.
55
-
56
- ## 💻 Development
131
+ ---
57
132
 
58
- To work locally, you should clone both the `azion-theme` repository and the other repository where the theme will be used.
133
+ ## 🎨 Token types
59
134
 
60
- ### Example:
135
+ ### Primitives
61
136
 
62
- In this example, we will use the [azion-webkit](https://github.com/aziontech/azion-webkit) repository:
137
+ Plain JS objects with literal values. Theme-invariant.
63
138
 
64
- 1. Clone the `azion-webkit` and `azion-theme` repositories:
65
-
66
- ```bash
67
- git clone https://github.com/aziontech/azion-webkit.git
68
- git clone https://github.com/aziontech/azion-theme.git
69
- ```
139
+ ```js
140
+ // tokens/primitives/colors/brand.js
141
+ export const brandPrimitives = {
142
+ primary: { 50: '#FFF5EF', 100: '#FFE7D8', /* … */ 500: '#FE601F', /* … */ 950: '#401602' },
143
+ accent: { 50: '#F6F6FF', /* … */ 500: '#8A84EC', /* … */ 950: '#0B0A19' },
144
+ absolute: { black: '#0A0A0A', white: '#FCFCFC' },
145
+ };
146
+ ```
70
147
 
71
- 2. Install dependencies and create the link point:
72
-
73
- ```bash
74
- cd ./azion-theme && npm i && npm link
75
- ```
148
+ ```js
149
+ // tokens/primitives/shape/spacing.js
150
+ export const spacing = { 1: '4px', 2: '8px', /* … */ 96: '384px' };
151
+ ```
76
152
 
77
- 3. Link the `azion-theme` to the `azion-webkit` project:
78
-
79
- ```bash
80
- cd ../azion-webkit && npm i && npm link azion-theme
81
- ```
153
+ ### Semantic / theme
82
154
 
83
- Any modifications made to `azion-theme` will be reflected on this development server with hot reload.
155
+ Objects with `light` / `dark` variants. Values are `tokenRef(...)` calls that point to primitives.
84
156
 
85
- ## 🎨 Design Tokens
157
+ ```js
158
+ // tokens/theme/primary.js
159
+ import { tokenRef } from '../../scripts/refs.js';
86
160
 
87
- This project includes **primitive color tokens** extracted directly from Figma, ready to be consumed via Tailwind CSS.
161
+ export const primary = {
162
+ light: {
163
+ primary: tokenRef('brand.primary.primary-500'),
164
+ 'primary-mask': tokenRef('primitives.alpha.orange.100'),
165
+ 'primary-hover': tokenRef('brand.primary.primary-600'),
166
+ 'primary-contrast': tokenRef('primitives.base.black'),
167
+ },
168
+ dark: {
169
+ primary: tokenRef('brand.primary.primary-500'),
170
+ 'primary-mask': tokenRef('primitives.alpha.orange.100'),
171
+ 'primary-hover': tokenRef('brand.primary.primary-600'),
172
+ 'primary-contrast': tokenRef('primitives.base.white'),
173
+ },
174
+ };
175
+ ```
88
176
 
89
- ### 🚀 How to Use the Tokens
177
+ ### Responsive semantic data (`*.data.js`)
90
178
 
91
- ```javascript
92
- // tailwind.config.js
93
- import typography from '@tailwindcss/typography';
94
- import { tokenUtilities } from 'azion-theme/tokens/build/tailwind-plugin';
95
- import colors from 'azion-theme/tokens';
179
+ Containers, spacings, and texts use a per-breakpoint table that `build-tokens.mjs` flattens into `@media` overrides plus matching component classes (`.gap-…`, `.p-…`, `.text-…`, `.px-container`, `.py-container`, `.max-container-width`).
96
180
 
97
- export default {
98
- content: ['./src/**/*.{js,ts,jsx,tsx,html}'],
99
- darkMode: ['class', '.dark', '.azion.azion-dark'],
100
- theme: {
101
- extend: {
102
- colors: {
103
- ...colors,
104
- },
105
- },
106
- },
107
- plugins: [tokenUtilities(), typography],
181
+ ```js
182
+ // tokens/semantic/spacings.data.js
183
+ export const spacingsData = {
184
+ 'gap-sm': { _: '8px', md: '12px', xl: '16px' },
185
+ 'gap-md': { _: '12px', md: '16px', xl: '24px' },
186
+ // …
108
187
  };
109
188
  ```
110
189
 
111
- #### Token structure overview
190
+ `_` is the base value emitted in `:root`; the breakpoint keys (`sm`, `md`, `lg`, `xl`, `2xl`) become media-query overrides.
112
191
 
113
- **Global/Primitive tokens** (direct values, use with `dark:` variant):
114
- ```javascript
115
- // Primitive palettes (all with 50-950 shades)
116
- colors.orange[500]; // #fe601f
117
- colors.violet[500]; // #8a84ec
118
- colors.neutral[900]; // #171717
192
+ ---
119
193
 
120
- // Brand colors
121
- colors.brand.black; // #0a0a0a
122
- colors.brand.white; // #fafafa
123
- colors.brand.orange; // #fe601f
194
+ ## 🔧 Building & consuming
124
195
 
125
- // Brand primitives (aliases)
126
- colors.primary[500]; // orange palette
127
- colors.accent[500]; // violet palette
196
+ ### Building the package
128
197
 
129
- // Surface primitives (neutral-based)
130
- colors.surface[950]; // #0a0a0a
131
- ```
198
+ ```bash
199
+ # emit both v3 and v4 bundles
200
+ pnpm --filter @aziontech/theme build:tokens
132
201
 
133
- **Semantic tokens** (theme-aware, no `dark:` variant needed):
134
- ```javascript
135
- // Text colors - automatically switches between light/dark
136
- colors.text.base; // neutral-900 (light) / neutral-50 (dark)
137
- colors.text.muted; // neutral-600 (light) / neutral-400 (dark)
138
- colors.text.accent; // accent-500 (both modes)
139
-
140
- // Background colors - theme-aware layers
141
- colors.background.layer1; // surface-0 (light) / surface-800 (dark)
142
- colors.background.layer2; // surface-50 (light) / surface-700 (dark)
143
- colors.background.canvas; // surface-100 (light) / surface-950 (dark)
144
-
145
- // Border colors - theme-aware borders
146
- colors.border.base; // surface-200 (light) / surface-700 (dark)
147
- colors.border.primary; // primary-500 (both modes)
148
- colors.border.accent; // accent-500 (both modes)
202
+ # only one target
203
+ pnpm --filter @aziontech/theme build:tokens:v3
204
+ pnpm --filter @aziontech/theme build:tokens:v4
205
+
206
+ # v3 + compile final CSS with tailwindcss
207
+ pnpm --filter @aziontech/theme build:css:v3
149
208
  ```
150
209
 
151
- #### Usage in HTML/Tailwind Classes
152
-
153
- **Using semantic tokens** (theme-aware, no `dark:` variant needed):
154
- ```html
155
- <!-- Semantic background - automatically switches theme -->
156
- <div class="bg-layer1">
157
- Layer 1 background (white in light, dark in dark mode)
158
- </div>
159
-
160
- <!-- Semantic text colors -->
161
- <p class="text-base">
162
- Base text color (auto-adapts to theme)
163
- </p>
164
-
165
- <!-- Semantic borders -->
166
- <div class="border border-base">
167
- Border adapts to current theme
168
- </div>
169
-
170
- <!-- Semantic interactive states -->
171
- <button class="bg-layer1 hover:bg-layer1-hover border border-primary text-primary">
172
- Themed button
173
- </button>
210
+ Outputs land in `packages/theme/dist/v3/` and `packages/theme/dist/v4/`.
211
+
212
+ ### Consuming in a Tailwind v3 project
213
+
214
+ ```js
215
+ // tailwind.config.js
216
+ import themePreset from '@aziontech/theme/tailwind-preset/v3'
217
+
218
+ export default {
219
+ presets: [themePreset],
220
+ content: ['./src/**/*.{vue,js,ts,jsx,tsx}'],
221
+ darkMode: ['class'],
222
+ }
174
223
  ```
175
224
 
176
- **Using global tokens** (can use `dark:` in this cases):
177
- ```html
178
- <!-- Background with dark variant -->
179
- <div class="bg-neutral-50 dark:bg-neutral-950">
180
- Adaptive background
181
- </div>
182
-
183
- <!-- Text colors with dark variant -->
184
- <p class="text-neutral-900 dark:text-neutral-100">
185
- Primary text color
186
- </p>
187
-
188
- <!-- Border colors with dark variant -->
189
- <div class="border border-neutral-200 dark:border-neutral-800">
190
- Card with adaptive border
191
- </div>
192
-
193
- <!-- Using brand colors (no dark variant needed) -->
194
- <button class="bg-orange-500 text-white hover:bg-orange-600">
195
- Action Button
196
- </button>
225
+ ```css
226
+ /* main.css */
227
+ @import '@aziontech/theme/v3/globals.css';
197
228
  ```
198
229
 
199
- **Available token classes:**
230
+ Utilities like `text-default`, `bg-surface`, `border-default`, `text-primary`, `gap-md`, `p-md`, `.text-heading-lg`, etc. are then available everywhere.
200
231
 
201
- *Global tokens* (use with `dark:` variant):
202
- - **Neutrals:** `neutral-50` → `neutral-950` (surface backgrounds, text, borders)
203
- - **Brand:** `orange-50` → `orange-950` (primary actions)
204
- - **Accent:** `violet-50` → `violet-950` (secondary highlights)
205
- - **Status:** `red-*`, `green-*`, `yellow-*`, `blue-*` (semantic status colors)
232
+ ### Consuming in a Tailwind v4 project
206
233
 
207
- *Semantic tokens* (theme-aware, no `dark:` needed):
208
- - **Text:** `text-base`, `text-muted`, `text-accent`, `text-primary`, `text-link`
209
- - **Background:** `bg-layer1`, `bg-layer2`, `bg-canvas`, `bg-base`
210
- - **Border:** `border-base`, `border-primary`, `border-accent`, `border-warning`, `border-success`, `border-danger`
234
+ ```css
235
+ /* main.css */
236
+ @import '@aziontech/theme/v4/globals.css';
237
+ ```
211
238
 
212
- ### Theme Switch Compatibility
239
+ No `tailwind.config.js` needed — v4 reads `@theme { … }` directly from the imported CSS.
213
240
 
214
- The CSS variable initializer targets both the Tailwind `.dark` class and the existing theme classes used by the SCSS theme:
241
+ ### As JS objects (Node / build steps)
215
242
 
216
- ```css
217
- :root, [data-theme=light], .azion.azion-light { /* light vars */ }
218
- [data-theme=dark], .dark, .azion.azion-dark { /* dark vars */ }
243
+ ```js
244
+ import { createCssVars, cssVarsString } from '@aziontech/theme';
245
+
246
+ createCssVars(); // → { light: { '--text-default': '#1A1A1A', … }, dark: { … } }
247
+ cssVarsString(); // → ':root, [data-theme=light], .azion.azion-light { … } [data-theme=dark], … { … }'
219
248
  ```
220
249
 
221
- ### Granular Imports (Advanced)
222
-
223
- ```javascript
224
- // Named exports for specific token types
225
- import {
226
- primitives,
227
- brandColors,
228
- brandPrimitives,
229
- surfacePrimitives,
230
- preset,
231
- createTailwindConfig,
232
- tokenUtilities
233
- } from 'azion-theme/tokens';
250
+ ### Injecting at runtime (browser)
251
+
252
+ ```js
253
+ import { injectCssVars } from '@aziontech/theme';
254
+
255
+ injectCssVars(); // appends a <style data-azion-tokens> element to <head>
234
256
  ```
235
257
 
236
- ### 🛠️ Sync & Maintenance (With Script)
258
+ Only useful if you can't precompile and import `globals.css` — production usage should prefer the static stylesheet.
259
+
260
+ ---
261
+
262
+ ## ➕ How to add a new token
263
+
264
+ ### Add a new primitive
265
+
266
+ 1. Open the relevant file (e.g., `tokens/primitives/shape/spacing.js`).
267
+ 2. Add the key/value:
268
+
269
+ ```js
270
+ export const spacing = {
271
+ /* … */
272
+ 128: '512px', // new
273
+ };
274
+ ```
275
+
276
+ 3. Rebuild (`pnpm --filter @aziontech/theme build:tokens`). The compiler picks it up and emits `--spacing-128: 512px`.
277
+
278
+ ### Add a new semantic (theme) token
279
+
280
+ 1. Pick the right file (`tokens/theme/*.js` or `tokens/theme/feedback/*.js`).
281
+ 2. Add the key with `tokenRef(...)` for both `light` and `dark`:
282
+
283
+ ```js
284
+ // tokens/theme/border.js
285
+ export const border = {
286
+ light: {
287
+ /* … */
288
+ 'border-emphasis': tokenRef('primitives.gray.400'),
289
+ },
290
+ dark: {
291
+ /* … */
292
+ 'border-emphasis': tokenRef('primitives.gray.500'),
293
+ },
294
+ };
295
+ ```
296
+
297
+ 3. Rebuild. The new variable lands in both `:root` and `[data-theme=dark]` blocks.
298
+
299
+ ### Add a new responsive semantic token
300
+
301
+ 1. Add an entry to the relevant `*.data.js` file in `tokens/semantic/`:
302
+
303
+ ```js
304
+ // tokens/semantic/spacings.data.js
305
+ export const spacingsData = {
306
+ /* … */
307
+ 'gap-2xl': { _: '32px', md: '40px', xl: '56px' },
308
+ };
309
+ ```
310
+
311
+ 2. Rebuild. `build-tokens.mjs` emits the base var in `:root`, per-breakpoint `@media` overrides, **and** a matching `.gap-2xl { gap: var(--gap-2xl) }` utility.
312
+
313
+ ---
237
314
 
238
- #### How to feed new and changed tokens from Figma
315
+ ## 🔗 Token references (`tokenRef`)
239
316
 
240
- 1) **Update Figma Variables**
241
- - Ensure **Global** and **Semantic** variables are updated and organized correctly (naming, groups, modes, and values).
317
+ `tokenRef(path)` returns a marker object `{ __ref: path }` that the compiler resolves at build time. Supported path prefixes (see `scripts/resolve.js`):
242
318
 
243
- 2) **Open the Tokens Studio for Figma plugin**
319
+ | Prefix | Looks up |
320
+ |---|---|
321
+ | `primitives.X.Y.Z` | `tokens/primitives/colors/colors.js` tree (e.g., `primitives.gray.900`, `primitives.alpha.orange.100`) |
322
+ | `surfacePrimitives.surface.N` | the surface palette (used internally; usually referenced via `brand.surfaces.…`) |
323
+ | `brand.surfaces.surface-N` | `surfacePrimitives.surface[N]` (e.g., `brand.surfaces.surface-100` → `#F5F5F5`) |
324
+ | `brand.primary.primary-N` | `brandPrimitives.primary[N]` (e.g., `brand.primary.primary-500` → `#FE601F`) |
325
+ | `brand.accent.accent-N` | `brandPrimitives.accent[N]` |
326
+ | `brand.absolute.X` | `brandPrimitives.absolute.X` (`black` / `white`) |
244
327
 
245
- 3) **Import Figma Variables into Tokens Studio**
246
- - Use Tokens Studio’s import-from-variables flow to bring the current Variables state into the token sets.
328
+ Refs of unknown prefixes are left as the raw path string in the output — flag for "this needs resolver support".
247
329
 
248
- 4) **Export to file/folder**
249
- - Export using **Multiple files**.
330
+ ---
250
331
 
251
- 5) **Copy the exported files into this repo**
252
- - Place them under [`src/tokens/figma-reference-tokens-studio/`](src/tokens/figma-reference-tokens-studio:1) (replace existing contents).
332
+ ## 🧪 Test pages
253
333
 
254
- 6) **Regenerate the code tokens**
255
- - Run:
334
+ Local visual harnesses (require a static server because of ESM imports):
256
335
 
257
336
  ```bash
258
- node ./scripts/figma-sync.js
337
+ npx http-server packages/theme/src -p 8080
259
338
  ```
260
339
 
261
- 7) **Review and commit**
262
- - Inspect the diff in the generated files and validate light/dark semantics before committing.
263
-
264
- Files affected by the script:
265
- - [`src/tokens/primitives/colors.js`](src/tokens/primitives/colors.js)
266
- - [`src/tokens/primitives/brand.js`](src/tokens/primitives/brand.js)
267
- - [`src/tokens/semantic/text.js`](src/tokens/semantic/text.js)
268
- - [`src/tokens/semantic/backgrounds.js`](src/tokens/semantic/backgrounds.js)
269
- - [`src/tokens/semantic/borders.js`](src/tokens/semantic/borders.js)
270
-
271
- ### 🧰 Manual Maintenance (Without Script)
272
-
273
- When updating or adding tokens manually, edit the files below depending on the token type:
274
-
275
- - **Primitive palettes:** [`src/tokens/primitives/colors.js`](src/tokens/primitives/colors.js)
276
- - **Brand + surface primitives:** [`src/tokens/primitives/brand.js`](src/tokens/primitives/brand.js)
277
- - **Semantic text (light/dark):** [`src/tokens/semantic/text.js`](src/tokens/semantic/text.js)
278
- - **Semantic backgrounds (light/dark):** [`src/tokens/semantic/backgrounds.js`](src/tokens/semantic/backgrounds.js)
279
- - **Semantic borders (light/dark):** [`src/tokens/semantic/borders.js`](src/tokens/semantic/borders.js)
280
- - **Brand aliases:** [`src/tokens/colors-brand.js`](src/tokens/colors-brand.js)
281
- - **Tailwind mappings (class names):** [`src/tokens/build/preset.js`](src/tokens/build/preset.js)
282
- - **CSS vars output/selectors:** [`src/tokens/build/css-vars.js`](src/tokens/build/css-vars.js)
283
-
284
- Checklist when adding a new token manually:
285
- 1) Add/update the primitive or surface scale value (if needed).
286
- 2) Add matching semantic entries for both `light` and `dark`.
287
- 3) Update Tailwind mappings if you want a class for the token.
288
- 4) Regenerate or verify CSS vars output for both themes.
289
-
290
- ### 🎨 Available Colors
291
-
292
- #### Main Palette (Orange)
293
- - `orange-50` → `orange-950`
294
- - **Primary**: `orange-500` (#fe601f)
295
-
296
- #### Brand Palette
297
- - `brand-black` (#0a0a0a)
298
- - `brand-white` (#fafafa)
299
- - `brand-dark-gray` (#171717)
300
- - `brand-medium-gray` (#737373)
301
-
302
- #### Other Complete Palettes
303
- - **Violet, Slate, Gray, Neutral, Blue, Red, Yellow, Green**
304
- - All with 11 shades (50 → 950)
305
-
306
- #### Semantic Colors
307
- - `primary` (orange-500)
308
- - `success` (green-500)
309
- - `warning` (yellow-500)
310
- - `error` (red-500)
311
- - `info` (blue-500)
312
-
313
- ### ⚠️ Troubleshooting
314
-
315
- #### If you get import errors:
316
-
317
- **ES Modules (recommended)**
318
- ```javascript
319
- import colors from 'azion-theme/tokens';
320
- ```
340
+ - `http://localhost:8080/tests/primitives.html` — every primitive rendered as a swatch / scale.
341
+ - `http://localhost:8080/tests/theme.html` — semantic tokens with a **light/dark toggle**.
342
+ - `http://localhost:8080/tests/tokens.html` — combined view.
321
343
 
322
- **Named exports**
323
- ```javascript
324
- import { primitives, brandColors, brandPrimitives, surfacePrimitives } from 'azion-theme/tokens';
325
- ```
344
+ ---
326
345
 
327
- **Direct file imports**
328
- ```javascript
329
- import { primitives } from 'azion-theme/tokens/primitives/colors.js';
330
- import { brandColors } from 'azion-theme/tokens/colors-brand.js';
331
- ```
346
+ ## 🌗 Theme switching
332
347
 
333
- **Configure Vite (if using Vite)**
334
- Add to your `vite.config.js`:
335
- ```javascript
336
- export default {
337
- resolve: {
338
- conditions: ['import', 'module', 'browser', 'default']
339
- }
348
+ The compiled CSS targets multiple hooks so the runtime can pick whichever convention the consumer uses:
349
+
350
+ ```css
351
+ :root, [data-theme=light], .azion.azion-light {
352
+ /* light theme vars */
353
+ }
354
+
355
+ [data-theme=dark], .dark, .azion.azion-dark {
356
+ /* dark theme vars */
340
357
  }
341
358
  ```
342
359
 
360
+ Switching is a one-liner:
361
+
362
+ ```js
363
+ // data-attribute strategy
364
+ document.documentElement.setAttribute('data-theme', 'dark'); // or 'light'
365
+
366
+ // Tailwind class strategy
367
+ document.documentElement.classList.toggle('dark');
368
+
369
+ // Azion namespaced classes (use one or the other)
370
+ document.documentElement.classList.add('azion', 'azion-dark');
371
+ ```
372
+
373
+ All three strategies hit the same set of CSS variables.
374
+
375
+ ---
376
+
343
377
  ## 🔗 Links
344
378
 
345
379
  - [Figma Global Tokens](https://www.figma.com/design/t97pXRs7xME3SJDs5iZ5RF/Global-Tokens?node-id=0-1)