@ambientcss/components 2.0.1 → 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/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);
@@ -73,16 +89,18 @@
73
89
  padding: var(--ambx-grid-half); /* the clearance gap ring */
74
90
  --amb-thickness: 0.27; /* seat depth of the well */
75
91
  background-color: var(--amb-lume);
76
- border-radius: calc(var(--ambx-grid) * 3 + var(--ambx-grid-half));
77
- min-width: calc(var(--ambx-grid) * 16);
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);
78
96
  }
79
97
 
80
98
  .amb-button-cap {
81
99
  display: grid;
82
100
  place-items: center;
83
101
  width: 100%;
84
- padding: calc(var(--ambx-grid) * 1.5) calc(var(--ambx-grid) * 2);
85
- border-radius: calc(var(--ambx-grid) * 3);
102
+ padding: var(--ambx-button-cap-pad-y) var(--ambx-button-cap-pad-x);
103
+ border-radius: var(--ambx-radius-lg);
86
104
  text-transform: uppercase;
87
105
  font-weight: 600;
88
106
  color: var(--amb-label);
@@ -107,27 +125,30 @@
107
125
  3.6mm cap instead of the key's 4.5mm — thickness 0.8 — with the same
108
126
  0.7mm press travel). */
109
127
  .amb-button.amb-button-round {
110
- min-width: calc(var(--ambx-grid) * 12);
128
+ min-width: var(--ambx-button-size);
111
129
  aspect-ratio: 1;
112
130
  border-radius: 50%;
113
131
  }
114
132
 
115
133
  .amb-button-round .amb-button-cap {
116
134
  height: 100%;
117
- padding: var(--ambx-grid);
135
+ padding: var(--ambx-button-cap-inset);
118
136
  border-radius: 50%;
119
137
  }
120
138
 
121
139
  .amb-button.amb-button-square {
122
- min-width: calc(var(--ambx-grid) * 14);
140
+ min-width: var(--ambx-button-size);
123
141
  aspect-ratio: 1;
124
- border-radius: calc(var(--ambx-grid) * 2);
142
+ border-radius: var(--ambx-radius-md);
125
143
  }
126
144
 
127
145
  .amb-button-square .amb-button-cap {
128
146
  height: 100%;
129
- padding: var(--ambx-grid);
130
- border-radius: calc(var(--ambx-grid) * 1.5);
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));
131
152
  --amb-thickness: 0.8;
132
153
  }
133
154
 
@@ -144,8 +165,8 @@
144
165
  fingers like the real thing. */
145
166
  .amb-knob {
146
167
  border-radius: 50%;
147
- height: calc(var(--ambx-grid) * 16);
148
- width: calc(var(--ambx-grid) * 16);
168
+ height: var(--ambx-knob-size);
169
+ width: var(--ambx-knob-size);
149
170
  }
150
171
 
151
172
  /* The body is the smooth circle at the tooth-root radius: it carries
@@ -282,8 +303,8 @@
282
303
  top: 16%;
283
304
  left: 50%;
284
305
  transform: translateX(-50%);
285
- width: calc(var(--ambx-grid) * 2);
286
- height: calc(var(--ambx-grid) * 2);
306
+ width: calc(var(--ambx-knob-size) * 0.125);
307
+ height: calc(var(--ambx-knob-size) * 0.125);
287
308
  border-radius: 50%;
288
309
  background: var(--amb-highlight-color);
289
310
  }
@@ -293,8 +314,8 @@
293
314
  .amb-knob-indicator-dot-center {
294
315
  top: 50%;
295
316
  transform: translate(-50%, -50%);
296
- width: calc(var(--ambx-grid) * 4.5);
297
- height: calc(var(--ambx-grid) * 4.5);
317
+ width: calc(var(--ambx-knob-size) * 0.28125);
318
+ height: calc(var(--ambx-knob-size) * 0.28125);
298
319
  }
299
320
 
300
321
  /* Radial indicator line (line variant): the referent's accent bar,
@@ -304,9 +325,9 @@
304
325
  top: 12%;
305
326
  left: 50%;
306
327
  transform: translateX(-50%);
307
- width: calc(var(--ambx-grid) * 0.75);
328
+ width: var(--ambx-knob-line-width);
308
329
  height: 34%;
309
- border-radius: calc(var(--ambx-grid) * 0.375);
330
+ border-radius: calc(var(--ambx-knob-line-width) / 2);
310
331
  background: var(--amb-highlight-color);
311
332
  }
312
333
 
@@ -320,9 +341,9 @@
320
341
  light, glowing in low light — overriding the groove's neutral floor. */
321
342
  .amb-fader {
322
343
  position: relative;
323
- width: var(--ambx-grid);
344
+ width: var(--ambx-fader-track);
324
345
  height: calc(var(--ambx-grid) * 30);
325
- border-radius: var(--ambx-grid);
346
+ border-radius: var(--ambx-radius-full);
326
347
  background-color: var(--amb-lume);
327
348
  }
328
349
 
@@ -331,12 +352,12 @@
331
352
  with a single grip line across the top. */
332
353
  .amb-fader-thumb {
333
354
  position: absolute;
334
- width: calc(var(--ambx-grid) * 6);
335
- height: calc(var(--ambx-grid) * 9);
355
+ width: var(--ambx-fader-thumb-w);
356
+ height: var(--ambx-fader-thumb-h);
336
357
  left: 50%;
337
358
  top: 50%;
338
359
  transform: translate(-50%, -50%);
339
- border-radius: calc(var(--ambx-grid) * 2);
360
+ border-radius: var(--ambx-radius-md);
340
361
  display: grid;
341
362
  place-items: center;
342
363
  --amb-thickness: 1.5;
@@ -355,17 +376,17 @@
355
376
  gliding over it. */
356
377
  .amb-slider {
357
378
  position: relative;
358
- height: calc(var(--ambx-grid) * 1.5);
379
+ height: var(--ambx-slider-track);
359
380
  width: calc(var(--ambx-grid) * 30);
360
- border-radius: var(--ambx-grid);
381
+ border-radius: var(--ambx-radius-full);
361
382
  background-color: var(--amb-lume);
362
383
  --amb-thickness: 0.22;
363
384
  }
364
385
 
365
386
  .amb-slider-thumb {
366
387
  position: absolute;
367
- width: calc(var(--ambx-grid) * 6);
368
- height: calc(var(--ambx-grid) * 6);
388
+ width: var(--ambx-slider-thumb);
389
+ height: var(--ambx-slider-thumb);
369
390
  top: 50%;
370
391
  left: 50%;
371
392
  transform: translate(-50%, -50%);
@@ -451,13 +472,91 @@
451
472
  }
452
473
 
453
474
  .ambx-panel {
454
- border-radius: calc(var(--ambx-grid) * 4);
475
+ border-radius: var(--ambx-radius-xl);
455
476
  padding: calc(var(--ambx-grid) * 4);
456
477
  }
457
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
+
458
511
  .ambx-button {
459
- min-width: calc(var(--ambx-grid) * 18);
460
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);
461
560
  }
462
561
 
463
562
  .ambx-switch {
@@ -513,18 +612,43 @@
513
612
  place-items: center;
514
613
  touch-action: none;
515
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);
516
617
  }
517
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
+
518
623
  .ambx-knob-rotation {
519
624
  position: absolute;
520
625
  inset: 0;
521
626
  }
522
627
 
523
628
  .ambx-fader {
524
- width: calc(var(--ambx-grid) * 2);
525
- border-radius: 999px;
526
629
  touch-action: none;
527
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 */
528
652
  }
529
653
 
530
654
  .ambx-fader-thumb {
@@ -532,10 +656,25 @@
532
656
  }
533
657
 
534
658
  .ambx-slider {
535
- height: calc(var(--ambx-grid) * 2);
536
- border-radius: 999px;
537
659
  touch-action: none;
538
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 */
539
678
  }
540
679
 
541
680
  .ambx-slider-thumb {