@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
@@ -16,7 +16,6 @@
16
16
  initial-value: 4px;
17
17
  }
18
18
 
19
- /* The size is the thickness */
20
19
  @layer sonic {
21
20
  :is(sonic-meter, .sonic-meter) {
22
21
  --_sonic-meter-size: var(--sonic-meter-size, 0.5rem);
@@ -40,17 +39,10 @@
40
39
  }
41
40
 
42
41
  .sonic-meter {
43
- /* Absolute, so a longer meter gains segments rather than stretching them */
44
42
  --_sonic-meter-pitch: var(--sonic-meter-segment-pitch, 4px);
45
-
46
- /* A fraction of the pitch */
47
43
  --_sonic-meter-gap-ratio: var(--sonic-meter-gap-ratio, 0.25);
48
44
  --_sonic-meter-radius-ratio: var(--sonic-meter-radius-ratio, 0.25);
49
-
50
- /* A fraction of the light's length along the meter */
51
45
  --_sonic-meter-segment-radius-ratio: var(--sonic-meter-segment-radius-ratio, 0.35);
52
-
53
- /* dBFS */
54
46
  --_sonic-meter-hot-from: var(--sonic-meter-hot-from, -12);
55
47
  --_sonic-meter-clip-from: var(--sonic-meter-clip-from, -3);
56
48
  --_sonic-unit: calc(var(--_sonic-meter-size) / 8);
@@ -94,8 +86,7 @@
94
86
  block-size: var(--_sonic-meter-size);
95
87
  }
96
88
 
97
- /* No clip on either, so the lights take the lens's room */
98
- :is([scale='linear'], :state(ladder)) > .sonic-meter {
89
+ :is([value], :state(ladder)) > .sonic-meter {
99
90
  --_sonic-meter-clip-space: 0px;
100
91
  }
101
92
 
@@ -105,7 +96,7 @@
105
96
  );
106
97
  --_sonic-meter-gap: 0px;
107
98
  --_sonic-meter-segments: calc(var(--_sonic-meter-length) - 2 * var(--_sonic-meter-inset));
108
- --_sonic-meter-light-radius: calc(
99
+ --_sonic-meter-ladder-radius: calc(
109
100
  min(
110
101
  var(--_sonic-meter-lens),
111
102
  var(--_sonic-meter-pitch) * (1 - var(--_sonic-meter-gap-ratio))
@@ -114,8 +105,7 @@
114
105
  );
115
106
  }
116
107
 
117
- /* Snapped to whole lights, so none is split between two colours */
118
- :is(.sonic-meter-segments, .sonic-meter-level) {
108
+ :is(.sonic-meter-segments, .sonic-meter-bar) {
119
109
  --_sonic-meter-span: calc(var(--_sonic-meter-max, 0) - var(--_sonic-meter-min, -60));
120
110
  --_sonic-meter-hot-at: round(
121
111
  clamp(
@@ -129,7 +119,7 @@
129
119
  --_sonic-meter-clip-at: round(
130
120
  clamp(
131
121
  0,
132
- /* fallow-ignore-next-line code-duplication -- each zone snaps its own threshold by the same rule */
122
+ /* fallow-ignore-next-line code-duplication -- each zone snaps its own threshold */
133
123
  (var(--_sonic-meter-clip-from) - var(--_sonic-meter-min, -60)) /
134
124
  var(--_sonic-meter-span),
135
125
  1
@@ -137,9 +127,7 @@
137
127
  var(--_sonic-meter-segments),
138
128
  var(--_sonic-meter-pitch)
139
129
  );
140
-
141
- /* Each rounded light is two crossed bands and four corner dots added together */
142
- --_sonic-meter-lights:
130
+ --_sonic-meter-segment-mask:
143
131
  linear-gradient(to top, #000 var(--_sonic-meter-segment), transparent 0)
144
132
  var(--_sonic-meter-segment-radius) 100% /
145
133
  calc(100% - 2 * var(--_sonic-meter-segment-radius)) var(--_sonic-meter-pitch) no-repeat
@@ -184,29 +172,28 @@
184
172
  position: absolute;
185
173
  inset: auto var(--_sonic-meter-inset) var(--_sonic-meter-inset);
186
174
  block-size: calc(var(--_sonic-meter-segments) - var(--_sonic-meter-gap));
187
- mask: var(--_sonic-meter-lights);
175
+ mask: var(--_sonic-meter-segment-mask);
188
176
  mask-composite: add;
189
177
  }
190
178
 
191
- :state(ladder) > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-level) {
192
- --_sonic-meter-hot-at: calc(var(--_sonic-meter-hot-lights, 0) * var(--_sonic-meter-pitch));
193
- --_sonic-meter-clip-at: calc(var(--_sonic-meter-clip-lights, 0) * var(--_sonic-meter-pitch));
194
- --_sonic-meter-lights: radial-gradient(
195
- circle var(--_sonic-meter-light-radius),
179
+ :state(ladder) > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-bar) {
180
+ --_sonic-meter-hot-at: calc(var(--_sonic-meter-hot-segments, 0) * var(--_sonic-meter-pitch));
181
+ --_sonic-meter-clip-at: calc(var(--_sonic-meter-clip-segments, 0) * var(--_sonic-meter-pitch));
182
+ --_sonic-meter-segment-mask: radial-gradient(
183
+ circle var(--_sonic-meter-ladder-radius),
196
184
  #000 calc(100% - 0.5px),
197
185
  transparent
198
186
  )
199
187
  0 100% / 100% var(--_sonic-meter-pitch) no-repeat repeat;
200
188
  }
201
189
 
202
- /* The zones are dBFS, which a linear level is not */
203
- [scale='linear'] > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-level) {
190
+ [value] > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-bar) {
204
191
  --_sonic-meter-hot-at: var(--_sonic-meter-segments);
205
192
  --_sonic-meter-clip-at: var(--_sonic-meter-segments);
206
193
  }
207
194
 
208
- [orientation='horizontal'] > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-level) {
209
- --_sonic-meter-lights:
195
+ [orientation='horizontal'] > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-bar) {
196
+ --_sonic-meter-segment-mask:
210
197
  linear-gradient(to right, #000 var(--_sonic-meter-segment), transparent 0) 0
211
198
  var(--_sonic-meter-segment-radius) / var(--_sonic-meter-pitch)
212
199
  calc(100% - 2 * var(--_sonic-meter-segment-radius)) repeat no-repeat,
@@ -257,16 +244,16 @@
257
244
 
258
245
  [orientation='horizontal']:state(ladder)
259
246
  > .sonic-meter
260
- > :is(.sonic-meter-segments, .sonic-meter-level) {
261
- --_sonic-meter-lights: radial-gradient(
262
- circle var(--_sonic-meter-light-radius),
247
+ > :is(.sonic-meter-segments, .sonic-meter-bar) {
248
+ --_sonic-meter-segment-mask: radial-gradient(
249
+ circle var(--_sonic-meter-ladder-radius),
263
250
  #000 calc(100% - 0.5px),
264
251
  transparent
265
252
  )
266
253
  0 0 / var(--_sonic-meter-pitch) 100% repeat no-repeat;
267
254
  }
268
255
 
269
- :state(ladder) > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-level)::after {
256
+ :state(ladder) > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-bar)::after {
270
257
  position: absolute;
271
258
  inset: 0;
272
259
  content: '';
@@ -274,9 +261,9 @@
274
261
  100% / 100% var(--_sonic-meter-pitch) repeat-y;
275
262
  }
276
263
 
277
- :state(ladder) > .sonic-meter > .sonic-meter-level::after {
264
+ :state(ladder) > .sonic-meter > .sonic-meter-bar::after {
278
265
  background: radial-gradient(
279
- circle var(--_sonic-meter-light-radius),
266
+ circle var(--_sonic-meter-ladder-radius),
280
267
  rgb(255 255 255 / 45%),
281
268
  transparent
282
269
  )
@@ -285,7 +272,7 @@
285
272
 
286
273
  [orientation='horizontal']:state(ladder)
287
274
  > .sonic-meter
288
- > :is(.sonic-meter-segments, .sonic-meter-level)::after {
275
+ > :is(.sonic-meter-segments, .sonic-meter-bar)::after {
289
276
  background-repeat: repeat-x;
290
277
  background-position: 0 0;
291
278
  background-size: var(--_sonic-meter-pitch) 100%;
@@ -300,25 +287,23 @@
300
287
  );
301
288
  }
302
289
 
303
- /* One mask for the bar and peak, so a frame repaints without layout */
304
-
305
- /* The hair of slack keeps an exact fraction from losing a light to float error */
306
- .sonic-meter-level {
290
+ /* The hair of slack keeps an exact fraction from losing a segment to float error */
291
+ .sonic-meter-bar {
307
292
  --_sonic-meter-lit-from: round(
308
293
  up,
309
- min(var(--_sonic-meter-origin, 0), var(--_sonic-meter-level, 0)) *
294
+ min(var(--_sonic-meter-origin, 0), var(--_sonic-meter-bar, 0)) *
310
295
  var(--_sonic-meter-segments) - 0.01px,
311
296
  var(--_sonic-meter-pitch)
312
297
  );
313
298
  --_sonic-meter-lit: round(
314
299
  down,
315
- max(var(--_sonic-meter-origin, 0), var(--_sonic-meter-level, 0)) *
300
+ max(var(--_sonic-meter-origin, 0), var(--_sonic-meter-bar, 0)) *
316
301
  var(--_sonic-meter-segments) + 0.01px,
317
302
  var(--_sonic-meter-pitch)
318
303
  );
319
- --_sonic-meter-held: round(
304
+ --_sonic-meter-peak-hold-edge: round(
320
305
  down,
321
- var(--_sonic-meter-peak, 0) * var(--_sonic-meter-segments) + 0.01px,
306
+ var(--_sonic-meter-peak-hold, 0) * var(--_sonic-meter-segments) + 0.01px,
322
307
  var(--_sonic-meter-pitch)
323
308
  );
324
309
 
@@ -333,11 +318,11 @@
333
318
  var(--_sonic-meter-toward),
334
319
  transparent var(--_sonic-meter-lit-from),
335
320
  #000 0 var(--_sonic-meter-lit),
336
- transparent 0 calc(var(--_sonic-meter-held) - var(--_sonic-meter-pitch)),
337
- #000 0 var(--_sonic-meter-held),
321
+ transparent 0 calc(var(--_sonic-meter-peak-hold-edge) - var(--_sonic-meter-pitch)),
322
+ #000 0 var(--_sonic-meter-peak-hold-edge),
338
323
  transparent 0
339
324
  ),
340
- var(--_sonic-meter-lights);
325
+ var(--_sonic-meter-segment-mask);
341
326
  mask-composite: intersect, add, add, add, add, add, add;
342
327
  }
343
328
 
@@ -362,7 +347,7 @@
362
347
  }
363
348
  }
364
349
 
365
- :is([scale='linear'], :state(ladder)) > .sonic-meter > .sonic-meter-clip {
350
+ :is([value], :state(ladder)) > .sonic-meter > .sonic-meter-clip {
366
351
  display: none;
367
352
  }
368
353
 
@@ -388,7 +373,7 @@
388
373
  background: var(--_sonic-unlit);
389
374
  }
390
375
 
391
- .sonic-meter-level {
376
+ .sonic-meter-bar {
392
377
  background: var(--_sonic-lit);
393
378
  }
394
379
 
@@ -396,7 +381,7 @@
396
381
  background: Mark;
397
382
  }
398
383
 
399
- :state(ladder) > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-level)::after {
384
+ :state(ladder) > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-bar)::after {
400
385
  display: none;
401
386
  }
402
387
  }
@@ -40,12 +40,16 @@
40
40
  font-size: calc(var(--_sonic-number-size) * var(--_sonic-number-text-ratio));
41
41
  font-variant-numeric: tabular-nums;
42
42
  line-height: 1;
43
- touch-action: none;
43
+ touch-action: pan-x;
44
44
  cursor: ns-resize;
45
45
  border-radius: calc(var(--_sonic-number-size) * var(--_sonic-number-radius-ratio));
46
46
  box-shadow: var(--_sonic-focus-shadow);
47
47
  }
48
48
 
49
+ [press='step'] > .sonic-number {
50
+ cursor: pointer;
51
+ }
52
+
49
53
  :disabled > .sonic-number {
50
54
  color: var(--_sonic-etch);
51
55
  cursor: default;
@@ -0,0 +1,59 @@
1
+ @property --_sonic-panel-depth {
2
+ syntax: '<length>';
3
+ inherits: true;
4
+ initial-value: 2px;
5
+ }
6
+
7
+ @property --_sonic-panel-radius {
8
+ syntax: '<length>';
9
+ inherits: true;
10
+ initial-value: 12px;
11
+ }
12
+
13
+ @layer sonic {
14
+ :is(.sonic-panel, .sonic-panel-title, .sonic-panel-rule) {
15
+ --_sonic-panel-line: color-mix(in oklab, currentcolor 20%, transparent);
16
+ }
17
+
18
+ .sonic-panel {
19
+ --_sonic-panel-depth: var(--sonic-panel-depth, 0.125rem);
20
+ --_sonic-panel-radius: var(--sonic-panel-radius, 0.75rem);
21
+ --_sonic-unit: var(--_sonic-panel-depth);
22
+
23
+ background: var(--sonic-panel, rgb(255 255 255 / 3%));
24
+ border: 1px solid var(--_sonic-panel-line);
25
+ border-radius: var(--_sonic-panel-radius);
26
+ box-shadow:
27
+ inset var(--_sonic-cast-x) var(--_sonic-cast-y)
28
+ max(var(--_sonic-panel-depth), -1 * var(--_sonic-panel-depth)) rgb(255 255 255 / 7%),
29
+ inset calc(-1 * var(--_sonic-cast-x)) calc(-1 * var(--_sonic-cast-y))
30
+ max(var(--_sonic-panel-depth), -1 * var(--_sonic-panel-depth)) rgb(0 0 0 / 35%),
31
+ calc(2 * sin(var(--_sonic-light-tilt)) * max(0px, var(--_sonic-panel-depth)))
32
+ calc(2 * cos(var(--_sonic-light-tilt)) * max(0px, var(--_sonic-panel-depth)))
33
+ calc(3 * max(0px, var(--_sonic-panel-depth))) rgb(0 0 0 / 45%);
34
+ }
35
+
36
+ .sonic-panel-title {
37
+ display: flex;
38
+ gap: 0.75em;
39
+ align-items: center;
40
+ margin: 0;
41
+ white-space: nowrap;
42
+
43
+ &::before,
44
+ &::after {
45
+ flex: 1;
46
+ min-inline-size: 1em;
47
+ content: '';
48
+ border-block-start: 1px solid var(--_sonic-panel-line);
49
+ }
50
+ }
51
+
52
+ .sonic-panel-rule {
53
+ align-self: stretch;
54
+ block-size: 0;
55
+ margin: 0;
56
+ border: 0;
57
+ border-block-start: 1px solid var(--_sonic-panel-line);
58
+ }
59
+ }
@@ -0,0 +1,74 @@
1
+ @property --_sonic-ring-size {
2
+ syntax: '<length>';
3
+ inherits: true;
4
+ initial-value: 40px;
5
+ }
6
+
7
+ @layer sonic {
8
+ .sonic-ring {
9
+ --_sonic-ring-size: var(--sonic-ring-size, 2.5rem);
10
+ --_sonic-ring-ratio: var(--sonic-ring-ratio, 0.075);
11
+ --_sonic-ring-gap-ratio: var(--sonic-ring-gap-ratio, 0.05);
12
+ --_sonic-ring-start: var(--sonic-ring-start, 0deg);
13
+ --_sonic-ring-sweep: var(--sonic-ring-sweep, 360deg);
14
+ --_sonic-ring-from: clamp(0, var(--sonic-ring-from, 0), 1);
15
+ --_sonic-ring-to: clamp(0, var(--sonic-ring-to, 0), 1);
16
+
17
+ position: relative;
18
+ box-sizing: border-box;
19
+ display: inline-grid;
20
+ flex-shrink: 0;
21
+ grid-template: minmax(0, 1fr) / minmax(0, 1fr);
22
+ place-items: center;
23
+ inline-size: var(--_sonic-ring-size);
24
+ block-size: var(--_sonic-ring-size);
25
+ padding: calc(
26
+ var(--_sonic-ring-size) * (var(--_sonic-ring-ratio) + var(--_sonic-ring-gap-ratio))
27
+ );
28
+ border-radius: 50%;
29
+
30
+ &::before {
31
+ --_sonic-arc-width: calc(var(--_sonic-ring-size) * var(--_sonic-ring-ratio));
32
+ --_sonic-arc-inset: 0px;
33
+
34
+ position: absolute;
35
+ inset: 0;
36
+ pointer-events: none;
37
+ content: '';
38
+ background:
39
+ var(--_sonic-arc-shade),
40
+ conic-gradient(
41
+ from var(--_sonic-ring-start),
42
+ var(--_sonic-unlit)
43
+ calc(min(var(--_sonic-ring-from), var(--_sonic-ring-to)) * var(--_sonic-ring-sweep)),
44
+ var(--_sonic-lit) 0
45
+ calc(max(var(--_sonic-ring-from), var(--_sonic-ring-to)) * var(--_sonic-ring-sweep)),
46
+ var(--_sonic-unlit) 0 var(--_sonic-ring-sweep),
47
+ transparent 0
48
+ );
49
+ border-radius: 50%;
50
+ mask: var(--_sonic-arc-mask);
51
+ }
52
+
53
+ @media (forced-colors: active) {
54
+ &::before {
55
+ --_sonic-arc-shade: none;
56
+
57
+ forced-color-adjust: none;
58
+ }
59
+ }
60
+ }
61
+
62
+ .sonic-ring > :not(:defined),
63
+ .sonic-ring > * > .sonic-button {
64
+ --_sonic-button-size: calc(
65
+ var(--_sonic-ring-size) * (1 - 2 * (var(--_sonic-ring-ratio) + var(--_sonic-ring-gap-ratio)))
66
+ );
67
+ --_sonic-button-aspect-ratio: 1;
68
+ }
69
+
70
+ .sonic-ring > * > .sonic-button {
71
+ --_sonic-button-radius-ratio: 0.5;
72
+ --_sonic-button-face-radius-ratio: 0.5;
73
+ }
74
+ }
@@ -34,9 +34,7 @@
34
34
  --_sonic-segmented-corner: calc(
35
35
  var(--_sonic-segmented-size) * var(--_sonic-segmented-radius-ratio)
36
36
  );
37
- --_sonic-segmented-depth: calc(
38
- var(--_sonic-segmented-size) * var(--_sonic-segmented-depth-ratio)
39
- );
37
+ --_sonic-keycap-depth: calc(var(--_sonic-segmented-size) * var(--_sonic-segmented-depth-ratio));
40
38
  --_sonic-segmented-gap: calc(var(--_sonic-segmented-size) * var(--_sonic-segmented-gap-ratio));
41
39
  --_sonic-segmented-inner-corner: max(
42
40
  0px,
@@ -56,13 +54,7 @@
56
54
  box-shadow: var(--_sonic-well);
57
55
  }
58
56
 
59
- .sonic-segmented-segment {
60
- --_sonic-segmented-shift: calc(var(--_sonic-segmented-depth) / -2);
61
- --_sonic-segmented-scale: 1;
62
- --_sonic-segmented-drop: calc(1.5 * var(--_sonic-cast-x)) calc(1.5 * var(--_sonic-cast-y))
63
- calc(2 * var(--_sonic-unit)) var(--_sonic-drop-shade);
64
- --_sonic-segmented-glow: transparent;
65
-
57
+ .sonic-segmented-option {
66
58
  display: grid;
67
59
  min-inline-size: calc(var(--_sonic-segmented-size) - 2 * var(--_sonic-segmented-gap));
68
60
  padding: 0;
@@ -77,29 +69,29 @@
77
69
  transition: color 120ms ease-out;
78
70
  }
79
71
 
80
- .sonic-segmented-segment:where([data-sonic-pressed], :focus-visible:active):not(:disabled),
81
- .sonic-segmented-segment[aria-checked='true'] {
82
- --_sonic-segmented-shift: calc(var(--_sonic-segmented-depth) / 2);
83
- --_sonic-segmented-scale: var(--_sonic-segmented-press-scale);
84
- --_sonic-segmented-drop: var(--_sonic-press-drop);
72
+ .sonic-segmented-option:where([data-sonic-pressed], :focus-visible:active):not(:disabled),
73
+ .sonic-segmented-option[aria-checked='true'] {
74
+ --_sonic-keycap-shift: calc(var(--_sonic-keycap-depth) / 2);
75
+ --_sonic-keycap-scale: var(--_sonic-segmented-press-scale);
76
+ --_sonic-keycap-drop: var(--_sonic-press-drop);
85
77
  }
86
78
 
87
- .sonic-segmented-segment[aria-checked='true'] {
88
- --_sonic-segmented-glow: color-mix(in oklab, var(--_sonic-lit) 22%, transparent);
79
+ .sonic-segmented-option[aria-checked='true'] {
80
+ --_sonic-keycap-glow: color-mix(in oklab, var(--_sonic-lit) 22%, transparent);
89
81
 
90
82
  color: var(--_sonic-lit);
91
83
  background: var(--_sonic-lit);
92
84
  box-shadow: var(--_sonic-well);
93
85
  }
94
86
 
95
- .sonic-segmented-segment:disabled {
87
+ .sonic-segmented-option:disabled {
96
88
  --_sonic-lit: var(--_sonic-lit-disabled);
97
89
 
98
90
  color: var(--_sonic-etch);
99
91
  cursor: default;
100
92
  }
101
93
 
102
- .sonic-segmented-segment:not([aria-checked='true'], :disabled):is(
94
+ .sonic-segmented-option:not([aria-checked='true'], :disabled):is(
103
95
  :focus-visible,
104
96
  :active,
105
97
  [data-sonic-pressed]
@@ -108,41 +100,23 @@
108
100
  }
109
101
 
110
102
  @media (hover: hover) {
111
- .sonic-segmented-segment:not([aria-checked='true'], :disabled):hover {
103
+ .sonic-segmented-option:not([aria-checked='true'], :disabled):hover {
112
104
  color: var(--_sonic-ink-lift);
113
105
  }
114
106
  }
115
107
 
116
- /* In flow, so a long label widens its segment rather than spilling over the next */
117
108
  .sonic-segmented-cap {
109
+ --_sonic-keycap-corner: var(--_sonic-segmented-inner-corner);
110
+ --_sonic-keycap-bevel: calc(var(--_sonic-segmented-size) * var(--_sonic-segmented-bevel-ratio));
111
+ --_sonic-keycap-face-corner: max(
112
+ 0px,
113
+ var(--_sonic-segmented-inner-corner) - var(--_sonic-keycap-bevel)
114
+ );
115
+
118
116
  position: relative;
119
- display: grid;
120
- place-items: center;
121
117
  padding-inline: calc(var(--_sonic-segmented-size) * 0.25);
122
- background: var(--_sonic-skirt);
123
- border-radius: var(--_sonic-segmented-inner-corner);
124
- box-shadow: var(--_sonic-segmented-drop), var(--_sonic-rim), var(--_sonic-focus-shadow);
125
- scale: var(--_sonic-segmented-scale);
126
- translate: 0 var(--_sonic-segmented-shift);
127
- transition: var(--_sonic-press-transition);
128
-
129
- &::before {
130
- position: absolute;
131
- inset: calc(var(--_sonic-segmented-size) * var(--_sonic-segmented-bevel-ratio));
132
- content: '';
133
- background:
134
- radial-gradient(closest-side, var(--_sonic-segmented-glow), transparent),
135
- var(--_sonic-sheen), var(--_sonic-face);
136
- border-radius: max(
137
- 0px,
138
- var(--_sonic-segmented-inner-corner) - var(--_sonic-segmented-size) *
139
- var(--_sonic-segmented-bevel-ratio)
140
- );
141
- box-shadow: var(--_sonic-face-shadow);
142
- }
143
118
 
144
119
  & > * {
145
- position: relative;
146
120
  filter: var(--_sonic-engraving);
147
121
  }
148
122
 
@@ -152,8 +126,7 @@
152
126
  }
153
127
  }
154
128
 
155
- /* Engraving under the glow keeps a lit label's edge */
156
- .sonic-segmented-segment[aria-checked='true'] .sonic-segmented-cap > * {
129
+ .sonic-segmented-option[aria-checked='true'] .sonic-segmented-cap > * {
157
130
  filter: var(--_sonic-engraving)
158
131
  drop-shadow(0 0 var(--_sonic-unit) color-mix(in oklab, var(--_sonic-lit) 35%, transparent));
159
132
  }
@@ -163,7 +136,7 @@
163
136
  filter: none;
164
137
  }
165
138
 
166
- .sonic-segmented-segment[aria-checked='true'] {
139
+ .sonic-segmented-option[aria-checked='true'] {
167
140
  --_sonic-skirt: var(--_sonic-lit);
168
141
  --_sonic-face: var(--_sonic-lit);
169
142
  --_sonic-ink: HighlightText;