← The Infinite Internet

GenAiA · project guide

GenAiA · guía del proyecto

How the Infinite Internet was made

Cómo se hizo el Internet Infinito

Fifteen radically different homepages for one association, plus a gateway that generates a sixteenth — yours — in real time. Everything below was designed and built autonomously by Claude Fable 5. This page documents the full workflow so anyone can replicate it.

Quince homepages radicalmente distintas para una misma asociación, más una puerta que genera la decimosexta — la tuya — en tiempo real. Todo lo de abajo lo diseñó y construyó de forma autónoma Claude Fable 5. Esta página documenta el workflow completo para que cualquiera pueda replicarlo.

01

Creative direction: 15 concepts, fixed up front

Dirección creativa: 15 conceptos fijados de antemano

Before a single line of code, an art-direction pass assigned each site a non-negotiable concept: aesthetic, palette family, typography direction and one signature technique (volumetric raymarching, canvas weaving, kinetic type, L-systems, a 3D globe, GPU particles, WebAudio-reactive layout…). Fixing the concepts first is what prevents fifteen parallel builders from converging on the same safe design.

Antes de una sola línea de código, una pasada de dirección de arte asignó a cada sitio un concepto innegociable: estética, familia de paleta, dirección tipográfica y una técnica firma (raymarching volumétrico, telar en canvas, tipografía cinética, L-systems, globo 3D, partículas GPU, layout audio-reactivo con WebAudio…). Fijar los conceptos primero es lo que evita que quince constructores en paralelo converjan en el mismo diseño seguro.

02

15 Claude Fable 5 workers, in parallel, headless

15 workers Claude Fable 5 en paralelo, headless

Each site is built by its own headless CLI worker (claude -p), all launched at once. The runner is glitch-proof: transient API errors retry immediately, a real session limit sleeps until the quota resets, and a done flag file makes every phase idempotent.

Cada sitio lo construye su propio worker CLI headless (claude -p), todos lanzados a la vez. El runner es a prueba de glitches: los errores transitorios de la API se reintentan al instante, un límite de sesión real duerme hasta el reset de cuota, y un fichero-bandera done hace idempotente cada fase.

# worker.sh <slug> <phase> <promptfile> — Fable worker with anti-glitch retries
for attempt in $(seq 1 12); do
  timeout 3000 claude -p "$(cat "$PROMPTFILE")" \
    --model claude-fable-5 --effort high \
    --allowedTools "Read,Write,Edit,Bash,Glob,Grep" \
    --dangerously-skip-permissions >> "$LOG" 2>&1
  rc=$?
  if [ $rc -eq 0 ]; then touch "$DONE"; exit 0; fi
  if tail -3 "$LOG" | grep -qi "session limit"; then
    # real quota limit → sleep until the advertised reset, then continue
    sleep $WAIT
  else
    # transient glitch → immediate retry (never reduce parallelism, never stop)
    sleep 5
  fi
done
tools/worker.sh
03

Assets: gpt-image-2 through LiteLLM

Assets: gpt-image-2 vía LiteLLM

Every image a site needs is generated with gpt-image-2 through a local LiteLLM proxy (POST /v1/images/generations) — no stock photography, no licensing doubts. Workers write the prompt, request the render, and drop the file into the site’s assets/ folder. Sites that are purely procedural (particles, raymarching, weaving) need no images at all.

Cada imagen que necesita un sitio se genera con gpt-image-2 a través de un proxy LiteLLM local (POST /v1/images/generations) — nada de stock, ninguna duda de licencia. Los workers escriben el prompt, piden el render y dejan el fichero en la carpeta assets/ del sitio. Los sitios puramente procedurales (partículas, raymarching, telar) no necesitan imágenes.

04

Three critique passes per site, on real screenshots

Tres pasadas de crítica por sitio, sobre capturas reales

After the build, a pipeline shoots real Playwright screenshots (desktop 1440, mobile 390, mid-scroll, footer) and hands them to a fresh worker with a mandatory brief: find at least 8 concrete defects and fix them. Each pass has its own magnifying glass:

Tras el build, un pipeline toma capturas Playwright reales (desktop 1440, móvil 390, medio scroll, footer) y se las entrega a un worker nuevo con un encargo obligatorio: encuentra al menos 8 defectos concretos y corrígelos. Cada pasada lleva su propia lupa:

The loupe pass keeps finding the same families of defects across sites, so they became standing checks: a global :focus-visible rule with a border-radius will outrank a component’s own radius and deform it on keyboard focus; a page-wide script that touches a canvas context must guard against getContext returning null (privacy hardening) or one throw kills every button on the page; animation timers restarted from visibilitychange silently stack duplicate chains unless each loop clears its own handle first; the mobile URL bar fires resize on every scroll, so a full canvas rebuild must ignore height-only jitter; backdrop-filter still needs its -webkit- twin on iOS; and prefers-reduced-motion deserves a live change listener, not a one-time read.

La pasada de lupa encuentra una y otra vez las mismas familias de defectos, así que quedaron como comprobaciones fijas: una regla global de :focus-visible con border-radius pisa el radio propio del componente y lo deforma al foco de teclado; un script de página que toca un contexto canvas debe protegerse de que getContext devuelva null (hardening de privacidad) o un solo throw mata todos los botones; los timers de animación rearrancados desde visibilitychange apilan cadenas duplicadas en silencio salvo que cada bucle limpie primero su propio handle; la barra de URL móvil dispara resize en cada scroll, así que un rebuild completo del canvas debe ignorar el jitter de solo-altura; backdrop-filter aún necesita su gemelo -webkit- en iOS; y prefers-reduced-motion merece un listener de change en vivo, no una lectura única.

# passprompt.py — each iteration pass gets its own mandatory focus
FOCUS = {
  1: "FIRST PASS — structural and concept problems: does the core
      technique truly dazzle or fall short? … raise the stakes.",
  2: "SECOND PASS — fine craft: exact spacing, display kerning,
      AA contrast, hover/focus states, easing of every animation…",
  3: "THIRD PASS — the final loupe: flawless 390px mobile, 60fps,
      accessibility, robustness… hunt the last 5 defects only an
      obsessive art director would see.",
}
print(f"""You are Claude Fable 5 on iteration pass {n}/3…
REAL SCREENSHOTS of the current state (Read them BEFORE touching anything):
- {shots}-desktop.png (1440px)  - {shots}-mobile.png (390px)""")
tools/passprompt.py · tools/pipeline.sh · tools/shoot.py
05

The gateway: moods by cookie + a live synthesis engine

La puerta: moods por cookie + motor de síntesis en vivo

The front door stores your chosen mood in a cookie (ii_mood) and routes every future visit straight to your web. Describe your mood in free text and either a fuzzy keyword matcher (accent-normalized, ES/EN) proposes the closest of the 15, or the synthesis engine invents design #16: from seed = hash(text + timestamp) it derives a harmonic HSL palette with enforced AA contrast, one of 15 curated Google-Fonts pairs, one of 4 structural layouts and a generative background (gradient mesh, SVG noise or canvas pattern), then renders the complete GenAiA homepage client-side. Deterministic: the same seed always rebuilds the same design. The door itself wears the concept: its background is a living canvas mosaic of tiny procedural “micro-webs” that boots up in a radial wave, rewrites itself in varied sweeps (both diagonals plus horizontal row ripples), and repaints the whole field in a mood’s palette the moment you hover its tile — each cell’s design is frozen in a spec at regeneration time so fades never flicker, and a static film-grain veil (one tiled SVG feTurbulence texture, zero per-frame cost) keeps the glass surfaces from reading flat.

La portada guarda tu mood elegido en una cookie (ii_mood) y dirige cada visita futura directamente a tu web. Describe tu mood en texto libre y o bien un matcher difuso de keywords (acentos normalizados, ES/EN) propone el más cercano de los 15, o el motor de síntesis inventa el diseño nº 16: de seed = hash(texto + timestamp) deriva una paleta HSL armónica con contraste AA garantizado, uno de 15 pares curados de Google Fonts, uno de 4 layouts estructurales y un fondo generativo (gradient mesh, ruido SVG o patrón canvas), y renderiza la home completa de GenAiA en el cliente. Determinista: la misma semilla reconstruye siempre el mismo diseño. La propia puerta viste el concepto: su fondo es un mosaico canvas vivo de “micro-webs” procedurales que arranca en una onda radial, se reescribe en barridos variados (ambas diagonales más ondas horizontales por filas) y repinta todo el campo con la paleta de un mood en cuanto haces hover sobre su tile — el diseño de cada celda se congela en un spec al regenerarse, así los fades nunca parpadean, y un velo estático de grano fílmico (una textura SVG feTurbulence en mosaico, coste cero por frame) evita que las superficies glass lean planas.

06

The widget: one pill on every site, injected at deploy

El widget: una píldora en cada sitio, inyectada en el deploy

The 15 sites never knew about each other while being built. The deploy script injects a single self-contained widget.js (Shadow-DOM pill, bilingual, reduced-motion aware) into each one, linking back to /?choose=1 — so the visitor can change webs from anywhere without any site having been modified by hand.

Los 15 sitios no supieron unos de otros mientras se construían. El script de deploy inyecta un único widget.js autocontenido (píldora en Shadow DOM, bilingüe, respetuosa con reduced-motion) en cada uno, enlazando de vuelta a /?choose=1 — el visitante puede cambiar de web desde cualquier sitio sin que ninguno se haya tocado a mano.

# deploy.sh — inject the style-switcher pill into the 15 sites (not the door)
for s in $SLUGS; do
  if ! grep -q "_infinite/widget.js" "$STAGE/$s/index.html"; then
    python3 - "$f" <<'EOF'
tag = '<script src="/_infinite/widget.js" defer></script>'
h = h.replace('</body>', tag + '\n</body>', 1)
EOF
  fi
done
tools/deploy.sh
07

Deploy: nginx + TLS on Hetzner

Deploy: nginx + TLS en Hetzner

A staging copy receives the widget injection and the tile thumbnails, then rsyncs to a dockerized nginx behind TLS on a Hetzner dev node. Everything is static files — the whole Infinite Internet, synthesis engine included, runs entirely in the visitor’s browser.

Una copia de staging recibe la inyección del widget y las miniaturas, y se sincroniza por rsync a un nginx dockerizado tras TLS en un nodo dev de Hetzner. Todo son ficheros estáticos — el Internet Infinito entero, motor de síntesis incluido, corre por completo en el navegador del visitante.

The fifteen, one by one

Los quince, uno a uno

Every site has its own guide explaining its concept, its signature technique and the key code behind it:

Cada sitio tiene su propia guía explicando su concepto, su técnica firma y el código clave detrás: