@deriv-ds/design-intelligence-layer 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,817 @@
1
+ # Quill Design System Guide
2
+
3
+ > **Package:** `@deriv-ds/design-intelligence-layer`
4
+ > **Audience:** AI agents and developers building UI with Quill. This is the single source of truth for setting up and using the design system in any project.
5
+
6
+ ---
7
+
8
+ ## MANDATORY RULES — READ FIRST
9
+
10
+ ### Rule 1 — Component existence check
11
+
12
+ ```
13
+ BEFORE using any component:
14
+ 1. Check the Component Catalogue (Section 8). Does it exist?
15
+ YES → Import it from the npm package exactly as documented. Do NOT re-implement it.
16
+ NO → STOP. Tell the user:
17
+ "The [ComponentName] component does not exist in the Quill design system.
18
+ Options:
19
+ (a) Build a custom one using design system tokens only (no hardcoded colors or values)
20
+ (b) Use a different component that exists in the system
21
+ (c) Skip this component entirely"
22
+ Wait for the user to choose. Do NOT proceed without confirmation.
23
+ ```
24
+
25
+ ### Rule 2 — Token-only styling
26
+
27
+ ```
28
+ NEVER use:
29
+ ❌ Hardcoded hex: #FF444F, #FFFFFF, etc.
30
+ ❌ Raw Tailwind palette: bg-gray-100, text-zinc-500, text-slate-400, bg-black, bg-white
31
+ ❌ Raw opacity on non-tokens: bg-black/50 (use bg-overlay instead)
32
+ ❌ Arbitrary color values: bg-[#FF6600], text-[rgba(0,0,0,0.5)]
33
+ ❌ hsl(var(--token)) syntax — this is Tailwind v3. This project uses Tailwind v4.
34
+ ❌ Non-existent tokens: bg-hover, bg-badge-rank, text-primary-foreground, text-on-decorative
35
+ ❌ border-border — deprecated alias; use border-default or border-selected
36
+
37
+ ALWAYS use semantic tokens:
38
+ ✅ bg-primary-surface, bg-primary-canvas, bg-secondary-surface, bg-secondary-canvas, bg-overlay
39
+ ✅ text-prominent, text-subtle, text-on-prominent-static-inverse
40
+ ✅ border-default, border-selected, ring-ring
41
+ ✅ bg-primary, bg-primary-hover, bg-secondary-hover
42
+ ✅ text-warning, text-info, text-alert-info-text, text-alert-error-text
43
+ ✅ Opacity on a token IS allowed: bg-primary/20, border-default/50, ring-primary/10
44
+ ```
45
+
46
+ ### Rule 3 — Layout utilities are exempt
47
+
48
+ ```
49
+ Tailwind layout/spacing utilities are freely usable for structural layout:
50
+ ✅ flex, grid, gap-4, p-6, m-2, w-full, h-screen, max-w-lg, col-span-2, etc.
51
+ ✅ z-50, overflow-hidden, transition-all, etc.
52
+
53
+ Token rules apply ONLY to:
54
+ - Color (background, text, border, ring, shadow color)
55
+ - Border radius (use the design system's radius scale — see Section 5)
56
+ - Typography (font family must use font-display or font-body, never raw font names)
57
+ ```
58
+
59
+ ### Rule 4 — Do NOT install or import these separately
60
+
61
+ ```
62
+ ❌ lucide-react — already bundled in the npm package
63
+ ❌ tailwindcss — the package ships its own Tailwind v4 config
64
+ ❌ @apply with hsl(var(--token)) — Tailwind v4 uses CSS variables directly
65
+ ❌ tailwind.config.js — configuration is handled by the package via CSS
66
+ ❌ Manual font-family in CSS — use font-display and font-body utility classes
67
+ ```
68
+
69
+ ### Rule 5 — Complexity-aware implementation
70
+
71
+ ```
72
+ Each component in the catalogue is tagged:
73
+ [simple] → Drop in, one import, works immediately
74
+ [composed] → Has required sub-components; use the full pattern shown
75
+ [complex] → Has significant state or setup; ask clarifying questions first
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 1 — Quick Start
81
+
82
+ ### Step 1 — Install the package
83
+
84
+ ```bash
85
+ npm install @deriv-ds/design-intelligence-layer@latest --safe-chain-skip-minimum-package-age
86
+ ```
87
+
88
+ ### Step 2 — Add CSS imports
89
+
90
+ In your main CSS file (e.g. `globals.css` or `index.css`):
91
+
92
+ ```css
93
+ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap");
94
+ @import "tailwindcss";
95
+ @import "@deriv-ds/design-intelligence-layer/styles";
96
+ @source "../node_modules/@deriv-ds/design-intelligence-layer/dist";
97
+ ```
98
+
99
+ > **Note:** Fonts are loaded via a direct Google Fonts `@import` URL. Do NOT use `next/font`.
100
+
101
+ ### Step 3 — Set base HTML class
102
+
103
+ The design system is light-first. No extra class is required on `<html>` for the default light theme. Add `.dark` on `<html>` to switch to dark theme — all foundation, semantic, and component tokens are fully defined for both themes.
104
+
105
+ ### Step 4 — Import components
106
+
107
+ ```tsx
108
+ import { Button, Card, Tag } from "@deriv-ds/design-intelligence-layer"
109
+ ```
110
+
111
+ ---
112
+
113
+ ## 2 — Design Tokens
114
+
115
+ > This is the single authoritative token reference. All tokens are defined as CSS variables in the package and mapped to Tailwind utility classes automatically.
116
+
117
+ ### 2.1 — Backgrounds
118
+
119
+ | CSS Variable | Tailwind Class | Usage |
120
+ | ----------------------- | ----------------------- | ------------------------- |
121
+ | `--background-primary-surface` | `bg-primary-surface` | Primary surfaces (cards, panels, modals) |
122
+ | `--background-primary-canvas` | `bg-primary-canvas` | Main page / canvas background |
123
+ | `--background-secondary-surface` | `bg-secondary-surface` | Secondary / muted surfaces |
124
+ | `--background-secondary-canvas` | `bg-secondary-canvas` | Secondary canvas areas |
125
+ | `--overlay` | `bg-overlay` | Modal/dialog/drawer/sheet backdrop (semi-transparent) |
126
+ | `--tabs` | `bg-tabs` | Tab container / tab bar background — 4% alpha, adapts to any surface |
127
+ | `--tabs-active` | `bg-tabs-active` | Active / selected tab background |
128
+
129
+ ### 2.2 — Primary (Brand Coral)
130
+
131
+ | CSS Variable | Tailwind Class | Usage |
132
+ | --------------------- | ------------------- | ------------------------- |
133
+ | `--primary` | `bg-primary` / `text-primary` | Primary CTA, brand color (#FF444F coral-700), interactive elements |
134
+ | `--primary-hover` | `bg-primary-hover` | Hover & pressed states on primary elements (coral-800) |
135
+
136
+ ### 2.3 — Semantic (Status)
137
+
138
+ | CSS Variable | Tailwind Class | Usage |
139
+ | --------------------------- | ----------------------- | ------------------------- |
140
+ | `--text-success-default` | `text-success` (via foundation) | Success / Positive outcomes (green-900 light, green-500 dark) |
141
+ | `--text-error-default` | `text-error` (via foundation) | Error / Negative outcomes (red-900 light, red-500 dark) |
142
+ | `--text-warning-default` | `text-warning` | Warning / Caution / Non-destructive alerts (yellow-900 light, yellow-500 dark) |
143
+ | `--text-information-default`| `text-info` | Informational alerts (blue-900 light, blue-500 dark) |
144
+
145
+ > All semantic tokens support opacity variants (e.g. `bg-warning/10` for tinted backgrounds). Foundation background tokens are also available: `--background-success-default`, `--background-error-default`, `--background-warning-default`, `--background-information-default`. For structured alpha surfaces, use the primitive alpha scales — see Section 2.10.
146
+
147
+ ### 2.4 — Text & Icon Colors
148
+
149
+ | CSS Variable | Tailwind Class | Usage |
150
+ | ------------------------------- | --------------------------------------- | ------------------------- |
151
+ | `--text-prominent-default` | `text-prominent` | Primary text (headings, body) — slate-1200 light, slate-50 dark |
152
+ | `--on-prominent-static-inverse` | `text-on-prominent-static-inverse` | Always-white text (e.g. on primary coral buttons) — always slate-50 |
153
+ | `--text-subtle-default` | `text-subtle` | Secondary text (descriptions, labels) — slate @ 48% alpha |
154
+
155
+ ### 2.5 — Borders & Inputs
156
+
157
+ | CSS Variable | Tailwind Class | Usage |
158
+ | --------------------------- | ------------------------- | ------------------------- |
159
+ | `--border-default-default` | `border-default` | Default border (slate @ 16% alpha) |
160
+ | `--border-subtle-default` | (via `--input`) | Subtle / light border (slate @ 8% alpha) |
161
+ | `--border-selected-default` | `border-selected` | Selected / emphasized border (solid slate-1200) |
162
+ | `--input` | `border-input` | Input resting state border (aliases `--border-subtle-default`) |
163
+ | `--ring` | `ring-ring` / `border-ring` | Focus ring and focus border color (coral-700) |
164
+
165
+ ### 2.6 — Supporting Colors
166
+
167
+ | CSS Variable | Tailwind Class | Usage |
168
+ | ------------------------ | -------------------- | ------------------------- |
169
+ | `--secondary-hover` | `bg-secondary-hover` | Hover bg on neutral elements (aliases `--background-secondary-surface`) |
170
+ | `--slider-range` | `bg-slider-range` | Slider range fill (coral-700 at 40% opacity) |
171
+ | `--alert-info-text` | `text-alert-info-text` | Alert info text color |
172
+ | `--alert-info-border` | `border-alert-info-border` | Alert info border |
173
+ | `--alert-error-text` | `text-alert-error-text` | Alert error text color |
174
+ | `--alert-error-border` | `border-alert-error-border` | Alert error border |
175
+
176
+ > **Utility tokens:** `--text-utility-brand` (coral-700), `--text-utility-real` (emerald-700), and `--text-utility-demo` are available as CSS variables for brand-specific highlights. The primitive palette includes coral, cherry, emerald, and full color alpha scales — reference these via semantic or component tokens, not directly.
177
+
178
+ ### 2.7 — Opacity Patterns
179
+
180
+ | Usage | Tailwind Class |
181
+ | ------------------------------ | ---------------------- |
182
+ | Subtle hover tint | `bg-primary/[0.08]` |
183
+ | Medium highlight | `bg-primary/[0.16]` |
184
+ | Selected/active tint | `bg-primary/10` |
185
+ | Status tint backgrounds | `bg-success/10`, `bg-error/10`, `bg-warning/10`, etc. |
186
+
187
+ ### 2.8 — Interactive States
188
+
189
+ > **`bg-hover` does not exist.** Use `bg-secondary-hover` or `bg-primary/[0.08]` for hover states.
190
+
191
+ **Universal pattern for interactive list/row/chip elements** (except Button and Tabs which have their own):
192
+
193
+ | State | Background | Text |
194
+ | -------- | -------------------- | ---------------------------------- |
195
+ | Default | transparent | `text-prominent` or `text-subtle` |
196
+ | Hover | `bg-secondary-hover` | `text-primary` |
197
+ | Selected | `bg-secondary-hover` | `text-primary font-semibold` |
198
+
199
+ > **NEVER** use `bg-accent` or `text-accent-foreground`. Do NOT add borders to selected states.
200
+
201
+ ### 2.9 — Transitions
202
+
203
+ **Duration tokens:**
204
+
205
+ | Tailwind Class | CSS Variable | Value | Usage |
206
+ | ----------------- | ------------------------------ | ------ | -------------------------------------- |
207
+ | `duration-instant`| `--primitive-duration-instant` | `50ms` | Focus rings, hover color tints |
208
+ | `duration-fast` | `--primitive-duration-fast` | `100ms`| Buttons, inputs, badges, checkboxes |
209
+ | `duration-base` | `--primitive-duration-base` | `200ms`| Dropdowns, popovers, accordions |
210
+ | `duration-slow` | `--primitive-duration-slow` | `300ms`| Dialogs, sheets, drawers closing |
211
+ | `duration-open` | `--primitive-duration-open` | `500ms`| Sheets, drawers entering |
212
+
213
+ **Easing tokens:**
214
+
215
+ | Tailwind Class | CSS Variable | Value | Usage |
216
+ | ---------------- | ----------------------------- | ------------------------------ | -------------------------------------- |
217
+ | `ease-standard` | `--primitive-ease-standard` | `cubic-bezier(0.2, 0, 0, 1)` | General UI — bidirectional state changes |
218
+ | `ease-enter` | `--primitive-ease-enter` | `cubic-bezier(0, 0, 0.2, 1)` | Overlays / surfaces entering |
219
+ | `ease-exit` | `--primitive-ease-exit` | `cubic-bezier(0.4, 0, 1, 1)` | Overlays / surfaces leaving |
220
+ | `ease-linear` | `--primitive-ease-linear` | `linear` | Sidebar width, progress bar |
221
+
222
+ **Usage pattern:**
223
+
224
+ ```tsx
225
+ <div className="transition-colors duration-fast ease-standard">...</div>
226
+ ```
227
+
228
+ ### 2.10 — Primitive Alpha Scales
229
+
230
+ > Raw alpha (opacity) variants. These are **internal CSS variables only** — not exposed as Tailwind utility classes. Reference them only from semantic or component tokens, never directly in components.
231
+
232
+ **Naming convention:** `--primitive-[color]-alpha-[stop]`
233
+
234
+ **All alpha scales** share the same stop progression: `50` (0%), `75` (4%), `100` (8%), `200` (16%), `300` (24%), `400` (32%), `500` (40%), `600` (48%), `700` (56%), `800` (64%), `900` (72%), `1000` (80%), `1100` (88%).
235
+
236
+ **Slate alpha scale** (dark text/surface base — `oklch(0.227 0.019 266.2 / X%)`)
237
+
238
+ | CSS Variable | Opacity | Typical use |
239
+ | ------------------------------- | ------- | ---------------------------------------- |
240
+ | `--primitive-slate-alpha-75` | 4% | Tab container background (`--tabs`), default opacity surfaces |
241
+ | `--primitive-slate-alpha-100` | 8% | Subtle hover tint, secondary-hover, subtle borders |
242
+ | `--primitive-slate-alpha-200` | 16% | Pressed / active surface tint, default borders |
243
+ | `--primitive-slate-alpha-300` | 24% | Disabled text, field disabled text |
244
+ | `--primitive-slate-alpha-500` | 40% | Subtle text (via `--text-subtle-default`) |
245
+ | `--primitive-slate-alpha-600` | 48% | Field subtle text, placeholder text |
246
+
247
+ **White alpha scale** (light surface base — `oklch(1.000 0.000 263.3 / X%)`)
248
+
249
+ | CSS Variable | Opacity | Typical use |
250
+ | ------------------------------- | ------- | ---------------------------------------- |
251
+ | `--primitive-white-alpha-75` | 4% | Dark theme default opacity surfaces |
252
+ | `--primitive-white-alpha-100` | 8% | Dark theme hover, subtle borders |
253
+ | `--primitive-white-alpha-200` | 16% | Dark theme pressed, default borders, disabled text |
254
+ | `--primitive-white-alpha-500` | 40% | Dark theme subtle text |
255
+
256
+ **Black alpha scale** (overlay base — `oklch(0.000 0.000 0.0 / X%)`)
257
+
258
+ | CSS Variable | Opacity | Typical use |
259
+ | ------------------------------- | ------- | ---------------------------------------- |
260
+ | `--primitive-black-alpha-75` | 4% | Lightest elevation shadow |
261
+ | `--primitive-black-alpha-100` | 8% | Medium elevation shadow, dark theme elevation colour |
262
+ | `--primitive-black-alpha-200` | 16% | Strong elevation shadow (dark theme) |
263
+ | `--primitive-black-alpha-300` | 24% | Bottom sheet handle bar |
264
+
265
+ **Color alpha scales** — Blue, Green, Emerald, Yellow, Red, Coral, Cherry all follow the same stop pattern:
266
+
267
+ | Scale prefix | Base color | Typical use |
268
+ | --------------------------- | ---------- | ---------------------------------------- |
269
+ | `--primitive-blue-alpha-*` | `oklch(0.676 0.177 251.1)` | Information backgrounds, badge status |
270
+ | `--primitive-green-alpha-*` | `oklch(0.546 0.160 147.5)` | Success backgrounds, field success tint |
271
+ | `--primitive-yellow-alpha-*`| `oklch(0.777 0.171 65.3)` | Warning backgrounds, section message |
272
+ | `--primitive-red-alpha-*` | `oklch(0.588 0.232 29.5)` | Error backgrounds, field error tint |
273
+ | `--primitive-coral-alpha-*` | `oklch(0.665 0.222 22.7)` | Brand alpha tints |
274
+ | `--primitive-emerald-alpha-*`| `oklch(0.725 0.150 166.0)` | Real-account highlights |
275
+ | `--primitive-cherry-alpha-*`| `oklch(0.571 0.229 18.2)` | Reserved |
276
+
277
+ > The `--overlay` semantic token resolves to `--primitive-black-50` (black at 0% — effectively transparent). For modal backdrops, use `bg-overlay` which is handled by the semantic layer.
278
+
279
+ ---
280
+
281
+ ## 3 — AI Agent Decision Rules
282
+
283
+ > Quick-lookup table: "If I need X, use Y, never Z."
284
+
285
+ | IF you need to... | THEN use | NEVER use |
286
+ | -------------------------------------- | --------------------------------- | -------------------------------------- |
287
+ | Pick a primary CTA button color | `bg-primary` | Green, blue, or any other color for primary CTA |
288
+ | Show SUCCESS / profit / positive | `text-success` (foundation) | Primary coral for profit |
289
+ | Show ERROR / negative | `text-error` (foundation) | Any non-token red |
290
+ | Show WARNING / caution | `text-warning` | Raw orange hex or primary tint |
291
+ | Color a tab container background | `bg-tabs` | `bg-secondary-surface` for tabs |
292
+ | Color an active/selected tab | `bg-tabs-active` | `bg-primary-surface` for active tab |
293
+ | Color a page background | `bg-primary-canvas` | `bg-white` directly |
294
+ | Color a modal/dialog backdrop | `bg-overlay` | `bg-black/50` or raw black opacity |
295
+ | Color a card or panel | `bg-primary-surface` | Arbitrary gray |
296
+ | Color an elevated surface (popover) | `bg-primary-surface` | Arbitrary gray for popovers |
297
+ | Color a secondary/muted surface | `bg-secondary-surface` | `bg-gray-*` or raw values |
298
+ | Write primary heading text | `text-prominent` | Pure white, raw hex colors |
299
+ | Write body / description text | `text-subtle` | `text-prominent` for descriptions |
300
+ | Write a subtle label | `text-subtle` | Raw gray values |
301
+ | Add a default border | `border-default` | Solid black borders, raw hex |
302
+ | Add a selected/strong border | `border-selected` | — |
303
+ | Style an input (resting) | `border-input` | Solid colored backgrounds |
304
+ | Style an input (focused) | `border-ring` + `ring-[3px] ring-ring/50` | Generic shadows on inputs |
305
+ | Pick a heading font | `font-display` | System fonts, raw font-family names |
306
+ | Pick a body font | `font-body` | Raw font-family names |
307
+ | Style button text | `font-display font-semibold`, sentence case | `uppercase` on buttons, `font-bold` |
308
+ | Write white text on a dark surface | `text-on-prominent-static-inverse`| `text-white` or raw white hex |
309
+
310
+ ---
311
+
312
+ ## 4 — Typography
313
+
314
+ ### 4.1 — Font Setup
315
+
316
+ All text uses **Inter** (loaded weights: 300–800). Three Tailwind aliases are available — they all resolve to the same font:
317
+
318
+ | Tailwind Class | Purpose |
319
+ | --------------- | ------------------------------- |
320
+ | `font-display` | Headings, wordmark, buttons |
321
+ | `font-body` | Body text, UI elements |
322
+ | `font-sans` | Default sans-serif fallback |
323
+
324
+ ### 4.2 — Pre-built Typography Classes
325
+
326
+ The npm package ships these ready-to-use CSS classes:
327
+
328
+ **Heading scale** (Inter · ExtraBold 800 · letter-spacing: -0.02em):
329
+
330
+ | Class | Size | Line Height | Weight | Letter Spacing |
331
+ | -------------- | ----- | ----------- | ------ | -------------- |
332
+ | `heading-hero` | 64px | 64px | 800 | -0.02em |
333
+ | `heading-h1` | 56px | 56px | 800 | -0.02em |
334
+ | `heading-h2` | 40px | 40px | 800 | -0.02em |
335
+ | `heading-h3` | 32px | 32px | 800 | -0.02em |
336
+ | `heading-h4` | 24px | 24px | 800 | -0.02em |
337
+ | `heading-h5` | 20px | 20px | 800 | -0.02em |
338
+ | `heading-h6` | 16px | 16px | 800 | -0.02em |
339
+
340
+ > `heading-xs` is **deprecated** — use `heading-h4` instead (same size: 24px/24px/800).
341
+
342
+ **Body scale** (Inter · Regular 400):
343
+
344
+ | Class | Size | Line Height | Weight |
345
+ | ---------- | ----- | ----------- | ------ |
346
+ | `body-xl` | 20px | 30px | 400 |
347
+ | `body-lg` | 18px | 27px | 400 |
348
+ | `body-md` | 16px | 24px | 400 |
349
+ | `body-sm` | 14px | 21px | 400 |
350
+ | `body-xs` | 12px | 18px | 400 |
351
+
352
+ ### 4.3 — Custom Text Size Overrides
353
+
354
+ These sizes differ from standard Tailwind defaults — use the design system values:
355
+
356
+ | Class | Size | Line Height | How it differs from Tailwind |
357
+ | ----------- | ------ | ----------- | ---------------------------- |
358
+ | `text-xxs` | 8px | 12px | Custom (not in standard TW) |
359
+ | `text-2xl` | 24px | **24px** | Line height differs (TW: 32px) |
360
+ | `text-3xl` | **32px** | **32px** | Size differs (TW: 30px) |
361
+ | `text-4xl` | **40px** | **40px** | Size differs (TW: 36px) |
362
+ | `text-6xl` | **64px** | **64px** | Size differs (TW: 60px) |
363
+
364
+ > All other `text-*` sizes (`xs`, `sm`, `base`, `lg`, `xl`, `5xl`, `7xl`, `8xl`, `9xl`) match standard Tailwind.
365
+
366
+ ### 4.4 — Typography Usage Rules
367
+
368
+ | Context | Class | Weight |
369
+ | ------------------------ | -------------- | ------------------- |
370
+ | Page headings | `font-display` | `font-extrabold` (800) |
371
+ | Button labels | `font-display` | `font-semibold` (600), sentence case |
372
+ | Body text | `font-body` | `font-normal` (400) |
373
+ | Tiny labels / decorative | `font-body` | `font-medium` (500) |
374
+
375
+ ### 4.5 — Letter Spacing Tokens
376
+
377
+ | Token value | Usage |
378
+ | ----------- | ------------------------ |
379
+ | -0.02em | Headings (all levels) |
380
+ | -0.4px | Paragraphs, tight text |
381
+ | -0.8px | Tight display text |
382
+
383
+ ---
384
+
385
+ ## 5 — Border Radius
386
+
387
+ The design system uses a custom radius scale (base = 10px). Use these named tokens instead of arbitrary values:
388
+
389
+ | Tailwind Class | Value |
390
+ | -------------- | ------ |
391
+ | `rounded-2xs` | 2px |
392
+ | `rounded-xs` | 4px |
393
+ | `rounded-sm` | 6px |
394
+ | `rounded-md` | 8px |
395
+ | `rounded-lg` | 10px |
396
+ | `rounded-xl` | 14px |
397
+ | `rounded-2xl` | 18px |
398
+ | `rounded-3xl` | 22px |
399
+ | `rounded-4xl` | 26px |
400
+ | `rounded-full` | 9999px |
401
+
402
+ > **Important:** Do NOT use `rounded-[4px]` or `rounded-[2px]` — use `rounded-xs` and `rounded-2xs` instead. Arbitrary radius values should only be used for sizes not in this scale (e.g. `rounded-[24px]`, `rounded-[32px]`).
403
+
404
+ ---
405
+
406
+ ## 6 — Button System
407
+
408
+ ### 6.1 — Variants
409
+
410
+ | Variant | Background | Text Color | Border | Hover |
411
+ | ----------- | --------------------------------------- | ---------------------------------- | ----------------------------------------- | ----------------------------------------- |
412
+ | `primary` | `bg-button-primary-bg` | `text-on-prominent-static-inverse` | none | `bg-button-primary-bg-hover` |
413
+ | `secondary` | transparent | `text-prominent` | `border-[1.5px] border-button-secondary-border` | `bg-button-secondary-bg-hover` |
414
+ | `tertiary` | `bg-button-tertiary-bg` | `text-prominent` | none | `bg-button-tertiary-bg-hover` |
415
+ | `ghost` | transparent | `text-prominent` | none | `bg-button-ghost-bg-hover` |
416
+
417
+ > All button variants support `normal`, `inverse`, `static-light`, and `static-dark` sub-variants via component tokens.
418
+
419
+ ### 6.2 — Sizes
420
+
421
+ | Size | Height | Padding X | Font Size | Min Width | Radius |
422
+ | --------- | ------ | --------- | --------- | --------- | --------- |
423
+ | `lg` | 48px | 20px | 18px | 96px | `rounded-full` (999px) |
424
+ | `md` | 40px | 16px | 16px | 80px | `rounded-full` (999px) |
425
+ | `sm` | 32px | 12px | 14px | 64px | `rounded-full` (999px) |
426
+
427
+ **Icon-only sizes:**
428
+
429
+ | Size | Dimensions | Icon Size |
430
+ | ---------- | ---------- | --------- |
431
+ | `icon-lg` | 48×48px | 48px |
432
+ | `icon-md` | 40×40px | 40px |
433
+ | `icon-sm` | 32×32px | 32px |
434
+
435
+ ### 6.3 — Button Typography & States
436
+
437
+ All buttons: `font-display font-semibold` (600), sentence case (no `uppercase`, no `tracking-wide`).
438
+
439
+ | State | Behavior |
440
+ | -------- | ------------------------------------------------ |
441
+ | Default | Base styling per variant |
442
+ | Hover | Color shift per variant (see above) |
443
+ | Focus | 3px ring with `ring-ring/50` opacity |
444
+ | Pressed | Pressed bg token per variant (e.g. `bg-button-primary-bg-pressed`) |
445
+ | Loading | `opacity-24`, `pointer-events-none`, `data-loading`, `aria-busy` — applies to all variants |
446
+ | Disabled | Dedicated disabled tokens: `bg-button-disabled-normal-bg`, `text-button-disabled-normal-text` — not generic opacity |
447
+
448
+ ---
449
+
450
+ ## 7 — Responsive Layout
451
+
452
+ ### 7.1 — Layout Grid
453
+
454
+ | Breakpoint | Viewport | Columns | Gutter | Margin |
455
+ | ---------- | ---------- | ------- | ------ | ------ |
456
+ | Default | 0–319px | 1 | 0 | 16px |
457
+ | Small | 320–599px | 4 | 16px | 16px |
458
+ | Medium | 600–1135px | 8 | 36px | 36px |
459
+ | Large | 1136px+ | 12 | 36px | 64px |
460
+
461
+ **Tailwind utilities:** `gap-layout-gutter`, `px-layout-margin-inline`.
462
+
463
+ **CSS variables for custom grids:** `var(--semantic-layout-grid-columns)`, `var(--spacing-layout-gutter)`, `var(--spacing-layout-margin-inline)`.
464
+
465
+ ### 7.2 — Responsive Spacing Tokens
466
+
467
+ | Token | Desktop | Mobile |
468
+ | -------------------- | ------- | ------ |
469
+ | container-padding-x | 24px | 16px |
470
+ | section-padding-y | 96px | 64px |
471
+ | section-title-gap-xl | 24px | 20px |
472
+ | section-title-gap-lg | 20px | 16px |
473
+ | section-title-gap-md | 20px | 16px |
474
+ | section-title-gap-sm | 16px | 16px |
475
+
476
+ ---
477
+
478
+ ## 8 — Available Components
479
+
480
+ > **All components below are exported from `@deriv-ds/design-intelligence-layer`.**
481
+ > - If a component is listed → import and use it. Do NOT re-implement.
482
+ > - If NOT listed → STOP and ask the user (see Rule 1).
483
+ > - For props, variants, sizes, and sub-components → inspect the package's TypeScript types after installation.
484
+
485
+ ### Import pattern
486
+
487
+ All components use the same import path:
488
+
489
+ ```tsx
490
+ import { Button, Card, Tag } from "@deriv-ds/design-intelligence-layer"
491
+ ```
492
+
493
+ ### Example — composed component with sub-components
494
+
495
+ ```tsx
496
+ import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose } from "@deriv-ds/design-intelligence-layer"
497
+
498
+ <Dialog>
499
+ <DialogTrigger asChild><Button>Open</Button></DialogTrigger>
500
+ <DialogContent showCloseButton>
501
+ <DialogHeader>
502
+ <DialogTitle>Title</DialogTitle>
503
+ <DialogDescription>Description text.</DialogDescription>
504
+ </DialogHeader>
505
+ <div>Content here</div>
506
+ <DialogFooter>
507
+ <Button variant="primary" size="md">Confirm</Button>
508
+ </DialogFooter>
509
+ </DialogContent>
510
+ </Dialog>
511
+ ```
512
+
513
+ ### Component list
514
+
515
+ > **Complexity tags:** `[simple]` = drop in, one import | `[composed]` = has required sub-components | `[complex]` = has significant state/setup, ask the user first
516
+
517
+ | Component | Tag | Sub-components |
518
+ |-----------|-----|----------------|
519
+ | Accordion | [composed] | AccordionItem, AccordionTrigger, AccordionContent |
520
+ | AspectRatio | [simple] | — |
521
+ | Avatar | [composed] | AvatarImage, AvatarFallback, AvatarBadge, AvatarGroup, AvatarGroupCount |
522
+ | Breadcrumb | [composed] | BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis |
523
+ | Button | [simple] | — |
524
+ | Calendar | [complex] | — |
525
+ | Card | [composed] | CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction |
526
+ | Carousel | [complex] | CarouselContent, CarouselItem, CarouselPrevious, CarouselNext |
527
+ | Chart | [complex] | ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle |
528
+ | Checkbox | [simple] | — |
529
+ | Collapsible | [composed] | CollapsibleTrigger, CollapsibleContent |
530
+ | Combobox | [complex] | ComboboxInput, ComboboxContent, ComboboxList, ComboboxItem, ComboboxEmpty, ComboboxGroup, ComboboxLabel |
531
+ | Command | [complex] | CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator, CommandShortcut |
532
+ | ContextMenu | [composed] | ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuLabel, ContextMenuCheckboxItem, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent |
533
+ | Dialog | [complex] | DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, DialogClose |
534
+ | DirectionProvider | [simple] | — |
535
+ | Drawer | [complex] | DrawerTrigger, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription, DrawerClose |
536
+ | DropdownMenu | [composed] | DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuShortcut |
537
+ | Empty | [composed] | EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent |
538
+ | Field | [complex] | FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSet, FieldContent, FieldTitle, FieldSeparator |
539
+ | Form | [complex] | FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage |
540
+ | HoverCard | [composed] | HoverCardTrigger, HoverCardContent |
541
+ | Input | [simple] | — |
542
+ | InputGroup | [composed] | InputGroupAddon, InputGroupInput, InputGroupButton, InputGroupText, InputGroupTextarea |
543
+ | Item | [composed] | ItemGroup, ItemContent, ItemTitle, ItemDescription, ItemMedia, ItemActions, ItemHeader, ItemFooter, ItemSeparator |
544
+ | Kbd | [simple] | KbdGroup |
545
+ | Label | [simple] | — |
546
+ | Link | [simple] | — |
547
+ | Menubar | [complex] | MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem, MenubarSeparator, MenubarLabel, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent, MenubarShortcut |
548
+ | Modal | [complex] | ModalTrigger, ModalContent, ModalHeader, ModalFooter, ModalTitle, ModalDescription, ModalAction, ModalCancel, ModalMedia |
549
+ | NativeSelect | [simple] | NativeSelectOption, NativeSelectOptGroup |
550
+ | NavigationMenu | [complex] | NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, navigationMenuTriggerStyle |
551
+ | OTPField | [composed] | OTPFieldGroup, OTPFieldSlot, OTPFieldSeparator |
552
+ | Pagination | [composed] | PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis |
553
+ | Popover | [composed] | PopoverTrigger, PopoverContent, PopoverHeader, PopoverTitle, PopoverDescription |
554
+ | Progress | [simple] | — |
555
+ | RadioGroup | [composed] | RadioGroupItem |
556
+ | Resizable | [complex] | ResizablePanelGroup, ResizablePanel, ResizableHandle |
557
+ | ScrollArea | [simple] | ScrollBar |
558
+ | SectionMessage | [composed] | SectionMessageTitle, SectionMessageDescription |
559
+ | Select | [composed] | SelectTrigger, SelectValue, SelectContent, SelectGroup, SelectLabel, SelectItem, SelectSeparator |
560
+ | Separator | [simple] | — |
561
+ | Sheet | [complex] | SheetTrigger, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription, SheetClose |
562
+ | Sidebar | [complex] | SidebarProvider, SidebarTrigger, SidebarInset, SidebarHeader, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarGroupContent, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarRail, useSidebar |
563
+ | Skeleton | [simple] | — |
564
+ | Slider | [simple] | — |
565
+ | Sonner (Toaster) | [simple] | — (also import `toast` from `sonner`) |
566
+ | Spinner | [simple] | — |
567
+ | Stepper | [simple] | — |
568
+ | Switch | [simple] | — |
569
+ | Table | [composed] | TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption |
570
+ | Tabs | [composed] | TabsList (`variant`: default/line, `size`: sm/md/lg), TabsTrigger (`iconPosition`: inline/top), TabsContent. Root accepts `orientation`: horizontal/vertical. |
571
+ | Tag | [simple] | — |
572
+ | Textarea | [simple] | — |
573
+ | TicketCard | [composed] | — |
574
+ | Toggle | [simple] | — |
575
+ | ToggleGroup | [composed] | ToggleGroupItem |
576
+ | Tooltip | [composed] | TooltipTrigger, TooltipContent, TooltipProvider |
577
+
578
+ ### Component styling notes
579
+
580
+ These are styling behaviors you can't discover from TypeScript types alone:
581
+
582
+ | Component | Note |
583
+ |-----------|------|
584
+ | Button | `font-display font-semibold` (600), sentence case (no `uppercase`). Primary: `text-on-prominent-static-inverse`. Radius: `rounded-full` (pill). 4 variants: primary, secondary, tertiary, ghost |
585
+ | Card | Flat by default (no shadow). Add elevation manually: `className="shadow-sm"` or use elevation tokens `var(--elevation-100)` through `var(--elevation-500)` |
586
+ | Input | Resting: `border-input`. Focus: `border-ring` + `ring-[3px] ring-ring/50`. Radius: `rounded-sm` (6px) |
587
+ | Tooltip | Bubble: uses component tokens `--tooltip-bg-default` + `--tooltip-text-default`. Always wrap in `<TooltipProvider>` |
588
+ | Sidebar | Menu buttons use `rounded-sm`. Selection: `bg-secondary-hover` + `text-primary` + `font-semibold` |
589
+ | Breadcrumb | Active page: `text-primary font-medium`. Links: `text-subtle` |
590
+ | Tabs | **Variants:** `default` (pill, `bg-tabs`) and `line` (underline, transparent bg). **Sizes:** `sm` (32px, 14px text), `md` (40px, 16px text, default), `lg` (48px, 18px text). Uses component tokens: `--tab-text-default`, `--tab-text-selected`, `--tab-bg-hover`. Selected weight: 600. |
591
+ | Select | Item hover: `bg-primary/[0.08]`. Selected: `text-primary font-medium` + checkmark. `SelectTrigger` accepts `readOnly` prop: blocks interaction, retains full default appearance, chevron renders at `opacity-30` |
592
+ | Progress | Track and indicator use component tokens `--progress-bar-bg-*`. Sizes: sm (4px height) and md (8px height). Radius: `rounded-full` |
593
+ | Spinner | Uses `--loading-spinner-bg-default` (coral-700). Inherits parent text color for custom use |
594
+ | Stepper | Numeric input flanked by `−` / `+` tertiary `icon-xs` buttons. Composes `InputGroup` internally. Props: `value`, `defaultValue`, `onValueChange`, `min`, `max`, `step` (default 1), `disabled`, `placeholder`. Supports controlled & uncontrolled modes, keyboard Arrow Up/Down, and floating-point steps. Default width: `w-32` |
595
+ | Switch | Checked track: `bg-slider-range`. Checked thumb: `bg-primary` |
596
+ | Slider | Thumb: square `rounded-[4px]`, `bg-primary`. Track range: `bg-slider-range` |
597
+ | Dialog/Sheet | Footer buttons should use `size="md"`. Overlay: `bg-overlay` |
598
+ | Menubar | Hover: `bg-primary/[0.08]`. Open state: `bg-primary/10` |
599
+ | Toggle | Pressed: `bg-primary/10` + `border-primary` + `text-primary` |
600
+ | Calendar | Selected: `bg-secondary-hover` + `text-primary font-bold`. Today: primary dot below date |
601
+
602
+ ---
603
+
604
+ ## 8.5 — Blocks Catalogue
605
+
606
+ > Blocks are fully composed UI sections built from design system primitives. They appear in the **Blocks** tab of the playground.
607
+ > - Blocks are **NOT exported** from the npm package — they are playground demonstrations only.
608
+ > - To build them in a consuming project, import the underlying components (`Button`, etc.) from `@deriv-ds/design-intelligence-layer` and compose them manually using design tokens only.
609
+ > - Do NOT mistake a Block for a component — it will not appear in Rule 1's component list.
610
+
611
+ ### NavBar
612
+
613
+ A landing page top navigation bar with Desktop and Mobile breakpoint variants.
614
+
615
+ | Variant | Description |
616
+ |---------|-------------|
617
+ | Desktop | Full-width bar: logo left, ghost nav links centre-left, Sign in (ghost) + Sign up (primary) right |
618
+ | Mobile — closed | Logo left, hamburger icon-button right |
619
+ | Mobile — open | Logo + close icon top row; stacked ghost nav links + full-width Sign in / Sign up below a divider |
620
+
621
+ **Components used:** `Button` (variants: `ghost`, `primary`, `secondary`; sizes: `sm`, `icon-sm`)
622
+
623
+ **Tokens used:** `bg-primary-surface`, `bg-primary`, `border-default`, `rounded-xs`, `rounded-md`
624
+
625
+ ---
626
+
627
+ ### Hero
628
+
629
+ Landing page hero sections in multiple layout types.
630
+
631
+ | Variant | Description |
632
+ |---------|-------------|
633
+ | Type 1 — Desktop | Two columns: tagline pill + heading + body + Get started / Learn more CTAs left; square image panel right |
634
+ | Type 1 — Mobile | Single column stacked: text content centred above, image panel full-width below |
635
+ | Type 2 — Desktop | Centred single-column: tagline pill + heading + body + single primary CTA with `ArrowRight` icon; no image |
636
+
637
+ **Components used:** `Button` (default `sm`, `secondary sm`); `ArrowUpRight`, `ArrowRight` icons (lucide)
638
+
639
+ **Tokens used:** `bg-primary-surface`, `bg-secondary-surface`, `border-default`, `text-prominent`, `text-subtle`, `bg-success`, `rounded-xl`, `rounded-full`, `px-layout-margin-inline`, `gap-layout-gutter`, `py-24`, `text-5xl`, `font-semibold`, `font-display`, `tracking-tight`, `text-lg`, `font-body`, `text-sm`, `shadow-sm`, `max-w-2xl`
640
+
641
+ ---
642
+
643
+ ## 9 — Common Mistakes
644
+
645
+ | Mistake | Correct Approach |
646
+ | ------- | ---------------- |
647
+ | Using hardcoded hex (`#FF444F`) for primary | Use `bg-primary` or `text-primary` |
648
+ | Using `bg-white` or `bg-black` | Use `bg-primary-surface` or `bg-overlay` |
649
+ | Using `border-border` | Use `border-default` or `border-selected` |
650
+ | Using `bg-hover` | Use `bg-primary/[0.08]` or `bg-secondary-hover` |
651
+ | Using `text-primary-foreground` | Use `text-on-prominent-static-inverse` |
652
+ | Using `text-on-decorative` | Use `text-subtle` |
653
+ | Using `font-mono` expecting Inter | Use `font-display` or `font-body` |
654
+ | Using `font-semibold` for headings | Use `font-extrabold` (800) for headings |
655
+ | Using `font-bold` for buttons | Use `font-semibold` (600) for buttons |
656
+ | Using `uppercase` on buttons | Buttons use sentence case (no `uppercase`) |
657
+ | Using standard TW sizes for headings (e.g. `text-6xl` = 60px) | Use design system values (`text-6xl` = 64px in this system) |
658
+ | Using `rounded-[4px]` or `rounded-[2px]` | Use `rounded-xs` (4px) or `rounded-2xs` (2px) |
659
+ | Using small radius on buttons | Buttons use `rounded-full` (pill shape, 999px) |
660
+ | Installing `lucide-react` separately | Already bundled — import icons directly |
661
+ | Adding `tailwind.config.js` | Tailwind v4 uses CSS config via the package |
662
+ | Using `bg-gray-*`, `text-zinc-*`, etc. | Use semantic tokens only |
663
+ | Using `bg-prominent`, `bg-card`, `bg-popover`, `bg-subtle` | Use `bg-primary-surface`, `bg-primary-canvas`, `bg-secondary-surface`, `bg-secondary-canvas` |
664
+ | Using `text-on-prominent`, `text-on-subtle` | Use `text-prominent`, `text-subtle` |
665
+ | Using `border-border-subtle`, `border-border-prominent` | Use `border-default`, `border-selected` |
666
+ | Using `text-semantic-win`, `text-semantic-loss` | Use foundation tokens or component tokens for status colors |
667
+
668
+ ---
669
+
670
+ ## 10 — Accessibility Notes
671
+
672
+ 1. **Primary coral text on white** (~4.5:1 for coral-700 #FF444F) — check contrast for small text; reserve for large/bold UI labels if ratio is borderline.
673
+ 2. **Secondary text `text-subtle` on white** (~4.5:1) — meets WCAG AA for normal text.
674
+ 3. **Success green on white** (green-900 #007A22 ~5.0:1) — safe for normal text at AA.
675
+ 4. **Error red on white** (red-900 #C40000 ~4.5:1) — safe for normal text at AA in light theme.
676
+ 5. **Warning yellow on white** (yellow-900 #C47D00) — check contrast; pair with icons.
677
+ 6. Always pair semantic colors with **icons or labels** — never communicate meaning through color alone.
678
+
679
+ ---
680
+
681
+ ## Quick Reference — Code Snippets
682
+
683
+ **Primary CTA:**
684
+ ```tsx
685
+ <Button variant="primary" size="lg">Get Started</Button>
686
+ ```
687
+
688
+ **Success/Error display:**
689
+ ```tsx
690
+ <span className="text-success font-body font-semibold">+$84.00</span>
691
+ <span className="text-error font-body font-semibold">-$120.00</span>
692
+ ```
693
+
694
+ **Heading:**
695
+ ```tsx
696
+ <h1 className="heading-h1">Quill Design System</h1>
697
+ ```
698
+
699
+ **Body text:**
700
+ ```tsx
701
+ <p className="body-md">Your portfolio summary for today.</p>
702
+ ```
703
+
704
+ **Input with focus styling:**
705
+ ```tsx
706
+ <Input type="email" placeholder="Enter your email" />
707
+ ```
708
+
709
+ ---
710
+
711
+ ## 11 — Elevation Tokens
712
+
713
+ The design system provides a 5-level elevation scale using multi-layer box shadows. Each level adapts automatically between light and dark themes.
714
+
715
+ | Token | Layers | Typical use |
716
+ | ------------------ | ------ | ------------------------------- |
717
+ | `var(--elevation-100)` | 1 | Subtle lift (cards, inputs) |
718
+ | `var(--elevation-200)` | 2 | Low elevation (dropdown menus) |
719
+ | `var(--elevation-300)` | 3 | Medium elevation (popovers, tooltips) |
720
+ | `var(--elevation-400)` | 3 | High elevation (dialogs, modals)|
721
+ | `var(--elevation-500)` | 3 | Maximum elevation (sheets, drawers) |
722
+
723
+ **Usage:**
724
+ ```tsx
725
+ <div style={{ boxShadow: 'var(--elevation-300)' }}>Elevated card</div>
726
+ ```
727
+
728
+ > These are CSS variables, not Tailwind utilities. Use inline style or custom class. Shadow colours auto-swap between light (`--primitive-black-alpha-*`) and dark themes.
729
+
730
+ ---
731
+
732
+ ## 12 — Component Token Reference
733
+
734
+ > Component tokens are CSS variables that drive individual component styling. They reference Layer 1 primitives or Layer 2 semantics only, and they auto-adapt between light (`:root`) and dark (`.dark`) themes. You should not reference these directly in application code — they are consumed internally by the component CSS.
735
+
736
+ ### 12.1 — Button Component Tokens
737
+
738
+ | Token pattern | Example | Description |
739
+ |---------------|---------|-------------|
740
+ | `--button-{variant}-{mode}-bg-{state}` | `--button-primary-normal-bg-default` | Background for given variant, mode (normal/inverse/static-light/static-dark), and state (default/hover/pressed) |
741
+ | `--button-{variant}-{mode}-text` | `--button-secondary-normal-text` | Text color |
742
+ | `--button-{variant}-{mode}-border` | `--button-secondary-normal-border` | Border color (secondary only) |
743
+ | `--button-{variant}-{mode}-icon` | `--button-ghost-normal-icon` | Icon color |
744
+ | `--button-disabled-{mode}-*` | `--button-disabled-normal-bg` | Disabled state tokens |
745
+
746
+ ### 12.2 — Field Component Tokens
747
+
748
+ | Token pattern | Example | Description |
749
+ |---------------|---------|-------------|
750
+ | `--field-text-{role}` | `--field-text-prominent`, `--field-text-error` | Field text colors (prominent, subtle, disabled, success, error) |
751
+ | `--field-outline-bg-{state}` | `--field-outline-bg-focus` | Outline variant backgrounds |
752
+ | `--field-outline-border-{state}` | `--field-outline-border-error` | Outline variant borders |
753
+ | `--field-fill-bg-{state}` | `--field-fill-bg-hover` | Fill variant backgrounds |
754
+ | `--field-fill-bg-{status}-{state}` | `--field-fill-bg-error-default` | Status-specific fill backgrounds |
755
+
756
+ ### 12.3 — Tab Component Tokens
757
+
758
+ | Token | Description |
759
+ |-------|-------------|
760
+ | `--tab-text-default` | Default (unselected) tab text |
761
+ | `--tab-text-selected` | Selected tab text |
762
+ | `--tab-text-disabled` | Disabled tab text |
763
+ | `--tab-bg-hover` | Tab hover background |
764
+ | `--tab-bg-pressed` | Tab pressed background |
765
+ | `--tab-border-selected` | Selected tab indicator/border |
766
+
767
+ ### 12.4 — Tag Component Tokens
768
+
769
+ | Token | Description |
770
+ |-------|-------------|
771
+ | `--badge-text-default` | Tag text color (always slate-50 / white) |
772
+ | `--badge-bg-number` | Number tag background (red) |
773
+ | `--badge-bg-status-{color}` | Status dot colors: red, yellow, green, blue |
774
+
775
+ ### 12.5 — Other Component Token Namespaces
776
+
777
+ | Namespace | Components covered |
778
+ |-----------|-------------------|
779
+ | `--chip-*` | Chip text, border, bg, icon (prominent, disabled, selected states) |
780
+ | `--tag-*` | Tag text, icon, outline-border, fill-bg (neutral, red, yellow, green, blue) |
781
+ | `--code-input-*` | Code/OTP input fill bg, border, text (default, hover, focus, success, error) |
782
+ | `--dropdown-field-*` | Dropdown field text, bg, border (outline + fill variants) |
783
+ | `--list-item-*` | List item text, border, bg (primary + secondary variants with all states) |
784
+ | `--search-field-*` | Search field text, icon, bg, border (outline + fill variants) |
785
+ | `--segmented-control-*` | Segmented control text, icon, container bg, segment bg |
786
+ | `--tooltip-*` | Tooltip text, bg (default + error) |
787
+ | `--snackbar-*` | Snackbar bg, text, icon (default + fail) |
788
+ | `--notification-*` | Notification title, description, icon, bg (banner + item variants) |
789
+ | `--pagination-*` | Pagination bg, border, text (number + dot variants) |
790
+ | `--progress-bar-*` | Progress bar track + progress bg (normal, inverse, static-light, static-dark × default, green, red, yellow, blue) |
791
+ | `--bottom-sheet-*` | Bottom sheet bg, handle bar color (`black-alpha-300` light / `white-alpha-300` dark), handle container bg, handle pressed state. Handle bar: 4px × 40px pill, 32px container. |
792
+ | `--section-message-*` | Section message title, description, icon, fill bg (default, danger, information, success, warning) |
793
+ | `--link-*` | Link primary + secondary colors (default, disabled × normal, inverse, static variants) |
794
+ | `--marker-*` | Marker asterisk text, optional text |
795
+ | `--loading-spinner-*` | Spinner bg color |
796
+ | `--menu-*` | Menu background, border |
797
+
798
+ ---
799
+
800
+ ## 13 — Base Layer & Body Defaults
801
+
802
+ The design system sets these base defaults:
803
+
804
+ ```css
805
+ @layer base {
806
+ * {
807
+ border-color: var(--color-default);
808
+ outline-color: color-mix(in oklch, var(--color-ring) 50%, transparent);
809
+ }
810
+
811
+ body {
812
+ @apply bg-primary-surface text-prominent font-sans antialiased;
813
+ }
814
+ }
815
+ ```
816
+
817
+ > All elements default to `border-default` for border color. Body uses `bg-primary-surface` (white in light, slate-1300 in dark) and `text-prominent` (slate-1200 in light, slate-50 in dark).