@syncedco/flow 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -44,6 +44,7 @@ brand drift, or generated class chaos.
44
44
  ## Links
45
45
 
46
46
  - GitHub: [github.com/SyncedCo/synced-flow](https://github.com/SyncedCo/synced-flow)
47
+ - Docs: [docs.syncedflow.dev](https://docs.syncedflow.dev)
47
48
  - Website: [syncedco.com](https://syncedco.com)
48
49
  - Issues: [github.com/SyncedCo/synced-flow/issues](https://github.com/SyncedCo/synced-flow/issues)
49
50
  - Support: [SUPPORT.md](SUPPORT.md)
@@ -2909,7 +2909,7 @@ function selectorFor(token, variants) {
2909
2909
  function colourValue(name) {
2910
2910
  const [raw, opacity] = name.split('/')
2911
2911
  const paletteMatch = raw.match(/^([a-z]+)-(\d+)$/)
2912
- const base = semanticColours[raw] ?? (paletteMatch ? palette[paletteMatch[1]]?.[paletteMatch[2]] : null)
2912
+ const base = semanticColours[raw] ?? configuredThemeColourValue(raw) ?? (paletteMatch ? palette[paletteMatch[1]]?.[paletteMatch[2]] : null)
2913
2913
  if (!base) return null
2914
2914
  if (!opacity) return base
2915
2915
  const amount = Number(opacity)
@@ -2918,6 +2918,16 @@ function colourValue(name) {
2918
2918
  return `color-mix(in oklch, ${base} ${amount}%, transparent)`
2919
2919
  }
2920
2920
 
2921
+ function configuredThemeColourValue(name) {
2922
+ const token = cssTokenName(name)
2923
+ const colourNames = [
2924
+ ...Object.keys(config.theme?.colours ?? {}),
2925
+ ...Object.keys(config.theme?.darkColours ?? {}),
2926
+ ].map(cssTokenName)
2927
+
2928
+ return colourNames.includes(token) ? `var(--color-${token}, var(--sf-colour-${token}))` : null
2929
+ }
2930
+
2921
2931
  function declarationsFor(base) {
2922
2932
  if (base.startsWith('sf-')) return []
2923
2933
 
@@ -3562,7 +3572,7 @@ function buildThemeCss(theme) {
3562
3572
  sections.push(` :where(.sf-theme-dark, [data-sf-theme="dark"]) {\n${dark.join('\n')}\n }`)
3563
3573
  }
3564
3574
 
3565
- return `@layer tokens {\n${sections.join('\n\n')}\n}`
3575
+ return sections.join('\n\n')
3566
3576
  }
3567
3577
 
3568
3578
  function buildTokensCss() {
@@ -3604,8 +3614,7 @@ function buildTokensCss() {
3604
3614
 
3605
3615
  const colours = fluidConfig.colours
3606
3616
 
3607
- return `@layer tokens {
3608
- :root {
3617
+ return `:root {
3609
3618
  color-scheme: light;
3610
3619
  --font-sans: var(--sf-font-sans, ui-sans-serif, system-ui, sans-serif);
3611
3620
  --font-display: var(--sf-font-display, ui-serif, Georgia, serif);
@@ -3725,8 +3734,7 @@ ${pairs.join('\n')}
3725
3734
  --ease-standard: cubic-bezier(.2, 0, 0, 1);
3726
3735
  --icon-size: 1em;
3727
3736
  --icon-stroke: 2;
3728
- }
3729
- }`
3737
+ }`
3730
3738
  }
3731
3739
 
3732
3740
  function buildBaseCss() {
@@ -11,7 +11,7 @@ These are intended for application code and examples.
11
11
  | Surface | Public API |
12
12
  | --- | --- |
13
13
  | Imports | `@syncedco/flow/styles.css`, `tokens.css`, `reset.css`, `base.css`, `defaults.css`, `layout.css`, `components.css`, `utilities.css` |
14
- | Tokens | `--sf-*` custom properties emitted by `tokens.css` |
14
+ | Tokens | Unlayered `--sf-*` custom properties emitted by `tokens.css` |
15
15
  | Theme config | `theme.fonts`, `theme.colours`, `theme.darkColours`, `theme.radii`, `theme.layout`, `theme.components` |
16
16
  | Layout classes | `sf-container`, `sf-section`, `sf-stack`, `sf-flow`, `sf-cluster`, `sf-repel`, `sf-toolbar`, `sf-app-shell`, `sf-app-sidebar`, `sf-app-main`, `sf-auto-grid`, `sf-switcher`, `sf-sidebar`, `sf-split`, `sf-frame`, `sf-cover`, `sf-metric-grid`, `sf-pipeline` |
17
17
  | Components | `sf-button`, `sf-icon`, `sf-icon-button`, `sf-avatar`, `sf-chart`, `sf-meter`, `sf-card`, `sf-surface`, `sf-hero`, `sf-nav`, `sf-form`, `sf-field`, `sf-input`, `sf-select`, `sf-textarea`, `sf-check`, `sf-alert`, `sf-badge`, `sf-section-header`, `sf-kicker` |
@@ -46,6 +46,17 @@ These can change more freely.
46
46
  They are useful for migration output, but `--sf-*` tokens are the preferred
47
47
  long-term API.
48
48
 
49
+ ## Theme Cascade Policy
50
+
51
+ Design tokens are intentionally emitted outside CSS layers. Synced Flow uses
52
+ layers for reset, base, layout, components, and utilities, but foundational
53
+ theme variables need the normal cascade so values from `synced-flow.config.mjs`
54
+ are not weaker than unlayered project CSS.
55
+
56
+ Put reusable brand decisions in `theme.colours`, `theme.darkColours`,
57
+ `theme.radii`, `theme.layout`, and `theme.components`. Theme switcher CSS should
58
+ only style the toggle/control UI; it should not redefine `--sf-*` colour tokens.
59
+
49
60
  ## Unit Policy
50
61
 
51
62
  Design decisions should use `rem`, fluid `clamp()` tokens, logical properties,
@@ -78,6 +78,10 @@ Use `--check` in CI to fail when the generated file is stale.
78
78
  Generated CSS only includes source-scanned utility classes, configured theme
79
79
  overrides, and keyframes needed by scanned animation classes.
80
80
 
81
+ Configured theme tokens are emitted outside CSS layers so they are not weaker
82
+ than unlayered project CSS. Use `theme.darkColours` for dark theme values rather
83
+ than maintaining duplicate colour overrides in a theme switcher stylesheet.
84
+
81
85
  ## watch
82
86
 
83
87
  Run `build`, then rebuild when configured scan files change.
@@ -154,8 +154,14 @@ export default defineConfig({
154
154
  },
155
155
  colours: {
156
156
  primary: 'oklch(68% 0.18 44)',
157
+ secondary: 'oklch(62% 0.12 205)',
158
+ tertiary: 'oklch(64% 0.14 185)',
157
159
  primaryForeground: 'oklch(100% 0 0)',
158
160
  },
161
+ darkColours: {
162
+ primary: 'oklch(76% 0.14 44)',
163
+ tertiary: 'oklch(82% 0.12 205)',
164
+ },
159
165
  },
160
166
  })
161
167
  ```
@@ -172,6 +178,10 @@ Use the CSS entry file for one-off local overrides.
172
178
  }
173
179
  ```
174
180
 
181
+ Synced Flow emits theme tokens outside CSS layers so config values are the site
182
+ theme source of truth. Keep theme switcher styles focused on the toggle UI; do
183
+ not mirror colour tokens into a separate `theme-switcher.css` file.
184
+
175
185
  ## Config
176
186
 
177
187
  ```js
@@ -61,3 +61,21 @@ node bin/synced-flow.mjs doctor --cwd examples/plain-html
61
61
 
62
62
  If a browser-visible example changes, inspect it at mobile and desktop widths
63
63
  before calling the release ready.
64
+
65
+ ## npm Trusted Publishing
66
+
67
+ Publishing is handled by `.github/workflows/npm-publish.yml` when a `v*` tag is
68
+ pushed. The workflow checks that the tag matches `package.json`, installs with
69
+ pnpm, runs tests, verifies package contents, and publishes with npm trusted
70
+ publishing.
71
+
72
+ Configure npm package trusted publishing for `@syncedco/flow` with:
73
+
74
+ - Provider: GitHub Actions
75
+ - Organization or user: `SyncedCo`
76
+ - Repository: `synced-flow`
77
+ - Workflow filename: `npm-publish.yml`
78
+ - Allowed action: `npm publish`
79
+
80
+ After this is verified, prefer npm's package setting to require two-factor
81
+ authentication and disallow token publishing.
package/docs/tokens.md CHANGED
@@ -28,6 +28,11 @@ Semantic tokens describe intent.
28
28
  --sf-colour-success-soft: oklch(62% 0.13 150 / 0.12);
29
29
  ```
30
30
 
31
+ Tokens are emitted outside CSS layers so configured themes can act as the
32
+ source of truth for brand colours, radius, layout, and component decisions.
33
+ Use `theme.darkColours` for dark-mode values instead of maintaining a separate
34
+ CSS file that redefines `--sf-*` variables.
35
+
31
36
  Use semantic utilities in projects:
32
37
 
33
38
  ```html
@@ -77,3 +82,9 @@ The generated core includes enough semantic variables for common website UI:
77
82
  `--sf-radius-control`, `--sf-radius-panel`, `--sf-shadow-*`
78
83
 
79
84
  For class-level usage, see [System primitives](system-primitives.md).
85
+
86
+ Custom semantic colour names from `theme.colours`, such as `secondary` or
87
+ `tertiary`, are emitted as CSS variables and can be consumed directly with
88
+ `var(--sf-colour-tertiary)`. Generated colour utilities are available when the
89
+ class token is present in scanned source, for example `text-tertiary` or
90
+ `bg-tertiary`.
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@syncedco/flow",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "AI-native fluid CSS design system for brand-consistent websites and agency builds.",
5
5
  "type": "module",
6
+ "packageManager": "pnpm@11.2.2",
6
7
  "license": "MIT",
7
8
  "keywords": [
8
9
  "css",
@@ -21,7 +22,7 @@
21
22
  "type": "git",
22
23
  "url": "git+https://github.com/SyncedCo/synced-flow.git"
23
24
  },
24
- "homepage": "https://syncedco.com",
25
+ "homepage": "https://docs.syncedflow.dev",
25
26
  "bugs": {
26
27
  "url": "https://github.com/SyncedCo/synced-flow/issues"
27
28
  },
package/styles.css CHANGED
@@ -1,7 +1,6 @@
1
1
  /* Generated by @syncedco/flow. Edit src/tokens.mjs or scripts/build-css.mjs, then run pnpm build. */
2
2
  @layer reset, tokens, base, app, layout, components, utilities;
3
- @layer tokens {
4
- :root {
3
+ :root {
5
4
  color-scheme: light;
6
5
 
7
6
  --sf-font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
@@ -195,7 +194,6 @@
195
194
  --sf-colour-link: var(--sf-colour-orange-500);
196
195
  --sf-colour-link-hover: oklch(80% 0.14 50);
197
196
  }
198
- }
199
197
  @layer reset {
200
198
  *, *::before, *::after { box-sizing: border-box; }
201
199
  *:where(:not(dialog)) { margin: 0; }
package/tokens.css CHANGED
@@ -1,7 +1,6 @@
1
1
  /* Generated by @syncedco/flow. Edit src/tokens.mjs or scripts/build-css.mjs, then run pnpm build. */
2
2
  @layer reset, tokens, base, app, layout, components, utilities;
3
- @layer tokens {
4
- :root {
3
+ :root {
5
4
  color-scheme: light;
6
5
 
7
6
  --sf-font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
@@ -195,4 +194,3 @@
195
194
  --sf-colour-link: var(--sf-colour-orange-500);
196
195
  --sf-colour-link-hover: oklch(80% 0.14 50);
197
196
  }
198
- }