@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
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Website Patterns
|
|
2
|
+
|
|
3
|
+
Synced Flow pattern classes cover common website sections without turning the
|
|
4
|
+
system into a large utility framework. Use them as semantic building blocks, then
|
|
5
|
+
override tokens for brand-specific decisions.
|
|
6
|
+
|
|
7
|
+
## Pattern Classes
|
|
8
|
+
|
|
9
|
+
| Class | Purpose |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `sf-logo-cloud` | Wraps partner, client, or integration names/logos. |
|
|
12
|
+
| `sf-feature`, `sf-feature__icon`, `sf-feature__title`, `sf-feature__text` | Feature or benefit blocks. |
|
|
13
|
+
| `sf-stats`, `sf-stat`, `sf-stat__value`, `sf-stat__label` | Metric and proof sections. |
|
|
14
|
+
| `sf-testimonial`, `sf-testimonial__quote`, `sf-testimonial__meta` | Customer quote blocks. |
|
|
15
|
+
| `sf-pricing-grid`, `sf-price-card`, `sf-price`, `sf-price__value`, `sf-price__interval` | Pricing sections. |
|
|
16
|
+
| `sf-faq`, `sf-faq__item` | Native `details`/`summary` FAQ sections. |
|
|
17
|
+
| `sf-cta` | Call-to-action block. Add `data-layout="split"` for a two-column CTA when space allows. |
|
|
18
|
+
| `sf-footer` | Footer region with tokenized spacing and top border. |
|
|
19
|
+
|
|
20
|
+
These patterns are intentionally broad. They provide enough structure for a
|
|
21
|
+
developer to ship a normal website while leaving project-specific visual details
|
|
22
|
+
to semantic tokens and local CSS.
|
|
23
|
+
|
|
24
|
+
## Feature Grid
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<section class="sf-section">
|
|
28
|
+
<div class="sf-container sf-stack sf-stack--loose">
|
|
29
|
+
<div class="sf-section-header">
|
|
30
|
+
<p class="sf-kicker">Features</p>
|
|
31
|
+
<h2>Reusable sections without page CSS.</h2>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div class="sf-auto-grid">
|
|
35
|
+
<article class="sf-feature">
|
|
36
|
+
<span class="sf-feature__icon" aria-hidden="true">1</span>
|
|
37
|
+
<h3 class="sf-feature__title">Fluid defaults</h3>
|
|
38
|
+
<p class="sf-feature__text">Type, spacing, and surfaces adapt from shared tokens.</p>
|
|
39
|
+
</article>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</section>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Proof Section
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<div class="sf-logo-cloud" aria-label="Trusted by">
|
|
49
|
+
<span>Studio</span>
|
|
50
|
+
<span>Agency</span>
|
|
51
|
+
<span>Startup</span>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="sf-stats">
|
|
55
|
+
<div class="sf-stat">
|
|
56
|
+
<p class="sf-stat__value">10.5 KB</p>
|
|
57
|
+
<p class="sf-stat__label">Full core gzip size</p>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<figure class="sf-testimonial">
|
|
62
|
+
<blockquote class="sf-testimonial__quote">"Custom CSS is reserved for brand moments."</blockquote>
|
|
63
|
+
<figcaption class="sf-testimonial__meta">Example client</figcaption>
|
|
64
|
+
</figure>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Pricing And FAQ
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<div class="sf-pricing-grid">
|
|
71
|
+
<article class="sf-price-card sf-price-card--featured">
|
|
72
|
+
<p class="sf-badge">Most useful</p>
|
|
73
|
+
<h3 class="sf-card__title">Website</h3>
|
|
74
|
+
<div class="sf-price">
|
|
75
|
+
<span class="sf-price__value">£49</span>
|
|
76
|
+
<span class="sf-price__interval">project</span>
|
|
77
|
+
</div>
|
|
78
|
+
<p class="sf-card__description">Patterns, docs, and examples for a complete site.</p>
|
|
79
|
+
<a class="sf-button sf-button--default sf-button--block" href="/contact">Start</a>
|
|
80
|
+
</article>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div class="sf-faq">
|
|
84
|
+
<details class="sf-faq__item">
|
|
85
|
+
<summary>Is this a Tailwind replacement?</summary>
|
|
86
|
+
<p>No. Synced Flow uses named primitives and patterns for common website work.</p>
|
|
87
|
+
</details>
|
|
88
|
+
</div>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## CTA And Footer
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<section class="sf-section">
|
|
95
|
+
<div class="sf-container">
|
|
96
|
+
<div class="sf-cta" data-layout="split">
|
|
97
|
+
<div class="sf-stack sf-stack--tight">
|
|
98
|
+
<h2>Ready to build?</h2>
|
|
99
|
+
<p class="sf-text-muted">Start with patterns, then customize tokens.</p>
|
|
100
|
+
</div>
|
|
101
|
+
<a class="sf-button" href="/contact">Start a project</a>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</section>
|
|
105
|
+
|
|
106
|
+
<footer class="sf-footer">
|
|
107
|
+
<div class="sf-container sf-repel">
|
|
108
|
+
<p class="sf-text-caption">Synced Flow</p>
|
|
109
|
+
<a class="sf-link" href="#main">Back to top</a>
|
|
110
|
+
</div>
|
|
111
|
+
</footer>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
See `examples/plain-html` for the complete website demo.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Why Synced Flow?
|
|
2
|
+
|
|
3
|
+
AI can build front ends quickly. The harder problem is keeping those front ends consistent once a project has more than one page, one template, one developer, or one coding agent.
|
|
4
|
+
|
|
5
|
+
Synced Flow exists for that gap.
|
|
6
|
+
|
|
7
|
+
It gives humans and AI coding agents a shared CSS contract: tokens, fluid scales, layout primitives, website recipes, accessibility defaults, and CLI checks that keep the work inside the system.
|
|
8
|
+
|
|
9
|
+
## The problem
|
|
10
|
+
|
|
11
|
+
Most websites do not become inconsistent all at once.
|
|
12
|
+
|
|
13
|
+
They drift.
|
|
14
|
+
|
|
15
|
+
One section gets a custom spacing value. Another gets a one-off colour. A third gets a breakpoint patch because the first two nearly worked. AI-assisted development can make that drift happen faster because it is very good at generating plausible CSS.
|
|
16
|
+
|
|
17
|
+
Plausible is not the same as systemised.
|
|
18
|
+
|
|
19
|
+
Synced Flow is designed to reduce the number of styling decisions made from scratch during a build.
|
|
20
|
+
|
|
21
|
+
## The position
|
|
22
|
+
|
|
23
|
+
Synced Flow is not trying to be a Tailwind clone, a Bootstrap replacement, or a React component library.
|
|
24
|
+
|
|
25
|
+
It is an AI-native fluid CSS design system for brand-consistent websites and agency builds.
|
|
26
|
+
|
|
27
|
+
Use it when you want:
|
|
28
|
+
|
|
29
|
+
- fluid type and spacing before breakpoint patches
|
|
30
|
+
- brand tokens before one-off colours
|
|
31
|
+
- layout primitives before custom wrappers
|
|
32
|
+
- accessible defaults before decorative resets
|
|
33
|
+
- source-scanned utilities before shipping a large universal stylesheet
|
|
34
|
+
- project-local agent guidance before asking AI to guess the styling rules
|
|
35
|
+
|
|
36
|
+
## What it gives an AI coding agent
|
|
37
|
+
|
|
38
|
+
Most CSS frameworks document for humans. Synced Flow also gives coding agents a discoverable styling contract.
|
|
39
|
+
|
|
40
|
+
Useful surfaces include:
|
|
41
|
+
|
|
42
|
+
- `catalog --json` for machine-readable class and token discovery
|
|
43
|
+
- `suggest` for finding matching primitives and recipes
|
|
44
|
+
- `recipe` and `pattern` for generating known page sections
|
|
45
|
+
- `lint` for spotting drift from the system
|
|
46
|
+
- `doctor` for setup checks
|
|
47
|
+
- `agents install` for adding project-local AI guidance
|
|
48
|
+
- a packaged Synced Flow skill for coding agents that support skill files
|
|
49
|
+
|
|
50
|
+
The result is not magic. It is constraint.
|
|
51
|
+
|
|
52
|
+
The agent gets fewer opportunities to invent a second design system inside the first one.
|
|
53
|
+
|
|
54
|
+
## What it gives agencies
|
|
55
|
+
|
|
56
|
+
Agencies need systems that work across real client projects, not just React demos.
|
|
57
|
+
|
|
58
|
+
Synced Flow supports:
|
|
59
|
+
|
|
60
|
+
- WordPress themes and plugins
|
|
61
|
+
- PHP and template scanning
|
|
62
|
+
- enqueue-ready CSS output
|
|
63
|
+
- Next
|
|
64
|
+
- Astro
|
|
65
|
+
- Vite
|
|
66
|
+
- plain HTML
|
|
67
|
+
- reusable website patterns
|
|
68
|
+
|
|
69
|
+
That makes it useful for brand-led websites, local business sites, campaign pages, portfolios, SaaS landing pages, and agency delivery systems.
|
|
70
|
+
|
|
71
|
+
## What it gives developers
|
|
72
|
+
|
|
73
|
+
Synced Flow gives developers a practical CSS foundation with modern defaults:
|
|
74
|
+
|
|
75
|
+
- CSS custom properties
|
|
76
|
+
- cascade layers
|
|
77
|
+
- OKLCH colour tokens
|
|
78
|
+
- `clamp()` based fluid scales
|
|
79
|
+
- logical properties
|
|
80
|
+
- container-aware layout primitives
|
|
81
|
+
- reduced-motion safeguards
|
|
82
|
+
- visible focus states
|
|
83
|
+
- modular CSS exports
|
|
84
|
+
- generated utilities based on real project usage
|
|
85
|
+
|
|
86
|
+
You can import the full stylesheet for speed, or import only the layers a project needs.
|
|
87
|
+
|
|
88
|
+
## Comparison in one line
|
|
89
|
+
|
|
90
|
+
- Tailwind gives you utilities.
|
|
91
|
+
- Bootstrap gives you a complete responsive toolkit.
|
|
92
|
+
- shadcn/ui gives you owned components.
|
|
93
|
+
- Synced Flow gives you an owned, fluid, agent-readable CSS system for brand-consistent websites.
|
|
94
|
+
|
|
95
|
+
## The practical promise
|
|
96
|
+
|
|
97
|
+
Build quickly without handing every spacing, colour, and responsive decision to a blank page.
|
|
98
|
+
|
|
99
|
+
That is the point of Synced Flow.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# WordPress
|
|
2
|
+
|
|
3
|
+
Synced Flow can be used in WordPress themes and plugins without asking
|
|
4
|
+
WordPress to resolve npm CSS imports in the browser.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pnpm add @syncedco/flow
|
|
10
|
+
pnpm exec synced-flow init --preset wordpress
|
|
11
|
+
pnpm flow:build
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The WordPress preset:
|
|
15
|
+
|
|
16
|
+
- scans `templates`, `parts`, `patterns`, `blocks`, `inc`, `includes`, `src`,
|
|
17
|
+
and `assets` when those folders exist
|
|
18
|
+
- scans PHP, HTML, JS, TS, JSX, TSX, Twig, Vue, Svelte, Astro, and MDX files
|
|
19
|
+
- enables `includeCore`
|
|
20
|
+
- writes `assets/css/synced-flow.css`
|
|
21
|
+
|
|
22
|
+
See [`examples/wordpress`](../examples/wordpress) for a lean block theme style
|
|
23
|
+
template with `theme.json`, template parts, PHP patterns, enqueue code, and an
|
|
24
|
+
enqueue-ready generated CSS output.
|
|
25
|
+
|
|
26
|
+
## Example Structure
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
examples/wordpress/
|
|
30
|
+
functions.php
|
|
31
|
+
theme.json
|
|
32
|
+
synced-flow.config.mjs
|
|
33
|
+
assets/css/synced-flow.css
|
|
34
|
+
parts/header.html
|
|
35
|
+
parts/footer.html
|
|
36
|
+
templates/front-page.html
|
|
37
|
+
templates/index.html
|
|
38
|
+
patterns/landing-hero.php
|
|
39
|
+
patterns/feature-grid.php
|
|
40
|
+
patterns/contact-cta.php
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Enqueue
|
|
44
|
+
|
|
45
|
+
```php
|
|
46
|
+
wp_enqueue_style(
|
|
47
|
+
'synced-flow',
|
|
48
|
+
get_theme_file_uri('assets/css/synced-flow.css'),
|
|
49
|
+
[],
|
|
50
|
+
wp_get_theme()->get('Version')
|
|
51
|
+
);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For plugins, use `plugins_url()` or `plugin_dir_url()` instead of
|
|
55
|
+
`get_theme_file_uri()`.
|
|
56
|
+
|
|
57
|
+
## Dynamic Classes
|
|
58
|
+
|
|
59
|
+
Synced Flow generates utility CSS from complete class tokens. Keep class names
|
|
60
|
+
complete in PHP and templates.
|
|
61
|
+
|
|
62
|
+
```php
|
|
63
|
+
<section class="sf-section text-primary">
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
When a class is composed dynamically, add the full class to `safelist`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
These examples show the intended starting point for new projects.
|
|
4
|
+
|
|
5
|
+
- `next` - Next.js App Router setup
|
|
6
|
+
- `astro` - Astro content-site setup
|
|
7
|
+
- `vite` - Vite React setup
|
|
8
|
+
- `plain-html` - no framework setup with a complete website demo using only
|
|
9
|
+
Synced Flow primitives for header, hero, content, cards, form, notice, and footer
|
|
10
|
+
- `templates` - copy-ready full-page HTML templates for SaaS, portfolio, blog,
|
|
11
|
+
and coming soon pages
|
|
12
|
+
- `wordpress` - block theme style setup with enqueue code, templates, parts,
|
|
13
|
+
and PHP patterns
|
|
14
|
+
|
|
15
|
+
Each example uses `synced-flow.config.mjs`, imports a single CSS entry file,
|
|
16
|
+
and keeps `responsiveVariants` off.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "synced-flow-astro-example",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "astro dev",
|
|
7
|
+
"flow:build": "synced-flow build",
|
|
8
|
+
"flow:check": "synced-flow build --check",
|
|
9
|
+
"flow:lint": "synced-flow lint",
|
|
10
|
+
"flow:watch": "synced-flow watch",
|
|
11
|
+
"flow:doctor": "synced-flow doctor"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@astrojs/check": "^0.9.0",
|
|
15
|
+
"@syncedco/flow": "file:../..",
|
|
16
|
+
"astro": "^5.0.0",
|
|
17
|
+
"typescript": "^5.0.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
import '../styles/synced-flow.css'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<html lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<meta name="viewport" content="width=device-width" />
|
|
9
|
+
<title>Synced Flow Astro Example</title>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<header class="sf-section sf-section--compact sf-sticky-top sf-bg-background">
|
|
13
|
+
<nav class="sf-container sf-nav" aria-label="Main navigation">
|
|
14
|
+
<a class="sf-nav__link" href="#home">Studio</a>
|
|
15
|
+
<ul class="sf-nav__list">
|
|
16
|
+
<li><a class="sf-nav__link" href="#articles">Articles</a></li>
|
|
17
|
+
<li><a class="sf-nav__link" href="#contact">Contact</a></li>
|
|
18
|
+
</ul>
|
|
19
|
+
</nav>
|
|
20
|
+
</header>
|
|
21
|
+
|
|
22
|
+
<main id="home">
|
|
23
|
+
<section class="sf-section">
|
|
24
|
+
<div class="sf-container sf-stack">
|
|
25
|
+
<p class="sf-badge">Astro template</p>
|
|
26
|
+
<h1 class="sf-text-display">A content site from native CSS primitives.</h1>
|
|
27
|
+
<p class="sf-text-lead sf-prose">
|
|
28
|
+
Replace these sections with project content. The layout, typography, cards, navigation, and form styling come from Synced Flow.
|
|
29
|
+
</p>
|
|
30
|
+
<div class="sf-cluster">
|
|
31
|
+
<a class="sf-button sf-button--default" href="#contact">Start a project</a>
|
|
32
|
+
<a class="sf-button sf-button--outline" href="#articles">Read articles</a>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</section>
|
|
36
|
+
|
|
37
|
+
<section id="articles" class="sf-section">
|
|
38
|
+
<div class="sf-container sf-stack">
|
|
39
|
+
<div class="sf-section-header">
|
|
40
|
+
<p class="sf-kicker">Articles</p>
|
|
41
|
+
<h2 class="sf-text-h2">Blog cards and article metadata without custom CSS.</h2>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="sf-auto-grid">
|
|
44
|
+
<article class="sf-card sf-card--interactive sf-stack">
|
|
45
|
+
<p class="sf-meta">Guide · 5 min read</p>
|
|
46
|
+
<h3 class="sf-text-h4">Theme from reusable tokens</h3>
|
|
47
|
+
<p class="sf-text-muted">Keep brand choices in config before adding project CSS.</p>
|
|
48
|
+
</article>
|
|
49
|
+
<article class="sf-card sf-card--interactive sf-stack">
|
|
50
|
+
<p class="sf-meta">Pattern · 3 min read</p>
|
|
51
|
+
<h3 class="sf-text-h4">Native disclosure and tabs</h3>
|
|
52
|
+
<p class="sf-text-muted">Use browser primitives first and add optional JS only when needed.</p>
|
|
53
|
+
</article>
|
|
54
|
+
<article class="sf-card sf-card--interactive sf-stack">
|
|
55
|
+
<p class="sf-meta">Recipe · 4 min read</p>
|
|
56
|
+
<h3 class="sf-text-h4">Scroll panels</h3>
|
|
57
|
+
<p class="sf-text-muted">Create immersive panels with scroll snap and sticky layout classes.</p>
|
|
58
|
+
</article>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</section>
|
|
62
|
+
|
|
63
|
+
<section id="contact" class="sf-section">
|
|
64
|
+
<div class="sf-container sf-split">
|
|
65
|
+
<div class="sf-stack">
|
|
66
|
+
<p class="sf-kicker">Contact</p>
|
|
67
|
+
<h2 class="sf-text-h2">Ready for a real content workflow.</h2>
|
|
68
|
+
<p class="sf-prose">This example is deliberately complete enough for an AI agent to replace sections instead of inventing new styling.</p>
|
|
69
|
+
</div>
|
|
70
|
+
<form class="sf-form sf-card">
|
|
71
|
+
<label class="sf-field">
|
|
72
|
+
<span class="sf-label">Email</span>
|
|
73
|
+
<input class="sf-input" type="email" placeholder="you@example.com" />
|
|
74
|
+
</label>
|
|
75
|
+
<label class="sf-field">
|
|
76
|
+
<span class="sf-label">Project</span>
|
|
77
|
+
<textarea class="sf-textarea" rows="4" placeholder="Tell us about the site."></textarea>
|
|
78
|
+
</label>
|
|
79
|
+
<button class="sf-button sf-button--default" type="submit">Send</button>
|
|
80
|
+
</form>
|
|
81
|
+
</div>
|
|
82
|
+
</section>
|
|
83
|
+
</main>
|
|
84
|
+
</body>
|
|
85
|
+
</html>
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/* Generated by @syncedco/flow. Edit synced-flow.config.mjs or run synced-flow build to refresh. */
|
|
2
|
+
|
|
3
|
+
@layer reset, tokens, base, app, layout, components, utilities, overrides;
|
|
4
|
+
|
|
5
|
+
@layer tokens {
|
|
6
|
+
:root {
|
|
7
|
+
color-scheme: light;
|
|
8
|
+
--font-sans: var(--sf-font-sans, ui-sans-serif, system-ui, sans-serif);
|
|
9
|
+
--font-display: var(--sf-font-display, ui-serif, Georgia, serif);
|
|
10
|
+
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
|
11
|
+
|
|
12
|
+
--step--2: clamp(0.6944rem, 0.6866rem + 0.0348vw, 0.72rem);
|
|
13
|
+
--step--1: clamp(0.8333rem, 0.8129rem + 0.0907vw, 0.9rem);
|
|
14
|
+
--step-0: clamp(1rem, 0.9617rem + 0.1701vw, 1.125rem);
|
|
15
|
+
--step-1: clamp(1.2rem, 1.1369rem + 0.2806vw, 1.4063rem);
|
|
16
|
+
--step-2: clamp(1.44rem, 1.3427rem + 0.4324vw, 1.7578rem);
|
|
17
|
+
--step-3: clamp(1.728rem, 1.5843rem + 0.6385vw, 2.1973rem);
|
|
18
|
+
--step-4: clamp(2.0736rem, 1.8676rem + 0.9156vw, 2.7466rem);
|
|
19
|
+
--step-5: clamp(2.4883rem, 2.1991rem + 1.2856vw, 3.4332rem);
|
|
20
|
+
--step-6: clamp(2.986rem, 2.5863rem + 1.7763vw, 4.2915rem);
|
|
21
|
+
--step-7: clamp(3.5832rem, 3.0379rem + 2.4235vw, 5.3644rem);
|
|
22
|
+
--step-8: clamp(4.2998rem, 3.5634rem + 3.2731vw, 6.7055rem);
|
|
23
|
+
|
|
24
|
+
--space-3xs: clamp(0.25rem, 0.2404rem + 0.0425vw, 0.2813rem);
|
|
25
|
+
--space-2xs: clamp(0.5rem, 0.4809rem + 0.085vw, 0.5625rem);
|
|
26
|
+
--space-xs: clamp(0.75rem, 0.7213rem + 0.1276vw, 0.8438rem);
|
|
27
|
+
--space-s: clamp(1rem, 0.9617rem + 0.1701vw, 1.125rem);
|
|
28
|
+
--space-m: clamp(1.5rem, 1.4426rem + 0.2551vw, 1.6875rem);
|
|
29
|
+
--space-l: clamp(2rem, 1.9235rem + 0.3401vw, 2.25rem);
|
|
30
|
+
--space-xl: clamp(3rem, 2.8852rem + 0.5102vw, 3.375rem);
|
|
31
|
+
--space-2xl: clamp(4rem, 3.8469rem + 0.6803vw, 4.5rem);
|
|
32
|
+
--space-3xl: clamp(6rem, 5.7704rem + 1.0204vw, 6.75rem);
|
|
33
|
+
--space-4xl: clamp(8rem, 7.6939rem + 1.3605vw, 9rem);
|
|
34
|
+
--space-3xs-2xs: clamp(0.25rem, 0.1543rem + 0.4252vw, 0.5625rem);
|
|
35
|
+
--space-2xs-xs: clamp(0.5rem, 0.3948rem + 0.4677vw, 0.8438rem);
|
|
36
|
+
--space-xs-s: clamp(0.75rem, 0.6352rem + 0.5102vw, 1.125rem);
|
|
37
|
+
--space-s-m: clamp(1rem, 0.7895rem + 0.9354vw, 1.6875rem);
|
|
38
|
+
--space-m-l: clamp(1.5rem, 1.2704rem + 1.0204vw, 2.25rem);
|
|
39
|
+
--space-l-xl: clamp(2rem, 1.5791rem + 1.8707vw, 3.375rem);
|
|
40
|
+
--space-xl-2xl: clamp(3rem, 2.5408rem + 2.0408vw, 4.5rem);
|
|
41
|
+
--space-2xl-3xl: clamp(4rem, 3.1582rem + 3.7415vw, 6.75rem);
|
|
42
|
+
--space-s-l: clamp(1rem, 0.6173rem + 1.7007vw, 2.25rem);
|
|
43
|
+
--space-m-xl: clamp(1.5rem, 0.926rem + 2.551vw, 3.375rem);
|
|
44
|
+
--space-l-2xl: clamp(2rem, 1.2347rem + 3.4014vw, 4.5rem);
|
|
45
|
+
|
|
46
|
+
--grid-max-width: 90rem;
|
|
47
|
+
--grid-gutter: var(--space-s-l);
|
|
48
|
+
--grid-columns: 12;
|
|
49
|
+
|
|
50
|
+
--radius-none: 0;
|
|
51
|
+
--radius-xs: 0.25rem;
|
|
52
|
+
--radius-sm: 0.375rem;
|
|
53
|
+
--radius-md: 0.5rem;
|
|
54
|
+
--radius-lg: 0.75rem;
|
|
55
|
+
--radius-xl: 1rem;
|
|
56
|
+
--radius-2xl: 1.25rem;
|
|
57
|
+
--radius-3xl: 1.5rem;
|
|
58
|
+
--radius-full: 999rem;
|
|
59
|
+
--radius: var(--radius-xl);
|
|
60
|
+
|
|
61
|
+
--color-ink-950: oklch(14% 0.025 248);
|
|
62
|
+
--color-ink-900: oklch(18% 0.024 246);
|
|
63
|
+
--color-ink-800: oklch(24% 0.022 244);
|
|
64
|
+
--color-ink-700: oklch(34% 0.02 240);
|
|
65
|
+
--color-ink-600: oklch(45% 0.018 236);
|
|
66
|
+
--color-ink-500: oklch(56% 0.015 232);
|
|
67
|
+
--color-paper: oklch(98.6% 0.014 78);
|
|
68
|
+
--color-paper-alt: oklch(96.6% 0.018 82);
|
|
69
|
+
--color-white: oklch(100% 0 0);
|
|
70
|
+
--color-black: oklch(0% 0 0);
|
|
71
|
+
|
|
72
|
+
--color-background: oklch(14% 0.025 248);
|
|
73
|
+
--color-foreground: oklch(96% 0.01 92);
|
|
74
|
+
--color-card: oklch(18% 0.024 246);
|
|
75
|
+
--color-card-foreground: oklch(96% 0.01 92);
|
|
76
|
+
--color-popover: oklch(18% 0.024 246);
|
|
77
|
+
--color-popover-foreground: oklch(96% 0.01 92);
|
|
78
|
+
--color-primary: oklch(69% 0.18 44);
|
|
79
|
+
--color-primary-hover: oklch(64% 0.18 44);
|
|
80
|
+
--color-primary-label: oklch(55% 0.18 44);
|
|
81
|
+
--color-primary-border: oklch(66% 0.17 43);
|
|
82
|
+
--color-primary-foreground: oklch(98% 0.01 95);
|
|
83
|
+
--color-secondary: oklch(24% 0.018 22);
|
|
84
|
+
--color-secondary-foreground: oklch(96% 0.01 92);
|
|
85
|
+
--color-muted: oklch(26% 0.012 24);
|
|
86
|
+
--color-muted-foreground: oklch(76% 0.01 92);
|
|
87
|
+
--color-accent: oklch(24% 0.018 22);
|
|
88
|
+
--color-accent-foreground: oklch(96% 0.01 92);
|
|
89
|
+
--color-destructive: oklch(55% 0.2 28);
|
|
90
|
+
--color-destructive-foreground: oklch(98% 0.01 95);
|
|
91
|
+
--color-border: oklch(100% 0 0 / 0.12);
|
|
92
|
+
--color-input: oklch(100% 0 0 / 0.12);
|
|
93
|
+
--color-ring: oklch(69% 0.18 44);
|
|
94
|
+
--color-heading: oklch(20% 0.02 18);
|
|
95
|
+
--color-page-text: oklch(23% 0.02 18);
|
|
96
|
+
--color-body: oklch(45% 0.02 28);
|
|
97
|
+
--color-body-dark: oklch(40% 0.02 28);
|
|
98
|
+
--color-subdued: oklch(42% 0.02 20);
|
|
99
|
+
--color-surface: oklch(96% 0.015 80);
|
|
100
|
+
--color-surface-alt: oklch(96.6% 0.018 82);
|
|
101
|
+
--color-hero-bg: oklch(8% 0.02 260);
|
|
102
|
+
--color-green: oklch(55% 0.12 148);
|
|
103
|
+
--color-green-dark: oklch(45% 0.12 148);
|
|
104
|
+
--color-green-muted: oklch(40% 0.12 148);
|
|
105
|
+
--color-green-light: oklch(90% 0.06 148);
|
|
106
|
+
--color-green-lighter: oklch(92% 0.04 148);
|
|
107
|
+
--color-green-bg: oklch(88% 0.07 148);
|
|
108
|
+
--color-green-bg-alt: oklch(82% 0.1 148);
|
|
109
|
+
--color-green-vivid: oklch(78% 0.08 148);
|
|
110
|
+
--color-green-mid: oklch(75% 0.12 148);
|
|
111
|
+
--color-green-deep: oklch(70% 0.14 150);
|
|
112
|
+
--color-green-deepest: oklch(60% 0.14 150);
|
|
113
|
+
--color-green-wash: oklch(93% 0.06 148);
|
|
114
|
+
--color-green-wash-alt: oklch(88% 0.08 148);
|
|
115
|
+
--color-green-gradient-from: oklch(82% 0.1 148);
|
|
116
|
+
--color-green-gradient-to: oklch(86% 0.06 148);
|
|
117
|
+
--color-deco-lime: oklch(80% 0.18 130);
|
|
118
|
+
--color-deco-blue: oklch(60% 0.12 240);
|
|
119
|
+
--color-deco-warm: oklch(80% 0.06 60);
|
|
120
|
+
--color-deco-warm-light: oklch(92% 0.02 80);
|
|
121
|
+
--color-deco-warm-mid: oklch(80% 0.15 60);
|
|
122
|
+
--color-purple-light: oklch(95% 0.05 280);
|
|
123
|
+
--color-purple-mid: oklch(92% 0.05 280);
|
|
124
|
+
--color-purple-dark: oklch(90% 0.06 280);
|
|
125
|
+
--color-purple-darker: oklch(87% 0.07 280);
|
|
126
|
+
--color-purple-icon: oklch(55% 0.2 280);
|
|
127
|
+
--color-warm-light: oklch(95.6% 0.05 22);
|
|
128
|
+
--color-warm-mid: oklch(95% 0.04 40);
|
|
129
|
+
--color-warm-grad-to: oklch(90% 0.08 30);
|
|
130
|
+
--color-warm-grad-to-alt: oklch(90% 0.06 30);
|
|
131
|
+
--color-warm-icon: oklch(60% 0.17 44);
|
|
132
|
+
--color-cool-light: oklch(92% 0.04 200);
|
|
133
|
+
--color-cool-dark: oklch(87% 0.06 200);
|
|
134
|
+
--color-primary-glow: oklch(80% 0.12 44);
|
|
135
|
+
--color-primary-soft: oklch(69% 0.18 44 / 0.10);
|
|
136
|
+
--color-primary-soft-border: oklch(69% 0.18 44 / 0.30);
|
|
137
|
+
--color-primary-soft-border-light: oklch(69% 0.18 44 / 0.25);
|
|
138
|
+
--color-primary-soft-text: oklch(85% 0.08 44);
|
|
139
|
+
--color-primary-highlight: oklch(75% 0.14 44);
|
|
140
|
+
|
|
141
|
+
--shadow-sm: 0 0.125rem 0.375rem oklch(0% 0 0 / 0.06);
|
|
142
|
+
--shadow-md: 0 0.5rem 1.5rem oklch(0% 0 0 / 0.08);
|
|
143
|
+
--shadow-lg: 0 1rem 2rem oklch(0% 0 0 / 0.1);
|
|
144
|
+
--shadow-xl: 0 1.5rem 3rem oklch(0% 0 0 / 0.14);
|
|
145
|
+
--shadow-2xl: 0 2rem 4rem oklch(0% 0 0 / 0.18);
|
|
146
|
+
--shadow-primary-cta: 0 0.875rem 1.875rem oklch(69% 0.18 44 / 0.24);
|
|
147
|
+
--shadow-glow: 0 0 2rem oklch(69% 0.18 44 / 0.28);
|
|
148
|
+
|
|
149
|
+
--duration-fast: 150ms;
|
|
150
|
+
--duration-normal: 220ms;
|
|
151
|
+
--duration-slow: 360ms;
|
|
152
|
+
--ease-standard: cubic-bezier(.2, 0, 0, 1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@layer tokens {
|
|
157
|
+
:root {
|
|
158
|
+
--sf-font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
|
|
159
|
+
--font-sans: var(--sf-font-sans);
|
|
160
|
+
--sf-font-display: Fraunces, Georgia, serif;
|
|
161
|
+
--font-display: var(--sf-font-display);
|
|
162
|
+
--sf-colour-background: oklch(97% 0.018 78);
|
|
163
|
+
--color-background: var(--sf-colour-background);
|
|
164
|
+
--sf-colour-foreground: oklch(18% 0.022 55);
|
|
165
|
+
--color-foreground: var(--sf-colour-foreground);
|
|
166
|
+
--sf-colour-muted: oklch(43% 0.02 65);
|
|
167
|
+
--color-muted: var(--sf-colour-muted);
|
|
168
|
+
--sf-colour-surface: oklch(100% 0 0);
|
|
169
|
+
--color-surface: var(--sf-colour-surface);
|
|
170
|
+
--sf-colour-surface-alt: oklch(94% 0.02 80);
|
|
171
|
+
--color-surface-alt: var(--sf-colour-surface-alt);
|
|
172
|
+
--sf-colour-border: oklch(18% 0.022 55 / 0.14);
|
|
173
|
+
--color-border: var(--sf-colour-border);
|
|
174
|
+
--sf-colour-primary: oklch(58% 0.17 42);
|
|
175
|
+
--color-primary: var(--sf-colour-primary);
|
|
176
|
+
--sf-colour-primary-hover: oklch(50% 0.16 40);
|
|
177
|
+
--color-primary-hover: var(--sf-colour-primary-hover);
|
|
178
|
+
--sf-colour-primary-foreground: oklch(100% 0 0);
|
|
179
|
+
--color-primary-foreground: var(--sf-colour-primary-foreground);
|
|
180
|
+
--sf-colour-accent: oklch(62% 0.13 150);
|
|
181
|
+
--color-accent: var(--sf-colour-accent);
|
|
182
|
+
--sf-colour-link: oklch(50% 0.16 40);
|
|
183
|
+
--color-link: var(--sf-colour-link);
|
|
184
|
+
--sf-colour-link-hover: oklch(58% 0.17 42);
|
|
185
|
+
--color-link-hover: var(--sf-colour-link-hover);
|
|
186
|
+
--sf-colour-ring: oklch(58% 0.17 42);
|
|
187
|
+
--color-ring: var(--sf-colour-ring);
|
|
188
|
+
--sf-container-max: 72rem;
|
|
189
|
+
--grid-max-width: 72rem;
|
|
190
|
+
--sf-gutter: var(--sf-space-m-l);
|
|
191
|
+
--grid-gutter: var(--sf-space-m-l);
|
|
192
|
+
--sf-button-radius: 999rem;
|
|
193
|
+
--button-radius: 999rem;
|
|
194
|
+
--sf-button-block-size: 2.75rem;
|
|
195
|
+
--button-size: 2.75rem;
|
|
196
|
+
--sf-card-radius: 0.5rem;
|
|
197
|
+
--card-radius: 0.5rem;
|
|
198
|
+
--sf-card-padding: var(--sf-space-l);
|
|
199
|
+
--sf-input-radius: 0.375rem;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@layer utilities {
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { defineConfig } from '@syncedco/flow/config'
|
|
2
|
+
import { themePresets } from '@syncedco/flow/presets'
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
scan: ['src'],
|
|
6
|
+
out: 'src/styles/synced-flow.generated.css',
|
|
7
|
+
responsiveVariants: false,
|
|
8
|
+
theme: themePresets.editorial,
|
|
9
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import './synced-flow.css'
|
|
2
|
+
|
|
3
|
+
export const metadata = {
|
|
4
|
+
title: 'Synced Flow Next Example',
|
|
5
|
+
description: 'A strict-fluid Synced Flow starter.',
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
9
|
+
return (
|
|
10
|
+
<html lang="en">
|
|
11
|
+
<body>{children}</body>
|
|
12
|
+
</html>
|
|
13
|
+
)
|
|
14
|
+
}
|