Contexto: MVP de CAUDAL construido (2026-08-11/12) en ~/nef/projects/caudal, según build brief v2 (ver 2026-08-11-caudal-build-brief-v2.md).

Estado del MVP

Entregado y verificado (headless + SwiftShader)

  • Motor WebGL2: 65536 partículas (16384 móvil), FBO ping-pong MRT (32F→16F→RGBA8), curl noise + carriles, glifos del atlas runtime (canvas→textura), 2 draw calls.
  • 6 estados hidrológicos mapeados a 10 secciones por scroll (estiaje→…→delta), riel sticky con estado en vivo + progress bar + field/atlas/state.
  • Degradación: sin WebGL2→canvas 2D 900 partículas; reduced-motion→frame convergido; sin JS→SVG estático inline (LCP). Motor arranca en requestIdleCallback.
  • Instrumento: matcher determinístico (8 arquetipos, híbrido, nunca vacío), chips, contador localStorage real, ficha mono, submit mailto (endpoint propio pendiente), aria-live, ?p= y ficha SVG descargable fuera de alcance (decisión del usuario).
  • Perf: JS 14.6kb gz, CSS 2.8kb gz, fuentes 41kb, 0 imágenes, LCP=SVG inline.
  • Verificación: playwright+SwiftShader (scripts/smoke.mjs); 0 errores de consola.

Desviaciones del brief (conscientes)

  1. Fuentes: Instrument Sans variable (Neue Montreal es de pago) + stack mono sistema (Berkeley/Commit no en fontsource). Sustituir cuando haya licencias.
  2. Atlas: bitmap runtime en vez de PNG MSDF estático (misma arquitectura, 0 payload).
  3. Copy: v1 no disponible; escribí copy funcional. Sustituir por copy del v1.
  4. mailto como envío (sin servidor). Endpoint propio = pendiente.
  5. Canvas z-index 60 sobre el contenido (glifos por encima de headline; col 3-9 libre de partículas). Ritmo de inversión 01/03/05/10 lecho.

Pendientes

  • Copy v1, fuentes licenciadas, endpoint de correo, ?p=, ficha SVG, /llms.txt, /protocolo.md.
  • QA a mano: VoiceOver, teclado completo, zoom 200%, Lighthouse móvil con throttling.
  • gh: crear repo [usuario]/caudal y añadir a respaldos.

Comandos

npm run dev / npm run build / npm run preview node scripts/smoke.mjs http://localhost:PORT /tmp/shot.png