diff --git a/web/routes/temas/forma/+page.svelte b/web/routes/temas/forma/+page.svelte index f0a65e479..7ce285fa8 100644 --- a/web/routes/temas/forma/+page.svelte +++ b/web/routes/temas/forma/+page.svelte @@ -1,20 +1,20 @@ @@ -59,126 +62,219 @@

La esquina, repensada

- Toda la web reduce la forma a un número: border-radius, un arco circular. La - esquina tiene más ejes — continuidad, familia, - armonía y tensión. Aquí la forma es un canal, y también - ocurre. + Toda la web reduce la forma a un número: border-radius, un arco. La esquina + tiene más ejes — continuidad, familia, + armonía y tensión. Aquí la forma es un canal: tócala y mira + la misma UI cambiar de carácter.

- +
-

Continuidad

+

El taller

- El arco circular tiene un quiebre donde el lado encuentra la curva. El squircle - (superelipse) fluye sin costura — lo que hace premium a iOS. En Eidos es un token: - --shape-smoothing. Muévelo. + Una tarjeta real. Cambia familia, suavizado, magnitud o el anidado concéntrico y + todo 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.)

-
-
-
-
-
rounded · arco · superellipse(1)
-
-
-
-
continuous · superellipse({smoothing.toFixed(2)})
-
+ +
+ +
+
+ + +
+
+
+ N +
+ Continuum + Nocturne Ensemble +
+ FLAC +
+
+
+ + +
+
-
-
- + +
+
+

De cerca

+

+ El arco circular tiene un quiebre donde el lado encuentra la curva. El squircle + (superelipse) fluye sin costura — lo que hace premium a iOS. Misma magnitud, distinta + continuidad. +

+
+
+
+
+
rounded · superellipse(1) — arco
+
+
+
+
continuous · superellipse(2) — squircle
+
+
+
+ +

Familias

Una sola mecánica (corner-shape vía data-shape) cubre cuatro - familias perceptuales. Material solo tiene cut; Apple solo - continuous. Aquí, las cuatro. + familias. Material solo tiene cut; Apple solo continuous. Aquí, + la misma etiqueta en las cuatro:

-
+
{#each FAMILIES as f}
-
-
{f.label}{f.note}
+ etiqueta +
{f.label}
{/each}
- +
-

Armonía anidada

+

La forma ocurre

- Radios concéntricos: el interior = exterior − gap, así las esquinas quedan - paralelas. Sin esto, una tarjeta dentro de otra desencaja. Solo SwiftUI lo tiene; - aquí es data-shape-nest. Apágalo y míralo romperse. + Púlsalos: la esquina se afirma 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 rounded es el control: no morfea.

-
-
-
- {#if nest} -
-
- {:else} -
-
- {/if} -
-
- +
+ +
- +
-

La forma ocurre

+

Lo que solo hace Eidos

- Púlsalo: la esquina se afirma bajo el dedo (la continuidad se cuadra un instante) - — a la vez que baja de escala y se aplana la sombra. Un solo evento, tres canales: la - firma cross-modal. (Solo el botón continuous morfea; el otro es el - control.) + El campo entero (Tailwind · shadcn · Chakra · Mantine · Ant · Radix · Carbon · Fluent · + Spectrum · Polaris) se queda en la primera columna.

-
- - +
+
+ todos los demás +
+ escala + arco + estático +
+
+ + continuidad +
+ squircle tokenizado +
+
+ + familias +
+ cut · scoop · … +
+
+ + anidado +
+ +
+ concéntrico +
+
+ + eventful + + pulsa · morfea +
@@ -202,8 +298,7 @@ .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: 50ch; font-size: var(--font-size-lg); line-height: 1.5; color: var(--color-content-secondary); margin: 0; text-wrap: pretty; } - .mast-lede i { font-style: italic; } + .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); } @@ -214,38 +309,99 @@ .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 · Continuidad */ - .cont { display: grid; grid-template-columns: 1fr; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; } - @media (min-width: 46rem) { .cont { grid-template-columns: 1.2fr 1fr; } } - .cont-pair { display: flex; gap: clamp(1.5rem, 4vw, 3rem); justify-content: center; } - .cont-item { margin: 0; display: flex; flex-direction: column; gap: 1rem; align-items: center; } - .cont-box { inline-size: clamp(8rem, 20vw, 11rem); aspect-ratio: 1; border-radius: 38px; background: linear-gradient(145deg, var(--color-primary-solid), color-mix(in oklab, var(--color-primary-solid) 40%, #12a594)); } - .cont-item figcaption { font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-content-muted); } - .cont-item figcaption b { color: var(--color-content-primary); font-weight: 600; } - .dial { display: flex; flex-direction: column; gap: 1rem; } - .dial-row { display: flex; align-items: center; gap: 1rem; } - .dial-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); inline-size: 5rem; } - .dial-row input { flex: 1; accent-color: var(--color-primary-solid); } - .dial-val { font-family: var(--font-family-mono); font-size: var(--font-size-sm); color: var(--color-content-primary); inline-size: 3rem; text-align: end; } - .dial-code { display: block; font-family: var(--font-family-mono); font-size: var(--font-size-xs); padding: 0.85rem 1rem; border-radius: var(--radius-md); background: var(--color-surface-muted); color: var(--color-content-secondary); word-break: break-all; } + /* 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; } } - /* 2 · Familias */ - .fams { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); gap: clamp(1.25rem, 3vw, 2rem); } - .fam { margin: 0; display: flex; flex-direction: column; gap: 1rem; align-items: center; } - .fam-box { inline-size: 100%; aspect-ratio: 1.4; border-radius: 32px; background: linear-gradient(145deg, var(--color-surface-raised), var(--color-surface-overlay)); border: 1px solid var(--rule); box-shadow: var(--depth-raised-shadow); } - .fam figcaption { display: flex; flex-direction: column; gap: 0.2rem; text-align: center; } - .fam figcaption b { font-family: var(--font-family-mono); font-size: var(--font-size-sm); color: var(--color-content-primary); } - .fam figcaption span { font-size: var(--font-size-xs); color: var(--color-content-muted); } + .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); } - /* 3 · Anidado */ - .nest-stage { display: flex; flex-direction: column; gap: 1.5rem; align-items: center; } - .nest-outer { inline-size: min(30rem, 100%); padding: var(--space-2); border-radius: var(--radius-xl); background: var(--color-surface-overlay); border: 1px solid var(--rule); box-shadow: var(--depth-overlay-shadow); } - .nest-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); } - .nest-inner { aspect-ratio: 1.6; background: linear-gradient(145deg, var(--color-primary-solid), color-mix(in oklab, var(--color-primary-solid) 55%, transparent)); } - /* naive = fixed inner radius that ignores the outer/gap → corners visibly desync */ - .nest-naive { border-radius: var(--radius-xl); } - .nest-toggle { display: flex; align-items: center; gap: 0.6rem; font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-content-muted); cursor: pointer; } - .nest-toggle input { accent-color: var(--color-primary-solid); } + .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; } + .fam-chip { display: grid; place-items: center; min-inline-size: 6.5rem; padding: 1.1rem 1.5rem; border-radius: 18px; background: linear-gradient(145deg, var(--color-surface-raised), var(--color-surface-overlay)); border: 1px solid var(--rule); box-shadow: var(--depth-raised-shadow); 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; } @@ -253,8 +409,8 @@ font-family: var(--font-family-primary); font-size: var(--font-size-md); font-weight: 600; - padding: 1rem 2rem; - border-radius: 28px; + 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); @@ -263,7 +419,19 @@ will-change: transform, border-radius; } .press-ctrl { opacity: 0.85; } - @media (prefers-reduced-motion: reduce) { .press-btn { animation: none !important; } } + @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; }