← Torna al sito

Progetti

Cosa ho costruito

Ogni scheda dice il problema, le scelte tecniche e il risultato misurato. Cinque sono strumenti veri, online, che si provano dal browser in trenta secondi; il sesto è il sito che state guardando. Ogni numero citato si controlla aprendo i sorgenti, che sono pubblici.

Caso 01 Progetto personale 2026

Questo sito

Problema

I siti degli sviluppatori si somigliano tutti: stesso template, stesse animazioni, stesse frasi. Nessuno di loro dimostra niente — raccontano competenze invece di mostrarle. Volevo un sito che fosse esso stesso la prova, non la descrizione della prova, e che si potesse aprire davanti a un responsabile acquisti senza doverlo spiegare.

Approccio

Nessun framework e nessuna libreria di componenti: un file HTML per lingua, un foglio di stile, due file JavaScript. Si apre, si legge, si modifica — e non c'e' nessun passaggio di build da rifare fra un anno.

L'intestazione e' una scena three.js. La struttura che vedete e' una geodetica ricavata da un icosaedro suddiviso: 162 nodi e 480 spigoli, ottenuti de-duplicando a mano i vertici che la libreria restituisce ripetuti. I nodi partono sparsi fuori campo e convergono nella posizione esatta in poco piu' di un secondo — e' la cosa che faccio di mestiere, messa in figura.

La scena non ha una palette propria: legge i colori dal CSS. Quando si cambia tema, il 3D rilegge le stesse variabili della pagina, quindi non possono andare fuori sincrono. Si ferma quando esce dallo schermo, e con prefers-reduced-motion disegna un fotogramma solo, con la struttura gia' montata.

L'accessibilita' l'ho verificata misurando, non a occhio: uno script percorre ogni elemento di testo nei due temi e calcola il rapporto di contrasto contro lo sfondo reale, quello che risulta dopo aver risalito gli antenati. 464 elementi fra la home e questa pagina, nessuno sotto la soglia WCAG AA. Ha trovato un errore che a vista non si vedeva: nel menu compatto il pulsante ereditava il colore della lista e finiva grigio su ottone, 1.01:1.

Nessuna chiamata a domini esterni per rendere la pagina: caratteri tipografici e three.js sono ospitati qui dentro. L'unica richiesta in uscita parte quando qualcuno invia il modulo di contatto.

Risultato

Una pagina che si spiega da sola a chi sa leggere il codice, e che chi non lo sa leggere si ricorda comunque. Sobria abbastanza da mandarla a un'azienda, tecnica abbastanza da non sembrare comprata.

464elementi di testo verificati contro WCAG AA nelle due pagine e nei due temi, zero sotto soglia
162nodi e 480 spigoli calcolati nel browser a ogni fotogramma
0framework, librerie di componenti, passaggi di build
0chiamate a domini esterni per rendere la pagina
  • HTML
  • CSS
  • JavaScript
  • three.js
  • WebGL
  • WCAG AA
Caso 02 Progetto personale 2026

Norma — ricerca per citazione su un corpus giuridico

Problema

Un assistente che risponde sui documenti interni di un'azienda ha un vincolo che gli assistenti generici non hanno: deve citare, non parafrasare. Se non si puo' risalire al paragrafo esatto, la risposta non e' verificabile, e una risposta non verificabile in azienda non si puo' usare.

Approccio

Ricerca a citazione esatta sul GDPR, interamente nel browser: nessun server, nessun modello, nessuna chiave. L'unita' di recupero e' il comma, non l'articolo, cosi' la risposta e' "Articolo 33, paragrafo 1" e non due pagine di testo.

La scelta di non usare un modello a embedding e' misurata, non assunta: 45 domande scritte prima di guardare i risultati, e un'ablazione che spegne una correzione per volta. Il motore lessicale arriva al 56 % dove BM25 nudo si ferma al 18 %, e costa 156 KB invece di 30 MB.

Risultato

Uno strumento che si prova in dieci secondi e si verifica riga per riga — e un preventivo quantificato per il passo successivo, invece che immaginato.

56 %delle domande hanno l'articolo giusto al primo posto
586brani indicizzati: 413 commi e 173 considerando
156 KBsul filo, contro i circa 30 MB di un modello a embedding
  • JavaScript
  • Python
  • BM25
  • NLP
  • Recupero informazioni
Caso 03 Progetto personale 2026

Estratto — fatture elettroniche leggibili nel browser

Problema

Dal 2019 la fattura fra imprese in Italia e' un file XML, e chi la riceve non riesce a leggerla: e' marcatura, non un documento. Per una verifica veloce si finisce a caricarla su un sito qualsiasi — un documento che contiene i dati dei propri clienti.

Approccio

Si trascina il file e lo si legge in chiaro, con i codici tradotti e l'esportazione in CSV. Tutto nel browser: nessuna richiesta parte, e non e' una promessa — si verifica aprendo il pannello di rete.

Oltre a mostrarla, controlla i conti: lo schema dello Sdi verifica che i campi ci siano, non che il 22 % di 100 faccia 22. Il controllo piu' delicato e' quello sulle rate, perche' con la scissione dei pagamenti e con la ritenuta d'acconto sono legittimamente piu' basse del totale. Segnalarle come anomalie avrebbe reso lo strumento inservibile: la differenza fra «torna», «nota» e «attenzione» e' il prodotto.

Risultato

Nove casi di prova con l'esito calcolato a mano, due dei quali rotti di proposito. La suite e' stata provata rompendo il lettore in tre modi diversi: tutte e tre le mutazioni vengono intercettate.

0byte inviati: il documento non lascia il computer di chi lo apre
113verifiche su 9 casi, con le attese calcolate a mano
29 KBsul filo, tutti e nove gli esempi compresi, senza nessuna dipendenza
  • JavaScript
  • XML
  • FatturaPA
  • Parsing
  • Validazione
Caso 04Progetto personale2026

Distinta — configuratore di prodotto su misura

Problema

È la cosa che le PMI manifatturiere chiedono più spesso e trovano meno. Chi vende serramenti o arredo su misura rifà a mano lo stesso preventivo ogni giorno, e ogni combinazione impossibile scoperta tardi è un ordine che torna indietro dall’officina.

Approccio

Le incompatibilità sono simmetriche: se scegli prima il vetro triplo sparisce il profilo sottile, se scegli prima il profilo sparisce il vetro. Un configuratore che gestisce una direzione sola costringe a tornare indietro e indovinare. E ogni opzione spenta dice il motivo, perché un grigio senza spiegazione viene letto come un guasto del sito.

Il prodotto non è nel codice: opzioni, prezzi, regole e vincoli stanno in un file di dati. Il disegno tecnico è in scala vera — le unità sono millimetri — e si ridisegna con le quote a ogni modifica.

Risultato

Tutte le 2.560 combinazioni enumerate, e una visita completa dello spazio raggiungibile che dimostra che nessuno, cliccando, può comporre un prodotto che non si fabbrica. Il controllo ha trovato subito un difetto vero: la configurazione predefinita del catalogo violava un vincolo del catalogo stesso.

0configurazioni impossibili raggiungibili, su 664 stati e 10.616 mosse
2.560combinazioni di opzioni, enumerate tutte
19 KBsul filo, senza nessuna dipendenza
  • JavaScript
  • SVG
  • Motore di regole
  • Preventivazione
Caso 05Progetto personale2026

Quadro — cruscotto sull’Italia, dati ISTAT

Problema

Un cruscotto che riceve totali già calcolati sa rispondere soltanto alle domande che chi ha preparato i dati aveva previsto. Alla prima domanda diversa servono una modifica, un rilascio e una settimana.

Approccio

Il browser riceve il dettaglio comunale — 7.896 righe — e aggrega al volo. Cambiare livello, indicatore o filtro non è una richiesta a un server: è un ciclo su un array.

La mappa pesa 99 KB perché è TopoJSON: coordinate quantizzate, punti memorizzati per differenza e confini condivisi fra regioni confinanti invece che duplicati. Lo stesso disegno in GeoJSON ne pesa 2.700.

Risultato

Cinquantuno controlli che riconciliano i totali da ogni strada e li mettono contro fatti che non vengono dai dati. Alla prima esecuzione la popolazione italiana risultava di 118 milioni: il file ISTAT ha una riga di totale per comune, e sommandola col dettaglio si conta tutto due volte.

7.896comuni aggregati nel browser a ogni interazione
99 KBla mappa vettoriale, contro i 2,7 MB del formato ingenuo
51controlli di riconciliazione superati
  • JavaScript
  • Python
  • TopoJSON
  • Dati aperti
  • Visualizzazione
Caso 06Progetto personale2026

Soglia — verificatore di contrasti WCAG

Problema

Il rapporto di contrasto è un numero solo, e da solo non decide niente: la stessa coppia di colori passa a 24 px e non passa a 16. Gli strumenti che si trovano mostrano il numero con due spunte fisse accanto, e la domanda vera resta senza risposta — da che corpo in su questo colore va bene?

Approccio

La soglia si muove col corpo e col peso, perché è così che è scritta la norma. Il trasparente si compone prima di essere misurato: rgba(0,0,0,.5) sul bianco è #808080 e vale 3,95:1, non 21:1 — uno strumento che ignora l’alfa dà un numero che su nessuno schermo esiste.

E quando non passa, dice quale colore mettere. La correzione si muove solo in luminosità dentro OKLCh, così la tinta resta dov’era e un rosso corretto resta rosso invece di diventare rosa. A volte però la risposta giusta è che il fondo è sbagliato: su un grigio medio non esiste nessun colore di testo che arrivi a 7:1, e dirlo vale più che proporre un colore che non risolve.

Il lavoro vero comunque non è una coppia, è un tema intero, dove le coppie sono n×n: si incolla il blocco delle variabili di un foglio di stile ed escono tutte insieme.

Risultato

Centottantuno controlli, di cui otto su numeri pubblicati da altri che non ho calcolato io da nessuna parte. Le attese sono ricalcolate da una seconda implementazione scritta in Python leggendo la specifica, non dal motore che devono provare. E il tema della pagina passa il proprio strumento contro AAA, non AA: la verifica rilegge il foglio di stile dal disco, quindi un colore cambiato senza guardare il contrasto fa cadere la prova.

Misurando la pagina resa, e non i soli colori dichiarati, ha trovato un difetto suo: nella diagonale della matrice un trattino grigio a 12 px stava a 4,05:1. Era decorazione travestita da testo, ed è diventata un tratteggio.

181controlli superati, di cui 8 su valori pubblicati da altri
2implementazioni indipendenti che devono concordare: JavaScript e Python
0elementi sotto WCAG AA su 162, nei due temi: qui la soglia è AAA
  • JavaScript
  • Python
  • WCAG 2.1
  • OKLCh
  • Accessibilità