@syncedco/flow 0.3.1 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.2 - 2026-06-15
4
+
5
+ - Add an explicit accessible root typography baseline with `html { font-size: 100%; }`.
6
+ - Add `--sf-text-base` and generated `--text-base` aliases for fluid body text.
7
+ - Use the new fluid body text token in shipped and generated base CSS.
8
+ - Convert CLI-generated utility lengths for blur, rings, outlines, and thicker borders from static `px` to `rem`.
9
+ - Extend guardrails and tests so shipped generated examples reject raw pixels outside allowed hairline, visually-hidden, and forced-colors exceptions.
10
+
3
11
  ## 0.3.1 - 2026-06-13
4
12
 
5
13
  - Fix mobile app drawer scrolling by giving the drawer sidebar a viewport block size.
package/base.css CHANGED
@@ -4,6 +4,7 @@
4
4
  html {
5
5
  background: var(--sf-colour-background);
6
6
  color: var(--sf-colour-foreground);
7
+ font-size: 100%;
7
8
  scroll-behavior: smooth;
8
9
  }
9
10
 
@@ -11,7 +12,7 @@
11
12
  background: var(--sf-colour-background);
12
13
  color: var(--sf-colour-foreground);
13
14
  font-family: var(--sf-font-sans);
14
- font-size: var(--sf-type-body);
15
+ font-size: var(--sf-text-base);
15
16
  line-height: var(--sf-line-height-body);
16
17
  -webkit-font-smoothing: antialiased;
17
18
  text-rendering: optimizeLegibility;
@@ -2980,6 +2980,19 @@ function pxToRem(value) {
2980
2980
  })
2981
2981
  }
2982
2982
 
2983
+ function pixelNumberToRem(value) {
2984
+ const number = Number(value)
2985
+ if (Number.isNaN(number)) return null
2986
+ if (number === 0) return '0'
2987
+ return `${round(number / 16)}rem`
2988
+ }
2989
+
2990
+ function borderWidthUnit(value) {
2991
+ if (value === '0') return '0'
2992
+ if (value === '1') return '1px'
2993
+ return pixelNumberToRem(value)
2994
+ }
2995
+
2983
2996
  function arbitraryValue(value) {
2984
2997
  return pxToRem(value.replace(/_/g, ' '))
2985
2998
  }
@@ -3650,7 +3663,7 @@ function colourUtility(base) {
3650
3663
  function borderUtility(base) {
3651
3664
  if (base === 'border') return [['border-width', '1px']]
3652
3665
  if (base === 'border-0') return [['border-width', '0']]
3653
- if (base === 'border-2') return [['border-width', '2px']]
3666
+ if (base === 'border-2') return [['border-width', '0.125rem']]
3654
3667
  if (base === 'border-t') return [['border-top-width', '1px']]
3655
3668
  if (base === 'border-r') return [['border-right-width', '1px']]
3656
3669
  if (base === 'border-b') return [['border-bottom-width', '1px']]
@@ -3660,7 +3673,7 @@ function borderUtility(base) {
3660
3673
  const sideWidth = base.match(/^border-(t|r|b|l)-(\d+)$/)
3661
3674
  if (sideWidth) {
3662
3675
  const side = { t: 'top', r: 'right', b: 'bottom', l: 'left' }[sideWidth[1]]
3663
- return [[`border-${side}-width`, `${sideWidth[2]}px`]]
3676
+ return [[`border-${side}-width`, borderWidthUnit(sideWidth[2])]]
3664
3677
  }
3665
3678
  if (base === 'divide-y') return [['--sf-divide-y', '1px']]
3666
3679
  if (base === 'divide-x') return [['--sf-divide-x', '1px']]
@@ -3724,26 +3737,26 @@ function effectUtility(base) {
3724
3737
  if (match) return [['opacity', String(Number(match[1]) / 100)]]
3725
3738
  match = base.match(/^blur-(none|sm|md|lg|xl|2xl|3xl)$/)
3726
3739
  if (match) {
3727
- const map = { none: '0', sm: '4px', md: '12px', lg: '16px', xl: '24px', '2xl': '40px', '3xl': '64px' }
3740
+ const map = { none: '0', sm: '0.25rem', md: '0.75rem', lg: '1rem', xl: '1.5rem', '2xl': '2.5rem', '3xl': '4rem' }
3728
3741
  return [['filter', `blur(${map[match[1]]})`]]
3729
3742
  }
3730
3743
  match = base.match(/^backdrop-blur(?:-(none|sm|md|lg|xl))?$/)
3731
3744
  if (match) {
3732
- const map = { undefined: '8px', none: '0', sm: '4px', md: '12px', lg: '16px', xl: '24px' }
3745
+ const map = { undefined: '0.5rem', none: '0', sm: '0.25rem', md: '0.75rem', lg: '1rem', xl: '1.5rem' }
3733
3746
  return [['backdrop-filter', `blur(${map[match[1] ?? 'undefined']})`]]
3734
3747
  }
3735
3748
  match = base.match(/^ring(?:-(\d+))?$/)
3736
- if (match) return [['box-shadow', `0 0 0 ${match[1] ?? 3}px var(--sf-ring-color, var(--color-ring))`]]
3749
+ if (match) return [['box-shadow', `0 0 0 ${pixelNumberToRem(match[1] ?? 3)} var(--sf-ring-color, var(--color-ring))`]]
3737
3750
  if (base === 'ring-offset-white') return [['--sf-ring-offset-color', 'var(--color-white)']]
3738
3751
  if (base === 'ring-offset-background') return [['--sf-ring-offset-color', 'var(--color-background)']]
3739
3752
  match = base.match(/^ring-offset-(\d+)$/)
3740
- if (match) return [['--sf-ring-offset-width', `${match[1]}px`]]
3753
+ if (match) return [['--sf-ring-offset-width', pixelNumberToRem(match[1])]]
3741
3754
  if (base === 'outline') return [['outline-style', 'solid']]
3742
- if (base === 'outline-none') return [['outline', '2px solid transparent'], ['outline-offset', '2px']]
3755
+ if (base === 'outline-none') return [['outline', '0.125rem solid transparent'], ['outline-offset', '0.125rem']]
3743
3756
  match = base.match(/^outline-(\d+)$/)
3744
- if (match) return [['outline-width', `${match[1]}px`]]
3757
+ if (match) return [['outline-width', pixelNumberToRem(match[1])]]
3745
3758
  match = base.match(/^outline-offset-(\d+)$/)
3746
- if (match) return [['outline-offset', `${match[1]}px`]]
3759
+ if (match) return [['outline-offset', pixelNumberToRem(match[1])]]
3747
3760
  match = base.match(/^outline-(.+)$/)
3748
3761
  if (match) {
3749
3762
  const value = colourValue(match[1])
@@ -3944,6 +3957,7 @@ function buildTokensCss() {
3944
3957
 
3945
3958
  ${steps.join('\n')}
3946
3959
  --type-caption-sm: var(--step--2);
3960
+ --text-base: var(--step-0);
3947
3961
 
3948
3962
  ${spaces.join('\n')}
3949
3963
  ${pairs.join('\n')}
@@ -4074,7 +4088,7 @@ function buildBaseCss() {
4074
4088
  return `@layer reset {
4075
4089
  *, *::before, *::after { box-sizing: border-box; }
4076
4090
  *:where(:not(dialog)) { margin: 0; }
4077
- html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
4091
+ html { font-size: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
4078
4092
  body { min-block-size: 100%; }
4079
4093
  img, picture, video, canvas, svg { display: block; max-inline-size: 100%; }
4080
4094
  img, video { block-size: auto; }
@@ -4084,11 +4098,15 @@ function buildBaseCss() {
4084
4098
  }
4085
4099
 
4086
4100
  @layer base {
4101
+ html {
4102
+ font-size: 100%;
4103
+ }
4104
+
4087
4105
  body {
4088
4106
  background: var(--color-background);
4089
4107
  color: var(--color-foreground);
4090
4108
  font-family: var(--font-inter, var(--sf-font-sans, ui-sans-serif, system-ui, sans-serif));
4091
- font-size: var(--step-0);
4109
+ font-size: var(--text-base);
4092
4110
  line-height: 1.5;
4093
4111
  font-feature-settings: "rlig" 1, "calt" 1;
4094
4112
  -webkit-font-smoothing: antialiased;
@@ -4116,7 +4134,7 @@ function buildBaseCss() {
4116
4134
  :where(button:disabled, [aria-disabled="true"]) { cursor: not-allowed; }
4117
4135
 
4118
4136
  :where(:focus-visible) {
4119
- outline: 2px solid var(--color-ring);
4137
+ outline: 0.125rem solid var(--color-ring);
4120
4138
  outline-offset: .2rem;
4121
4139
  }
4122
4140
 
@@ -111,3 +111,8 @@ The base layer uses cascade layers, logical properties, low-specificity
111
111
  `prefers-reduced-motion`. Utopia informs the fluid type, space, and grid
112
112
  tokens; Synced Flow owns the reset, accessibility helpers, and component
113
113
  defaults.
114
+
115
+ The root element is kept at `font-size: 100%` rather than a fixed pixel value so
116
+ browser and user font-size settings remain respected. Body copy starts from the
117
+ fluid text token with `body { font-size: var(--sf-text-base); }`, where
118
+ `--sf-text-base` maps to the existing body type scale.
@@ -10,7 +10,7 @@ Use the `--sf-*` variables as the stable CSS foundation.
10
10
  | Layer | Examples | Use for |
11
11
  | --- | --- | --- |
12
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. |
13
+ | Type | `--sf-text-base`, `--sf-type-body`, `--sf-type-lead`, `--sf-type-h1`, `--sf-type-display` | Fluid text sizes. |
14
14
  | Space | `--sf-space-s`, `--sf-space-m-l`, `--sf-space-xl-2xl` | Fluid padding, margin, and gaps. |
15
15
  | Radius | `--sf-radius-control`, `--sf-radius-panel`, `--sf-radius-full` | Controls, panels, pills. |
16
16
  | Colour | `--sf-colour-background`, `--sf-colour-surface`, `--sf-colour-primary` | Semantic UI colour roles. |
package/docs/tokens.md CHANGED
@@ -64,10 +64,15 @@ Type and space tokens use Utopia-style `clamp()` values.
64
64
 
65
65
  ```css
66
66
  --sf-step-0: clamp(1rem, 0.9617rem + 0.1701vw, 1.125rem);
67
+ --sf-type-body: var(--sf-step-0);
68
+ --sf-text-base: var(--sf-type-body);
67
69
  --sf-space-s-l: clamp(1rem, 0.6173rem + 1.7007vw, 2.25rem);
68
70
  ```
69
71
 
70
- Prefer these tokens for new project CSS instead of fixed pixel values.
72
+ Prefer these tokens for new project CSS instead of fixed pixel values. The root
73
+ `html` element stays at `font-size: 100%` so browser and user accessibility
74
+ settings remain in control; Synced Flow starts its fluid body scale from
75
+ `--sf-text-base`.
71
76
 
72
77
  ## Core Starter Tokens
73
78
 
@@ -19,6 +19,8 @@
19
19
  --step-6: clamp(2.986rem, 2.5863rem + 1.7763vw, 4.2915rem);
20
20
  --step-7: clamp(3.5832rem, 3.0379rem + 2.4235vw, 5.3644rem);
21
21
  --step-8: clamp(4.2998rem, 3.5634rem + 3.2731vw, 6.7055rem);
22
+ --type-caption-sm: var(--step--2);
23
+ --text-base: var(--step-0);
22
24
 
23
25
  --space-3xs: clamp(0.25rem, 0.2404rem + 0.0425vw, 0.2813rem);
24
26
  --space-2xs: clamp(0.5rem, 0.4809rem + 0.085vw, 0.5625rem);
@@ -88,7 +90,9 @@
88
90
  --color-destructive: var(--sf-colour-destructive, oklch(55% 0.2 28));
89
91
  --color-destructive-foreground: var(--sf-colour-destructive-foreground, oklch(98% 0.01 95));
90
92
  --color-border: var(--sf-colour-border, oklch(100% 0 0 / 0.12));
93
+ --color-border-subtle: var(--sf-colour-border-subtle, oklch(100% 0 0 / 0.08));
91
94
  --color-input: var(--sf-colour-input, oklch(100% 0 0 / 0.12));
95
+ --color-backdrop: var(--sf-colour-backdrop, oklch(0% 0 0 / 0.56));
92
96
  --color-ring: var(--sf-colour-ring, oklch(69% 0.18 44));
93
97
  --color-heading: var(--sf-colour-heading, oklch(20% 0.02 18));
94
98
  --color-page-text: var(--sf-colour-page-text, oklch(23% 0.02 18));
@@ -97,6 +101,14 @@
97
101
  --color-subdued: var(--sf-colour-subdued, oklch(42% 0.02 20));
98
102
  --color-surface: var(--sf-colour-surface, oklch(96% 0.015 80));
99
103
  --color-surface-alt: var(--sf-colour-surface-alt, oklch(96.6% 0.018 82));
104
+ --color-surface-hover: var(--sf-colour-surface-hover, color-mix(in oklch, var(--color-surface-alt) 86%, var(--color-primary)));
105
+ --color-surface-raised-2: var(--sf-colour-surface-raised-2, color-mix(in oklch, var(--color-surface) 86%, white));
106
+ --color-categorical-1: var(--sf-colour-categorical-1, var(--color-primary));
107
+ --color-categorical-2: var(--sf-colour-categorical-2, var(--color-green));
108
+ --color-categorical-3: var(--sf-colour-categorical-3, var(--color-deco-blue));
109
+ --color-categorical-4: var(--sf-colour-categorical-4, var(--color-deco-lime));
110
+ --color-categorical-5: var(--sf-colour-categorical-5, var(--color-warm-icon));
111
+ --color-categorical-6: var(--sf-colour-categorical-6, var(--color-purple-icon));
100
112
  --color-hero-bg: oklch(8% 0.02 260);
101
113
  --color-green: var(--sf-colour-green, oklch(55% 0.12 148));
102
114
  --color-green-dark: var(--sf-colour-green-dark, oklch(45% 0.12 148));
@@ -168,6 +180,8 @@
168
180
  --color-surface: var(--sf-colour-surface);
169
181
  --sf-colour-surface-alt: oklch(94% 0.02 80);
170
182
  --color-surface-alt: var(--sf-colour-surface-alt);
183
+ --sf-colour-surface-elevated: var(--sf-colour-surface-raised);
184
+ --color-surface-elevated: var(--sf-colour-surface-elevated);
171
185
  --sf-colour-border: oklch(18% 0.022 55 / 0.14);
172
186
  --color-border: var(--sf-colour-border);
173
187
  --sf-colour-primary: oklch(58% 0.17 42);
@@ -19,6 +19,8 @@
19
19
  --step-6: clamp(2.986rem, 2.5863rem + 1.7763vw, 4.2915rem);
20
20
  --step-7: clamp(3.5832rem, 3.0379rem + 2.4235vw, 5.3644rem);
21
21
  --step-8: clamp(4.2998rem, 3.5634rem + 3.2731vw, 6.7055rem);
22
+ --type-caption-sm: var(--step--2);
23
+ --text-base: var(--step-0);
22
24
 
23
25
  --space-3xs: clamp(0.25rem, 0.2404rem + 0.0425vw, 0.2813rem);
24
26
  --space-2xs: clamp(0.5rem, 0.4809rem + 0.085vw, 0.5625rem);
@@ -88,7 +90,9 @@
88
90
  --color-destructive: var(--sf-colour-destructive, oklch(55% 0.2 28));
89
91
  --color-destructive-foreground: var(--sf-colour-destructive-foreground, oklch(98% 0.01 95));
90
92
  --color-border: var(--sf-colour-border, oklch(100% 0 0 / 0.12));
93
+ --color-border-subtle: var(--sf-colour-border-subtle, oklch(100% 0 0 / 0.08));
91
94
  --color-input: var(--sf-colour-input, oklch(100% 0 0 / 0.12));
95
+ --color-backdrop: var(--sf-colour-backdrop, oklch(0% 0 0 / 0.56));
92
96
  --color-ring: var(--sf-colour-ring, oklch(69% 0.18 44));
93
97
  --color-heading: var(--sf-colour-heading, oklch(20% 0.02 18));
94
98
  --color-page-text: var(--sf-colour-page-text, oklch(23% 0.02 18));
@@ -97,6 +101,14 @@
97
101
  --color-subdued: var(--sf-colour-subdued, oklch(42% 0.02 20));
98
102
  --color-surface: var(--sf-colour-surface, oklch(96% 0.015 80));
99
103
  --color-surface-alt: var(--sf-colour-surface-alt, oklch(96.6% 0.018 82));
104
+ --color-surface-hover: var(--sf-colour-surface-hover, color-mix(in oklch, var(--color-surface-alt) 86%, var(--color-primary)));
105
+ --color-surface-raised-2: var(--sf-colour-surface-raised-2, color-mix(in oklch, var(--color-surface) 86%, white));
106
+ --color-categorical-1: var(--sf-colour-categorical-1, var(--color-primary));
107
+ --color-categorical-2: var(--sf-colour-categorical-2, var(--color-green));
108
+ --color-categorical-3: var(--sf-colour-categorical-3, var(--color-deco-blue));
109
+ --color-categorical-4: var(--sf-colour-categorical-4, var(--color-deco-lime));
110
+ --color-categorical-5: var(--sf-colour-categorical-5, var(--color-warm-icon));
111
+ --color-categorical-6: var(--sf-colour-categorical-6, var(--color-purple-icon));
100
112
  --color-hero-bg: oklch(8% 0.02 260);
101
113
  --color-green: var(--sf-colour-green, oklch(55% 0.12 148));
102
114
  --color-green-dark: var(--sf-colour-green-dark, oklch(45% 0.12 148));
@@ -168,6 +180,8 @@
168
180
  --color-surface: var(--sf-colour-surface);
169
181
  --sf-colour-surface-alt: oklch(96.4% 0.011 80);
170
182
  --color-surface-alt: var(--sf-colour-surface-alt);
183
+ --sf-colour-surface-elevated: var(--sf-colour-surface-raised);
184
+ --color-surface-elevated: var(--sf-colour-surface-elevated);
171
185
  --sf-colour-border: oklch(18% 0.026 250 / 0.12);
172
186
  --color-border: var(--sf-colour-border);
173
187
  --sf-colour-primary: oklch(68% 0.18 44);
@@ -19,6 +19,8 @@
19
19
  --step-6: clamp(2.986rem, 2.5863rem + 1.7763vw, 4.2915rem);
20
20
  --step-7: clamp(3.5832rem, 3.0379rem + 2.4235vw, 5.3644rem);
21
21
  --step-8: clamp(4.2998rem, 3.5634rem + 3.2731vw, 6.7055rem);
22
+ --type-caption-sm: var(--step--2);
23
+ --text-base: var(--step-0);
22
24
 
23
25
  --space-3xs: clamp(0.25rem, 0.2404rem + 0.0425vw, 0.2813rem);
24
26
  --space-2xs: clamp(0.5rem, 0.4809rem + 0.085vw, 0.5625rem);
@@ -88,7 +90,9 @@
88
90
  --color-destructive: var(--sf-colour-destructive, oklch(55% 0.2 28));
89
91
  --color-destructive-foreground: var(--sf-colour-destructive-foreground, oklch(98% 0.01 95));
90
92
  --color-border: var(--sf-colour-border, oklch(100% 0 0 / 0.12));
93
+ --color-border-subtle: var(--sf-colour-border-subtle, oklch(100% 0 0 / 0.08));
91
94
  --color-input: var(--sf-colour-input, oklch(100% 0 0 / 0.12));
95
+ --color-backdrop: var(--sf-colour-backdrop, oklch(0% 0 0 / 0.56));
92
96
  --color-ring: var(--sf-colour-ring, oklch(69% 0.18 44));
93
97
  --color-heading: var(--sf-colour-heading, oklch(20% 0.02 18));
94
98
  --color-page-text: var(--sf-colour-page-text, oklch(23% 0.02 18));
@@ -97,6 +101,14 @@
97
101
  --color-subdued: var(--sf-colour-subdued, oklch(42% 0.02 20));
98
102
  --color-surface: var(--sf-colour-surface, oklch(96% 0.015 80));
99
103
  --color-surface-alt: var(--sf-colour-surface-alt, oklch(96.6% 0.018 82));
104
+ --color-surface-hover: var(--sf-colour-surface-hover, color-mix(in oklch, var(--color-surface-alt) 86%, var(--color-primary)));
105
+ --color-surface-raised-2: var(--sf-colour-surface-raised-2, color-mix(in oklch, var(--color-surface) 86%, white));
106
+ --color-categorical-1: var(--sf-colour-categorical-1, var(--color-primary));
107
+ --color-categorical-2: var(--sf-colour-categorical-2, var(--color-green));
108
+ --color-categorical-3: var(--sf-colour-categorical-3, var(--color-deco-blue));
109
+ --color-categorical-4: var(--sf-colour-categorical-4, var(--color-deco-lime));
110
+ --color-categorical-5: var(--sf-colour-categorical-5, var(--color-warm-icon));
111
+ --color-categorical-6: var(--sf-colour-categorical-6, var(--color-purple-icon));
100
112
  --color-hero-bg: oklch(8% 0.02 260);
101
113
  --color-green: var(--sf-colour-green, oklch(55% 0.12 148));
102
114
  --color-green-dark: var(--sf-colour-green-dark, oklch(45% 0.12 148));
@@ -168,6 +180,8 @@
168
180
  --color-surface: var(--sf-colour-surface);
169
181
  --sf-colour-surface-alt: oklch(96.4% 0.011 80);
170
182
  --color-surface-alt: var(--sf-colour-surface-alt);
183
+ --sf-colour-surface-elevated: var(--sf-colour-surface-raised);
184
+ --color-surface-elevated: var(--sf-colour-surface-elevated);
171
185
  --sf-colour-border: oklch(18% 0.026 250 / 0.12);
172
186
  --color-border: var(--sf-colour-border);
173
187
  --sf-colour-primary: oklch(68% 0.18 44);
@@ -19,6 +19,8 @@
19
19
  --step-6: clamp(2.986rem, 2.5863rem + 1.7763vw, 4.2915rem);
20
20
  --step-7: clamp(3.5832rem, 3.0379rem + 2.4235vw, 5.3644rem);
21
21
  --step-8: clamp(4.2998rem, 3.5634rem + 3.2731vw, 6.7055rem);
22
+ --type-caption-sm: var(--step--2);
23
+ --text-base: var(--step-0);
22
24
 
23
25
  --space-3xs: clamp(0.25rem, 0.2404rem + 0.0425vw, 0.2813rem);
24
26
  --space-2xs: clamp(0.5rem, 0.4809rem + 0.085vw, 0.5625rem);
@@ -88,7 +90,9 @@
88
90
  --color-destructive: var(--sf-colour-destructive, oklch(55% 0.2 28));
89
91
  --color-destructive-foreground: var(--sf-colour-destructive-foreground, oklch(98% 0.01 95));
90
92
  --color-border: var(--sf-colour-border, oklch(100% 0 0 / 0.12));
93
+ --color-border-subtle: var(--sf-colour-border-subtle, oklch(100% 0 0 / 0.08));
91
94
  --color-input: var(--sf-colour-input, oklch(100% 0 0 / 0.12));
95
+ --color-backdrop: var(--sf-colour-backdrop, oklch(0% 0 0 / 0.56));
92
96
  --color-ring: var(--sf-colour-ring, oklch(69% 0.18 44));
93
97
  --color-heading: var(--sf-colour-heading, oklch(20% 0.02 18));
94
98
  --color-page-text: var(--sf-colour-page-text, oklch(23% 0.02 18));
@@ -97,6 +101,14 @@
97
101
  --color-subdued: var(--sf-colour-subdued, oklch(42% 0.02 20));
98
102
  --color-surface: var(--sf-colour-surface, oklch(96% 0.015 80));
99
103
  --color-surface-alt: var(--sf-colour-surface-alt, oklch(96.6% 0.018 82));
104
+ --color-surface-hover: var(--sf-colour-surface-hover, color-mix(in oklch, var(--color-surface-alt) 86%, var(--color-primary)));
105
+ --color-surface-raised-2: var(--sf-colour-surface-raised-2, color-mix(in oklch, var(--color-surface) 86%, white));
106
+ --color-categorical-1: var(--sf-colour-categorical-1, var(--color-primary));
107
+ --color-categorical-2: var(--sf-colour-categorical-2, var(--color-green));
108
+ --color-categorical-3: var(--sf-colour-categorical-3, var(--color-deco-blue));
109
+ --color-categorical-4: var(--sf-colour-categorical-4, var(--color-deco-lime));
110
+ --color-categorical-5: var(--sf-colour-categorical-5, var(--color-warm-icon));
111
+ --color-categorical-6: var(--sf-colour-categorical-6, var(--color-purple-icon));
100
112
  --color-hero-bg: oklch(8% 0.02 260);
101
113
  --color-green: var(--sf-colour-green, oklch(55% 0.12 148));
102
114
  --color-green-dark: var(--sf-colour-green-dark, oklch(45% 0.12 148));
@@ -168,6 +180,8 @@
168
180
  --color-surface: var(--sf-colour-surface);
169
181
  --sf-colour-surface-alt: oklch(96.4% 0.011 80);
170
182
  --color-surface-alt: var(--sf-colour-surface-alt);
183
+ --sf-colour-surface-elevated: var(--sf-colour-surface-raised);
184
+ --color-surface-elevated: var(--sf-colour-surface-elevated);
171
185
  --sf-colour-border: oklch(18% 0.026 250 / 0.12);
172
186
  --color-border: var(--sf-colour-border);
173
187
  --sf-colour-primary: oklch(68% 0.18 44);
@@ -19,6 +19,8 @@
19
19
  --step-6: clamp(2.986rem, 2.5863rem + 1.7763vw, 4.2915rem);
20
20
  --step-7: clamp(3.5832rem, 3.0379rem + 2.4235vw, 5.3644rem);
21
21
  --step-8: clamp(4.2998rem, 3.5634rem + 3.2731vw, 6.7055rem);
22
+ --type-caption-sm: var(--step--2);
23
+ --text-base: var(--step-0);
22
24
 
23
25
  --space-3xs: clamp(0.25rem, 0.2404rem + 0.0425vw, 0.2813rem);
24
26
  --space-2xs: clamp(0.5rem, 0.4809rem + 0.085vw, 0.5625rem);
@@ -88,7 +90,9 @@
88
90
  --color-destructive: var(--sf-colour-destructive, oklch(55% 0.2 28));
89
91
  --color-destructive-foreground: var(--sf-colour-destructive-foreground, oklch(98% 0.01 95));
90
92
  --color-border: var(--sf-colour-border, oklch(100% 0 0 / 0.12));
93
+ --color-border-subtle: var(--sf-colour-border-subtle, oklch(100% 0 0 / 0.08));
91
94
  --color-input: var(--sf-colour-input, oklch(100% 0 0 / 0.12));
95
+ --color-backdrop: var(--sf-colour-backdrop, oklch(0% 0 0 / 0.56));
92
96
  --color-ring: var(--sf-colour-ring, oklch(69% 0.18 44));
93
97
  --color-heading: var(--sf-colour-heading, oklch(20% 0.02 18));
94
98
  --color-page-text: var(--sf-colour-page-text, oklch(23% 0.02 18));
@@ -97,6 +101,14 @@
97
101
  --color-subdued: var(--sf-colour-subdued, oklch(42% 0.02 20));
98
102
  --color-surface: var(--sf-colour-surface, oklch(96% 0.015 80));
99
103
  --color-surface-alt: var(--sf-colour-surface-alt, oklch(96.6% 0.018 82));
104
+ --color-surface-hover: var(--sf-colour-surface-hover, color-mix(in oklch, var(--color-surface-alt) 86%, var(--color-primary)));
105
+ --color-surface-raised-2: var(--sf-colour-surface-raised-2, color-mix(in oklch, var(--color-surface) 86%, white));
106
+ --color-categorical-1: var(--sf-colour-categorical-1, var(--color-primary));
107
+ --color-categorical-2: var(--sf-colour-categorical-2, var(--color-green));
108
+ --color-categorical-3: var(--sf-colour-categorical-3, var(--color-deco-blue));
109
+ --color-categorical-4: var(--sf-colour-categorical-4, var(--color-deco-lime));
110
+ --color-categorical-5: var(--sf-colour-categorical-5, var(--color-warm-icon));
111
+ --color-categorical-6: var(--sf-colour-categorical-6, var(--color-purple-icon));
100
112
  --color-hero-bg: oklch(8% 0.02 260);
101
113
  --color-green: var(--sf-colour-green, oklch(55% 0.12 148));
102
114
  --color-green-dark: var(--sf-colour-green-dark, oklch(45% 0.12 148));
@@ -202,7 +214,7 @@
202
214
  @layer reset {
203
215
  *, *::before, *::after { box-sizing: border-box; }
204
216
  *:where(:not(dialog)) { margin: 0; }
205
- html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
217
+ html { font-size: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
206
218
  body { min-block-size: 100%; }
207
219
  img, picture, video, canvas, svg { display: block; max-inline-size: 100%; }
208
220
  img, video { block-size: auto; }
@@ -212,11 +224,15 @@
212
224
  }
213
225
 
214
226
  @layer base {
227
+ html {
228
+ font-size: 100%;
229
+ }
230
+
215
231
  body {
216
232
  background: var(--color-background);
217
233
  color: var(--color-foreground);
218
234
  font-family: var(--font-inter, var(--sf-font-sans, ui-sans-serif, system-ui, sans-serif));
219
- font-size: var(--step-0);
235
+ font-size: var(--text-base);
220
236
  line-height: 1.5;
221
237
  font-feature-settings: "rlig" 1, "calt" 1;
222
238
  -webkit-font-smoothing: antialiased;
@@ -244,7 +260,7 @@
244
260
  :where(button:disabled, [aria-disabled="true"]) { cursor: not-allowed; }
245
261
 
246
262
  :where(:focus-visible) {
247
- outline: 2px solid var(--color-ring);
263
+ outline: 0.125rem solid var(--color-ring);
248
264
  outline-offset: .2rem;
249
265
  }
250
266
 
@@ -330,11 +346,47 @@
330
346
  }
331
347
 
332
348
  .sf-app-shell {
349
+ --sf-app-header-height: 4rem;
350
+ --sf-app-sidebar-collapsed-width: 4.75rem;
333
351
  background: var(--color-background);
334
352
  color: var(--color-foreground);
335
353
  display: grid;
336
354
  grid-template-columns: minmax(14rem, var(--sf-app-sidebar-width, 16rem)) minmax(0, 1fr);
337
355
  min-block-size: 100dvh;
356
+ position: relative;
357
+ transition: grid-template-columns var(--duration-normal) var(--ease-standard);
358
+ }
359
+
360
+ .sf-app-header {
361
+ align-items: center;
362
+ background: var(--color-card);
363
+ border-block-end: 1px solid var(--color-border);
364
+ display: flex;
365
+ gap: var(--space-s);
366
+ grid-column: 1 / -1;
367
+ justify-content: space-between;
368
+ min-block-size: var(--sf-app-header-height);
369
+ padding-inline: var(--space-s-m);
370
+ z-index: 20;
371
+ }
372
+
373
+ .sf-app-shell[data-layout~="fixed-header"] {
374
+ grid-template-rows: var(--sf-app-header-height) minmax(0, 1fr);
375
+ }
376
+
377
+ .sf-app-shell[data-layout~="fixed-header"] .sf-app-header {
378
+ inset-block-start: 0;
379
+ position: sticky;
380
+ }
381
+
382
+ .sf-app-shell[data-layout~="fixed-header"] .sf-app-sidebar {
383
+ inset-block-start: var(--sf-app-header-height);
384
+ max-block-size: calc(100dvh - var(--sf-app-header-height));
385
+ min-block-size: calc(100dvh - var(--sf-app-header-height));
386
+ }
387
+
388
+ .sf-app-shell[data-collapsed="true"] {
389
+ grid-template-columns: var(--sf-app-sidebar-collapsed-width) minmax(0, 1fr);
338
390
  }
339
391
 
340
392
  .sf-app-sidebar {
@@ -350,6 +402,7 @@
350
402
  padding: var(--space-s);
351
403
  position: sticky;
352
404
  inset-block-start: 0;
405
+ transition: transform var(--duration-normal) var(--ease-standard), inline-size var(--duration-normal) var(--ease-standard);
353
406
  }
354
407
 
355
408
  .sf-app-sidebar__brand {
@@ -402,6 +455,58 @@
402
455
  padding: var(--sf-app-main-padding, var(--space-m-l));
403
456
  }
404
457
 
458
+ .sf-app-shell[data-collapsed="true"] .sf-app-sidebar {
459
+ overflow-x: hidden;
460
+ }
461
+
462
+ .sf-app-shell[data-collapsed="true"] .sf-app-sidebar__brand,
463
+ .sf-app-shell[data-collapsed="true"] .sf-app-sidebar .sf-nav__link {
464
+ justify-content: center;
465
+ }
466
+
467
+ .sf-app-shell[data-collapsed="true"] [data-hide-collapsed="true"] {
468
+ display: none;
469
+ }
470
+
471
+ .sf-app-backdrop {
472
+ display: none;
473
+ }
474
+
475
+ @media (max-width: 48rem) {
476
+ .sf-app-shell[data-mobile="drawer"] {
477
+ display: block;
478
+ }
479
+
480
+ .sf-app-shell[data-mobile="drawer"] .sf-app-header {
481
+ position: sticky;
482
+ inset-block-start: 0;
483
+ }
484
+
485
+ .sf-app-shell[data-mobile="drawer"] .sf-app-sidebar {
486
+ box-shadow: var(--shadow-xl);
487
+ inline-size: min(18rem, calc(100vw - var(--space-l)));
488
+ inset-block: 0;
489
+ inset-inline-start: 0;
490
+ max-block-size: none;
491
+ min-block-size: 100dvh;
492
+ position: fixed;
493
+ transform: translateX(-100%);
494
+ z-index: 30;
495
+ }
496
+
497
+ .sf-app-shell[data-mobile="drawer"][data-sidebar-open="true"] .sf-app-sidebar {
498
+ transform: translateX(0);
499
+ }
500
+
501
+ .sf-app-shell[data-mobile="drawer"][data-sidebar-open="true"] .sf-app-backdrop {
502
+ background: var(--color-backdrop);
503
+ display: block;
504
+ inset: 0;
505
+ position: fixed;
506
+ z-index: 25;
507
+ }
508
+ }
509
+
405
510
  .sf-grid {
406
511
  display: grid;
407
512
  gap: var(--grid-gutter);
@@ -725,11 +830,268 @@
725
830
  overflow: hidden;
726
831
  }
727
832
 
833
+ .sf-progress {
834
+ accent-color: var(--progress-color, var(--color-primary));
835
+ block-size: var(--progress-size, .625rem);
836
+ inline-size: 100%;
837
+ }
838
+
839
+ .sf-progress::-webkit-progress-bar {
840
+ background: var(--color-surface-alt);
841
+ border-radius: var(--radius-full);
842
+ }
843
+
844
+ .sf-progress::-webkit-progress-value,
845
+ .sf-progress::-moz-progress-bar {
846
+ background: var(--progress-color, var(--color-primary));
847
+ border-radius: var(--radius-full);
848
+ }
849
+
850
+ .sf-skeleton {
851
+ background: color-mix(in oklch, var(--color-surface-alt) 82%, var(--color-foreground));
852
+ border-radius: var(--skeleton-radius, var(--radius-md));
853
+ color: transparent;
854
+ min-block-size: var(--skeleton-block-size, 1em);
855
+ }
856
+
857
+ @media (prefers-reduced-motion: no-preference) {
858
+ .sf-skeleton {
859
+ animation: sf-skeleton-pulse 1.4s var(--ease-standard) infinite alternate;
860
+ }
861
+ }
862
+
863
+ @keyframes sf-skeleton-pulse {
864
+ to { opacity: .62; }
865
+ }
866
+
867
+ .sf-filter-bar {
868
+ align-items: end;
869
+ background: var(--color-card);
870
+ border: 1px solid var(--color-border);
871
+ border-radius: var(--radius-lg);
872
+ display: flex;
873
+ flex-wrap: wrap;
874
+ gap: var(--space-xs);
875
+ padding: var(--space-s);
876
+ }
877
+
878
+ .sf-filter-bar > :where(.sf-field, form, label) {
879
+ flex: 1 1 min(100%, 14rem);
880
+ }
881
+
882
+ .sf-filter-bar > :where(.sf-button, button, a) {
883
+ flex: 0 0 auto;
884
+ }
885
+
886
+ .sf-data-table {
887
+ border-collapse: collapse;
888
+ inline-size: 100%;
889
+ min-inline-size: var(--data-table-min, 44rem);
890
+ }
891
+
892
+ .sf-data-table :where(th, td) {
893
+ border-block-end: 1px solid var(--color-border);
894
+ padding-block: var(--data-table-padding-block, var(--space-xs));
895
+ padding-inline: var(--data-table-padding-inline, var(--space-s));
896
+ text-align: start;
897
+ vertical-align: middle;
898
+ }
899
+
900
+ .sf-data-table :where(th) {
901
+ background: var(--color-surface-alt);
902
+ color: var(--color-muted-foreground);
903
+ font-size: var(--step--1);
904
+ font-weight: 800;
905
+ }
906
+
907
+ .sf-data-table :where(tbody tr:hover) {
908
+ background: color-mix(in oklch, var(--color-primary) 6%, transparent);
909
+ }
910
+
911
+ .sf-data-table[data-density="compact"] {
912
+ --data-table-padding-block: var(--space-2xs);
913
+ --data-table-padding-inline: var(--space-xs);
914
+ }
915
+
916
+ .sf-data-table :where(th button, .sf-table-sort) {
917
+ align-items: center;
918
+ color: inherit;
919
+ display: inline-flex;
920
+ font: inherit;
921
+ font-weight: inherit;
922
+ gap: var(--space-3xs);
923
+ padding: 0;
924
+ }
925
+
926
+ .sf-data-table :where(th button, .sf-table-sort)[aria-sort]::after {
927
+ color: var(--color-muted-foreground);
928
+ content: "\2195";
929
+ font-size: var(--step--2);
930
+ }
931
+
932
+ .sf-data-table :where(th button, .sf-table-sort)[aria-sort="ascending"]::after { content: "\2191"; }
933
+ .sf-data-table :where(th button, .sf-table-sort)[aria-sort="descending"]::after { content: "\2193"; }
934
+
935
+ .sf-data-table tr[data-clickable="true"] {
936
+ cursor: pointer;
937
+ }
938
+
939
+ .sf-data-table tr[data-clickable="true"]:focus-within {
940
+ outline: 0.125rem solid var(--color-ring);
941
+ outline-offset: -0.125rem;
942
+ }
943
+
944
+ @container (max-width: 38rem) {
945
+ .sf-table-wrap[data-view="cards"] {
946
+ border: 0;
947
+ overflow: visible;
948
+ }
949
+
950
+ .sf-table-wrap[data-view="cards"] .sf-data-table,
951
+ .sf-table-wrap[data-view="cards"] .sf-data-table :where(thead, tbody, tr, th, td) {
952
+ display: block;
953
+ min-inline-size: 0;
954
+ }
955
+
956
+ .sf-table-wrap[data-view="cards"] .sf-data-table thead {
957
+ display: none;
958
+ }
959
+
960
+ .sf-table-wrap[data-view="cards"] .sf-data-table tr {
961
+ background: var(--color-card);
962
+ border: 1px solid var(--color-border);
963
+ border-radius: var(--radius-lg);
964
+ margin-block-end: var(--space-xs);
965
+ padding: var(--space-xs);
966
+ }
967
+
968
+ .sf-table-wrap[data-view="cards"] .sf-data-table td {
969
+ align-items: center;
970
+ border: 0;
971
+ display: flex;
972
+ gap: var(--space-s);
973
+ justify-content: space-between;
974
+ padding-block: var(--space-2xs);
975
+ padding-inline: 0;
976
+ }
977
+
978
+ .sf-table-wrap[data-view="cards"] .sf-data-table td::before {
979
+ color: var(--color-muted-foreground);
980
+ content: attr(data-label);
981
+ font-size: var(--step--1);
982
+ font-weight: 800;
983
+ }
984
+ }
985
+
986
+ .sf-status {
987
+ align-items: center;
988
+ background: var(--status-bg, var(--color-surface-alt));
989
+ border: 1px solid var(--status-border, var(--color-border));
990
+ border-radius: var(--radius-full);
991
+ color: var(--status-color, var(--color-foreground));
992
+ display: inline-flex;
993
+ font-size: var(--step--1);
994
+ font-weight: 700;
995
+ gap: var(--space-3xs);
996
+ line-height: 1;
997
+ min-block-size: 1.75rem;
998
+ padding-inline: .7em;
999
+ }
1000
+
1001
+ .sf-status[data-size="sm"] {
1002
+ font-size: var(--step--2);
1003
+ min-block-size: 1.35rem;
1004
+ padding-inline: .55em;
1005
+ }
1006
+
1007
+ .sf-status::before {
1008
+ background: currentColor;
1009
+ block-size: .42em;
1010
+ border-radius: var(--radius-full);
1011
+ content: "";
1012
+ inline-size: .42em;
1013
+ }
1014
+
1015
+ .sf-status[data-tone="success"] {
1016
+ --status-bg: var(--sf-colour-success-soft, oklch(62% 0.13 150 / 0.12));
1017
+ --status-border: color-mix(in oklch, var(--sf-colour-success, oklch(62% 0.13 150)) 34%, transparent);
1018
+ --status-color: color-mix(in oklch, var(--sf-colour-success, oklch(62% 0.13 150)) 76%, var(--color-foreground));
1019
+ }
1020
+
1021
+ .sf-status[data-tone="warning"] {
1022
+ --status-bg: var(--sf-colour-warning-soft, oklch(78% 0.15 82 / 0.16));
1023
+ --status-border: color-mix(in oklch, var(--sf-colour-warning, oklch(78% 0.15 82)) 38%, transparent);
1024
+ --status-color: color-mix(in oklch, var(--sf-colour-warning, oklch(78% 0.15 82)) 70%, var(--color-foreground));
1025
+ }
1026
+
1027
+ .sf-status[data-tone="danger"] {
1028
+ --status-bg: var(--sf-colour-danger-soft, oklch(56% 0.2 28 / 0.12));
1029
+ --status-border: color-mix(in oklch, var(--sf-colour-danger, var(--color-destructive)) 34%, transparent);
1030
+ --status-color: color-mix(in oklch, var(--sf-colour-danger, var(--color-destructive)) 76%, var(--color-foreground));
1031
+ }
1032
+
1033
+ .sf-status[data-tone="info"] {
1034
+ --status-bg: var(--sf-colour-info-soft, oklch(70% 0.12 205 / 0.14));
1035
+ --status-border: color-mix(in oklch, var(--sf-colour-info, oklch(70% 0.12 205)) 34%, transparent);
1036
+ --status-color: color-mix(in oklch, var(--sf-colour-info, oklch(70% 0.12 205)) 76%, var(--color-foreground));
1037
+ }
1038
+
1039
+ .sf-data-list {
1040
+ display: grid;
1041
+ }
1042
+
1043
+ .sf-data-list > * {
1044
+ align-items: center;
1045
+ border-block-end: 1px solid var(--color-border);
1046
+ display: flex;
1047
+ flex-wrap: wrap;
1048
+ gap: var(--space-xs);
1049
+ justify-content: space-between;
1050
+ padding-block: var(--space-xs);
1051
+ }
1052
+
1053
+ .sf-data-list > :last-child {
1054
+ border-block-end: 0;
1055
+ }
1056
+
1057
+ .sf-empty-state {
1058
+ align-items: center;
1059
+ background: var(--color-surface-alt);
1060
+ border: 1px dashed var(--color-border);
1061
+ border-radius: var(--radius-lg);
1062
+ color: var(--color-muted-foreground);
1063
+ display: grid;
1064
+ gap: var(--space-xs);
1065
+ justify-items: center;
1066
+ padding: var(--space-l);
1067
+ text-align: center;
1068
+ }
1069
+
1070
+ .sf-settings-section,
1071
+ .sf-detail-panel {
1072
+ background: var(--color-card);
1073
+ border: 1px solid var(--color-border);
1074
+ border-radius: var(--radius-lg);
1075
+ display: grid;
1076
+ gap: var(--space-s);
1077
+ padding: var(--space-m);
1078
+ }
1079
+
1080
+ .sf-detail-panel {
1081
+ background: var(--color-surface-alt);
1082
+ }
1083
+
728
1084
  .sf-field {
729
1085
  display: grid;
730
1086
  gap: var(--space-2xs);
731
1087
  }
732
1088
 
1089
+ .sf-form[data-density="compact"],
1090
+ .sf-field[data-density="compact"] {
1091
+ --input-block-size: 2.25rem;
1092
+ --input-padding-inline: var(--space-xs);
1093
+ }
1094
+
733
1095
  .sf-field > label {
734
1096
  color: var(--color-muted-foreground);
735
1097
  font-size: var(--step--1);
@@ -742,7 +1104,41 @@
742
1104
  border-radius: var(--input-radius, var(--radius-md));
743
1105
  color: var(--color-foreground);
744
1106
  min-block-size: var(--input-block-size, 2.75rem);
745
- padding-inline: var(--space-s);
1107
+ padding-inline: var(--input-padding-inline, var(--space-s));
1108
+ }
1109
+
1110
+ .sf-search {
1111
+ position: relative;
1112
+ }
1113
+
1114
+ .sf-search::before {
1115
+ block-size: .75em;
1116
+ border: 0.125em solid currentColor;
1117
+ border-radius: var(--radius-full);
1118
+ color: var(--color-muted-foreground);
1119
+ content: "";
1120
+ inline-size: .75em;
1121
+ inset-block-start: 50%;
1122
+ inset-inline-start: var(--space-xs);
1123
+ line-height: 1;
1124
+ position: absolute;
1125
+ transform: translateY(-58%);
1126
+ }
1127
+
1128
+ .sf-search::after {
1129
+ background: var(--color-muted-foreground);
1130
+ block-size: .125em;
1131
+ content: "";
1132
+ inline-size: .45em;
1133
+ inset-block-start: 50%;
1134
+ inset-inline-start: calc(var(--space-xs) + .58em);
1135
+ position: absolute;
1136
+ transform: translateY(120%) rotate(45deg);
1137
+ transform-origin: inline-start center;
1138
+ }
1139
+
1140
+ .sf-search > .sf-input {
1141
+ padding-inline-start: var(--space-l);
746
1142
  }
747
1143
 
748
1144
  .sf-input:focus-visible {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncedco/flow",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
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",
package/reset.css CHANGED
@@ -3,7 +3,7 @@
3
3
  @layer reset {
4
4
  *, *::before, *::after { box-sizing: border-box; }
5
5
  *:where(:not(dialog)) { margin: 0; }
6
- html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
6
+ html { font-size: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
7
7
  body { min-block-size: 100%; }
8
8
  img, picture, video, canvas, svg { display: block; max-inline-size: 100%; }
9
9
  img, video { block-size: auto; }
package/styles.css CHANGED
@@ -21,6 +21,7 @@
21
21
  --sf-type-caption-sm: var(--sf-step--2);
22
22
  --sf-type-caption: var(--sf-step--1);
23
23
  --sf-type-body: var(--sf-step-0);
24
+ --sf-text-base: var(--sf-type-body);
24
25
  --sf-type-lead: var(--sf-step-1);
25
26
  --sf-type-h6: var(--sf-step-1);
26
27
  --sf-type-h5: var(--sf-step-2);
@@ -242,7 +243,7 @@
242
243
  @layer reset {
243
244
  *, *::before, *::after { box-sizing: border-box; }
244
245
  *:where(:not(dialog)) { margin: 0; }
245
- html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
246
+ html { font-size: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
246
247
  body { min-block-size: 100%; }
247
248
  img, picture, video, canvas, svg { display: block; max-inline-size: 100%; }
248
249
  img, video { block-size: auto; }
@@ -254,6 +255,7 @@
254
255
  html {
255
256
  background: var(--sf-colour-background);
256
257
  color: var(--sf-colour-foreground);
258
+ font-size: 100%;
257
259
  scroll-behavior: smooth;
258
260
  }
259
261
 
@@ -261,7 +263,7 @@
261
263
  background: var(--sf-colour-background);
262
264
  color: var(--sf-colour-foreground);
263
265
  font-family: var(--sf-font-sans);
264
- font-size: var(--sf-type-body);
266
+ font-size: var(--sf-text-base);
265
267
  line-height: var(--sf-line-height-body);
266
268
  -webkit-font-smoothing: antialiased;
267
269
  text-rendering: optimizeLegibility;
package/tokens.css CHANGED
@@ -21,6 +21,7 @@
21
21
  --sf-type-caption-sm: var(--sf-step--2);
22
22
  --sf-type-caption: var(--sf-step--1);
23
23
  --sf-type-body: var(--sf-step-0);
24
+ --sf-text-base: var(--sf-type-body);
24
25
  --sf-type-lead: var(--sf-step-1);
25
26
  --sf-type-h6: var(--sf-step-1);
26
27
  --sf-type-h5: var(--sf-step-2);