Inducción técnicaUso interno · v0.2 · octubre 2026

05 · Frontend

Next.js, React y el sitio

Las interfaces de los sistemas y el sitio de Naoro comparten base: Next.js 16, React 19, TypeScript y CSS propio. El sitio agrega movimiento con GSAP y Lenis, y dibujo con Canvas y SVG.

Next.js 16

  • App Router. Cada carpeta en app/ es una ruta. page.tsx es la página y layout.tsx envuelve a sus hijas.
  • Componentes de servidor por defecto. Solo lo que usa estado, efectos o el navegador lleva 'use client'. Esta guía es casi toda de servidor.
  • params es una promesa. En layouts y páginas dinámicas se lee con await. Los tipos LayoutProps y PageProps se generan solos y están disponibles sin importarlos.
  • Exportación estática. El sitio usa output: 'export': el build genera HTML en out/ y nginx lo sirve tal cual. No hay servidor de Node en producción, así que no hay rutas de API ni rutas dinámicas sin generateStaticParams.
  • Páginas solo de desarrollo. Los archivos page.dev.tsx existen solo con next dev (ver next.config.ts). Sirven para herramientas internas.
  • Fuentes con next/font: Host Grotesk desde Google y Departure Mono local, expuestas como variables CSS.

React 19 y TypeScript

  • StrictMode está activo (reactStrictMode: true). En desarrollo cada efecto se monta, se limpia y se vuelve a montar. Por eso todo efecto de animación devuelve su limpieza y revisa si sigue vivo antes de arrancar.
  • Menos efectos. Si algo se puede calcular durante el render, no va en un useEffect.
  • Refs para todo lo que se anima o se mide. React pinta la estructura, GSAP y Canvas mueven los píxeles.
  • TypeScript estricto. Tipos explícitos en los datos de los motores (lib/demos/*.ts). El build falla si tsc falla.

CSS

Sin Tailwind ni librerías de componentes. Todo el diseño sale de tokens propios.

  • Tokens en app/globals.css: --ink, --paper, --signal, tipografías, tamaños y márgenes.
  • Tokens vivos (--bg, --fg, --muted, --line): ThemeShift los interpola cuando una sección cambia entre Paper e Ink (data-theme).
  • CSS Modules para componentes nuevos (*.module.css). Los estilos del home están en globals.css.
  • Controles propios: components/ui/Select.tsx y Slider.tsx. Nada de <select> ni selectores de fecha nativos.

Movimiento

GSAP 3

Animación
  • Todo entra por lib/gsap.ts: registra los plugins una vez y exporta gsap, useGSAP, ScrollTrigger, SplitText y prefersReducedMotion. Nunca importes gsap directo en un componente.
  • Curvas propias: n.out para entradas largas y precisas, n.inOut para cambios de estado. Sin rebotes.
  • Las entradas de titulares están en lib/reveals.ts (revealArrive, revealBlocks, revealType…), con el hook useReveal. Reutilízalas antes de inventar otra.
  • Toda animación revisa prefersReducedMotion() primero y deja el estado final visible.

Lenis

Desplazamiento suave

components/SmoothScroll.tsx crea Lenis y lo conecta con el reloj de GSAP para que ScrollTrigger lea la misma posición. lib/scroll.ts guarda la instancia y expone scrollToTarget y onSiteEnter. La barra de desplazamiento es propia (ScrollBar.tsx).

Canvas, SVG y observadores

  • Canvas 2D + requestAnimationFrame para animaciones densas de celdas: el buscaminas del hero (lib/field.ts), la firma Partida del logo (lib/partida.ts), PixelMark y los planos de Capacidades. Con cientos de celdas, SVG con una animación por elemento se traba. Mide en Chrome real, no en suposiciones.
  • SVG en línea para ilustraciones con trazo: capas isométricas, glifos del proceso, antes y después. Algunos detalles usan la Web Animations API (element.animate).
  • IntersectionObserver pausa los canvas fuera de pantalla. ResizeObserver recalcula medidas y refresca ScrollTrigger cuando cambia la altura.
  • Solo en demos: Three.js en la demo de natación (/deporte) y Mapbox GL en el mapa de zonas. No se cargan en el home.

Mapa del home

SecciónArchivoTécnica
HeroHero.tsx, lib/field.tsBuscaminas en Canvas, SplitText, IntersectionObserver
La ideaManifesto.tsxSplitText con ScrollTrigger, registro de fricción
Qué es NaoroLayers.tsxSVG isométrico de tres capas, pasos ligados al scroll
ProcesoProcess.tsxScroll horizontal fijado con ScrollTrigger, ocho glifos SVG
CapacidadesCapabilities.tsxLista con planos en Canvas
EvidenciaEvidence.tsxAntes y después, tablero monocromo en SVG
EstándarStandard.tsxEntrada con barrido (revealWipe)
PrincipiosPrinciples.tsxFrases censuradas que se revelan letra por letra con el scroll
PieFooter.tsx, SweepMark.tsxEscritura con cursor, marca animada en SVG
Todo el sitioSmoothScroll.tsx, ThemeShift.tsx, Nav.tsxLenis, cambio de tema por sección, navegación

Recorrido por el código

En este orden, una tarde de lectura:

  1. package.json y next.config.ts: dependencias y exportación estática.
  2. app/layout.tsx y app/page.tsx: fuentes y la composición del home.
  3. app/globals.css, solo la parte de :root: los tokens.
  4. lib/gsap.ts, lib/scroll.ts y components/SmoothScroll.tsx: la base del movimiento.
  5. lib/reveals.ts: el catálogo de entradas.
  6. components/Hero.tsx con lib/field.ts: la pieza más compleja.
  7. components/demos/Workbench.tsx con lib/demos/approvals.ts: una prueba completa con su motor.
Terminal
npm install
npm run dev        # http://localhost:3000
npm run build      # genera out/ (también revisa los tipos)

Al terminar deberías poder

  • Explicar qué corre en el servidor y qué en el cliente en cualquier página del sitio.
  • Crear una ruta nueva con layout, metadatos y estilos en CSS Modules.
  • Agregar una entrada de titular con useGSAP y una de las entradas de lib/reveals, respetando el movimiento reducido.
  • Leer lib/field.ts y explicar cómo se dibuja y anima el buscaminas.
  • Construir una pantalla que consuma la API que hiciste en la sección de backend.