@robr0/design-system 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -27
- package/components/AgentStatus/AgentStatus.css +496 -0
- package/components/AgentStatus/AgentStatus.d.ts +41 -0
- package/components/AgentStatus/AgentStatus.js +85 -0
- package/components/AgentStatus/AgentStatusPatterns.d.ts +17 -0
- package/components/AgentStatus/AgentStatusPatterns.js +20 -0
- package/components/AiButton/AiButton.css +163 -0
- package/components/AiButton/AiButton.d.ts +36 -0
- package/components/AiButton/AiButton.js +58 -0
- package/components/AlertDialog/AlertDialog.css +5 -5
- package/components/Button/Button.d.ts +14 -2
- package/components/ButtonGroup/ButtonGroup.js +2 -9
- package/components/ChatHeader/ChatHeader.css +35 -0
- package/components/ChatHeader/ChatHeader.d.ts +30 -0
- package/components/ChatHeader/ChatHeader.js +17 -0
- package/components/ChatMarker/ChatMarker.css +52 -0
- package/components/ChatMarker/ChatMarker.d.ts +22 -0
- package/components/ChatMarker/ChatMarker.js +18 -0
- package/components/ChatMessage/ChatMessage.css +304 -0
- package/components/ChatMessage/ChatMessage.d.ts +68 -0
- package/components/ChatMessage/ChatMessage.js +69 -0
- package/components/ChatThread/ChatThread.css +171 -0
- package/components/ChatThread/ChatThread.d.ts +41 -0
- package/components/ChatThread/ChatThread.js +174 -0
- package/components/Checkbox/Checkbox.d.ts +17 -3
- package/components/Chip/Chip.css +27 -0
- package/components/Chip/Chip.d.ts +2 -2
- package/components/CircularButton/CircularButton.d.ts +31 -10
- package/components/CircularButton/CircularButton.js +54 -50
- package/components/CodeBlock/CodeBlock.css +2 -2
- package/components/Combobox/Combobox.d.ts +10 -2
- package/components/Composer/Composer.css +164 -0
- package/components/Composer/Composer.d.ts +67 -0
- package/components/Composer/Composer.js +120 -0
- package/components/ContextMenu/ContextMenu.css +0 -4
- package/components/DateInput/DateInput.d.ts +5 -1
- package/components/Dialog/Dialog.css +5 -5
- package/components/DocumentChip/DocumentChip.css +181 -0
- package/components/DocumentChip/DocumentChip.d.ts +41 -0
- package/components/DocumentChip/DocumentChip.js +78 -0
- package/components/Dropdown/Dropdown.css +2 -4
- package/components/Dropdown/Dropdown.d.ts +10 -2
- package/components/DropdownMenu/DropdownMenu.css +2 -4
- package/components/FileInput/FileInput.d.ts +5 -1
- package/components/Input/Input.d.ts +5 -1
- package/components/InterruptCard/InterruptCard.css +164 -0
- package/components/InterruptCard/InterruptCard.d.ts +55 -0
- package/components/InterruptCard/InterruptCard.js +57 -0
- package/components/LinkList/LinkList.d.ts +1 -0
- package/components/MessageActions/MessageActions.css +76 -0
- package/components/MessageActions/MessageActions.d.ts +38 -0
- package/components/MessageActions/MessageActions.js +33 -0
- package/components/MessageCard/MessageCard.css +112 -0
- package/components/MessageCard/MessageCard.d.ts +35 -0
- package/components/MessageCard/MessageCard.js +28 -0
- package/components/NavList/NavList.css +155 -0
- package/components/NavList/NavList.d.ts +56 -0
- package/components/NavList/NavList.js +99 -0
- package/components/PromptSuggestions/PromptSuggestions.css +87 -0
- package/components/PromptSuggestions/PromptSuggestions.d.ts +51 -0
- package/components/PromptSuggestions/PromptSuggestions.js +34 -0
- package/components/Prose/Prose.css +252 -0
- package/components/Prose/Prose.d.ts +21 -0
- package/components/Prose/Prose.js +14 -0
- package/components/RadioButton/RadioButton.d.ts +17 -3
- package/components/Reasoning/Reasoning.css +276 -0
- package/components/Reasoning/Reasoning.d.ts +55 -0
- package/components/Reasoning/Reasoning.js +98 -0
- package/components/SelectionCard/SelectionCard.d.ts +5 -1
- package/components/Slider/Slider.d.ts +5 -1
- package/components/SourceChip/SourceChip.css +102 -0
- package/components/SourceChip/SourceChip.d.ts +32 -0
- package/components/SourceChip/SourceChip.js +31 -0
- package/components/Stat/Stat.css +2 -2
- package/components/Textarea/Textarea.d.ts +5 -1
- package/components/Timeline/Timeline.d.ts +2 -0
- package/components/ToggleGroup/ToggleGroup.d.ts +10 -2
- package/components/ToggleSwitch/ToggleSwitch.d.ts +10 -2
- package/components/ToolCall/ToolCall.css +213 -0
- package/components/ToolCall/ToolCall.d.ts +43 -0
- package/components/ToolCall/ToolCall.js +89 -0
- package/components/registry.json +145 -8
- package/components/registry.json.d.ts +145 -8
- package/components/registry.json.js +2 -2
- package/index.d.ts +18 -0
- package/index.js +36 -0
- package/package.json +8 -4
- package/tokens/registry.json +13 -0
- package/tokens/registry.json.d.ts +13 -0
- package/tokens/registry.json.js +1 -1
- package/tokens/tokens-dark.css +13 -0
- package/tokens/tokens-light.css +42 -0
- package/tokens/tokens-motion.css +3 -1
- package/tokens/tokens-typography.css +24 -0
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# robr0
|
|
1
|
+
# robr0: portfolio + AI-ready design system
|
|
2
2
|
|
|
3
3
|
[](https://github.com/robritacca-dotcom/design-system/actions/workflows/ci.yml)
|
|
4
4
|
<!-- npm-badge:start -->
|
|
5
5
|
[](https://www.npmjs.com/package/@robr0/design-system)
|
|
6
6
|
<!-- npm-badge:end -->
|
|
7
7
|
|
|
8
|
-
A personal portfolio site built on
|
|
8
|
+
A personal portfolio site built on an AI-ready React design system, designed and engineered from scratch. Claude Code builds the components from the written specs in this repo (`CLAUDE.md` for the rules, `design.md` for the design language, `content-design.md` for how every word reads), and generated registries keep this README and the docs site from drifting. The design system is the backbone every portfolio page is built on, so the work is presented consistently and to the same craft standards throughout.
|
|
9
9
|
|
|
10
10
|
**[→ Live site](https://robertritacca.com/)** · **[→ Storybook](https://design-system-iota-one.vercel.app/?path=/docs/robr0-ds--docs)**
|
|
11
11
|
|
|
12
|
-
The **live site** is the portfolio built on the design system. **Storybook** is the interactive component explorer for the design system itself
|
|
12
|
+
The **live site** is the portfolio built on the design system. **Storybook** is the interactive component explorer for the design system itself. They are two separate parts of this repo.
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
@@ -17,8 +17,8 @@ The **live site** is the portfolio built on the design system. **Storybook** is
|
|
|
17
17
|
|
|
18
18
|
| Part | Description |
|
|
19
19
|
|---|---|
|
|
20
|
-
| **Portfolio website** (`/website`) | Next.js app with case studies, work history, writing, and about pages
|
|
21
|
-
| **Design system** (`/src`) | <!-- component-count -->
|
|
20
|
+
| **Portfolio website** (`/website`) | Next.js app with case studies, work history, writing, and about pages, all built exclusively with the design system components below. **[Live site →](https://robertritacca.com/)** |
|
|
21
|
+
| **Design system** (`/src`) | <!-- component-count -->78<!-- /component-count --> React components, a three-tier token architecture, dark mode, and a full documentation site. Built to production standards. **[Storybook →](https://design-system-iota-one.vercel.app/?path=/docs/robr0-ds--docs)** |
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
@@ -27,12 +27,12 @@ The **live site** is the portfolio built on the design system. **Storybook** is
|
|
|
27
27
|
### Components
|
|
28
28
|
|
|
29
29
|
<!-- component-list:start -->
|
|
30
|
-
Accordion · Alert · Alert dialog · App layout · App sidebar · Avatar · Badge · Breadcrumb · Button · Button group · Card · Carousel · Chart · Checkbox · Chip · Circular button · Code block · Colour picker · Combobox · Command palette · Contact card · Context menu · Contribution graph · Date input · Date picker · Dialog · Divider · Drawer · Dropdown · Dropdown menu · Empty state · Entity card · Field · Figure · File input · Input · Instructions · Kbd · Link list · Navigation · Pagination · Popover · Progress bar · Quote · Radio button · Section title · Segmented control · Selection card · Skeleton · Slider · Spinner · Stat · Swatch · Table · Tabs · Textarea · Timeline · Toast · Toggle group · Toggle switch · Tooltip
|
|
30
|
+
Accordion · Agent status · AI button · Alert · Alert dialog · App layout · App sidebar · Avatar · Badge · Breadcrumb · Button · Button group · Card · Carousel · Chart · Chat header · Chat marker · Chat message · Chat thread · Checkbox · Chip · Circular button · Code block · Colour picker · Combobox · Command palette · Composer · Contact card · Context menu · Contribution graph · Date input · Date picker · Dialog · Divider · Document chip · Drawer · Dropdown · Dropdown menu · Empty state · Entity card · Field · Figure · File input · Input · Instructions · Interrupt card · Kbd · Link list · Message actions · Message card · Navigation · Nav list · Pagination · Popover · Progress bar · Prompt suggestions · Prose · Quote · Radio button · Reasoning · Section title · Segmented control · Selection card · Skeleton · Slider · Source chip · Spinner · Stat · Swatch · Table · Tabs · Textarea · Timeline · Toast · Toggle group · Toggle switch · Tool call · Tooltip
|
|
31
31
|
<!-- component-list:end -->
|
|
32
32
|
|
|
33
33
|
### Using the package
|
|
34
34
|
|
|
35
|
-
The design system is published as [`@robr0/design-system`](https://www.npmjs.com/package/@robr0/design-system) (React 19+ is a peer dependency)
|
|
35
|
+
The design system is published as [`@robr0/design-system`](https://www.npmjs.com/package/@robr0/design-system) (React 19+ is a peer dependency). The **[full setup guide](https://robertritacca.com/docs/get-started)** covers install, dark mode, fonts, and re-theming:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
npm install @robr0/design-system
|
|
@@ -53,14 +53,14 @@ Deep imports work too (`@robr0/design-system/components/Button/Button`). Chart c
|
|
|
53
53
|
import { BarChart, LineChart } from '@robr0/design-system/charts';
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
**Theming and
|
|
56
|
+
**Theming and customisation** happen through CSS variables; there is no configuration API. Components are provider-free, with one exception: wrap your tree in `ToastProvider` if (and only if) you use the toast queue via `useToast`.
|
|
57
57
|
|
|
58
58
|
- **Dark mode**: set `data-theme="dark"` on the root element (light is the default).
|
|
59
59
|
- **Font**: the whole type scale chains to one token. Load any font you like and override it:
|
|
60
60
|
```css
|
|
61
61
|
:root { --font-family-primary: 'Inter', sans-serif; }
|
|
62
62
|
```
|
|
63
|
-
- **
|
|
63
|
+
- **Colours, radius, spacing**: every semantic token chains to a primitive, so overriding a primitive re-themes everything built on it:
|
|
64
64
|
```css
|
|
65
65
|
:root {
|
|
66
66
|
--primitive-teal-07: #7C3AED; /* your brand color becomes the action color */
|
|
@@ -68,11 +68,11 @@ import { BarChart, LineChart } from '@robr0/design-system/charts';
|
|
|
68
68
|
}
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
Icons use a bundled Material Symbols Rounded variable font (woff2)
|
|
71
|
+
Icons use a bundled Material Symbols Rounded variable font (woff2), with no extra setup. Nunito Sans, the system's default typeface, is intentionally *not* bundled: load it yourself (e.g. Google Fonts or `next/font`) or override `--font-family-primary`.
|
|
72
72
|
|
|
73
73
|
### Token architecture
|
|
74
74
|
|
|
75
|
-
Tokens flow in one direction
|
|
75
|
+
Tokens flow in one direction, and primitives are never referenced directly in components:
|
|
76
76
|
|
|
77
77
|
```
|
|
78
78
|
tokens-primitives.css --primitive-teal-07: #118AB2
|
|
@@ -82,40 +82,43 @@ tokens-light/dark.css --color-action-primary-bg: var(--primitive-teal-07)
|
|
|
82
82
|
Component CSS background-color: var(--color-action-primary-bg)
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
Dark mode is driven by `data-theme="dark"` on the root element
|
|
85
|
+
Dark mode is driven by `data-theme="dark"` on the root element, with no `prefers-color-scheme` queries in components.
|
|
86
86
|
|
|
87
87
|
### Design principles
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
- **White-floor UI**: depth comes from a container color ramp, not box shadows
|
|
91
|
-
- **Teal is the action color**: primary buttons and focus rings only — never decorative
|
|
92
|
-
- **Five status variants**: info, positive, warning, error, neutral — shared tokens across Badge, Alert, Toast, ProgressBar
|
|
93
|
-
- **Material Symbols Rounded** for all icons
|
|
89
|
+
Stated as token roles on purpose — what each role resolves to is the theme, and yours to override:
|
|
94
90
|
|
|
95
|
-
|
|
91
|
+
- **Style with semantic tokens, never raw values** — that is what makes one primitive override cascade through everything
|
|
92
|
+
- **One typeface**, hierarchy carried by weight contrast
|
|
93
|
+
- **The primary-action token means "click here"**: CTAs and focus only, never decoration
|
|
94
|
+
- **Shape is a per-element-type token**, not a per-instance choice
|
|
95
|
+
- **Five status roles** (info, positive, warning, error, neutral) shared by every status-bearing component
|
|
96
|
+
- **Depth is token-owned**: the container ramp plus the system's elevation tokens — components don't bring their own shadows
|
|
97
|
+
|
|
98
|
+
The defaults behind each role, and every component spec, live in [`design.md`](design.md).
|
|
96
99
|
|
|
97
100
|
---
|
|
98
101
|
|
|
99
102
|
## Tech
|
|
100
103
|
|
|
101
|
-
- **React 19 + TypeScript
|
|
102
|
-
- **Vite 7
|
|
103
|
-
- **Next.js 16
|
|
104
|
-
- **Storybook 10
|
|
105
|
-
- **Vitest + Playwright
|
|
106
|
-
- **CSS custom properties
|
|
104
|
+
- **React 19 + TypeScript**: component library
|
|
105
|
+
- **Vite 7**: dev server and library build
|
|
106
|
+
- **Next.js 16**: portfolio site and design system documentation
|
|
107
|
+
- **Storybook 10**: component explorer
|
|
108
|
+
- **Vitest + Playwright**: every Storybook story runs as a render test in headless Chromium
|
|
109
|
+
- **CSS custom properties**: all theming via semantic tokens, no CSS-in-JS
|
|
107
110
|
|
|
108
111
|
---
|
|
109
112
|
|
|
110
113
|
## Quality & CI
|
|
111
114
|
|
|
112
|
-
Every push and pull request runs a GitHub Actions pipeline ([`ci.yml`](.github/workflows/ci.yml)) with four jobs:
|
|
115
|
+
Every push and pull request runs a GitHub Actions pipeline ([`ci.yml`](.github/workflows/ci.yml)) with four jobs: lint + library build, story tests (every Storybook story rendered in headless Chromium via Vitest), Storybook build, and website lint + build. The same checklist runs locally with one command:
|
|
113
116
|
|
|
114
117
|
```bash
|
|
115
118
|
npm run verify # lint + library type-check + package build + story tests + Storybook build + website lint + build
|
|
116
119
|
```
|
|
117
120
|
|
|
118
|
-
CI also guards against documentation drift: generated surfaces (this README's component count and list, the website's skills pages, the published CLAUDE.md
|
|
121
|
+
CI also guards against documentation drift: generated surfaces (this README's component count and list, the website's skills pages, the published CLAUDE.md, design.md, and content-design.md blueprints) are rebuilt from their source registries on every build, and CI fails if the committed copies are stale. The numbers on the site are never hand-written.
|
|
119
122
|
|
|
120
123
|
---
|
|
121
124
|
|
|
@@ -125,7 +128,7 @@ CI also guards against documentation drift: generated surfaces (this README's co
|
|
|
125
128
|
# Storybook (the library's dev sandbox)
|
|
126
129
|
npm run storybook # http://localhost:6006
|
|
127
130
|
|
|
128
|
-
# Portfolio + documentation website (npm workspace
|
|
131
|
+
# Portfolio + documentation website (npm workspace: install once at the root)
|
|
129
132
|
npm install
|
|
130
133
|
npm run dev --workspace website # http://localhost:3000
|
|
131
134
|
```
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
AGENT STATUS COMPONENT
|
|
3
|
+
A dot-matrix indicator plus a line of status
|
|
4
|
+
text, reporting what an agent is doing now.
|
|
5
|
+
|
|
6
|
+
The matrix is a 4x3 grid of 12 dots, numbered
|
|
7
|
+
row-major:
|
|
8
|
+
|
|
9
|
+
1 2 3 4
|
|
10
|
+
5 6 7 8
|
|
11
|
+
9 10 11 12
|
|
12
|
+
|
|
13
|
+
Every pattern is choreography over that same
|
|
14
|
+
grid: each dot is told which of the cycle's
|
|
15
|
+
twelve slots it lights in (--ds-agent-step),
|
|
16
|
+
and dots a pattern never lights opt out of the
|
|
17
|
+
animation entirely. One grid, one cycle length,
|
|
18
|
+
fifteen patterns — so changing pattern never
|
|
19
|
+
changes the indicator's footprint or rhythm.
|
|
20
|
+
============================================ */
|
|
21
|
+
|
|
22
|
+
.ds-agent-status {
|
|
23
|
+
--ds-agent-color: var(--color-text-secondary);
|
|
24
|
+
--ds-agent-label-color: var(--color-text-secondary);
|
|
25
|
+
--ds-agent-shimmer-base: var(--color-text-primary);
|
|
26
|
+
--ds-agent-shimmer-sweep: var(--color-text-tertiary);
|
|
27
|
+
--ds-agent-dot-dim: 0.2;
|
|
28
|
+
--ds-agent-dot-rest: 0.82;
|
|
29
|
+
--ds-agent-cycle: var(--motion-duration-loop-matrix);
|
|
30
|
+
--ds-agent-slot: calc(var(--ds-agent-cycle) / 12);
|
|
31
|
+
--ds-agent-matrix-size: var(--icon-size-md);
|
|
32
|
+
|
|
33
|
+
display: inline-flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
gap: var(--gap-sm-md);
|
|
36
|
+
font-family: var(--font-paragraph-family);
|
|
37
|
+
font-size: var(--font-paragraph-size);
|
|
38
|
+
font-weight: var(--font-paragraph-weight);
|
|
39
|
+
line-height: var(--font-paragraph-line-height);
|
|
40
|
+
letter-spacing: var(--font-paragraph-letter-spacing);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* ============================================
|
|
44
|
+
MATRIX
|
|
45
|
+
============================================ */
|
|
46
|
+
|
|
47
|
+
.ds-agent-status__matrix {
|
|
48
|
+
display: grid;
|
|
49
|
+
grid-template-columns: repeat(4, 1fr);
|
|
50
|
+
gap: var(--gap-xxs);
|
|
51
|
+
flex: none;
|
|
52
|
+
width: var(--ds-agent-matrix-size);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ds-agent-status__dot {
|
|
56
|
+
aspect-ratio: 1;
|
|
57
|
+
border-radius: var(--radius-full);
|
|
58
|
+
background-color: var(--ds-agent-color);
|
|
59
|
+
opacity: var(--ds-agent-dot-dim);
|
|
60
|
+
transform: scale(var(--ds-agent-dot-rest));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ============================================
|
|
64
|
+
LABEL
|
|
65
|
+
============================================ */
|
|
66
|
+
|
|
67
|
+
.ds-agent-status__label {
|
|
68
|
+
position: relative;
|
|
69
|
+
color: var(--ds-agent-label-color);
|
|
70
|
+
min-width: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Label crossfade: when the label string changes, the outgoing copy sits
|
|
74
|
+
absolutely over the incoming one and fades up and out while the new one
|
|
75
|
+
fades up and in — one continuous upward motion. */
|
|
76
|
+
.ds-agent-status__label-text {
|
|
77
|
+
display: inline-block;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* The animations live only on the modifier classes, and the modifiers come
|
|
81
|
+
off once the swap settles: a filled animation can pin the span to its
|
|
82
|
+
own compositor layer, which would escape the shimmer's text clip and
|
|
83
|
+
leave the label invisible for good. */
|
|
84
|
+
.ds-agent-status__label-text--in {
|
|
85
|
+
animation: ds-agent-label-in var(--motion-duration-slow) var(--motion-ease-entrance) both;
|
|
86
|
+
animation-delay: calc(var(--motion-duration-slow) / 2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.ds-agent-status__label-text--out {
|
|
90
|
+
position: absolute;
|
|
91
|
+
left: 0;
|
|
92
|
+
top: 0;
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
animation: ds-agent-label-out var(--motion-duration-slow) var(--motion-ease-standard) both;
|
|
95
|
+
animation-delay: 0s;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@keyframes ds-agent-label-in {
|
|
99
|
+
from {
|
|
100
|
+
opacity: 0;
|
|
101
|
+
transform: translateY(8px);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@keyframes ds-agent-label-out {
|
|
106
|
+
to {
|
|
107
|
+
opacity: 0;
|
|
108
|
+
transform: translateY(-8px);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* A gradient between the shimmer base and sweep colours, moving left to
|
|
113
|
+
right: with an oversized background image, background-position 100% shows
|
|
114
|
+
its right edge, 0% its left, so counting down walks the sweep band across
|
|
115
|
+
the text. */
|
|
116
|
+
.ds-agent-status__label--shimmer {
|
|
117
|
+
background-image: linear-gradient(
|
|
118
|
+
100deg,
|
|
119
|
+
var(--ds-agent-shimmer-base) 35%,
|
|
120
|
+
var(--ds-agent-shimmer-sweep) 50%,
|
|
121
|
+
var(--ds-agent-shimmer-base) 65%
|
|
122
|
+
);
|
|
123
|
+
background-size: 250% 100%;
|
|
124
|
+
background-clip: text;
|
|
125
|
+
-webkit-background-clip: text;
|
|
126
|
+
color: transparent;
|
|
127
|
+
animation: ds-agent-shimmer var(--motion-duration-loop-shimmer)
|
|
128
|
+
var(--motion-ease-linear) infinite;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* While a label crossfade runs, the shimmer's text clip stands down: an
|
|
132
|
+
animated descendant composites on its own layer, which escapes
|
|
133
|
+
background-clip: text and renders the text invisible. The swap motion
|
|
134
|
+
covers the pause; the sweep resumes on the settled text. */
|
|
135
|
+
.ds-agent-status__label--shimmer.ds-agent-status__label--swapping {
|
|
136
|
+
background-image: none;
|
|
137
|
+
animation: none;
|
|
138
|
+
color: var(--ds-agent-label-color);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* ============================================
|
|
142
|
+
STATES
|
|
143
|
+
The three working states are deliberately
|
|
144
|
+
monochrome. Colour is reserved for the states
|
|
145
|
+
where it carries meaning: waiting on a person,
|
|
146
|
+
finished, failed.
|
|
147
|
+
============================================ */
|
|
148
|
+
|
|
149
|
+
.ds-agent-status--idle {
|
|
150
|
+
--ds-agent-color: var(--color-text-tertiary);
|
|
151
|
+
--ds-agent-label-color: var(--color-text-tertiary);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.ds-agent-status--waiting {
|
|
155
|
+
--ds-agent-color: var(--color-status-warning-text);
|
|
156
|
+
--ds-agent-label-color: var(--color-status-warning-text);
|
|
157
|
+
|
|
158
|
+
/* Waiting keeps its warning colour through the shimmer — colour is the
|
|
159
|
+
signal, so the sweep only brightens it rather than going monochrome. */
|
|
160
|
+
--ds-agent-shimmer-base: var(--color-status-warning-text);
|
|
161
|
+
--ds-agent-shimmer-sweep: var(--color-text-primary);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.ds-agent-status--done {
|
|
165
|
+
--ds-agent-color: var(--color-status-positive-text);
|
|
166
|
+
--ds-agent-label-color: var(--color-status-positive-text);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.ds-agent-status--error {
|
|
170
|
+
--ds-agent-color: var(--color-status-error-text);
|
|
171
|
+
--ds-agent-label-color: var(--color-status-error-text);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Terminal states fill the matrix solid — the shape itself reads as finished */
|
|
175
|
+
.ds-agent-status--done .ds-agent-status__dot,
|
|
176
|
+
.ds-agent-status--error .ds-agent-status__dot {
|
|
177
|
+
opacity: 1;
|
|
178
|
+
transform: none;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* ============================================
|
|
182
|
+
SIZES
|
|
183
|
+
The scale pairs with ChatMessage: default
|
|
184
|
+
matches default message text, compact
|
|
185
|
+
matches compact message text.
|
|
186
|
+
============================================ */
|
|
187
|
+
|
|
188
|
+
.ds-agent-status--compact {
|
|
189
|
+
--ds-agent-matrix-size: var(--icon-size-sm);
|
|
190
|
+
|
|
191
|
+
gap: var(--gap-sm);
|
|
192
|
+
font-family: var(--font-paragraph-sm-family);
|
|
193
|
+
font-size: var(--font-paragraph-sm-size);
|
|
194
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
195
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
196
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* ============================================
|
|
200
|
+
VARIANTS
|
|
201
|
+
============================================ */
|
|
202
|
+
|
|
203
|
+
.ds-agent-status--bar {
|
|
204
|
+
display: flex;
|
|
205
|
+
width: 100%;
|
|
206
|
+
padding: var(--padding-xs) var(--padding-sm-md);
|
|
207
|
+
background-color: var(--color-bg-container-secondary);
|
|
208
|
+
border: var(--border-xs) solid var(--color-bg-container-border);
|
|
209
|
+
border-radius: var(--radius-md);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* ============================================
|
|
213
|
+
ANIMATION ENGINE
|
|
214
|
+
Each dot blinks once per cycle, offset by the
|
|
215
|
+
slot its pattern assigns it.
|
|
216
|
+
============================================ */
|
|
217
|
+
|
|
218
|
+
.ds-agent-status--animated .ds-agent-status__dot {
|
|
219
|
+
animation: ds-agent-dot var(--ds-agent-cycle) var(--motion-ease-standard) infinite;
|
|
220
|
+
animation-delay: calc(var(--ds-agent-step, 0) * var(--ds-agent-slot));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* A dot ramps up over roughly one slot and falls away over three, so the
|
|
224
|
+
leading edge arrives as smoothly as the trail leaves. Popping straight to
|
|
225
|
+
full opacity reads as a strobe at this size. */
|
|
226
|
+
@keyframes ds-agent-dot {
|
|
227
|
+
0% {
|
|
228
|
+
opacity: var(--ds-agent-dot-dim);
|
|
229
|
+
transform: scale(var(--ds-agent-dot-rest));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
10% {
|
|
233
|
+
opacity: 1;
|
|
234
|
+
transform: scale(1);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
35%,
|
|
238
|
+
100% {
|
|
239
|
+
opacity: var(--ds-agent-dot-dim);
|
|
240
|
+
transform: scale(var(--ds-agent-dot-rest));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* Fill sweep holds each column lit until the band has passed */
|
|
245
|
+
@keyframes ds-agent-dot-fill {
|
|
246
|
+
0% {
|
|
247
|
+
opacity: var(--ds-agent-dot-dim);
|
|
248
|
+
transform: scale(var(--ds-agent-dot-rest));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
8%,
|
|
252
|
+
74% {
|
|
253
|
+
opacity: 1;
|
|
254
|
+
transform: scale(1);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
86%,
|
|
258
|
+
100% {
|
|
259
|
+
opacity: var(--ds-agent-dot-dim);
|
|
260
|
+
transform: scale(var(--ds-agent-dot-rest));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Breathe swells the whole matrix rather than travelling through it */
|
|
265
|
+
@keyframes ds-agent-dot-breathe {
|
|
266
|
+
0%,
|
|
267
|
+
100% {
|
|
268
|
+
opacity: var(--ds-agent-dot-dim);
|
|
269
|
+
transform: scale(var(--ds-agent-dot-rest));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
50% {
|
|
273
|
+
opacity: 1;
|
|
274
|
+
transform: scale(1);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@keyframes ds-agent-shimmer {
|
|
279
|
+
from {
|
|
280
|
+
background-position-x: 100%;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
to {
|
|
284
|
+
background-position-x: 0%;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* ============================================
|
|
289
|
+
PATTERNS
|
|
290
|
+
One block per pattern: the slot each dot
|
|
291
|
+
lights in, and the dots it leaves dark.
|
|
292
|
+
============================================ */
|
|
293
|
+
|
|
294
|
+
/* Braille — a 2x3 cell rotating, the right half dark */
|
|
295
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(1) { --ds-agent-step: 0; }
|
|
296
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(2) { --ds-agent-step: 2; }
|
|
297
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(6) { --ds-agent-step: 4; }
|
|
298
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(10) { --ds-agent-step: 6; }
|
|
299
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 8; }
|
|
300
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(5) { --ds-agent-step: 10; }
|
|
301
|
+
|
|
302
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(3),
|
|
303
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(4),
|
|
304
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(7),
|
|
305
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(8),
|
|
306
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(11),
|
|
307
|
+
.ds-agent-status--braille .ds-agent-status__dot:nth-child(12) {
|
|
308
|
+
animation: none;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* Orbit — clockwise around the perimeter, core dark */
|
|
312
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(1) { --ds-agent-step: 0; }
|
|
313
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(2) { --ds-agent-step: 1; }
|
|
314
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(3) { --ds-agent-step: 2; }
|
|
315
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(4) { --ds-agent-step: 3; }
|
|
316
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(8) { --ds-agent-step: 4; }
|
|
317
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 5; }
|
|
318
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 6; }
|
|
319
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(10) { --ds-agent-step: 7; }
|
|
320
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 8; }
|
|
321
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(5) { --ds-agent-step: 9; }
|
|
322
|
+
|
|
323
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(6),
|
|
324
|
+
.ds-agent-status--orbit .ds-agent-status__dot:nth-child(7) {
|
|
325
|
+
animation: none;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/* Breathe — every dot together, on its own swell */
|
|
329
|
+
.ds-agent-status--animated.ds-agent-status--breathe .ds-agent-status__dot {
|
|
330
|
+
animation-name: ds-agent-dot-breathe;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* Snake — boustrophedon, one dot at a time */
|
|
334
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(1) { --ds-agent-step: 0; }
|
|
335
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(2) { --ds-agent-step: 1; }
|
|
336
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(3) { --ds-agent-step: 2; }
|
|
337
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(4) { --ds-agent-step: 3; }
|
|
338
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(8) { --ds-agent-step: 4; }
|
|
339
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(7) { --ds-agent-step: 5; }
|
|
340
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(6) { --ds-agent-step: 6; }
|
|
341
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(5) { --ds-agent-step: 7; }
|
|
342
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 8; }
|
|
343
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(10) { --ds-agent-step: 9; }
|
|
344
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 10; }
|
|
345
|
+
.ds-agent-status--snake .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 11; }
|
|
346
|
+
|
|
347
|
+
/* Fill sweep — columns light and hold, a band wiping left to right */
|
|
348
|
+
.ds-agent-status--animated.ds-agent-status--fill-sweep .ds-agent-status__dot {
|
|
349
|
+
animation-name: ds-agent-dot-fill;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.ds-agent-status--fill-sweep .ds-agent-status__dot:nth-child(4n + 1) { --ds-agent-step: 0; }
|
|
353
|
+
.ds-agent-status--fill-sweep .ds-agent-status__dot:nth-child(4n + 2) { --ds-agent-step: 3; }
|
|
354
|
+
.ds-agent-status--fill-sweep .ds-agent-status__dot:nth-child(4n + 3) { --ds-agent-step: 6; }
|
|
355
|
+
.ds-agent-status--fill-sweep .ds-agent-status__dot:nth-child(4n) { --ds-agent-step: 9; }
|
|
356
|
+
|
|
357
|
+
/* Pulse — rings expanding from the core */
|
|
358
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(6),
|
|
359
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(7) { --ds-agent-step: 0; }
|
|
360
|
+
|
|
361
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(2),
|
|
362
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(3),
|
|
363
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(5),
|
|
364
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(8),
|
|
365
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(10),
|
|
366
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 4; }
|
|
367
|
+
|
|
368
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(1),
|
|
369
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(4),
|
|
370
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(9),
|
|
371
|
+
.ds-agent-status--pulse .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 8; }
|
|
372
|
+
|
|
373
|
+
/* Columns — odd columns, then even */
|
|
374
|
+
.ds-agent-status--columns .ds-agent-status__dot:nth-child(odd) { --ds-agent-step: 0; }
|
|
375
|
+
.ds-agent-status--columns .ds-agent-status__dot:nth-child(even) { --ds-agent-step: 6; }
|
|
376
|
+
|
|
377
|
+
/* Checkerboard — the two parities alternating */
|
|
378
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(1),
|
|
379
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(3),
|
|
380
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(6),
|
|
381
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(8),
|
|
382
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(9),
|
|
383
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 0; }
|
|
384
|
+
|
|
385
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(2),
|
|
386
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(4),
|
|
387
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(5),
|
|
388
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(7),
|
|
389
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(10),
|
|
390
|
+
.ds-agent-status--checkerboard .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 6; }
|
|
391
|
+
|
|
392
|
+
/* Scan — a single column travelling left to right */
|
|
393
|
+
.ds-agent-status--scan .ds-agent-status__dot:nth-child(4n + 1) { --ds-agent-step: 0; }
|
|
394
|
+
.ds-agent-status--scan .ds-agent-status__dot:nth-child(4n + 2) { --ds-agent-step: 3; }
|
|
395
|
+
.ds-agent-status--scan .ds-agent-status__dot:nth-child(4n + 3) { --ds-agent-step: 6; }
|
|
396
|
+
.ds-agent-status--scan .ds-agent-status__dot:nth-child(4n) { --ds-agent-step: 9; }
|
|
397
|
+
|
|
398
|
+
/* Rain — drops falling down each column, columns out of phase */
|
|
399
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(1) { --ds-agent-step: 0; }
|
|
400
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(5) { --ds-agent-step: 2; }
|
|
401
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 4; }
|
|
402
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(2) { --ds-agent-step: 4; }
|
|
403
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(6) { --ds-agent-step: 6; }
|
|
404
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(10) { --ds-agent-step: 8; }
|
|
405
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(3) { --ds-agent-step: 2; }
|
|
406
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(7) { --ds-agent-step: 4; }
|
|
407
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 6; }
|
|
408
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(4) { --ds-agent-step: 6; }
|
|
409
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(8) { --ds-agent-step: 8; }
|
|
410
|
+
.ds-agent-status--rain .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 10; }
|
|
411
|
+
|
|
412
|
+
/* Cascade — column by column, top to bottom */
|
|
413
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(1) { --ds-agent-step: 0; }
|
|
414
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(5) { --ds-agent-step: 1; }
|
|
415
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 2; }
|
|
416
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(2) { --ds-agent-step: 3; }
|
|
417
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(6) { --ds-agent-step: 4; }
|
|
418
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(10) { --ds-agent-step: 5; }
|
|
419
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(3) { --ds-agent-step: 6; }
|
|
420
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(7) { --ds-agent-step: 7; }
|
|
421
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 8; }
|
|
422
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(4) { --ds-agent-step: 9; }
|
|
423
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(8) { --ds-agent-step: 10; }
|
|
424
|
+
.ds-agent-status--cascade .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 11; }
|
|
425
|
+
|
|
426
|
+
/* Sparkle — a fixed scatter, so it reads as random without being random */
|
|
427
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(1) { --ds-agent-step: 7; }
|
|
428
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(2) { --ds-agent-step: 2; }
|
|
429
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(3) { --ds-agent-step: 10; }
|
|
430
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(4) { --ds-agent-step: 4; }
|
|
431
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(5) { --ds-agent-step: 0; }
|
|
432
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(6) { --ds-agent-step: 9; }
|
|
433
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(7) { --ds-agent-step: 5; }
|
|
434
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(8) { --ds-agent-step: 11; }
|
|
435
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 3; }
|
|
436
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(10) { --ds-agent-step: 8; }
|
|
437
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 1; }
|
|
438
|
+
.ds-agent-status--sparkle .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 6; }
|
|
439
|
+
|
|
440
|
+
/* Wave rows — whole rows breaking top to bottom */
|
|
441
|
+
.ds-agent-status--wave-rows .ds-agent-status__dot:nth-child(-n + 4) { --ds-agent-step: 0; }
|
|
442
|
+
.ds-agent-status--wave-rows .ds-agent-status__dot:nth-child(n + 5):nth-child(-n + 8) { --ds-agent-step: 4; }
|
|
443
|
+
.ds-agent-status--wave-rows .ds-agent-status__dot:nth-child(n + 9) { --ds-agent-step: 8; }
|
|
444
|
+
|
|
445
|
+
/* Helix — two strands crossing, everything off-strand dark */
|
|
446
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(1),
|
|
447
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 0; }
|
|
448
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(6) { --ds-agent-step: 3; }
|
|
449
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(3),
|
|
450
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 6; }
|
|
451
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(8) { --ds-agent-step: 9; }
|
|
452
|
+
|
|
453
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(2),
|
|
454
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(4),
|
|
455
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(5),
|
|
456
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(7),
|
|
457
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(10),
|
|
458
|
+
.ds-agent-status--helix .ds-agent-status__dot:nth-child(12) {
|
|
459
|
+
animation: none;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* Diagonal swipe — anti-diagonals, top-left to bottom-right */
|
|
463
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(1) { --ds-agent-step: 0; }
|
|
464
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(2),
|
|
465
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(5) { --ds-agent-step: 2; }
|
|
466
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(3),
|
|
467
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(6),
|
|
468
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(9) { --ds-agent-step: 4; }
|
|
469
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(4),
|
|
470
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(7),
|
|
471
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(10) { --ds-agent-step: 6; }
|
|
472
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(8),
|
|
473
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(11) { --ds-agent-step: 8; }
|
|
474
|
+
.ds-agent-status--diagonal-swipe .ds-agent-status__dot:nth-child(12) { --ds-agent-step: 10; }
|
|
475
|
+
|
|
476
|
+
/* ============================================
|
|
477
|
+
REDUCED MOTION
|
|
478
|
+
The global guard collapses every animation to
|
|
479
|
+
its final frame, which for the matrix is dark.
|
|
480
|
+
Park it at a legible resting state instead and
|
|
481
|
+
let the label carry the meaning on its own.
|
|
482
|
+
============================================ */
|
|
483
|
+
|
|
484
|
+
@media (prefers-reduced-motion: reduce) {
|
|
485
|
+
.ds-agent-status--animated .ds-agent-status__dot {
|
|
486
|
+
animation: none;
|
|
487
|
+
opacity: 0.55;
|
|
488
|
+
transform: none;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.ds-agent-status__label--shimmer {
|
|
492
|
+
background-image: none;
|
|
493
|
+
color: var(--ds-agent-label-color);
|
|
494
|
+
animation: none;
|
|
495
|
+
}
|
|
496
|
+
}
|