Imported from nakato156/datavis-ef (
SKILL.md). Install upstream withnpx skills add nakato156/datavis-ef. Copyright stays with the author.
Scientific Scrollytelling UI
Propósito
Diseñar o transformar una interfaz web de divulgación científica para que el scroll funcione como mecanismo narrativo y epistemológico: cada paso debe introducir una afirmación, mostrar la evidencia que la sustenta y conducir a una interpretación comprensible sin deformar el resultado científico.
La implementación debe priorizar:
- rigor científico;
- claridad narrativa;
- continuidad visual;
- accesibilidad;
- rendimiento;
- reproducibilidad;
- degradación progresiva.
No conviertas una página en scrollytelling únicamente añadiendo animaciones. El resultado debe organizar evidencia, texto y visualización en una secuencia argumental verificable.
Cuándo activar esta skill
Actívala cuando el usuario pida cualquiera de las siguientes tareas:
- transformar una página, dashboard, paper o reporte en una experiencia de scrollytelling;
- implementar una narrativa científica controlada por scroll;
- revisar si una UI usa correctamente scrollytelling;
- explicar un modelo, experimento, proceso, dataset o hallazgo mediante una historia visual;
- adaptar una visualización interactiva para divulgación científica;
- reproducir el patrón de una pieza periodística de datos sin copiar su diseño;
- auditar accesibilidad, rendimiento o fidelidad científica en una experiencia narrativa;
- integrar Scrollama, IntersectionObserver, GSAP ScrollTrigger, Motion, D3, Vega, Observable Plot, Three.js u otra tecnología equivalente.
No la actives para:
- páginas de marketing sin contenido científico;
- dashboards destinados principalmente a exploración libre;
- galerías con parallax decorativo;
- animaciones sin una progresión argumental;
- artículos estáticos que no necesitan estados visuales sucesivos.
Principio rector
Cada escena debe implementar el ciclo:
afirmación → evidencia → interpretación → transición
Una escena es válida solo cuando:
- comunica una idea científica concreta;
- modifica o enfoca una representación visual;
- ofrece evidencia trazable;
- evita afirmar más de lo que permiten los datos;
- prepara cognitivamente la siguiente escena.
Referencia conceptual
Usa como referencia estructural las piezas de periodismo de datos donde:
- una tesis general abre la experiencia;
- una visualización principal introduce el fenómeno;
- el relato revela que el promedio agregado oculta heterogeneidad;
- los datos se desglosan por categorías o subgrupos;
- se comparan tendencias, magnitudes y puntos de referencia;
- los gráficos aparecen junto a interpretación editorial;
- las fuentes, decisiones metodológicas, faltantes y limitaciones se declaran al final.
Toma de la referencia sus principios de composición, no su identidad visual, textos, datos, código ni gráficos específicos.
Contrato de ejecución
Entradas mínimas
Antes de implementar, localiza o infiere:
- pregunta científica principal;
- audiencia objetivo;
- hallazgo central;
- dataset o evidencia disponible;
- unidades, variables y categorías;
- incertidumbres y limitaciones;
- framework y arquitectura existente;
- dispositivos objetivo;
- restricciones de accesibilidad y rendimiento.
Si faltan datos, no inventes resultados. Implementa placeholders tipados, fixtures claramente marcadas o estados vacíos, y documenta qué fuente debe conectarse.
Salidas obligatorias
Entrega, según el alcance del repositorio:
- implementación funcional;
- mapa narrativo de escenas;
- contrato de datos;
- componentes reutilizables;
- fallback sin JavaScript o con movimiento reducido;
- pruebas automatizadas;
- auditoría de accesibilidad;
- auditoría de rendimiento;
- checklist de fidelidad científica;
- documentación para modificar texto, datos y escenas.
Flujo de trabajo obligatorio
Fase 1 — Inspección
Antes de editar:
- identifica framework, rutas, componentes, estilos y sistema de diseño;
- localiza las fuentes de datos y transformaciones;
- determina si ya existe una visualización central;
- detecta efectos de scroll, sticky containers y observers existentes;
- revisa breakpoints, SSR, hidratación y carga de assets;
- ejecuta tests, lint y build para obtener una línea base;
- captura o documenta el comportamiento actual en desktop y móvil.
No reemplaces la arquitectura existente sin justificarlo.
Fase 2 — Modelo narrativo
Construye un story-map antes de programar.
Cada escena debe declarar:
type ScientificStoryStep = {
id: string;
claim: string;
evidence: string[];
visualState: string;
annotation?: string;
uncertainty?: string;
sourceIds: string[];
transitionPurpose: string;
};
El mapa narrativo debe incluir como mínimo:
- contexto o pregunta;
- fenómeno general;
- ruptura del promedio o primera sorpresa;
- desglose explicativo;
- comparación o mecanismo;
- incertidumbre y límites;
- conclusión proporcional a la evidencia;
- fuentes y metodología.
No fuerces ocho escenas si la historia requiere menos. Sí deben estar representadas todas las funciones epistemológicas anteriores.
Fase 3 — Jerarquía científica
Clasifica cada afirmación:
- observación: procede directamente de los datos;
- resultado: procede de un análisis o modelo;
- interpretación: explicación razonada;
- hipótesis: mecanismo aún no demostrado;
- limitación: condición que reduce el alcance;
- recomendación: acción derivada del análisis.
La UI debe distinguir visual o verbalmente estas categorías. Nunca presentes una hipótesis como causalidad demostrada.
Fase 4 — Arquitectura de componentes
Prefiere una arquitectura desacoplada:
ScientificStoryPage
├── StoryHeader
├── ScrollySection
│ ├── StickyStage
│ │ └── ScientificVisualization
│ └── StorySteps
│ └── StoryStep[]
├── EvidenceDetails
├── Methodology
├── Sources
└── AccessibleStaticSummary
Responsabilidades:
StoryStep: texto, semántica, fuentes y activación;StickyStage: posicionamiento y contención visual;ScientificVisualization: render determinista desdevisualState;ScrollyController: traduce visibilidad a estado;Methodology: explica datos y transformaciones;AccessibleStaticSummary: conserva el contenido sin animación.
No mezcles cálculo científico, observación del scroll y renderizado en un solo componente.
Fase 5 — Motor de scroll
Prioriza APIs nativas:
IntersectionObserverpara activación de escenas;- CSS
position: stickypara la etapa visual; requestAnimationFrameúnicamente para animación continua;ResizeObservercuando la geometría dependa del contenedor.
Usa una librería cuando reduzca complejidad real:
- Scrollama para escenas discretas;
- GSAP ScrollTrigger para secuencias temporales complejas;
- Motion para transiciones declarativas;
- D3/Vega/Observable Plot para visualización;
- Three.js solo si la dimensión espacial es esencial.
Reglas:
- un único paso activo;
- estados visuales deterministas;
- navegación hacia adelante y atrás;
- actualización idempotente;
- cleanup completo de observers/listeners;
- ausencia de scroll hijacking;
- el usuario conserva el control de velocidad y dirección;
- no dependas de coordenadas rígidas del viewport;
- la URL debe seguir siendo compartible;
- el contenido principal debe existir en el DOM.
Fase 6 — Diseño visual
Composición
Usa preferentemente:
- texto narrativo de 35–70 caracteres por línea;
- etapa visual sticky en desktop;
- secuencia apilada o visual inline en móvil;
- suficiente espacio vertical para identificar cada transición;
- anotaciones cercanas a la evidencia;
- leyenda persistente cuando cambien estados del mismo gráfico;
- títulos que expresen hallazgos, no solo nombres de variables.
Continuidad
Mantén objetos visuales estables entre escenas. Cuando sea posible, transforma el mismo gráfico mediante:
- filtrado;
- resaltado;
- anotación;
- reordenamiento;
- cambio de escala justificado;
- small multiples;
- comparación con baseline;
- zoom semántico.
Evita sustituir un gráfico completo en cada paso si una transición preservando identidad permite entender mejor el cambio.
Color
- usa color para codificar significado, no decoración;
- no dependas solo del color;
- conserva mapeos de color entre escenas;
- verifica contraste WCAG;
- emplea paletas aptas para daltonismo;
- reserva un color de énfasis para el hallazgo activo;
- muestra datos faltantes con una codificación distinta a cero.
Movimiento
Toda animación debe responder: “¿qué relación científica ayuda a comprender?”.
Duración recomendada para transiciones discretas: 200–700 ms.
Evita:
- parallax gratuito;
- rebotes;
- partículas decorativas;
- animaciones que alteren la lectura de magnitudes;
- interpolaciones engañosas;
- cambios simultáneos de demasiadas variables.
Divulgación científica
Lenguaje
Escribe para una audiencia culta no especialista:
- introduce términos técnicos antes de usarlos;
- define una idea por escena;
- emplea analogías solo si preservan la estructura del fenómeno;
- acompaña porcentajes con denominadores o magnitudes cuando sean relevantes;
- evita “demuestra” cuando corresponde “sugiere” o “es consistente con”;
- explica por qué el hallazgo importa;
- no sacrifiques precisión por dramatismo.
Estructura recomendada
1. Apertura
- pregunta concreta;
- fenómeno observable;
- promesa de lo que el lector comprenderá.
2. Vista general
- gráfico o escena inicial comprensible;
- escala y unidad visibles;
- baseline o referencia explícita.
3. Complicación
- revela heterogeneidad, anomalía o contradicción;
- muestra por qué el promedio no basta.
4. Descomposición
- separa categorías, etapas, cohortes o mecanismos;
- presenta una comparación por vez.
5. Explicación
- conecta patrón con método o hipótesis;
- distingue evidencia de interpretación.
6. Incertidumbre
- intervalos, variabilidad, sensibilidad o faltantes;
- límites de generalización;
- posibles explicaciones alternativas.
7. Cierre
- responde la pregunta inicial;
- evita una conclusión más fuerte que el análisis;
- indica qué sigue abierto.
8. Metodología y fuentes
- procedencia de los datos;
- periodo;
- población;
- exclusiones;
- transformaciones;
- definición de métricas;
- código o repositorio, si existe;
- fecha de actualización.
Integridad de datos y evidencia
Reglas inmutables
- No inventes observaciones.
- No ocultes datos faltantes.
- No confundas conteos con porcentajes.
- No cambies escalas entre escenas sin señalarlo.
- No trunques ejes para exagerar diferencias sin justificación visible.
- No uses áreas o volúmenes para representar magnitudes lineales.
- No interpoles años ausentes como datos observados.
- No presentes correlación como causalidad.
- No suprimas intervalos de incertidumbre cuando sean fundamentales.
- No uses animación para ocultar discontinuidades metodológicas.
- Toda cifra textual debe derivarse de la misma fuente de datos que el gráfico.
- Toda escena debe referenciar al menos una fuente o transformación trazable.
Contrato de datos recomendado
type SourceMetadata = {
id: string;
title: string;
publisher?: string;
url?: string;
accessedAt?: string;
license?: string;
};
type Observation = {
entity: string;
period: string | number;
value: number | null;
unit: string;
subgroup?: string;
lowerBound?: number;
upperBound?: number;
sourceId: string;
status?: "observed" | "estimated" | "missing";
};
Valida los datos en runtime o build time con Zod, Valibot, JSON Schema, Pydantic u otra herramienta equivalente.
Accesibilidad obligatoria
Cumple como mínimo:
- estructura semántica con encabezados ordenados;
- cada paso es contenido legible, no un trigger vacío;
- navegación por teclado;
- foco visible;
- textos alternativos o descripción extensa de gráficos;
- tabla o resumen textual equivalente;
- contraste WCAG AA;
aria-livesolo para cambios que necesiten anunciarse;- respeto de
prefers-reduced-motion; - no activar información exclusivamente por hover;
- no bloquear zoom;
- orden DOM coherente con el orden narrativo;
- visualización comprensible sin color;
- fallback cuando sticky no esté disponible;
- enlaces a fuentes con texto descriptivo.
Ejemplo:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Para movimiento reducido, cambia estados de forma inmediata y conserva todas las anotaciones y explicaciones.
Responsive design
Desktop
- etapa visual sticky;
- columna narrativa separada;
- ancho suficiente para etiquetas;
- altura máxima que no recorte leyendas.
Tablet
- reduce densidad y anotaciones simultáneas;
- permite sticky solo si no crea saltos;
- conserva targets táctiles.
Móvil
No reduzcas simplemente la versión desktop.
Prefiere una de estas estrategias:
- visual inline después de cada paso;
- sticky de corta duración;
- small multiples estáticos;
- snapshots por escena;
- controles anterior/siguiente complementarios.
En móvil:
- evita tooltips esenciales;
- reduce ticks;
- reubica leyendas;
- aumenta targets táctiles;
- verifica barras del navegador y viewport dinámico;
- usa
100dvhcon fallback cuando sea apropiado.
Rendimiento
Objetivos recomendados:
- LCP ≤ 2.5 s;
- CLS ≤ 0.1;
- INP ≤ 200 ms;
- interacción de scroll sin tareas largas;
- imágenes responsivas;
- fuentes optimizadas;
- datasets grandes preagregados;
- visualizaciones pesadas lazy-loaded;
- observers compartidos cuando sea posible;
- cero renders React innecesarios por cada píxel de scroll.
No vincules directamente todos los eventos de scroll al estado global.
Para escenas discretas, actualiza únicamente cuando cambie el paso activo.
SEO, SSR y preservación del contenido
La historia debe seguir siendo indexable y citable:
- renderiza títulos, afirmaciones y explicaciones como HTML;
- no almacenes el contenido narrativo exclusivamente en canvas;
- usa SSR/SSG cuando el framework lo permita;
- proporciona metadatos Open Graph;
- incluye fecha, autores, fuentes y metodología;
- permite enlazar secciones mediante IDs estables;
- evita que la experiencia dependa totalmente de hidratación.
Implementación de referencia
Ejemplo conceptual en React/TypeScript:
type StepProps = {
id: string;
index: number;
onEnter: (index: number) => void;
children: React.ReactNode;
};
function StoryStep({ id, index, onEnter, children }: StepProps) {
const ref = React.useRef<HTMLElement>(null);
React.useEffect(() => {
const node = ref.current;
if (!node) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) onEnter(index);
},
{
root: null,
rootMargin: "-35% 0px -45% 0px",
threshold: 0,
},
);
observer.observe(node);
return () => observer.disconnect();
}, [index, onEnter]);
return (
<section
ref={ref}
id={id}
className="story-step"
aria-labelledby={`${id}-title`}
>
{children}
</section>
);
}
Estado visual declarativo:
const visualStates = {
overview: { mode: "overview", highlightedSeries: [] },
aggregate: { mode: "aggregate", highlightedSeries: ["total"] },
breakdown: { mode: "small-multiples", highlightedSeries: [] },
anomaly: { mode: "detail", highlightedSeries: ["physics"] },
uncertainty: { mode: "uncertainty", showIntervals: true },
} as const;
No disperses mutaciones imperativas del gráfico entre los pasos. Cada
visualState debe producir una representación reproducible.
Estrategia de pruebas
Unitarias
Prueba:
- validación del dataset;
- transformaciones y agregaciones;
- cálculo de porcentajes;
- tratamiento de valores faltantes;
- mapeo escena → estado visual;
- formato de unidades;
- generación de descripciones accesibles.
Integración
Comprueba:
- activación correcta al avanzar;
- activación correcta al retroceder;
- un único paso activo;
- limpieza de observers;
- cambio de viewport;
- contenido disponible con JavaScript deshabilitado cuando sea viable;
prefers-reduced-motion;- hidratación sin errores.
End-to-end
Con Playwright o equivalente:
test("updates the visualization as story steps enter", async ({ page }) => {
await page.goto("/story");
await page.locator("#step-breakdown").scrollIntoViewIfNeeded();
await expect(page.locator("[data-visual-state]"))
.toHaveAttribute("data-visual-state", "breakdown");
});
Ejecuta escenarios en:
- desktop;
- móvil;
- teclado;
- movimiento reducido;
- red lenta;
- datos incompletos.
Regresión visual
Captura al menos:
- apertura;
- estado agregado;
- desglose;
- hallazgo principal;
- incertidumbre;
- móvil;
- movimiento reducido.
No apruebes snapshots si etiquetas, escalas o anotaciones quedan cortadas.
Auditoría de una UI existente
Asigna una puntuación de 0 a 2 en cada criterio:
| Criterio | 0 | 1 | 2 |
|---|---|---|---|
| Pregunta científica | ausente | implícita | explícita |
| Progresión narrativa | aleatoria | parcial | causal y clara |
| Evidencia por escena | ausente | incompleta | trazable |
| Continuidad visual | confusa | mixta | consistente |
| Incertidumbre | oculta | mencionada | visualizada |
| Fuentes | ausentes | generales | vinculadas por afirmación |
| Accesibilidad | bloqueante | parcial | equivalente |
| Responsive | roto | adaptado | rediseñado |
| Rendimiento | deficiente | aceptable | fluido |
| Fallback | inexistente | limitado | completo |
| Fidelidad científica | riesgosa | revisable | sólida |
| Tests | ausentes | básicos | integrales |
Interpretación:
- 0–8: no es un scrollytelling científico confiable;
- 9–16: prototipo funcional con riesgos;
- 17–21: publicación viable con correcciones menores;
- 22–24: implementación sólida.
Incluye evidencia concreta para cada puntuación y una lista priorizada:
- P0: errores científicos, inaccesibilidad bloqueante o pérdida de contenido;
- P1: narrativa, responsive, rendimiento o interacción;
- P2: refinamientos visuales y mantenibilidad.
Criterios de aceptación
No declares la tarea terminada hasta verificar:
Narrativa
- La pregunta científica aparece al inicio.
- Cada escena comunica una sola idea principal.
- Existe una progresión comprensible.
- La conclusión responde la pregunta inicial.
- La historia diferencia observación, interpretación e hipótesis.
Evidencia
- Todas las cifras son reproducibles.
- Fuentes y metodología están visibles.
- Datos faltantes y exclusiones están documentados.
- Las unidades permanecen consistentes.
- La incertidumbre relevante está representada.
- No se exagera causalidad ni generalización.
Interacción
- El scroll hacia adelante y atrás funciona.
- No existe scroll hijacking.
- Solo hay una escena activa.
- Las transiciones preservan contexto.
- La UI funciona sin animaciones.
Accesibilidad
- Navegable con teclado.
- Contraste AA.
- Alternativa textual o tabular.
- Movimiento reducido.
- Orden semántico correcto.
- No depende solo de color o hover.
Responsive
- Probado en móvil real o emulado.
- No hay texto, ejes ni leyendas cortadas.
- La estrategia móvil no es una reducción ciega de desktop.
- Sticky y viewport no generan saltos.
Calidad técnica
- Build, lint y typecheck pasan.
- Tests unitarios e integración pasan.
- No hay listeners u observers sin limpiar.
- No hay errores de hidratación.
- Core Web Vitals dentro de objetivos razonables.
- El contenido es indexable y enlazable.
Formato de respuesta del agente
Al completar una implementación o auditoría, responde con:
Diagnóstico
Estado actual, riesgos científicos y problemas principales.
Story map
Tabla breve con escena, afirmación, evidencia, estado visual y transición.
Cambios realizados
Archivos y responsabilidades, sin enumerar cambios irrelevantes.
Decisiones científicas
Cómo se preservaron unidades, incertidumbre, fuentes y límites.
Validación
Comandos ejecutados, tests, viewports y resultados.
Pendientes
Solo bloqueos reales, datos ausentes o decisiones editoriales no inferibles.
Conducta del agente
- Inspecciona antes de reescribir.
- Reutiliza componentes y tokens existentes.
- Realiza cambios incrementales.
- No copies literalmente la referencia.
- No introduzcas dependencias sin necesidad.
- No inventes datos, fuentes ni resultados.
- Señala cualquier afirmación no sustentada.
- Prefiere explicaciones visuales estables sobre efectos llamativos.
- Conserva siempre una versión accesible y estática del contenido.
- Cuando exista tensión entre espectacularidad y fidelidad científica, elige fidelidad científica.