@ -40,10 +40,26 @@
let nest = $state(true)
let nest = $state(true)
let playing = $state(true)
let playing = $state(true)
// `full` (pill/circle) is dimension-capped per element → concentric nesting is impossible there:
// `full` (pill/circle) caps the radius to half each element's SHORTER side. A 16:10 cover can't
// a tall pill can't have a concentric wide-pill child (their radii cap to different values).
// be concentric on all four corners (its height caps them to ~half-height), but its TOP corners
// Concentric needs FINITE radii; `full` is for leaf elements (chips · buttons · avatars).
// can match the card if the bottom stays square. CSS can't read the card's dimension-capped
// radius (computed value is still 9999px), so we measure it and derive the concentric top radius.
const isFull = $derived(radius === 'full');
const isFull = $derived(radius === 'full');
let cardEl = $state< HTMLDivElement > ();
let coverTopRadius = $state(0);
const NEST_GAP = 8; // var(--space-2)
$effect(() => {
const el = cardEl;
if (!el) return;
const measure = () => {
const r = el.getBoundingClientRect();
coverTopRadius = Math.max(0, Math.round(Math.min(r.width, r.height) / 2 - NEST_GAP));
};
measure();
const ro = new ResizeObserver(measure);
ro.observe(el);
return () => ro.disconnect();
});
const RADII = ['sm', 'md', 'lg', 'xl', 'full'] as const
const RADII = ['sm', 'md', 'lg', 'xl', 'full'] as const
@ -88,6 +104,7 @@
< div class = "lab" >
< div class = "lab" >
<!-- the sample UI -->
<!-- the sample UI -->
< div
< div
bind:this={ cardEl }
class="player"
class="player"
data-shape={ family }
data-shape={ family }
style="--sample-radius: var(--radius-{ radius } ); --shape-outer-radius: var(--radius-{ radius } ); --shape-smoothing: { smoothing } "
style="--sample-radius: var(--radius-{ radius } ); --shape-outer-radius: var(--radius-{ radius } ); --shape-smoothing: { smoothing } "
@ -98,6 +115,9 @@
data-shape-nest={ nest && ! isFull ? '' : undefined }
data-shape-nest={ nest && ! isFull ? '' : undefined }
class:cover-naive={ ! nest && ! isFull }
class:cover-naive={ ! nest && ! isFull }
class:cover-full={ isFull }
class:cover-full={ isFull }
style={ isFull
? `border-start-start-radius:${ coverTopRadius } px;border-start-end-radius:${ coverTopRadius } px`
: undefined}
>
>
< button class = "player-play" data-shape = { family } onclick= {() => ( playing = ! playing )} >
< button class = "player-play" data-shape = { family } onclick= {() => ( playing = ! playing )} >
{ playing ? '❚❚' : '▶' }
{ playing ? '❚❚' : '▶' }
@ -153,7 +173,7 @@
< input type = "checkbox" bind:checked = { nest } disabled= { isFull } />
< input type = "checkbox" bind:checked = { nest } disabled= { isFull } />
< span class = "ctl-label"
< span class = "ctl-label"
>radios concéntricos { isFull
>radios concéntricos { isFull
? '· n/a a full (geometría de hoja )'
? '· auto a full (solo top: la píldora no deja redondear el pie )'
: nest
: nest
? ''
? ''
: '· off (la carátula desencaja)'}< /span
: '· off (la carátula desencaja)'}< /span
@ -349,11 +369,11 @@
overflow: hidden;
overflow: hidden;
}
}
.cover-naive { border - radius : var ( -- radius - xl ); }
.cover-naive { border - radius : var ( -- radius - xl ); }
/* at `full` the card is a pill (radius caps to half its shorter side); a finite-radius cover
/* at `full` the card is a pill (radius caps to half its shorter side). The cover can't be
floating inside reads as broken, and a concentric cover is impossible (different aspect ratios
concentric on all 4 corners (its height caps them), but its TOP corners CAN match the card —
cap differently). So at full the cover bleeds edge-to-edge with NO radius of its own — the
set inline from the measured radius (card·½ − gap) — while the bottom stays square and meets
card's overflow:hidden + its real corner clip the cover's top to match the card exactly . */
the metadata: the iOS-player geometry. Inset frame kept on top/sides so the inner radius reads . */
.cover-full { margin : 0; border - radius : 0 ; }
.cover-full { margin : var( -- space - 2 ) var ( -- space - 2 ) 0; border - end - start - radius : 0 ; border - end - end - radius : 0 ; }
.player-play {
.player-play {
inline-size: 3.25rem;
inline-size: 3.25rem;
aspect-ratio: 1;
aspect-ratio: 1;