@seyuna/postcss 1.0.0-canary.2 → 1.0.0-canary.21

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 (58) hide show
  1. package/.github/workflows/release.yml +1 -1
  2. package/CHANGELOG.md +146 -0
  3. package/README.md +275 -0
  4. package/dist/at-rules/color-scheme.d.ts +4 -0
  5. package/dist/at-rules/color-scheme.js +49 -0
  6. package/dist/at-rules/color.d.ts +10 -0
  7. package/dist/at-rules/color.js +34 -0
  8. package/dist/at-rules/container.d.ts +19 -0
  9. package/dist/at-rules/container.js +55 -0
  10. package/dist/at-rules/index.d.ts +6 -2
  11. package/dist/at-rules/index.js +16 -7
  12. package/dist/config.d.ts +6 -0
  13. package/dist/config.js +53 -0
  14. package/dist/errors.d.ts +7 -0
  15. package/dist/errors.js +18 -0
  16. package/dist/functions/color.d.ts +7 -1
  17. package/dist/functions/color.js +66 -12
  18. package/dist/functions/index.d.ts +2 -1
  19. package/dist/functions/index.js +9 -7
  20. package/dist/functions/theme.d.ts +6 -0
  21. package/dist/functions/theme.js +20 -0
  22. package/dist/helpers.d.ts +12 -0
  23. package/dist/helpers.js +63 -0
  24. package/dist/index.d.ts +3 -3
  25. package/dist/index.js +7 -4
  26. package/dist/parser.d.ts +4 -0
  27. package/dist/parser.js +65 -0
  28. package/dist/plugin.d.ts +2 -4
  29. package/dist/plugin.js +28 -16
  30. package/dist/types.d.ts +59 -0
  31. package/dist/types.js +4 -0
  32. package/package.json +14 -5
  33. package/release.config.mjs +6 -1
  34. package/src/at-rules/color-scheme.ts +53 -0
  35. package/src/at-rules/color.ts +33 -0
  36. package/src/at-rules/container.ts +58 -0
  37. package/src/at-rules/index.ts +22 -8
  38. package/src/config.ts +59 -0
  39. package/src/errors.ts +23 -0
  40. package/src/functions/color.ts +80 -14
  41. package/src/functions/index.ts +11 -5
  42. package/src/functions/theme.ts +20 -0
  43. package/src/helpers.ts +75 -0
  44. package/src/index.ts +5 -3
  45. package/src/parser.ts +81 -0
  46. package/src/plugin.ts +29 -24
  47. package/src/types.ts +72 -0
  48. package/tests/plugin.test.ts +143 -0
  49. package/tsconfig.json +2 -2
  50. package/dist/at-rules/dark.d.ts +0 -2
  51. package/dist/at-rules/dark.js +0 -28
  52. package/dist/at-rules/light.d.ts +0 -2
  53. package/dist/at-rules/light.js +0 -28
  54. package/dist/functions/spacing.d.ts +0 -1
  55. package/dist/functions/spacing.js +0 -6
  56. package/src/at-rules/dark.ts +0 -33
  57. package/src/at-rules/light.ts +0 -33
  58. package/src/functions/spacing.ts +0 -3
@@ -24,7 +24,7 @@ jobs:
24
24
  - name: Setup Node.js with npm auth
25
25
  uses: actions/setup-node@v4
26
26
  with:
27
- node-version: 20
27
+ node-version: 22
28
28
  registry-url: https://registry.npmjs.org/
29
29
  scope: "@seyuna"
30
30
  always-auth: true
package/CHANGELOG.md CHANGED
@@ -1,3 +1,149 @@
1
+ # [1.0.0-canary.21](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.20...v1.0.0-canary.21) (2026-01-10)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * resolve deadlock by switching to CJS and lazy initialization ([5ae6db2](https://github.com/seyuna-corp/seyuna-postcss/commit/5ae6db23e8fdc630787e2feb4c062af0187bf8c4))
7
+
8
+ # [1.0.0-canary.20](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.19...v1.0.0-canary.20) (2026-01-10)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * remove @seyuna/cli dependency to prevent bundler loading Deno polyfills ([544a37e](https://github.com/seyuna-corp/seyuna-postcss/commit/544a37e412fcfd585c1dbcdfe28484ce63bec3c1))
14
+
15
+ # [1.0.0-canary.19](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.18...v1.0.0-canary.19) (2026-01-10)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * define types locally to avoid @seyuna/cli polyfill side-effects ([acdbcc9](https://github.com/seyuna-corp/seyuna-postcss/commit/acdbcc977fd2a501302d675ff7ffd2c307e25a95))
21
+
22
+ # [1.0.0-canary.18](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.17...v1.0.0-canary.18) (2026-01-10)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * break circular dependency between config.ts and parser.ts ([88ae984](https://github.com/seyuna-corp/seyuna-postcss/commit/88ae9848ed2eb4d4ca5fb6340cbe5aa1c986f1b8))
28
+
29
+ # [1.0.0-canary.17](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.16...v1.0.0-canary.17) (2026-01-10)
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * transition to proper ESM with correct file extensions ([b330b4f](https://github.com/seyuna-corp/seyuna-postcss/commit/b330b4fcd3394b78ecc39ef5f23f5e993bd425be))
35
+
36
+ # [1.0.0-canary.16](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.15...v1.0.0-canary.16) (2026-01-10)
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * Fixed release configuration. ([3e7f764](https://github.com/seyuna-corp/seyuna-postcss/commit/3e7f76488e109110cbec50cb4c5bdc89397b3b40))
42
+ * release configuration error. ([076eb34](https://github.com/seyuna-corp/seyuna-postcss/commit/076eb348d2ce7ca61bbc1c7a9ad597cadbe59f34))
43
+
44
+ # [1.0.0-canary.15](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.14...v1.0.0-canary.15) (2026-01-09)
45
+
46
+
47
+ ### Bug Fixes
48
+
49
+ * workflow node version upgrade. ([e98349a](https://github.com/seyuna-corp/seyuna-postcss/commit/e98349af69aab446f0ac4d0790112d5c702c1b36))
50
+
51
+ # [1.0.0-canary.14](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.13...v1.0.0-canary.14) (2025-10-09)
52
+
53
+
54
+ ### Bug Fixes
55
+
56
+ * bug in generateRules ([d5b66d3](https://github.com/seyuna-corp/seyuna-postcss/commit/d5b66d32786f554c0e4f7ea98ae526e7f7ac82c5))
57
+ * removed pnpm lock file that ([6d87d61](https://github.com/seyuna-corp/seyuna-postcss/commit/6d87d616a79a2a539b09dea26bc907dee1d437e2))
58
+ * updated lock file ([d52dcfb](https://github.com/seyuna-corp/seyuna-postcss/commit/d52dcfb2bccbd502d744ceb09aa83394df4ac057))
59
+
60
+ # [1.0.0-canary.13](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.12...v1.0.0-canary.13) (2025-10-07)
61
+
62
+
63
+ ### Bug Fixes
64
+
65
+ * safely clone nodes and replace {name} placeholders ([8a68ee6](https://github.com/seyuna-corp/seyuna-postcss/commit/8a68ee6f1ade947639151bdbf365c102aa439d37))
66
+
67
+ # [1.0.0-canary.12](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.11...v1.0.0-canary.12) (2025-09-15)
68
+
69
+
70
+ ### Bug Fixes
71
+
72
+ * color functions not running when used inside at-each rules ([995fd98](https://github.com/seyuna-corp/seyuna-postcss/commit/995fd9816f2c2d51caa67add4d3172cee41d0c65))
73
+
74
+ # [1.0.0-canary.11](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.10...v1.0.0-canary.11) (2025-09-15)
75
+
76
+
77
+ ### Bug Fixes
78
+
79
+ * nested rules for at-each-standard-color & at-each-fixed-color ([197a755](https://github.com/seyuna-corp/seyuna-postcss/commit/197a75542798ecacaa071802b2abbf962bcd6538))
80
+
81
+ # [1.0.0-canary.10](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.9...v1.0.0-canary.10) (2025-09-10)
82
+
83
+
84
+ ### Bug Fixes
85
+
86
+ * registered each breakpoint to the same handler for at-rule `container` ([f3f5b36](https://github.com/seyuna-corp/seyuna-postcss/commit/f3f5b3665291dc94e92f3f7c2b2a576b4bdb4517))
87
+
88
+ # [1.0.0-canary.9](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.8...v1.0.0-canary.9) (2025-09-10)
89
+
90
+
91
+ ### Bug Fixes
92
+
93
+ * colors selector in at-rule `each-fixed-color` ([31adb28](https://github.com/seyuna-corp/seyuna-postcss/commit/31adb28f3576a0dcfb78a9aadf331ee4b7ef3e0c))
94
+
95
+ # [1.0.0-canary.8](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.7...v1.0.0-canary.8) (2025-09-10)
96
+
97
+
98
+ ### Features
99
+
100
+ * added at-rule `each-fixed-color` ([699ee0d](https://github.com/seyuna-corp/seyuna-postcss/commit/699ee0defd1fbb0ff91a90c1e13358b1ef9832b2))
101
+
102
+
103
+ ### BREAKING CHANGES
104
+
105
+ * at-rule `each-seyuna-color` renamed to `each-standard-color`
106
+
107
+ # [1.0.0-canary.7](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.6...v1.0.0-canary.7) (2025-09-10)
108
+
109
+
110
+ ### Features
111
+
112
+ * Added at-rule ([8a08289](https://github.com/seyuna-corp/seyuna-postcss/commit/8a08289023f4aa6f65d56e10697e64d02444f118))
113
+
114
+ # [1.0.0-canary.6](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.5...v1.0.0-canary.6) (2025-09-09)
115
+
116
+
117
+ ### Features
118
+
119
+ * add new color function 'fc' ([70e961f](https://github.com/seyuna-corp/seyuna-postcss/commit/70e961fb0b0a13e358de15b42a87b7890f3fc5c0))
120
+
121
+
122
+ ### BREAKING CHANGES
123
+
124
+ * changed how 'sc' functions, not backward-compatible
125
+
126
+ # [1.0.0-canary.5](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.4...v1.0.0-canary.5) (2025-08-25)
127
+
128
+
129
+ ### Bug Fixes
130
+
131
+ * changed color function name to sc to avoid conflicts with the default css color() function ([a46e96c](https://github.com/seyuna-corp/seyuna-postcss/commit/a46e96c74839f930d39a2c273c822a689a942783))
132
+
133
+ # [1.0.0-canary.4](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.3...v1.0.0-canary.4) (2025-08-24)
134
+
135
+
136
+ ### Bug Fixes
137
+
138
+ * at-rules for mode now ensure that [data-mode=system] before enforcing prefers-color-scheme ([475055d](https://github.com/seyuna-corp/seyuna-postcss/commit/475055db1d5662d25631953af669bf64b2e0468e))
139
+
140
+ # [1.0.0-canary.3](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.2...v1.0.0-canary.3) (2025-08-24)
141
+
142
+
143
+ ### Bug Fixes
144
+
145
+ * prioritized data-mode over prefers-color-scheme for [@dark](https://github.com/dark) & [@light](https://github.com/light) rules ([1dafbe7](https://github.com/seyuna-corp/seyuna-postcss/commit/1dafbe74c2ceae8faf28f55ac64846e9e752405b))
146
+
1
147
  # [1.0.0-canary.2](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.1...v1.0.0-canary.2) (2025-08-08)
2
148
 
3
149
 
package/README.md ADDED
@@ -0,0 +1,275 @@
1
+ # @seyuna/postcss
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/@seyuna/postcss.svg)](https://www.npmjs.com/package/@seyuna/postcss)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ > Build interfaces that transcend resolution.
7
+
8
+ ---
9
+
10
+ ## What is this
11
+
12
+ Seyuna PostCSS is the engine behind the Seyuna design system. It compiles a declarative color configuration into fully functional CSS, handles theme switching, and provides a suite of utilities that make authoring stylesheets faster and more intuitive.
13
+
14
+ The core philosophy is simple: **design once at 1080p, deploy everywhere**. Seyuna UI handles upscaling automatically through viewport-relative font sizing. The result is pixel-perfect consistency from a laptop to a 4K display without breakpoints, without media queries, without you lifting a finger.
15
+
16
+ ```css
17
+ html {
18
+ font-size: max(1rem, 0.833vw);
19
+ }
20
+ ```
21
+
22
+ This single line is the foundation. At 1920px viewport width, `0.833vw` equals exactly `16px`. Everything scales proportionally. No more designing three versions of every component.
23
+
24
+ ---
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install @seyuna/postcss postcss-import postcss-advanced-variables postcss-preset-env --save-dev
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Configuration
35
+
36
+ Create a `postcss.config.js` at your project root:
37
+
38
+ ```javascript
39
+ import seyunaPostcss from '@seyuna/postcss';
40
+ import postcssImport from 'postcss-import';
41
+ import postcssAdvancedVariables from 'postcss-advanced-variables';
42
+ import postcssPresetEnv from 'postcss-preset-env';
43
+
44
+ export default {
45
+ plugins: [
46
+ seyunaPostcss({
47
+ configPath: 'seyuna.json',
48
+ modeAttribute: 'data-mode',
49
+ }),
50
+ postcssImport,
51
+ postcssAdvancedVariables,
52
+ postcssPresetEnv({
53
+ stage: 3,
54
+ features: {
55
+ 'nesting-rules': true,
56
+ },
57
+ }),
58
+ ],
59
+ };
60
+ ```
61
+
62
+ The plugin reads from `seyuna.json` at build time. This file is your single source of truth for colors, themes, and any other design tokens you want accessible in CSS.
63
+
64
+ ---
65
+
66
+ ## The Color Model
67
+
68
+ Seyuna operates entirely in the OKLCH color space. Unlike HSL or RGB, OKLCH is perceptually uniform. A lightness of `0.66` looks equally bright across all hues. This makes it possible to build harmonious palettes programmatically.
69
+
70
+ ### Standard Colors
71
+
72
+ Standard colors are hue-only tokens. They inherit the global `--lightness` and `--chroma` values from the current theme mode. When the user switches from light to dark, every standard color adapts automatically.
73
+
74
+ ```css
75
+ .button {
76
+ background: sc(primary);
77
+ }
78
+ ```
79
+
80
+ Compiles to:
81
+
82
+ ```css
83
+ .button {
84
+ background: oklch(var(--lightness) var(--chroma) var(--primary-hue) / 1);
85
+ }
86
+ ```
87
+
88
+ ### Fixed Colors
89
+
90
+ Fixed colors are absolute. They define their own lightness, chroma, and hue. Use these for colors that must remain constant regardless of theme, like brand logos or semantic status indicators.
91
+
92
+ ```css
93
+ .badge {
94
+ background: fc(white);
95
+ }
96
+ ```
97
+
98
+ Compiles to:
99
+
100
+ ```css
101
+ .badge {
102
+ background: oklch(var(--white-lightness) var(--white-chroma) var(--white-hue) / 1);
103
+ }
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Color Manipulation
109
+
110
+ All color functions accept a color name from your configuration.
111
+
112
+ | Function | Purpose | Example |
113
+ |:----------------------|:-----------------------------------------|:----------------------------|
114
+ | `alpha(color, value)` | Adjusts opacity | `alpha(primary, 0.5)` |
115
+ | `lighten(color, amt)` | Increases lightness by `amt` | `lighten(primary, 0.1)` |
116
+ | `darken(color, amt)` | Decreases lightness by `amt` | `darken(primary, 0.1)` |
117
+ | `contrast(color)` | Returns black or white based on lightness| `color: contrast(surface);` |
118
+
119
+ The `contrast()` function uses a dynamic CSS calculation internally. It does not bake in a static value. If `--surface-lightness` changes at runtime, the contrast color updates with it.
120
+
121
+ ---
122
+
123
+ ## Theme Switching
124
+
125
+ Seyuna supports three modes: `light`, `dark`, and `system`. The system mode respects `prefers-color-scheme`. All switching is handled via the `data-mode` attribute on your root element.
126
+
127
+ ```html
128
+ <html data-mode="system">
129
+ ```
130
+
131
+ The compiled CSS contains rules for all three states:
132
+
133
+ ```css
134
+ [data-mode="light"] {
135
+ --lightness: 0.66;
136
+ --chroma: 0.26;
137
+ }
138
+
139
+ @media (prefers-color-scheme: dark) {
140
+ [data-mode="system"] {
141
+ --lightness: 0.66;
142
+ --chroma: 0.26;
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### In-CSS Overrides
148
+
149
+ Need a component to look different in dark mode? Use the `@dark` and `@light` at-rules directly in your stylesheet:
150
+
151
+ ```css
152
+ .card {
153
+ background: fc(white);
154
+
155
+ @dark {
156
+ background: fc(black);
157
+ }
158
+ }
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Container Queries
164
+
165
+ Seyuna ships with shorthand breakpoints that compile to CSS Container Queries instead of traditional media queries. This means components respond to their container size, not the viewport.
166
+
167
+ ```css
168
+ .grid {
169
+ display: grid;
170
+ grid-template-columns: 1fr;
171
+
172
+ @md {
173
+ grid-template-columns: repeat(2, 1fr);
174
+ }
175
+
176
+ @lg {
177
+ grid-template-columns: repeat(3, 1fr);
178
+ }
179
+ }
180
+ ```
181
+
182
+ Available breakpoints:
183
+
184
+ | At-Rule | Container Width |
185
+ |:--------|:----------------|
186
+ | `@xs` | 20rem |
187
+ | `@sm` | 30rem |
188
+ | `@md` | 48rem |
189
+ | `@lg` | 62rem |
190
+ | `@xl` | 80rem |
191
+ | `@2xl` | 96rem |
192
+
193
+ ---
194
+
195
+ ## Configuration Reference
196
+
197
+ ```json
198
+ {
199
+ "ui": {
200
+ "theme": {
201
+ "hues": {
202
+ "primary": 240,
203
+ "secondary": 30,
204
+ "accent": 150
205
+ },
206
+ "colors": {
207
+ "white": { "lightness": 1, "chroma": 0, "hue": 0 },
208
+ "black": { "lightness": 0, "chroma": 0, "hue": 0 }
209
+ },
210
+ "light": {
211
+ "lightness": 0.66,
212
+ "chroma": 0.26,
213
+ "background": { "lightness": 1, "chroma": 0, "hue": 0 },
214
+ "text": { "lightness": 0, "chroma": 0, "hue": 0 }
215
+ },
216
+ "dark": {
217
+ "lightness": 0.66,
218
+ "chroma": 0.26,
219
+ "background": { "lightness": 0, "chroma": 0, "hue": 0 },
220
+ "text": { "lightness": 1, "chroma": 0, "hue": 0 }
221
+ }
222
+ },
223
+ "mode": "system",
224
+ "output_dir": "src/styles"
225
+ }
226
+ }
227
+ ```
228
+
229
+ `hues` defines standard colors. Only the hue angle is specified because lightness and chroma come from the theme mode.
230
+
231
+ `colors` defines fixed colors with explicit lightness, chroma, and hue values.
232
+
233
+ `light` and `dark` set the global lightness and chroma for standard colors, plus any mode-specific fixed colors like background and text.
234
+
235
+ ---
236
+
237
+ ## Palette Iteration
238
+
239
+ Generate utility classes by iterating over your entire color configuration:
240
+
241
+ ```css
242
+ @each-standard-color {
243
+ .bg-{name} {
244
+ background-color: sc({name});
245
+ }
246
+ }
247
+
248
+ @each-fixed-color {
249
+ .text-{name} {
250
+ color: fc({name});
251
+ }
252
+ }
253
+ ```
254
+
255
+ ---
256
+
257
+ ## The Reset Layer
258
+
259
+ Seyuna UI generates a CSS file that includes a minimal, opinionated reset. It zeroes out margins and padding, removes default list styles, and sets sensible defaults for text rendering. The reset is applied to the `reset` layer, so your styles can override it without specificity battles.
260
+
261
+ The upscaling magic happens here:
262
+
263
+ ```css
264
+ html {
265
+ font-size: max(1rem, 0.833vw);
266
+ }
267
+ ```
268
+
269
+ At 1920px, the computed font size is 16px. At 2560px, it becomes roughly 21px. Every `rem` value in your stylesheet scales accordingly. Design at 1080p. Ship at any resolution.
270
+
271
+ ---
272
+
273
+ ## License
274
+
275
+ MIT
@@ -0,0 +1,4 @@
1
+ import type { AtRule } from "postcss";
2
+ import { PluginContext } from "../types.js";
3
+ export declare const light: (atRule: AtRule, context: PluginContext) => void;
4
+ export declare const dark: (atRule: AtRule, context: PluginContext) => void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.dark = exports.light = void 0;
7
+ const postcss_1 = __importDefault(require("postcss"));
8
+ /**
9
+ * Custom PostCSS plugin handler factory for `@light` and `@dark` at-rules.
10
+ */
11
+ function createColorSchemeHandler(scheme) {
12
+ return (atRule, context) => {
13
+ const { options } = context;
14
+ const modeAttribute = options.modeAttribute;
15
+ const clonedNodes = [];
16
+ // Clone all child nodes inside the block
17
+ atRule.each((node) => {
18
+ clonedNodes.push(node.clone());
19
+ });
20
+ /**
21
+ * Rule 1: [data-mode="scheme"] & { ... } (Explicit mode)
22
+ */
23
+ const explicitRule = new postcss_1.default.Rule({
24
+ selector: `[${modeAttribute}="${scheme}"] &`,
25
+ source: atRule.source,
26
+ });
27
+ clonedNodes.forEach((node) => explicitRule.append(node.clone()));
28
+ /**
29
+ * Rule 2: @media (prefers-color-scheme: scheme) { [data-mode="system"] & { ... } } (System preference)
30
+ */
31
+ const mediaAtRule = new postcss_1.default.AtRule({
32
+ name: "media",
33
+ params: `(prefers-color-scheme: ${scheme})`,
34
+ source: atRule.source,
35
+ });
36
+ const systemRule = new postcss_1.default.Rule({
37
+ selector: `[${modeAttribute}="system"] &`,
38
+ source: atRule.source,
39
+ });
40
+ clonedNodes.forEach((node) => systemRule.append(node.clone()));
41
+ mediaAtRule.append(systemRule);
42
+ /**
43
+ * Replace the original at-rule with the generated rules.
44
+ */
45
+ atRule.replaceWith(mediaAtRule, explicitRule);
46
+ };
47
+ }
48
+ exports.light = createColorSchemeHandler('light');
49
+ exports.dark = createColorSchemeHandler('dark');
@@ -0,0 +1,10 @@
1
+ import type { AtRule } from "postcss";
2
+ import { PluginContext } from "../types.js";
3
+ /**
4
+ * Handler for @each-standard-color
5
+ */
6
+ export declare function eachStandardColor(atRule: AtRule, context: PluginContext): void;
7
+ /**
8
+ * Handler for @each-fixed-color
9
+ */
10
+ export declare function eachFixedColor(atRule: AtRule, context: PluginContext): void;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.eachStandardColor = eachStandardColor;
4
+ exports.eachFixedColor = eachFixedColor;
5
+ const helpers_js_1 = require("../helpers.js");
6
+ /**
7
+ * Handler for @each-standard-color
8
+ */
9
+ function eachStandardColor(atRule, context) {
10
+ const { config } = context;
11
+ const hueNames = config.ui ? Object.keys(config.ui.theme.hues) : [];
12
+ const rules = (0, helpers_js_1.generateRules)(hueNames, atRule, context);
13
+ if (rules.length)
14
+ atRule.replaceWith(...rules);
15
+ else
16
+ atRule.remove();
17
+ }
18
+ /**
19
+ * Handler for @each-fixed-color
20
+ */
21
+ function eachFixedColor(atRule, context) {
22
+ const { config } = context;
23
+ const mergedNames = [
24
+ ...new Set([
25
+ ...(config.ui ? Object.keys(config.ui.theme.light.colors) : []),
26
+ ...(config.ui ? Object.keys(config.ui.theme.dark.colors) : []),
27
+ ]),
28
+ ];
29
+ const rules = (0, helpers_js_1.generateRules)(mergedNames, atRule, context);
30
+ if (rules.length)
31
+ atRule.replaceWith(...rules);
32
+ else
33
+ atRule.remove();
34
+ }
@@ -0,0 +1,19 @@
1
+ import type { AtRule } from "postcss";
2
+ import { PluginContext } from "../types.js";
3
+ /**
4
+ * Custom PostCSS plugin handler for responsive at-rules.
5
+ *
6
+ * Example:
7
+ *
8
+ * @xs {
9
+ * .box { color: red; }
10
+ * }
11
+ *
12
+ * Into:
13
+ *
14
+ * @xs (min-width: 234px) {
15
+ * .box { color: red; }
16
+ * }
17
+ *
18
+ */
19
+ export default function container(atRule: AtRule, context: PluginContext): void;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = container;
7
+ const postcss_1 = __importDefault(require("postcss"));
8
+ /**
9
+ * Custom PostCSS plugin handler for responsive at-rules.
10
+ *
11
+ * Example:
12
+ *
13
+ * @xs {
14
+ * .box { color: red; }
15
+ * }
16
+ *
17
+ * Into:
18
+ *
19
+ * @xs (min-width: 234px) {
20
+ * .box { color: red; }
21
+ * }
22
+ *
23
+ */
24
+ function container(atRule, context) {
25
+ var _a, _b;
26
+ const { config } = context;
27
+ // Default breakpoints
28
+ const defaultBreakpoints = {
29
+ xs: "20rem",
30
+ sm: "40rem",
31
+ md: "48rem",
32
+ lg: "64rem",
33
+ xl: "80rem",
34
+ "2xl": "96rem",
35
+ };
36
+ // Merge with config if available (assuming config.ui.breakpoints exists)
37
+ const breakpoints = {
38
+ ...defaultBreakpoints,
39
+ ...(((_b = (_a = config.ui) === null || _a === void 0 ? void 0 : _a.theme) === null || _b === void 0 ? void 0 : _b.breakpoints) || {}),
40
+ };
41
+ if (Object.keys(breakpoints).includes(atRule.name)) {
42
+ const minWidth = breakpoints[atRule.name];
43
+ const clonedNodes = [];
44
+ atRule.each((node) => {
45
+ clonedNodes.push(node.clone());
46
+ });
47
+ const containerAtRule = new postcss_1.default.AtRule({
48
+ name: "container",
49
+ params: `(min-width: ${minWidth})`,
50
+ source: atRule.source,
51
+ });
52
+ clonedNodes.forEach((node) => containerAtRule.append(node));
53
+ atRule.replaceWith(containerAtRule);
54
+ }
55
+ }
@@ -1,3 +1,7 @@
1
1
  import type { AtRule } from "postcss";
2
- export type AtRuleHandler = (atRule: AtRule) => void;
3
- export declare const atRuleHandlers: Record<string, AtRuleHandler>;
2
+ import { PluginContext } from "../types.js";
3
+ export interface AtRuleHandler {
4
+ name: string;
5
+ handler: (atRule: AtRule, context: PluginContext) => void;
6
+ }
7
+ export declare const atRuleHandlers: AtRuleHandler[];
@@ -4,10 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.atRuleHandlers = void 0;
7
- const dark_1 = __importDefault(require("./dark"));
8
- const light_1 = __importDefault(require("./light"));
9
- exports.atRuleHandlers = {
10
- light: light_1.default,
11
- dark: dark_1.default,
12
- // add more handlers here as needed
13
- };
7
+ const color_js_1 = require("./color.js");
8
+ const container_js_1 = __importDefault(require("./container.js"));
9
+ const color_scheme_js_1 = require("./color-scheme.js");
10
+ // Ordered array ensures execution order
11
+ exports.atRuleHandlers = [
12
+ { name: "each-standard-color", handler: color_js_1.eachStandardColor },
13
+ { name: "each-fixed-color", handler: color_js_1.eachFixedColor },
14
+ { name: "light", handler: color_scheme_js_1.light },
15
+ { name: "dark", handler: color_scheme_js_1.dark },
16
+ { name: "xs", handler: container_js_1.default },
17
+ { name: "sm", handler: container_js_1.default },
18
+ { name: "md", handler: container_js_1.default },
19
+ { name: "lg", handler: container_js_1.default },
20
+ { name: "xl", handler: container_js_1.default },
21
+ { name: "2xl", handler: container_js_1.default },
22
+ ];
@@ -0,0 +1,6 @@
1
+ import { SeyunaConfig, PluginOptions } from './types.js';
2
+ export type { PluginOptions, PluginContext, FunctionMap } from './types.js';
3
+ export declare function loadConfig(options?: PluginOptions): {
4
+ config: SeyunaConfig;
5
+ options: Required<PluginOptions>;
6
+ };