feat(dolores): las cuatro frases se apilan en vez de desfilar

El rótulo en bucle era idea mía y era peor que las tarjetas que sustituía.
Medido contra el tono bloqueado de la marca —«seguridad + cercanía»,
«simple, directo, limpio»— un marquee es lo contrario de los tres:
arrastra la asociación con banner de rebajas y teletipo. Y cortaba cada
frase por los dos bordes, así que ninguna llegaba entera.

Ahora entran de una en una al bajar y se quedan. El peso lo da el montón,
no el recorrido: cada una cae con una sangría distinta —irregular a
propósito, una regular se lee como lista y una irregular como cuatro
voces en la misma habitación— y al llegar la cuarta el lector las ve
todas juntas. Debajo, el remate alineado a la izquierda y quieto.

Se acabó la duplicación: el bucle necesitaba pintar cada frase cuatro
veces y esconder tres de los lectores de pantalla. Una frase, una vez.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
erikghandClaude Opus 5 committed 2026-08-03 15:50:17 -06:00
1 parent 2ae3c3ad9b
commit 99c9f77547
2 files changed
+36 -86

No files matched your search

+10 -9
View File
@@ -11,20 +11,21 @@ describe('<Dolores />', () => {
}
});
it('says each pain only once out loud, however many times it is painted', () => {
it('says each pain exactly once', () => {
const { container } = render(<Dolores />);
// 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(<Dolores />);