feat(recorrido): el fotograma es el mensaje, y la respuesta llega en azul

Fuera tarjetas: la situación va a tamaño de titular sobre el fondo claro,
y al bajar el escenario entero se vuelve azul profundo para la respuesta
de creeer, en blanco y del mismo tamaño. No es una tarjeta sobre la
página del lector, es el terreno de creeer.

El rótulo del punto se repite en la respuesta a propósito: como solo hay
una cosa en pantalla, es lo único que la ata a la pregunta que contesta.
El test lo fija con esa razón escrita.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
erikghandClaude Opus 5 committed 2026-08-03 12:26:32 -06:00
1 parent 253ff26fa2
commit 3f65a2a2c3
3 files changed
+68 -48

No files matched your search

+18 -2
View File
@@ -111,11 +111,21 @@ function Escenificado() {
{/* One viewport of stage, six viewports of scroll to move through it. */}
<div ref={contenedor} className="relative" style={{ height: `${TOTAL * 100}vh` }}>
<div data-escena={activo} data-tiempo={tiempo} className="sticky top-0 h-screen overflow-hidden">
<div data-escena={activo} data-tiempo={tiempo} className="sticky top-0 h-screen overflow-hidden bg-gris-claro">
<motion.div style={{ y: fondoY }} className="absolute inset-0">
<FondoPuntos className="-bottom-10 -right-16 w-80 md:w-[34rem] text-azul-profundo/10" distance={32} />
</motion.div>
{/* The frame itself turns over on the answer. The whole stage goes to
azul-profundo, not a panel inside it — the answer is not a card on
the reader's page, it is creeer's ground. */}
<motion.div
aria-hidden="true"
animate={{ opacity: respondida ? 1 : 0 }}
transition={{ duration: 0.55, ease: [0.22, 1, 0.36, 1] }}
className="absolute inset-0 bg-azul-profundo"
/>
<Container className="relative h-full">
{/* left-6 / md:left-12, not left-0: an absolutely positioned child
resolves against Container's padding box, so `left-0` lands on
@@ -133,7 +143,13 @@ function Escenificado() {
<li key={item.name}>
<span
className={`block h-px origin-right transition-all duration-500 ${
i === activo ? 'w-10 bg-dorado' : i < activo ? 'w-6 bg-dorado/40' : 'w-4 bg-azul-profundo/20'
i === activo
? 'w-10 bg-dorado'
: i < activo
? 'w-6 bg-dorado/40'
: respondida
? 'w-4 bg-white/25'
: 'w-4 bg-azul-profundo/20'
}`}
/>
</li>
@@ -9,12 +9,15 @@ describe('<PuntosInflexion />', () => {
expect(screen.getByText(/llegan a un punto de inflexión/i)).toBeInTheDocument();
});
it('renders the six inflection points from the dueña deck', () => {
it('labels both halves of every exchange with its inflection point', () => {
render(<PuntosInflexion />);
// Each point now renders once, not twice: the mobile carousel is gone and
// the conversation stacks vertically at every breakpoint.
// Twice per point, once on each frame. The pinned sequence shows one thing
// at a time, so when creeer's answer is on screen the question that
// prompted it is gone — the repeated label is the only thing left tying the
// two together. Dropping it from the answer would leave six statements
// floating with nothing to answer.
for (const name of ['Crecer', 'Consolidarse', 'Recuperar rentabilidad', 'Simplificar', 'Expandirse', 'Replantear el portafolio']) {
expect(screen.getByText(new RegExp(name))).toBeInTheDocument();
expect(screen.getAllByText(new RegExp(name))).toHaveLength(2);
}
expect(screen.getAllByRole('listitem')).toHaveLength(6);
});