@cognite/aura 0.2.0 → 0.3.1
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/DESIGN.md +869 -870
- package/README.md +143 -9
- package/dist/colors.css +30 -0
- package/dist/components/index.d.ts +7 -36
- package/dist/components/index.js +319 -350
- package/dist/components/ui/core/accordion/accordion.d.ts +7 -7
- package/dist/components/ui/core/accordion/accordion.js +49 -47
- package/dist/components/ui/core/action-toolbar/action-toolbar.d.ts +41 -0
- package/dist/components/ui/core/action-toolbar/action-toolbar.js +176 -0
- package/dist/components/ui/core/alert/alert.d.ts +23 -12
- package/dist/components/ui/core/alert/alert.js +123 -120
- package/dist/components/ui/core/avatar/avatar.d.ts +12 -8
- package/dist/components/ui/core/badge/badge.d.ts +11 -8
- package/dist/components/ui/core/banner/banner.d.ts +18 -28
- package/dist/components/ui/core/breadcrumb/breadcrumb.d.ts +10 -9
- package/dist/components/ui/core/breadcrumb/breadcrumb.js +98 -88
- package/dist/components/ui/core/button/button.d.ts +8 -5
- package/dist/components/ui/core/button/button.js +22 -19
- package/dist/components/ui/core/button-group/button-group.d.ts +7 -6
- package/dist/components/ui/core/card/card.d.ts +17 -16
- package/dist/components/ui/core/chart/chart.d.ts +69 -0
- package/dist/components/ui/core/chart/chart.js +215 -0
- package/dist/components/ui/core/chart/index.d.ts +2 -0
- package/dist/components/ui/core/chart/index.js +8 -0
- package/dist/components/ui/core/checkbox/checkbox.d.ts +13 -9
- package/dist/components/ui/core/checkbox/checkbox.js +32 -28
- package/dist/components/ui/core/code-block/code-block.d.ts +6 -9
- package/dist/components/ui/core/code-block/code-block.js +48 -44
- package/dist/components/ui/core/collapsible/collapsible.d.ts +5 -3
- package/dist/components/ui/core/combobox/combobox.d.ts +2 -2
- package/dist/components/ui/core/command/command.d.ts +11 -78
- package/dist/components/ui/core/command/command.js +53 -52
- package/dist/components/ui/core/count/count.d.ts +7 -6
- package/dist/components/ui/core/date-time-pickers/date-picker/date-picker.d.ts +15 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/date-picker.js +84 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/index.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/types.d.ts +18 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/use-date-picker.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/use-date-picker.js +63 -0
- package/dist/components/ui/core/date-time-pickers/date-range-picker/date-range-picker.d.ts +15 -0
- package/dist/components/ui/core/date-time-pickers/date-range-picker/date-range-picker.js +99 -0
- package/dist/components/ui/core/date-time-pickers/date-range-picker/index.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/date-range-picker/types.d.ts +25 -0
- package/dist/components/ui/core/date-time-pickers/date-range-picker/use-date-range-picker.d.ts +4 -0
- package/dist/components/ui/core/date-time-pickers/date-range-picker/use-date-range-picker.js +82 -0
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/date-time-range-picker.d.ts +17 -0
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/date-time-range-picker.js +190 -0
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/index.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/types.d.ts +42 -0
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/use-date-time-range-picker.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/use-date-time-range-picker.js +161 -0
- package/dist/components/ui/core/date-time-pickers/index.d.ts +8 -0
- package/dist/components/ui/core/date-time-pickers/index.js +8 -0
- package/dist/components/ui/core/date-time-pickers/shared/am-pm-scroll/am-pm-scroll.d.ts +7 -0
- package/dist/components/ui/core/date-time-pickers/shared/am-pm-scroll/am-pm-scroll.js +57 -0
- package/dist/components/ui/core/date-time-pickers/shared/calendar/calendar.d.ts +13 -0
- package/dist/components/ui/core/date-time-pickers/shared/calendar/calendar.js +119 -0
- package/dist/components/ui/core/date-time-pickers/shared/calendar-header/calendar-header.d.ts +10 -0
- package/dist/components/ui/core/date-time-pickers/shared/calendar-header/calendar-header.js +93 -0
- package/dist/components/ui/core/date-time-pickers/shared/constants.d.ts +20 -0
- package/dist/components/ui/core/date-time-pickers/shared/constants.js +14 -0
- package/dist/components/ui/core/date-time-pickers/shared/date-time-input/date-time-input.d.ts +19 -0
- package/dist/components/ui/core/date-time-pickers/shared/date-time-input/date-time-input.js +99 -0
- package/dist/components/ui/core/date-time-pickers/shared/date-time-input/range-input-display.d.ts +12 -0
- package/dist/components/ui/core/date-time-pickers/shared/date-time-input/range-input-display.js +68 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-popover-state.d.ts +12 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-popover-state.js +40 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-range-date-state.d.ts +29 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-range-date-state.js +63 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-range-step-manager.d.ts +8 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-range-step-manager.js +19 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-single-date-state.d.ts +23 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-single-date-state.js +32 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-time-state.d.ts +17 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-time-state.js +34 -0
- package/dist/components/ui/core/date-time-pickers/shared/scroll-cell-classes.d.ts +8 -0
- package/dist/components/ui/core/date-time-pickers/shared/scroll-cell-classes.js +7 -0
- package/dist/components/ui/core/date-time-pickers/shared/shortcuts-panel/shortcuts-panel.d.ts +13 -0
- package/dist/components/ui/core/date-time-pickers/shared/shortcuts-panel/shortcuts-panel.js +31 -0
- package/dist/components/ui/core/date-time-pickers/shared/time-picker-scroll/time-picker-scroll.d.ts +10 -0
- package/dist/components/ui/core/date-time-pickers/shared/time-picker-scroll/time-picker-scroll.js +52 -0
- package/dist/components/ui/core/date-time-pickers/utils/calendar-utils.d.ts +48 -0
- package/dist/components/ui/core/date-time-pickers/utils/calendar-utils.js +52 -0
- package/dist/components/ui/core/date-time-pickers/utils/date-range-utils.d.ts +26 -0
- package/dist/components/ui/core/date-time-pickers/utils/format-utils.d.ts +37 -0
- package/dist/components/ui/core/date-time-pickers/utils/segment-utils.d.ts +34 -0
- package/dist/components/ui/core/date-time-pickers/utils/time-utils.d.ts +43 -0
- package/dist/components/ui/core/date-time-pickers/utils/time-utils.js +15 -0
- package/dist/components/ui/core/date-time-pickers/utils/time-validation.d.ts +23 -0
- package/dist/components/ui/core/dialog/dialog.d.ts +10 -10
- package/dist/components/ui/core/dialog/dialog.js +12 -3
- package/dist/components/ui/core/dropdown-menu/dropdown-menu.d.ts +24 -47
- package/dist/components/ui/core/dropdown-menu/dropdown-menu.js +125 -123
- package/dist/components/ui/core/empty-state/empty-state.context.d.ts +10 -0
- package/dist/components/ui/core/empty-state/empty-state.context.js +8 -0
- package/dist/components/ui/core/empty-state/empty-state.d.ts +18 -0
- package/dist/components/ui/core/empty-state/empty-state.js +139 -0
- package/dist/components/ui/core/helper-text/helper-text.d.ts +7 -5
- package/dist/components/ui/core/hover-card/hover-card.d.ts +5 -7
- package/dist/components/ui/core/hover-card/hover-card.js +23 -22
- package/dist/components/ui/core/inline-citation/inline-citation.d.ts +10 -10
- package/dist/components/ui/core/inline-citation/inline-citation.js +57 -49
- package/dist/components/ui/core/input/input.d.ts +2 -1
- package/dist/components/ui/core/input/input.js +1 -1
- package/dist/components/ui/core/input-group/input-group.d.ts +17 -13
- package/dist/components/ui/core/input-group/input-group.js +35 -36
- package/dist/components/ui/core/kbd/kbd.d.ts +3 -2
- package/dist/components/ui/core/label/label.d.ts +3 -2
- package/dist/components/ui/core/loader/loader.d.ts +2 -2
- package/dist/components/ui/core/message/message.d.ts +18 -17
- package/dist/components/ui/core/message/message.js +387 -99
- package/dist/components/ui/core/pagination/pagination-size-context.d.ts +5 -0
- package/dist/components/ui/core/pagination/pagination-size-context.js +6 -0
- package/dist/components/ui/core/pagination/pagination-teleport.d.ts +11 -0
- package/dist/components/ui/core/pagination/pagination-teleport.js +108 -0
- package/dist/components/ui/core/pagination/pagination-teleport.utils.d.ts +1 -0
- package/dist/components/ui/core/pagination/pagination-teleport.utils.js +7 -0
- package/dist/components/ui/core/pagination/pagination.d.ts +41 -0
- package/dist/components/ui/core/pagination/pagination.js +337 -0
- package/dist/components/ui/core/popover/popover.d.ts +12 -16
- package/dist/components/ui/core/popover/popover.js +52 -51
- package/dist/components/ui/core/progress/progress.d.ts +7 -4
- package/dist/components/ui/core/prompt-input/prompt-input.d.ts +36 -103
- package/dist/components/ui/core/prompt-input/prompt-input.js +180 -167
- package/dist/components/ui/core/radio-group/radio-group.d.ts +12 -8
- package/dist/components/ui/core/radio-group/radio-group.js +56 -53
- package/dist/components/ui/core/reasoning/reasoning.d.ts +5 -5
- package/dist/components/ui/core/scroll-area/scroll-area.d.ts +4 -2
- package/dist/components/ui/core/search/search.d.ts +10 -0
- package/dist/components/ui/core/search/search.js +99 -0
- package/dist/components/ui/core/segmented-control/segmented-control.d.ts +15 -11
- package/dist/components/ui/core/segmented-control/segmented-control.js +4 -1
- package/dist/components/ui/core/select/select.d.ts +15 -14
- package/dist/components/ui/core/select/select.js +135 -108
- package/dist/components/ui/core/separator/separator.d.ts +2 -4
- package/dist/components/ui/core/separator/separator.js +4 -5
- package/dist/components/ui/core/shimmer/shimmer.d.ts +5 -5
- package/dist/components/ui/core/shimmer/shimmer.js +91 -52
- package/dist/components/ui/core/skeleton/skeleton.d.ts +2 -1
- package/dist/components/ui/core/sonner-toast/sonner-toast.d.ts +2 -1
- package/dist/components/ui/core/sources/sources.d.ts +3 -3
- package/dist/components/ui/core/sources/sources.js +6 -1
- package/dist/components/ui/core/switch/switch.d.ts +11 -0
- package/dist/components/ui/core/{button/button.metadata.d.ts → switch/switch.metadata.d.ts} +1 -1
- package/dist/components/ui/core/tabs/tabs.d.ts +21 -17
- package/dist/components/ui/core/tabs/tabs.js +11 -9
- package/dist/components/ui/core/textarea/textarea.d.ts +2 -1
- package/dist/components/ui/core/textarea/textarea.js +20 -18
- package/dist/components/ui/core/toggle/toggle.d.ts +15 -0
- package/dist/components/ui/core/toggle/toggle.js +74 -0
- package/dist/components/ui/core/tool/tool.d.ts +7 -6
- package/dist/components/ui/core/tool/tool.js +47 -43
- package/dist/components/ui/core/tooltip/tooltip.d.ts +6 -5
- package/dist/components/ui/core/tooltip/tooltip.js +10 -8
- package/dist/components/ui/core/topbar/topbar.d.ts +11 -13
- package/dist/eslint/index.d.ts +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/portal-container-context.d.ts +2 -1
- package/dist/lib/portal-container-context.js +3 -5
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.js +7 -7
- package/dist/styles.css +1 -1
- package/dist/styles.source.css +12 -1
- package/package.json +217 -14
- package/dist/components/ui/core/accordion/accordion.metadata.d.ts +0 -2
- package/dist/components/ui/core/accordion/accordion.metadata.js +0 -9
- package/dist/components/ui/core/alert/alert.metadata.d.ts +0 -2
- package/dist/components/ui/core/alert/alert.metadata.js +0 -9
- package/dist/components/ui/core/avatar/avatar.metadata.d.ts +0 -8
- package/dist/components/ui/core/avatar/avatar.metadata.js +0 -9
- package/dist/components/ui/core/badge/badge.metadata.d.ts +0 -2
- package/dist/components/ui/core/badge/badge.metadata.js +0 -8
- package/dist/components/ui/core/banner/banner.metadata.d.ts +0 -2
- package/dist/components/ui/core/banner/banner.metadata.js +0 -9
- package/dist/components/ui/core/breadcrumb/breadcrumb.metadata.d.ts +0 -2
- package/dist/components/ui/core/breadcrumb/breadcrumb.metadata.js +0 -9
- package/dist/components/ui/core/button/button.metadata.js +0 -9
- package/dist/components/ui/core/button-group/button-group.metadata.d.ts +0 -2
- package/dist/components/ui/core/button-group/button-group.metadata.js +0 -8
- package/dist/components/ui/core/card/card.metadata.d.ts +0 -8
- package/dist/components/ui/core/card/card.metadata.js +0 -9
- package/dist/components/ui/core/code-block/code-block.metadata.d.ts +0 -2
- package/dist/components/ui/core/code-block/code-block.metadata.js +0 -8
- package/dist/components/ui/core/collapsible/collapsible.metadata.d.ts +0 -2
- package/dist/components/ui/core/collapsible/collapsible.metadata.js +0 -9
- package/dist/components/ui/core/combobox/combobox.metadata.d.ts +0 -2
- package/dist/components/ui/core/command/command.metadata.d.ts +0 -2
- package/dist/components/ui/core/command/command.metadata.js +0 -9
- package/dist/components/ui/core/dialog/dialog.metadata.d.ts +0 -2
- package/dist/components/ui/core/dialog/dialog.metadata.js +0 -9
- package/dist/components/ui/core/dropdown-menu/dropdown-menu.metadata.d.ts +0 -2
- package/dist/components/ui/core/dropdown-menu/dropdown-menu.metadata.js +0 -9
- package/dist/components/ui/core/helper-text/helper-text.metadata.d.ts +0 -2
- package/dist/components/ui/core/helper-text/helper-text.metadata.js +0 -9
- package/dist/components/ui/core/hover-card/hover-card.metadata.d.ts +0 -2
- package/dist/components/ui/core/hover-card/hover-card.metadata.js +0 -8
- package/dist/components/ui/core/inline-citation/inline-citation.metadata.d.ts +0 -2
- package/dist/components/ui/core/inline-citation/inline-citation.metadata.js +0 -8
- package/dist/components/ui/core/input/input.metadata.d.ts +0 -2
- package/dist/components/ui/core/input/input.metadata.js +0 -9
- package/dist/components/ui/core/input-group/input-group.metadata.d.ts +0 -2
- package/dist/components/ui/core/input-group/input-group.metadata.js +0 -9
- package/dist/components/ui/core/kbd/kbd.metadata.d.ts +0 -2
- package/dist/components/ui/core/kbd/kbd.metadata.js +0 -9
- package/dist/components/ui/core/label/label.metadata.d.ts +0 -2
- package/dist/components/ui/core/label/label.metadata.js +0 -9
- package/dist/components/ui/core/loader/loader.metadata.d.ts +0 -2
- package/dist/components/ui/core/loader/loader.metadata.js +0 -9
- package/dist/components/ui/core/message/message.metadata.d.ts +0 -2
- package/dist/components/ui/core/popover/popover.metadata.d.ts +0 -2
- package/dist/components/ui/core/popover/popover.metadata.js +0 -9
- package/dist/components/ui/core/progress/progress.metadata.d.ts +0 -2
- package/dist/components/ui/core/progress/progress.metadata.js +0 -9
- package/dist/components/ui/core/prompt-input/prompt-input.metadata.d.ts +0 -2
- package/dist/components/ui/core/prompt-input/prompt-input.metadata.js +0 -9
- package/dist/components/ui/core/radio-group/radio-group.metadata.d.ts +0 -2
- package/dist/components/ui/core/radio-group/radio-group.metadata.js +0 -9
- package/dist/components/ui/core/reasoning/reasoning.metadata.d.ts +0 -2
- package/dist/components/ui/core/reasoning/reasoning.metadata.js +0 -8
- package/dist/components/ui/core/scroll-area/scroll-area.metadata.d.ts +0 -2
- package/dist/components/ui/core/scroll-area/scroll-area.metadata.js +0 -9
- package/dist/components/ui/core/select/select.metadata.d.ts +0 -2
- package/dist/components/ui/core/select/select.metadata.js +0 -9
- package/dist/components/ui/core/separator/separator.metadata.d.ts +0 -2
- package/dist/components/ui/core/separator/separator.metadata.js +0 -8
- package/dist/components/ui/core/shimmer/shimmer.metadata.d.ts +0 -2
- package/dist/components/ui/core/shimmer/shimmer.metadata.js +0 -9
- package/dist/components/ui/core/skeleton/skeleton.metadata.d.ts +0 -2
- package/dist/components/ui/core/skeleton/skeleton.metadata.js +0 -9
- package/dist/components/ui/core/sonner-toast/sonner-toast.metadata.d.ts +0 -2
- package/dist/components/ui/core/sonner-toast/sonner-toast.metadata.js +0 -9
- package/dist/components/ui/core/sources/sources.metadata.d.ts +0 -2
- package/dist/components/ui/core/textarea/textarea.metadata.d.ts +0 -2
- package/dist/components/ui/core/textarea/textarea.metadata.js +0 -9
- package/dist/components/ui/core/tool/tool.metadata.d.ts +0 -2
- package/dist/components/ui/core/tool/tool.metadata.js +0 -8
- package/dist/components/ui/core/tooltip/tooltip.metadata.d.ts +0 -8
- package/dist/components/ui/core/tooltip/tooltip.metadata.js +0 -9
- package/dist/index.js +0 -342
package/DESIGN.md
CHANGED
|
@@ -1,742 +1,575 @@
|
|
|
1
|
-
## Overview
|
|
2
|
-
|
|
3
|
-
Aura is the design system for Cognite Data Fusion experiences: composable UI primitives (buttons, inputs, overlays, AI/chat surfaces), Tailwind v4 theme extensions, and **Base**, **Decorative**, and **Semantic** tokens. Interfaces should feel **clear, layered without clutter, and trustworthy** — mountain neutrals for structure, fjord for links and focus, and restrained decorative ramps for accents, charts, and status.
|
|
4
|
-
|
|
5
|
-
**What belongs in this file:** identity, token *names*, *roles*, and *resolved reference values* so humans and agents choose the right variable or Tailwind color/shadow/radius utility; **[Content](#content)** for UI copy (action labels, dates, grammar, localization, voice, accessible writing). **How** to wire themes, run Figma sync, or verify in CI belongs in Aura engineering / agent skills, not here.
|
|
6
|
-
|
|
7
|
-
**Where the CSS sources live**
|
|
8
|
-
|
|
9
|
-
The canonical token files (`colors.css`, `styles.source.css`) live in the Aura library repo under `src/`. In a consuming app they are available through the published package — import from `@cognite/aura/colors.css` and `@cognite/aura/styles.css`. Do not look for `src/colors.css` next to your app code; resolve token names via your IDE's autocomplete on `@cognite/aura`, or consult the tables in [Tokens](#tokens) below.
|
|
10
|
-
|
|
11
|
-
**Code:** In Fusion / host apps (example convention), ship UI from Aura exports (`@cognite/aura/components`, [Storybook](https://storybook-aura-23638.fusion-preview.preview.cogniteapp.com)) under e.g. `src/components/ui`; prefer **CVA** variants. **[Interaction states](#interaction-states)**, **[Heuristics](#heuristics)**, and **[Content](#content)** define how to use primitives — prefer component APIs over reimplementing or overriding internals when a variant already matches intent. **Prop names, `size` values, and subcomponents** are **not** duplicated here; use [Storybook](https://storybook-aura-23638.fusion-preview.preview.cogniteapp.com), the [Aura design system documentation](https://docs.cognite.com/aura-design-system/get-started) (foundations, primitives, installation), and TypeScript types from `@cognite/aura/components` as the source of truth. For color in product UI, use tokens — not raw `hex` / `rgb` / `hsl` when a semantic or base token exists; details under **[Tokens](#tokens)**.
|
|
12
|
-
|
|
13
|
-
## Dashboard quick start (agent checklist)
|
|
14
|
-
|
|
15
|
-
For pages with data-heavy layouts — cards, charts, metric tiles — work through these steps before writing component code.
|
|
16
|
-
|
|
17
|
-
- [ ] **Tokens** — confirm all colors use semantic or chart tokens, no raw hex. Metric tiles: `decorative-*`. Data series: `chart-*`. Status: `info-*`, `success-*`, `warning-*`, `destructive-*`. See [Tokens → Color](#color).
|
|
18
|
-
- [ ] **Layout** — use a 12-column grid with `gap-4` or `gap-6`. Tile widths: `col-span-12 sm:col-span-6 lg:col-span-3`. Cap the page frame with `max-w-[min(100%,var(--container-8xl))]`.
|
|
19
|
-
- [ ] **Cards** — use the `Card` component with title, description, and a primary action. Do not stack unrelated actions in the same card. See [Heuristics §6.1](#61-grouping-and-proximity).
|
|
20
|
-
- [ ] **Loading states** — every data region must show `Shimmer` (known layout) or `Loader` (unknown layout) while fetching. See [Heuristics §1.1](#11-loading-states).
|
|
21
|
-
- [ ] **Status signals** — default to **Badge** or compact status cards for repeated states; keep **Alert** to one page-level inline instance unless multiple independent incidents each need separate action. See [Alert vs Banner vs Badge vs Sonner](#alert-vs-banner-vs-badge-vs-sonner).
|
|
22
|
-
- [ ] **Navigation** — one Topbar, no sidebar. Chart sub-navigation lives in the content area. See [Heuristics §3.3](#33-contextual-menus-and-secondary-actions).
|
|
23
|
-
- [ ] **Accessibility** — every chart must have a text summary of key insights. Icon-only controls must have `aria-label` and a `Tooltip`. See [Heuristics §7](#7-accessibility-and-inclusive-design).
|
|
24
|
-
|
|
25
1
|
---
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
|
|
2
|
+
version: alpha
|
|
3
|
+
name: Aura
|
|
4
|
+
description: Cognite's design system for composable UI primitives in data-heavy industrial software.
|
|
5
|
+
colors:
|
|
6
|
+
primary: '#212426'
|
|
7
|
+
secondary: '#E4E6E8'
|
|
8
|
+
tertiary: '#486AED'
|
|
9
|
+
neutral: '#F1F2F3'
|
|
10
|
+
background: '#FFFFFF'
|
|
11
|
+
foreground: '#191B1D'
|
|
12
|
+
alternate-background: '#F9FAFA'
|
|
13
|
+
card-background: '#F9FAFA'
|
|
14
|
+
muted-background: '#F1F2F3'
|
|
15
|
+
muted-foreground: '#6D767E'
|
|
16
|
+
primary-background-hover: '#40464A'
|
|
17
|
+
secondary-background-hover: '#D4D7D9'
|
|
18
|
+
foreground-on-primary: '#F1F2F3'
|
|
19
|
+
secondary-foreground: '#40464A'
|
|
20
|
+
link-foreground: '#486AED'
|
|
21
|
+
border: '#E4E6E8'
|
|
22
|
+
border-emphasized: '#D4D7D9'
|
|
23
|
+
ring: '#7081C7'
|
|
24
|
+
ring-muted: '#B5BEE2'
|
|
25
|
+
info-background: '#D0D6ED'
|
|
26
|
+
info-foreground-on-info: '#32417F'
|
|
27
|
+
success-background: '#BBF3D0'
|
|
28
|
+
success-foreground-on-success: '#0F5026'
|
|
29
|
+
warning-background: '#FFE3A2'
|
|
30
|
+
warning-foreground-on-warning: '#755200'
|
|
31
|
+
destructive-background: '#FCCAD2'
|
|
32
|
+
destructive-foreground-on-critical: '#8D081F'
|
|
33
|
+
overlay-background: '#7C868E80'
|
|
34
|
+
typography:
|
|
35
|
+
display:
|
|
36
|
+
fontFamily: Space Grotesk
|
|
37
|
+
fontSize: 36px
|
|
38
|
+
fontWeight: 600
|
|
39
|
+
lineHeight: 44px
|
|
40
|
+
letterSpacing: -0.08px
|
|
41
|
+
h1:
|
|
42
|
+
fontFamily: Inter
|
|
43
|
+
fontSize: 32px
|
|
44
|
+
fontWeight: 600
|
|
45
|
+
lineHeight: 40px
|
|
46
|
+
letterSpacing: -0.08px
|
|
47
|
+
h2:
|
|
48
|
+
fontFamily: Inter
|
|
49
|
+
fontSize: 28px
|
|
50
|
+
fontWeight: 600
|
|
51
|
+
lineHeight: 32px
|
|
52
|
+
letterSpacing: -0.08px
|
|
53
|
+
h3:
|
|
54
|
+
fontFamily: Inter
|
|
55
|
+
fontSize: 24px
|
|
56
|
+
fontWeight: 600
|
|
57
|
+
lineHeight: 28px
|
|
58
|
+
letterSpacing: -0.04px
|
|
59
|
+
h4:
|
|
60
|
+
fontFamily: Inter
|
|
61
|
+
fontSize: 20px
|
|
62
|
+
fontWeight: 500
|
|
63
|
+
lineHeight: 24px
|
|
64
|
+
letterSpacing: -0.04px
|
|
65
|
+
body-md:
|
|
66
|
+
fontFamily: Inter
|
|
67
|
+
fontSize: 16px
|
|
68
|
+
fontWeight: 400
|
|
69
|
+
lineHeight: 20px
|
|
70
|
+
letterSpacing: -0.04px
|
|
71
|
+
body-sm:
|
|
72
|
+
fontFamily: Inter
|
|
73
|
+
fontSize: 14px
|
|
74
|
+
fontWeight: 400
|
|
75
|
+
lineHeight: 18px
|
|
76
|
+
letterSpacing: -0.04px
|
|
77
|
+
label:
|
|
78
|
+
fontFamily: Inter
|
|
79
|
+
fontSize: 12px
|
|
80
|
+
fontWeight: 500
|
|
81
|
+
lineHeight: 14px
|
|
82
|
+
letterSpacing: -0.04px
|
|
83
|
+
code:
|
|
84
|
+
fontFamily: Source Code Pro
|
|
85
|
+
fontSize: 14px
|
|
86
|
+
fontWeight: 400
|
|
87
|
+
lineHeight: 20px
|
|
88
|
+
rounded:
|
|
89
|
+
none: 0px
|
|
90
|
+
xs: 2px
|
|
91
|
+
sm: 4px
|
|
92
|
+
md: 6px
|
|
93
|
+
lg: 8px
|
|
94
|
+
xl: 12px
|
|
95
|
+
2xl: 16px
|
|
96
|
+
3xl: 24px
|
|
97
|
+
4xl: 32px
|
|
98
|
+
full: 9999px
|
|
99
|
+
spacing:
|
|
100
|
+
base: 4px
|
|
101
|
+
xs: 4px
|
|
102
|
+
sm: 8px
|
|
103
|
+
md: 12px
|
|
104
|
+
lg: 16px
|
|
105
|
+
xl: 20px
|
|
106
|
+
2xl: 24px
|
|
107
|
+
3xl: 32px
|
|
108
|
+
prose-max: 600px
|
|
109
|
+
container-2xl: 640px
|
|
110
|
+
container-8xl: 1536px
|
|
111
|
+
components:
|
|
112
|
+
button-primary:
|
|
113
|
+
backgroundColor: '{colors.primary}'
|
|
114
|
+
textColor: '{colors.foreground-on-primary}'
|
|
115
|
+
rounded: '{rounded.lg}'
|
|
116
|
+
padding: '{spacing.md}'
|
|
117
|
+
height: 36px
|
|
118
|
+
button-primary-hover:
|
|
119
|
+
backgroundColor: '{colors.primary-background-hover}'
|
|
120
|
+
button-secondary:
|
|
121
|
+
backgroundColor: '{colors.secondary}'
|
|
122
|
+
textColor: '{colors.foreground}'
|
|
123
|
+
rounded: '{rounded.lg}'
|
|
124
|
+
padding: '{spacing.md}'
|
|
125
|
+
height: 36px
|
|
126
|
+
button-destructive:
|
|
127
|
+
backgroundColor: '{colors.destructive-background}'
|
|
128
|
+
textColor: '{colors.destructive-foreground-on-critical}'
|
|
129
|
+
rounded: '{rounded.lg}'
|
|
130
|
+
height: 36px
|
|
131
|
+
button-sm:
|
|
132
|
+
height: 28px
|
|
133
|
+
rounded: '{rounded.lg}'
|
|
134
|
+
button-lg:
|
|
135
|
+
height: 40px
|
|
136
|
+
rounded: '{rounded.lg}'
|
|
137
|
+
button-secondary-hover:
|
|
138
|
+
backgroundColor: '{colors.secondary-background-hover}'
|
|
139
|
+
input-default:
|
|
140
|
+
backgroundColor: '{colors.background}'
|
|
141
|
+
textColor: '{colors.foreground}'
|
|
142
|
+
rounded: '{rounded.lg}'
|
|
143
|
+
height: 36px
|
|
144
|
+
input-muted:
|
|
145
|
+
backgroundColor: '{colors.muted-background}'
|
|
146
|
+
textColor: '{colors.muted-foreground}'
|
|
147
|
+
rounded: '{rounded.lg}'
|
|
148
|
+
height: 36px
|
|
149
|
+
dialog-overlay:
|
|
150
|
+
backgroundColor: '{colors.overlay-background}'
|
|
151
|
+
divider-default:
|
|
152
|
+
backgroundColor: '{colors.border}'
|
|
153
|
+
divider-emphasized:
|
|
154
|
+
backgroundColor: '{colors.border-emphasized}'
|
|
155
|
+
badge-neutral:
|
|
156
|
+
backgroundColor: '{colors.neutral}'
|
|
157
|
+
textColor: '{colors.secondary-foreground}'
|
|
158
|
+
rounded: '{rounded.sm}'
|
|
159
|
+
panel-alternate:
|
|
160
|
+
backgroundColor: '{colors.alternate-background}'
|
|
161
|
+
textColor: '{colors.foreground}'
|
|
162
|
+
card-default:
|
|
163
|
+
backgroundColor: '{colors.card-background}'
|
|
164
|
+
textColor: '{colors.foreground}'
|
|
165
|
+
rounded: '{rounded.xl}'
|
|
166
|
+
padding: '{spacing.lg}'
|
|
167
|
+
link-default:
|
|
168
|
+
textColor: '{colors.link-foreground}'
|
|
169
|
+
typography: '{typography.body-md}'
|
|
170
|
+
badge-xs:
|
|
171
|
+
height: 20px
|
|
172
|
+
rounded: '{rounded.sm}'
|
|
173
|
+
alert-info:
|
|
174
|
+
backgroundColor: '{colors.info-background}'
|
|
175
|
+
textColor: '{colors.info-foreground-on-info}'
|
|
176
|
+
rounded: '{rounded.lg}'
|
|
177
|
+
alert-success:
|
|
178
|
+
backgroundColor: '{colors.success-background}'
|
|
179
|
+
textColor: '{colors.success-foreground-on-success}'
|
|
180
|
+
rounded: '{rounded.lg}'
|
|
181
|
+
alert-warning:
|
|
182
|
+
backgroundColor: '{colors.warning-background}'
|
|
183
|
+
textColor: '{colors.warning-foreground-on-warning}'
|
|
184
|
+
rounded: '{rounded.lg}'
|
|
185
|
+
alert-destructive:
|
|
186
|
+
backgroundColor: '{colors.destructive-background}'
|
|
187
|
+
textColor: '{colors.destructive-foreground-on-critical}'
|
|
188
|
+
rounded: '{rounded.lg}'
|
|
39
189
|
---
|
|
40
190
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Users **must** always know what changed: loading, success, failure, or background work needs a visible signal.
|
|
44
|
-
|
|
45
|
-
#### 1.1 Loading states
|
|
46
|
-
|
|
47
|
-
**Applies when:** Data fetch, async work, route transition, or slow AI step blocks meaningful UI.
|
|
48
|
-
|
|
49
|
-
**Aura components:** `Shimmer`, `Loader`, `Progress`, `Skeleton`
|
|
50
|
-
|
|
51
|
-
**Rules**
|
|
52
|
-
|
|
53
|
-
- **Must** show loading for any wait the user is expected to sit through.
|
|
54
|
-
- **Must** use **Shimmer** when the layout of incoming content is known (list rows, cards, table skeleton).
|
|
55
|
-
- **Must** use **Loader** for compact inline waits (e.g. inside a **Button** or card header).
|
|
56
|
-
- **Must** use a **full-surface** pattern (centered **Loader**, **Skeleton** layout, or app **PageLoader**) for full-page or high-latency transitions including long AI operations.
|
|
57
|
-
- **Should** use **Progress** when completion is measurable (upload %, stepped flow).
|
|
58
|
-
- **Avoid** blank content areas with no indicator.
|
|
59
|
-
- **Avoid** using only a tiny spinner for large unknown layouts — prefer **Shimmer** / **Skeleton**.
|
|
60
|
-
|
|
61
|
-
#### 1.2 Action confirmation
|
|
62
|
-
|
|
63
|
-
**Applies when:** User actions mutate state (save, submit, delete, copy, send).
|
|
64
|
-
|
|
65
|
-
**Aura components:** `Dialog` (+ destructive **Button**), `Alert`, `Tooltip`, `Banner`
|
|
66
|
-
**App / shell:** Sonner (or equivalent toast), dedicated confirm **AlertDialog** where the shell provides it
|
|
67
|
-
|
|
68
|
-
**Rules**
|
|
69
|
-
|
|
70
|
-
- **Must** acknowledge user-triggered mutations with a visible signal.
|
|
71
|
-
- **Must** use **transient toast** (e.g. Sonner, bottom-right, ~4s auto-dismiss) for low-stakes confirmations (“Saved”, “Copied”) — theme with Aura tokens.
|
|
72
|
-
- **Must** use **Dialog** (or shell **AlertDialog**) with explicit copy **before** irreversible actions — not only after the fact.
|
|
73
|
-
- **Should** offer **Undo** in the toast when the action is reversible and undo is cheap.
|
|
74
|
-
- **Should** use **Tooltip** (“Copied!”) for copy on small icon targets.
|
|
75
|
-
- **Avoid** `alert()` and other native blocking dialogs for product UX.
|
|
76
|
-
- **Avoid** stacking multiple toasts for a single user gesture.
|
|
77
|
-
|
|
78
|
-
#### 1.3 System status visibility
|
|
79
|
-
|
|
80
|
-
**Applies when:** **Persistent** problems with **user-visible workflow impact** — degraded mode, auth expiry, data stale beyond policy, or API health that blocks or misleads work — not routine connection handshakes or background connectivity that users do not need to monitor continuously.
|
|
81
|
-
|
|
82
|
-
**Aura components:** `Alert`, `Badge`, `Banner`, `Loader` (see §1.1)
|
|
83
|
-
**App:** `Sonner` for ephemeral global notices
|
|
84
|
-
|
|
85
|
-
**Rules**
|
|
86
|
-
|
|
87
|
-
- **Must** surface problems that stay **until dismissed or resolved** and **scope to a region** with **Banner** at the top of that region — when the issue is **persistent** and **not** low-salience ambient state.
|
|
88
|
-
- **Must** use **Alert** for inline, page-scoped status that needs awareness but not always immediate action, and keep it to **one page-level Alert per view** in standard dashboards.
|
|
89
|
-
- **Should** use **Badge** semantic variants (`warning`, `destructive`, …) on entities carrying that state.
|
|
90
|
-
- **Should** represent repeated or list-level status (many assets, tasks, signals) with **Badge**, metric/status cards, or concise icon+text rows — not repeated Alert stacks.
|
|
91
|
-
- **Should** use **Loader** (inline or full-surface per §1.1) for transient waits such as host handshake or reconnect; use **Banner** only when the degraded state **remains** after loading settles.
|
|
92
|
-
- **Should** use a short **Sonner** or **inline Alert** for **optional** or **intermittent** connection notices instead of permanent chrome.
|
|
93
|
-
- **Avoid** hiding workflow-critical status **only** behind hover.
|
|
94
|
-
- **Avoid** dedicating **Banner** or other persistent strip space to connection state when users **do not** need that signal continuously — prefer compact indicators (**Badge**, toolbar dot, footer text) or nothing until failure.
|
|
95
|
-
- **Avoid** treating routine “connecting / connected” or handshake flows as the default **Banner** channel — same rationale as **Avoid** using **Banner** for long onboarding when critical alerts need that channel (§5.3).
|
|
96
|
-
- **Avoid** stacking multiple Alerts inside one card or page section to enumerate line items; aggregate the message and push per-item state to badges or compact status rows.
|
|
97
|
-
|
|
98
|
-
### Alert vs Banner vs Badge vs Sonner
|
|
99
|
-
|
|
100
|
-
Use this matrix to pick the right feedback component. Priority is defined by whether the message requires immediate action and how long it needs to persist.
|
|
101
|
-
|
|
102
|
-
| Priority | When | Components | Notes |
|
|
103
|
-
| :--- | :--- | :--- | :--- |
|
|
104
|
-
| **Low** | Non-disruptive updates, minor status, validation hints | `Badge`, notification dot, inline `HelperText` | Does not interrupt the user. Badge for entity state; HelperText for field-level feedback. |
|
|
105
|
-
| **Medium** | Informative, occasionally actionable, not urgent | `Sonner` (toast), `Alert` | Sonner for transient confirmations (~4 s, bottom-right). Alert for inline, page-scoped status that needs awareness but not immediate action (typically one per page section/view). |
|
|
106
|
-
| **High** | Requires immediate attention or action; may interrupt task flow | `Banner` (system errors), `Dialog` / `AlertDialog`, full-page error state | Banner for persistent, region-scoped degraded states. Dialog for irreversible actions. Never use Sonner as the sole safety net for destructive work. |
|
|
107
|
-
|
|
108
|
-
**Rules**
|
|
109
|
-
|
|
110
|
-
- **Must not** use Banner for low-priority or transient notices — it occupies persistent chrome and dilutes high-priority signals.
|
|
111
|
-
- **Must not** use Sonner for errors that require user action — it auto-dismisses.
|
|
112
|
-
- **Must not** use repeated Alerts as a list visualization pattern; one Alert communicates the grouped situation, while item-level status belongs in Badge/status-card patterns.
|
|
113
|
-
- **Should** use `Badge` semantic variants (`warning`, `destructive`, `success`) on entities that carry that state, not as page-level alerts.
|
|
114
|
-
- **Avoid** stacking multiple Sonner toasts for a single user gesture.
|
|
115
|
-
|
|
116
|
-
**Industrial / operational states**
|
|
117
|
-
|
|
118
|
-
The matrix above covers standard cases. For domain-specific states (e.g. sensor offline, process limit breach, control system degraded), apply the same priority logic: does the user need to act now? -> Banner or Dialog. Informational? -> Alert or Badge on the asset. Transient confirmation? -> Sonner. When many entities share similar state, summarize once (Alert/Banner) and show per-entity state with Badge or status cards.
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
### 2. Affordance and discoverability
|
|
123
|
-
|
|
124
|
-
Controls **must** read as interactive; users **should** not guess what is clickable, expandable, or editable.
|
|
125
|
-
|
|
126
|
-
#### 2.1 Interactive signifiers
|
|
127
|
-
|
|
128
|
-
**Applies when:** Click, drag, expand, or edit.
|
|
129
|
-
|
|
130
|
-
**Aura components:** `Button`, `DropdownMenu`, `Collapsible`, `Accordion`, `Select`, `Command`
|
|
131
|
-
|
|
132
|
-
**Rules**
|
|
133
|
-
|
|
134
|
-
- **Must** use **Button** for discrete actions — not `div`/`span` with `onClick` styled as buttons.
|
|
135
|
-
- **Must** match **Button** `variant` to prominence: `default` = primary CTA, `secondary` / `outline` / `ghost` for supporting actions, `destructive` for irreversible commit.
|
|
136
|
-
- **Must** use a **chevron-down** (or equivalent) on controls that open menus or expandable regions, consistent with **DropdownMenu** / **Collapsible** / **Accordion** patterns.
|
|
137
|
-
- **Should** keep **`pointer`** cursor on interactive surfaces — Aura sets this; do not override without cause.
|
|
138
|
-
- **Avoid** custom “clickable text” that looks identical to body copy.
|
|
139
|
-
|
|
140
|
-
#### 2.2 Labels and recognizable patterns
|
|
141
|
-
|
|
142
|
-
**Applies when:** Forms, navigation, empty views, search.
|
|
143
|
-
|
|
144
|
-
**Aura components:** `Label`, `Input`, `Textarea`, `Select`, `Card`, `Command` / `CommandInput`
|
|
145
|
-
|
|
146
|
-
**Rules**
|
|
147
|
-
|
|
148
|
-
- **Must** pair every field with a visible **Label** — placeholders are not labels.
|
|
149
|
-
- **Must** use recognizable patterns (search field + magnifier icon, menu trigger + chevron).
|
|
150
|
-
- **Should** use **Card** + title/description + **Button** for first-use empty views — not a bare white panel.
|
|
151
|
-
- **Avoid** ambiguous icon-only controls without **Tooltip** + accessible name (see §2.3).
|
|
152
|
-
|
|
153
|
-
#### 2.3 Contextual help
|
|
154
|
-
|
|
155
|
-
**Applies when:** Non-obvious behavior, format rules, or icon-only controls.
|
|
156
|
-
|
|
157
|
-
**Aura components:** `Tooltip`, `Popover`, `HelperText`, `HoverCard`
|
|
158
|
-
|
|
159
|
-
**Rules**
|
|
160
|
-
|
|
161
|
-
- **Must** put **Tooltip** on icon-only **Button**s with no visible label.
|
|
162
|
-
- **Must** use **HelperText** under fields for format and constraints **before** error.
|
|
163
|
-
- **Should** use **Popover** / **HoverCard** when help needs paragraphs or links.
|
|
164
|
-
- **Avoid** **Tooltip** as the **only** place for information users must have on touch-first flows.
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
### 3. Progressive disclosure
|
|
169
|
-
|
|
170
|
-
Introduce complexity only when needed; default views **should** stay scannable.
|
|
171
|
-
|
|
172
|
-
#### 3.1 Collapsible content
|
|
173
|
-
|
|
174
|
-
**Applies when:** Secondary detail, advanced settings, or optional blocks.
|
|
175
|
-
|
|
176
|
-
**Aura components:** `Accordion`, `Collapsible`, `Dialog`, `Popover`
|
|
177
|
-
**App:** `Sheet`, `Drawer` where the shell provides them — still use Aura tokens
|
|
178
|
-
|
|
179
|
-
**Rules**
|
|
180
|
-
|
|
181
|
-
- **Must** use **Accordion** for stacked, independent sections (FAQ, settings groups).
|
|
182
|
-
- **Must** use **Collapsible** for a single inline expandable block.
|
|
183
|
-
- **Must** use **Drawer** / **Sheet** (shell) for edge panels or lightweight overlays that should not replace the whole page; otherwise **Dialog** for modal tasks.
|
|
184
|
-
- **Should** default **Accordion** / **Collapsible** to collapsed unless the section is the main purpose of the view.
|
|
185
|
-
- **Avoid** nesting **Accordion** more than one level.
|
|
191
|
+
## Overview
|
|
186
192
|
|
|
187
|
-
|
|
193
|
+
Aura is the official design system for Cognite experiences: composable UI primitives for data-heavy industrial software.
|
|
188
194
|
|
|
189
|
-
**
|
|
195
|
+
Aura should feel like an **industrial control room**: quiet surfaces, stable hierarchy, immediate status signals, and controls that stay out of the operator's way until action is needed. The interface is engineered, not decorated. It gives dense operational data enough structure to scan quickly, reserves color for meaning, and makes interaction states predictable under pressure.
|
|
190
196
|
|
|
191
|
-
|
|
197
|
+
Light and dark themes share the same semantic roles; fixed tokens support persistent shell chrome.
|
|
192
198
|
|
|
193
|
-
**
|
|
199
|
+
**Tokens:** Reference values live in the YAML front matter at the top of this file. They provide context for agents and humans — the prose sections below carry design intent, constraints, and reasoning. Reference tokens in prose as `{colors.<name>}`, `{spacing.<name>}`, `{typography.<name>}`, `{rounded.<name>}`, and `{components.<name>}`.
|
|
194
200
|
|
|
195
|
-
|
|
196
|
-
- **Must** let users return to earlier steps unless that causes data loss.
|
|
197
|
-
- **Avoid** multiple irreversible **primary** decisions in one step.
|
|
201
|
+
**Implementation:** Package imports, component APIs, and host-shell integration live in the Aura [README](./README.md) — not in this file.
|
|
198
202
|
|
|
199
|
-
|
|
203
|
+
### For agents: how to read this file
|
|
200
204
|
|
|
201
|
-
|
|
205
|
+
Before editing or generating from this file, read Google's [DESIGN.md Philosophy](https://github.com/google-labs-code/design.md/blob/main/PHILOSOPHY.md). The philosophy applies directly to how Aura's spec should be used:
|
|
202
206
|
|
|
203
|
-
**
|
|
204
|
-
**
|
|
207
|
+
1. **Start with prose, not tokens.** The quality of generated UI depends more on understanding _intent_ than on copying hex values. Read **Overview**, **Do's and Don'ts**, **Heuristics**, **Interaction states**, and **Content** before implementing from the YAML block. Use **Heuristics** for detailed feedback, disclosure, error, layout, and accessibility decisions.
|
|
208
|
+
2. **Tokens are context, not rendering instructions.** YAML values anchor names and approximate light-theme references. Runtime styling comes from `@cognite/aura/colors.css`, `@cognite/aura/styles.css`, and component APIs — not from reimplementing token literals in product code.
|
|
209
|
+
3. **Prefer specific constraints over adjectives.** Aura targets data-heavy industrial software: flat hierarchy, semantic color only for status and feedback, predictable interaction states, and calm surfaces. When prose and a token disagree, follow the prose rationale.
|
|
210
|
+
4. **Negative constraints matter.** **Do's and Don'ts** and the **Avoid** / **Must not** rules in Heuristics define character as much as the palette.
|
|
211
|
+
5. **Extension sections are intentional.** Sections beyond the core design.md spec order — **Assets & Motion**, **Heuristics**, **Interaction states**, **Content** — extend the format for Aura. UX playbook guidance lives in this file.
|
|
205
212
|
|
|
206
|
-
|
|
213
|
+
### Alignment with Google design.md
|
|
207
214
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
215
|
+
| Philosophy principle | Aura approach |
|
|
216
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
217
|
+
| Prose carries design intent | Overview, colors, interaction states, content, and do's/don'ts are the primary identity guidance |
|
|
218
|
+
| Tokens referenced in prose | Key roles use `{colors.*}`, `{spacing.*}`, etc. inline; full ramps stay in tables and CSS |
|
|
219
|
+
| Specific reference > vague adjectives | Overview names data-heavy industrial UI; heuristic rules carry constraints |
|
|
220
|
+
| Do's and don'ts as guardrails | Dedicated **Do's and Don'ts** section plus compact severity-rated heuristics |
|
|
221
|
+
| Format extends beyond the spec | Motion, iconography, elevation, copy, accessibility, and extended UX guidance live in extension sections |
|
|
212
222
|
|
|
213
223
|
---
|
|
214
224
|
|
|
215
|
-
|
|
225
|
+
## Colors
|
|
216
226
|
|
|
217
|
-
|
|
227
|
+
Aura color behaves like instrumentation in a control room. Most of the interface is neutral structure; important changes appear as clear signals; decorative color is rare and never competes with status. A screen should still make sense when color is removed, but color should make state faster to recognize.
|
|
218
228
|
|
|
219
|
-
|
|
229
|
+
Use **Base** color for the operating surface: page backgrounds, cards, text, borders, focus, and persistent chrome. This is ~80–90% of the UI.
|
|
220
230
|
|
|
221
|
-
**
|
|
231
|
+
Use **Semantic** color only for status and feedback: info, success, warning, destructive, validation, and operational state. This is ~5–10% of the UI.
|
|
222
232
|
|
|
223
|
-
**
|
|
224
|
-
**App:** `AlertDialog` / confirm flow where supplied by shell
|
|
233
|
+
Use **Decorative** color only for non-status differentiation: accents, avatars, illustrations, and small visual markers that do not imply system health. This is ~5–10% of the UI.
|
|
225
234
|
|
|
226
|
-
|
|
235
|
+
Light-theme reference values for key roles are defined as `colors.*` tokens in the YAML front matter (referenced in tables as `{colors.<name>}`); full ramps and dark-theme values are in the tables below.
|
|
227
236
|
|
|
228
|
-
|
|
229
|
-
- **Must** name what will be destroyed — not generic “Are you sure?”.
|
|
230
|
-
- **Must** label the confirm action with a **specific verb** (“Delete report”), not “OK”.
|
|
231
|
-
- **Should** use **Button** `variant="destructive"` for the confirming destructive action.
|
|
232
|
-
- **Avoid** toast as the **only** safety net for irreversible work.
|
|
237
|
+
Do not hardcode hex, font sizes, or shadow strings in product UI when a token exists.
|
|
233
238
|
|
|
234
|
-
|
|
239
|
+
Aura supports **light** (`:root`) and **dark** (`.dark` / `prefers-color-scheme: dark` per library setup). Semantic and base tokens **resolve to different ramps** per theme. **`background-fixed-dark`**, **`background-fixed-light`**, **`foreground-fixed-*`**, and related **fixed** tokens keep the same appearance in both themes (persistent chrome such as sidebars). Always verify contrast in both themes before shipping.
|
|
235
240
|
|
|
236
|
-
**
|
|
241
|
+
Reference tokens by **full CSS name** or Tailwind token. Never use raw `hex` / `rgb` / `hsl` in product code. If no semantic token fits, use a documented **base** token; **step colors** on ramps (`mountain/*`, `fjord/*`, …) are only for custom, branding, or marketing surfaces where no semantic token exists yet.
|
|
237
242
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
**Rules**
|
|
241
|
-
|
|
242
|
-
- **Must** show errors inline with **HelperText** (or documented `aria-invalid` pattern) on the affected field.
|
|
243
|
-
- **Must** say what is wrong and how to fix it — not only “Invalid”.
|
|
244
|
-
- **Must** gate “next step” until blocking errors are resolved.
|
|
245
|
-
- **Must** use component **`error`** / invalid props where **Input** / **Select** expose them — do not invent parallel red borders.
|
|
246
|
-
- **Should** validate on **blur** when the value is incomplete mid-typing.
|
|
247
|
-
- **Should** validate live when rules are cheap (length, pattern).
|
|
248
|
-
- **Avoid** revealing every error only on final submit with no prior field feedback.
|
|
249
|
-
|
|
250
|
-
#### 4.3 Auto-save and data loss prevention
|
|
251
|
-
|
|
252
|
-
**Applies when:** Edits would be lost on navigation or timeout.
|
|
253
|
-
|
|
254
|
-
**Aura components:** `Banner`, `Badge`, `Dialog`
|
|
255
|
-
**App:** Sonner for “Saved” pulse
|
|
243
|
+
### Common Tailwind mappings
|
|
256
244
|
|
|
257
|
-
**
|
|
245
|
+
Tables in this section use **CSS role names** (e.g. `link-foreground`, `card-background`). Each role maps to a `--color-{role}` custom property and Tailwind v4 utilities (`text-{role}`, `bg-{role}`, `border-{role}`, and `ring-{role}` where applicable). Prefer these utilities over raw `var(--…)` when the theme wire-up matches.
|
|
246
|
+
|
|
247
|
+
| Role (suffix after `text-` / `bg-` / `border-`) | Typical utilities | Notes |
|
|
248
|
+
| ----------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
249
|
+
| `background` | `bg-background` | Page base |
|
|
250
|
+
| `foreground` | `text-foreground` | Primary text |
|
|
251
|
+
| `muted-foreground` | `text-muted-foreground` | Tertiary copy |
|
|
252
|
+
| `card-background` | `bg-card-background` | Cards (see **Card** component) |
|
|
253
|
+
| `muted-background` | `bg-muted-background` | Static fills, inputs, secondary chrome |
|
|
254
|
+
| `border` | `border-border` | Default strokes |
|
|
255
|
+
| `link-foreground` (`{colors.link-foreground}`) | `text-link-foreground` | Text links — same value as `{colors.tertiary}` |
|
|
256
|
+
| `primary-background` | `bg-primary-background`, `text-foreground-on-primary` | Default **Button** (`variant="default"`) pattern |
|
|
257
|
+
| `destructive-background` | `bg-destructive-background`, `text-destructive-foreground-on-critical` (on surface) | Destructive actions — pairings in **Semantic colors** |
|
|
258
|
+
| `info-background`, `success-background`, … | `bg-info-background`, `text-info-foreground`, … | Full names match **Semantic colors** token columns |
|
|
259
|
+
|
|
260
|
+
Semantic utilities use the **full token name** as the Tailwind segment (e.g. `bg-info-background`, not `bg-info`). For **charts**, utilities follow the **Chart tokens** names (`bg-chart-fjord-color-1`, `bg-chart-gridlines`, …).
|
|
261
|
+
|
|
262
|
+
Tables below list **light-theme** values as `{colors.<name>}` token references in the YAML front matter and **dark-theme** resolved values in the second column; the published `colors.css` is the runtime source of truth (some entries are `rgba()`).
|
|
263
|
+
|
|
264
|
+
### Base — Background
|
|
265
|
+
|
|
266
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
267
|
+
| ------------------------------- | ------------------------------------- | ---------------- | ------------------------------------------------------------------ |
|
|
268
|
+
| `background` | `{colors.background}` | `#191B1D` | Primary surface — lowest layer |
|
|
269
|
+
| `alternate-background` | `{colors.alternate-background}` | `#111213` | Distinct layer or block separate from `background` |
|
|
270
|
+
| `card-background` | `{colors.card-background}` | `#212426` | Cards without drop shadow on `background` / `alternate-background` |
|
|
271
|
+
| `muted-background` | `{colors.muted-background}` | `#2D3134` | Static fills for controls, rows, segmented controls |
|
|
272
|
+
| `primary-background` | `{colors.primary}` | `#F9FAFA` | Primary actions (default button); use sparingly |
|
|
273
|
+
| `primary-background-hover` | `{colors.primary-background-hover}` | `#E4E6E8` | Hover on `primary-background` |
|
|
274
|
+
| `secondary-background` | `#E4E6E8` | `#40464A` | Secondary actions, switch track |
|
|
275
|
+
| `secondary-background-hover` | `{colors.secondary-background-hover}` | `#5E666D` | Hover on `secondary-background` |
|
|
276
|
+
| `accent-background` | `#F1F2F3` | `#2D3134` | Neutral hover on `background` / `card-background` (e.g. tabs) |
|
|
277
|
+
| `accent-background-strong` | `#E4E6E8` | `#40464A` | Neutral hover on `muted-background` / `active-muted-background` |
|
|
278
|
+
| `highlight-background` | `#F1F2F3` | `#2D3134` | Focused / active fields (inputs, selects, comboboxes) |
|
|
279
|
+
| `highlight-background-strong` | `#E4E6E8` | `#40464A` | Stronger focused / active field fill |
|
|
280
|
+
| `active-background` | `#191B1D` | `#F9FAFA` | High-contrast “on” (switch, checkbox, radio) |
|
|
281
|
+
| `active-background-hover` | `#2D3134` | `#F1F2F3` | Hover on `active-background` |
|
|
282
|
+
| `active-muted-background` | `#F1F2F3` | `#2D3134` | Lower-contrast selected (e.g. tabs) |
|
|
283
|
+
| `active-muted-background-hover` | `#E4E6E8` | `#40464A` | Hover on `active-muted-background` |
|
|
284
|
+
| `popover-background` | `#FFFFFF` | `#212426` | Top-layer surfaces with shadow (dialogs, popovers) |
|
|
285
|
+
| `raised-background` | `#2D3134` | `#40464A` | Tooltips, Sonner toasts — floats above page |
|
|
286
|
+
| `disabled-background` | `#F1F2F3` | `#2D3134` | Disabled inputs and controls |
|
|
287
|
+
| `overlay-background` | `{colors.overlay-background}` | `#7C868E80` | Scrim behind modals |
|
|
288
|
+
| `background-fixed-dark` | `#212426` | `#212426` | Must stay **dark** in both themes |
|
|
289
|
+
| `background-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay **light** in both themes |
|
|
290
|
+
| `accent-background-fixed-dark` | `#2D3134` | `#2D3134` | Persistent dark accent chrome (e.g. sidebar) |
|
|
291
|
+
|
|
292
|
+
### Base — Foreground
|
|
293
|
+
|
|
294
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
295
|
+
| ---------------------------------- | -------------------------------- | ---------------- | ------------------------------ |
|
|
296
|
+
| `foreground` | `{colors.foreground}` | `#F1F2F3` | Primary text and icons |
|
|
297
|
+
| `secondary-foreground` | `{colors.secondary-foreground}` | `#D4D7D9` | Supporting text and icons |
|
|
298
|
+
| `muted-foreground` | `{colors.muted-foreground}` | `#A5ABB1` | Tertiary / low emphasis |
|
|
299
|
+
| `disabled-foreground` | `#D4D7D9` | `#5E666D` | Disabled text and icons |
|
|
300
|
+
| `link-foreground` | `{colors.link-foreground}` | `#1742E7` | Text links |
|
|
301
|
+
| `foreground-on-primary` | `{colors.foreground-on-primary}` | `#191B1D` | On `primary-background` |
|
|
302
|
+
| `foreground-on-active` | `#F1F2F3` | `#191B1D` | On `active-background` |
|
|
303
|
+
| `active-foreground` | `#191B1D` | `#F1F2F3` | On `active-muted-background` |
|
|
304
|
+
| `foreground-fixed-dark` | `#191B1D` | `#191B1D` | Must stay dark in both themes |
|
|
305
|
+
| `foreground-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay light in both themes |
|
|
306
|
+
| `foreground-secondary-fixed-dark` | `#40464A` | `#40464A` | Secondary copy, always dark |
|
|
307
|
+
| `secondary-foreground-fixed-light` | `#D4D7D9` | `#D4D7D9` | Secondary copy, always light |
|
|
308
|
+
| `muted-foreground-fixed-light` | `#BBC0C4` | `#BBC0C4` | Muted copy, always light |
|
|
309
|
+
|
|
310
|
+
### Base — Borders and focus
|
|
311
|
+
|
|
312
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
313
|
+
| ------------------- | ---------------------------- | ---------------- | ------------------------------------------------ |
|
|
314
|
+
| `border` | `{colors.border}` | `#2D3134` | Default strokes |
|
|
315
|
+
| `border-emphasized` | `{colors.border-emphasized}` | `#40464A` | Stronger separation |
|
|
316
|
+
| `border-on-dark` | `#2D3134` | `#2D3134` | Strokes on dark chrome (both themes) |
|
|
317
|
+
| `border-active` | `#191B1D` | `#F9FAFA` | Active / toggled outlines |
|
|
318
|
+
| `ring` | `{colors.ring}` | `#7081C7` | Focus ring outer (maps to `--shadow-focus-ring`) |
|
|
319
|
+
| `ring-muted` | `{colors.ring-muted}` | `#B5BEE2` | Focus ring inner companion |
|
|
258
320
|
|
|
259
|
-
|
|
260
|
-
- **Must** warn before discard navigation (**Dialog** confirm) when changes are unsaved.
|
|
261
|
-
- **Should** show “Saved” / timestamp feedback (toast or inline) after auto-save.
|
|
321
|
+
Also generated: `ring-destructive`, `ring-destructive-muted` for destructive / invalid focus (see **Effects — Focus rings**).
|
|
262
322
|
|
|
263
|
-
|
|
323
|
+
### Semantic colors
|
|
264
324
|
|
|
265
|
-
**
|
|
325
|
+
Semantic tokens are **only** for status and system feedback (Alert, Banner, Sonner, badge status variants, validation). Do not use them as generic fills or decoration.
|
|
266
326
|
|
|
267
|
-
**
|
|
268
|
-
**App:** Sonner with undo
|
|
327
|
+
Each family has **default** pairings (theme-switching surfaces) and **muted** pairings (blocks on **persistent dark chrome**). On muted surfaces, use the same `*-foreground-on-*` token names with the muted background; verify contrast in context.
|
|
269
328
|
|
|
270
|
-
**
|
|
329
|
+
**Info**
|
|
271
330
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
-
|
|
331
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
332
|
+
| ------------------------- | ---------------------------------- | ---------------- | ----------------------------------------------------------------------------- |
|
|
333
|
+
| `info-background` | `{colors.info-background}` | `#B5BEE2` | Info surface |
|
|
334
|
+
| `info-background-hover` | `#B5BEE2` | `#D0D6ED` | Hover on `info-background` |
|
|
335
|
+
| `info-foreground` | `#4A5FB8` | `#9DA9D9` | Text near info context on standard surfaces |
|
|
336
|
+
| `info-foreground-on-info` | `{colors.info-foreground-on-info}` | `#1A2242` | Text **on** `info-background` |
|
|
337
|
+
| `info-muted-background` | `#F0F2F9` | `#2D3134` | Info tint on dark chrome |
|
|
338
|
+
| _(pairing)_ | — | — | On `info-muted-background`, use `info-foreground-on-info` for on-surface copy |
|
|
275
339
|
|
|
276
|
-
|
|
340
|
+
**Success**
|
|
277
341
|
|
|
278
|
-
|
|
342
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
343
|
+
| ------------------------------- | ---------------------------------------- | ---------------- | ------------------------------------------------------------------ |
|
|
344
|
+
| `success-background` | `{colors.success-background}` | `#8BDEAE` | Success surface |
|
|
345
|
+
| `success-background-hover` | `#8BDEAE` | `#BBF3D0` | Hover on `success-background` |
|
|
346
|
+
| `success-foreground` | `#1C984A` | `#24C45E` | Text near success on standard surfaces |
|
|
347
|
+
| `success-foreground-on-success` | `{colors.success-foreground-on-success}` | `#0A381C` | Text **on** `success-background` |
|
|
348
|
+
| `success-muted-background` | `#DDF9E7` | `#2D3134` | Success on dark chrome |
|
|
349
|
+
| _(pairing)_ | — | — | On `success-muted-background`, use `success-foreground-on-success` |
|
|
279
350
|
|
|
280
|
-
|
|
351
|
+
**Warning**
|
|
281
352
|
|
|
282
|
-
|
|
353
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
354
|
+
| ------------------------------- | ---------------------------------------- | ---------------- | -------------------------------------- |
|
|
355
|
+
| `warning-background` | `{colors.warning-background}` | `#FFE3A2` | Warning surface |
|
|
356
|
+
| `warning-background-hover` | `#FFD062` | `#FFF1D0` | Hover on `warning-background` |
|
|
357
|
+
| `warning-foreground` | `#C18800` | `#D8BF00` | Text near warning on standard surfaces |
|
|
358
|
+
| `warning-foreground-on-warning` | `{colors.warning-foreground-on-warning}` | `#5B4000` | Text **on** `warning-background` |
|
|
359
|
+
| `warning-muted-background` | `#FFF1D0` | `#2D3134` | Warning on dark chrome |
|
|
283
360
|
|
|
284
|
-
**
|
|
361
|
+
**Destructive**
|
|
285
362
|
|
|
286
|
-
|
|
363
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
364
|
+
| ------------------------------------ | --------------------------------------------- | ---------------- | -------------------------------------------------- |
|
|
365
|
+
| `destructive-background` | `{colors.destructive-background}` | `#FAA9B7` | Error / destructive surface |
|
|
366
|
+
| `destructive-background-hover` | `#FAA9B7` | `#FCCAD2` | Hover on `destructive-background` |
|
|
367
|
+
| `destructive-foreground` | `#CB0B2C` | `#F65E78` | Text near destructive context on standard surfaces |
|
|
368
|
+
| `destructive-foreground-on-critical` | `{colors.destructive-foreground-on-critical}` | `#8D081F` | Text **on** `destructive-background` |
|
|
369
|
+
| `destructive-muted-background` | `#FDDEE4` | `#2D3134` | Destructive on dark chrome |
|
|
370
|
+
| `destructive-muted-background-hover` | `#FCCAD2` | `#40464A` | Hover on `destructive-muted-background` |
|
|
287
371
|
|
|
288
|
-
**
|
|
372
|
+
**Neutral** (status: draft, archived — not “semantic calm” in the same sense as info/success)
|
|
289
373
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
-
|
|
293
|
-
-
|
|
374
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
375
|
+
| ------------------------------- | ----------------- | ---------------- | -------------------------------- |
|
|
376
|
+
| `neutral-background` | `#E4E6E8` | `#D4D7D9` | Neutral status surface |
|
|
377
|
+
| `neutral-background-hover` | `#D4D7D9` | `#E4E6E8` | Hover on `neutral-background` |
|
|
378
|
+
| `neutral-foreground` | `#52595F` | `#A5ABB1` | Text near neutral status |
|
|
379
|
+
| `neutral-foreground-on-neutral` | `#40464A` | `#2D3134` | Text **on** `neutral-background` |
|
|
380
|
+
| `neutral-muted-background` | `#F1F2F3` | `#2D3134` | Neutral on dark chrome |
|
|
294
381
|
|
|
295
|
-
|
|
382
|
+
**Naming:** CSS uses full role names (`info-foreground-on-info`, `neutral-foreground-on-neutral`, `destructive-foreground-on-critical`). There is no shortened alias in the theme.
|
|
296
383
|
|
|
297
|
-
|
|
384
|
+
### Decorative colors
|
|
298
385
|
|
|
299
|
-
**
|
|
300
|
-
**App:** table selection, **ActionToolbar** pattern
|
|
386
|
+
For **small accents** (badges, avatars, empty states) where color differentiates but does **not** signal status — use **Chart tokens** for plot colors, not this ramp, unless a design explicitly maps a tile to a series color. Pattern: `decorative-background-{ramp}`, `decorative-background-{ramp}-hover`, `decorative-foreground-{ramp}`.
|
|
301
387
|
|
|
302
|
-
**
|
|
388
|
+
**Preference order for new work:**
|
|
303
389
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
390
|
+
| Priority | Ramp | Background | Foreground |
|
|
391
|
+
| -------- | -------- | -------------------------------- | -------------------------------- |
|
|
392
|
+
| 1 | Fjord | `decorative-background-fjord` | `decorative-foreground-fjord` |
|
|
393
|
+
| 2 | Nordic | `decorative-background-nordic` | `decorative-foreground-nordic` |
|
|
394
|
+
| 3 | Aurora | `decorative-background-aurora` | `decorative-foreground-aurora` |
|
|
395
|
+
| 4 | Dusk | `decorative-background-dusk` | `decorative-foreground-dusk` |
|
|
396
|
+
| 5 | Orange | `decorative-background-orange` | `decorative-foreground-orange` |
|
|
397
|
+
| 6 | Sky | `decorative-background-sky` | `decorative-foreground-sky` |
|
|
398
|
+
| 7 | Mountain | `decorative-background-mountain` | `decorative-foreground-mountain` |
|
|
308
399
|
|
|
309
|
-
|
|
400
|
+
Example (fjord ramp): light `decorative-background-fjord` → `#CCD5FA` (fjord-200), `decorative-foreground-fjord` → `#1234B6` (fjord-700); dark → `#AEBDF7` / `#0D2582` (fjord-300 / fjord-800).
|
|
310
401
|
|
|
311
|
-
|
|
402
|
+
### Chart tokens
|
|
312
403
|
|
|
313
|
-
**
|
|
404
|
+
**Priority rule:** use `chart-*` for any data plotted on axes or series; use `decorative-*` for non-data visual differentiation (tiles, avatars, accents); use semantic tokens (`info-*`, `success-*`, `warning-*`, `destructive-*`) for operational status and feedback only. Never swap between these groups.
|
|
314
405
|
|
|
315
|
-
|
|
406
|
+
| Token | Use |
|
|
407
|
+
| ----------------------------------------------- | ----------------------------------------------------------- |
|
|
408
|
+
| `chart-{ramp}-color-1` … `chart-{ramp}-color-6` | Alpha-based series / area-fill steps (strongest → lightest) |
|
|
409
|
+
| `chart-gridlines` | Grid lines |
|
|
316
410
|
|
|
317
|
-
|
|
318
|
-
- **Should** explain what the view is for and how to populate it.
|
|
319
|
-
- **Should** use **HelperText** / **Tooltip** for compact role- or context-specific hints.
|
|
320
|
-
- **Avoid** using **Banner** for long onboarding tours if **Banner** is already the channel for critical system alerts — mixed priority dilutes both.
|
|
411
|
+
Default series order: **fjord → nordic → aurora → dusk → orange**.
|
|
321
412
|
|
|
322
413
|
---
|
|
323
414
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
Information **must** be scannable and oriented before action.
|
|
327
|
-
|
|
328
|
-
#### 6.1 Grouping and proximity
|
|
329
|
-
|
|
330
|
-
**Applies when:** Forms, settings, detail layouts.
|
|
331
|
-
|
|
332
|
-
**Aura components:** `Card`, `InputGroup`, `Accordion`, `Separator`, `Label`
|
|
333
|
-
|
|
334
|
-
**Rules**
|
|
335
|
-
|
|
336
|
-
- **Must** group related fields in one **Card** or labeled section.
|
|
337
|
-
- **Must** use **Separator** between unrelated groups in the same container.
|
|
338
|
-
- **Must** use **InputGroup** when addons and input share one logical value.
|
|
339
|
-
- **Should** use **Accordion** for distinct sub-topics in long settings.
|
|
340
|
-
- **Avoid** unrelated primary actions in the same **Card** as sensitive fields without hierarchy.
|
|
341
|
-
|
|
342
|
-
#### 6.2 Persistent actions and navigation
|
|
343
|
-
|
|
344
|
-
**Applies when:** Global vs page-local actions.
|
|
345
|
-
|
|
346
|
-
**Aura components:** `Button`, `DropdownMenu`
|
|
347
|
-
**Fusion shell:** `Topbar`, `Tabs`, `SegmentedControl` — follow shell **SKILL** / **RULES** where your repo defines them
|
|
348
|
-
|
|
349
|
-
**Rules**
|
|
350
|
-
|
|
351
|
-
- **Must** keep **one** clear **primary** CTA per view in content; put global-only actions in shell chrome, page actions in page header/toolbar.
|
|
352
|
-
- **Must** use shell **Tabs** / **SegmentedControl** for primary view switching when the product uses that pattern — do not duplicate the same navigation inline without reason.
|
|
353
|
-
- **Avoid** duplicating shell navigation inside content.
|
|
354
|
-
|
|
355
|
-
#### 6.3 Visual hierarchy
|
|
356
|
-
|
|
357
|
-
**Applies when:** Any view with competing focal points.
|
|
358
|
-
|
|
359
|
-
**Aura components:** `Button`, `Badge`, `Alert`, `Label`
|
|
360
|
-
|
|
361
|
-
**Rules**
|
|
362
|
-
|
|
363
|
-
- **Must** limit **primary** (`default` **Button**) to one obvious main action per view.
|
|
364
|
-
- **Must** use **semantic tokens** for status (**Tokens** § Semantic) — no arbitrary hex.
|
|
365
|
-
- **Must not** use **Button** `destructive` for non-destructive actions.
|
|
366
|
-
- **Should** use type scale, weight, and spacing (**Tokens** § Typography / spacing) to lead attention.
|
|
367
|
-
|
|
368
|
-
#### 6.4 Responsive behaviour
|
|
415
|
+
## Typography
|
|
369
416
|
|
|
370
|
-
**
|
|
417
|
+
Aura uses **Inter** for product UI, **Space Grotesk** for marketing display, and **Source Code Pro** for monospace. The type scale balances density for data interfaces with readable body copy at `{typography.body-md.fontSize}`.
|
|
371
418
|
|
|
372
|
-
|
|
373
|
-
|
|
419
|
+
| Token | Font | Use |
|
|
420
|
+
| ------------------------------ | --------------- | ----------------------------------- |
|
|
421
|
+
| `--font-sans` / `--font-inter` | Inter | Default UI — copy, labels, dense UI |
|
|
422
|
+
| `--font-marketing` | Space Grotesk | Marketing / display headings only |
|
|
423
|
+
| `--font-mono` | Source Code Pro | Code, technical strings |
|
|
374
424
|
|
|
375
|
-
**
|
|
425
|
+
**Type scale** — values live in the YAML `typography` tokens. Typical **semantic styles** map as follows:
|
|
376
426
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
427
|
+
| Style | Token | Tailwind class | Use |
|
|
428
|
+
| --------- | ---------------------- | -------------- | ------------------------ |
|
|
429
|
+
| `display` | `{typography.display}` | `text-5xl` | Hero / marketing display |
|
|
430
|
+
| `h1` | `{typography.h1}` | `text-4xl` | Page title |
|
|
431
|
+
| `h2` | `{typography.h2}` | `text-3xl` | Section title |
|
|
432
|
+
| `h3` | `{typography.h3}` | `text-2xl` | Subsection |
|
|
433
|
+
| `h4` | `{typography.h4}` | `text-xl` | Group label |
|
|
434
|
+
| `body-md` | `{typography.body-md}` | `text-base` | Default body |
|
|
435
|
+
| `body-sm` | `{typography.body-sm}` | `text-sm` | Secondary body |
|
|
436
|
+
| `label` | `{typography.label}` | `text-xs` | Form labels, compact UI |
|
|
437
|
+
| `code` | `{typography.code}` | `text-sm` | Monospace content |
|
|
380
438
|
|
|
381
439
|
---
|
|
382
440
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
Aura targets **WCAG AA** for primitives — usage must preserve that.
|
|
386
|
-
|
|
387
|
-
#### 7.1 Keyboard accessibility
|
|
388
|
-
|
|
389
|
-
**Applies when:** Any interactive **Aura** component or custom control.
|
|
390
|
-
|
|
391
|
-
**Rules**
|
|
392
|
-
|
|
393
|
-
- **Must** complete every task path with keyboard alone — do not break Radix / Base focus traps or `Tab` order.
|
|
394
|
-
- **Must** keep a visible **focus** treatment per **Interaction states** — never `outline-none` / `ring-0` **without** Aura’s `shadow-focus-ring` equivalent.
|
|
395
|
-
- **Must** expose **DropdownMenu**, **Dialog**, and other overlays via keyboard, not pointer-only triggers.
|
|
396
|
-
- **Avoid** critical behavior on `onMouseEnter` / `onMouseLeave` without a keyboard-accessible path.
|
|
397
|
-
|
|
398
|
-
#### 7.2 Color contrast and readability
|
|
441
|
+
## Layout
|
|
399
442
|
|
|
400
|
-
|
|
443
|
+
### Dashboard quick start (agent checklist)
|
|
401
444
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
- **Must** use **Tokens** for color — no stray hex / arbitrary Tailwind color literals.
|
|
405
|
-
- **Must not** override colors in ways that drop below **4.5:1** for normal text (or **3:1** for large text) against its background.
|
|
406
|
-
- **Must not** encode meaning with **color alone** — pair with icon, **HelperText**, or label.
|
|
407
|
-
- **Avoid** `muted-foreground` for text the user must read to complete a task.
|
|
408
|
-
|
|
409
|
-
#### 7.3 ARIA and semantic markup
|
|
410
|
-
|
|
411
|
-
**Applies when:** Composing Aura primitives or wrapping native elements.
|
|
412
|
-
|
|
413
|
-
**Rules**
|
|
414
|
-
|
|
415
|
-
- **Must** use each primitive for its intended role — not **Button** as navigation that should be `<a>`.
|
|
416
|
-
- **Must** name icon-only controls (`aria-label` / `aria-labelledby`) and supply **Tooltip** where design hides text.
|
|
417
|
-
- **Should** use landmark elements (`main`, `nav`, `header`) at page level alongside Aura layout.
|
|
418
|
-
- **Avoid** stripping default ARIA from primitives without an equivalent.
|
|
419
|
-
|
|
420
|
-
#### 7.4 Touch and click targets
|
|
421
|
-
|
|
422
|
-
**Applies when:** Touch or motor accessibility matters.
|
|
423
|
-
|
|
424
|
-
**Rules**
|
|
445
|
+
For pages with data-heavy layouts — cards, charts, metric tiles — work through these steps before writing component code.
|
|
425
446
|
|
|
426
|
-
- **
|
|
427
|
-
- **
|
|
428
|
-
- **
|
|
447
|
+
- [ ] **Tokens** — confirm all colors use semantic or chart tokens, no raw hex. Metric tiles: `decorative-*`. Data series: `chart-*`. Status: `info-*`, `success-*`, `warning-*`, `destructive-*`. See [Colors](#colors).
|
|
448
|
+
- [ ] **Layout** — use a 12-column grid with `gap-4` or `gap-6`. Tile widths: `col-span-12 sm:col-span-6 lg:col-span-3`. Cap the page frame with `max-w-[min(100%,var(--container-8xl))]`.
|
|
449
|
+
- [ ] **Cards** — use the `Card` component with title, description, and a primary action. Do not stack unrelated actions in the same card. See [Layout and hierarchy](#6-layout-and-hierarchy).
|
|
450
|
+
- [ ] **Loading states** — every data region must show `Shimmer` (known layout) or `Loader` (unknown layout) while fetching. See [Feedback and system status](#1-feedback-and-system-status).
|
|
451
|
+
- [ ] **Status signals** — default to **Badge** or compact status cards for repeated states; keep **Alert** to one page-level inline instance unless multiple independent incidents each need separate action. See [Alert vs Banner vs Badge vs Sonner](#alert-vs-banner-vs-badge-vs-sonner).
|
|
452
|
+
- [ ] **Navigation** — one primary app chrome; avoid duplicating global navigation inside content. See [Layout and hierarchy](#6-layout-and-hierarchy).
|
|
453
|
+
- [ ] **Accessibility** — every chart must have a text summary of key insights. Icon-only controls must have `aria-label` and a `Tooltip`. See [Accessibility and inclusive design](#7-accessibility-and-inclusive-design).
|
|
429
454
|
|
|
430
|
-
###
|
|
455
|
+
### Layout and spacing
|
|
431
456
|
|
|
432
|
-
|
|
457
|
+
Width and spacing values in this subsection follow the **`{spacing.base}`-based** spacing scale in **[Layout → Size and dimensions](#size-and-dimensions)**.
|
|
433
458
|
|
|
434
|
-
**
|
|
459
|
+
**Body text reading width**
|
|
435
460
|
|
|
436
|
-
|
|
461
|
+
- **Must** cap **continuous body text** (paragraphs, descriptions, long labels) at a **maximum width of `{spacing.prose-max}`** for comfortable reading.
|
|
462
|
+
- **Must** apply that limit to the **text column only** — companion UI (icons, thumbnails, side metadata, charts, code blocks) **may** sit outside that `{spacing.prose-max}` band in the same row or card; do not shrink the text measure to absorb those elements.
|
|
463
|
+
- **Should** implement the cap with `max-w-[{spacing.prose-max}]` / `max-w-[37.5rem]` (or an equivalent layout wrapper) on the text block, not by stretching typography alone inside an arbitrarily wide container.
|
|
437
464
|
|
|
438
|
-
|
|
465
|
+
### Size and dimensions
|
|
439
466
|
|
|
440
|
-
|
|
467
|
+
Aura aligns to a **`{spacing.base}` base grid**. Spacing in components follows **Tailwind spacing** (`p-*`, `gap-*`, `m-*`): one unit = **`{spacing.base}`** unless overridden. Common steps:
|
|
441
468
|
|
|
442
|
-
|
|
469
|
+
| Name | Token | Tailwind | Typical use |
|
|
470
|
+
| ---- | --------------- | -------- | -------------------------------- |
|
|
471
|
+
| xs | `{spacing.xs}` | `1` | Tight gaps, icon padding |
|
|
472
|
+
| sm | `{spacing.sm}` | `2` | Inline controls, compact padding |
|
|
473
|
+
| md | `{spacing.md}` | `3` | Card / popover internal padding |
|
|
474
|
+
| lg | `{spacing.lg}` | `4` | Related groups |
|
|
475
|
+
| xl | `{spacing.xl}` | `5` | Sections |
|
|
476
|
+
| 2xl | `{spacing.2xl}` | `6` | Page regions |
|
|
477
|
+
| 3xl | `{spacing.3xl}` | `8` | Large layout gaps |
|
|
443
478
|
|
|
444
|
-
|
|
479
|
+
Layout helpers in theme: `--container-2xl` (`{spacing.container-2xl}`), `--container-8xl` (`{spacing.container-8xl}`), `--message-content-max-width` (80% for chat content).
|
|
445
480
|
|
|
446
|
-
|
|
481
|
+
### Width and max content
|
|
447
482
|
|
|
448
|
-
|
|
483
|
+
Aura adjusts Tailwind **container** breakpoints where the default scale is too wide or too narrow for data-dense product surfaces:
|
|
449
484
|
|
|
450
|
-
|
|
485
|
+
| Token | Value | Role |
|
|
486
|
+
| ----------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
487
|
+
| `--container-2xl` | `{spacing.container-2xl}` | Narrower than Tailwind’s default `2xl` container — useful outer bound for regions; **body copy** inside can still follow the **`{spacing.prose-max}`** reading rule above |
|
|
488
|
+
| `--container-8xl` | `{spacing.container-8xl}` | Wide upper bound for dashboards and full-bleed marketing rows |
|
|
451
489
|
|
|
452
|
-
|
|
490
|
+
Prefer **`max-w-*`** (and other width utilities) tied to the theme over ad-hoc pixel `max-width` on wrappers. **Global frame** width (host chrome) is defined by the **host application**; **inside** the frame, combine these tokens with responsive utilities so regions reflow predictably.
|
|
453
491
|
|
|
454
|
-
|
|
492
|
+
### Specialized variables
|
|
455
493
|
|
|
456
|
-
|
|
494
|
+
| Variable | Value | Use |
|
|
495
|
+
| ----------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
496
|
+
| `--message-content-max-width` | `80%` | Primary column for chat / assistant **Message** content in wide threads |
|
|
497
|
+
| `--drawer-max-height` | `80vh` | Maximum height for top/bottom drawer-style panels when the host implements them |
|
|
498
|
+
| `--alert-icon-width` | `calc(var(--spacing) * 4)` (typically **16px**) | Fixed icon column in the **Alert** layout so titles and descriptions align |
|
|
457
499
|
|
|
458
|
-
|
|
500
|
+
### Regional spacing
|
|
459
501
|
|
|
460
|
-
|
|
502
|
+
- **Must** use the **spacing scale** for padding, margin, and `gap` between regions (`gap-*`, `p-*`, `m-*`) — see **Layout → Size and dimensions**.
|
|
503
|
+
- **Should** keep major block **padding** and **gap** on **`{spacing.base}`** multiples so control heights, radii, and typography line up visually.
|
|
504
|
+
- **Should** group related regions in **Card** (and **Separator** when two unrelated groups share a container) before mixing unrelated actions into the same band — see [Layout and hierarchy](#6-layout-and-hierarchy).
|
|
505
|
+
- **Avoid** one-off pixel gutters that ignore the scale unless matching a fixed graphic asset.
|
|
461
506
|
|
|
462
|
-
|
|
507
|
+
### Responsive behavior
|
|
463
508
|
|
|
464
|
-
|
|
509
|
+
- **Should** move secondary work into **Dialog** or a shell **Drawer** on narrow widths instead of compressing multi-column chrome.
|
|
510
|
+
- **Avoid** single-breakpoint layouts tuned only to a static design frame — use breakpoints, wrapping, and flexible sizing utilities where content must grow and shrink.
|
|
465
511
|
|
|
466
|
-
|
|
512
|
+
### Shell vs content
|
|
467
513
|
|
|
468
|
-
-
|
|
469
|
-
- Keep **Must** / **Should** / **Avoid** / **must not** wording — severity is the routing signal.
|
|
470
|
-
- Keep each **Applies when:** line — it tells the agent which subsection fires.
|
|
471
|
-
- Keep **Aura components:** lines aligned with [`src/components/index.ts`](./src/components/index.ts) exports (public entry for `@cognite/aura/components`); treat **App / Fusion shell** lines as integration responsibilities, not as Aura package exports.
|
|
472
|
-
- Preserve links: [Aura Storybook](https://storybook-aura-23638.fusion-preview.preview.cogniteapp.com); [Aura documentation](https://docs.cognite.com/aura-design-system/get-started) for published guides. Fetch current prop names from Storybook or source before codegen.
|
|
473
|
-
- If you split by section (§1–§7), repeat the **Severity** and **Scope** bullets at the top of each file so standalone chunks stay interpretable.
|
|
474
|
-
- Preserve **[Content](#content)** for action verbs, date/time rules, and tone; agents generating strings should follow it alongside **Heuristics**.
|
|
514
|
+
**Global chrome** (workspace switcher, app-level navigation) is implemented by the **host application shell**, not the Aura component library. **Must** still theme that chrome with Aura **tokens** so shell and in-app surfaces feel continuous. **In-app content** should rely on Aura primitives (**Card**, **Banner**, **Dialog**, forms) plus the width and spacing rules above.
|
|
475
515
|
|
|
476
516
|
---
|
|
477
517
|
|
|
478
|
-
##
|
|
479
|
-
|
|
480
|
-
**What this section is:** The token reference for Aura — color (base, semantic, decorative), typography, spacing, radii, borders, and effects. Consume tokens via **CSS variables** (e.g. `var(--background)`) or **Tailwind theme** utilities (e.g. `bg-background`, `text-muted-foreground`, `shadow-default`, `rounded-lg`). Do not hardcode hex, font sizes, or shadow strings in product UI when a token exists.
|
|
481
|
-
|
|
482
|
-
**Theming:** Aura supports **light** (`:root`) and **dark** (`.dark` / `prefers-color-scheme: dark` per library setup). Semantic and base tokens **resolve to different ramps** per theme. **`background-fixed-dark`**, **`background-fixed-light`**, **`foreground-fixed-*`**, and related **fixed** tokens keep the same appearance in both themes (persistent chrome such as sidebars). Always verify contrast in both themes in Storybook or the consuming app.
|
|
483
|
-
|
|
484
|
-
**Agents:** Reference tokens by **full CSS name** or Tailwind token. Never use raw `hex` / `rgb` / `hsl` in product code. If no semantic token fits, use a documented **base** token; **step colors** on ramps (`mountain/*`, `fjord/*`, …) are only for custom, branding, or marketing surfaces where no semantic token exists yet.
|
|
485
|
-
|
|
486
|
-
### Common Tailwind mappings
|
|
487
|
-
|
|
488
|
-
Tables in this section use **CSS role names** (e.g. `link-foreground`, `card-background`). Aura registers each role as `--color-{role}` in `@theme inline` in [`src/colors.css`](./src/colors.css); Tailwind v4 exposes utilities **`text-{role}`**, **`bg-{role}`**, **`border-{role}`** (and **`ring-{role}`** / **`shadow-*`** where documented in **Effects**). Prefer these utilities in components over raw `var(--…)` when the theme wire-up matches.
|
|
489
|
-
|
|
490
|
-
| Role (suffix after `text-` / `bg-` / `border-`) | Typical utilities | Notes |
|
|
491
|
-
| :--- | :--- | :--- |
|
|
492
|
-
| `background` | `bg-background` | Page base |
|
|
493
|
-
| `foreground` | `text-foreground` | Primary text |
|
|
494
|
-
| `muted-foreground` | `text-muted-foreground` | Tertiary copy |
|
|
495
|
-
| `card-background` | `bg-card-background` | Cards (see **Card** component) |
|
|
496
|
-
| `muted-background` | `bg-muted-background` | Static fills, inputs, secondary chrome |
|
|
497
|
-
| `border` | `border-border` | Default strokes |
|
|
498
|
-
| `link-foreground` | `text-link-foreground` | Text links |
|
|
499
|
-
| `primary-background` | `bg-primary-background`, `text-foreground-on-primary` | Default **Button** (`variant="default"`) pattern |
|
|
500
|
-
| `destructive-background` | `bg-destructive-background`, `text-destructive-foreground-on-critical` (on surface) | Destructive actions — pairings in **Semantic colors** |
|
|
501
|
-
| `info-background`, `success-background`, … | `bg-info-background`, `text-info-foreground`, … | Full names match **Semantic colors** token columns |
|
|
502
|
-
|
|
503
|
-
Semantic utilities use the **full token name** as the Tailwind segment (e.g. `bg-info-background`, not `bg-info`). For **charts**, utilities follow the **Chart tokens** names (`bg-chart-fjord-color-1`, `bg-chart-gridlines`, …). For exhaustive coverage, use [`src/colors.css`](./src/colors.css) or your IDE on `@cognite/aura`.
|
|
504
|
-
|
|
505
|
-
Tables below list **approximate hex** resolved from [`src/colors.css`](./src/colors.css) at build time; the source of truth is the synced file (some entries are `rgba()`).
|
|
506
|
-
|
|
507
|
-
### Color
|
|
508
|
-
|
|
509
|
-
Aura groups color into **Base** (~80–90% of UI), **Semantic** (status and feedback, ~5–10%), and **Decorative** (accents and illustration, ~5–10%) so color carries **meaning** and stays calm.
|
|
510
|
-
|
|
511
|
-
#### Base — Background
|
|
512
|
-
|
|
513
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
514
|
-
| :--- | :--- | :--- | :--- |
|
|
515
|
-
| `background` | `#FFFFFF` | `#191B1D` | Primary surface — lowest layer |
|
|
516
|
-
| `alternate-background` | `#F9FAFA` | `#111213` | Distinct layer or block separate from `background` |
|
|
517
|
-
| `card-background` | `#F9FAFA` | `#212426` | Cards without drop shadow on `background` / `alternate-background` |
|
|
518
|
-
| `muted-background` | `#F1F2F3` | `#2D3134` | Static fills for controls, rows, segmented controls |
|
|
519
|
-
| `primary-background` | `#212426` | `#F9FAFA` | Primary actions (default button); use sparingly |
|
|
520
|
-
| `primary-background-hover` | `#40464A` | `#E4E6E8` | Hover on `primary-background` |
|
|
521
|
-
| `secondary-background` | `#E4E6E8` | `#40464A` | Secondary actions, switch track |
|
|
522
|
-
| `secondary-background-hover` | `#D4D7D9` | `#5E666D` | Hover on `secondary-background` |
|
|
523
|
-
| `accent-background` | `#F1F2F3` | `#2D3134` | Neutral hover on `background` / `card-background` (e.g. tabs) |
|
|
524
|
-
| `accent-background-strong` | `#E4E6E8` | `#40464A` | Neutral hover on `muted-background` / `active-muted-background` |
|
|
525
|
-
| `highlight-background` | `#F1F2F3` | `#2D3134` | Focused / active fields (inputs, selects, comboboxes) |
|
|
526
|
-
| `highlight-background-strong` | `#E4E6E8` | `#40464A` | Stronger focused / active field fill |
|
|
527
|
-
| `active-background` | `#191B1D` | `#F9FAFA` | High-contrast “on” (switch, checkbox, radio) |
|
|
528
|
-
| `active-background-hover` | `#2D3134` | `#F1F2F3` | Hover on `active-background` |
|
|
529
|
-
| `active-muted-background` | `#F1F2F3` | `#2D3134` | Lower-contrast selected (e.g. tabs) |
|
|
530
|
-
| `active-muted-background-hover` | `#E4E6E8` | `#40464A` | Hover on `active-muted-background` |
|
|
531
|
-
| `popover-background` | `#FFFFFF` | `#212426` | Top-layer surfaces with shadow (dialogs, popovers) |
|
|
532
|
-
| `raised-background` | `#2D3134` | `#40464A` | Tooltips, Sonner toasts — floats above page |
|
|
533
|
-
| `disabled-background` | `#F1F2F3` | `#2D3134` | Disabled inputs and controls |
|
|
534
|
-
| `overlay-background` | `#7C868E80` | `#7C868E80` | Scrim behind modals |
|
|
535
|
-
| `background-fixed-dark` | `#212426` | `#212426` | Must stay **dark** in both themes |
|
|
536
|
-
| `background-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay **light** in both themes |
|
|
537
|
-
| `accent-background-fixed-dark` | `#2D3134` | `#2D3134` | Persistent dark accent chrome (e.g. sidebar) |
|
|
538
|
-
|
|
539
|
-
#### Base — Foreground
|
|
540
|
-
|
|
541
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
542
|
-
| :--- | :--- | :--- | :--- |
|
|
543
|
-
| `foreground` | `#191B1D` | `#F1F2F3` | Primary text and icons |
|
|
544
|
-
| `secondary-foreground` | `#40464A` | `#D4D7D9` | Supporting text and icons |
|
|
545
|
-
| `muted-foreground` | `#6D767E` | `#A5ABB1` | Tertiary / low emphasis |
|
|
546
|
-
| `disabled-foreground` | `#D4D7D9` | `#5E666D` | Disabled text and icons |
|
|
547
|
-
| `link-foreground` | `#486AED` | `#1742E7` | Text links |
|
|
548
|
-
| `foreground-on-primary` | `#F1F2F3` | `#191B1D` | On `primary-background` |
|
|
549
|
-
| `foreground-on-active` | `#F1F2F3` | `#191B1D` | On `active-background` |
|
|
550
|
-
| `active-foreground` | `#191B1D` | `#F1F2F3` | On `active-muted-background` |
|
|
551
|
-
| `foreground-fixed-dark` | `#191B1D` | `#191B1D` | Must stay dark in both themes |
|
|
552
|
-
| `foreground-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay light in both themes |
|
|
553
|
-
| `foreground-secondary-fixed-dark` | `#40464A` | `#40464A` | Secondary copy, always dark |
|
|
554
|
-
| `secondary-foreground-fixed-light` | `#D4D7D9` | `#D4D7D9` | Secondary copy, always light |
|
|
555
|
-
| `muted-foreground-fixed-light` | `#BBC0C4` | `#BBC0C4` | Muted copy, always light |
|
|
556
|
-
|
|
557
|
-
#### Base — Borders and focus
|
|
558
|
-
|
|
559
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
560
|
-
| :--- | :--- | :--- | :--- |
|
|
561
|
-
| `border` | `#E4E6E8` | `#2D3134` | Default strokes |
|
|
562
|
-
| `border-emphasized` | `#D4D7D9` | `#40464A` | Stronger separation |
|
|
563
|
-
| `border-on-dark` | `#2D3134` | `#2D3134` | Strokes on dark chrome (both themes) |
|
|
564
|
-
| `border-active` | `#191B1D` | `#F9FAFA` | Active / toggled outlines |
|
|
565
|
-
| `ring` | `#7081C7` | `#7081C7` | Focus ring outer (maps to `--shadow-focus-ring`) |
|
|
566
|
-
| `ring-muted` | `#B5BEE2` | `#B5BEE2` | Focus ring inner companion |
|
|
567
|
-
|
|
568
|
-
Also generated: `ring-destructive`, `ring-destructive-muted` for destructive / invalid focus (see **Effects — Focus rings**).
|
|
569
|
-
|
|
570
|
-
#### Semantic colors
|
|
571
|
-
|
|
572
|
-
Semantic tokens are **only** for status and system feedback (Alert, Banner, Sonner, badge status variants, validation). Do not use them as generic fills or decoration.
|
|
573
|
-
|
|
574
|
-
Each family has **default** pairings (theme-switching surfaces) and **muted** pairings (blocks on **persistent dark chrome**). On muted surfaces, use the same `*-foreground-on-*` token names with the muted background; verify contrast in context.
|
|
575
|
-
|
|
576
|
-
**Info**
|
|
577
|
-
|
|
578
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
579
|
-
| :--- | :--- | :--- | :--- |
|
|
580
|
-
| `info-background` | `#D0D6ED` | `#B5BEE2` | Info surface |
|
|
581
|
-
| `info-background-hover` | `#B5BEE2` | `#D0D6ED` | Hover on `info-background` |
|
|
582
|
-
| `info-foreground` | `#4A5FB8` | `#9DA9D9` | Text near info context on standard surfaces |
|
|
583
|
-
| `info-foreground-on-info` | `#32417F` | `#1A2242` | Text **on** `info-background` |
|
|
584
|
-
| `info-muted-background` | `#F0F2F9` | `#2D3134` | Info tint on dark chrome |
|
|
585
|
-
| *(pairing)* | — | — | On `info-muted-background`, use `info-foreground-on-info` for on-surface copy |
|
|
586
|
-
|
|
587
|
-
**Success**
|
|
588
|
-
|
|
589
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
590
|
-
| :--- | :--- | :--- | :--- |
|
|
591
|
-
| `success-background` | `#BBF3D0` | `#8BDEAE` | Success surface |
|
|
592
|
-
| `success-background-hover` | `#8BDEAE` | `#BBF3D0` | Hover on `success-background` |
|
|
593
|
-
| `success-foreground` | `#1C984A` | `#24C45E` | Text near success on standard surfaces |
|
|
594
|
-
| `success-foreground-on-success` | `#0F5026` | `#0A381C` | Text **on** `success-background` |
|
|
595
|
-
| `success-muted-background` | `#DDF9E7` | `#2D3134` | Success on dark chrome |
|
|
596
|
-
| *(pairing)* | — | — | On `success-muted-background`, use `success-foreground-on-success` |
|
|
597
|
-
|
|
598
|
-
**Warning**
|
|
599
|
-
|
|
600
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
601
|
-
| :--- | :--- | :--- | :--- |
|
|
602
|
-
| `warning-background` | `#FFE3A2` | `#FFE3A2` | Warning surface |
|
|
603
|
-
| `warning-background-hover` | `#FFD062` | `#FFF1D0` | Hover on `warning-background` |
|
|
604
|
-
| `warning-foreground` | `#C18800` | `#D8BF00` | Text near warning on standard surfaces |
|
|
605
|
-
| `warning-foreground-on-warning` | `#755200` | `#5B4000` | Text **on** `warning-background` |
|
|
606
|
-
| `warning-muted-background` | `#FFF1D0` | `#2D3134` | Warning on dark chrome |
|
|
607
|
-
|
|
608
|
-
**Destructive**
|
|
609
|
-
|
|
610
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
611
|
-
| :--- | :--- | :--- | :--- |
|
|
612
|
-
| `destructive-background` | `#FCCAD2` | `#FAA9B7` | Error / destructive surface |
|
|
613
|
-
| `destructive-background-hover` | `#FAA9B7` | `#FCCAD2` | Hover on `destructive-background` |
|
|
614
|
-
| `destructive-foreground` | `#CB0B2C` | `#F65E78` | Text near destructive context on standard surfaces |
|
|
615
|
-
| `destructive-foreground-on-critical` | `#8D081F` | `#8D081F` | Text **on** `destructive-background` |
|
|
616
|
-
| `destructive-muted-background` | `#FDDEE4` | `#2D3134` | Destructive on dark chrome |
|
|
617
|
-
| `destructive-muted-background-hover` | `#FCCAD2` | `#40464A` | Hover on `destructive-muted-background` |
|
|
618
|
-
|
|
619
|
-
**Neutral** (status: draft, archived — not “semantic calm” in the same sense as info/success)
|
|
620
|
-
|
|
621
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
622
|
-
| :--- | :--- | :--- | :--- |
|
|
623
|
-
| `neutral-background` | `#E4E6E8` | `#D4D7D9` | Neutral status surface |
|
|
624
|
-
| `neutral-background-hover` | `#D4D7D9` | `#E4E6E8` | Hover on `neutral-background` |
|
|
625
|
-
| `neutral-foreground` | `#52595F` | `#A5ABB1` | Text near neutral status |
|
|
626
|
-
| `neutral-foreground-on-neutral` | `#40464A` | `#2D3134` | Text **on** `neutral-background` |
|
|
627
|
-
| `neutral-muted-background` | `#F1F2F3` | `#2D3134` | Neutral on dark chrome |
|
|
628
|
-
|
|
629
|
-
**Naming:** CSS uses full role names (`info-foreground-on-info`, `neutral-foreground-on-neutral`, `destructive-foreground-on-critical`). There is no shortened alias in the theme.
|
|
630
|
-
|
|
631
|
-
#### Decorative colors
|
|
632
|
-
|
|
633
|
-
For **small accents** (badges, avatars, empty states) where color differentiates but does **not** signal status — use **Chart tokens** for plot colors, not this ramp, unless a design explicitly maps a tile to a series color. Pattern: `decorative-background-{ramp}`, `decorative-background-{ramp}-hover`, `decorative-foreground-{ramp}`.
|
|
634
|
-
|
|
635
|
-
**Preference order for new work:**
|
|
636
|
-
|
|
637
|
-
| Priority | Ramp | Background | Foreground |
|
|
638
|
-
| :---: | :--- | :--- | :--- |
|
|
639
|
-
| 1 | Fjord | `decorative-background-fjord` | `decorative-foreground-fjord` |
|
|
640
|
-
| 2 | Nordic | `decorative-background-nordic` | `decorative-foreground-nordic` |
|
|
641
|
-
| 3 | Aurora | `decorative-background-aurora` | `decorative-foreground-aurora` |
|
|
642
|
-
| 4 | Dusk | `decorative-background-dusk` | `decorative-foreground-dusk` |
|
|
643
|
-
| 5 | Orange | `decorative-background-orange` | `decorative-foreground-orange` |
|
|
644
|
-
| 6 | Sky | `decorative-background-sky` | `decorative-foreground-sky` |
|
|
645
|
-
| 7 | Mountain | `decorative-background-mountain` | `decorative-foreground-mountain` |
|
|
646
|
-
|
|
647
|
-
Example (fjord ramp): light `decorative-background-fjord` → `#CCD5FA` (fjord-200), `decorative-foreground-fjord` → `#1234B6` (fjord-700); dark → `#AEBDF7` / `#0D2582` (fjord-300 / fjord-800). Every ramp resolves in [`src/colors.css`](./src/colors.css).
|
|
648
|
-
|
|
649
|
-
#### Chart tokens
|
|
518
|
+
## Elevation & Depth
|
|
650
519
|
|
|
651
|
-
|
|
520
|
+
### Shadows
|
|
652
521
|
|
|
653
|
-
|
|
654
|
-
| :--- | :--- |
|
|
655
|
-
| `chart-{ramp}-color-1` … `chart-{ramp}-color-6` | Alpha-based series / area-fill steps (strongest → lightest) |
|
|
656
|
-
| `chart-gridlines` | Grid lines |
|
|
522
|
+
`--effect-shadow-sm` through `--effect-shadow-xl` are **alpha blacks** tuned per theme. Tailwind shadow utilities compose layered stacks from these tokens:
|
|
657
523
|
|
|
658
|
-
|
|
524
|
+
| Tailwind shadow | Built from `--effect-shadow-*` | Light (α) | Dark (α) | Use (per theme comments in CSS) |
|
|
525
|
+
| ---------------- | ------------------------------ | ----------- | ----------- | -------------------------------------------------- |
|
|
526
|
+
| `shadow-sm` | `--effect-shadow-sm` | 0.04 | 0.2 | Tooltips, small floating containers |
|
|
527
|
+
| `shadow-default` | md + sm layers | 0.05 + 0.04 | 0.302 + 0.2 | Menus, popovers, hover cards |
|
|
528
|
+
| `shadow-md` | lg + md layers | 0.06 + 0.05 | 0.4 + 0.302 | Sonner toasts, temporary elevated elements |
|
|
529
|
+
| `shadow-lg` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **without** full backdrop overlay |
|
|
530
|
+
| `shadow-xl` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **with** backdrop overlay |
|
|
659
531
|
|
|
660
|
-
|
|
532
|
+
Exact pixel stacks are defined in the theme CSS alongside `--shadow-sm` … `--shadow-xl`.
|
|
661
533
|
|
|
662
|
-
###
|
|
534
|
+
### Focus rings
|
|
663
535
|
|
|
664
|
-
|
|
536
|
+
Shadow-based (not `outline`) for consistent rendering:
|
|
665
537
|
|
|
666
|
-
| Token
|
|
667
|
-
|
|
|
668
|
-
| `--
|
|
669
|
-
| `--
|
|
670
|
-
| `--font-mono` | Source Code Pro | Code, technical strings |
|
|
538
|
+
| Token | Composition | Use |
|
|
539
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------- |
|
|
540
|
+
| `--shadow-focus-ring` | `0 0 0 1px var(--ring)` (`{colors.ring}`), `0 0 0 3px var(--ring-muted)` (`{colors.ring-muted}`) | Default focus on interactive controls |
|
|
541
|
+
| `--shadow-focus-ring-destructive` | `0 0 0 1px var(--ring-destructive), 0 0 0 3px var(--ring-destructive-muted)` | Destructive / invalid focus |
|
|
671
542
|
|
|
672
|
-
|
|
543
|
+
### Opacity
|
|
673
544
|
|
|
674
|
-
|
|
|
675
|
-
|
|
|
676
|
-
| `
|
|
677
|
-
|
|
|
678
|
-
|
|
|
679
|
-
| `h3` | Inter | 24px (`text-2xl`) | 600 | 28px | -0.04px | Subsection |
|
|
680
|
-
| `h4` | Inter | 20px (`text-xl`) | 500 | 24px | -0.04px | Group label |
|
|
681
|
-
| `body-md` | Inter | 16px (`text-base`) | 400 | 20px | -0.04px | Default body |
|
|
682
|
-
| `body-sm` | Inter | 14px (`text-sm`) | 400 | 18px | -0.04px | Secondary body |
|
|
683
|
-
| `label` | Inter | 12px (`text-xs`) | 500 | 14px | -0.04px | Form labels, compact UI |
|
|
684
|
-
| `code` | Source Code Pro | 14px (`text-sm`) | 400 | 20px | — | Monospace content |
|
|
545
|
+
| Token / concept | Value | Use |
|
|
546
|
+
| ------------------------------------------------ | ------------------------ | --------------------------------- |
|
|
547
|
+
| `--opacity-10` … `--opacity-80` (+ `*-inverted`) | rgba steps | Overlays, glass effects |
|
|
548
|
+
| Overlay scrim | via `overlay-background` | Modal backdrop (see color tables) |
|
|
549
|
+
| Chart fills | `chart-*-color-*` | See **Chart tokens** |
|
|
685
550
|
|
|
686
551
|
---
|
|
687
552
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
Aura aligns to a **4px base grid**. Spacing in components follows **Tailwind spacing** (`p-*`, `gap-*`, `m-*`): one unit = **4px** unless overridden. Common steps:
|
|
691
|
-
|
|
692
|
-
| Name | Value | Tailwind | Typical use |
|
|
693
|
-
| :--- | :--- | :--- | :--- |
|
|
694
|
-
| xs | 4px | `1` | Tight gaps, icon padding |
|
|
695
|
-
| sm | 8px | `2` | Inline controls, compact padding |
|
|
696
|
-
| md | 12px | `3` | Card / popover internal padding |
|
|
697
|
-
| lg | 16px | `4` | Related groups |
|
|
698
|
-
| xl | 20px | `5` | Sections |
|
|
699
|
-
| 2xl | 24px | `6` | Page regions |
|
|
700
|
-
| 3xl | 32px | `8` | Large layout gaps |
|
|
701
|
-
|
|
702
|
-
Layout helpers in theme: `--container-2xl` (40rem), `--container-8xl` (96rem), `--message-content-max-width` (80% for chat content).
|
|
703
|
-
|
|
704
|
-
#### Component heights
|
|
705
|
-
|
|
706
|
-
Heights are **not** always single CSS variables; primitives use Tailwind height utilities. Representative values from core components:
|
|
707
|
-
|
|
708
|
-
| Size | Height | Aura usage |
|
|
709
|
-
| :--- | :--- | :--- |
|
|
710
|
-
| xs | 20px (`h-5`) | Badge (default) |
|
|
711
|
-
| sm | 28px (`h-7`) | Button `sm`, compact rows |
|
|
712
|
-
| md | 36px (`h-9`) | Button default, Input, Select, many menu rows |
|
|
713
|
-
| lg | 40px (`h-10`) | Button `lg` |
|
|
714
|
-
| Icon button | 28 / 36 / 40px | `icon-sm` / default / `icon-lg` (`size-7`, `size-9`, `size-10`) |
|
|
715
|
-
|
|
716
|
-
**Topbar** height is **application-defined** (not a single Aura token). **Table / list row** density varies by product; menu and command patterns often use **36px** (`h-9`) rows.
|
|
717
|
-
|
|
718
|
-
---
|
|
553
|
+
## Shapes
|
|
719
554
|
|
|
720
555
|
### Corner radius
|
|
721
556
|
|
|
722
|
-
Defined in
|
|
723
|
-
|
|
724
|
-
| Token | Value | Use |
|
|
725
|
-
| :--- | :--- | :--- |
|
|
726
|
-
| `--radius-none` | 0px | Dividers, full-bleed |
|
|
727
|
-
| `--radius-xs` | 2px | Tight inner chrome |
|
|
728
|
-
| `--radius-sm` | 4px | Small controls, badges |
|
|
729
|
-
| `--radius-md` / `--radius` | 6px | Maps to `rounded-md` — shared default in theme |
|
|
730
|
-
| `--radius-lg` | 8px | **Default** for many controls (Button, Input) via `rounded-lg` |
|
|
731
|
-
| `--radius-xl` | 12px | Dialogs, large cards, popovers |
|
|
732
|
-
| `--radius-2xl` | 16px | Extra-large surfaces |
|
|
733
|
-
| `--radius-3xl` | 24px | Marketing / hero panels |
|
|
734
|
-
| `--radius-4xl` | 32px | Largest marketing rounding |
|
|
735
|
-
| `--radius-full` | 9999px | Pills, avatars |
|
|
557
|
+
Defined in the theme. Default interactive radius in components is often **`rounded-lg`** (`{rounded.lg}`) for buttons/inputs; cards and overlays use **`rounded-lg`**–**`rounded-xl`** (`{rounded.lg}`–`{rounded.xl}`).
|
|
736
558
|
|
|
737
|
-
|
|
559
|
+
| CSS variable | Token | Use |
|
|
560
|
+
| -------------------------- | ---------------- | -------------------------------------------------------------- |
|
|
561
|
+
| `--radius-none` | `{rounded.none}` | Dividers, full-bleed |
|
|
562
|
+
| `--radius-xs` | `{rounded.xs}` | Tight inner chrome |
|
|
563
|
+
| `--radius-sm` | `{rounded.sm}` | Small controls, badges |
|
|
564
|
+
| `--radius-md` / `--radius` | `{rounded.md}` | Maps to `rounded-md` — shared default in theme |
|
|
565
|
+
| `--radius-lg` | `{rounded.lg}` | **Default** for many controls (Button, Input) via `rounded-lg` |
|
|
566
|
+
| `--radius-xl` | `{rounded.xl}` | Dialogs, large cards, popovers |
|
|
567
|
+
| `--radius-2xl` | `{rounded.2xl}` | Extra-large surfaces |
|
|
568
|
+
| `--radius-3xl` | `{rounded.3xl}` | Marketing / hero panels |
|
|
569
|
+
| `--radius-4xl` | `{rounded.4xl}` | Largest marketing rounding |
|
|
570
|
+
| `--radius-full` | `{rounded.full}` | Pills, avatars |
|
|
738
571
|
|
|
739
|
-
###
|
|
572
|
+
### Borders
|
|
740
573
|
|
|
741
574
|
Aura is visually **flat**; surfaces, spacing, and typography do most structure. Add borders only when separation or affordance needs extra clarity.
|
|
742
575
|
|
|
@@ -748,105 +581,65 @@ Aura is visually **flat**; surfaces, spacing, and typography do most structure.
|
|
|
748
581
|
- **Avoid** drawing borders around every item in a list/card just to create visual rhythm.
|
|
749
582
|
- **Avoid** decorative outline stacks (`border` + `ring` + inset strokes) when no state or interaction meaning is conveyed.
|
|
750
583
|
|
|
751
|
-
| Concept
|
|
752
|
-
|
|
|
753
|
-
| Default width
|
|
754
|
-
| Emphasized width | **2px**
|
|
755
|
-
| Border color
|
|
756
|
-
| Style
|
|
584
|
+
| Concept | Value | Use |
|
|
585
|
+
| ---------------- | -------------------------------- | ---------------------------------------------------------------------- |
|
|
586
|
+
| Default width | **1px** | Tailwind `border` — tables, inputs, and occasional structural dividers |
|
|
587
|
+
| Emphasized width | **2px** | Stronger separation or invalid/critical state emphasis |
|
|
588
|
+
| Border color | `border`, `border-emphasized`, … | See **Base — Borders and focus** |
|
|
589
|
+
| Style | solid | Default |
|
|
757
590
|
|
|
758
591
|
---
|
|
759
592
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
#### Shadows
|
|
593
|
+
## Components
|
|
763
594
|
|
|
764
|
-
|
|
595
|
+
### Component heights
|
|
765
596
|
|
|
766
|
-
|
|
767
|
-
| :--- | :--- | :--- | :--- | :--- |
|
|
768
|
-
| `shadow-sm` | `--effect-shadow-sm` | 0.04 | 0.2 | Tooltips, small floating containers |
|
|
769
|
-
| `shadow-default` | md + sm layers | 0.05 + 0.04 | 0.302 + 0.2 | Menus, popovers, hover cards |
|
|
770
|
-
| `shadow-md` | lg + md layers | 0.06 + 0.05 | 0.4 + 0.302 | Sonner toasts, temporary elevated elements |
|
|
771
|
-
| `shadow-lg` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **without** full backdrop overlay |
|
|
772
|
-
| `shadow-xl` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **with** backdrop overlay |
|
|
773
|
-
|
|
774
|
-
Exact pixel stacks: `--shadow-sm` … `--shadow-xl` in [`src/styles.source.css`](./src/styles.source.css).
|
|
775
|
-
|
|
776
|
-
#### Focus rings
|
|
777
|
-
|
|
778
|
-
Shadow-based (not `outline`) for consistent rendering:
|
|
779
|
-
|
|
780
|
-
| Token | Composition | Use |
|
|
781
|
-
| :--- | :--- | :--- |
|
|
782
|
-
| `--shadow-focus-ring` | `0 0 0 1px var(--ring), 0 0 0 3px var(--ring-muted)` | Default focus on interactive controls |
|
|
783
|
-
| `--shadow-focus-ring-destructive` | `0 0 0 1px var(--ring-destructive), 0 0 0 3px var(--ring-destructive-muted)` | Destructive / invalid focus |
|
|
784
|
-
|
|
785
|
-
#### Opacity
|
|
786
|
-
|
|
787
|
-
| Token / concept | Value | Use |
|
|
788
|
-
| :--- | :--- | :--- |
|
|
789
|
-
| `--opacity-10` … `--opacity-80` (+ `*-inverted`) | rgba steps | Overlays, glass effects |
|
|
790
|
-
| Overlay scrim | via `overlay-background` | Modal backdrop (see color tables) |
|
|
791
|
-
| Chart fills | `chart-*-color-*` | See **Chart tokens** |
|
|
597
|
+
Heights are **not** always single CSS variables; primitives use Tailwind height utilities. Representative values from core components:
|
|
792
598
|
|
|
793
|
-
|
|
599
|
+
| Size | Component token | Height | Aura usage |
|
|
600
|
+
| ----------- | ----------------------------- | -------------- | --------------------------------------------- |
|
|
601
|
+
| xs | `{components.badge-xs}` | 20px (`h-5`) | Badge (default) |
|
|
602
|
+
| sm | `{components.button-sm}` | 28px (`h-7`) | Button `sm`, compact rows |
|
|
603
|
+
| md | `{components.button-primary}` | 36px (`h-9`) | Button default, Input, Select, many menu rows |
|
|
604
|
+
| lg | `{components.button-lg}` | 40px (`h-10`) | Button `lg` |
|
|
605
|
+
| Icon button | sm / md / lg tokens | 28 / 36 / 40px | `icon-sm` / default / `icon-lg` |
|
|
794
606
|
|
|
795
|
-
|
|
607
|
+
**Topbar** height is **application-defined** (not a single Aura token). **Table / list row** density varies by product; menu and command patterns often use **`{components.button-primary.height}`** (`h-9`) rows.
|
|
796
608
|
|
|
797
609
|
---
|
|
798
610
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
Width and spacing values in this subsection come from [`src/styles.source.css`](./src/styles.source.css) (`@theme inline` and `:root`) where noted. **Gutters and gaps** use the same **4px-based** spacing scale as **[Tokens → Size and dimensions](#size-and-dimensions)**.
|
|
802
|
-
|
|
803
|
-
**Body text reading width**
|
|
804
|
-
|
|
805
|
-
- **Must** cap **continuous body text** (paragraphs, descriptions, long labels) at a **maximum width of 600px** for comfortable reading.
|
|
806
|
-
- **Must** apply that limit to the **text column only** — companion UI (icons, thumbnails, side metadata, charts, code blocks) **may** sit outside that 600px band in the same row or card; do not shrink the text measure to absorb those elements.
|
|
807
|
-
- **Should** implement the cap with `max-w-[600px]` / `max-w-[37.5rem]` (or an equivalent layout wrapper) on the text block, not by stretching typography alone inside an arbitrarily wide container.
|
|
808
|
-
|
|
809
|
-
### Width and max content
|
|
810
|
-
|
|
811
|
-
Aura adjusts Tailwind **container** breakpoints where the default scale is too wide or too narrow for Fusion-style surfaces:
|
|
812
|
-
|
|
813
|
-
| Token | Value | Role |
|
|
814
|
-
| :--- | :--- | :--- |
|
|
815
|
-
| `--container-2xl` | 40rem (**640px**) | Narrower than Tailwind’s default `2xl` container — useful outer bound for regions; **body copy** inside can still follow the **600px** reading rule above |
|
|
816
|
-
| `--container-8xl` | 96rem (**1536px**) | Wide upper bound for dashboards and full-bleed marketing rows |
|
|
611
|
+
## Do's and Don'ts
|
|
817
612
|
|
|
818
|
-
|
|
613
|
+
Practical guardrails for Aura-based UI. For full rationale, see [Heuristics](#heuristics), [Interaction states](#interaction-states), and [Content](#content).
|
|
819
614
|
|
|
615
|
+
### Do
|
|
820
616
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
617
|
+
- Use semantic or base **color tokens** — never raw hex, rgb, or hsl when a token exists.
|
|
618
|
+
- Prefer Aura component **variants and APIs** over overriding styles with visual Tailwind utilities on primitives.
|
|
619
|
+
- Show **loading feedback** (`Shimmer`, `Loader`, `Skeleton`) for any wait the user is expected to sit through.
|
|
620
|
+
- Provide a **visible focus ring** on every interactive control (`shadow-focus-ring` / `shadow-focus-ring-destructive` on `:focus-visible`).
|
|
621
|
+
- Cap continuous **body text** at `{spacing.prose-max}` width; keep companion UI outside that measure.
|
|
622
|
+
- Use the **`{spacing.base}` spacing scale** for padding, margin, and gaps.
|
|
623
|
+
- Pair **icon-only controls** with `aria-label` and a `Tooltip`.
|
|
624
|
+
- Use **sentence case** for all UI copy; write action labels as verb + object ("Save changes", "Delete pipeline").
|
|
625
|
+
- Verify **contrast in both light and dark themes** before shipping.
|
|
830
626
|
|
|
831
|
-
|
|
832
|
-
- **Should** keep major block **padding** and **gap** on **4px** multiples so control heights, radii, and typography line up visually.
|
|
833
|
-
- **Should** group related regions in **Card** (and **Separator** when two unrelated groups share a container) before mixing unrelated actions into the same band — see **Heuristics §6**.
|
|
834
|
-
- **Avoid** one-off pixel gutters that ignore the scale unless matching a fixed graphic asset.
|
|
627
|
+
### Don't
|
|
835
628
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
-
|
|
839
|
-
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
629
|
+
- Don't use semantic status colors (`info-*`, `success-*`, `warning-*`, `destructive-*`) as generic decoration or toggled selection fills.
|
|
630
|
+
- Don't remove focus styling or use `outline-none` / `ring-0` without an equivalent token-based focus ring.
|
|
631
|
+
- Don't stack multiple **Alerts** or **toasts** for a single user gesture.
|
|
632
|
+
- Don't use `alert()` or other native blocking dialogs for product UX.
|
|
633
|
+
- Don't hardcode **font sizes, shadows, or border radii** when theme tokens exist.
|
|
634
|
+
- Don't use icon-only targets without an accessible name and tooltip.
|
|
635
|
+
- Don't mix **chart**, **decorative**, and **semantic** color groups interchangeably.
|
|
636
|
+
- Don't override Aura primitive appearance with visual `className` utilities — use variants instead.
|
|
844
637
|
|
|
845
638
|
---
|
|
846
639
|
|
|
847
|
-
## Assets
|
|
640
|
+
## Assets & Motion
|
|
848
641
|
|
|
849
|
-
**What this section is:** Rules for **illustrations**, **document icons**, **app icons**, and **system icons** in Aura-based products. Each type has a distinct job; mixing types or bending the rules adds noise and weakens trust. Visual execution (where files live, export pipelines) belongs in brand tooling and engineering skills, not here.
|
|
642
|
+
**What this section is:** Rules for **illustrations**, **document icons**, **app icons**, and **system icons** in Aura-based products. It also includes rules and guidance for motion design. Each type has a distinct job; mixing types or bending the rules adds noise and weakens trust. Visual execution (where files live, export pipelines) belongs in brand tooling and engineering skills, not here.
|
|
850
643
|
|
|
851
644
|
### Illustrations
|
|
852
645
|
|
|
@@ -940,18 +733,156 @@ Rare exceptions (third-party or Cognite logos inside a cell) use **provided SVGs
|
|
|
940
733
|
- **Must** give icon-only controls an accessible name (`aria-label` / `aria-labelledby`) **and** a **Tooltip** on hover/focus where the design hides the text label.
|
|
941
734
|
- Icons that only repeat the meaning of adjacent visible text **should** be `aria-hidden="true"`.
|
|
942
735
|
|
|
736
|
+
### Motion (reference)
|
|
737
|
+
|
|
738
|
+
Short UI motion (e.g. accordion height) uses **~0.2s ease-out** in utilities; there is no separate “motion duration” token table in Aura today — follow component and `tw-animate-css` patterns.
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## Heuristics
|
|
743
|
+
|
|
744
|
+
**What this section is:** The short interaction contract for Aura-based UIs. It keeps the design identity usable by agents and reviewers without turning this file into a full UX playbook.
|
|
745
|
+
|
|
746
|
+
This section contains Aura's decision rules, component selection guidance, and common failure modes. Severity terms carry specific meaning: **Must** / **must not** breaks usability, accessibility, or system conformance; **Should** is the strong default; **Avoid** is a known failure mode.
|
|
747
|
+
|
|
748
|
+
These rules apply to Aura primitives, host-shell components themed with Aura tokens, and standalone apps using Aura. Component props and enum names live in the component APIs, not in this spec.
|
|
749
|
+
|
|
750
|
+
---
|
|
751
|
+
|
|
752
|
+
### 1. Feedback and system status
|
|
753
|
+
|
|
754
|
+
Users must always know whether the system is waiting, succeeded, failed, or needs action.
|
|
755
|
+
|
|
756
|
+
- **Must** show loading for any wait the user is expected to sit through. Use **Shimmer** or **Skeleton** when the incoming layout is known, **Loader** for compact waits, and **Progress** when completion is measurable.
|
|
757
|
+
- **Must** acknowledge user-triggered mutations with visible feedback. Use a transient toast for low-stakes confirmations, inline feedback for scoped changes, and **Dialog** / shell **AlertDialog** before irreversible actions.
|
|
758
|
+
- **Must** surface persistent workflow-impacting problems until dismissed or resolved. Use **Banner** for high-priority degraded states, **Alert** for page-scoped awareness, and **Badge** or compact status rows for repeated entity state.
|
|
759
|
+
- **Avoid** blank loading areas, stacked toasts for one gesture, repeated Alert lists, and using **Banner** for routine connection handshakes.
|
|
760
|
+
|
|
761
|
+
### Alert vs Banner vs Badge vs Sonner
|
|
762
|
+
|
|
763
|
+
Use this matrix to pick the right feedback component. Priority is defined by whether the message requires immediate action and how long it needs to persist.
|
|
764
|
+
|
|
765
|
+
| Priority | When | Components | Notes |
|
|
766
|
+
| ---------- | --------------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
767
|
+
| **Low** | Non-disruptive updates, minor status, validation hints | `Badge`, notification dot, inline `HelperText` | Does not interrupt the user. Badge for entity state; HelperText for field-level feedback. |
|
|
768
|
+
| **Medium** | Informative, occasionally actionable, not urgent | `Sonner` (toast), `Alert` | Sonner for transient confirmations (~4 s, bottom-right). Alert for inline, page-scoped status that needs awareness but not immediate action (typically one per page section/view). |
|
|
769
|
+
| **High** | Requires immediate attention or action; may interrupt task flow | `Banner` (system errors), `Dialog` / `AlertDialog`, full-page error state | Banner for persistent, region-scoped degraded states. Dialog for irreversible actions. Never use Sonner as the sole safety net for destructive work. |
|
|
770
|
+
|
|
771
|
+
**Rules**
|
|
772
|
+
|
|
773
|
+
- **Must not** use Banner for low-priority or transient notices — it occupies persistent chrome and dilutes high-priority signals.
|
|
774
|
+
- **Must not** use Sonner for errors that require user action — it auto-dismisses.
|
|
775
|
+
- **Must not** use repeated Alerts as a list visualization pattern; one Alert communicates the grouped situation, while item-level status belongs in Badge/status-card patterns.
|
|
776
|
+
- **Should** use `Badge` semantic variants (`warning`, `destructive`, `success`) on entities that carry that state, not as page-level alerts.
|
|
777
|
+
- **Avoid** stacking multiple Sonner toasts for a single user gesture.
|
|
778
|
+
|
|
779
|
+
**Industrial / operational states**
|
|
780
|
+
|
|
781
|
+
The matrix above covers standard cases. For domain-specific states (e.g. sensor offline, process limit breach, control system degraded), apply the same priority logic: does the user need to act now? -> Banner or Dialog. Informational? -> Alert or Badge on the asset. Transient confirmation? -> Sonner. When many entities share similar state, summarize once (Alert/Banner) and show per-entity state with Badge or status cards.
|
|
782
|
+
|
|
783
|
+
---
|
|
784
|
+
|
|
785
|
+
### 2. Affordance and discoverability
|
|
786
|
+
|
|
787
|
+
Controls must read as interactive; users should not guess what is clickable, expandable, editable, or destructive.
|
|
788
|
+
|
|
789
|
+
- **Must** use semantic controls for actions, links, form fields, menus, and disclosure. Do not make generic elements behave like buttons.
|
|
790
|
+
- **Must** match component variant to intent: primary for one main action, secondary or ghost for support, destructive only for irreversible work.
|
|
791
|
+
- **Must** pair every field with a visible **Label**. Placeholder text is not a label.
|
|
792
|
+
- **Must** give icon-only controls both an accessible name and a **Tooltip**.
|
|
793
|
+
- **Should** use recognizable signifiers: chevrons for menus and disclosure, magnifier icons for search, helper text for constraints, and empty-state cards with an explanation plus a next action.
|
|
794
|
+
- **Avoid** clickable text that looks identical to body copy or help that exists only in hover on touch-first flows.
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
### 3. Progressive disclosure
|
|
799
|
+
|
|
800
|
+
Introduce complexity only when needed; default views should stay scannable.
|
|
801
|
+
|
|
802
|
+
- **Must** use **Accordion** for stacked independent sections and **Collapsible** for one inline expandable block.
|
|
803
|
+
- **Must** use **Dialog** for modal tasks and shell **Drawer** / **Sheet** for secondary edge panels where the host provides them.
|
|
804
|
+
- **Must** split flows with 3 or more steps into discrete steps with visible progress.
|
|
805
|
+
- **Must** scope menu items to the entity they affect. Do not mix row actions, page actions, and global actions in one menu.
|
|
806
|
+
- **Should** keep advanced settings, rare metadata, and secondary actions behind disclosure when they are not needed for the main task.
|
|
807
|
+
- **Avoid** deeply nested accordions, long flat menus, and multiple irreversible primary decisions in one step.
|
|
808
|
+
|
|
809
|
+
---
|
|
810
|
+
|
|
811
|
+
### 4. Error handling and prevention
|
|
812
|
+
|
|
813
|
+
Prevent errors where possible. When errors happen, users must understand what failed, why it matters, and how to recover.
|
|
814
|
+
|
|
815
|
+
- **Must** confirm high-impact destructive actions before execution. Name the object and consequence; do not ask only "Are you sure?".
|
|
816
|
+
- **Must** label destructive confirmation with the specific action, such as "Delete report", not "OK" or "Confirm".
|
|
817
|
+
- **Must** show form errors inline on the affected field and explain how to fix them.
|
|
818
|
+
- **Must** protect unsaved work with auto-save where feasible, persistent unsaved state where not, and a discard warning before navigation.
|
|
819
|
+
- **Should** offer **Undo** for reversible destructive actions when recovery is cheap and contained in the same session.
|
|
820
|
+
- **Avoid** using toast as the only safety net for irreversible work or revealing every validation error only on final submit.
|
|
821
|
+
|
|
822
|
+
---
|
|
823
|
+
|
|
824
|
+
### 5. Enabling power users
|
|
825
|
+
|
|
826
|
+
Experts should move faster without harming first-time clarity.
|
|
827
|
+
|
|
828
|
+
- **Should** provide shortcuts for the top few high-frequency actions and render them with Aura shortcut components.
|
|
829
|
+
- **Should** align shortcuts with platform norms where they do not fight the browser or operating system.
|
|
830
|
+
- **Must** support multi-select in list or table UIs that offer per-row destructive or batch actions.
|
|
831
|
+
- **Must** show bulk action controls only when selection is non-empty, with selected count.
|
|
832
|
+
- **Must** use structured empty states for first use or no data: title, explanation, and one clear next action.
|
|
833
|
+
- **Avoid** bulk destructive work without confirmation, stealing reserved shortcuts, or using **Banner** for long onboarding tours.
|
|
834
|
+
|
|
835
|
+
---
|
|
836
|
+
|
|
837
|
+
### 6. Layout and hierarchy
|
|
838
|
+
|
|
839
|
+
Information must be scannable and oriented before action.
|
|
840
|
+
|
|
841
|
+
- **Must** group related fields and content in one **Card** or labeled section.
|
|
842
|
+
- **Must** separate unrelated groups with spacing, section labels, or **Separator** before adding nested borders.
|
|
843
|
+
- **Must** keep one clear primary CTA per view. Global actions belong in shell chrome; page actions belong in the page header or toolbar.
|
|
844
|
+
- **Must** use shell **Tabs** / **SegmentedControl** for primary view switching where the product uses that pattern; do not duplicate global navigation in content.
|
|
845
|
+
- **Should** use type scale, weight, and spacing to lead attention before using color or elevation.
|
|
846
|
+
- **Avoid** unrelated actions in the same card, hard-coded pixel widths, duplicated navigation, and destructive styling for non-destructive actions.
|
|
847
|
+
|
|
848
|
+
---
|
|
849
|
+
|
|
850
|
+
### 7. Accessibility and inclusive design
|
|
851
|
+
|
|
852
|
+
Aura targets **WCAG AA** for primitives — usage must preserve that.
|
|
853
|
+
|
|
854
|
+
- **Must** complete every task path with keyboard alone.
|
|
855
|
+
- **Must** keep visible focus treatment on every interactive control. Never use `outline-none` or `ring-0` without an equivalent Aura focus ring.
|
|
856
|
+
- **Must** preserve primitive roles and ARIA behavior when composing or wrapping Aura components.
|
|
857
|
+
- **Must** name icon-only controls and pair them with a **Tooltip**.
|
|
858
|
+
- **Must not** encode meaning with color alone. Pair color with text, icon, helper text, or label.
|
|
859
|
+
- **Must** meet contrast and target-size requirements for the shipped context.
|
|
860
|
+
- **Avoid** pointer-only behavior, unreadable `muted-foreground` copy for required tasks, and sub-24px icon hit zones without expansion.
|
|
861
|
+
|
|
862
|
+
### Common pitfalls (agent guidance)
|
|
863
|
+
|
|
864
|
+
These are the most frequent mistakes when generating or modifying Aura-based UI. Avoid all of them.
|
|
865
|
+
|
|
866
|
+
- Raw hex, `rgb(...)`, or arbitrary Tailwind colors in product UI.
|
|
867
|
+
- Visual `className` overrides that bypass Aura variants, props, or tokens.
|
|
868
|
+
- Duplicate shell navigation inside content.
|
|
869
|
+
- Cards that mix unrelated actions, unrelated data, and dense nested borders.
|
|
870
|
+
- Semantic, decorative, and chart colors used interchangeably.
|
|
871
|
+
- Icon-only controls without accessible names and tooltips.
|
|
872
|
+
- Disabled primary CTAs with no visible path to resolve the blocker.
|
|
873
|
+
|
|
943
874
|
---
|
|
944
875
|
|
|
945
876
|
## Interaction states
|
|
946
877
|
|
|
947
|
-
**What this section is:** What each interaction state
|
|
878
|
+
**What this section is:** What each interaction state _means_ for users, which **Tokens** and patterns Aura uses, and rules for custom controls built outside the library. **How** to wire `focus-visible`, CVA variants, or component props belongs in code and engineering skills.
|
|
948
879
|
|
|
949
|
-
Every interactive control signals what is possible, what is happening, and what the system registered. **States are signifiers** — visual cues for affordances (what the element
|
|
880
|
+
Every interactive control signals what is possible, what is happening, and what the system registered. **States are signifiers** — visual cues for affordances (what the element _can_ do). Using them consistently builds trust and keeps keyboard and assistive-tech use predictable.
|
|
950
881
|
|
|
951
|
-
| Concept
|
|
952
|
-
|
|
|
953
|
-
| **Affordance** | A property that makes an action possible (e.g. a control can be activated).
|
|
954
|
-
| **Signifier**
|
|
882
|
+
| Concept | Meaning |
|
|
883
|
+
| -------------- | -------------------------------------------------------------------------------------- |
|
|
884
|
+
| **Affordance** | A property that makes an action possible (e.g. a control can be activated). |
|
|
885
|
+
| **Signifier** | A visible cue that communicates that affordance (shape, label, shadow, state styling). |
|
|
955
886
|
|
|
956
887
|
Aura primitives ship these states by default; the rules below describe the **design contract** and apply when extending Aura or building one-off interactives.
|
|
957
888
|
|
|
@@ -989,7 +920,7 @@ Keyboard or assistive tech has moved focus to the element. This is the main non-
|
|
|
989
920
|
- **Must** use Aura’s **token-based focus ring** — `shadow-focus-ring` (CSS variable `--shadow-focus-ring`, composed from `ring` + `ring-muted` tokens) for default controls, and **`shadow-focus-ring-destructive`** / `--shadow-focus-ring-destructive` for invalid or destructive fields. Shared utilities in the library pair `outline-none` **with** these rings on `:focus-visible` — never `outline-none` or `ring-0` **alone**.
|
|
990
921
|
- **Must** meet **WCAG AA** for the focus indicator against its immediate background.
|
|
991
922
|
- **Should** use **`:focus-visible`** (or library equivalents) so pointers do not get a keyboard ring on every click, while keyboard users always see one.
|
|
992
|
-
- **Invalid inputs:** on focus, use the **destructive** focus ring token pair above (see **
|
|
923
|
+
- **Invalid inputs:** on focus, use the **destructive** focus ring token pair above (see **Elevation & Depth → Focus rings**).
|
|
993
924
|
|
|
994
925
|
### Disabled
|
|
995
926
|
|
|
@@ -1009,7 +940,7 @@ Persistent **on/off**, **selected**, **active filter**, or **applied setting** u
|
|
|
1009
940
|
|
|
1010
941
|
**Guidance**
|
|
1011
942
|
|
|
1012
|
-
- **Must** use **`active-background`** / **`active-background-hover`** or **`active-muted-background`** / **`active-muted-background-hover`** (and matching foreground tokens such as **`foreground-on-active`**, **`active-foreground`**) — **not** semantic status colors (`info
|
|
943
|
+
- **Must** use **`active-background`** / **`active-background-hover`** or **`active-muted-background`** / **`active-muted-background-hover`** (and matching foreground tokens such as **`foreground-on-active`**, **`active-foreground`**) — **not** semantic status colors (`info-`*, `success-`*, …) for generic toggles.
|
|
1013
944
|
- **Must not** rely on **color alone** — combine fill with icon, checkmark, label, or border treatment where the pattern is ambiguous.
|
|
1014
945
|
- **Must** implement **hover**, **pressed**, and **focus** for the **selected** variant as well as the default variant when both exist.
|
|
1015
946
|
- **Must not** show “selected” visuals for controls that are not actually in a selected state.
|
|
@@ -1028,184 +959,252 @@ Work is **in progress**; the control or region may be temporarily inert or show
|
|
|
1028
959
|
|
|
1029
960
|
## Content
|
|
1030
961
|
|
|
1031
|
-
**What this section is:** Conventions for **UI copy**
|
|
962
|
+
**What this section is:** Conventions for **Fusion monorepo UI copy** in Aura-based surfaces: action labels, date and time presentation, grammar and style, localization, voice and tone, and writing that supports accessibility. Use it with **Heuristics** and **Interaction states** when designing or implementing strings.
|
|
1032
963
|
|
|
1033
964
|
**Who:** Designers, product writers, engineers, and agents generating microcopy.
|
|
1034
965
|
|
|
1035
|
-
**Scope:** English
|
|
1036
|
-
|
|
1037
|
-
---
|
|
1038
|
-
|
|
1039
|
-
### Action labels
|
|
1040
|
-
|
|
1041
|
-
Users predict behavior from **consistent verbs**. Action labels use **sentence case** (e.g. “Edit model”).
|
|
1042
|
-
|
|
1043
|
-
**Must not** use **Confirm** as the primary action — name the outcome (**Delete**, **Save**, **Send**, …). **Must** use **Sign in** and **Sign out**; **must not** use “Log in” / “Log out” in UI.
|
|
1044
|
-
|
|
1045
|
-
**Avoid** a labeled **Close** action **alongside** **Cancel** or a **Confirm**-labeled button in the same surface — use **Cancel** to abandon without applying, the **outcome verb** for commit, and/or icon-only dismiss per pattern library.
|
|
1046
|
-
|
|
1047
|
-
| Label | Use |
|
|
1048
|
-
| :--- | :--- |
|
|
1049
|
-
| **Add** | Attach an existing object to a new context (e.g. add to canvas). |
|
|
1050
|
-
| **Apply** | Commit filters or settings so they drive subsequent behavior. |
|
|
1051
|
-
| **Approve** | User agrees; in workflows, usually advances the process. |
|
|
1052
|
-
| **Back** | Previous step in a sequence or hierarchy. |
|
|
1053
|
-
| **Browse** | Structured scanning (categories, menus, filters). |
|
|
1054
|
-
| **Cancel** | Stop the current action and dismiss the surface; warn if stopping risks data loss. |
|
|
1055
|
-
| **Clear (all)** | Clear fields or selections; restore default where a control always has a value (e.g. radio). |
|
|
1056
|
-
| **Close** | Close a page, pane, or window (often icon-only). |
|
|
1057
|
-
| **Collapse** / **Expand** | Hide or show a panel (often icon-only). |
|
|
1058
|
-
| **Copy** | Copy to clipboard for use elsewhere. |
|
|
1059
|
-
| **Create** | New object from nothing (vs **Add** / **Duplicate**). |
|
|
1060
|
-
| **Delete** | Permanently remove the object. |
|
|
1061
|
-
| **Discard** | Abandon unsaved draft or edits. |
|
|
1062
|
-
| **Download** / **Upload** | Transfer file remote → local / local → remote. |
|
|
1063
|
-
| **Duplicate** | Copy in the same location as the original. |
|
|
1064
|
-
| **Edit** | Change data or values. |
|
|
1065
|
-
| **Explore** | Open-ended discovery without a fixed goal. |
|
|
1066
|
-
| **Export** | Save in an external format (often via a secondary step for type and destination). |
|
|
1067
|
-
| **Finish** | Complete a multi-step flow (e.g. wizard). |
|
|
1068
|
-
| **Hide** / **Show** | Toggle visibility in the UI only (not delete). |
|
|
1069
|
-
| **Import** | Bring data in from an external source. |
|
|
1070
|
-
| **Insert** | Place at a position in an ordered structure (e.g. table row). |
|
|
1071
|
-
| **Next** | Advance one step in a sequence. |
|
|
1072
|
-
| **Open** | **Internal:** drawer, modal, or in-app route (support open-in-new-tab where appropriate). **External:** new tab/window for external URLs. |
|
|
1073
|
-
| **Publish** / **Unpublish** | Make content available to intended audiences / remove from public view without deleting. |
|
|
1074
|
-
| **Query** | Request specific data from a store or service. |
|
|
1075
|
-
| **Redo** / **Undo** | Redo reverses undo; undo steps back through user edits (not all actions are undoable). |
|
|
1076
|
-
| **Refresh** | Reload when the view may be stale. |
|
|
1077
|
-
| **Register** | Create an account or enroll a user (prefer over “Sign up” where it could be confused with **Sign in**). |
|
|
1078
|
-
| **Reject** | User does not approve; in workflows, usually blocks progression. |
|
|
1079
|
-
| **Remove** | Remove from current context without destroying the object. |
|
|
1080
|
-
| **Reset** | Revert to last saved or default values. |
|
|
1081
|
-
| **Restore** | Revert to last saved version. |
|
|
1082
|
-
| **Save** | Persist changes without closing the surface. |
|
|
1083
|
-
| **Search** | Goal-oriented lookup. |
|
|
1084
|
-
| **Select** | Pick from a set of options. |
|
|
1085
|
-
| **Sign in** / **Sign out** | Authenticate / end session. |
|
|
1086
|
-
| **View** | Show details or properties (read-heavy). |
|
|
1087
|
-
|
|
1088
|
-
---
|
|
1089
|
-
|
|
1090
|
-
### Date and time formatting
|
|
1091
|
-
|
|
1092
|
-
**Defaults:** Respect user or product **dateTime** configuration (CDF preferences where applicable). **Read-only** stamps (lists, headers, audit) follow these guidelines; **input** fields and pickers follow component behavior and the same provider unless an exceptional case is documented.
|
|
1093
|
-
|
|
1094
|
-
**Dimensions**
|
|
1095
|
-
|
|
1096
|
-
| Concept | Meaning |
|
|
1097
|
-
| :--- | :--- |
|
|
1098
|
-
| **Read-only vs input** | Read-only is display-only; input uses pickers/fields — both should stay consistent within a feature. |
|
|
1099
|
-
| **Full vs abbreviated** | Full (“2 January 2023”, “6 hours 7 minutes”) vs short (“2 Jan 2023”, “6 hr 7 min”). Prefer abbreviated only when space is tight. |
|
|
1100
|
-
| **Absolute vs relative** | Absolute = calendar date/time of the event; relative = “32 min ago”. |
|
|
1101
|
-
|
|
1102
|
-
**Must** prefer **written** month forms over numeric dates when readability matters across locales. **Must** stay consistent within the same feature for format style. **Must** use **absolute** timestamps when the event is **more than 24 hours** in the past or future; **should** use **relative** timestamps within **24 hours** before/after “now” (either can be full or abbreviated).
|
|
966
|
+
**Scope:** English UI strings authored in the Fusion monorepo unless a feature explicitly ships localized strings. Numeric date order and clocks follow the host platform `dateTime` configuration. Product naming, white-labeling policy, and market-facing terminology are owned by product documentation and brand guidance; this section covers in-product microcopy patterns that Aura surfaces should follow.
|
|
1103
967
|
|
|
1104
|
-
|
|
968
|
+
### Role
|
|
1105
969
|
|
|
1106
|
-
|
|
1107
|
-
- **Must** use **UTC** (not GMT) when a zone label is required; do not spell out “UTC” unless prose clarity needs it. **Must not** ask users to hand-convert zones — the application converts.
|
|
970
|
+
You are writing interface copy for Fusion applications. Every string must be purposeful, concise, conversational, and clear. Identify the target audience persona before writing; the persona determines reading level, technical vocabulary, and tone.
|
|
1108
971
|
|
|
1109
|
-
|
|
972
|
+
For code-level accessibility (keyboard navigation, ARIA, focus, headings, live regions), see `handling-states.md`.
|
|
1110
973
|
|
|
1111
|
-
|
|
1112
|
-
- **Must not** use **ordinal** day forms (“1st”, “23rd”) in UI dates.
|
|
1113
|
-
- If numeric dates are required, **should** use **`/`** separators, zero-pad single-digit days/months, and include the year; stay consistent across the feature.
|
|
1114
|
-
- For combined date + time in prose, **should** separate with **“at”** or an unambiguous pattern; **must** keep date and time ordering consistent.
|
|
974
|
+
### Audience personas
|
|
1115
975
|
|
|
1116
|
-
**
|
|
976
|
+
Canonical persona definitions live in the cogdocs repository (`cogdocs/cogdocs-metadata.mdx`, **Audience** section). This summary covers what matters for microcopy decisions.
|
|
1117
977
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
978
|
+
| Persona | Technical level | UX copy implication |
|
|
979
|
+
| ----------------------- | --------------- | ------------------------------------------------------------------------------- |
|
|
980
|
+
| `businessUser` | Low | Plain language; outcomes over features; domain terms OK, avoid platform jargon |
|
|
981
|
+
| `businessDecisionMaker` | Low | Plain language; ROI, business value, strategic impact; minimal technical detail |
|
|
982
|
+
| `appMaker` | Mid | Configuration, automation, outcomes; avoid deep code/API detail |
|
|
983
|
+
| `dataAnalyst` | Mid | Analytics, insights, dashboards; data terms OK, keep explanations clear |
|
|
984
|
+
| `partner` | Mid–high | Precise; balance technical accuracy with clarity |
|
|
985
|
+
| `administrator` | High | Technical terms OK; reliability, security, compliance, access; be precise |
|
|
986
|
+
| `dataEngineer` | High | Technical terms OK; pipelines, ingestion, transformation |
|
|
987
|
+
| `developer` | High | Technical terms OK; APIs, SDKs, integrations; precise and concise |
|
|
988
|
+
| `aiEngineer` | High | Technical terms OK; ML/AI, models, automation |
|
|
989
|
+
| `dataScientist` | High | Technical terms OK; experiments, models, analytics |
|
|
990
|
+
| `securityEngineer` | High | Technical terms OK; IAM, threats, compliance |
|
|
991
|
+
| `solutionArchitect` | High | Technical terms OK; integration, strategy, best practices |
|
|
992
|
+
| `internal` | Varies | Can use Cognite-internal jargon; match internal conventions |
|
|
1121
993
|
|
|
1122
|
-
**
|
|
994
|
+
**Reading level:** Low = 7th–8th grade; Mid = 9th–10th grade; High = 10th–11th grade.
|
|
1123
995
|
|
|
1124
|
-
|
|
1125
|
-
- No “relative” phrasing for duration lists.
|
|
1126
|
-
- **Should** use a **space** between number and unit in body text and tables (`3 seconds`); compact controls may omit the space per component spec.
|
|
1127
|
-
- **Should** avoid commas between compound units (`10 minutes 3 seconds` not `10 minutes, 3 seconds`).
|
|
1128
|
-
- For sub-second precision, **should** use decimals (`2.5 seconds`) or round to a meaningful whole unit to reduce noise.
|
|
996
|
+
When the persona is unknown, default to plain language and outcomes.
|
|
1129
997
|
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
| Full (examples) | Abbreviated |
|
|
1133
|
-
| :--- | :--- |
|
|
1134
|
-
| millisecond(s), second(s), minute(s), hour(s) | ms, s, min, hr |
|
|
1135
|
-
| day(s), week(s), month(s), year(s) | d, wk, mo, yr |
|
|
1136
|
-
|
|
1137
|
-
Days and months: **Monday** → **Mon**, **January** → **Jan**, etc.; capitalize; allow width for **four-letter** abbreviations where internationalization may need it.
|
|
998
|
+
### Voice and tone
|
|
1138
999
|
|
|
1139
|
-
|
|
1000
|
+
Voice is consistent; tone adapts to the user's emotional state.
|
|
1140
1001
|
|
|
1141
|
-
|
|
1002
|
+
| Scenario | Tone | Example |
|
|
1003
|
+
| ----------------------- | ------------------------- | ------------------------------------------------------------------------------ |
|
|
1004
|
+
| First-time onboarding | Friendly, welcoming | "Let's get started. Your workspace is ready when you are." |
|
|
1005
|
+
| Technical documentation | Clear, direct, supportive | "Configure your endpoint and authenticate using your API key." |
|
|
1006
|
+
| Error messages | Empathetic, constructive | "Something went wrong. Try refreshing, or check your connection." |
|
|
1007
|
+
| Success states | Encouraging, concise | "Your data is now flowing." |
|
|
1008
|
+
| Product tours / help | Conversational, helpful | "Want a quick tour? We'll walk you through the essentials in under 2 minutes." |
|
|
1009
|
+
| High-stakes actions | Serious, transparent | "Delete pipeline? All history will be permanently removed." |
|
|
1142
1010
|
|
|
1143
1011
|
### Grammar and style
|
|
1144
1012
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
**Should** prefer **active voice**; use passive only for objectivity or legal emphasis.
|
|
1148
|
-
|
|
1149
|
-
**Numbers:** use **numerals** for all magnitudes in UI (`6 queries per second`, `50 Mbps`). **Should** use a **non-breaking space** between a number and its unit where line breaks would confuse.
|
|
1013
|
+
#### Language and capitalization
|
|
1150
1014
|
|
|
1151
|
-
|
|
1015
|
+
- **American English**: color, center, organization, modeling
|
|
1016
|
+
- **Sentence case everywhere**: "Create data model" — not "Create Data Model". No exceptions for UI text. Only proper nouns and product names are capitalized: Fusion, OPC-UA, Aura.
|
|
1017
|
+
- **No all-caps**
|
|
1018
|
+
- **No internal codenames** in customer-facing UI copy; use the feature or resource name users recognize.
|
|
1152
1019
|
|
|
1153
|
-
|
|
1020
|
+
#### Numbers and units
|
|
1154
1021
|
|
|
1155
|
-
- **
|
|
1156
|
-
-
|
|
1157
|
-
-
|
|
1158
|
-
- **Should** use the **Oxford comma** in lists.
|
|
1159
|
-
- **Avoid** ampersands (`&`) in translatable UI — use **and**.
|
|
1022
|
+
- **Numerals for all numbers**, including those under 10: "6 queries", "3 items", "1 result"
|
|
1023
|
+
- Non-breaking space between number and unit: "50 Mbps"
|
|
1024
|
+
- Don't use "(s)" or "(es)" — choose singular or plural based on context
|
|
1160
1025
|
|
|
1161
|
-
|
|
1026
|
+
#### Abbreviations and punctuation
|
|
1162
1027
|
|
|
1163
|
-
|
|
1028
|
+
- No Latin abbreviations: use "for example" not "e.g.", "and more" not "etc."
|
|
1029
|
+
- Define acronyms and technical terms when first used (unless writing for technical personas)
|
|
1030
|
+
- No ampersands (&): use "and" — including in headings
|
|
1031
|
+
- **Oxford comma**: "apples, oranges, and pears"
|
|
1032
|
+
- No exclamation marks in UI copy
|
|
1033
|
+
- No period after labels, tooltip text, or single-sentence bulleted list items; use periods for multiple/complex sentences
|
|
1034
|
+
- Ellipsis (…): only for ongoing processes or truncated text — use sparingly
|
|
1164
1035
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
### Localization
|
|
1036
|
+
#### Pronouns
|
|
1168
1037
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
---
|
|
1038
|
+
- Don't mix "my" and "your" in the same context
|
|
1039
|
+
- **"My [resource]"** for app-owned items: "My data", "My assets"
|
|
1040
|
+
- Minimize "I" and "we" representing the application; focus on the user's perspective
|
|
1041
|
+
- Avoid ambiguous pronouns ("this", "that") without an explicit referent — name the thing
|
|
1174
1042
|
|
|
1175
|
-
###
|
|
1176
|
-
|
|
1177
|
-
**Voice** stays consistent; **tone** shifts with context (onboarding vs error vs success).
|
|
1178
|
-
|
|
1179
|
-
**Should** lead with the user’s **intent** and **task**; use **plain**, customer vocabulary; stay **concise** and **scannable** (headings first, steps chunked; prefer visuals over long notes).
|
|
1180
|
-
|
|
1181
|
-
**Should** acknowledge friction honestly where UX is rough; keep disclaimers minimal.
|
|
1182
|
-
|
|
1183
|
-
| Scenario | Tone | Example |
|
|
1184
|
-
| :--- | :--- | :--- |
|
|
1185
|
-
| First-time onboarding | Friendly, welcoming | “Let’s get started — you’re ready when you are.” |
|
|
1186
|
-
| Technical flows | Clear, direct | “Configure your endpoint and authenticate with your API key.” |
|
|
1187
|
-
| Errors | Empathetic, constructive | “Something went wrong. Try refreshing or check your connection.” |
|
|
1188
|
-
| Success | Brief, positive | “Your data is now flowing.” |
|
|
1189
|
-
| Tours / help | Conversational | “Want a quick tour? We’ll cover the essentials in under two minutes.” |
|
|
1190
|
-
|
|
1191
|
-
Align microcopy with the same **product terminology** glossary referenced in **Grammar and style**.
|
|
1043
|
+
### Action labels
|
|
1192
1044
|
|
|
1193
|
-
|
|
1045
|
+
Use sentence case with an object: "Edit model", "Delete asset".
|
|
1194
1046
|
|
|
1195
|
-
|
|
1047
|
+
#### Approved labels
|
|
1196
1048
|
|
|
1197
|
-
|
|
1049
|
+
| Label | Use when |
|
|
1050
|
+
| ------------------ | --------------------------------------------------------------------------- |
|
|
1051
|
+
| Add | Taking an existing object into a new context ("Add to canvas") |
|
|
1052
|
+
| Apply | Setting filtered values that affect subsequent system behavior |
|
|
1053
|
+
| Approve | User agrees; initiates next step in a business process |
|
|
1054
|
+
| Back | Returning to the previous step in a sequence or hierarchy |
|
|
1055
|
+
| Cancel | Stopping the current action or closing a modal — warn of data loss |
|
|
1056
|
+
| Clear | Clearing all fields/selections; restores defaults |
|
|
1057
|
+
| Close | Closing a page, panel, or secondary window — often icon-only |
|
|
1058
|
+
| Copy | Copying an object to the clipboard |
|
|
1059
|
+
| Create | Making a new object from scratch |
|
|
1060
|
+
| Delete | Permanently destroying an object |
|
|
1061
|
+
| Discard | Discarding unsaved changes during create/edit |
|
|
1062
|
+
| Download | Transferring a file from remote to local |
|
|
1063
|
+
| Duplicate | Creating a copy in the same location as the original |
|
|
1064
|
+
| Edit | Changing data/values of an existing object |
|
|
1065
|
+
| Export | Saving data in an external format; typically opens a dialog |
|
|
1066
|
+
| Import | Bringing data from an external source; typically opens a dialog |
|
|
1067
|
+
| Next | Advancing to the next step in a wizard |
|
|
1068
|
+
| Finish | Completing a multi-step wizard |
|
|
1069
|
+
| Open | Opening a drawer, modal, or new page within current context |
|
|
1070
|
+
| Publish | Making content available to intended users |
|
|
1071
|
+
| Refresh | Reloading a view that is out of sync with the source |
|
|
1072
|
+
| Register | Creating a new user account |
|
|
1073
|
+
| Remove | Removing an object from the current context without destroying it |
|
|
1074
|
+
| Reset | Reverting to last saved or default state |
|
|
1075
|
+
| Save | Saving pending changes without closing the window/panel |
|
|
1076
|
+
| Search | Goal-oriented action to find precise information |
|
|
1077
|
+
| Select | Choosing one or more options from a list |
|
|
1078
|
+
| Show / Hide | Revealing or removing an element from view without deleting — use as a pair |
|
|
1079
|
+
| Sign in / Sign out | Entering or exiting the application |
|
|
1080
|
+
| Undo / Redo | Reversing or re-applying the most recent action |
|
|
1081
|
+
| Upload | Transferring a file from local to remote |
|
|
1082
|
+
| View | Presenting additional information or properties for an object |
|
|
1083
|
+
|
|
1084
|
+
#### Labels to avoid
|
|
1085
|
+
|
|
1086
|
+
| Avoid | Use instead | Reason |
|
|
1087
|
+
| --------------------- | ------------------------------------------- | -------------------------------- |
|
|
1088
|
+
| Confirm | The specific action verb ("Delete", "Send") | Too vague |
|
|
1089
|
+
| Log in / Log out | Sign in / Sign out | "Log" is technical jargon |
|
|
1090
|
+
| Sign up | Register | Avoids confusion with "Sign in" |
|
|
1091
|
+
| Submit, OK, Yes | The specific outcome verb | Generic; tell users what happens |
|
|
1092
|
+
| Click here, Read more | Descriptive link text | Inaccessible; not input-agnostic |
|
|
1093
|
+
|
|
1094
|
+
### UI text patterns
|
|
1095
|
+
|
|
1096
|
+
#### Titles
|
|
1097
|
+
|
|
1098
|
+
Noun phrases, sentence case. Examples: "Asset overview", "Pipeline runs", "Configure integration"
|
|
1099
|
+
|
|
1100
|
+
#### Buttons and CTAs
|
|
1101
|
+
|
|
1102
|
+
Active imperative verb + object. 2–4 words target, 6 max. Examples: "Save changes", "Delete pipeline", "View details"
|
|
1103
|
+
|
|
1104
|
+
#### Error messages
|
|
1105
|
+
|
|
1106
|
+
Pattern: `[What failed]. [Why/context if known]. [What to do].`
|
|
1107
|
+
Examples:
|
|
1108
|
+
|
|
1109
|
+
- "Ingestion failed. Check your extractor configuration and try again."
|
|
1110
|
+
- "Couldn't save changes. Connection lost. Reconnect and retry."
|
|
1111
|
+
Avoid: blame language, dead ends with no recovery path
|
|
1112
|
+
|
|
1113
|
+
#### Success messages
|
|
1114
|
+
|
|
1115
|
+
Past tense, specific, brief. Pattern: `[Action] [result]`
|
|
1116
|
+
Avoid "successfully"; that's implied in the pattern
|
|
1117
|
+
Examples: "Changes saved", "Pipeline started", "Integration configured"
|
|
1118
|
+
|
|
1119
|
+
#### Empty states
|
|
1120
|
+
|
|
1121
|
+
Explanation + CTA. Example: "No assets yet. Connect a data source to start exploring."
|
|
1122
|
+
|
|
1123
|
+
#### Tooltips
|
|
1124
|
+
|
|
1125
|
+
One to two sentences, present tense. Pattern: `[What it is]. [What it does or why it matters].`
|
|
1126
|
+
Examples:
|
|
1127
|
+
|
|
1128
|
+
- "Asset ID. The unique identifier for this asset."
|
|
1129
|
+
- "Time granularity. Controls how data points are aggregated in the chart."
|
|
1130
|
+
Never repeat the label. Never write more than 2 sentences.
|
|
1131
|
+
|
|
1132
|
+
#### Confirmation dialogs
|
|
1133
|
+
|
|
1134
|
+
State the consequence, not just the action. Pattern: `[What will be lost or affected]. [Reversibility]. [Specific action].`
|
|
1135
|
+
|
|
1136
|
+
- Primary CTA: match the specific action ("Delete pipeline", not "Confirm")
|
|
1137
|
+
- Secondary CTA: always provide a clear exit ("Cancel")
|
|
1138
|
+
Examples:
|
|
1139
|
+
- "Delete pipeline? All runs and history will be permanently removed. This can't be undone."
|
|
1140
|
+
- "Remove team member? They'll lose access to all shared resources immediately."
|
|
1141
|
+
Avoid: "Are you sure?", manipulative phrasing
|
|
1142
|
+
|
|
1143
|
+
#### Form fields
|
|
1144
|
+
|
|
1145
|
+
- **Labels**: Clear noun phrases ("Time series ID", "Email address")
|
|
1146
|
+
- **Placeholder text**: Use sparingly, only for standard formats like "[name@example.com](mailto:name@example.com)"
|
|
1147
|
+
- **Helper text**: Verb-first; explain why the information is needed
|
|
1148
|
+
|
|
1149
|
+
#### Notifications
|
|
1150
|
+
|
|
1151
|
+
Verb-first title + contextual description. 10–15 words total.
|
|
1152
|
+
Example: "Extractor disconnected. Check your network and reconnect."
|
|
1153
|
+
|
|
1154
|
+
### Accessibility
|
|
1155
|
+
|
|
1156
|
+
- Use **"Select"** not "Click" — input-agnostic: mouse, keyboard, touch, voice
|
|
1157
|
+
- Avoid ambiguous pronouns — screen readers lose surrounding context
|
|
1158
|
+
- Write descriptive link text: "Read pricing details" not "Click here"
|
|
1159
|
+
- Alt text by image type:
|
|
1160
|
+
- Icon → describes function: "Download PDF" not "download icon"
|
|
1161
|
+
- Link image → describes destination: "Contact support" not "question mark"
|
|
1162
|
+
- Chart/diagram → summarizes meaning: "Bar chart showing pipeline throughput declining 20% in Q3"
|
|
1163
|
+
- Decorative image → empty alt text (`alt=""`)
|
|
1164
|
+
- Never write "image of" or "photo of"
|
|
1165
|
+
- For charts and metrics, describe key trends or values in adjacent text — don't rely on visual encoding alone
|
|
1166
|
+
- Target 8–14 words per sentence (8 = 100% comprehension, 14 = 90%)
|
|
1167
|
+
- Pair visual indicators with text: "Error: field required" alongside a red icon
|
|
1198
1168
|
|
|
1199
|
-
|
|
1169
|
+
### Date and time formatting
|
|
1200
1170
|
|
|
1201
|
-
|
|
1171
|
+
- **Prefer written dates**: "2 January 2023" not "02/01/2023"
|
|
1172
|
+
- **Relative vs absolute**: ≤24 h from now → relative ("32 min ago"); >24 h → absolute ("2 Jan 2023")
|
|
1173
|
+
- Always include the year unless obvious from context
|
|
1174
|
+
- No ordinal numbers: "2 January" not "2nd January"
|
|
1175
|
+
- Separate date and time with "at": "2 Jan 2023 at 10:00 AM" — no comma
|
|
1176
|
+
- **12-hour time**: uppercase AM/PM, no periods, space before: "10:00 AM"
|
|
1177
|
+
- **Time zone**: UTC only; spell out "UTC" in text-only contexts
|
|
1178
|
+
- Never make the user convert time zones — handle in code
|
|
1179
|
+
- Ranges: consistent format across start and end; for ongoing processes use absolute start + "ongoing" until complete
|
|
1180
|
+
- Duration: no comma between units ("10 minutes 3 seconds"); space between number and unit in running text ("3 min"); no space in controls ("3min")
|
|
1202
1181
|
|
|
1203
|
-
**
|
|
1182
|
+
**Time unit abbreviations** (no periods; same form singular/plural):
|
|
1183
|
+
ms, s, min, hr, d, wk, mo, yr
|
|
1204
1184
|
|
|
1205
|
-
**
|
|
1185
|
+
**Day abbreviations** (3 chars for i18n):
|
|
1186
|
+
Mon, Tue, Wed, Thu, Fri, Sat, Sun
|
|
1206
1187
|
|
|
1207
|
-
**
|
|
1188
|
+
**Month abbreviations** (4 chars for i18n):
|
|
1189
|
+
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
|
|
1208
1190
|
|
|
1209
|
-
|
|
1191
|
+
### Localization
|
|
1210
1192
|
|
|
1211
|
-
|
|
1193
|
+
- Keep sentences short with the subject near the start — compound clauses increase translation cost
|
|
1194
|
+
- Maintain consistent terminology and capitalization across strings (critical for translation memory)
|
|
1195
|
+
- No Latin abbreviations in translatable strings: "for example" not "e.g.", "and more" not "etc."
|
|
1196
|
+
- Avoid idioms and cultural references
|
|
1197
|
+
- No ampersands: use "and"
|
|
1198
|
+
- Small words (a, the, that, is): include in prose; may omit only in space-constrained labels and CTAs
|
|
1199
|
+
|
|
1200
|
+
### Benchmarks
|
|
1201
|
+
|
|
1202
|
+
| Element | Target | Maximum |
|
|
1203
|
+
| -------------- | ------------------------ | ------------- |
|
|
1204
|
+
| Buttons / CTAs | 2–4 words | 6 words |
|
|
1205
|
+
| Titles | 3–6 words, 40 characters | — |
|
|
1206
|
+
| Tooltips | 10–20 words | 2 sentences |
|
|
1207
|
+
| Error messages | 12–18 words | — |
|
|
1208
|
+
| Instructions | 14 words | 20 words |
|
|
1209
|
+
| Notifications | 10–15 words total | — |
|
|
1210
|
+
| Line length | 40–60 characters | 70 characters |
|