@seyuna/postcss 1.0.0-canary.37 → 1.0.0-canary.39
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/CHANGELOG.md +26 -0
- package/README.md +444 -156
- package/dist/at-rules/color-scheme.d.ts +3 -2
- package/dist/at-rules/color-scheme.js +6 -7
- package/dist/at-rules/color.d.ts +5 -4
- package/dist/at-rules/color.js +5 -4
- package/dist/at-rules/config.d.ts +2 -1
- package/dist/at-rules/config.js +44 -13
- package/dist/at-rules/container.d.ts +2 -1
- package/dist/at-rules/container.js +4 -6
- package/dist/at-rules/import.d.ts +3 -2
- package/dist/at-rules/import.js +107 -139
- package/dist/at-rules/index.d.ts +2 -1
- package/dist/at-rules/index.js +3 -4
- package/dist/config.js +70 -28
- package/dist/errors.d.ts +3 -5
- package/dist/errors.js +2 -4
- package/dist/functions/color.d.ts +4 -4
- package/dist/functions/color.js +4 -4
- package/dist/functions/index.js +5 -7
- package/dist/helpers.d.ts +4 -6
- package/dist/helpers.js +26 -22
- package/dist/index.d.ts +8 -1
- package/dist/index.js +1 -0
- package/dist/parser.js +36 -49
- package/dist/plugin.d.ts +3 -1
- package/dist/plugin.js +15 -19
- package/dist/types.d.ts +6 -1
- package/dist/types.js +0 -2
- package/package.json +20 -3
- package/.github/workflows/release.yml +0 -41
- package/.vscode/settings.json +0 -4
- package/dist/functions/theme.d.ts +0 -6
- package/dist/functions/theme.js +0 -17
- package/release.config.mjs +0 -37
- package/src/at-rules/color-scheme.ts +0 -54
- package/src/at-rules/color.ts +0 -33
- package/src/at-rules/config.ts +0 -78
- package/src/at-rules/container.ts +0 -58
- package/src/at-rules/import.ts +0 -196
- package/src/at-rules/index.ts +0 -29
- package/src/config.ts +0 -98
- package/src/errors.ts +0 -27
- package/src/functions/color.ts +0 -123
- package/src/functions/index.ts +0 -22
- package/src/functions/theme.ts +0 -20
- package/src/helpers.ts +0 -75
- package/src/index.ts +0 -10
- package/src/parser.ts +0 -81
- package/src/plugin.ts +0 -58
- package/src/styles/seyuna-global.css +0 -94
- package/src/types.ts +0 -71
- package/tests/plugin.test.ts +0 -244
- package/tsconfig.json +0 -14
package/README.md
CHANGED
|
@@ -3,91 +3,65 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@seyuna/postcss)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
>
|
|
6
|
+
> A CSS compiler for theme-aware design tokens.
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Overview
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
`@seyuna/postcss` is a PostCSS plugin that turns Seyuna-specific CSS syntax into plain CSS.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
It is designed for projects that want:
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
- design tokens declared directly in CSS
|
|
17
|
+
- theme-aware colors without runtime JavaScript
|
|
18
|
+
- reusable light/dark/system mode styling
|
|
19
|
+
- container query shortcuts
|
|
20
|
+
- generated utility-like selectors from token lists
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
html {
|
|
20
|
-
font-size: max(1rem, 0.833vw);
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
At 1920px viewport width, `0.833vw` equals exactly `16px`. On a 4K display, everything scales proportionally. Your 1080p design becomes a 4K design automatically. No breakpoints. No media queries. No redesigning.
|
|
25
|
-
|
|
26
|
-
### 2. Seamless Dark / Light Mode
|
|
27
|
-
|
|
28
|
-
Theme switching shouldn't require duplicating your entire stylesheet. With Seyuna, colors are defined once and adapt automatically:
|
|
29
|
-
|
|
30
|
-
```css
|
|
31
|
-
.button {
|
|
32
|
-
background: SeyunaStandardColor(primary);
|
|
33
|
-
}
|
|
34
|
-
```
|
|
22
|
+
In practice, you write Seyuna syntax such as:
|
|
35
23
|
|
|
36
|
-
|
|
24
|
+
- `@config "seyuna"` for tokens and theme settings
|
|
25
|
+
- `@seyuna;` to inject the generated design system
|
|
26
|
+
- helper functions like `SeyunaTone(primary)` and `SeyunaSwatch(brand)`
|
|
27
|
+
- at-rules like `@dark`, `@light`, `@xs`, `@each-tone`, and `@each-swatch`
|
|
37
28
|
|
|
38
|
-
|
|
29
|
+
Seyuna compiles that into regular CSS:
|
|
39
30
|
|
|
40
|
-
|
|
31
|
+
- custom properties
|
|
32
|
+
- light and dark mode selectors
|
|
33
|
+
- system preference media queries
|
|
34
|
+
- container queries
|
|
35
|
+
- repeated selectors for palette iteration
|
|
36
|
+
- a global reset and layer setup
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
/* Instead of this */
|
|
44
|
-
.card {
|
|
45
|
-
background: rgba(66, 133, 244, 0.5);
|
|
46
|
-
border: 1px solid rgba(66, 133, 244, 0.8);
|
|
47
|
-
}
|
|
38
|
+
The important idea is that the source stays token-driven, but the browser receives standard CSS with no JavaScript color runtime.
|
|
48
39
|
|
|
49
|
-
|
|
50
|
-
.card {
|
|
51
|
-
background: SeyunaAlpha(primary, 0.5);
|
|
52
|
-
border: 1px solid SeyunaAlpha(primary, 0.8);
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Your color palette is defined directly in your CSS. Your stylesheets reference colors by name. Change a value once in `@config`, and it updates everywhere.
|
|
40
|
+
---
|
|
57
41
|
|
|
58
|
-
|
|
42
|
+
## Core Idea
|
|
59
43
|
|
|
60
|
-
|
|
44
|
+
Seyuna works in three steps:
|
|
61
45
|
|
|
62
|
-
|
|
63
|
-
.
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.button:hover {
|
|
68
|
-
background: SeyunaLighten(primary, 0.1);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.button:disabled {
|
|
72
|
-
background: SeyunaAlpha(primary, 0.3);
|
|
73
|
-
}
|
|
74
|
-
```
|
|
46
|
+
1. Define tokens in CSS with `@config "seyuna"`.
|
|
47
|
+
2. Generate the runtime variables and theme rules with `@seyuna;`.
|
|
48
|
+
3. Reference those generated variables through helper functions like `SeyunaTone()` and `SeyunaAlpha()`.
|
|
75
49
|
|
|
76
|
-
|
|
50
|
+
That means your source CSS stays token-based, while the browser receives plain CSS variables and selectors.
|
|
77
51
|
|
|
78
52
|
---
|
|
79
53
|
|
|
80
54
|
## Quick Start
|
|
81
55
|
|
|
82
|
-
###
|
|
56
|
+
### Install
|
|
83
57
|
|
|
84
58
|
```bash
|
|
85
59
|
npm install @seyuna/postcss postcss-import postcss-advanced-variables postcss-preset-env --save-dev
|
|
86
60
|
```
|
|
87
61
|
|
|
88
|
-
### PostCSS
|
|
62
|
+
### Configure PostCSS
|
|
89
63
|
|
|
90
|
-
```
|
|
64
|
+
```js
|
|
91
65
|
// postcss.config.js
|
|
92
66
|
import seyunaPostcss from "@seyuna/postcss";
|
|
93
67
|
import postcssImport from "postcss-import";
|
|
@@ -96,9 +70,9 @@ import postcssPresetEnv from "postcss-preset-env";
|
|
|
96
70
|
|
|
97
71
|
export default {
|
|
98
72
|
plugins: [
|
|
73
|
+
postcssImport(),
|
|
99
74
|
seyunaPostcss(),
|
|
100
|
-
|
|
101
|
-
postcssAdvancedVariables,
|
|
75
|
+
postcssAdvancedVariables(),
|
|
102
76
|
postcssPresetEnv({
|
|
103
77
|
stage: 3,
|
|
104
78
|
features: {
|
|
@@ -109,138 +83,442 @@ export default {
|
|
|
109
83
|
};
|
|
110
84
|
```
|
|
111
85
|
|
|
112
|
-
###
|
|
86
|
+
### Recommended Plugin Order
|
|
87
|
+
|
|
88
|
+
Seyuna should run early in the pipeline.
|
|
113
89
|
|
|
114
|
-
|
|
90
|
+
- `postcss-import()` first if your CSS is split across files
|
|
91
|
+
- `seyunaPostcss()` next so it can see `@config`, `@seyuna`, and Seyuna helper functions before another plugin rewrites them
|
|
92
|
+
- nesting and other syntax transforms after that
|
|
93
|
+
|
|
94
|
+
If Seyuna runs too late, another plugin may already have removed or changed the syntax it needs to process.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Smallest Working Example
|
|
115
99
|
|
|
116
100
|
```css
|
|
117
101
|
@config "seyuna" {
|
|
118
|
-
/* Define hues (0-360) */
|
|
119
102
|
--hue-primary: 240;
|
|
120
|
-
--hue-secondary: 30;
|
|
121
|
-
|
|
122
|
-
/* Define fixed colors (lightness chroma hue) */
|
|
123
|
-
--color-white: 1 0 0;
|
|
124
|
-
--color-black: 0 0 0;
|
|
125
|
-
|
|
126
|
-
/* Configure theme modes */
|
|
127
103
|
--light-lightness: 0.66;
|
|
128
104
|
--light-chroma: 0.26;
|
|
105
|
+
--dark-lightness: 0.78;
|
|
106
|
+
--dark-chroma: 0.18;
|
|
129
107
|
--light-background: 1 0 0;
|
|
130
108
|
--light-text: 0 0 0;
|
|
131
|
-
|
|
132
|
-
--dark-lightness: 0.66;
|
|
133
|
-
--dark-chroma: 0.26;
|
|
134
109
|
--dark-background: 0 0 0;
|
|
135
110
|
--dark-text: 1 0 0;
|
|
136
111
|
}
|
|
137
112
|
|
|
138
113
|
@seyuna;
|
|
139
114
|
|
|
140
|
-
|
|
115
|
+
.button {
|
|
116
|
+
background: SeyunaTone(primary);
|
|
117
|
+
color: SeyunaContrast(primary);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.button:hover {
|
|
121
|
+
background: SeyunaTint(primary, 0.06);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
What this does:
|
|
126
|
+
|
|
127
|
+
1. `--hue-primary` defines the hue token named `primary`.
|
|
128
|
+
2. `--light-lightness` and `--dark-lightness` define the base lightness used by theme-aware standard colors.
|
|
129
|
+
3. `--light-chroma` and `--dark-chroma` define the base chroma used by theme-aware standard colors.
|
|
130
|
+
4. `@seyuna;` injects the variables, theme selectors, and reset.
|
|
131
|
+
5. `SeyunaTone(primary)` resolves to an `oklch(...)` color using the current theme's `--lightness`, `--chroma`, and the `--primary-hue`.
|
|
132
|
+
6. `SeyunaTint(primary, 0.06)` creates a lighter version of the same standard color.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## How `@config "seyuna"` Works
|
|
137
|
+
|
|
138
|
+
`@config "seyuna"` is a build-time configuration block written directly in CSS.
|
|
139
|
+
|
|
140
|
+
The plugin reads its custom properties, merges them into the Seyuna theme config, and removes the block from the final output.
|
|
141
|
+
|
|
142
|
+
You can have one `@config "seyuna"` block or several. If there are several, they are merged in source order.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
|
|
146
|
+
```css
|
|
147
|
+
@config "seyuna" {
|
|
148
|
+
--hue-primary: 240;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@config "seyuna" {
|
|
152
|
+
--dark-lightness: 0.8;
|
|
153
|
+
}
|
|
141
154
|
```
|
|
142
155
|
|
|
143
|
-
|
|
156
|
+
That behaves as one combined configuration.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## What `@seyuna;` Injects
|
|
161
|
+
|
|
162
|
+
`@seyuna;` expands the config into runtime CSS.
|
|
163
|
+
|
|
164
|
+
It injects:
|
|
165
|
+
|
|
166
|
+
- the global Seyuna reset and cascade layers
|
|
167
|
+
- `:root` hue variables such as `--primary-hue`
|
|
168
|
+
- `:root` fixed color variables such as `--brand-lightness`, `--brand-chroma`, and `--brand-hue`
|
|
169
|
+
- `[data-mode="light"]` and `[data-mode="dark"]` blocks
|
|
170
|
+
- system preference media queries for `[data-mode="system"]`
|
|
144
171
|
|
|
145
|
-
|
|
146
|
-
- Theme mode selectors (`[data-mode="light"]`, `[data-mode="dark"]`)
|
|
147
|
-
- System preference media queries
|
|
148
|
-
- A modern CSS reset with cascade layers
|
|
172
|
+
Use `@seyuna;` once in the compiled stylesheet output. If it appears multiple times, Seyuna keeps the first one and warns about the duplicates.
|
|
149
173
|
|
|
150
174
|
---
|
|
151
175
|
|
|
152
|
-
## Color
|
|
176
|
+
## Understanding the Color Model
|
|
153
177
|
|
|
154
|
-
Seyuna
|
|
178
|
+
Seyuna uses **OKLCH**.
|
|
179
|
+
|
|
180
|
+
You do not usually write full `oklch(...)` values in your component styles. Instead, you define tokens and let the helpers produce the final colors.
|
|
181
|
+
|
|
182
|
+
There are two kinds of color tokens:
|
|
155
183
|
|
|
156
184
|
### Standard Colors
|
|
157
185
|
|
|
158
|
-
Standard colors
|
|
186
|
+
Standard colors are hue-driven.
|
|
159
187
|
|
|
160
|
-
|
|
188
|
+
They use:
|
|
161
189
|
|
|
162
|
-
|
|
190
|
+
- a hue from `--hue-*`
|
|
191
|
+
- a theme lightness from `--light-lightness` or `--dark-lightness`
|
|
192
|
+
- a theme chroma from `--light-chroma` or `--dark-chroma`
|
|
163
193
|
|
|
164
|
-
|
|
194
|
+
That means standard colors automatically adapt between light and dark modes.
|
|
165
195
|
|
|
166
|
-
|
|
196
|
+
Example:
|
|
167
197
|
|
|
168
198
|
```css
|
|
169
199
|
@config "seyuna" {
|
|
170
|
-
--hue-
|
|
200
|
+
--hue-primary: 240;
|
|
201
|
+
--light-lightness: 0.66;
|
|
202
|
+
--light-chroma: 0.26;
|
|
203
|
+
--dark-lightness: 0.78;
|
|
204
|
+
--dark-chroma: 0.18;
|
|
171
205
|
}
|
|
172
206
|
|
|
173
|
-
.
|
|
174
|
-
background:
|
|
207
|
+
.button {
|
|
208
|
+
background: SeyunaTone(primary);
|
|
175
209
|
}
|
|
176
210
|
```
|
|
177
211
|
|
|
212
|
+
In light mode, `SeyunaTone(primary)` uses:
|
|
213
|
+
|
|
214
|
+
- `var(--lightness)` from the light palette
|
|
215
|
+
- `var(--chroma)` from the light palette
|
|
216
|
+
- `var(--primary-hue)`
|
|
217
|
+
|
|
218
|
+
In dark mode, the same function call uses the dark palette values instead.
|
|
219
|
+
|
|
178
220
|
### Fixed Colors
|
|
179
221
|
|
|
180
|
-
Fixed colors
|
|
222
|
+
Fixed colors are fully specified tokens.
|
|
223
|
+
|
|
224
|
+
They use:
|
|
225
|
+
|
|
226
|
+
- `--color-name: lightness chroma hue`
|
|
227
|
+
|
|
228
|
+
and become three runtime variables:
|
|
229
|
+
|
|
230
|
+
- `--name-lightness`
|
|
231
|
+
- `--name-chroma`
|
|
232
|
+
- `--name-hue`
|
|
233
|
+
|
|
234
|
+
Example:
|
|
181
235
|
|
|
182
236
|
```css
|
|
183
237
|
@config "seyuna" {
|
|
184
|
-
--color-
|
|
185
|
-
--color-brand: 0.5 0.2 100; /* Global value */
|
|
186
|
-
--light-color-brand: 1 0 100; /* Light mode override */
|
|
238
|
+
--color-brand: 0.5 0.2 100;
|
|
187
239
|
}
|
|
188
240
|
|
|
189
241
|
.logo {
|
|
190
|
-
color:
|
|
242
|
+
color: SeyunaSwatch(brand);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Unlike standard colors, fixed colors do not depend on the theme-wide `--lightness` and `--chroma` values unless you override them per mode.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## What `--light-lightness` and `--dark-lightness` Actually Do
|
|
251
|
+
|
|
252
|
+
This is the most important config concept to understand.
|
|
253
|
+
|
|
254
|
+
`--light-lightness` and `--dark-lightness` do **not** define one specific named color.
|
|
255
|
+
|
|
256
|
+
Instead, they define the base `--lightness` variable for the active theme mode:
|
|
257
|
+
|
|
258
|
+
- `--light-lightness` becomes `--lightness` inside `[data-mode="light"]`
|
|
259
|
+
- `--dark-lightness` becomes `--lightness` inside `[data-mode="dark"]`
|
|
260
|
+
- both are also emitted inside the matching `prefers-color-scheme` media queries for `[data-mode="system"]`
|
|
261
|
+
|
|
262
|
+
That `--lightness` value is then used by standard-color helpers such as:
|
|
263
|
+
|
|
264
|
+
- `SeyunaTone()`
|
|
265
|
+
- `SeyunaAlpha()` when the referenced token is a standard color
|
|
266
|
+
- `SeyunaTint()` when the referenced token is a standard color
|
|
267
|
+
- `SeyunaShade()` when the referenced token is a standard color
|
|
268
|
+
- `SeyunaContrast()` when the referenced token is a standard color
|
|
269
|
+
|
|
270
|
+
So this:
|
|
271
|
+
|
|
272
|
+
```css
|
|
273
|
+
@config "seyuna" {
|
|
274
|
+
--hue-primary: 240;
|
|
275
|
+
--light-lightness: 0.66;
|
|
276
|
+
--dark-lightness: 0.8;
|
|
191
277
|
}
|
|
192
278
|
|
|
193
|
-
.
|
|
194
|
-
background:
|
|
279
|
+
.button {
|
|
280
|
+
background: SeyunaTone(primary);
|
|
195
281
|
}
|
|
196
282
|
```
|
|
197
283
|
|
|
284
|
+
means:
|
|
285
|
+
|
|
286
|
+
- in light mode, `primary` uses lightness `0.66`
|
|
287
|
+
- in dark mode, `primary` uses lightness `0.8`
|
|
288
|
+
|
|
289
|
+
The same idea applies to `--light-chroma` and `--dark-chroma`. They define the shared `--chroma` variable for standard colors in each mode.
|
|
290
|
+
|
|
198
291
|
---
|
|
199
292
|
|
|
200
|
-
##
|
|
293
|
+
## Theme Palette Properties
|
|
294
|
+
|
|
295
|
+
Inside `@config "seyuna"`, theme-level properties control the generated palette for light and dark modes.
|
|
296
|
+
|
|
297
|
+
### Shared Theme Controls
|
|
298
|
+
|
|
299
|
+
These values shape standard colors in each mode:
|
|
300
|
+
|
|
301
|
+
- `--light-lightness`
|
|
302
|
+
- `--light-chroma`
|
|
303
|
+
- `--dark-lightness`
|
|
304
|
+
- `--dark-chroma`
|
|
305
|
+
|
|
306
|
+
They are used to populate:
|
|
307
|
+
|
|
308
|
+
- `--lightness`
|
|
309
|
+
- `--chroma`
|
|
201
310
|
|
|
202
|
-
|
|
203
|
-
| :----------------------------- | :---------------------------------------- | :----------------------------- |
|
|
204
|
-
| `SeyunaStandardColor(name)` | Standard color with theme-aware lightness | `SeyunaStandardColor(primary)` |
|
|
205
|
-
| `SeyunaFixedColor(name)` | Fixed color with explicit values | `SeyunaFixedColor(white)` |
|
|
206
|
-
| `SeyunaAlpha(color, value)` | Adjusts opacity | `SeyunaAlpha(primary, 0.5)` |
|
|
207
|
-
| `SeyunaLighten(color, amount)` | Increases lightness | `SeyunaLighten(primary, 0.1)` |
|
|
208
|
-
| `SeyunaDarken(color, amount)` | Decreases lightness | `SeyunaDarken(primary, 0.1)` |
|
|
209
|
-
| `SeyunaContrast(color)` | Returns black or white for readability | `SeyunaContrast(surface)` |
|
|
311
|
+
inside each generated mode selector.
|
|
210
312
|
|
|
211
|
-
|
|
313
|
+
### Theme Surface Colors
|
|
314
|
+
|
|
315
|
+
These values define the page-level background and text colors for each mode:
|
|
316
|
+
|
|
317
|
+
- `--light-background`
|
|
318
|
+
- `--light-text`
|
|
319
|
+
- `--dark-background`
|
|
320
|
+
- `--dark-text`
|
|
321
|
+
|
|
322
|
+
Each one must be written as:
|
|
323
|
+
|
|
324
|
+
```css
|
|
325
|
+
lightness chroma hue
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
For example:
|
|
329
|
+
|
|
330
|
+
```css
|
|
331
|
+
--dark-background: 0 0 0;
|
|
332
|
+
--dark-text: 1 0 0;
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
They become:
|
|
336
|
+
|
|
337
|
+
- `--background`
|
|
338
|
+
- `--text`
|
|
339
|
+
|
|
340
|
+
inside the generated mode blocks.
|
|
341
|
+
|
|
342
|
+
### Mode-Specific Fixed Color Overrides
|
|
343
|
+
|
|
344
|
+
You can override a fixed color inside a specific mode by using:
|
|
345
|
+
|
|
346
|
+
- `--light-color-*`
|
|
347
|
+
- `--dark-color-*`
|
|
348
|
+
|
|
349
|
+
Example:
|
|
350
|
+
|
|
351
|
+
```css
|
|
352
|
+
@config "seyuna" {
|
|
353
|
+
--color-brand: 0.5 0.2 100;
|
|
354
|
+
--light-color-brand: 0.92 0.05 100;
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
That keeps `brand` global by default but changes it when light mode is active.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Full Configuration Reference
|
|
363
|
+
|
|
364
|
+
Within `@config "seyuna"`, the following prefixes are supported:
|
|
365
|
+
|
|
366
|
+
| Prefix | What it means | Used by |
|
|
367
|
+
| :----- | :------------ | :------ |
|
|
368
|
+
| `--hue-*` | Defines a standard color hue token | `SeyunaTone`, standard-color `SeyunaAlpha`, `SeyunaTint`, `SeyunaShade`, `SeyunaContrast` |
|
|
369
|
+
| `--color-*` | Defines a global fixed color as `lightness chroma hue` | `SeyunaSwatch`, fixed-color `SeyunaAlpha`, `SeyunaTint`, `SeyunaShade`, `SeyunaContrast` |
|
|
370
|
+
| `--light-lightness` | Sets the base `--lightness` for light mode | Standard colors in light mode |
|
|
371
|
+
| `--light-chroma` | Sets the base `--chroma` for light mode | Standard colors in light mode |
|
|
372
|
+
| `--dark-lightness` | Sets the base `--lightness` for dark mode | Standard colors in dark mode |
|
|
373
|
+
| `--dark-chroma` | Sets the base `--chroma` for dark mode | Standard colors in dark mode |
|
|
374
|
+
| `--light-background` | Sets `--background` in light mode | Your global/page styling |
|
|
375
|
+
| `--light-text` | Sets `--text` in light mode | Your global/page styling |
|
|
376
|
+
| `--dark-background` | Sets `--background` in dark mode | Your global/page styling |
|
|
377
|
+
| `--dark-text` | Sets `--text` in dark mode | Your global/page styling |
|
|
378
|
+
| `--light-color-*` | Overrides a fixed color in light mode | Fixed colors in light mode |
|
|
379
|
+
| `--dark-color-*` | Overrides a fixed color in dark mode | Fixed colors in dark mode |
|
|
380
|
+
|
|
381
|
+
If a value is malformed, Seyuna warns and skips it rather than generating broken CSS.
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Color Helper Functions
|
|
386
|
+
|
|
387
|
+
The `Seyuna` prefix is intentionally kept on the helper names so they are obviously custom and do not collide with CSS or other tooling.
|
|
388
|
+
|
|
389
|
+
| Function | What it returns | Best use |
|
|
390
|
+
| :------- | :-------------- | :------- |
|
|
391
|
+
| `SeyunaTone(name)` | A theme-aware standard color | Buttons, accents, semantic hues |
|
|
392
|
+
| `SeyunaSwatch(name)` | A fixed named color | Brand colors, literal palette tokens |
|
|
393
|
+
| `SeyunaAlpha(color, value)` | The same color with a different alpha | Borders, overlays, subtle backgrounds |
|
|
394
|
+
| `SeyunaTint(color, amount)` | A lighter version of the color | Hover states, active states |
|
|
395
|
+
| `SeyunaShade(color, amount)` | A darker version of the color | Pressed states, stronger contrast |
|
|
396
|
+
| `SeyunaContrast(color)` | A readable contrast color | Foreground text over token-driven backgrounds |
|
|
397
|
+
|
|
398
|
+
### `SeyunaTone(name)`
|
|
399
|
+
|
|
400
|
+
Uses:
|
|
401
|
+
|
|
402
|
+
- `var(--lightness)`
|
|
403
|
+
- `var(--chroma)`
|
|
404
|
+
- `var(--name-hue)`
|
|
405
|
+
|
|
406
|
+
Example:
|
|
407
|
+
|
|
408
|
+
```css
|
|
409
|
+
.button {
|
|
410
|
+
background: SeyunaTone(primary);
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### `SeyunaSwatch(name)`
|
|
415
|
+
|
|
416
|
+
Uses:
|
|
417
|
+
|
|
418
|
+
- `var(--name-lightness)`
|
|
419
|
+
- `var(--name-chroma)`
|
|
420
|
+
- `var(--name-hue)`
|
|
421
|
+
|
|
422
|
+
Example:
|
|
423
|
+
|
|
424
|
+
```css
|
|
425
|
+
.logo {
|
|
426
|
+
color: SeyunaSwatch(brand);
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### `SeyunaAlpha(color, value)`
|
|
431
|
+
|
|
432
|
+
Keeps the same base color but changes the alpha channel.
|
|
433
|
+
|
|
434
|
+
Example:
|
|
435
|
+
|
|
436
|
+
```css
|
|
437
|
+
.overlay {
|
|
438
|
+
background: SeyunaAlpha(primary, 0.12);
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### `SeyunaTint(color, amount)`
|
|
443
|
+
|
|
444
|
+
Adds to the lightness value using `calc(...)`.
|
|
445
|
+
|
|
446
|
+
Example:
|
|
447
|
+
|
|
448
|
+
```css
|
|
449
|
+
.button:hover {
|
|
450
|
+
background: SeyunaTint(primary, 0.08);
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### `SeyunaShade(color, amount)`
|
|
455
|
+
|
|
456
|
+
Subtracts from the lightness value using `calc(...)`.
|
|
457
|
+
|
|
458
|
+
Example:
|
|
459
|
+
|
|
460
|
+
```css
|
|
461
|
+
.button:active {
|
|
462
|
+
background: SeyunaShade(primary, 0.08);
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### `SeyunaContrast(color)`
|
|
467
|
+
|
|
468
|
+
Returns a black-or-white-style readable contrast color based on the color's lightness.
|
|
469
|
+
|
|
470
|
+
Example:
|
|
471
|
+
|
|
472
|
+
```css
|
|
473
|
+
.badge {
|
|
474
|
+
background: SeyunaTone(primary);
|
|
475
|
+
color: SeyunaContrast(primary);
|
|
476
|
+
}
|
|
477
|
+
```
|
|
212
478
|
|
|
213
479
|
---
|
|
214
480
|
|
|
215
481
|
## Theme Switching
|
|
216
482
|
|
|
217
|
-
Seyuna supports three modes:
|
|
483
|
+
Seyuna supports three modes:
|
|
484
|
+
|
|
485
|
+
- `light`
|
|
486
|
+
- `dark`
|
|
487
|
+
- `system`
|
|
488
|
+
|
|
489
|
+
Use the `data-mode` attribute on a parent element, usually `<html>`:
|
|
218
490
|
|
|
219
491
|
```html
|
|
220
492
|
<html data-mode="system"></html>
|
|
221
493
|
```
|
|
222
494
|
|
|
223
|
-
|
|
495
|
+
Behavior:
|
|
496
|
+
|
|
497
|
+
- `[data-mode="light"]` forces the light palette
|
|
498
|
+
- `[data-mode="dark"]` forces the dark palette
|
|
499
|
+
- `[data-mode="system"]` follows `prefers-color-scheme`
|
|
224
500
|
|
|
225
|
-
|
|
501
|
+
### `@light` and `@dark`
|
|
502
|
+
|
|
503
|
+
You can write mode-specific overrides directly in CSS:
|
|
226
504
|
|
|
227
505
|
```css
|
|
228
506
|
.card {
|
|
229
|
-
background:
|
|
507
|
+
background: SeyunaSwatch(white);
|
|
230
508
|
|
|
231
509
|
@dark {
|
|
232
|
-
background:
|
|
510
|
+
background: SeyunaSwatch(black);
|
|
233
511
|
}
|
|
234
512
|
}
|
|
235
513
|
```
|
|
236
514
|
|
|
237
|
-
|
|
515
|
+
This compiles to selectors for explicit mode choice and system preference behavior.
|
|
238
516
|
|
|
239
517
|
---
|
|
240
518
|
|
|
241
|
-
## Container
|
|
519
|
+
## Container Query Shortcuts
|
|
242
520
|
|
|
243
|
-
Seyuna
|
|
521
|
+
Seyuna provides shorthand at-rules that compile to native `@container` rules:
|
|
244
522
|
|
|
245
523
|
```css
|
|
246
524
|
.grid {
|
|
@@ -250,73 +528,83 @@ Seyuna includes shorthand breakpoints that compile to CSS Container Queries:
|
|
|
250
528
|
@md {
|
|
251
529
|
grid-template-columns: repeat(2, 1fr);
|
|
252
530
|
}
|
|
253
|
-
|
|
254
|
-
@lg {
|
|
255
|
-
grid-template-columns: repeat(3, 1fr);
|
|
256
|
-
}
|
|
257
531
|
}
|
|
258
532
|
```
|
|
259
533
|
|
|
260
|
-
|
|
261
|
-
| :------ | :-------------- |
|
|
262
|
-
| `@xs` | 20rem |
|
|
263
|
-
| `@sm` | 40rem |
|
|
264
|
-
| `@md` | 48rem |
|
|
265
|
-
| `@lg` | 64rem |
|
|
266
|
-
| `@xl` | 80rem |
|
|
267
|
-
| `@2xl` | 96rem |
|
|
534
|
+
Supported shorthands:
|
|
268
535
|
|
|
269
|
-
|
|
536
|
+
| At-rule | Expands to |
|
|
537
|
+
| :------ | :--------- |
|
|
538
|
+
| `@xs` | `@container (min-width: 20rem)` |
|
|
539
|
+
| `@sm` | `@container (min-width: 40rem)` |
|
|
540
|
+
| `@md` | `@container (min-width: 48rem)` |
|
|
541
|
+
| `@lg` | `@container (min-width: 64rem)` |
|
|
542
|
+
| `@xl` | `@container (min-width: 80rem)` |
|
|
543
|
+
| `@2xl` | `@container (min-width: 96rem)` |
|
|
544
|
+
|
|
545
|
+
These react to the container, not the viewport, so components stay reusable in nested layouts.
|
|
270
546
|
|
|
271
547
|
---
|
|
272
548
|
|
|
273
549
|
## Palette Iteration
|
|
274
550
|
|
|
275
|
-
|
|
551
|
+
Seyuna can generate repeated selectors from your token lists.
|
|
552
|
+
|
|
553
|
+
The recommended shape is to pass a selector template as the at-rule parameter. This keeps the CSS parseable while still letting you generate class selectors.
|
|
554
|
+
|
|
555
|
+
### `@each-tone "<selector-template>"`
|
|
556
|
+
|
|
557
|
+
Iterates over the names in the standard hue map.
|
|
276
558
|
|
|
277
559
|
```css
|
|
278
|
-
@each-
|
|
279
|
-
|
|
280
|
-
background-color: SeyunaStandardColor({name});
|
|
281
|
-
}
|
|
560
|
+
@each-tone ".bg-{name}" {
|
|
561
|
+
background-color: SeyunaTone({name});
|
|
282
562
|
}
|
|
563
|
+
```
|
|
283
564
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
565
|
+
That generates selectors such as:
|
|
566
|
+
|
|
567
|
+
- `.bg-primary`
|
|
568
|
+
- `.bg-alpha`
|
|
569
|
+
- `.bg-omega`
|
|
570
|
+
|
|
571
|
+
### `@each-swatch "<selector-template>"`
|
|
572
|
+
|
|
573
|
+
Iterates over fixed colors from:
|
|
574
|
+
|
|
575
|
+
- global fixed colors declared with `--color-*`
|
|
576
|
+
- light-mode fixed color overrides
|
|
577
|
+
- dark-mode fixed color overrides
|
|
578
|
+
|
|
579
|
+
```css
|
|
580
|
+
@each-swatch ".text-{name}" {
|
|
581
|
+
color: SeyunaSwatch({name});
|
|
288
582
|
}
|
|
289
583
|
```
|
|
290
584
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
## Configuration Properties
|
|
585
|
+
That generates selectors such as:
|
|
294
586
|
|
|
295
|
-
|
|
587
|
+
- `.text-white`
|
|
588
|
+
- `.text-black`
|
|
589
|
+
- `.text-brand`
|
|
296
590
|
|
|
297
|
-
|
|
298
|
-
| :---------------- | :--------------------------------------------------------------- | :---------------------------------- |
|
|
299
|
-
| `--hue-*` | Defines a hue angle for a standard color | `--hue-primary: 240;` |
|
|
300
|
-
| `--color-*` | Defines a global fixed color (L C H) | `--color-brand: 0.6 0.2 120;` |
|
|
301
|
-
| `--light-color-*` | Overrides a fixed color for light mode | `--light-color-brand: 0.8 0.1 120;` |
|
|
302
|
-
| `--light-*` | Configures the light theme (lightness, chroma, background, text) | `--light-lightness: 0.8;` |
|
|
303
|
-
| `--dark-color-*` | Overrides a fixed color for dark mode | `--dark-color-brand: 0.4 0.1 120;` |
|
|
304
|
-
| `--dark-*` | Configures the dark theme | `--dark-background: 0 0 0;` |
|
|
591
|
+
`{name}` is replaced inside the selector template and inside declaration values.
|
|
305
592
|
|
|
306
|
-
|
|
593
|
+
If you write nested parseable selectors inside the block, Seyuna still replaces `{name}` there as well. But for class generation, the selector-template parameter is the easiest and safest approach.
|
|
307
594
|
|
|
308
595
|
---
|
|
309
596
|
|
|
310
|
-
##
|
|
597
|
+
## Common Gotchas
|
|
311
598
|
|
|
312
|
-
|
|
599
|
+
- Run Seyuna early in the PostCSS chain.
|
|
600
|
+
- Keep `@seyuna;` to a single final injection point.
|
|
601
|
+
- Do not use the same token name for both a hue and a fixed color unless you intentionally want both variable shapes to exist.
|
|
602
|
+
- If CSS is split across files, make sure the files containing `@config "seyuna"` and `@seyuna;` are processed together in the same build pipeline.
|
|
603
|
+
- Prefer selector templates for palette iteration, e.g. `@each-tone ".bg-{name}"`.
|
|
313
604
|
|
|
314
|
-
|
|
315
|
-
.container {
|
|
316
|
-
max-width: SeyunaTheme(ui.theme.breakpoints.lg);
|
|
317
|
-
}
|
|
318
|
-
```
|
|
605
|
+
If output looks wrong, check plugin order first. That is the most common source of problems.
|
|
319
606
|
|
|
607
|
+
---
|
|
320
608
|
---
|
|
321
609
|
|
|
322
610
|
## License
|