@deriv-ds/design-intelligence-layer 0.6.1 → 0.6.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.
@@ -123,6 +123,8 @@ Rule: don't add `flex-1` to the body unless `get_design_context` confirms the fo
123
123
 
124
124
  The package ships whole page sections as blocks. **Before you build any region from primitives, match it against the block catalog.** A region that corresponds to a shipped block must be *imported*, not mocked up — re-implementing a navbar, hero, or card the package already exports is a defect, even if your version "looks right".
125
125
 
126
+ **Step 0 — classify the page type FIRST, then apply the App Shell defaults.** Before matching individual regions, decide what kind of page this is (home/dashboard, trading, form/settings, marketing/landing, auth, standalone). Home/dashboard pages have a **mandatory default app shell** — a header block + `Navbar` — that must be included *even when the prompt or frame never mentions them* (see [App Shell defaults](#app-shell-defaults--homedashboard-pages) below). This is the fix for the most common defect: a home page rendered with no top header and no bottom nav. Match on **intent and implication, not just explicit mentions** — a "home page" implies the shell whether or not the word "navbar" appears.
127
+
126
128
  **Procedure — for every distinct region of the page (header strip, nav, hero/balance area, banner, highlight cards, trading cards, action buttons, empty state, referral panel, footer/section wrapper):**
127
129
 
128
130
  1. **Identify the region's intent** — not its pixels. "Top nav with menu items", "balance/total-assets header", "promo banner card", "row of highlight cards", "account card with balance + actions", "empty trading list", "referral invite panel". The intent is what you match on.
@@ -142,6 +144,48 @@ Record every region's outcome (`block: <Name>` or `composed`) — this feeds the
142
144
 
143
145
  ---
144
146
 
147
+ ## App Shell defaults — home/dashboard pages
148
+
149
+ **Home and dashboard pages ship with an app shell by default — a header block on top and a `Navbar`.** These regions are *implied* by the page type, so the Block Matching gate must inject them even when the user's prompt or the Figma frame never names them. A home page rendered as a bare content column with no top header and no bottom nav is a defect — this section exists to kill it.
150
+
151
+ **When it applies:** the page is classified (gate Step 0) as **home** or **dashboard** — prompts like "home page", "dashboard", "wallet home", "main app screen", or a Figma frame that is clearly the app home/landing-after-login. It does NOT auto-apply to marketing/landing pages, auth screens, or explicitly standalone screens (a single card, a success screen, one onboarding step).
152
+
153
+ **What the shell is:**
154
+
155
+ | Shell region | Block | Notes |
156
+ |---|---|---|
157
+ | Top header | `HeaderAppHome` (home) or `HeaderApp` (in-app sub-page) | Match to the frame's header if one is shown; **inject `HeaderAppHome` if the design omits it** on a home/dashboard page. |
158
+ | Navigation | `Navbar` (responsive) | Renders `NavDesktopSidebar` ≥768px and `NavMobileBottomBar` <768px automatically. Wire `activeId` to the current page. |
159
+
160
+ **Rules:**
161
+ - Include the shell by default on home/dashboard builds. **Skip it only** when the user explicitly says "no nav / no header / just the content", or the page is clearly not a home/dashboard.
162
+ - The shell counts as matched blocks — read their real props (`HeaderAppHomeProps`, `Navbar`'s `activeId`/`badges`/`onNavChange`) from `dist/index.d.ts` before wiring, per gate step 4.
163
+ - Record the shell decision in the Build Report's block audit — either `block: HeaderAppHome` + `block: Navbar`, or `omitted (reason)`.
164
+
165
+ ---
166
+
167
+ ## Responsive coverage — every build ships mobile AND desktop
168
+
169
+ **Every page build must render correctly at BOTH a mobile viewport (~375px) and a desktop viewport (~1440px).** A mobile-only render (the second common defect) is not "done". Blocks are designed for this: `Navbar` is responsive internally, and heroes/trading blocks ship as mobile/desktop pairs.
170
+
171
+ **How to cover both viewports:**
172
+ - **Responsive blocks** (`Navbar`, `Section`, and any block taking a `layout` prop) work at both widths out of the box — use them directly.
173
+ - **Paired blocks** (mobile/desktop hero + trading variants) have no single responsive export — render BOTH and switch on the package's **768px breakpoint** using visibility utilities, mirroring how `Navbar` picks its variant:
174
+
175
+ ```tsx
176
+ {/* mobile hero <768px */}
177
+ <div className="md:hidden"><HeroMobileHomeTotalAssets /></div>
178
+ {/* desktop hero ≥768px */}
179
+ <div className="hidden md:block"><HeroDesktopHomeWithBalance /></div>
180
+ ```
181
+
182
+ - The mobile/desktop pairing table lives in [references/components-and-tokens.md](references/components-and-tokens.md) (Blocks section) — resolve BOTH variants of every paired region before writing JSX.
183
+ - **Only render a single viewport** when the user explicitly restricts scope ("mobile only", "just the desktop view").
184
+
185
+ **Mode 4 (Figma) responsive rule:** the provided frame is the 1:1 ground truth **at its own viewport**. The *other* viewport is generated by default from the corresponding desktop/mobile block variants and brand-consistent layout — flagged in the Build Report as "generated, no frame provided". If the user supplies frames for both viewports, each is its own 1:1 replica. The visual-diff loop (4.4) runs against the frame's viewport; the generated viewport gets the runtime responsive checks (Final Checklist), not a pixel diff.
186
+
187
+ ---
188
+
145
189
  ## Mode 1 — Router
146
190
 
147
191
  When invoked, classify the user's message:
@@ -220,11 +264,13 @@ If the user immediately follows with a build request, chain into the matching mo
220
264
  2. Read `node_modules/@deriv-ds/design-intelligence-layer/guides/rules/design-system-consuming-project.mdc`.
221
265
  3. Read [references/components-and-tokens.md](references/components-and-tokens.md) for the canonical component list and token cheatsheet.
222
266
  4. **Run Preflight** (above) to clean any leftover Geist/font/`:root` scaffold defects.
223
- 5. **Run the Block Matching gate** (above) over the page's regions FIRST any region the prompt names or implies that maps to a block (nav/navbar, hero/balance header, banner, highlights, explore, trading cards, action buttons, empty state, referral, header) is imported as that block, not mocked up. Only the regions with no block match proceed to primitive composition.
224
- 6. Map the remaining (non-block) regions to components. For each required UI element, confirm it's on the list (HARD RULE 1). Anything missing compose from package components + tokens, flag in the Build Report.
225
- 7. Sketch the layout structurally (flex/grid utilities are fine); if the page has a bottom action bar, use the **Page layout scaffold** above. Then drop in matched blocks and package components. Every colour/radius/font value goes through the **Token Resolution Loop**. Page background → `bg-card`, primary text → `text-prominent` (never `bg-prominent` as a surface). Typography → `heading-*`/`body-*` classes (NOT `text-heading-*`).
226
- 8. Write copy in a voice aligned with `deriv-brand-voice.md`.
227
- 9. Run the Final Checklist below.
267
+ 5. **Classify the page type** (gate Step 0)home/dashboard, trading, form/settings, marketing, auth, standalone. If home/dashboard, the **App Shell defaults** apply: include `HeaderAppHome` (or `HeaderApp`) + `Navbar` by default, even though the prompt didn't name them.
268
+ 6. **Run the Block Matching gate** (above) over the page's regions — any region the prompt names OR implies that maps to a block (app shell header + nav, hero/balance header, banner, highlights, explore, trading cards, action buttons, empty state, referral) is imported as that block, not mocked up. Only the regions with no block match proceed to primitive composition.
269
+ 7. Map the remaining (non-block) regions to components. For each required UI element, confirm it's on the list (HARD RULE 1). Anything missing compose from package components + tokens, flag in the Build Report.
270
+ 8. Sketch the layout structurally (flex/grid utilities are fine); if the page has a bottom action bar, use the **Page layout scaffold** above. Then drop in matched blocks and package components. Every colour/radius/font value goes through the **Token Resolution Loop**. Page background → `bg-card`, primary text → `text-prominent` (never `bg-prominent` as a surface). Typography → `heading-*`/`body-*` classes (NOT `text-heading-*`).
271
+ 9. **Cover both viewports** (see [Responsive coverage](#responsive-coverage--every-build-ships-mobile-and-desktop)) — use responsive blocks directly and render both variants of any paired block behind `md:hidden` / `hidden md:block`, unless the user restricted scope to one viewport.
272
+ 10. Write copy in a voice aligned with `deriv-brand-voice.md`.
273
+ 11. Run the Final Checklist below.
228
274
 
229
275
  ---
230
276
 
@@ -272,6 +318,8 @@ Build a table with one row per **visible node** from `get_metadata` (not just "k
272
318
 
273
319
  Generate the page from the contract — the contract is the spec, the screenshot is the ground truth. Register all created tokens in `globals.css` first, then write JSX using only generated classes and package components.
274
320
 
321
+ **App shell + responsive expansion:** if the frame is a home/dashboard page, apply the **App Shell defaults** (inject `HeaderAppHome`/`HeaderApp` + `Navbar` even if the frame omits them). Then expand to the viewport the frame does NOT cover per the **Mode 4 responsive rule** — swap paired blocks to their opposite variant (`HeroMobile*` ⇄ `HeroDesktop*`) behind `md:hidden` / `hidden md:block`, and let responsive blocks (`Navbar`, `Section`) handle themselves. The generated viewport is brand-consistent layout, not a pixel replica — flag it in the Build Report.
322
+
275
323
  ### 4.4 Visual-diff loop — iterate until it matches
276
324
 
277
325
  "Renders without errors" proves nothing about parity. With the dev server running:
@@ -337,6 +385,15 @@ The runtime check below is the backstop: a token-intended element whose computed
337
385
 
338
386
  **Blocks matched, not mocked** — every page region went through the Block Matching gate. No region hand-rolls a navbar, hero, card, banner, action-button cluster, empty state, or referral panel that the package already ships as a block. A region built from primitives must have NO matching block in the catalog — confirm before declaring done; this is recorded in the Build Report's block audit.
339
387
 
388
+ **App shell present (home/dashboard)** — if the page is a home/dashboard build, confirm the default shell is there: a header block (`HeaderAppHome`/`HeaderApp`) at the top AND `Navbar`. A home page with no header or no nav is a defect unless the user explicitly opted out (record the opt-out in the block audit).
389
+
390
+ **Responsive verification** — the build must work at BOTH viewports, not just mobile. With the preview running, `preview_resize` to **375px** and to **1440px** and confirm at each:
391
+ - At **1440px**: `Navbar` renders the **desktop sidebar** (not the mobile bottom bar); no mobile-only block is stretched full-width; paired blocks show their desktop variant.
392
+ - At **375px**: `Navbar` renders the **bottom bar**; paired blocks show their mobile variant; no horizontal overflow.
393
+ - The header block (on home/dashboard) is present at both widths.
394
+ - (Mode 4) the frame's own viewport still matches the visual-diff loop result; the generated viewport is laid out cleanly.
395
+ A single-viewport render is a defect unless the user restricted scope.
396
+
340
397
  **Import audit** — every import in the diff comes from `@deriv-ds/design-intelligence-layer`, including icons via `<Icon />`. No `lucide-react` or other icon lib. No `@/components/ui/*`. No `@deriv-com/quill-ui*`. Every imported name exists in `dist/index.d.ts` (beware `Tabs`/`Notification`/`Chart`/`Resizable`/`Direction` — see the hallucinated-imports table).
341
398
 
342
399
  **Created tokens registered** — every class generated by the Token Resolution Loop has its `@theme inline` registration in `globals.css`, named by intent, listed for the Build Report.
@@ -412,25 +469,28 @@ The build is not "done" until the runtime checks pass **and** you present this r
412
469
 
413
470
  **Hallucinated classes must be fixed before this report is shown** — the table is proof they were caught and corrected, not a to-do list.
414
471
 
415
- 3. **Block audit (Block Matching gate)** — one row per page region, proving each was matched against the block catalog and either imported as a block or consciously composed. A region that *should* have used a block but was hand-rolled is a defect — fix before showing this report.
472
+ 3. **Block audit (Block Matching gate)** — one row per page region, proving each was matched against the block catalog and either imported as a block or consciously composed. A region that *should* have used a block but was hand-rolled is a defect — fix before showing this report. For home/dashboard pages, the **app shell rows (header + nav) are mandatory** — show them as imported blocks or as an explicit user opt-out.
416
473
 
417
474
  | Region | Outcome | Evidence / reason |
418
475
  |---|---|---|
419
- | Top nav | `block: Navbar` | export in dist/index.d.ts; Code Connect map |
420
- | Balance header | `block: HeroDesktopHomeWithBalance` | matched home balance hero |
476
+ | App header | `block: HeaderAppHome` | app shell default (home page); export in dist/index.d.ts |
477
+ | Navigation | `block: Navbar` | app shell default; responsive sidebar/bottom-bar; export in dist/index.d.ts |
478
+ | Balance header | `block: HeroMobileHomeTotalAssets` + `HeroDesktopHomeWithBalance` | paired mobile/desktop, `md:hidden` switch |
421
479
  | Promo strip | `composed` | no block matches a 2-up promo grid — flagged |
422
480
 
423
- 4. **Created tokens** — every `@theme inline` registration added to `globals.css`, with which loop step produced it (semantic var / primitive / exact value) and whether it's dark-mode-aware.
481
+ 4. **Responsive coverage** — state which viewports were built and verified (mobile ~375px, desktop ~1440px), which regions used responsive blocks vs paired mobile/desktop variants, and in Mode 4 — which viewport was a 1:1 frame replica vs generated from the opposite block variant. A build verified at only one viewport must say so and why (explicit user scope).
482
+
483
+ 5. **Created tokens** — every `@theme inline` registration added to `globals.css`, with which loop step produced it (semantic var / primitive / exact value) and whether it's dark-mode-aware.
424
484
 
425
- 5. **Fidelity results (Mode 4)** — visual-diff loop: how many iterations, what was fixed each pass. Then the contract: every row ✅ matched or listed as a deviation with the reason. State explicitly: zero invented elements, zero omitted elements, copy verbatim.
485
+ 6. **Fidelity results (Mode 4)** — visual-diff loop: how many iterations, what was fixed each pass. Then the contract: every row ✅ matched or listed as a deviation with the reason. State explicitly: zero invented elements, zero omitted elements, copy verbatim.
426
486
 
427
- 6. **⚠ Flagged** — composed (non-package) elements, token substitutions, assumptions made. If nothing was flagged, say so explicitly.
487
+ 7. **⚠ Flagged** — composed (non-package) elements, token substitutions, assumptions made. If nothing was flagged, say so explicitly.
428
488
 
429
- 7. **Intentional DS behaviours** — surface things that look like bugs but aren't (e.g. the coral focus ring on inputs), so the user doesn't try to "fix" them.
489
+ 8. **Intentional DS behaviours** — surface things that look like bugs but aren't (e.g. the coral focus ring on inputs), so the user doesn't try to "fix" them.
430
490
 
431
- 8. **Needs your review** — anything uncertain or that you couldn't verify (e.g. preview tools unavailable), plus any critic violations still unresolved after 3 rounds.
491
+ 9. **Needs your review** — anything uncertain or that you couldn't verify (e.g. preview tools unavailable), plus any critic violations still unresolved after 3 rounds.
432
492
 
433
- 9. **Independent audit** — the critic verdict: how many rounds ran, and what it caught and you fixed (hallucinated imports, unregistered tokens, out-of-scope edits). If the critic could not run (no subagent + you did the fresh pass yourself), say so.
493
+ 10. **Independent audit** — the critic verdict: how many rounds ran, and what it caught and you fixed (hallucinated imports, unregistered tokens, out-of-scope edits). If the critic could not run (no subagent + you did the fresh pass yourself), say so.
434
494
 
435
495
  ---
436
496
 
@@ -1,6 +1,6 @@
1
1
  # Components & tokens — `@deriv-ds/design-intelligence-layer`
2
2
 
3
- This is the **authoritative cheatsheet** for building in a consuming project, verified against the published package (v0.6.1). If something isn't here and isn't in the package's `dist/index.d.ts`, it doesn't exist — resolve it with the Token Resolution Loop (for styles) or compose it from real components (for UI). Never invent an import or a class. (The `npm run check:skill-catalog` script in the source repo guards this list against the package's real exports.)
3
+ This is the **authoritative cheatsheet** for building in a consuming project, verified against the published package (v0.6.2). If something isn't here and isn't in the package's `dist/index.d.ts`, it doesn't exist — resolve it with the Token Resolution Loop (for styles) or compose it from real components (for UI). Never invent an import or a class. (The `npm run check:skill-catalog` script in the source repo guards this list against the package's real exports.)
4
4
 
5
5
  > **Verification targets** (the package ships compiled — there is NO `src/index.ts`):
6
6
  > - Components → `node_modules/@deriv-ds/design-intelligence-layer/dist/index.d.ts`
@@ -125,9 +125,10 @@ grep -w "<ComponentName>" node_modules/@deriv-ds/design-intelligence-layer/dist/
125
125
 
126
126
  These files exist under `components/ui/` in the source repo but are **not** re-exported from the package, so they are not importable by consumers. Treat them as nonexistent and compose the equivalent from real exports:
127
127
 
128
- - `navigation-menu` (`NavigationMenu*`) — use `Navbar` / the nav blocks, or compose with `DropdownMenu` / `Sidebar`.
129
128
  - `theme-toggle` (`ThemeToggle`) — compose from `Button` + `Switch` + `<Icon />`.
130
129
 
130
+ > `NavigationMenu*` (`NavigationMenu`, `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`, `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuIndicator`, `NavigationMenuViewport`) **is now a real export** — prefer the `Navbar` / nav blocks for app navigation, but the primitive is available when you need a custom menu. Verify with `grep -w NavigationMenu node_modules/@deriv-ds/design-intelligence-layer/dist/index.d.ts` against the installed version.
131
+
131
132
  ### Secondary exports (real, but rarely imported directly)
132
133
 
133
134
  Exported and valid, but niche — only reach for them when you specifically need them: `ChartStyle` (internal to the Chart family), `IconSizeContext` (advanced `<Icon />` sizing). Most builds never touch these.
@@ -200,25 +201,26 @@ variable `component/app/background/normal` (`#ffffff`) → **`bg-card`**.
200
201
  | `text-primary` | brand text — coral | #FF444F |
201
202
  | `text-warning` | warning text | #C47D00 |
202
203
  | `text-info` | informational text | #0777C4 |
204
+ | `text-success` | success text — green | #007A22 light / #4DBC6B dark |
205
+ | `text-error` | error / danger text — red | #C40000 light / #FF4D4D dark |
206
+ | `text-on-primary` / `text-on-success` / `text-on-error` / `text-on-warning` / `text-on-info` | foreground for text/icons **on a solid coloured surface** (`bg-primary`, `bg-success`, …) — always-legible static-inverse | #FFFFFF |
203
207
 
204
- ### Status / profit-loss colours — NOT built in, register them
208
+ ### Status colours — now built in
205
209
 
206
- **`text-success`, `text-error`, `bg-success`, `bg-error`, `text-win`, `text-loss` do NOT exist as
207
- utilities** there is no `--color-success` / `--color-error` in the theme. The package DOES ship
208
- the underlying **theme-aware variables** (they flip automatically in dark mode). Register them once
209
- in the consuming project's `globals.css` and then use the generated classes:
210
+ `text-success`, `text-error`, `text-warning`, `text-info` are **shipped utilities** (theme-aware —
211
+ they flip automatically in dark mode). Their solid `bg-*` / `border-*` / `ring-*` counterparts also
212
+ generate (`bg-success`, `bg-error`, `border-success`, …) and pair with the `text-on-*` foregrounds
213
+ above. For a **subtle opaque status tint** that reads identically on any background (cards, chips,
214
+ banners) use the surface utilities:
210
215
 
211
- ```css
212
- /* globals.css — after the DS imports */
213
- @theme inline {
214
- --color-success: var(--text-success-default); /* #007A22 light / #4DBC6B dark text-success */
215
- --color-error: var(--text-error-default); /* #C40000 light / #FF4D4D dark → text-error */
216
- --color-success-fill: var(--background-success-default); /* green tint → bg-success-fill */
217
- --color-error-fill: var(--background-error-default); /* red tint → bg-error-fill */
218
- }
219
- ```
216
+ | Class | Use |
217
+ |---|---|
218
+ | `bg-success-surface` / `bg-error-surface` / `bg-warning-surface` / `bg-info-surface` | opaque status tint background (color-mix — no bleed-through on coloured surfaces) |
219
+ | `bg-success/10`, `bg-error/16`, | alpha status tint (fine on the page canvas; can bleed on coloured surfaces) |
220
220
 
221
- This is the canonical Token Creation pattern (below) never use a raw green/red hex or `text-green-600`.
221
+ Only **game-specific profit/loss** utilities (`text-win`, `text-loss`, `bg-win`, `bg-loss`) are NOT
222
+ shipped — register those with the Token Creation pattern below (map to `--text-success-default` /
223
+ `--text-error-default`). Never use a raw green/red hex or `text-green-600`.
222
224
 
223
225
  ### Borders & ring
224
226
 
@@ -232,7 +234,7 @@ This is the canonical Token Creation pattern (below) — never use a raw green/r
232
234
  | `ring-ring` | focus ring — **coral** | #FF444F |
233
235
 
234
236
  > `border-border` is deprecated — use `border-border-subtle` or `border-border-prominent`.
235
- > `border-success` / `border-error` do NOT exist register them like the status colours above if needed.
237
+ > `border-success` / `border-error` now generate (solid status colour) alongside `bg-success` / `bg-error`.
236
238
 
237
239
  ### Radius
238
240
 
@@ -247,10 +249,9 @@ definition, so they produce **no CSS** — the element silently inherits a wrong
247
249
 
248
250
  | ❌ Doesn't exist | ✅ Real fix |
249
251
  |---|---|
250
- | `text-on-prominent` | `text-prominent` |
252
+ | `text-on-prominent` | `text-prominent` (`text-on-prominent` is always-white — for dark/coloured surfaces only) |
251
253
  | `text-on-subtle` | `text-subtle` |
252
- | `text-success` / `bg-success` / `text-error` / `bg-error` | register first (see Status colours above), then use |
253
- | `bg-loss` / `text-loss` / `bg-win` / `text-win` | registered `text-error` / `text-success` |
254
+ | `bg-loss` / `text-loss` / `bg-win` / `text-win` | register first (game profit/loss — see Status colours above), then use |
254
255
  | `bg-prominent` (as page bg) | `bg-card` |
255
256
  | `bg-subtle` (as page bg) | `bg-card` / `bg-primary-canvas` |
256
257
  | `text-heading-h1`, `text-body-md`, `text-heading-mega` | `heading-h1`, `body-md`, `heading-hero` (see Typography) |
@@ -396,7 +397,33 @@ The **"matches when"** column is what the Block Matching gate matches on — int
396
397
  | **Referral** | `Referral` | refer-a-friend / invite panel |
397
398
  | **Section** | `Section` | eyebrow tag + title + control cluster + segmented control wrapping a content slot (children) |
398
399
 
399
- Most heroes/trading blocks also export a `*Skeleton` variant for loading states. Pick the **mobile vs desktop** variant from the target viewport.
400
+ Most heroes/trading blocks also export a `*Skeleton` variant for loading states.
401
+
402
+ ### Default app shell — home/dashboard pages
403
+
404
+ **Home and dashboard pages ship a default app shell even when the prompt/frame never mentions it:** a header block on top + `Navbar`. The build skill's Block Matching gate injects these automatically (see SKILL.md → *App Shell defaults*). Skip only on explicit user opt-out, or for marketing/auth/standalone screens.
405
+
406
+ | Shell region | Block | Wire |
407
+ |---|---|---|
408
+ | Top header | `HeaderAppHome` (home) / `HeaderApp` (in-app sub-page) | avatar, notification badge, actions |
409
+ | Navigation | `Navbar` (responsive) | `activeId`, `badges`, `onNavChange` |
410
+
411
+ ### Mobile / desktop variant pairing — render BOTH viewports
412
+
413
+ Blocks target **both** a mobile (~375px) and desktop (~1440px) viewport. Some blocks are responsive on their own; others ship as an explicit mobile/desktop pair with **no** single responsive export — render BOTH and switch on the **768px** breakpoint with `md:hidden` (mobile) / `hidden md:block` (desktop), mirroring how `Navbar` picks its variant internally. Resolve BOTH variants of every paired region before writing JSX. Render a single viewport only when the user restricts scope.
414
+
415
+ | Region | Mobile | Desktop | Responsive? |
416
+ |---|---|---|---|
417
+ | Navigation | `NavMobileBottomBar` | `NavDesktopSidebar` | **Yes — use `Navbar`** (auto-switches) |
418
+ | Hero — home (title) | `HeroMobileHomeTitle` | `HeroDesktopHomeOnboarding` | No — pair + `md:` switch |
419
+ | Hero — home (balance) | `HeroMobileHomeTotalAssets` | `HeroDesktopHomeWithBalance` | No — pair + `md:` switch |
420
+ | Hero — main | `HeroMobileMain` | `HeroDesktopMain` | No — pair + `md:` switch |
421
+ | Hero — secondary | `HeroMobileSecondary` | `HeroDesktopSecondary` | No — pair + `md:` switch |
422
+ | Hero — transaction | `HeroMobileTransaction` | *(reuse mobile / compose)* | No |
423
+ | Section | `Section` | `Section` | Yes — same export |
424
+ | Trading / home cards | responsive via `layout` prop where present | — | Prefer `layout` prop |
425
+
426
+ New blocks favour a single `layout="mobile" \| "desktop"` prop over separate exports — check the block's props in `dist/index.d.ts` before assuming a pair.
400
427
 
401
428
  ---
402
429
 
package/AGENTS.md CHANGED
@@ -10,7 +10,7 @@ Before building any landing page, product screen, game view, or feature UI, you
10
10
 
11
11
  **Design principles** — the decision framework for every layout, hierarchy, motion, copy, and component choice:
12
12
  ```
13
- node_modules/@deriv-ds/design-intelligence-layer/guides/design-principles/trading-game-design-principles.md
13
+ node_modules/@deriv-ds/design-intelligence-layer/guides/design-principles/quill-design-principles.md
14
14
  ```
15
15
 
16
16
  **Accessibility standards** — the inclusion standard every screen must meet (WCAG 2.1 AA):
@@ -75,7 +75,7 @@ Re-copy both after every version bump so the shims match the installed release.
75
75
  ## Step 3 — Core rules summary
76
76
 
77
77
  1. **Check before building** — if a component exists in `@deriv-ds/design-intelligence-layer`, import it. Never re-implement it.
78
- 2. **Tokens only** — use semantic token classes (`bg-prominent`, `text-on-prominent`, `border-border`, etc.). Never hardcode hex values, raw Tailwind palette colors, or CSS variables.
78
+ 2. **Tokens only** — use semantic token classes (`bg-primary-canvas`, `text-prominent`, `border-default`, etc.). Never hardcode hex values, raw Tailwind palette colors, or CSS variables.
79
79
  3. **Design principles and accessibility first** — every screen must reflect the 8 design principles and meet the accessibility standards (WCAG 2.1 AA). Run both checklists before shipping.
80
80
  4. **No separate installs** — do not install `tailwindcss` or other bundled dependencies separately. Never install or import `lucide-react` or any other icon library.
81
81
  5. **Icons** — use the exported `<Icon />` component (`@deriv/quill-icons`): `<Icon name="bell" weight="bold" />`. Three weights: `regular` (unselected nav, subtle), `bold` (default), `fill` (selected nav, strong actions). Full catalog of names, weights, and intent → icon mappings: `guides/design-system-guide/icon-reference.md`. At runtime, `ICON_NAMES` and `iconAvailableWeights(name)` are exported from the package.
@@ -102,7 +102,7 @@ Re-copy both after every version bump so the shims match the installed release.
102
102
  ## Reference
103
103
 
104
104
  - Full token + component reference: `node_modules/@deriv-ds/design-intelligence-layer/README.md`
105
- - Design principles: `node_modules/@deriv-ds/design-intelligence-layer/guides/design-principles/trading-game-design-principles.md`
105
+ - Design principles: `node_modules/@deriv-ds/design-intelligence-layer/guides/design-principles/quill-design-principles.md`
106
106
  - Accessibility standards: `node_modules/@deriv-ds/design-intelligence-layer/guides/accessibility-standards/trading-game-accessibility-standards.md`
107
107
  - Personas: `node_modules/@deriv-ds/design-intelligence-layer/guides/personas/trading-game-player-field-guide.md`
108
108
  - Brand voice: `node_modules/@deriv-ds/design-intelligence-layer/guides/brand-voice/deriv-brand-voice.md`
package/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.2]
11
+
12
+ ### Fixed
13
+ - **Focus ring contrast (WCAG 1.4.11 / 2.4.7)** — the base focus outline was rendered at 50% alpha and the `--ring` token (coral-700) fell well under the 3:1 minimum once composited. `--ring` is now blue-800 (`#1789e1`), rendered at full opacity, and every component's `focus-visible` ring is standardized to `ring-2 ring-ring ring-offset-2 ring-offset-primary-surface` — verified at ≥3:1 against both light and dark surfaces, and against coral primary buttons via the offset gap. (#38)
14
+ - **`prefers-reduced-motion` support** — added a global `@media (prefers-reduced-motion: reduce)` rule that collapses animation/transition durations and disables smooth scrolling package-wide. (#38)
15
+ - **Stale agent-facing docs** — corrected `AGENTS.md`'s design-principles path (was pointing at a non-existent file) and refreshed ring-color references in the consuming-project rules and design-system guides to match the shipped coral/blue theme. (#38)
16
+
10
17
  ## [0.6.1]
11
18
 
12
19
  ### Note
package/README.md CHANGED
@@ -87,7 +87,7 @@ Icons are provided by **`@deriv/quill-icons`** via the bundled `Icon` component
87
87
  import { Icon } from "@deriv-ds/design-intelligence-layer"
88
88
 
89
89
  <Icon name="bell" />
90
- <Icon name="circle-check" weight="fill" className="text-success" />
90
+ <Icon name="circle-check" weight="fill" className="text-[var(--text-success-default)]" />
91
91
  ```
92
92
 
93
93
  The full icon catalog is at `node_modules/@deriv-ds/design-intelligence-layer/guides/design-system-guide/icon-reference.md`.
@@ -146,6 +146,7 @@ The full icon catalog is at `node_modules/@deriv-ds/design-intelligence-layer/gu
146
146
  | Link | `Link` |
147
147
  | Loading Spinner | `LoadingSpinner` |
148
148
  | Native Select | `NativeSelect, NativeSelectOptGroup, NativeSelectOption` |
149
+ | Navigation Menu | `NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, ...` |
149
150
  | Notification | `NotificationBanner, NotificationItem, NotificationDivider` |
150
151
  | OTP Field | `CodeInput, CodeInputGroup, CodeInputSlot, CodeInputSeparator` |
151
152
  | Pagination | `Pagination, PaginationContent, PaginationLink, ...` |
@@ -164,7 +165,7 @@ The full icon catalog is at `node_modules/@deriv-ds/design-intelligence-layer/gu
164
165
  | Sidebar | `Sidebar, SidebarProvider, SidebarMenu, SidebarMenuItem, ...` |
165
166
  | Skeleton | `Skeleton` |
166
167
  | Slider | `Slider` |
167
- | Snackbar | `Snackbar` |
168
+ | Snackbar | `Snackbar` (+ imperative `toast` — re-exported from sonner) |
168
169
  | Spinner | `Spinner` |
169
170
  | Stepper | `Stepper` |
170
171
  | Switch | `Switch` |
@@ -190,18 +191,23 @@ Wire each block's props/children to your real content — don't re-implement the
190
191
 
191
192
  ### Available blocks
192
193
 
193
- | Block | Import(s) |
194
- |---|---|
195
- | NavBar | `Navbar` (responsive) · `NavMobileBottomBar` · `NavDesktopSidebar` |
196
- | Header | `HeaderApp` · `HeaderAppHome` · `HeaderBranding` |
197
- | Hero — home | `HeroMobileHomeTitle` · `HeroMobileHomeTotalAssets` · `HeroDesktopHomeOnboarding` · `HeroDesktopHomeWithBalance` |
198
- | Hero — main / secondary / transaction | `HeroMobileMain` · `HeroDesktopMain` · `HeroMobileSecondary` · `HeroDesktopSecondary` · `HeroMobileTransaction` |
199
- | Hero action button | `HeroActionButton` |
200
- | Home — banner / highlights / explore | `HomeBanner` · `BannerCard` · `HomeHighlights` · `HomeHighlightCard` · `HomeExploreDeriv` |
201
- | Trading | `TradingAccountCard` · `TradingActionButtonsPrimary` · `TradingActionButtonsSecondary` · `TradingEmpty` |
202
- | Account / feedback | `AccountActivatedCard` · `FeedbackSuccessScreen` · `FeedbackTradeWithAccounts` · `FeedbackTransferSuggestion` |
203
- | Referral | `Referral` |
204
- | Section | `Section` |
194
+ | Block | Variants / exports | Description |
195
+ |---|---|---|
196
+ | NavBar | `Navbar` (responsive) · `NavMobileBottomBar` · `NavDesktopSidebar` — props `activeId`, `badges`, `onNavChange` | App navigation. `Navbar` auto-switches: sidebar ≥768px, bottom tab bar <768px. |
197
+ | Header | `HeaderApp` · `HeaderAppHome` · `HeaderBranding` | App top header. Home (avatar + notifications + Ask Amy), in-app sub-page (back, tabs, actions), or branding bar (language + actions). |
198
+ | Hero — home | `HeroMobileHomeTitle` · `HeroMobileHomeTotalAssets` · `HeroDesktopHomeOnboarding` · `HeroDesktopHomeWithBalance` (+ `*Skeleton`) | Home top area: greeting/title, total-assets balance, or onboarding hero. Mobile/desktop pair. |
199
+ | Hero — main / secondary / transaction | `HeroMobileMain` · `HeroDesktopMain` · `HeroMobileSecondary` · `HeroDesktopSecondary` · `HeroMobileTransaction` (+ `*Skeleton`) | Primary/secondary page hero with account tabs + action buttons; transaction details card. |
200
+ | Hero action button | `HeroActionButton` | The prominent circular action button used inside heroes. |
201
+ | Home — banner | `HomeBanner` · `BannerCard` props `banner`, `layout`, `onClose` | Promo / announcement banner (carousel of cards, or a single dismissible card). |
202
+ | Home — highlights | `HomeHighlights` · `HomeHighlightCard` prop `cards` | Row/grid of highlight cards. |
203
+ | Home explore | `HomeExploreDeriv` | "Explore Deriv" discovery section. |
204
+ | Trading — account card | `TradingAccountCard` — prop `layout` | Account card with balance + actions. |
205
+ | Trading — action buttons | `TradingActionButtonsPrimary` · `TradingActionButtonsSecondary` (+ `*Skeleton`) | Deposit / withdraw / transfer action button cluster. |
206
+ | Trading — empty | `TradingEmpty` (+ `TradingEmptySkeleton`) | Empty trading list / no-accounts state. |
207
+ | Account activated | `AccountActivatedCard` | "Account activated" confirmation card. |
208
+ | Feedback / success | `FeedbackSuccessScreen` · `FeedbackTradeWithAccounts` · `FeedbackTransferSuggestion` | Post-action success / confirmation screens. |
209
+ | Referral | `Referral` — props `metrics`, … | Refer-a-friend / invite panel with metrics. |
210
+ | Section | `Section` | Section header pattern: eyebrow tag, title (+ chevron), control cluster, segmented control, content slot (`children`). |
205
211
 
206
212
  Block source files live in `components/blocks/`. Most heroes and trading blocks also export a `*Skeleton` loading variant. See `.claude/skills/build/references/components-and-tokens.md` for the full catalog with "matches when" hints.
207
213
 
@@ -715,7 +721,7 @@ This project uses @deriv-ds/design-intelligence-layer (Quill Design System). Bef
715
721
  3. Read node_modules/@deriv-ds/design-intelligence-layer/guides/personas/trading-game-player-field-guide.md — understand the player personas that shape all copy and UX
716
722
  4. Read node_modules/@deriv-ds/design-intelligence-layer/guides/brand-voice/deriv-brand-voice.md — apply the brand voice: channel-specific voice, banned phrases, vocabulary, and formatting rules for all player-facing copy
717
723
  5. Check if the component exists in the package — import it, don't re-implement
718
- 6. Use only design token classes (bg-prominent, text-on-prominent, border-border-subtle, etc.) — no hardcoded hex or raw Tailwind palette colors
724
+ 6. Use only design token classes (bg-primary-canvas, text-prominent, border-default, etc.) — no hardcoded hex or raw Tailwind palette colors
719
725
  7. Do not install lucide-react — icons come from @deriv/quill-icons via the bundled Icon component; do not install tailwindcss or other bundled dependencies separately
720
726
  8. If no token exists for a value, ask before using a hardcoded value
721
727
  9. After upgrading the package: prefer package imports over local copies of components; if replacing local UI code with the package version, tell the user what was overwritten; re-copy guides/rules/design-system-consuming-project.mdc into .cursor/rules if using Cursor