@syncedco/flow 0.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/CODE_OF_CONDUCT.md +26 -0
- package/CONTRIBUTING.md +54 -0
- package/LICENSE +21 -0
- package/README.md +334 -0
- package/SECURITY.md +30 -0
- package/SUPPORT.md +32 -0
- package/TRADEMARKS.md +14 -0
- package/base.css +100 -0
- package/bin/synced-flow.mjs +4639 -0
- package/components.css +1392 -0
- package/defaults.css +26 -0
- package/dist/config.d.ts +94 -0
- package/dist/config.js +3 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +67 -0
- package/docs/accessibility-css.md +133 -0
- package/docs/ai-usage.md +112 -0
- package/docs/api-contract.md +81 -0
- package/docs/base-styling.md +113 -0
- package/docs/build-a-site-walkthrough.md +122 -0
- package/docs/cli-reference.md +230 -0
- package/docs/config-reference.md +81 -0
- package/docs/css-optimisation.md +117 -0
- package/docs/migration-from-tailwind.md +60 -0
- package/docs/native-components.md +156 -0
- package/docs/patterns.md +32 -0
- package/docs/presets.md +60 -0
- package/docs/quick-start.md +252 -0
- package/docs/recipes.md +285 -0
- package/docs/release-readiness.md +63 -0
- package/docs/system-primitives.md +150 -0
- package/docs/tailwind-comparison.md +66 -0
- package/docs/tokens.md +79 -0
- package/docs/website-patterns.md +114 -0
- package/docs/why-synced-flow.md +99 -0
- package/docs/wordpress.md +66 -0
- package/examples/README.md +16 -0
- package/examples/astro/package.json +19 -0
- package/examples/astro/src/pages/index.astro +85 -0
- package/examples/astro/src/styles/synced-flow.css +2 -0
- package/examples/astro/src/styles/synced-flow.generated.css +206 -0
- package/examples/astro/synced-flow.config.mjs +9 -0
- package/examples/next/app/layout.tsx +14 -0
- package/examples/next/app/page.tsx +92 -0
- package/examples/next/app/synced-flow.css +2 -0
- package/examples/next/app/synced-flow.generated.css +205 -0
- package/examples/next/package.json +19 -0
- package/examples/next/synced-flow.config.mjs +9 -0
- package/examples/plain-html/index.html +384 -0
- package/examples/plain-html/package.json +15 -0
- package/examples/plain-html/synced-flow.config.mjs +9 -0
- package/examples/plain-html/synced-flow.css +2 -0
- package/examples/plain-html/synced-flow.generated.css +205 -0
- package/examples/templates/README.md +22 -0
- package/examples/templates/blog-index.html +41 -0
- package/examples/templates/coming-soon.html +27 -0
- package/examples/templates/portfolio-scroll.html +45 -0
- package/examples/templates/saas-dashboard.html +171 -0
- package/examples/templates/saas-landing.html +104 -0
- package/examples/vite/index.html +2 -0
- package/examples/vite/package.json +20 -0
- package/examples/vite/src/main.jsx +27 -0
- package/examples/vite/src/synced-flow.css +2 -0
- package/examples/vite/src/synced-flow.generated.css +205 -0
- package/examples/vite/synced-flow.config.mjs +9 -0
- package/examples/wordpress/assets/css/synced-flow.css +641 -0
- package/examples/wordpress/functions.php +13 -0
- package/examples/wordpress/package.json +15 -0
- package/examples/wordpress/parts/footer.html +12 -0
- package/examples/wordpress/parts/header.html +10 -0
- package/examples/wordpress/patterns/contact-cta.php +28 -0
- package/examples/wordpress/patterns/feature-grid.php +38 -0
- package/examples/wordpress/patterns/landing-hero.php +45 -0
- package/examples/wordpress/synced-flow.config.mjs +11 -0
- package/examples/wordpress/templates/front-page.html +11 -0
- package/examples/wordpress/templates/index.html +27 -0
- package/examples/wordpress/theme.json +19 -0
- package/layout.css +365 -0
- package/package.json +93 -0
- package/reset.css +13 -0
- package/skills/synced-flow/SKILL.md +151 -0
- package/src/config.ts +98 -0
- package/src/index.ts +75 -0
- package/src/presets.d.mts +21 -0
- package/src/presets.mjs +171 -0
- package/src/tokens.mjs +138 -0
- package/src/utility-tokens.mjs +47 -0
- package/styles.css +2313 -0
- package/tokens.css +198 -0
- package/utilities.css +255 -0
package/docs/recipes.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Recipes
|
|
2
|
+
|
|
3
|
+
These recipes are copy-ready starting points. They intentionally compose the
|
|
4
|
+
public API from [System primitives](system-primitives.md) and avoid one-off page
|
|
5
|
+
CSS.
|
|
6
|
+
|
|
7
|
+
## CLI Recipe Catalog
|
|
8
|
+
|
|
9
|
+
The CLI also ships page-level recipes for AI agents and template generators:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm exec synced-flow recipe
|
|
13
|
+
pnpm exec synced-flow recipe saas-landing --markup
|
|
14
|
+
pnpm exec synced-flow recipe saas-dashboard --framework next --markup
|
|
15
|
+
pnpm exec synced-flow recipe saas-landing --framework next --markup
|
|
16
|
+
pnpm exec synced-flow recipe --section form --framework astro --markup
|
|
17
|
+
pnpm exec synced-flow suggest "portfolio with full page scroll" --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Available recipe ids:
|
|
21
|
+
|
|
22
|
+
- `saas-landing`
|
|
23
|
+
- `saas-dashboard`
|
|
24
|
+
- `portfolio-scroll`
|
|
25
|
+
- `agency-home`
|
|
26
|
+
- `blog-index`
|
|
27
|
+
- `article-page`
|
|
28
|
+
- `about-timeline`
|
|
29
|
+
- `team-grid`
|
|
30
|
+
- `contact-page`
|
|
31
|
+
- `not-found`
|
|
32
|
+
- `coming-soon`
|
|
33
|
+
|
|
34
|
+
## Marketing Homepage
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<a class="sf-skip-link" href="#main">Skip to main content</a>
|
|
38
|
+
<header class="sf-container sf-repel" role="banner">
|
|
39
|
+
<a class="sf-link-plain sf-focus-ring" href="/">Acme Studio</a>
|
|
40
|
+
<nav class="sf-nav" aria-label="Primary">
|
|
41
|
+
<ul class="sf-nav__list">
|
|
42
|
+
<li><a class="sf-nav__link" href="#features" aria-current="page">Features</a></li>
|
|
43
|
+
<li><a class="sf-nav__link" href="#pricing">Pricing</a></li>
|
|
44
|
+
<li><a class="sf-nav__link" href="#contact">Contact</a></li>
|
|
45
|
+
</ul>
|
|
46
|
+
</nav>
|
|
47
|
+
</header>
|
|
48
|
+
|
|
49
|
+
<main id="main">
|
|
50
|
+
<section class="sf-hero">
|
|
51
|
+
<div class="sf-container sf-split">
|
|
52
|
+
<div class="sf-stack">
|
|
53
|
+
<p class="sf-kicker">Fluid by default</p>
|
|
54
|
+
<h1 class="sf-text-display">Launch a modern website without writing page CSS.</h1>
|
|
55
|
+
<p class="sf-text-lead sf-prose">Compose sections from tokens, layout primitives, patterns, and accessible form states.</p>
|
|
56
|
+
<div class="sf-cluster">
|
|
57
|
+
<a class="sf-button" href="#contact">Start a project</a>
|
|
58
|
+
<a class="sf-button sf-button--outline" href="#features">See features</a>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
<aside class="sf-surface sf-stack" aria-label="Included primitives">
|
|
62
|
+
<h2 class="sf-text-h4">Included</h2>
|
|
63
|
+
<ul class="sf-list-disc">
|
|
64
|
+
<li>Fluid type and spacing</li>
|
|
65
|
+
<li>Layout and website patterns</li>
|
|
66
|
+
<li>Buttons, forms, cards, and states</li>
|
|
67
|
+
</ul>
|
|
68
|
+
</aside>
|
|
69
|
+
</div>
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
<section class="sf-section" id="features">
|
|
73
|
+
<div class="sf-container sf-stack">
|
|
74
|
+
<header class="sf-section-header">
|
|
75
|
+
<p class="sf-kicker">Features</p>
|
|
76
|
+
<h2 class="sf-text-h2">Common sections are already covered.</h2>
|
|
77
|
+
</header>
|
|
78
|
+
<div class="sf-auto-grid">
|
|
79
|
+
<article class="sf-feature">
|
|
80
|
+
<span class="sf-feature__icon" aria-hidden="true">1</span>
|
|
81
|
+
<h3 class="sf-feature__title">Tokens</h3>
|
|
82
|
+
<p class="sf-feature__text">Use semantic colour, type, space, radius, shadow, and component variables.</p>
|
|
83
|
+
</article>
|
|
84
|
+
<article class="sf-feature">
|
|
85
|
+
<span class="sf-feature__icon" aria-hidden="true">2</span>
|
|
86
|
+
<h3 class="sf-feature__title">Patterns</h3>
|
|
87
|
+
<p class="sf-feature__text">Build proof, pricing, FAQ, CTA, and footer sections from named classes.</p>
|
|
88
|
+
</article>
|
|
89
|
+
<article class="sf-feature">
|
|
90
|
+
<span class="sf-feature__icon" aria-hidden="true">3</span>
|
|
91
|
+
<h3 class="sf-feature__title">States</h3>
|
|
92
|
+
<p class="sf-feature__text">Focus, current, invalid, disabled, busy, and forced-colors states are visible.</p>
|
|
93
|
+
</article>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
</main>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## SaaS Product Page
|
|
101
|
+
|
|
102
|
+
Use `saas-landing` for public marketing and product showcase pages.
|
|
103
|
+
Use `saas-dashboard` for authenticated SaaS app screens, portals, CRMs, admin
|
|
104
|
+
panels, and product workspaces.
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<main>
|
|
108
|
+
<section class="sf-section">
|
|
109
|
+
<div class="sf-container sf-stack">
|
|
110
|
+
<header class="sf-section-header">
|
|
111
|
+
<p class="sf-kicker">Product</p>
|
|
112
|
+
<h1 class="sf-text-h1">A calm operating layer for busy teams.</h1>
|
|
113
|
+
<p class="sf-text-lead sf-prose">Use the same primitives for landing pages, feature pages, and product-led flows.</p>
|
|
114
|
+
</header>
|
|
115
|
+
<div class="sf-logo-cloud" aria-label="Trusted by">
|
|
116
|
+
<span>Studio</span>
|
|
117
|
+
<span>Agency</span>
|
|
118
|
+
<span>Startup</span>
|
|
119
|
+
<span>Product</span>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="sf-stats">
|
|
122
|
+
<article class="sf-stat">
|
|
123
|
+
<strong class="sf-stat__value">0</strong>
|
|
124
|
+
<span class="sf-stat__label">Runtime dependencies</span>
|
|
125
|
+
</article>
|
|
126
|
+
<article class="sf-stat">
|
|
127
|
+
<strong class="sf-stat__value">1</strong>
|
|
128
|
+
<span class="sf-stat__label">Core import</span>
|
|
129
|
+
</article>
|
|
130
|
+
<article class="sf-stat">
|
|
131
|
+
<strong class="sf-stat__value">10.5 KB</strong>
|
|
132
|
+
<span class="sf-stat__label">Full core gzip size</span>
|
|
133
|
+
</article>
|
|
134
|
+
</div>
|
|
135
|
+
<blockquote class="sf-testimonial">
|
|
136
|
+
<p class="sf-testimonial__quote">"Synced Flow gives us enough structure without locking the brand down."</p>
|
|
137
|
+
<footer class="sf-testimonial__meta">Example product team</footer>
|
|
138
|
+
</blockquote>
|
|
139
|
+
</div>
|
|
140
|
+
</section>
|
|
141
|
+
</main>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## SaaS Dashboard And Auth State
|
|
145
|
+
|
|
146
|
+
This recipe is CSS and markup only. Authentication, sessions, permissions, and
|
|
147
|
+
providers belong to the consuming app.
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pnpm exec synced-flow recipe saas-dashboard --markup
|
|
151
|
+
pnpm exec synced-flow recipe saas-dashboard --framework next --markup
|
|
152
|
+
pnpm exec synced-flow suggest "SaaS dashboard with login and metrics"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The recipe includes:
|
|
156
|
+
|
|
157
|
+
- signed-out sign-in form
|
|
158
|
+
- signed-in sidebar account area with initials, role, settings, and sign-out
|
|
159
|
+
- Lucide-compatible inline SVG sidebar icons using `sf-icon`
|
|
160
|
+
- Generic account initials using `sf-avatar`
|
|
161
|
+
- Inline SVG and native meter analytics using `sf-chart` and `sf-meter`
|
|
162
|
+
- traditional SaaS app shell with persistent desktop navigation and a visible stacked mobile navigation rail
|
|
163
|
+
- KPI cards, theme-aware toolbar, filter/search form, customer table, and activity list
|
|
164
|
+
|
|
165
|
+
It uses Synced Flow primitives such as `sf-app-shell`, `sf-app-sidebar`,
|
|
166
|
+
`sf-app-main`, `sf-toolbar`, `sf-metric-grid`, `sf-panel-grid`, `sf-icon`,
|
|
167
|
+
`sf-chart`, `sf-chart--wide`, `sf-meter`, `sf-card`, `sf-form`, and
|
|
168
|
+
`sf-table-wrap`.
|
|
169
|
+
|
|
170
|
+
## Documentation Page
|
|
171
|
+
|
|
172
|
+
```html
|
|
173
|
+
<main class="sf-section">
|
|
174
|
+
<div class="sf-container sf-sidebar">
|
|
175
|
+
<aside class="sf-sidebar__sidebar" aria-label="Documentation navigation">
|
|
176
|
+
<nav class="sf-nav">
|
|
177
|
+
<ul class="sf-nav__list">
|
|
178
|
+
<li><a class="sf-nav__link" href="#install" aria-current="page">Install</a></li>
|
|
179
|
+
<li><a class="sf-nav__link" href="#tokens">Tokens</a></li>
|
|
180
|
+
<li><a class="sf-nav__link" href="#components">Components</a></li>
|
|
181
|
+
</ul>
|
|
182
|
+
</nav>
|
|
183
|
+
</aside>
|
|
184
|
+
<article class="sf-sidebar__content sf-prose">
|
|
185
|
+
<h1 id="install">Install Synced Flow</h1>
|
|
186
|
+
<p>Import the full stylesheet for the smallest setup path, or use modular layers when a project needs tighter control.</p>
|
|
187
|
+
<pre><code>@import "@syncedco/flow/styles.css";</code></pre>
|
|
188
|
+
<h2 id="tokens">Tokens</h2>
|
|
189
|
+
<p>Use <code>--sf-*</code> variables for stable project styling.</p>
|
|
190
|
+
<h2 id="components">Components</h2>
|
|
191
|
+
<p>Compose cards, buttons, forms, alerts, and website patterns from public <code>sf-*</code> classes.</p>
|
|
192
|
+
</article>
|
|
193
|
+
</div>
|
|
194
|
+
</main>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Contact Or Lead Form
|
|
198
|
+
|
|
199
|
+
```html
|
|
200
|
+
<section class="sf-section" id="contact">
|
|
201
|
+
<div class="sf-container sf-split">
|
|
202
|
+
<div class="sf-stack">
|
|
203
|
+
<p class="sf-kicker">Contact</p>
|
|
204
|
+
<h2 class="sf-text-h2">Collect a lead with accessible states included.</h2>
|
|
205
|
+
<p class="sf-prose">Labels, help text, required markers, invalid states, and submit buttons share the same token system.</p>
|
|
206
|
+
</div>
|
|
207
|
+
<form class="sf-card sf-form" action="#" method="post">
|
|
208
|
+
<div class="sf-field">
|
|
209
|
+
<label class="sf-required" for="name">Name</label>
|
|
210
|
+
<input class="sf-input" id="name" name="name" required aria-describedby="name-help" />
|
|
211
|
+
<p class="sf-help" id="name-help">Your name is required.</p>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="sf-field" data-invalid="true">
|
|
214
|
+
<label class="sf-required" for="email">Email</label>
|
|
215
|
+
<input class="sf-input" id="email" name="email" type="email" required aria-invalid="true" aria-describedby="email-help email-error" />
|
|
216
|
+
<p class="sf-help" id="email-help">Use a work email address.</p>
|
|
217
|
+
<p class="sf-error" id="email-error">Enter a valid email address.</p>
|
|
218
|
+
</div>
|
|
219
|
+
<button class="sf-button" type="submit">Send enquiry</button>
|
|
220
|
+
</form>
|
|
221
|
+
</div>
|
|
222
|
+
</section>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Lightweight App Shell
|
|
226
|
+
|
|
227
|
+
```html
|
|
228
|
+
<div class="sf-section sf-bg-surface-alt">
|
|
229
|
+
<div class="sf-container sf-stack">
|
|
230
|
+
<header class="sf-repel">
|
|
231
|
+
<div>
|
|
232
|
+
<p class="sf-kicker">Workspace</p>
|
|
233
|
+
<h1 class="sf-text-h2">Project dashboard</h1>
|
|
234
|
+
</div>
|
|
235
|
+
<button class="sf-button sf-button--secondary" type="button" aria-pressed="false">Filter</button>
|
|
236
|
+
</header>
|
|
237
|
+
<div class="sf-panel-grid">
|
|
238
|
+
<article class="sf-card">
|
|
239
|
+
<h2 class="sf-card__title">Pipeline</h2>
|
|
240
|
+
<p class="sf-card__description">Review the current work queue.</p>
|
|
241
|
+
</article>
|
|
242
|
+
<article class="sf-card">
|
|
243
|
+
<h2 class="sf-card__title">Messages</h2>
|
|
244
|
+
<p class="sf-card__description">Keep client updates visible.</p>
|
|
245
|
+
</article>
|
|
246
|
+
<article class="sf-alert sf-alert--info" role="status">
|
|
247
|
+
<p class="sf-alert__title">Sync complete</p>
|
|
248
|
+
<p>The workspace is up to date.</p>
|
|
249
|
+
</article>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Pricing And FAQ
|
|
256
|
+
|
|
257
|
+
```html
|
|
258
|
+
<section class="sf-section" id="pricing">
|
|
259
|
+
<div class="sf-container sf-stack">
|
|
260
|
+
<header class="sf-section-header">
|
|
261
|
+
<p class="sf-kicker">Pricing</p>
|
|
262
|
+
<h2 class="sf-text-h2">Commercial sections use the same primitives.</h2>
|
|
263
|
+
</header>
|
|
264
|
+
<div class="sf-pricing-grid">
|
|
265
|
+
<article class="sf-price-card">
|
|
266
|
+
<h3>Starter</h3>
|
|
267
|
+
<p class="sf-price"><span class="sf-price__value">£0</span> <span class="sf-price__interval">prototype</span></p>
|
|
268
|
+
<a class="sf-button sf-button--outline" href="/start">Try it</a>
|
|
269
|
+
</article>
|
|
270
|
+
<article class="sf-price-card sf-price-card--featured">
|
|
271
|
+
<p class="sf-badge">Most useful</p>
|
|
272
|
+
<h3>Website</h3>
|
|
273
|
+
<p class="sf-price"><span class="sf-price__value">£49</span> <span class="sf-price__interval">project</span></p>
|
|
274
|
+
<a class="sf-button" href="/start">Start</a>
|
|
275
|
+
</article>
|
|
276
|
+
</div>
|
|
277
|
+
<div class="sf-faq">
|
|
278
|
+
<details class="sf-faq__item">
|
|
279
|
+
<summary>Can I customize the theme?</summary>
|
|
280
|
+
<p>Yes. Override semantic tokens before writing custom CSS.</p>
|
|
281
|
+
</details>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</section>
|
|
285
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Release Readiness
|
|
2
|
+
|
|
3
|
+
Use this checklist before tagging or publishing Synced Flow.
|
|
4
|
+
|
|
5
|
+
## Lean Package Checks
|
|
6
|
+
|
|
7
|
+
- `package.json` has no runtime dependencies.
|
|
8
|
+
- `styles.css` stays below the gzip budget in `scripts/guardrails.mjs`.
|
|
9
|
+
- `components.css`, `layout.css`, `utilities.css`, and `tokens.css` stay below
|
|
10
|
+
their gzip budgets.
|
|
11
|
+
- New CSS uses existing tokens before introducing new variables.
|
|
12
|
+
- New classes are broad primitives or common website patterns, not project
|
|
13
|
+
one-offs.
|
|
14
|
+
|
|
15
|
+
## CSS System Checks
|
|
16
|
+
|
|
17
|
+
- Type and spacing use Utopia-style `clamp()` tokens.
|
|
18
|
+
- Fixed dimensions use `rem`.
|
|
19
|
+
- Raw `px` appears only for allowed hairlines or forced-colors fallbacks.
|
|
20
|
+
- Reset, base, app, layout, components, and utilities remain separate layer
|
|
21
|
+
files.
|
|
22
|
+
- `styles.css` is generated from the same layer sources and does not duplicate
|
|
23
|
+
reset/base content.
|
|
24
|
+
|
|
25
|
+
## Accessibility Confidence Pass
|
|
26
|
+
|
|
27
|
+
Synced Flow does not run audits for consuming projects, but the package should
|
|
28
|
+
keep the CSS affordances in place.
|
|
29
|
+
|
|
30
|
+
- Keyboard focus is visible on links, buttons, form fields, summaries, and
|
|
31
|
+
skip links.
|
|
32
|
+
- `aria-current`, `aria-expanded`, `aria-pressed`, `aria-selected`,
|
|
33
|
+
`aria-disabled`, `aria-busy`, and `aria-invalid` have visible states where
|
|
34
|
+
the system provides matching primitives.
|
|
35
|
+
- Native disabled, required, invalid, `details[open]`, and `:target` states are
|
|
36
|
+
styled.
|
|
37
|
+
- Forced-colors fallbacks keep borders and focus outlines visible.
|
|
38
|
+
- `prefers-reduced-motion` is respected by the base styles.
|
|
39
|
+
- Examples use semantic landmarks, real buttons, real links, labels, help text,
|
|
40
|
+
and native disclosure controls.
|
|
41
|
+
|
|
42
|
+
## Documentation Checks
|
|
43
|
+
|
|
44
|
+
- README points to the main docs.
|
|
45
|
+
- Quick start explains the import choices.
|
|
46
|
+
- System primitives lists current tokens/classes.
|
|
47
|
+
- CSS API contract explains public vs internal surfaces.
|
|
48
|
+
- Recipes show how to build common pages without one-off CSS.
|
|
49
|
+
- CSS optimisation docs include current measured sizes.
|
|
50
|
+
|
|
51
|
+
## Commands
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pnpm build
|
|
55
|
+
pnpm check
|
|
56
|
+
pnpm test
|
|
57
|
+
node bin/synced-flow.mjs tokens --json
|
|
58
|
+
node bin/synced-flow.mjs catalog --json
|
|
59
|
+
node bin/synced-flow.mjs doctor --cwd examples/plain-html
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
If a browser-visible example changes, inspect it at mobile and desktop widths
|
|
63
|
+
before calling the release ready.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# System Primitives
|
|
2
|
+
|
|
3
|
+
Synced Flow is meant to cover the common styling decisions needed for a basic
|
|
4
|
+
modern website before a developer reaches for project-specific CSS.
|
|
5
|
+
|
|
6
|
+
## Token Layers
|
|
7
|
+
|
|
8
|
+
Use the `--sf-*` variables as the stable CSS foundation.
|
|
9
|
+
|
|
10
|
+
| Layer | Examples | Use for |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Font | `--sf-font-sans`, `--sf-font-display`, `--sf-font-mono` | Site typography families. |
|
|
13
|
+
| Type | `--sf-type-body`, `--sf-type-lead`, `--sf-type-h1`, `--sf-type-display` | Fluid text sizes. |
|
|
14
|
+
| Space | `--sf-space-s`, `--sf-space-m-l`, `--sf-space-xl-2xl` | Fluid padding, margin, and gaps. |
|
|
15
|
+
| Radius | `--sf-radius-control`, `--sf-radius-panel`, `--sf-radius-full` | Controls, panels, pills. |
|
|
16
|
+
| Colour | `--sf-colour-background`, `--sf-colour-surface`, `--sf-colour-primary` | Semantic UI colour roles. |
|
|
17
|
+
| State | `--sf-colour-success`, `--sf-colour-warning`, `--sf-colour-danger`, `--sf-colour-info` | Feedback and notices. |
|
|
18
|
+
| Motion | `--sf-duration-fast`, `--sf-duration-normal`, `--sf-ease-standard` | Consistent transitions. |
|
|
19
|
+
| Component | `--sf-button-*`, `--sf-card-*`, `--sf-input-*`, `--sf-alert-*` | Reusable component defaults. |
|
|
20
|
+
| Accessibility | `:focus-visible`, `:target`, `[aria-invalid]`, `[aria-current]`, `[aria-expanded]`, `[aria-selected]`, `[aria-busy]`, `[aria-disabled]` | Visible native and ARIA states. |
|
|
21
|
+
|
|
22
|
+
Light and dark modes can be applied with `.sf-theme-light`,
|
|
23
|
+
`[data-sf-theme="light"]`, `.sf-theme-dark`, or `[data-sf-theme="dark"]`.
|
|
24
|
+
|
|
25
|
+
## Layout Classes
|
|
26
|
+
|
|
27
|
+
These classes are the first choice for page structure.
|
|
28
|
+
|
|
29
|
+
| Class | Purpose |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `sf-container` | Fluid max-width wrapper with tokenized gutters. |
|
|
32
|
+
| `sf-container--narrow`, `sf-container--wide`, `sf-container--full` | Container width variants. |
|
|
33
|
+
| `sf-section`, `sf-section--compact`, `sf-section--spacious` | Vertical section rhythm. |
|
|
34
|
+
| `sf-stack`, `sf-stack--tight`, `sf-stack--loose` | Vertical spacing between children. |
|
|
35
|
+
| `sf-flow` | Adds block flow spacing between prose-like children. |
|
|
36
|
+
| `sf-cluster` | Wrapping inline groups such as actions or tags. |
|
|
37
|
+
| `sf-repel` | Space-between layout that wraps safely. |
|
|
38
|
+
| `sf-toolbar` | Dense app/page toolbar that wraps actions safely. |
|
|
39
|
+
| `sf-app-shell`, `sf-app-sidebar`, `sf-app-sidebar__brand`, `sf-app-main` | Product app shell with persistent sidebar and main workspace. |
|
|
40
|
+
| `sf-split` | Responsive two-column layout. |
|
|
41
|
+
| `sf-split--reverse` | Reverses split layout visual order. |
|
|
42
|
+
| `sf-auto-grid`, `sf-panel-grid`, `sf-metric-grid`, `sf-pipeline` | Responsive card, metric, and operational grids. |
|
|
43
|
+
| `sf-frame`, `sf-frame--square`, `sf-frame--portrait`, `sf-frame--wide` | Stable media aspect ratios. |
|
|
44
|
+
| `sf-cover`, `sf-hero` | Full-height and hero section structure. |
|
|
45
|
+
| `sf-scroll-viewport`, `sf-scroll-panel`, `sf-scroll-snap-y`, `sf-sticky-top`, `sf-media-object`, `sf-aside-rail` | Scroll, sticky, and intent-based layout modes. |
|
|
46
|
+
|
|
47
|
+
## Component Classes
|
|
48
|
+
|
|
49
|
+
These cover the common UI elements needed for a simple site.
|
|
50
|
+
|
|
51
|
+
| Class | Purpose |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `sf-button` | Base button/link button. |
|
|
54
|
+
| `sf-button--default`, `sf-button--secondary`, `sf-button--outline`, `sf-button--ghost`, `sf-button--link`, `sf-button--destructive` | Button variants. |
|
|
55
|
+
| `sf-button--sm`, `sf-button--lg`, `sf-button--icon`, `sf-icon-button`, `sf-button--block` | Button sizing and width. |
|
|
56
|
+
| `sf-button-group` | Wrapped action group. |
|
|
57
|
+
| `sf-icon`, `sf-icon--xs`, `sf-icon--sm`, `sf-icon--md`, `sf-icon--lg`, `sf-icon--xl` | Fluid, currentColor SVG icon sizing for Lucide, Heroicons, Bootstrap Icons, or inline SVG. |
|
|
58
|
+
| `sf-card`, `sf-card--flat`, `sf-card--raised`, `sf-card--interactive` | Card surfaces. |
|
|
59
|
+
| `sf-card__header`, `sf-card__body`, `sf-card__footer`, `sf-card__title`, `sf-card__description` | Card structure. |
|
|
60
|
+
| `sf-surface`, `sf-surface--alt`, `sf-surface--raised` | Generic reusable panels. |
|
|
61
|
+
| `sf-logo-cloud`, `sf-feature`, `sf-stats`, `sf-testimonial`, `sf-pricing-grid`, `sf-faq`, `sf-cta`, `sf-footer` | Common website patterns. |
|
|
62
|
+
| `sf-nav`, `sf-nav__list`, `sf-nav__link` | Navigation basics. |
|
|
63
|
+
| `sf-nav--mobile`, `sf-menu`, `sf-breadcrumb`, `sf-pagination` | Mobile, menu, breadcrumb, and paginated navigation. |
|
|
64
|
+
| `sf-dialog`, `sf-dialog__header`, `sf-dialog__body`, `sf-dialog__footer` | Native `<dialog>` styling. |
|
|
65
|
+
| `sf-popover`, `sf-tooltip`, `sf-tooltip-trigger`, `sf-menu-popover`, `sf-toast`, `sf-banner`, `sf-drawer` | Popover-backed native overlays. |
|
|
66
|
+
| `sf-disclosure`, `sf-accordion` | Native `details`/`summary` disclosure patterns. |
|
|
67
|
+
| `sf-tabs`, `sf-tab-list`, `sf-tab`, `sf-tab-panel` | HTML/CSS-first tab styling. |
|
|
68
|
+
| `sf-form`, `sf-fieldset`, `sf-field`, `sf-label`, `sf-help`, `sf-error` | Form structure and messaging. |
|
|
69
|
+
| `sf-input`, `sf-select`, `sf-textarea`, `sf-check` | Form controls. |
|
|
70
|
+
| `sf-alert`, `sf-alert--info`, `sf-alert--success`, `sf-alert--warning`, `sf-alert--danger`, `sf-alert__title` | Notices and feedback. |
|
|
71
|
+
| `sf-section-header`, `sf-kicker`, `sf-badge`, `sf-avatar` | Common marketing/content and account patterns. |
|
|
72
|
+
| `sf-chart`, `sf-chart__plot`, `sf-chart__svg`, `sf-chart__legend`, `sf-meter-list`, `sf-meter` | Lightweight chart shells for app-owned SVG charts and native meter bars. |
|
|
73
|
+
|
|
74
|
+
## Utility Classes
|
|
75
|
+
|
|
76
|
+
Use utility classes for small decisions that do not need a new component.
|
|
77
|
+
|
|
78
|
+
| Class | Purpose |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `sf-text-caption`, `sf-text-body`, `sf-text-lead`, `sf-text-h4`, `sf-text-h3`, `sf-text-h2`, `sf-text-h1`, `sf-text-display` | Fluid text scale. |
|
|
81
|
+
| `sf-text-muted`, `sf-text-subtle`, `sf-text-primary`, `sf-text-success`, `sf-text-warning`, `sf-text-danger` | Semantic text colour. |
|
|
82
|
+
| `sf-bg-background`, `sf-bg-surface`, `sf-bg-surface-alt`, `sf-bg-primary-soft`, `sf-bg-success-soft`, `sf-bg-warning-soft`, `sf-bg-danger-soft` | Semantic backgrounds. |
|
|
83
|
+
| `sf-border`, `sf-border-strong`, `sf-rounded`, `sf-rounded-panel`, `sf-rounded-full` | Border and radius helpers. |
|
|
84
|
+
| `sf-shadow-sm`, `sf-shadow-md`, `sf-shadow-lg`, `sf-shadow-none` | Shadow helpers. |
|
|
85
|
+
| `sf-push-block-end`, `sf-push-block-start`, `sf-push-inline-end`, `sf-push-inline-start` | Auto-margin positioning helpers for pushing items to an edge inside flex/grid layouts. |
|
|
86
|
+
| `sf-prose`, `sf-text-balance`, `sf-text-pretty` | Content width and wrapping helpers. |
|
|
87
|
+
| `sf-prose--blog`, `sf-prose--legal`, `sf-meta`, `sf-figure`, `sf-caption`, `sf-table-wrap` | Long-form content and article helpers. |
|
|
88
|
+
| `sf-link`, `sf-link-subtle`, `sf-link-plain` | Link treatments. |
|
|
89
|
+
| `sf-list-reset`, `sf-list-disc`, `sf-list-decimal` | List treatments. |
|
|
90
|
+
| `sf-skip-link`, `sf-focus-ring`, `sf-focus-ring-inset`, `sf-touch-target`, `sr-only`, `not-sr-only` | Accessibility helpers. |
|
|
91
|
+
| `sf-animate-fade`, `sf-animate-rise`, `sf-animate-scale`, `sf-animate-slide`, `sf-animate-stagger` | Reduced-motion-safe motion primitives. |
|
|
92
|
+
|
|
93
|
+
## Example
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<button class="sf-button">
|
|
97
|
+
<svg class="sf-icon" aria-hidden="true" viewBox="0 0 24 24">...</svg>
|
|
98
|
+
Settings
|
|
99
|
+
</button>
|
|
100
|
+
|
|
101
|
+
<button class="sf-button sf-button--ghost sf-icon-button" aria-label="Settings">
|
|
102
|
+
<svg class="sf-icon sf-icon--lg" aria-hidden="true" viewBox="0 0 24 24">...</svg>
|
|
103
|
+
</button>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { Settings } from "lucide-react"
|
|
108
|
+
|
|
109
|
+
export function SettingsButton() {
|
|
110
|
+
return (
|
|
111
|
+
<button className="sf-button">
|
|
112
|
+
<Settings className="sf-icon" aria-hidden="true" />
|
|
113
|
+
Settings
|
|
114
|
+
</button>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<section class="sf-section">
|
|
121
|
+
<div class="sf-container sf-split">
|
|
122
|
+
<div class="sf-stack">
|
|
123
|
+
<p class="sf-badge">Fluid by default</p>
|
|
124
|
+
<h1 class="sf-text-display">Build from reusable CSS primitives.</h1>
|
|
125
|
+
<p class="sf-text-lead sf-text-muted sf-prose">
|
|
126
|
+
Start with tokens, layout classes, and components before writing custom CSS.
|
|
127
|
+
</p>
|
|
128
|
+
<div class="sf-button-group">
|
|
129
|
+
<a class="sf-button sf-button--default" href="/contact">Start a project</a>
|
|
130
|
+
<a class="sf-button sf-button--outline" href="/docs">Read docs</a>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<form class="sf-surface sf-form">
|
|
135
|
+
<div class="sf-field">
|
|
136
|
+
<label for="email">Email</label>
|
|
137
|
+
<input class="sf-input" id="email" type="email" />
|
|
138
|
+
</div>
|
|
139
|
+
<button class="sf-button sf-button--block" type="submit">Send</button>
|
|
140
|
+
</form>
|
|
141
|
+
</div>
|
|
142
|
+
</section>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
See `examples/plain-html` for a complete page using the same primitives.
|
|
146
|
+
|
|
147
|
+
For copy-ready section patterns, see [Website patterns](website-patterns.md).
|
|
148
|
+
For native browser component patterns, see [Native Components](native-components.md).
|
|
149
|
+
For accessibility state hooks, see [Accessibility CSS](accessibility-css.md).
|
|
150
|
+
For public API stability rules, see [CSS API Contract](api-contract.md).
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Tailwind Migration Context
|
|
2
|
+
|
|
3
|
+
Tailwind CSS is referenced here only to help teams migrate existing projects.
|
|
4
|
+
Synced Flow is an independent fluid CSS system, not a Tailwind copy,
|
|
5
|
+
compatibility layer, or one-for-one feature replacement.
|
|
6
|
+
|
|
7
|
+
## Developer Expectations During Migration
|
|
8
|
+
|
|
9
|
+
Teams coming from Tailwind often expect a short install flow, a CLI, generated
|
|
10
|
+
CSS from source files, clear framework setup, safelisting for dynamic class
|
|
11
|
+
names, and setup diagnostics. Synced Flow supports those expectations while
|
|
12
|
+
using its own fluid, token-led styling model.
|
|
13
|
+
|
|
14
|
+
| Migration expectation | Synced Flow direction |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| Install a package, import one stylesheet, start building | `pnpm add @syncedco/flow`, `synced-flow init`, import the generated CSS entry |
|
|
17
|
+
| CLI builds CSS from scanned source files | `synced-flow build` scans configured project folders and writes generated utility CSS |
|
|
18
|
+
| Framework-specific setup docs | `synced-flow init --preset next/vite/astro/plain` |
|
|
19
|
+
| Theme variables as the styling API | CSS custom properties in `@syncedco/flow/styles.css` plus project overrides |
|
|
20
|
+
| Source registration and monorepo-friendly paths | `scan` and `cwd` config options |
|
|
21
|
+
| Safelisting for dynamic class names | `safelist` config option and `--safelist` CLI flag |
|
|
22
|
+
| Setup diagnostics | `synced-flow doctor` |
|
|
23
|
+
|
|
24
|
+
## How Synced Flow Differs
|
|
25
|
+
|
|
26
|
+
Synced Flow starts with a fluid design system rather than a breakpoint-first
|
|
27
|
+
utility framework. New projects keep `responsiveVariants` off, then use fluid
|
|
28
|
+
type, spacing, layout primitives, and container-aware component CSS.
|
|
29
|
+
|
|
30
|
+
For CSS size, Synced Flow favours modular layer imports and source-scanned
|
|
31
|
+
utility generation rather than shipping a large universal utility file. See
|
|
32
|
+
[CSS optimisation](css-optimisation.md) for current size measurements and
|
|
33
|
+
marketing-safe claims.
|
|
34
|
+
|
|
35
|
+
Responsive variants such as `sm:` and `lg:` are available only as an explicit
|
|
36
|
+
migration option:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
export default defineConfig({
|
|
40
|
+
scan: ['app', 'components', 'lib'],
|
|
41
|
+
out: 'app/synced-flow.generated.css',
|
|
42
|
+
responsiveVariants: true,
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Migration Docs Should Keep
|
|
47
|
+
|
|
48
|
+
- `init` should get a project compiling quickly.
|
|
49
|
+
- `build --check` should fail CI when generated CSS is stale.
|
|
50
|
+
- `doctor` should explain missing imports, config, scripts, and stale setup.
|
|
51
|
+
- Docs should show copy-pasteable install paths for common frameworks.
|
|
52
|
+
- Scanner docs must clearly explain dynamic class limits.
|
|
53
|
+
- Token docs should show the primitive, semantic, and component layers.
|
|
54
|
+
|
|
55
|
+
## References For Migration Planning
|
|
56
|
+
|
|
57
|
+
- Tailwind's Vite guide shows the value of a short install/import/start flow:
|
|
58
|
+
https://tailwindcss.com/docs/installation/using-vite
|
|
59
|
+
- Tailwind's CLI guide shows the expected build/watch mental model:
|
|
60
|
+
https://tailwindcss.com/docs/installation/tailwind-cli
|
|
61
|
+
- Tailwind's source detection docs explain scanner behaviour, explicit source
|
|
62
|
+
paths, and safelisting:
|
|
63
|
+
https://tailwindcss.com/docs/detecting-classes-in-source-files
|
|
64
|
+
- Tailwind's theme variable docs show why tokens should be the public styling
|
|
65
|
+
API:
|
|
66
|
+
https://tailwindcss.com/docs/theme
|
package/docs/tokens.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Tokens Guide
|
|
2
|
+
|
|
3
|
+
Synced Flow uses a three-layer token model.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
Primitive -> Semantic -> Component
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Primitive
|
|
10
|
+
|
|
11
|
+
Primitive tokens hold raw design values.
|
|
12
|
+
|
|
13
|
+
```css
|
|
14
|
+
--sf-colour-orange-600: oklch(68% 0.18 44);
|
|
15
|
+
--sf-radius-md: 0.5rem;
|
|
16
|
+
--sf-font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Semantic
|
|
20
|
+
|
|
21
|
+
Semantic tokens describe intent.
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
--sf-colour-background: var(--sf-colour-neutral-50);
|
|
25
|
+
--sf-colour-foreground: var(--sf-colour-neutral-900);
|
|
26
|
+
--sf-colour-primary: var(--sf-colour-orange-600);
|
|
27
|
+
--sf-colour-surface-raised: var(--sf-colour-neutral-0);
|
|
28
|
+
--sf-colour-success-soft: oklch(62% 0.13 150 / 0.12);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Use semantic utilities in projects:
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<section class="bg-background text-foreground">
|
|
35
|
+
<a class="sf-button sf-button--default">Book a call</a>
|
|
36
|
+
</section>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Component
|
|
40
|
+
|
|
41
|
+
Component tokens define reusable component defaults.
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
--sf-button-radius: var(--sf-radius-md);
|
|
45
|
+
--sf-button-block-size: 2.75rem;
|
|
46
|
+
--sf-card-padding: var(--sf-space-m-l);
|
|
47
|
+
--sf-input-padding-inline: var(--sf-space-s);
|
|
48
|
+
--sf-alert-padding: var(--sf-space-s-m);
|
|
49
|
+
--sf-nav-gap: var(--sf-space-xs-s);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Fluid Scale
|
|
53
|
+
|
|
54
|
+
Type and space tokens use Utopia-style `clamp()` values.
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
--sf-step-0: clamp(1rem, 0.9617rem + 0.1701vw, 1.125rem);
|
|
58
|
+
--sf-space-s-l: clamp(1rem, 0.6173rem + 1.7007vw, 2.25rem);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Prefer these tokens for new project CSS instead of fixed pixel values.
|
|
62
|
+
|
|
63
|
+
## Core Starter Tokens
|
|
64
|
+
|
|
65
|
+
The generated core includes enough semantic variables for common website UI:
|
|
66
|
+
|
|
67
|
+
- surfaces: `--sf-colour-background`, `--sf-colour-surface`,
|
|
68
|
+
`--sf-colour-surface-alt`, `--sf-colour-surface-raised`,
|
|
69
|
+
`--sf-colour-surface-inset`
|
|
70
|
+
- text and links: `--sf-colour-foreground`, `--sf-colour-muted`,
|
|
71
|
+
`--sf-colour-subtle`, `--sf-colour-link`, `--sf-colour-link-hover`
|
|
72
|
+
- actions: `--sf-colour-primary`, `--sf-colour-primary-hover`,
|
|
73
|
+
`--sf-colour-primary-foreground`, `--sf-colour-primary-soft`
|
|
74
|
+
- state feedback: `--sf-colour-success`, `--sf-colour-warning`,
|
|
75
|
+
`--sf-colour-danger`, `--sf-colour-info`, plus matching soft variants
|
|
76
|
+
- structure: `--sf-colour-border`, `--sf-colour-border-strong`,
|
|
77
|
+
`--sf-radius-control`, `--sf-radius-panel`, `--sf-shadow-*`
|
|
78
|
+
|
|
79
|
+
For class-level usage, see [System primitives](system-primitives.md).
|