feat: rediseño «El documento» en curso, contacto real y enlaces externos

Primitivas y contenido del rediseño (escala tipográfica, Revelar,
MarcaSeccion, Seccion, Antetitulo, SimboloMarca, Resplandor, ClaridadHero,
sección Proceso de ocho etapas, lib/content.ts reestructurado en seis
secciones con alias para las viejas). Mecanismo y FormaTrabajar se retiran.

Encima, lo de esta sesión:
- recorrido: creeer vuelve a responder cada situación en vez de repetirla
  (el alias apuntaba respuesta a situacion); respuestas en plural. Créditos
  de las seis fotos de México.
- contacto: WhatsApp, email (con mailto:) y LinkedIn reales; iconos de las
  redes en el cierre y el footer (IconoRed, trazos de Simple Icons, CC0).
- enlaces: lo externo abre en otra pestaña con noopener y aviso para
  lectores de pantalla (lib/enlaces.ts); mailto y anclas se quedan.
- Proceso: las ocho tarjetas no aparecían nunca en móvil (amount 0.3 sobre
  una lista de ~3000px); ahora cada una se revela sola. El ≡ de la 08 ya no
  tapa un entregable, título equilibrado, etiqueta a 12px, sin elevar al
  hover lo que no es clicable.
- Disciplinas: la frase «No son la promesa — son los medios» gana peso y
  se agrupa con título e ilustración; sin cortes huérfanos en móvil.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
erikghandClaude Opus 5.5 committed 2026-09-30 11:27:20 -06:00
1 parent 3242a8bf71
commit 89e54a6e84
73 files changed
+5261 -592

No files matched your search

+66 -22
View File
@@ -8,8 +8,9 @@ import { VIEWBOX_SIMBOLO, LINEAS_SIMBOLO } from '@/lib/simbolo';
// Eighteen crossing lines converge in three groups; in the "completa" variant
// each group collapses onto one of the three bars of the ≡, so the mark is
// literally produced by the resolution of the tangle rather than placed next
// to it. The "hero" variant stops at convergence and leaves the tension open —
// FraseAncla pays it off further down the page.
// to it. The "hero" variant resolves the chaos into a skyline silhouette —
// structure emerging from disorder, what creeer builds for its clients.
// FraseAncla pays off the full ≡ resolution further down the page.
type Variant = 'completa' | 'hero';
@@ -40,6 +41,55 @@ const DISPERSAS = [
// converge — many/disordered becomes few/aligned, per the manual.
const SOBREVIVE = [0, 6, 12];
// Skyline destination for the hero variant. Eighteen lines form a city
// silhouette: vertical segments are building walls, horizontal segments
// are rooftops and the ground line. The skyline reads left to right as
// buildings of increasing height — chaos becoming structure, the visual
// promise of what creeer delivers.
//
// ViewBox: 64×64. Ground at y=58. Tallest building peaks at y=10.
//
// ┌──┐
// ┌──┐ │ │ ┌─┐
// │ │ │ │ │ │┌──┐
// ┌─┤ │ │ │ │ ││ │
// │ │ │ │ │ │ ││ │
// └─┴──┴─┴──┴─┴─┴┴──┘
//
const SKYLINE = [
// Building 1 (left, medium) — x: 4–14, top: 28
{ x1: 4, y1: 58, x2: 4, y2: 28 }, // 0: left wall
{ x1: 4, y1: 28, x2: 14, y2: 28 }, // 1: rooftop
{ x1: 14, y1: 28, x2: 14, y2: 58 }, // 2: right wall
// Building 2 (tall) — x: 18–30, top: 12
{ x1: 18, y1: 58, x2: 18, y2: 12 }, // 3: left wall
{ x1: 18, y1: 12, x2: 30, y2: 12 }, // 4: rooftop
{ x1: 30, y1: 12, x2: 30, y2: 58 }, // 5: right wall
// Building 3 (short) — x: 34–40, top: 32
{ x1: 34, y1: 58, x2: 34, y2: 32 }, // 6: left wall
{ x1: 34, y1: 32, x2: 40, y2: 32 }, // 7: rooftop
{ x1: 40, y1: 32, x2: 40, y2: 58 }, // 8: right wall
// Building 4 (medium-tall) — x: 42–54, top: 20
{ x1: 42, y1: 58, x2: 42, y2: 20 }, // 9: left wall
{ x1: 42, y1: 20, x2: 54, y2: 20 }, // 10: rooftop
{ x1: 54, y1: 20, x2: 54, y2: 58 }, // 11: right wall
// Small tower on building 1 — x: 7–11, top: 22
{ x1: 7, y1: 28, x2: 7, y2: 22 }, // 12: left wall
{ x1: 7, y1: 22, x2: 11, y2: 22 }, // 13: rooftop
{ x1: 11, y1: 22, x2: 11, y2: 28 }, // 14: right wall
// Ground line segments
{ x1: 2, y1: 58, x2: 30, y2: 58 }, // 15: ground left
{ x1: 30, y1: 58, x2: 56, y2: 58 }, // 16: ground right
// Antenna on tallest building — a small vertical detail
{ x1: 24, y1: 12, x2: 24, y2: 6 }, // 17: antenna
];
const EASE = [0.22, 1, 0.36, 1] as const;
export function SecuenciaClaridad({
@@ -54,26 +104,23 @@ export function SecuenciaClaridad({
const completa = variant === 'completa';
// Where each line ends up. In "completa" the survivors land exactly on the
// symbol's own coordinates; in "hero" they merely tighten toward their
// group's axis without ever aligning.
// symbol's own coordinates; in "hero" the lines form a skyline silhouette.
const destino = (i: number) => {
if (!completa) {
// Hero variant: lines converge into the skyline shape.
const s = SKYLINE[i];
return {
x1: s.x1,
y1: s.y1,
x2: s.x2,
y2: s.y2,
opacity: i === 17 ? 0.7 : 0.85, // antenna slightly dimmer
};
}
// Completa variant: survivors land on the ≡ bars.
const { barra } = DISPERSAS[i];
const linea = LINEAS_SIMBOLO[barra];
const sobrevive = SOBREVIVE.includes(i);
if (!completa) {
const eje = linea.y1;
const d = DISPERSAS[i];
// Pulled a good way further in than it used to be: at a third of the way
// the tangle still read as a scratched-out scribble instead of as lines
// finding their axis. It must arrive close to aligned and stop short.
return {
x1: d.x1 + (26 - d.x1) * 0.5,
y1: d.y1 + (eje - d.y1) * 0.7,
x2: d.x2 + (38 - d.x2) * 0.5,
y2: d.y2 + (eje - d.y2) * 0.7,
opacity: sobrevive ? 0.95 : 0.28,
};
}
return {
x1: linea.x1,
y1: linea.y1,
@@ -87,8 +134,7 @@ export function SecuenciaClaridad({
completa && SOBREVIVE.includes(i) ? LINEAS_SIMBOLO[DISPERSAS[i].barra].grosor : 1.5;
// Reduced motion renders plain <line> elements: motion.line would apply its
// own dash scaffolding and leave the drawing invisible (see the same trap in
// IlustracionInflexion).
// own dash scaffolding and leave the drawing invisible.
if (reduced) {
return (
<svg ref={ref} viewBox={VIEWBOX_SIMBOLO} className={className} aria-hidden="true" focusable="false">
@@ -118,8 +164,6 @@ export function SecuenciaClaridad({
<svg ref={ref} viewBox={VIEWBOX_SIMBOLO} className={className} aria-hidden="true" focusable="false">
{DISPERSAS.map(({ barra: _barra, ...inicio }, i) => {
const d = destino(i);
// `barra` is grouping metadata, not an SVG attribute — destructured out
// so it never reaches the DOM.
const reposo = { ...inicio, opacity: 0.55, strokeWidth: 1.5 };
return (
<motion.line