|
|
<script lang="ts">
|
|
|
/**
|
|
|
* Shape demo — the Eidos shape channel, made tangible on real UI.
|
|
|
*
|
|
|
* 1. Taller — a real "now playing" card + a control panel (family · smoothing · radius ·
|
|
|
* concentric) that retunes the WHOLE card live (the jaula-abierta centerpiece).
|
|
|
* 2. De cerca — round vs squircle, big, so the seam difference reads.
|
|
|
* 3. Familias — the same chip in all 4 families + each on a fitting component.
|
|
|
* 4. Ocurre — press real buttons → the corner firms (the press-squeeze firma).
|
|
|
* 5. Vs el resto— the field is arc+static; the strip shows what only Eidos does.
|
|
|
*
|
|
|
* Self-contained: eidos foundation (shape tokens + families + firma) + `data-theme`.
|
|
|
* Continuity needs `corner-shape` (Chromium 2025+); degrades to the plain arc elsewhere.
|
|
|
*/
|
|
|
import '@/uix/eidos/index.css'
|
|
|
|
|
|
let theme = $state<'light' | 'dark'>('dark')
|
|
|
$effect(() => {
|
|
|
const el = document.documentElement
|
|
|
const prev = el.getAttribute('data-theme')
|
|
|
el.setAttribute('data-theme', theme)
|
|
|
return () => {
|
|
|
if (prev === null) el.removeAttribute('data-theme')
|
|
|
else el.setAttribute('data-theme', prev)
|
|
|
}
|
|
|
})
|
|
|
|
|
|
const FAMILIES = [
|
|
|
{ id: 'rounded', label: 'rounded' },
|
|
|
{ id: 'continuous', label: 'continuous' },
|
|
|
{ id: 'cut', label: 'cut' },
|
|
|
{ id: 'scoop', label: 'scoop' }
|
|
|
] as const
|
|
|
type Family = (typeof FAMILIES)[number]['id']
|
|
|
|
|
|
// ── 1 · Taller: the live control panel drives the whole sample card ──────────
|
|
|
let family = $state<Family>('continuous')
|
|
|
let smoothing = $state(2)
|
|
|
let radius = $state('xl')
|
|
|
let nest = $state(true)
|
|
|
let playing = $state(true)
|
|
|
|
|
|
const RADII = ['sm', 'md', 'lg', 'xl'] as const
|
|
|
|
|
|
// ── 4 · eventful press ───────────────────────────────────────────────────────
|
|
|
let pressed = $state<string | null>(null)
|
|
|
function firePress(id: string): void {
|
|
|
pressed = null
|
|
|
requestAnimationFrame(() => (pressed = id))
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<svelte:head><title>Forma · Eidos</title></svelte:head>
|
|
|
|
|
|
<div class="root" data-theme={theme}>
|
|
|
<header class="masthead">
|
|
|
<div class="mast-row">
|
|
|
<p class="kicker">Eidos · canal de forma</p>
|
|
|
<button class="theme-toggle" onclick={() => (theme = theme === 'light' ? 'dark' : 'light')}>
|
|
|
{theme === 'light' ? '◐ claro' : '◑ oscuro'}
|
|
|
</button>
|
|
|
</div>
|
|
|
<h1 class="mast-title">La esquina, <em>repensada</em></h1>
|
|
|
<p class="mast-lede">
|
|
|
Toda la web reduce la forma a un número: <code>border-radius</code>, un arco. La esquina
|
|
|
tiene más ejes — <strong>continuidad</strong>, <strong>familia</strong>,
|
|
|
<strong>armonía</strong> y <strong>tensión</strong>. Aquí la forma es un canal: tócala y mira
|
|
|
la misma UI cambiar de carácter.
|
|
|
</p>
|
|
|
</header>
|
|
|
|
|
|
<!-- ── 1 · Taller (centerpiece) ─────────────────────────────────────────── -->
|
|
|
<section class="section">
|
|
|
<div class="sec-head">
|
|
|
<h2 class="sec-title">El taller</h2>
|
|
|
<p class="sec-note">
|
|
|
Una tarjeta real. Cambia familia, suavizado, magnitud o el anidado concéntrico y
|
|
|
<em>todo</em> se reentona a la vez — un solo sistema, no estilos sueltos. (El avatar es un
|
|
|
círculo de verdad: las familias no lo deforman, por diseño.)
|
|
|
</p>
|
|
|
</div>
|
|
|
|
|
|
<div class="lab">
|
|
|
<!-- the sample UI -->
|
|
|
<div
|
|
|
class="player"
|
|
|
data-shape={family}
|
|
|
style="--sample-radius: var(--radius-{radius}); --shape-outer-radius: var(--radius-{radius}); --shape-smoothing: {smoothing}"
|
|
|
>
|
|
|
<div
|
|
|
class="player-cover"
|
|
|
data-shape={family}
|
|
|
data-shape-nest={nest ? '' : undefined}
|
|
|
class:cover-naive={!nest}
|
|
|
>
|
|
|
<button class="player-play" data-shape={family} onclick={() => (playing = !playing)}>
|
|
|
{playing ? '❚❚' : '▶'}
|
|
|
</button>
|
|
|
<span class="player-eq" data-on={playing}><i></i><i></i><i></i><i></i></span>
|
|
|
</div>
|
|
|
<div class="player-body">
|
|
|
<div class="player-head">
|
|
|
<span class="player-avatar">N</span>
|
|
|
<div class="player-meta">
|
|
|
<span class="player-title">Continuum</span>
|
|
|
<span class="player-artist">Nocturne Ensemble</span>
|
|
|
</div>
|
|
|
<span class="player-tag" data-shape={family}>FLAC</span>
|
|
|
</div>
|
|
|
<div class="player-track"><span class="player-fill"></span></div>
|
|
|
<div class="player-row">
|
|
|
<input class="player-input" data-shape={family} placeholder="añade a una lista…" />
|
|
|
<button class="player-add" data-shape={family}>+</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- the control panel -->
|
|
|
<div class="panel">
|
|
|
<div class="ctl">
|
|
|
<span class="ctl-label">familia</span>
|
|
|
<div class="chips">
|
|
|
{#each FAMILIES as f}
|
|
|
<button class="chip" data-active={family === f.id} onclick={() => (family = f.id)}>
|
|
|
{f.label}
|
|
|
</button>
|
|
|
{/each}
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="ctl" class:ctl-dim={family !== 'continuous'}>
|
|
|
<span class="ctl-label">suavizado</span>
|
|
|
<input type="range" min="1" max="3.2" step="0.05" bind:value={smoothing} disabled={family !== 'continuous'} />
|
|
|
<span class="ctl-val">{smoothing.toFixed(2)}</span>
|
|
|
</div>
|
|
|
|
|
|
<div class="ctl">
|
|
|
<span class="ctl-label">magnitud</span>
|
|
|
<div class="chips">
|
|
|
{#each RADII as r}
|
|
|
<button class="chip" data-active={radius === r} onclick={() => (radius = r)}>{r}</button>
|
|
|
{/each}
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<label class="ctl ctl-check">
|
|
|
<input type="checkbox" bind:checked={nest} />
|
|
|
<span class="ctl-label">radios concéntricos {nest ? '' : '· off (la carátula desencaja)'}</span>
|
|
|
</label>
|
|
|
|
|
|
<code class="panel-code"
|
|
|
>data-shape="{family}"{family === 'continuous' ? ` · --shape-smoothing:${smoothing.toFixed(2)}` : ''}</code
|
|
|
>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
<!-- ── 2 · De cerca ─────────────────────────────────────────────────────── -->
|
|
|
<section class="section">
|
|
|
<div class="sec-head">
|
|
|
<h2 class="sec-title">De cerca</h2>
|
|
|
<p class="sec-note">
|
|
|
El arco circular tiene un <em>quiebre</em> donde el lado encuentra la curva. El squircle
|
|
|
(superelipse) fluye sin costura — lo que hace premium a iOS. Misma magnitud, distinta
|
|
|
continuidad.
|
|
|
</p>
|
|
|
</div>
|
|
|
<div class="closeup">
|
|
|
<figure class="cu">
|
|
|
<div class="cu-box" data-shape="rounded"></div>
|
|
|
<figcaption><b>rounded</b> · <code>superellipse(1)</code> — arco</figcaption>
|
|
|
</figure>
|
|
|
<figure class="cu">
|
|
|
<div class="cu-box" data-shape="continuous"></div>
|
|
|
<figcaption><b>continuous</b> · <code>superellipse(2)</code> — squircle</figcaption>
|
|
|
</figure>
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
<!-- ── 3 · Familias ─────────────────────────────────────────────────────── -->
|
|
|
<section class="section">
|
|
|
<div class="sec-head">
|
|
|
<h2 class="sec-title">Familias</h2>
|
|
|
<p class="sec-note">
|
|
|
Una sola mecánica (<code>corner-shape</code> vía <code>data-shape</code>) cubre cuatro
|
|
|
familias. Material solo tiene <code>cut</code>; Apple solo <code>continuous</code>. Aquí,
|
|
|
la misma etiqueta en las cuatro:
|
|
|
</p>
|
|
|
</div>
|
|
|
<div class="fam-row">
|
|
|
{#each FAMILIES as f}
|
|
|
<figure class="fam">
|
|
|
<span class="fam-chip" data-shape={f.id}>etiqueta</span>
|
|
|
<figcaption>{f.label}</figcaption>
|
|
|
</figure>
|
|
|
{/each}
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
<!-- ── 4 · Ocurre ───────────────────────────────────────────────────────── -->
|
|
|
<section class="section">
|
|
|
<div class="sec-head">
|
|
|
<h2 class="sec-title">La forma <em>ocurre</em></h2>
|
|
|
<p class="sec-note">
|
|
|
Púlsalos: la esquina <em>se afirma</em> bajo el dedo (la continuidad se cuadra un instante)
|
|
|
a la vez que baja de escala y se aplana la sombra — un evento, tres canales: la firma
|
|
|
cross-modal. El botón <code>rounded</code> es el control: no morfea.
|
|
|
</p>
|
|
|
</div>
|
|
|
<div class="press-row">
|
|
|
<button
|
|
|
class="press-btn"
|
|
|
data-shape="continuous"
|
|
|
data-event-family={pressed === 'a' ? 'contact' : undefined}
|
|
|
data-event-phase={pressed === 'a' ? 'active' : undefined}
|
|
|
onanimationend={() => (pressed = null)}
|
|
|
onpointerdown={() => firePress('a')}
|
|
|
>continuous</button>
|
|
|
<button class="press-btn press-ctrl" data-shape="rounded">rounded</button>
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
<!-- ── 5 · Vs el resto ──────────────────────────────────────────────────── -->
|
|
|
<section class="section">
|
|
|
<div class="sec-head">
|
|
|
<h2 class="sec-title">Lo que solo hace Eidos</h2>
|
|
|
<p class="sec-note">
|
|
|
El campo entero (Tailwind · shadcn · Chakra · Mantine · Ant · Radix · Carbon · Fluent ·
|
|
|
Spectrum · Polaris) se queda en la primera columna.
|
|
|
</p>
|
|
|
</div>
|
|
|
<div class="vs">
|
|
|
<div class="vs-col vs-them">
|
|
|
<span class="vs-h">todos los demás</span>
|
|
|
<div class="vs-sample" data-shape="rounded"></div>
|
|
|
<span class="vs-cap">escala + arco + estático</span>
|
|
|
</div>
|
|
|
<div class="vs-col">
|
|
|
<span class="vs-h">+ continuidad</span>
|
|
|
<div class="vs-sample" data-shape="continuous"></div>
|
|
|
<span class="vs-cap">squircle tokenizado</span>
|
|
|
</div>
|
|
|
<div class="vs-col">
|
|
|
<span class="vs-h">+ familias</span>
|
|
|
<div class="vs-sample" data-shape="scoop"></div>
|
|
|
<span class="vs-cap">cut · scoop · …</span>
|
|
|
</div>
|
|
|
<div class="vs-col">
|
|
|
<span class="vs-h">+ anidado</span>
|
|
|
<div class="vs-sample vs-nest" data-shape="continuous" style="--shape-outer-radius: 28px">
|
|
|
<span data-shape="continuous" data-shape-nest></span>
|
|
|
</div>
|
|
|
<span class="vs-cap">concéntrico</span>
|
|
|
</div>
|
|
|
<div class="vs-col">
|
|
|
<span class="vs-h">+ eventful</span>
|
|
|
<button
|
|
|
class="vs-sample vs-press"
|
|
|
data-shape="continuous"
|
|
|
data-event-family={pressed === 'v' ? 'contact' : undefined}
|
|
|
data-event-phase={pressed === 'v' ? 'active' : undefined}
|
|
|
onanimationend={() => (pressed = null)}
|
|
|
onpointerdown={() => firePress('v')}
|
|
|
aria-label="pulsa"
|
|
|
></button>
|
|
|
<span class="vs-cap">pulsa · morfea</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
|
|
|
<footer class="footnote">
|
|
|
<p>
|
|
|
<strong>El primer squircle-como-token de la web.</strong> Continuidad + familias + anidado +
|
|
|
eventful como tokens abiertos — magnitud intacta en <code>--radius-*</code>, degradando al
|
|
|
arco donde no hay <code>corner-shape</code>. Config-driven + runtime
|
|
|
<code>applyShape()</code>. La continuidad solo existía en Apple (plataforma); el morph solo
|
|
|
en Material (ad-hoc). Aquí se reúnen, y son tuyos.
|
|
|
</p>
|
|
|
</footer>
|
|
|
</div>
|
|
|
|
|
|
<style>
|
|
|
.root {
|
|
|
min-block-size: 100vh;
|
|
|
background:
|
|
|
radial-gradient(130% 90% at 50% -15%, var(--color-surface-raised), transparent 55%),
|
|
|
var(--color-surface-default);
|
|
|
color: var(--color-content-primary);
|
|
|
font-family: var(--font-family-primary);
|
|
|
padding: clamp(1.5rem, 5vw, 5rem) clamp(1.25rem, 5vw, 6rem) 6rem;
|
|
|
--rule: var(--color-border-default);
|
|
|
}
|
|
|
|
|
|
.masthead { max-inline-size: 56rem; margin-block-end: clamp(3rem, 8vw, 6rem); }
|
|
|
.mast-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-block-end: 2.5rem; }
|
|
|
.kicker { margin: 0; font-family: var(--font-family-mono); font-size: var(--font-size-xs); letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-content-muted); }
|
|
|
.theme-toggle { font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-content-secondary); background: var(--color-surface-raised); border: 1px solid var(--rule); border-radius: 999px; padding: 0.5rem 1rem; cursor: pointer; }
|
|
|
.theme-toggle:hover { color: var(--color-content-primary); }
|
|
|
.mast-title { font-family: var(--font-family-display); font-size: var(--font-size-xxxl); font-weight: 600; line-height: 1; letter-spacing: -0.03em; margin: 0 0 1.25rem; text-wrap: balance; }
|
|
|
.mast-title em { font-style: italic; color: var(--color-primary-text, var(--color-content-primary)); }
|
|
|
.mast-lede { max-inline-size: 52ch; font-size: var(--font-size-lg); line-height: 1.5; color: var(--color-content-secondary); margin: 0; text-wrap: pretty; }
|
|
|
.mast-lede strong { color: var(--color-content-primary); font-weight: 600; }
|
|
|
|
|
|
.section { margin-block-end: clamp(3.5rem, 9vw, 7rem); }
|
|
|
.sec-head { margin-block-end: 2.5rem; }
|
|
|
.sec-title { font-family: var(--font-family-display); font-size: var(--font-size-xl); font-weight: 600; letter-spacing: -0.01em; margin: 0 0 0.5rem; }
|
|
|
.sec-title em { font-style: italic; color: var(--color-primary-text, var(--color-content-primary)); }
|
|
|
.sec-note { margin: 0; max-inline-size: 64ch; font-size: var(--font-size-sm); line-height: 1.55; color: var(--color-content-muted); }
|
|
|
.sec-note em { color: var(--color-content-primary); font-style: normal; font-weight: 600; }
|
|
|
code { font-family: var(--font-family-mono); font-size: 0.9em; color: var(--color-content-secondary); background: var(--color-surface-muted); padding: 0.1em 0.4em; border-radius: 4px; }
|
|
|
|
|
|
/* 1 · Taller */
|
|
|
.lab { display: grid; grid-template-columns: 1fr; gap: clamp(1.5rem, 4vw, 3rem); align-items: start; }
|
|
|
@media (min-width: 52rem) { .lab { grid-template-columns: 22rem 1fr; } }
|
|
|
|
|
|
.player {
|
|
|
inline-size: 100%;
|
|
|
max-inline-size: 22rem;
|
|
|
border-radius: var(--sample-radius);
|
|
|
background: var(--color-surface-raised);
|
|
|
border: 1px solid var(--rule);
|
|
|
box-shadow: var(--depth-overlay-shadow), var(--depth-overlay-halo);
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
.player-cover {
|
|
|
position: relative;
|
|
|
aspect-ratio: 16 / 10;
|
|
|
margin: var(--space-2);
|
|
|
/* radius comes from [data-shape-nest] (concentric) or .cover-naive — never set here, or the
|
|
|
scoped rule would beat the foundation's nest rule and the inset would stop being concentric */
|
|
|
background:
|
|
|
radial-gradient(60% 80% at 30% 20%, color-mix(in oklab, var(--color-primary-solid) 90%, white), transparent 70%),
|
|
|
radial-gradient(70% 90% at 80% 90%, #12a594, transparent 70%),
|
|
|
linear-gradient(145deg, var(--color-primary-solid), #2a1a4a);
|
|
|
display: grid;
|
|
|
place-items: center;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
.cover-naive { border-radius: var(--radius-xl); }
|
|
|
.player-play {
|
|
|
inline-size: 3.25rem;
|
|
|
aspect-ratio: 1;
|
|
|
border-radius: var(--sample-radius);
|
|
|
border: 0;
|
|
|
background: color-mix(in srgb, #000 28%, transparent);
|
|
|
backdrop-filter: blur(6px);
|
|
|
color: #fff;
|
|
|
font-size: var(--font-size-sm);
|
|
|
cursor: pointer;
|
|
|
display: grid;
|
|
|
place-items: center;
|
|
|
}
|
|
|
.player-play:hover { background: color-mix(in srgb, #000 40%, transparent); }
|
|
|
.player-eq { position: absolute; inset-block-end: 0.6rem; inset-inline-start: 0.7rem; display: flex; gap: 3px; align-items: flex-end; block-size: 1rem; opacity: 0; transition: opacity 200ms; }
|
|
|
.player-eq[data-on='true'] { opacity: 0.9; }
|
|
|
.player-eq i { inline-size: 3px; background: #fff; border-radius: 2px; animation: eq 900ms ease-in-out infinite; }
|
|
|
.player-eq i:nth-child(1) { block-size: 40%; animation-delay: -200ms; }
|
|
|
.player-eq i:nth-child(2) { block-size: 90%; animation-delay: -500ms; }
|
|
|
.player-eq i:nth-child(3) { block-size: 60%; animation-delay: -100ms; }
|
|
|
.player-eq i:nth-child(4) { block-size: 100%; animation-delay: -350ms; }
|
|
|
@keyframes eq { 0%, 100% { block-size: 25%; } 50% { block-size: 100%; } }
|
|
|
@media (prefers-reduced-motion: reduce) { .player-eq i { animation: none; } }
|
|
|
|
|
|
.player-body { padding: var(--space-1) var(--space-3) var(--space-3); display: flex; flex-direction: column; gap: var(--space-2-5); }
|
|
|
.player-head { display: flex; align-items: center; gap: 0.75rem; }
|
|
|
.player-avatar { inline-size: 2.25rem; aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; background: var(--color-primary-solid); color: var(--color-primary-on-solid, #fff); font-weight: 600; font-size: var(--font-size-sm); flex: none; }
|
|
|
.player-meta { display: flex; flex-direction: column; min-inline-size: 0; flex: 1; }
|
|
|
.player-title { font-family: var(--font-family-display); font-weight: 600; color: var(--color-content-primary); }
|
|
|
.player-artist { font-size: var(--font-size-xs); color: var(--color-content-muted); }
|
|
|
.player-tag { font-family: var(--font-family-mono); font-size: 0.62rem; letter-spacing: 0.06em; padding: 0.2rem 0.5rem; border-radius: var(--radius-sm); background: var(--color-surface-overlay); color: var(--color-content-secondary); border: 1px solid var(--rule); }
|
|
|
.player-track { block-size: 5px; border-radius: 999px; background: var(--color-surface-muted); overflow: hidden; }
|
|
|
.player-fill { display: block; inline-size: 42%; block-size: 100%; background: var(--color-primary-solid); }
|
|
|
.player-row { display: flex; gap: 0.5rem; }
|
|
|
.player-input { flex: 1; min-inline-size: 0; padding: 0.5rem 0.75rem; border-radius: var(--sample-radius); border: 1px solid var(--rule); background: var(--color-surface-default); color: var(--color-content-primary); font: inherit; font-size: var(--font-size-xs); outline: none; }
|
|
|
.player-input:focus { border-color: color-mix(in srgb, var(--color-primary-solid) 55%, var(--rule)); }
|
|
|
.player-add { inline-size: 2.1rem; border-radius: var(--sample-radius); border: 1px solid var(--rule); background: var(--color-surface-overlay); color: var(--color-content-primary); cursor: pointer; font-size: var(--font-size-md); }
|
|
|
.player-add:hover { background: var(--color-surface-muted); }
|
|
|
|
|
|
.panel { display: flex; flex-direction: column; gap: 1.5rem; padding: clamp(1.25rem, 3vw, 2rem); border-radius: var(--radius-lg); background: var(--color-surface-default); border: 1px solid var(--rule); }
|
|
|
.ctl { display: flex; flex-direction: column; gap: 0.65rem; }
|
|
|
.ctl-dim { opacity: 0.45; }
|
|
|
.ctl-check { flex-direction: row; align-items: center; gap: 0.6rem; cursor: pointer; }
|
|
|
.ctl-check input { accent-color: var(--color-primary-solid); }
|
|
|
.ctl-label { font-family: var(--font-family-mono); font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-content-muted); }
|
|
|
.ctl input[type='range'] { accent-color: var(--color-primary-solid); }
|
|
|
.ctl-val { font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-content-primary); }
|
|
|
.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
|
|
|
.chip { font-family: var(--font-family-mono); font-size: var(--font-size-xs); padding: 0.35rem 0.75rem; border-radius: 999px; cursor: pointer; background: var(--color-surface-raised); color: var(--color-content-secondary); border: 1px solid var(--rule); }
|
|
|
.chip:hover { color: var(--color-content-primary); }
|
|
|
.chip[data-active='true'] { background: var(--color-primary-solid); color: var(--color-primary-on-solid, #fff); border-color: var(--color-primary-solid); }
|
|
|
.panel-code { display: block; font-family: var(--font-family-mono); font-size: var(--font-size-xs); padding: 0.7rem 0.9rem; border-radius: var(--radius-md); background: var(--color-surface-muted); color: var(--color-content-secondary); word-break: break-all; }
|
|
|
|
|
|
/* 2 · De cerca */
|
|
|
.closeup { display: flex; flex-wrap: wrap; gap: clamp(1.5rem, 5vw, 4rem); justify-content: center; }
|
|
|
.cu { margin: 0; display: flex; flex-direction: column; gap: 1.25rem; align-items: center; }
|
|
|
.cu-box { inline-size: clamp(9rem, 26vw, 14rem); aspect-ratio: 1; border-radius: clamp(2.5rem, 7vw, 4.5rem); background: linear-gradient(145deg, var(--color-primary-solid), #12a594); }
|
|
|
.cu figcaption { font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-content-muted); }
|
|
|
.cu figcaption b { color: var(--color-content-primary); }
|
|
|
|
|
|
/* 3 · Familias */
|
|
|
.fam-row { display: flex; flex-wrap: wrap; gap: clamp(1rem, 4vw, 2.5rem); justify-content: center; }
|
|
|
.fam { margin: 0; display: flex; flex-direction: column; gap: 0.9rem; align-items: center; }
|
|
|
/* filled chips (no border / drop-shadow): a concave `scoop` casts shadow INTO its notches and
|
|
|
a 1px border seams at the concave corners — both read as broken. Flat fills render every
|
|
|
family cleanly and are the right home for cut/scoop anyway (chips/badges). */
|
|
|
.fam-chip { display: grid; place-items: center; min-inline-size: 6.5rem; padding: 0.9rem 1.6rem; border-radius: 16px; background: color-mix(in oklab, var(--color-primary-solid) 26%, var(--color-surface-overlay)); font-family: var(--font-family-mono); font-size: var(--font-size-sm); color: var(--color-content-primary); }
|
|
|
.fam figcaption { font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-content-muted); }
|
|
|
|
|
|
/* 4 · Ocurre */
|
|
|
.press-row { display: flex; flex-wrap: wrap; gap: 1.5rem; }
|
|
|
.press-btn {
|
|
|
font-family: var(--font-family-primary);
|
|
|
font-size: var(--font-size-md);
|
|
|
font-weight: 600;
|
|
|
padding: 1rem 2.25rem;
|
|
|
border-radius: 26px;
|
|
|
border: 1px solid color-mix(in srgb, var(--color-primary-solid) 50%, var(--rule));
|
|
|
background: linear-gradient(145deg, var(--color-surface-raised), var(--color-surface-overlay));
|
|
|
color: var(--color-content-primary);
|
|
|
box-shadow: var(--depth-raised-shadow);
|
|
|
cursor: pointer;
|
|
|
will-change: transform, border-radius;
|
|
|
}
|
|
|
.press-ctrl { opacity: 0.85; }
|
|
|
@media (prefers-reduced-motion: reduce) { .press-btn, .vs-press { animation: none !important; } }
|
|
|
|
|
|
/* 5 · Vs el resto */
|
|
|
.vs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 8rem), 1fr)); gap: clamp(1rem, 3vw, 2rem); }
|
|
|
.vs-col { display: flex; flex-direction: column; gap: 0.75rem; align-items: center; text-align: center; }
|
|
|
.vs-h { font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-content-primary); font-weight: 600; }
|
|
|
.vs-them .vs-h { color: var(--color-content-muted); }
|
|
|
.vs-sample { inline-size: 100%; aspect-ratio: 1; border-radius: 28px; background: linear-gradient(145deg, var(--color-primary-solid), #12a594); border: 0; padding: 0; }
|
|
|
.vs-them .vs-sample { background: linear-gradient(145deg, var(--color-surface-overlay), var(--color-surface-muted)); }
|
|
|
.vs-nest { background: var(--color-surface-overlay); display: grid; place-items: center; }
|
|
|
.vs-nest span { inline-size: 64%; aspect-ratio: 1; background: linear-gradient(145deg, var(--color-primary-solid), #12a594); }
|
|
|
.vs-press { cursor: pointer; will-change: transform, border-radius; }
|
|
|
.vs-cap { font-size: var(--font-size-xs); color: var(--color-content-muted); }
|
|
|
|
|
|
.footnote { max-inline-size: 60rem; padding-block-start: 2rem; border-block-start: 1px solid var(--rule); }
|
|
|
.footnote p { margin: 0; font-size: var(--font-size-sm); line-height: 1.6; color: var(--color-content-muted); text-wrap: pretty; }
|
|
|
.footnote strong { color: var(--color-content-primary); font-weight: 600; }
|
|
|
</style>
|