feat: FraseAncla section (02) — anchor quote
This commit is contained in:
1 parent
ccfcf71491
commit
d2fe1fcf64
5 files changed
+63
-1
No files matched your search
@@ -1,9 +1,11 @@
|
|||||||
import { Hero } from '@/components/sections/Hero';
|
import { Hero } from '@/components/sections/Hero';
|
||||||
|
import { FraseAncla } from '@/components/sections/FraseAncla';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<Hero variant="editorial" />
|
<Hero variant="editorial" />
|
||||||
|
<FraseAncla />
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { Container } from '@/components/primitives/Container';
|
||||||
|
import { fraseAncla } from '@/lib/content';
|
||||||
|
import { fadeInUp, viewportOnce } from '@/lib/motion';
|
||||||
|
|
||||||
|
export function FraseAncla() {
|
||||||
|
return (
|
||||||
|
<section className="bg-base">
|
||||||
|
<Container className="py-24 md:py-32 text-center max-w-4xl">
|
||||||
|
<motion.blockquote
|
||||||
|
variants={fadeInUp}
|
||||||
|
initial="hidden"
|
||||||
|
whileInView="visible"
|
||||||
|
viewport={viewportOnce}
|
||||||
|
className="font-serif italic text-2xl md:text-4xl font-bold leading-snug text-ink"
|
||||||
|
>
|
||||||
|
<span className="text-gold">“</span>
|
||||||
|
{fraseAncla.quote.before}{' '}
|
||||||
|
<span className="text-gold">{fraseAncla.quote.accent}</span>
|
||||||
|
<span className="text-gold">”</span>
|
||||||
|
</motion.blockquote>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { FraseAncla } from '../FraseAncla';
|
||||||
|
|
||||||
|
describe('<FraseAncla />', () => {
|
||||||
|
it('renders the anchor quote', () => {
|
||||||
|
render(<FraseAncla />);
|
||||||
|
expect(screen.getByText(/Las empresas no dejan de crecer/i)).toBeInTheDocument();
|
||||||
|
expect(screen.getByText(/falta de claridad/i)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
+5
-1
@@ -18,7 +18,11 @@ export const hero = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const fraseAncla = {
|
export const fraseAncla = {
|
||||||
quote: 'Las empresas no dejan de crecer por falta de talento; dejan de crecer por falta de claridad.',
|
// Quote split into parts so the second clause can render in gold.
|
||||||
|
quote: {
|
||||||
|
before: 'Las empresas no dejan de crecer por falta de talento;',
|
||||||
|
accent: 'dejan de crecer por falta de claridad.', // gold
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const paraQuien = {
|
export const paraQuien = {
|
||||||
|
|||||||
@@ -1 +1,19 @@
|
|||||||
import '@testing-library/jest-dom/vitest';
|
import '@testing-library/jest-dom/vitest';
|
||||||
|
|
||||||
|
// jsdom lacks IntersectionObserver; Framer Motion's `whileInView` needs it.
|
||||||
|
if (typeof window !== 'undefined' && !('IntersectionObserver' in window)) {
|
||||||
|
class IntersectionObserverStub {
|
||||||
|
observe() {}
|
||||||
|
unobserve() {}
|
||||||
|
disconnect() {}
|
||||||
|
takeRecords() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
root = null;
|
||||||
|
rootMargin = '';
|
||||||
|
thresholds = [];
|
||||||
|
}
|
||||||
|
// @ts-expect-error – installing stub on window
|
||||||
|
window.IntersectionObserver = IntersectionObserverStub;
|
||||||
|
global.IntersectionObserver = IntersectionObserverStub;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user