ScrollyTelling: un CMS costruito parlando con l'AI
Un CMS leggero per creare gallerie fotografiche narrative in stile "ScrollyTelling": si scorre la pagina e le foto si susseguono come un piccolo film, con una colonna sonora ambientale. Niente database: solo file PHP e JSON. Tutto il progetto, dal primo bug fix all'ultima rifinitura estetica, è stato costruito in una serie di conversazioni con Claude Code, senza scrivere codice a mano.
Prima di scoprire come funziona il CMS, esplora una galleria reale. Le immagini vengono presentate a tutto schermo e sono accompagnate da un ambiente sonoro pensato per valorizzarne la fruizione. L'audio è consigliato.
Cos'è
ScrollyTelling è un piccolo sistema pensato per raccontare per immagini. Ha due facce:
- Un pannello admin, protetto da password, per creare gallerie, caricare foto, scrivere didascalie e scegliere una colonna sonora.
- Una pagina pubblica generata automaticamente per ogni galleria: scrolli e le foto scorrono a schermo intero, con un motore audio ambientale.
Nessun database: ogni galleria è un file JSON, le immagini sono file caricati e la pagina pubblica è un file HTML statico rigenerato ad ogni modifica. Chi lo usa non tocca codice: crea la galleria, carica le foto, scrive due righe di descrizione, sceglie un tema musicale, salva, e ottiene un link pronto da condividere.
Come è stato costruito: il metodo
Il progetto non è partito da uno scheletro predefinito o da un framework: è cresciuto un problema alla volta, in una conversazione continua con Claude Code. Il pattern tipico è stato sempre lo stesso:
- Segnalazione in linguaggio naturale, spesso imprecisa o "di pancia": non un ticket tecnico, ma un'osservazione come la farebbe chiunque guardando il risultato finale.
- Claude indaga il codice esistente prima di scrivere qualsiasi riga: legge i file coinvolti, individua la causa reale (non la prima ipotesi), e solo dopo propone una correzione.
- Implementazione mirata, senza aggiungere funzionalità non richieste né "abbellire" codice che non c'entra col problema.
- Verifica e resoconto di cosa è cambiato, in linguaggio semplice, con indicazione di eventuali passi manuali da fare (es. "risalva le impostazioni per rigenerare la pagina").
Questo ciclo si è ripetuto per bug fix, nuove funzionalità e rifiniture estetiche allo stesso modo: il prompt non deve essere un progetto tecnico, deve essere un'osservazione onesta di cosa non va o cosa si vorrebbe vedere.
Le funzionalità, con i prompt reali che le hanno generate
Diagnosi di un bug di deploy
Spostato dalla root del dominio a una sottocartella, il sito mostrava una pagina vuota: CSS e JavaScript non si caricavano perché i percorsi erano assoluti (/assets/…) invece che relativi.
«C'è qualcosa che non va nel render del progetto: il CMS funziona correttamente, ma la pagina pubblica generata risulta completamente rotta a questo link: [link alla pagina].»
Letta la causa (tutti i percorsi assumevano che il sito vivesse nella root), sono stati convertiti in percorsi relativi: più robusti di qualsiasi configurazione manuale, perché funzionano identici ovunque il progetto venga spostato.
Copertina personalizzabile
«Aggiungiamo dei testi descrittivi in apertura alla galleria: un occhiello, il titolo e una breve descrizione. Mantieni la coerenza tipografica con il resto della pagina.»
Prima la copertina mostrava un testo fisso ("Galleria · N fotografie"). Ora occhiello e descrizione sono campi editabili dal pannello, con lo stesso sistema tipografico del resto della pagina.
Titolo per singola immagine
«Sopra il campo "didascalia", aggiungi un campo opzionale per un titolo da mostrare accanto al numero della foto, con lo stesso font del numero.»
Ogni foto ha un numero progressivo (01, 02…). Ora gli si può affiancare un titolo opzionale, con lo stesso font del numero per coerenza visiva, mentre la didascalia narrativa resta separata sotto.
Sistema musicale: dalla richiesta generica ai preset su misura
Questa funzione è nata in più passaggi, un buon esempio di come il dialogo iterativo affini il risultato.
«Suggeriscimi un modo per migliorare la gestione del sottofondo musicale.»
«Limitiamoci a preparare un set di brani sintetizzati, selezionabili alla creazione della galleria. È fattibile?»
«I brani devono essere leggeri e malinconici, in stile fado: niente di aggressivo o troppo dinamico, deve risultare immersivo.»
Il risultato: 4 temi musicali generati via Web Audio API (nessun file audio da gestire), ciascuno con un accordo armonico distinto: non trasposizioni dello stesso accordo, ma quattro "voci" davvero riconoscibili, tutte nel registro malinconico richiesto.
«Il sottofondo musicale non mi convince: c'è sempre un rumore di mare in sottofondo, i temi sono troppo simili tra loro, e non mi convince il cambio di tonalità a metà scroll.»
Da qui: rimossa la transizione di accordo a metà ascolto (la "deformazione"), rumore ambientale relegato a un solo tema, differenze fra i temi rese più marcate su tempo, registro e riverbero.
«Aggiungiamo un'opzione "personale" che permetta di caricare una traccia audio propria (ad esempio un brano royalty-free scaricato online) in alternativa ai temi generati.»
Aggiunta la possibilità di caricare un proprio brano (mp3/ogg/wav/m4a) in alternativa ai temi generativi, con relativo credito visibile in pagina (per attribuzioni CC / royalty-free) e icona di collegamento a un sito esterno.
Rifinitura visiva: meno effetti, più immagine
«Ci sono troppi effetti di zoom sulle immagini, e lo sfondo sfocato dietro le foto è troppo invasivo: proviamo a toglierlo e lasciare l'immagine pulita. Aggiungi anche un po' di margine sopra e sotto le immagini, senza sovrapporre le miniature.»
Rimosso lo sfondo sfocato dietro ogni foto, ridotto drasticamente l'effetto "Ken Burns", aggiunto un margine sopra e sotto calcolato per non invadere mai la fascia delle miniature in basso.
Debug di un bug introdotto a mano
«Se sostituisco l'audio con una traccia personale, la pagina si rompe completamente: il frontend non carica più.»
Un elemento HTML era stato rinominato durante una modifica manuale al template, ma il JavaScript cercava ancora il vecchio nome: un riferimento a un elemento inesistente mandava in errore silenzioso l'intero script. Diagnosi e correzione mirata, senza toccare il resto.
Refactor architetturale su richiesta esplicita
«Nel CSS usi molti selettori per ID invece che per classe: perché questa scelta? Non è replicabile: ad esempio due pulsanti non possono condividere la stessa classe. Preferirei un'impostazione più lineare, con elementi riutilizzabili, senza abusare degli ID.»
Una critica tecnica puntuale, accolta con una spiegazione del perché e un piano condiviso prima di agire. Risultato: ogni ID resta solo un aggancio per il JavaScript, mentre tutto lo stile vive in classi CSS riutilizzabili (pattern base + modificatore, es. .film-btn + .film-btn--mute): zero comportamento cambiato, struttura molto più manutenibile.
Cosa dice questo progetto sullo sviluppare con l'AI
- La direzione conta più della sintassi. Guidare lo sviluppo significa definire con precisione requisiti, vincoli e criteri di accettazione; la traduzione in codice corretto è il livello successivo, delegabile all'AI a condizione di mantenere il controllo sulle decisioni tecniche.
- Il requisito qualitativo è un requisito a tutti gli effetti. Le osservazioni percettive su ritmo visivo, intensità di un effetto o resa sonora vanno formalizzate in parametri misurabili: ampiezza dello zoom, presenza di rumore ambientale, densità armonica. Il valore del processo sta nel rendere operativo un criterio soggettivo.
- L'iterazione è parte del metodo, non un suo scarto. Il sistema musicale è passato per specificazione progressiva: da un obiettivo generico a una specifica verificabile (quattro temi distinti, registro malinconico, assenza di transizioni intrusive). Ogni ciclo ha ridotto l'ambiguità del requisito.
- Disambiguare prima di implementare riduce il costo dell'errore. Esplicitare i valori di default e il comportamento nei casi limite (dati mancanti, campi opzionali, stati non previsti) evita di consolidare scelte implicite, costose da correggere a valle.
- Il codice generato è revisionabile come qualsiasi altro. Una scelta architetturale, ad esempio l'uso di selettori per ID anziché per classi, può essere discussa nel merito, motivata e sottoposta a refactoring, con gli stessi criteri di manutenibilità applicati al codice scritto manualmente.
In sintesi
| Cosa | Come è nato | Risultato |
|---|---|---|
| Fix percorsi assoluti | Segnalazione di una pagina rotta | Percorsi relativi, portabili ovunque |
| Copertina personalizzabile | Richiesta di più testo in apertura | Occhiello / titolo / descrizione editabili |
| Titoli per immagine | Richiesta puntuale su un campo | Titolo opzionale accanto al numero |
| Musica generativa | Suggerimento → scope → correzione di direzione | 4 temi fado immersivi, coerenti tra loro |
| Audio personalizzato | Estensione esplicita della funzione | Upload traccia propria + credito CC |
| Pulizia visiva | Feedback estetico diretto | Meno zoom, niente sfondo sfocato, più aria |
| Refactor CSS | Critica tecnica motivata | ID solo come hook JS, stile tutto su classi |
Vuoi vederlo in azione? Apri la galleria "Emotional" generata con questo CMS.