@sableui/react 0.9.1 → 0.10.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/AGENTS.md +1 -1
- package/CHANGELOG.md +95 -0
- package/CONTRIBUTING.md +2 -2
- package/DESIGN.md +55 -16
- package/README.md +12 -0
- package/dist/{_contract-C2M1SjBf.d.ts → _contract-CkqXDVww.d.ts} +25 -2
- package/dist/blocks/danger-zone-block.js +3 -3
- package/dist/blocks/danger-zone-block.meta.js +1 -1
- package/dist/blocks/faq-block.js +3 -3
- package/dist/blocks/goal-progress-block.js +1 -1
- package/dist/blocks/notification-list-block.js +1 -1
- package/dist/blocks/pricing-table-block.js +12 -12
- package/dist/blocks/product-card-block.js +3 -3
- package/dist/blocks/product-card-block.meta.js +3 -3
- package/dist/blocks/profile-card-block.js +1 -1
- package/dist/blocks/profile-form-block.js +3 -3
- package/dist/blocks/revenue-breakdown-block.js +5 -5
- package/dist/blocks/stat-row-block.js +3 -3
- package/dist/blocks/task-list-block.js +2 -2
- package/dist/blocks/team-members-block.js +1 -1
- package/dist/blocks/wallet-block.js +4 -4
- package/dist/blocks/wallet-block.meta.js +3 -3
- package/dist/components/accordion/accordion.meta.js +2 -2
- package/dist/components/app-header/app-header.meta.js +1 -1
- package/dist/components/app-shell/app-shell.meta.js +2 -2
- package/dist/components/area-chart/area-chart.meta.js +3 -3
- package/dist/components/badge/badge.js +13 -4
- package/dist/components/badge/badge.meta.js +24 -13
- package/dist/components/badge/badge.variants.js +37 -23
- package/dist/components/banner/banner.meta.js +8 -8
- package/dist/components/banner/banner.variants.js +3 -3
- package/dist/components/bar-chart/bar-chart.meta.js +4 -4
- package/dist/components/breadcrumbs/breadcrumbs.meta.js +1 -1
- package/dist/components/button/button.meta.js +3 -3
- package/dist/components/card/card.js +16 -7
- package/dist/components/card/card.meta.js +4 -4
- package/dist/components/checkbox-card/checkbox-card.meta.js +10 -10
- package/dist/components/checkbox-card/checkbox-card.variants.js +15 -15
- package/dist/components/code-block/code-block.meta.js +1 -1
- package/dist/components/command-menu/command-menu.meta.js +1 -1
- package/dist/components/context-card/context-card.meta.js +2 -2
- package/dist/components/destructive-action-modal/destructive-action-modal.meta.js +1 -1
- package/dist/components/dialog/dialog.meta.js +2 -2
- package/dist/components/disclosure-picker/disclosure-picker.js +48 -2
- package/dist/components/disclosure-picker/disclosure-picker.meta.js +3 -2
- package/dist/components/empty-state/empty-state.meta.js +4 -4
- package/dist/components/gradient-art/gradient-art.meta.js +3 -3
- package/dist/components/label/label.meta.js +1 -1
- package/dist/components/line-chart/line-chart.meta.js +3 -3
- package/dist/components/meter/meter.js +1 -1
- package/dist/components/meter/meter.meta.js +2 -2
- package/dist/components/meter/meter.variants.js +1 -1
- package/dist/components/middle-truncate/middle-truncate.meta.js +4 -4
- package/dist/components/note/note.meta.js +3 -3
- package/dist/components/page-header/page-header.js +1 -1
- package/dist/components/pagination/pagination.meta.js +2 -2
- package/dist/components/phone/phone.meta.js +1 -1
- package/dist/components/pie-chart/pie-chart.meta.js +3 -3
- package/dist/components/pill/pill.js +4 -2
- package/dist/components/pill/pill.meta.js +19 -2
- package/dist/components/pill/pill.variants.js +23 -2
- package/dist/components/popover/popover.meta.js +2 -2
- package/dist/components/radar-chart/radar-chart.meta.js +3 -3
- package/dist/components/radial-chart/radial-chart.meta.js +3 -3
- package/dist/components/radio/radio.meta.js +2 -2
- package/dist/components/radio-card/radio-card.meta.js +6 -6
- package/dist/components/radio-card/radio-card.variants.js +15 -15
- package/dist/components/scroller/scroller.meta.js +1 -1
- package/dist/components/search-input/search-input.meta.js +1 -1
- package/dist/components/section-header/section-header.js +1 -1
- package/dist/components/segmented-bar/segmented-bar.js +1 -1
- package/dist/components/segmented-bar/segmented-bar.meta.js +6 -6
- package/dist/components/segmented-bar/segmented-bar.variants.js +4 -4
- package/dist/components/select/select.meta.js +2 -2
- package/dist/components/sheet/sheet.meta.js +1 -1
- package/dist/components/side-nav/side-nav.meta.js +1 -1
- package/dist/components/sidebar/sidebar.meta.js +1 -1
- package/dist/components/sparkline/sparkline.meta.js +4 -4
- package/dist/components/spinner/spinner.meta.js +1 -1
- package/dist/components/status-dot/status-dot.js +4 -1
- package/dist/components/status-dot/status-dot.meta.js +8 -16
- package/dist/components/status-dot/status-dot.variants.js +13 -4
- package/dist/components/table/table.meta.js +4 -4
- package/dist/components/tabs/tabs.meta.js +1 -1
- package/dist/components/textarea/textarea.meta.js +2 -2
- package/dist/components/toast/toast.meta.js +1 -1
- package/dist/components/tooltip/tooltip.meta.js +2 -2
- package/dist/file-hashes.json +120 -118
- package/dist/foundations/spacing.js +8 -8
- package/dist/index.d.ts +137 -72
- package/dist/index.js +12 -1
- package/dist/lib/chart/types.js +3 -3
- package/dist/lib/palette.js +103 -0
- package/dist/lib/selection-card.js +4 -4
- package/dist/palette.css +669 -0
- package/dist/patterns/auth-page.js +6 -6
- package/dist/patterns/auth-page.meta.js +3 -3
- package/dist/patterns/brand-landing-page.js +2 -2
- package/dist/patterns/chat-panel.js +2 -2
- package/dist/patterns/dashboard-page.js +71 -71
- package/dist/patterns/dashboard-page.meta.js +5 -5
- package/dist/patterns/feed-page.js +25 -25
- package/dist/patterns/feed-page.meta.js +3 -3
- package/dist/patterns/landing-page.js +1 -1
- package/dist/patterns/list-detail-page.js +17 -17
- package/dist/patterns/settings-page.js +17 -17
- package/dist/presets/index.d.ts +1 -1
- package/dist/presets/index.js +17 -2
- package/dist/styles.css +115 -50
- package/dist/{theme-provider-S0NVJs2Y.d.ts → theme-provider-CdSicAad.d.ts} +1 -1
- package/dist/themes/_contract.js +22 -8
- package/dist/themes/atelier/atelier.css +13 -13
- package/dist/themes/atelier/index.d.ts +1 -1
- package/dist/themes/ember/ember.css +13 -13
- package/dist/themes/ember/index.d.ts +1 -1
- package/dist/themes/index.d.ts +2 -2
- package/dist/themes/meridian/index.d.ts +1 -1
- package/dist/themes/meridian/meridian.css +13 -13
- package/dist/themes/poppy/index.d.ts +1 -1
- package/dist/themes/poppy/poppy.css +19 -16
- package/dist/themes/prism/index.d.ts +1 -1
- package/dist/themes/prism/prism.css +18 -15
- package/dist/themes/sable/index.d.ts +1 -1
- package/dist/themes/sable/sable.css +18 -22
- package/dist/themes/verdant/index.d.ts +1 -1
- package/dist/themes/verdant/verdant.css +15 -15
- package/llms/blocks/danger-zone-block.md +4 -4
- package/llms/blocks/faq-block.md +3 -3
- package/llms/blocks/goal-progress-block.md +1 -1
- package/llms/blocks/notification-list-block.md +1 -1
- package/llms/blocks/pricing-table-block.md +12 -12
- package/llms/blocks/product-card-block.md +6 -6
- package/llms/blocks/profile-card-block.md +1 -1
- package/llms/blocks/profile-form-block.md +3 -3
- package/llms/blocks/revenue-breakdown-block.md +5 -5
- package/llms/blocks/stat-row-block.md +3 -3
- package/llms/blocks/task-list-block.md +2 -2
- package/llms/blocks/team-members-block.md +1 -1
- package/llms/blocks/wallet-block.md +7 -7
- package/llms/components/accordion.md +2 -2
- package/llms/components/app-header.md +1 -1
- package/llms/components/app-shell.md +2 -2
- package/llms/components/area-chart.md +1 -1
- package/llms/components/badge.md +15 -7
- package/llms/components/banner.md +6 -6
- package/llms/components/bar-chart.md +2 -2
- package/llms/components/breadcrumbs.md +1 -1
- package/llms/components/button.md +3 -3
- package/llms/components/card.md +4 -4
- package/llms/components/checkbox-card.md +5 -5
- package/llms/components/code-block.md +1 -1
- package/llms/components/command-menu.md +1 -1
- package/llms/components/context-card.md +2 -2
- package/llms/components/destructive-action-modal.md +1 -1
- package/llms/components/dialog.md +2 -2
- package/llms/components/disclosure-picker.md +2 -1
- package/llms/components/empty-state.md +4 -4
- package/llms/components/gradient-art.md +3 -3
- package/llms/components/label.md +1 -1
- package/llms/components/line-chart.md +1 -1
- package/llms/components/meter.md +2 -2
- package/llms/components/middle-truncate.md +5 -5
- package/llms/components/note.md +3 -3
- package/llms/components/pagination.md +2 -2
- package/llms/components/phone.md +1 -1
- package/llms/components/pie-chart.md +1 -1
- package/llms/components/pill.md +12 -2
- package/llms/components/popover.md +2 -2
- package/llms/components/radar-chart.md +1 -1
- package/llms/components/radial-chart.md +1 -1
- package/llms/components/radio-card.md +4 -4
- package/llms/components/radio.md +2 -2
- package/llms/components/scroller.md +1 -1
- package/llms/components/search-input.md +1 -1
- package/llms/components/segmented-bar.md +7 -7
- package/llms/components/select.md +2 -2
- package/llms/components/sheet.md +1 -1
- package/llms/components/side-nav.md +1 -1
- package/llms/components/sidebar.md +1 -1
- package/llms/components/sparkline.md +2 -2
- package/llms/components/spinner.md +1 -1
- package/llms/components/status-dot.md +4 -4
- package/llms/components/table.md +8 -8
- package/llms/components/tabs.md +1 -1
- package/llms/components/textarea.md +2 -2
- package/llms/components/toast.md +1 -1
- package/llms/components/tooltip.md +2 -2
- package/llms/foundations/spacing.md +7 -7
- package/llms/layout/grid.md +1 -1
- package/llms/layout/page.md +1 -1
- package/llms/layout/region.md +1 -1
- package/llms/layout/split-pane.md +1 -1
- package/llms/patterns/auth-page.md +11 -11
- package/llms/patterns/brand-landing-page.md +2 -2
- package/llms/patterns/chat-panel.md +2 -2
- package/llms/patterns/dashboard-page.md +78 -78
- package/llms/patterns/feed-page.md +31 -31
- package/llms/patterns/landing-page.md +1 -1
- package/llms/patterns/list-detail-page.md +18 -18
- package/llms/patterns/settings-page.md +18 -18
- package/llms/reference/token-intent.md +25 -11
- package/llms/reference/utilities.md +1 -1
- package/llms/tasks/adding-a-component.md +4 -1
- package/llms/tasks/building-a-page.md +40 -0
- package/llms/tasks/converting-an-app.md +3 -1
- package/llms/tasks/using-presets.md +4 -0
- package/llms-full.txt +429 -347
- package/llms.txt +7 -7
- package/package.json +4 -4
- package/registry.json +369 -233
- package/scripts/lint-rules.mjs +26 -5
- package/skills/sable/SKILL.md +14 -3
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Meridian — a Sable theme, developed from reference analysis.
|
|
3
3
|
|
|
4
4
|
Components must reference the SEMANTIC tokens (--background, --primary,
|
|
5
|
-
--tone-
|
|
5
|
+
--tone-1, …), never any palette ramp directly. See themes/_contract.ts.
|
|
6
6
|
========================================================================== */
|
|
7
7
|
|
|
8
8
|
/* Scoped to [data-sable-theme="meridian"]; no bare :root fallback (base owns the default). */
|
|
@@ -148,9 +148,9 @@
|
|
|
148
148
|
--success: oklch(43% 0.1 165);
|
|
149
149
|
--success-text: oklch(43% 0.1 165);
|
|
150
150
|
--success-foreground: oklch(94.6% 0.0083 91.48);
|
|
151
|
-
--tone-
|
|
152
|
-
--tone-
|
|
153
|
-
--tone-
|
|
151
|
+
--tone-3: oklch(40% 0.07 130);
|
|
152
|
+
--tone-2: oklch(46% 0.14 285);
|
|
153
|
+
--tone-1: oklch(45% 0.15 309);
|
|
154
154
|
--tone-info: oklch(48% 0.13 250);
|
|
155
155
|
--tone-info-text: oklch(48% 0.13 250);
|
|
156
156
|
--tone-warning: oklch(50% 0.12 52);
|
|
@@ -161,9 +161,9 @@
|
|
|
161
161
|
same hue, deep enough for 5.2:1. A theme-local token: Meridian's art
|
|
162
162
|
direction is the only one that sets its accent as type. */
|
|
163
163
|
--meridian-ember-ink: oklch(52% 0.19 31.5);
|
|
164
|
-
--tone-
|
|
165
|
-
--tone-
|
|
166
|
-
--tone-
|
|
164
|
+
--tone-3-foreground: oklch(94.6% 0.0083 91.48);
|
|
165
|
+
--tone-2-foreground: oklch(94.6% 0.0083 91.48);
|
|
166
|
+
--tone-1-foreground: oklch(94.6% 0.0083 91.48);
|
|
167
167
|
--tone-info-foreground: oklch(94.6% 0.0083 91.48);
|
|
168
168
|
--tone-warning-foreground: oklch(94.6% 0.0083 91.48);
|
|
169
169
|
--highlight-foreground: oklch(99% 0.004 91.5);
|
|
@@ -241,18 +241,18 @@
|
|
|
241
241
|
--success: oklch(75.5% 0.12 165);
|
|
242
242
|
--success-text: oklch(75.5% 0.12 165);
|
|
243
243
|
--success-foreground: oklch(22.46% 0.0094 107.13);
|
|
244
|
-
--tone-
|
|
245
|
-
--tone-
|
|
246
|
-
--tone-
|
|
244
|
+
--tone-3: oklch(70% 0.09 130);
|
|
245
|
+
--tone-2: oklch(70% 0.12 285);
|
|
246
|
+
--tone-1: oklch(68% 0.14 309);
|
|
247
247
|
--tone-info: oklch(76.5% 0.11 250);
|
|
248
248
|
--tone-info-text: oklch(76.5% 0.11 250);
|
|
249
249
|
--tone-warning: oklch(78% 0.13 60);
|
|
250
250
|
--tone-warning-text: oklch(78% 0.13 60);
|
|
251
251
|
--highlight: oklch(57.5% 0.2 31.5);
|
|
252
252
|
--meridian-ember-ink: oklch(72% 0.17 33); /* 6.4:1 on the dark ground */
|
|
253
|
-
--tone-
|
|
254
|
-
--tone-
|
|
255
|
-
--tone-
|
|
253
|
+
--tone-3-foreground: oklch(22.46% 0.0094 107.13);
|
|
254
|
+
--tone-2-foreground: oklch(22.46% 0.0094 107.13);
|
|
255
|
+
--tone-1-foreground: oklch(22.46% 0.0094 107.13);
|
|
256
256
|
--tone-info-foreground: oklch(22.46% 0.0094 107.13);
|
|
257
257
|
--tone-warning-foreground: oklch(22.46% 0.0094 107.13);
|
|
258
258
|
--highlight-foreground: oklch(99% 0.004 91.5);
|
|
@@ -84,17 +84,17 @@
|
|
|
84
84
|
--success: oklch(44.82304% 0.085811 158.9570);
|
|
85
85
|
--success-text: oklch(44.82304% 0.085811 158.9570);
|
|
86
86
|
--success-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
87
|
-
--tone-
|
|
88
|
-
--tone-
|
|
89
|
-
--tone-
|
|
87
|
+
--tone-3: oklch(45.04846% 0.050543 265.7140);
|
|
88
|
+
--tone-2: oklch(44.74226% 0.160756 301.6122);
|
|
89
|
+
--tone-1: oklch(48.37678% 0.151106 344.8805);
|
|
90
90
|
--tone-info: oklch(47.10428% 0.117665 253.7666);
|
|
91
91
|
--tone-info-text: oklch(47.10428% 0.117665 253.7666);
|
|
92
92
|
--tone-warning: oklch(48.46763% 0.102195 75.1153);
|
|
93
93
|
--tone-warning-text: oklch(48.46763% 0.102195 75.1153);
|
|
94
94
|
--highlight: oklch(86.64637% 0.118528 86.6791);
|
|
95
|
-
--tone-
|
|
96
|
-
--tone-
|
|
97
|
-
--tone-
|
|
95
|
+
--tone-3-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
96
|
+
--tone-2-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
97
|
+
--tone-1-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
98
98
|
--tone-info-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
99
99
|
--tone-warning-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
100
100
|
--highlight-foreground: oklch(27.91553% 0.070219 323.8141);
|
|
@@ -122,7 +122,10 @@
|
|
|
122
122
|
--motion-ease-spring: cubic-bezier(0.34, 1.35, 0.5, 1);
|
|
123
123
|
--motion-ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
124
124
|
--motion-ease-linear: linear;
|
|
125
|
-
|
|
125
|
+
/* Open: set looser than the default, so the baseline step is 9px (15px
|
|
126
|
+
body on a 27px line) and every gap opens with the text — the 0.28rem
|
|
127
|
+
spacing this theme used to set by hand, now on rhythm. */
|
|
128
|
+
--theme-leading-scale: 1.1;
|
|
126
129
|
--theme-button-radius: 12px;
|
|
127
130
|
--button-radius: var(--theme-button-radius);
|
|
128
131
|
/* Hard offsets the whole way up. Only sm and md were declared, so the
|
|
@@ -171,9 +174,9 @@
|
|
|
171
174
|
--success: oklch(83.08052% 0.080357 158.1865);
|
|
172
175
|
--success-text: oklch(83.08052% 0.080357 158.1865);
|
|
173
176
|
--success-foreground: oklch(27.91553% 0.070219 323.8141);
|
|
174
|
-
--tone-
|
|
175
|
-
--tone-
|
|
176
|
-
--tone-
|
|
177
|
+
--tone-3: oklch(82.64273% 0.059760 270.2687);
|
|
178
|
+
--tone-2: oklch(81.83406% 0.094036 306.4836);
|
|
179
|
+
--tone-1: oklch(82.56509% 0.096677 343.4480);
|
|
177
180
|
--tone-info: oklch(85.19509% 0.074997 252.9332);
|
|
178
181
|
--tone-info-text: oklch(85.19509% 0.074997 252.9332);
|
|
179
182
|
--tone-warning: oklch(86.64637% 0.118528 86.6791);
|
|
@@ -190,9 +193,9 @@
|
|
|
190
193
|
--sidebar-accent-foreground: oklch(96.99788% 0.031195 84.5922);
|
|
191
194
|
--sidebar-border: oklch(62.48980% 0.070560 325.5308);
|
|
192
195
|
--sidebar-ring: oklch(86.64637% 0.118528 86.6791);
|
|
193
|
-
--tone-
|
|
194
|
-
--tone-
|
|
195
|
-
--tone-
|
|
196
|
+
--tone-3-foreground: oklch(27.91553% 0.070219 323.8141);
|
|
197
|
+
--tone-2-foreground: oklch(27.91553% 0.070219 323.8141);
|
|
198
|
+
--tone-1-foreground: oklch(27.91553% 0.070219 323.8141);
|
|
196
199
|
--tone-info-foreground: oklch(27.91553% 0.070219 323.8141);
|
|
197
200
|
--tone-warning-foreground: oklch(27.91553% 0.070219 323.8141);
|
|
198
201
|
}
|
|
@@ -207,11 +210,11 @@
|
|
|
207
210
|
[data-sable-theme="poppy"] .dark,
|
|
208
211
|
[data-sable-theme="poppy"] .light {
|
|
209
212
|
--theme-art-1: oklch(from var(--highlight) 0.88 0.15 h);
|
|
210
|
-
--theme-art-2: oklch(from var(--tone-
|
|
211
|
-
--theme-art-3: oklch(from var(--tone-
|
|
213
|
+
--theme-art-2: oklch(from var(--tone-1) 0.72 0.19 h);
|
|
214
|
+
--theme-art-3: oklch(from var(--tone-2) 0.64 0.2 h);
|
|
212
215
|
--theme-art-4: oklch(from var(--tone-info) 0.76 0.13 h);
|
|
213
216
|
--theme-art-5: oklch(0.85 0.12 168);
|
|
214
|
-
--theme-art-ground: oklch(from var(--tone-
|
|
217
|
+
--theme-art-ground: oklch(from var(--tone-2) 0.45 0.16 h);
|
|
215
218
|
--theme-art-warp: 1;
|
|
216
219
|
--theme-art-softness: 0.5;
|
|
217
220
|
--theme-art-grain: 0;
|
|
@@ -84,17 +84,17 @@
|
|
|
84
84
|
--success: oklch(45.54384% 0.081395 166.9049);
|
|
85
85
|
--success-text: oklch(45.54384% 0.081395 166.9049);
|
|
86
86
|
--success-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
87
|
-
--tone-
|
|
88
|
-
--tone-
|
|
89
|
-
--tone-
|
|
87
|
+
--tone-3: oklch(44.17719% 0.043085 257.4210);
|
|
88
|
+
--tone-2: oklch(45.52411% 0.167785 299.9667);
|
|
89
|
+
--tone-1: oklch(46.78672% 0.141265 343.5094);
|
|
90
90
|
--tone-info: oklch(46.18475% 0.139719 259.8084);
|
|
91
91
|
--tone-info-text: oklch(46.18475% 0.139719 259.8084);
|
|
92
92
|
--tone-warning: oklch(48.72795% 0.103396 73.7587);
|
|
93
93
|
--tone-warning-text: oklch(48.72795% 0.103396 73.7587);
|
|
94
94
|
--highlight: oklch(87.60451% 0.060193 266.4847);
|
|
95
|
-
--tone-
|
|
96
|
-
--tone-
|
|
97
|
-
--tone-
|
|
95
|
+
--tone-3-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
96
|
+
--tone-2-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
97
|
+
--tone-1-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
98
98
|
--tone-info-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
99
99
|
--tone-warning-foreground: oklch(100.00000% 0.000000 89.8756);
|
|
100
100
|
--highlight-foreground: oklch(26.55994% 0.047330 255.4106);
|
|
@@ -122,7 +122,10 @@
|
|
|
122
122
|
--motion-ease-spring: cubic-bezier(0.34, 1.35, 0.5, 1);
|
|
123
123
|
--motion-ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
124
124
|
--motion-ease-linear: linear;
|
|
125
|
-
|
|
125
|
+
/* Precise: set tighter than the default, so the baseline step is 7px
|
|
126
|
+
(16px body on a 21px line) and every gap tightens with the text — the
|
|
127
|
+
0.22rem spacing this theme used to set by hand, now on rhythm. */
|
|
128
|
+
--theme-leading-scale: 0.86;
|
|
126
129
|
--theme-button-radius: 4px;
|
|
127
130
|
--button-radius: var(--theme-button-radius);
|
|
128
131
|
--type-body-md-size: 1rem;
|
|
@@ -167,9 +170,9 @@
|
|
|
167
170
|
--success: oklch(82.23776% 0.085532 165.8233);
|
|
168
171
|
--success-text: oklch(82.23776% 0.085532 165.8233);
|
|
169
172
|
--success-foreground: oklch(25.20350% 0.047984 259.9119);
|
|
170
|
-
--tone-
|
|
171
|
-
--tone-
|
|
172
|
-
--tone-
|
|
173
|
+
--tone-3: oklch(82.02131% 0.046953 256.4806);
|
|
174
|
+
--tone-2: oklch(77.28561% 0.118760 301.0442);
|
|
175
|
+
--tone-1: oklch(80.44093% 0.102099 341.6738);
|
|
173
176
|
--tone-info: oklch(80.57243% 0.097939 259.4939);
|
|
174
177
|
--tone-info-text: oklch(80.57243% 0.097939 259.4939);
|
|
175
178
|
--tone-warning: oklch(84.66478% 0.108333 84.1636);
|
|
@@ -186,9 +189,9 @@
|
|
|
186
189
|
--sidebar-accent-foreground: oklch(96.50786% 0.016545 259.4182);
|
|
187
190
|
--sidebar-border: oklch(58.06940% 0.052170 251.5856);
|
|
188
191
|
--sidebar-ring: oklch(82.28684% 0.088371 261.1846);
|
|
189
|
-
--tone-
|
|
190
|
-
--tone-
|
|
191
|
-
--tone-
|
|
192
|
+
--tone-3-foreground: oklch(25.20350% 0.047984 259.9119);
|
|
193
|
+
--tone-2-foreground: oklch(25.20350% 0.047984 259.9119);
|
|
194
|
+
--tone-1-foreground: oklch(25.20350% 0.047984 259.9119);
|
|
192
195
|
--tone-info-foreground: oklch(25.20350% 0.047984 259.9119);
|
|
193
196
|
--tone-warning-foreground: oklch(25.20350% 0.047984 259.9119);
|
|
194
197
|
}
|
|
@@ -201,8 +204,8 @@
|
|
|
201
204
|
[data-sable-theme="prism"],
|
|
202
205
|
[data-sable-theme="prism"] .dark,
|
|
203
206
|
[data-sable-theme="prism"] .light {
|
|
204
|
-
--theme-art-1: oklch(from var(--tone-
|
|
205
|
-
--theme-art-2: oklch(from var(--tone-
|
|
207
|
+
--theme-art-1: oklch(from var(--tone-1) 0.83 0.1 h);
|
|
208
|
+
--theme-art-2: oklch(from var(--tone-2) 0.68 0.16 h);
|
|
206
209
|
--theme-art-3: oklch(from var(--tone-info) 0.82 0.09 h);
|
|
207
210
|
--theme-art-4: oklch(from var(--theme-art-brand, var(--primary)) 0.55 0.2 h);
|
|
208
211
|
--theme-art-ground: oklch(from var(--theme-art-brand, var(--primary)) 0.35 0.14 h);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
does not load the font files (load them via <link> or @font-face in your app).
|
|
11
11
|
|
|
12
12
|
Components must reference the SEMANTIC tokens (--background, --primary,
|
|
13
|
-
--tone-
|
|
13
|
+
--tone-1, …), never the palette steps below. See themes/_contract.ts.
|
|
14
14
|
========================================================================== */
|
|
15
15
|
|
|
16
16
|
:root,
|
|
@@ -215,9 +215,9 @@
|
|
|
215
215
|
--azure-radiance-950: oklch(16% 0.075 250);
|
|
216
216
|
|
|
217
217
|
/* Dark-tuned tone values (boosted chroma; activated via .dark below) */
|
|
218
|
-
--tone-
|
|
219
|
-
--tone-
|
|
220
|
-
--tone-
|
|
218
|
+
--tone-1-dark: oklch(62% 0.295 318);
|
|
219
|
+
--tone-2-dark: oklch(72% 0.225 285);
|
|
220
|
+
--tone-3-dark: oklch(78% 0.205 168);
|
|
221
221
|
--tone-info-dark: oklch(76% 0.165 235);
|
|
222
222
|
--tone-warning-dark: oklch(82% 0.165 65);
|
|
223
223
|
/* A labelled fill: dropped to where white reads (4.8:1, Lc 72) rather than
|
|
@@ -265,9 +265,9 @@
|
|
|
265
265
|
--ring: var(--zinc-500);
|
|
266
266
|
|
|
267
267
|
/* Tones — light (all clear WCAG AA on white) */
|
|
268
|
-
--tone-
|
|
269
|
-
--tone-
|
|
270
|
-
--tone-
|
|
268
|
+
--tone-3: var(--caribbean-green-600);
|
|
269
|
+
--tone-2: var(--blue-gem-600);
|
|
270
|
+
--tone-1: var(--purple-heart-700);
|
|
271
271
|
--tone-warning: var(--flush-orange-700);
|
|
272
272
|
--tone-warning-text: var(--flush-orange-700);
|
|
273
273
|
--tone-info: var(--azure-radiance-600);
|
|
@@ -276,9 +276,9 @@
|
|
|
276
276
|
|
|
277
277
|
/* Tone ink — light mode the tone fills resolve to dark 600/700 steps, so the
|
|
278
278
|
legible ink on them is the light neutral. (Flips to dark ink under .dark.) */
|
|
279
|
-
--tone-
|
|
280
|
-
--tone-
|
|
281
|
-
--tone-
|
|
279
|
+
--tone-3-foreground: var(--zinc-50);
|
|
280
|
+
--tone-2-foreground: var(--zinc-50);
|
|
281
|
+
--tone-1-foreground: var(--zinc-50);
|
|
282
282
|
--tone-warning-foreground: var(--zinc-50);
|
|
283
283
|
--tone-info-foreground: var(--zinc-50);
|
|
284
284
|
--highlight-foreground: var(--zinc-50);
|
|
@@ -305,13 +305,9 @@
|
|
|
305
305
|
Layout tokens (mode-independent) — see DESIGN.md → Grid & layout.
|
|
306
306
|
Fluid-first: no global max-width; max-width is opt-in per region.
|
|
307
307
|
---------------------------------------------------------------------- */
|
|
308
|
-
/*
|
|
309
|
-
|
|
310
|
-
the spacing scale instead of staying a fixed 8px beside it. */
|
|
311
|
-
--rhythm-unit: calc(var(--spacing) * 2);
|
|
308
|
+
/* --rhythm-unit and --grid-gutter are contract, not theme: they derive from
|
|
309
|
+
the baseline step in styles.css → Vertical rhythm. */
|
|
312
310
|
--grid-columns: 12;
|
|
313
|
-
/* Inter-column gutter: 16px on phones, easing to 24px on desktop. */
|
|
314
|
-
--grid-gutter: clamp(1rem, 0.8rem + 1vw, 1.5rem);
|
|
315
311
|
/* Page margin (outer inset): 16px → 32px, fluid. */
|
|
316
312
|
--page-inset: clamp(16px, 4vw, 32px);
|
|
317
313
|
|
|
@@ -451,9 +447,9 @@
|
|
|
451
447
|
--ring: var(--zinc-500);
|
|
452
448
|
|
|
453
449
|
/* Tones — dark-tuned (boosted chroma for vibrancy on the dark canvas) */
|
|
454
|
-
--tone-
|
|
455
|
-
--tone-
|
|
456
|
-
--tone-
|
|
450
|
+
--tone-3: var(--tone-3-dark);
|
|
451
|
+
--tone-2: var(--tone-2-dark);
|
|
452
|
+
--tone-1: var(--tone-1-dark);
|
|
457
453
|
--tone-warning: var(--tone-warning-dark);
|
|
458
454
|
--tone-warning-text: var(--tone-warning-dark);
|
|
459
455
|
--tone-info: var(--tone-info-dark);
|
|
@@ -463,9 +459,9 @@
|
|
|
463
459
|
/* Tone ink — dark mode the tone fills resolve to lighter dark-tuned values,
|
|
464
460
|
so the legible ink flips to the dark neutral. (--overlay* repeat the :root
|
|
465
461
|
values verbatim — a dark scrim is the same in both modes.) */
|
|
466
|
-
--tone-
|
|
467
|
-
--tone-
|
|
468
|
-
--tone-
|
|
462
|
+
--tone-3-foreground: var(--zinc-950);
|
|
463
|
+
--tone-2-foreground: var(--zinc-950);
|
|
464
|
+
--tone-1-foreground: var(--zinc-950);
|
|
469
465
|
--tone-warning-foreground: var(--zinc-950);
|
|
470
466
|
--tone-info-foreground: var(--zinc-950);
|
|
471
467
|
--highlight-foreground: var(--zinc-50);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Verdant — a Sable theme, developed from reference analysis.
|
|
3
3
|
|
|
4
4
|
Components must reference the SEMANTIC tokens (--background, --primary,
|
|
5
|
-
--tone-
|
|
5
|
+
--tone-1, …), never any palette ramp directly. See themes/_contract.ts.
|
|
6
6
|
========================================================================== */
|
|
7
7
|
|
|
8
8
|
[data-sable-theme="verdant"] {
|
|
@@ -116,12 +116,12 @@
|
|
|
116
116
|
--success: oklch(50% 0.11 173);
|
|
117
117
|
--success-text: oklch(50% 0.11 173);
|
|
118
118
|
--success-foreground: oklch(98.6% 0.004 106);
|
|
119
|
-
--tone-
|
|
120
|
-
--tone-
|
|
121
|
-
--tone-
|
|
122
|
-
--tone-
|
|
123
|
-
--tone-
|
|
124
|
-
--tone-
|
|
119
|
+
--tone-3: oklch(49% 0.018 175);
|
|
120
|
+
--tone-3-foreground: oklch(98.6% 0.004 106);
|
|
121
|
+
--tone-2: oklch(45% 0.07 175);
|
|
122
|
+
--tone-2-foreground: oklch(98.6% 0.004 106);
|
|
123
|
+
--tone-1: oklch(50% 0.11 173);
|
|
124
|
+
--tone-1-foreground: oklch(98.6% 0.004 106);
|
|
125
125
|
--tone-info: oklch(51% 0.12 250);
|
|
126
126
|
--tone-info-text: oklch(51% 0.12 250);
|
|
127
127
|
--tone-info-foreground: oklch(98.6% 0.004 106);
|
|
@@ -197,12 +197,12 @@
|
|
|
197
197
|
--success: oklch(74% 0.13 173);
|
|
198
198
|
--success-text: oklch(74% 0.13 173);
|
|
199
199
|
--success-foreground: oklch(16% 0.03 175);
|
|
200
|
-
--tone-
|
|
201
|
-
--tone-
|
|
202
|
-
--tone-
|
|
203
|
-
--tone-
|
|
204
|
-
--tone-
|
|
205
|
-
--tone-
|
|
200
|
+
--tone-3: oklch(72% 0.015 175);
|
|
201
|
+
--tone-3-foreground: oklch(16% 0.03 175);
|
|
202
|
+
--tone-2: oklch(74% 0.09 175);
|
|
203
|
+
--tone-2-foreground: oklch(16% 0.03 175);
|
|
204
|
+
--tone-1: oklch(76% 0.12 173);
|
|
205
|
+
--tone-1-foreground: oklch(16% 0.03 175);
|
|
206
206
|
--tone-info: oklch(76% 0.11 250);
|
|
207
207
|
--tone-info-text: oklch(76% 0.11 250);
|
|
208
208
|
--tone-info-foreground: oklch(16% 0.03 175);
|
|
@@ -233,12 +233,12 @@
|
|
|
233
233
|
[data-sable-theme="verdant"],
|
|
234
234
|
[data-sable-theme="verdant"] .dark,
|
|
235
235
|
[data-sable-theme="verdant"] .light {
|
|
236
|
-
--theme-art-1: oklch(from var(--tone-
|
|
236
|
+
--theme-art-1: oklch(from var(--tone-1) 0.76 0.15 h);
|
|
237
237
|
--theme-art-2: oklch(from var(--tone-warning) 0.76 0.16 h);
|
|
238
238
|
--theme-art-3: oklch(0.66 0.24 355);
|
|
239
239
|
--theme-art-4: oklch(from var(--tone-info) 0.62 0.17 h);
|
|
240
240
|
--theme-art-5: oklch(0.8 0.19 140);
|
|
241
|
-
--theme-art-ground: oklch(from var(--tone-
|
|
241
|
+
--theme-art-ground: oklch(from var(--tone-2) 0.24 0.05 h);
|
|
242
242
|
--theme-art-warp: 0.9;
|
|
243
243
|
--theme-art-softness: 0.62;
|
|
244
244
|
--theme-art-grain: 0;
|
|
@@ -10,7 +10,7 @@ A delete-account card: what deleting removes and what survives, one destructive
|
|
|
10
10
|
|
|
11
11
|
- Copied from the SettingsPage page shell's Delete account section.
|
|
12
12
|
- The button never acts directly: it opens the modal, whose confirm stays disabled until the handle is typed.
|
|
13
|
-
- The description says what is lost AND what is kept ("
|
|
13
|
+
- The description says what is lost AND what is kept ("Files you shared stay with your team"), which is what people want to know before they decide.
|
|
14
14
|
|
|
15
15
|
## Accessibility
|
|
16
16
|
|
|
@@ -23,7 +23,7 @@ A delete-account card: what deleting removes and what survives, one destructive
|
|
|
23
23
|
import { useState } from "react"
|
|
24
24
|
import { Button, Card, CardDescription, CardFooter, CardHeader, CardTitle, cn, DestructiveActionModal } from "@sableui/react"
|
|
25
25
|
|
|
26
|
-
const account = { handle: "ada",
|
|
26
|
+
const account = { handle: "ada", projects: 12 }
|
|
27
27
|
|
|
28
28
|
export interface DangerZoneBlockProps {
|
|
29
29
|
className?: string
|
|
@@ -41,7 +41,7 @@ export function DangerZoneBlock({ className, framed = true, onDelete }: DangerZo
|
|
|
41
41
|
<CardHeader>
|
|
42
42
|
<CardTitle render={<h2 />}>Delete account</CardTitle>
|
|
43
43
|
<CardDescription>
|
|
44
|
-
Permanently remove your profile,
|
|
44
|
+
Permanently remove your profile, projects, and billing history. Files you shared stay with your team.
|
|
45
45
|
</CardDescription>
|
|
46
46
|
</CardHeader>
|
|
47
47
|
<CardFooter actions className="justify-end">
|
|
@@ -54,7 +54,7 @@ export function DangerZoneBlock({ className, framed = true, onDelete }: DangerZo
|
|
|
54
54
|
open={open}
|
|
55
55
|
onOpenChange={setOpen}
|
|
56
56
|
title="Delete your account?"
|
|
57
|
-
description={`This permanently removes your profile, ${account.
|
|
57
|
+
description={`This permanently removes your profile, ${account.projects} projects, and billing history. Your final invoice is still sent. This can't be undone.`}
|
|
58
58
|
confirmLabel="Delete account"
|
|
59
59
|
confirmingLabel="Deleting…"
|
|
60
60
|
confirmText={account.handle}
|
package/llms/blocks/faq-block.md
CHANGED
|
@@ -30,10 +30,10 @@ const intro = {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
const questions = [
|
|
33
|
-
{ q: "Is there a free plan?", a: "Yes. Starter is free forever for three
|
|
33
|
+
{ q: "Is there a free plan?", a: "Yes. Starter is free forever for three active projects, with no card needed to sign up." },
|
|
34
34
|
{ q: "Can I change plans later?", a: "Any time. Upgrades apply immediately and are prorated; downgrades take effect at the end of the billing period." },
|
|
35
|
-
{ q: "Who owns the
|
|
36
|
-
{ q: "How
|
|
35
|
+
{ q: "Who owns the data I add?", a: "You do. You can export everything in your workspace at any time, and we never sell it." },
|
|
36
|
+
{ q: "How does billing work?", a: "Plans are billed per seat at the start of each period, to the card or account you add in settings." },
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
export interface FaqBlockProps {
|
|
@@ -24,7 +24,7 @@ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,
|
|
|
24
24
|
|
|
25
25
|
const goals = [
|
|
26
26
|
{ goal: "Releases", progress: 82 },
|
|
27
|
-
{ goal: "
|
|
27
|
+
{ goal: "Customers", progress: 64 },
|
|
28
28
|
{ goal: "Revenue", progress: 91 },
|
|
29
29
|
]
|
|
30
30
|
|
|
@@ -23,7 +23,7 @@ An activity list: Entity rows with the actor's Avatar, who did what, and a compa
|
|
|
23
23
|
import { Avatar, Card, CardList, cn, Entity, StatusDot } from "@sableui/react"
|
|
24
24
|
|
|
25
25
|
const notifications = [
|
|
26
|
-
{ initials: "MO", name: "Mara Okafor", what: "
|
|
26
|
+
{ initials: "MO", name: "Mara Okafor", what: "invited you to Q3 planning", when: "2m", unread: true },
|
|
27
27
|
{ initials: "SR", name: "Sam Rivera", what: "left a comment on Dusk", when: "1h", unread: false },
|
|
28
28
|
]
|
|
29
29
|
|
|
@@ -27,32 +27,32 @@ const tiers = [
|
|
|
27
27
|
{
|
|
28
28
|
id: "starter",
|
|
29
29
|
name: "Starter",
|
|
30
|
-
blurb: "For one person
|
|
30
|
+
blurb: "For one person getting a first project going.",
|
|
31
31
|
monthly: 0,
|
|
32
32
|
yearly: 0,
|
|
33
33
|
cta: "Start for free",
|
|
34
34
|
featured: false,
|
|
35
|
-
features: ["3
|
|
35
|
+
features: ["3 active projects", "Shared docs", "Community support"],
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
id: "studio",
|
|
39
39
|
name: "Studio",
|
|
40
|
-
blurb: "For
|
|
40
|
+
blurb: "For small teams shipping on a steady schedule.",
|
|
41
41
|
monthly: 20,
|
|
42
42
|
yearly: 16,
|
|
43
43
|
cta: "Start free trial",
|
|
44
44
|
featured: true,
|
|
45
|
-
features: ["Unlimited
|
|
45
|
+
features: ["Unlimited projects", "Scheduled reports", "Usage analytics", "Priority support"],
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
|
-
id: "
|
|
49
|
-
name: "
|
|
50
|
-
blurb: "For
|
|
48
|
+
id: "business",
|
|
49
|
+
name: "Business",
|
|
50
|
+
blurb: "For companies running several teams at once.",
|
|
51
51
|
monthly: 48,
|
|
52
52
|
yearly: 40,
|
|
53
53
|
cta: "Talk to sales",
|
|
54
54
|
featured: false,
|
|
55
|
-
features: ["Everything in Studio", "Up to 10 seats", "
|
|
55
|
+
features: ["Everything in Studio", "Up to 10 seats", "SSO and audit log", "Roles and approvals"],
|
|
56
56
|
},
|
|
57
57
|
]
|
|
58
58
|
|
|
@@ -72,10 +72,10 @@ export function PricingTableBlock({ className, onChoose }: PricingTableBlockProp
|
|
|
72
72
|
<Stack gap={10}>
|
|
73
73
|
<Stack gap={4} align="center" className="text-center">
|
|
74
74
|
<h2 id={titleId} className="text-balance text-heading-1">
|
|
75
|
-
Pricing that grows with your
|
|
75
|
+
Pricing that grows with your team
|
|
76
76
|
</h2>
|
|
77
77
|
<p className="max-w-(--measure-prose) text-body-lg text-muted-foreground">
|
|
78
|
-
Every plan includes unlimited
|
|
78
|
+
Every plan includes unlimited guests, and you can switch plans at any time.
|
|
79
79
|
</p>
|
|
80
80
|
<ToggleGroup value={[period]} onValueChange={(v: unknown[]) => v[0] && setPeriod(v[0] as Period)} aria-label="Billing period">
|
|
81
81
|
<Toggle value="monthly">Monthly</Toggle>
|
|
@@ -87,14 +87,14 @@ export function PricingTableBlock({ className, onChoose }: PricingTableBlockProp
|
|
|
87
87
|
<Card
|
|
88
88
|
key={tier.id}
|
|
89
89
|
render={<article />}
|
|
90
|
-
className={cn("flex flex-col", tier.featured && "
|
|
90
|
+
className={cn("flex flex-col", tier.featured && "outline-primary ring-1 ring-primary")}
|
|
91
91
|
>
|
|
92
92
|
<CardHeader>
|
|
93
93
|
<CardTitle render={<h3 />}>{tier.name}</CardTitle>
|
|
94
94
|
<CardDescription>{tier.blurb}</CardDescription>
|
|
95
95
|
{tier.featured ? (
|
|
96
96
|
<CardAction>
|
|
97
|
-
<Badge tone="
|
|
97
|
+
<Badge tone="1" size="sm">
|
|
98
98
|
Most popular
|
|
99
99
|
</Badge>
|
|
100
100
|
</CardAction>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# ProductCardBlock
|
|
2
2
|
|
|
3
|
-
A product card: edge-to-edge
|
|
3
|
+
A product card: edge-to-edge product image, title and maker, a status Badge, and the price beside a single buy action.
|
|
4
4
|
|
|
5
|
-
**Intent:** Reach for this for a product
|
|
5
|
+
**Intent:** Reach for this for a product or listing in a grid or a featured slot. For a row in a dense list, use an Entity with the image as `leading` instead.
|
|
6
6
|
|
|
7
7
|
**Block:** Commerce · card · designed for 16rem–20rem wide (fills its container up to the max)
|
|
8
8
|
|
|
9
9
|
## Notes
|
|
10
10
|
|
|
11
|
-
- The
|
|
11
|
+
- The image runs to the card's edges; the card clips it to its own corners (overflow-hidden).
|
|
12
12
|
- Prices are `text-mono-lg` — the metric mono tier with tabular figures — never a heading tier.
|
|
13
13
|
- The placeholder art is painted from the palette's decorative tones so it follows the theme; swap it for the product image with real alt text.
|
|
14
14
|
|
|
@@ -23,7 +23,7 @@ A product card: edge-to-edge artwork, title and maker, an edition Badge, and the
|
|
|
23
23
|
import { AspectBox, Badge, Button, Card, CardAction, CardDescription, CardFooter, CardHeader, CardTitle, cn, MediaImage } from "@sableui/react"
|
|
24
24
|
|
|
25
25
|
// `image` is the product shot URL; left empty, it paints art seeded by the title.
|
|
26
|
-
const product = { title: "
|
|
26
|
+
const product = { title: "Linen throw blanket", maker: "Northfield Home", image: "", badge: "New", price: "$64.00" }
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
export interface ProductCardBlockProps {
|
|
@@ -44,12 +44,12 @@ export function ProductCardBlock({ className, framed = true, onCollect }: Produc
|
|
|
44
44
|
<CardTitle>{product.title}</CardTitle>
|
|
45
45
|
<CardDescription>{product.maker}</CardDescription>
|
|
46
46
|
<CardAction>
|
|
47
|
-
<Badge tone="
|
|
47
|
+
<Badge tone="1">{product.badge}</Badge>
|
|
48
48
|
</CardAction>
|
|
49
49
|
</CardHeader>
|
|
50
50
|
<CardFooter className="justify-between pt-4">
|
|
51
51
|
<span className="text-mono-lg">{product.price}</span>
|
|
52
|
-
<Button onClick={onCollect}>
|
|
52
|
+
<Button onClick={onCollect}>Add to cart</Button>
|
|
53
53
|
</CardFooter>
|
|
54
54
|
</Card>
|
|
55
55
|
)
|
|
@@ -27,7 +27,7 @@ const profile = {
|
|
|
27
27
|
name: "Juno Avery",
|
|
28
28
|
initials: "JA",
|
|
29
29
|
handle: "@juno · Sound and light",
|
|
30
|
-
bio: "Field recordings, slowed down. New
|
|
30
|
+
bio: "Field recordings, slowed down. New track every full moon.",
|
|
31
31
|
stats: [
|
|
32
32
|
{ value: "128", label: "posts" },
|
|
33
33
|
{ value: "4.2k", label: "followers" },
|
|
@@ -26,7 +26,7 @@ const profile = {
|
|
|
26
26
|
name: "Ada Lovelace",
|
|
27
27
|
initials: "AL",
|
|
28
28
|
handle: "ada",
|
|
29
|
-
bio: "
|
|
29
|
+
bio: "Product designer working on tools for small teams. Writing about process every month.",
|
|
30
30
|
timezone: "europe-london",
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -51,7 +51,7 @@ export function ProfileFormBlock({ className, framed = true, onSave }: ProfileFo
|
|
|
51
51
|
<Card variant={framed ? "default" : "flat"} className={cn("w-full max-w-2xl", className)}>
|
|
52
52
|
<CardHeader>
|
|
53
53
|
<CardTitle render={<h2 />}>Profile</CardTitle>
|
|
54
|
-
<CardDescription>How
|
|
54
|
+
<CardDescription>How your team sees you.</CardDescription>
|
|
55
55
|
</CardHeader>
|
|
56
56
|
{/* The one explicit save: profile text is drafted, then committed. */}
|
|
57
57
|
<Form
|
|
@@ -85,7 +85,7 @@ export function ProfileFormBlock({ className, framed = true, onSave }: ProfileFo
|
|
|
85
85
|
<Input defaultValue={profile.handle} autoComplete="username" spellCheck={false} />
|
|
86
86
|
</Field>
|
|
87
87
|
</Grid>
|
|
88
|
-
<Field label="Bio" name="bio" description="Shown on your profile and
|
|
88
|
+
<Field label="Bio" name="bio" description="Shown on your profile and in comments.">
|
|
89
89
|
<Textarea rows={3} defaultValue={profile.bio} />
|
|
90
90
|
</Field>
|
|
91
91
|
<Grid cols={{ base: 1, sm: 2 }} gap={3}>
|
|
@@ -25,10 +25,10 @@ import { Badge, Card, CardAction, CardContent, CardDescription, CardHeader, cn,
|
|
|
25
25
|
const revenue = { label: "Revenue this month", total: "$12,480", change: "+8.2%" }
|
|
26
26
|
|
|
27
27
|
const segments = [
|
|
28
|
-
{ label: "
|
|
29
|
-
{ label: "
|
|
30
|
-
{ label: "
|
|
31
|
-
{ label: "
|
|
28
|
+
{ label: "Direct", value: 42, tone: "1" },
|
|
29
|
+
{ label: "Partners", value: 27, tone: "2" },
|
|
30
|
+
{ label: "Referrals", value: 19, tone: "3" },
|
|
31
|
+
{ label: "Resellers", value: 12, tone: "info" },
|
|
32
32
|
] as const
|
|
33
33
|
|
|
34
34
|
export interface RevenueBreakdownBlockProps {
|
|
@@ -50,7 +50,7 @@ export function RevenueBreakdownBlock({ className, framed = true }: RevenueBreak
|
|
|
50
50
|
</CardHeader>
|
|
51
51
|
<CardContent className="flex flex-col gap-4 pt-2">
|
|
52
52
|
<span className="text-mono-xl">{revenue.total}</span>
|
|
53
|
-
<SegmentedBar label="Revenue by
|
|
53
|
+
<SegmentedBar label="Revenue by channel" segments={[...segments]} size="lg" />
|
|
54
54
|
{/* Two columns while each entry fits whole, one when they would not:
|
|
55
55
|
sized in em, so a larger type or a narrower card drops to one.
|
|
56
56
|
aria-hidden: the bar already reads every share aloud. */}
|