@ambientcss/components 2.0.0 → 2.1.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.
- package/dist/index.cjs +63 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -5
- package/dist/index.d.ts +23 -5
- package/dist/index.js +55 -26
- package/dist/index.js.map +1 -1
- package/dist/styles.css +197 -33
- package/package.json +1 -1
- package/src/components/AmbientButton.tsx +4 -0
- package/src/components/AmbientFader.tsx +5 -1
- package/src/components/AmbientKnob.tsx +5 -1
- package/src/components/AmbientRack.tsx +32 -0
- package/src/components/AmbientSlider.tsx +5 -1
- package/src/index.ts +7 -4
- package/src/styles.css +197 -33
package/src/styles.css
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
--ambx-grid: 4px;
|
|
3
3
|
--ambx-grid-half: calc(var(--ambx-grid) / 2);
|
|
4
4
|
--ambx-grid-quarter: calc(var(--ambx-grid) / 4);
|
|
5
|
+
/* Border-radius scale: deliberately identical in px to
|
|
6
|
+
@ambientcss/css's frozen .amb-rounded/-md/-lg/-xl/-full utilities
|
|
7
|
+
(4/8/12/16/9999) — cross-layer coherence, not coincidence. Radius
|
|
8
|
+
stays fixed across size variants; only footprint scales with size. */
|
|
9
|
+
--ambx-radius-sm: calc(var(--ambx-grid) * 1);
|
|
10
|
+
--ambx-radius-md: calc(var(--ambx-grid) * 2);
|
|
11
|
+
--ambx-radius-lg: calc(var(--ambx-grid) * 3);
|
|
12
|
+
--ambx-radius-xl: calc(var(--ambx-grid) * 4);
|
|
13
|
+
--ambx-radius-full: 9999px;
|
|
14
|
+
/* Spacing/clearance scale for composing controls into a device face
|
|
15
|
+
(hardware-panel convention: a single modular pitch, tighter within a
|
|
16
|
+
functional cluster, looser between clusters/at the panel edge). Each
|
|
17
|
+
tier ~1.6-1.7x the last so they stay visually distinct at a glance. */
|
|
18
|
+
--ambx-gap-tight: calc(var(--ambx-grid) * 3);
|
|
19
|
+
--ambx-gap-normal: calc(var(--ambx-grid) * 5);
|
|
20
|
+
--ambx-gap-loose: calc(var(--ambx-grid) * 8);
|
|
5
21
|
--ambx-type-1-size: calc(var(--ambx-grid) * 8);
|
|
6
22
|
--ambx-type-1-line: calc(var(--ambx-grid) * 10);
|
|
7
23
|
--ambx-type-2-size: calc(var(--ambx-grid) * 6);
|
|
@@ -17,6 +33,31 @@
|
|
|
17
33
|
--ambx-fader-label-clearance: calc(var(--ambx-grid) * 4);
|
|
18
34
|
}
|
|
19
35
|
|
|
36
|
+
/* Every control sizes its moving part as a percentage of a padded box —
|
|
37
|
+
a button's cap is 100% of a well inset by the clearance ring, a knob's
|
|
38
|
+
face 100% of the knob. Under the default content-box those paddings add
|
|
39
|
+
to the percentage instead of fitting inside it, and the cap renders
|
|
40
|
+
larger than the well it sits in. Scoped to the package's own elements
|
|
41
|
+
rather than shipped as a global reset: apps that already reset globally
|
|
42
|
+
(apps/demo does) see no change, and apps that do not are no longer
|
|
43
|
+
silently broken. */
|
|
44
|
+
.amb-button,
|
|
45
|
+
.amb-knob,
|
|
46
|
+
.amb-switch,
|
|
47
|
+
.amb-fader,
|
|
48
|
+
.amb-slider,
|
|
49
|
+
.ambx-panel,
|
|
50
|
+
.ambx-stack,
|
|
51
|
+
.amb-button *,
|
|
52
|
+
.amb-knob *,
|
|
53
|
+
.amb-switch *,
|
|
54
|
+
.amb-fader *,
|
|
55
|
+
.amb-slider *,
|
|
56
|
+
.ambx-panel *,
|
|
57
|
+
.ambx-stack * {
|
|
58
|
+
box-sizing: border-box;
|
|
59
|
+
}
|
|
60
|
+
|
|
20
61
|
.amb-heading-1 {
|
|
21
62
|
font-size: var(--ambx-type-1-size);
|
|
22
63
|
line-height: var(--ambx-type-1-line);
|
|
@@ -48,16 +89,18 @@
|
|
|
48
89
|
padding: var(--ambx-grid-half); /* the clearance gap ring */
|
|
49
90
|
--amb-thickness: 0.27; /* seat depth of the well */
|
|
50
91
|
background-color: var(--amb-lume);
|
|
51
|
-
|
|
52
|
-
|
|
92
|
+
/* Well radius = cap radius + its own clearance padding (concentric
|
|
93
|
+
shapes nest by adding the gap, not by picking a second number). */
|
|
94
|
+
border-radius: calc(var(--ambx-radius-lg) + var(--ambx-grid-half));
|
|
95
|
+
min-width: var(--ambx-button-size);
|
|
53
96
|
}
|
|
54
97
|
|
|
55
98
|
.amb-button-cap {
|
|
56
99
|
display: grid;
|
|
57
100
|
place-items: center;
|
|
58
101
|
width: 100%;
|
|
59
|
-
padding:
|
|
60
|
-
border-radius:
|
|
102
|
+
padding: var(--ambx-button-cap-pad-y) var(--ambx-button-cap-pad-x);
|
|
103
|
+
border-radius: var(--ambx-radius-lg);
|
|
61
104
|
text-transform: uppercase;
|
|
62
105
|
font-weight: 600;
|
|
63
106
|
color: var(--amb-label);
|
|
@@ -82,27 +125,30 @@
|
|
|
82
125
|
3.6mm cap instead of the key's 4.5mm — thickness 0.8 — with the same
|
|
83
126
|
0.7mm press travel). */
|
|
84
127
|
.amb-button.amb-button-round {
|
|
85
|
-
min-width:
|
|
128
|
+
min-width: var(--ambx-button-size);
|
|
86
129
|
aspect-ratio: 1;
|
|
87
130
|
border-radius: 50%;
|
|
88
131
|
}
|
|
89
132
|
|
|
90
133
|
.amb-button-round .amb-button-cap {
|
|
91
134
|
height: 100%;
|
|
92
|
-
padding: var(--ambx-
|
|
135
|
+
padding: var(--ambx-button-cap-inset);
|
|
93
136
|
border-radius: 50%;
|
|
94
137
|
}
|
|
95
138
|
|
|
96
139
|
.amb-button.amb-button-square {
|
|
97
|
-
min-width:
|
|
140
|
+
min-width: var(--ambx-button-size);
|
|
98
141
|
aspect-ratio: 1;
|
|
99
|
-
border-radius:
|
|
142
|
+
border-radius: var(--ambx-radius-md);
|
|
100
143
|
}
|
|
101
144
|
|
|
102
145
|
.amb-button-square .amb-button-cap {
|
|
103
146
|
height: 100%;
|
|
104
|
-
padding: var(--ambx-
|
|
105
|
-
|
|
147
|
+
padding: var(--ambx-button-cap-inset);
|
|
148
|
+
/* Cap radius = well radius (var(--ambx-radius-md)) minus its own inset
|
|
149
|
+
clearance — the same concentric-nesting rule as the pill, solved the
|
|
150
|
+
other way because here the well, not the cap, sits on the scale. */
|
|
151
|
+
border-radius: calc(var(--ambx-radius-md) - var(--ambx-grid-half));
|
|
106
152
|
--amb-thickness: 0.8;
|
|
107
153
|
}
|
|
108
154
|
|
|
@@ -119,8 +165,8 @@
|
|
|
119
165
|
fingers like the real thing. */
|
|
120
166
|
.amb-knob {
|
|
121
167
|
border-radius: 50%;
|
|
122
|
-
height:
|
|
123
|
-
width:
|
|
168
|
+
height: var(--ambx-knob-size);
|
|
169
|
+
width: var(--ambx-knob-size);
|
|
124
170
|
}
|
|
125
171
|
|
|
126
172
|
/* The body is the smooth circle at the tooth-root radius: it carries
|
|
@@ -257,8 +303,8 @@
|
|
|
257
303
|
top: 16%;
|
|
258
304
|
left: 50%;
|
|
259
305
|
transform: translateX(-50%);
|
|
260
|
-
width: calc(var(--ambx-
|
|
261
|
-
height: calc(var(--ambx-
|
|
306
|
+
width: calc(var(--ambx-knob-size) * 0.125);
|
|
307
|
+
height: calc(var(--ambx-knob-size) * 0.125);
|
|
262
308
|
border-radius: 50%;
|
|
263
309
|
background: var(--amb-highlight-color);
|
|
264
310
|
}
|
|
@@ -268,8 +314,8 @@
|
|
|
268
314
|
.amb-knob-indicator-dot-center {
|
|
269
315
|
top: 50%;
|
|
270
316
|
transform: translate(-50%, -50%);
|
|
271
|
-
width: calc(var(--ambx-
|
|
272
|
-
height: calc(var(--ambx-
|
|
317
|
+
width: calc(var(--ambx-knob-size) * 0.28125);
|
|
318
|
+
height: calc(var(--ambx-knob-size) * 0.28125);
|
|
273
319
|
}
|
|
274
320
|
|
|
275
321
|
/* Radial indicator line (line variant): the referent's accent bar,
|
|
@@ -279,9 +325,9 @@
|
|
|
279
325
|
top: 12%;
|
|
280
326
|
left: 50%;
|
|
281
327
|
transform: translateX(-50%);
|
|
282
|
-
width:
|
|
328
|
+
width: var(--ambx-knob-line-width);
|
|
283
329
|
height: 34%;
|
|
284
|
-
border-radius: calc(var(--ambx-
|
|
330
|
+
border-radius: calc(var(--ambx-knob-line-width) / 2);
|
|
285
331
|
background: var(--amb-highlight-color);
|
|
286
332
|
}
|
|
287
333
|
|
|
@@ -295,9 +341,9 @@
|
|
|
295
341
|
light, glowing in low light — overriding the groove's neutral floor. */
|
|
296
342
|
.amb-fader {
|
|
297
343
|
position: relative;
|
|
298
|
-
width: var(--ambx-
|
|
344
|
+
width: var(--ambx-fader-track);
|
|
299
345
|
height: calc(var(--ambx-grid) * 30);
|
|
300
|
-
border-radius: var(--ambx-
|
|
346
|
+
border-radius: var(--ambx-radius-full);
|
|
301
347
|
background-color: var(--amb-lume);
|
|
302
348
|
}
|
|
303
349
|
|
|
@@ -306,12 +352,12 @@
|
|
|
306
352
|
with a single grip line across the top. */
|
|
307
353
|
.amb-fader-thumb {
|
|
308
354
|
position: absolute;
|
|
309
|
-
width:
|
|
310
|
-
height:
|
|
355
|
+
width: var(--ambx-fader-thumb-w);
|
|
356
|
+
height: var(--ambx-fader-thumb-h);
|
|
311
357
|
left: 50%;
|
|
312
358
|
top: 50%;
|
|
313
359
|
transform: translate(-50%, -50%);
|
|
314
|
-
border-radius:
|
|
360
|
+
border-radius: var(--ambx-radius-md);
|
|
315
361
|
display: grid;
|
|
316
362
|
place-items: center;
|
|
317
363
|
--amb-thickness: 1.5;
|
|
@@ -330,17 +376,17 @@
|
|
|
330
376
|
gliding over it. */
|
|
331
377
|
.amb-slider {
|
|
332
378
|
position: relative;
|
|
333
|
-
height:
|
|
379
|
+
height: var(--ambx-slider-track);
|
|
334
380
|
width: calc(var(--ambx-grid) * 30);
|
|
335
|
-
border-radius: var(--ambx-
|
|
381
|
+
border-radius: var(--ambx-radius-full);
|
|
336
382
|
background-color: var(--amb-lume);
|
|
337
383
|
--amb-thickness: 0.22;
|
|
338
384
|
}
|
|
339
385
|
|
|
340
386
|
.amb-slider-thumb {
|
|
341
387
|
position: absolute;
|
|
342
|
-
width:
|
|
343
|
-
height:
|
|
388
|
+
width: var(--ambx-slider-thumb);
|
|
389
|
+
height: var(--ambx-slider-thumb);
|
|
344
390
|
top: 50%;
|
|
345
391
|
left: 50%;
|
|
346
392
|
transform: translate(-50%, -50%);
|
|
@@ -426,13 +472,91 @@
|
|
|
426
472
|
}
|
|
427
473
|
|
|
428
474
|
.ambx-panel {
|
|
429
|
-
border-radius:
|
|
475
|
+
border-radius: var(--ambx-radius-xl);
|
|
430
476
|
padding: calc(var(--ambx-grid) * 4);
|
|
431
477
|
}
|
|
432
478
|
|
|
479
|
+
/* Opt-in "device face" mode: edge margin = the loose gap tier, so a
|
|
480
|
+
panel composing a .ambx-rack of controls reads its own border as one
|
|
481
|
+
more slot in the same lattice (Rams/Braun, Teenage Engineering
|
|
482
|
+
convention). Not the default padding above, which serves general
|
|
483
|
+
containers (cards, settings panels) that aren't device faces. */
|
|
484
|
+
.ambx-panel-device {
|
|
485
|
+
padding: var(--ambx-gap-loose);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/* Layout primitive for composing controls into a device face: pick a
|
|
489
|
+
gap tier by how tightly the controls belong together (tight = one
|
|
490
|
+
functional unit/repeated row, normal = a few related controls, loose
|
|
491
|
+
= separating distinct zones or the panel edge, see .ambx-panel-device
|
|
492
|
+
above) rather than picking an arbitrary gap per layout. */
|
|
493
|
+
.ambx-rack {
|
|
494
|
+
display: flex;
|
|
495
|
+
align-items: center;
|
|
496
|
+
gap: var(--ambx-gap-normal);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.ambx-rack-tight {
|
|
500
|
+
gap: var(--ambx-gap-tight);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.ambx-rack-loose {
|
|
504
|
+
gap: var(--ambx-gap-loose);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
.ambx-rack-column {
|
|
508
|
+
flex-direction: column;
|
|
509
|
+
}
|
|
510
|
+
|
|
433
511
|
.ambx-button {
|
|
434
|
-
min-width: calc(var(--ambx-grid) * 18);
|
|
435
512
|
line-height: var(--ambx-type-3-line);
|
|
513
|
+
--ambx-button-size: calc(var(--ambx-grid) * 18); /* 72px pill */
|
|
514
|
+
--ambx-button-cap-pad-x: calc(var(--ambx-grid) * 2); /* 8px */
|
|
515
|
+
--ambx-button-cap-pad-y: calc(var(--ambx-grid) * 1.5); /* 6px */
|
|
516
|
+
--ambx-button-cap-inset: var(--ambx-grid); /* 4px */
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.ambx-button-sm {
|
|
520
|
+
--ambx-button-size: calc(var(--ambx-grid) * 16); /* 64px pill */
|
|
521
|
+
--ambx-button-cap-pad-x: calc(var(--ambx-grid) * 1.5); /* 6px */
|
|
522
|
+
--ambx-button-cap-pad-y: var(--ambx-grid); /* 4px */
|
|
523
|
+
--ambx-button-cap-inset: calc(var(--ambx-grid) * 0.75); /* 3px */
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.ambx-button-md {
|
|
527
|
+
--ambx-button-size: calc(var(--ambx-grid) * 18); /* 72px pill */
|
|
528
|
+
--ambx-button-cap-pad-x: calc(var(--ambx-grid) * 2); /* 8px */
|
|
529
|
+
--ambx-button-cap-pad-y: calc(var(--ambx-grid) * 1.5); /* 6px */
|
|
530
|
+
--ambx-button-cap-inset: var(--ambx-grid); /* 4px */
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.ambx-button-lg {
|
|
534
|
+
--ambx-button-size: calc(var(--ambx-grid) * 20); /* 80px pill */
|
|
535
|
+
--ambx-button-cap-pad-x: calc(var(--ambx-grid) * 2.5); /* 10px */
|
|
536
|
+
--ambx-button-cap-pad-y: calc(var(--ambx-grid) * 2); /* 8px */
|
|
537
|
+
--ambx-button-cap-inset: calc(var(--ambx-grid) * 1.25); /* 5px */
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/* Round/square shapes have their own min-width table per size (not a
|
|
541
|
+
ratio of the pill's — the three shapes' true md values, 72/48/56,
|
|
542
|
+
share no common factor), overridden via compound selectors so they
|
|
543
|
+
win regardless of source order relative to .ambx-button-sm/-md/-lg. */
|
|
544
|
+
.amb-button-round.ambx-button-sm { --ambx-button-size: calc(var(--ambx-grid) * 10); } /* 40px */
|
|
545
|
+
.amb-button-round.ambx-button-md { --ambx-button-size: calc(var(--ambx-grid) * 12); } /* 48px */
|
|
546
|
+
.amb-button-round.ambx-button-lg { --ambx-button-size: calc(var(--ambx-grid) * 14); } /* 56px */
|
|
547
|
+
|
|
548
|
+
.amb-button-square.ambx-button-sm { --ambx-button-size: calc(var(--ambx-grid) * 12); } /* 48px */
|
|
549
|
+
.amb-button-square.ambx-button-md { --ambx-button-size: calc(var(--ambx-grid) * 14); } /* 56px */
|
|
550
|
+
.amb-button-square.ambx-button-lg { --ambx-button-size: calc(var(--ambx-grid) * 16); } /* 64px */
|
|
551
|
+
|
|
552
|
+
.ambx-button-sm .amb-button-cap {
|
|
553
|
+
font-size: var(--ambx-label-size);
|
|
554
|
+
line-height: var(--ambx-label-line);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
.ambx-button-lg .amb-button-cap {
|
|
558
|
+
font-size: calc(var(--ambx-grid) * 3.5);
|
|
559
|
+
line-height: calc(var(--ambx-grid) * 5);
|
|
436
560
|
}
|
|
437
561
|
|
|
438
562
|
.ambx-switch {
|
|
@@ -488,18 +612,43 @@
|
|
|
488
612
|
place-items: center;
|
|
489
613
|
touch-action: none;
|
|
490
614
|
user-select: none;
|
|
615
|
+
--ambx-knob-size: calc(var(--ambx-grid) * 16); /* 64px */
|
|
616
|
+
--ambx-knob-line-width: calc(var(--ambx-knob-size) * 0.046875);
|
|
491
617
|
}
|
|
492
618
|
|
|
619
|
+
.ambx-knob-sm { --ambx-knob-size: calc(var(--ambx-grid) * 12); } /* 48px */
|
|
620
|
+
.ambx-knob-md { --ambx-knob-size: calc(var(--ambx-grid) * 16); } /* 64px */
|
|
621
|
+
.ambx-knob-lg { --ambx-knob-size: calc(var(--ambx-grid) * 20); } /* 80px */
|
|
622
|
+
|
|
493
623
|
.ambx-knob-rotation {
|
|
494
624
|
position: absolute;
|
|
495
625
|
inset: 0;
|
|
496
626
|
}
|
|
497
627
|
|
|
498
628
|
.ambx-fader {
|
|
499
|
-
width: calc(var(--ambx-grid) * 2);
|
|
500
|
-
border-radius: 999px;
|
|
501
629
|
touch-action: none;
|
|
502
630
|
user-select: none;
|
|
631
|
+
--ambx-fader-track: calc(var(--ambx-grid) * 2); /* 8px */
|
|
632
|
+
--ambx-fader-thumb-w: calc(var(--ambx-grid) * 6); /* 24px */
|
|
633
|
+
--ambx-fader-thumb-h: calc(var(--ambx-grid) * 9); /* 36px */
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
.ambx-fader-sm {
|
|
637
|
+
--ambx-fader-track: calc(var(--ambx-grid) * 1.5); /* 6px */
|
|
638
|
+
--ambx-fader-thumb-w: calc(var(--ambx-grid) * 5); /* 20px */
|
|
639
|
+
--ambx-fader-thumb-h: calc(var(--ambx-grid) * 7.5); /* 30px */
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
.ambx-fader-md {
|
|
643
|
+
--ambx-fader-track: calc(var(--ambx-grid) * 2); /* 8px */
|
|
644
|
+
--ambx-fader-thumb-w: calc(var(--ambx-grid) * 6); /* 24px */
|
|
645
|
+
--ambx-fader-thumb-h: calc(var(--ambx-grid) * 9); /* 36px */
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.ambx-fader-lg {
|
|
649
|
+
--ambx-fader-track: calc(var(--ambx-grid) * 3); /* 12px */
|
|
650
|
+
--ambx-fader-thumb-w: calc(var(--ambx-grid) * 8); /* 32px */
|
|
651
|
+
--ambx-fader-thumb-h: calc(var(--ambx-grid) * 12); /* 48px */
|
|
503
652
|
}
|
|
504
653
|
|
|
505
654
|
.ambx-fader-thumb {
|
|
@@ -507,10 +656,25 @@
|
|
|
507
656
|
}
|
|
508
657
|
|
|
509
658
|
.ambx-slider {
|
|
510
|
-
height: calc(var(--ambx-grid) * 2);
|
|
511
|
-
border-radius: 999px;
|
|
512
659
|
touch-action: none;
|
|
513
660
|
user-select: none;
|
|
661
|
+
--ambx-slider-track: calc(var(--ambx-grid) * 2); /* 8px */
|
|
662
|
+
--ambx-slider-thumb: calc(var(--ambx-grid) * 6); /* 24px */
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
.ambx-slider-sm {
|
|
666
|
+
--ambx-slider-track: calc(var(--ambx-grid) * 1.5); /* 6px */
|
|
667
|
+
--ambx-slider-thumb: calc(var(--ambx-grid) * 5); /* 20px */
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
.ambx-slider-md {
|
|
671
|
+
--ambx-slider-track: calc(var(--ambx-grid) * 2); /* 8px */
|
|
672
|
+
--ambx-slider-thumb: calc(var(--ambx-grid) * 6); /* 24px */
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
.ambx-slider-lg {
|
|
676
|
+
--ambx-slider-track: calc(var(--ambx-grid) * 3); /* 12px */
|
|
677
|
+
--ambx-slider-thumb: calc(var(--ambx-grid) * 8); /* 32px */
|
|
514
678
|
}
|
|
515
679
|
|
|
516
680
|
.ambx-slider-thumb {
|