feat(dolores): las cuatro frases dejan de estar ordenaditas y pasan a moverse

Eran cuatro tarjetas alineadas describiendo desorden — lo contrario de lo
que dicen. Ahora cruzan la sección en dos filas lentas y en direcciones
opuestas, a sangre, mientras el remate en dorado no se mueve. Ese
contraste es el argumento de la sección.

Siguen legibles a propósito. Bajarlas a un susurro habría dado mejor
textura y habría tirado a la basura la voz del cliente: son palabras
suyas, verbatim de la diapositiva 3. El murmullo lo hace el movimiento.

Cada frase se pinta cuatro veces —dos por fila para que el bucle no tenga
costura, y dos filas— pero solo una llega a los lectores de pantalla. Sin
eso recitarían la lista entera de dolores y luego la recitarían otra vez.
Hay una prueba que lo exige.

Con prefers-reduced-motion no hay rótulo: las cuatro frases se leen
quietas a dos columnas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
erikghandClaude Opus 5 committed 2026-08-03 15:01:37 -06:00
1 parent c1f611e9ec
commit 7af36e2a93
2 files changed
+108 -24

No files matched your search

+20 -5
View File
@@ -1,15 +1,30 @@
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { Dolores } from '../Dolores';
import { dolores } from '@/lib/content';
describe('<Dolores />', () => {
it('renders the four pains verbatim, in the client\'s first person', () => {
render(<Dolores />);
expect(screen.getByText(/Trabajo más y gano casi lo mismo que hace dos años\./)).toBeInTheDocument();
expect(screen.getByText(/no sé en cuál enfocar mi tiempo y mi dinero\./)).toBeInTheDocument();
expect(screen.getByText(/no puede crecer si yo no estoy en cada decisión\./)).toBeInTheDocument();
expect(screen.getByText(/ya no me sirve para el siguiente nivel\./)).toBeInTheDocument();
expect(screen.getAllByRole('listitem')).toHaveLength(4);
for (const dolor of dolores.quotes) {
expect(screen.getAllByText(new RegExp(dolor.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))).length).toBeGreaterThan(0);
}
});
it('says each pain only once out loud, however many times it is painted', () => {
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.
for (const dolor of dolores.quotes) {
const apariciones = Array.from(container.querySelectorAll('span')).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);
}
});
it('closes with the resolution, not with more effort', () => {
const { container } = render(<Dolores />);