# Especificación de Tórculo

> El texto normativo del estándar Tórculo: la lengua de pliegos, el proyecto portable, las piezas, el canon, las láminas, las materias y las tomas. Manda el inglés si discrepan.

URL: https://torculo.joseluissaorin.com/especificacion · Revisado: 2026-10-15 · English: https://torculo.joseluissaorin.com/en/spec.md

- **Estado:** Borrador de trabajo, 2026-10-15. Lo bastante estable para implementarlo; los
  cambios pasan por el proceso de RFC (`spec/rfcs/`). La batería de conformidad de
  `conformance/` forma parte de esta especificación.
- **Editor:** José Luis Saorín Ferrer.
- **Esta versión:** `spec/SPEC.md` en <https://github.com/joseluissaorin/torculo> (privado
  hasta que pasen la especificación, la batería de conformidad y las implementaciones de
  referencia).
- **Traducción:** traducción española fiel de [`SPEC.md`](SPEC.md); si discrepan, manda el
  inglés.
- **Licencia:** esta especificación se publica bajo
  [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). El código del repositorio es
  MIT OR Apache-2.0. Quienes contribuyen se comprometen a no hacer valer patentes contra las
  implementaciones.

## Resumen

Tórculo es un estándar abierto para hacer películas, vídeos explicativos, cortos de
animación e ilustraciones en movimiento a partir de un texto que se lee como la película.
Ese texto es un **pliego**, un fichero `.mesa` escrito en la **lengua de Tórculo**: un
guion orientado a líneas, en español, con vocabularios cerrados, en el que el autor dice
*qué pasa y cómo* («la piedra rueda hasta el borde, pesada») y el motor deriva todos los
números (posiciones, curvas, duraciones, colores, sonoridad). El estándar tiene siete
partes: la lengua de pliegos, el proyecto portable (`.mesapack`) con su sidecar de voz, las
piezas (dibujos, marionetas, personajes y collage), el **canon** de la casa (paleta y azar
determinista, con vectores de prueba en tres lenguajes), las **láminas** (dibujos a mano
revelados por un atlas de tiempo), las **materias** (la convención de pasadas WGSL para
papel, acuarela, risografía y transiciones) y las **tomas** (la salida grabada del motor,
un fork de ManimGX, con su API pública). Todas las partes son deterministas: las mismas
entradas dan la misma película.

## Estado de este documento

Esta es la primera versión pública del estándar. Su parte de la lengua absorbe y
reorganiza `SPEC-MESA-2.md` de manim-saorín (el documento de trabajo de la implementación
de referencia, época 2 de la lengua); las demás partes formalizan documentos que ya
existían (`pluma/LAMINA.md`, `materias/README.md`, `FORK.md`, `SPEC-PIEZAS.md`). Cuando
este texto y un caso de conformidad discrepan, la discrepancia es un fallo que se resuelve
por el proceso de RFC; mientras no se resuelva, las implementaciones siguen el caso de
conformidad. Las desviaciones conocidas de la implementación de referencia respecto de este
texto se enumeran en el apéndice D y figuran como casos pendientes en la batería.

## Índice

- [Prefacio](#preface)
- [1. Convenciones y terminología](#terminology)
- [2. Arquitectura y conformidad](#architecture)
- Parte 1. La lengua de pliegos
  - [3. Principios](#principles)
  - [4. Estructura léxica](#lexical)
  - [5. Gramática](#grammar)
  - [6. Vocabularios cerrados](#vocabularies)
  - [7. Semántica](#semantics)
  - [8. Perfiles](#profiles)
  - [9. Extensión por capas](#extension)
  - [10. La representación intermedia](#ir)
  - [11. Invariantes](#invariants)
  - [12. Diagnósticos](#diagnostics)
  - [13. Herramientas y huellas](#tools)
- Parte 2. [14. El proyecto portable](#mesapack)
- Parte 3. [15. Piezas](#pieces)
- Parte 4. [16. El canon](#canon)
- Parte 5. [17. Láminas](#laminas)
- Parte 6. [18. Materias: la convención de pasadas](#materias)
- Parte 7. [19. Tomas y la API pública](#takes)
- [20. Consideraciones de seguridad](#security)
- [21. Consideraciones de privacidad](#privacy)
- [22. Versiones y compatibilidad](#versioning)
- [23. Tipos de medio e identificación de ficheros](#media-types)
- [24. Internacionalización](#i18n)
- [Apéndice A. Vocabularios cerrados](#appendix-a)
- [Apéndice B. Gramática](#appendix-b)
- [Apéndice C. Códigos de diagnóstico](#appendix-c)
- [Apéndice D. Desviaciones conocidas de la implementación de referencia](#appendix-d)
- [Apéndice E. Referencias](#appendix-e)
- [Apéndice F. Perfiles en desarrollo (informativo)](#appendix-f)

## Prefacio {#preface}

Un *tórculo* es la prensa del grabador. La plancha se trabaja una vez y se estampa tantas
veces como haga falta. En este estándar la plancha es un pliego, un dibujo o una materia, y
las estampas son un vídeo, una página web, una app o un juego. La *mesa* es la mesa de
trabajo donde se dispone el pliego (la hoja que pasa por la prensa): por eso los pliegos
conservan la extensión `.mesa`.

La lengua nació dentro de manim-saorín, una biblioteca de collage en movimiento sobre
Manim, para vídeo-ensayos con aspecto de cuaderno: papel, tinta que hierve, recortes con
cinta, tambores de risografía. Su primera época (`SPEC-MESA.md`) creció como un registro de
cambios; la segunda (`SPEC-MESA-2.md`, 2026-08) la hizo formal; el cortometraje
*Radiointermisión* (2026-10) le enseñó carteles, cámaras, sonido y una imagen que escucha.
En paralelo, Scholaris dio a la casa su pluma de dibujo a mano y su papel crema, y un fork
de ManimGX (un motor en Rust y wgpu con la API de Python de Manim) se convirtió en el motor
común: una película escrita en un pliego que tardaba unas tres horas y tres cuartos en
renderizarse con Cairo se renderiza en él en menos de ocho minutos. Tórculo es el nombre de
ese conjunto: la lengua, los formatos que la rodean y el motor con que se imprimen.

La lengua es española por diseño. Sus palabras clave son palabras españolas que se leen
como español (`la piedra rueda hasta el borde · pesado`), las tildes distinguen palabras
donde el español lo necesita (`él` es un personaje, `el` un artículo), y las derivaciones
del motor codifican un oficio (los principios de animación de Lasseter, el montaje de
continuidad, la imprenta) en lugar de parámetros. Esta especificación está escrita en
inglés para que cualquiera pueda implementarla; cada palabra clave se cita tal como se
escribe en un pliego.

## 1. Convenciones y terminología {#terminology}

Las palabras clave DEBE (MUST), NO DEBE (MUST NOT), OBLIGATORIO (REQUIRED), DEBERÁ (SHALL),
NO DEBERÁ (SHALL NOT), DEBERÍA (SHOULD), NO DEBERÍA (SHOULD NOT), RECOMENDADO
(RECOMMENDED), PUEDE (MAY) y OPCIONAL (OPTIONAL) se interpretan como se describe en BCP 14
(RFC 2119 y RFC 8174) cuando, y solo cuando, aparecen en mayúsculas. En esta traducción
cada una sustituye a la palabra inglesa indicada entre paréntesis, con su mismo alcance; sus
formas de plural (DEBEN, PUEDEN, DEBERÍAN…) tienen el mismo valor.

### 1.1 Términos

| Término | Significado |
|---|---|
| **pliego** | Un fichero `.mesa`: un guion en la lengua de Tórculo. |
| **servilleta** | Un pliego sin ninguna cabecera de capítulo (`==`): prosa llana (§5.12). |
| **capítulo** (*chapter*) | Una unidad de página y de render, abierta por `==`. Los capítulos PUEDEN renderizarse en paralelo. |
| **escena** (*scene*) | Una unidad de mundo dentro de un capítulo, abierta por `--`; el mundo persiste entre sus planos. |
| **clip** o **beat** | Una unidad de tiempo (un plano), abierta por `*`. |
| **línea** (*line*) | Una unidad de acción dentro de un clip. |
| **pieza** (*piece*) | Todo lo que se pone en la mesa: una cartulina, una etiqueta, un dibujo, una marioneta, una fotografía, un letrero. |
| **bestiario** (*bestiary*) | El catálogo de piezas con nombre del proyecto (`PYTHON`, `PIEZAS`). |
| **compilador** | Un programa que analiza un pliego, lo comprueba (§12) y produce su IR (§10). |
| **intérprete** | Un programa que convierte un IR en fotogramas y sonido. La referencia tiene dos: `ce` (Manim Community Edition, Cairo) y `gx` (el motor de Tórculo). |
| **IR** | La representación intermedia (*guion rico*), en JSON (§10). |
| **sidecar** | `<pliego>.tiempos.json`: las duraciones de la voz y los tiempos de cada palabra, y dónde están sus grabaciones (§14.3). |
| **toma** (*take*) | Una grabación de una ejecución del motor como un flujo de mensajes (`.take`, §19). |
| **lámina** | Un dibujo a mano con un atlas de tiempo, listo para que cualquier motor lo revele (§17). |
| **materia** | Una pasada de cómputo sobre un plano (papel, acuarela, risografía…), en la convención de §18. |
| **canon** | La única fuente de verdad de la casa: paleta, azar, números del oficio, pesos del foley (§16). |
| **época** (*epoch*) | La versión de la lengua en que está escrito un pliego (§22). |

### 1.2 Notación

Las producciones de la gramática usan el EBNF del apéndice B (`spec/gramatica/mesa.ebnf`):
los nombres en mayúsculas son no terminales, `"literal"` es texto literal, `[ ]` opcional,
`{ }` cero o más, `|` alternativa, `TEXT` el resto de la línea, `NL` un fin de línea,
`QUOTE` un texto entre comillas latinas. Un no terminal en mayúsculas que la gramática no
define es un **vocabulario cerrado** (§6, apéndice A); esa correspondencia es exhaustiva.

En este documento las palabras clave se escriben con sus tildes, como se leen; la
comparación se hace sobre la forma normalizada (§4.5).

### 1.3 JSON canónico

Siempre que esta especificación calcula el hash de un JSON o lo compara, usa el esquema de
canonicalización JSON de la RFC 8785 (JCS): claves de objeto ordenadas por unidades de
código UTF-16, sin espacios en blanco, números en la forma más corta que se conserva en
ida y vuelta en notación ECMAScript (`1.0` es `1`, `1e-7` es `1e-7`), cadenas en UTF-8
crudo que solo escapan `"`, `\` y de U+0000 a U+001F. La implementación de referencia es
`conformance/tools/jcs.py`.

## 2. Arquitectura y conformidad {#architecture}

### 2.1 Las siete partes

| Parte | Objeto normativo | Versión en Tórculo 1.0 |
|---|---|---|
| 1. Lengua de pliegos | el fichero `.mesa`, su compilación y su interpretación | época 2 |
| 2. Proyecto portable | el paquete `.mesapack` y el sidecar de voz | `mesapack 1` |
| 3. Piezas | el contrato de pieza (niveles, ficha, partes, marionetas, personajes) | 1 |
| 4. Canon | paleta, azar, números del oficio y del foley | canon 1 |
| 5. Láminas | el formato `.lamina` | 1 |
| 6. Materias | la convención de pasadas WGSL | 1 |
| 7. Tomas y API | el flujo `.take` del fork y las interfaces públicas del motor | `0x8000_0002` |

Cada parte puede implementarse por separado. Un producto declara su conformidad con una
parte y, cuando la parte define clases o perfiles, con esas clases y perfiles.

### 2.2 Clases de producto

| Clase | Parte | Pasa los tipos de caso de la batería |
|---|---|---|
| **Compilador** | 1 | `vocabulario`, `lee`, `ir` (proyección normativa, §10.6), `cierre`, `espejo` |
| **Intérprete**, por perfil | 1 | `huella` y `banda` para los pliegos de sus perfiles (§8) |
| **Empaquetador** | 2 | `mesapack_referencia`; sus paquetes pasan `mesapack` |
| **Lector de paquetes** | 2 | `mesapack` |
| **Proveedor de piezas** | 3 | las comprobaciones de piezas de §15.6 |
| **Implementación del canon** | 4 | `canon_azar` y `canon_paleta` para su lenguaje |
| **Productor de láminas** | 5 | `lamina` (salida idéntica byte a byte) |
| **Lector de láminas** | 5 | revela cada lámina de la batería como dice §17.5 |
| **Anfitrión de pasadas** | 6 | ejecuta toda materia conforme; `materia` para el comprobador |
| **Escritor / lector de tomas** | 7 | `toma` |

### 2.3 La conformidad en general

Un producto conforme:

1. DEBE aceptar todo lo que esta especificación declara válido para su clase, y rechazar lo
   que declara inválido, con los códigos de diagnóstico del apéndice C donde haya un código
   definido;
2. NO DEBE extender un vocabulario cerrado en silencio (§6.1);
3. DEBE ser determinista en el sentido de §7.4 y §16.3;
4. DEBE pasar todos los casos no pendientes de su clase en la batería de conformidad de la
   misma versión (`conformance/manifest.json`);
5. DEBERÍA comunicar sus resultados en el formato de informe de `conformance/README.md`.

A un compilador no se le exige renderizar: comprobar un pliego y producir su IR son
operaciones conformes sin ningún motor gráfico.

---

# Parte 1. La lengua de pliegos

## 3. Principios {#principles}

Estos principios son normativos: deciden toda cuestión que este texto no zanja, y una RFC
que rompa alguno DEBE decirlo y explicar por qué.

1. **La constitución anti-parámetro.** El pliego dice cuentas humanas y maneras; el motor
   pone los números. Un pliego no tiene easing, fotogramas clave, tiradores de Bézier,
   funciones de ritmo, colores hexadecimales, sombras por pieza ni duraciones sueltas en el
   dialecto pobre (§3.1). Ninguna capacidad nueva entra en la lengua si obliga a los pliegos
   a decir números que antes se derivaban.
2. **Vocabularios cerrados.** La constitución solo se sostiene porque todo vocabulario es
   cerrado, y los vocabularios cerrados solo son tolerables porque el motor deriva. Una
   palabra fuera de su lista es un error, nunca una extensión silenciosa.
3. **Cierre.** Escribir lo que el motor decidió no cambia la película (§11.1).
4. **La identidad es la semilla.** Todo lo aleatorio se siembra a partir de la identidad de
   lo que afecta, calculada a partir del contenido, nunca de la posición, el proceso, el
   reloj ni el sistema de archivos (§7.4).
5. **Lo que no cabe en la hoja no se lee.** Un texto que no puede leerse en el tiempo que
   está en pantalla es un defecto (§12, la revisión de Lasseter).
6. **La lejanía manda.** La velocidad, el color y la profundidad de cada capa se derivan de
   su distancia (*lejanía*) y de nada más, con una excepción declarada (§7.7).
7. **Los tres asientos.** Una capacidad que no está en la gramática, el compilador y el
   intérprete no existe. Una directiva que conociera el vocabulario pero no el analizador
   se imprimiría en pantalla como narración, que es el peor fallo del sistema; por eso todo
   no terminal tiene su tabla (§6) y todo evento declara si está vivo o reservado (§6.3).
8. **La ley de autoridad.** La documentación se enumera desde el analizador, no desde la
   memoria. Los vocabularios del apéndice A se extraen del analizador de referencia
   (`spec/vocabularios/extrae.py`) y la batería comprueba que coinciden (`vocabulario`).

### 3.1 Los dos dialectos

| Dialecto | Quién lo escribe | Números |
|---|---|---|
| **pobre** (*plain*) | una persona | ninguno |
| **revelado** (*revealed*) | `mesa escribe`, los transpiladores, el modo réplica | sí, cada decisión marcada `(máquina)` |

La **proporción pobre** de un pliego es la fracción de sus líneas de dramaturgia sin
cifras. Un pliego de autor DEBERÍA mantenerla en el 85 % o más; un compilador DEBE
calcularla y DEBERÍA avisar por debajo del 85 % (`W112`). Quedan fuera de la cuenta, cada
cosa por su razón: los bloques de sección (calibran un oficio, y ahí los números son
legítimos), el cuerpo de un `ver:` (los datos que dibuja una visualización), los títulos de
capítulo, los comentarios y la línea de formato. Los nombres de cues de sonido y de efectos
(por ejemplo `1M1`) son nombres, no cifras, y NO DEBERÍAN contar (véase el apéndice D).

## 4. Estructura léxica {#lexical}

### 4.1 Codificación y líneas

Un pliego es UTF-8 sin marca de orden de bytes. Los compiladores DEBEN normalizarlo a NFC
antes del análisis. Las líneas terminan en LF o CRLF. El análisis es por líneas: cada línea
se clasifica por su prefijo, y **el prefijo siempre gana**. Solo los bloques de sección
(§5.3) y `dentro:` (§5.10) abarcan varias líneas. Las líneas en blanco separan clips. La
sangría inicial no es significativa salvo dentro de los bloques de sección y de `dentro:`.

### 4.2 Comentarios, digresiones y encargos

| Forma | Significado | En el IR |
|---|---|---|
| `// text` | comentario técnico | no |
| `( text )` en una línea propia | digresión del autor | sí, `digresiones` |
| `~ deriva: text` | un encargo al motor | sí, `derivas` |

### 4.3 El separador de campos

El punto medio `·` (U+00B7), con espacios opcionales alrededor, es el único separador de
campos dentro de una línea.

### 4.4 Las comillas

El texto que va a pantalla, y los nombres que se refieren a texto, se escriben entre
comillas latinas `«…»` (U+00AB, U+00BB). Las comillas rectas no son equivalentes y NO
DEBEN aceptarse en su lugar. Una línea que consiste solo en un texto entrecomillado es un
**grito** (*shout*); un clip tiene como mucho uno (`E030`).

### 4.5 Identificadores y normalización

Un identificador es una secuencia de letras (incluidas las letras con tilde y la `ñ`),
dígitos y `_`. Las claves de sección PUEDEN contener espacios.

Las palabras clave y las palabras de los vocabularios se comparan tras esta normalización:

1. minúsculas;
2. las series de espacios se reducen a uno;
3. `_` equivale a un espacio (`toca_la_truca` es `toca la truca`);
4. se eliminan los diacríticos combinantes (NFD, se descartan de U+0300 a U+036F): la forma
   canónica no lleva tildes, y se aceptan las dos formas (`ilustración` es `ilustracion`).

**Excepción:** las palabras reservadas (§6.4) se comparan **tal como se escriben, sin
normalizar**, porque en español la tilde diacrítica distingue palabras: `el` es un
artículo reservado y `él` es un nombre de personaje válido; igual `tu`/`tú`, `si`/`sí`,
`mas`/`más`.

Los identificadores de piezas y dibujos (`id`, nombres del bestiario) DEBERÍAN ser ASCII:
son semillas (§16.3), y una tilde cambia la semilla.

### 4.6 Números

`NUMBER` es un entero o un decimal con punto, con signo opcional. Donde la lengua acepta
coma decimal, lo dice (`2,39:1`).

### 4.7 La marca `(máquina)`

Un `(máquina)` al final declara que esa decisión la tomó el motor, no una persona. Afecta a
los campos de procedencia del IR (`autor_cabecera`, `origen`) y a nada más; en particular,
no afecta al hash maestro (§7.4).

### 4.8 La raya

La raya `—` (U+2014) separa una cabeza de su cuerpo en `MOTIVO`, `PERSONAJE`, `ver:` y
`juntos:`. Los compiladores DEBEN aceptarla con o sin espacios a cualquiera de sus lados. El
estilo canónico, el que usan este documento y la batería, la pega al cuerpo, como hace la
puntuación española con una raya de apertura: `MOTIVO «error» —empieza como enemigo`,
`ver: votos —sí: 7 · no: 4`, `juntos: a · b · c —en fila`. En el diálogo, la raya que abre
un parlamento forma parte del texto (`él: —¿Falta mucho?`).

## 5. Gramática {#grammar}

La gramática completa es el apéndice B. Esta sección expone la estructura y las reglas que
las producciones por sí solas no expresan.

### 5.1 El documento

```ebnf
PLIEGO   = PREAMBLE { CHAPTER } [ END ] ;
CHAPTER  = CHAPTER-HEAD { UNIT-LINE | SECTION | COMMENT } { SCENE | CLIP } ;
SCENE    = SCENE-HEAD { UNIT-LINE | SECTION | COMMENT } { CLIP } ;
CLIP     = CLIP-HEAD { CLIP-LINE } ;
```

El mismo conjunto de **líneas de unidad** es válido en el preámbulo, en un capítulo y en
una escena; las secciones son válidas en los tres niveles. Dentro de un clip, las líneas se
clasifican por su prefijo, el prefijo siempre gana, y se conserva su orden.

### 5.2 El preámbulo

`MESA [v N] TITLE` abre un pliego y PUEDE declarar la época (`MESA v2 «El puerto»`). Un
pliego que declara una época más nueva que la del compilador DEBE rechazarse (`E001`).

`formato` declara propiedades: una relación de aspecto (`16:9`, `4:3`, `2,39:1`), `sala
crema` o `sala pizarra`, `tirada borrador` o `tirada definitiva`, `página desnuda` (sin
folio ni sello, solo papel) y `en dos` (todo lo dibujado, animado a dos fotogramas).

`REPARTO NAME: drum[, voice][, voice colour][, side][, alias: A · B]` declara a un
hablante. **El reparto es normativo para el diálogo**: un hablante que no está declarado
en `REPARTO` o en `PERSONAJE` no es un hablante (§5.5). El color de voz es `con radio` o
`seca` (si no, `E016`); el lado es `a la izquierda`, `a la derecha` o `al centro`.

El preámbulo lleva también los recursos del proyecto: `PYTHON` (o `PIEZAS`, parte 3) para
el bestiario, `EFECTOS` y `BANDA` para las carpetas de sonido, `MEZCLA` para la mezcla,
`PARTITURA`, `SOPORTE`, `LETRA`, `ARCHIVO`, `FANTASMA`, `RELOJES` y `SONIDO`. Las rutas son
relativas a la carpeta del pliego; en un proyecto portable DEBEN serlo (§14).

En la época 2, la línea de preámbulo `MUSICA path` (modo canción: la canción manda en el
montaje) y la línea de unidad `MÚSICA cue` (una cue de `BANDA`) comparten palabra clave.
Un compilador DEBE tratar `MÚSICA` seguida de un nombre que existe en `BANDA` como una cue,
y cualquier otra línea `MÚSICA` del preámbulo como una canción, con tilde o sin ella
(RFC 0004; apéndice D).

### 5.3 Las secciones y la ley del espejo

```ebnf
SECTION = "#" NOMBRE-SECCION [ IDENT ] NL { SECTION-LINE } "#FIN" | NOMBRE-SECCION PATH ;
```

Un bloque de sección escrito dentro del pliego es **idéntico en gramática** al fichero
importado en su lugar. Invariante (§11.2):

```text
effective(p) == effective(parte(p)) == effective(funde(parte(p)))
```

Las claves de varias palabras llevan dos puntos (`por defecto: tijera`) para que
sobrevivan a la ida y vuelta. La precedencia, única y sin excepciones, es por herencia
parcial (una línea sobrescribe una línea):

```text
imported  <  inline in the preamble  <  chapter block  <  scene block
```

(Es decir: lo importado, menos que lo escrito en el preámbulo, menos que el bloque de
capítulo, menos que el bloque de escena.)

`TALLER` y `MANO` son normativas (apéndice A: `FAMILIA_TALLER`, `CLAVE_MANO`); la sección
`BESTIARIO` equivale a la línea `PYTHON` del preámbulo, y la sección `REPARTO`, a las líneas
`REPARTO` del preámbulo; `MONTAJE` y
`CASCADA` están reservadas (§6.3).

### 5.4 Capítulos y escenas

`== TITLE · attributes ====` abre un capítulo. Atributos: `tensión` (una `TENSION`), `nº`,
`tambor`, `gigante`, `plano fijo` (una `PLANTILLA`, no una talla), `tramo a → b`,
`nocturno`, `diurno`.

`-- TITLE [· HORA] --` abre una escena. Líneas de unidad del núcleo:

- `EJE de A a B`: la regla de los 180 grados. De ella se derivan el lado de cada quien, la
  dirección de las miradas y por dónde vuelve a entrar quien salió por un lado.
- `LUZ direction · hardness [· rasante]`: **una por escena**; gobierna todas las sombras.
  Ninguna pieza declara su propia sombra.
- `MUNDO movement [N] · direction`: el reloj del mundo (§7.7).
- `FONDO key · distance` y `DELANTE key [· distance] [· cada N]`: fondo multiplano y
  proscenio; la velocidad, el color y la profundidad se derivan de la lejanía.
- `ESCENARIO`, `TABLAS` (el teatro de papel como decorado fijo; la hora tiñe, no oscurece;
  quien tiene pies se apoya en el suelo), `ARCHIVO`, `REPITE «scene»` (los mismos clips con
  las mismas identidades: el mismo vídeo).

Las líneas de unidad del preámbulo se aplican a todo el pliego; en un capítulo o una
escena, a ese capítulo o esa escena. La escena prevalece sobre el capítulo y el capítulo
sobre el preámbulo.

### 5.5 Clips

```ebnf
CLIP-HEAD = "*" [ BEAT-ID ] ( FUNCION | SHOT ) [ "·" AFECTO ] [ "(máquina)" ] ;
SHOT      = { TALLA | ALTURA | FRENTE | MODO } [ "de" [ ARTICLE ] IDENT ] ;
```

Dos lenguajes, los dos legítimos: una **función** dramatúrgica (`* prueba · seco`), de la
que se deriva la plantilla de composición (§6.5), o un **plano** (`* corto contrapicado de
tercero · nervioso`), que declara una talla. Son dos ejes (§6.5). El artículo del sujeto se
descarta (`general de la carretera` tiene por sujeto `carretera`). Un id de beat opcional
(`* r01_02 primer de LOCUTOR · …`) da al clip un identificador estable, el que usa el
sidecar.

Líneas de contenido: `di: TEXT` es la narración y **la partitura del beat**: su locución da
la duración del beat. `SPEAKER: TEXT` es diálogo; el hablante DEBE estar declarado y NO
DEBE ser una palabra reservada (`E021`); las directivas se resuelven primero, de modo que
un hablante con nombre de directiva no puede capturarla. `SPEAKER / SPEAKER: …` es una
frase partida entre dos voces. `letrero (register): TEXT` es un letrero
(`REGISTRO_LETRERO`; desconocido: `E014`; reservado: `W111`). `terminal:`, `canta:` y la
prosa llana completan las líneas de contenido.

### 5.6 Piezas y colocación

`pon: TYPE «text» · attributes` pone una pieza de un `TIPO-PIEZA`; `foto:`, `recorte:` y
`prensada:` ponen material de archivo; `ver: KEY —body`, una visualización del catálogo
`CLAVE_VIS`, cuyo cuerpo son datos; `pica:`; `python: NAME args`, una pieza del bestiario
(parte 3); `arriba:`, `pie:`, `nota:`; `marca: GESTURE «text»` (`GESTO_MARCA`).

**La ley del cuerpo:** casi nada va en coordenadas. La colocación es relacional:
`en los pies de primero:`, `bajo «X» a 0.42:`, `junto a`, `delante de`, `detrás de`,
`juntos: a · b · c —disposition`, `en el mundo:`, `en el documento:`, y los prefijos de los
perfiles (`en MATERIA:`, `de «A» a «B»:`, `a la izquierda:`, una lejanía, `en silueta:`).
Los prefijos se encadenan, y se encadenan con `al decir «…»:`. El tamaño de un dibujo va
tras un `·` (`grande`, `enorme`, `gigante`, `a sangre`).

`clip: path [de mm:ss a mm:ss]` pone vídeo real, un recorte vivo cuyo sonido entra en la
mezcla en su tiempo exacto. **Un clip dura lo que dice que dura**: un beat NO DEBE cerrarse
mientras uno de sus clips sigue corriendo; en su lugar, el beat crece (`W123` dice cuánto).
`> espera al clip` da al clip el turno entero: primero suena la narración, luego una
respiración, luego el clip, y la banda de subtítulos se retira mientras corre. **La
realidad no se revela**: un clip de vídeo real nunca pasa por el cuarto oscuro (ni trama,
ni duotono, ni troquel de tijera).

### 5.7 Movimiento

```ebnf
MOVEMENT = [ PLACEMENT ] [ ARTICLE ] SUBJECT VERB [ DESTINATION ]
           { "·" ( [ "por" ] TRAYECTO | MANERA | GRANULADO | REGISTRO-MOV | RASTRO ) } [ WINDOW ] ;
```

**Un movimiento se reconoce por su verbo** (`VERBO_MOV`, `VERBO_RELACIONAL`), nunca por sus
sufijos. Si no, `la piedra rueda hasta el borde`, sin sufijo, caería en la prosa y se
imprimiría como narración (§3, principio 7). Tras un `·` en una línea de movimiento solo
son válidos un trayecto, una manera, un granulado, un registro, un rastro o una ventana;
cualquier otra cosa es un error (`E012`). Los verbos relacionales crean una ligadura viva
que muere con su objetivo; un ciclo de ligaduras, una cadena de más de tres eslabones o un
anidamiento de más de tres niveles son un error (`E032`).

**La ley del movimiento:** la curva nunca se declara; se deriva de la materia, la mano, el
afecto y la manera (§7.6).

**Verbos de la vida.** Un personaje o una marioneta también se gira, se sienta y mira,
con palabras llanas: `X se gira`, `X se da la vuelta`, `X se vuelve hacia la cámara`, `X se
pone de frente | de perfil`, `X se vuelve de espaldas`; `X se sienta | se levanta | se
inclina | se yergue | se asoma a la barandilla | se apoya en la barandilla`; `X asiente |
niega | se encoge de hombros | se rasca la cabeza`; `X se acerca` (camina hacia la cámara
y crece sobre sus pies), `X se aleja`; `X mira a «Y»` (cabeza y ojos hacia otra pieza
hasta el beat siguiente); `X se queda quieto` (solo respira). Todos se pueden anclar (`al
decir «gol»: X se asoma a la barandilla`). Sin comillas, `A mira a B` es **a la vez** la
mirada que actúa la pieza y la mirada del cine (§5.8, `W103`); un compilador DEBE
conservar los dos sentidos.

### 5.8 Cámara, cine y viaje

`la truca ORDER [IDENT] [en SIZE]` mueve la truca (`ORDEN_TRUCA`); `A mira a B` (también a
alguien fuera de cuadro); `A sale|entra por la SIDE`; `sonido: adelanta|retiene|dentro|fuera`
(cortes en J y en L); `fuera de campo: TEXT`; `el foco en X`, `el foco pasa a X`, `todo en
foco` (el foco es densidad de tinta, nitidez del borde y sombra, nunca desenfoque); `X está
STATE` (un estado para la continuidad). El viaje: `X viaja`, `X se apea`, `el mundo
MOVEMENT`, `por la ventanilla: … desfilan`.

### 5.9 Eventos

```ebnf
EVENT = ">" EVENT-NAME [ ARG ] { "·" ">" EVENT-NAME [ ARG ] } ;
```

Los nombres de evento son un vocabulario cerrado con estado (§6.3). Un evento escrito en un
clip actúa en su lugar dentro del orden del autor y puede anclarse a la voz (`al decir
«GOL»: > temblor`). Una transición escrita en un clip dice cómo **entra** el clip; `funde a
negro` y `funde a blanco` dicen cómo **sale**. Cuatro eventos se copian además a un campo
del clip porque otra pasada los lee (`EVENTO_A_CAMPO`): `salta` y `cruza el eje` (las
escapatorias de los avisos de continuidad), `congela` y `continúa`.

### 5.10 Anidamiento y concurrencia

`dentro:` abre subclips (como mucho tres niveles); `mientras:` abre una pista paralela;
`al decir «w»: LINE` ancla una línea al momento en que la voz dice `w`; `LINE hasta decir
«w»` la estira hasta entonces. Las anclas se escriben **como se escriben**, no como suenan;
un compilador con el sidecar empareja las cifras con su lectura (`1154` y «mil ciento
cincuenta y cuatro») y las transcripciones aproximadas por distancia de edición, y avisa de
las anclas que nunca casan (`W120`) o que casan con la voz pero no con el texto (`W122`).

### 5.11 El final

`== FIN ===` cierra la película; las líneas que lo siguen son su colofón; `> silencio N`, su
silencio final (sin él, el compilador aplica 3 segundos y avisa, `W113`).

### 5.12 La servilleta

Un pliego sin ningún `==` es prosa: cada frase es un clip y el dramaturgo (reglas fijas,
sin aprendizaje automático) decide el resto. Es la puerta de entrada y DEBE funcionar
siempre: todo compilador y todo intérprete del perfil núcleo DEBE aceptar una servilleta,
incluida una con un preámbulo que declara su sonido (`BANDA`, `MÚSICA`, `AMBIENTE`).

## 6. Vocabularios cerrados {#vocabularies}

### 6.1 La ley

**Si una palabra no está en su lista, es un error, no una extensión silenciosa.** Todo no
terminal de la gramática que la gramática no define es un vocabulario cerrado que figura en
el apéndice A, con la estructura del analizador de referencia de la que se extrae y el
perfil al que pertenece. El apéndice A se genera (`spec/vocabularios/vocabularios.json`);
un compilador DEBE aceptar exactamente esas palabras para la época que implementa,
comparadas tras la normalización (§4.5), y DEBE rechazar cualquier otra palabra en una
posición cerrada con el código de esa posición (apéndice C).

Los vocabularios de una época están **congelados**: una versión posterior de un compilador
NO DEBE rechazar una palabra que la época declaró, incluidas las reservadas (§6.3). Las
palabras nuevas solo entran mediante una RFC y están disponibles para los pliegos que
declaran la época que las introdujo.

**Un compilador acepta la lengua entera.** Los perfiles (§8) dicen lo que un intérprete
*realiza*; nunca restringen lo que acepta un compilador. Un compilador NO DEBE rechazar una
palabra de ningún perfil porque un intérprete concreto no la realice.

### 6.2 Panorama

El apéndice A enumera 98 vocabularios (1015 palabras en total en esta versión). Los más
usados:

| Vocabulario | Palabras | Notas |
|---|---|---|
| `AFECTO` | 8 | contenido, eufórico, exhausto, juguetón, nervioso, seco, sereno, solemne |
| `FUNCION` | 11 | apertura, cartel, contrapunto, digresión, eco, giro, ilustración, prueba, remate, respiro, tesis |
| `TENSION` | 4 | sube, mantiene, cae, rompe |
| `ARCO` | 6 | espiral, letanía, pregunta→respuesta, ruina, tesis→antítesis→síntesis, viaje y vuelta |
| `TALLA` | 7, **con orden** | general, conjunto, medio, americano, corto, primer, detalle |
| `ALTURA`, `FRENTE`, `MODO` | 5, 5, 3 | los demás ejes de un plano |
| `PLANTILLA` | 8 | documento, primerísimo, general, mapa, contraplano, orla, nocturno, cartel |
| `VERBO_MOV` | 24 | baja, cae, camina, corre, cruza, entra, esquiva, flota, gira… |
| `VERBO_RELACIONAL` | 11 | agarra, alcanza, arrastra, cuelga, empuja, esquiva, huye, orbita, se apoya, sigue, suelta |
| `TRAYECTO`, `MANERA`, `GRANULADO` | 16, 15, 4 | trayectos, maneras y granulados de un movimiento |
| `EVENTO` | 163 | eventos de todos los perfiles, cada uno con su estado (§6.3) |
| `LEJANIA` | 8, **con orden** | al pie, al paso, cerca, a media distancia, lejos, al fondo, en el horizonte, en el cielo |
| `CLAVE_VIS` | 68 | el catálogo de `ver:` |
| `TAMBOR` | 7 | ámbar, bermellón, naranja, rosa, ultramar, verde, violeta |
| `PALABRA_RESERVADA` | 76 | §6.4 |

Los vocabularios con orden (`TALLA`, `LEJANIA`, `DISTANCIA`, `CADENCIA`, `INTENSIDAD`,
`SOPORTE`) llevan significado en su orden: la distancia entre dos tallas es su número de
escalones, y una intensidad es un nivel de 0 a 10.

### 6.3 Estado: vivo y reservado

Todo evento, y todo nombre de sección, declara un estado:

- **vivo** (*alive*): el compilador o el intérprete lo consume;
- **reservado** (*reserved*): la lengua lo acepta y el intérprete todavía no hace nada. Es
  vocabulario congelado: escribirlo hoy no rompe mañana. Un compilador DEBE aceptarlo y
  DEBERÍA avisar (`W110`).

En esta versión todos los eventos están vivos. Están reservadas las secciones `MONTAJE` y
`CASCADA` y los registros de letrero `máquina`, `dymo` y `tira`
(`REGISTRO_LETRERO_RESERVADO`).

### 6.4 Palabras reservadas

`PALABRA_RESERVADA` enumera las palabras que abren una línea en el analizador, más artículos
y preposiciones. NO DEBEN ser el nombre de un hablante ni un identificador (`E021`), y se
comparan sin normalizar (§4.5): `él` no es `el`.

### 6.5 Plantillas y tallas son dos ejes

Una **talla** (`TALLA`) dice cuánto del encuadre ocupa el sujeto. Una **plantilla**
(`PLANTILLA`) dice dónde caen las piezas en la hoja. Comparten una palabra, `general`, y
`primerísimo` no es `primer`. Consecuencias:

1. `PLANO_DE` hace corresponder funciones con plantillas, no con tallas:

   | Función | Plantilla |
   |---|---|
   | apertura | orla |
   | remate, giro | primerísimo |
   | respiro | general |
   | ilustración, contrapunto | contraplano |
   | digresión | mapa |
   | tesis, prueba, eco | documento |
   | cartel | cartel |

2. El aviso de salto de talla (`W102`) solo se evalúa entre dos planos consecutivos que
   declaran talla los dos.
3. `plano fijo` toma una plantilla.

### 6.6 Tipos de pieza y sustratos

`TIPO-PIEZA` (lo que acepta `pon:`: cartulina, dymo, mano, python, rescate, sello, texto,
tira, y `apunte`) es un papel dramatúrgico; `SUSTRATO` (14: papel, tira, cartulina, postit,
vegetal, acetato, foto, periódico, pijama, milimetrado, kraft, dymo, ficha, polaroid) es
una propiedad física (color de base, opacidad, sombra, foley al posarse). Todo tipo se
resuelve en un sustrato (`rescate`, `texto` y `mano` en `papel`, `sello` en `cartulina`, y
los homónimos en sí mismos); a los sustratos que no son tipos se llega desde el taller
(`materia NAME`) o desde el bestiario, no desde `pon:`.

## 7. Semántica {#semantics}

### 7.1 Unidades y estratos

```text
PLIEGO
 └─ CHAPTER      unit of page and of rendering (rendered in parallel)
     └─ SCENE    unit of world (the world persists between shots)
         └─ CLIP unit of time: a beat, a shot
             └─ LINE  unit of action
```

(El capítulo es la unidad de página y de render, y se renderiza en paralelo; la escena, la
unidad de mundo, que persiste entre planos; el clip, la unidad de tiempo: un beat, un
plano; la línea, la unidad de acción.)

Como los capítulos PUEDEN renderizarse en procesos separados, la continuidad entre ellos son
**datos serializados** (`estado_entrada`, §10.4), nunca objetos vivos.

| Estrato | Vive | Espacio | Banda de z | Lo compone el resolutor |
|---|---|---|---|---|
| `FONDO` | por secuencia | espacio de mesa | de −60 a −30 | no |
| `MUNDO` | hasta el mutis o el telón | suelo, marcas, ligaduras | de −20 a 0 | no (relacional) |
| `DOCUMENTO` | por frase | zonas y slots, con reserva | de 1 a 100 | sí |
| `PROSCENIO` | mientras cruza | espacio de mesa | de 101 a 200 | no |
| `ANOTACIÓN` | con su objetivo | el objetivo | 9000 en adelante | no |

El proscenio (lo que está entre la cámara y la escena) va por encima del documento, porque
si no cualquier cartulina se dibujaría sobre él y la oclusión no ocluiría, y por debajo de
la anotación, porque un subtítulo no está en la habitación: está sobre la película. La
pertenencia se infiere del tipo de pieza y se corrige con una palabra (`en el mundo:`, `en
el documento:`).

### 7.2 Las cinco leyes

1. La constitución anti-parámetro (§3).
2. El cierre (§11.1).
3. La identidad es la semilla (§7.4).
4. Lo que no cabe en la hoja no se lee.
5. La lejanía manda sobre la velocidad, el color y la profundidad de cada estrato (§7.7).

### 7.3 Precedencia

Toda decisión del motor tiene una dimensión y una lista ordenada de autoridades; gana la
primera autoridad que tiene un valor. Todo decisor devuelve un valor **y su razón**, o nada;
la razón es obligatoria por firma. Las autoridades son un vocabulario cerrado (`AUTORIDAD`,
34 palabras).

| Dimensión | Orden de autoridad (gana la de la izquierda) |
|---|---|
| sitio | mano, ligadura, cuerpo, slot, compositor, semilla |
| z | estrato, proscenio, llegada |
| tamaño | **declarado**, mano, identidad, papel, legibilidad |
| tiempo | partitura, ventana, tope, gesto |
| fondo | orden de la mano, escena, capítulo, carácter |
| velocidad de estrato | lejanía, **orden del mundo** |
| color de estrato | lejanía, archivo, paleta |
| curva | manera, materia, mano, afecto |
| sombra | luz (la dice la escena, nunca la pieza) |
| nombre | **exacto, alias, texto exacto, texto difuso** |

Dos candidatos que empatan en el mismo nivel de la dimensión `name` (nombre) son una
ambigüedad y un error (`E020`). La presencia de un campo en el IR **es** la señal de
autoridad (§10.5): una herramienta de explicación (`mesa por-que`) lee exactamente eso, de
modo que su explicación no puede apartarse del render.

### 7.4 Identidad, semilla y determinismo

La **identidad** es la ruta declarada (`id portada/fabula`) o la ruta derivada
(`chapter/scene/text`, es decir, capítulo/escena/texto). Se calcula a partir del
**contenido**, nunca de la posición; un índice `#n` solo desempata piezas literalmente
idénticas, y localmente.

**Semilla:**

```text
seed(piece) = H(identity) ⊕ H(take)
```

donde `H` es la función de semilla del canon (FNV-1a de 32 bits sobre UTF-8, §16.3) y
`take` es el número de interpretación (`--toma N`). La identidad gobierna lo que debe verse
siempre igual; la toma gobierna la materia: `--toma 3` da otra interpretación de la misma
película (mismos planos, misma duración, distinta materia).

**Semillas prohibidas:** ninguna semilla puede depender del orden de render o de creación,
de las direcciones de los objetos, del proceso, del reloj ni del sistema de archivos.

**El hash maestro** se calcula sobre el pliego desnudado y canonicalizado: espacios
normalizados, comentarios y digresiones fuera, secciones resueltas, marcas `(máquina)`
retiradas. Volver a escribir un pliego (`escribe`) no cambia su semilla.

**El contrato de determinismo.** Dos ejecuciones producen **la misma película** cuando
coinciden estas cinco entradas: (1) el pliego canonicalizado, (2) el número de toma, (3) la
versión del motor, (4) el bestiario y las secciones importadas, (5) el sidecar de voz. El
sidecar forma parte del contrato, no es un metadato: su `hash` y su `metodo` por beat son
entradas. Una huella dorada (§13.4) es válida para un juego de esas cinco entradas en una
máquina y una GPU; entre GPU distintas la huella se compara con tolerancia. Un pliego que
se use como referencia dorada DEBE declarar `tirada definitiva` y fijar su toma.

### 7.5 El tiempo

**Un beat, un reloj.** Todo beat tiene una duración antes de renderizarse: la de la voz
(`di:` y el diálogo, a través del sidecar, §14.3), la de `> dura N`, la de sus clips (un
beat no se cierra mientras corre un clip, §5.6) o una sintética (el tiempo de lectura de su
texto, §16.4). No hay régimen libre.

**La partitura** (`al decir «w»:`) es la primera autoridad del tiempo. Toda acción tiene una
ventana; `mientras:` abre una pista paralela; `hasta decir` estira; el **tope** impide que
una acción se coma el turno de la siguiente. Dos acciones sobre el mismo sujeto en la misma
ventana son un error (`E031`). El movimiento persiste a través de un corte salvo con
`> congela`.

### 7.6 El movimiento y el oficio

La curva de todo movimiento se deriva; el pliego nunca la declara. Los principios de
Lasseter (1987) son el comportamiento por defecto de todo verbo de movimiento, con los
números del canon (`oficio`, §16.4):

| Principio | Qué hace el intérprete | Quién lo modula |
|---|---|---|
| entrada y salida lentas | la curva derivada se suaviza en los dos extremos; nunca es lineal | la manera (`de golpe` conserva la brusquedad) |
| anticipación | retrocede por su trayecto antes de salir, en proporción a la velocidad | `con anticipación` la fuerza; `de golpe` la quita |
| arcos | sin trayecto, decide el verbo (`salta` en arco, `vuela` en curva, `cae` cayendo); si no, un arco suave hacia arriba; nada sale de la hoja por el camino | un trayecto escrito prevalece; `recto` es recto |
| estirar y encoger | se estira a lo largo de la marcha conservando su área; se aplasta al aterrizar | la velocidad y la materia (lo rígido cede la mitad) |
| acción continuada | se pasa y se asienta; se inclina contra la marcha | la masa, el rebote y el cimbreo |
| acción superpuesta | las partes de un grupo salen escalonadas, como muelles amortiguados; nunca hay más de `simultaneos_maximos` moviéndose a la vez | |
| tiempo | la duración sale de la distancia y la manera, nunca por debajo de `fotogramas_minimos` | la manera |
| pausa viva | lo que se ha movido respira (una deriva mínima sembrada): nunca un fotograma congelado | `> deja posar` la alarga |
| exageración | todo factor × `exageracion` | el canon |

**A dos fotogramas:** `en dos` anima lo dibujado a la mitad de la cadencia, con poses
sostenidas; es un sufijo de un movimiento o una propiedad del pliego entero. El vídeo real,
el hervor y los actualizadores siguen a un fotograma.

El **movimiento secundario** (arrastre, rebote, cimbreo) es una propiedad de la materia y
nunca se declara en el pliego. **Apoyo:** una pieza soltada cae hasta su apoyo; solo flota
si su materia lo permite (si no, `E033`).

### 7.7 La lejanía manda, y su única excepción

De la **lejanía** (`LEJANIA`), y de nada más, se derivan la velocidad, el color y la z de
una capa. **La excepción, declarada:** `MUNDO acelera a N` y `MUNDO frena a N` son una orden
explícita de la mano al reloj del mundo; la dimensión *velocidad de estrato* tiene una
segunda autoridad, *orden del mundo*, por debajo de la lejanía. La ley sigue valiendo entre
capas (una capa no puede ir despacio y estar delante); la orden cambia el reloj común, que
las multiplica a todas por igual. `MUNDO para` fija el reloj a cero.

### 7.8 La materia

**Nada es un relleno plano.** Toda pieza pertenece a un registro (`REGISTRO_MATERIA`):
`recorte` (contorno de tijera, grano, sombra dura, canto), `pintado` (gouache o rotulador:
pasadas con ductus y un borde desbordado), `fotográfico` (revelado y troquelado), `tinta`
(una línea dibujada a mano, que hierve). **El hervor:** tres poses del mismo camino, misma
geometría, distinto temblor, periodos sembrados por la identidad; las poses DEBEN ser
isomorfas. El hervor cambia la forma, nunca el sitio.

### 7.9 Cámara, continuidad, luz y foco

Del **eje** se derivan el lado de cada quien, su vista y su lado de entrada. El volteo solo
se aplica a las piezas declaradas espejables. Las tres leyes de cámara: el desplazamiento es
un dato, no una caja envolvente; **el corte no viaja**; una escena con mundo propio es un
lugar nuevo. Cuando la mano declara `toca la truca: sí`, la truca hereda su pulso
(anticipación, un temblor de periodo primo, sobrepaso, y pierde al sujeto medio segundo).

**Una luz por escena**, y todas las sombras la obedecen; la hora la tiñe. Está prohibido
ajustar la sombra de una sola pieza. **El foco no es desenfoque**: lo que está fuera de foco
es más pálido, con un borde más blando y algo más grande. El texto nunca se desenfoca, salvo
que se rompa una regla con permiso (§8.5).

### 7.10 Avisos de continuidad

Ninguno es fatal: romperlos es legítimo, pero hay que decirlo. `AVISO_CONTINUIDAD`:

| Aviso | Cuándo | Lo silencia |
|---|---|---|
| `W101` salto de eje | se cruza la línea sin un plano neutro | `> cruza el eje`, `> rompe el eje porque «…»` |
| `W102` salto de talla | la misma talla y el mismo ángulo sobre el mismo sujeto, o más de dos escalones, entre planos que declaran talla los dos | `> salta` |
| `W103` raccord de mirada | en un contraplano los dos miran al mismo lado | |
| `W104` dirección | sale por un lado y entra por el mismo | |
| `W105` estado | una pieza cambia sin una acción que lo explique | |

## 8. Perfiles {#profiles}

Un perfil es un conjunto de capacidades que un **intérprete** realiza. Todo intérprete DEBE
aceptar todo IR válido; ante una capacidad ajena a sus perfiles DEBE comportarse como si la
línea no estuviera, NO DEBE fallar y DEBERÍA avisar al autor una vez por capacidad. Un
intérprete declara los perfiles que realiza; los casos `huella` y `banda` de la batería se
agrupan por perfil.

| Perfil | Alcance (gramática en el apéndice B) | Referencia |
|---|---|---|
| **núcleo** (*core*) | §5 y §7: la mesa, el collage, las piezas, el movimiento con el oficio, el cine y la continuidad, el viaje, el teatro de papel, el mapa, y las líneas de aspecto de §8.1 | `ce` (en parte: no el aspecto) y `gx` |
| **sonido** (*sound*) | §8.2: voz, efectos, la partitura del sonido, cues de música, ambientes, salas, paneo y máster | `gx` |
| **cartel** (*poster*) | §8.3: todo plano es un cartel | `gx` |
| **oído** (*hearing*) | §8.4: la imagen que escucha, luz, soporte, intensidad | `gx` |
| **cámara** (*camera*) | §8.5: la cámara como objeto, profundidad, tiempo por capas, el cuadro como objeto, romper con permiso | `gx` |

La RFC 0002 propone separar las líneas de aspecto en un perfil propio.

### 8.1 Aspecto (parte del perfil núcleo)

Líneas de unidad (preámbulo, capítulo o escena; prevalece la escena) y eventos, todo
vocabulario cerrado y sin números; los números son cosa del intérprete:

- `MATERIA papel PAPEL | acuarela | risografía A y B [y C] · registration · screen | pincel
  | tejido [drum] | tinta | ninguna [sobre papel PAPEL]`: de qué está hecho el cuadro, una
  pasada sobre el fotograma terminado en la convención de la parte 6. Las mismas palabras
  como prefijo dan la materia de una pieza (`en acuarela: python: gamba`). Una fotografía no
  tiene capas: su materia se hornea una vez sobre la imagen original, no sobre su trama.
  Eventos: `> se moja`, `> se seca`, `> se lava`, `> florece [drum] [en «X»]`, `> se teje`,
  `> la tinta lo cubre todo [drum]`.
- `BOBINA truca | sin grano | noticiario`: la película (el noticiario a 18 fotogramas por
  segundo, sepia, rayas, parpadeo y vaivén).
- `FORMATO 4:3 | 16:9 | 2,39:1 [· de televisión] [· bandas de papel]` y `> formato X`:
  bandas de tinta con bordes rasgados; el cambio se anima. En un pliego que cambia de
  formato, todo formato es un visor con esquinas redondeadas y papel alrededor, y la pasada
  del visor va la última.
- `ESPEJO [side]`, `PANTALLA PARTIDA [· con un espejo en medio] [· que se miran] [·
  desigual] [· inclinada]`, `SIMULTÁNEO en rejilla | en abanico | en abanico que gira`, con
  sus eventos (`> se rompe el espejo`, `> se parte la pantalla`, `> un solo plano`…).
- Transiciones (`TRANSICION`): transiciones de dos planos en las que el plano entrante está
  vivo y el saliente es una lámina fija de su último fotograma; `corta`, `corta en la
  acción`, `sintoniza`, `a la vez`, `se sostiene`, `retención larga`.
- `RÍO TIPOGRÁFICO [· en fila | en libertad | a pantalla completa | no]`: la voz escrita
  palabra a palabra en el instante en que se dice; las mayúsculas y `> revienta «…»`
  crecen, estampan y desbordan. La frase partida (`A / B: —…`) y el letrero volador
  (`de «A» a «B»: pon: …`).
- `MONTAJE se acelera · al ritmo de las palabras · al pulso · cada vez más cerca · la
  cámara no para · mezcla «A» · «B»`: cortes dentro del beat.
- Rastros de movimiento (`con estela`, `con líneas de fuerza`, `en cronofotografía`),
  metamorfosis (`X se funde en Y`, `X hierve con Y`, `el pelo pasa de X a Y`), `> se rasga
  el papel y asoma «SCENE»`, `> asoma «SCENE» en el hueco`, `REPITE «SCENE»`, personajes con
  ficha (parte 3) y `HERVOR dibujado | suave | no`.

La cadena de cada instante es: materia, lo que asoma, espejo y pantalla partida,
simultaneidad, cámara, formato, noticiario, transición, sintonía y el baño (papel y
película). Una pasada solo cambia cuando algo cambia; sus animaciones son funciones del
tiempo de la escena.

### 8.2 Sonido

El perfil sonido abarca la voz y la banda entera. **Todo ejemplo, pieza de galería y pliego
de conformidad de este estándar lleva música y diseño sonoro.**

Preámbulo: `EFECTOS folder` (efectos y ambientes, por nombre de fichero), `BANDA folder`
(cues de música), `MEZCLA para la web | para cine · con stems | sin stems`, y en `REPARTO`
la voz, su color (`con radio`: la banda del altavoz, un toque de saturación y el soplido de
la emisora; o `seca`) y su lado. Líneas de unidad: `MÚSICA cue | ninguna`, `AMBIENTE a · b`
(capas), `ESPACIO estadio | patio | estudio | radio | seco` (la sala de los efectos),
`CAMA`, `JINGLE`. Líneas de clip: `sonido: effect [side]` (anclable: `al decir «X»: sonido:
pitido`). Eventos: `> entra la música «cue»`, `> la música se corta`, `> la música se
apaga`, `> silencio de verdad`, `> las voces se juntan en el centro`, `> cada voz a su
lado`, `> la voz se vuelve radio`.

Un intérprete del perfil sonido DEBE:

1. resolver los nombres sin distinguir mayúsculas y con la normalización de §4.5: `sonido:`
   y `AMBIENTE` en `EFECTOS` y después en `BANDA`; `MÚSICA` en `BANDA`. (Un nombre que no
   está en ninguna es un error que da el **compilador**: `E040`, `E041`, `E042`; un
   intérprete NO DEBE rodar ese pliego como si el sonido fuera silencio.)
2. mezclar en estéreo a través de cuatro buses: voces, música, efectos y ambientes;
3. mantener sonando una cue de música mientras escenas consecutivas nombran la misma cue (no
   vuelve a empezar), encadenar con un fundido cruzado al cambiar de cue, dejar que una cue
   más corta que su tramo termine por sí sola y fundir al final de su tramo una más larga;
4. repetir en bucle los ambientes con un fundido cruzado en cada vuelta, mientras duren;
5. bajar la música bajo la voz más que los ambientes: la voz siempre se entiende;
6. con `> silencio de verdad`, cortar la música, los ambientes y lo que estuviera sonando
   hasta el siguiente beat, sin tono de sala; un efecto que empieza en ese mismo instante
   suena entero;
7. colocar cada voz en su lado, moverlas con los eventos de paneo y aplicar la sala de
   `ESPACIO` a los efectos (la voz ya lleva su color en la toma);
8. masterizar a **−14 LUFS integrados para la web y −24 LUFS para cine**, con picos
   verdaderos por debajo de **−1 dBTP** (un limitador con sobremuestreo de al menos cuatro
   veces) y, con stems, escribir los cuatro buses con la ganancia del máster y sin el
   limitador;
9. no llamar nunca a un servicio de pago mientras renderiza: las voces llegan grabadas en el
   sidecar (§14.3).

La referencia escribe el máster como WAV de 24 bits junto al vídeo (`<out>.master.wav`),
los stems en `<out>.stems/` y un informe en `<out>.banda.json` con la sonoridad medida, el
pico verdadero, las cues y los recuentos; los casos `banda` de la batería leen ese informe.

### 8.3 Cartel: todo plano es un cartel

`PALETA A, B y C` (campo, figura, acento, más el papel; `COLOR_CARTEL`) y `CARTEL
composition · …` (`COMPOSICION`) componen la página como un cartel; dentro de un clip se
aplican a ese plano. **Los letreros son piezas**: `LETRA «WORD» · en TYPE · arrangement ·
place · size · de COLOUR`, `«X» es un PAPEL-SIGNO [a «SCENE»]`, una letra que es una figura
o se convierte en una, `[las letras de] «X» VERB` (cada letra con su montura y el oficio),
`la raya corta «X»`, `«X» forma FORM`, `ESCALA A como B`, `BOSQUE de …`, `en silueta:`. El
borde puede cortar las piezas (`CORTE`) y estas pueden crecer `gigante`. **La salvaguarda:**
un corte nunca quita lo esencial de una pieza (la cara y la boca de quien habla, la mano que
actúa, el objeto que importa: las partes esenciales de la parte 3); el texto que debe leerse
se lee; `· sin leer` da permiso. **El texto se teje**: `TEJE`, `SINTONIZA`, `se interrumpe
en`, `sigue`, `FRASES`, y los eventos con estado del tejido. `PARTITURA path` deja que la
tipografía del texto fuente proponga lo que un clip no dice (cursivas, rayas, mayúsculas);
lo que el clip declara prevalece.

### 8.4 Oído: la imagen que escucha

El intérprete **oye el audio real** (la voz de cada beat, ambientes, música, efectos) como
curvas a 100 muestras por segundo: intensidad (absoluta y relativa), tono (en octavas),
ataque, centroide espectral y 32 bandas logarítmicas. Pistas (`PISTA`): `la voz`, `la
música`, `la cama`, `los efectos`, `la radio`, o un sonido con nombre. Líneas: `la cámara
respira con PISTA`, `el río mide la voz`, `la luz sube con PISTA`, `el dial es la línea de
tiempo`, `X es el espectrograma de PISTA`. Luz: `LUZ de «piece» · desde abajo · drum` (una
sola fuente dura, sujeta a su pieza), `LUZ de los focos · en contraluz`, `LUZ plana`, `COLOR
monocromo [drum] | pleno`, `> estalla el color`. Soporte (la degradación como dramaturgia):
`SOPORTE limpio | usado | gastado | sucio | roto`, `> el soporte empeora | se deshace | se
limpia`; el soporte dura toda la película. **La intensidad como parámetro de dirección**:
`INTENSIDAD WORD | de WORD a WORD [· extraña] [· con PISTA]`, con once palabras de `nula`
(0) a `rota` (10), que gobiernan a la vez el temblor, la inclinación, el fuera de registro,
el grano y el ritmo de `MONTAJE al pulso`.

### 8.5 Cámara: la cámara como objeto

Líneas de unidad: `CÁMARA lens · weight · hand · depth`, `HORIZONTE recto | se inclina |
gira`, `CADENCIA target cadence · …` (cada capa dibuja a su propia cadencia), `GOLPES con
impacto | con borrón`, `PISTA ÓPTICA [side]`; los prefijos de lejanía (`lejos: python:
fachada`) ponen una pieza a esa distancia de una cámara de perspectiva real, y **el
paralaje nunca se declara**: sale de la perspectiva cuando la cámara se mueve. El cielo
está en el infinito. Los eventos (`EVENTO_CAMARA`) incluyen panorámicas con masa, travelín,
grúa, objetivos con la focal y la distancia separadas, el plano de vértigo, una curva de
tensión continua para la cámara en mano, el horizonte que se inclina, la snorricam, la
órbita, el tiempo bala, atravesar piezas, el plano secuencia, los cortes en el eje, el
cuadro como objeto (bandas de papel, perforaciones, un cuadro descarrilado) y `X mira a
cámara`.

**Romper con permiso.** Un plano puede romper una regla a sabiendas, **con su razón**:
`> rompe el eje porque «…»`, `> se sale del cuadro porque «…»`, `> sin leer porque «…»`,
`> demasiado rápido porque «…»`, `> todo a la vez porque «…»`, `> sin respiro porque «…»`,
y los encuadres incómodos con nombre (`ENCUADRE_INCOMODO`). Una regla rota sin su razón es
un error (`E060`); un compilador lo explica y la revisión de Lasseter lo enumera aparte.

## 9. Extensión por capas {#extension}

La lengua no se extiende nunca en silencio. Crece por capas, de dentro afuera:

1. **La lengua**: vocabulario cerrado, que solo cambia por RFC y en una época nueva (§22).
2. **Las secciones** `#TALLER` y `#MANO`: calibran el oficio de un proyecto o de una escena
   (papel, tinta, cantos, anclas, sombra, materias con masa y arrastre, el baño, la
   retícula; el pulso de la mano, su precisión, su grano, su entrada y su salida, su
   cansancio, y si toca la truca). Aquí los números son legítimos; la ley del espejo (§5.3)
   se cumple.
3. **El bestiario** (`PYTHON`, `PIEZAS`): piezas con nombre con sus parámetros, partes,
   poses, acciones y ciclos (parte 3), llamadas desde el pliego por su nombre (`python:
   radio`, `LOCUTOR señala`). Un bestiario añade piezas, nunca gramática; sus acciones son
   el vocabulario cerrado de esa pieza.
4. **El intérprete**: pasadas en la convención de la parte 6, materias, foley. Un intérprete
   PUEDE añadir pasadas y apariencias bajo palabras existentes; NO DEBE añadir palabras.

**La capa de la casa.** Un pliego que solo dice (un REPARTO y líneas `di:`) ya es una
película: en una unidad en la que ningún beat pone nada propio, un intérprete DEBERÍA
poner en el papel la frase de cada beat con la pieza que piden la función y el afecto (una
pregunta a mano, un grito en nota de rescate, una cita recortada de un periódico, lo demás
a máquina). La capa se apaga sola, unidad a unidad, en cuanto un beat enseña algo propio;
`página vacía` en la línea de propiedades la apaga en todo el pliego. Es lo que permite a
una persona o a un modelo pequeño escribir un primer pliego sin ningún dibujo.

`~ deriva: text` registra un encargo al motor en el IR sin cambiar la película. **Lo que
un pliego no puede decir:** easing, fotogramas clave, funciones de ritmo ni duraciones
sueltas en el dialecto pobre; colores en hexadecimal o RGB; sombra, velocidad de estrato o z
por pieza; piezas sin nombre; dos sitios para la misma decisión.

## 10. La representación intermedia {#ir}

### 10.1 Qué es

`compile(pliego)` devuelve `(script, report, extra)`: el IR (*guion rico*), una lista de
frases legibles sobre la dirección, y las decisiones por beat (función, afecto, plantilla,
tensión, autor), los motivos, el reparto y el arco. El IR es JSON, **se regenera siempre y
nunca se versiona** dentro de los proyectos; es el contrato del que comen un intérprete y un
narrador (`mesa cuenta`). **Si el narrador no sabe contar una capacidad nueva, la capacidad
está mal integrada.**

Los nombres de campo son identificadores españoles sin tildes. Los intérpretes DEBEN ignorar
los campos desconocidos (compatibilidad hacia delante, §22).

### 10.2 Nivel de guion

**Obligatorios** (un compilador conforme los emite siempre):

| Campo | Tipo | Significado |
|---|---|---|
| `escena` | cadena | nombre de la escena que se renderiza |
| `capitulo` | entero | índice de página (empieza en 0) |
| `sala` | cadena | `crema` o `pizarra` |
| `beats` | array | los clips compilados (§10.3) |
| `taller` | objeto | el taller **efectivo**, con toda la precedencia aplicada |
| `mano` | objeto | la mano **efectiva** |
| `unidades` | array | los capítulos (§10.4); OBLIGATORIO cuando el pliego tiene capítulos |

**Opcionales** (ausentes o `null` cuando el pliego no los declara): `registro` (el afecto
dominante), `subtitulos`, `gigantes`, `personajes`, `reparto`, `claves_cap`, `tambor_cap`,
`tramos_cap`, `archivo`, `archivo_cap`, `archivo_tintas`, `fantasma`, `python_ruta`,
`python_rutas`, `replica`, `efectos`, `banda`, `mezcla`, `bano`, `en_dos`, `pagina`,
`aspectos` y `colofon` (`{lineas, tirada, semilla, toma, pobre}`: **contado, no
declarado**).

El nivel de guion lleva además `marionetas` (las marionetas de foto declaradas con
`MARIONETA`: `nombre`, `foto`, `mira`, `canto`), y el aspecto de cada unidad y de cada beat
lleva `partitura_modo` (si la voz se compone como partitura tipográfica, §8.3; `null`
cuando el pliego no dice nada). Los dos son parte del IR de referencia; ninguno entra en la
proyección normativa.

### 10.3 Nivel de beat

**Obligatorios:** `id` (el ordinal del clip, `b07`, o su id de beat declarado), `cap`
(índice del capítulo), `plano` (la plantilla resuelta), `afecto` (el afecto resuelto),
`acciones` (§10.5) e `identidad` (la ruta estable de §7.4, fuente de las semillas; véase el
apéndice D).

**Opcionales, y lo que distingue a las parejas:** `di` (la locución del beat), `dura`
(duración declarada cuando no hay voz), `sec`, `corte` (hay un corte antes de este beat, lo
haya decidido quien sea) y `corte_mano` (lo pidió la mano), `plano_mano` (la plantilla se
declaró, no se derivó), `limpia`, `queda`, `canta`, `nocturno`, `congela`, `luz` (la luz
efectiva, ya resuelta con la hora), `escena`, `escena_titulo`, `abre_escena`,
`lugar_nuevo`, `linea` (la línea de origen), `aspecto` (el aspecto efectivo de §8.1 a §8.5,
un objeto por beat), `transicion`, `montaje`, `rio`, `voces`, `frase_partida`, `revienta`,
`rotos` (reglas rotas con permiso) y el resto de los campos de los perfiles. El patrón `X` /
`X_mano` es sistemático: `X` es el valor y `X_mano` dice si lo puso una persona.

### 10.4 Nivel de unidad

Cada elemento de `unidades`: `n`, `titulo`, `beats` (ids), `escenas` (títulos) y
**`estado_entrada`** (OBLIGATORIO): `{velocidad_mundo, sentido, hora}`, el estado con que
se abre el capítulo. Existe porque el movimiento persiste a través de los cortes y los
capítulos se renderizan en procesos distintos: la única manera de que el capítulo 3 sepa a
qué velocidad iba el mundo es que el compilador lo escriba, recorriendo todo lo anterior, de
forma determinista.

### 10.5 Nivel de acción

`verbo` es OBLIGATORIO. **La presencia de un campo es la señal de autoridad**: `en` (sitio
declarado por la mano: autoridad *mano*), `liga` (*ligadura*), `cuerpo` (*cuerpo*),
`al_decir` (*partitura*), `run` (*gesto*), y los `trayecto`, `manera` y `granulado` del
movimiento; `spec` y `sobre` llevan el cuerpo de un `ver:` y el objetivo de una marca. Los
verbos que emite el compilador de referencia figuran en su IR; un intérprete DEBE ignorar
un verbo que no conoce y DEBERÍA avisar al autor.

### 10.6 Forma canónica y proyección normativa

La **forma canónica** de un IR es su serialización JCS (§1.3); su **resumen** es el SHA-256
de esa serialización, en hexadecimal en minúsculas (no confundir con la huella de una
película, §13.4).

La **proyección normativa** de un IR conserva solo los campos obligatorios de §10.2 a §10.5
(niveles de guion, beat, unidad y acción). Dos compiladores conformes DEBEN producir IR con
proyecciones normativas iguales para todo pliego de la batería. A la implementación de
referencia se le exige además su IR **completo**, congelado en `conformance/expected/ir/`:
todo cambio es o una regresión o el objeto de una RFC.

## 11. Invariantes {#invariants}

### 11.1 Cierre

```text
canon(compile(p)) == canon(compile(escribe(p)))
```

donde `escribe` materializa en el pliego todas las decisiones del motor (dialecto revelado,
§3.1) y `canon(ir)` elimina la procedencia y la posición, y nada más: los campos `origen`,
`autor_cabecera`, `_importado`, `linea` y `colofon`. Todo lo que decide un fotograma DEBE
coincidir; quién lo decidió, y en qué línea, no tiene por qué.

### 11.2 El espejo

Para las secciones de §5.3, `effective(p) == effective(parte(p)) ==
effective(funde(parte(p)))`, donde `parte` lleva cada bloque a su propio fichero y lo
importa, `funde` incorpora en línea cada importación, y `effective` es el taller y la mano
tras la precedencia, comparados línea a línea tras la normalización.

### 11.3 Compatibilidad

**Un pliego que compiló una vez compila siempre** (§22).

## 12. Diagnósticos {#diagnostics}

Un compilador comprueba un pliego (`mesa lee` en la referencia) e informa de **errores** y
**avisos**, cada uno con un código estable (apéndice C, `spec/diagnosticos.json`) y un
mensaje libre, que DEBERÍA enseñar: decir qué se esperaba y ofrecer las palabras válidas más
cercanas. Un pliego con algún error es inválido; la orden de comprobación de un compilador
DEBE terminar con un estado distinto de cero para un pliego inválido y DEBERÍA terminar con
cero en caso contrario. La batería compara **conjuntos de códigos**, nunca mensajes ni
orden.

Los errores cubren las palabras fuera de un vocabulario cerrado (de `E010` a `E019`), los
nombres (de `E020` a `E022`), la estructura (de `E030` a `E033`), los recursos de sonido (de
`E040` a `E042`), el bestiario (`E050`, `E051`), las reglas rotas sin razón (`E060`) y las
líneas mal formadas (`E090`). Los avisos cubren la continuidad (de `W101` a `W105`), las
palabras reservadas en uso (`W110`, `W111`), la salud del pliego (de `W112` a `W118`), lo
que necesita el sidecar de voz (de `W120` a `W123`) y la revisión de Lasseter (`W130`).

**Los avisos que necesitan el sidecar** solo se emiten cuando existe
`<pliego>.tiempos.json`: el ancla muerta, las dos voces (un clip que suena dentro de un beat
narrado sin `> espera al clip`), el ancla ilegible y el beat que crece.

**La revisión de Lasseter** se mide sobre la línea de tiempo real de un render (o de un
render en seco que interpola los mismos fotogramas sin rasterizar), nunca sobre el pliego:
movimiento de menos de `fotogramas_minimos` fotogramas a 24 fps, más de
`simultaneos_maximos` piezas que siguen en escena moviéndose en el mismo fotograma, falta de
`pausa_fin_beat` al final de un beat, texto en pantalla durante menos de
`words / palabras_por_minuto · 60 + asiento_lectura` segundos (palabras entre palabras por
minuto, por 60, más el asiento de lectura), beats gemelos, movimiento lineal, movimiento
rápido sin anticipación. Cada aviso lleva su beat, su línea, su instante, una sugerencia y
una gravedad.

**Los diagnósticos que necesitan el bestiario** se calculan leyendo el bestiario **sin
ejecutarlo** (en la referencia, con el `ast` de Python): un nombre de `python:` que no
existe (`E050`), una pose que no se declaró (`E051`), una pose escrita sin normalizar, un
grupo que compone una pieza no creada en ese beat.

### 12.1 Diagnósticos que enseñan

El criterio de usabilidad de la lengua es que **una persona, o un modelo de lenguaje mucho
más pequeño que el que la diseñó, escriba un pliego limpio en pocos intentos sin leer
código**. Los diagnósticos son la herramienta principal para ello, así que un compilador
conforme:

- DEBE dar la **línea** de todo diagnóstico que la tenga;
- DEBERÍA dar, tras el mensaje, **el porqué** (la regla que se aplica), **el arreglo** (con
  «¿quisiste decir…?» construido por distancia de escritura, prefijo y una tabla de
  sinónimos: `lento` → `despacio`, `de frente` → `frontal`) y **un ejemplo** de la línea
  correcta;
- DEBERÍA ofrecer una **explicación de cualquier palabra o línea** (en la referencia, `mesa
  explica «X»`: qué es, dónde va y un ejemplo; para una línea entera, lo que entiende el
  parser) y una **chuleta de una página** de la lengua (`mesa chuleta`);
- DEBERÍA listar **las piezas que ve un pliego**, con su tipo, su descripción y las
  acciones que declara cada una, y la línea exacta para pedirlas (`mesa bestiario
  pliego.mesa`).

### 12.2 Ningún fallo silencioso

**Lo que parece una orden y no lo es es un error**, nunca prosa. Una línea que el
intérprete escribiría en el papel sin querer (un diálogo de quien no está en el REPARTO,
una línea de escena escrita dentro de un clip, una orden o un verbo que no existen) es
`E023`; una línea de prosa que se escribirá a máquina a propósito es el aviso `W125`. Un
compilador DEBE informar además, leyendo el pliego y el bestiario sin ejecutar nada:

| Código | Lo que, si no, fallaría en silencio |
|---|---|
| `E018` | un modificador desconocido tras `·` en `foto:`, `recorte:` o `clip:`, o un campo desconocido de `MARIONETA` |
| `E024` | `NOMBRE acción` para una pieza que no está en el REPARTO (con la pieza como alias) ni es una `MARIONETA`: la acción no le llegaría nunca |
| `E025` | `al decir «X»` cuando la voz escrita de ese beat no dice X (sin el sidecar; con él, `W120`) |
| `E052` | un dibujo mal invocado: argumentos tras `·`, paréntesis como en un lenguaje de programación, o argumentos que la firma de la pieza no admite |
| `E053` | el bestiario declarado con `PYTHON` o `PIEZAS` no existe junto al pliego |
| `E054` | una acción que la pieza no declara entre sus acciones, poses o ciclos (§15.2) |
| `W124` | una página vacía: un beat abre cuadro nuevo (una talla declarada, un capítulo o una escena nuevos) y no pone nada mientras suena la voz; no se emite en un `respiro`, que vacía la página a propósito |

El color de una entrada del REPARTO es vocabulario cerrado (los tambores del canon y las
tintas de la paleta del cartel); otra palabra es un error (`E019`).

## 13. Herramientas y huellas {#tools}

### 13.1 La orden (informativo)

La referencia trae una orden, `mesa` (`python -m manim_saorin.formato.cli`). Sus
subórdenes no son normativas, pero los adaptadores de conformidad las usan: `lee`
(comprobar), `ir` (volcar el IR), `cuenta` (contar el pliego en prosa), `escribe`
(revelar), `indice` (censo de nombres y ambigüedades), `por-que` (cada decisión con su
autoridad y su línea), `mueve`, `taller`, `parte`, `funde`, `graba` (sintetizar la voz y
escribir el sidecar), `animatica`, `toca` (renderizar; `--motor gx` sobre el motor de
Tórculo), `suena` (la banda sin renderizar), `lasseter`, `intensidad`, `dura`, `empaqueta`,
`desempaqueta`, `comprueba` (parte 2), `pieza` y `bestiario` (parte 3), y las
herramientas que enseñan de §12.1: `explica`, `chuleta` y `nuevo` (`mesa nuevo "Título"
[--desde texto.md]` escribe un proyecto con una plantilla comentada capa a capa, un
bestiario mínimo y sus carpetas, o un primer pliego sacado de un texto).

### 13.2 Lo que un compilador DEBE ofrecer

Un compilador conforme DEBE ofrecer, por cualquier interfaz: la comprobación de un pliego
con los códigos del apéndice C, el volcado de su IR como JSON, y la revelación de un pliego
(`escribe`) y la partición y fusión de sus secciones (`parte`, `funde`), de modo que pueda
probarse §11.

### 13.3 Lo que un intérprete DEBE ofrecer

Un intérprete conforme DEBE renderizar un pliego con su sidecar a un vídeo con sonido, y
DEBERÍA ofrecer una ejecución en seco que produzca la línea de tiempo que lee la revisión de
Lasseter.

### 13.4 La huella de una película

La **huella** (*fingerprint*) de un vídeo es una secuencia de miniaturas en gris de 96 × 54
píxeles, una por segundo, escaladas promediando por área (`ffmpeg -vf
fps=1,scale=96:54:flags=area -pix_fmt gray`), guardadas en base64 en JSON con el MD5 de
cada miniatura cuantizada a 4 bits. Dos huellas **casan** cuando tienen el mismo número de
muestras (±1) y la diferencia absoluta media por píxel de cada pareja de muestras es como
mucho 10 (sobre una escala de 0 a 255). En la misma máquina y con el mismo motor, la
referencia casa con diferencia 0. **Las métricas mienten**: una huella dice dónde están las
cosas, no si viven; no se cambia ninguna huella dorada sin mirar antes una tira de la
película.

---

# Parte 2. El proyecto portable

## 14. El proyecto portable {#mesapack}

### 14.1 Qué es un proyecto

Un proyecto es **el pliego, su bestiario y su sonido** (la voz con su sidecar, los efectos,
la música) **más todo lo que el pliego lee** (la `PARTITURA`, las secciones importadas, los
clips de vídeo real, las fotografías, el cerrojo de las láminas elegidas). Un empaquetador
DEBE **descubrir** esos ficheros leyendo el pliego y el bestiario, y NO DEBE ejecutar código
del proyecto para hacerlo (la referencia lee el bestiario con el `ast` de Python).

Un proyecto es **portable** cuando toda ruta que usa es relativa a la carpeta del pliego y
queda dentro de ella, y todo fichero que necesita está dentro de ella o figura en el
manifiesto como dependencia de la instalación.

### 14.2 El paquete

Un `.mesapack` es un archivo ZIP (PKWARE APPNOTE; se admite ZIP64). El audio, el vídeo y las
imágenes DEBERÍAN guardarse sin recomprimir (método 0). Contiene el árbol del proyecto, con
el pliego en la raíz, y un fichero `MANIFIESTO.json` en la raíz:

| Miembro | Tipo | Obligatorio | Significado |
|---|---|---|---|
| `formato` | cadena | sí | `"mesapack 1"`; un lector DEBE rechazar otra versión mayor (`P003`) |
| `pliego` | cadena | sí | la ruta del pliego dentro del paquete; DEBE terminar en `.mesa` y existir (`P008`) |
| `titulo` | cadena | no | el título del pliego |
| `creado` | cadena | no | ISO 8601 |
| `por` | cadena | no | la herramienta que lo empaquetó |
| `versiones` | objeto | sí | `lengua` (la época, OBLIGATORIO), `motor` (nombre, versión, commit, rama), `torculo` (commits del estándar y del motor), o `null` donde se desconozca |
| `voces` | objeto | no | el reparto con voz, color y lado, y cuántas tomas de cada método hay (§14.3) |
| `fuentes` | objeto | no | por fuente tipográfica: dónde está (`motor`, `sistema`, `usuario`) y, para las fuentes del usuario, su ruta en el paquete (`_fuentes/…`) |
| `externos` | array | no | lo que el bestiario lee de la instalación y no viaja: `{ruta, por, donde}` |
| `no_portable` | array | no | lo que no pudo hacerse portable: `{donde, ruta, arreglo}` |
| `archivo_fotos` | array | no | las fotografías de archivo que van en `_archivo/` |
| `archivos` | objeto | sí | por ruta: `{sha256, bytes, por}`; `por` dice **por qué** está el fichero en el paquete |

Un lector:

1. DEBE rechazar las entradas con una ruta absoluta, un segmento `..`, una barra invertida o
   una letra de unidad (`P004`), y NO DEBE escribir fuera de la carpeta de destino;
2. DEBE verificar el SHA-256 y el tamaño de cada fichero declarado (`P005`) y DEBERÍA
   rechazar los ficheros no declarados (`P006`);
3. DEBE comprobar que las grabaciones del sidecar son rutas relativas dentro del paquete
   (`P007`);
4. DEBERÍA, tras desempaquetar, comprobar el proyecto como lo haría un empaquetador y avisar
   cuando las versiones de la lengua, del motor o del estándar difieran de las del
   manifiesto.

El validador de referencia es `conformance/tools/mesapack.py`; el empaquetador de
referencia es `mesa empaqueta` (con `desempaqueta` y `comprueba`).

### 14.3 El sidecar de voz

`<pliego without extension>.tiempos.json` (el nombre del pliego sin extensión) está junto
al pliego. Es la quinta entrada del contrato de determinismo (§7.4).

```json
{
  "beats": {
    "b01": {"dur": 2.57, "pause": 0.4, "hash": "cf79cc76fda2", "metodo": "silabas",
            "palabras": [{"w": "Un", "t": 0.05, "d": 0.214}, {"w": "tórculo", "t": 0.264, "d": 0.482}]}
  },
  "wavs": {"b01": "audio/voz/b01.wav"}
}
```

- `beats` hace corresponder un id de beat con su locución: `dur` (segundos), `pause`
  (segundos tras ella), `hash` (del texto que se dijo, de modo que un texto cambiado
  invalida la toma), `metodo` (cómo se obtuvieron los tiempos: `whisper`, `silabas`,
  `elevenlabs`, `declarado`, `cancion`, `hueco` u otro nombre) y `palabras`, cada palabra
  `w` con su inicio `t` y su duración `d` en segundos desde el comienzo del beat. Un beat
  PUEDE llevar `t_abs` (un tiempo absoluto, para las canciones).
- `wavs` hace corresponder un id de beat con su grabación: una ruta, una lista de rutas
  (tomas encadenadas, como en una frase partida entre dos hablantes) o una lista de objetos
  `{ruta, desde}` (tomas que suenan a la vez, cada una desde su instante).
- **Las rutas DEBERÍAN ser relativas a la carpeta del sidecar** (la del pliego) y, en un
  paquete, DEBEN serlo. Los lectores DEBEN aceptar rutas relativas y absolutas, y resolver
  las relativas respecto de la carpeta del sidecar. Un sidecar cuyas rutas absolutas apuntan
  a una ubicación antigua de un proyecto que se ha movido PUEDE reanclarse cuando el mismo
  fichero (mismo sufijo de ruta y mismo tamaño) existe en la ubicación nueva.
- Un pliego cuyas voces se grabaron fuera del motor (por ejemplo, en un servicio de
  casting) las lleva en el sidecar; el render NO DEBE llamar a un servicio de voz.

### 14.4 Diagnósticos

`P001` no es un ZIP, `P002` no hay un `MANIFIESTO.json` legible, `P003` formato
desconocido, `P004` ruta peligrosa, `P005` fichero que falta o hash incorrecto, `P006`
fichero no declarado, `P007` una grabación del sidecar fuera del paquete o absoluta, `P008`
falta el pliego, `P009` falta un miembro obligatorio.

---

# Parte 3. Piezas

## 15. Piezas {#pieces}

Esta parte normaliza lo que entra en un pliego por `PYTHON`/`PIEZAS`, `python:`,
`MARIONETA`, `foto:` y `clip:`. Sigue `SPEC-PIEZAS.md` v1 de manim-saorín (rama `piezas`,
2026-10-15); la vinculación con Python que allí se describe es la vinculación de
referencia, y otro motor PUEDE ofrecer el mismo contrato en otro lenguaje.

### 15.1 Niveles

| Nivel | Qué es | El pliego puede además |
|---|---|---|
| **0, dibujo** | un dibujo a pluma, una fotografía, un recorte | ponerlo, moverlo, filmarlo, cortarlo por el borde |
| **1, partes** | más partes con nombre y con pivote | `el pelo pasa de A a B`; proteger lo esencial al cortar |
| **2, marioneta** | más articulación (madres y pivotes), poses, acciones y ciclos | `X saluda`, `X corre hasta…`; la boca sigue a la voz si hay mandíbula |
| **3, personaje** | más cinco vistas, expresiones, visemas, manos, ciclos de andar y correr, mundos de color | `X de espaldas`; la vista sigue al plano; `al decir «…»: X se asombra` |

**Cada nivel es un superconjunto del anterior.**

### 15.2 El contrato de una pieza

Una pieza es un **constructor** (en la vinculación de referencia, una función de Python que
devuelve un mobject de ManimGX) con:

- sus propios argumentos, por posición o por nombre (lo que el pliego escribe tras
  `python: name`), y los extras con valores por defecto: `alto` (altura en unidades de
  escena; la pantalla mide 8 de alto), `hervor` (0, 1 o 2 fija una pose de hervor; sin él,
  la mesa lo hace hervir), `mundo` (§15.5), `espejo`, `id`;
- su **ficha** (§15.3);
- su **hervor**: tres poses con la misma estructura y otro pulso;
- su **apoyo**: la altura donde descansa (sus pies), de modo que se sostiene por los pies,
  no por el centro.

Desde el nivel 1, una pieza expone `partes` (de nombre a subobjeto) y un pivote por parte.
Desde el nivel 2: la firma de ficha `vista`, `pose`, `expresion`, `boca`, `mano_i`,
`mano_d`, `hervor`; `POSES` (nombres), `ACCIONES` (de acción a una lista de poses, que se
ejecutan a dos fotogramas) y `CICLOS` (de ciclo a una lista de poses que se repite; `corre`
y `anda` los ponen en marcha los verbos de movimiento); un pivote y una madre para cada
parte articulada; una parte llamada `mandibula` se abre con los visemas. **Las acciones de
una marioneta son su vocabulario cerrado**: `X saluda` es válido si `saluda` está entre sus
acciones o sus poses; si no, el intérprete avisa con la lista que tiene.

Un personaje de nivel 3 tiene vistas (`frente`, `tres cuartos`, `perfil`, `tres cuartos de
espalda`, `espalda`), expresiones, bocas (`reposo`, `a`, `e`, `i`, `o`, `u`, `m`, `f`, `l`,
`gol`), manos (abierta, puño, señalando, aplaudiendo, pinza, o con un objeto en la mano),
poses comunes y los ciclos `corre` (8 dibujos), `anda` (8) y `habla` (6), y partes anidadas
con pivotes (tronco, cuello, cabeza con sus rasgos, pelo, bufanda, brazos, antebrazos,
manos, muslos, piernas, pies).

### 15.3 La ficha

| Clave | Qué | Obligatoria |
|---|---|---|
| `nivel` | `dibujo`, `partes`, `marioneta` o `personaje` | sí |
| `nombre` | ASCII sin espacios: es la semilla y lo que escribe el pliego | sí |
| `titulo` | con tildes, para las hojas | no |
| `descripcion` | lo que se ve, para quien no puede verlo; la usan la capa de sentido y el listado del bestiario | sí, de 20 caracteres o más |
| `alto` | altura natural en la escena | recomendada |
| `mira` | `derecha`, `izquierda` o `frente`: para el espejo y el eje | recomendada |
| `tintas` | los colores que usa | recomendada |
| `registro` | `dibujo`, `foto`, `recorte`, `clip`, `tipografia`, `materia` o `escaneo` | no |
| `partes` | las partes que tiene | desde el nivel 1 |
| `esenciales` | de esencial a parte | desde el nivel 1 |

### 15.4 Partes esenciales

Lo que la lengua protege al cortar por el borde (§8.3): `cara`, `boca`, `cabeza`, `mano` (la
que actúa) y `objeto` (lo que importa). Un personaje declara las cuatro primeras; una
marioneta, al menos `cabeza` u `objeto`; un dibujo, `objeto`. **Ninguna parte esencial
puede salirse del contorno de su pieza.** Sin declaraciones, el centro de la pieza es lo
esencial.

### 15.5 Mundos de color

`mundo=`: `natural`, `tinta`, `sepia`, `noche`, `hielo`, `silueta` o `silueta:#RRGGBB`,
`riso:DRUM+DRUM` (dos tambores del canon), y los mundos que registre un proyecto. Un mundo
recolorea todas las tintas de un dibujo y lleva los grises de una fotografía a sus dos
tintas.

### 15.6 En el pliego, y las comprobaciones

`PIEZAS path` (un módulo, un fichero declarativo de un personaje, una marioneta o un
recorte, o una carpeta entera) amplía `PYTHON`. `MARIONETA name · de la foto path [· mira a
la izquierda | derecha] [· canto …]` declara una marioneta de foto. `python: name [args]`
pone cualquier pieza; los argumentos con nombre fijan la pose y la vista iniciales de una
ficha. `WHO action` ejecuta una acción que la pieza declara. Collage en movimiento: `foto:
path · sin fondo · canto de tijera | de troquel | rasgado | limpio · sombra pegada |
levantada | sin sombra · con cinta | celo | chincheta`, y `clip: path de a a b · sin fondo`
(una película recortada, a dos fotogramas por defecto).

Un proveedor de piezas DEBE ofrecer una comprobación que llame a cada pieza como lo hará el
intérprete y verifique: que dibuja; que hierve (tres poses, misma estructura, distinto
pulso); que tiene sus partes y sus esenciales, ninguno fuera del contorno; que toda parte
articulada tiene un pivote dentro de la pieza; que toda acción y todo ciclo usan poses que
existen; y, para un personaje, las cinco vistas, los visemas y los ciclos. La referencia es
`mesa pieza comprueba`.

### 15.7 Marionetas de foto

Una marioneta de foto es una pieza de nivel 2 hecha de una fotografía sin código:
`MARIONETA nombre · de la foto ruta …` en el preámbulo o una ficha
`nombre.marioneta.toml`. El proveedor encuentra las articulaciones y la cara de la persona,
corta la foto una vez con el canto declarado y la parte por las articulaciones (cabeza,
tronco, brazos, antebrazos, muslos, piernas; las piernas solo si se ven enteras), cada parte
con su pivote y solapada con su madre; lo que queda bajo el labio es la `mandibula`, que se
abre con la voz. Sin persona ni cara, la foto es una sola pieza que tiembla. **Toda
marioneta de foto sabe**, además de lo que declare su ficha: `saluda`, `celebra`,
`señala`, `baila`, `se inclina`, `duda`, `grita`, `aplaude`, `en jarras`, y los ciclos
`anda` y `corre`. Una acción cuyas partes no tiene la foto (un brazo que no se encontró)
DEBERÍA avisarla la comprobación de la pieza.

Una **ficha de personaje con palabras** (`nombre.personaje.toml`) declara un personaje de
nivel 3 con palabras cerradas en vez de código: cuerpo (altura, complexión, edad), cabeza
(cráneo, nariz, gafas, ojos), pelo (estilo, color), ropa (arriba, abajo, calzado y sus
colores), el objeto que sostiene y sus poses propias (`[poses.recuerda] brazo_i = "a la
boca"`). Las palabras son vocabulario cerrado del proveedor; una palabra desconocida es un
error de la comprobación de la pieza.

### 15.8 El collage en movimiento

Fotos, recortes, vídeo real, letra, pluma y materias comparten un mismo plano.

- `foto: ruta [· modificadores]` pega una foto; con `· sin fondo` la figura se recorta (el
  proveedor quita el fondo), y el canto (`canto de tijera | de troquel | rasgado |
  limpio`), la sombra (`sombra pegada | levantada | sin sombra`) y la sujeción (`con cinta |
  con celo | con chincheta`) se declaran con palabras. `recorte:` es una foto ya sin fondo.
  La materia de una pieza sigue valiendo (`en risografía rosa: foto: …`).
- `clip: ruta [de a a b] · sin fondo` es una **película recortada**: cada fotograma se
  recorta y se vuelve a cortar a tijera, así que el canto hierve solo; va **en dos** (12
  dibujos por segundo) salvo que se diga `en uno` / `a 24` o `en cuatro`, y es un actor sin
  marco ni celo.
- `clip de fondo: ruta [de a a b]` llena el cuadro a la cadencia del cine. **Un clip de
  fondo dura su tramo**: cuando acaba, se va al abrir el beat siguiente aunque el plano
  siga; nunca se queda congelado encima de lo que viene.
- `CADENCIA` (§8.5) fija la cadencia de cada capa (`las figuras en dos · el fondo en uno`),
  de modo que la mezcla de cadencias del collage (el vídeo real a 24, los recortes en dos,
  la pluma hirviendo a 8) sale sola.
- **Los decorados de la casa.** `FONDO` y `DELANTE` montan piezas del bestiario como
  decorado de una escena; un intérprete del perfil núcleo DEBE ofrecer además, sin ningún
  bestiario, los decorados de la casa: `cielo`, `sierra`, `agua`, `arcada`, `celosia`,
  `ciudad`, `farola`, `lluvia`, `arboleda`, `cuarto`, `luna`. Una pieza del bestiario con
  el mismo nombre lo sustituye. Un decorado que no es ni lo uno ni lo otro es un error.

**Quién actúa.** Una acción se pide con un nombre del REPARTO cuyo alias es el nombre de
la pieza, también para una pieza que no habla (`REPARTO TIJERAS: minio, alias: tijeras`, y
luego `al decir «corta»: TIJERAS corta`); un alias igual a su propio nombre del REPARTO no
es una ambigüedad. La pieza tiene que estar en la mesa en ese beat o antes.

---

# Parte 4. El canon

## 16. El canon {#canon}

### 16.1 Fuente y ficheros generados

`canon/canon.toml` es la única fuente de verdad. Todas las demás formas las genera
`canon/genera.py`: Python (`canon.py`), TypeScript (`canon.ts`), Rust (`canon.rs`), WGSL
(`canon.wgsl`) y CSS (`canon.css`). Los ficheros generados NO DEBEN editarse a mano;
`genera.py --check` falla si alguno está desfasado. El fichero declara `version = 1`.

### 16.2 Paleta

Los colores son sRGB, escritos `#RRGGBB`. En WGSL y Rust son esos mismos valores sRGB como
flotantes, `component / 255` redondeados a seis decimales (sin pasarlos a luz lineal); en CSS, propiedades
personalizadas `--group-name` (grupo y nombre).

| Grupo | Colores |
|---|---|
| `papel` (papel) | base `#F5F0E8`, hundido `#EDE6D6`, hoja `#FAF7F0`, filete `#D4C4B0`, filete_hondo `#C4AE96`, noche `#1A0F0A` |
| `tinta` (tinta) | base `#2C1810`, segunda `#5C3D2E`, apagada `#7A5F4E`, lapiz `#9A8E80`, negro `#1A120D`, sobre_noche `#FAF7F0` |
| `escritorio` (escritorio) | rojo `#C1453B` (minio), azul `#2B4C7E` (azurita), amarillo `#E8A838`, oro `#D6A03A` |
| `tambores` (tambores de risografía) | ultramar `#2B3BC7`, bermellon `#D93325`, naranja `#E8501A`, ambar `#F2C744`, verde `#00A95C`, rosa `#FF48B0`, violeta `#765BA7`, humo `#1A1A1A` |

Los tambores son para el contenido, nunca para el cromo de la interfaz. El vocabulario
`TAMBOR` del pliego nombra siete (todos menos `humo`); la materia de risografía
(`TAMBOR_RISO`) acepta también `humo`, `tinta` y `azurita`. La obra nueva DEBE
usar este papel y esta tinta; los cremas antiguos `#F2EEE4` y `#F6F0E2` son legado.

### 16.3 Azar

Todo el azar de Tórculo es determinista y se deriva de tres funciones, que toda
implementación DEBE calcular bit a bit:

```text
semilla(text):   FNV-1a, 32 bits, over the UTF-8 bytes of text
                 h = 0x811C9DC5; for each byte b: h = (h XOR b) * 0x01000193 mod 2^32
serie(s):        Mulberry32 seeded with s; each call:
                 a = (a + 0x6D2B79F5) mod 2^32; t = a
                 t = (t XOR (t >> 15)) * (t OR 1)               mod 2^32
                 t = t XOR ((t + ((t XOR (t >> 7)) * (t OR 61))) mod 2^32)
                 return (t XOR (t >> 14)) / 2^32                  in [0, 1)
hash32(n):       x = (n * 0x9E3779B9 mod 2^32) XOR 0x85EBCA6B
                 x = x XOR (x >> 13); x = x * 0xC2B2AE35 mod 2^32; x = x XOR (x >> 16)
                 return (x AND 0xFFFFFF) / 2^24                   in [0, 1)
```

`serie` devuelve dobles que son múltiplos exactos de 2^−32; `hash32` devuelve valores que
son exactos en un flotante de 32 bits. Nada puede usar el reloj del sistema, `Math.random`
ni un generador sin semilla. Las semillas se calculan sobre **UTF-8**; un antiguo auxiliar
de Scholaris en TypeScript sembraba sobre unidades de código UTF-16, lo que solo coincide en
ASCII: esa es una de las razones por las que los identificadores DEBERÍAN ser ASCII.

Los vectores de prueba son normativos: `conformance/canon/vectores.json` da, para un
conjunto de textos (vacío, ASCII, con tildes, `ñ`, CJK y un carácter fuera del BMP), la
semilla, los ocho primeros valores de la serie como enteros antes de la división, y el
`hash32` de la semilla y de cinco enteros fijos. Una implementación del canon en cualquier
lenguaje DEBE reproducirlos.

### 16.4 Oficio y foley

`oficio` (el oficio, Lasseter en números; ningún pliego los escribe, el motor los aplica):
`palabras_por_minuto = 220` y `asiento_lectura = 1.0` s (tiempo de lectura de un texto),
`fotogramas_minimos = 8` (a 24 fps, nada se mueve durante menos), `simultaneos_maximos = 3`,
`pausa_fin_beat = 0.6` s, `anticipacion = 0.2` (fracción de la acción), `exageracion =
1.25`, `hervor_fps = 8`, `hervor_poses = 3`, `dibujo_en = 2` (lo dibujado, a dos
fotogramas). Un canon de una versión posterior PUEDE añadir claves; las implementaciones
DEBEN ignorar las claves que no conocen.

`foley`: el peso relativo de cada evento de foley (el oído no oye una tecla como un sello):
rotulador 0.55, tecla 0.75, hilo 0.8, papel-deslizar 1.0, papel-posar 1.0, carton-posar 1.1,
celo 1.15, despegar 1.15, tijera 1.3, chincheta 1.25, sello 1.35, punzon 1.2, papel-rasgar
1.3, pagina 1.4, campanilla 1.1, pincel 0.6, lavado 0.7.

---

# Parte 5. Láminas

## 17. Láminas {#laminas}

Una lámina es un dibujo a mano listo para que cualquier motor (web, app, juego, vídeo) lo
haga aparecer bajo la pluma **sin volver a calcular la mano**: la imagen se rasteriza una
vez y, a su lado, un **atlas de tiempo** dice en qué instante llega la pluma a cada píxel.

### 17.1 Dos envoltorios, el mismo contenido

- **Directorio** `name.lamina/` con los ficheros de §17.2.
- **Empaquetada**, un único fichero `name.lamina`:

  | Bytes | Contenido |
  |---|---|
  | de 0 a 7 | la firma `LAMINA\0\x01` (`4C 41 4D 49 4E 41 00 01`) |
  | de 8 a 11 | `n`, la longitud del índice, u32 little-endian |
  | de 12 a 12+n | el índice, JSON en UTF-8: `{"archivos": [{"ruta", "inicio", "largo"}, …]}` |
  | desde 12+n | los ficheros uno tras otro; `inicio` cuenta desde aquí |

Las rutas del índice son las rutas del directorio. Un lector distingue los dos casos por
la firma.

### 17.2 Ficheros

```text
manifiesto.json                 what there is and how it is composed (always first)
geometria.json                  the vector geometry of every pose (optional)
vista.png                       the finished drawing on paper, pose 0 (preview)
capas/<layer>-<pose>.png        colour atlas of a layer in a pose
capas/<layer>-<pose>-tiempo.png time atlas of that layer in that pose
```

(`manifiesto.json`: lo que hay y cómo se compone, siempre el primero; `geometria.json`: la
geometría vectorial de cada pose, opcional; `vista.png`: el dibujo terminado sobre papel,
pose 0, como vista previa; `capas/<layer>-<pose>.png`: el atlas de color de una capa en una
pose; `capas/<layer>-<pose>-tiempo.png`: el atlas de tiempo de esa capa en esa pose.)

Todas las imágenes de una lámina tienen el mismo tamaño: `tamano.ancho` × `tamano.alto`
píxeles, la caja del dibujo por su escala (2 por defecto).

**Atlas de color:** PNG RGBA de 8 bits **con alfa premultiplicado** (el PNG declara alfa
directo; un lector DEBE cargarlo sin tocar los valores: en WebGL,
`createImageBitmap(blob, {premultiplyAlpha: 'none', colorSpaceConversion: 'none'})` y
`UNPACK_PREMULTIPLY_ALPHA_WEBGL = false`). Sin papel: lo que no tiene tinta es transparente.

**Atlas de tiempo:** PNG RGB de 8 bits. En cada píxel, `R·256 + G` es el instante
normalizado a 16 bits, `t = (R·256 + G) / 65535`, con 0 el comienzo y 1 la `duracion` de la
lámina; `B` vale 255 donde la capa tiene tinta y 0 en el resto (y entonces R y G no
significan nada). DEBE muestrearse **sin filtrado** (vecino más próximo o `texelFetch`).
Donde se cruzan dos piezas de la misma capa, gana el instante más temprano.

| Pieza | Instante de un píxel |
|---|---|
| tinta y color (pluma) | el del punto más cercano de su línea central; a lo largo de la línea, `inicio + duracion · B⁻¹(arc/length)`, con `B` la Bézier cúbica (0.55, 0.1, 0.45, 0.95) |
| lápiz | lo mismo, lineal: `inicio + duracion · arc/length` |
| plano | un pincel en diagonal: `inicio + 0.7 s · f`, con `f` la posición a lo largo de la diagonal de su caja |
| nota | escrita de izquierda a derecha, línea tras línea, en 0.9 s |

### 17.3 Capas

En este orden, solo las que tienen algo: `lapiz` (normal), `planos` (multiplicar), `tinta`
(normal), `color` (multiplicar, con el desplazamiento de fuera de registro), `encima`
(multiplicar, con el desplazamiento), `notas` (normal; no hierve: todas sus poses apuntan a
la misma imagen).

### 17.4 Hervor

`hervor.variantes` poses (3 por defecto). La pose 0 es el dibujo de siempre; las demás
tienen la misma geometría y el mismo ritmo y solo cambian el temblor. En reproducción,
`pose = floor(seconds_at_rest · fps + offset) mod variantes` (los segundos en reposo por
los fps, más el desfase), con `fps = 8` y el desfase escrito en el manifiesto
(`hash32(semilla(id)) · variantes`). Mientras la pluma dibuja, se muestra la pose 0; el
hervor empieza cuando el dibujo está entero (`al_reposar: true`).

### 17.5 El revelado

Para cada capa, de abajo arriba, con `progress` de 0 a 1:

```glsl
float t = (R * 255.0 * 256.0 + G * 255.0) / 65535.0;
float reveal = B > 0.5 ? clamp((progress * 1.03 - t) * 60.0, 0.0, 1.0) : 1.0;
vec4 c = color * reveal;                        // premultiplied
dst = blend == "multiplicar" ? dst * (1.0 - c.a) + dst * c.rgb
                             : c.rgb + dst * (1.0 - c.a);
```

`dst` empieza siendo el papel. El adelanto de 1.03 garantiza que con `progress = 1` todo
está dibujado; la pendiente 60 da un frente de tinta de 1/60 de la duración. Los dos números
están en el manifiesto (`revelado`).

### 17.6 El manifiesto

`manifiesto.json` tiene: `formato` (`"lamina"`), `version` (1), `id` (el id y la semilla
del dibujo, en ASCII), `titulo` y `descripcion` (para los lectores de pantalla, en la lengua
de la lámina), `lengua`, `tamano` (`ancho`, `alto`, `escala`, `caja`), `duracion`, `papel`,
`alfa` (`"premultiplicada"`), `revelado` (`formula`, `adelanto` 1.03, `pendiente` 60),
`hervor` (`variantes`, `fps`, `desfase`, `semilla`, `al_reposar`), `capas` (por capa:
`nombre`, `mezcla`, `desplazamiento`, `hierve`, y las rutas de `color` y `tiempo` por pose),
`trazos` (el orden de la mano: `indice`, `capa`, `elemento`, `pasada`, `modo` (`lineal`,
`pluma`, `pincel`, `escritura`), `inicio`, `duracion`, `t0`, `t1`), `trayectoria` (dos
herramientas, `lapiz` y `pluma`, cada una una lista de `[ms, x, y, down]` en unidades de
dibujo, con milisegundos que nunca decrecen), `geometria` (ruta o null), `vista` y `canon`
(`version`, `semilla`, `serie`).

`geometria.json` da, por pose y por trazo en el orden de la mano: `tipo` (`cinta`, `linea`,
`relleno`, `nota`), su capa y sus índices, cómo se pinta, `inicio`, `duracion`, `modo`, la
línea central temblada `puntos`, el `arco` acumulado, la anchura `ancho` por punto, la
llegada `llegada` por punto, el `contorno` y, para las notas, su texto, posición, tamaño,
rotación y ancla. Los números se redondean a milésimas.

### 17.7 Garantías

- **Determinismo.** La misma lámina sale idéntica byte a byte en Rust nativo, en Python y en
  WebAssembly: el azar es el del canon y nada lee el reloj. La batería da el SHA-256 de tres
  láminas empaquetadas (casos `lamina`); un productor DEBE reproducirlos.
- **Fidelidad.** La pose 0 es el mismo dibujo que el SVG del motor de dibujo a mano
  (diferencia media inferior a medio nivel de gris, por el antialiasing).
- **Ids en ASCII** (§4.5).

### 17.8 Memoria

Cada capa en cada pose son dos texturas de `width × height × 4` bytes (ancho por alto por
4). Los lectores DEBERÍAN permitir a los productores bajar la escala o las variantes en los
dibujos grandes.

### 17.9 Diagnósticos

`L001` firma incorrecta, `L002` índice incorrecto, `L003` falta un fichero de la lista,
`L004` manifiesto incorrecto o incompleto, `L005` una imagen de tamaño equivocado, `L006` un
PNG de tipo equivocado, `L007` un atlas de tiempo cuyo canal azul no es 0 ni 255, `L008`
capas desordenadas o con la mezcla o el número de poses equivocados, `L009` trazos, `L010`
trayectoria, `L011` parámetros de hervor o de revelado. El validador de referencia es
`conformance/tools/lamina.py`.

---

# Parte 6. Materias

## 18. Materias: la convención de pasadas {#materias}

### 18.1 Qué es una materia

Una materia convierte un plano limpio en papel, acuarela, pintura, risografía, punto de
tejido o una transición. Es una o varias **pasadas de cómputo WGSL** en una convención
común, de modo que cualquier anfitrión (la cadena de posproceso del motor, una biblioteca,
una herramienta) la ejecuta tal cual. La biblioteca de referencia es `materias/` (Rust +
WGSL) y el `m.Pass` del motor (§19.6).

### 18.2 Grupo 0: la convención

Toda pasada de una materia de plano enlaza exactamente:

| Enlace | Nombre | Tipo |
|---|---|---|
| `@group(0) @binding(0)` | `entrada` | `texture_2d<f32>`: la entrada, **en luz lineal, premultiplicada**, en flotantes de media precisión |
| `@group(0) @binding(1)` | `muestreo` | `sampler`: bilineal, sujeto a los bordes |
| `@group(0) @binding(2)` | `plano` | `var<uniform> Plano` |
| `@group(0) @binding(3)` | `salida` | `texture_storage_2d<rgba16float, write>`: la salida, en la misma forma |

```wgsl
struct Plano {
    resolucion: vec2f,     // offset 0
    fotograma: u32,        // 8
    tiempo: f32,           // 12: scene time in seconds, never the system clock
    semilla: u32,          // 16
    paso: u32,             // 20: free for the materia (simulation step, pass number)
    _hueco0: u32,          // 24
    _hueco1: u32,          // 28
    params: array<vec4f, 4>, // 32: sixteen parameters
}                          // 96 bytes
```

(`tiempo` es el tiempo de la escena en segundos, nunca el reloj del sistema; `paso` queda
libre para la materia, como paso de simulación o número de pasada; `params` son dieciséis
parámetros; la estructura ocupa 96 bytes.)

Una materia DEBERÍA obtener el grupo 0 con `#import plano` en lugar de declararlo.

### 18.3 Grupos 1 y 2

Lo que es propio de una materia va en `@group(1)`: las texturas que lee o escribe, los
búferes. En el motor, el `@group(1)` de una pasada contiene solo sus imágenes (una
plancha, el plano saliente de una transición), una textura muestreada por enlace desde el 0,
en el orden dado. **El estado persistente** va en `@group(2)`: en el enlace 0, el estado tal
como está (una textura); en el enlace 1, el siguiente (una textura de almacenamiento
`rgba16float`); antes de la pasada, su punto de entrada de paso se ejecuta un número fijo de
veces por fotograma, cada una del estado al siguiente, intercambiándolos. Una materia NO DEBE
enlazar otros grupos, y NO DEBE repetir un enlace.

### 18.4 Determinismo

El único tiempo que ve una pasada es el de la escena (`plano.tiempo`, `plano.fotograma`).
Las materias con estado (la acuarela) avanzan en **pasos fijos de 60 Hz**: dos ejecuciones
dan los mismos píxeles. Un fotograma sostenido también avanza; retroceder en el tiempo
vuelve a empezar el estado desde cero. Una materia NO DEBE leer el reloj del sistema.

### 18.5 Módulos y cadenas

`#import name` pega un módulo una vez (un preprocesador de la biblioteca). Módulos
compartidos: `canon` (paleta y `hash32`, generados a partir del canon), `comun` (sRGB y
lineal, PCG, ruido de valor, fbm, ruido de gradiente entrelazado, `sobre`), `plano` (la
convención), `campos_papel` (los once campos del papel y `color_papel`), `espectral`
(transmitancia en 16 bandas y reconstrucción espectral).

Una cadena de materias se escribe `materia(key=value, …) > materia > …`; los valores son
números, nombres que la materia entiende (`tipo=khadi`, `tambor1=rosa`) o colores
`#RRGGBB`. Los puntos de entrada son puntos de entrada de cómputo con `@workgroup_size`; una
pasada que escribe `salida` DEBERÍA tomar `@builtin(global_invocation_id)` y tratar un píxel
por invocación.

### 18.6 Diagnósticos

`M001` ni importa `plano` ni declara el grupo 0 de la convención, `M002` el grupo 0 no es
exactamente el de la convención, `M003` `Plano` no es la estructura de la convención, `M004`
un punto de entrada que no es de cómputo o al que le falta `@workgroup_size`, `M005`
recursos propios fuera de los grupos 1 y 2, o un enlace repetido, `M006` lee un reloj. El
comprobador de referencia es `conformance/tools/materias.py`; la compilación y los
fotogramas de referencia los prueban las pruebas propias de la biblioteca (`cargo test
--release` en `materias/`).

---

# Parte 7. Tomas y la API pública

## 19. Tomas y la API pública {#takes}

### 19.1 El motor

El motor de referencia es un fork de ManimGX (Rust y wgpu, con la API de Python de Manim
Community Edition), rama `seams`. Todo lo que el fork añade está **desactivado por
defecto**: si no se usa nada de ello, el motor dibuja exactamente como el original
(*upstream*), píxel a píxel en el corpus de referencia. Las tomas propias del fork tienen
versiones propias (§19.3), que los lectores del original rechazan.

### 19.2 El flujo de la toma

Una toma registra una ejecución del motor como las llamadas del motor: formas, pinceles e
imágenes subidas bajo sus claves, y luego fotogramas (una vista y sus registros, mostrados
durante cierto número de fotogramas). Es un único flujo de **mensajes**, en little-endian:

```text
message  = length:u32  opcode:u8  fields…        (length counts the opcode and the fields)
bytes    = length:u32  data…
```

(La longitud cuenta el código de operación y los campos.)

El primer mensaje DEBE ser START; una toma completa termina con END. Los lectores DEBEN
rechazar una toma cuyo primer mensaje no sea START, cuya versión no conozcan, que contenga
un código de operación desconocido, un mensaje más largo que lo que queda, un segundo START
o cualquier cosa después de END.

| Código | Mensaje | Campos |
|---|---|---|
| 14 | START | versión u32, anchura u32, altura u32, cadencia f64 |
| 1 | PATH | clave u64, centroide y área f32 × 6, claves de array (puntos, subtrayectos) |
| 2 | POINTS | clave u64, clave de array |
| 3 | MESH | clave u64, contorno u32, bloque u32, claves de array |
| 4 | ROWS | clave u64, clave de array (las filas de un pincel) |
| 5 | TEXTURE | clave u64, anchura u32, altura u32, clave de array (RGBA8) |
| 6 | GROW | clave u64, cerrado u8, clave de array |
| 8 | FRAME | repetición u32, vista (bytes), clave de registros u64, número de cámaras u32 y, por cámara: clave u64, anchura u32, altura u32, vista (bytes), clave de registros u64 |
| 9 | NOTE | bytes: JSON en UTF-8 (las jugadas, las secciones y los rótulos) |
| 10 | SOUND | bytes: un fichero de audio que el reproductor reproduce junto a los fotogramas |
| 11 | ARRAY | clave u64, clave base u64 (0: ninguna), tipo u8, codificación u8, bytes (zstd) |
| 12 | END | fallida u8 |
| 13 | ENVIRONMENT | id u32, anchura u32, altura u32, clave de array |
| 15 | POST | bytes: la descripción de la cadena de posproceso (solo en `0x8000_0002`, justo después de START) |
| 16 | MATERIAL | id u32, bytes: código fuente WGSL (en `0x8000_0002`; código 15 en `0x8000_0001`) |

Las subidas se retienen hasta que un fotograma las muestra; los arrays se envían una vez
bajo una clave de su tipo y su contenido (un resumen opaco de 64 bits: los lectores DEBEN
tratar las claves como opacas) y se codifican respecto del array al que sustituyen: `ALONE`
(0), `FIRST` (diferencia respecto de la base), `SECOND` (diferencia respecto de la
predicción lineal), `TAIL` (la base es su comienzo), carril a carril y comprimidos con zstd,
con un fotograma clave cada 32 versiones. Los registros de un FRAME ocupan 424 bytes cada
uno (ocho claves de 8 bytes, banderas, dos matrices de 3 × 4, pinturas, parámetros, trazo
discontinuo, material, el id de la materia u32, la mezcla u32, un id de usuario u64 y
dieciséis flotantes de usuario). El número de fotogramas de una toma es la suma de las
repeticiones de los mensajes FRAME.

### 19.3 Versiones

| Versión | Registros | Códigos 15 y 16 | Lectores |
|---|---|---|---|
| `0x8000_0001` | 424 B | 15 = MATERIAL | DEBE leerse |
| `0x8000_0002` | 424 B | 15 = POST, 16 = MATERIAL | la escribe el motor de Tórculo 1.0 |

El rango de `0x8000_0000` en adelante es del fork; las versiones del original están por
debajo. Un escritor de tomas de este estándar DEBE escribir `0x8000_0002`. Una disposición
o un código de operación nuevos toman la versión siguiente.

### 19.4 Diagnósticos

`T001` el primer mensaje no es START, `T002` versión desconocida, `T003` un mensaje más
largo que la toma, `T004` código de operación desconocido, `T005` START repetido o datos
después de END, `T006` POST no va justo después de START, `T007` un NOTE o un MATERIAL que
no es UTF-8 válido (JSON, en el caso de NOTE). El lector de referencia es
`conformance/tools/toma.py`.

### 19.5 Determinismo del motor

Los sombreadores ven el tiempo de la escena (o el índice del fotograma), nunca el reloj. La
misma escena, renderizada dos veces en la misma máquina y la misma GPU con el mismo motor,
da los mismos bytes; entre GPU distintas no se garantiza, y por eso las huellas se comparan
con tolerancia (§13.4). Las semillas de las materias, del fuera de registro y del hervor
salen de la `semilla` del canon aplicada al nombre de una pieza
(`set_material(…, pieza="c1_09/rosa")`), nunca de un contador.

### 19.6 La API pública

**Estabilidad.** Las interfaces de esta sección son públicas en Tórculo 1.0: solo cambian
mediante una RFC. Todo lo demás del fork es interno.

Python (`import manimgx as m`; la API de Manim CE, véase la guía propia del motor):

| Interfaz | Qué |
|---|---|
| `m.config.post = [m.Papel(), m.Bobina("truca")]` | la cadena de posproceso: pasadas sobre cada fotograma terminado; el grano vive en las pausas |
| `m.Pass(shader, entry=None, reach=…, moves=…, params=(), paths=(), pictures=…, estado=None, pasos=…)` | cualquier pasada en la convención de la parte 6, con las imágenes en `@group(1)` y el estado persistente en `@group(2)` |
| `m.Papel(plate=None, …)`, `m.Bobina(reel="truca", lut_in=None, lut=None, papel=canon paper, …)` | el baño de imprenta y la película de la casa |
| `m.config.compositing = "linear"` | componer en luz lineal (flotantes de media precisión); por defecto, sRGB |
| `mobject.set_material(name, …, pieza=None)`, `m.register_material(name, wgsl, params)` | materias por objeto (`papel`, `acuarela`, `riso`, y las registradas que definen `fn materia(m: Materia) -> vec4<f32>`) |
| `mobject.set_blend("normal" | "multiplicar")` | cómo descansa un objeto sobre lo que tiene debajo |
| `mobject.set_clip("mascara" | "dentro" | "fuera", name)` | recorte por forma en la composición |
| `m.Trazo(points, widths, tiempos=None, grano=None)`, `m.Trazo.de_pluma(stroke)` | el trazo de pluma de anchura variable, que `Create` dibuja al ritmo de la mano |
| `m.Hervor(drawing, poses=3, fps=8, desfase=True, gpu=False)` | la línea que vive en reposo |
| `m.sidecar(pliego | tiempos.json | folder)` | la voz real de un pliego como voz de `self.say`, sincronizada por palabra; sin voz, la voz por defecto lanza un error en lugar de llamar a un servicio de pago |

Línea de órdenes: `manimgx render scene.py [--codec h264 | hevc | prores | prores4444]
[--take] [-r WxH] [--fps N] [--sound-events]`. HEVC Main10 y ProRes usan VideoToolbox
(macOS); ProRes 4444 lleva alfa, sin premultiplicar. **Los binarios que incluyen x264
(`--codec h264`) son GPL; las compilaciones solo con VideoToolbox no lo son**
(`DECISIONES.md`). Los errores estrictos son lo predeterminado: el LaTeX mal formado y los
avisos de Typst fallan en la línea de la escena; `--no-strict` los convierte en avisos.

Rust: el crate `manimgx-render` (`Replay::read(&bytes)`, `replay.render(i)` a RGBA,
`Gpu::from_device(…)` para dibujar en el dispositivo de otra aplicación).

Web: `<manimgx-film src="Scene.take" autoplay>` reproduce una toma con WebGPU, sin Python;
necesita mezcla en float32 y `depth32float-stencil8` (Chrome y Edge 113 y posteriores,
Safari 26).

---

## 20. Consideraciones de seguridad {#security}

- **Compilar NO DEBE ejecutar código del proyecto.** Un compilador comprueba y compila un
  pliego y lee su bestiario sin ejecutarlo (§12). Un empaquetador descubre los ficheros de
  la misma manera (§14.1).
- **Renderizar ejecuta el bestiario.** Un pliego con `PYTHON` o `PIEZAS` ejecuta ese código
  cuando se renderiza: un intérprete DEBE tratar un pliego así como un programa, y un visor
  de proyectos que no son de confianza NO DEBE renderizarlos fuera de un entorno aislado. Una
  servilleta o un pliego sin bestiario no ejecuta nada más que el motor.
- **Los paquetes** pueden llevar rutas peligrosas (§14.2): los lectores DEBEN rechazarlas
  antes de escribir nada, verificar los hashes y acotar el tamaño total sin comprimir.
- **Las tomas llevan código fuente de sombreadores** (MATERIAL, POST) que se ejecuta en la
  GPU. WebGPU y wgpu lo validan, pero una toma hostil aún puede agotar recursos: los
  reproductores DEBERÍAN acotar el número de materiales, el tamaño de los arrays y de las
  texturas, y el tamaño descomprimido de cada ARRAY, y DEBEN rechazar una toma que
  incumpla §19.2.
- **Las láminas** están acotadas por su manifiesto; un lector DEBERÍA rechazar una lámina
  cuyos tamaños de imagen o número de capas superen su presupuesto de memoria (§17.8).
- **Sin red durante el render.** Las voces, la música y los efectos vienen del proyecto; un
  intérprete NO DEBE llamar a un servicio de pago o remoto mientras renderiza.

## 21. Consideraciones de privacidad {#privacy}

- Las grabaciones de voz son datos personales de quien habla. Un paquete las lleva; su
  manifiesto dice cuántas tomas de cada método tiene, nunca quién las grabó, salvo que lo
  declare el reparto.
- Las rutas absolutas revelan nombres de usuario y estructuras de carpetas
  (`/Users/name/Library/Caches/…`). Los sidecars DEBERÍAN usar rutas relativas, y los
  paquetes DEBEN usarlas (§14.3).
- El manifiesto registra los commits y las versiones de las herramientas, no la máquina.

## 22. Versiones y compatibilidad {#versioning}

- **La constitución de la compatibilidad: un pliego que compiló una vez compila siempre.**
  La época se declara en el preámbulo (`MESA v2`); un compilador DEBE compilar todo pliego
  de toda época que declare soportar, y DEBERÍA leer la época 1 (`SPEC-MESA.md`) como
  legado. El vocabulario de una época está congelado, palabras reservadas incluidas.
- Una época nueva PUEDE añadir palabras y líneas; NO DEBE cambiar el significado de un
  pliego válido de una época anterior. Retirar una palabra solo es posible declarándola
  legado en una época nueva, y los compiladores siguen aceptándola en los pliegos que
  declaran la antigua.
- El IR no se versiona (§10.1): los intérpretes DEBEN ignorar los campos y los verbos
  desconocidos.
- Las versiones mayores de `mesapack` son incompatibles entre sí (`mesapack 2` sería otro
  formato); las menores (`mesapack 1.1`) solo añaden miembros que los lectores pueden
  ignorar.
- La versión 1 de las láminas se escribe en la firma y en el manifiesto; una disposición
  nueva toma la versión 2.
- Las versiones de las tomas figuran en §19.3.
- La `version` del canon cambia cuando cambia cualquier valor; los ficheros generados la
  llevan.
- La especificación se numera MAYOR.MENOR con publicaciones editoriales (`spec-v1.0.0`); su
  número y los de las bibliotecas son independientes (`governance/VERSIONING.md`).

## 23. Tipos de medio e identificación de ficheros {#media-types}

Propuestos, no registrados:

| Extensión | Tipo de medio | Identificación |
|---|---|---|
| `.mesa` | `text/vnd.torculo.mesa; charset=utf-8` | texto UTF-8 cuya primera línea que no es comentario empieza por `MESA` (o prosa: una servilleta) |
| `.mesapack` | `application/vnd.torculo.mesapack+zip` | un ZIP con `MANIFIESTO.json` cuyo `formato` empieza por `mesapack` |
| `.lamina` | `application/vnd.torculo.lamina` | la firma `LAMINA\0\x01` (un directorio `.lamina/` tiene `manifiesto.json`) |
| `.take` | `application/vnd.torculo.take` | primer mensaje START (código 14) con una versión desde `0x8000_0001` |
| `.tiempos.json` | `application/json` | junto a un pliego con la misma raíz de nombre |

## 24. Internacionalización {#i18n}

La lengua de Tórculo es el español: las palabras clave, los vocabularios y los diagnósticos
son palabras españolas, y las tildes son significativas donde el español las hace
significativas (§4.5, palabras reservadas). El texto en pantalla es lo que escriba el autor,
en cualquier escritura, normalizado a NFC. Los compiladores DEBERÍAN escribir sus mensajes en
español y PUEDEN ofrecer traducciones; los códigos no dependen de la lengua. Un juego de
palabras clave localizado (por ejemplo, palabras clave inglesas que lleven al mismo IR)
sería un dialecto nuevo y necesita una RFC; el IR, que es el contrato, no cambiaría.

---

## Apéndice A. Vocabularios cerrados {#appendix-a}

Generado a partir de `spec/vocabularios/vocabularios.json`, que se extrae del analizador de
referencia. Cada vocabulario da su perfil, la estructura de la que procede y sus palabras en
forma canónica (sin tildes, §4.5); un compilador las acepta con tildes o sin ellas.

<!-- vocabularios:inicio -->

### Perfil: núcleo

**`ACCION_FICHA`** (15 palabras; Fuente: `formato.aspecto.ACCIONES`)

anda · aplaude · baila · cae · celebra · corre · gesticula · gira el dial · grita · habla · recoge · salta · se levanta · senala · señala

**`AFECTO`** (8 palabras; Fuente: `formato.vocabulario.AFECTOS`)

contenido · euforico · exhausto · jugueton · nervioso · seco · sereno · solemne

**`ALTURA`** (5 palabras; Fuente: `formato.continuidad.ALTURAS`)

cenital · contrapicado · nadir · normal · picado

**`ANCLA`** (5 palabras; Fuente: `formato.vocabulario.ANCLAS`)

bordado · celo · chincheta · esquineras · washi

**`ARCO`** (6 palabras; Fuente: `formato.vocabulario.ARCOS`)

espiral · letania · pregunta→respuesta · ruina · tesis→antitesis→sintesis · viaje y vuelta

**`AUTORIDAD`** (34 palabras; Fuente: `formato.precedencia.AUTORIDADES`)

afecto · alias · archivo · capitulo · caracter · compositor · cuerpo · declarado · escena · estrato · exacto · gesto · identidad · legibilidad · lejania · ligadura · llegada · luz · manera · mano · mano_taller · materia · orden_mano · orden_mundo · paleta · papel · partitura · proscenio · semilla · slot · texto_difuso · texto_exacto · tope · ventana

**`AVISO_CONTINUIDAD`** (5 palabras; Fuente: `formato.continuidad.AVISOS`)

RACCORD DE DIRECCIÓN · RACCORD DE ESTADO · RACCORD DE MIRADA · SALTO DE EJE · SALTO DE TALLA

**`BOBINA`** (3 palabras; Fuente: `formato.aspecto.BOBINAS`)

noticiario · sin grano · truca

**`CLAVE_MANO`** (7 palabras; Fuente: `formato.taller.MANO_BASE`)

cansa · entra · granulado · precision · pulso · sale · toca la truca

**`CLAVE_VIS`** (68 palabras; Fuente: `visualizaciones.CATALOGO`)

alfiler · ancla · arbol · balanza · barras · brujula · bucle · cadena · caja · cancelacion · ciclo · comparacion · constelacion · convergencia · cuadrante · cuenta · curva · dado · diana · dispersion · distribucion · domino · ecuacion · ejes · embudo · engranaje · escalera · espectro · espiral · flecha de proceso · fraccion · globo · grieta · huella · interruptor · isla · jerarquia · laberinto · linea temporal · lista tachada · lupa · mapa · medidor · moneda · monton · multitud · onda · orbita · papeleta · pendulo · pila · ping pong · porcentaje · proceso · puente · recorrido · red · reloj · resta · semaforo · suma · telarana · teorema · termometro · titere · venn · versus · votos

**`DESREGISTRO`** (2 palabras; Fuente: `formato.aspecto.DESREGISTROS`)

desregistrada · en registro

**`DIMENSION`** (10 palabras; Fuente: `formato.precedencia.DIMENSIONES`)

color_estrato · curva · fondo · nombre · sitio · sombra · tamaño · tiempo · velocidad_estrato · z

**`DIRECCION_LUZ`** (5 palabras; Fuente: `formato.vocabulario.DIRECCIONES_LUZ`)

cenital · de atras · de frente · de la derecha · de la izquierda

**`DISPOSICION`** (8 palabras; Fuente: `formato.vocabulario.DISPOSICIONES`)

amontonados · como flores · en abanico · en columna · en corro · en fila · en fila holgados · en rejilla

**`DUREZA`** (2 palabras; Fuente: `formato.vocabulario.DUREZAS`)

blanda · dura

**`ESPEJO_LADO`** (2 palabras; Fuente: `formato.aspecto.ESPEJO_LADOS`)

de la derecha · de la izquierda

**`EVENTO`** (163 palabras; Fuente: `formato.vocabulario.EVENTOS`)

a la vez · aire al reves · amanece · anochece · arranca de golpe · asoma · barre · barrido · barrido a la derecha · barrido a la izquierda · barrido hacia abajo · barrido hacia arriba · barrido temporal · cada voz a su lado · camara lenta · camara lenta a saltos · capitulo · chasquido · congela · congela la imagen · continua · corta · corta en la accion · cortado por la barbilla · cortado por la frente · cortinilla de tijera · cruza el eje · cuadro vacio · deja posar · demasiado cerca de · demasiado rapido · desenfoque de pasada · destellan los focos · dura · el clip se agranda y se va · el color se apaga · el cuadro gira · el cuadro se endereza · el fotograma se descarrila · el horizonte se endereza · el horizonte se inclina · el montaje se acelera · el que habla fuera de campo · el rio mide · el soporte empeora · el soporte se deshace · el soporte se limpia · empapela · encadena · entra de golpe · entra la musica · espectrograma de · espera al clip · estalla el color · florece · formato · fotograma de impacto · fotograma en blanco · funde a blanco · funde a negro · funde desde blanco · funde desde negro · gigante · gran angular · iris · la camara atraviesa · la camara baja · la camara deja de respirar · la camara entra en · la camara gira alrededor de · la camara mira desde dentro de · la camara no para · la camara respira con · la camara sale de · la camara se acerca a · la camara se aleja · la camara sube · la camara va a · la camara va montada en · la camara va pegada a · la camara vuelve · la costura se mueve hacia · la intensidad cae a · la intensidad salta a · la intensidad sube a · la linea se endereza · la linea se inclina · la linea se mueve · la linea se rompe · la luz sube con · la mancha deja · la mano tapa · la musica se apaga · la musica se corta · la pista se desborda · la pista vuelve · la tela se desenreda · la tela se enreda · la tension cae · la tension rompe · la tension se mantiene · la tension sube · la tinta lo cubre todo · la voz se vuelve radio · las bandas bajan · las bandas suben · las voces se juntan en el centro · lente normal · mezcla los registros · mirando fuera de campo · montaje al pulso · montaje al ritmo de las palabras · ojo de pez · pasa pagina · pasa por delante · plano holandes · plano secuencia por · queda · rampa de velocidad · respira · retencion larga · revienta · rio tipografico · rompe el eje · salta · salto axial a · se desteje · se junta la pantalla · se lava · se moja · se para en seco · se parte la pantalla · se quema · se rasga el papel · se rasga la banda · se rompe el espejo · se sale del cuadro · se seca · se sostiene · se teje · se van las perforaciones · se ven las perforaciones · seco · silencio · silencio de verdad · simultaneo en abanico · simultaneo en abanico que gira · simultaneo en rejilla · sin leer · sin respiro · sintoniza · teleobjetivo · temblor · tiempo bala sobre · todo a la vez · todo se para menos · triple salto axial a · un solo plano · velocidad normal · vertigo · vertigo al reves · vuelve el espejo · zoom de golpe

Reservados: ninguno.

**`EVENTO_A_CAMPO`** (8 palabras; Fuente: `formato.vocabulario.EVENTO_A_CAMPO`)

Correspondencia: congela → congela_mano · continua → continua · cortado por la barbilla → salta · cortado por la frente → salta · cruza el eje → cruza_eje · demasiado cerca de → salta · rompe el eje → cruza_eje · salta → salta

**`EXPRESION`** (9 palabras; Fuente: `formato.aspecto.EXPRESIONES`)

duda · se asombra · se asusta · se calma · se enfada · se entristece · se pone serio · se rie · sonrie

**`FAMILIA_TALLER`** (10 palabras; Fuente: `formato.taller.TALLER_BASE`)

ancla · bano · canto · fantasma · materia · papel · reticula · sombra · tinta · vida

**`FORMATO`** (6 palabras; Fuente: `formato.aspecto.FORMATOS`)

16:9 · 1:1 · 2,39:1 · 4:3 · 4:5 · 9:16

**`FORMATO_MODO`** (2 palabras; Fuente: `formato.aspecto.FORMATO_MODOS`)

bandas de papel · de television

**`FRENTE`** (5 palabras; Fuente: `formato.continuidad.FRENTES`)

escorzo · espalda · frontal · perfil · tres cuartos

**`FUNCION`** (11 palabras; Fuente: `formato.vocabulario.FUNCIONES`)

apertura · cartel · contrapunto · digresion · eco · giro · ilustracion · prueba · remate · respiro · tesis

**`GESTO_MARCA`** (4 palabras; Fuente: `formato.vocabulario.GESTO_MARCA`)

rodea · senala · subraya · tacha

**`GRANULADO`** (4 palabras; Fuente: `movimiento.GRANULADOS`)

a doses · a pulso · a treses · a unos

**`HERVOR`** (3 palabras; Fuente: `formato.aspecto.HERVORES`)

dibujado · no · suave

**`HORA`** (5 palabras; Fuente: `formato.vocabulario.HORAS`)

amanece · atardece · diurna · mediodia · nocturna

**`LADO`** (4 palabras; Fuente: `formato.vocabulario.LADOS`)

abajo · arriba · derecha · izquierda

**`LEJANIA`** (8 palabras, con orden; Fuente: `viaje.LEJANIAS`)

al pie · al paso · cerca · a media distancia · lejos · al fondo · en el horizonte · en el cielo

**`LINEA_UNIDAD_ASPECTO`** (20 palabras; Fuente: `formato.aspecto.UNIDAD`)

AMBIENTE · BANDA · BOBINA · CAMA · EFECTOS · ESPACIO · ESPEJO · FORMATO · HERVOR · JINGLE · MATERIA · MEZCLA · MONTAJE · MÚSICA · PANTALLA PARTIDA · REPITE · RIO TIPOGRAFICO · RÍO TIPOGRÁFICO · SIMULTANEO · SIMULTÁNEO

**`MANERA`** (15 palabras; Fuente: `movimiento.MANERAS`)

a la deriva · a regañadientes · a tirones · con anticipación · con cuidado · de golpe · de un tirón · despacio · en volandas · ligero · pesado · resuelto · rozando · sin ganas · titubeante

**`MATERIA`** (7 palabras; Fuente: `formato.aspecto.MATERIAS`)

acuarela · ninguna · papel · pincel · risografia · tejido · tinta

**`MODO`** (3 palabras; Fuente: `formato.continuidad.MODOS`)

cartel · documento · mundo

**`MONTAJE`** (6 palabras; Fuente: `formato.aspecto.MONTAJES`)

al pulso · al ritmo de las palabras · cada vez mas cerca · la camara no para · mezcla · se acelera

**`MOVIMIENTO_MUNDO`** (4 palabras; Fuente: `formato.vocabulario.MOVIMIENTO_MUNDO`)

acelera · avanza · frena · para

**`NOMBRE_SECCION`** (6 palabras; Fuente: `formato.taller.SECCIONES`)

BESTIARIO · CASCADA · MANO · MONTAJE · REPARTO · TALLER

**`ORDEN_TRUCA`** (9 palabras; Fuente: `formato.vocabulario.ORDEN_TRUCA`)

baja · busca a · encuadra a · se acerca · se acerca a · se queda · sigue a · sube · viaja con

**`PALABRA_RESERVADA`** (76 palabras; Fuente: `formato.vocabulario.PALABRAS_RESERVADAS`)

a · al · alias · ancla · archivo · arco · arriba · bajo · bestiario · camino · canta · cascada · clip · con · contenido · de · del · delante · dentro · deriva · detras · di · eco · eje · el · en · escenario · fantasma · foco · fondo · formato · foto · fuera · hilo · junto · juntos · la · las · letra · letrero · los · luz · mano · marca · mesa · mientras · montaje · motivo · mundo · musica · nota · o · para · personaje · pica · pie · pon · por · prensada · python · que · recorte · relojes · reparto · revelado · se · sobre · sonido · su · sus · taller · terminal · un · una · ver · y

**`PAPEL`** (11 palabras; Fuente: `formato.aspecto.PAPELES`)

cuaderno · escolar · grano fino · khadi · kraft · lienzo · satinado · tintado · torchon · verjurado · washi

**`PARTE_CUERPO`** (7 palabras; Fuente: `formato.vocabulario.PARTES_CUERPO`)

el hombro · el pecho · el regazo · la cabeza · la espalda · las manos · los pies

**`PLANO_DE`** (11 palabras; Fuente: `formato.vocabulario.PLANO_DE`)

Correspondencia: apertura → orla · cartel → cartel · contrapunto → contraplano · digresion → mapa · eco → documento · giro → primerisimo · ilustracion → contraplano · prueba → documento · remate → primerisimo · respiro → general · tesis → documento

**`PLANTILLA`** (8 palabras; Fuente: `formato.vocabulario.PLANTILLAS`)

cartel · contraplano · documento · general · mapa · nocturno · orla · primerisimo

**`RASTRO`** (4 palabras; Fuente: `formato.aspecto.RASTROS`)

con borron · con estela · con lineas de fuerza · en cronofotografia

**`REGISTRO_LETRERO`** (6 palabras; Fuente: `formato.vocabulario.REGISTROS_LETRERO`)

cartulina · cita · cita maquina · cita moderna · mano · rescate

**`REGISTRO_LETRERO_RESERVADO`** (3 palabras; Fuente: `formato.vocabulario.REGISTROS_LETRERO_RESERVADOS`)

dymo · maquina · tira

**`REGISTRO_MATERIA`** (4 palabras; Fuente: `materia.REGISTROS`)

fotografico · pintado · recorte · tinta

**`REGISTRO_MOV`** (1 palabras; Fuente: `movimiento.REGISTROS`)

en dos

**`RIO_MODO`** (3 palabras; Fuente: `formato.aspecto.RIO_MODOS`)

a pantalla completa · en fila · en libertad

**`SENTIDO`** (2 palabras; Fuente: `formato.vocabulario.SENTIDOS`)

de espaldas · de frente

**`SIMULTANEO`** (3 palabras; Fuente: `formato.aspecto.SIMULTANEOS`)

en abanico · en abanico que gira · en rejilla

**`SUSTRATO`** (14 palabras; Fuente: `pieza.SUSTRATOS`)

acetato · cartulina · dymo · ficha · foto · kraft · milimetrado · papel · periodico · pijama · polaroid · postit · tira · vegetal

**`TALLA`** (7 palabras, con orden; Fuente: `formato.continuidad.TALLAS`)

general · conjunto · medio · americano · corto · primer · detalle

**`TAMBOR`** (7 palabras; Fuente: `formato.vocabulario.TAMBORES_V`)

ambar · bermellon · naranja · rosa · ultramar · verde · violeta

**`TAMBOR_RISO`** (10 palabras; Fuente: `formato.aspecto.TAMBORES_RISO`)

ambar · azurita · bermellon · humo · naranja · rosa · tinta · ultramar · verde · violeta

**`TENSION`** (4 palabras; Fuente: `formato.vocabulario.TENSIONES`)

cae · mantiene · rompe · sube

**`TRAMA`** (3 palabras; Fuente: `formato.aspecto.TRAMAS`)

de grano · de lineas · de puntos

**`TRANSICION`** (16 palabras; Fuente: `formato.vocabulario.TRANSICIONES`)

chasquido · corta · corta en la accion · cortinilla de tijera · desenfoque de pasada · encadena · entra de golpe · funde a blanco · funde a negro · funde desde blanco · funde desde negro · iris · la mano tapa · pasa pagina · se quema · sintoniza

**`TRAYECTO`** (16 palabras; Fuente: `movimiento.TRAYECTOS`)

a saltos · cayendo · en arco · en curva · en espiral · en zigzag · flotando · fuera de campo · girando · por el borde · por el camino · por el suelo · rebotando · recto · resbalando · rodando

**`VENTANA`** (2 palabras; Fuente: `movimiento.VENTANAS`)

hasta decir · mientras

**`VERBO_MOV`** (24 palabras; Fuente: `movimiento.VERBOS`)

baja · cae · camina · corre · cruza · entra · esquiva · flota · gira · rebota · resbala · rueda · sale · salta · se apea · se encaja · se levanta · se sienta · sube · tiembla · tropieza · va · viaja · vuela

**`VERBO_RELACIONAL`** (11 palabras; Fuente: `movimiento.VERBOS_RELACIONALES`)

agarra · alcanza · arrastra · cuelga · empuja · esquiva · huye · orbita · se apoya · sigue · suelta

**`VISTA`** (5 palabras; Fuente: `formato.aspecto.VISTAS`)

de espaldas · de frente · de perfil · de tres cuartos · de tres cuartos de espaldas

### Perfil: sonido

**`ESPACIO`** (5 palabras; Fuente: `formato.aspecto.ESPACIOS_SALA`)

estadio · estudio · patio · radio · seco

**`MEZCLA`** (4 palabras; Fuente: `formato.aspecto.MEZCLAS`)

con stems · para cine · para la web · sin stems

**`VOZ`** (6 palabras; Fuente: `formato.sonido.VOCES`)

cita · cita_f · cita_f2 · cita_f3 · cita_m2 · narrador

### Perfil: cartel

**`BOSQUE`** (5 palabras; Fuente: `formato.cartel.BOSQUES`)

brazos · brazos y punos · manos · manos abiertas · punos

**`COLOR_CARTEL`** (16 palabras; Fuente: `formato.cartel.COLORES`)

amarillo · arena · azul · blanco · celeste · crema · lila · minio · morado · naranja · negro · rojo · rosa · tinta · ultramar · verde

**`COMPOSICION`** (15 palabras; Fuente: `formato.cartel.COMPOSICIONES`)

campo a sangre · campo en bandas · campo partido en diagonal · centro vacio · columna a sangre a la derecha · columna a sangre a la izquierda · diagonal de abajo a la izquierda arriba a la derecha · diagonal de arriba a la izquierda abajo a la derecha · disco detras · en silueta · enorme · figura delante de la letra · la letra corta a la figura · la letra delante de la figura · tercios

**`CORTE`** (12 palabras; Fuente: `formato.cartel.CORTES`)

cortada por abajo · cortada por arriba · cortada por el borde · cortada por la derecha · cortada por la frente · cortada por la izquierda · cortado por abajo · cortado por arriba · cortado por el borde · cortado por la derecha · cortado por la frente · cortado por la izquierda

**`DISPOSICION_SIGNO`** (6 palabras; Fuente: `formato.cartel.DISPOSICIONES`)

a sangre · en abanico · en columna · en escalera · girada · rota por el borde

**`EVENTO_CARTEL`** (5 palabras; Fuente: `formato.cartel.EVENTOS`)

la costura se mueve hacia · la mancha deja · la tela se desenreda · la tela se enreda · se desteje

**`FORMA_PALABRA`** (5 palabras; Fuente: `formato.cartel.FORMAS`)

el patio · un marco · un muro · una columna · una porteria

**`LINEA_UNIDAD_CARTEL`** (3 palabras; Fuente: `formato.cartel.UNIDAD`)

CARTEL · PALETA · PARTITURA

**`PAPEL_SIGNO`** (9 palabras; Fuente: `formato.cartel.ROLES`)

barandilla · cielo · cuchilla · mascara · muro · persiana · porteria · suelo · ventana

**`SITIO_SIGNO`** (5 palabras; Fuente: `formato.cartel.SITIOS`)

a la derecha · a la izquierda · abajo · arriba · en el centro

**`TIPO_LETRA`** (6 palabras; Fuente: `formato.cartel.TIPOS`)

anton · la serifa de pretexto · league gothic · letra de mano · maquina de escribir · serifa

**`VERBO_SIGNO`** (14 palabras; Fuente: `formato.cartel.VERBOS_SIGNO`)

cae · caen · se abre · se abren · se apila · se apilan · se estampa · se estampan · se rompe · se rompen · se separa · se separan · se va · se van

### Perfil: oído

**`DIRECCION_FUENTE`** (4 palabras; Fuente: `formato.oye.DIRECCIONES_LUZ`)

desde abajo · desde arriba · desde la derecha · desde la izquierda

**`EVENTO_OYE`** (14 palabras; Fuente: `formato.oye.EVENTOS_OYE`)

destellan los focos · el color se apaga · el rio mide · el soporte empeora · el soporte se deshace · el soporte se limpia · espectrograma de · estalla el color · la camara deja de respirar · la camara respira con · la intensidad cae a · la intensidad salta a · la intensidad sube a · la luz sube con

**`INTENSIDAD`** (11 palabras, con orden; Fuente: `formato.oye.INTENSIDADES`)

nula · quieta · serena · templada · viva · agitada · tensa · encendida · desatada · furiosa · rota

**`PISTA`** (5 palabras; Fuente: `formato.oye.PISTAS`)

la cama · la musica · la radio · la voz · los efectos

**`SOPORTE`** (5 palabras, con orden; Fuente: `formato.oye.SOPORTES`)

limpio · usado · gastado · sucio · roto

### Perfil: cámara

**`BANDA_CUADRO`** (4 palabras; Fuente: `formato.camara.BANDAS`)

de abajo · de arriba · de la derecha · de la izquierda

**`BLANCO_CADENCIA`** (6 palabras; Fuente: `formato.camara.BLANCOS_CADENCIA`)

el fondo · la camara · la letra · las figuras · lo de delante · todo

**`CADENCIA`** (4 palabras, con orden; Fuente: `formato.camara.CADENCIAS`)

en uno · en dos · en tres · en cuatro

**`DISTANCIA`** (9 palabras, con orden; Fuente: `formato.camara.DISTANCIAS`)

delante · al pie · cerca · al paso · a media distancia · lejos · al fondo · en el horizonte · en el cielo

**`ENCUADRE_INCOMODO`** (7 palabras; Fuente: `formato.camara.INCOMODOS`)

aire al reves · cortado por la barbilla · cortado por la frente · cuadro vacio · demasiado cerca de · el que habla fuera de campo · mirando fuera de campo

**`EVENTO_CAMARA`** (47 palabras; Fuente: `formato.camara.EVENTOS_CAMARA`)

barrido temporal · camara lenta a saltos · el cuadro gira · el cuadro se endereza · el fotograma se descarrila · el horizonte se endereza · el horizonte se inclina · fotograma de impacto · gran angular · la camara atraviesa · la camara baja · la camara entra en · la camara gira alrededor de · la camara mira desde dentro de · la camara sale de · la camara se acerca a · la camara se aleja · la camara sube · la camara va a · la camara va montada en · la linea se endereza · la linea se inclina · la linea se mueve · la linea se rompe · la pista se desborda · la pista vuelve · la tension cae · la tension rompe · la tension se mantiene · la tension sube · las bandas bajan · las bandas suben · lente normal · ojo de pez · pasa por delante · plano secuencia por · rampa de velocidad · salto axial a · se rasga la banda · se van las perforaciones · se ven las perforaciones · teleobjetivo · tiempo bala sobre · todo se para menos · triple salto axial a · vertigo · vertigo al reves

**`GOLPE`** (2 palabras; Fuente: `formato.camara.GOLPES`)

con borron · con impacto

**`HORIZONTE`** (3 palabras; Fuente: `formato.camara.HORIZONTES`)

gira · recto · se inclina

**`LENTE`** (4 palabras; Fuente: `formato.camara.LENTES`)

gran angular · normal · ojo de pez · teleobjetivo

**`LINEA_UNIDAD_CAMARA`** (7 palabras; Fuente: `formato.camara.UNIDAD`)

CADENCIA · CAMARA · CÁMARA · GOLPES · HORIZONTE · PISTA OPTICA · PISTA ÓPTICA

**`MANO_CAMARA`** (2 palabras; Fuente: `formato.camara.MANOS`)

al hombro · en tripode

**`PESO_CAMARA`** (3 palabras; Fuente: `formato.camara.PESOS`)

con masa · ligera · pesada

**`PISTA_LADO`** (2 palabras; Fuente: `formato.camara.PISTA_LADOS`)

a la derecha · a la izquierda

**`PROFUNDIDAD`** (2 palabras; Fuente: `formato.camara.PROFUNDIDADES`)

poca profundidad · profundidad total

**`ROTURA`** (6 palabras; Fuente: `formato.camara.ROTURAS`)

demasiado rapido · rompe el eje · se sale del cuadro · sin leer · sin respiro · todo a la vez

<!-- vocabularios:fin -->

## Apéndice B. Gramática {#appendix-b}

La gramática completa es `spec/gramatica/mesa.ebnf`, normativa, que se reproduce aquí.

<!-- gramatica:inicio -->

```ebnf
(* Tórculo 1.0, part 1: the grammar of the pliego language (.mesa), epoch 2.

   Normative. Notation (SPEC §1.4):
     NAME            nonterminal; every nonterminal in capitals that is not defined
                     here is a closed vocabulary of Appendix A (spec/vocabularios/
                     vocabularios.json), and that correspondence is exhaustive.
     "literal"       literal text, compared after normalization (SPEC §4.5),
                     except reserved words, which are compared as written.
     A | B           alternative          [ A ]   optional       { A }  zero or more
     TEXT            any characters up to the end of the line
     NL              end of line
     IDENT           identifier (SPEC §4.5)
     NUMBER          integer or decimal with a point, optional sign
     QUOTE           "«" TEXT-WITHOUT-» "»"      (U+00AB … U+00BB; straight quotes are not equivalent)
     ·               the field separator, U+00B7 MIDDLE DOT, with optional spaces around it

   Analysis is line oriented: each line is classified by its prefix and the
   prefix always wins (SPEC §5.1). Only section blocks and "dentro:" span lines.
   Blank lines separate clips. *)

PLIEGO          = PREAMBLE { CHAPTER } [ END ] ;
PREAMBLE        = { PREAMBLE-LINE | UNIT-LINE | SECTION | COMMENT } ;

(* ---------- preamble ---------- *)
PREAMBLE-LINE   = "MESA" [ "v" NUMBER ] TITLE
                | "formato" PROPERTY { "·" PROPERTY }
                | "ARCO" ARCO
                | "MOTIVO" QUOTE [ "—" TEXT ]
                | "ECO" IDENT ( "→" | "->" ) IDENT
                | "REPARTO" SPEAKER ":" TAMBOR [ "," VOZ ] [ "," VOICE-COLOUR ] [ "," SIDE ] [ "," "alias:" ALIAS { "·" ALIAS } ]
                | "PERSONAJE" IDENT "—" TEXT
                | "LETRA" PATH
                | "PYTHON" PATH
                | "ARCHIVO" KEY { "·" KEY }
                | "FANTASMA" ( "foto" | "texto" | "numeral" ) NUMBER
                | "RELOJES" IDENT NUMBER { IDENT NUMBER }
                | "SONIDO" TEXT
                | "EFECTOS" PATH                       (* sound profile: folder of effects and ambiences *)
                | "BANDA" PATH                         (* sound profile: folder of music cues *)
                | "MEZCLA" MEZCLA { "·" MEZCLA }       (* sound profile: "para la web" | "para cine"; "con stems" | "sin stems" *)
                | "PARTITURA" PATH                     (* cartel profile *)
                | "SOPORTE" SOPORTE                    (* oído profile *)
                | "el dial es la línea de tiempo"      (* oído profile *)
                | "baño" BOBINA ;
PROPERTY        = ASPECT-RATIO | "sala" ( "crema" | "pizarra" ) | "tirada" ( "borrador" | "definitiva" )
                | "página desnuda" | "en dos" ;
ASPECT-RATIO    = FORMATO ;
VOICE-COLOUR    = "con radio" | "seca" ;
SIDE            = "a la izquierda" | "a la derecha" | "al centro" ;

(* ---------- sections: the mirror law (SPEC §5.3) ---------- *)
SECTION         = BLOCK | IMPORT ;
BLOCK           = "#" NOMBRE-SECCION [ IDENT ] NL { SECTION-LINE } "#FIN" ;
IMPORT          = NOMBRE-SECCION PATH ;
SECTION-LINE    = FAMILY [ VALUE ] { "·" FIELD } ;
FIELD           = KEY ( " " | ": " ) VALUE ;       (* keys of several words take a colon *)
FAMILY          = FAMILIA-TALLER | CLAVE-MANO ;

(* ---------- chapter and scene ---------- *)
CHAPTER         = CHAPTER-HEAD { UNIT-LINE | SECTION | COMMENT } { SCENE | CLIP } ;
CHAPTER-HEAD    = "==" TITLE { "·" CHAPTER-ATTR } { "=" } ;
CHAPTER-ATTR    = "tensión" TENSION | "nº" NUMBER | "tambor" TAMBOR | "gigante" WORD
                | "plano fijo" PLANTILLA | "tramo" NUMBER ( "→" | "->" | "a" ) NUMBER
                | "nocturno" | "diurno" ;
SCENE           = SCENE-HEAD { UNIT-LINE | SECTION | COMMENT } { CLIP } ;
SCENE-HEAD      = "--" TITLE [ "·" HORA ] "--" ;

(* Unit lines are valid in the preamble (whole pliego), a chapter or a scene;
   the scene prevails over the chapter, the chapter over the preamble. Several
   are also valid inside a clip, for that shot only (SPEC §5.6). *)
UNIT-LINE       = CORE-UNIT-LINE | ASPECT-UNIT-LINE | SOUND-UNIT-LINE
                | CARTEL-UNIT-LINE | OIDO-UNIT-LINE | CAMERA-UNIT-LINE ;
CORE-UNIT-LINE  = "EJE" "de" IDENT "a" IDENT
                | "LUZ" DIRECCION-LUZ { "·" ( DUREZA | "rasante" ) }
                | "MUNDO" MOVIMIENTO-MUNDO [ NUMBER ] [ "·" SENTIDO ]
                | "FONDO" KEY { ARG } "·" LEJANIA [ "·" NUMBER ]
                | "DELANTE" KEY { ARG } [ "·" LEJANIA ] [ "·" "cada" NUMBER ]
                | "ESCENARIO" TEXT
                | "TABLAS" { "·" ( HORA | "suelo" NUMBER | "a sangre" | "ancho" NUMBER | "alto" NUMBER ) }
                | "ARCHIVO" KEY { "·" KEY }
                | "REPITE" QUOTE ;
ASPECT-UNIT-LINE= "MATERIA" MATERIA-SPEC
                | "BOBINA" BOBINA
                | "FORMATO" FORMATO { "·" FORMATO-MODO }
                | "ESPEJO" [ ESPEJO-LADO ]
                | "PANTALLA PARTIDA" { "·" ( "con un espejo en medio" | "que se miran" | "desigual" | "inclinada" ) }
                | "RÍO TIPOGRÁFICO" [ "·" ( RIO-MODO | "no" ) ]
                | "SIMULTÁNEO" SIMULTANEO
                | "MONTAJE" MONTAJE-SPEC { "·" MONTAJE-SPEC }
                | "HERVOR" HERVOR ;
MATERIA-SPEC    = "papel" PAPEL
                | "acuarela" [ ON-PAPER ]
                | "risografía" TAMBOR-RISO "y" TAMBOR-RISO [ "y" TAMBOR-RISO ]
                     { "·" ( DESREGISTRO | "trama" TRAMA ) } [ ON-PAPER ]
                | "pincel" [ ON-PAPER ] | "tejido" [ TAMBOR-RISO ] | "tinta" [ ON-PAPER ] | "ninguna" ;
ON-PAPER        = "sobre papel" PAPEL ;
MONTAJE-SPEC    = MONTAJE | "mezcla" QUOTE { "·" QUOTE } ;
SOUND-UNIT-LINE = "MÚSICA" ( CUE | "ninguna" )
                | "AMBIENTE" EFFECT-NAME { "·" EFFECT-NAME }
                | "ESPACIO" ESPACIO
                | "CAMA" EFFECT-NAME | "JINGLE" EFFECT-NAME ;
CARTEL-UNIT-LINE= "PALETA" COLOR-CARTEL "," COLOR-CARTEL "y" COLOR-CARTEL
                | "CARTEL" COMPOSICION { "·" COMPOSICION } ;
OIDO-UNIT-LINE  = "INTENSIDAD" ( INTENSIDAD | "de" INTENSIDAD "a" INTENSIDAD ) { "·" ( "extraña" | "con" PISTA ) }
                | "SOPORTE" SOPORTE
                | "COLOR" ( "monocromo" [ TAMBOR-RISO ] | "pleno" )
                | "LUZ" ( "de" ( QUOTE | "los focos" ) { "·" ( DIRECCION-FUENTE | TAMBOR-RISO | "en contraluz" ) }
                        | "plana" [ "·" "de estudio" ] )
                | "la cámara respira con" PISTA | "el río mide la voz" | "la luz sube con" PISTA ;
CAMERA-UNIT-LINE= ( "CÁMARA" | "CAMARA" ) CAMERA-SPEC { "·" CAMERA-SPEC }
                | "HORIZONTE" HORIZONTE
                | "CADENCIA" BLANCO-CADENCIA CADENCIA { "·" BLANCO-CADENCIA CADENCIA }
                | "GOLPES" GOLPE { "·" GOLPE }
                | "PISTA ÓPTICA" [ PISTA-LADO ] ;
CAMERA-SPEC     = LENTE | PESO-CAMARA | MANO-CAMARA | PROFUNDIDAD ;

(* ---------- clip ---------- *)
CLIP            = CLIP-HEAD { CLIP-LINE } ;
CLIP-HEAD       = "*" [ BEAT-ID ] ( FUNCION | SHOT ) [ "·" AFECTO ] [ "(máquina)" ] ;
BEAT-ID         = IDENT ;                         (* optional, stable id for the sidecar (e.g. r01_02) *)
SHOT            = { TALLA | ALTURA | FRENTE | MODO } [ "de" [ ARTICLE ] IDENT ] ;

CLIP-LINE       = CONTENT | PIECE | REAL-VIDEO | PLACEMENT | SCENE-VERB | MAP | MOVEMENT | CAMERA
                | JOURNEY | SOUND | EVENT | NESTING | UNIT-LINE | SIGN | WEAVE | CHARACTER | COMMENT ;

CONTENT         = "di" [ "(" VOZ ")" ] ":" TEXT
                | SPEAKER-LIST ":" TEXT                (* the speaker MUST be declared (REPARTO, PERSONAJE) *)
                | "letrero" [ "(" REGISTRO-LETRERO ")" ] ":" TEXT { "/" TEXT }
                | "terminal:" TEXT | "canta:" TEXT | "contenido (máquina):" TEXT
                | QUOTE                              (* a shout: at most one per clip *)
                | TEXT ;                             (* prose: the beat's content *)
SPEAKER-LIST    = SPEAKER { "/" SPEAKER } ;        (* "VECINO / LOCUTOR": the split sentence *)

PIECE           = "pon:" TIPO-PIEZA QUOTE { "·" PIECE-ATTR }
                | ( "foto" | "recorte" | "prensada" ) ":" KEY
                | "ver:" CLAVE-VIS [ "—" BODY ]
                | "pica:" KEY [ "en" NUMBER ]
                | "python:" NAME { ARG | NAME "=" VALUE } { "·" PIECE-SIZE | "·" CORTE | "·" "sin leer" }
                | ( "arriba" | "pie" | "nota" ) ":" TEXT
                | "marca:" GESTO-MARCA QUOTE ;
PIECE-ATTR      = NUMBER | "id" PATH | TAMBOR ;
PIECE-SIZE      = "grande" | "enorme" | "gigante" | "a sangre" ;

REAL-VIDEO      = "clip" [ " de fondo" | " mudo" ] ":" PATH [ "de" TIME "a" TIME ] ;
TIME            = [ DIGITS ":" ] DIGITS [ "." DIGITS ] ;

PLACEMENT       = "en" NUMBER NUMBER ":" CLIP-LINE
                | "en" PARTE-CUERPO "de" IDENT [ NUMBER NUMBER ] ":" CLIP-LINE
                | RELATION OBJECT [ "a" NUMBER ] ":" CLIP-LINE
                | RELATION "cada uno:" IDENT TEXT
                | "juntos:" LIST "—" DISPOSICION
                | ( "en el mundo" | "en el documento" ) ":" CLIP-LINE
                | "en" MATERIA-SPEC ":" CLIP-LINE          (* the material of one piece *)
                | "de" QUOTE "a" QUOTE ":" CLIP-LINE       (* the sign that flies *)
                | ( "a la izquierda" | "a la derecha" ) ":" CLIP-LINE
                | DISTANCIA ":" CLIP-LINE                  (* camera profile: depth *)
                | "en silueta:" CLIP-LINE ;                (* cartel profile *)
RELATION        = "bajo" | "sobre" | "junto a" | "delante de" | "detrás de" ;

SCENE-VERB      = IDENT "con vista" VISTA
                | IDENT "se encaja en" HOLE | "en sus huecos:" LIST
                | "recoge" IDENT | "clava" IDENT "en" IDENT
                | ( "recorta" | "dobla" | "tapa" | "traslada" ) QUOTE TEXT
                | "retira:" ( "el escenario" | "las tablas" | "el teatro" )
                | "la truca" ( "se acerca a" IDENT | "vuelve" | "se aleja" ) ;

MAP             = "mapa:" MAP-ORDER ;
MAP-ORDER       = "territorio" QUOTE { "·" ( "con" LIST | "grande" | "en" PLACE ) }
                | "línea desde" QUOTE [ "hacia" QUOTE ]
                | "la línea de" QUOTE ( "llega a otro igual" | "se hunde" | "vuelve" )
                | "conecta" QUOTE { "·" QUOTE } | "el círculo se abre" | "mira a" QUOTE
                | "en fila abajo" | "en columna izquierda" | "se va" ;

(* Movement is recognized BY THE VERB (VERBO-MOV, VERBO-RELACIONAL), never by its suffixes. *)
MOVEMENT        = [ PLACEMENT-PREFIX ] [ ARTICLE ] SUBJECT ( VERBO-MOV | VERBO-RELACIONAL ) [ DESTINATION ]
                     { "·" ( [ "por" ] TRAYECTO | MANERA | GRANULADO | REGISTRO-MOV | RASTRO ) } [ VENTANA-SPEC ]
                | SUBJECT "se funde en" SUBJECT | SUBJECT "hierve con" SUBJECT
                | "el pelo pasa de" SUBJECT "a" SUBJECT
                | SUBJECT "se sale del cuadro" [ "por la" LADO ] ;
DESTINATION     = ( "hasta" | "a" | "hacia" ) OBJECT | "fuera de campo" [ "por la" LADO ] ;
VENTANA-SPEC    = "hasta decir" QUOTE | "mientras" ;

CAMERA          = "la truca" ORDEN-TRUCA [ IDENT ] [ "en" TALLA ]
                | IDENT "mira a" IDENT | IDENT "mira a cámara"
                | [ ARTICLE ] IDENT ( "sale" | "entra" ) "por la" LADO
                | "sonido:" CRUCE-SONIDO [ NUMBER ]
                | "fuera de campo" [ "por la" LADO ] ":" TEXT
                | [ "el" ] "foco" ( "en" | "pasa a" ) IDENT [ "y en" IDENT ] | "todo en foco"
                | IDENT "está" TEXT ;                   (* a state, for continuity *)

JOURNEY         = IDENT "viaja" | IDENT "se apea"
                | "el mundo" MOVIMIENTO-MUNDO [ NUMBER ]
                | "por la ventanilla:" LIST "desfilan"
                | "por" WINDOW-OF "de" IDENT "se ve el mundo" ;

SOUND           = "sonido:" EFFECT-NAME [ SIDE ] ;      (* an effect, at its place; anchorable with "al decir" *)

CHARACTER       = SUBJECT ( ACCION-FICHA | EXPRESION | "de espaldas" | "de perfil" | "de frente"
                          | "de tres cuartos" | "de tres cuartos de espaldas" ) ;

SIGN            = "LETRA" QUOTE { "·" ( "en" TIPO-LETRA | DISPOSICION-SIGNO | SITIO-SIGNO | PIECE-SIZE
                                      | "de" COLOR-CARTEL | "sin leer" ) }
                | QUOTE "es" ( "un" | "una" ) PAPEL-SIGNO [ ( "a" | "de" ) QUOTE ]
                | [ "la" | "el" ] LETTER "de" QUOTE ( "es" | "se convierte en" ) IDENT
                | IDENT "se convierte en" [ "la" | "el" ] LETTER "de" QUOTE
                | [ "las letras de" ] QUOTE VERBO-SIGNO
                | "la raya corta" QUOTE
                | QUOTE "forma" FORMA-PALABRA
                | QUOTE "tapa a" IDENT | IDENT "tapa" QUOTE
                | "el ojo completa" QUOTE
                | "ESCALA" IDENT "como" IDENT
                | "BOSQUE de" BOSQUE ;
WEAVE           = ( "TEJE" | "SINTONIZA" ) QUOTE { "·" ( "en" TIPO-LETRA | "con la aguja del dial" | PIECE-SIZE | DISPOSICION-SIGNO ) }
                | QUOTE "se interrumpe en" QUOTE | QUOTE "sigue"
                | "los hilos de" IDENT "y" IDENT "se entretejen"
                | "FRASES" QUOTE { "·" QUOTE } ;

(* Events: a closed vocabulary with state (alive | reserved). The union of
   EVENTO, EVENTO-CARTEL, EVENTO-OYE and EVENTO-CAMARA, some with an argument. *)
EVENT           = ">" EVENT-NAME [ ARG ] { "·" ">" EVENT-NAME [ ARG ] } ;
EVENT-NAME      = EVENTO | EVENTO-CARTEL | EVENTO-OYE | EVENTO-CAMARA | ROTURA-WITH-REASON | ENCUADRE-INCOMODO ;
ROTURA-WITH-REASON = ROTURA "porque" QUOTE ;      (* breaking a rule with permission: the reason is required *)

NESTING         = "dentro:" NL { CLIP-LINE }          (* sub-clips; at most three levels *)
                | "mientras:" CLIP-LINE
                | "al decir" QUOTE ":" CLIP-LINE
                | CLIP-LINE "hasta decir" QUOTE ;

(* ---------- end ---------- *)
END             = "==" "FIN" { "=" } { TEXT } [ NL ">" "silencio" NUMBER ] ;

(* ---------- comments ---------- *)
COMMENT         = "//" TEXT                  (* technical comment: not in the IR *)
                | "(" TEXT ")"               (* author's digression: in the IR, `digresiones` *)
                | "~" "deriva:" TEXT ;       (* a commission to the engine: in the IR, `derivas` *)

(* ---------- terminals ---------- *)
ARTICLE         = "el" | "la" | "los" | "las" ;
TITLE           = QUOTE | TEXT ;
SPEAKER         = IDENT ;          (* not a reserved word; compared as written *)
CUE             = WORD ;           (* a file of BANDA, by name, case-insensitive *)
EFFECT-NAME     = WORD { WORD } ;  (* a file of EFECTOS (or BANDA), by name *)
PATH            = TEXT ;           (* relative to the pliego's folder in a portable project *)
LIST            = IDENT { "·" IDENT } ;
```

<!-- gramatica:fin -->

## Apéndice C. Códigos de diagnóstico {#appendix-c}

Códigos de la lengua de pliegos (`spec/diagnosticos.json`):

<!-- diagnosticos:inicio -->

| Código | Gravedad | Qué significa |
|---|---|---|
| `E001` | error | el pliego declara una época mayor que la del compilador |
| `E010` | error | afecto fuera del vocabulario cerrado |
| `E011` | error | función o plano desconocidos en la cabecera de un clip |
| `E012` | error | palabra suelta en una línea de movimiento (no es trayecto, manera, granulado, registro ni ventana) |
| `E013` | error | evento `>` fuera del vocabulario cerrado |
| `E014` | error | registro de letrero desconocido |
| `E015` | error | ESPACIO (sala) desconocido |
| `E016` | error | color de voz desconocido en el REPARTO |
| `E017` | error | arco desconocido |
| `E018` | error | modificador de collage o campo de MARIONETA desconocido (detrás de `·` en `foto:`, `recorte:`, `clip:` o `MARIONETA`) |
| `E019` | error | otra palabra fuera de un vocabulario cerrado |
| `E020` | error | nombre ambiguo: dos candidatos empatan en el mismo nivel de la dimensión `nombre` |
| `E021` | error | palabra reservada usada como nombre de hablante o identificador |
| `E022` | error | referencia a algo que no existe (pieza, clip, id de ECO, personaje) |
| `E023` | error | línea que parece una orden y no lo es: se escribiría en pantalla sin querer (diálogo de quien no está en el REPARTO, línea de escena dentro de un clip, orden o verbo inexistentes) |
| `E024` | error | una pieza actúa (`NOMBRE acción`) sin estar en el REPARTO ni ser una MARIONETA |
| `E025` | error | ancla muerta en el texto: `al decir «X»` y la voz escrita de ese beat no dice X |
| `E030` | error | dos gritos en un clip |
| `E031` | error | dos acciones sobre el mismo sujeto en la misma ventana, o una duración declarada dos veces |
| `E032` | error | ciclo de ligaduras, cadena de más de tres eslabones o anidamiento excesivo |
| `E033` | error | pieza sin apoyo cuando su materia no flota |
| `E040` | error | MÚSICA que no está en BANDA (o BANDA sin declarar) |
| `E041` | error | efecto `sonido:` que no está en EFECTOS ni en BANDA |
| `E042` | error | AMBIENTE que no está en EFECTOS |
| `E050` | error | `python:` nombra algo que no está en el bestiario |
| `E051` | error | pose que el bestiario no declara |
| `E052` | error | dibujo mal invocado: argumentos detrás de `·`, paréntesis, o argumentos que la firma de la pieza no admite |
| `E053` | error | el bestiario declarado (`PYTHON` o `PIEZAS`) no existe junto al pliego |
| `E054` | error | acción que la pieza no declara (ni entre sus ACCIONES, ni sus POSES, ni sus CICLOS) |
| `E060` | error | rotura de una regla sin su `porque` |
| `E090` | error | línea mal formada (el parser no puede seguir) |
| `W101` | aviso | SALTO DE EJE |
| `W102` | aviso | SALTO DE TALLA |
| `W103` | aviso | RACCORD DE MIRADA |
| `W104` | aviso | RACCORD DE DIRECCIÓN |
| `W105` | aviso | RACCORD DE ESTADO |
| `W110` | aviso | evento reservado: la lengua lo acepta y el intérprete aún no lo realiza |
| `W111` | aviso | registro de letrero reservado |
| `W112` | aviso | porcentaje pobre por debajo del 85 % |
| `W113` | aviso | sin silencio final declarado |
| `W114` | aviso | demasiados clips sin respiro |
| `W115` | aviso | escena con dos o más personajes y sin EJE |
| `W116` | aviso | clip vacío |
| `W117` | aviso | relojes no coprimos |
| `W118` | aviso | acción dudosa sobre una pieza (entra dos veces, actúa sobre algo ausente) |
| `W120` | aviso | ancla muerta: `al decir «X»` y la voz nunca dice X |
| `W121` | aviso | dos voces: clip con sonido dentro de un beat narrado sin `> espera al clip` |
| `W122` | aviso | ancla ilegible: casa con la voz pero no con su `di:` |
| `W123` | aviso | el beat se alarga: el clip dura más que la voz |
| `W124` | aviso | página vacía: el beat abre cuadro nuevo y no pone nada mientras suena la voz |
| `W125` | aviso | texto en pantalla: una línea de prosa que se escribirá a máquina en el papel |
| `W130` | aviso | revisión Lasseter (sobre la cronología real) |
| `W199` | aviso | otro aviso |

<!-- diagnosticos:fin -->

Códigos de las demás partes: de `P001` a `P009` (proyecto portable, §14.4), de `L001` a
`L011` (láminas, §17.9), de `M001` a `M006` (materias, §18.6), de `T001` a `T007` (tomas,
§19.4).

## Apéndice D. Desviaciones conocidas de la implementación de referencia {#appendix-d}

Encontradas al construir la batería de conformidad (2026-10-15) frente a manim-saorín
1.0.0b1. Cada una es un caso pendiente en la batería; deja de estar pendiente cuando la
referencia lo pasa.

| Caso | Qué hace la referencia | Qué dice esta especificación |
|---|---|---|
| `lee-errores-reservada` | acepta `REPARTO nota: …` y luego trata `nota:` como una directiva (avisa «clip vacío») | un hablante con nombre de palabra reservada es `E021` (§5.5, §6.4) |
| `lee-estampas` | avisa «clip vacío» (`W116`) en un clip cuyo único contenido es un letrero (`LETRA`) | un letrero es una pieza (§8.3); el clip no está vacío |
| `lee-errores-letra-preambulo` | acepta en el preámbulo una línea `LETRA` (una línea de clip) sin error y la descarta en silencio: el signo no llega a la IR | las tres sedes (§3): una línea fuera de su sitio es un error (`E090`), nunca una línea que desaparece |
| `cierre-servilleta` | `mesa escribe` reescribe el preámbulo de una servilleta y pierde `BANDA`, `EFECTOS`, `MEZCLA`, `MÚSICA` y `AMBIENTE` | el cierre (§11.1): el pliego revelado suena igual |
| `espejo-taller` | un `.mano` importado lee `toca la truca: sí` como `no`; un `precisión alta` escrito en línea se queda como clave sin normalizar junto a `precision alta`; `parte` pierde el nombre de la sección | la ley del espejo (§11.2) |
| (todos los casos `ir`) | no emite `identidad` en cada beat | `identidad` es un campo obligatorio del beat (§10.3); la proyección normativa lo incluirá cuando la referencia lo emita |
| (preámbulo) | `MUSICA 1M1` sin tilde en el preámbulo se toma como ruta de canción y la cue se pierde en silencio | `MÚSICA` y `MUSICA` son la misma palabra (§4.5); un nombre que está en `BANDA` es una cue (§5.2, RFC 0004) |
| (proporción pobre) | cuenta como cifras nombres de cue como `1M1` | los nombres no son cifras (§3.1) |
| (comprobación) | `mesa lee` no informa de las ambigüedades de nombre; `mesa indice` sí, con estado de salida 0 | la comprobación de un compilador informa de `E020` y falla (§12); el adaptador une las dos órdenes |
| (códigos) | mensajes sin códigos | los códigos del apéndice C (RFC 0003); el adaptador los deriva de los mensajes |

## Apéndice E. Referencias {#appendix-e}

- BCP 14: RFC 2119 y RFC 8174, palabras clave.
- RFC 8785, JSON Canonicalization Scheme (JCS).
- RFC 6838, especificaciones y procedimientos de registro de tipos de medio.
- ISO/IEC 14977, EBNF.
- PKWARE, .ZIP File Format Specification (APPNOTE).
- W3C, WebGPU y WGSL.
- EBU R 128 e ITU-R BS.1770, sonoridad y pico verdadero.
- J. Lasseter, *Principles of Traditional Animation Applied to 3D Computer Animation*,
  SIGGRAPH 1987.
- Real Academia Española, *Diccionario panhispánico de dudas*, «raya».
- `SPEC-MESA-2.md`, `SPEC-PIEZAS.md` (manim-saorín); `pluma/LAMINA.md`, `materias/README.md`,
  `FORK.md` (este repositorio); ManimGX (Academa, MIT).

## Apéndice F. Perfiles en desarrollo (informativo) {#appendix-f}

Tres ramas de la implementación de referencia construyen perfiles nuevos en el momento de
este borrador. Lo que sigue es **informativo**: deja constancia de las líneas que
introducen para que otras implementaciones no usen las mismas palabras para otra cosa.
Cada uno pasa a normativo cuando su rama se fusiona y la batería tiene casos para él.

- **metraje** (metraje real), fusionado en la implementación de referencia el
  15-10-2026 (su documento de trabajo es `SPEC-METRAJE.md`); las palabras nuevas de
  `FORMATO` ya están en el apéndice A, y el aspecto del IR lleva `formato.reencuadre`.
  Preámbulo: `METRAJE`, `REVELADO`, `RECORTA`, `LIMPIA`,
  `ESTABILIZA`. Clip: `plano ≈ «…»` y `recurso ≈ «…»` (un plano encontrado por sentido en
  una biblioteca indexada), `toma: «…»`, `plano: fichero de A a B`, y los prefijos de
  seguimiento `sobre la mano de X:` y `sobre «objeto»:` (la pluma sigue a lo filmado).
  REPARTO admite la voz `filmada`. `FORMATO` gana `9:16`, `1:1` y `4:5`, con reencuadre
  tras `·`: `sigue a quien habla | sigue al sujeto | sigue a NOMBRE | centrado`.
  Herramientas: `ingesta`, `busca`, `monta` (montaje por palabras), `exporta`, `importa`,
  `planilla`. La transcripción es local y palabra a palabra.
- **géneros** (géneros y producción). Preámbulo: `GÉNERO X [· campo …]`, que solo pone
  valores por defecto donde el pliego no dice nada. Clip: `ecuación:`, `fuente:`, `dato:`,
  `rótulo:`, `cita:`, y `ver: curva | barras | puntos desde datos.csv`. Lienzos vertical y
  cuadrado nativos. Herramientas: `nuevo --género`, `serie`, `variantes`, `traduce`,
  `subtitulos`, `audiodescribe`, `accesible`, `revisa`, `notas`, `trailer`, `canal`,
  `deriva`.
- **3D** (volumen). El escenario en volumen a partir de las palabras del pliego, la misma
  cámara física en el 3D ligero del motor y en Blender orquestado por capas, el
  intercambio por glTF y USD, y las imágenes y clips generados, declarados y congelados.
