@syncedco/flow 0.3.0 → 0.3.1
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/CHANGELOG.md +13 -0
- package/README.md +2 -1
- package/components.css +18 -2
- package/docs/audit-2026-06.md +113 -0
- package/docs/config-reference.md +27 -0
- package/docs/system-primitives.md +1 -0
- package/docs/tokens.md +2 -0
- package/docs/why-synced-flow.md +1 -1
- package/layout.css +5 -4
- package/package.json +3 -2
- package/styles.css +50 -7
- package/tokens.css +26 -0
- package/utilities.css +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.1 - 2026-06-13
|
|
4
|
+
|
|
5
|
+
- Fix mobile app drawer scrolling by giving the drawer sidebar a viewport block size.
|
|
6
|
+
- Vertically center `.sf-tab` contents.
|
|
7
|
+
- Improve built-in dark theme token coverage for primary, state, soft, ring, and glow tokens.
|
|
8
|
+
- Make `.sf-filter-bar` alignment token-configurable with a centered default.
|
|
9
|
+
- Add a status-chip dot opt-out with `data-dot="false"` and `sf-status--label`.
|
|
10
|
+
- Add reduced-motion safeguards for hover lift and marquee animation.
|
|
11
|
+
- Add public `--sf-z-*` stacking tokens for header, backdrop, drawer, overlay, toast, sticky, and skip-link layers.
|
|
12
|
+
- Reframe positioning copy from "AI-native" to "AI-friendly".
|
|
13
|
+
- Document the global theme config scope and the project-CSS pattern for advanced theme matrices.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Synced Flow
|
|
2
2
|
|
|
3
|
-
AI-
|
|
3
|
+
AI-friendly fluid CSS design system for brand-consistent websites, agency builds,
|
|
4
4
|
and modern frontend projects.
|
|
5
5
|
|
|
6
6
|
Synced Flow gives developers and AI coding agents a shared styling contract:
|
|
@@ -58,6 +58,7 @@ documentation, and recipes.
|
|
|
58
58
|
Useful project files:
|
|
59
59
|
|
|
60
60
|
- [Contributing](CONTRIBUTING.md)
|
|
61
|
+
- [Changelog](CHANGELOG.md)
|
|
61
62
|
- [Security policy](SECURITY.md)
|
|
62
63
|
- [Code of conduct](CODE_OF_CONDUCT.md)
|
|
63
64
|
- [Support](SUPPORT.md)
|
package/components.css
CHANGED
|
@@ -432,6 +432,16 @@
|
|
|
432
432
|
to { transform: translateX(-50%); }
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
+
@media (prefers-reduced-motion: reduce) {
|
|
436
|
+
:where(.sf-button:hover, .sf-card--interactive:hover) {
|
|
437
|
+
transform: none;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.sf-marquee__track {
|
|
441
|
+
animation: none;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
435
445
|
.sf-command-list {
|
|
436
446
|
display: grid;
|
|
437
447
|
font-family: var(--sf-font-mono);
|
|
@@ -837,7 +847,7 @@
|
|
|
837
847
|
}
|
|
838
848
|
|
|
839
849
|
.sf-filter-bar {
|
|
840
|
-
align-items:
|
|
850
|
+
align-items: var(--sf-filter-bar-align, center);
|
|
841
851
|
background: var(--sf-colour-surface);
|
|
842
852
|
border: 1px solid var(--sf-colour-border);
|
|
843
853
|
border-radius: var(--sf-radius-panel);
|
|
@@ -984,6 +994,10 @@
|
|
|
984
994
|
inline-size: .42em;
|
|
985
995
|
}
|
|
986
996
|
|
|
997
|
+
:where(.sf-status[data-dot="false"], .sf-status--label)::before {
|
|
998
|
+
content: none;
|
|
999
|
+
}
|
|
1000
|
+
|
|
987
1001
|
.sf-status[data-tone="success"] {
|
|
988
1002
|
--sf-status-bg: var(--sf-colour-success-soft);
|
|
989
1003
|
--sf-status-border: color-mix(in oklch, var(--sf-colour-success) 34%, transparent);
|
|
@@ -1418,6 +1432,7 @@
|
|
|
1418
1432
|
:where(.sf-popover, .sf-menu-popover, .sf-tooltip, .sf-toast, .sf-banner, .sf-drawer):popover-open {
|
|
1419
1433
|
display: grid;
|
|
1420
1434
|
gap: var(--sf-space-xs);
|
|
1435
|
+
z-index: var(--sf-z-overlay);
|
|
1421
1436
|
}
|
|
1422
1437
|
|
|
1423
1438
|
.sf-popover {
|
|
@@ -1489,7 +1504,7 @@
|
|
|
1489
1504
|
inset-block-start: var(--sf-space-s);
|
|
1490
1505
|
inset-inline-end: var(--sf-space-s);
|
|
1491
1506
|
position: fixed;
|
|
1492
|
-
z-index:
|
|
1507
|
+
z-index: var(--sf-z-toast);
|
|
1493
1508
|
}
|
|
1494
1509
|
|
|
1495
1510
|
.sf-banner {
|
|
@@ -1604,6 +1619,7 @@
|
|
|
1604
1619
|
}
|
|
1605
1620
|
|
|
1606
1621
|
.sf-tab {
|
|
1622
|
+
align-items: center;
|
|
1607
1623
|
border-block-end: 0.125rem solid transparent;
|
|
1608
1624
|
border-radius: var(--sf-radius-full);
|
|
1609
1625
|
color: var(--sf-colour-muted);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Synced Flow Audit — June 2026 (v0.3.0)
|
|
2
|
+
|
|
3
|
+
Independent audit of `@syncedco/flow` at v0.3.0 (`a8a1f68`), run across three
|
|
4
|
+
passes: product coherence (claims vs shipped), CSS quality, and tooling/release
|
|
5
|
+
engineering. Findings are grounded in the source and in real consumer feedback
|
|
6
|
+
from the Synced CRM (`synced-crm`, the first production app consumer).
|
|
7
|
+
|
|
8
|
+
## Verdict
|
|
9
|
+
|
|
10
|
+
Flow delivers its **original model (websites/agency) almost completely** and
|
|
11
|
+
the **engineering discipline behind it impressively**. It falls short in three
|
|
12
|
+
places: **app-tier depth**, **advanced theming scope**, and a few product
|
|
13
|
+
positioning/docs gaps. It is a real, well-built system, and the positioning now
|
|
14
|
+
fits better as AI-friendly / agent-ready.
|
|
15
|
+
|
|
16
|
+
| Dimension | Rating | Summary |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| Fluid foundation (tokens, scales, layout) | ✅ Excellent | Genuine Utopia-style fluidity; modern CSS (layers, oklch, logical props, container queries); clean layer hygiene |
|
|
19
|
+
| Website/agency coverage | ✅ ~90% | Everything claimed ships; agency-ready without custom CSS |
|
|
20
|
+
| Tooling & release engineering | ✅ Excellent | 14 tested CLI commands, guardrails (size budgets, zero-dep, px policy), 40/40 tests, automated tag-driven publishing |
|
|
21
|
+
| App/SaaS tier (0.2–0.3) | ⚠️ ~60% | Real scaffolding (proven by the CRM) but thin; consumers carry 20–40% custom CSS |
|
|
22
|
+
| Dark mode | ✅ Patched after audit | `.sf-theme-dark` now overrides primary/status/soft/ring/glow tokens rather than inheriting light-tuned values |
|
|
23
|
+
| Theming config | ✅ Documented boundary | Config handles global light/dark token themes; advanced per-surface/multi-variant theming belongs in project CSS token scopes |
|
|
24
|
+
| AI positioning | ✅ Reframed | Positioning now uses AI-friendly / agent-ready language for the shipped CLI, skill, and agent guidance |
|
|
25
|
+
| Docs | ⚠️ Improving | Website docs thorough; CHANGELOG and theming-scope docs added; app-tier docs can still mature |
|
|
26
|
+
|
|
27
|
+
## Confirmed bugs (found by the CRM, verified in source)
|
|
28
|
+
|
|
29
|
+
1. **Drawer can't scroll** — fixed after audit by adding `block-size: 100dvh`
|
|
30
|
+
to `.sf-app-shell[data-mobile="drawer"] .sf-app-sidebar`, giving the
|
|
31
|
+
existing `overflow: auto` a real viewport-height scroll container.
|
|
32
|
+
2. **`.sf-tab` not vertically centred** — fixed after audit with
|
|
33
|
+
`align-items: center`.
|
|
34
|
+
3. **`.sf-filter-bar` `align-items: end`** — fixed after audit with
|
|
35
|
+
`align-items: var(--sf-filter-bar-align, center)`, preserving a project
|
|
36
|
+
escape hatch without adding a new component variant.
|
|
37
|
+
4. **`.sf-status` dot is mandatory** — fixed after audit with
|
|
38
|
+
`data-dot="false"` and `sf-status--label` opt-outs.
|
|
39
|
+
|
|
40
|
+
## Higher-severity findings the CRM did NOT hit
|
|
41
|
+
|
|
42
|
+
These mattered because no consumer had exercised them yet. They are now patched
|
|
43
|
+
or documented, but should still be validated in the next real consumer.
|
|
44
|
+
|
|
45
|
+
5. **Dark mode token coverage is critically incomplete** — fixed after audit
|
|
46
|
+
for the shipped base theme by adding dark-mode primary, state, soft, ring,
|
|
47
|
+
and glow token overrides.
|
|
48
|
+
6. **Z-index scale is compressed and undocumented** — fixed after audit with
|
|
49
|
+
public `--sf-z-*` tokens wired into header, backdrop, drawer, overlay, toast,
|
|
50
|
+
sticky, and skip-link layers.
|
|
51
|
+
7. **Missing `prefers-reduced-motion` guards** — fixed after audit for
|
|
52
|
+
`.sf-button:hover`, `.sf-card--interactive:hover`, and the marquee track.
|
|
53
|
+
|
|
54
|
+
## Theming model limitation (real, undocumented)
|
|
55
|
+
|
|
56
|
+
Config supports global light + `darkColours` + per-preset overrides. It does
|
|
57
|
+
not try to express per-surface / multi-variant theming (e.g. `[data-theme]` ×
|
|
58
|
+
`[data-surface]` matrices, per-tenant white-label, density-by-context). That is
|
|
59
|
+
a legitimate design choice for Synced Flow's scope, and `config-reference.md`
|
|
60
|
+
now documents the hand-written token-scope pattern for advanced cases.
|
|
61
|
+
|
|
62
|
+
## AI-Friendly Positioning
|
|
63
|
+
|
|
64
|
+
What ships is real and good: `catalog --json`, `suggest`, `pattern`, `recipe`,
|
|
65
|
+
`lint`, `doctor`, a packaged skill, and `agents install` for 8 targets. The
|
|
66
|
+
project now describes this as **AI-friendly** and agent-readable tooling rather
|
|
67
|
+
than implying runtime AI integration.
|
|
68
|
+
|
|
69
|
+
## App-tier coverage gaps (from real CRM adoption)
|
|
70
|
+
|
|
71
|
+
Shipped and adopted: app-shell, data-table, empty-state, filter-bar, status
|
|
72
|
+
chips, tabs, toast skin, form field shells. Still missing for production app
|
|
73
|
+
work (CRM kept custom or deferred): combobox/searchable select, pagination
|
|
74
|
+
depth (page size, jump-to-page), modal-with-form as a primitive (not just a
|
|
75
|
+
pattern), bulk-actions toolbar, multi-step/wizard, skeleton loading compounds,
|
|
76
|
+
sticky-header + horizontal-scroll tables. Kanban/timesheet/invoice-doc are
|
|
77
|
+
deliberately consumer-specific and out of scope.
|
|
78
|
+
|
|
79
|
+
## Strengths (keep doing)
|
|
80
|
+
|
|
81
|
+
- Real fluidity; modern CSS; excellent cascade-layer hygiene.
|
|
82
|
+
- Tooling/release engineering is the strongest area: guardrails enforce
|
|
83
|
+
zero-dependency, per-layer gzip size budgets, layer order, and a raw-px
|
|
84
|
+
policy; 40/40 tests pass; tag-driven OIDC publishing; complete exports map.
|
|
85
|
+
- CLI catalog currently in sync with shipped CSS (verified) — though by hand.
|
|
86
|
+
- AI agent guidance (skill + `agents install`) is current with 0.3.0 primitives.
|
|
87
|
+
|
|
88
|
+
## Recommended roadmap
|
|
89
|
+
|
|
90
|
+
**0.3.1 — bug patch (small, soon):**
|
|
91
|
+
1. Drawer viewport scroll container. ✅
|
|
92
|
+
2. `.sf-tab` `align-items: center`. ✅
|
|
93
|
+
3. `.sf-filter-bar` tokenized alignment with centered default. ✅
|
|
94
|
+
4. `.sf-status` dot opt-out. ✅
|
|
95
|
+
5. `prefers-reduced-motion` guards on hover transforms + marquee. ✅
|
|
96
|
+
|
|
97
|
+
**0.4.0 — structural gaps:**
|
|
98
|
+
6. Continue dark-mode validation with a real consumer using Flow's built-in
|
|
99
|
+
theme selectors.
|
|
100
|
+
7. Begin app-tier depth: combobox, pagination, modal-with-form, bulk-actions —
|
|
101
|
+
prioritised by what the CRM had to keep custom.
|
|
102
|
+
|
|
103
|
+
**Docs / positioning / CI (cheap, high-trust):**
|
|
104
|
+
8. CI: smoke-build the examples; add a test asserting the CLI catalog matches
|
|
105
|
+
the shipped CSS (in sync today only by hand); consider a CSS parse/lint and
|
|
106
|
+
a small visual-regression pass.
|
|
107
|
+
|
|
108
|
+
## Meta-observation
|
|
109
|
+
|
|
110
|
+
The four bugs the CRM surfaced are exactly the class only a real consumer finds
|
|
111
|
+
— the proving-ground loop is working as intended. The most useful next
|
|
112
|
+
validation step is getting a second consumer, or the CRM itself, onto Flow's
|
|
113
|
+
built-in dark mode and app primitives before 1.0.
|
package/docs/config-reference.md
CHANGED
|
@@ -79,3 +79,30 @@ theme: {
|
|
|
79
79
|
},
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
|
+
|
|
83
|
+
## Theme Scope
|
|
84
|
+
|
|
85
|
+
The config theme model is intentionally global. Use `theme.colours` for the
|
|
86
|
+
default token set and `theme.darkColours` for `.sf-theme-dark` /
|
|
87
|
+
`[data-sf-theme="dark"]` overrides. This covers the common site or app case:
|
|
88
|
+
one brand token set, with an optional dark-mode token set.
|
|
89
|
+
|
|
90
|
+
Synced Flow does not try to encode every theme matrix in config. If a project
|
|
91
|
+
needs per-tenant branding, `[data-surface]` variants, density-by-context, or
|
|
92
|
+
other multi-axis theme rules, keep the reusable defaults in config and write
|
|
93
|
+
the extra token scopes in project CSS:
|
|
94
|
+
|
|
95
|
+
```css
|
|
96
|
+
[data-tenant="acme"] {
|
|
97
|
+
--sf-colour-primary: oklch(62% 0.19 252);
|
|
98
|
+
--sf-colour-primary-hover: oklch(56% 0.19 252);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
[data-surface="inset"] {
|
|
102
|
+
--sf-colour-surface: var(--sf-colour-surface-inset);
|
|
103
|
+
--sf-card-padding: var(--sf-space-s);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use this pattern for deliberate product theming. Avoid scattering one-off
|
|
108
|
+
colour values through page components when a value can live in a token scope.
|
|
@@ -17,6 +17,7 @@ Use the `--sf-*` variables as the stable CSS foundation.
|
|
|
17
17
|
| App colour | `--sf-colour-surface-hover`, `--sf-colour-surface-raised-2`, `--sf-colour-border-subtle`, `--sf-colour-backdrop` | App surfaces, hover states, subtle dividers, and overlays. |
|
|
18
18
|
| Categorical colour | `--sf-colour-categorical-1` ... `--sf-colour-categorical-6` | Charts, stages, labels, and recurring data accents. |
|
|
19
19
|
| State | `--sf-colour-success`, `--sf-colour-warning`, `--sf-colour-danger`, `--sf-colour-info` | Feedback and notices. |
|
|
20
|
+
| Z-index | `--sf-z-header`, `--sf-z-backdrop`, `--sf-z-drawer`, `--sf-z-overlay`, `--sf-z-toast` | Shared stacking slots for app chrome, drawers, popovers, and feedback. |
|
|
20
21
|
| Motion | `--sf-duration-fast`, `--sf-duration-normal`, `--sf-ease-standard` | Consistent transitions. |
|
|
21
22
|
| Component | `--sf-button-*`, `--sf-card-*`, `--sf-input-*`, `--sf-alert-*` | Reusable component defaults. |
|
|
22
23
|
| Accessibility | `:focus-visible`, `:target`, `[aria-invalid]`, `[aria-current]`, `[aria-expanded]`, `[aria-selected]`, `[aria-busy]`, `[aria-disabled]` | Visible native and ARIA states. |
|
package/docs/tokens.md
CHANGED
|
@@ -86,6 +86,8 @@ The generated core includes enough semantic variables for common website UI:
|
|
|
86
86
|
- structure: `--sf-colour-border-subtle`, `--sf-colour-border`,
|
|
87
87
|
`--sf-colour-border-strong`, `--sf-colour-backdrop`,
|
|
88
88
|
`--sf-radius-control`, `--sf-radius-panel`, `--sf-shadow-*`
|
|
89
|
+
- stacking: `--sf-z-sticky`, `--sf-z-header`, `--sf-z-backdrop`,
|
|
90
|
+
`--sf-z-drawer`, `--sf-z-overlay`, `--sf-z-toast`, `--sf-z-skip-link`
|
|
89
91
|
- data accents: `--sf-colour-categorical-1` through
|
|
90
92
|
`--sf-colour-categorical-6`
|
|
91
93
|
|
package/docs/why-synced-flow.md
CHANGED
|
@@ -22,7 +22,7 @@ Synced Flow is designed to reduce the number of styling decisions made from scra
|
|
|
22
22
|
|
|
23
23
|
Synced Flow is not trying to be a Tailwind clone, a Bootstrap replacement, or a React component library.
|
|
24
24
|
|
|
25
|
-
It is an AI-
|
|
25
|
+
It is an AI-friendly fluid CSS design system for brand-consistent websites and agency builds.
|
|
26
26
|
|
|
27
27
|
Use it when you want:
|
|
28
28
|
|
package/layout.css
CHANGED
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
justify-content: space-between;
|
|
117
117
|
min-block-size: var(--sf-app-header-height);
|
|
118
118
|
padding-inline: var(--sf-space-s-m);
|
|
119
|
-
z-index:
|
|
119
|
+
z-index: var(--sf-z-header);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
.sf-app-shell[data-layout~="fixed-header"] {
|
|
@@ -199,6 +199,7 @@
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
.sf-app-shell[data-mobile="drawer"] .sf-app-sidebar {
|
|
202
|
+
block-size: 100dvh;
|
|
202
203
|
box-shadow: var(--sf-shadow-xl);
|
|
203
204
|
inline-size: min(18rem, calc(100vw - var(--sf-space-l)));
|
|
204
205
|
inset-block: 0;
|
|
@@ -207,7 +208,7 @@
|
|
|
207
208
|
min-block-size: 100dvh;
|
|
208
209
|
position: fixed;
|
|
209
210
|
transform: translateX(-100%);
|
|
210
|
-
z-index:
|
|
211
|
+
z-index: var(--sf-z-drawer);
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
.sf-app-shell[data-mobile="drawer"][data-sidebar-open="true"] .sf-app-sidebar {
|
|
@@ -219,7 +220,7 @@
|
|
|
219
220
|
display: block;
|
|
220
221
|
inset: 0;
|
|
221
222
|
position: fixed;
|
|
222
|
-
z-index:
|
|
223
|
+
z-index: var(--sf-z-backdrop);
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
|
|
@@ -363,7 +364,7 @@
|
|
|
363
364
|
.sf-sticky-top {
|
|
364
365
|
position: sticky;
|
|
365
366
|
inset-block-start: var(--sf-sticky-offset, 0);
|
|
366
|
-
z-index: var(--sf-sticky-z,
|
|
367
|
+
z-index: var(--sf-sticky-z, var(--sf-z-sticky));
|
|
367
368
|
}
|
|
368
369
|
|
|
369
370
|
.sf-media-object {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncedco/flow",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "AI-
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "AI-friendly fluid CSS design system for brand-consistent websites and agency builds.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.2.2",
|
|
7
7
|
"license": "MIT",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"examples",
|
|
64
64
|
"skills",
|
|
65
65
|
"src",
|
|
66
|
+
"CHANGELOG.md",
|
|
66
67
|
"CODE_OF_CONDUCT.md",
|
|
67
68
|
"CONTRIBUTING.md",
|
|
68
69
|
"LICENSE",
|
package/styles.css
CHANGED
|
@@ -150,6 +150,13 @@
|
|
|
150
150
|
--sf-shadow-xl: 0 1.75rem 4rem oklch(0% 0 0 / 0.18);
|
|
151
151
|
--sf-shadow-inset: inset 0 0 0 1px var(--sf-colour-border);
|
|
152
152
|
--sf-shadow-glow: 0 0 2rem oklch(68% 0.18 44 / 0.24);
|
|
153
|
+
--sf-z-sticky: 20;
|
|
154
|
+
--sf-z-header: 20;
|
|
155
|
+
--sf-z-backdrop: 25;
|
|
156
|
+
--sf-z-drawer: 30;
|
|
157
|
+
--sf-z-overlay: 40;
|
|
158
|
+
--sf-z-toast: 50;
|
|
159
|
+
--sf-z-skip-link: 999;
|
|
153
160
|
--sf-duration-fast: 150ms;
|
|
154
161
|
--sf-duration-normal: 220ms;
|
|
155
162
|
--sf-duration-slow: 360ms;
|
|
@@ -210,8 +217,27 @@
|
|
|
210
217
|
--sf-colour-border: oklch(100% 0 0 / 0.14);
|
|
211
218
|
--sf-colour-border-strong: oklch(100% 0 0 / 0.24);
|
|
212
219
|
--sf-colour-backdrop: oklch(0% 0 0 / 0.64);
|
|
220
|
+
--sf-colour-primary: var(--sf-colour-orange-500);
|
|
221
|
+
--sf-colour-primary-hover: oklch(80% 0.14 50);
|
|
222
|
+
--sf-colour-primary-foreground: var(--sf-colour-neutral-950);
|
|
223
|
+
--sf-colour-primary-soft: oklch(74% 0.17 48 / 0.18);
|
|
224
|
+
--sf-colour-primary-soft-border: oklch(74% 0.17 48 / 0.34);
|
|
213
225
|
--sf-colour-link: var(--sf-colour-orange-500);
|
|
214
226
|
--sf-colour-link-hover: oklch(80% 0.14 50);
|
|
227
|
+
--sf-colour-success: oklch(72% 0.13 150);
|
|
228
|
+
--sf-colour-success-foreground: var(--sf-colour-neutral-950);
|
|
229
|
+
--sf-colour-success-soft: oklch(72% 0.13 150 / 0.16);
|
|
230
|
+
--sf-colour-warning: oklch(84% 0.15 82);
|
|
231
|
+
--sf-colour-warning-foreground: var(--sf-colour-neutral-950);
|
|
232
|
+
--sf-colour-warning-soft: oklch(84% 0.15 82 / 0.18);
|
|
233
|
+
--sf-colour-danger: oklch(70% 0.18 28);
|
|
234
|
+
--sf-colour-danger-foreground: var(--sf-colour-neutral-950);
|
|
235
|
+
--sf-colour-danger-soft: oklch(70% 0.18 28 / 0.16);
|
|
236
|
+
--sf-colour-info: oklch(76% 0.12 205);
|
|
237
|
+
--sf-colour-info-foreground: var(--sf-colour-neutral-950);
|
|
238
|
+
--sf-colour-info-soft: oklch(76% 0.12 205 / 0.16);
|
|
239
|
+
--sf-colour-ring: var(--sf-colour-orange-500);
|
|
240
|
+
--sf-shadow-glow: 0 0 2rem oklch(74% 0.17 48 / 0.18);
|
|
215
241
|
}
|
|
216
242
|
@layer reset {
|
|
217
243
|
*, *::before, *::after { box-sizing: border-box; }
|
|
@@ -438,7 +464,7 @@
|
|
|
438
464
|
justify-content: space-between;
|
|
439
465
|
min-block-size: var(--sf-app-header-height);
|
|
440
466
|
padding-inline: var(--sf-space-s-m);
|
|
441
|
-
z-index:
|
|
467
|
+
z-index: var(--sf-z-header);
|
|
442
468
|
}
|
|
443
469
|
|
|
444
470
|
.sf-app-shell[data-layout~="fixed-header"] {
|
|
@@ -521,6 +547,7 @@
|
|
|
521
547
|
}
|
|
522
548
|
|
|
523
549
|
.sf-app-shell[data-mobile="drawer"] .sf-app-sidebar {
|
|
550
|
+
block-size: 100dvh;
|
|
524
551
|
box-shadow: var(--sf-shadow-xl);
|
|
525
552
|
inline-size: min(18rem, calc(100vw - var(--sf-space-l)));
|
|
526
553
|
inset-block: 0;
|
|
@@ -529,7 +556,7 @@
|
|
|
529
556
|
min-block-size: 100dvh;
|
|
530
557
|
position: fixed;
|
|
531
558
|
transform: translateX(-100%);
|
|
532
|
-
z-index:
|
|
559
|
+
z-index: var(--sf-z-drawer);
|
|
533
560
|
}
|
|
534
561
|
|
|
535
562
|
.sf-app-shell[data-mobile="drawer"][data-sidebar-open="true"] .sf-app-sidebar {
|
|
@@ -541,7 +568,7 @@
|
|
|
541
568
|
display: block;
|
|
542
569
|
inset: 0;
|
|
543
570
|
position: fixed;
|
|
544
|
-
z-index:
|
|
571
|
+
z-index: var(--sf-z-backdrop);
|
|
545
572
|
}
|
|
546
573
|
}
|
|
547
574
|
|
|
@@ -685,7 +712,7 @@
|
|
|
685
712
|
.sf-sticky-top {
|
|
686
713
|
position: sticky;
|
|
687
714
|
inset-block-start: var(--sf-sticky-offset, 0);
|
|
688
|
-
z-index: var(--sf-sticky-z,
|
|
715
|
+
z-index: var(--sf-sticky-z, var(--sf-z-sticky));
|
|
689
716
|
}
|
|
690
717
|
|
|
691
718
|
.sf-media-object {
|
|
@@ -1206,6 +1233,16 @@
|
|
|
1206
1233
|
to { transform: translateX(-50%); }
|
|
1207
1234
|
}
|
|
1208
1235
|
|
|
1236
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1237
|
+
:where(.sf-button:hover, .sf-card--interactive:hover) {
|
|
1238
|
+
transform: none;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
.sf-marquee__track {
|
|
1242
|
+
animation: none;
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1209
1246
|
.sf-command-list {
|
|
1210
1247
|
display: grid;
|
|
1211
1248
|
font-family: var(--sf-font-mono);
|
|
@@ -1611,7 +1648,7 @@
|
|
|
1611
1648
|
}
|
|
1612
1649
|
|
|
1613
1650
|
.sf-filter-bar {
|
|
1614
|
-
align-items:
|
|
1651
|
+
align-items: var(--sf-filter-bar-align, center);
|
|
1615
1652
|
background: var(--sf-colour-surface);
|
|
1616
1653
|
border: 1px solid var(--sf-colour-border);
|
|
1617
1654
|
border-radius: var(--sf-radius-panel);
|
|
@@ -1758,6 +1795,10 @@
|
|
|
1758
1795
|
inline-size: .42em;
|
|
1759
1796
|
}
|
|
1760
1797
|
|
|
1798
|
+
:where(.sf-status[data-dot="false"], .sf-status--label)::before {
|
|
1799
|
+
content: none;
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1761
1802
|
.sf-status[data-tone="success"] {
|
|
1762
1803
|
--sf-status-bg: var(--sf-colour-success-soft);
|
|
1763
1804
|
--sf-status-border: color-mix(in oklch, var(--sf-colour-success) 34%, transparent);
|
|
@@ -2192,6 +2233,7 @@
|
|
|
2192
2233
|
:where(.sf-popover, .sf-menu-popover, .sf-tooltip, .sf-toast, .sf-banner, .sf-drawer):popover-open {
|
|
2193
2234
|
display: grid;
|
|
2194
2235
|
gap: var(--sf-space-xs);
|
|
2236
|
+
z-index: var(--sf-z-overlay);
|
|
2195
2237
|
}
|
|
2196
2238
|
|
|
2197
2239
|
.sf-popover {
|
|
@@ -2263,7 +2305,7 @@
|
|
|
2263
2305
|
inset-block-start: var(--sf-space-s);
|
|
2264
2306
|
inset-inline-end: var(--sf-space-s);
|
|
2265
2307
|
position: fixed;
|
|
2266
|
-
z-index:
|
|
2308
|
+
z-index: var(--sf-z-toast);
|
|
2267
2309
|
}
|
|
2268
2310
|
|
|
2269
2311
|
.sf-banner {
|
|
@@ -2378,6 +2420,7 @@
|
|
|
2378
2420
|
}
|
|
2379
2421
|
|
|
2380
2422
|
.sf-tab {
|
|
2423
|
+
align-items: center;
|
|
2381
2424
|
border-block-end: 0.125rem solid transparent;
|
|
2382
2425
|
border-radius: var(--sf-radius-full);
|
|
2383
2426
|
color: var(--sf-colour-muted);
|
|
@@ -2656,7 +2699,7 @@
|
|
|
2656
2699
|
text-decoration: none;
|
|
2657
2700
|
transform: translateY(calc(-100% - var(--sf-space-m)));
|
|
2658
2701
|
transition: opacity var(--sf-duration-fast) var(--sf-ease-standard), transform var(--sf-duration-fast) var(--sf-ease-standard);
|
|
2659
|
-
z-index:
|
|
2702
|
+
z-index: var(--sf-z-skip-link);
|
|
2660
2703
|
}
|
|
2661
2704
|
|
|
2662
2705
|
.sf-skip-link:focus-visible {
|
package/tokens.css
CHANGED
|
@@ -150,6 +150,13 @@
|
|
|
150
150
|
--sf-shadow-xl: 0 1.75rem 4rem oklch(0% 0 0 / 0.18);
|
|
151
151
|
--sf-shadow-inset: inset 0 0 0 1px var(--sf-colour-border);
|
|
152
152
|
--sf-shadow-glow: 0 0 2rem oklch(68% 0.18 44 / 0.24);
|
|
153
|
+
--sf-z-sticky: 20;
|
|
154
|
+
--sf-z-header: 20;
|
|
155
|
+
--sf-z-backdrop: 25;
|
|
156
|
+
--sf-z-drawer: 30;
|
|
157
|
+
--sf-z-overlay: 40;
|
|
158
|
+
--sf-z-toast: 50;
|
|
159
|
+
--sf-z-skip-link: 999;
|
|
153
160
|
--sf-duration-fast: 150ms;
|
|
154
161
|
--sf-duration-normal: 220ms;
|
|
155
162
|
--sf-duration-slow: 360ms;
|
|
@@ -210,6 +217,25 @@
|
|
|
210
217
|
--sf-colour-border: oklch(100% 0 0 / 0.14);
|
|
211
218
|
--sf-colour-border-strong: oklch(100% 0 0 / 0.24);
|
|
212
219
|
--sf-colour-backdrop: oklch(0% 0 0 / 0.64);
|
|
220
|
+
--sf-colour-primary: var(--sf-colour-orange-500);
|
|
221
|
+
--sf-colour-primary-hover: oklch(80% 0.14 50);
|
|
222
|
+
--sf-colour-primary-foreground: var(--sf-colour-neutral-950);
|
|
223
|
+
--sf-colour-primary-soft: oklch(74% 0.17 48 / 0.18);
|
|
224
|
+
--sf-colour-primary-soft-border: oklch(74% 0.17 48 / 0.34);
|
|
213
225
|
--sf-colour-link: var(--sf-colour-orange-500);
|
|
214
226
|
--sf-colour-link-hover: oklch(80% 0.14 50);
|
|
227
|
+
--sf-colour-success: oklch(72% 0.13 150);
|
|
228
|
+
--sf-colour-success-foreground: var(--sf-colour-neutral-950);
|
|
229
|
+
--sf-colour-success-soft: oklch(72% 0.13 150 / 0.16);
|
|
230
|
+
--sf-colour-warning: oklch(84% 0.15 82);
|
|
231
|
+
--sf-colour-warning-foreground: var(--sf-colour-neutral-950);
|
|
232
|
+
--sf-colour-warning-soft: oklch(84% 0.15 82 / 0.18);
|
|
233
|
+
--sf-colour-danger: oklch(70% 0.18 28);
|
|
234
|
+
--sf-colour-danger-foreground: var(--sf-colour-neutral-950);
|
|
235
|
+
--sf-colour-danger-soft: oklch(70% 0.18 28 / 0.16);
|
|
236
|
+
--sf-colour-info: oklch(76% 0.12 205);
|
|
237
|
+
--sf-colour-info-foreground: var(--sf-colour-neutral-950);
|
|
238
|
+
--sf-colour-info-soft: oklch(76% 0.12 205 / 0.16);
|
|
239
|
+
--sf-colour-ring: var(--sf-colour-orange-500);
|
|
240
|
+
--sf-shadow-glow: 0 0 2rem oklch(74% 0.17 48 / 0.18);
|
|
215
241
|
}
|
package/utilities.css
CHANGED
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
text-decoration: none;
|
|
146
146
|
transform: translateY(calc(-100% - var(--sf-space-m)));
|
|
147
147
|
transition: opacity var(--sf-duration-fast) var(--sf-ease-standard), transform var(--sf-duration-fast) var(--sf-ease-standard);
|
|
148
|
-
z-index:
|
|
148
|
+
z-index: var(--sf-z-skip-link);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
.sf-skip-link:focus-visible {
|