Commits
La capitular real i un editor de maquetes: el dia més llarg del projecte
Vuit hores de treball seguit: resolem la capitular flotant amb el seu ajust al mil·límetre, tanquem el issue #7 i els tickets de IA es converteixen en el editor de maquetes, de la biblioteca de elements al pilot amb IA.
Un dia de matinada i de vetlla. Vuit hores de treball seguit amb material real, cinc hores de planificació que es van convertir en codi el mateix vespre. El fil del dia és doble: al matí vaig tancar el poliment amb la capitular flotant real, i al vespre els tickets de IA de l'editor de maquetes van passar d'esborrany a feature construïda.
El poliment: modal, cola global i subides que informen
Les dues friccions que el mapa del MVP arrossegava van caure de matinada. El panell deixava de recarregar-se amb meta-refresh cada tres segons: ara una tasca llarga obre un modal que diu què corre i quant porta, la cola és global (mostra també el que corre en altres edicions) i el panell es repinta en calent amb el que arriba de /edicion/{id}/estado. Sense HTMX ni res nou: el servidor pinta els fragments HTML que canvien i el JavaScript només els intercanvia. Un sol fragment (_estado.html) serveix la pàgina i l'endpoint, així que no hi ha dues versions que es puguin desincronitzar.
La subida web era una caixa negra: els fitxers descartats es perdien en silenci i dues imatges amb el mateix nom es pisaven. Ara torna un informe fitxer a fitxer: què s'ha guardat, què s'ha renombrat (amb el nom nou) i què s'ha descartat, amb el seu motiu. I el forat de dades tancat: el segon «foto.png» es guarda com «foto-2.png».
La revisió tipogràfica post-render i el descobriment de WeasyPrint
El motor ara recorre el render i avisa si un títol ha quedat sol: al peu de pàgina o en una pàgina pròpia. El descobriment del camí és que WeasyPrint ja evita els títols orfes per defecte (break-after: avoid a la seva fulla del navegador), així que el títol només queda sol quan el bloc que el segueix no cap a cap pàgina. La revisió, doncs, és de verificació, no de rescat diari.
La capitular flotant, de la investigació impossible al descobriment
La investigació de paginació havia descartat la capitular flotant: el float dins de ::first-letter fa caure WeasyPrint 70 amb un AssertionError dins de float_layout. Però el fallo és del pseudo-element, no del float. Embolcallant la primera lletra en un element real (span.capitular, que el motor crea en construir el cos de l'article), el float es maqueta bé. Ja hi ha drop cap real: la lletra flota sobre tres línies amb el text envoltant-la, en color de marca i amb la tipografia de títols.
Al vespre, verificada amb material real, la capitular estava a mitges: la lletra al 400% es veia de dues línies però la caixa del float mesurava tres i pic, i empenyia quatre línies deixant un buit. La recepta correcta per a una capitular de N línies: la caixa ha de mesurar exactament N línies i la lletra les ha d'omplir. Amb cos de 10,5pt/1,6, tres línies són 50,4pt: font-size: 700% omple la lletra i line-height: 0.68 ajusta la caixa. Provades tres variants renderitzant el material real, la 700/0,68 deixa la lletra clavada a les tres línies.
I després el report del usuari: «segueix igual». El diagnòstic amb les marques de temps del contenidor: la maqueta re-maquetada a les 20:34 SÍ tenia la capitular bona, però el PDF d'impremta era de les 20:13, exportat abans del desplegament de l'arreglo (20:28). El visor llegia l'export vell. Lliçó: els artefactes derivats (PDF d'impremta, ZIP d'InDesign) no es regeneren en re-maquetar, només en exportar; després de qualsevol canvi de CSS cal re-exportar tot el que l'usuari vagi a verificar.
La capitular també a InDesign: drop cap natiu
Al ZIP, l'usuari veia la lletra capital «com una lletra normal». La limitació documentada era innecessària: InDesign té capitular nativa de paràgraf. Ara l'export l'activa pels dos camins: l'IDML surt amb DropCapCharacters, DropCapLines i un DropCapStyle que apunta a un estil de caràcter Capitular nou, amb la font de títols, el cos i el color de marca llegits del render (no hardcodejats); el JSX crea l'estil i aplica el drop cap només als paràgrafs que el porten. Detall del camí: el índex d'estils ha de ser global al document, no per pàgina — amb l'índex per pàgina, dos de tres articles perdia la capitular segons caigués el tall.
Amb la verificació de l'usuari («ok, listo ahora funciona»), el issue #7 es tanca i la n2 queda íntegra: maqueta, impremta i ZIP coherents, verificats pàgina a pàgina. La llista de poliment queda buida excepte el perfil ICC del taller.
La planificació de l'editor de maquetes
Al vespre va demanar dissenyar les pàgines amb una biblioteca de elements i poder encargar la composició a un model de IA. Especió en borrador i nou tickets; dues proves amb WeasyPrint (una pàgina aïllada amb foli equivocat, un text desbordat en una caixa d'una sola pàgina) van obligar a una vista prèvia amb context i una comprovació de desbordaments. Es va decidir que la IA només modifiqui l'edició que es maqueta; la biblioteca i les maquetes base queden compartides, i convertir una composició d'una edició en maqueta global serà una acció separada. La spec es va aprovar amb deu issues «llestos per implementar» i un ticket de prototip (#25) davant del compilador i de la vista prèvia.
El prototip va mesurar al motor real les tres apostes, i les tres es sostenen — amb dos detalls que canvien la construcció. El marge del body de 8px del navegador són 2,12mm: un titular declarat a 18mm es mesurava a 20,12mm. I l'origen surt del TrimBox: la hoja DINA4 exacta és el tall, el MediaBox arrossega el sangrat de 3mm per fora i els marges negatius el motor els ignora. Queda escrit a l'ADR 0004.
La biblioteca i el compilador
La biblioteca de elements és la primera peça construïda: a Configuració hi ha les deu peces (sigla, marca, edició, titular, entradilla, sumari, imatge, firma, filete i foli), cada una amb el seu estil, els seus vincles de contingut i la seva marca per a l'export. La vista prèvia no és una descripció: és la peça renderitzada pel motor d'impremta i retallada, perquè les primeres captures eren fulles DINA4 senceres i es llegien com una franja minúscula. Suite en verd: 296 proves.
El compilador converteix la maqueta en plantilles amb caixes absolutes en mil·límetres, amb coordenades mesurades sobre el disseny vigent i guardades a la llavor. Dos canvis de comportament conscients: la composició deixa de fluir (cada element es queda on es va dissenyar, que és el que demanava l'usuari) i el contingut es mou 2,12mm perquè ara la pàgina mesura des del tall. Si una plantilla editada a mà no coincideix amb el contingut, la maqueta deixa d'aplicar-se i avisa.
El camí va tenir quatre fallos que només van sortir en mesurar: la injecció duplicava l'atribut class, el CSS dels elements venia com a declaracions soltes que no són CSS vàlid, les caixes no portaven estil en línia i els elements s'apilaven a l'inici de la pàgina, i l'origen dels bucles no s'enllaçava i les llistes sortien buides. Suite en verd: 302 proves.
Tipografies, vista prèvia i editor
Les tipografies ja no són text lliure: es pugen com a fitxer i s'elegeixen d'una llista, i el nom de família es llegeix de dins del fitxer, no del que escriguis a mà: si no coincidís, el motor buscaria una font que no existeix i substituiria en silenci. Comprovat al PDF real: la font surt incrustada amb el seu /FontFile dins. Suite: 310 proves.
La vista prèvia maqueta el número sencer i n'extreu la pàgina, perquè una pàgina renderitzada sola reinicia el comptador i el foli no és el que li toca. De la pàgina surten el PNG, les caixes mesurades en mil·límetres per al llenç de l'editor i els desbordaments, mesurats element a element. La primera versió mesurava la pàgina sencera i l'element més baix semblava desbordat. «Encaixar» baixa el cos en passes del 4% amb sostre del 20%.
L'editor ja s'usa: una fulla DINA4 amb la pàgina real a sota i les caixes a sobre, col·locar peces amb un clic, moure amb ratolí amb imant a marges i columnes, autoguardat, desfer/refer i tornar a fàbrica. JavaScript pla en app/static/maquetas.js, perquè el repo no té build.
Les variants amb maqueta i la IA que compon
La Pàgina adaptable guanya una Maqueta: breve, estàndard i llarga ja no es maqueten igual. Dos modes: cabecera (el cos segueix fluint en columnes) i llenç (tota la pàgina). Dos coses només es van veure en el render de veritat: el text que canvia d'una edició a una altra (editorial, índex) no pot viure en una caixa fixa, i amb posicions fixes una pàgina es pot pisar a si mateixa, així que la vista prèvia avisa ara de solapaments. Suite: 330 proves.
I la IA ja compon pàgines: rep el catàleg de la biblioteca, la retícula i el contingut real de l'edició, i retorna la maqueta en JSON. Li enviem dades, no imatges: un model de només text no pot mirar-les, i dir-ho és millor que fingir. La proposta es valida i es mesura en el render real; si alguna cosa es surt o es pisa, se li torna el problema amb els mil·límetres i es li demana una altra vegada, fins a dues vegades. I no es guarda: és una proposta, no es guarda fins que l'administrador l'accepta al llenç.
Reobertura honesta
La darrera entrada del dia em va atrapar: la medició de la IA modificava temporalment una maqueta global, i vaig reobrir el issue #23. Van entrar composicions per edició, propostes amb vista prèvia, pilot amb informe i seccions; la suite va acabar amb 343 proves correctes. Queda pendent el recorregut amb proveïdor real, la comprovació d'impremta i InDesign i l'equivalència de migració de plantilles existents.