@tempoxyz/ds 0.3.10 → 0.3.11
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/dist/docs/AGENTS.md +9 -0
- package/dist/docs/components/accordion.md +489 -0
- package/dist/docs/components/address-card.md +147 -0
- package/dist/docs/components/agent-logo.md +194 -0
- package/dist/docs/components/alert-dialog.md +631 -0
- package/dist/docs/components/alert.md +448 -0
- package/dist/docs/components/amount-input.md +305 -0
- package/dist/docs/components/amount.md +794 -0
- package/dist/docs/components/app-shell.md +559 -0
- package/dist/docs/components/asset-chip.md +294 -0
- package/dist/docs/components/autocomplete.md +619 -0
- package/dist/docs/components/avatar.md +321 -0
- package/dist/docs/components/badge.md +339 -0
- package/dist/docs/components/badged-logo.md +116 -0
- package/dist/docs/components/banner.md +379 -0
- package/dist/docs/components/bar-chart.md +208 -0
- package/dist/docs/components/breadcrumbs.md +380 -0
- package/dist/docs/components/button-group.md +286 -0
- package/dist/docs/components/button.md +650 -0
- package/dist/docs/components/calendar.md +375 -0
- package/dist/docs/components/callout.md +96 -0
- package/dist/docs/components/checkbox-group.md +521 -0
- package/dist/docs/components/checkbox.md +467 -0
- package/dist/docs/components/choice-group.md +516 -0
- package/dist/docs/components/choicebox.md +641 -0
- package/dist/docs/components/code.md +100 -0
- package/dist/docs/components/combobox.md +939 -0
- package/dist/docs/components/container.md +257 -0
- package/dist/docs/components/copy-button.md +642 -0
- package/dist/docs/components/date-picker.md +514 -0
- package/dist/docs/components/dialog.md +1332 -0
- package/dist/docs/components/drawer.md +966 -0
- package/dist/docs/components/empty.md +340 -0
- package/dist/docs/components/field.md +570 -0
- package/dist/docs/components/fieldset.md +398 -0
- package/dist/docs/components/frame.md +434 -0
- package/dist/docs/components/gauge.md +299 -0
- package/dist/docs/components/get-started-visual.md +117 -0
- package/dist/docs/components/grid.md +288 -0
- package/dist/docs/components/hero-visual.md +155 -0
- package/dist/docs/components/hex.md +487 -0
- package/dist/docs/components/icon-tile.md +292 -0
- package/dist/docs/components/identicon.md +371 -0
- package/dist/docs/components/inline.md +233 -0
- package/dist/docs/components/inset.md +225 -0
- package/dist/docs/components/kbd.md +423 -0
- package/dist/docs/components/list-group.md +981 -0
- package/dist/docs/components/loading-dots.md +237 -0
- package/dist/docs/components/menu.md +934 -0
- package/dist/docs/components/native-select.md +204 -0
- package/dist/docs/components/network-logo.md +248 -0
- package/dist/docs/components/number-field.md +543 -0
- package/dist/docs/components/otp-field.md +616 -0
- package/dist/docs/components/pagination.md +516 -0
- package/dist/docs/components/popover.md +544 -0
- package/dist/docs/components/progress.md +388 -0
- package/dist/docs/components/qr.md +314 -0
- package/dist/docs/components/radio-group.md +528 -0
- package/dist/docs/components/secret-value.md +406 -0
- package/dist/docs/components/select.md +751 -0
- package/dist/docs/components/separator.md +379 -0
- package/dist/docs/components/sidebar-menu.md +922 -0
- package/dist/docs/components/skeleton.md +517 -0
- package/dist/docs/components/slider.md +539 -0
- package/dist/docs/components/snippet.md +424 -0
- package/dist/docs/components/spinner.md +216 -0
- package/dist/docs/components/split-bar.md +139 -0
- package/dist/docs/components/split-button.md +464 -0
- package/dist/docs/components/stack.md +299 -0
- package/dist/docs/components/status-chip.md +226 -0
- package/dist/docs/components/status-indicator.md +119 -0
- package/dist/docs/components/status-row.md +174 -0
- package/dist/docs/components/stepper.md +451 -0
- package/dist/docs/components/success-hero.md +157 -0
- package/dist/docs/components/surface.md +639 -0
- package/dist/docs/components/switch.md +472 -0
- package/dist/docs/components/table.md +967 -0
- package/dist/docs/components/tabs.md +627 -0
- package/dist/docs/components/tempo-logo.md +185 -0
- package/dist/docs/components/text-input.md +624 -0
- package/dist/docs/components/textarea.md +352 -0
- package/dist/docs/components/toast.md +535 -0
- package/dist/docs/components/token-logo.md +371 -0
- package/dist/docs/components/token.md +247 -0
- package/dist/docs/components/tooltip.md +490 -0
- package/dist/docs/components/verification-code.md +116 -0
- package/dist/docs/components/visual.md +249 -0
- package/dist/docs/components.md +203 -0
- package/dist/docs/foundations/accessibility.md +377 -0
- package/dist/docs/foundations/agents.md +150 -0
- package/dist/docs/foundations/color.md +522 -0
- package/dist/docs/foundations/content/tone.md +194 -0
- package/dist/docs/foundations/content/voice.md +194 -0
- package/dist/docs/foundations/content/writing-style.md +406 -0
- package/dist/docs/foundations/iconography.md +282 -0
- package/dist/docs/foundations/intent.md +360 -0
- package/dist/docs/foundations/layout.md +508 -0
- package/dist/docs/foundations/linter.md +296 -0
- package/dist/docs/foundations/motion.md +151 -0
- package/dist/docs/foundations/radius-and-padding.md +86 -0
- package/dist/docs/foundations/typography.md +266 -0
- package/dist/docs/index.md +137 -0
- package/dist/docs/introduction/faq.md +132 -0
- package/dist/docs/introduction/getting-started.md +377 -0
- package/dist/docs/patterns/blockchain-values.md +709 -0
- package/dist/docs/patterns/dashboards.md +638 -0
- package/dist/docs/patterns/destructive-actions.md +626 -0
- package/dist/docs/patterns/empty-states.md +612 -0
- package/dist/docs/patterns/errors-and-validation.md +808 -0
- package/dist/docs/patterns/feedback-and-status.md +518 -0
- package/dist/docs/patterns/forms.md +679 -0
- package/dist/docs/patterns/loading.md +630 -0
- package/dist/docs/patterns/navigation.md +397 -0
- package/dist/docs/patterns/payments.md +765 -0
- package/dist/docs/patterns/responsive-layout.md +997 -0
- package/dist/docs/patterns/tables-and-lists.md +964 -0
- package/dist/docs/products/tempo-console.md +671 -0
- package/dist/docs/products/tempo-performance.md +437 -0
- package/dist/docs/products/tempo-wallet.md +438 -0
- package/package.json +1 -1
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
# Color
|
|
2
|
+
|
|
3
|
+
Color tokens for text, surfaces, borders, and status, with contrast rules.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Color in Tempo is mostly black and white. Text, fills, and edges are neutrals at different strengths, so a screen reads through contrast and hierarchy rather than hue. A white card on a light gray page, black text, and one black primary action carry most of the interface.
|
|
8
|
+
|
|
9
|
+
Hue is the exception. Green, orange, and red report status in alerts, banners, and field states, and never decorate. Blue and violet mark tips and announcements.
|
|
10
|
+
|
|
11
|
+
Every color is a token named for its role. Backgrounds and containers fill, content colors text and icons, and lines and borders draw edges. Each token holds a light and a dark value, so one token works in both schemes.
|
|
12
|
+
|
|
13
|
+
## Scales
|
|
14
|
+
|
|
15
|
+
Scales hold the raw colors that tokens draw from. Use a scale step directly only for charts and categories.
|
|
16
|
+
|
|
17
|
+
### Neutral
|
|
18
|
+
|
|
19
|
+
| TokenLogo | Value |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `neutral.000` | `#fff` |
|
|
22
|
+
| `neutral.003` | `#f7f7f7` |
|
|
23
|
+
| `neutral.004` | `#f5f5f5` |
|
|
24
|
+
| `neutral.006` | `#f0f0f0` |
|
|
25
|
+
| `neutral.008` | `#ebebeb` |
|
|
26
|
+
| `neutral.012` | `#e0e0e0` |
|
|
27
|
+
| `neutral.016` | `#d6d6d6` |
|
|
28
|
+
| `neutral.020` | `#ccc` |
|
|
29
|
+
| `neutral.024` | `#c2c2c2` |
|
|
30
|
+
| `neutral.028` | `#b8b8b8` |
|
|
31
|
+
| `neutral.032` | `#adadad` |
|
|
32
|
+
| `neutral.036` | `#a3a3a3` |
|
|
33
|
+
| `neutral.040` | `#999` |
|
|
34
|
+
| `neutral.044` | `#8f8f8f` |
|
|
35
|
+
| `neutral.048` | `#858585` |
|
|
36
|
+
| `neutral.052` | `#7a7a7a` |
|
|
37
|
+
| `neutral.056` | `#707070` |
|
|
38
|
+
| `neutral.060` | `#666` |
|
|
39
|
+
| `neutral.064` | `#5c5c5c` |
|
|
40
|
+
| `neutral.068` | `#525252` |
|
|
41
|
+
| `neutral.072` | `#474747` |
|
|
42
|
+
| `neutral.076` | `#3d3d3d` |
|
|
43
|
+
| `neutral.080` | `#333` |
|
|
44
|
+
| `neutral.084` | `#292929` |
|
|
45
|
+
| `neutral.088` | `#1f1f1f` |
|
|
46
|
+
| `neutral.092` | `#141414` |
|
|
47
|
+
| `neutral.096` | `#0a0a0a` |
|
|
48
|
+
| `neutral.100` | `#000` |
|
|
49
|
+
|
|
50
|
+
Each step names a percentage of black, from white to black.
|
|
51
|
+
|
|
52
|
+
### Shade and Tint
|
|
53
|
+
|
|
54
|
+
| TokenLogo | Value |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `neutral.shade.000` | `#00000000` |
|
|
57
|
+
| `neutral.shade.003` | `#00000008` |
|
|
58
|
+
| `neutral.shade.004` | `#0000000a` |
|
|
59
|
+
| `neutral.shade.008` | `#00000014` |
|
|
60
|
+
| `neutral.shade.012` | `#0000001f` |
|
|
61
|
+
| `neutral.shade.016` | `#00000029` |
|
|
62
|
+
| `neutral.shade.020` | `#00000033` |
|
|
63
|
+
| `neutral.shade.032` | `#00000052` |
|
|
64
|
+
| `neutral.shade.040` | `#00000066` |
|
|
65
|
+
| `neutral.shade.056` | `#0000008f` |
|
|
66
|
+
| `neutral.shade.060` | `#00000099` |
|
|
67
|
+
| `neutral.shade.080` | `#000000cc` |
|
|
68
|
+
|
|
69
|
+
| TokenLogo | Value |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `neutral.tint.000` | `#ffffff00` |
|
|
72
|
+
| `neutral.tint.008` | `#ffffff14` |
|
|
73
|
+
| `neutral.tint.012` | `#ffffff1f` |
|
|
74
|
+
| `neutral.tint.016` | `#ffffff29` |
|
|
75
|
+
| `neutral.tint.020` | `#ffffff33` |
|
|
76
|
+
| `neutral.tint.024` | `#ffffff3d` |
|
|
77
|
+
| `neutral.tint.040` | `#ffffff66` |
|
|
78
|
+
| `neutral.tint.048` | `#ffffff7a` |
|
|
79
|
+
| `neutral.tint.052` | `#ffffff85` |
|
|
80
|
+
| `neutral.tint.056` | `#ffffff8f` |
|
|
81
|
+
| `neutral.tint.064` | `#ffffffa3` |
|
|
82
|
+
| `neutral.tint.080` | `#ffffffcc` |
|
|
83
|
+
|
|
84
|
+
Shades are black and tints are white, at the opacity the step names, so a fill keeps the same relative step on any background.
|
|
85
|
+
|
|
86
|
+
### Accent
|
|
87
|
+
|
|
88
|
+
| Hue | Background | Foreground |
|
|
89
|
+
| --- | --- | --- |
|
|
90
|
+
| blue | `accent.blue.background` (`#4471ed` light, `#7498fb` dark) | `accent.blue.foreground` (`#3059d3` light, `#7498fb` dark) |
|
|
91
|
+
| cyan | `accent.cyan.background` (`#00aacb` light, `#48cce6` dark) | `accent.cyan.foreground` (`#056e85` light, `#48cce6` dark) |
|
|
92
|
+
| green | `accent.green.background` (`#13a963` light, `#59e5a4` dark) | `accent.green.foreground` (`#007441` light, `#59e5a4` dark) |
|
|
93
|
+
| magenta | `accent.magenta.background` (`#cc055b` light, `#e54088` dark) | `accent.magenta.foreground` (`#ba0352` light, `#e54088` dark) |
|
|
94
|
+
| olive | `accent.olive.background` (`#95b226` light, `#c4dc65` dark) | `accent.olive.foreground` (`#596d01` light, `#c4dc65` dark) |
|
|
95
|
+
| orange | `accent.orange.background` (`#e06f12` light, `#fa8e36` dark) | `accent.orange.foreground` (`#a14d04` light, `#fa8e36` dark) |
|
|
96
|
+
| purple | `accent.purple.background` (`#ba59dd` light, `#cf79ef` dark) | `accent.purple.foreground` (`#9835ba` light, `#cf79ef` dark) |
|
|
97
|
+
| red | `accent.red.background` (`#eb3417` light, `#f55c45` dark) | `accent.red.foreground` (`#bf1d00` light, `#f55c45` dark) |
|
|
98
|
+
| violet | `accent.violet.background` (`#7e59e4` light, `#9877f1` dark) | `accent.violet.foreground` (`#6f47d1` light, `#9877f1` dark) |
|
|
99
|
+
|
|
100
|
+
Each hue has a background, which switches with the scheme, and a foreground for accent text that stays readable on every surface.
|
|
101
|
+
|
|
102
|
+
## Backgrounds
|
|
103
|
+
|
|
104
|
+
Two backgrounds sit below every component, and a third fills small chips on a visual. Components on them take their fills, borders, and text from the tokens that follow.
|
|
105
|
+
|
|
106
|
+
* `background.primary` (`#f5f5f5` light, `#141414` dark): The page behind cards, tables, and the app shell.
|
|
107
|
+
* `background.elevated` (`#fff` light, `#1a1a1a` dark): Cards, dialogs, menus, and popovers above the page.
|
|
108
|
+
* `background.secondary` (`#fff` light, `#141414` dark): Badges and chips that sit on a visual or a tint.
|
|
109
|
+
|
|
110
|
+
## Containers
|
|
111
|
+
|
|
112
|
+
Containers fill components such as menu items, badges, and selected rows. They are translucent, so a fill keeps the same relative step on the page and on an elevated surface.
|
|
113
|
+
|
|
114
|
+
* `container.subtle` (`#00000008` light, `#ffffff14` dark): The faintest fill, such as a disabled field.
|
|
115
|
+
* `container.regular` (`#0000000a` light, `#ffffff14` dark): Secondary buttons, filled fields, and tags.
|
|
116
|
+
* `container.strong` (`#00000014` light, `#ffffff29` dark): Hovered and pressed controls, and slider tracks.
|
|
117
|
+
* `container.positive` (`rgb(19 169 99 / 0.08)` light, `rgb(89 229 164 / 0.16)` dark): Positive alerts and tags, and copied values.
|
|
118
|
+
* `container.warning` (`rgb(224 111 18 / 0.08)` light, `rgb(250 142 54 / 0.16)` dark): Warning alerts, banners, and tags.
|
|
119
|
+
* `container.negative` (`rgb(235 52 23 / 0.08)` light, `rgb(245 92 69 / 0.16)` dark): Negative alerts, banners, and tags.
|
|
120
|
+
|
|
121
|
+
## Borders
|
|
122
|
+
|
|
123
|
+
Lines outline edges and divide content, and borders mark focus and validation.
|
|
124
|
+
|
|
125
|
+
* `line.secondary` (`#00000014` light, `#ffffff14` dark): Dividers, table borders, and resting outlined fields.
|
|
126
|
+
* `line.primary` (`#00000029` light, `#ffffff3d` dark): Outlined fields on hover, and unchecked choices.
|
|
127
|
+
* `border.focus` (`#00000066` light, `#ffffff85` dark): The 2px outline that controls draw on keyboard focus.
|
|
128
|
+
* `border.positive` (`rgb(19 169 99 / 0.16)` light, `rgb(89 229 164 / 0.32)` dark): The ring around a field that passed validation.
|
|
129
|
+
* `border.warning` (`rgb(224 111 18 / 0.16)` light, `rgb(250 142 54 / 0.32)` dark): A ring that flags a field the reader should check.
|
|
130
|
+
* `border.negative` (`rgb(235 52 23 / 0.16)` light, `rgb(245 92 69 / 0.32)` dark): The ring around an invalid field, checkbox, or switch.
|
|
131
|
+
|
|
132
|
+
## Content
|
|
133
|
+
|
|
134
|
+
Content tokens color text and icons. Pick one by how much the reader needs it.
|
|
135
|
+
|
|
136
|
+
* `content.primary` (`#000` light, `#fff` dark): Titles, values, body text, and primary fills.
|
|
137
|
+
* `content.secondary` (`#0000008f` light, `#ffffffa3` dark): Descriptions, captions, table cells, and placeholders.
|
|
138
|
+
* `content.tertiary` (`#00000066` light, `#ffffff85` dark): Icons, chevrons, and separators beside a label.
|
|
139
|
+
* `content.subtle` (`#00000033` light, `#ffffff33` dark): Tracks and marks that carry no text, such as a gauge.
|
|
140
|
+
* `content.positive` (`#13a963` light, `#59e5a4` dark): Success text and icons, such as a confirmed payment.
|
|
141
|
+
* `content.warning` (`#e06f12` light, `#fa8e36` dark): Caution text and icons, such as a fee warning.
|
|
142
|
+
* `content.negative` (`#eb3417` light, `#f55c45` dark): Error text, field errors, and negative button fills.
|
|
143
|
+
|
|
144
|
+
## Materials and Scrims
|
|
145
|
+
|
|
146
|
+
Materials are translucent layers in five strengths, and scrims dim the page behind an overlay. No component uses them yet.
|
|
147
|
+
|
|
148
|
+
* `material.ultrathin` (`#00000014` light, `#ffffff29` dark): The lightest translucent layer.
|
|
149
|
+
* `material.thin` (`#00000033` light, `#ffffff3d` dark): A light translucent layer.
|
|
150
|
+
* `material.regular` (`#00000066` light, `#ffffff7a` dark): A translucent layer of medium strength.
|
|
151
|
+
* `material.thick` (`#00000099` light, `#ffffffa3` dark): A dense translucent layer.
|
|
152
|
+
* `material.ultrathick` (`#000000cc` light, `#ffffffcc` dark): The densest translucent layer.
|
|
153
|
+
|
|
154
|
+
* `scrim.regular` (`#00000029`): Dims the page behind an overlay, at 16% black.
|
|
155
|
+
* `scrim.strong` (`#00000052`): Dims the page further, at 32% black.
|
|
156
|
+
|
|
157
|
+
## Intents
|
|
158
|
+
|
|
159
|
+
Components that report status take an intent, not a hue, so a status looks the same everywhere. Choose the intent by the message. An [Alert](/docs/components/alert) tints its container and colors its indicator by intent.
|
|
160
|
+
|
|
161
|
+
* **Neutral (content.subtle):** Default states and features, such as a payment that is still pending.
|
|
162
|
+
* **Positive (content.positive):** Success, completion, and incoming funds, such as a confirmed payment.
|
|
163
|
+
* **Warning (content.warning):** A risk that the reader must know about before they confirm an action.
|
|
164
|
+
* **Negative (content.negative):** Errors, failures, and destructive actions, such as a payment that failed.
|
|
165
|
+
* **Tip (accent.blue.background):** Optional context, such as the token that pays the network fee for a payment.
|
|
166
|
+
* **Special (accent.violet.background):** A new feature to announce, such as a vault that earns on idle USDC balances.
|
|
167
|
+
|
|
168
|
+
Cyan, magenta, olive, and purple have no intent, so keep them for charts and categories.
|
|
169
|
+
|
|
170
|
+
## Guidelines
|
|
171
|
+
|
|
172
|
+
### Choose Tokens by Role
|
|
173
|
+
|
|
174
|
+
Pick the token that names the role, not a scale step that looks right in one scheme. Never write a raw color into product styles, and propose a token in the Design System project when none fits.
|
|
175
|
+
|
|
176
|
+
**Do:** Use tokens, which switch value with the scheme.
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
/**
|
|
180
|
+
* Do example for "Choose Tokens by Job" on the Color page.
|
|
181
|
+
* Use tokens, which switch value with the scheme.
|
|
182
|
+
* @module
|
|
183
|
+
*/
|
|
184
|
+
import { style, variants } from '@tempoxyz/ds'
|
|
185
|
+
|
|
186
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
187
|
+
export function Demo() {
|
|
188
|
+
return (
|
|
189
|
+
<div {...styles.row()}>
|
|
190
|
+
<div {...styles.panel({ scheme: 'light' })}>
|
|
191
|
+
<span {...styles.label()}>Balance</span>
|
|
192
|
+
<span {...styles.value()}>1,250.00 USDC</span>
|
|
193
|
+
</div>
|
|
194
|
+
<div {...styles.panel({ scheme: 'dark' })}>
|
|
195
|
+
<span {...styles.label()}>Balance</span>
|
|
196
|
+
<span {...styles.value()}>1,250.00 USDC</span>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
namespace styles {
|
|
203
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
204
|
+
|
|
205
|
+
export const panel = variants({
|
|
206
|
+
base: {
|
|
207
|
+
backgroundColor: 'background.elevated',
|
|
208
|
+
borderColor: 'line.secondary',
|
|
209
|
+
borderRadius: 'xs',
|
|
210
|
+
borderStyle: 'solid',
|
|
211
|
+
borderWidth: 'regular',
|
|
212
|
+
display: 'grid',
|
|
213
|
+
gap: '4',
|
|
214
|
+
padding: '16',
|
|
215
|
+
},
|
|
216
|
+
variants: {
|
|
217
|
+
scheme: {
|
|
218
|
+
dark: { colorScheme: 'dark !custom' },
|
|
219
|
+
light: { colorScheme: 'light !custom' },
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
export const row = style({ display: 'flex', flexWrap: 'wrap', gap: '12' })
|
|
225
|
+
|
|
226
|
+
export const value = style({ color: 'content.primary', typography: 'body.b1Strong' })
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Don't:** Fix a color that only passes in one scheme.
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
/**
|
|
234
|
+
* Don't example for "Choose Tokens by Job" on the Color page.
|
|
235
|
+
* Don't fix a color that only passes in one scheme.
|
|
236
|
+
* @module
|
|
237
|
+
*/
|
|
238
|
+
import { style, variants } from '@tempoxyz/ds'
|
|
239
|
+
|
|
240
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
241
|
+
export function Demo() {
|
|
242
|
+
return (
|
|
243
|
+
<div {...styles.row()}>
|
|
244
|
+
<div {...styles.panel({ scheme: 'light' })}>
|
|
245
|
+
<span {...styles.label()}>Balance</span>
|
|
246
|
+
<span {...styles.value()}>1,250.00 USDC</span>
|
|
247
|
+
</div>
|
|
248
|
+
<div {...styles.panel({ scheme: 'dark' })}>
|
|
249
|
+
<span {...styles.label()}>Balance</span>
|
|
250
|
+
<span {...styles.value()}>1,250.00 USDC</span>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
namespace styles {
|
|
257
|
+
export const label = style({ color: '#666666 !custom', typography: 'body.b3' })
|
|
258
|
+
|
|
259
|
+
export const panel = variants({
|
|
260
|
+
base: {
|
|
261
|
+
backgroundColor: 'background.elevated',
|
|
262
|
+
borderColor: 'line.secondary',
|
|
263
|
+
borderRadius: 'xs',
|
|
264
|
+
borderStyle: 'solid',
|
|
265
|
+
borderWidth: 'regular',
|
|
266
|
+
display: 'grid',
|
|
267
|
+
gap: '4',
|
|
268
|
+
padding: '16',
|
|
269
|
+
},
|
|
270
|
+
variants: {
|
|
271
|
+
scheme: {
|
|
272
|
+
dark: { colorScheme: 'dark !custom' },
|
|
273
|
+
light: { colorScheme: 'light !custom' },
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
export const row = style({ display: 'flex', flexWrap: 'wrap', gap: '12' })
|
|
279
|
+
|
|
280
|
+
export const value = style({ color: '#171717 !custom', typography: 'body.b1Strong' })
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Keep Text at Readable Contrast
|
|
285
|
+
|
|
286
|
+
Set text in the primary or secondary content color, since WCAG counts it as text. Field placeholders are the exception: they take the tertiary color, as the design draws them, below 4.5:1. Otherwise keep the tertiary color for glyphs, such as chevrons and separators.
|
|
287
|
+
|
|
288
|
+
**Do:** Set descriptions in `content.secondary`, which stays above 4.5:1 on both backgrounds.
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
/**
|
|
292
|
+
* Do example for "Keep Text at Readable Contrast" on the Color page.
|
|
293
|
+
* Set descriptions in `content.secondary`, which stays above 4.5:1 on both backgrounds.
|
|
294
|
+
* @module
|
|
295
|
+
*/
|
|
296
|
+
import { style } from '@tempoxyz/ds'
|
|
297
|
+
|
|
298
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
299
|
+
export function Demo() {
|
|
300
|
+
return (
|
|
301
|
+
<div {...styles.stack()}>
|
|
302
|
+
<span {...styles.title()}>Network fee</span>
|
|
303
|
+
<span {...styles.description()}>Paid in PathUSD. Settles with the payment.</span>
|
|
304
|
+
</div>
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
namespace styles {
|
|
309
|
+
export const description = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
310
|
+
|
|
311
|
+
export const stack = style({ display: 'grid', gap: '4' })
|
|
312
|
+
|
|
313
|
+
export const title = style({ color: 'content.primary', typography: 'body.b1Strong' })
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Don't:** Set text people need to read in `content.tertiary`.
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
/**
|
|
321
|
+
* Don't example for "Keep Text at Readable Contrast" on the Color page.
|
|
322
|
+
* Don't set text people need to read in `content.tertiary`.
|
|
323
|
+
* @module
|
|
324
|
+
*/
|
|
325
|
+
import { style } from '@tempoxyz/ds'
|
|
326
|
+
|
|
327
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
328
|
+
export function Demo() {
|
|
329
|
+
return (
|
|
330
|
+
<div {...styles.stack()}>
|
|
331
|
+
<span {...styles.title()}>Network fee</span>
|
|
332
|
+
<span {...styles.description()}>Paid in PathUSD. Settles with the payment.</span>
|
|
333
|
+
</div>
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
namespace styles {
|
|
338
|
+
export const description = style({ color: 'content.tertiary', typography: 'body.b2' })
|
|
339
|
+
|
|
340
|
+
export const stack = style({ display: 'grid', gap: '4' })
|
|
341
|
+
|
|
342
|
+
export const title = style({ color: 'content.primary', typography: 'body.b1Strong' })
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Reserve Accents for Meaning
|
|
347
|
+
|
|
348
|
+
Blue marks information, green success, orange caution, and red errors and destructive actions. Focus and selection stay neutral.
|
|
349
|
+
|
|
350
|
+
**Do:** Use red for an error or a removal.
|
|
351
|
+
|
|
352
|
+
```tsx
|
|
353
|
+
<Alert intent="negative">
|
|
354
|
+
<Alert.Icon />
|
|
355
|
+
<Alert.Content>This access key was revoked.</Alert.Content>
|
|
356
|
+
</Alert>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Don't:** Use red to draw attention to a safe event.
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
<Alert intent="negative">
|
|
363
|
+
<Alert.Icon />
|
|
364
|
+
<Alert.Content>Your funds arrived.</Alert.Content>
|
|
365
|
+
</Alert>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Use One Intent per Message
|
|
369
|
+
|
|
370
|
+
**Do:** Use a single warning for a single risk.
|
|
371
|
+
|
|
372
|
+
```tsx
|
|
373
|
+
<Alert intent="warning">
|
|
374
|
+
<Alert.Icon />
|
|
375
|
+
<Alert.Content>This address has never received a payment from you.</Alert.Content>
|
|
376
|
+
</Alert>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Don't:** Stack alerts of different intents for one risk.
|
|
380
|
+
|
|
381
|
+
```tsx
|
|
382
|
+
<Alert>
|
|
383
|
+
<Alert.Icon />
|
|
384
|
+
<Alert.Content>New address.</Alert.Content>
|
|
385
|
+
</Alert>
|
|
386
|
+
<Alert intent="warning">
|
|
387
|
+
<Alert.Icon />
|
|
388
|
+
<Alert.Content>Check the address.</Alert.Content>
|
|
389
|
+
</Alert>
|
|
390
|
+
<Alert intent="negative">
|
|
391
|
+
<Alert.Icon />
|
|
392
|
+
<Alert.Content>Payments cannot be reversed.</Alert.Content>
|
|
393
|
+
</Alert>
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Never Use Color Alone
|
|
397
|
+
|
|
398
|
+
Pair every status color with text or an icon. In charts, name each series in a label or a legend.
|
|
399
|
+
|
|
400
|
+
**Do:** Name each status in text beside its color.
|
|
401
|
+
|
|
402
|
+
```tsx
|
|
403
|
+
/** Do example for "Never Use Color Alone" on the Color page: name each status in text beside its color. @module */
|
|
404
|
+
import { Alert, style } from '@tempoxyz/ds'
|
|
405
|
+
|
|
406
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
407
|
+
export function Demo() {
|
|
408
|
+
return (
|
|
409
|
+
<div {...styles.stack()}>
|
|
410
|
+
<Alert intent="positive">
|
|
411
|
+
<Alert.Icon />
|
|
412
|
+
<Alert.Content>Confirmed</Alert.Content>
|
|
413
|
+
</Alert>
|
|
414
|
+
<Alert intent="warning">
|
|
415
|
+
<Alert.Icon />
|
|
416
|
+
<Alert.Content>Pending</Alert.Content>
|
|
417
|
+
</Alert>
|
|
418
|
+
<Alert intent="negative">
|
|
419
|
+
<Alert.Icon />
|
|
420
|
+
<Alert.Content>Failed</Alert.Content>
|
|
421
|
+
</Alert>
|
|
422
|
+
</div>
|
|
423
|
+
)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
namespace styles {
|
|
427
|
+
export const stack = style({
|
|
428
|
+
display: 'flex',
|
|
429
|
+
flexDirection: 'column',
|
|
430
|
+
gap: '8',
|
|
431
|
+
width: '100% !custom',
|
|
432
|
+
})
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Don't:** Rely on colored dots to tell Confirmed from Failed.
|
|
437
|
+
|
|
438
|
+
```tsx
|
|
439
|
+
/**
|
|
440
|
+
* Don't example for "Never Use Color Alone" on the Color page.
|
|
441
|
+
* Don't rely on colored dots to tell Confirmed from Failed.
|
|
442
|
+
* @module
|
|
443
|
+
*/
|
|
444
|
+
import { style, variants } from '@tempoxyz/ds'
|
|
445
|
+
|
|
446
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
447
|
+
export function Demo() {
|
|
448
|
+
return (
|
|
449
|
+
<div {...styles.row()}>
|
|
450
|
+
<span {...styles.dot({ intent: 'positive' })} />
|
|
451
|
+
<span {...styles.dot({ intent: 'warning' })} />
|
|
452
|
+
<span {...styles.dot({ intent: 'negative' })} />
|
|
453
|
+
</div>
|
|
454
|
+
)
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
namespace styles {
|
|
458
|
+
export const dot = variants({
|
|
459
|
+
base: { borderRadius: 'full', cornerShape: 'round', height: '12', width: '12' },
|
|
460
|
+
variants: {
|
|
461
|
+
intent: {
|
|
462
|
+
negative: { backgroundColor: 'content.negative' },
|
|
463
|
+
positive: { backgroundColor: 'content.positive' },
|
|
464
|
+
warning: { backgroundColor: 'content.warning' },
|
|
465
|
+
},
|
|
466
|
+
},
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '16' })
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Contrast
|
|
474
|
+
|
|
475
|
+
Tempo targets WCAG 2.2 AA in both schemes.
|
|
476
|
+
|
|
477
|
+
* **Body Text (4.5:1):** Body text against its background.
|
|
478
|
+
* **Large Text (3:1):** Text from 24px, or bold text from 18.66px.
|
|
479
|
+
* **Non-Text (3:1):** Focus outlines, state borders, and icons.
|
|
480
|
+
|
|
481
|
+
Each ratio lists light mode first. Several pairs fall below these targets.
|
|
482
|
+
|
|
483
|
+
* **Primary on Elevated (21:1 and 18.4:1):** `content.primary` on `background.elevated`. Passes for any text, in light and dark.
|
|
484
|
+
* **Secondary on Elevated (4.9:1 and 6.4:1):** `content.secondary` on `background.elevated`. Passes for body text, such as card descriptions.
|
|
485
|
+
* **Secondary on Page (4.8:1 and 6.5:1):** `content.secondary` on `background.primary`. Passes for body text, such as page captions.
|
|
486
|
+
* **Tertiary on Elevated (2.9:1 and 3.8:1):** `content.tertiary` glyphs, such as breadcrumb separators. Too faint for text in either scheme.
|
|
487
|
+
* **Status Text on Status Fill (2.8:1+ and 4.7:1+):** `content.positive`, `warning`, and `negative` on their containers. Below 4.5:1 in light mode.
|
|
488
|
+
* **Focus Outline (2.8:1 and 5.7:1):** The `border.focus` outline against the page. Below the 3:1 minimum in light mode.
|
|
489
|
+
* **Invalid Border (1.3:1 and 1.6:1):** The `border.negative` ring against a surface. Below 3:1, so pair it with `Field.Error` text.
|
|
490
|
+
|
|
491
|
+
Lines measure below 3:1, so they divide content but never identify a control alone. Disabled controls are exempt, but must still look disabled.
|
|
492
|
+
|
|
493
|
+
## Accessibility
|
|
494
|
+
|
|
495
|
+
* **Visible Focus (border.focus):** Components draw a 2px outline on keyboard focus. Don't replace it with a color change alone.
|
|
496
|
+
* **Forced Colors (forced-colors):** Fields and buttons swap their resting outline for a system color outline on keyboard focus.
|
|
497
|
+
|
|
498
|
+
## Related
|
|
499
|
+
|
|
500
|
+
[Typography](/docs/foundations/typography)
|
|
501
|
+
|
|
502
|
+
Covers text sizes that change contrast thresholds.
|
|
503
|
+
|
|
504
|
+
[Accessibility](/docs/foundations/accessibility)
|
|
505
|
+
|
|
506
|
+
Covers the full WCAG 2.2 AA checklist.
|
|
507
|
+
|
|
508
|
+
[Feedback and Status](/docs/patterns/feedback-and-status)
|
|
509
|
+
|
|
510
|
+
Covers choosing an intent.
|
|
511
|
+
|
|
512
|
+
[Banner](/docs/components/banner)
|
|
513
|
+
|
|
514
|
+
Use for status text on a status fill.
|
|
515
|
+
|
|
516
|
+
[Alert](/docs/components/alert)
|
|
517
|
+
|
|
518
|
+
Use for intent colors in context.
|
|
519
|
+
|
|
520
|
+
[Banner](/docs/components/banner)
|
|
521
|
+
|
|
522
|
+
Use for intent colors in context.
|