windrunner 1.0.3 → 1.1.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.
package/LICENSE CHANGED
@@ -1,15 +1,15 @@
1
- ISC License
2
-
3
- Copyright (c) 2026 Bigetion
4
-
5
- Permission to use, copy, modify, and/or distribute this software for any
6
- purpose with or without fee is hereby granted, provided that the above
7
- copyright notice and this permission notice appear in all copies.
8
-
9
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Bigetion
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md CHANGED
@@ -1,240 +1,328 @@
1
- # windrunner
2
-
3
- Zero-config Tailwind v4 runtime for the browser. Compile utility classes on-demand — no build step, no PostCSS, no config file.
4
-
5
- Drop a `<script>` tag and start using Tailwind classes anywhere.
6
-
7
- ## How it works
8
-
9
- Instead of generating a full CSS bundle upfront, `windrunner` scans the DOM for class names and compiles only the CSS rules actually used — then injects them into a `<style>` tag in `<head>`. A `MutationObserver` watches for DOM changes and compiles new classes as they appear.
10
-
11
- ```
12
- Page loads → scan DOM → compile used classes → inject <style>
13
- ↑ |
14
- MutationObserver detects new classes ←─────────────┘
15
- ```
16
-
17
- ## Install
18
-
19
- ```bash
20
- npm install windrunner
21
- ```
22
-
23
- ## Usage
24
-
25
- ### Drop-in script (zero config)
26
-
27
- ```html
28
- <script type="module">
29
- import { windrunner } from "windrunner";
30
- windrunner({ autoStart: true });
31
- </script>
32
-
33
- <div class="flex items-center gap-4 p-6 bg-blue-50 rounded-xl">
34
- <h1 class="text-2xl font-bold text-slate-900">Hello</h1>
35
- <button class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200">
36
- Click me
37
- </button>
38
- </div>
39
- ```
40
-
41
- ### CDN
42
-
43
- ```html
44
- <script type="module">
45
- import { windrunner } from "https://cdn.jsdelivr.net/npm/windrunner@1.0.1/dist/index.min.js";
46
- windrunner({ autoStart: true });
47
- </script>
48
- ```
49
-
50
- ### Live demo / Example landing page
51
-
52
- Try the example landing page:
53
-
54
- - CodeSandbox (example landing): https://xj6q66.csb.app
55
-
56
-
57
- ### React / Vue
58
-
59
- ```js
60
- import { useEffect } from "react";
61
- import { windrunner } from "windrunner";
62
-
63
- export default function App() {
64
- useEffect(() => {
65
- const wind = windrunner({ id: "my-app", autoStart: true });
66
- return () => wind.disconnect();
67
- }, []);
68
-
69
- return (
70
- <main className="min-h-screen bg-slate-50 p-8">
71
- <h1 className="text-3xl font-bold text-slate-900">React + Windrunner</h1>
72
- </main>
73
- );
74
- }
75
- ```
76
-
77
- ### Manual control
78
-
79
- ```js
80
- import { createWindrunner, compileClass } from "windrunner";
81
-
82
- // Compile a single class to a CSS rule string
83
- const css = compileClass("md:hover:bg-blue-500");
84
- // → '@media (min-width: 768px) { .md\\:hover\\:bg-blue-500:hover { background-color: oklch(...); } }'
85
-
86
- // Create an instance with full control
87
- const wind = createWindrunner({ id: "my-app" });
88
- wind.processClassList("flex items-center justify-between gap-4");
89
- wind.scan(); // scan entire document
90
- wind.observe(); // start watching DOM mutations
91
- wind.disconnect(); // stop watching
92
- ```
93
-
94
- ## API
95
-
96
- ### `windrunner(options?)`
97
-
98
- Auto-start mode. Scans DOM and begins observing immediately.
99
-
100
- ```ts
101
- windrunner({
102
- id?: string, // style tag id, default: "tailwind-runtime-css"
103
- autoStart?: boolean, // default: true
104
- theme?: { // override/extend theme values
105
- extend: {
106
- colors: { brand: "#ff6b6b" }
107
- }
108
- }
109
- })
110
- ```
111
-
112
- ### `createWindrunner(options?)`
113
-
114
- Returns a runtime instance with manual control methods:
115
-
116
- | Method | Description |
117
- |---|---|
118
- | `start()` | Scan DOM + start observer (waits for DOMContentLoaded) |
119
- | `scan(root?)` | One-time scan of all `[class]` elements |
120
- | `observe(root?)` | Start MutationObserver |
121
- | `processClassName(cls)` | Compile + inject one class |
122
- | `processClassList(str)` | Compile + inject space-separated classes |
123
- | `processElement(el)` | Compile all classes on a DOM element |
124
- | `flush()` | Force-flush pending element queue |
125
- | `disconnect()` | Stop observer, cleanup |
126
- | `getCacheSize()` | Number of compiled classes in cache |
127
- | `getInsertedRuleCount()` | Number of CSS rules injected |
128
-
129
- ### `compileClass(className, options?)`
130
-
131
- Compile a single class name to a CSS rule string. Works in Node.js too.
132
-
133
- ```js
134
- compileClass("hover:text-blue-500")
135
- // → '.hover\\:text-blue-500:hover { color: oklch(0.623 0.214 259.8); }'
136
- ```
137
-
138
- ### `parseClass(className, screens?, containers?)`
139
-
140
- Parse a class name into its parts:
141
-
142
- ```js
143
- parseClass("md:hover:mt-4", { md: "768px" })
144
- // → { original: "md:hover:mt-4", baseToken: "mt-4", variants: ["hover"],
145
- // breakpoint: "md", containerBreakpoint: null, important: false, starting: false }
146
- ```
147
-
148
- ## Supported utilities
149
-
150
- Full Tailwind v4 coverage including:
151
-
152
- - **Layout** — display, position, overflow, z-index, visibility, float, clear, aspect-ratio, columns, isolation, object-fit/position
153
- - **Spacing** — margin, padding, gap, space (with negative values)
154
- - **Sizing** width, height, min/max-w/h, size-*
155
- - **Flexbox** flex, grow, shrink, basis, direction, wrap, align, justify, place
156
- - **Grid** — grid-cols/rows, col/row-span, grid-flow, auto-cols/rows, place-*
157
- - **Typography** font-size, font-weight, line-height, letter-spacing, text-align, text-color, text-decoration, text-transform, text-overflow, whitespace, word-break, list-style
158
- - **Colors** — all OKLCH P3 Tailwind v4 palette + mauve/olive/mist/taupe, opacity modifier (`bg-blue-500/50`)
159
- - **Backgrounds** — bg-color, bg-linear-to-* (v4), gradient stops (from/via/to), bg-size/position/repeat/attachment/clip/origin
160
- - **Borders** — border-width/style/color/radius (all sides + logical)
161
- - **Effects** shadow, opacity, inset-shadow-* (v4), ring, inset-ring-* (v4)
162
- - **Transforms** — rotate, scale, translate (2D + 3D), skew, origin, perspective, backface, transform-style
163
- - **Filters** blur, brightness, contrast, grayscale, hue-rotate, invert, saturate, sepia, drop-shadow, all backdrop-* variants
164
- - **Transitions** — transition, duration, delay, ease
165
- - **Animations** animate-spin/ping/pulse/bounce
166
- - **Interactivity** cursor, select, resize, outline, pointer-events, appearance, touch-action, scroll-behavior, scroll-margin/padding, will-change
167
- - **v4 New** field-sizing-*, mask-*, @container, @container breakpoints (@sm: @md: etc.)
168
- - **Variants** hover, focus, focus-visible, active, visited, disabled, dark, group-hover/focus, peer-*, not-hover/focus/disabled, in-hover, starting: (@starting-style), first/last/odd/even, before/after, placeholder
169
-
170
- ## Custom theme
171
-
172
- ```js
173
- windrunner({
174
- autoStart: true,
175
- theme: {
176
- extend: {
177
- colors: {
178
- brand: {
179
- 50: "oklch(0.97 0.01 200)",
180
- 500: "oklch(0.55 0.18 200)",
181
- 900: "oklch(0.25 0.10 200)",
182
- }
183
- },
184
- spacing: {
185
- 18: "4.5rem",
186
- 128: "32rem",
187
- }
188
- }
189
- }
190
- });
191
- ```
192
-
193
- ## Preventing FOUC
194
-
195
- Because windrunner compiles CSS at runtime, browsers may briefly render unstyled content before styles are injected (Flash of Unstyled Content). The recommended fix:
196
-
197
- ```html
198
- <head>
199
- <!-- 1. Hide the page before styles are ready -->
200
- <style>html { opacity: 0; transition: opacity 0.2s ease; }</style>
201
-
202
- <!-- 2. Reveal after windrunner finishes its first scan -->
203
- <script type="module">
204
- import { windrunner } from "windrunner";
205
- windrunner({
206
- autoStart: true,
207
- onReady: () => document.documentElement.style.opacity = "1",
208
- });
209
- </script>
210
- </head>
211
- ```
212
-
213
- The `onReady` callback fires after the initial DOM scan completes and CSS rules are injected, ensuring the page is fully styled before it becomes visible. The `transition` gives a smooth 200ms fade-in instead of an abrupt pop.
214
-
215
- ## Preflight
216
-
217
- windrunner injects a CSS reset (based on Tailwind's preflight) automatically. To opt out:
218
-
219
- ```js
220
- windrunner({ autoStart: true, preflight: false });
221
- ```
222
-
223
- ## vs Tailwind Play CDN
224
-
225
- | | windrunner | Tailwind Play CDN |
226
- |---|---|---|
227
- | Size | ~78 KB min | ~350 KB |
228
- | Dependencies | 0 | 0 |
229
- | Tailwind version | v4 | v4 |
230
- | Works in Node.js | ✓ (compile only) | ✗ |
231
- | Custom theme | ✓ | ✓ |
232
- | Arbitrary values | ✓ | ✓ |
233
- | Preflight | ✓ | ✓ |
234
- | FOUC prevention | ✓ (onReady) | ✗ |
235
- | Plugins | ✗ | ✓ |
236
- | Full utility coverage | ✓ | ✓ |
237
-
238
- ## License
239
-
240
- ISC
1
+ # windrunner
2
+
3
+ Zero-config Tailwind v4 runtime for the browser. Compile utility classes on-demand — no build step, no PostCSS, no config file.
4
+
5
+ Drop a `<script>` tag and start using Tailwind classes anywhere.
6
+
7
+ ## How it works
8
+
9
+ Instead of generating a full CSS bundle upfront, `windrunner` scans the DOM for class names and compiles only the CSS rules actually used — then injects them into a `<style>` tag in `<head>`. A `MutationObserver` watches for DOM changes and compiles new classes as they appear.
10
+
11
+ ```
12
+ Page loads → scan DOM → compile used classes → inject <style>
13
+ ↑ |
14
+ MutationObserver detects new classes ←─────────────┘
15
+ ```
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install windrunner
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### Drop-in script (zero config)
26
+
27
+ ```html
28
+ <script type="module">
29
+ import { windrunner } from "windrunner";
30
+ windrunner({ autoStart: true });
31
+ </script>
32
+
33
+ <div class="flex items-center gap-4 p-6 bg-blue-50 rounded-xl">
34
+ <h1 class="text-2xl font-bold text-slate-900">Hello</h1>
35
+ <button class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200">
36
+ Click me
37
+ </button>
38
+ </div>
39
+ ```
40
+
41
+ ### CDN
42
+
43
+ ```html
44
+ <script type="module">
45
+ import { windrunner } from "https://cdn.jsdelivr.net/npm/windrunner@1.0.1/dist/index.min.js";
46
+ windrunner({ autoStart: true });
47
+ </script>
48
+ ```
49
+
50
+ ### Live demo / Example landing page
51
+
52
+ Try the example landing page:
53
+
54
+ - CodeSandbox (example landing): https://xj6q66.csb.app
55
+
56
+
57
+ ### React / Vue
58
+
59
+ ```js
60
+ import { useEffect } from "react";
61
+ import { windrunner } from "windrunner";
62
+
63
+ export default function App() {
64
+ useEffect(() => {
65
+ const wind = windrunner({ id: "my-app", autoStart: true });
66
+ return () => wind.disconnect();
67
+ }, []);
68
+
69
+ return (
70
+ <main className="min-h-screen bg-slate-50 p-8">
71
+ <h1 className="text-3xl font-bold text-slate-900">React + Windrunner</h1>
72
+ </main>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ### Manual control
78
+
79
+ ```js
80
+ import { createWindrunner, compileClass } from "windrunner";
81
+
82
+ // Compile a single class to a CSS rule string
83
+ const css = compileClass("md:hover:bg-blue-500");
84
+ // → '@media (min-width: 768px) { .md\\:hover\\:bg-blue-500:hover { background-color: oklch(...); } }'
85
+
86
+ // Create an instance with full control
87
+ const wind = createWindrunner({ id: "my-app" });
88
+ wind.processClassList("flex items-center justify-between gap-4");
89
+ wind.scan(); // scan entire document
90
+ wind.observe(); // start watching DOM mutations
91
+ wind.disconnect(); // stop watching
92
+ ```
93
+
94
+ ## API
95
+
96
+ ### `windrunner(options?)`
97
+
98
+ Auto-start mode. Scans DOM and begins observing immediately.
99
+
100
+ ```ts
101
+ windrunner({
102
+ id?: string, // style tag id, default: "tailwind-runtime-css"
103
+ autoStart?: boolean, // default: true
104
+ plugins?: Plugin[], // custom plugins (see Plugin System)
105
+ theme?: { // override/extend theme values
106
+ extend: {
107
+ colors: { brand: "#ff6b6b" }
108
+ }
109
+ }
110
+ })
111
+ ```
112
+
113
+ ### Plugin System (NEW in v1.1.0)
114
+
115
+ Create custom utilities and variants:
116
+
117
+ ```js
118
+ import { windrunner, plugin } from 'windrunner';
119
+
120
+ // Define a plugin
121
+ const myPlugin = plugin(({ addUtility, addVariant, theme }) => {
122
+ // Add custom utility
123
+ addUtility('glass', 'backdrop-filter: blur(10px); background: rgba(255,255,255,0.1);');
124
+
125
+ // Add pattern-based utility
126
+ addUtility(/^text-stroke-(\d+)$/, (match) => {
127
+ return `-webkit-text-stroke-width: ${match[1]}px;`;
128
+ });
129
+
130
+ // Add custom variant
131
+ addVariant('parent-hover', (selector) => `.parent:hover ${selector}`);
132
+
133
+ // Access theme
134
+ const colors = theme('colors');
135
+ addUtility('brand-bg', `background-color: ${colors.brand};`);
136
+ });
137
+
138
+ // Use the plugin
139
+ windrunner({
140
+ autoStart: true,
141
+ plugins: [myPlugin]
142
+ });
143
+ ```
144
+
145
+ See [Plugin Examples](./examples/plugins/) for ready-to-use plugins:
146
+ - **text-stroke** - Text outline effects
147
+ - **glass-morphism** - Glassmorphism effects
148
+ - **custom-variants** - parent-hover, loading, and more
149
+
150
+ **Plugin API:**
151
+ - `addUtility(pattern, handler)` - Add custom utility
152
+ - `addUtilities(utilities)` - Add multiple utilities
153
+ - `addVariant(name, handler)` - Add custom variant
154
+ - `theme(key)` - Access theme values
155
+ - `config()` - Access full configuration
156
+
157
+ Full plugin documentation: [Plugin System Guide](./docs/guides/plugins.md) (coming soon)
158
+
159
+ ### `createWindrunner(options?)`
160
+
161
+ Returns a runtime instance with manual control methods:
162
+
163
+ | Method | Description |
164
+ |---|---|
165
+ | `start()` | Scan DOM + start observer (waits for DOMContentLoaded) |
166
+ | `scan(root?)` | One-time scan of all `[class]` elements |
167
+ | `observe(root?)` | Start MutationObserver |
168
+ | `processClassName(cls)` | Compile + inject one class |
169
+ | `processClassList(str)` | Compile + inject space-separated classes |
170
+ | `processElement(el)` | Compile all classes on a DOM element |
171
+ | `flush()` | Force-flush pending element queue |
172
+ | `disconnect()` | Stop observer, cleanup |
173
+ | `getCacheSize()` | Number of compiled classes in cache |
174
+ | `getInsertedRuleCount()` | Number of CSS rules injected |
175
+
176
+ ### `compileClass(className, options?)`
177
+
178
+ Compile a single class name to a CSS rule string. Works in Node.js too.
179
+
180
+ ```js
181
+ compileClass("hover:text-blue-500")
182
+ // → '.hover\\:text-blue-500:hover { color: oklch(0.623 0.214 259.8); }'
183
+ ```
184
+
185
+ ### `parseClass(className, screens?, containers?)`
186
+
187
+ Parse a class name into its parts:
188
+
189
+ ```js
190
+ parseClass("md:hover:mt-4", { md: "768px" })
191
+ // → { original: "md:hover:mt-4", baseToken: "mt-4", variants: ["hover"],
192
+ // breakpoint: "md", containerBreakpoint: null, important: false, starting: false }
193
+ ```
194
+
195
+ ## Supported utilities
196
+
197
+ Full Tailwind v4 coverage including:
198
+
199
+ - **Layout** display, position, overflow, z-index, visibility, float, clear, aspect-ratio, columns, isolation, object-fit/position
200
+ - **Spacing** margin, padding, gap, space (with negative values)
201
+ - **Sizing** — width, height, min/max-w/h, size-*
202
+ - **Flexbox** flex, grow, shrink, basis, direction, wrap, align, justify, place
203
+ - **Grid** — grid-cols/rows, col/row-span, grid-flow, auto-cols/rows, place-*
204
+ - **Typography** font-size, font-weight, line-height, letter-spacing, text-align, text-color, text-decoration, text-transform, text-overflow, whitespace, word-break, list-style
205
+ - **Colors** — all OKLCH P3 Tailwind v4 palette + mauve/olive/mist/taupe, opacity modifier (`bg-blue-500/50`)
206
+ - **Backgrounds** — bg-color, bg-linear-to-* (v4), gradient stops (from/via/to), bg-size/position/repeat/attachment/clip/origin
207
+ - **Borders** border-width/style/color/radius (all sides + logical)
208
+ - **Effects** — shadow, opacity, inset-shadow-* (v4), ring, inset-ring-* (v4)
209
+ - **Transforms** — rotate, scale, translate (2D + 3D), skew, origin, perspective, backface, transform-style
210
+ - **Filters** — blur, brightness, contrast, grayscale, hue-rotate, invert, saturate, sepia, drop-shadow, all backdrop-* variants
211
+ - **Transitions** — transition, duration, delay, ease
212
+ - **Animations** — animate-spin/ping/pulse/bounce
213
+ - **Interactivity** cursor, select, resize, outline, pointer-events, appearance, touch-action, scroll-behavior, scroll-margin/padding, will-change
214
+ - **v4 New** — field-sizing-*, mask-*, @container, @container breakpoints (@sm: @md: etc.)
215
+ - **Variants** — hover, focus, focus-visible, active, visited, disabled, dark, group-hover/focus, peer-*, not-hover/focus/disabled, in-hover, starting: (@starting-style), first/last/odd/even, before/after, placeholder
216
+
217
+ ## Custom theme
218
+
219
+ ```js
220
+ windrunner({
221
+ autoStart: true,
222
+ theme: {
223
+ extend: {
224
+ colors: {
225
+ brand: {
226
+ 50: "oklch(0.97 0.01 200)",
227
+ 500: "oklch(0.55 0.18 200)",
228
+ 900: "oklch(0.25 0.10 200)",
229
+ }
230
+ },
231
+ spacing: {
232
+ 18: "4.5rem",
233
+ 128: "32rem",
234
+ }
235
+ }
236
+ }
237
+ });
238
+ ```
239
+
240
+ ## Preventing FOUC
241
+
242
+ Because windrunner compiles CSS at runtime, browsers may briefly render unstyled content before styles are injected (Flash of Unstyled Content). The recommended fix:
243
+
244
+ ```html
245
+ <head>
246
+ <!-- 1. Hide the page before styles are ready -->
247
+ <style>html { opacity: 0; transition: opacity 0.2s ease; }</style>
248
+
249
+ <!-- 2. Reveal after windrunner finishes its first scan -->
250
+ <script type="module">
251
+ import { windrunner } from "windrunner";
252
+ windrunner({
253
+ autoStart: true,
254
+ onReady: () => document.documentElement.style.opacity = "1",
255
+ });
256
+ </script>
257
+ </head>
258
+ ```
259
+
260
+ The `onReady` callback fires after the initial DOM scan completes and CSS rules are injected, ensuring the page is fully styled before it becomes visible. The `transition` gives a smooth 200ms fade-in instead of an abrupt pop.
261
+
262
+ ## Preflight
263
+
264
+ windrunner injects a CSS reset (based on Tailwind's preflight) automatically. To opt out:
265
+
266
+ ```js
267
+ windrunner({ autoStart: true, preflight: false });
268
+ ```
269
+
270
+ ## vs Tailwind Play CDN
271
+
272
+ | | windrunner | Tailwind Play CDN |
273
+ |---|---|---|
274
+ | Size | ~78 KB min | ~350 KB |
275
+ | Dependencies | 0 | 0 |
276
+ | Tailwind version | v4 | v4 |
277
+ | Works in Node.js | ✓ (compile only) | ✗ |
278
+ | Custom theme | ✓ | ✓ |
279
+ | Arbitrary values | ✓ | ✓ |
280
+ | Preflight | ✓ | ✓ |
281
+ | FOUC prevention | ✓ (onReady) | ✗ |
282
+ | Plugins | ✗ | ✓ |
283
+ | Full utility coverage | ✓ | ✓ |
284
+
285
+ ## 📚 Documentation
286
+
287
+ **New to Windrunner?** Start here:
288
+
289
+ - **[Quick Start Guide](./docs/getting-started/quick-start.md)** - Get running in 5 minutes
290
+ - **[React Integration](./docs/frameworks/react.md)** - Best practices for React apps
291
+ - **[FOUC Prevention](./docs/guides/fouc-prevention.md)** - 5 strategies to prevent flash of unstyled content
292
+ - **[Full Documentation](./docs/)** - Complete guides, API reference, and recipes
293
+
294
+ ### Example Projects
295
+
296
+ Learn by example with our sample applications:
297
+
298
+ 1. **[Landing Page](./examples/landing.html)** - Modern marketing page with animations
299
+ 2. **[Todo App](./examples/todo-app/)** - React app with dark mode and local storage
300
+ 3. **[Coverage Demo](./examples/coverage/)** - Showcase of utility class coverage
301
+
302
+ ## When to Use Windrunner
303
+
304
+ ✅ **Perfect for:**
305
+ - Rapid prototyping and MVPs
306
+ - Landing pages and marketing sites
307
+ - Internal tools and dashboards
308
+ - No-code platforms (Webflow, WordPress, etc.)
309
+ - Projects without build tooling
310
+ - Learning Tailwind v4
311
+
312
+ ⚠️ **Consider traditional Tailwind for:**
313
+ - Large production apps with strict performance budgets
314
+ - SEO-critical pages (requires FOUC prevention)
315
+ - Projects already using PostCSS/build tools
316
+ - Enterprise applications requiring battle-tested solutions
317
+
318
+ See the [documentation](./docs/) for detailed use case analysis and migration guides.
319
+
320
+ ## Contributing
321
+
322
+ Contributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
323
+
324
+ Found a bug? Have a feature request? [Open an issue](https://github.com/Bigetion/windrunner/issues/new).
325
+
326
+ ## License
327
+
328
+ ISC