@putdotio/design 1.1.0 → 1.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putdotio/design",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Public put.io design tokens, brand assets, and design-system guidance.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -65,7 +65,7 @@
65
65
  "scripts": {
66
66
  "dev": "node scripts/serve-system.ts",
67
67
  "tokens:build": "node scripts/build-tokens.ts",
68
- "tokens:check": "pnpm tokens:build && node scripts/verify-design-system.ts && git diff --exit-code -- DESIGN.md dist system/tokens.css",
68
+ "tokens:check": "node scripts/check-generated-tokens.ts && node scripts/verify-design-system.ts",
69
69
  "typecheck:scripts": "tsc --noEmit --ignoreConfig --skipLibCheck --module ESNext --moduleResolution Bundler --target ES2022 --strict --types node scripts/*.ts playwright.config.ts tests/e2e/*.ts sst.config.ts infra/*.ts",
70
70
  "smoke": "node scripts/smoke-static.ts",
71
71
  "html:check": "html-validate \"system/**/*.html\"",
package/system/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # put.io design system
2
2
 
3
- This is the `system/` folder inside [`putdotio/putio-design`](https://github.com/putdotio/putio-design). It holds the **tokens**, **preview cards**, and an **index** of the design system.
3
+ This folder holds the generated site tokens, preview cards, and design-system index.
4
4
 
5
5
  ## Layout
6
6
 
@@ -18,38 +18,42 @@ project root/
18
18
 
19
19
  ## Fonts
20
20
 
21
- Fonts are loaded directly from `static.put.io`, so the design system uses the same public type families as put.io product surfaces. Each HTML file links three stylesheets in `<head>`:
22
-
23
- ```html
24
- <link rel="stylesheet" href="https://static.put.io/fonts/gt-america/standard/font.css">
25
- <link rel="stylesheet" href="https://static.put.io/fonts/gt-america/mono/font.css">
26
- <link rel="stylesheet" href="https://static.put.io/fonts/berkeley-mono/variable/font.css">
27
- ```
28
-
29
- Canonical weight mapping (matches `putdotio/putio-static`):
30
- `100 ultra-light · 200 thin · 300 light · 400 regular · 500 medium · 700 bold · 900 black`
21
+ Preview pages load the public put.io font CSS from `static.put.io`: GT America,
22
+ GT America Mono, and Berkeley Mono. Do not commit font files here.
31
23
 
32
24
  ## Using tokens
33
25
 
26
+ For the static guide, pages in `system/` load the generated site stylesheet:
27
+
34
28
  ```html
35
- <link rel="stylesheet" href="system/tokens.css">
29
+ <link rel="stylesheet" href="./tokens.css">
36
30
  ```
37
31
 
38
32
  The canonical source is DTCG-compatible JSON in [`../tokens`](../tokens). This
39
- CSS file is generated for the design site and package consumers. Everything else
40
- is a variable. Brand yellow is emitted as `var(--yellow-solid)`; its CSS token
41
- value is `hsl(44.7, 97.9%, 63.1%)`, the hsl form of canonical `#FDCE45`.
33
+ site stylesheet (`system/tokens.css`) and the package stylesheet
34
+ (`dist/css/tokens.css`, exported as `@putdotio/design/css`) are generated from
35
+ the same source. Guide and component CSS should consume custom properties rather
36
+ than hard-coded palette values. Brand yellow is emitted as
37
+ `var(--yellow-solid)`; its CSS token value is `hsl(44.7, 97.9%, 63.1%)`, the
38
+ hsl form of canonical `#FDCE45`. Primary hover feedback uses
39
+ `--yellow-solid-hover`, exposed to consumers as `--button-primary-bg-hover`.
40
+
41
+ Web package consumers import the package CSS export:
42
+
43
+ ```css
44
+ @import "@putdotio/design/css";
45
+ ```
42
46
 
43
47
  For **TV preview cards**, also load `preview/tv-shell.css` — it adds the `.tv`, `.topnav`, `.scr`, glass tiers, and player chrome on top of the tokens. This is preview-only support CSS; platform repos implement TV components in their native UI stacks:
44
48
 
45
49
  ```html
46
- <link rel="stylesheet" href="system/tokens.css">
47
- <link rel="stylesheet" href="system/preview/tv-shell.css">
50
+ <link rel="stylesheet" href="./tokens.css">
51
+ <link rel="stylesheet" href="./preview/tv-shell.css">
48
52
  ```
49
53
 
50
54
  ## Core rules
51
55
 
52
- - **Yellow `#FDCE45` is sacred.** Never gradient, tint, or replace. Primary CTAs, folder icons, button/nav/TV focus rings (at 35% alpha), progress bars. `--yellow-solid` is the brand value; for yellow text on light backgrounds use `--yellow-text-secondary` instead.
56
+ - **Yellow `#FDCE45` is the brand fill in both modes.** Use it for primary CTAs, folder icons, button/nav/TV focus rings (at 35% alpha), and progress bars. Use `--yellow-solid-hover` / `--button-primary-bg-hover` for CTA hover feedback, `--primary-foreground` for labels on yellow, and `--yellow-text-secondary` for yellow text on light backgrounds.
53
57
  - **Icons: Phosphor-style inline SVG.** No emoji, ever.
54
58
  - **One design, two modes.** Light and dark are the same markup and components with different token values. Toggle `.dark` on `<html>`; do not fork the page or rebuild a light-specific copy.
55
59
  - **Fields stay quiet.** Use `--field-bg`, `--field-border`, and `--field-ring` for text entry. Invalid fields use `aria-invalid="true"` with red border/text only, never a red fill.
@@ -81,6 +85,4 @@ Four documented type stacks — pick one per surface:
81
85
 
82
86
  ## Preview cards
83
87
 
84
- Open `system/design-system.html` for the full index. Each card renders a single concept against the actual tokens — read it like a spec.
85
-
86
- See the root [`AGENTS.md`](../AGENTS.md) for naming conventions and the rules agents must follow.
88
+ Open `system/design-system.html` for the full index. Each card renders a single concept against the actual tokens; treat it as the visual spec.
@@ -14,9 +14,31 @@
14
14
  }
15
15
  }
16
16
  },
17
+ "backgroundHover": {
18
+ "$type": "color",
19
+ "$value": "{color.yellow.light.solidHover}",
20
+ "$description": "Primary command hover background in light mode.",
21
+ "$extensions": {
22
+ "putio": {
23
+ "cssName": "button-primary-bg-hover",
24
+ "mode": "light"
25
+ }
26
+ }
27
+ },
28
+ "backgroundHoverDark": {
29
+ "$type": "color",
30
+ "$value": "{color.yellow.dark.solidHover}",
31
+ "$description": "Primary command hover background in dark mode.",
32
+ "$extensions": {
33
+ "putio": {
34
+ "cssName": "button-primary-bg-hover",
35
+ "mode": "dark"
36
+ }
37
+ }
38
+ },
17
39
  "foreground": {
18
40
  "$type": "color",
19
- "$value": "hsl(0, 0%, 4.0%)",
41
+ "$value": "{component.alias.primaryForeground}",
20
42
  "$description": "Text or icon color on the yellow primary button.",
21
43
  "$extensions": {
22
44
  "putio": {
@@ -77,6 +99,144 @@
77
99
  }
78
100
  }
79
101
  }
102
+ },
103
+ "success": {
104
+ "background": {
105
+ "$type": "color",
106
+ "$value": "{color.green.light.solid}",
107
+ "$description": "Success command background in light mode.",
108
+ "$extensions": {
109
+ "putio": {
110
+ "cssName": "button-success-bg",
111
+ "mode": "light"
112
+ }
113
+ }
114
+ },
115
+ "backgroundDark": {
116
+ "$type": "color",
117
+ "$value": "{color.green.dark.solid}",
118
+ "$description": "Success command background in dark mode.",
119
+ "$extensions": {
120
+ "putio": {
121
+ "cssName": "button-success-bg",
122
+ "mode": "dark"
123
+ }
124
+ }
125
+ },
126
+ "backgroundHover": {
127
+ "$type": "color",
128
+ "$value": "{color.green.light.solidHover}",
129
+ "$description": "Success command hover background in light mode. Step-10 hover companion to the green solid fill.",
130
+ "$extensions": {
131
+ "putio": {
132
+ "cssName": "button-success-bg-hover",
133
+ "mode": "light"
134
+ }
135
+ }
136
+ },
137
+ "backgroundHoverDark": {
138
+ "$type": "color",
139
+ "$value": "{color.green.dark.solidHover}",
140
+ "$description": "Success command hover background in dark mode. Step-10 hover companion to the green solid fill.",
141
+ "$extensions": {
142
+ "putio": {
143
+ "cssName": "button-success-bg-hover",
144
+ "mode": "dark"
145
+ }
146
+ }
147
+ },
148
+ "foreground": {
149
+ "$type": "color",
150
+ "$value": "{component.alias.successForeground}",
151
+ "$description": "Text or icon color on success command backgrounds.",
152
+ "$extensions": {
153
+ "putio": {
154
+ "cssName": "button-success-fg",
155
+ "mode": "global"
156
+ }
157
+ }
158
+ }
159
+ },
160
+ "danger": {
161
+ "background": {
162
+ "$type": "color",
163
+ "$value": "{color.red.light.solid}",
164
+ "$description": "Destructive command background in light mode.",
165
+ "$extensions": {
166
+ "putio": {
167
+ "cssName": "button-danger-bg",
168
+ "mode": "light"
169
+ }
170
+ }
171
+ },
172
+ "backgroundDark": {
173
+ "$type": "color",
174
+ "$value": "{color.red.dark.solid}",
175
+ "$description": "Destructive command background in dark mode.",
176
+ "$extensions": {
177
+ "putio": {
178
+ "cssName": "button-danger-bg",
179
+ "mode": "dark"
180
+ }
181
+ }
182
+ },
183
+ "backgroundHover": {
184
+ "$type": "color",
185
+ "$value": "{color.red.light.solidHover}",
186
+ "$description": "Destructive command hover background in light mode. Step-10 hover companion to the red solid fill.",
187
+ "$extensions": {
188
+ "putio": {
189
+ "cssName": "button-danger-bg-hover",
190
+ "mode": "light"
191
+ }
192
+ }
193
+ },
194
+ "backgroundHoverDark": {
195
+ "$type": "color",
196
+ "$value": "{color.red.dark.solidHover}",
197
+ "$description": "Destructive command hover background in dark mode. Step-10 hover companion to the red solid fill.",
198
+ "$extensions": {
199
+ "putio": {
200
+ "cssName": "button-danger-bg-hover",
201
+ "mode": "dark"
202
+ }
203
+ }
204
+ },
205
+ "foreground": {
206
+ "$type": "color",
207
+ "$value": "{component.alias.destructiveForeground}",
208
+ "$description": "Text or icon color on destructive command backgrounds.",
209
+ "$extensions": {
210
+ "putio": {
211
+ "cssName": "button-danger-fg",
212
+ "mode": "global"
213
+ }
214
+ }
215
+ }
216
+ },
217
+ "info": {
218
+ "backgroundHover": {
219
+ "$type": "color",
220
+ "$value": "{color.neutral.light.solidHover}",
221
+ "$description": "Neutral solid command hover background in light mode.",
222
+ "$extensions": {
223
+ "putio": {
224
+ "cssName": "button-info-bg-hover",
225
+ "mode": "light"
226
+ }
227
+ }
228
+ },
229
+ "backgroundHoverDark": {
230
+ "$type": "color",
231
+ "$value": "{color.neutral.dark.solidHover}",
232
+ "$description": "Neutral solid command hover background in dark mode.",
233
+ "$extensions": {
234
+ "putio": {
235
+ "cssName": "button-info-bg-hover",
236
+ "mode": "dark"
237
+ }
238
+ }
239
+ }
80
240
  }
81
241
  },
82
242
  "input": {
@@ -491,7 +651,7 @@
491
651
  },
492
652
  "primaryForeground": {
493
653
  "$type": "color",
494
- "$value": "hsl(0, 0%, 0%)",
654
+ "$value": "hsl(38, 65%, 10%)",
495
655
  "$extensions": {
496
656
  "putio": {
497
657
  "cssName": "primary-foreground",
@@ -502,7 +662,7 @@
502
662
  },
503
663
  "success": {
504
664
  "$type": "color",
505
- "$value": "{color.green.light.textSecondary}",
665
+ "$value": "{color.green.light.solid}",
506
666
  "$extensions": {
507
667
  "putio": {
508
668
  "cssName": "success",
@@ -513,7 +673,7 @@
513
673
  },
514
674
  "successDark": {
515
675
  "$type": "color",
516
- "$value": "{color.green.dark.borderHover}",
676
+ "$value": "{color.green.dark.solid}",
517
677
  "$extensions": {
518
678
  "putio": {
519
679
  "cssName": "success",
@@ -535,7 +695,7 @@
535
695
  },
536
696
  "destructive": {
537
697
  "$type": "color",
538
- "$value": "{color.red.light.textSecondary}",
698
+ "$value": "{color.red.light.solid}",
539
699
  "$extensions": {
540
700
  "putio": {
541
701
  "cssName": "destructive",
@@ -546,7 +706,7 @@
546
706
  },
547
707
  "destructiveDark": {
548
708
  "$type": "color",
549
- "$value": "{color.red.dark.borderHover}",
709
+ "$value": "{color.red.dark.solid}",
550
710
  "$extensions": {
551
711
  "putio": {
552
712
  "cssName": "destructive",
@@ -566,13 +726,48 @@
566
726
  }
567
727
  }
568
728
  },
729
+ "invertForeground": {
730
+ "$type": "color",
731
+ "$value": "{surface.light.appBg}",
732
+ "$description": "Text or icon color on invert command backgrounds in light mode.",
733
+ "$extensions": {
734
+ "putio": {
735
+ "cssName": "invert-foreground",
736
+ "mode": "light",
737
+ "figma": false
738
+ }
739
+ }
740
+ },
741
+ "invertForegroundDark": {
742
+ "$type": "color",
743
+ "$value": "{surface.dark.appBg}",
744
+ "$description": "Text or icon color on invert command backgrounds in dark mode.",
745
+ "$extensions": {
746
+ "putio": {
747
+ "cssName": "invert-foreground",
748
+ "mode": "dark",
749
+ "figma": false
750
+ }
751
+ }
752
+ },
569
753
  "solidForeground": {
754
+ "$type": "color",
755
+ "$value": "hsl(0, 0%, 0%)",
756
+ "$extensions": {
757
+ "putio": {
758
+ "cssName": "solid-foreground",
759
+ "mode": "light",
760
+ "figma": false
761
+ }
762
+ }
763
+ },
764
+ "solidForegroundDark": {
570
765
  "$type": "color",
571
766
  "$value": "hsl(0, 0%, 100%)",
572
767
  "$extensions": {
573
768
  "putio": {
574
769
  "cssName": "solid-foreground",
575
- "mode": "global",
770
+ "mode": "dark",
576
771
  "figma": false
577
772
  }
578
773
  }
@@ -5,7 +5,7 @@
5
5
  "surface": {
6
6
  "0": {
7
7
  "$type": "color",
8
- "$value": "#000",
8
+ "$value": "hsl(0, 0%, 0%)",
9
9
  "$extensions": {
10
10
  "putio": {
11
11
  "cssName": "surf-0",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "1": {
17
17
  "$type": "color",
18
- "$value": "#0a0a0a",
18
+ "$value": "hsl(0, 0%, 3.9%)",
19
19
  "$extensions": {
20
20
  "putio": {
21
21
  "cssName": "surf-1",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "2": {
27
27
  "$type": "color",
28
- "$value": "#161616",
28
+ "$value": "hsl(0, 0%, 8.6%)",
29
29
  "$extensions": {
30
30
  "putio": {
31
31
  "cssName": "surf-2",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "3": {
37
37
  "$type": "color",
38
- "$value": "#1f1f1f",
38
+ "$value": "hsl(0, 0%, 12.2%)",
39
39
  "$extensions": {
40
40
  "putio": {
41
41
  "cssName": "surf-3",
@@ -47,7 +47,7 @@
47
47
  "text": {
48
48
  "primary": {
49
49
  "$type": "color",
50
- "$value": "#f4f4f4",
50
+ "$value": "hsl(0, 0%, 95.7%)",
51
51
  "$extensions": {
52
52
  "putio": {
53
53
  "cssName": "text-1",
@@ -57,7 +57,7 @@
57
57
  },
58
58
  "secondary": {
59
59
  "$type": "color",
60
- "$value": "rgba(244,244,244,0.62)",
60
+ "$value": "hsla(0, 0%, 95.7%, 0.62)",
61
61
  "$extensions": {
62
62
  "putio": {
63
63
  "cssName": "text-2",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "tertiary": {
69
69
  "$type": "color",
70
- "$value": "rgba(244,244,244,0.38)",
70
+ "$value": "hsla(0, 0%, 95.7%, 0.38)",
71
71
  "$extensions": {
72
72
  "putio": {
73
73
  "cssName": "text-3",
@@ -79,7 +79,7 @@
79
79
  "glass": {
80
80
  "1": {
81
81
  "$type": "color",
82
- "$value": "rgba(255,255,255,0.06)",
82
+ "$value": "hsla(0, 0%, 100%, 0.06)",
83
83
  "$extensions": {
84
84
  "putio": {
85
85
  "cssName": "glass-1-bg",
@@ -89,7 +89,7 @@
89
89
  },
90
90
  "2": {
91
91
  "$type": "color",
92
- "$value": "rgba(255,255,255,0.10)",
92
+ "$value": "hsla(0, 0%, 100%, 0.10)",
93
93
  "$extensions": {
94
94
  "putio": {
95
95
  "cssName": "glass-2-bg",
@@ -99,7 +99,7 @@
99
99
  },
100
100
  "3": {
101
101
  "$type": "color",
102
- "$value": "rgba(255,255,255,0.14)",
102
+ "$value": "hsla(0, 0%, 100%, 0.14)",
103
103
  "$extensions": {
104
104
  "putio": {
105
105
  "cssName": "glass-3-bg",
@@ -109,7 +109,7 @@
109
109
  },
110
110
  "border": {
111
111
  "$type": "color",
112
- "$value": "rgba(255,255,255,0.12)",
112
+ "$value": "hsla(0, 0%, 100%, 0.12)",
113
113
  "$extensions": {
114
114
  "putio": {
115
115
  "cssName": "glass-border",
@@ -119,7 +119,7 @@
119
119
  },
120
120
  "borderStrong": {
121
121
  "$type": "color",
122
- "$value": "rgba(255,255,255,0.22)",
122
+ "$value": "hsla(0, 0%, 100%, 0.22)",
123
123
  "$extensions": {
124
124
  "putio": {
125
125
  "cssName": "glass-border-strong",
@@ -131,7 +131,7 @@
131
131
  "focus": {
132
132
  "ring": {
133
133
  "$type": "color",
134
- "$value": "rgba(253,206,69,0.18)",
134
+ "$value": "hsla(44.7, 97.9%, 63.1%, 0.18)",
135
135
  "$extensions": {
136
136
  "putio": {
137
137
  "cssName": "focus-ring",
@@ -141,7 +141,7 @@
141
141
  },
142
142
  "liftShadow": {
143
143
  "$type": "string",
144
- "$value": "0 14px 30px rgba(0,0,0,0.45)",
144
+ "$value": "0 14px 30px hsla(0, 0%, 0%, 0.45)",
145
145
  "$extensions": {
146
146
  "putio": {
147
147
  "cssName": "focus-shadow",
@@ -154,7 +154,7 @@
154
154
  "production": {
155
155
  "posterBackground": {
156
156
  "$type": "color",
157
- "$value": "#333333",
157
+ "$value": "hsl(0, 0%, 20%)",
158
158
  "$extensions": {
159
159
  "putio": {
160
160
  "cssName": "tv-channel-art-production-poster-bg",
@@ -176,7 +176,7 @@
176
176
  "development": {
177
177
  "background": {
178
178
  "$type": "color",
179
- "$value": "#248FE5",
179
+ "$value": "hsl(206.7, 78.8%, 52%)",
180
180
  "$extensions": {
181
181
  "putio": {
182
182
  "cssName": "tv-channel-art-development-bg",
@@ -186,7 +186,7 @@
186
186
  },
187
187
  "accent": {
188
188
  "$type": "color",
189
- "$value": "#9FD5FF",
189
+ "$value": "hsl(206.3, 100%, 81.2%)",
190
190
  "$extensions": {
191
191
  "putio": {
192
192
  "cssName": "tv-channel-art-development-accent",
@@ -196,7 +196,7 @@
196
196
  },
197
197
  "grid": {
198
198
  "$type": "color",
199
- "$value": "rgba(255,255,255,0.18)",
199
+ "$value": "hsla(0, 0%, 100%, 0.18)",
200
200
  "$extensions": {
201
201
  "putio": {
202
202
  "cssName": "tv-channel-art-development-grid",
@@ -208,7 +208,7 @@
208
208
  "lab": {
209
209
  "background": {
210
210
  "$type": "color",
211
- "$value": "#0a0f0a",
211
+ "$value": "hsl(120, 20%, 4.9%)",
212
212
  "$extensions": {
213
213
  "putio": {
214
214
  "cssName": "tv-channel-art-lab-bg",
@@ -218,7 +218,7 @@
218
218
  },
219
219
  "foreground": {
220
220
  "$type": "color",
221
- "$value": "#e8ffe4",
221
+ "$value": "hsl(111.1, 100%, 94.7%)",
222
222
  "$extensions": {
223
223
  "putio": {
224
224
  "cssName": "tv-channel-art-lab-fg",
@@ -228,7 +228,7 @@
228
228
  },
229
229
  "accent": {
230
230
  "$type": "color",
231
- "$value": "#39FF14",
231
+ "$value": "hsl(110.6, 100%, 53.9%)",
232
232
  "$extensions": {
233
233
  "putio": {
234
234
  "cssName": "tv-channel-art-lab-accent",
@@ -5,7 +5,7 @@
5
5
  "yellow": {
6
6
  "$type": "color",
7
7
  "$value": "hsl(44.7, 97.9%, 63.1%)",
8
- "$description": "Sacred put.io brand yellow (canonical hex #FDCE45). Do not change or tint.",
8
+ "$description": "put.io brand yellow (canonical hex #FDCE45). The resting brand fill is the same in light and dark modes.",
9
9
  "$extensions": {
10
10
  "putio": {
11
11
  "cssName": "yellow-solid",