@tempoxyz/ds 0.3.9 → 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.
Files changed (128) hide show
  1. package/dist/docs/AGENTS.md +9 -0
  2. package/dist/docs/components/accordion.md +489 -0
  3. package/dist/docs/components/address-card.md +147 -0
  4. package/dist/docs/components/agent-logo.md +194 -0
  5. package/dist/docs/components/alert-dialog.md +631 -0
  6. package/dist/docs/components/alert.md +448 -0
  7. package/dist/docs/components/amount-input.md +305 -0
  8. package/dist/docs/components/amount.md +794 -0
  9. package/dist/docs/components/app-shell.md +559 -0
  10. package/dist/docs/components/asset-chip.md +294 -0
  11. package/dist/docs/components/autocomplete.md +619 -0
  12. package/dist/docs/components/avatar.md +321 -0
  13. package/dist/docs/components/badge.md +339 -0
  14. package/dist/docs/components/badged-logo.md +116 -0
  15. package/dist/docs/components/banner.md +379 -0
  16. package/dist/docs/components/bar-chart.md +208 -0
  17. package/dist/docs/components/breadcrumbs.md +380 -0
  18. package/dist/docs/components/button-group.md +286 -0
  19. package/dist/docs/components/button.md +650 -0
  20. package/dist/docs/components/calendar.md +375 -0
  21. package/dist/docs/components/callout.md +96 -0
  22. package/dist/docs/components/checkbox-group.md +521 -0
  23. package/dist/docs/components/checkbox.md +467 -0
  24. package/dist/docs/components/choice-group.md +516 -0
  25. package/dist/docs/components/choicebox.md +641 -0
  26. package/dist/docs/components/code.md +100 -0
  27. package/dist/docs/components/combobox.md +939 -0
  28. package/dist/docs/components/container.md +257 -0
  29. package/dist/docs/components/copy-button.md +642 -0
  30. package/dist/docs/components/date-picker.md +514 -0
  31. package/dist/docs/components/dialog.md +1332 -0
  32. package/dist/docs/components/drawer.md +966 -0
  33. package/dist/docs/components/empty.md +340 -0
  34. package/dist/docs/components/field.md +570 -0
  35. package/dist/docs/components/fieldset.md +398 -0
  36. package/dist/docs/components/frame.md +434 -0
  37. package/dist/docs/components/gauge.md +299 -0
  38. package/dist/docs/components/get-started-visual.md +117 -0
  39. package/dist/docs/components/grid.md +288 -0
  40. package/dist/docs/components/hero-visual.md +155 -0
  41. package/dist/docs/components/hex.md +487 -0
  42. package/dist/docs/components/icon-tile.md +292 -0
  43. package/dist/docs/components/identicon.md +371 -0
  44. package/dist/docs/components/inline.md +233 -0
  45. package/dist/docs/components/inset.md +225 -0
  46. package/dist/docs/components/kbd.md +423 -0
  47. package/dist/docs/components/list-group.md +981 -0
  48. package/dist/docs/components/loading-dots.md +237 -0
  49. package/dist/docs/components/menu.md +934 -0
  50. package/dist/docs/components/native-select.md +204 -0
  51. package/dist/docs/components/network-logo.md +248 -0
  52. package/dist/docs/components/number-field.md +543 -0
  53. package/dist/docs/components/otp-field.md +616 -0
  54. package/dist/docs/components/pagination.md +516 -0
  55. package/dist/docs/components/popover.md +544 -0
  56. package/dist/docs/components/progress.md +388 -0
  57. package/dist/docs/components/qr.md +314 -0
  58. package/dist/docs/components/radio-group.md +528 -0
  59. package/dist/docs/components/secret-value.md +406 -0
  60. package/dist/docs/components/select.md +751 -0
  61. package/dist/docs/components/separator.md +379 -0
  62. package/dist/docs/components/sidebar-menu.md +922 -0
  63. package/dist/docs/components/skeleton.md +517 -0
  64. package/dist/docs/components/slider.md +539 -0
  65. package/dist/docs/components/snippet.md +424 -0
  66. package/dist/docs/components/spinner.md +216 -0
  67. package/dist/docs/components/split-bar.md +139 -0
  68. package/dist/docs/components/split-button.md +464 -0
  69. package/dist/docs/components/stack.md +299 -0
  70. package/dist/docs/components/status-chip.md +226 -0
  71. package/dist/docs/components/status-indicator.md +119 -0
  72. package/dist/docs/components/status-row.md +174 -0
  73. package/dist/docs/components/stepper.md +451 -0
  74. package/dist/docs/components/success-hero.md +157 -0
  75. package/dist/docs/components/surface.md +639 -0
  76. package/dist/docs/components/switch.md +472 -0
  77. package/dist/docs/components/table.md +967 -0
  78. package/dist/docs/components/tabs.md +627 -0
  79. package/dist/docs/components/tempo-logo.md +185 -0
  80. package/dist/docs/components/text-input.md +624 -0
  81. package/dist/docs/components/textarea.md +352 -0
  82. package/dist/docs/components/toast.md +535 -0
  83. package/dist/docs/components/token-logo.md +371 -0
  84. package/dist/docs/components/token.md +247 -0
  85. package/dist/docs/components/tooltip.md +490 -0
  86. package/dist/docs/components/verification-code.md +116 -0
  87. package/dist/docs/components/visual.md +249 -0
  88. package/dist/docs/components.md +203 -0
  89. package/dist/docs/foundations/accessibility.md +377 -0
  90. package/dist/docs/foundations/agents.md +150 -0
  91. package/dist/docs/foundations/color.md +522 -0
  92. package/dist/docs/foundations/content/tone.md +194 -0
  93. package/dist/docs/foundations/content/voice.md +194 -0
  94. package/dist/docs/foundations/content/writing-style.md +406 -0
  95. package/dist/docs/foundations/iconography.md +282 -0
  96. package/dist/docs/foundations/intent.md +360 -0
  97. package/dist/docs/foundations/layout.md +508 -0
  98. package/dist/docs/foundations/linter.md +296 -0
  99. package/dist/docs/foundations/motion.md +151 -0
  100. package/dist/docs/foundations/radius-and-padding.md +86 -0
  101. package/dist/docs/foundations/typography.md +266 -0
  102. package/dist/docs/index.md +137 -0
  103. package/dist/docs/introduction/faq.md +132 -0
  104. package/dist/docs/introduction/getting-started.md +377 -0
  105. package/dist/docs/patterns/blockchain-values.md +709 -0
  106. package/dist/docs/patterns/dashboards.md +638 -0
  107. package/dist/docs/patterns/destructive-actions.md +626 -0
  108. package/dist/docs/patterns/empty-states.md +612 -0
  109. package/dist/docs/patterns/errors-and-validation.md +808 -0
  110. package/dist/docs/patterns/feedback-and-status.md +518 -0
  111. package/dist/docs/patterns/forms.md +679 -0
  112. package/dist/docs/patterns/loading.md +630 -0
  113. package/dist/docs/patterns/navigation.md +397 -0
  114. package/dist/docs/patterns/payments.md +765 -0
  115. package/dist/docs/patterns/responsive-layout.md +997 -0
  116. package/dist/docs/patterns/tables-and-lists.md +964 -0
  117. package/dist/docs/products/tempo-console.md +671 -0
  118. package/dist/docs/products/tempo-performance.md +437 -0
  119. package/dist/docs/products/tempo-wallet.md +438 -0
  120. package/dist/web/components/OtpField.css +1 -1
  121. package/dist/web/components/OtpField.d.ts +1 -1
  122. package/dist/web/components/OtpField.d.ts.map +1 -1
  123. package/dist/web/components/OtpField.js +3 -4
  124. package/dist/web/components/OtpField.js.map +1 -1
  125. package/dist/web/components/OtpField.js.zyzz.json +1 -1
  126. package/dist/web/index.js.zyzz.json +1 -1
  127. package/package.json +1 -1
  128. package/src/web/components/OtpField.tsx +2 -24
@@ -0,0 +1,375 @@
1
+ # Calendar
2
+
3
+ A month grid for picking one date or a date range.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Calendar.tsx)
6
+
7
+ ## Overview
8
+
9
+ Shows one month at a time. The month buttons page through months, and each day is a button.
10
+
11
+ ## Examples
12
+
13
+ ### Basic
14
+
15
+ ```tsx
16
+ import { Calendar } from '@tempoxyz/ds'
17
+
18
+ export function Demo() {
19
+ return <Calendar defaultValue={new Date()} />
20
+ }
21
+ ```
22
+
23
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Calendar/Basic.tsx)
24
+
25
+ ### Mode
26
+
27
+ Set `mode="range"` to select a `{ from, to }` range. The default is `single`.
28
+
29
+ ```tsx
30
+ import { Calendar } from '@tempoxyz/ds'
31
+ import { useState } from 'react'
32
+
33
+ export function Demo() {
34
+ const [range, setRange] = useState<Calendar.Range | null>(null)
35
+
36
+ return <Calendar mode="range" onValueChange={setRange} value={range} />
37
+ }
38
+ ```
39
+
40
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Calendar/Mode.tsx)
41
+
42
+ ### Disabled Dates
43
+
44
+ Set `min`, `max`, or `isDateDisabled` to mark unavailable days.
45
+
46
+ ```tsx
47
+ import { Calendar } from '@tempoxyz/ds'
48
+
49
+ export function Demo() {
50
+ const today = new Date()
51
+
52
+ return (
53
+ <Calendar
54
+ isDateDisabled={(date) => date.getDay() === 0}
55
+ max={new Date(today.getFullYear(), today.getMonth() + 1, 20)}
56
+ min={new Date(today.getFullYear(), today.getMonth() - 1, 5)}
57
+ />
58
+ )
59
+ }
60
+ ```
61
+
62
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Calendar/DisabledDates.tsx)
63
+
64
+ ### Locale
65
+
66
+ Set `locale` to format the month and weekdays. The default is the browser's locale.
67
+
68
+ ```tsx
69
+ import { Calendar } from '@tempoxyz/ds'
70
+
71
+ export function Demo() {
72
+ return <Calendar locale="de-DE" />
73
+ }
74
+ ```
75
+
76
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Calendar/Locale.tsx)
77
+
78
+ ## Anatomy
79
+
80
+ Import the component and assemble its parts.
81
+
82
+ ```tsx
83
+ import { Calendar } from '@tempoxyz/ds'
84
+
85
+ <Calendar />
86
+ ```
87
+
88
+ ## Guidelines
89
+
90
+ ### When to Use
91
+
92
+ * Pick a date near today with the grid always on screen, such as a start date in a side panel.
93
+ * Pick a date range with `mode="range"`, such as the period for an activity export.
94
+ * Show which days are available, such as business days for a bank withdrawal.
95
+
96
+ ### When Not to Use
97
+
98
+ * If the date is one field in a form, use [DatePicker](/docs/components/date-picker). It opens the same calendar in a popup.
99
+ * Use [TextInput](/docs/components/text-input) for dates far from today, such as a date of birth.
100
+ * Use [ChoiceGroup](/docs/components/choice-group) for preset ranges, such as 24H, 7D, and 30D above a chart.
101
+
102
+ ### Explain Unavailable Days
103
+
104
+ Set `min`, `max`, or `isDateDisabled`, and state the rule in text beside the calendar, not in a tooltip on each day. The month buttons can't page past `min` or `max`.
105
+
106
+ **Do:** State the rule below the calendar, such as Bank withdrawals settle on business days.
107
+
108
+ ```tsx
109
+ /**
110
+ * Do example for "Explain Unavailable Days" on the Calendar page.
111
+ * State the rule below the calendar, such as Bank withdrawals settle on business days.
112
+ * @module
113
+ */
114
+ import { Calendar, style } from '@tempoxyz/ds'
115
+
116
+ /** Renders the static preview, which the guideline card shows inert. */
117
+ export function Demo() {
118
+ return (
119
+ <div {...styles.stack()}>
120
+ <Calendar
121
+ defaultMonth={new Date(2026, 9, 1)}
122
+ isDateDisabled={(date) => date.getDay() === 0 || date.getDay() === 6}
123
+ />
124
+ <span {...styles.note()}>Bank withdrawals settle on business days.</span>
125
+ </div>
126
+ )
127
+ }
128
+
129
+ namespace styles {
130
+ export const stack = style({ display: 'flex', flexDirection: 'column', rowGap: '12' })
131
+
132
+ export const note = style({ color: 'content.secondary', typography: 'body.b3' })
133
+ }
134
+ ```
135
+
136
+ **Don't:** Disable days without saying why.
137
+
138
+ ```tsx
139
+ /**
140
+ * Don't example for "Explain Unavailable Days" on the Calendar page.
141
+ * Don't disable days without saying why.
142
+ * @module
143
+ */
144
+ import { Calendar } from '@tempoxyz/ds'
145
+
146
+ /** Renders the static preview, which the guideline card shows inert. */
147
+ export function Demo() {
148
+ return (
149
+ <Calendar
150
+ defaultMonth={new Date(2026, 9, 1)}
151
+ isDateDisabled={(date) => date.getDay() === 0 || date.getDay() === 6}
152
+ />
153
+ )
154
+ }
155
+ ```
156
+
157
+ ### Show a Range in Text Too
158
+
159
+ In range mode, `onValueChange` runs on every press: `{ from }` after the first, `{ from, to }` after the second. Apply a filter only after `to` is set.
160
+
161
+ **Do:** Show the selected range as text, such as Oct 1 to 14, 2026.
162
+
163
+ ```tsx
164
+ /**
165
+ * Do example for "Show a Range in Text Too" on the Calendar page.
166
+ * Show the selected range as text, such as Oct 1 to 14, 2026.
167
+ * @module
168
+ */
169
+ import { Calendar, style } from '@tempoxyz/ds'
170
+
171
+ /** Renders the static preview, which the guideline card shows inert. */
172
+ export function Demo() {
173
+ return (
174
+ <div {...styles.stack()}>
175
+ <span {...styles.range()}>Oct 1 to 14, 2026</span>
176
+ <Calendar
177
+ defaultValue={{ from: new Date(2026, 9, 1), to: new Date(2026, 9, 14) }}
178
+ mode="range"
179
+ />
180
+ </div>
181
+ )
182
+ }
183
+
184
+ namespace styles {
185
+ export const stack = style({ display: 'flex', flexDirection: 'column', rowGap: '12' })
186
+
187
+ export const range = style({ color: 'content.primary', typography: 'body.b2Strong' })
188
+ }
189
+ ```
190
+
191
+ **Don't:** Rely on the highlighted days alone to show the range.
192
+
193
+ ```tsx
194
+ /**
195
+ * Don't example for "Show a Range in Text Too" on the Calendar page.
196
+ * Don't rely on the highlighted days alone to show the range.
197
+ * @module
198
+ */
199
+ import { Calendar } from '@tempoxyz/ds'
200
+
201
+ /** Renders the static preview, which the guideline card shows inert. */
202
+ export function Demo() {
203
+ return (
204
+ <Calendar
205
+ defaultValue={{ from: new Date(2026, 9, 1), to: new Date(2026, 9, 14) }}
206
+ mode="range"
207
+ />
208
+ )
209
+ }
210
+ ```
211
+
212
+ ### Start on the Month of the Task
213
+
214
+ `defaultMonth` falls back to the selected day's month, then the current month. Set it to the month of the task, such as the start of a statement period. To sync the page with a typed [TextInput](/docs/components/text-input), control it with `month` and `onMonthChange`.
215
+
216
+ **Do:** Open on the month the task is about.
217
+
218
+ ```tsx
219
+ /**
220
+ * Do example for "Start on the Month of the Task" on the Calendar page.
221
+ * Open on the month the task is about.
222
+ * @module
223
+ */
224
+ import { Calendar, style } from '@tempoxyz/ds'
225
+
226
+ /** Renders the static preview, which the guideline card shows inert. */
227
+ export function Demo() {
228
+ return (
229
+ <div {...styles.stack()}>
230
+ <span {...styles.label()}>Start of the September statement</span>
231
+ <Calendar defaultMonth={new Date(2026, 8, 1)} />
232
+ </div>
233
+ )
234
+ }
235
+
236
+ namespace styles {
237
+ export const stack = style({ display: 'flex', flexDirection: 'column', rowGap: '12' })
238
+
239
+ export const label = style({ color: 'content.primary', typography: 'body.b2Strong' })
240
+ }
241
+ ```
242
+
243
+ **Don't:** Open on the current month when the task is about another one.
244
+
245
+ ```tsx
246
+ /**
247
+ * Don't example for "Start on the Month of the Task" on the Calendar page.
248
+ * Don't open on the current month when the task is about another one.
249
+ * @module
250
+ */
251
+ import { Calendar, style } from '@tempoxyz/ds'
252
+
253
+ /** Renders the static preview, which the guideline card shows inert. */
254
+ export function Demo() {
255
+ return (
256
+ <div {...styles.stack()}>
257
+ <span {...styles.label()}>Start of the September statement</span>
258
+ <Calendar defaultMonth={new Date(2026, 9, 1)} />
259
+ </div>
260
+ )
261
+ }
262
+
263
+ namespace styles {
264
+ export const stack = style({ display: 'flex', flexDirection: 'column', rowGap: '12' })
265
+
266
+ export const label = style({ color: 'content.primary', typography: 'body.b2Strong' })
267
+ }
268
+ ```
269
+
270
+ ### Follow the Locale
271
+
272
+ `locale` defaults to the browser's locale, and `weekStartsOn` to that locale's first weekday. Leave both unset unless the product uses a fixed locale. The month button names default to English, so translate them through `labels`.
273
+
274
+ **Do:** Let the locale set the first weekday, and translate `labels`.
275
+
276
+ ```tsx
277
+ /**
278
+ * Do example for "Follow the Locale" on the Calendar page.
279
+ * Let the locale set the first weekday, and translate `labels`.
280
+ * @module
281
+ */
282
+ import { Calendar } from '@tempoxyz/ds'
283
+
284
+ /** Renders the static preview, which the guideline card shows inert. */
285
+ export function Demo() {
286
+ return (
287
+ <Calendar
288
+ defaultMonth={new Date(2026, 9, 1)}
289
+ labels={{ next: 'Nächster Monat', previous: 'Vorheriger Monat' }}
290
+ locale="de-DE"
291
+ />
292
+ )
293
+ }
294
+ ```
295
+
296
+ **Don't:** Override `weekStartsOn` against the locale, such as Sunday first in German.
297
+
298
+ ```tsx
299
+ /**
300
+ * Don't example for "Follow the Locale" on the Calendar page.
301
+ * Don't override `weekStartsOn` against the locale, such as Sunday first in German.
302
+ * @module
303
+ */
304
+ import { Calendar } from '@tempoxyz/ds'
305
+
306
+ /** Renders the static preview, which the guideline card shows inert. */
307
+ export function Demo() {
308
+ return (
309
+ <Calendar
310
+ defaultMonth={new Date(2026, 9, 1)}
311
+ labels={{ next: 'Nächster Monat', previous: 'Vorheriger Monat' }}
312
+ locale="de-DE"
313
+ weekStartsOn={0}
314
+ />
315
+ )
316
+ }
317
+ ```
318
+
319
+ ## Content
320
+
321
+ If a date maps to a time, such as a statement cutoff, name the time zone, such as UTC.
322
+
323
+ ## Accessibility
324
+
325
+ Follows the [WAI-ARIA grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/), as in the [date picker dialog example](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/).
326
+
327
+ ### Semantics
328
+
329
+ * **Month Grid (grid):** A table labelled by the month heading.
330
+ * **Weeks and Weekdays (gridcell):** Weekday names are column headers, and each week is a row of day cells.
331
+ * **Days (button):** Named with the full localized date, such as "Tuesday, October 20, 2026".
332
+ * **Today and Selection (aria-selected):** Today is marked as the current date. Selected days, including every day in a range, are marked.
333
+ * **Unavailable Days (aria-disabled):** Days outside the allowed range stay focusable and announced.
334
+ * **Month Buttons:** Named "Previous month" and "Next month". Translate them with `labels`.
335
+
336
+ ### Keyboard
337
+
338
+ * **Move into the Calendar (Tab):** Moves focus to the month buttons, then to one day in the grid.
339
+ * **Next or Previous Day (Right Arrow and Left Arrow):** Moves focus to the next or previous day.
340
+ * **Next or Previous Week (Down Arrow and Up Arrow):** Moves focus to the same day in the next or previous week.
341
+ * **First or Last Day of the Week (Home and End):** Moves focus to the first or last day of the week.
342
+ * **Next or Previous Month (Page Down and Page Up):** Moves focus to the same day in the next or previous month.
343
+ * **Next or Previous Year (Shift+Page Down or Page Up):** Moves focus to the same day in the next or previous year.
344
+ * **Select the Focused Day (Enter or Space):** Selects the focused day. In `range` mode, the first press sets the start, the second the end.
345
+
346
+ ### Focus
347
+
348
+ Focus starts on the selected day or today. Moving past the shown month turns the page, and focus stops at `min` and `max`.
349
+
350
+ ### Announcements
351
+
352
+ Turning the page announces the new month in a polite live region.
353
+
354
+ ### Your Responsibilities
355
+
356
+ * **Localize Labels (labels):** Translate the month buttons. Set `locale` to match the page language.
357
+ * **Explain Unavailable Days (isDateDisabled):** Explain the rule in nearby text, such as "Weekends are unavailable".
358
+
359
+ ## Related
360
+
361
+ [DatePicker](/docs/components/date-picker)
362
+
363
+ Use for a date field in a form.
364
+
365
+ [TextInput](/docs/components/text-input)
366
+
367
+ Use for typed dates.
368
+
369
+ [ChoiceGroup](/docs/components/choice-group)
370
+
371
+ Use for preset ranges.
372
+
373
+ [Field](/docs/components/field)
374
+
375
+ Use for labelling the date and its constraints.
@@ -0,0 +1,96 @@
1
+ # Callout
2
+
3
+ Sets a short passage of body text apart in a subtle box.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Callout.tsx)
6
+
7
+ Figma: [Callout](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=3506-2664)
8
+
9
+ ## Overview
10
+
11
+ A callout renders body text in a subtle box, padded 24px above and below and 32px at the sides. It sets a summary or an aside apart from the text around it, and adds no role or announcement.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { Callout } from '@tempoxyz/ds'
19
+
20
+ export function Demo() {
21
+ return (
22
+ <Callout>
23
+ Stablecoin payments move fiat-referenced digital assets over blockchain networks. The onchain
24
+ transfer is only one part of the end-to-end payment.
25
+ </Callout>
26
+ )
27
+ }
28
+ ```
29
+
30
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Callout/Basic.tsx)
31
+
32
+ ## Anatomy
33
+
34
+ Import the component and assemble its parts.
35
+
36
+ ```tsx
37
+ import { Callout } from '@tempoxyz/ds'
38
+
39
+ <Callout />
40
+ ```
41
+
42
+ ## Guidelines
43
+
44
+ ### When to Use
45
+
46
+ * Set a summary, a definition, or an aside apart from the body of an article or a docs page.
47
+
48
+ ### When Not to Use
49
+
50
+ * Use an [Alert](/docs/components/alert) for a message about a status or an outcome.
51
+ * Use a [Banner](/docs/components/banner) for a message about the whole page or product.
52
+ * Use a [Snippet](/docs/components/snippet) for code that people copy.
53
+
54
+ ### Keep the Passage Optional
55
+
56
+ **Do:** Use it for context that a reader can skip without missing a step.
57
+
58
+ ```tsx
59
+ <Callout style={{ width: 360 }}>
60
+ Tempo settles a payment in under a second, with fees paid in stablecoins.
61
+ </Callout>
62
+ ```
63
+
64
+ **Don't:** Use it for an error or a warning. Use an Alert instead.
65
+
66
+ ```tsx
67
+ <Callout style={{ width: 360 }}>Your payment failed. Check the address and try again.</Callout>
68
+ ```
69
+
70
+ ### Keep One Callout per Section
71
+
72
+ * **One Passage (1):** Sets one passage apart, so the reader notices it among the body text.
73
+ * **Short Text (3 lines):** Holds a few lines at most. Move a longer passage into the body text.
74
+
75
+ ## Content
76
+
77
+ * Write complete sentences in the same voice as the text around the callout.
78
+ * Keep it to one idea in two or three lines.
79
+
80
+ ## Accessibility
81
+
82
+ A callout renders a `<div>` with no role, so screen readers read its text in place.
83
+
84
+ * **Root (div):** Reads its text in place, as part of the surrounding content, with no role.
85
+ * **Landmark (role):** If the callout is an aside, set `role="note"` and an `aria-label` that names it.
86
+ * **Contrast (4.5:1):** Renders primary text on the subtle fill, above 4.5:1 in both color schemes.
87
+
88
+ ## Related
89
+
90
+ [Alert](/docs/components/alert)
91
+
92
+ Use for a message about a status or an outcome.
93
+
94
+ [Banner](/docs/components/banner)
95
+
96
+ Use for a message about the whole page.