feat(diseño): los diez arreglos de la revisión visual
Revisada la página con Chromium a 1440x900 y 390x844 en nueve alturas de scroll, y verificado cada cambio contra capturas nuevas. - El ≡ deja de leerse como icono de menú. lib/simbolo.ts se anunciaba como single source of truth pero no coincidía con Wordmark.tsx, que traza la marca con las proporciones medidas del Manual: barra de largo 5.919× su grosor, hueco de 2×, extremos de píldora. Ahora se derivan de ahí. De paso, las líneas se meten medio grosor por cada extremo: el remate redondo alargaba el trazo un grosor entero sobre la barra que debía reproducir. - Banda: 12px en escritorio y 7px en móvil vía CSS (14px era el 3,6% de una pantalla de 390px y partía los párrafos), opacidad al 18%, y muelle de 90/30 a 210/40 — sobreamortiguado tardaba ~2s en asentar y la punta se arrastraba a media pantalla. El punto suelto que aparecía centrado arriba al cargar era el remate redondo pintándose en el origen con longitud cero: ahora la opacidad sigue al avance. - Ritmo vertical un 25-30% más apretado en las diez secciones. La página pasa de 8.061 a 7.457px sin tocar contenido. - Números 01-06: de marca de agua de 48px al 6% (que chocaba con títulos y reglas) a índice dorado sentado sobre la regla. - Hero: los dos CTA al mismo ancho en móvil, el patrón de puntos fuera del logotipo, y la secuencia visible en todos los tamaños — oculta bajo lg dejaba el hero del móvil sin ninguna pieza gráfica. La convergencia de la variante "hero" se cierra más para que se lea como líneas buscando su eje y no como un garabato tachado. - Estratega: fuera la retícula de puntos del retrato, que parecía el recuadro de imagen rota del navegador; la etiqueta del 30+ cabía en menos de lo que mide "construyendo" y salía en tres líneas. - El nudo de Dolores, más pequeño y con algo más de contraste. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
174fcb855a
commit
fa86605b39
15 files changed
+135
-52
No files matched your search
@@ -13,7 +13,7 @@ export function Cierre() {
|
||||
return (
|
||||
<section id="contacto" className="bg-azul-profundo text-white scroll-mt-24 relative overflow-hidden">
|
||||
<FondoPuntos className="top-12 -left-16 w-72 md:w-[30rem] text-dorado/25" distance={36} />
|
||||
<Container className="relative py-24 md:py-32 text-center">
|
||||
<Container className="relative py-16 md:py-24 text-center">
|
||||
<motion.div variants={staggerContainer} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
className="flex flex-col items-center">
|
||||
<motion.div variants={fadeInUp}><Wordmark size="lg" onDark showTagline /></motion.div>
|
||||
|
||||
@@ -19,7 +19,7 @@ export function ComoEmpezar() {
|
||||
const desplazamiento = useTransform(scrollYProgress, [0, 1], [20, -20]);
|
||||
return (
|
||||
<section className="bg-white">
|
||||
<Container className="py-24 md:py-32 grid gap-12 md:grid-cols-[1fr_auto] md:items-center">
|
||||
<Container className="py-16 md:py-24 grid gap-12 md:grid-cols-[1fr_auto] md:items-center">
|
||||
<motion.div variants={staggerContainer} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}>
|
||||
<motion.p variants={fadeInUp} className="text-xs tracking-[0.3em] uppercase font-black text-dorado">{comoEmpezar.eyebrow}</motion.p>
|
||||
<motion.h2 variants={fadeInUp} className="mt-4 font-sans font-black text-seccion text-azul-profundo max-w-xl">{comoEmpezar.title}</motion.h2>
|
||||
|
||||
@@ -13,7 +13,7 @@ export function Disciplinas() {
|
||||
const reduced = usePrefersReducedMotion();
|
||||
return (
|
||||
<section className="bg-white">
|
||||
<Container className="py-24 md:py-32">
|
||||
<Container className="py-16 md:py-24">
|
||||
<motion.p variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
className="text-xs tracking-[0.3em] uppercase font-black text-dorado">{disciplinas.eyebrow}</motion.p>
|
||||
<motion.h2 variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
|
||||
@@ -11,8 +11,11 @@ export function Dolores() {
|
||||
const reduced = usePrefersReducedMotion();
|
||||
return (
|
||||
<section className="bg-white relative overflow-hidden">
|
||||
<IlustracionNudo className="pointer-events-none select-none absolute top-0 left-1/2 -translate-x-1/2 w-64 md:w-[28rem] text-azul-profundo/[0.08]" />
|
||||
<Container className="relative py-24 md:py-32">
|
||||
{/* Smaller and a touch stronger than it was: sprawling at 8% across the
|
||||
whole title it read as a smudge over the headline rather than as a
|
||||
knot. Stays centred so the conductor thread runs through it. */}
|
||||
<IlustracionNudo className="pointer-events-none select-none absolute top-0 left-1/2 -translate-x-1/2 w-56 md:w-80 text-azul-profundo/[0.11]" />
|
||||
<Container className="relative py-16 md:py-24">
|
||||
<motion.p variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
className="text-xs tracking-[0.3em] uppercase font-black text-dorado">{dolores.eyebrow}</motion.p>
|
||||
<motion.h2 variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use client';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Container } from '@/components/primitives/Container';
|
||||
import { PatronPuntos } from '@/components/primitives/PatronPuntos';
|
||||
import { Wordmark } from '@/components/primitives/Wordmark';
|
||||
import { ContadorNumero } from '@/components/primitives/ContadorNumero';
|
||||
import { MarcoRetrato } from '@/components/primitives/MarcoRetrato';
|
||||
@@ -12,16 +11,20 @@ export function Estratega() {
|
||||
const reduced = usePrefersReducedMotion();
|
||||
return (
|
||||
<section className="bg-gris-claro">
|
||||
<Container className="py-24 md:py-32">
|
||||
<Container className="py-16 md:py-24">
|
||||
<motion.div variants={staggerContainer} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
className="grid gap-12 md:grid-cols-[auto_1fr] md:items-center">
|
||||
{/* TODO dueña: real portrait. The frame is built to take it as-is —
|
||||
drop an <Image fill /> in place of the placeholder below. */}
|
||||
<motion.div variants={fadeInUp}>
|
||||
<MarcoRetrato>
|
||||
{/* Reads as a brand plate, not as a broken image. The dot grid
|
||||
that used to sit behind the wordmark looked like the
|
||||
checkerboard a browser shows for a picture that failed to
|
||||
load; the ≡ alone, meanwhile, reads as a hamburger menu once
|
||||
it stands by itself in a circle. The wordmark is neither. */}
|
||||
<div className="w-full h-full bg-azul-profundo grid place-items-center" role="img" aria-label="Retrato de la estratega — pendiente">
|
||||
<PatronPuntos rows={4} cols={7} className="absolute inset-0 m-auto w-[150%] h-auto text-white/15" />
|
||||
<span className="relative"><Wordmark size="sm" onDark /></span>
|
||||
<Wordmark size="md" onDark />
|
||||
</div>
|
||||
</MarcoRetrato>
|
||||
</motion.div>
|
||||
@@ -32,7 +35,9 @@ export function Estratega() {
|
||||
<motion.h2 variants={fadeInUp} className="mt-4 font-sans font-black text-seccion text-azul-profundo">{estratega.title}</motion.h2>
|
||||
<motion.div variants={fadeInUp} className="mt-6 flex items-baseline gap-3">
|
||||
<ContadorNumero hasta={30} sufijo="+" className="font-sans font-black text-5xl md:text-6xl text-dorado leading-none" />
|
||||
<p className="text-xs uppercase tracking-[0.2em] text-gris-medio font-semibold max-w-[8rem] leading-tight">años construyendo marcas</p>
|
||||
{/* 8rem was narrower than the word "construyendo" itself, which
|
||||
broke the label into three ragged lines beside the number. */}
|
||||
<p className="text-xs uppercase tracking-[0.14em] text-gris-medio font-semibold max-w-[12rem] leading-snug">años construyendo marcas</p>
|
||||
</motion.div>
|
||||
<motion.p variants={fadeInUp} className="mt-6 text-lg text-gris-medio leading-relaxed max-w-2xl">{estratega.bio}</motion.p>
|
||||
<motion.blockquote variants={fadeInUp} className="mt-6 font-sans italic text-xl md:text-2xl text-azul-profundo border-l-4 border-dorado pl-4">
|
||||
|
||||
@@ -11,7 +11,7 @@ export function FraseAncla() {
|
||||
const reduced = usePrefersReducedMotion();
|
||||
return (
|
||||
<section className="bg-azul-profundo relative overflow-hidden">
|
||||
<Container className="relative py-28 md:py-40 text-center max-w-5xl">
|
||||
<Container className="relative py-20 md:py-28 text-center max-w-5xl">
|
||||
<motion.div variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
className="flex justify-center">
|
||||
{/* Payoff for the tension the hero leaves open: here the lines do
|
||||
|
||||
@@ -23,10 +23,13 @@ export function Hero({ variant = 'editorial' }: { variant?: Variant }) {
|
||||
|
||||
return (
|
||||
<section className="bg-white relative overflow-hidden">
|
||||
<FondoPuntos className="top-24 -right-16 w-72 md:w-[28rem] text-azul-profundo/10" interactivo />
|
||||
{/* Kept clear of the wordmark on narrow screens: at 390px the md field
|
||||
reached back across the logotype and the tagline, so the pattern read
|
||||
as collision rather than texture. */}
|
||||
<FondoPuntos className="top-80 -right-20 w-56 md:top-24 md:-right-16 md:w-[28rem] text-azul-profundo/10" interactivo />
|
||||
<FondoPuntos className="bottom-16 -left-20 w-64 md:w-96 text-dorado/20" distance={28} rows={2} />
|
||||
<Container className="relative min-h-[88vh] flex items-center py-24">
|
||||
<div className="grid gap-14 lg:grid-cols-[1.1fr_0.9fr] lg:items-center w-full">
|
||||
<Container className="relative min-h-[80vh] lg:min-h-[88vh] flex items-center py-16 md:py-24">
|
||||
<div className="grid gap-8 lg:gap-14 lg:grid-cols-[1.1fr_0.9fr] lg:items-center w-full">
|
||||
<motion.div variants={staggerContainer} initial="hidden" animate="visible" {...motionProps(reduced)}
|
||||
className="min-w-0 flex flex-col items-center text-center lg:items-start lg:text-left">
|
||||
<motion.div variants={fadeInUp}><Wordmark size="xl" showTagline /></motion.div>
|
||||
@@ -44,16 +47,21 @@ export function Hero({ variant = 'editorial' }: { variant?: Variant }) {
|
||||
]}
|
||||
/>
|
||||
</motion.h1>
|
||||
<motion.div variants={fadeInUp} className="mt-10 flex flex-col md:flex-row items-center gap-4">
|
||||
<CTA href="#contacto" label={hero.cta} variant="light" className="md:whitespace-nowrap" />
|
||||
<CTA href="#mecanismo" label={hero.ctaSecundario} variant="ghost" className="md:whitespace-nowrap" />
|
||||
{/* Full width while stacked: at their natural widths the two CTAs
|
||||
came out ragged and unequal, which read as an accident rather
|
||||
than as hierarchy. */}
|
||||
<motion.div variants={fadeInUp} className="mt-10 w-full flex flex-col md:flex-row items-stretch md:items-center md:w-auto gap-4">
|
||||
<CTA href="#contacto" label={hero.cta} variant="light" className="text-center md:whitespace-nowrap" />
|
||||
<CTA href="#mecanismo" label={hero.ctaSecundario} variant="ghost" className="text-center md:whitespace-nowrap" />
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
{/* Complexity → focus, left unresolved: the hero poses the tension
|
||||
and FraseAncla pays it off by resolving into the ≡. */}
|
||||
and FraseAncla pays it off by resolving into the ≡. Shown on every
|
||||
breakpoint — hidden below lg it left the phone hero with no piece
|
||||
of the brand's own graphic language at all. */}
|
||||
<motion.div variants={fadeInUp} initial="hidden" animate="visible" {...motionProps(reduced)}
|
||||
className="hidden lg:block min-w-0">
|
||||
<SecuenciaClaridad variant="hero" className="w-full max-w-md mx-auto text-azul-profundo" />
|
||||
className="min-w-0">
|
||||
<SecuenciaClaridad variant="hero" className="w-32 lg:w-full max-w-md mx-auto text-azul-profundo" />
|
||||
</motion.div>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@@ -24,7 +24,7 @@ export function Mecanismo() {
|
||||
>
|
||||
<FondoFoto src="/images/mecanismo-bg.jpg" className="inset-0 opacity-25" wash="bg-azul-profundo/80" />
|
||||
</motion.div>
|
||||
<Container className="relative py-24 md:py-32">
|
||||
<Container className="relative py-16 md:py-24">
|
||||
<motion.p variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
className="text-xs tracking-[0.3em] uppercase font-black text-dorado">{mecanismo.eyebrow}</motion.p>
|
||||
<motion.h2 variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function ParaQuien() {
|
||||
const reduced = usePrefersReducedMotion();
|
||||
return (
|
||||
<section className="bg-white relative overflow-hidden">
|
||||
<Container className="relative pt-24 md:pt-32 pb-12 md:pb-16 md:flex md:items-center md:justify-between md:gap-12">
|
||||
<Container className="relative pt-16 md:pt-24 pb-8 md:pb-12 md:flex md:items-center md:justify-between md:gap-12">
|
||||
<motion.h2 variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
className="font-sans font-black text-seccion text-azul-profundo max-w-3xl">{paraQuien.title}</motion.h2>
|
||||
<motion.div variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
|
||||
@@ -12,7 +12,10 @@ import { fadeInUp, staggerContainer, viewportOnce, usePrefersReducedMotion, moti
|
||||
function Tarjeta({ n, name, desc }: { n: number; name: string; desc: string }) {
|
||||
return (
|
||||
<TarjetaSpotlight className="relative h-full rounded-md border-t-2 border-dorado pt-5 pl-1 pr-1 pb-1 overflow-visible">
|
||||
<span aria-hidden="true" className="pointer-events-none absolute -top-2 right-0 font-sans font-black text-5xl text-azul-profundo/[0.06] leading-none select-none">
|
||||
{/* An index, not a watermark. At 48px and 6% opacity these collided with
|
||||
the titles and with the gold rule while carrying no contrast of their
|
||||
own; sat on the rule they encode the sequence and stay out of the way. */}
|
||||
<span aria-hidden="true" className="pointer-events-none absolute -top-1.5 right-0 bg-gris-claro pl-2 font-sans font-black text-xs tracking-[0.2em] text-dorado leading-none select-none">
|
||||
{String(n).padStart(2, '0')}
|
||||
</span>
|
||||
<h3 className="relative font-sans font-bold text-xl text-azul-profundo">{name}</h3>
|
||||
@@ -26,7 +29,7 @@ export function PuntosInflexion() {
|
||||
return (
|
||||
<section className="bg-gris-claro relative overflow-hidden">
|
||||
<FondoPuntos className="-bottom-6 -right-12 w-80 md:w-[32rem] text-azul-profundo/10" distance={32} />
|
||||
<Container className="relative py-24 md:py-32">
|
||||
<Container className="relative py-16 md:py-24">
|
||||
<div className="flex flex-col md:flex-row md:items-center md:justify-between md:gap-12">
|
||||
<div>
|
||||
<motion.p variants={fadeInUp} initial="hidden" whileInView="visible" viewport={viewportOnce} {...motionProps(reduced)}
|
||||
|
||||
Reference in new issue
Block a user