@echothink-ui/motion 0.1.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.
Files changed (37) hide show
  1. package/README.md +5 -0
  2. package/dist/components/AgentThinkingAnimation.d.ts +2 -0
  3. package/dist/components/AttentionPulse.d.ts +2 -0
  4. package/dist/components/DAGStatusTransition.d.ts +2 -0
  5. package/dist/components/DocumentLockPulse.d.ts +2 -0
  6. package/dist/components/PipelineFlowAnimation.d.ts +2 -0
  7. package/dist/components/ProgressTransition.d.ts +2 -0
  8. package/dist/components/SkeletonLoadingPattern.d.ts +2 -0
  9. package/dist/components/StatusChangeAnimation.d.ts +2 -0
  10. package/dist/components/StepCompletionAnimation.d.ts +2 -0
  11. package/dist/components/StreamingText.d.ts +2 -0
  12. package/dist/components/SyncProgressAnimation.d.ts +2 -0
  13. package/dist/components/motionUtils.d.ts +5 -0
  14. package/dist/components/types.d.ts +82 -0
  15. package/dist/index.cjs +2381 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.js +2333 -0
  19. package/dist/index.js.map +1 -0
  20. package/package.json +38 -0
  21. package/src/components/AgentThinkingAnimation.tsx +59 -0
  22. package/src/components/AttentionPulse.tsx +57 -0
  23. package/src/components/DAGStatusTransition.tsx +292 -0
  24. package/src/components/DocumentLockPulse.tsx +72 -0
  25. package/src/components/PipelineFlowAnimation.tsx +243 -0
  26. package/src/components/ProgressTransition.tsx +51 -0
  27. package/src/components/SkeletonLoadingPattern.tsx +248 -0
  28. package/src/components/StatusChangeAnimation.test.tsx +20 -0
  29. package/src/components/StatusChangeAnimation.tsx +89 -0
  30. package/src/components/StepCompletionAnimation.tsx +75 -0
  31. package/src/components/StreamingText.tsx +77 -0
  32. package/src/components/SyncProgressAnimation.test.tsx +49 -0
  33. package/src/components/SyncProgressAnimation.tsx +256 -0
  34. package/src/components/motionUtils.tsx +942 -0
  35. package/src/components/types.ts +111 -0
  36. package/src/index.test.tsx +97 -0
  37. package/src/index.tsx +44 -0
@@ -0,0 +1,942 @@
1
+ import * as React from "react";
2
+ import type { EthOperationalStatus, EthSeverity } from "@echothink-ui/core";
3
+
4
+ const reducedMotionQuery = "(prefers-reduced-motion: reduce)";
5
+
6
+ export function usePrefersReducedMotion() {
7
+ return React.useSyncExternalStore(
8
+ subscribeToReducedMotion,
9
+ getReducedMotionSnapshot,
10
+ getReducedMotionServerSnapshot
11
+ );
12
+ }
13
+
14
+ function subscribeToReducedMotion(onStoreChange: () => void) {
15
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
16
+ return () => {};
17
+ }
18
+
19
+ const media = window.matchMedia(reducedMotionQuery);
20
+ const listener = () => onStoreChange();
21
+ media.addEventListener?.("change", listener);
22
+ return () => media.removeEventListener?.("change", listener);
23
+ }
24
+
25
+ function getReducedMotionSnapshot() {
26
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
27
+ return window.matchMedia(reducedMotionQuery).matches;
28
+ }
29
+
30
+ function getReducedMotionServerSnapshot() {
31
+ return false;
32
+ }
33
+
34
+ export function MotionStyles() {
35
+ return (
36
+ <style>{`
37
+ @keyframes eth-motion-flow-dash { to { stroke-dashoffset: -24; } }
38
+ @keyframes eth-motion-pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.035); opacity: .72; } 100% { transform: scale(1); opacity: 1; } }
39
+ @keyframes eth-motion-attention-ring { 0% { opacity: .52; transform: scale(.64); } 70%, 100% { opacity: 0; transform: scale(1.8); } }
40
+ @keyframes eth-motion-flow-node-pulse { 0% { opacity: .42; stroke-width: 1; } 100% { opacity: 0; stroke-width: 7; } }
41
+ @keyframes eth-motion-dot { 0%, 80%, 100% { opacity: .28; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }
42
+ @keyframes eth-motion-spin { to { transform: rotate(360deg); } }
43
+ @keyframes eth-motion-sync-sweep { 0% { transform: translateX(-120%); } 100% { transform: translateX(320%); } }
44
+ @keyframes eth-motion-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
45
+ @keyframes eth-motion-check { 0% { transform: scale(.78); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
46
+ @keyframes eth-motion-step-check { 0% { stroke-dashoffset: 18; } 100% { stroke-dashoffset: 0; } }
47
+ @keyframes eth-motion-step-current { 0% { box-shadow: 0 0 0 0 rgba(15, 98, 254, .24); } 100% { box-shadow: 0 0 0 .375rem rgba(15, 98, 254, 0); } }
48
+ @keyframes eth-motion-status-ring { 0% { stroke-dashoffset: 18; opacity: .18; } 55% { opacity: .48; } 100% { stroke-dashoffset: 0; opacity: .32; } }
49
+ @keyframes eth-motion-status-halo { 0% { opacity: .36; transform: scale(.68); } 100% { opacity: 0; transform: scale(1.85); } }
50
+ @keyframes eth-motion-lock-pulse { 0% { opacity: .34; transform: scale(.72); } 70%, 100% { opacity: 0; transform: scale(1.72); } }
51
+ @keyframes eth-motion-stream-cursor { 0%, 46% { opacity: 1; } 47%, 100% { opacity: 0; } }
52
+ .eth-motion-streaming-text {
53
+ align-items: baseline;
54
+ color: var(--cds-text-primary, #161616);
55
+ display: inline-flex;
56
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
57
+ font-size: inherit;
58
+ line-height: inherit;
59
+ max-inline-size: 100%;
60
+ min-inline-size: 0;
61
+ overflow-wrap: anywhere;
62
+ white-space: pre-wrap;
63
+ }
64
+ .eth-motion-streaming-text__content {
65
+ min-inline-size: 0;
66
+ }
67
+ .eth-motion-streaming-text__cursor {
68
+ background: var(--cds-interactive, #0f62fe);
69
+ block-size: 1em;
70
+ display: inline-block;
71
+ flex: 0 0 auto;
72
+ inline-size: 2px;
73
+ margin-inline-start: .125rem;
74
+ transform: translateY(.125em);
75
+ }
76
+ .eth-motion-streaming-text--streaming .eth-motion-streaming-text__cursor {
77
+ animation: eth-motion-stream-cursor 1s steps(1, end) infinite;
78
+ }
79
+ .eth-motion-streaming-text--complete .eth-motion-streaming-text__cursor {
80
+ inline-size: 0;
81
+ margin-inline-start: 0;
82
+ opacity: 0;
83
+ }
84
+ .eth-motion-pipeline-flow {
85
+ color: var(--cds-text-primary, #161616);
86
+ display: block;
87
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
88
+ inline-size: fit-content;
89
+ max-inline-size: 100%;
90
+ }
91
+ .eth-motion-pipeline-flow__svg {
92
+ block-size: auto;
93
+ display: block;
94
+ font-family: inherit;
95
+ max-inline-size: 100%;
96
+ overflow: visible;
97
+ }
98
+ .eth-motion-pipeline-flow__edge {
99
+ stroke-linecap: round;
100
+ stroke-linejoin: round;
101
+ vector-effect: non-scaling-stroke;
102
+ }
103
+ .eth-motion-pipeline-flow__card {
104
+ fill: var(--cds-layer-02, #ffffff);
105
+ shape-rendering: crispEdges;
106
+ stroke: var(--cds-border-subtle, #e0e0e0);
107
+ stroke-width: 1;
108
+ vector-effect: non-scaling-stroke;
109
+ }
110
+ .eth-motion-pipeline-flow__node--active .eth-motion-pipeline-flow__card {
111
+ fill: var(--cds-layer-01, #f4f4f4);
112
+ stroke: var(--cds-border-strong, #8d8d8d);
113
+ }
114
+ .eth-motion-pipeline-flow__stripe {
115
+ shape-rendering: crispEdges;
116
+ }
117
+ .eth-motion-pipeline-flow__pulse {
118
+ animation: eth-motion-flow-node-pulse 1.3s var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) infinite;
119
+ vector-effect: non-scaling-stroke;
120
+ }
121
+ .eth-motion-pipeline-flow__dot {
122
+ stroke: var(--cds-layer-02, #ffffff);
123
+ stroke-width: 2;
124
+ vector-effect: non-scaling-stroke;
125
+ }
126
+ .eth-motion-pipeline-flow__label {
127
+ fill: var(--cds-text-primary, #161616);
128
+ font-size: 13px;
129
+ font-weight: 600;
130
+ }
131
+ .eth-motion-pipeline-flow__status {
132
+ fill: var(--cds-text-secondary, #525252);
133
+ font-size: 11px;
134
+ }
135
+ .eth-motion-pipeline-flow__empty {
136
+ fill: var(--cds-text-secondary, #525252);
137
+ font-size: 13px;
138
+ }
139
+ .eth-motion-pipeline-flow__fallback {
140
+ block-size: 1px;
141
+ clip: rect(0 0 0 0);
142
+ clip-path: inset(50%);
143
+ inline-size: 1px;
144
+ margin: 0;
145
+ overflow: hidden;
146
+ padding: 0;
147
+ position: absolute;
148
+ white-space: nowrap;
149
+ }
150
+ .eth-motion-dag-status {
151
+ color: var(--cds-text-primary, #161616);
152
+ display: block;
153
+ max-inline-size: 100%;
154
+ }
155
+ .eth-motion-dag-status__svg {
156
+ block-size: auto;
157
+ display: block;
158
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
159
+ max-inline-size: 100%;
160
+ overflow: visible;
161
+ }
162
+ .eth-motion-dag-status__edge {
163
+ stroke-linecap: round;
164
+ stroke-linejoin: round;
165
+ vector-effect: non-scaling-stroke;
166
+ }
167
+ .eth-motion-dag-status__card {
168
+ shape-rendering: crispEdges;
169
+ stroke-width: 1;
170
+ vector-effect: non-scaling-stroke;
171
+ }
172
+ .eth-motion-dag-status__change-ring {
173
+ animation: eth-motion-status-ring 700ms var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) 1;
174
+ stroke-dasharray: 4 4;
175
+ stroke-width: 1;
176
+ vector-effect: non-scaling-stroke;
177
+ }
178
+ .eth-motion-dag-status__label {
179
+ fill: var(--cds-text-primary, #161616);
180
+ font-size: 13px;
181
+ font-weight: 600;
182
+ }
183
+ .eth-motion-dag-status__status {
184
+ fill: var(--cds-text-secondary, #525252);
185
+ font-size: 11px;
186
+ }
187
+ .eth-motion-dag-status__fallback {
188
+ block-size: 1px;
189
+ clip: rect(0 0 0 0);
190
+ clip-path: inset(50%);
191
+ inline-size: 1px;
192
+ margin: 0;
193
+ overflow: hidden;
194
+ padding: 0;
195
+ position: absolute;
196
+ white-space: nowrap;
197
+ }
198
+ .eth-motion-sync-progress {
199
+ --eth-motion-sync-accent: var(--cds-interactive, #0f62fe);
200
+ --eth-motion-sync-accent-soft: var(--cds-highlight, #edf5ff);
201
+
202
+ box-sizing: border-box;
203
+ color: var(--cds-text-primary, #161616);
204
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
205
+ line-height: 1.2857;
206
+ max-inline-size: 100%;
207
+ min-inline-size: 0;
208
+ }
209
+ .eth-motion-sync-progress *,
210
+ .eth-motion-sync-progress *::before,
211
+ .eth-motion-sync-progress *::after {
212
+ box-sizing: border-box;
213
+ }
214
+ .eth-motion-sync-progress--compact {
215
+ align-items: center;
216
+ background: var(--cds-layer-01, #ffffff);
217
+ border: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
218
+ border-inline-start: 3px solid var(--eth-motion-sync-accent);
219
+ display: inline-flex;
220
+ gap: var(--cds-spacing-03, .5rem);
221
+ inline-size: fit-content;
222
+ min-block-size: 2rem;
223
+ padding: .375rem .75rem .375rem .625rem;
224
+ vertical-align: middle;
225
+ }
226
+ .eth-motion-sync-progress--detailed {
227
+ align-items: stretch;
228
+ background: var(--cds-layer-01, #ffffff);
229
+ border: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
230
+ border-inline-start: 4px solid var(--eth-motion-sync-accent);
231
+ display: grid;
232
+ grid-template-columns: 1.5rem minmax(0, 1fr);
233
+ inline-size: 100%;
234
+ max-inline-size: 52rem;
235
+ min-block-size: 7.5rem;
236
+ }
237
+ .eth-motion-sync-progress__indicator {
238
+ align-items: center;
239
+ color: var(--eth-motion-sync-accent);
240
+ display: inline-flex;
241
+ flex: 0 0 auto;
242
+ inline-size: 1.125rem;
243
+ justify-content: center;
244
+ }
245
+ .eth-motion-sync-progress--detailed .eth-motion-sync-progress__indicator {
246
+ align-items: start;
247
+ inline-size: auto;
248
+ justify-content: center;
249
+ padding-block-start: var(--cds-spacing-05, 1rem);
250
+ padding-inline-start: var(--cds-spacing-04, .75rem);
251
+ }
252
+ .eth-motion-sync-progress__spinner,
253
+ .eth-motion-sync-progress__glyph {
254
+ block-size: 1rem;
255
+ border-radius: 50%;
256
+ display: inline-block;
257
+ inline-size: 1rem;
258
+ }
259
+ .eth-motion-sync-progress__spinner {
260
+ animation: eth-motion-spin 850ms linear infinite;
261
+ border: 2px solid var(--cds-border-subtle-01, #c6c6c6);
262
+ border-block-start-color: var(--eth-motion-sync-accent);
263
+ }
264
+ .eth-motion-sync-progress__glyph {
265
+ background: var(--eth-motion-sync-accent);
266
+ box-shadow: inset 0 0 0 3px var(--cds-layer-01, #ffffff);
267
+ }
268
+ .eth-motion-sync-progress__compact-copy {
269
+ align-items: baseline;
270
+ display: inline-flex;
271
+ gap: var(--cds-spacing-03, .5rem);
272
+ min-inline-size: 0;
273
+ }
274
+ .eth-motion-sync-progress__label {
275
+ color: var(--cds-text-primary, #161616);
276
+ font-size: var(--cds-body-compact-01-font-size, .875rem);
277
+ font-weight: 600;
278
+ line-height: var(--cds-body-compact-01-line-height, 1.2857);
279
+ min-inline-size: 0;
280
+ overflow-wrap: anywhere;
281
+ }
282
+ .eth-motion-sync-progress__compact-state {
283
+ color: var(--cds-text-secondary, #525252);
284
+ flex: 0 0 auto;
285
+ font-size: var(--cds-label-01-font-size, .75rem);
286
+ line-height: var(--cds-label-01-line-height, 1.3333);
287
+ white-space: nowrap;
288
+ }
289
+ .eth-motion-sync-progress__body {
290
+ display: grid;
291
+ gap: var(--cds-spacing-04, .75rem);
292
+ min-inline-size: 0;
293
+ padding: var(--cds-spacing-05, 1rem);
294
+ }
295
+ .eth-motion-sync-progress__header {
296
+ align-items: start;
297
+ display: flex;
298
+ gap: var(--cds-spacing-04, .75rem);
299
+ justify-content: space-between;
300
+ min-inline-size: 0;
301
+ }
302
+ .eth-motion-sync-progress__title-group {
303
+ display: grid;
304
+ gap: var(--cds-spacing-01, .125rem);
305
+ min-inline-size: 0;
306
+ }
307
+ .eth-motion-sync-progress__eyebrow,
308
+ .eth-motion-sync-progress__description,
309
+ .eth-motion-sync-progress__progress-copy,
310
+ .eth-motion-sync-progress__meta dt {
311
+ color: var(--cds-text-secondary, #525252);
312
+ font-size: var(--cds-label-01-font-size, .75rem);
313
+ line-height: var(--cds-label-01-line-height, 1.3333);
314
+ }
315
+ .eth-motion-sync-progress__eyebrow,
316
+ .eth-motion-sync-progress__meta dt {
317
+ font-weight: 600;
318
+ text-transform: uppercase;
319
+ }
320
+ .eth-motion-sync-progress__description {
321
+ margin: 0;
322
+ max-inline-size: 38rem;
323
+ overflow-wrap: anywhere;
324
+ }
325
+ .eth-motion-sync-progress__chip {
326
+ align-items: center;
327
+ background: var(--eth-motion-sync-accent-soft);
328
+ border: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
329
+ color: var(--cds-text-primary, #161616);
330
+ display: inline-flex;
331
+ flex: 0 0 auto;
332
+ font-size: var(--cds-label-01-font-size, .75rem);
333
+ font-weight: 600;
334
+ gap: var(--cds-spacing-02, .25rem);
335
+ line-height: var(--cds-label-01-line-height, 1.3333);
336
+ min-block-size: 1.5rem;
337
+ padding: .1875rem var(--cds-spacing-03, .5rem);
338
+ white-space: nowrap;
339
+ }
340
+ .eth-motion-sync-progress__chip-dot {
341
+ background: var(--eth-motion-sync-accent);
342
+ block-size: .5rem;
343
+ border-radius: 50%;
344
+ display: inline-block;
345
+ inline-size: .5rem;
346
+ }
347
+ .eth-motion-sync-progress__meter {
348
+ display: grid;
349
+ gap: var(--cds-spacing-03, .5rem);
350
+ min-inline-size: 0;
351
+ }
352
+ .eth-motion-sync-progress__track {
353
+ background: var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
354
+ block-size: .5rem;
355
+ inline-size: 100%;
356
+ overflow: hidden;
357
+ position: relative;
358
+ }
359
+ .eth-motion-sync-progress__bar {
360
+ background: var(--eth-motion-sync-accent);
361
+ block-size: 100%;
362
+ display: block;
363
+ min-inline-size: .25rem;
364
+ transition: inline-size var(--cds-duration-fast-02, 110ms)
365
+ var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9));
366
+ }
367
+ .eth-motion-sync-progress__bar--indeterminate {
368
+ animation: eth-motion-sync-sweep 1.35s var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) infinite;
369
+ inline-size: 34%;
370
+ }
371
+ .eth-motion-sync-progress__progress-copy {
372
+ font-variant-numeric: tabular-nums;
373
+ justify-self: end;
374
+ }
375
+ .eth-motion-sync-progress__meta {
376
+ background: var(--cds-layer-02, #f4f4f4);
377
+ border-block-start: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
378
+ display: grid;
379
+ gap: 0;
380
+ grid-column: 1 / -1;
381
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
382
+ margin: 0;
383
+ min-inline-size: 0;
384
+ }
385
+ .eth-motion-sync-progress__meta-item {
386
+ display: grid;
387
+ gap: var(--cds-spacing-02, .25rem);
388
+ min-inline-size: 0;
389
+ padding: var(--cds-spacing-04, .75rem) var(--cds-spacing-05, 1rem);
390
+ }
391
+ .eth-motion-sync-progress__meta-item + .eth-motion-sync-progress__meta-item {
392
+ border-inline-start: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
393
+ }
394
+ .eth-motion-sync-progress__meta dd {
395
+ color: var(--cds-text-primary, #161616);
396
+ font-size: var(--cds-body-compact-01-font-size, .875rem);
397
+ font-weight: 600;
398
+ line-height: var(--cds-body-compact-01-line-height, 1.2857);
399
+ margin: 0;
400
+ min-inline-size: 0;
401
+ overflow-wrap: anywhere;
402
+ }
403
+ .eth-motion-sync-progress.eth-motion-reduced .eth-motion-sync-progress__bar--indeterminate {
404
+ animation: none;
405
+ inline-size: 38%;
406
+ }
407
+ .eth-motion-skeleton-loading {
408
+ color: var(--cds-text-primary, #161616);
409
+ display: block;
410
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
411
+ inline-size: 100%;
412
+ max-inline-size: 100%;
413
+ min-inline-size: 0;
414
+ }
415
+ .eth-motion-skeleton-loading__surface {
416
+ background: var(--cds-layer-01, #f4f4f4);
417
+ border: 1px solid var(--cds-border-subtle, #e0e0e0);
418
+ display: grid;
419
+ inline-size: 100%;
420
+ min-inline-size: 0;
421
+ overflow: hidden;
422
+ }
423
+ .eth-motion-skeleton-loading__block {
424
+ background: var(--cds-skeleton-background, #e0e0e0);
425
+ block-size: .875rem;
426
+ display: block;
427
+ inline-size: 100%;
428
+ min-inline-size: .75rem;
429
+ }
430
+ .eth-motion-skeleton-loading:not(.eth-motion-reduced) .eth-motion-skeleton-loading__block {
431
+ animation: eth-motion-shimmer 1.2s var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) infinite;
432
+ background-image: linear-gradient(
433
+ 90deg,
434
+ var(--cds-skeleton-background, #e0e0e0) 0%,
435
+ var(--cds-skeleton-element, #f4f4f4) 46%,
436
+ var(--cds-skeleton-background, #e0e0e0) 82%
437
+ );
438
+ background-size: 200% 100%;
439
+ }
440
+ .eth-motion-skeleton-loading__surface--article {
441
+ gap: var(--cds-spacing-05, 1rem);
442
+ padding: var(--cds-spacing-05, 1rem);
443
+ }
444
+ .eth-motion-skeleton-loading__article-header,
445
+ .eth-motion-skeleton-loading__article-body,
446
+ .eth-motion-skeleton-loading__card-body,
447
+ .eth-motion-skeleton-loading__list-copy {
448
+ display: grid;
449
+ gap: var(--cds-spacing-03, .5rem);
450
+ min-inline-size: 0;
451
+ }
452
+ .eth-motion-skeleton-loading__article-body,
453
+ .eth-motion-skeleton-loading__card-body {
454
+ gap: var(--cds-spacing-04, .75rem);
455
+ }
456
+ .eth-motion-skeleton-loading__block--eyebrow {
457
+ block-size: .5rem;
458
+ }
459
+ .eth-motion-skeleton-loading__block--title {
460
+ block-size: 1.125rem;
461
+ }
462
+ .eth-motion-skeleton-loading__block--caption,
463
+ .eth-motion-skeleton-loading__block--column {
464
+ block-size: .625rem;
465
+ }
466
+ .eth-motion-skeleton-loading__surface--card {
467
+ background: var(--cds-layer-01, #ffffff);
468
+ }
469
+ .eth-motion-skeleton-loading__block--media {
470
+ block-size: 6rem;
471
+ inline-size: 100%;
472
+ }
473
+ .eth-motion-skeleton-loading__card-body {
474
+ padding: var(--cds-spacing-05, 1rem);
475
+ }
476
+ .eth-motion-skeleton-loading__card-metrics {
477
+ border-block-start: 1px solid var(--cds-border-subtle, #e0e0e0);
478
+ display: grid;
479
+ gap: var(--cds-spacing-05, 1rem);
480
+ grid-template-columns: repeat(3, minmax(0, 1fr));
481
+ padding: var(--cds-spacing-04, .75rem) var(--cds-spacing-05, 1rem);
482
+ }
483
+ .eth-motion-skeleton-loading__block--metric {
484
+ block-size: 1.5rem;
485
+ }
486
+ .eth-motion-skeleton-loading__list-row {
487
+ align-items: center;
488
+ display: grid;
489
+ gap: var(--cds-spacing-04, .75rem);
490
+ grid-template-columns: 2rem minmax(0, 1fr) minmax(3rem, 5rem);
491
+ min-block-size: 4rem;
492
+ padding: var(--cds-spacing-04, .75rem);
493
+ }
494
+ .eth-motion-skeleton-loading__list-row + .eth-motion-skeleton-loading__list-row {
495
+ border-block-start: 1px solid var(--cds-border-subtle, #e0e0e0);
496
+ }
497
+ .eth-motion-skeleton-loading__block--avatar {
498
+ block-size: 2rem;
499
+ inline-size: 2rem;
500
+ }
501
+ .eth-motion-skeleton-loading__block--tag {
502
+ block-size: 1.25rem;
503
+ justify-self: end;
504
+ }
505
+ .eth-motion-skeleton-loading__surface--table {
506
+ background: var(--cds-layer-01, #ffffff);
507
+ }
508
+ .eth-motion-skeleton-loading__table-header,
509
+ .eth-motion-skeleton-loading__table-row {
510
+ display: grid;
511
+ gap: var(--cds-spacing-05, 1rem);
512
+ min-inline-size: 0;
513
+ }
514
+ .eth-motion-skeleton-loading__table-header {
515
+ align-items: center;
516
+ background: var(--cds-layer-02, #f4f4f4);
517
+ min-block-size: 2.5rem;
518
+ padding: var(--cds-spacing-04, .75rem);
519
+ }
520
+ .eth-motion-skeleton-loading__table-row {
521
+ align-items: center;
522
+ border-block-start: 1px solid var(--cds-border-subtle, #e0e0e0);
523
+ min-block-size: 3rem;
524
+ padding: var(--cds-spacing-04, .75rem);
525
+ }
526
+ .eth-motion-skeleton-loading__block--cell {
527
+ block-size: .75rem;
528
+ }
529
+ @media (max-width: 42rem) {
530
+ .eth-motion-sync-progress__header {
531
+ align-items: stretch;
532
+ flex-direction: column;
533
+ }
534
+ .eth-motion-sync-progress__chip {
535
+ align-self: start;
536
+ }
537
+ .eth-motion-sync-progress__meta {
538
+ grid-template-columns: minmax(0, 1fr);
539
+ }
540
+ .eth-motion-sync-progress__meta-item + .eth-motion-sync-progress__meta-item {
541
+ border-block-start: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
542
+ border-inline-start: 0;
543
+ }
544
+ .eth-motion-skeleton-loading__list-row {
545
+ grid-template-columns: 2rem minmax(0, 1fr);
546
+ }
547
+ .eth-motion-skeleton-loading__block--tag {
548
+ display: none;
549
+ }
550
+ .eth-motion-skeleton-loading__table-header,
551
+ .eth-motion-skeleton-loading__table-row {
552
+ gap: var(--cds-spacing-04, .75rem);
553
+ }
554
+ }
555
+ .eth-motion-status-change {
556
+ --eth-motion-status-color: var(--cds-interactive, #0f62fe);
557
+ --eth-motion-status-previous-color: var(--cds-text-secondary, #525252);
558
+
559
+ align-items: center;
560
+ background: var(--cds-layer-01, #ffffff);
561
+ border: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
562
+ border-inline-start: 3px solid var(--eth-motion-status-color);
563
+ border-radius: var(--cds-radius-sm, 2px);
564
+ box-sizing: border-box;
565
+ color: var(--cds-text-primary, #161616);
566
+ display: inline-flex;
567
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
568
+ gap: var(--cds-spacing-04, .75rem);
569
+ inline-size: fit-content;
570
+ line-height: 1.2857;
571
+ max-inline-size: 100%;
572
+ min-block-size: 2.5rem;
573
+ padding: .5rem .75rem .5rem .625rem;
574
+ vertical-align: middle;
575
+ }
576
+ .eth-motion-status-change--changed {
577
+ animation: eth-motion-pulse 650ms var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) 1;
578
+ background: var(--cds-layer-02, #f4f4f4);
579
+ }
580
+ .eth-motion-status-change__indicator {
581
+ align-items: center;
582
+ display: inline-flex;
583
+ flex: 0 0 auto;
584
+ inline-size: 2.5rem;
585
+ }
586
+ .eth-motion-status-change__previous-dot,
587
+ .eth-motion-status-change__current-dot {
588
+ border-radius: 50%;
589
+ box-sizing: border-box;
590
+ display: inline-block;
591
+ flex: 0 0 auto;
592
+ }
593
+ .eth-motion-status-change__previous-dot {
594
+ background: var(--eth-motion-status-previous-color);
595
+ block-size: .5rem;
596
+ inline-size: .5rem;
597
+ opacity: .64;
598
+ }
599
+ .eth-motion-status-change__connector {
600
+ background: var(--cds-border-strong-01, #8d8d8d);
601
+ block-size: 1px;
602
+ flex: 1 1 auto;
603
+ margin-inline: .25rem;
604
+ min-inline-size: .625rem;
605
+ }
606
+ .eth-motion-status-change__current-dot {
607
+ background: var(--eth-motion-status-color);
608
+ block-size: .625rem;
609
+ box-shadow: 0 0 0 2px var(--cds-layer-01, #ffffff);
610
+ inline-size: .625rem;
611
+ position: relative;
612
+ }
613
+ .eth-motion-status-change--changed .eth-motion-status-change__current-dot::after {
614
+ animation: eth-motion-status-halo 700ms var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) 1;
615
+ border: 1px solid var(--eth-motion-status-color);
616
+ border-radius: 50%;
617
+ content: "";
618
+ inset: -.375rem;
619
+ opacity: 0;
620
+ position: absolute;
621
+ }
622
+ .eth-motion-status-change__content {
623
+ display: grid;
624
+ gap: var(--cds-spacing-01, .125rem);
625
+ min-inline-size: 0;
626
+ }
627
+ .eth-motion-status-change__label {
628
+ color: var(--cds-text-primary, #161616);
629
+ font-size: var(--cds-body-compact-01-font-size, .875rem);
630
+ font-weight: 600;
631
+ line-height: var(--cds-body-compact-01-line-height, 1.2857);
632
+ min-inline-size: 0;
633
+ overflow-wrap: anywhere;
634
+ }
635
+ .eth-motion-status-change__state {
636
+ align-items: center;
637
+ color: var(--cds-text-secondary, #525252);
638
+ display: flex;
639
+ flex-wrap: wrap;
640
+ font-size: var(--cds-label-01-font-size, .75rem);
641
+ gap: var(--cds-spacing-02, .25rem);
642
+ line-height: var(--cds-label-01-line-height, 1.3333);
643
+ min-inline-size: 0;
644
+ }
645
+ .eth-motion-status-change__previous,
646
+ .eth-motion-status-change__current {
647
+ overflow-wrap: anywhere;
648
+ }
649
+ .eth-motion-status-change__current {
650
+ color: var(--cds-text-primary, #161616);
651
+ font-weight: 600;
652
+ }
653
+ .eth-motion-status-change__separator {
654
+ color: var(--cds-text-secondary, #525252);
655
+ }
656
+ .eth-motion-attention-pulse {
657
+ --eth-motion-attention-color: var(--cds-support-warning, #f1c21b);
658
+ --eth-motion-attention-border: #8a6a00;
659
+ --eth-motion-attention-ink: var(--cds-text-primary, #161616);
660
+ --eth-motion-attention-repeat: infinite;
661
+
662
+ align-items: center;
663
+ background: var(--cds-layer-02, #ffffff);
664
+ border: 1px solid var(--cds-border-subtle, #e0e0e0);
665
+ border-radius: var(--cds-radius-sm, 2px);
666
+ box-shadow: inset 3px 0 0 var(--eth-motion-attention-color);
667
+ color: var(--cds-text-primary, #161616);
668
+ display: inline-flex;
669
+ font-size: .875rem;
670
+ font-weight: 500;
671
+ gap: var(--cds-spacing-03, .5rem);
672
+ inline-size: fit-content;
673
+ line-height: 1.2857;
674
+ max-inline-size: 100%;
675
+ min-block-size: 2rem;
676
+ padding: .375rem .75rem .375rem .625rem;
677
+ vertical-align: middle;
678
+ }
679
+ .eth-motion-attention-pulse__marker {
680
+ align-items: center;
681
+ block-size: 1rem;
682
+ display: inline-flex;
683
+ flex: 0 0 auto;
684
+ inline-size: 1rem;
685
+ justify-content: center;
686
+ position: relative;
687
+ }
688
+ .eth-motion-attention-pulse__marker::before {
689
+ animation: eth-motion-attention-ring 1.4s var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) var(--eth-motion-attention-repeat);
690
+ border: 1px solid var(--eth-motion-attention-color);
691
+ border-radius: 50%;
692
+ content: "";
693
+ inset: -.125rem;
694
+ position: absolute;
695
+ }
696
+ .eth-motion-attention-pulse__dot {
697
+ align-items: center;
698
+ background: var(--eth-motion-attention-color);
699
+ block-size: 1rem;
700
+ border: 1px solid var(--eth-motion-attention-border);
701
+ border-radius: 50%;
702
+ color: var(--eth-motion-attention-ink);
703
+ display: inline-flex;
704
+ font-size: .6875rem;
705
+ font-weight: 700;
706
+ inline-size: 1rem;
707
+ justify-content: center;
708
+ line-height: 1;
709
+ position: relative;
710
+ }
711
+ .eth-motion-attention-pulse__label {
712
+ min-inline-size: 0;
713
+ overflow-wrap: anywhere;
714
+ }
715
+ .eth-motion-attention-pulse.eth-motion-reduced .eth-motion-attention-pulse__marker::before {
716
+ animation: none;
717
+ opacity: .32;
718
+ transform: scale(1);
719
+ }
720
+ .eth-motion-document-lock {
721
+ --eth-motion-document-lock-accent: var(--cds-interactive, #0f62fe);
722
+
723
+ align-items: center;
724
+ background: var(--cds-layer-01, #ffffff);
725
+ border: 1px solid var(--cds-border-subtle-01, var(--cds-border-subtle, #e0e0e0));
726
+ border-inline-start: 3px solid var(--cds-border-strong-01, #8d8d8d);
727
+ box-sizing: border-box;
728
+ color: var(--cds-text-primary, #161616);
729
+ display: inline-flex;
730
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
731
+ gap: var(--cds-spacing-03, .5rem);
732
+ inline-size: fit-content;
733
+ line-height: 1.2857;
734
+ max-inline-size: 100%;
735
+ min-block-size: 2.5rem;
736
+ padding: .375rem .75rem .375rem .625rem;
737
+ vertical-align: middle;
738
+ }
739
+ .eth-motion-document-lock--active {
740
+ background: var(--cds-layer-02, #f4f4f4);
741
+ border-inline-start-color: var(--eth-motion-document-lock-accent);
742
+ }
743
+ .eth-motion-document-lock__indicator {
744
+ align-items: center;
745
+ block-size: 1.25rem;
746
+ color: var(--cds-icon-secondary, #525252);
747
+ display: inline-flex;
748
+ flex: 0 0 auto;
749
+ inline-size: 1.25rem;
750
+ justify-content: center;
751
+ position: relative;
752
+ }
753
+ .eth-motion-document-lock--active .eth-motion-document-lock__indicator {
754
+ color: var(--eth-motion-document-lock-accent);
755
+ }
756
+ .eth-motion-document-lock__pulse {
757
+ border: 1px solid currentColor;
758
+ border-radius: 50%;
759
+ inset: .125rem;
760
+ opacity: 0;
761
+ position: absolute;
762
+ }
763
+ .eth-motion-document-lock--active .eth-motion-document-lock__pulse {
764
+ animation: eth-motion-lock-pulse 1.45s var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) infinite;
765
+ opacity: .34;
766
+ }
767
+ .eth-motion-document-lock__icon {
768
+ block-size: 1rem;
769
+ inline-size: 1rem;
770
+ position: relative;
771
+ }
772
+ .eth-motion-document-lock__content {
773
+ display: grid;
774
+ gap: 0;
775
+ min-inline-size: 0;
776
+ }
777
+ .eth-motion-document-lock__state {
778
+ color: var(--cds-text-secondary, #525252);
779
+ font-size: .75rem;
780
+ font-weight: 600;
781
+ line-height: 1.3333;
782
+ }
783
+ .eth-motion-document-lock--active .eth-motion-document-lock__state {
784
+ color: var(--cds-link-primary, #0f62fe);
785
+ }
786
+ .eth-motion-document-lock__owner {
787
+ color: var(--cds-text-primary, #161616);
788
+ font-size: .875rem;
789
+ font-weight: 600;
790
+ line-height: 1.2857;
791
+ overflow-wrap: anywhere;
792
+ }
793
+ .eth-motion-document-lock.eth-motion-reduced .eth-motion-document-lock__pulse {
794
+ animation: none;
795
+ opacity: .18;
796
+ transform: scale(1);
797
+ }
798
+ .eth-motion-step-completion {
799
+ align-items: start;
800
+ color: var(--cds-text-primary, #161616);
801
+ display: inline-grid;
802
+ font-family: var(--cds-font-family, "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
803
+ font-size: var(--cds-body-compact-01-font-size, .875rem);
804
+ gap: var(--cds-spacing-03, .5rem);
805
+ grid-template-columns: 1.5rem minmax(0, 1fr);
806
+ line-height: var(--cds-body-compact-01-line-height, 1.4286);
807
+ max-inline-size: 100%;
808
+ min-inline-size: 0;
809
+ vertical-align: middle;
810
+ }
811
+ .eth-motion-step-completion__marker {
812
+ align-items: center;
813
+ background: var(--cds-layer-01, #ffffff);
814
+ block-size: 1.5rem;
815
+ border: 1px solid var(--cds-border-strong-01, #8d8d8d);
816
+ border-radius: 50%;
817
+ color: var(--cds-icon-secondary, #525252);
818
+ display: inline-flex;
819
+ flex: 0 0 auto;
820
+ inline-size: 1.5rem;
821
+ justify-content: center;
822
+ margin-block-start: .0625rem;
823
+ }
824
+ .eth-motion-step-completion--completed .eth-motion-step-completion__marker {
825
+ animation: eth-motion-check 220ms var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) 1;
826
+ background: var(--cds-support-success, #24a148);
827
+ border-color: var(--cds-support-success, #24a148);
828
+ color: var(--cds-text-on-color, #ffffff);
829
+ }
830
+ .eth-motion-step-completion--current .eth-motion-step-completion__marker {
831
+ animation: eth-motion-step-current 1.25s var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) infinite;
832
+ background: var(--cds-highlight, #edf5ff);
833
+ border-color: var(--cds-interactive, #0f62fe);
834
+ color: var(--cds-interactive, #0f62fe);
835
+ }
836
+ .eth-motion-step-completion--pending .eth-motion-step-completion__marker {
837
+ background: var(--cds-layer-02, #f4f4f4);
838
+ border-color: var(--cds-border-strong-01, #8d8d8d);
839
+ color: var(--cds-icon-secondary, #525252);
840
+ }
841
+ .eth-motion-step-completion__check {
842
+ block-size: 1rem;
843
+ display: block;
844
+ inline-size: 1rem;
845
+ }
846
+ .eth-motion-step-completion__check-path {
847
+ animation: eth-motion-step-check 260ms var(--cds-productive-standard-easing, cubic-bezier(.2, 0, .38, .9)) 90ms both;
848
+ fill: none;
849
+ stroke: currentColor;
850
+ stroke-dasharray: 18;
851
+ stroke-dashoffset: 18;
852
+ stroke-linecap: round;
853
+ stroke-linejoin: round;
854
+ stroke-width: 2;
855
+ }
856
+ .eth-motion-step-completion__dot {
857
+ background: currentColor;
858
+ block-size: .4375rem;
859
+ border-radius: 50%;
860
+ display: block;
861
+ inline-size: .4375rem;
862
+ }
863
+ .eth-motion-step-completion--current .eth-motion-step-completion__dot {
864
+ block-size: .5rem;
865
+ inline-size: .5rem;
866
+ }
867
+ .eth-motion-step-completion__content {
868
+ display: grid;
869
+ gap: .125rem;
870
+ min-inline-size: 0;
871
+ }
872
+ .eth-motion-step-completion__label {
873
+ color: var(--cds-text-primary, #161616);
874
+ font-weight: 600;
875
+ overflow-wrap: anywhere;
876
+ }
877
+ .eth-motion-step-completion__state {
878
+ color: var(--cds-text-secondary, #525252);
879
+ font-size: var(--cds-label-01-font-size, .75rem);
880
+ font-weight: 600;
881
+ line-height: var(--cds-label-01-line-height, 1.3333);
882
+ }
883
+ .eth-motion-step-completion--completed .eth-motion-step-completion__state {
884
+ color: var(--cds-support-success-strong, #198038);
885
+ }
886
+ .eth-motion-step-completion--current .eth-motion-step-completion__state {
887
+ color: var(--cds-link-primary, #0f62fe);
888
+ }
889
+ .eth-motion-step-completion__description {
890
+ color: var(--cds-text-secondary, #525252);
891
+ font-size: var(--cds-label-01-font-size, .75rem);
892
+ line-height: var(--cds-label-01-line-height, 1.3333);
893
+ overflow-wrap: anywhere;
894
+ }
895
+ .eth-motion-step-completion.eth-motion-reduced .eth-motion-step-completion__check-path {
896
+ stroke-dashoffset: 0;
897
+ }
898
+ .eth-motion-reduced,
899
+ .eth-motion-reduced * { animation: none !important; transition: none !important; }
900
+ `}</style>
901
+ );
902
+ }
903
+
904
+ export function statusColor(status: EthOperationalStatus) {
905
+ switch (status) {
906
+ case "succeeded":
907
+ case "completed":
908
+ case "synced":
909
+ return "#24a148";
910
+ case "failed":
911
+ case "blocked":
912
+ return "#da1e28";
913
+ case "warning":
914
+ case "pending-approval":
915
+ case "approval-required":
916
+ return "#f1c21b";
917
+ case "running":
918
+ case "in-progress":
919
+ case "active":
920
+ return "#0f62fe";
921
+ case "paused":
922
+ case "stale":
923
+ return "#8d8d8d";
924
+ default:
925
+ return "#6f6f6f";
926
+ }
927
+ }
928
+
929
+ export function severityColor(severity: EthSeverity | undefined) {
930
+ switch (severity) {
931
+ case "danger":
932
+ return "#da1e28";
933
+ case "warning":
934
+ return "#f1c21b";
935
+ case "success":
936
+ return "#24a148";
937
+ case "info":
938
+ return "#0f62fe";
939
+ default:
940
+ return "#6f6f6f";
941
+ }
942
+ }