feat(hero): la metáfora de marca sustituye al carrusel de dolores
This commit is contained in:
1 parent
bd16de2aa3
commit
a03b6c1f92
2 files changed
+17
-22
No files matched your search
@@ -5,10 +5,9 @@ import { Wordmark } from '@/components/primitives/Wordmark';
|
|||||||
import { CTA } from '@/components/primitives/CTA';
|
import { CTA } from '@/components/primitives/CTA';
|
||||||
import { Container } from '@/components/primitives/Container';
|
import { Container } from '@/components/primitives/Container';
|
||||||
import { FondoPuntos } from '@/components/primitives/FondoPuntos';
|
import { FondoPuntos } from '@/components/primitives/FondoPuntos';
|
||||||
import { Carrusel } from '@/components/primitives/Carrusel';
|
import { SecuenciaClaridad } from '@/components/primitives/SecuenciaClaridad';
|
||||||
import { TextoDesenfoque } from '@/components/primitives/TextoDesenfoque';
|
import { TextoDesenfoque } from '@/components/primitives/TextoDesenfoque';
|
||||||
import { TarjetaSpotlight } from '@/components/primitives/TarjetaSpotlight';
|
import { hero } from '@/lib/content';
|
||||||
import { hero, dolores } from '@/lib/content';
|
|
||||||
import { fadeInUp, staggerContainer, usePrefersReducedMotion, motionProps } from '@/lib/motion';
|
import { fadeInUp, staggerContainer, usePrefersReducedMotion, motionProps } from '@/lib/motion';
|
||||||
|
|
||||||
type Variant = 'hormozi' | 'editorial';
|
type Variant = 'hormozi' | 'editorial';
|
||||||
@@ -25,7 +24,7 @@ export function Hero({ variant = 'editorial' }: { variant?: Variant }) {
|
|||||||
return (
|
return (
|
||||||
<section className="bg-white relative overflow-hidden">
|
<section className="bg-white relative overflow-hidden">
|
||||||
<FondoPuntos className="top-24 -right-16 w-72 md:w-[28rem] text-azul-profundo/10" interactivo />
|
<FondoPuntos className="top-24 -right-16 w-72 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} 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">
|
<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">
|
<div className="grid gap-14 lg:grid-cols-[1.1fr_0.9fr] lg:items-center w-full">
|
||||||
<motion.div variants={staggerContainer} initial="hidden" animate="visible" {...motionProps(reduced)}
|
<motion.div variants={staggerContainer} initial="hidden" animate="visible" {...motionProps(reduced)}
|
||||||
@@ -50,22 +49,11 @@ export function Hero({ variant = 'editorial' }: { variant?: Variant }) {
|
|||||||
<CTA href="#mecanismo" label={hero.ctaSecundario} variant="ghost" className="md:whitespace-nowrap" />
|
<CTA href="#mecanismo" label={hero.ctaSecundario} variant="ghost" className="md:whitespace-nowrap" />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
{/* Rota las frases textuales de `dolores` — quien llega al hero se ve
|
{/* Complejidad → Enfoque, sin resolver: el hero plantea la tensión y
|
||||||
reflejado antes de haber bajado a leer la sección completa. */}
|
FraseAncla la paga resolviendo en el ≡. */}
|
||||||
<motion.div variants={fadeInUp} initial="hidden" animate="visible" {...motionProps(reduced)}
|
<motion.div variants={fadeInUp} initial="hidden" animate="visible" {...motionProps(reduced)}
|
||||||
className="hidden lg:block min-w-0">
|
className="hidden lg:block min-w-0">
|
||||||
<Carrusel
|
<SecuenciaClaridad variant="hero" className="w-full max-w-md mx-auto text-azul-profundo" />
|
||||||
ariaLabel="Lo que sienten nuestros clientes"
|
|
||||||
autoplayMs={4500}
|
|
||||||
slides={dolores.quotes.map((quote) => (
|
|
||||||
<TarjetaSpotlight key={quote} className="rounded-2xl border border-azul-profundo/10 bg-white shadow-xl shadow-azul-profundo/5 p-8 lg:p-10 min-h-[15rem] flex flex-col justify-center">
|
|
||||||
<p className="text-xs uppercase tracking-[0.3em] font-semibold text-dorado">lo que escuchamos</p>
|
|
||||||
<blockquote className="mt-4 font-sans italic text-xl lg:text-2xl leading-snug text-azul-profundo">
|
|
||||||
<span className="text-dorado not-italic">“</span>{quote}<span className="text-dorado not-italic">”</span>
|
|
||||||
</blockquote>
|
|
||||||
</TarjetaSpotlight>
|
|
||||||
))}
|
|
||||||
/>
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -25,9 +25,16 @@ describe('<Hero />', () => {
|
|||||||
const { container } = render(<Hero variant="editorial" />);
|
const { container } = render(<Hero variant="editorial" />);
|
||||||
expect(container.textContent).not.toMatch(/cupos|cohorte|generación fundadora/i);
|
expect(container.textContent).not.toMatch(/cupos|cohorte|generación fundadora/i);
|
||||||
});
|
});
|
||||||
it('mirrors the client\'s own words back in a rotating carousel', () => {
|
it('does not pre-empt the Dolores section with its own copy', () => {
|
||||||
render(<Hero variant="editorial" />);
|
const { container } = render(<Hero variant="editorial" />);
|
||||||
expect(screen.getByRole('group', { name: /lo que sienten nuestros clientes/i })).toBeInTheDocument();
|
// The hero used to rotate the same four quotes that Dolores renders in
|
||||||
expect(screen.getByText(/Trabajo más y gano casi lo mismo/i)).toBeInTheDocument();
|
// full further down. Duplicating them spent the emotional beat early and
|
||||||
|
// competed with the headline.
|
||||||
|
expect(container.textContent).not.toMatch(/Trabajo más y gano casi lo mismo/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('carries the brand metaphor as its visual anchor', () => {
|
||||||
|
const { container } = render(<Hero variant="editorial" />);
|
||||||
|
expect(container.querySelectorAll('svg').length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user