Progetti di UI/UX e Analisi
In questa sezione raccolgo esercizi e mini-progetti con cui ho iniziato a esplorare UX, UI e un po’ di front-end. Sono lavori didattici e di base: servono a mostrare il percorso di apprendimento, il metodo e l’attenzione ai dettagli, più che risultati “finito-prodotto”.

Mini-Progetto Web
Pagina web interattiva realizzata con HTML, CSS e JavaScript.

Testing e Analisi
Esercitazioni con task tree, valutazioni SUS e report di usabilità e accessibilità..

Festival Design
Prototipazione UI sviluppata in Figma e implementazione iniziale in WordPress.
Mini-Progetto Web
Pievepelago
Il progetto rappresenta un mini sito web interattivo sviluppato come esercitazione pratica ai fondamenti di HTML, CSS e JavaScript, con un focus sulla progettazione UX/UI e sull’integrazione di logiche funzionali.
La scelta di ambientarlo a Pievepelago, località montana dell’Appennino modenese, non è casuale: l’obiettivo era combinare lo sviluppo tecnico con un contenuto reale e personale. Le fotografie dei paesaggi e dei percorsi escursionistici sono state scattate personalmente, così da rendere l’esperienza più autentica e contestualizzata.
🔹 Funzionalità principali
- Calcolo distanze e tempi di percorrenza
L’utente può selezionare un luogo di partenza e uno di arrivo tra diversi punti di interesse (Monte Giovo, Monte Rondinaio, Lago Santo Modenese, Lago Baccio).
Il programma, sfruttando una struttura dati JavaScript (distanze), restituisce:- i chilometri di distanza tra i due punti;
- il calcolo dei minuti di percorrenza moltiplicando tempo stimato × km, con gestione di input validi/non validi.
- Gestione errori e feedback dinamico
Sono stati implementati controlli per:- campi vuoti, valori non numerici o negativi;
- messaggi di errore in tempo reale con aggiornamento dinamico della pagina.
- Lista interattiva “Oggetti in valigia”
Una mini-applicazione interna consente di inserire elementi da portare nello zaino, aggiungerli a una lista e rimuoverli in qualsiasi momento.
Questa sezione unisce l’aspetto ludico a quello pratico, simulando una checklist per l’escursionista. - Slider fotografico
Con JavaScript puro è stato realizzato uno slider di immagini dei laghi e dei sentieri, con frecce di navigazione e indicatori (dots). Questo permette di esplorare i contenuti visivi in modo più dinamico. - Navigazione e UI
- Un menù orizzontale (Percorsi, Laghi, Attività) guida la navigazione.
- Lo stile, realizzato in CSS personalizzato, adotta colori coerenti con l’ambiente naturale (azzurro, verde, lightcyan).
- Sono stati applicati effetti di hover, ombre sui testi e un layout centrato per garantire leggibilità.












🔹 Codice e tecnologie
- HTML5: struttura semantica della pagina e dei contenuti.
- CSS3: personalizzazione grafica, gestione layout responsive di base, slider.
- JavaScript vanilla: logiche di calcolo, validazione input, dinamica slider, gestione lista oggetti.
- Strutture dati: utilizzo di oggetti annidati in JavaScript per rappresentare le distanze tra i vari punti.
Il codice completo è stato inserito qua sotto, mentre la descrizione contiene sia gli screenshot del progetto sia gli scatti fotografici originali da me realizzati.
// Distanze Tempo Percorsi
var nodoPartenza;
var nodoDestinazione;
var nodoDistanza;
var nodoMinuti;
var nodoKilometri;
var nodoCalcola;
var nodoRisultato;
var nodoMessaggioCalcola;
var distanze = {
lagosantomodenese: {
montegiovo: 21,
monterondinaio: 17,
lagobaccio: 21,
lagosantomodenese: 0,
},
montegiovo: {
lagosantomodenese: 21,
monterondinaio: 6,
lagobaccio: 4,
montegiovo: 0,
},
monterondinaio: {
lagobaccio: 5,
lagosantomodenese: 17,
montegiovo: 6,
monterondinaio: 0,
},
lagobaccio: {
lagosantomodenese: 21,
montegiovo: 4,
monterondinaio: 5,
lagobaccio: 0,
}
}
function gestoreLoad () {
try {
nodoPartenza = document.getElementById("whereFrom");
nodoDestinazione = document.getElementById("whereTo");
nodoDistanza = document.getElementById("distanza");
nodoDistanza.value = "";
var PartenzaCorrente = "";
var destinazioneCorrente = "";
var distanzaCorrente = "";
nodoPartenza.onchange = impostaViaggio;
nodoDestinazione.onchange = impostaViaggio;
nodoMinuti = document.getElementById("minuti");
nodoKilometri = document.getElementById("kilometri");
nodoCalcola = document.getElementById("calcola");
nodoRisultato = document.getElementById("risultato");
nodoMessaggioCalcola = document.getElementById ("messaggioCalcola");
nodoMinuti.value = "";
nodoKilometri.value = "";
nodoRisultato.value = "";
nodoCalcola.onclick = gestoreCalcola;
var nodoTesto = document.createTextNode ("");
nodoMessaggioCalcola.appendChild (nodoTesto);
} catch ( e ) {
alert("gestoreLoad " + e);
}
}
window.onload = gestoreLoad;
function impostaViaggio () {
try{
nodoDistanza.value = "";
partenzaCorrente = nodoPartenza.value;
destinazioneCorrente = nodoDestinazione.value;
var i;
if ((partenzaCorrente == "whereFrom") || (destinazioneCorrente == "whereTo")) {
nodoDistanza.value = "0";
} else {
distanzaCorrente = distanze[partenzaCorrente][destinazioneCorrente];
while ((i < distanze.length) && (distanze[i].distanza != distanzaCorrente)) {
i++;
}
nodoDistanza.value = distanzaCorrente;
}
} catch ( e ) {
alert("impostaViaggio " + e);
}
}
function gestoreCalcola () {
try{
scriviMessaggio(nodoMessaggioCalcola, "");
if (nodoMinuti.value == "") {
scriviMessaggio(nodoMessaggioCalcola, "Non hai inserito i minuti");
return;
}
var minuti = Number(nodoMinuti.value);
if (isNaN(minuti)) {
scriviMessaggio(nodoMessaggioCalcola, nodoMinuti.value + " " + "non è un numero");
return;
}
if (minuti <= 0) {
scriviMessaggio(nodoMessaggioCalcola, "I minuti inseriti non sono validi");
return;
}
if (nodoKilometri.value == "") {
scriviMessaggio(nodoMessaggioCalcola, "Non hai inserito i km");
return;
}
var kilometri = Number(nodoKilometri.value);
if (isNaN(kilometri)) {
scriviMessaggio(nodoMessaggioCalcola, nodoKilometri.value + " " + "non è un numero");
return;
}
if (kilometri <= 0) {
scriviMessaggio(nodoMessaggioCalcola, "I km inseriti non sono validi");
return;
}
nodoRisultato.value = nodoMinuti.value * nodoKilometri.value;
} catch ( e ) {
alert("gestoreCalcola " + e);
}
}
function scriviMessaggio (nodo, messaggio) {
var nodoTesto = document.createTextNode(messaggio);
nodo.replaceChild(nodoTesto, nodo.firstChild);
}
// slider
var slides;
var dots;
var slideIndex = 0;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += 1);
}
function minusSlides(n) {
showSlides (slideIndex -= 1);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
if (n >= slides.length) {slideIndex = 0}
if (n < 0) {slideIndex = slides.length -1}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex].style.display = "block";
dots[slideIndex].className += " active";
}// oggetti valigia
function newElement() {
var li = document.createElement("li");
var inputValue = document.getElementById("myInput").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
nodoMessaggioValigia = document.getElementById ("messaggioValigia");
var nodoTesto = document.createTextNode ("");
nodoMessaggioValigia.appendChild (nodoTesto);
scriviMessaggio(nodoMessaggioValigia, "");
if (inputValue == "") {
scriviMessaggio(nodoMessaggioValigia,"Inserire un oggetto!");
return;
} else {
document.getElementById("myUL").appendChild(li);
}
document.getElementById("myInput").value = "";
var span = document.createElement("Span");
var txt = document.createTextNode("u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
}
function scriviMessaggio (nodo, messaggio) {
var nodoTesto = document.createTextNode(messaggio);
nodo.replaceChild(nodoTesto, nodo.firstChild);
}/* stylesheet */
body {
margin-left: 200px;
margin-right: 200px;
}
/*--------------------------------------------------------*/
/* header */
h1 {
color: black;
text-align: center;
padding: 20px;
font-size: 65px;
text-shadow: 4px 4px 8px;
background-color: lightcyan;
font-family: "Fantasy", "Papyrus";
font-weight: bold;
margin-top: 0;
}
/*top navigation bar */
.topnav {
overflow: hidden;
background-color: aliceblue;
font-weight: bold;
}
/*topnav links */
.topnav a {
display: block;
color: black;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 18px;
}
/* Cambia colore on hover */
.topnav a:hover {
background-color: lightcyan;
color: black;
}
/*---------------------------------------------------------*/
/*slider*/
body {font-family: Verdana, sans-serif; text-align:center; background-color:lightblue;}
.mySlides {display:none;}
/* Next and previous buttons */
.prev, .next {
padding: 16px;
color: black;
font-weight: bold;
font-size: 25px;
user-select: none;
margin-left: 250px;
margin-right: 250px;
cursor: pointer;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, aggiungere un colore di sfondo con un po' di trasparenza*/
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.8);
}
/* The dots/bullets/indicators */
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: cornsilk;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,.dot:hover {
background-color: royalblue;
}
/*---------------------------------------------------------*/
p{
background-color:lightcyan;
font-size:20px;
color:black;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
text-align:center;
padding: 40px;
}
h2 {
background-color:lightcyan;
font-size:25px;
color:black;
text-shadow: 2px 2px 4px;
text-align:center;
padding: 40px;
}
/*--------------------------------------------------------/
/*luggage box/
/* padding e bordi inclusi nel width and height */
#bagaglio {margin:20px; font-size: 18px; font-weight: bold;text-shadow: 2px 2px 4px;}
* {
box-sizing: border-box;
background-color:lightblue;
}
/* list items - controlla i valori di padding*/
ul li {
list-style-type: none;
background: aliceblue;
font-size: 18px;
padding:12px 8px 12px 40px;
text-align: center;
}
/* header */
.header {
background-color: lightblue;
padding: 30px 40px;
color: black;
text-align: center;
}
/*lascia la riga libera dopo il header*/
.header:after {
content: "";
display: table;
clear: both;
}
/* input - allinea obj */
input {
margin: 0;
border: none;
border-radius: 0;
width: 75%;
padding: 10px;
float: left;
font-size: 16px;
background-color:aliceblue;
}
/* "Add" button */
.addBtn {
padding: 10px;
width: 25%;
background: lightgrey;
color: black;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
border-radius: 0;
}
.close {
cursor: pointer;
}
#messaggioValigia {
float: right;
color: red;
}
/*--------------------------------------------------------*/
h3 {font-size:18px;}
#distanza {
border: 2px solid black;
margin-right: 500px;
margin-left: 500px;
height: 30px;
width: 12%;
text-align: center;
}
label {
text-align: center;
}
select {background:aliceblue;}
/*--------------------------------------------------------*/
h4 {font-size:18px; }
#minuti {
border: 2px solid black;
margin-right: 500px;
margin-left: 500px;
height: 30px;
width: 12%;
text-align:center;
}
#kilometri {
border: 2px solid black;
margin-right: 500px;
margin-left: 500px;
height: 30px;
width: 12%;
text-align: center;
}
#risultato {
border: 2px solid black;
margin-right: 500px;
margin-left: 500px;
height: 30px;
width: 12%;
text-align:center;
}
#calcola {
border: 3px solid blue;
border-radius: 17px;
padding: 8px;
width: 12%;
background: lightgrey;
color: black;
float: right;
margin-right: 500px;
text-align: center;
font-size: 16px;
cursor: pointer;
}
#messaggioCalcola {
float: right;
color: red;
margin-right: 200px;
}
/*---------------------------------------------------------*/
h5 {
background-color:lightcyan;
font-size:25px;
color:black;
text-shadow: 2px 2px 4px;
text-align:center;
padding: 40px;
}
h6 {
background-color:lightcyan;
font-size:25px;
color:black;
text-shadow: 2px 2px 4px;
text-align:center;
padding: 40px;
}Testing e Analisi
Questa sezione raccoglie esercitazioni e analisi dedicate alla valutazione dell’usabilità e dell’accessibilità.
Attraverso casi di studio e verifiche pratiche, sono stati applicati metodi di visual design, test di responsive design, analisi euristiche e strumenti per la valutazione automatica.
L’obiettivo è mostrare come progettare interfacce efficaci e inclusive, migliorando la user experience e garantendo conformità agli standard di usabilità e accessibilità.
Festival Design
Il sito progettato per il Festival “démadé – Liberi Libri” di Livorno è di proprietà dell’agenzia Oimmei Digital di Livorno.
Ho curato la progettazione dei prototipi ad alta fedeltà in Figma e l’avvio dell’implementazione su WordPress, con attenzione alla chiarezza informativa, all’accessibilità e all’interazione del pubblico.



Il Processo
Design & Analisi
Fase Uno: Ricerca e Pianificazione
Analisi del contesto, definizione utenti e raccolta requisiti.
Fase Due: Prototipazione e Test
Creazione di prototipi interattivi e test di usabilità con strumenti dedicati.
Fase Tre: Validazione e Iterazione
Applicazione di metriche (SUS, questionari) e revisione per migliorare il design.
