@xsynaptic/sonic-ui 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +2 -21
  2. package/dist/default/dat.js +50 -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 +367 -0
  14. package/dist/default/elements/meter.js +149 -61
  15. package/dist/default/elements/number.js +21 -8
  16. package/dist/default/elements/radio-group.js +185 -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 +24 -13
  22. package/dist/default/elements/split.js +249 -0
  23. package/dist/default/elements/switch.js +279 -0
  24. package/dist/default/elements/value-element.js +691 -0
  25. package/dist/default/elements/{range-entry.js → value-entry.js} +3 -3
  26. package/dist/default/elements/wave-element.js +77 -0
  27. package/dist/default/elements/waveform.js +305 -0
  28. package/dist/default/elements/wavestrip.js +182 -0
  29. package/dist/default/elements/xy.js +473 -0
  30. package/dist/default/index.js +10 -2
  31. package/dist/default/lib/adsr-shape.js +108 -0
  32. package/dist/default/lib/ballistics.js +55 -0
  33. package/dist/default/lib/canvas-surface.js +192 -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 +62 -0
  42. package/dist/default/lib/hold.js +38 -0
  43. package/dist/default/lib/marker-band.js +36 -0
  44. package/dist/default/lib/marker-rider.js +114 -0
  45. package/dist/default/lib/math.js +12 -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 +43 -0
  49. package/dist/default/lib/render.js +20 -5
  50. package/dist/default/lib/resample-peaks.js +36 -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/dev/dat.d.ts +19 -0
  58. package/dist/dev/dat.js +51 -0
  59. package/dist/dev/dat.js.map +1 -0
  60. package/dist/dev/define/button.d.ts +2 -0
  61. package/dist/dev/define/button.js +8 -0
  62. package/dist/dev/define/button.js.map +1 -0
  63. package/dist/dev/define/dial.js.map +1 -1
  64. package/dist/dev/define/envelope.d.ts +2 -0
  65. package/dist/dev/define/envelope.js +8 -0
  66. package/dist/dev/define/envelope.js.map +1 -0
  67. package/dist/dev/define/meter.js.map +1 -1
  68. package/dist/dev/define/number.js.map +1 -1
  69. package/dist/dev/define/segmented.js.map +1 -1
  70. package/dist/dev/define/slider.js.map +1 -1
  71. package/dist/dev/define/split.d.ts +2 -0
  72. package/dist/dev/define/split.js +8 -0
  73. package/dist/dev/define/split.js.map +1 -0
  74. package/dist/dev/define/switch.d.ts +2 -0
  75. package/dist/dev/define/switch.js +8 -0
  76. package/dist/dev/define/switch.js.map +1 -0
  77. package/dist/dev/define/waveform.d.ts +2 -0
  78. package/dist/dev/define/waveform.js +8 -0
  79. package/dist/dev/define/waveform.js.map +1 -0
  80. package/dist/dev/define/wavestrip.d.ts +2 -0
  81. package/dist/dev/define/wavestrip.js +8 -0
  82. package/dist/dev/define/wavestrip.js.map +1 -0
  83. package/dist/dev/define/xy.d.ts +2 -0
  84. package/dist/dev/define/xy.js +8 -0
  85. package/dist/dev/define/xy.js.map +1 -0
  86. package/dist/dev/define.d.ts +15 -3
  87. package/dist/dev/define.js +7 -1
  88. package/dist/dev/elements/{key.d.ts → button.d.ts} +8 -6
  89. package/dist/dev/elements/button.js +166 -0
  90. package/dist/dev/elements/button.js.map +1 -0
  91. package/dist/dev/elements/dial.d.ts +6 -4
  92. package/dist/dev/elements/dial.js +16 -22
  93. package/dist/dev/elements/dial.js.map +1 -1
  94. package/dist/dev/elements/envelope.d.ts +36 -0
  95. package/dist/dev/elements/envelope.js +372 -0
  96. package/dist/dev/elements/envelope.js.map +1 -0
  97. package/dist/dev/elements/form-element.d.ts +1 -1
  98. package/dist/dev/elements/form-element.js.map +1 -1
  99. package/dist/dev/elements/meter.d.ts +10 -5
  100. package/dist/dev/elements/meter.js +149 -61
  101. package/dist/dev/elements/meter.js.map +1 -1
  102. package/dist/dev/elements/number.d.ts +7 -3
  103. package/dist/dev/elements/number.js +21 -8
  104. package/dist/dev/elements/number.js.map +1 -1
  105. package/dist/dev/elements/radio-group.d.ts +25 -0
  106. package/dist/dev/elements/radio-group.js +186 -0
  107. package/dist/dev/elements/radio-group.js.map +1 -0
  108. package/dist/dev/elements/readout-claim.js +82 -0
  109. package/dist/dev/elements/readout-claim.js.map +1 -0
  110. package/dist/dev/elements/readout.js +36 -0
  111. package/dist/dev/elements/readout.js.map +1 -0
  112. package/dist/dev/elements/segmented.d.ts +4 -10
  113. package/dist/dev/elements/segmented.js +9 -159
  114. package/dist/dev/elements/segmented.js.map +1 -1
  115. package/dist/dev/elements/slider.d.ts +6 -6
  116. package/dist/dev/elements/slider.js +42 -51
  117. package/dist/dev/elements/slider.js.map +1 -1
  118. package/dist/dev/elements/sonic-element.d.ts +4 -3
  119. package/dist/dev/elements/sonic-element.js +51 -22
  120. package/dist/dev/elements/sonic-element.js.map +1 -1
  121. package/dist/dev/elements/split.d.ts +21 -0
  122. package/dist/dev/elements/split.js +258 -0
  123. package/dist/dev/elements/split.js.map +1 -0
  124. package/dist/dev/elements/switch.d.ts +35 -0
  125. package/dist/dev/elements/switch.js +280 -0
  126. package/dist/dev/elements/switch.js.map +1 -0
  127. package/dist/dev/elements/value-element.d.ts +84 -0
  128. package/dist/dev/elements/value-element.js +692 -0
  129. package/dist/dev/elements/value-element.js.map +1 -0
  130. package/dist/dev/elements/{range-entry.js → value-entry.js} +4 -4
  131. package/dist/dev/elements/value-entry.js.map +1 -0
  132. package/dist/dev/elements/wave-element.d.ts +36 -0
  133. package/dist/dev/elements/wave-element.js +78 -0
  134. package/dist/dev/elements/wave-element.js.map +1 -0
  135. package/dist/dev/elements/waveform.d.ts +55 -0
  136. package/dist/dev/elements/waveform.js +306 -0
  137. package/dist/dev/elements/waveform.js.map +1 -0
  138. package/dist/dev/elements/wavestrip.d.ts +51 -0
  139. package/dist/dev/elements/wavestrip.js +183 -0
  140. package/dist/dev/elements/wavestrip.js.map +1 -0
  141. package/dist/dev/elements/xy.d.ts +62 -0
  142. package/dist/dev/elements/xy.js +474 -0
  143. package/dist/dev/elements/xy.js.map +1 -0
  144. package/dist/dev/index.d.ts +11 -2
  145. package/dist/dev/index.js +10 -2
  146. package/dist/dev/lib/adsr-shape.js +109 -0
  147. package/dist/dev/lib/adsr-shape.js.map +1 -0
  148. package/dist/dev/lib/ballistics.js +56 -0
  149. package/dist/dev/lib/ballistics.js.map +1 -0
  150. package/dist/dev/lib/canvas-surface.d.ts +25 -0
  151. package/dist/dev/lib/canvas-surface.js +193 -0
  152. package/dist/dev/lib/canvas-surface.js.map +1 -0
  153. package/dist/dev/lib/copy-node.js +32 -2
  154. package/dist/dev/lib/copy-node.js.map +1 -1
  155. package/dist/dev/lib/crossfade.d.ts +12 -0
  156. package/dist/dev/lib/crossfade.js +23 -0
  157. package/dist/dev/lib/crossfade.js.map +1 -0
  158. package/dist/dev/lib/distribute.d.ts +4 -0
  159. package/dist/dev/lib/distribute.js +216 -0
  160. package/dist/dev/lib/distribute.js.map +1 -0
  161. package/dist/dev/lib/drag-step.js +100 -0
  162. package/dist/dev/lib/drag-step.js.map +1 -0
  163. package/dist/dev/lib/envelope-curve.d.ts +4 -0
  164. package/dist/dev/lib/envelope-curve.js +10 -0
  165. package/dist/dev/lib/envelope-curve.js.map +1 -0
  166. package/dist/dev/lib/field.d.ts +4 -0
  167. package/dist/dev/lib/field.js +95 -0
  168. package/dist/dev/lib/field.js.map +1 -0
  169. package/dist/dev/lib/focus-by-pointer.js +29 -0
  170. package/dist/dev/lib/focus-by-pointer.js.map +1 -0
  171. package/dist/dev/lib/frame-timeline.js +63 -0
  172. package/dist/dev/lib/frame-timeline.js.map +1 -0
  173. package/dist/dev/lib/hold.js +39 -0
  174. package/dist/dev/lib/hold.js.map +1 -0
  175. package/dist/dev/lib/marker-band.js +37 -0
  176. package/dist/dev/lib/marker-band.js.map +1 -0
  177. package/dist/dev/lib/marker-rider.js +115 -0
  178. package/dist/dev/lib/marker-rider.js.map +1 -0
  179. package/dist/dev/lib/math.js +12 -3
  180. package/dist/dev/lib/math.js.map +1 -1
  181. package/dist/dev/lib/modifier-press.js +12 -0
  182. package/dist/dev/lib/modifier-press.js.map +1 -0
  183. package/dist/dev/lib/number-list.js +6 -6
  184. package/dist/dev/lib/number-list.js.map +1 -1
  185. package/dist/dev/lib/pointer-drag.js +44 -0
  186. package/dist/dev/lib/pointer-drag.js.map +1 -0
  187. package/dist/dev/lib/read-px-property.js.map +1 -1
  188. package/dist/dev/lib/render.js +20 -5
  189. package/dist/dev/lib/render.js.map +1 -1
  190. package/dist/dev/lib/resample-peaks.js +37 -0
  191. package/dist/dev/lib/resample-peaks.js.map +1 -0
  192. package/dist/dev/lib/strip-scene.js +49 -0
  193. package/dist/dev/lib/strip-scene.js.map +1 -0
  194. package/dist/dev/lib/taper.js +23 -17
  195. package/dist/dev/lib/taper.js.map +1 -1
  196. package/dist/dev/lib/time-regions.d.ts +4 -0
  197. package/dist/dev/lib/time-regions.js +9 -0
  198. package/dist/dev/lib/time-regions.js.map +1 -0
  199. package/dist/dev/lib/tracking-clock.js +36 -0
  200. package/dist/dev/lib/tracking-clock.js.map +1 -0
  201. package/dist/dev/lib/value-mapping.d.ts +23 -0
  202. package/dist/dev/lib/value-mapping.js +116 -0
  203. package/dist/dev/lib/value-mapping.js.map +1 -0
  204. package/dist/dev/lib/waveform-buckets.d.ts +9 -0
  205. package/dist/dev/lib/waveform-buckets.js +42 -0
  206. package/dist/dev/lib/waveform-buckets.js.map +1 -0
  207. package/dist/skins/ivory.css +1 -2
  208. package/dist/styles/button.css +212 -0
  209. package/dist/styles/controls.css +8 -1
  210. package/dist/styles/dial.css +88 -42
  211. package/dist/styles/envelope.css +159 -0
  212. package/dist/styles/led.css +36 -5
  213. package/dist/styles/material.css +277 -76
  214. package/dist/styles/meter.css +33 -48
  215. package/dist/styles/number.css +5 -1
  216. package/dist/styles/panel.css +59 -0
  217. package/dist/styles/ring.css +74 -0
  218. package/dist/styles/segmented.css +21 -48
  219. package/dist/styles/slider.css +175 -39
  220. package/dist/styles/switch.css +347 -0
  221. package/dist/styles/waveform.css +173 -0
  222. package/dist/styles/wavestrip.css +215 -0
  223. package/dist/styles/xy.css +204 -0
  224. package/package.json +14 -2
  225. package/dist/default/define/key.js +0 -7
  226. package/dist/default/elements/key.js +0 -169
  227. package/dist/default/elements/range-element.js +0 -546
  228. package/dist/default/lib/detent.js +0 -17
  229. package/dist/dev/define/key.d.ts +0 -2
  230. package/dist/dev/define/key.js +0 -8
  231. package/dist/dev/define/key.js.map +0 -1
  232. package/dist/dev/elements/key.js +0 -170
  233. package/dist/dev/elements/key.js.map +0 -1
  234. package/dist/dev/elements/range-element.d.ts +0 -64
  235. package/dist/dev/elements/range-element.js +0 -547
  236. package/dist/dev/elements/range-element.js.map +0 -1
  237. package/dist/dev/elements/range-entry.js.map +0 -1
  238. package/dist/dev/lib/detent.js +0 -18
  239. package/dist/dev/lib/detent.js.map +0 -1
  240. package/dist/styles/key.css +0 -242
@@ -10,23 +10,37 @@
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 */
30
44
  --_sonic-light-tilt: var(--sonic-light-tilt, 17deg);
31
45
  --_sonic-light-fall: calc(180deg - var(--_sonic-light-tilt));
32
46
  --_sonic-cast-x: calc(sin(var(--_sonic-light-tilt)) * var(--_sonic-unit));
@@ -35,32 +49,67 @@
35
49
 
36
50
  :is(
37
51
  .sonic-dial,
38
- .sonic-key,
52
+ .sonic-envelope,
53
+ .sonic-button,
39
54
  .sonic-led,
40
55
  .sonic-meter,
41
56
  .sonic-number,
42
- .sonic-segmented-segment,
43
- .sonic-slider
57
+ .sonic-ring,
58
+ .sonic-segmented-option,
59
+ .sonic-slider,
60
+ .sonic-waveform,
61
+ .sonic-wavestrip,
62
+ .sonic-xy
44
63
  ) {
45
64
  --_sonic-lit: var(--sonic-lit, oklch(76.9% 0.165 70deg));
46
65
  }
47
66
 
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);
67
+ /* On the parts, since a recipe's `var()`s resolve where it is declared */
68
+ .sonic-dial-ring,
69
+ .sonic-dial-modulation,
70
+ .sonic-ring::before {
71
+ --_sonic-arc-mask: radial-gradient(
72
+ closest-side,
73
+ transparent calc(100% - var(--_sonic-arc-width) - 0.5px),
74
+ #000 calc(100% - var(--_sonic-arc-width)),
75
+ #000 calc(100% - var(--_sonic-arc-inset) - 0.5px),
76
+ transparent calc(100% - var(--_sonic-arc-inset))
77
+ );
78
+ --_sonic-arc-shade: radial-gradient(
79
+ closest-side,
80
+ rgb(0 0 0 / 55%) calc(100% - var(--_sonic-arc-width)),
81
+ transparent calc(100% - var(--_sonic-arc-width) * 0.4),
82
+ rgb(0 0 0 / 25%) 100%
83
+ );
52
84
  }
53
85
 
54
- .sonic-meter {
86
+ :is(.sonic-led, .sonic-meter) {
87
+ --_sonic-lens-glint: linear-gradient(
88
+ var(--_sonic-light-fall),
89
+ rgb(255 255 255 / 10%),
90
+ transparent 60%
91
+ );
92
+ --_sonic-lens-glass: color-mix(in oklab, var(--_sonic-unlit) 60%, #000);
93
+ --_sonic-lens: var(--_sonic-lens-glint), var(--_sonic-lens-glass);
55
94
  --_sonic-hot: var(--sonic-hot, oklch(70.5% 0.187 48deg));
56
95
  --_sonic-clip: var(--sonic-clip, oklch(63.7% 0.208 25deg));
57
96
  }
58
97
 
59
- :is(.sonic-dial, .sonic-key, .sonic-number, .sonic-segmented-segment, .sonic-slider) {
98
+ :is(
99
+ .sonic-dial,
100
+ .sonic-button,
101
+ .sonic-switch,
102
+ .sonic-number,
103
+ .sonic-segmented-option,
104
+ .sonic-slider,
105
+ .sonic-waveform,
106
+ .sonic-wavestrip,
107
+ .sonic-xy
108
+ ) {
60
109
  --_sonic-cap: var(--sonic-cap, oklch(37% 0.012 286deg));
61
110
  --_sonic-cap-hover: var(--sonic-cap-hover, oklch(44.2% 0.015 286deg));
62
111
  --_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));
112
+ --_sonic-ink: var(--sonic-ink, color-mix(in oklab, var(--_sonic-cap) 30%, #fff));
64
113
  --_sonic-etch: color-mix(in oklab, var(--_sonic-ink) 30%, transparent);
65
114
  --_sonic-ink-lift: color-mix(in oklab, var(--_sonic-ink) 60%, #fff);
66
115
  --_sonic-lit-disabled: color-mix(in oklab, var(--_sonic-ink) 25%, var(--_sonic-unlit));
@@ -69,8 +118,6 @@
69
118
  color-mix(in oklab, var(--_sonic-cap) 70%, #fff),
70
119
  color-mix(in oklab, var(--_sonic-cap) 55%, #000)
71
120
  );
72
-
73
- /* Inverted from the skirt, as a dished face takes light */
74
121
  --_sonic-face: linear-gradient(
75
122
  var(--_sonic-light-fall),
76
123
  color-mix(in oklab, var(--_sonic-cap) 85%, #000),
@@ -99,21 +146,35 @@
99
146
  color-mix(in oklab, var(--_sonic-focus) 60%, transparent);
100
147
  }
101
148
 
102
- /* A gesture distance, absolute like the travel */
103
- :is(.sonic-dial, .sonic-number, .sonic-slider) {
149
+ :is(.sonic-dial, .sonic-number, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
104
150
  --_sonic-detent-zone: var(--sonic-detent-zone, 8px);
105
151
  }
106
152
 
107
- :is(.sonic-dial, .sonic-slider) {
108
- /* On the control, since the readout's font size reads it */
153
+ :is(.sonic-dial, .sonic-envelope, .sonic-slider, .sonic-waveform, .sonic-wavestrip, .sonic-xy) {
109
154
  --_sonic-readout-size: var(--sonic-readout-size, 1.5rem);
155
+ }
156
+
157
+ :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
110
158
  --_sonic-lit-off: var(
111
159
  --sonic-dimmed,
112
160
  color-mix(in oklab, var(--_sonic-lit) 50%, var(--_sonic-unlit))
113
161
  );
114
162
  }
115
163
 
116
- :is(.sonic-dial-readout, .sonic-number, .sonic-screen, .sonic-slider-readout) {
164
+ :is(
165
+ .sonic-dial-readout,
166
+ .sonic-envelope,
167
+ .sonic-envelope-readout,
168
+ .sonic-number,
169
+ .sonic-screen,
170
+ .sonic-slider-readout,
171
+ .sonic-waveform,
172
+ .sonic-waveform-readout,
173
+ .sonic-wavestrip,
174
+ .sonic-wavestrip-readout,
175
+ .sonic-xy,
176
+ .sonic-xy-readout
177
+ ) {
117
178
  --_sonic-glass: var(--sonic-glass, color-mix(in oklab, var(--_sonic-unlit) 45%, #000));
118
179
  --_sonic-glass-fill: radial-gradient(
119
180
  closest-side,
@@ -121,49 +182,134 @@
121
182
  var(--_sonic-glass)
122
183
  )
123
184
  var(--_sonic-glass);
124
-
125
- /* Not the cap's ink, which a skin may darken */
126
185
  --_sonic-glass-text: var(
127
186
  --sonic-glass-text,
128
187
  color-mix(in oklab, var(--_sonic-glass) 20%, #fff)
129
188
  );
189
+ --_sonic-glass-edge: 0 none;
190
+
191
+ /* Glass is forced to Canvas like the page, so only a border shows its edge */
192
+ @media (forced-colors: active) {
193
+ --_sonic-glass-edge: 1px solid CanvasText;
194
+ }
130
195
  }
131
196
 
132
197
  /* 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) {
198
+ :is(.sonic-envelope, .sonic-number, .sonic-screen, .sonic-waveform, .sonic-wavestrip, .sonic-xy) {
199
+ --_sonic-glass-depth: var(--sonic-glass-depth, 1);
200
+ --_sonic-glass-texture: var(--sonic-glass-texture, 1);
201
+ --_sonic-glass-pitch: max(2px, round(2 * var(--_sonic-unit), 1px));
202
+
134
203
  position: relative;
135
204
  box-sizing: border-box;
136
205
  display: grid;
137
206
  flex-shrink: 0;
138
207
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
139
208
  place-items: center;
140
- font-family: var(--sonic-glass-font);
209
+ font-family: var(--sonic-glass-font, inherit);
141
210
  color: var(--_sonic-glass-text);
142
-
143
- /* A double click aimed at a neighbouring control would highlight it */
144
211
  user-select: none;
145
212
  background: var(--_sonic-glass-fill);
213
+ border: var(--_sonic-glass-edge);
214
+
215
+ @media (forced-colors: active) {
216
+ --_sonic-glass-texture: 0;
217
+ }
146
218
 
147
219
  &::after {
148
220
  position: absolute;
149
221
  inset: 0;
150
222
  pointer-events: none;
151
223
  content: '';
152
- background: linear-gradient(var(--_sonic-light-fall), rgb(255 255 255 / 7%), transparent 45%);
224
+ background:
225
+ linear-gradient(
226
+ var(--_sonic-light-fall),
227
+ rgb(255 255 255 / calc(0.07 * var(--_sonic-glass-depth))),
228
+ transparent 45%
229
+ ),
230
+ radial-gradient(
231
+ farthest-corner,
232
+ transparent 55%,
233
+ rgb(0 0 0 / calc(0.4 * var(--_sonic-glass-texture)))
234
+ ),
235
+ repeating-linear-gradient(
236
+ to bottom,
237
+ rgb(0 0 0 / calc(0.04 * var(--_sonic-glass-texture))) 0
238
+ calc(var(--_sonic-glass-pitch) / 2),
239
+ transparent 0 var(--_sonic-glass-pitch)
240
+ );
153
241
  border-radius: inherit;
154
242
  box-shadow:
155
243
  var(--_sonic-well),
156
- inset 0 0 calc(3 * var(--_sonic-unit)) rgb(0 0 0 / 45%);
244
+ inset 0 0 calc(3 * var(--_sonic-glass-depth) * var(--_sonic-unit)) rgb(0 0 0 / 45%);
245
+ }
246
+
247
+ @media (forced-colors: none) {
248
+ /* No var() beside the tile, which would parse the url() again on every style recalculation */
249
+ &::before {
250
+ position: absolute;
251
+ inset: 0;
252
+ color: color-mix(in oklab, var(--_sonic-glass-text) 7.5%, transparent);
253
+ pointer-events: none;
254
+ content: '';
255
+ background:
256
+ radial-gradient(closest-side, currentcolor, transparent) no-repeat,
257
+ 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")
258
+ 0 0 / 128px 128px repeat;
259
+ border-radius: inherit;
260
+ opacity: min(1, var(--_sonic-glass-texture));
261
+ }
262
+
263
+ @media (prefers-reduced-motion: no-preference) {
264
+ &:is(:focus-visible, :focus-within)::before,
265
+ :state(dragging) > &::before {
266
+ animation: sonic-glass-breathe 3s ease-in-out infinite alternate;
267
+ }
268
+
269
+ @media (hover: hover) {
270
+ &:hover::before {
271
+ animation: sonic-glass-breathe 3s ease-in-out infinite alternate;
272
+ }
273
+ }
274
+ }
157
275
  }
158
276
  }
159
277
 
160
- :is(.sonic-key, .sonic-number, .sonic-screen, .sonic-segmented) {
278
+ @media (forced-colors: none) {
279
+ :is(.sonic-number, .sonic-screen),
280
+ :is(.sonic-envelope, .sonic-waveform, .sonic-wavestrip, .sonic-xy)::after {
281
+ 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.04' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3C/svg%3E#w");
282
+ }
283
+
284
+ /* A query reads the parent, or a pseudo-element's own element: on a readout itself, 0 leaves the warp on */
285
+ @container style(--sonic-glass-texture: 0) {
286
+ :is(.sonic-number, .sonic-screen),
287
+ :is(.sonic-envelope, .sonic-waveform, .sonic-wavestrip, .sonic-xy)::after {
288
+ filter: none;
289
+ }
290
+ }
291
+ }
292
+
293
+ :is(
294
+ .sonic-envelope,
295
+ .sonic-button,
296
+ .sonic-number,
297
+ .sonic-screen,
298
+ .sonic-segmented,
299
+ .sonic-waveform,
300
+ .sonic-wavestrip,
301
+ .sonic-xy
302
+ ) {
303
+ --_sonic-well-depth: var(--_sonic-glass-depth, 1);
161
304
  --_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%);
305
+ inset calc(var(--_sonic-well-depth) * var(--_sonic-cast-x))
306
+ calc(var(--_sonic-well-depth) * var(--_sonic-cast-y))
307
+ calc(2 * var(--_sonic-well-depth) * var(--_sonic-unit)) rgb(0 0 0 / 60%),
308
+ calc(0.5 * var(--_sonic-well-depth) * var(--_sonic-cast-x))
309
+ calc(0.5 * var(--_sonic-well-depth) * var(--_sonic-cast-y)) 0 rgb(255 255 255 / 6%);
164
310
  }
165
311
 
166
- :is(.sonic-key, .sonic-segmented) {
312
+ :is(.sonic-button, .sonic-segmented) {
167
313
  --_sonic-well-floor: linear-gradient(
168
314
  var(--_sonic-light-fall),
169
315
  color-mix(in oklab, var(--_sonic-unlit) 55%, #000),
@@ -178,13 +324,44 @@
178
324
  );
179
325
  }
180
326
 
181
- /* On the segment rather than the strip, where forced colours clear the drop shade */
182
- :is(.sonic-key, .sonic-segmented-segment) {
327
+ /* On the option rather than the strip, where forced colours clear the drop shade */
328
+ :is(.sonic-button, .sonic-segmented-option) {
183
329
  --_sonic-press-drop: calc(0.5 * var(--_sonic-cast-x)) calc(0.5 * var(--_sonic-cast-y))
184
330
  var(--_sonic-unit) var(--_sonic-drop-shade);
331
+ --_sonic-keycap-shift: calc(var(--_sonic-keycap-depth) / -2);
332
+ --_sonic-keycap-scale: 1;
333
+ --_sonic-keycap-drop: calc(1.5 * var(--_sonic-cast-x)) calc(1.5 * var(--_sonic-cast-y))
334
+ calc(2 * var(--_sonic-unit)) var(--_sonic-drop-shade);
335
+ --_sonic-keycap-glow: transparent;
336
+ }
337
+
338
+ /* Each sheet maps its own depth, corner, bevel and face corner onto the `keycap` tokens */
339
+ :is(.sonic-button-cap, .sonic-segmented-cap) {
340
+ display: grid;
341
+ place-items: center;
342
+ background: var(--_sonic-skirt);
343
+ border-radius: var(--_sonic-keycap-corner);
344
+ box-shadow: var(--_sonic-keycap-drop), var(--_sonic-rim), var(--_sonic-focus-shadow);
345
+ scale: var(--_sonic-keycap-scale);
346
+ translate: 0 var(--_sonic-keycap-shift);
347
+ transition: var(--_sonic-press-transition);
348
+
349
+ &::before {
350
+ position: absolute;
351
+ inset: var(--_sonic-keycap-bevel);
352
+ content: '';
353
+ background:
354
+ radial-gradient(closest-side, var(--_sonic-keycap-glow), transparent), var(--_sonic-sheen),
355
+ var(--_sonic-face);
356
+ border-radius: var(--_sonic-keycap-face-corner);
357
+ box-shadow: var(--_sonic-face-shadow);
358
+ }
359
+
360
+ & > * {
361
+ position: relative;
362
+ }
185
363
  }
186
364
 
187
- /* The well's full blur would fill a slot this narrow */
188
365
  :is(.sonic-meter, .sonic-slider) {
189
366
  --_sonic-groove:
190
367
  inset var(--_sonic-cast-x) var(--_sonic-cast-y) calc(0.75 * var(--_sonic-unit))
@@ -194,7 +371,7 @@
194
371
  }
195
372
 
196
373
  @media (hover: hover) {
197
- :is(.sonic-dial, .sonic-key, .sonic-segmented-segment, .sonic-slider):not(
374
+ :is(.sonic-dial, .sonic-button, .sonic-segmented-option, .sonic-slider):not(
198
375
  :disabled,
199
376
  [aria-disabled='true']
200
377
  ):hover {
@@ -204,25 +381,37 @@
204
381
 
205
382
  :is(
206
383
  .sonic-dial,
207
- .sonic-key,
384
+ .sonic-button,
208
385
  .sonic-number,
209
- .sonic-segmented-segment,
210
- .sonic-slider
386
+ .sonic-segmented-option,
387
+ .sonic-slider,
388
+ .sonic-waveform,
389
+ .sonic-wavestrip,
390
+ .sonic-xy-axis
211
391
  ):focus-visible {
212
- --_sonic-cap: var(--_sonic-cap-hover);
213
- --_sonic-focus-shadow: var(--_sonic-focus-glow);
214
-
215
392
  outline: 2px solid transparent;
216
393
  outline-offset: -2px;
394
+
395
+ &:not([data-sonic-pointer-focus]) {
396
+ --_sonic-cap: var(--_sonic-cap-hover);
397
+ --_sonic-focus-shadow: var(--_sonic-focus-glow);
398
+ }
217
399
  }
218
400
 
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) {
401
+ :state(editing)
402
+ > :is(.sonic-dial, .sonic-number, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
221
403
  --_sonic-cap: var(--_sonic-cap-hover);
222
404
  --_sonic-focus-shadow: var(--_sonic-focus-glow);
223
405
  }
224
406
 
225
- :is(.sonic-dial-readout, .sonic-slider-readout) {
407
+ :is(
408
+ .sonic-dial-readout,
409
+ .sonic-envelope-readout,
410
+ .sonic-slider-readout,
411
+ .sonic-waveform-readout,
412
+ .sonic-wavestrip-readout,
413
+ .sonic-xy-readout
414
+ ) {
226
415
  --_sonic-unit: calc(var(--_sonic-readout-size) / 32);
227
416
 
228
417
  box-sizing: border-box;
@@ -235,7 +424,7 @@
235
424
  position-try-fallbacks: flip-block;
236
425
  overflow: visible;
237
426
  font: inherit;
238
- font-family: var(--sonic-glass-font);
427
+ font-family: var(--sonic-glass-font, inherit);
239
428
  font-size: calc(0.5 * var(--_sonic-readout-size));
240
429
  font-variant-numeric: tabular-nums;
241
430
  line-height: 1;
@@ -244,7 +433,7 @@
244
433
  cursor: default;
245
434
  user-select: none;
246
435
  background: var(--_sonic-glass-fill);
247
- border: 0;
436
+ border: var(--_sonic-glass-edge);
248
437
  border-radius: calc(0.25 * var(--_sonic-readout-size));
249
438
  box-shadow:
250
439
  calc(2 * var(--_sonic-cast-x)) calc(2 * var(--_sonic-cast-y)) calc(6 * var(--_sonic-unit))
@@ -258,7 +447,7 @@
258
447
  display 120ms allow-discrete,
259
448
  overlay 120ms allow-discrete;
260
449
 
261
- /* Grid only while open; a closed readout left rendered is placed against a filtered ancestor, and engines keep the flip it took there */
450
+ /* Grid only while open; engines keep the flip a closed readout took against a filtered ancestor */
262
451
  &:popover-open {
263
452
  display: grid;
264
453
  opacity: 1;
@@ -279,16 +468,20 @@
279
468
  }
280
469
  }
281
470
  }
282
- }
283
471
 
284
- :state(editing)
285
- > :is(.sonic-dial, .sonic-slider)
286
- > :is(.sonic-dial-readout, .sonic-slider-readout) {
287
- pointer-events: auto;
288
- cursor: text;
472
+ :state(editing) > :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip) > & {
473
+ pointer-events: auto;
474
+ cursor: text;
475
+ }
289
476
  }
290
477
 
291
- :is(.sonic-dial-entry, .sonic-number-entry, .sonic-slider-entry) {
478
+ :is(
479
+ .sonic-dial-entry,
480
+ .sonic-number-entry,
481
+ .sonic-slider-entry,
482
+ .sonic-waveform-entry,
483
+ .sonic-wavestrip-entry
484
+ ) {
292
485
  inline-size: 6ch;
293
486
  padding: 0;
294
487
  font: inherit;
@@ -314,7 +507,6 @@
314
507
  }
315
508
  }
316
509
 
317
- /* Printed on the consumer's panel rather than the cap, so the text takes the page's colour and font */
318
510
  :is(.sonic-dial-scale, .sonic-slider-scale) {
319
511
  position: absolute;
320
512
  inset: 0;
@@ -344,11 +536,12 @@
344
536
 
345
537
  :is(
346
538
  .sonic-dial,
347
- .sonic-key,
539
+ .sonic-button,
348
540
  .sonic-led,
349
541
  .sonic-meter,
350
542
  .sonic-number,
351
- .sonic-segmented-segment,
543
+ .sonic-ring,
544
+ .sonic-segmented-option,
352
545
  .sonic-slider
353
546
  ) {
354
547
  --_sonic-lit: Highlight;
@@ -356,7 +549,16 @@
356
549
  }
357
550
 
358
551
  /* 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) {
552
+ :is(
553
+ .sonic-dial,
554
+ .sonic-button,
555
+ .sonic-number,
556
+ .sonic-segmented-option,
557
+ .sonic-slider,
558
+ .sonic-waveform,
559
+ .sonic-wavestrip,
560
+ .sonic-xy
561
+ ) {
360
562
  --_sonic-ink: ButtonText;
361
563
  --_sonic-etch: ButtonText;
362
564
  --_sonic-lit-disabled: GrayText;
@@ -369,39 +571,38 @@
369
571
  --_sonic-focus-glow: 0 0 transparent;
370
572
  }
371
573
 
372
- /* Dimmed is a hint, not a state; the value stays readable */
373
- :is(.sonic-dial, .sonic-slider) {
574
+ :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
374
575
  --_sonic-lit-off: Highlight;
375
576
  }
376
577
 
377
578
  :is(
378
- :disabled > :is(.sonic-dial, .sonic-slider),
379
- .sonic-key:is(:disabled, [aria-disabled='true']),
380
- .sonic-segmented-segment:disabled
579
+ :disabled > :is(.sonic-dial, .sonic-slider, .sonic-waveform, .sonic-wavestrip, .sonic-xy),
580
+ .sonic-button:is(:disabled, [aria-disabled='true']),
581
+ .sonic-segmented-option:disabled
381
582
  ) {
382
583
  --_sonic-ink: GrayText;
383
584
  --_sonic-etch: GrayText;
384
585
  }
385
586
 
386
- /* Stands in for the glow, which forced colours drop; inset, it merged with the cap's rim */
387
587
  :is(
388
588
  .sonic-dial,
389
- .sonic-key,
589
+ .sonic-button,
390
590
  .sonic-number,
391
- .sonic-segmented-segment,
392
- .sonic-slider
591
+ .sonic-segmented-option,
592
+ .sonic-slider,
593
+ .sonic-waveform,
594
+ .sonic-wavestrip
393
595
  ):focus-visible {
394
596
  outline-offset: 2px;
597
+
598
+ &[data-sonic-pointer-focus] {
599
+ outline-style: none;
600
+ }
395
601
  }
396
602
 
397
- :is(.sonic-dial-cap, .sonic-key-cap, .sonic-segmented-cap, .sonic-slider-cap) {
603
+ :is(.sonic-dial-cap, .sonic-button-cap, .sonic-segmented-cap, .sonic-slider-cap) {
398
604
  color: var(--_sonic-ink);
399
605
  forced-color-adjust: none;
400
606
  }
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
607
  }
407
608
  }