@xsynaptic/sonic-ui 0.6.0 → 0.8.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 (118) hide show
  1. package/README.md +4 -0
  2. package/dist/default/define/spectrum.js +7 -0
  3. package/dist/default/define.js +1 -0
  4. package/dist/default/elements/button.js +33 -4
  5. package/dist/default/elements/dial.js +5 -1
  6. package/dist/default/elements/display-element.js +77 -0
  7. package/dist/default/elements/envelope.js +15 -3
  8. package/dist/default/elements/meter.js +1 -1
  9. package/dist/default/elements/radio-group.js +3 -2
  10. package/dist/default/elements/readout-claim.js +0 -29
  11. package/dist/default/elements/scale.js +43 -0
  12. package/dist/default/elements/slider.js +82 -3
  13. package/dist/default/elements/sonic-element.js +2 -67
  14. package/dist/default/elements/spectrum.js +230 -0
  15. package/dist/default/elements/switch.js +1 -1
  16. package/dist/default/elements/value-element.js +81 -91
  17. package/dist/default/elements/wave-element.js +59 -9
  18. package/dist/default/elements/waveform.js +56 -10
  19. package/dist/default/elements/wavestrip.js +45 -21
  20. package/dist/default/elements/xy.js +3 -2
  21. package/dist/default/index.js +2 -1
  22. package/dist/default/lib/canvas-surface.js +7 -4
  23. package/dist/default/lib/frame-timeline.js +2 -2
  24. package/dist/default/lib/hover-preview.js +46 -0
  25. package/dist/default/lib/marker-rider.js +7 -4
  26. package/dist/default/lib/mirror-children.js +64 -0
  27. package/dist/default/lib/owned-control.js +10 -0
  28. package/dist/default/lib/pointer-drag.js +7 -2
  29. package/dist/default/lib/spectrum-columns.js +74 -0
  30. package/dist/default/lib/spectrum-levels.js +55 -0
  31. package/dist/default/lib/strip-scene.js +12 -1
  32. package/dist/default/lib/time-regions.js +8 -1
  33. package/dist/dev/define/spectrum.d.ts +2 -0
  34. package/dist/dev/define/spectrum.js +8 -0
  35. package/dist/dev/define/spectrum.js.map +1 -0
  36. package/dist/dev/define.d.ts +3 -1
  37. package/dist/dev/define.js +1 -0
  38. package/dist/dev/elements/button.d.ts +2 -0
  39. package/dist/dev/elements/button.js +33 -4
  40. package/dist/dev/elements/button.js.map +1 -1
  41. package/dist/dev/elements/dial.js +5 -1
  42. package/dist/dev/elements/dial.js.map +1 -1
  43. package/dist/dev/elements/display-element.d.ts +29 -0
  44. package/dist/dev/elements/display-element.js +78 -0
  45. package/dist/dev/elements/display-element.js.map +1 -0
  46. package/dist/dev/elements/envelope.js +15 -3
  47. package/dist/dev/elements/envelope.js.map +1 -1
  48. package/dist/dev/elements/meter.js +1 -1
  49. package/dist/dev/elements/radio-group.js +3 -2
  50. package/dist/dev/elements/radio-group.js.map +1 -1
  51. package/dist/dev/elements/readout-claim.js +0 -29
  52. package/dist/dev/elements/readout-claim.js.map +1 -1
  53. package/dist/dev/elements/scale.js +44 -0
  54. package/dist/dev/elements/scale.js.map +1 -0
  55. package/dist/dev/elements/slider.d.ts +9 -0
  56. package/dist/dev/elements/slider.js +82 -3
  57. package/dist/dev/elements/slider.js.map +1 -1
  58. package/dist/dev/elements/sonic-element.d.ts +0 -8
  59. package/dist/dev/elements/sonic-element.js +3 -90
  60. package/dist/dev/elements/sonic-element.js.map +1 -1
  61. package/dist/dev/elements/spectrum.d.ts +59 -0
  62. package/dist/dev/elements/spectrum.js +231 -0
  63. package/dist/dev/elements/spectrum.js.map +1 -0
  64. package/dist/dev/elements/switch.js +1 -1
  65. package/dist/dev/elements/value-element.d.ts +8 -6
  66. package/dist/dev/elements/value-element.js +81 -91
  67. package/dist/dev/elements/value-element.js.map +1 -1
  68. package/dist/dev/elements/wave-element.d.ts +8 -2
  69. package/dist/dev/elements/wave-element.js +59 -9
  70. package/dist/dev/elements/wave-element.js.map +1 -1
  71. package/dist/dev/elements/waveform.d.ts +12 -4
  72. package/dist/dev/elements/waveform.js +56 -10
  73. package/dist/dev/elements/waveform.js.map +1 -1
  74. package/dist/dev/elements/wavestrip.d.ts +7 -0
  75. package/dist/dev/elements/wavestrip.js +45 -21
  76. package/dist/dev/elements/wavestrip.js.map +1 -1
  77. package/dist/dev/elements/xy.js +3 -2
  78. package/dist/dev/elements/xy.js.map +1 -1
  79. package/dist/dev/index.d.ts +4 -1
  80. package/dist/dev/index.js +2 -1
  81. package/dist/dev/lib/canvas-surface.d.ts +4 -3
  82. package/dist/dev/lib/canvas-surface.js +7 -4
  83. package/dist/dev/lib/canvas-surface.js.map +1 -1
  84. package/dist/dev/lib/frame-timeline.js +2 -2
  85. package/dist/dev/lib/frame-timeline.js.map +1 -1
  86. package/dist/dev/lib/hover-preview.js +47 -0
  87. package/dist/dev/lib/hover-preview.js.map +1 -0
  88. package/dist/dev/lib/marker-rider.js +7 -4
  89. package/dist/dev/lib/marker-rider.js.map +1 -1
  90. package/dist/dev/lib/mirror-children.js +80 -0
  91. package/dist/dev/lib/mirror-children.js.map +1 -0
  92. package/dist/dev/lib/owned-control.js +23 -0
  93. package/dist/dev/lib/owned-control.js.map +1 -0
  94. package/dist/dev/lib/pointer-drag.js +7 -2
  95. package/dist/dev/lib/pointer-drag.js.map +1 -1
  96. package/dist/dev/lib/spectrum-columns.js +75 -0
  97. package/dist/dev/lib/spectrum-columns.js.map +1 -0
  98. package/dist/dev/lib/spectrum-levels.js +56 -0
  99. package/dist/dev/lib/spectrum-levels.js.map +1 -0
  100. package/dist/dev/lib/strip-scene.js +12 -1
  101. package/dist/dev/lib/strip-scene.js.map +1 -1
  102. package/dist/dev/lib/time-regions.js +8 -1
  103. package/dist/dev/lib/time-regions.js.map +1 -1
  104. package/dist/skins/flat.css +2 -1
  105. package/dist/styles/button.css +28 -1
  106. package/dist/styles/controls.css +1 -0
  107. package/dist/styles/envelope.css +30 -30
  108. package/dist/styles/led.css +18 -2
  109. package/dist/styles/material.css +90 -29
  110. package/dist/styles/meter.css +22 -18
  111. package/dist/styles/panel.css +2 -1
  112. package/dist/styles/slider.css +42 -5
  113. package/dist/styles/spectrum.css +105 -0
  114. package/dist/styles/switch.css +10 -7
  115. package/dist/styles/waveform.css +38 -16
  116. package/dist/styles/wavestrip.css +22 -4
  117. package/dist/styles/xy.css +14 -30
  118. package/package.json +2 -1
@@ -50,6 +50,25 @@
50
50
  clip-path: inset(calc(-1 * var(--_sonic-envelope-inset)));
51
51
  }
52
52
 
53
+ .sonic-envelope-bracket {
54
+ --_sonic-point-size: calc(
55
+ 2 * var(--_sonic-envelope-size) * var(--_sonic-envelope-handle-ratio)
56
+ );
57
+ --_sonic-bracket-size: var(--_sonic-point-size);
58
+
59
+ position: absolute;
60
+ inset: 0;
61
+ overflow: clip;
62
+ pointer-events: none;
63
+ border-radius: inherit;
64
+
65
+ &[data-sonic-part='curve'] {
66
+ --_sonic-point-size: calc(
67
+ 2 * var(--_sonic-envelope-size) * var(--_sonic-envelope-curve-ratio)
68
+ );
69
+ }
70
+ }
71
+
53
72
  .sonic-envelope-fill {
54
73
  fill: color-mix(in oklab, var(--_sonic-lit) 18%, transparent);
55
74
  }
@@ -69,15 +88,8 @@
69
88
  vector-effect: non-scaling-stroke;
70
89
  }
71
90
 
72
- :is(.sonic-envelope-handle, .sonic-envelope-curve) {
73
- --_sonic-point-ring: var(--_sonic-lit);
74
- --_sonic-point-core: var(--_sonic-lit);
75
- --_sonic-point-lift: color-mix(in oklab, var(--_sonic-lit) 85%, #fff);
76
- --_sonic-point-edge: max(1px, var(--_sonic-point-stroke, 0px));
77
- --_sonic-point-halo: transparent;
78
- --_sonic-point-bracket: transparent;
79
- --_sonic-point-bracket-scale: 0.6;
80
-
91
+ :is(.sonic-envelope-handle, .sonic-envelope-curve),
92
+ .sonic-envelope-bracket::before {
81
93
  position: absolute;
82
94
  inset: auto auto
83
95
  calc(
@@ -88,6 +100,15 @@
88
100
  var(--_sonic-envelope-inset) + var(--_sonic-envelope-x, 0) *
89
101
  (100cqi - 2 * var(--_sonic-envelope-inset)) - var(--_sonic-point-size) / 2
90
102
  );
103
+ }
104
+
105
+ :is(.sonic-envelope-handle, .sonic-envelope-curve) {
106
+ --_sonic-point-ring: var(--_sonic-lit);
107
+ --_sonic-point-core: var(--_sonic-lit);
108
+ --_sonic-point-lift: color-mix(in oklab, var(--_sonic-lit) 85%, #fff);
109
+ --_sonic-point-edge: max(1px, var(--_sonic-point-stroke, 0px));
110
+ --_sonic-point-halo: transparent;
111
+
91
112
  z-index: 1;
92
113
  box-sizing: border-box;
93
114
  inline-size: var(--_sonic-point-size);
@@ -104,21 +125,6 @@
104
125
  background-color 120ms ease-out,
105
126
  border-color 120ms ease-out,
106
127
  box-shadow 120ms ease-out;
107
-
108
- &::after {
109
- position: absolute;
110
- inset: calc(-0.4 * var(--_sonic-point-size) - 2 * var(--_sonic-point-edge));
111
- pointer-events: none;
112
- content: '';
113
- border: var(--_sonic-point-edge) solid var(--_sonic-point-bracket);
114
- border-block-start-color: transparent;
115
- border-radius: 50%;
116
- rotate: 45deg;
117
- scale: var(--_sonic-point-bracket-scale);
118
- transition:
119
- border-color 120ms ease-out,
120
- scale 120ms ease-out;
121
- }
122
128
  }
123
129
 
124
130
  .sonic-envelope-handle {
@@ -167,12 +173,6 @@
167
173
  var(--_sonic-lit) calc(50% * var(--_sonic-relief)),
168
174
  transparent
169
175
  );
170
- --_sonic-point-bracket: color-mix(
171
- in oklab,
172
- var(--_sonic-lit) calc(100% * (1 - var(--_sonic-relief))),
173
- transparent
174
- );
175
- --_sonic-point-bracket-scale: 1;
176
176
  }
177
177
 
178
178
  @media (forced-colors: active) {
@@ -7,10 +7,26 @@
7
7
  @layer sonic {
8
8
  .sonic-led {
9
9
  --_sonic-led-size: var(--sonic-led-size, 0.5rem);
10
- --_sonic-led-lens-ratio: var(--sonic-led-lens-ratio, 0.625);
10
+ --_sonic-led-lens-ratio: var(--sonic-led-lens-ratio, calc(0.8 - 0.175 * var(--_sonic-relief)));
11
11
  --_sonic-lit-alt: var(--sonic-lit-alt, oklch(79% 0.2 150deg));
12
12
  --_sonic-unit: calc(var(--_sonic-led-size) / 8);
13
- --_sonic-led-bezel: var(--sonic-bezel, color-mix(in oklab, var(--_sonic-unlit) 55%, #000));
13
+ --_sonic-led-modelled: calc(100% * var(--_sonic-relief));
14
+ --_sonic-led-bezel: var(
15
+ --sonic-bezel,
16
+ color-mix(
17
+ in oklab,
18
+ color-mix(in oklab, var(--_sonic-unlit) 55%, #000) var(--_sonic-led-modelled),
19
+ transparent
20
+ )
21
+ );
22
+ --_sonic-lens-glass: var(
23
+ --sonic-lens,
24
+ color-mix(
25
+ in oklab,
26
+ color-mix(in oklab, var(--_sonic-unlit) 60%, #000) var(--_sonic-led-modelled),
27
+ color-mix(in oklab, currentcolor 30%, transparent)
28
+ )
29
+ );
14
30
 
15
31
  position: relative;
16
32
  display: inline-block;
@@ -33,6 +33,7 @@
33
33
  .sonic-segmented,
34
34
  .sonic-slider,
35
35
  .sonic-slider-readout,
36
+ .sonic-spectrum,
36
37
  .sonic-waveform,
37
38
  .sonic-waveform-readout,
38
39
  .sonic-wavestrip,
@@ -58,6 +59,7 @@
58
59
  .sonic-ring,
59
60
  .sonic-segmented-option,
60
61
  .sonic-slider,
62
+ .sonic-spectrum,
61
63
  .sonic-waveform,
62
64
  .sonic-wavestrip,
63
65
  .sonic-xy
@@ -92,6 +94,9 @@
92
94
  );
93
95
  --_sonic-lens-glass: var(--sonic-lens, color-mix(in oklab, var(--_sonic-unlit) 60%, #000));
94
96
  --_sonic-lens: var(--_sonic-lens-glint), var(--_sonic-lens-glass);
97
+ }
98
+
99
+ :is(.sonic-led, .sonic-meter, .sonic-spectrum) {
95
100
  --_sonic-hot: var(--sonic-hot, oklch(70.5% 0.187 48deg));
96
101
  --_sonic-clip: var(--sonic-clip, oklch(63.7% 0.208 25deg));
97
102
  }
@@ -150,6 +155,10 @@
150
155
  color-mix(in oklab, var(--_sonic-focus) 60%, transparent);
151
156
  }
152
157
 
158
+ :is(.sonic-number, .sonic-waveform, .sonic-wavestrip, .sonic-xy) {
159
+ --_sonic-ink: var(--_sonic-glass-text);
160
+ }
161
+
153
162
  :is(.sonic-dial, .sonic-number, .sonic-slider, .sonic-waveform, .sonic-wavestrip) {
154
163
  --_sonic-detent-zone: var(--sonic-detent-zone, 8px);
155
164
  }
@@ -172,6 +181,7 @@
172
181
  .sonic-number,
173
182
  .sonic-screen,
174
183
  .sonic-slider-readout,
184
+ .sonic-spectrum,
175
185
  .sonic-waveform,
176
186
  .sonic-waveform-readout,
177
187
  .sonic-wavestrip,
@@ -179,18 +189,42 @@
179
189
  .sonic-xy,
180
190
  .sonic-xy-readout
181
191
  ) {
182
- --_sonic-glass: var(--sonic-glass, color-mix(in oklab, var(--_sonic-unlit) 45%, #000));
192
+ --_sonic-glass-slab: color-mix(in oklab, var(--_sonic-unlit) 45%, #000);
193
+ --_sonic-glass-base: var(
194
+ --sonic-glass,
195
+ color-mix(
196
+ in oklab,
197
+ var(--_sonic-glass-slab) calc(100% * var(--_sonic-relief)),
198
+ light-dark(oklch(97% 0.003 286deg), var(--_sonic-glass-slab))
199
+ )
200
+ );
201
+ --_sonic-glass: var(--_sonic-glass-base);
183
202
  --_sonic-glass-fill: radial-gradient(
184
203
  closest-side,
185
- color-mix(in oklab, var(--_sonic-glass) 88%, #fff),
204
+ color-mix(
205
+ in oklab,
206
+ var(--_sonic-glass) calc(100% - 12% * var(--_sonic-glass-depth, var(--_sonic-relief))),
207
+ #fff
208
+ ),
186
209
  var(--_sonic-glass)
187
210
  )
188
211
  var(--_sonic-glass);
189
212
  --_sonic-glass-text: var(
190
213
  --sonic-glass-text,
191
- color-mix(in oklab, var(--_sonic-glass) 20%, #fff)
214
+ color-mix(
215
+ in oklab,
216
+ var(--_sonic-glass) 20%,
217
+ oklch(from var(--_sonic-glass) clamp(0, (0.6 - l) * 1000, 1) 0 0deg / 100%)
218
+ )
219
+ );
220
+
221
+ /* Invalid with the token unset, so the default takes over */
222
+ --_sonic-glass-edge-set: 1px solid var(--sonic-glass-edge);
223
+ --_sonic-glass-edge: var(
224
+ --_sonic-glass-edge-set,
225
+ calc(1px * (1 - var(--_sonic-relief))) solid
226
+ color-mix(in oklab, currentcolor 35%, transparent)
192
227
  );
193
- --_sonic-glass-edge: 1px solid var(--sonic-glass-edge);
194
228
 
195
229
  /* Glass is forced to Canvas like the page, so only a border shows its edge */
196
230
  @media (forced-colors: active) {
@@ -199,7 +233,15 @@
199
233
  }
200
234
 
201
235
  /* A definite cell, so percentage-sized content fills the glass; a canvas sized to its own box would feed back */
202
- :is(.sonic-envelope, .sonic-number, .sonic-screen, .sonic-waveform, .sonic-wavestrip, .sonic-xy) {
236
+ :is(
237
+ .sonic-envelope,
238
+ .sonic-number,
239
+ .sonic-screen,
240
+ .sonic-spectrum,
241
+ .sonic-waveform,
242
+ .sonic-wavestrip,
243
+ .sonic-xy
244
+ ) {
203
245
  --_sonic-glass-depth: var(--sonic-glass-depth, var(--_sonic-relief));
204
246
  --_sonic-glass-texture: var(--sonic-glass-texture, var(--_sonic-relief));
205
247
  --_sonic-glass-pitch: max(2px, round(2 * var(--_sonic-unit), 1px));
@@ -238,7 +280,7 @@
238
280
  ),
239
281
  repeating-linear-gradient(
240
282
  to bottom,
241
- rgb(0 0 0 / calc(0.04 * var(--_sonic-glass-texture))) 0
283
+ rgb(0 0 0 / calc(0.025 * var(--_sonic-glass-texture))) 0
242
284
  calc(var(--_sonic-glass-pitch) / 2),
243
285
  transparent 0 var(--_sonic-glass-pitch)
244
286
  );
@@ -279,31 +321,13 @@
279
321
  }
280
322
  }
281
323
 
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
- }
298
- }
299
- }
300
-
301
324
  :is(
302
325
  .sonic-envelope,
303
326
  .sonic-button,
304
327
  .sonic-number,
305
328
  .sonic-screen,
306
329
  .sonic-segmented,
330
+ .sonic-spectrum,
307
331
  .sonic-waveform,
308
332
  .sonic-wavestrip,
309
333
  .sonic-xy
@@ -382,7 +406,11 @@
382
406
  place-items: center;
383
407
  background: var(--_sonic-skirt);
384
408
  border-radius: var(--_sonic-keycap-corner);
385
- box-shadow: var(--_sonic-keycap-drop), var(--_sonic-rim), var(--_sonic-focus-shadow);
409
+ box-shadow:
410
+ var(--_sonic-keycap-drop),
411
+ var(--_sonic-rim),
412
+ 0 0 0 max(1px, 0.75 * var(--_sonic-unit)) var(--_sonic-blank-edge, transparent),
413
+ var(--_sonic-focus-shadow);
386
414
  scale: var(--_sonic-keycap-scale);
387
415
  translate: 0 var(--_sonic-keycap-shift);
388
416
  transition: var(--_sonic-press-transition);
@@ -403,6 +431,36 @@
403
431
  }
404
432
  }
405
433
 
434
+ .sonic-xy-bracket,
435
+ .sonic-envelope-bracket::before {
436
+ box-sizing: border-box;
437
+ inline-size: var(--_sonic-bracket-size);
438
+ block-size: var(--_sonic-bracket-size);
439
+ pointer-events: none;
440
+ content: '';
441
+ border: max(1px, 0.06 * var(--_sonic-bracket-size)) solid
442
+ color-mix(in oklab, var(--_sonic-glass-text) 45%, transparent);
443
+ border-radius: 50%;
444
+ opacity: 0;
445
+ mask: conic-gradient(
446
+ from 10deg,
447
+ #000 0 70deg,
448
+ transparent 0 180deg,
449
+ #000 0 250deg,
450
+ transparent 0
451
+ );
452
+ scale: 0.6;
453
+ transition:
454
+ opacity 120ms ease-out,
455
+ scale 120ms ease-out;
456
+ }
457
+
458
+ :state(dragging) > * > .sonic-xy-bracket,
459
+ :state(dragging) > * > .sonic-envelope-bracket::before {
460
+ opacity: calc(1 - var(--_sonic-relief));
461
+ scale: 1;
462
+ }
463
+
406
464
  :is(.sonic-meter, .sonic-slider) {
407
465
  --_sonic-groove:
408
466
  inset var(--_sonic-cast-x) var(--_sonic-cast-y) calc(0.75 * var(--_sonic-unit))
@@ -455,6 +513,7 @@
455
513
  .sonic-xy-readout
456
514
  ) {
457
515
  --_sonic-unit: calc(var(--_sonic-readout-size) / 32);
516
+ --_sonic-glass: var(--sonic-readout-glass, var(--_sonic-glass-base));
458
517
 
459
518
  box-sizing: border-box;
460
519
  place-items: center;
@@ -470,7 +529,8 @@
470
529
  font-size: calc(0.5 * var(--_sonic-readout-size));
471
530
  font-variant-numeric: tabular-nums;
472
531
  line-height: 1;
473
- color: var(--_sonic-glass-text);
532
+ color: var(--sonic-readout-text, var(--_sonic-glass-text));
533
+ white-space: nowrap;
474
534
  pointer-events: none;
475
535
  cursor: default;
476
536
  user-select: none;
@@ -567,13 +627,14 @@
567
627
  }
568
628
 
569
629
  & > .sonic-scale-tick {
570
- background: var(--_sonic-etch);
630
+ background: var(--sonic-scale, var(--_sonic-etch));
571
631
  }
572
632
  }
573
633
 
574
634
  @media (forced-colors: active) {
575
- .sonic-scale-tick {
635
+ :is(.sonic-dial-scale, .sonic-slider-scale) > .sonic-scale-tick {
576
636
  forced-color-adjust: none;
637
+ background: var(--_sonic-etch);
577
638
  }
578
639
 
579
640
  :is(
@@ -5,7 +5,7 @@
5
5
  }
6
6
 
7
7
  @property --_sonic-meter-length {
8
- syntax: '<length>';
8
+ syntax: '<length-percentage>';
9
9
  inherits: true;
10
10
  initial-value: 128px;
11
11
  }
@@ -55,17 +55,12 @@
55
55
  --_sonic-meter-segment-radius: calc(
56
56
  var(--_sonic-meter-segment) * var(--_sonic-meter-segment-radius-ratio)
57
57
  );
58
- --_sonic-meter-segments: round(
59
- down,
60
- var(--_sonic-meter-length) - 2 * var(--_sonic-meter-inset) - var(--_sonic-meter-clip-space) +
61
- var(--_sonic-meter-gap),
62
- var(--_sonic-meter-pitch)
63
- );
64
58
 
65
59
  position: relative;
66
60
  flex-shrink: 0;
67
61
  inline-size: var(--_sonic-meter-size);
68
62
  block-size: var(--_sonic-meter-length);
63
+ container-type: size;
69
64
  background: var(--sonic-bezel, color-mix(in oklab, var(--_sonic-unlit) 55%, #000));
70
65
  border-radius: calc(var(--_sonic-meter-size) * var(--_sonic-meter-radius-ratio));
71
66
 
@@ -91,21 +86,18 @@
91
86
  }
92
87
 
93
88
  :state(ladder) > .sonic-meter {
94
- --_sonic-meter-pitch: calc(
95
- (var(--_sonic-meter-length) - 2 * var(--_sonic-meter-inset)) / var(--_sonic-meter-count, 1)
96
- );
97
89
  --_sonic-meter-gap: 0px;
98
- --_sonic-meter-segments: calc(var(--_sonic-meter-length) - 2 * var(--_sonic-meter-inset));
99
- --_sonic-meter-ladder-radius: calc(
100
- min(
101
- var(--_sonic-meter-lens),
102
- var(--_sonic-meter-pitch) * (1 - var(--_sonic-meter-gap-ratio))
103
- ) /
104
- 2
105
- );
106
90
  }
107
91
 
92
+ /* A percentage length means the parent only on the meter's own box; its parts measure the box */
108
93
  :is(.sonic-meter-segments, .sonic-meter-bar) {
94
+ --_sonic-meter-length: 100cqb;
95
+ --_sonic-meter-segments: round(
96
+ down,
97
+ var(--_sonic-meter-length) - 2 * var(--_sonic-meter-inset) - var(--_sonic-meter-clip-space) +
98
+ var(--_sonic-meter-gap),
99
+ var(--_sonic-meter-pitch)
100
+ );
109
101
  --_sonic-meter-span: calc(var(--_sonic-meter-max, 0) - var(--_sonic-meter-min, -60));
110
102
  --_sonic-meter-hot-at: round(
111
103
  clamp(
@@ -177,6 +169,17 @@
177
169
  }
178
170
 
179
171
  :state(ladder) > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-bar) {
172
+ --_sonic-meter-pitch: calc(
173
+ (var(--_sonic-meter-length) - 2 * var(--_sonic-meter-inset)) / var(--_sonic-meter-count, 1)
174
+ );
175
+ --_sonic-meter-segments: calc(var(--_sonic-meter-length) - 2 * var(--_sonic-meter-inset));
176
+ --_sonic-meter-ladder-radius: calc(
177
+ min(
178
+ var(--_sonic-meter-lens),
179
+ var(--_sonic-meter-pitch) * (1 - var(--_sonic-meter-gap-ratio))
180
+ ) /
181
+ 2
182
+ );
180
183
  --_sonic-meter-hot-at: calc(var(--_sonic-meter-hot-segments, 0) * var(--_sonic-meter-pitch));
181
184
  --_sonic-meter-clip-at: calc(var(--_sonic-meter-clip-segments, 0) * var(--_sonic-meter-pitch));
182
185
  --_sonic-meter-segment-mask: radial-gradient(
@@ -193,6 +196,7 @@
193
196
  }
194
197
 
195
198
  [orientation='horizontal'] > .sonic-meter > :is(.sonic-meter-segments, .sonic-meter-bar) {
199
+ --_sonic-meter-length: 100cqi;
196
200
  --_sonic-meter-segment-mask:
197
201
  linear-gradient(to right, #000 var(--_sonic-meter-segment), transparent 0) 0
198
202
  var(--_sonic-meter-segment-radius) / var(--_sonic-meter-pitch)
@@ -20,7 +20,8 @@
20
20
  --_sonic-panel-radius: var(--sonic-panel-radius, 0.75rem);
21
21
  --_sonic-unit: var(--_sonic-panel-depth);
22
22
 
23
- background: var(--sonic-panel, rgb(255 255 255 / 3%));
23
+ color: var(--sonic-panel-text, inherit);
24
+ background: var(--sonic-panel, color-mix(in oklab, currentcolor 3%, transparent));
24
25
  border: 1px solid var(--_sonic-panel-line);
25
26
  border-radius: var(--_sonic-panel-radius);
26
27
  box-shadow:
@@ -10,6 +10,12 @@
10
10
  initial-value: 128px;
11
11
  }
12
12
 
13
+ @property --_sonic-slider-groove-ratio {
14
+ syntax: '<number>';
15
+ inherits: true;
16
+ initial-value: 0.15;
17
+ }
18
+
13
19
  @property --_sonic-slider-value {
14
20
  syntax: '<number>';
15
21
  inherits: true;
@@ -56,6 +62,7 @@
56
62
  --sonic-buffered,
57
63
  color-mix(in oklab, var(--_sonic-ink) 18%, var(--_sonic-unlit))
58
64
  );
65
+ --_sonic-slider-scrub: var(--sonic-scrub, color-mix(in oklab, var(--_sonic-lit) 55%, #fff));
59
66
  --_sonic-slider-toward: to right;
60
67
  --_sonic-slider-across: to bottom;
61
68
  --_sonic-slider-cursor: ew-resize;
@@ -69,9 +76,32 @@
69
76
  inline-size: var(--_sonic-slider-length);
70
77
  block-size: var(--_sonic-slider-size);
71
78
  container-type: size;
72
- touch-action: pan-y;
79
+ touch-action: var(--sonic-touch-action, pan-y);
73
80
  cursor: var(--_sonic-slider-cursor);
74
81
  user-select: none;
82
+ transition: --_sonic-slider-groove-ratio 120ms ease-out;
83
+
84
+ @media (prefers-reduced-motion: reduce) {
85
+ transition: none;
86
+ }
87
+ }
88
+
89
+ :where(:not(:disabled)) > .sonic-slider:focus-visible,
90
+ :state(dragging) > .sonic-slider {
91
+ --_sonic-slider-groove-ratio: var(
92
+ --sonic-slider-groove-hover-ratio,
93
+ var(--sonic-slider-groove-ratio, 0.15)
94
+ );
95
+ }
96
+
97
+ @media (hover: hover) {
98
+ /* fallow-ignore-next-line code-duplication -- `:hover` and `:focus-visible` split by `(hover: hover)` */
99
+ :where(:not(:disabled)) > .sonic-slider:hover {
100
+ --_sonic-slider-groove-ratio: var(
101
+ --sonic-slider-groove-hover-ratio,
102
+ var(--sonic-slider-groove-ratio, 0.15)
103
+ );
104
+ }
75
105
  }
76
106
 
77
107
  [orientation='vertical'] > .sonic-slider {
@@ -82,7 +112,7 @@
82
112
 
83
113
  inline-size: var(--_sonic-slider-size);
84
114
  block-size: var(--_sonic-slider-length);
85
- touch-action: pan-x;
115
+ touch-action: var(--sonic-touch-action, pan-x);
86
116
  }
87
117
 
88
118
  :state(dragging) > .sonic-slider {
@@ -225,14 +255,16 @@
225
255
  }
226
256
 
227
257
  .sonic-slider-groove {
228
- --_sonic-slider-lit-low: min(var(--_sonic-slider-origin, 0), var(--_sonic-slider-value, 0));
229
- --_sonic-slider-lit-high: max(var(--_sonic-slider-origin, 0), var(--_sonic-slider-value, 0));
258
+ --_sonic-slider-lit-to: var(--_sonic-slider-played, var(--_sonic-slider-value, 0));
259
+ --_sonic-slider-lit-low: min(var(--_sonic-slider-origin, 0), var(--_sonic-slider-lit-to));
260
+ --_sonic-slider-lit-high: max(var(--_sonic-slider-origin, 0), var(--_sonic-slider-lit-to));
230
261
 
231
262
  position: absolute;
232
263
  inset: calc(50% + var(--_sonic-slider-scale-band) / 2 - var(--_sonic-slider-groove) / 2)
233
264
  calc((var(--_sonic-slider-cap) - var(--_sonic-slider-groove)) / 2)
234
265
  calc(50% - var(--_sonic-slider-scale-band) / 2 - var(--_sonic-slider-groove) / 2);
235
266
  background:
267
+ var(--_sonic-slider-scrub-region, none),
236
268
  linear-gradient(
237
269
  var(--_sonic-slider-toward),
238
270
  transparent
@@ -430,7 +462,11 @@
430
462
 
431
463
  /* Bare `block-start` spans the viewport; `translate` belongs to the open transition */
432
464
  :not([orientation='vertical']) > .sonic-slider > .sonic-slider-readout {
433
- --_sonic-slider-readout-at: calc(var(--_sonic-slider-cap) / 2 + var(--_sonic-slider-offset));
465
+ --_sonic-slider-readout-at: calc(
466
+ var(--_sonic-slider-cap) / 2 +
467
+ var(--_sonic-slider-readout-value, var(--_sonic-slider-value, 0)) *
468
+ var(--_sonic-slider-travel)
469
+ );
434
470
 
435
471
  inset-inline: var(--_sonic-slider-readout-at) calc(100cqi - var(--_sonic-slider-readout-at));
436
472
  justify-self: center;
@@ -454,6 +490,7 @@
454
490
 
455
491
  .sonic-slider {
456
492
  --_sonic-slider-buffered: color-mix(in srgb, CanvasText 50%, GrayText);
493
+ --_sonic-slider-scrub: CanvasText;
457
494
  }
458
495
 
459
496
  .sonic-slider-groove {
@@ -0,0 +1,105 @@
1
+ @property --_sonic-spectrum-size {
2
+ syntax: '<length>';
3
+ inherits: true;
4
+ initial-value: 96px;
5
+ }
6
+
7
+ @property --_sonic-spectrum-length {
8
+ syntax: '<length-percentage>';
9
+ inherits: true;
10
+ initial-value: 320px;
11
+ }
12
+
13
+ @property --_sonic-spectrum-lit {
14
+ syntax: '<color>';
15
+ inherits: true;
16
+ initial-value: rgb(245 158 10);
17
+ }
18
+
19
+ @property --_sonic-spectrum-hot {
20
+ syntax: '<color>';
21
+ inherits: true;
22
+ initial-value: rgb(250 115 20);
23
+ }
24
+
25
+ @property --_sonic-spectrum-clip {
26
+ syntax: '<color>';
27
+ inherits: true;
28
+ initial-value: rgb(240 70 70);
29
+ }
30
+
31
+ @property --_sonic-spectrum-grid {
32
+ syntax: '<color>';
33
+ inherits: true;
34
+ initial-value: rgb(96 96 104);
35
+ }
36
+
37
+ @property --_sonic-spectrum-hot-from {
38
+ syntax: '<number>';
39
+ inherits: true;
40
+ initial-value: -12;
41
+ }
42
+
43
+ @property --_sonic-spectrum-clip-from {
44
+ syntax: '<number>';
45
+ inherits: true;
46
+ initial-value: -3;
47
+ }
48
+
49
+ @layer sonic {
50
+ :is(sonic-spectrum, .sonic-spectrum) {
51
+ --_sonic-spectrum-size: var(--sonic-spectrum-size, 6rem);
52
+ --_sonic-spectrum-length: var(--sonic-spectrum-length, 20rem);
53
+ }
54
+
55
+ :has(> .sonic-spectrum):not([hidden]) {
56
+ display: contents;
57
+ }
58
+
59
+ sonic-spectrum:not(:defined, [hidden]) {
60
+ display: block;
61
+ visibility: hidden;
62
+ flex-shrink: 0;
63
+ inline-size: var(--_sonic-spectrum-length);
64
+ block-size: var(--_sonic-spectrum-size);
65
+ }
66
+
67
+ .sonic-spectrum {
68
+ --_sonic-unit: calc(var(--_sonic-spectrum-size) / 48);
69
+ --_sonic-spectrum-lit: var(--_sonic-lit);
70
+ --_sonic-spectrum-hot: var(--_sonic-hot);
71
+ --_sonic-spectrum-clip: var(--_sonic-clip);
72
+ --_sonic-spectrum-grid: color-mix(in oklab, var(--_sonic-glass-text) 20%, transparent);
73
+ --_sonic-spectrum-hot-from: var(--sonic-spectrum-hot-from, -12);
74
+ --_sonic-spectrum-clip-from: var(--sonic-spectrum-clip-from, -3);
75
+
76
+ inline-size: var(--_sonic-spectrum-length);
77
+ block-size: var(--_sonic-spectrum-size);
78
+ padding: calc(var(--_sonic-spectrum-size) * var(--sonic-spectrum-inset-ratio, 0.06));
79
+
80
+ /* The canvas's backing size would otherwise feed an intrinsically sized parent */
81
+ contain: size;
82
+
83
+ --_sonic-glass-radius: calc(
84
+ var(--_sonic-spectrum-size) * var(--sonic-spectrum-radius-ratio, 0.08)
85
+ );
86
+
87
+ border-radius: var(--_sonic-glass-radius);
88
+ }
89
+
90
+ .sonic-spectrum-canvas {
91
+ display: block;
92
+ inline-size: 100%;
93
+ block-size: 100%;
94
+ }
95
+
96
+ /* Opaque, since a system highlight carries alpha that would blend the bars into the glass */
97
+ @media (forced-colors: active) {
98
+ .sonic-spectrum {
99
+ --_sonic-spectrum-lit: rgb(from CanvasText r g b / 100%);
100
+ --_sonic-spectrum-hot: rgb(from Highlight r g b / 100%);
101
+ --_sonic-spectrum-clip: rgb(from Highlight r g b / 100%);
102
+ --_sonic-spectrum-grid: rgb(from GrayText r g b / 100%);
103
+ }
104
+ }
105
+ }
@@ -230,13 +230,16 @@
230
230
  inline-size: calc(var(--_sonic-switch-size) * var(--_sonic-switch-bushing-ratio));
231
231
  aspect-ratio: 1;
232
232
  pointer-events: none;
233
- background: radial-gradient(
234
- closest-side,
235
- color-mix(in oklab, var(--_sonic-cap) calc(100% - 70% * var(--_sonic-relief)), #000) 0 42%,
236
- var(--_sonic-switch-bushing-shade) 48%,
237
- var(--_sonic-cap) 70%,
238
- color-mix(in oklab, var(--_sonic-cap) calc(100% - 25% * var(--_sonic-relief)), #fff) 88%,
239
- var(--_sonic-switch-bushing-shade)
233
+ background: var(
234
+ --sonic-well,
235
+ radial-gradient(
236
+ closest-side,
237
+ color-mix(in oklab, var(--_sonic-cap) calc(100% - 70% * var(--_sonic-relief)), #000) 0 42%,
238
+ var(--_sonic-switch-bushing-shade) 48%,
239
+ var(--_sonic-cap) 70%,
240
+ color-mix(in oklab, var(--_sonic-cap) calc(100% - 25% * var(--_sonic-relief)), #fff) 88%,
241
+ var(--_sonic-switch-bushing-shade)
242
+ )
240
243
  );
241
244
  border-radius: 50%;
242
245
  box-shadow: