@actioneer/ads 1.0.7 → 1.0.8

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 (71) hide show
  1. package/DESIGN.md +80 -86
  2. package/README.md +6 -0
  3. package/components/ai-elements/chart.js +20 -20
  4. package/components/ai-elements/inline-citation.js +50 -50
  5. package/components/ai-elements/message.js +1 -1
  6. package/components/ai-elements/tool.js +5 -5
  7. package/components/alert.d.ts +3 -2
  8. package/components/alert.js +25 -25
  9. package/components/answer.js +1 -1
  10. package/components/assistant-ui/action-bar.js +1 -1
  11. package/components/assistant-ui/attachment.js +68 -49
  12. package/components/assistant-ui/composer-add-context.js +1 -1
  13. package/components/assistant-ui/composer-trigger-popover.js +1 -1
  14. package/components/assistant-ui/composer.js +13 -13
  15. package/components/assistant-ui/message-timing.js +6 -6
  16. package/components/assistant-ui/selection-toolbar.js +5 -5
  17. package/components/assistant-ui/sources.js +15 -15
  18. package/components/assistant-ui/tooltip-icon-button.js +18 -14
  19. package/components/audio-waveform.d.ts +21 -8
  20. package/components/audio-waveform.js +371 -94
  21. package/components/autocomplete.js +9 -9
  22. package/components/breadcrumbs.js +32 -38
  23. package/components/button.js +83 -73
  24. package/components/card.js +1 -1
  25. package/components/chart.js +732 -673
  26. package/components/chip.js +37 -35
  27. package/components/command-palette.js +12 -12
  28. package/components/connector-card.d.ts +1 -2
  29. package/components/connector-card.js +17 -17
  30. package/components/date-range-picker.js +1 -2
  31. package/components/drawer.js +9 -10
  32. package/components/dropdown.js +1 -1
  33. package/components/empty-state.d.ts +2 -0
  34. package/components/empty-state.js +17 -15
  35. package/components/field.js +9 -10
  36. package/components/file-dropzone.d.ts +6 -3
  37. package/components/file-dropzone.js +72 -60
  38. package/components/infinite-canvas.js +9 -9
  39. package/components/modal.js +1 -1
  40. package/components/page-body.js +8 -8
  41. package/components/popover.js +11 -11
  42. package/components/progress-circle.d.ts +1 -1
  43. package/components/progress-circle.js +57 -48
  44. package/components/segmented.d.ts +1 -0
  45. package/components/segmented.js +34 -36
  46. package/components/select.js +2 -2
  47. package/components/selection-action-bar.js +32 -31
  48. package/components/setting-row.js +10 -10
  49. package/components/slider.js +5 -5
  50. package/components/stepper.d.ts +1 -1
  51. package/components/stepper.js +1 -1
  52. package/components/switch.js +10 -10
  53. package/components/table.d.ts +2 -2
  54. package/components/table.js +177 -170
  55. package/components/tabs.js +41 -35
  56. package/components/timeline.js +3 -3
  57. package/components/toast.js +53 -56
  58. package/components/ui/button.js +4 -4
  59. package/components/ui/dialog.js +1 -1
  60. package/components/viz-charts.js +263 -221
  61. package/examples/README.md +30 -0
  62. package/examples/agents-screen.tsx +477 -0
  63. package/examples/settings-screen.tsx +90 -0
  64. package/examples/workspace-header.tsx +71 -0
  65. package/lib/icons.d.ts +8 -0
  66. package/lib/icons.js +171 -118
  67. package/llms.txt +14 -14
  68. package/manifest.json +77 -48
  69. package/package.json +1 -1
  70. package/styles.css +55 -68
  71. package/theme.css +50 -59
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actioneer/ads",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Actioneer Design System 1.0 — React 19 + Tailwind v4 component library.",
5
5
  "type": "module",
6
6
  "sideEffects": [
package/styles.css CHANGED
@@ -39,7 +39,7 @@
39
39
  /*
40
40
  * ============================================================
41
41
  * ADS 1.0 — Design Tokens
42
- * Palette: warm greys + product teal
42
+ * Palette: neutral greys + product teal
43
43
  * Typeface: Aribau Grotesk
44
44
  * ============================================================
45
45
  */
@@ -93,7 +93,7 @@
93
93
 
94
94
  /* ---- Foundation palette ----
95
95
  Canonical primitive names:
96
- T1…T12 = Teal · WG1…WG12 = Warm Grey.
96
+ T1…T12 = Teal · WG1…WG12 = Neutral Grey (the WG token names are kept).
97
97
  Each ramp progresses from light backgrounds and interactive fills through
98
98
  supporting tones to solid colors and accessible text. Neutral UI borders
99
99
  are intentionally restricted to WG3–WG5. ---- */
@@ -110,20 +110,20 @@
110
110
  --color-t11: #016159;
111
111
  --color-t12: #0f3c37;
112
112
 
113
- --color-wg1: #f9f7f0;
114
- --color-wg2: #f3f1e9;
115
- --color-wg3: #efece3;
116
- --color-wg4: #e8e5db;
117
- --color-wg5: #dfdcd0;
118
- --color-wg6: #d4d1c4;
119
- --color-wg7: #c6c2b3;
120
- --color-wg8: #aaa698;
121
- --color-wg9: #79766a;
122
- --color-wg10: #6b685e;
123
- --color-wg11: #4d4b44;
124
- --color-wg12: #21201d;
125
-
126
- /* Deprecated Neutral Grey names resolve to the canonical Warm Grey ramp.
113
+ --color-wg1: #fafafa;
114
+ --color-wg2: #f6f6f6;
115
+ --color-wg3: #f1f1f1;
116
+ --color-wg4: #ececec;
117
+ --color-wg5: #e6e6e6;
118
+ --color-wg6: #dedede;
119
+ --color-wg7: #d4d4d4;
120
+ --color-wg8: #bdbdbd;
121
+ --color-wg9: #868686;
122
+ --color-wg10: #7c7b7b;
123
+ --color-wg11: #5e5d5d;
124
+ --color-wg12: #202020;
125
+
126
+ /* Deprecated NG names resolve step-for-step to the canonical WG ramp.
127
127
  Keep these aliases so existing consumer utilities continue to render. */
128
128
  --color-ng1: var(--color-wg1);
129
129
  --color-ng2: var(--color-wg2);
@@ -267,41 +267,26 @@
267
267
  convention). */
268
268
  --radius-dot: 2px;
269
269
 
270
- /* ---- Elevation ---- Shopify-inspired 0–600 ladder, recolored with WG12.
271
- Geometry and opacity increase together; static surfaces remain at 0. */
270
+ /* ---- Elevation ---- five shadows, nothing else (ADS 1.0.8).
271
+ A shadow means "this layer floats above the page". Everything that sits
272
+ in the page — cards, panels, chips, buttons, tabs, fields — is flat and
273
+ reads by fill or border. Neutral WG12 ink (rgb 32 32 32); each floating
274
+ level pairs a 4% hairline (crisp edge on white), a tight contact shadow
275
+ and a wide ambient one. */
272
276
  --shadow-0: none;
273
- --shadow-100: 0 1px 0 0 rgb(32 32 32 / 0.07);
274
- --shadow-200: 0 3px 1px -1px rgb(32 32 32 / 0.07);
275
- --shadow-300: 0 4px 6px -2px rgb(32 32 32 / 0.2);
276
- --shadow-400: 0 8px 16px -4px rgb(32 32 32 / 0.22);
277
- --shadow-500: 0 12px 20px -8px rgb(32 32 32 / 0.24);
278
- --shadow-600: 0 20px 20px -8px rgb(32 32 32 / 0.28);
279
-
280
- /* Compatibility hook stays flat. Apply a numbered level only when the user
281
- explicitly requests elevation for a named surface. */
282
- --shadow-elevation: var(--shadow-0);
283
-
284
- /* Pinned-table-column smudges — whisper-soft directional casts shown only
285
- while content is hidden behind a sticky column (Table is scroll-aware).
286
- Deep negative spread keeps the edge feathered; the tint is warm grey. */
277
+ /* Menus, popovers, listboxes, tooltips with content, toasts, toolbars and
278
+ the chat composer dock. */
279
+ --shadow-float: 0 0 0 1px rgb(32 32 32 / 0.04), 0 2px 4px rgb(32 32 32 / 0.04), 0 8px 20px -4px rgb(32 32 32 / 0.10);
280
+ /* Modals, dialogs and overlay drawers — one step above float so a dialog
281
+ always reads on top of a menu. */
282
+ --shadow-overlay: 0 0 0 1px rgb(32 32 32 / 0.04), 0 4px 8px rgb(32 32 32 / 0.04), 0 16px 36px -8px rgb(32 32 32 / 0.14);
283
+
284
+ /* Table scroll hints — whisper-soft directional casts shown only while
285
+ content is hidden behind a sticky column (Table is scroll-aware). Deep
286
+ negative spread keeps the edge feathered; the tint is neutral grey. */
287
287
  --shadow-table-smudge-left: 8px 0 24px -14px rgb(32 32 32 / 0.05);
288
288
  --shadow-table-smudge-right: -8px 0 24px -14px rgb(32 32 32 / 0.05);
289
289
 
290
- /* ---- Button inset depth ---- Polaris-inspired stacked inner edges. The
291
- lower contact line, quiet inner outline, and half-pixel top catch make
292
- solid actions feel tactile without adding a decorative outer border. */
293
- --inner-glow-cta: inset 0 -1px 0 1px rgb(32 32 32 / 0.22),
294
- inset 0 0 0 1px rgb(32 32 32 / 0.12),
295
- inset 0 0.5px 0 1.5px rgb(255 255 255 / 0.28);
296
- /* Compatibility treatment for explicitly raised light fills. Its visible
297
- edge is entirely inset, so it keeps a transparent outer border. */
298
- --inner-glow-fill: inset 0 -1px 0 0 var(--border-primary),
299
- inset 0 0 0 1px rgb(32 32 32 / 0.1),
300
- inset 0 0.5px 0 1.5px rgb(255 255 255 / 0.86);
301
- /* Text fields — a whisper of inset depth so the writing surface reads
302
- recessed into the page (persists through hover/focus/invalid). */
303
- --inner-glow-field: inset 0 1px 2px 0 rgb(32 32 32 / 0.06);
304
-
305
290
  /* ---- Layout ---- app-frame dimensions (Sidebar / Panel) */
306
291
  --sidebar-width: 15rem; /* 240px — primary nav rail */
307
292
  --sidebar-width-sm: 3.5rem; /* 56px — collapsed icon rail */
@@ -446,7 +431,7 @@
446
431
  --color-menu-stroke: var(--menu-stroke);
447
432
  --color-toast-stroke: var(--toast-stroke);
448
433
  --color-tree-stroke: var(--tree-stroke);
449
- /* Focus ring and scrim, both translucent warm ink. */
434
+ /* Focus ring and scrim, both translucent neutral ink. */
450
435
  --color-ring: var(--ring);
451
436
  --color-overlay: var(--overlay);
452
437
 
@@ -482,21 +467,21 @@
482
467
  --foreground: var(--color-wg12); /* step 12 */
483
468
 
484
469
  /* Both surface contexts point directly into the approved WG text steps.
485
- WG9 is the tertiary/de-emphasis step for nonessential metadata. It clears
486
- normal-text AA on White; use Secondary when normal text on WG2 must clear
487
- AA. */
470
+ WG9 is the tertiary/de-emphasis step for nonessential metadata. On the
471
+ neutral ramp it clears large-text AA only; use Secondary whenever normal
472
+ text must clear AA. */
488
473
  --text-on-white-primary: var(--color-wg12); /* 16.29:1 · AAA */
489
- --text-on-white-secondary: var(--color-wg11); /* 8.73:1 · AAA */
490
- --text-on-white-tertiary: var(--color-wg9); /* 4.55:1 · AA */
491
- --text-on-warm-grey-primary: var(--color-wg12); /* 14.41:1 on WG2 · AAA */
492
- --text-on-warm-grey-secondary: var(--color-wg11); /* 7.72:1 on WG2 · AAA */
493
- --text-on-warm-grey-tertiary: var(--color-wg9); /* 4.03:1 on WG2 · large text AA */
474
+ --text-on-white-secondary: var(--color-wg11); /* 6.56:1 · AA */
475
+ --text-on-white-tertiary: var(--color-wg9); /* 3.64:1 · large text AA */
476
+ --text-on-warm-grey-primary: var(--color-wg12); /* 15.08:1 on WG2 · AAA */
477
+ --text-on-warm-grey-secondary: var(--color-wg11); /* 6.07:1 on WG2 · AA */
478
+ --text-on-warm-grey-tertiary: var(--color-wg9); /* 3.37:1 on WG2 · large text AA */
494
479
 
495
480
  /* Existing context-free utilities remain conservative compatibility aliases
496
481
  across WG2–WG4 and White until their call sites adopt a surface role. */
497
- --text-primary: var(--color-wg12); /* 12.93:1 AAA (WG4 min surf) */
498
- --text-secondary: var(--color-wg11); /* 6.93:1 AA (WG4 min surf) */
499
- --text-tertiary: color-mix(in srgb, var(--color-wg10) 80%, var(--color-wg11)); /* 4.83:1 AA (WG4) */
482
+ --text-primary: var(--color-wg12); /* 13.79:1 AAA (WG4 min surf) */
483
+ --text-secondary: var(--color-wg11); /* 5.56:1 AA (WG4 min surf) */
484
+ --text-tertiary: color-mix(in srgb, var(--color-wg10) 40%, var(--color-wg11)); /* 4.63:1 AA (WG4) */
500
485
 
501
486
  --surface: var(--color-wg3); /* step 3 · tinted canvas */
502
487
  --surface-foreground: var(--color-wg12);
@@ -620,6 +605,12 @@
620
605
  * clipped to the panel radius. Honours reduced-motion.
621
606
  * ============================================================
622
607
  */
608
+ /* Icon-only controls fill their icon on hover instead of drawing a
609
+ background (see IconHoverFillContext in src/lib/icons.tsx). */
610
+ .ads-icon-hover { display: none; }
611
+ [data-icon-hover-fill]:hover:not(:disabled) .ads-icon-rest { display: none; }
612
+ [data-icon-hover-fill]:hover:not(:disabled) .ads-icon-hover { display: block; }
613
+
623
614
  @keyframes ads-ripple-wave {
624
615
  0% { opacity: 0.6; transform: scale(0.15); }
625
616
  100% { opacity: 0; transform: scale(1.08); }
@@ -701,12 +692,12 @@
701
692
 
702
693
  .ask-empty-composer [data-slot="aui_composer-shell"] {
703
694
  border-color: var(--color-wg4);
704
- box-shadow: var(--shadow-200);
695
+ box-shadow: var(--shadow-float);
705
696
  }
706
697
 
707
698
  .ask-empty-composer:focus-within [data-slot="aui_composer-shell"] {
708
699
  border-color: var(--color-t8);
709
- box-shadow: 0 0 0 3px var(--color-t4), var(--shadow-300);
700
+ box-shadow: 0 0 0 3px var(--color-t4), var(--shadow-float);
710
701
  }
711
702
 
712
703
  .ask-section-label {
@@ -715,13 +706,10 @@
715
706
  }
716
707
 
717
708
  /* Artifact widgets are positioned by GridStack; ADS cards own the visible
718
- surface while the library content wrapper only clips during interaction.
719
- The subtle elevation lives on the wrapper (not the inner card) because the
720
- wrapper's own `overflow: hidden` would clip a shadow drawn on its child. */
709
+ surface while the library content wrapper only clips during interaction. */
721
710
  .artifact-grid-stack > .grid-stack-item > .grid-stack-item-content {
722
711
  overflow: hidden;
723
712
  border-radius: var(--radius-lg);
724
- box-shadow: var(--shadow-elevation);
725
713
  }
726
714
 
727
715
  /* Edit affordances live on a parent flag — never toggle GridStack's own
@@ -987,9 +975,8 @@
987
975
  --glow-border-rest: var(--border);
988
976
  --glow-border-hover: var(--brand);
989
977
  --glow-border-active: var(--foreground);
990
- /* Optional persistent inset (e.g. the field inner glow) — hosts opt in
991
- via [--glow-inset:var(--inner-glow-field)]; carried through every
992
- state below so hover/focus/invalid never strip it. */
978
+ /* Optional persistent inset hook. ADS fields are flat (no inset shadow);
979
+ carried through every state below so a host value is never stripped. */
993
980
  --glow-inset: 0 0 transparent;
994
981
 
995
982
  border-color: var(--glow-border-rest);
package/theme.css CHANGED
@@ -8,7 +8,7 @@
8
8
  /*
9
9
  * ============================================================
10
10
  * ADS 1.0 — Design Tokens
11
- * Palette: warm greys + product teal
11
+ * Palette: neutral greys + product teal
12
12
  * Typeface: Aribau Grotesk
13
13
  * ============================================================
14
14
  */
@@ -62,7 +62,7 @@
62
62
 
63
63
  /* ---- Foundation palette ----
64
64
  Canonical primitive names:
65
- T1…T12 = Teal · WG1…WG12 = Warm Grey.
65
+ T1…T12 = Teal · WG1…WG12 = Neutral Grey (the WG token names are kept).
66
66
  Each ramp progresses from light backgrounds and interactive fills through
67
67
  supporting tones to solid colors and accessible text. Neutral UI borders
68
68
  are intentionally restricted to WG3–WG5. ---- */
@@ -79,20 +79,20 @@
79
79
  --color-t11: #016159;
80
80
  --color-t12: #0f3c37;
81
81
 
82
- --color-wg1: #f9f7f0;
83
- --color-wg2: #f3f1e9;
84
- --color-wg3: #efece3;
85
- --color-wg4: #e8e5db;
86
- --color-wg5: #dfdcd0;
87
- --color-wg6: #d4d1c4;
88
- --color-wg7: #c6c2b3;
89
- --color-wg8: #aaa698;
90
- --color-wg9: #79766a;
91
- --color-wg10: #6b685e;
92
- --color-wg11: #4d4b44;
93
- --color-wg12: #21201d;
94
-
95
- /* Deprecated Neutral Grey names resolve to the canonical Warm Grey ramp.
82
+ --color-wg1: #fafafa;
83
+ --color-wg2: #f6f6f6;
84
+ --color-wg3: #f1f1f1;
85
+ --color-wg4: #ececec;
86
+ --color-wg5: #e6e6e6;
87
+ --color-wg6: #dedede;
88
+ --color-wg7: #d4d4d4;
89
+ --color-wg8: #bdbdbd;
90
+ --color-wg9: #868686;
91
+ --color-wg10: #7c7b7b;
92
+ --color-wg11: #5e5d5d;
93
+ --color-wg12: #202020;
94
+
95
+ /* Deprecated NG names resolve step-for-step to the canonical WG ramp.
96
96
  Keep these aliases so existing consumer utilities continue to render. */
97
97
  --color-ng1: var(--color-wg1);
98
98
  --color-ng2: var(--color-wg2);
@@ -236,41 +236,26 @@
236
236
  convention). */
237
237
  --radius-dot: 2px;
238
238
 
239
- /* ---- Elevation ---- Shopify-inspired 0–600 ladder, recolored with WG12.
240
- Geometry and opacity increase together; static surfaces remain at 0. */
239
+ /* ---- Elevation ---- five shadows, nothing else (ADS 1.0.8).
240
+ A shadow means "this layer floats above the page". Everything that sits
241
+ in the page — cards, panels, chips, buttons, tabs, fields — is flat and
242
+ reads by fill or border. Neutral WG12 ink (rgb 32 32 32); each floating
243
+ level pairs a 4% hairline (crisp edge on white), a tight contact shadow
244
+ and a wide ambient one. */
241
245
  --shadow-0: none;
242
- --shadow-100: 0 1px 0 0 rgb(32 32 32 / 0.07);
243
- --shadow-200: 0 3px 1px -1px rgb(32 32 32 / 0.07);
244
- --shadow-300: 0 4px 6px -2px rgb(32 32 32 / 0.2);
245
- --shadow-400: 0 8px 16px -4px rgb(32 32 32 / 0.22);
246
- --shadow-500: 0 12px 20px -8px rgb(32 32 32 / 0.24);
247
- --shadow-600: 0 20px 20px -8px rgb(32 32 32 / 0.28);
248
-
249
- /* Compatibility hook stays flat. Apply a numbered level only when the user
250
- explicitly requests elevation for a named surface. */
251
- --shadow-elevation: var(--shadow-0);
252
-
253
- /* Pinned-table-column smudges — whisper-soft directional casts shown only
254
- while content is hidden behind a sticky column (Table is scroll-aware).
255
- Deep negative spread keeps the edge feathered; the tint is warm grey. */
246
+ /* Menus, popovers, listboxes, tooltips with content, toasts, toolbars and
247
+ the chat composer dock. */
248
+ --shadow-float: 0 0 0 1px rgb(32 32 32 / 0.04), 0 2px 4px rgb(32 32 32 / 0.04), 0 8px 20px -4px rgb(32 32 32 / 0.10);
249
+ /* Modals, dialogs and overlay drawers — one step above float so a dialog
250
+ always reads on top of a menu. */
251
+ --shadow-overlay: 0 0 0 1px rgb(32 32 32 / 0.04), 0 4px 8px rgb(32 32 32 / 0.04), 0 16px 36px -8px rgb(32 32 32 / 0.14);
252
+
253
+ /* Table scroll hints — whisper-soft directional casts shown only while
254
+ content is hidden behind a sticky column (Table is scroll-aware). Deep
255
+ negative spread keeps the edge feathered; the tint is neutral grey. */
256
256
  --shadow-table-smudge-left: 8px 0 24px -14px rgb(32 32 32 / 0.05);
257
257
  --shadow-table-smudge-right: -8px 0 24px -14px rgb(32 32 32 / 0.05);
258
258
 
259
- /* ---- Button inset depth ---- Polaris-inspired stacked inner edges. The
260
- lower contact line, quiet inner outline, and half-pixel top catch make
261
- solid actions feel tactile without adding a decorative outer border. */
262
- --inner-glow-cta: inset 0 -1px 0 1px rgb(32 32 32 / 0.22),
263
- inset 0 0 0 1px rgb(32 32 32 / 0.12),
264
- inset 0 0.5px 0 1.5px rgb(255 255 255 / 0.28);
265
- /* Compatibility treatment for explicitly raised light fills. Its visible
266
- edge is entirely inset, so it keeps a transparent outer border. */
267
- --inner-glow-fill: inset 0 -1px 0 0 var(--border-primary),
268
- inset 0 0 0 1px rgb(32 32 32 / 0.1),
269
- inset 0 0.5px 0 1.5px rgb(255 255 255 / 0.86);
270
- /* Text fields — a whisper of inset depth so the writing surface reads
271
- recessed into the page (persists through hover/focus/invalid). */
272
- --inner-glow-field: inset 0 1px 2px 0 rgb(32 32 32 / 0.06);
273
-
274
259
  /* ---- Layout ---- app-frame dimensions (Sidebar / Panel) */
275
260
  --sidebar-width: 15rem; /* 240px — primary nav rail */
276
261
  --sidebar-width-sm: 3.5rem; /* 56px — collapsed icon rail */
@@ -415,7 +400,7 @@
415
400
  --color-menu-stroke: var(--menu-stroke);
416
401
  --color-toast-stroke: var(--toast-stroke);
417
402
  --color-tree-stroke: var(--tree-stroke);
418
- /* Focus ring and scrim, both translucent warm ink. */
403
+ /* Focus ring and scrim, both translucent neutral ink. */
419
404
  --color-ring: var(--ring);
420
405
  --color-overlay: var(--overlay);
421
406
 
@@ -451,21 +436,21 @@
451
436
  --foreground: var(--color-wg12); /* step 12 */
452
437
 
453
438
  /* Both surface contexts point directly into the approved WG text steps.
454
- WG9 is the tertiary/de-emphasis step for nonessential metadata. It clears
455
- normal-text AA on White; use Secondary when normal text on WG2 must clear
456
- AA. */
439
+ WG9 is the tertiary/de-emphasis step for nonessential metadata. On the
440
+ neutral ramp it clears large-text AA only; use Secondary whenever normal
441
+ text must clear AA. */
457
442
  --text-on-white-primary: var(--color-wg12); /* 16.29:1 · AAA */
458
- --text-on-white-secondary: var(--color-wg11); /* 8.73:1 · AAA */
459
- --text-on-white-tertiary: var(--color-wg9); /* 4.55:1 · AA */
460
- --text-on-warm-grey-primary: var(--color-wg12); /* 14.41:1 on WG2 · AAA */
461
- --text-on-warm-grey-secondary: var(--color-wg11); /* 7.72:1 on WG2 · AAA */
462
- --text-on-warm-grey-tertiary: var(--color-wg9); /* 4.03:1 on WG2 · large text AA */
443
+ --text-on-white-secondary: var(--color-wg11); /* 6.56:1 · AA */
444
+ --text-on-white-tertiary: var(--color-wg9); /* 3.64:1 · large text AA */
445
+ --text-on-warm-grey-primary: var(--color-wg12); /* 15.08:1 on WG2 · AAA */
446
+ --text-on-warm-grey-secondary: var(--color-wg11); /* 6.07:1 on WG2 · AA */
447
+ --text-on-warm-grey-tertiary: var(--color-wg9); /* 3.37:1 on WG2 · large text AA */
463
448
 
464
449
  /* Existing context-free utilities remain conservative compatibility aliases
465
450
  across WG2–WG4 and White until their call sites adopt a surface role. */
466
- --text-primary: var(--color-wg12); /* 12.93:1 AAA (WG4 min surf) */
467
- --text-secondary: var(--color-wg11); /* 6.93:1 AA (WG4 min surf) */
468
- --text-tertiary: color-mix(in srgb, var(--color-wg10) 80%, var(--color-wg11)); /* 4.83:1 AA (WG4) */
451
+ --text-primary: var(--color-wg12); /* 13.79:1 AAA (WG4 min surf) */
452
+ --text-secondary: var(--color-wg11); /* 5.56:1 AA (WG4 min surf) */
453
+ --text-tertiary: color-mix(in srgb, var(--color-wg10) 40%, var(--color-wg11)); /* 4.63:1 AA (WG4) */
469
454
 
470
455
  --surface: var(--color-wg3); /* step 3 · tinted canvas */
471
456
  --surface-foreground: var(--color-wg12);
@@ -589,6 +574,12 @@
589
574
  * clipped to the panel radius. Honours reduced-motion.
590
575
  * ============================================================
591
576
  */
577
+ /* Icon-only controls fill their icon on hover instead of drawing a
578
+ background (see IconHoverFillContext in src/lib/icons.tsx). */
579
+ .ads-icon-hover { display: none; }
580
+ [data-icon-hover-fill]:hover:not(:disabled) .ads-icon-rest { display: none; }
581
+ [data-icon-hover-fill]:hover:not(:disabled) .ads-icon-hover { display: block; }
582
+
592
583
  @keyframes ads-ripple-wave {
593
584
  0% { opacity: 0.6; transform: scale(0.15); }
594
585
  100% { opacity: 0; transform: scale(1.08); }