diff --git a/components/sections/Dolores.tsx b/components/sections/Dolores.tsx index a092f6a..2b001ca 100644 --- a/components/sections/Dolores.tsx +++ b/components/sections/Dolores.tsx @@ -4,66 +4,27 @@ import { motion } from 'framer-motion'; import { Container } from '@/components/primitives/Container'; import { IlustracionNudo } from '@/components/primitives/IlustracionNudo'; import { dolores } from '@/lib/content'; -import { fadeInUp, viewportOnce, usePrefersReducedMotion, motionProps } from '@/lib/motion'; +import { fadeInUp, staggerContainer, viewportOnce, usePrefersReducedMotion, motionProps } from '@/lib/motion'; // The four quotes are the client's own words, from slide 3 of the dueña's deck. -// They used to sit in four tidy cards — the opposite of what they describe. Here -// they drift past instead: the noise you carry around, still going, while the -// resolution underneath does not move at all. The contrast between the two is -// the argument. // -// They stay legible on purpose. Fading them to a whisper would have made a -// better texture and thrown away the client's own voice; the murmur is carried -// by the motion, not by hiding the words. +// They were four tidy cards, which was the opposite of what they describe; then +// they were a marquee, which was worse — a loop belongs to a sale banner, and +// the brand's locked tone is "seguridad + cercanía", "simple, directo, limpio". +// It also sliced every sentence at both edges, so none was ever fully framed. +// +// Now they arrive one at a time as the reader comes down and they stay. What +// carries the weight is the pile, not the travel: each one lands further in or +// further out than the last, the way overheard sentences do, and by the fourth +// the reader is looking at everything at once. Then the resolution, flush left +// and gold, with nothing moving. -const VUELTA_SEGUNDOS = 58; - -function Rotulo({ - frases, - haciaIzquierda, - mudo = false, -}: { - frases: string[]; - haciaIzquierda: boolean; - mudo?: boolean; -}) { - const tanda = (oculta: boolean) => ( -
- {frases.map((frase) => ( - - “ - {frase} - ” - - ))} -
- ); - - return ( -
- {/* Two identical runs inside one track: translating the track by exactly - half its own width lands the second run where the first began, so the - loop has no seam. The duplicate is hidden from assistive tech — it is - the same four sentences twice. */} - - {tanda(false)} - {tanda(true)} - -
- ); -} +// Deliberately not a staircase. A regular indent reads as a list; an irregular +// one reads as four separate voices that happen to be in the same room. +const SANGRIAS = ['md:ml-0', 'md:ml-[14%]', 'md:ml-[5%]', 'md:ml-[21%]']; export function Dolores() { const reduced = usePrefersReducedMotion(); - // Rotated so the two rows never show the same sentence side by side. - const segunda = [...dolores.quotes.slice(2), ...dolores.quotes.slice(0, 2)]; return (
@@ -72,40 +33,28 @@ export function Dolores() { knot. Stays centred. */} - + {dolores.eyebrow} {dolores.title} - - {/* Full-bleed on purpose: the noise does not respect the column. */} - {reduced ? ( - -
    - {dolores.quotes.map((quote) => ( -
  • + + {dolores.quotes.map((quote, i) => ( + +
    “ {quote} ” -
  • - ))} -
-
- ) : ( -
- - {/* The second row is the same four sentences again, rotated so no - pair lines up. It is a visual echo, so it is silent: without - `mudo` a screen reader would read all four pains, then read them - all over again. */} - -
- )} + + + ))} + - + {/* Flush left and still, against four sentences that are not. */} + className="mt-16 md:mt-20 font-sans font-black text-ancla text-azul-profundo max-w-4xl"> {dolores.remate.before}{' '} {dolores.remate.accent} diff --git a/components/sections/__tests__/Dolores.test.tsx b/components/sections/__tests__/Dolores.test.tsx index 54023b3..07da90f 100644 --- a/components/sections/__tests__/Dolores.test.tsx +++ b/components/sections/__tests__/Dolores.test.tsx @@ -11,20 +11,21 @@ describe('', () => { } }); - it('says each pain only once out loud, however many times it is painted', () => { + it('says each pain exactly once', () => { const { container } = render(); - // The drifting rows repeat the four sentences four times over: twice per - // row so the loop has no seam, and twice again because there are two rows. - // Only one of those runs may reach assistive tech — otherwise a screen - // reader recites the whole list of pains, and then recites it again. + // A marquee needed the four sentences painted four times over — twice per + // row for a seamless loop, twice again for the second row — and three of + // those runs had to be hidden from assistive tech or a screen reader would + // recite the whole list twice. Stacked, there is nothing to hide: one + // sentence, once, said once. for (const dolor of dolores.quotes) { - const apariciones = Array.from(container.querySelectorAll('span')).filter( + const apariciones = Array.from(container.querySelectorAll('blockquote')).filter( (el) => el.textContent?.includes(dolor), ); - const audibles = apariciones.filter((el) => !el.closest('[aria-hidden="true"]')); - expect(apariciones.length).toBeGreaterThan(1); - expect(audibles).toHaveLength(1); + expect(apariciones).toHaveLength(1); + expect(apariciones[0].closest('[aria-hidden="true"]')).toBeNull(); } + expect(container.querySelectorAll('li')).toHaveLength(dolores.quotes.length); }); it('closes with the resolution, not with more effort', () => { const { container } = render();