@xsynaptic/sonic-ui 0.4.0 → 0.6.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 (247) hide show
  1. package/README.md +3 -20
  2. package/dist/default/dat.js +51 -0
  3. package/dist/default/define/button.js +7 -0
  4. package/dist/default/define/envelope.js +7 -0
  5. package/dist/default/define/split.js +7 -0
  6. package/dist/default/define/switch.js +7 -0
  7. package/dist/default/define/waveform.js +7 -0
  8. package/dist/default/define/wavestrip.js +7 -0
  9. package/dist/default/define/xy.js +7 -0
  10. package/dist/default/define.js +7 -1
  11. package/dist/default/elements/button.js +165 -0
  12. package/dist/default/elements/dial.js +16 -22
  13. package/dist/default/elements/envelope.js +383 -0
  14. package/dist/default/elements/meter.js +155 -63
  15. package/dist/default/elements/number.js +22 -9
  16. package/dist/default/elements/radio-group.js +183 -0
  17. package/dist/default/elements/readout-claim.js +81 -0
  18. package/dist/default/elements/readout.js +35 -0
  19. package/dist/default/elements/segmented.js +9 -159
  20. package/dist/default/elements/slider.js +42 -51
  21. package/dist/default/elements/sonic-element.js +69 -31
  22. package/dist/default/elements/split.js +249 -0
  23. package/dist/default/elements/switch.js +273 -0
  24. package/dist/default/elements/value-element.js +694 -0
  25. package/dist/default/elements/{range-entry.js → value-entry.js} +3 -3
  26. package/dist/default/elements/wave-element.js +80 -0
  27. package/dist/default/elements/waveform.js +328 -0
  28. package/dist/default/elements/wavestrip.js +185 -0
  29. package/dist/default/elements/xy.js +487 -0
  30. package/dist/default/index.js +10 -2
  31. package/dist/default/lib/adsr-shape.js +113 -0
  32. package/dist/default/lib/ballistics.js +55 -0
  33. package/dist/default/lib/canvas-surface.js +203 -0
  34. package/dist/default/lib/copy-node.js +32 -2
  35. package/dist/default/lib/crossfade.js +22 -0
  36. package/dist/default/lib/distribute.js +215 -0
  37. package/dist/default/lib/drag-step.js +99 -0
  38. package/dist/default/lib/envelope-curve.js +9 -0
  39. package/dist/default/lib/field.js +94 -0
  40. package/dist/default/lib/focus-by-pointer.js +28 -0
  41. package/dist/default/lib/frame-timeline.js +63 -0
  42. package/dist/default/lib/hold.js +38 -0
  43. package/dist/default/lib/marker-band.js +80 -0
  44. package/dist/default/lib/marker-rider.js +120 -0
  45. package/dist/default/lib/math.js +17 -3
  46. package/dist/default/lib/modifier-press.js +11 -0
  47. package/dist/default/lib/number-list.js +6 -6
  48. package/dist/default/lib/pointer-drag.js +46 -0
  49. package/dist/default/lib/render.js +20 -5
  50. package/dist/default/lib/resample-peaks.js +46 -0
  51. package/dist/default/lib/strip-scene.js +48 -0
  52. package/dist/default/lib/taper.js +23 -17
  53. package/dist/default/lib/time-regions.js +8 -0
  54. package/dist/default/lib/tracking-clock.js +35 -0
  55. package/dist/default/lib/value-mapping.js +115 -0
  56. package/dist/default/lib/waveform-buckets.js +41 -0
  57. package/dist/default/lib/write-attribute.js +1 -0
  58. package/dist/dev/dat.d.ts +19 -0
  59. package/dist/dev/dat.js +52 -0
  60. package/dist/dev/dat.js.map +1 -0
  61. package/dist/dev/define/button.d.ts +2 -0
  62. package/dist/dev/define/button.js +8 -0
  63. package/dist/dev/define/button.js.map +1 -0
  64. package/dist/dev/define/dial.js.map +1 -1
  65. package/dist/dev/define/envelope.d.ts +2 -0
  66. package/dist/dev/define/envelope.js +8 -0
  67. package/dist/dev/define/envelope.js.map +1 -0
  68. package/dist/dev/define/meter.js.map +1 -1
  69. package/dist/dev/define/number.js.map +1 -1
  70. package/dist/dev/define/segmented.js.map +1 -1
  71. package/dist/dev/define/slider.js.map +1 -1
  72. package/dist/dev/define/split.d.ts +2 -0
  73. package/dist/dev/define/split.js +8 -0
  74. package/dist/dev/define/split.js.map +1 -0
  75. package/dist/dev/define/switch.d.ts +2 -0
  76. package/dist/dev/define/switch.js +8 -0
  77. package/dist/dev/define/switch.js.map +1 -0
  78. package/dist/dev/define/waveform.d.ts +2 -0
  79. package/dist/dev/define/waveform.js +8 -0
  80. package/dist/dev/define/waveform.js.map +1 -0
  81. package/dist/dev/define/wavestrip.d.ts +2 -0
  82. package/dist/dev/define/wavestrip.js +8 -0
  83. package/dist/dev/define/wavestrip.js.map +1 -0
  84. package/dist/dev/define/xy.d.ts +2 -0
  85. package/dist/dev/define/xy.js +8 -0
  86. package/dist/dev/define/xy.js.map +1 -0
  87. package/dist/dev/define.d.ts +15 -3
  88. package/dist/dev/define.js +7 -1
  89. package/dist/dev/elements/{key.d.ts → button.d.ts} +8 -6
  90. package/dist/dev/elements/button.js +166 -0
  91. package/dist/dev/elements/button.js.map +1 -0
  92. package/dist/dev/elements/dial.d.ts +6 -4
  93. package/dist/dev/elements/dial.js +16 -22
  94. package/dist/dev/elements/dial.js.map +1 -1
  95. package/dist/dev/elements/envelope.d.ts +36 -0
  96. package/dist/dev/elements/envelope.js +388 -0
  97. package/dist/dev/elements/envelope.js.map +1 -0
  98. package/dist/dev/elements/form-element.d.ts +1 -1
  99. package/dist/dev/elements/form-element.js.map +1 -1
  100. package/dist/dev/elements/meter.d.ts +11 -6
  101. package/dist/dev/elements/meter.js +155 -63
  102. package/dist/dev/elements/meter.js.map +1 -1
  103. package/dist/dev/elements/number.d.ts +7 -3
  104. package/dist/dev/elements/number.js +22 -9
  105. package/dist/dev/elements/number.js.map +1 -1
  106. package/dist/dev/elements/radio-group.d.ts +25 -0
  107. package/dist/dev/elements/radio-group.js +184 -0
  108. package/dist/dev/elements/radio-group.js.map +1 -0
  109. package/dist/dev/elements/readout-claim.js +82 -0
  110. package/dist/dev/elements/readout-claim.js.map +1 -0
  111. package/dist/dev/elements/readout.js +36 -0
  112. package/dist/dev/elements/readout.js.map +1 -0
  113. package/dist/dev/elements/segmented.d.ts +4 -10
  114. package/dist/dev/elements/segmented.js +9 -159
  115. package/dist/dev/elements/segmented.js.map +1 -1
  116. package/dist/dev/elements/slider.d.ts +6 -6
  117. package/dist/dev/elements/slider.js +42 -51
  118. package/dist/dev/elements/slider.js.map +1 -1
  119. package/dist/dev/elements/sonic-element.d.ts +6 -3
  120. package/dist/dev/elements/sonic-element.js +119 -40
  121. package/dist/dev/elements/sonic-element.js.map +1 -1
  122. package/dist/dev/elements/split.d.ts +21 -0
  123. package/dist/dev/elements/split.js +258 -0
  124. package/dist/dev/elements/split.js.map +1 -0
  125. package/dist/dev/elements/switch.d.ts +35 -0
  126. package/dist/dev/elements/switch.js +274 -0
  127. package/dist/dev/elements/switch.js.map +1 -0
  128. package/dist/dev/elements/value-element.d.ts +84 -0
  129. package/dist/dev/elements/value-element.js +695 -0
  130. package/dist/dev/elements/value-element.js.map +1 -0
  131. package/dist/dev/elements/{range-entry.js → value-entry.js} +4 -4
  132. package/dist/dev/elements/value-entry.js.map +1 -0
  133. package/dist/dev/elements/wave-element.d.ts +37 -0
  134. package/dist/dev/elements/wave-element.js +81 -0
  135. package/dist/dev/elements/wave-element.js.map +1 -0
  136. package/dist/dev/elements/waveform.d.ts +55 -0
  137. package/dist/dev/elements/waveform.js +329 -0
  138. package/dist/dev/elements/waveform.js.map +1 -0
  139. package/dist/dev/elements/wavestrip.d.ts +51 -0
  140. package/dist/dev/elements/wavestrip.js +186 -0
  141. package/dist/dev/elements/wavestrip.js.map +1 -0
  142. package/dist/dev/elements/xy.d.ts +62 -0
  143. package/dist/dev/elements/xy.js +488 -0
  144. package/dist/dev/elements/xy.js.map +1 -0
  145. package/dist/dev/index.d.ts +11 -2
  146. package/dist/dev/index.js +10 -2
  147. package/dist/dev/lib/adsr-shape.js +114 -0
  148. package/dist/dev/lib/adsr-shape.js.map +1 -0
  149. package/dist/dev/lib/ballistics.js +56 -0
  150. package/dist/dev/lib/ballistics.js.map +1 -0
  151. package/dist/dev/lib/canvas-surface.d.ts +26 -0
  152. package/dist/dev/lib/canvas-surface.js +204 -0
  153. package/dist/dev/lib/canvas-surface.js.map +1 -0
  154. package/dist/dev/lib/copy-node.js +32 -2
  155. package/dist/dev/lib/copy-node.js.map +1 -1
  156. package/dist/dev/lib/crossfade.d.ts +12 -0
  157. package/dist/dev/lib/crossfade.js +23 -0
  158. package/dist/dev/lib/crossfade.js.map +1 -0
  159. package/dist/dev/lib/distribute.d.ts +4 -0
  160. package/dist/dev/lib/distribute.js +216 -0
  161. package/dist/dev/lib/distribute.js.map +1 -0
  162. package/dist/dev/lib/drag-step.js +100 -0
  163. package/dist/dev/lib/drag-step.js.map +1 -0
  164. package/dist/dev/lib/envelope-curve.d.ts +4 -0
  165. package/dist/dev/lib/envelope-curve.js +10 -0
  166. package/dist/dev/lib/envelope-curve.js.map +1 -0
  167. package/dist/dev/lib/field.d.ts +4 -0
  168. package/dist/dev/lib/field.js +95 -0
  169. package/dist/dev/lib/field.js.map +1 -0
  170. package/dist/dev/lib/focus-by-pointer.js +29 -0
  171. package/dist/dev/lib/focus-by-pointer.js.map +1 -0
  172. package/dist/dev/lib/frame-timeline.js +64 -0
  173. package/dist/dev/lib/frame-timeline.js.map +1 -0
  174. package/dist/dev/lib/hold.js +39 -0
  175. package/dist/dev/lib/hold.js.map +1 -0
  176. package/dist/dev/lib/marker-band.js +81 -0
  177. package/dist/dev/lib/marker-band.js.map +1 -0
  178. package/dist/dev/lib/marker-rider.js +121 -0
  179. package/dist/dev/lib/marker-rider.js.map +1 -0
  180. package/dist/dev/lib/math.js +17 -3
  181. package/dist/dev/lib/math.js.map +1 -1
  182. package/dist/dev/lib/modifier-press.js +12 -0
  183. package/dist/dev/lib/modifier-press.js.map +1 -0
  184. package/dist/dev/lib/number-list.js +6 -6
  185. package/dist/dev/lib/number-list.js.map +1 -1
  186. package/dist/dev/lib/pointer-drag.js +47 -0
  187. package/dist/dev/lib/pointer-drag.js.map +1 -0
  188. package/dist/dev/lib/read-px-property.js.map +1 -1
  189. package/dist/dev/lib/render.js +20 -5
  190. package/dist/dev/lib/render.js.map +1 -1
  191. package/dist/dev/lib/resample-peaks.js +47 -0
  192. package/dist/dev/lib/resample-peaks.js.map +1 -0
  193. package/dist/dev/lib/strip-scene.js +49 -0
  194. package/dist/dev/lib/strip-scene.js.map +1 -0
  195. package/dist/dev/lib/taper.js +23 -17
  196. package/dist/dev/lib/taper.js.map +1 -1
  197. package/dist/dev/lib/time-regions.d.ts +4 -0
  198. package/dist/dev/lib/time-regions.js +9 -0
  199. package/dist/dev/lib/time-regions.js.map +1 -0
  200. package/dist/dev/lib/tracking-clock.js +36 -0
  201. package/dist/dev/lib/tracking-clock.js.map +1 -0
  202. package/dist/dev/lib/value-mapping.d.ts +23 -0
  203. package/dist/dev/lib/value-mapping.js +116 -0
  204. package/dist/dev/lib/value-mapping.js.map +1 -0
  205. package/dist/dev/lib/waveform-buckets.d.ts +9 -0
  206. package/dist/dev/lib/waveform-buckets.js +42 -0
  207. package/dist/dev/lib/waveform-buckets.js.map +1 -0
  208. package/dist/dev/lib/write-attribute.js +1 -0
  209. package/dist/dev/lib/write-attribute.js.map +1 -1
  210. package/dist/skins/amber.css +8 -0
  211. package/dist/skins/flat.css +25 -0
  212. package/dist/skins/ivory.css +2 -2
  213. package/dist/skins/lime.css +2 -0
  214. package/dist/skins/slate.css +2 -0
  215. package/dist/styles/button.css +240 -0
  216. package/dist/styles/controls.css +8 -1
  217. package/dist/styles/dial.css +110 -56
  218. package/dist/styles/envelope.css +204 -0
  219. package/dist/styles/led.css +39 -8
  220. package/dist/styles/material.css +343 -100
  221. package/dist/styles/meter.css +41 -52
  222. package/dist/styles/number.css +5 -1
  223. package/dist/styles/panel.css +61 -0
  224. package/dist/styles/ring.css +74 -0
  225. package/dist/styles/segmented.css +46 -51
  226. package/dist/styles/slider.css +177 -40
  227. package/dist/styles/switch.css +386 -0
  228. package/dist/styles/waveform.css +196 -0
  229. package/dist/styles/wavestrip.css +232 -0
  230. package/dist/styles/xy.css +241 -0
  231. package/package.json +15 -6
  232. package/dist/default/define/key.js +0 -7
  233. package/dist/default/elements/key.js +0 -169
  234. package/dist/default/elements/range-element.js +0 -546
  235. package/dist/default/lib/detent.js +0 -17
  236. package/dist/dev/define/key.d.ts +0 -2
  237. package/dist/dev/define/key.js +0 -8
  238. package/dist/dev/define/key.js.map +0 -1
  239. package/dist/dev/elements/key.js +0 -170
  240. package/dist/dev/elements/key.js.map +0 -1
  241. package/dist/dev/elements/range-element.d.ts +0 -64
  242. package/dist/dev/elements/range-element.js +0 -547
  243. package/dist/dev/elements/range-element.js.map +0 -1
  244. package/dist/dev/elements/range-entry.js.map +0 -1
  245. package/dist/dev/lib/detent.js +0 -18
  246. package/dist/dev/lib/detent.js.map +0 -1
  247. package/dist/styles/key.css +0 -242
@@ -10,23 +10,38 @@
10
10
  initial-value: 8px;
11
11
  }
12
12
 
13
+ @keyframes sonic-glass-breathe {
14
+ to {
15
+ opacity: calc(0.4 * min(1, var(--_sonic-glass-texture)));
16
+ }
17
+ }
18
+
13
19
  @layer sonic {
14
- /* Resolved per control rather than on `:root`, so each follows its own cap and unit */
15
20
  :is(
16
21
  .sonic-dial,
17
22
  .sonic-dial-readout,
18
- .sonic-key,
23
+ .sonic-envelope,
24
+ .sonic-envelope-readout,
25
+ .sonic-button,
19
26
  .sonic-led,
27
+ .sonic-switch,
20
28
  .sonic-meter,
21
29
  .sonic-number,
30
+ .sonic-panel,
31
+ .sonic-ring,
22
32
  .sonic-screen,
23
33
  .sonic-segmented,
24
34
  .sonic-slider,
25
- .sonic-slider-readout
35
+ .sonic-slider-readout,
36
+ .sonic-waveform,
37
+ .sonic-waveform-readout,
38
+ .sonic-wavestrip,
39
+ .sonic-wavestrip-readout,
40
+ .sonic-xy,
41
+ .sonic-xy-readout
26
42
  ) {
27
43
  --_sonic-unlit: var(--sonic-unlit, oklch(27.4% 0.005 286deg));
28
-
29
- /* Degrees left of overhead */
44
+ --_sonic-relief: var(--sonic-relief, 0);
30
45
  --_sonic-light-tilt: var(--sonic-light-tilt, 17deg);
31
46
  --_sonic-light-fall: calc(180deg - var(--_sonic-light-tilt));
32
47
  --_sonic-cast-x: calc(sin(var(--_sonic-light-tilt)) * var(--_sonic-unit));
@@ -35,85 +50,135 @@
35
50
 
36
51
  :is(
37
52
  .sonic-dial,
38
- .sonic-key,
53
+ .sonic-envelope,
54
+ .sonic-button,
39
55
  .sonic-led,
40
56
  .sonic-meter,
41
57
  .sonic-number,
42
- .sonic-segmented-segment,
43
- .sonic-slider
58
+ .sonic-ring,
59
+ .sonic-segmented-option,
60
+ .sonic-slider,
61
+ .sonic-waveform,
62
+ .sonic-wavestrip,
63
+ .sonic-xy
44
64
  ) {
45
65
  --_sonic-lit: var(--sonic-lit, oklch(76.9% 0.165 70deg));
46
66
  }
47
67
 
48
- :is(.sonic-led, .sonic-meter) {
49
- --_sonic-lens:
50
- linear-gradient(var(--_sonic-light-fall), rgb(255 255 255 / 10%), transparent 60%),
51
- color-mix(in oklab, var(--_sonic-unlit) 60%, #000);
68
+ /* On the parts, since a recipe's `var()`s resolve where it is declared */
69
+ .sonic-dial-ring,
70
+ .sonic-dial-modulation,
71
+ .sonic-ring::before {
72
+ --_sonic-arc-mask: radial-gradient(
73
+ closest-side,
74
+ transparent calc(100% - var(--_sonic-arc-width) - 0.5px),
75
+ #000 calc(100% - var(--_sonic-arc-width)),
76
+ #000 calc(100% - var(--_sonic-arc-inset) - 0.5px),
77
+ transparent calc(100% - var(--_sonic-arc-inset))
78
+ );
79
+ --_sonic-arc-shade: radial-gradient(
80
+ closest-side,
81
+ rgb(0 0 0 / calc(0.55 * var(--_sonic-relief))) calc(100% - var(--_sonic-arc-width)),
82
+ transparent calc(100% - var(--_sonic-arc-width) * 0.4),
83
+ rgb(0 0 0 / calc(0.25 * var(--_sonic-relief))) 100%
84
+ );
52
85
  }
53
86
 
54
- .sonic-meter {
87
+ :is(.sonic-led, .sonic-meter) {
88
+ --_sonic-lens-glint: linear-gradient(
89
+ var(--_sonic-light-fall),
90
+ rgb(255 255 255 / calc(0.1 * var(--_sonic-relief))),
91
+ transparent 60%
92
+ );
93
+ --_sonic-lens-glass: var(--sonic-lens, color-mix(in oklab, var(--_sonic-unlit) 60%, #000));
94
+ --_sonic-lens: var(--_sonic-lens-glint), var(--_sonic-lens-glass);
55
95
  --_sonic-hot: var(--sonic-hot, oklch(70.5% 0.187 48deg));
56
96
  --_sonic-clip: var(--sonic-clip, oklch(63.7% 0.208 25deg));
57
97
  }
58
98
 
59
- :is(.sonic-dial, .sonic-key, .sonic-number, .sonic-segmented-segment, .sonic-slider) {
60
- --_sonic-cap: var(--sonic-cap, oklch(37% 0.012 286deg));
61
- --_sonic-cap-hover: var(--sonic-cap-hover, oklch(44.2% 0.015 286deg));
99
+ :is(
100
+ .sonic-dial,
101
+ .sonic-button,
102
+ .sonic-switch,
103
+ .sonic-number,
104
+ .sonic-segmented-option,
105
+ .sonic-slider,
106
+ .sonic-waveform,
107
+ .sonic-wavestrip,
108
+ .sonic-xy
109
+ ) {
110
+ --_sonic-cap: var(--sonic-cap, transparent);
111
+ --_sonic-cap-hover: var(--sonic-cap-hover, transparent);
62
112
  --_sonic-focus: var(--sonic-focus, oklch(90% 0.23 128deg));
63
- --_sonic-ink: var(--sonic-mark, color-mix(in oklab, var(--_sonic-cap) 30%, #fff));
113
+ --_sonic-ink: var(--sonic-ink, currentcolor);
64
114
  --_sonic-etch: color-mix(in oklab, var(--_sonic-ink) 30%, transparent);
65
- --_sonic-ink-lift: color-mix(in oklab, var(--_sonic-ink) 60%, #fff);
115
+ --_sonic-ink-lift: var(--sonic-ink-hover, color-mix(in oklab, var(--_sonic-ink) 60%, #fff));
66
116
  --_sonic-lit-disabled: color-mix(in oklab, var(--_sonic-ink) 25%, var(--_sonic-unlit));
67
117
  --_sonic-skirt: linear-gradient(
68
118
  var(--_sonic-light-fall),
69
- color-mix(in oklab, var(--_sonic-cap) 70%, #fff),
70
- color-mix(in oklab, var(--_sonic-cap) 55%, #000)
119
+ color-mix(in oklab, var(--_sonic-cap) calc(100% - 30% * var(--_sonic-relief)), #fff),
120
+ color-mix(in oklab, var(--_sonic-cap) calc(100% - 45% * var(--_sonic-relief)), #000)
71
121
  );
72
-
73
- /* Inverted from the skirt, as a dished face takes light */
74
122
  --_sonic-face: linear-gradient(
75
123
  var(--_sonic-light-fall),
76
- color-mix(in oklab, var(--_sonic-cap) 85%, #000),
77
- color-mix(in oklab, var(--_sonic-cap) 90%, #fff)
124
+ color-mix(in oklab, var(--_sonic-cap) calc(100% - 15% * var(--_sonic-relief)), #000),
125
+ color-mix(in oklab, var(--_sonic-cap) calc(100% - 10% * var(--_sonic-relief)), #fff)
78
126
  );
79
127
  --_sonic-sheen: linear-gradient(
80
128
  105deg,
81
129
  transparent 20%,
82
- rgb(255 255 255 / 10%) 45%,
130
+ rgb(255 255 255 / calc(0.1 * var(--_sonic-relief))) 45%,
83
131
  transparent 55%,
84
- rgb(0 0 0 / 6%) 80%
132
+ rgb(0 0 0 / calc(0.06 * var(--_sonic-relief))) 80%
85
133
  );
86
134
  --_sonic-press-transition:
87
135
  scale 60ms cubic-bezier(0.4, 0, 0.2, 1), translate 60ms cubic-bezier(0.4, 0, 0.2, 1),
88
136
  box-shadow 60ms cubic-bezier(0.4, 0, 0.2, 1);
89
137
  --_sonic-face-shadow:
90
138
  inset var(--_sonic-cast-x) var(--_sonic-cast-y) calc(1.5 * var(--_sonic-unit))
91
- rgb(0 0 0 / 35%),
139
+ rgb(0 0 0 / calc(0.35 * var(--_sonic-relief))),
92
140
  calc(0.5 * var(--_sonic-cast-x)) calc(0.5 * var(--_sonic-cast-y)) var(--_sonic-unit)
93
- rgb(255 255 255 / 12%);
141
+ rgb(255 255 255 / calc(0.12 * var(--_sonic-relief)));
94
142
  --_sonic-rim: 0 0 0 max(1px, 0.75 * var(--_sonic-unit))
95
- color-mix(in oklab, var(--_sonic-cap) 40%, #000);
96
- --_sonic-drop-shade: rgb(0 0 0 / 65%);
143
+ var(
144
+ --sonic-cap-edge,
145
+ color-mix(in oklab, var(--_sonic-cap) calc(100% - 60% * var(--_sonic-relief)), #000)
146
+ );
147
+ --_sonic-drop-shade: rgb(0 0 0 / calc(0.65 * var(--_sonic-relief)));
97
148
  --_sonic-focus-shadow: 0 0 transparent;
98
149
  --_sonic-focus-glow: 0 0 max(4px, 3 * var(--_sonic-unit)) max(1px, 0.5 * var(--_sonic-unit))
99
150
  color-mix(in oklab, var(--_sonic-focus) 60%, transparent);
100
151
  }
101
152
 
102
- /* A gesture distance, absolute like the travel */
103
- :is(.sonic-dial, .sonic-number, .sonic-slider) {
153
+ :is(.sonic-dial, .sonic-number, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
104
154
  --_sonic-detent-zone: var(--sonic-detent-zone, 8px);
105
155
  }
106
156
 
107
- :is(.sonic-dial, .sonic-slider) {
108
- /* On the control, since the readout's font size reads it */
157
+ :is(.sonic-dial, .sonic-envelope, .sonic-slider, .sonic-waveform, .sonic-wavestrip, .sonic-xy) {
109
158
  --_sonic-readout-size: var(--sonic-readout-size, 1.5rem);
159
+ }
160
+
161
+ :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
110
162
  --_sonic-lit-off: var(
111
163
  --sonic-dimmed,
112
164
  color-mix(in oklab, var(--_sonic-lit) 50%, var(--_sonic-unlit))
113
165
  );
114
166
  }
115
167
 
116
- :is(.sonic-dial-readout, .sonic-number, .sonic-screen, .sonic-slider-readout) {
168
+ :is(
169
+ .sonic-dial-readout,
170
+ .sonic-envelope,
171
+ .sonic-envelope-readout,
172
+ .sonic-number,
173
+ .sonic-screen,
174
+ .sonic-slider-readout,
175
+ .sonic-waveform,
176
+ .sonic-waveform-readout,
177
+ .sonic-wavestrip,
178
+ .sonic-wavestrip-readout,
179
+ .sonic-xy,
180
+ .sonic-xy-readout
181
+ ) {
117
182
  --_sonic-glass: var(--sonic-glass, color-mix(in oklab, var(--_sonic-unlit) 45%, #000));
118
183
  --_sonic-glass-fill: radial-gradient(
119
184
  closest-side,
@@ -121,80 +186,234 @@
121
186
  var(--_sonic-glass)
122
187
  )
123
188
  var(--_sonic-glass);
124
-
125
- /* Not the cap's ink, which a skin may darken */
126
189
  --_sonic-glass-text: var(
127
190
  --sonic-glass-text,
128
191
  color-mix(in oklab, var(--_sonic-glass) 20%, #fff)
129
192
  );
193
+ --_sonic-glass-edge: 1px solid var(--sonic-glass-edge);
194
+
195
+ /* Glass is forced to Canvas like the page, so only a border shows its edge */
196
+ @media (forced-colors: active) {
197
+ --_sonic-glass-edge: 1px solid CanvasText;
198
+ }
130
199
  }
131
200
 
132
201
  /* A definite cell, so percentage-sized content fills the glass; a canvas sized to its own box would feed back */
133
- :is(.sonic-number, .sonic-screen) {
202
+ :is(.sonic-envelope, .sonic-number, .sonic-screen, .sonic-waveform, .sonic-wavestrip, .sonic-xy) {
203
+ --_sonic-glass-depth: var(--sonic-glass-depth, var(--_sonic-relief));
204
+ --_sonic-glass-texture: var(--sonic-glass-texture, var(--_sonic-relief));
205
+ --_sonic-glass-pitch: max(2px, round(2 * var(--_sonic-unit), 1px));
206
+
134
207
  position: relative;
135
208
  box-sizing: border-box;
136
209
  display: grid;
137
210
  flex-shrink: 0;
138
211
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
139
212
  place-items: center;
140
- font-family: var(--sonic-glass-font);
213
+ font-family: var(--sonic-glass-font, inherit);
141
214
  color: var(--_sonic-glass-text);
142
-
143
- /* A double click aimed at a neighbouring control would highlight it */
144
215
  user-select: none;
145
216
  background: var(--_sonic-glass-fill);
217
+ border: var(--_sonic-glass-edge);
218
+
219
+ @media (forced-colors: active) {
220
+ --_sonic-glass-texture: 0;
221
+ }
146
222
 
147
223
  &::after {
148
224
  position: absolute;
149
225
  inset: 0;
150
226
  pointer-events: none;
151
227
  content: '';
152
- background: linear-gradient(var(--_sonic-light-fall), rgb(255 255 255 / 7%), transparent 45%);
228
+ background:
229
+ linear-gradient(
230
+ var(--_sonic-light-fall),
231
+ rgb(255 255 255 / calc(0.07 * var(--_sonic-glass-depth))),
232
+ transparent 45%
233
+ ),
234
+ radial-gradient(
235
+ farthest-corner,
236
+ transparent 55%,
237
+ rgb(0 0 0 / calc(0.4 * var(--_sonic-glass-texture)))
238
+ ),
239
+ repeating-linear-gradient(
240
+ to bottom,
241
+ rgb(0 0 0 / calc(0.04 * var(--_sonic-glass-texture))) 0
242
+ calc(var(--_sonic-glass-pitch) / 2),
243
+ transparent 0 var(--_sonic-glass-pitch)
244
+ );
153
245
  border-radius: inherit;
154
246
  box-shadow:
155
247
  var(--_sonic-well),
156
- inset 0 0 calc(3 * var(--_sonic-unit)) rgb(0 0 0 / 45%);
248
+ inset 0 0 calc(3 * var(--_sonic-glass-depth) * var(--_sonic-unit)) rgb(0 0 0 / 45%);
249
+ }
250
+
251
+ @media (forced-colors: none) {
252
+ /* No var() beside the tile, which would parse the url() again on every style recalculation */
253
+ &::before {
254
+ position: absolute;
255
+ inset: 0;
256
+ color: color-mix(in oklab, var(--_sonic-glass-text) 7.5%, transparent);
257
+ pointer-events: none;
258
+ content: '';
259
+ background:
260
+ radial-gradient(closest-side, currentcolor, transparent) no-repeat,
261
+ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.056 -0.01925'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")
262
+ 0 0 / 128px 128px repeat;
263
+ border-radius: inherit;
264
+ opacity: min(1, var(--_sonic-glass-texture));
265
+ }
266
+
267
+ @media (prefers-reduced-motion: no-preference) {
268
+ &:is(:focus-visible, :focus-within)::before,
269
+ :state(dragging) > &::before {
270
+ animation: sonic-glass-breathe 3s ease-in-out infinite alternate;
271
+ }
272
+
273
+ @media (hover: hover) {
274
+ &:hover::before {
275
+ animation: sonic-glass-breathe 3s ease-in-out infinite alternate;
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ @media (forced-colors: none) {
283
+ /* A query reads the parent, or a pseudo-element's own element: on a readout itself, 0 leaves the warp on */
284
+ @container style(--sonic-relief: 1) and (not style(--sonic-glass-texture: 0)) {
285
+ :is(.sonic-number, .sonic-screen),
286
+ :is(.sonic-envelope, .sonic-waveform, .sonic-wavestrip, .sonic-xy)::after {
287
+ filter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='w' x='-0.3' y='-0.3' width='1.6' height='1.6' primitiveUnits='objectBoundingBox' color-interpolation-filters='sRGB'%3E%3CfeFlood x='0' y='0' width='1' height='1' flood-color='%23000'/%3E%3CfeFlood x='.5' y='0' width='.5' height='1' flood-color='%23f00' result='r'/%3E%3CfeFlood x='0' y='.5' width='1' height='.5' flood-color='%230f0' result='g'/%3E%3CfeFlood x='0' y='0' width='1' height='1' flood-color='%23000' result='k'/%3E%3CfeComposite in='r' in2='g' operator='arithmetic' k2='1' k3='1' result='h'/%3E%3CfeMerge x='0' y='0' width='1' height='1'%3E%3CfeMergeNode in='k'/%3E%3CfeMergeNode in='h'/%3E%3C/feMerge%3E%3CfeGaussianBlur x='0' y='0' width='1' height='1' stdDeviation='0.25'/%3E%3CfeColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1'/%3E%3CfeComponentTransfer result='a'%3E%3CfeFuncR type='table' tableValues='0 0.052 0.172 0.25 0.312 0.364 0.412 0.457 0.5 0.543 0.588 0.636 0.688 0.75 0.828 0.948 1'/%3E%3CfeFuncG type='table' tableValues='0 0.052 0.172 0.25 0.312 0.364 0.412 0.457 0.5 0.543 0.588 0.636 0.688 0.75 0.828 0.948 1'/%3E%3C/feComponentTransfer%3E%3CfeComponentTransfer%3E%3CfeFuncR type='table' tableValues='1 0.563 0.25 0.063 0 0.063 0.25 0.563 1'/%3E%3CfeFuncG type='table' tableValues='1 0.563 0.25 0.063 0 0.063 0.25 0.563 1'/%3E%3C/feComponentTransfer%3E%3CfeColorMatrix values='.5 .5 0 0 0 .5 .5 0 0 0 0 0 0 0 0 0 0 0 0 1'/%3E%3CfeComponentTransfer result='f'%3E%3CfeFuncR type='gamma' amplitude='0.333' exponent='2'/%3E%3CfeFuncG type='gamma' exponent='2'/%3E%3C/feComponentTransfer%3E%3CfeComposite in='a' in2='f' operator='arithmetic' k1='1' k3='-.5' k4='.5' result='m'/%3E%3CfeFlood flood-color='%23808080'/%3E%3CfeMerge result='n'%3E%3CfeMergeNode/%3E%3CfeMergeNode in='m'/%3E%3C/feMerge%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='0.016' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3C/svg%3E#w");
288
+ }
289
+
290
+ :is(.sonic-envelope, .sonic-waveform, .sonic-wavestrip, .sonic-xy)::after {
291
+ --_sonic-glass-bend: calc(0.008 * hypot(100cqi, 100cqb));
292
+
293
+ inset: calc(-1 * var(--_sonic-glass-bend));
294
+ border: var(--_sonic-glass-bend) solid rgb(0 0 0 / 50%);
295
+ border-radius: calc(var(--_sonic-glass-radius) + var(--_sonic-glass-bend));
296
+ clip-path: inset(var(--_sonic-glass-bend) round var(--_sonic-glass-radius));
297
+ }
157
298
  }
158
299
  }
159
300
 
160
- :is(.sonic-key, .sonic-number, .sonic-screen, .sonic-segmented) {
301
+ :is(
302
+ .sonic-envelope,
303
+ .sonic-button,
304
+ .sonic-number,
305
+ .sonic-screen,
306
+ .sonic-segmented,
307
+ .sonic-waveform,
308
+ .sonic-wavestrip,
309
+ .sonic-xy
310
+ ) {
311
+ --_sonic-well-depth: var(--_sonic-glass-depth, 1);
161
312
  --_sonic-well:
162
- inset var(--_sonic-cast-x) var(--_sonic-cast-y) calc(2 * var(--_sonic-unit)) rgb(0 0 0 / 60%),
163
- calc(0.5 * var(--_sonic-cast-x)) calc(0.5 * var(--_sonic-cast-y)) 0 rgb(255 255 255 / 6%);
313
+ inset calc(var(--_sonic-well-depth) * var(--_sonic-cast-x))
314
+ calc(var(--_sonic-well-depth) * var(--_sonic-cast-y))
315
+ calc(2 * var(--_sonic-well-depth) * var(--_sonic-unit))
316
+ rgb(0 0 0 / calc(0.6 * var(--_sonic-relief))),
317
+ calc(0.5 * var(--_sonic-well-depth) * var(--_sonic-cast-x))
318
+ calc(0.5 * var(--_sonic-well-depth) * var(--_sonic-cast-y)) 0
319
+ rgb(255 255 255 / calc(0.06 * var(--_sonic-relief)));
164
320
  }
165
321
 
166
- :is(.sonic-key, .sonic-segmented) {
167
- --_sonic-well-floor: linear-gradient(
168
- var(--_sonic-light-fall),
169
- color-mix(in oklab, var(--_sonic-unlit) 55%, #000),
170
- color-mix(in oklab, var(--_sonic-unlit) 85%, #000)
322
+ :is(.sonic-button, .sonic-segmented) {
323
+ --_sonic-well-floor: var(
324
+ --sonic-well,
325
+ linear-gradient(
326
+ var(--_sonic-light-fall),
327
+ color-mix(
328
+ in oklab,
329
+ color-mix(in oklab, var(--_sonic-unlit) 55%, #000) calc(100% * var(--_sonic-relief)),
330
+ transparent
331
+ ),
332
+ color-mix(
333
+ in oklab,
334
+ color-mix(in oklab, var(--_sonic-unlit) 85%, #000) calc(100% * var(--_sonic-relief)),
335
+ transparent
336
+ )
337
+ )
171
338
  );
172
339
  --_sonic-engraving: drop-shadow(
173
340
  calc(-0.4 * var(--_sonic-cast-x)) calc(-0.4 * var(--_sonic-cast-y))
174
- calc(0.4 * var(--_sonic-unit)) rgb(0 0 0 / 30%)
341
+ calc(0.4 * var(--_sonic-unit)) rgb(0 0 0 / calc(0.3 * var(--_sonic-relief)))
175
342
  )
176
343
  drop-shadow(
177
- calc(0.3 * var(--_sonic-cast-x)) calc(0.3 * var(--_sonic-cast-y)) 0 rgb(255 255 255 / 7%)
344
+ calc(0.3 * var(--_sonic-cast-x)) calc(0.3 * var(--_sonic-cast-y)) 0
345
+ rgb(255 255 255 / calc(0.07 * var(--_sonic-relief)))
178
346
  );
179
347
  }
180
348
 
181
- /* On the segment rather than the strip, where forced colours clear the drop shade */
182
- :is(.sonic-key, .sonic-segmented-segment) {
349
+ /* On the option rather than the strip, where forced colours clear the drop shade */
350
+ :is(.sonic-button, .sonic-segmented-option) {
183
351
  --_sonic-press-drop: calc(0.5 * var(--_sonic-cast-x)) calc(0.5 * var(--_sonic-cast-y))
184
352
  var(--_sonic-unit) var(--_sonic-drop-shade);
353
+ --_sonic-keycap-shift: calc(var(--_sonic-keycap-depth) / -2);
354
+ --_sonic-keycap-scale: 1;
355
+ --_sonic-keycap-drop: calc(1.5 * var(--_sonic-cast-x)) calc(1.5 * var(--_sonic-cast-y))
356
+ calc(2 * var(--_sonic-unit)) var(--_sonic-drop-shade);
357
+ --_sonic-keycap-glow: transparent;
358
+ --_sonic-keycap-lit-glow: color-mix(
359
+ in oklab,
360
+ var(--_sonic-lit) calc(22% * var(--_sonic-relief)),
361
+ transparent
362
+ );
363
+ --_sonic-legend-glow: drop-shadow(
364
+ 0 0 var(--_sonic-unit)
365
+ color-mix(in oklab, var(--_sonic-lit) calc(35% * var(--_sonic-relief)), transparent)
366
+ );
367
+ }
368
+
369
+ :is(.sonic-button, .sonic-segmented-option, .sonic-switch-position) {
370
+ --_sonic-target-outset: min(0px, calc((100% - var(--sonic-target-size, 100%)) / 2));
371
+
372
+ &::after {
373
+ position: absolute;
374
+ inset: var(--_sonic-target-outset);
375
+ content: '';
376
+ }
377
+ }
378
+
379
+ /* Each sheet maps its own depth, corner, bevel and face corner onto the `keycap` tokens */
380
+ :is(.sonic-button-cap, .sonic-segmented-cap) {
381
+ display: grid;
382
+ place-items: center;
383
+ background: var(--_sonic-skirt);
384
+ border-radius: var(--_sonic-keycap-corner);
385
+ box-shadow: var(--_sonic-keycap-drop), var(--_sonic-rim), var(--_sonic-focus-shadow);
386
+ scale: var(--_sonic-keycap-scale);
387
+ translate: 0 var(--_sonic-keycap-shift);
388
+ transition: var(--_sonic-press-transition);
389
+
390
+ &::before {
391
+ position: absolute;
392
+ inset: var(--_sonic-keycap-bevel);
393
+ content: '';
394
+ background:
395
+ radial-gradient(closest-side, var(--_sonic-keycap-glow), transparent), var(--_sonic-sheen),
396
+ var(--_sonic-face);
397
+ border-radius: var(--_sonic-keycap-face-corner);
398
+ box-shadow: var(--_sonic-face-shadow);
399
+ }
400
+
401
+ & > * {
402
+ position: relative;
403
+ }
185
404
  }
186
405
 
187
- /* The well's full blur would fill a slot this narrow */
188
406
  :is(.sonic-meter, .sonic-slider) {
189
407
  --_sonic-groove:
190
408
  inset var(--_sonic-cast-x) var(--_sonic-cast-y) calc(0.75 * var(--_sonic-unit))
191
- rgb(0 0 0 / 55%),
192
- inset 0 0 calc(0.5 * var(--_sonic-unit)) rgb(0 0 0 / 30%),
193
- calc(0.5 * var(--_sonic-cast-x)) calc(0.5 * var(--_sonic-cast-y)) 0 rgb(255 255 255 / 6%);
409
+ rgb(0 0 0 / calc(0.55 * var(--_sonic-relief))),
410
+ inset 0 0 calc(0.5 * var(--_sonic-unit)) rgb(0 0 0 / calc(0.3 * var(--_sonic-relief))),
411
+ calc(0.5 * var(--_sonic-cast-x)) calc(0.5 * var(--_sonic-cast-y)) 0
412
+ rgb(255 255 255 / calc(0.06 * var(--_sonic-relief)));
194
413
  }
195
414
 
196
415
  @media (hover: hover) {
197
- :is(.sonic-dial, .sonic-key, .sonic-segmented-segment, .sonic-slider):not(
416
+ :is(.sonic-dial, .sonic-button, .sonic-segmented-option, .sonic-slider):not(
198
417
  :disabled,
199
418
  [aria-disabled='true']
200
419
  ):hover {
@@ -204,25 +423,37 @@
204
423
 
205
424
  :is(
206
425
  .sonic-dial,
207
- .sonic-key,
426
+ .sonic-button,
208
427
  .sonic-number,
209
- .sonic-segmented-segment,
210
- .sonic-slider
428
+ .sonic-segmented-option,
429
+ .sonic-slider,
430
+ .sonic-waveform,
431
+ .sonic-wavestrip,
432
+ .sonic-xy-axis
211
433
  ):focus-visible {
212
- --_sonic-cap: var(--_sonic-cap-hover);
213
- --_sonic-focus-shadow: var(--_sonic-focus-glow);
214
-
215
434
  outline: 2px solid transparent;
216
435
  outline-offset: -2px;
436
+
437
+ &:not([data-sonic-pointer-focus]) {
438
+ --_sonic-cap: var(--_sonic-cap-hover);
439
+ --_sonic-focus-shadow: var(--_sonic-focus-glow);
440
+ }
217
441
  }
218
442
 
219
- /* Keeps the glow while focus is in the entry; its own rule, since an engine without `:state()` drops a whole selector list */
220
- :state(editing) > :is(.sonic-dial, .sonic-number, .sonic-slider) {
443
+ :state(editing)
444
+ > :is(.sonic-dial, .sonic-number, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
221
445
  --_sonic-cap: var(--_sonic-cap-hover);
222
446
  --_sonic-focus-shadow: var(--_sonic-focus-glow);
223
447
  }
224
448
 
225
- :is(.sonic-dial-readout, .sonic-slider-readout) {
449
+ :is(
450
+ .sonic-dial-readout,
451
+ .sonic-envelope-readout,
452
+ .sonic-slider-readout,
453
+ .sonic-waveform-readout,
454
+ .sonic-wavestrip-readout,
455
+ .sonic-xy-readout
456
+ ) {
226
457
  --_sonic-unit: calc(var(--_sonic-readout-size) / 32);
227
458
 
228
459
  box-sizing: border-box;
@@ -235,7 +466,7 @@
235
466
  position-try-fallbacks: flip-block;
236
467
  overflow: visible;
237
468
  font: inherit;
238
- font-family: var(--sonic-glass-font);
469
+ font-family: var(--sonic-glass-font, inherit);
239
470
  font-size: calc(0.5 * var(--_sonic-readout-size));
240
471
  font-variant-numeric: tabular-nums;
241
472
  line-height: 1;
@@ -244,12 +475,12 @@
244
475
  cursor: default;
245
476
  user-select: none;
246
477
  background: var(--_sonic-glass-fill);
247
- border: 0;
478
+ border: var(--_sonic-glass-edge);
248
479
  border-radius: calc(0.25 * var(--_sonic-readout-size));
249
480
  box-shadow:
250
481
  calc(2 * var(--_sonic-cast-x)) calc(2 * var(--_sonic-cast-y)) calc(6 * var(--_sonic-unit))
251
- rgb(0 0 0 / 55%),
252
- inset 0 0 0 max(1px, var(--_sonic-unit)) rgb(255 255 255 / 8%);
482
+ rgb(0 0 0 / calc(0.55 * var(--_sonic-relief))),
483
+ inset 0 0 0 max(1px, var(--_sonic-unit)) rgb(255 255 255 / calc(0.08 * var(--_sonic-relief)));
253
484
  opacity: 0;
254
485
  translate: 0 calc(0.15 * var(--_sonic-readout-size));
255
486
  transition:
@@ -258,7 +489,7 @@
258
489
  display 120ms allow-discrete,
259
490
  overlay 120ms allow-discrete;
260
491
 
261
- /* Grid only while open; a closed readout left rendered is placed against a filtered ancestor, and engines keep the flip it took there */
492
+ /* Grid only while open; engines keep the flip a closed readout took against a filtered ancestor */
262
493
  &:popover-open {
263
494
  display: grid;
264
495
  opacity: 1;
@@ -279,16 +510,20 @@
279
510
  }
280
511
  }
281
512
  }
282
- }
283
513
 
284
- :state(editing)
285
- > :is(.sonic-dial, .sonic-slider)
286
- > :is(.sonic-dial-readout, .sonic-slider-readout) {
287
- pointer-events: auto;
288
- cursor: text;
514
+ :state(editing) > :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip) > & {
515
+ pointer-events: auto;
516
+ cursor: text;
517
+ }
289
518
  }
290
519
 
291
- :is(.sonic-dial-entry, .sonic-number-entry, .sonic-slider-entry) {
520
+ :is(
521
+ .sonic-dial-entry,
522
+ .sonic-number-entry,
523
+ .sonic-slider-entry,
524
+ .sonic-waveform-entry,
525
+ .sonic-wavestrip-entry
526
+ ) {
292
527
  inline-size: 6ch;
293
528
  padding: 0;
294
529
  font: inherit;
@@ -314,7 +549,6 @@
314
549
  }
315
550
  }
316
551
 
317
- /* Printed on the consumer's panel rather than the cap, so the text takes the page's colour and font */
318
552
  :is(.sonic-dial-scale, .sonic-slider-scale) {
319
553
  position: absolute;
320
554
  inset: 0;
@@ -344,11 +578,12 @@
344
578
 
345
579
  :is(
346
580
  .sonic-dial,
347
- .sonic-key,
581
+ .sonic-button,
348
582
  .sonic-led,
349
583
  .sonic-meter,
350
584
  .sonic-number,
351
- .sonic-segmented-segment,
585
+ .sonic-ring,
586
+ .sonic-segmented-option,
352
587
  .sonic-slider
353
588
  ) {
354
589
  --_sonic-lit: Highlight;
@@ -356,7 +591,16 @@
356
591
  }
357
592
 
358
593
  /* Tokens rather than properties, so a state rule that restates one still paints in system colours */
359
- :is(.sonic-dial, .sonic-key, .sonic-number, .sonic-segmented-segment, .sonic-slider) {
594
+ :is(
595
+ .sonic-dial,
596
+ .sonic-button,
597
+ .sonic-number,
598
+ .sonic-segmented-option,
599
+ .sonic-slider,
600
+ .sonic-waveform,
601
+ .sonic-wavestrip,
602
+ .sonic-xy
603
+ ) {
360
604
  --_sonic-ink: ButtonText;
361
605
  --_sonic-etch: ButtonText;
362
606
  --_sonic-lit-disabled: GrayText;
@@ -369,39 +613,38 @@
369
613
  --_sonic-focus-glow: 0 0 transparent;
370
614
  }
371
615
 
372
- /* Dimmed is a hint, not a state; the value stays readable */
373
- :is(.sonic-dial, .sonic-slider) {
616
+ :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
374
617
  --_sonic-lit-off: Highlight;
375
618
  }
376
619
 
377
620
  :is(
378
- :disabled > :is(.sonic-dial, .sonic-slider),
379
- .sonic-key:is(:disabled, [aria-disabled='true']),
380
- .sonic-segmented-segment:disabled
621
+ :disabled > :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip, .sonic-xy),
622
+ .sonic-button:is(:disabled, [aria-disabled='true']),
623
+ .sonic-segmented-option:disabled
381
624
  ) {
382
625
  --_sonic-ink: GrayText;
383
626
  --_sonic-etch: GrayText;
384
627
  }
385
628
 
386
- /* Stands in for the glow, which forced colours drop; inset, it merged with the cap's rim */
387
629
  :is(
388
630
  .sonic-dial,
389
- .sonic-key,
631
+ .sonic-button,
390
632
  .sonic-number,
391
- .sonic-segmented-segment,
392
- .sonic-slider
633
+ .sonic-segmented-option,
634
+ .sonic-slider,
635
+ .sonic-waveform,
636
+ .sonic-wavestrip
393
637
  ):focus-visible {
394
638
  outline-offset: 2px;
639
+
640
+ &[data-sonic-pointer-focus] {
641
+ outline-style: none;
642
+ }
395
643
  }
396
644
 
397
- :is(.sonic-dial-cap, .sonic-key-cap, .sonic-segmented-cap, .sonic-slider-cap) {
645
+ :is(.sonic-dial-cap, .sonic-button-cap, .sonic-segmented-cap, .sonic-slider-cap) {
398
646
  color: var(--_sonic-ink);
399
647
  forced-color-adjust: none;
400
648
  }
401
-
402
- /* Glass is forced to Canvas like the page, so only a border shows its edge */
403
- :is(.sonic-dial-readout, .sonic-number, .sonic-screen, .sonic-slider-readout) {
404
- border: 1px solid CanvasText;
405
- }
406
649
  }
407
650
  }