@jaimevalasek/aioson 1.30.0 → 1.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/docs/design-previews/cognitive-core-ui-auth.html +95 -0
- package/docs/design-previews/cognitive-core-ui-kanban.html +231 -0
- package/docs/design-previews/cognitive-core-ui-list-detail.html +174 -0
- package/docs/design-previews/cognitive-core-ui-preview.css +1315 -0
- package/docs/design-previews/cognitive-core-ui-settings.html +142 -0
- package/docs/design-previews/cognitive-core-ui-website.html +190 -1009
- package/docs/design-previews/cognitive-core-ui.html +281 -463
- package/docs/design-previews/index.html +83 -31
- package/package.json +1 -1
- package/src/constants.js +578 -514
- package/template/.aioson/docs/integrations/dashboard-app-form-publish-mapping.md +183 -0
- package/template/.aioson/docs/play/README.md +74 -0
- package/template/.aioson/docs/play/agent-usage-guide.md +112 -0
- package/template/.aioson/docs/play/app-compatibility-guide.md +117 -0
- package/template/.aioson/docs/play/auth-services-and-testing.md +235 -0
- package/template/.aioson/docs/play/llm-data-and-bindings.md +238 -0
- package/template/.aioson/docs/play/manifest-and-runtime.md +267 -0
- package/template/.aioson/docs/play/source-map.md +104 -0
- package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +266 -243
- package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -293
- package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -827
- package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -250
- package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -585
- package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -365
- package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +485 -482
- package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +386 -387
- package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +228 -205
- package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -338
- package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -977
- package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -218
- package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -326
- package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -461
- package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -293
- package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -352
- package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +233 -210
- package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -319
- package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -365
- package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -196
- package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -244
- package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -235
- package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -215
- package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -295
- package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +239 -203
- package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -339
- package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +417 -407
- package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +289 -272
- package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +525 -524
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +279 -279
- package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +355 -289
- package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +443 -437
- package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +245 -222
- package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -159
- package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -498
- package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -236
- package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -274
- package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -355
- package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -198
- package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -307
- package/template/.aioson/skills/design/interface-design/SKILL.md +68 -47
- package/template/.aioson/skills/design/interface-design/references/components-and-states.md +105 -105
- package/template/.aioson/skills/design/interface-design/references/design-directions.md +101 -101
- package/template/.aioson/skills/design/interface-design/references/handoff-and-quality.md +92 -71
- package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +74 -74
- package/template/.aioson/skills/design/interface-design/references/tokens-and-depth.md +173 -173
- package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +236 -213
- package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -228
- package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -855
- package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -334
- package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -342
- package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -286
- package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -458
- package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -723
- package/template/.aioson/skills/design/premium-command-center-ui/SKILL.md +83 -62
- package/template/.aioson/skills/design/premium-command-center-ui/references/operations.md +74 -74
- package/template/.aioson/skills/design/premium-command-center-ui/references/patterns.md +116 -116
- package/template/.aioson/skills/design/premium-command-center-ui/references/validation.md +47 -47
- package/template/.aioson/skills/design/premium-command-center-ui/references/visual-system.md +215 -215
- package/template/.aioson/skills/design/pt.squarespace.com/.skill-meta.json +31 -31
- package/template/.aioson/skills/design/pt.squarespace.com/SKILL.md +94 -66
- package/template/.aioson/skills/design/pt.squarespace.com/references/components.md +366 -366
- package/template/.aioson/skills/design/pt.squarespace.com/references/design-tokens.md +150 -150
- package/template/.aioson/skills/design/pt.squarespace.com/references/motion.md +270 -270
- package/template/.aioson/skills/design/pt.squarespace.com/references/patterns.md +189 -189
- package/template/.aioson/skills/design/pt.squarespace.com/references/websites.md +161 -161
- package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +232 -209
- package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -324
- package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -508
- package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -223
- package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -374
- package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -356
- package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -288
- package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -289
|
@@ -1,365 +1,365 @@
|
|
|
1
|
-
# Components — Clean SaaS UI
|
|
2
|
-
|
|
3
|
-
All components must use tokens from `design-tokens.md`. Never hardcode values. Never invent a new variant without a domain reason.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Table (first-class citizen)
|
|
8
|
-
|
|
9
|
-
Tables are the most important component in this skill. Treat them with the same care you would a hero section in a marketing page.
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
┌─────────────────────────────────────────────────────────┐
|
|
13
|
-
│ ☐ Column A ↕ Column B ↕ Status Actions │ ← sticky header
|
|
14
|
-
├─────────────────────────────────────────────────────────┤
|
|
15
|
-
│ ☐ Row data Row data ● Active [Edit][Delete] │ ← actions on hover
|
|
16
|
-
│ ☐ Row data Row data ○ Inactive │
|
|
17
|
-
│ ☐ Row data Row data ⚠ Warning │
|
|
18
|
-
├─────────────────────────────────────────────────────────┤
|
|
19
|
-
│ Showing 1–25 of 143 [← Prev] 1 2 3 ... [Next →] │ ← pagination footer
|
|
20
|
-
└─────────────────────────────────────────────────────────┘
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Anatomy:**
|
|
24
|
-
- Header: `bg-surface`, `border-bottom: 1px var(--border-medium)`, `position: sticky; top: 0`, `text-sm font-medium text-secondary uppercase tracking-wide`
|
|
25
|
-
- Row height: 48px (comfortable) or 40px (compact mode)
|
|
26
|
-
- Row hover: `bg-elevated`
|
|
27
|
-
- Striped variant: alternate rows `bg-void` / `bg-surface`
|
|
28
|
-
- Checkbox column: 40px, left-aligned
|
|
29
|
-
- Sort indicators: `↕` inactive, `↑`/`↓` active with accent color
|
|
30
|
-
- Inline actions: appear on row hover, right-aligned, `control-xs` height
|
|
31
|
-
- Bulk action bar: slides in below header when rows selected, `bg-accent-dim border-y border-accent`
|
|
32
|
-
- Pagination: `flex between`, `text-sm text-secondary`, page buttons `control-sm`
|
|
33
|
-
- Column resize handles: `4px drag zone` at column edge
|
|
34
|
-
- Expandable rows: `▸` toggle, expanded area uses `bg-elevated` with inner padding
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## 2. Filter Bar
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
[ Search... 🔍 ] [ Status ▾ ] [ Date range ▾ ] [ Owner ▾ ] ×2 active [Clear all]
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
- Container: `bg-surface border-b border-default px-6 py-3`
|
|
45
|
-
- Search input: `control-md`, left icon, `w-64`
|
|
46
|
-
- Filter dropdowns: `control-md`, label + chevron
|
|
47
|
-
- Active filter badges: `bg-accent-dim text-accent text-xs px-2 py-0.5 rounded-full` with `×` dismiss
|
|
48
|
-
- Clear all: `text-sm text-secondary hover:text-primary`
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## 3. Sidebar
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
┌───────────────────┐
|
|
56
|
-
│ [Logo] Product │ ← 56px top bar
|
|
57
|
-
├───────────────────┤
|
|
58
|
-
│ ▸ Dashboard │
|
|
59
|
-
│ ▸ Contacts │ ← active item: blue left border 2px + bg-elevated
|
|
60
|
-
│ ├ Leads │
|
|
61
|
-
│ └ Accounts │ ← sub-items indented 16px
|
|
62
|
-
│ ▸ Reports │
|
|
63
|
-
│ ▸ Settings │
|
|
64
|
-
├───────────────────┤
|
|
65
|
-
│ [Avatar] J. Smith │ ← user footer
|
|
66
|
-
└───────────────────┘
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
- Width: `256px` fixed, `bg-surface border-r border-default`
|
|
70
|
-
- Nav group label: `text-xs font-semibold text-muted uppercase tracking-wider mb-1 px-3`
|
|
71
|
-
- Nav item: `height: 36px px-3 flex items-center gap-2 text-sm text-primary rounded-md`
|
|
72
|
-
- Active item: `border-l-2 border-accent bg-elevated text-accent font-medium` (no pl adjustment needed if border is inside)
|
|
73
|
-
- Hover item: `bg-elevated`
|
|
74
|
-
- Sub-items: `pl-8` indent, `text-sm text-secondary`, same hover/active states
|
|
75
|
-
- Collapsible: toggle `▸`/`▾` with `150ms ease` transition
|
|
76
|
-
- User footer: `border-t border-default px-3 py-3 mt-auto`, avatar 32px + name + role
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 4. Page Header
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
[ Breadcrumb > Trail ]
|
|
84
|
-
|
|
85
|
-
Contacts [Export] [+ New Contact]
|
|
86
|
-
Active CRM contacts (secondary action) (primary action)
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
- Container: `px-6 py-5 border-b border-default`
|
|
90
|
-
- Breadcrumbs: `text-sm text-secondary` with `/` separator, active item `text-primary`
|
|
91
|
-
- Title: `text-2xl font-bold text-heading tracking-
|
|
92
|
-
- Subtitle: `text-sm text-secondary mt-0.5`
|
|
93
|
-
- Actions: right-aligned, `gap-2`, secondary button + primary button
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## 5. Stat Card
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
┌──────────────────────────┐
|
|
101
|
-
│ Monthly Revenue [⋯] │
|
|
102
|
-
│ $48,250 ↑ │
|
|
103
|
-
│ +12.3% │
|
|
104
|
-
│ ▁▂▃▄▅▆▇█ sparkline │
|
|
105
|
-
└──────────────────────────┘
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
- Container: `bg-surface border border-default rounded-lg p-4 shadow-xs`
|
|
109
|
-
- Label: `text-sm text-secondary font-medium`
|
|
110
|
-
- Number: `text-3xl font-bold text-heading tracking-
|
|
111
|
-
- Trend: `text-sm font-medium` — green for positive, red for negative, inline with icon `↑`/`↓`
|
|
112
|
-
- Sparkline: `height: 32px`, accent color, no axes, no labels
|
|
113
|
-
- Overflow menu: `control-xs` icon button, top-right
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## 6. Badge
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
● Active ○ Inactive ⚠ Warning ✕ Cancelled ℹ Draft ● Custom
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
- Height: `20px`
|
|
124
|
-
- Padding: `px-2`
|
|
125
|
-
- Font: `text-xs font-medium`
|
|
126
|
-
- Radius: `radius-full`
|
|
127
|
-
- 6 semantic variants:
|
|
128
|
-
- `success`: `bg-semantic-success-dim text-semantic-success`
|
|
129
|
-
- `warning`: `bg-semantic-warning-dim text-semantic-warning`
|
|
130
|
-
- `danger`: `bg-semantic-danger-dim text-semantic-danger`
|
|
131
|
-
- `info`: `bg-accent-dim text-accent`
|
|
132
|
-
- `neutral`: `bg-semantic-neutral-dim text-secondary`
|
|
133
|
-
- `default`: `bg-elevated text-primary border border-default`
|
|
134
|
-
- Optional leading dot `●` 6px with matching color
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 7. Button
|
|
139
|
-
|
|
140
|
-
```
|
|
141
|
-
[Primary] [Secondary] [Ghost] [Danger] [Icon only]
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
- Height: `control-md` (36px) default, `control-sm` (32px) small, `control-lg` (40px) large
|
|
145
|
-
- Radius: `radius-md` (6px)
|
|
146
|
-
- Font: `text-sm font-medium`
|
|
147
|
-
- Padding: `px-4`
|
|
148
|
-
- **Primary**: `bg-accent text-accent-contrast hover:bg-accent-strong`
|
|
149
|
-
- **Secondary**: `bg-surface text-primary border border-medium hover:bg-elevated`
|
|
150
|
-
- **Ghost**: `text-primary hover:bg-elevated` (no border, no bg)
|
|
151
|
-
- **Danger**: `bg-semantic-danger text-white hover:bg-red-700`
|
|
152
|
-
- **Icon only**: `w-9 h-9 p-0 flex items-center justify-center` (for control-md)
|
|
153
|
-
- Disabled: `opacity-50 cursor-not-allowed`
|
|
154
|
-
- Loading: spinner replaces leading icon, text unchanged
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## 8. Form Group
|
|
159
|
-
|
|
160
|
-
```
|
|
161
|
-
Label *
|
|
162
|
-
[___________________________] ← input control-md
|
|
163
|
-
Helper text or error message
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
- Label: `text-sm font-medium text-primary mb-1`
|
|
167
|
-
- Required marker: `text-semantic-danger ml-0.5`
|
|
168
|
-
- Input: `control-md w-full border border-medium rounded-md px-3 text-sm text-primary bg-surface`
|
|
169
|
-
- Input focus: `outline-none ring-2 ring-accent/20 border-accent`
|
|
170
|
-
- Helper text: `text-xs text-secondary mt-1`
|
|
171
|
-
- Error: `text-xs text-semantic-danger mt-1` — border becomes `border-semantic-danger`
|
|
172
|
-
- Select: same as input + trailing chevron icon
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## 9. Dropdown Menu
|
|
177
|
-
|
|
178
|
-
```
|
|
179
|
-
┌──────────────────┐
|
|
180
|
-
│ ✏ Edit │
|
|
181
|
-
│ ⧉ Duplicate │
|
|
182
|
-
├──────────────────┤
|
|
183
|
-
│ 🗑 Delete │ ← destructive: text-semantic-danger
|
|
184
|
-
└──────────────────┘
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
- Container: `bg-surface border border-default rounded-lg shadow-md py-1 min-w-48`
|
|
188
|
-
- Item: `height: 36px px-3 flex items-center gap-2 text-sm text-primary hover:bg-elevated cursor-pointer`
|
|
189
|
-
- Divider: `border-t border-default my-1`
|
|
190
|
-
- Destructive item: `text-semantic-danger hover:bg-semantic-danger-dim`
|
|
191
|
-
- Leading icon: 16px, `text-secondary` (except destructive)
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## 10. Modal
|
|
196
|
-
|
|
197
|
-
```
|
|
198
|
-
┌────────────────────────────────────────┐
|
|
199
|
-
│ Modal Title ✕ │ ← header border-b
|
|
200
|
-
│────────────────────────────────────────│
|
|
201
|
-
│ │
|
|
202
|
-
│ Content area │
|
|
203
|
-
│ │
|
|
204
|
-
│────────────────────────────────────────│
|
|
205
|
-
│ [Cancel] [Confirm] │ ← footer border-t
|
|
206
|
-
└────────────────────────────────────────┘
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
- Container: `bg-surface rounded-xl shadow-lg max-w-[560px] w-full`
|
|
210
|
-
- Header: `px-6 py-4 border-b border-default flex justify-between items-center`
|
|
211
|
-
- Title: `text-lg font-semibold text-heading`
|
|
212
|
-
- Close button: `control-xs ghost`
|
|
213
|
-
- Body: `px-6 py-5`
|
|
214
|
-
- Footer: `px-6 py-4 border-t border-default flex justify-end gap-2`
|
|
215
|
-
- Backdrop: `bg-black/40 fixed inset-0`
|
|
216
|
-
- Max height: `80vh` with internal scroll
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## 11. Toast
|
|
221
|
-
|
|
222
|
-
```
|
|
223
|
-
┌──────────────────────────────────────────┐
|
|
224
|
-
│ ‖ Your changes were saved successfully. │ ← success: green left border 4px
|
|
225
|
-
└──────────────────────────────────────────┘
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
- Container: `bg-surface border border-default rounded-lg shadow-md px-4 py-3 max-w-sm`
|
|
229
|
-
- Left border: `4px solid` matching semantic color
|
|
230
|
-
- Icon: 16px semantic color
|
|
231
|
-
- Message: `text-sm text-primary`
|
|
232
|
-
- Auto-dismiss: 5s, progress bar optional
|
|
233
|
-
- Position: `fixed bottom-4 right-4`
|
|
234
|
-
- Variants: success / warning / danger / info (same structure, different border + icon color)
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## 12. Tabs
|
|
239
|
-
|
|
240
|
-
```
|
|
241
|
-
Overview Contacts Activity Documents
|
|
242
|
-
─────────────────────────────────────────────
|
|
243
|
-
‾‾‾‾‾‾‾‾ ← active tab: 2px accent bottom border
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
- Container: `border-b border-default`
|
|
247
|
-
- Tab item: `px-4 py-2 text-sm font-medium text-secondary hover:text-primary cursor-pointer`
|
|
248
|
-
- Active tab: `text-accent border-b-2 border-accent -mb-px`
|
|
249
|
-
- Count badge: `ml-1.5 bg-elevated text-xs px-1.5 rounded-full`
|
|
250
|
-
|
|
251
|
-
---
|
|
252
|
-
|
|
253
|
-
## 13. Breadcrumbs
|
|
254
|
-
|
|
255
|
-
```
|
|
256
|
-
Contacts / Acme Corp / Overview
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
- Container: `flex items-center gap-1 text-sm`
|
|
260
|
-
- Item: `text-secondary hover:text-primary`
|
|
261
|
-
- Separator: `text-muted` — `/`
|
|
262
|
-
- Active (last): `text-primary font-medium` (not a link)
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
## 14. Avatar
|
|
267
|
-
|
|
268
|
-
- Sizes: 24px / 32px / 40px / 48px
|
|
269
|
-
- Radius: `radius-full`
|
|
270
|
-
- Image: `object-cover`
|
|
271
|
-
- Fallback: initials, `bg-accent-dim text-accent font-semibold`
|
|
272
|
-
- Group: `-ml-2` overlap, `border-2 border-surface`
|
|
273
|
-
- Max visible in group: 4, then `+N` chip
|
|
274
|
-
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
## 15. Tooltip
|
|
278
|
-
|
|
279
|
-
- Container: `bg-gray-900 text-white text-xs rounded-md px-2 py-1 shadow-sm`
|
|
280
|
-
- Max width: `200px`
|
|
281
|
-
- Delay: 400ms before showing
|
|
282
|
-
- Always appears above target unless obstructed
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
## 16. Progress Bar
|
|
287
|
-
|
|
288
|
-
```
|
|
289
|
-
[██████████░░░░░░░] 67%
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
- Container: `bg-elevated rounded-full h-1.5`
|
|
293
|
-
- Fill: `bg-accent rounded-full h-1.5`
|
|
294
|
-
- Semantic fill variants: success (green), warning (amber), danger (red)
|
|
295
|
-
- Label: `text-xs text-secondary ml-2` (optional)
|
|
296
|
-
|
|
297
|
-
---
|
|
298
|
-
|
|
299
|
-
## 17. Toggle Switch
|
|
300
|
-
|
|
301
|
-
```
|
|
302
|
-
●── OFF ──● ON
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
- Container: `w-10 h-5` (40×20px), `rounded-full`
|
|
306
|
-
- Off state: `bg-border-strong`
|
|
307
|
-
- On state: `bg-accent`
|
|
308
|
-
- Thumb: `w-4 h-4 bg-white rounded-full shadow-xs` — translates `150ms ease`
|
|
309
|
-
- Label: `text-sm text-primary ml-2`
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
## 18. Empty State
|
|
314
|
-
|
|
315
|
-
```
|
|
316
|
-
[geometric illustration]
|
|
317
|
-
|
|
318
|
-
No contacts yet
|
|
319
|
-
|
|
320
|
-
Start by importing your contacts
|
|
321
|
-
or adding them manually.
|
|
322
|
-
|
|
323
|
-
[+ Add Contact]
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
- Container: `flex flex-col items-center justify-center py-16 px-6`
|
|
327
|
-
- Illustration: simple geometric SVG — clean, not hand-drawn, not emoji
|
|
328
|
-
- Title: `text-lg font-semibold text-heading mt-4`
|
|
329
|
-
- Description: `text-sm text-secondary text-center max-w-xs mt-1`
|
|
330
|
-
- CTA: primary button `mt-6`
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## 19. Loading Spinner
|
|
335
|
-
|
|
336
|
-
- Size: `20px` circle
|
|
337
|
-
- Border: `2px solid var(--border-medium)`
|
|
338
|
-
- Active arc: `border-top-color: var(--accent)`
|
|
339
|
-
- Animation: `spin 0.8s linear infinite`
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
## 20. Skeleton
|
|
344
|
-
|
|
345
|
-
- Container matches the real element's shape and size
|
|
346
|
-
- Background: `bg-elevated` with `animate-pulse`
|
|
347
|
-
- Text skeleton: `h-4 rounded-md` (varies)
|
|
348
|
-
- Card skeleton: full card shape with header + body regions
|
|
349
|
-
- Table skeleton: rows with alternating cell widths
|
|
350
|
-
|
|
351
|
-
---
|
|
352
|
-
|
|
353
|
-
## Component interaction states (all components)
|
|
354
|
-
|
|
355
|
-
Every interactive component must handle:
|
|
356
|
-
|
|
357
|
-
| State | Treatment |
|
|
358
|
-
|-------|-----------|
|
|
359
|
-
| Default | As specified above |
|
|
360
|
-
| Hover | `bg-elevated` or `border-medium` shift |
|
|
361
|
-
| Focus | `ring-2 ring-accent/20 border-accent` |
|
|
362
|
-
| Active/pressed | `scale(0.99)` 60ms |
|
|
363
|
-
| Disabled | `opacity-50 cursor-not-allowed` |
|
|
364
|
-
| Loading | Spinner + muted label |
|
|
365
|
-
| Error | `border-semantic-danger` + error text |
|
|
1
|
+
# Components — Clean SaaS UI
|
|
2
|
+
|
|
3
|
+
All components must use tokens from `design-tokens.md`. Never hardcode values. Never invent a new variant without a domain reason.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Table (first-class citizen)
|
|
8
|
+
|
|
9
|
+
Tables are the most important component in this skill. Treat them with the same care you would a hero section in a marketing page.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────────────────────────────┐
|
|
13
|
+
│ ☐ Column A ↕ Column B ↕ Status Actions │ ← sticky header
|
|
14
|
+
├─────────────────────────────────────────────────────────┤
|
|
15
|
+
│ ☐ Row data Row data ● Active [Edit][Delete] │ ← actions on hover
|
|
16
|
+
│ ☐ Row data Row data ○ Inactive │
|
|
17
|
+
│ ☐ Row data Row data ⚠ Warning │
|
|
18
|
+
├─────────────────────────────────────────────────────────┤
|
|
19
|
+
│ Showing 1–25 of 143 [← Prev] 1 2 3 ... [Next →] │ ← pagination footer
|
|
20
|
+
└─────────────────────────────────────────────────────────┘
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Anatomy:**
|
|
24
|
+
- Header: `bg-surface`, `border-bottom: 1px var(--border-medium)`, `position: sticky; top: 0`, `text-sm font-medium text-secondary uppercase tracking-wide`
|
|
25
|
+
- Row height: 48px (comfortable) or 40px (compact mode)
|
|
26
|
+
- Row hover: `bg-elevated`
|
|
27
|
+
- Striped variant: alternate rows `bg-void` / `bg-surface`
|
|
28
|
+
- Checkbox column: 40px, left-aligned
|
|
29
|
+
- Sort indicators: `↕` inactive, `↑`/`↓` active with accent color
|
|
30
|
+
- Inline actions: appear on row hover, right-aligned, `control-xs` height
|
|
31
|
+
- Bulk action bar: slides in below header when rows selected, `bg-accent-dim border-y border-accent`
|
|
32
|
+
- Pagination: `flex between`, `text-sm text-secondary`, page buttons `control-sm`
|
|
33
|
+
- Column resize handles: `4px drag zone` at column edge
|
|
34
|
+
- Expandable rows: `▸` toggle, expanded area uses `bg-elevated` with inner padding
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 2. Filter Bar
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
[ Search... 🔍 ] [ Status ▾ ] [ Date range ▾ ] [ Owner ▾ ] ×2 active [Clear all]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- Container: `bg-surface border-b border-default px-6 py-3`
|
|
45
|
+
- Search input: `control-md`, left icon, `w-64`
|
|
46
|
+
- Filter dropdowns: `control-md`, label + chevron
|
|
47
|
+
- Active filter badges: `bg-accent-dim text-accent text-xs px-2 py-0.5 rounded-full` with `×` dismiss
|
|
48
|
+
- Clear all: `text-sm text-secondary hover:text-primary`
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 3. Sidebar
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
┌───────────────────┐
|
|
56
|
+
│ [Logo] Product │ ← 56px top bar
|
|
57
|
+
├───────────────────┤
|
|
58
|
+
│ ▸ Dashboard │
|
|
59
|
+
│ ▸ Contacts │ ← active item: blue left border 2px + bg-elevated
|
|
60
|
+
│ ├ Leads │
|
|
61
|
+
│ └ Accounts │ ← sub-items indented 16px
|
|
62
|
+
│ ▸ Reports │
|
|
63
|
+
│ ▸ Settings │
|
|
64
|
+
├───────────────────┤
|
|
65
|
+
│ [Avatar] J. Smith │ ← user footer
|
|
66
|
+
└───────────────────┘
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- Width: `256px` fixed, `bg-surface border-r border-default`
|
|
70
|
+
- Nav group label: `text-xs font-semibold text-muted uppercase tracking-wider mb-1 px-3`
|
|
71
|
+
- Nav item: `height: 36px px-3 flex items-center gap-2 text-sm text-primary rounded-md`
|
|
72
|
+
- Active item: `border-l-2 border-accent bg-elevated text-accent font-medium` (no pl adjustment needed if border is inside)
|
|
73
|
+
- Hover item: `bg-elevated`
|
|
74
|
+
- Sub-items: `pl-8` indent, `text-sm text-secondary`, same hover/active states
|
|
75
|
+
- Collapsible: toggle `▸`/`▾` with `150ms ease` transition
|
|
76
|
+
- User footer: `border-t border-default px-3 py-3 mt-auto`, avatar 32px + name + role
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 4. Page Header
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
[ Breadcrumb > Trail ]
|
|
84
|
+
|
|
85
|
+
Contacts [Export] [+ New Contact]
|
|
86
|
+
Active CRM contacts (secondary action) (primary action)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Container: `px-6 py-5 border-b border-default`
|
|
90
|
+
- Breadcrumbs: `text-sm text-secondary` with `/` separator, active item `text-primary`
|
|
91
|
+
- Title: `text-2xl font-bold text-heading tracking-normal`
|
|
92
|
+
- Subtitle: `text-sm text-secondary mt-0.5`
|
|
93
|
+
- Actions: right-aligned, `gap-2`, secondary button + primary button
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 5. Stat Card
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
┌──────────────────────────┐
|
|
101
|
+
│ Monthly Revenue [⋯] │
|
|
102
|
+
│ $48,250 ↑ │
|
|
103
|
+
│ +12.3% │
|
|
104
|
+
│ ▁▂▃▄▅▆▇█ sparkline │
|
|
105
|
+
└──────────────────────────┘
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- Container: `bg-surface border border-default rounded-lg p-4 shadow-xs`
|
|
109
|
+
- Label: `text-sm text-secondary font-medium`
|
|
110
|
+
- Number: `text-3xl font-bold text-heading tracking-normal mt-1`
|
|
111
|
+
- Trend: `text-sm font-medium` — green for positive, red for negative, inline with icon `↑`/`↓`
|
|
112
|
+
- Sparkline: `height: 32px`, accent color, no axes, no labels
|
|
113
|
+
- Overflow menu: `control-xs` icon button, top-right
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 6. Badge
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
● Active ○ Inactive ⚠ Warning ✕ Cancelled ℹ Draft ● Custom
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- Height: `20px`
|
|
124
|
+
- Padding: `px-2`
|
|
125
|
+
- Font: `text-xs font-medium`
|
|
126
|
+
- Radius: `radius-full`
|
|
127
|
+
- 6 semantic variants:
|
|
128
|
+
- `success`: `bg-semantic-success-dim text-semantic-success`
|
|
129
|
+
- `warning`: `bg-semantic-warning-dim text-semantic-warning`
|
|
130
|
+
- `danger`: `bg-semantic-danger-dim text-semantic-danger`
|
|
131
|
+
- `info`: `bg-accent-dim text-accent`
|
|
132
|
+
- `neutral`: `bg-semantic-neutral-dim text-secondary`
|
|
133
|
+
- `default`: `bg-elevated text-primary border border-default`
|
|
134
|
+
- Optional leading dot `●` 6px with matching color
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 7. Button
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
[Primary] [Secondary] [Ghost] [Danger] [Icon only]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
- Height: `control-md` (36px) default, `control-sm` (32px) small, `control-lg` (40px) large
|
|
145
|
+
- Radius: `radius-md` (6px)
|
|
146
|
+
- Font: `text-sm font-medium`
|
|
147
|
+
- Padding: `px-4`
|
|
148
|
+
- **Primary**: `bg-accent text-accent-contrast hover:bg-accent-strong`
|
|
149
|
+
- **Secondary**: `bg-surface text-primary border border-medium hover:bg-elevated`
|
|
150
|
+
- **Ghost**: `text-primary hover:bg-elevated` (no border, no bg)
|
|
151
|
+
- **Danger**: `bg-semantic-danger text-white hover:bg-red-700`
|
|
152
|
+
- **Icon only**: `w-9 h-9 p-0 flex items-center justify-center` (for control-md)
|
|
153
|
+
- Disabled: `opacity-50 cursor-not-allowed`
|
|
154
|
+
- Loading: spinner replaces leading icon, text unchanged
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 8. Form Group
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
Label *
|
|
162
|
+
[___________________________] ← input control-md
|
|
163
|
+
Helper text or error message
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- Label: `text-sm font-medium text-primary mb-1`
|
|
167
|
+
- Required marker: `text-semantic-danger ml-0.5`
|
|
168
|
+
- Input: `control-md w-full border border-medium rounded-md px-3 text-sm text-primary bg-surface`
|
|
169
|
+
- Input focus: `outline-none ring-2 ring-accent/20 border-accent`
|
|
170
|
+
- Helper text: `text-xs text-secondary mt-1`
|
|
171
|
+
- Error: `text-xs text-semantic-danger mt-1` — border becomes `border-semantic-danger`
|
|
172
|
+
- Select: same as input + trailing chevron icon
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 9. Dropdown Menu
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
┌──────────────────┐
|
|
180
|
+
│ ✏ Edit │
|
|
181
|
+
│ ⧉ Duplicate │
|
|
182
|
+
├──────────────────┤
|
|
183
|
+
│ 🗑 Delete │ ← destructive: text-semantic-danger
|
|
184
|
+
└──────────────────┘
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
- Container: `bg-surface border border-default rounded-lg shadow-md py-1 min-w-48`
|
|
188
|
+
- Item: `height: 36px px-3 flex items-center gap-2 text-sm text-primary hover:bg-elevated cursor-pointer`
|
|
189
|
+
- Divider: `border-t border-default my-1`
|
|
190
|
+
- Destructive item: `text-semantic-danger hover:bg-semantic-danger-dim`
|
|
191
|
+
- Leading icon: 16px, `text-secondary` (except destructive)
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 10. Modal
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
┌────────────────────────────────────────┐
|
|
199
|
+
│ Modal Title ✕ │ ← header border-b
|
|
200
|
+
│────────────────────────────────────────│
|
|
201
|
+
│ │
|
|
202
|
+
│ Content area │
|
|
203
|
+
│ │
|
|
204
|
+
│────────────────────────────────────────│
|
|
205
|
+
│ [Cancel] [Confirm] │ ← footer border-t
|
|
206
|
+
└────────────────────────────────────────┘
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
- Container: `bg-surface rounded-xl shadow-lg max-w-[560px] w-full`
|
|
210
|
+
- Header: `px-6 py-4 border-b border-default flex justify-between items-center`
|
|
211
|
+
- Title: `text-lg font-semibold text-heading`
|
|
212
|
+
- Close button: `control-xs ghost`
|
|
213
|
+
- Body: `px-6 py-5`
|
|
214
|
+
- Footer: `px-6 py-4 border-t border-default flex justify-end gap-2`
|
|
215
|
+
- Backdrop: `bg-black/40 fixed inset-0`
|
|
216
|
+
- Max height: `80vh` with internal scroll
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 11. Toast
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
┌──────────────────────────────────────────┐
|
|
224
|
+
│ ‖ Your changes were saved successfully. │ ← success: green left border 4px
|
|
225
|
+
└──────────────────────────────────────────┘
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
- Container: `bg-surface border border-default rounded-lg shadow-md px-4 py-3 max-w-sm`
|
|
229
|
+
- Left border: `4px solid` matching semantic color
|
|
230
|
+
- Icon: 16px semantic color
|
|
231
|
+
- Message: `text-sm text-primary`
|
|
232
|
+
- Auto-dismiss: 5s, progress bar optional
|
|
233
|
+
- Position: `fixed bottom-4 right-4`
|
|
234
|
+
- Variants: success / warning / danger / info (same structure, different border + icon color)
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 12. Tabs
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
Overview Contacts Activity Documents
|
|
242
|
+
─────────────────────────────────────────────
|
|
243
|
+
‾‾‾‾‾‾‾‾ ← active tab: 2px accent bottom border
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
- Container: `border-b border-default`
|
|
247
|
+
- Tab item: `px-4 py-2 text-sm font-medium text-secondary hover:text-primary cursor-pointer`
|
|
248
|
+
- Active tab: `text-accent border-b-2 border-accent -mb-px`
|
|
249
|
+
- Count badge: `ml-1.5 bg-elevated text-xs px-1.5 rounded-full`
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 13. Breadcrumbs
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
Contacts / Acme Corp / Overview
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
- Container: `flex items-center gap-1 text-sm`
|
|
260
|
+
- Item: `text-secondary hover:text-primary`
|
|
261
|
+
- Separator: `text-muted` — `/`
|
|
262
|
+
- Active (last): `text-primary font-medium` (not a link)
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 14. Avatar
|
|
267
|
+
|
|
268
|
+
- Sizes: 24px / 32px / 40px / 48px
|
|
269
|
+
- Radius: `radius-full`
|
|
270
|
+
- Image: `object-cover`
|
|
271
|
+
- Fallback: initials, `bg-accent-dim text-accent font-semibold`
|
|
272
|
+
- Group: `-ml-2` overlap, `border-2 border-surface`
|
|
273
|
+
- Max visible in group: 4, then `+N` chip
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 15. Tooltip
|
|
278
|
+
|
|
279
|
+
- Container: `bg-gray-900 text-white text-xs rounded-md px-2 py-1 shadow-sm`
|
|
280
|
+
- Max width: `200px`
|
|
281
|
+
- Delay: 400ms before showing
|
|
282
|
+
- Always appears above target unless obstructed
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 16. Progress Bar
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
[██████████░░░░░░░] 67%
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
- Container: `bg-elevated rounded-full h-1.5`
|
|
293
|
+
- Fill: `bg-accent rounded-full h-1.5`
|
|
294
|
+
- Semantic fill variants: success (green), warning (amber), danger (red)
|
|
295
|
+
- Label: `text-xs text-secondary ml-2` (optional)
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## 17. Toggle Switch
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
●── OFF ──● ON
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
- Container: `w-10 h-5` (40×20px), `rounded-full`
|
|
306
|
+
- Off state: `bg-border-strong`
|
|
307
|
+
- On state: `bg-accent`
|
|
308
|
+
- Thumb: `w-4 h-4 bg-white rounded-full shadow-xs` — translates `150ms ease`
|
|
309
|
+
- Label: `text-sm text-primary ml-2`
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## 18. Empty State
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
[geometric illustration]
|
|
317
|
+
|
|
318
|
+
No contacts yet
|
|
319
|
+
|
|
320
|
+
Start by importing your contacts
|
|
321
|
+
or adding them manually.
|
|
322
|
+
|
|
323
|
+
[+ Add Contact]
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
- Container: `flex flex-col items-center justify-center py-16 px-6`
|
|
327
|
+
- Illustration: simple geometric SVG — clean, not hand-drawn, not emoji
|
|
328
|
+
- Title: `text-lg font-semibold text-heading mt-4`
|
|
329
|
+
- Description: `text-sm text-secondary text-center max-w-xs mt-1`
|
|
330
|
+
- CTA: primary button `mt-6`
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 19. Loading Spinner
|
|
335
|
+
|
|
336
|
+
- Size: `20px` circle
|
|
337
|
+
- Border: `2px solid var(--border-medium)`
|
|
338
|
+
- Active arc: `border-top-color: var(--accent)`
|
|
339
|
+
- Animation: `spin 0.8s linear infinite`
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## 20. Skeleton
|
|
344
|
+
|
|
345
|
+
- Container matches the real element's shape and size
|
|
346
|
+
- Background: `bg-elevated` with `animate-pulse`
|
|
347
|
+
- Text skeleton: `h-4 rounded-md` (varies)
|
|
348
|
+
- Card skeleton: full card shape with header + body regions
|
|
349
|
+
- Table skeleton: rows with alternating cell widths
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Component interaction states (all components)
|
|
354
|
+
|
|
355
|
+
Every interactive component must handle:
|
|
356
|
+
|
|
357
|
+
| State | Treatment |
|
|
358
|
+
|-------|-----------|
|
|
359
|
+
| Default | As specified above |
|
|
360
|
+
| Hover | `bg-elevated` or `border-medium` shift |
|
|
361
|
+
| Focus | `ring-2 ring-accent/20 border-accent` |
|
|
362
|
+
| Active/pressed | `scale(0.99)` 60ms |
|
|
363
|
+
| Disabled | `opacity-50 cursor-not-allowed` |
|
|
364
|
+
| Loading | Spinner + muted label |
|
|
365
|
+
| Error | `border-semantic-danger` + error text |
|