/* ════════════════════════════════════════════
   RESET
   * prende tutti gli elementi.
   ::before e ::after sono pseudo-elementi finti creati dal CSS,
   li azzeriamo per sicurezza.
   box-sizing: border-box fa sì che padding e border siano
   INCLUSI nella larghezza dichiarata, non aggiunti sopra.
══════════════════════════════════════════════ */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* ════════════════════════════════════════════
   VARIABILI GLOBALI
   :root è l'elemento radice della pagina (<html>).
   Le variabili definite qui sono accessibili ovunque
   con var(--nome). Cambi un valore qui, cambia in tutto il CSS.
══════════════════════════════════════════════ */
:root {
  --bg: #080808; /* sfondo — quasi nero */
  --text: #ebebeb; /* testo principale — bianco sporco */
  --muted: #4a4a4a; /* testo secondario — grigio medio */
  --dim: #1e1e1e; /* grigio scurissimo — per bordi sottili */
  --accent: #c8ff00; /* verde lime — colore di accento */

  /* clamp(min, ideale, max): padding orizzontale che si adatta
     allo schermo senza media query.
     min 1.5rem, ideale 5vw, max 5rem */
  --pad-x: clamp(1.5rem, 5vw, 5rem);
}

/* ════════════════════════════════════════════
   BASE
══════════════════════════════════════════════ */
html {
  /* scroll fluido quando si clicca un link tipo href="#about" */
  scroll-behavior: smooth;
}

body {
  background: var(--bg);
  color: var(--text);

  /* DM Mono è il font principale.
     "monospace" è il fallback se DM Mono non carica */
  font-family: "DM Mono", monospace;
  font-weight: 300;

  /* nasconde la scrollbar orizzontale che potrebbe apparire
     quando elementi animati escono temporaneamente dal bordo */
  overflow-x: hidden;
}

/* ════════════════════════════════════════════
   GRAIN OVERLAY — texture sottile di "rumore" sopra tutta la pagina

   Cosa fa visivamente:
   Aggiunge un effetto "pulviscolo" leggerissimo sopra tutto il sito,
   tipo il grano della pellicola fotografica vecchia. È quasi invisibile
   (2.5% di opacità) ma fa la differenza: senza, il nero del background
   sembra "piatto digitale" — con, sembra "nero vivo" come nei film.
   È un dettaglio premium che usano portfolio e siti di agenzia.

   Cosa è una "texture di rumore frattale":
   "Rumore" in grafica significa puntini casuali sparsi su una superficie,
   tipo il "fruscio" della TV vecchia quando non c'era segnale.
   "Frattale" significa che il pattern si ripete in scale diverse —
   cioè se zoomi un pezzo del rumore, vedi pattern simili a livelli
   più piccoli. È il modo in cui in natura si formano nuvole, montagne,
   venature del legno: caos organizzato.
   "Generata matematicamente" significa che il rumore non è un'immagine
   disegnata da qualcuno — è il risultato di una formula matematica
   che il browser calcola al volo.

   Perché non usiamo una PNG di rumore:
   1) Performance — zero richieste HTTP, niente file da scaricare
   2) Qualità — un'immagine matematica è perfetta a qualsiasi zoom,
      una PNG diventerebbe sgranata su monitor 4K
   3) Peso — il codice qui sotto pesa ~300 caratteri,
      una PNG equivalente sarebbe 5-10 KB
══════════════════════════════════════════════ */
body::before {
  /* ::before è uno PSEUDO-ELEMENTO — un elemento "finto" che il CSS
     crea automaticamente attaccato al body. È come se avessi scritto
     un <div> invisibile come primo figlio del body, ma senza toccare
     l'HTML. Si usa proprio per cose decorative come questa. */

  content: "";
  /* OBBLIGATORIO per gli pseudo-elementi.
     Senza "content", lo pseudo-elemento non esiste affatto.
     Lo lasciamo vuoto perché non vogliamo testo, vogliamo solo
     la sua "scatola" su cui applicare il background. */

  position: fixed;
  /* Lo ancoriamo al viewport (la finestra del browser), NON alla pagina.
     Significa: mentre scrolli, lui rimane fermo. La texture rimane
     uguale ovunque tu scrolli, dà continuità all'esperienza. */

  inset: 0;
  /* Scorciatoia per: top: 0; right: 0; bottom: 0; left: 0;
     Combinato con position: fixed → copre TUTTO lo schermo,
     dal bordo superiore a quello inferiore, sinistra a destra. */

  pointer-events: none;
  /* Disabilita le interazioni del mouse su questo elemento.
     SENZA questa riga, lo pseudo-elemento intercetterebbe tutti i click —
     sta sopra a tutto, quindi se cliccassi un bottone, cliccheresti
     prima sulla texture e il bottone non funzionerebbe.
     Con "none", i click "attraversano" come se la texture non esistesse. */

  z-index: 1;
  /* Ordine di sovrapposizione. Più alto = più davanti.
     z-index: 1 → sta SOPRA il contenuto delle sezioni,
     ma SOTTO la nav (che ha z-index: 100) e SOTTO il menu mobile (1050).
     Risultato: la texture è ovunque ma non copre la nav. */

  opacity: 0.025;
  /* Trasparenza al 2.5%. Quasi invisibile.
     L'obiettivo è che si SENTA ma non si VEDA chiaramente —
     se metti opacity: 0.1 il rumore diventa fastidioso,
     se metti 0.005 sparisce del tutto. 0.025 è il punto giusto. */

  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* QUI C'È IL TRUCCO INTELLIGENTE:
     normalmente background-image si scrive così:
       background-image: url("immagine.png");
     e il browser scarica un file da disco o da internet.

     Qui invece NON c'è nessun file. C'è un "data URL":
     un modo per scrivere l'immagine direttamente nel CSS come testo.

     Il formato è: data:[tipo],[contenuto]
     - "data:image/svg+xml" → dice "questa è un'immagine SVG"
     - "%3Csvg..." → è il codice SVG dell'immagine, dove
       %3C e %3E sono le versioni "URL-encoded" di < e >
       (un URL non può contenere < direttamente, va codificato).

     Tradotto in SVG vero, l'immagine è questa:
       <svg viewBox='0 0 256 256'>
         <filter id='n'>
           <feTurbulence type='fractalNoise'
                         baseFrequency='0.9'
                         numOctaves='4'
                         stitchTiles='stitch'/>
         </filter>
         <rect width='100%' height='100%' filter='url(#n)'/>
       </svg>

     Cosa fa questo SVG:
     - Crea un FILTRO chiamato "n" che usa feTurbulence —
       una funzione SVG nativa che genera rumore frattale (la texture
       a puntini casuali tipo grano della pellicola)
     - Crea un RETTANGOLO che riempie tutto e applica il filtro

     I parametri:
     - baseFrequency='0.9' → quanto è "fitto" il rumore.
       Valori più alti = puntini più piccoli e fitti.
       Valori bassi = macchie più grandi.
     - numOctaves='4' → quanti livelli di dettaglio sovrapposti.
       Più alto = rumore più ricco e dettagliato.
     - stitchTiles='stitch' → fa in modo che i bordi del rumore
       si "uniscano" perfettamente quando viene ripetuto in tile,
       senza linee visibili.

     Tutto questo viene calcolato dal browser al volo —
     zero file da scaricare, zero richieste HTTP,
     l'immagine "esiste" solo dentro la stringa qui sopra. */

  background-size: 200px 200px;
  /* Dice al browser di mostrare l'immagine a 200×200 pixel.
     Siccome lo schermo è più grande, il background si RIPETE
     come un mosaico/tile (è il comportamento default di background-image).

     Tile più piccoli (200px) = grana più FINE, simile a polvere.
     Tile più grandi (800px) = pattern più MARCATO, simile a macchie.

     200px è il valore tipico per un grain effect elegante. */
}
/* ════════════════════════════════════════════
   DECO LINE
   linea verticale fissa sul bordo destro della pagina.
   Il gradient la fa dissolvere sopra e sotto invece di tagliare netto.
   Parte con height: 0 e cresce dopo 2s.
══════════════════════════════════════════════ */
.deco-line {
  position: fixed;
  right: clamp(1.5rem, 3vw, 3rem);
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 0;
  background: linear-gradient(
    to bottom,
    transparent,
    var(--dim) 30%,
    var(--dim) 70%,
    transparent
  );
  z-index: 2;
  animation: lineHeight 1.4s ease 2s forwards;
}

@keyframes lineHeight {
  to {
    height: 35vh;
  }
}

/* ════════════════════════════════════════════
   NAV
   position: fixed: rimane in cima anche quando scrolli.
   z-index alto: sta sopra a tutto il resto.
   La transition + classe .hidden la fa scivolare via
   quando scrolli verso il basso (gestita dal JS).
══════════════════════════════════════════════ */
nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: 2rem var(--pad-x);

  /* flexbox: logo a sinistra, links a destra */
  display: flex;
  justify-content: space-between;
  align-items: center;

  /* parte invisibile, appare dopo che le animazioni hero sono finite */
  opacity: 0;
  animation: fadeIn 0.6s ease 1.9s forwards;

  /* per la classe .hidden quando scrolli giù */
  transition: transform 0.35s ease;
}

nav.hidden {
  transform: translateY(-100%);
}

/* ── LOGO ── */
.nav-logo {
  font-family: "DM Mono", monospace;
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  color: var(--text);
  text-decoration: none;
  transition: color 0.2s;
}

.nav-logo:hover {
  color: var(--accent);
}

/* ── LINKS DESKTOP ── */
.nav-links {
  display: flex;
  gap: 2.2rem;
  list-style: none; /* toglie i pallini di default dell'ul */
}

.nav-links a {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  transition: color 0.2s;
}

.nav-links a:hover {
  color: var(--text);
}

/* ════════════════════════════════════════════
   HAMBURGER (visibile solo su mobile via media query)
   Le 3 <span> sono le 3 lineette.
   Quando .open: la prima ruota, la seconda sparisce,
   la terza ruota in senso opposto → forma una X.
══════════════════════════════════════════════ */
.hamburger {
  display: none; /* nascosto di default — appare nella media query mobile */
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
}

.hamburger span {
  display: block;
  width: 22px;
  height: 1px;
  background: var(--text);
  transition:
    transform 0.3s ease,
    opacity 0.3s ease;
}

.hamburger.open span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
.hamburger.open span:nth-child(2) {
  opacity: 0;
}
.hamburger.open span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

/* ════════════════════════════════════════════
   MOBILE MENU — pannello che scivola da destra
   Parte translateX(100%) cioè fuori dallo schermo a destra.
   Quando .open → translateX(0) → entra in vista.
══════════════════════════════════════════════ */
.mobile-menu {
  display: none; /* attivato nella media query mobile */
  position: fixed;
  top: 0;
  right: 0;
  width: min(75vw, 280px);
  height: 100%;
  z-index: 1050;
  background: #0d0d0d;
  border-left: 1px solid var(--dim);
  transform: translateX(100%);
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.mobile-menu.open {
  transform: translateX(0);
}

.mobile-menu-inner {
  display: flex;
  flex-direction: column;
  padding: 5rem 2rem 3rem;
  height: 100%;
}

.mobile-nav-links {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  flex: 1;
}

.mobile-link {
  font-family: "Syne", sans-serif;
  font-weight: 800;
  font-size: clamp(1.5rem, 6vw, 2rem);
  color: var(--muted);
  text-decoration: none;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--dim);
  transition:
    color 0.2s,
    padding-left 0.2s;
}

.mobile-link:hover {
  color: var(--text);
  padding-left: 6px;
}

.mobile-menu-footer {
  font-size: 0.55rem;
  letter-spacing: 0.2em;
  color: var(--muted);
  text-transform: uppercase;
}

/* backdrop scuro che oscura il resto della pagina quando il menu è aperto */
.mobile-backdrop {
  display: none; /* attivato nella media query mobile */
  position: fixed;
  inset: 0;
  z-index: 1040;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}

.mobile-backdrop.show {
  opacity: 1;
  pointer-events: all;
}

/* ════════════════════════════════════════════
   HERO
══════════════════════════════════════════════ */
#hero {
  min-height: 100vh;
  padding: 7rem var(--pad-x) 2rem;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* ── TOP ROW: indice a sinistra, status a destra ── */
.hero-top-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.4rem;
  opacity: 0;
  animation: fadeUp 0.7s ease 0.4s forwards;
}

.hero-index,
.hero-status {
  font-size: 0.6rem;
  letter-spacing: 0.15em;
  color: var(--muted);
  text-transform: uppercase;
}

/* pallino verde che pulsa */
.status-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  background: var(--accent);
  border-radius: 50%;
  margin-right: 0.5rem;
  animation: pulse 2.4s ease-in-out infinite;
}

/* linea che cresce da 0 a 100% */
.hero-line {
  width: 0;
  height: 1px;
  background: var(--dim);
  animation: lineGrow 0.9s ease 0.6s forwards;
}

/* ── NOME GRANDE ──
   flex: 1 → questo blocco occupa tutto lo spazio
   tra la linea e la riga inferiore. Tiene il nome
   centrato verticalmente. */
.hero-name-block {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 2rem 0;
}

.hero-first,
.hero-last {
  font-family: "Syne", sans-serif;
  font-weight: 800;
  font-size: clamp(2.6rem, 10.5vw, 8.5rem);
  line-height: 0.88;
  letter-spacing: -0.03em;
  /* overflow: hidden è il segreto della curtain reveal —
     nasconde lo span interno quando parte sotto il bordo */
  overflow: hidden;
  display: block;
}

/* ANDRES — solo contorno verde */
.hero-first span {
  display: block;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--accent);
  /* parte fuori dal bordo, sale su con l'animazione */
  transform: translateY(105%);
  animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.55s forwards;
}

/* PELIZZER — bianco pieno, leggermente rientrato per tensione editoriale */
.hero-last {
  padding-left: clamp(0.5rem, 3vw, 4rem);
}
.hero-last span {
  display: block;
  color: var(--text);
  transform: translateY(105%);
  animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.8s forwards;
}

/* ── LIVE SYSTEM PANEL ──
   border-left accent: richiama il verde del nome.
   background quasi trasparente: sfumatura verde leggerissima. */
.live-system {
  margin-bottom: 1.2rem;
  padding: 0.9rem 1.2rem;
  border: 1px solid var(--dim);
  border-left: 2px solid var(--accent);
  background: rgba(200, 255, 0, 0.02);
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem;
  opacity: 0;
  animation: fadeUp 0.7s ease 1.1s forwards;
}

.sys-item {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.sys-label {
  font-size: 0.5rem;
  letter-spacing: 0.2em;
  color: var(--accent);
  text-transform: uppercase;
}

.sys-value {
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--text);
}

/* ── HERO BOTTOM: meta a sinistra, bottoni a destra ── */
.hero-bottom {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  padding-top: 1.6rem;
  border-top: 1px solid var(--dim);
  opacity: 0;
  animation: fadeUp 0.7s ease 1.35s forwards;
}

.hero-meta {
  display: flex;
  align-items: center;
  gap: 1.2rem;
}

.hero-role,
.hero-location {
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.hero-sep {
  width: 1px;
  height: 12px;
  background: var(--dim);
}

/* ── BOTTONI ── */
.hero-cta {
  display: flex;
  gap: 0.8rem;
}

.btn {
  font-family: "DM Mono", monospace;
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.7rem 1.4rem;
  border: 1px solid var(--dim);
  color: var(--muted);
  transition:
    color 0.2s,
    border-color 0.2s,
    transform 0.2s;
}

.btn:hover {
  color: var(--text);
  border-color: rgba(235, 235, 235, 0.3);
  /* il bottone si solleva di 2px → effetto "alzarsi" */
  transform: translateY(-2px);
}

/* ════════════════════════════════════════════
   SECTION HEADER (riusabile per tutte le sezioni)
══════════════════════════════════════════════ */
section {
  padding: 7rem var(--pad-x) 4rem;
}

.section-header {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  margin-bottom: 4rem;
}

.section-index {
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  color: var(--muted);
  text-transform: uppercase;
  white-space: nowrap; /* non va a capo */
}

/* la linea occupa tutto lo spazio rimanente */
.section-line {
  flex: 1;
  height: 1px;
  background: var(--dim);
}

/* ════════════════════════════════════════════
   REVEAL ANIMATION (riusabile)
   Stato iniziale: invisibile e spostato 30px in basso.
   Il JS aggiunge la classe .revealed quando l'elemento
   entra nel viewport — il CSS fa il resto.
══════════════════════════════════════════════ */
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity 0.8s ease,
    transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal.revealed {
  opacity: 1;
  transform: translateY(0);
}

/* delay sfalsati: ogni elemento parte un po' dopo l'altro */
.reveal.delay-1 {
  transition-delay: 0.1s;
}
.reveal.delay-2 {
  transition-delay: 0.2s;
}
.reveal.delay-3 {
  transition-delay: 0.3s;
}
.reveal.delay-4 {
  transition-delay: 0.4s;
}

/* ════════════════════════════════════════════
   KEYFRAMES — animazioni globali
══════════════════════════════════════════════ */

/* sale di 15px e appare */
@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(15px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* solo opacità */
@keyframes fadeIn {
  to {
    opacity: 1;
  }
}

/* cresce da 0 a 100% di larghezza */
@keyframes lineGrow {
  to {
    width: 100%;
  }
}

/* sale dal bordo inferiore — usato per la curtain reveal del nome */
@keyframes slideUp {
  to {
    transform: translateY(0);
  }
}

/* pulsazione infinita per il pallino status */
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.4;
    transform: scale(0.8);
  }
}

/* ════════════════════════════════════════════
   ABOUT — editorial layout
   3 zone: meta in cima, citazione grande, body a 2 colonne
══════════════════════════════════════════════ */

#about {
  max-width: 1300px;
  margin: 0 auto; /* centra orizzontalmente:
                     0 sopra/sotto, auto a destra/sinistra */
}

/* ── META TOP — riga sottile sopra la citazione ── */
.about-meta-top {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 3rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--dim);
  max-width: 200px;
}

.meta-label {
  font-size: 0.5rem;
  letter-spacing: 0.25em;
  color: var(--accent);
  text-transform: uppercase;
}

.meta-value {
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  color: var(--muted);
}

/* ── CITAZIONE GRANDE ──
   Stesso DNA del nome hero ma più piccola.
   line-height 1.1 + padding-bottom 0.2em: serve per dare aria
   ai discendenti del corsivo Syne (g, y, p) che tagliavano. */
.about-quote {
  font-family: "Syne", sans-serif;
  font-weight: 800;
  font-size: clamp(2rem, 5.5vw, 4.5rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--text);
  max-width: 22ch;
  margin-bottom: 5rem;
  padding-bottom: 0.2em;
}

.quote-accent {
  color: var(--accent);
  font-style: italic;
}

/* ── CORPO 2 COLONNE 50/50 ── */
.about-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.5rem;
  align-items: start;
}

/* ── PARAGRAFI ── */
.about-para {
  font-size: 0.78rem;
  line-height: 1.9;
  color: var(--text);
  margin-bottom: 2.5rem;
}

/* <em> diventa Syne corsivo verde, leggermente più grande
   per bilanciare otticamente con il DM Mono intorno */
.about-para em {
  font-family: "Syne", sans-serif;
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  font-size: 0.9rem;
}

/* <strong> resta DM Mono ma con underline accent */
.about-para strong {
  color: var(--text);
  font-weight: 400;
  border-bottom: 1px solid var(--accent);
  padding-bottom: 1px;
}

/* ── STATS — 3 mini-card chiave/valore affiancate ── */
.about-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  padding-top: 2rem;
  border-top: 1px solid var(--dim);
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* la "chiave" piccola in cima */
.stat-key {
  font-size: 0.5rem;
  letter-spacing: 0.22em;
  color: var(--accent);
  text-transform: uppercase;
}

/* il valore vero, leggibile */
.stat-val {
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: var(--text);
  line-height: 1.6;
}

/* ── LISTA DETTAGLI ── */
.about-list {
  list-style: none;
  border-top: 1px solid var(--dim);
}

.about-list li {
  display: flex;
  justify-content: space-between;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--dim);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
}

/* primo span = label (uppercase, grigio, spaziato),
   ultimo span = valore (bianco) — selezionati per posizione */
.about-list li span:first-child {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.2em;
}

.about-list li span:last-child {
  color: var(--text);
}

/* ════════════════════════════════════════════
   PROJECTS — sticky scroll layout
   Due metà affiancate:
   - sinistra (frame): sticky, rimane fissa mentre scrolli
   - destra (content): scorre normalmente
══════════════════════════════════════════════ */
#projects {
  max-width: 1440px;
  margin: 0 auto;
}

.projects-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4rem;
  align-items: start; /* importante per sticky:
                         senza questo le colonne si stirerebbero
                         e sticky non funzionerebbe correttamente */
}

/* ── COLONNA SINISTRA — sticky frame ── */
.projects-frame {
  position: sticky;
  top: 8rem; /* a quanto si "incolla" dall'alto.
                8rem dà respiro alla nav che è in cima */
  align-self: start;
}

/* ── COLONNA DESTRA — contenuto scrollabile ──
   Le schede progetto al suo interno hanno un grande spazio
   verticale per dare tempo al frame sticky di "vivere" */
.projects-content {
  display: flex;
  flex-direction: column;
  gap: 8rem; /* tanto spazio tra le schede:
                così quando una scheda esce dallo schermo,
                l'altra arriva al centro e cambia il frame */
}

/* ── BROWSER FRAME ──
   Container che imita una finestra browser.
   border-radius arrotonda gli angoli, il border lo separa dallo sfondo,
   overflow: hidden taglia l'immagine se sborda. */
.browser {
  border: 1px solid var(--dim);
  border-radius: 10px;
  overflow: hidden;
  background: #0d0d0d;
  /* box-shadow sottile per far "staccare" il frame dallo sfondo —
     dà un senso di profondità */
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.4);
}

/* ── BROWSER BAR (top, dove ci sono i pallini e l'URL) ── */
.browser-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1rem;
  background: #111;
  border-bottom: 1px solid var(--dim);
}

/* ── 3 PALLINI macOS ──
   .browser-dots è il container, ogni span dentro è un pallino.
   :nth-child(N) seleziona l'N-esimo figlio:
   1° rosso (close) — 2° giallo (minimize) — 3° verde (maximize) */
.browser-dots {
  display: flex;
  gap: 6px;
}

.browser-dots span {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #333;
}

.browser-dots span:nth-child(1) {
  background: #ff5f57;
}
.browser-dots span:nth-child(2) {
  background: #febc2e;
}
.browser-dots span:nth-child(3) {
  background: #28c840;
}

/* ── URL BAR ──
   flex: 1 le fa occupare tutto lo spazio rimanente sulla riga */
.browser-url {
  flex: 1;
  text-align: center;
  font-family: "DM Mono", monospace;
  font-size: 0.55rem;
  letter-spacing: 0.05em;
  color: var(--muted);
  padding: 0.4rem 0.8rem;
  background: var(--bg);
  border: 1px solid var(--dim);
  border-radius: 4px;
}

/* ── VIEWPORT (dove sta l'immagine del progetto) ──
   aspect-ratio 16/10: rapporto fisso schermo laptop,
   il riquadro non cambia altezza quando l'immagine cambia */
.browser-viewport {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--dim);
}

.browser-viewport img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* riempie l'area senza deformare l'immagine */
  display: block; /* toglie 4px sotto le immagini di default
                     (è una stranezza HTML antica) */
  transition: opacity 0.4s ease; /* per quando il JS cambia immagine
                                    vogliamo una fade smooth, non uno scatto */
}

/* ════════════════════════════════════════════
   PROJECTS — singola scheda progetto
══════════════════════════════════════════════ */

.project {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* "01 / 02" piccolo in cima */
.project-num {
  font-size: 0.55rem;
  letter-spacing: 0.25em;
  color: var(--accent);
  text-transform: uppercase;
}

/* TITOLO — Syne come tutti i titoli del sito */
.project-title {
  font-family: "Syne", sans-serif;
  font-weight: 800;
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--text);
}

/* sottotitolo: anno + tipo progetto */
.project-year {
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  color: var(--muted);
  text-transform: uppercase;
}

/* paragrafo descrittivo */
.project-desc {
  font-size: 0.78rem;
  line-height: 1.9;
  color: var(--text);
  margin-top: 0.5rem;
}

/* ── STACK LIST ──
   Trasforma l'<ul> in una riga di "tag" inline.
   list-style: none toglie i pallini.
   flex + flex-wrap: vanno a capo se non c'è spazio. */
.project-stack {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

/* ogni <li> diventa un piccolo "chip" con bordo */
.project-stack li {
  font-size: 0.55rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--dim);
  border-radius: 4px;
}

/* ── LINKS in fondo (View live, GitHub) ── */
.project-links {
  display: flex;
  gap: 1.5rem;
  margin-top: 1rem;
}

.project-link {
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text);
  text-decoration: none; /* toglie la sottolineatura blu di default */
  border-bottom: 1px solid var(--accent);
  padding-bottom: 2px;
  transition:
    color 0.2s,
    border-color 0.2s;
}

.project-link:hover {
  color: var(--accent);
}

/* ════════════════════════════════════════════
   SKILLS — marquee infinito orizzontale
   3 nastri sovrapposti che scorrono in direzioni alterne.
   Ogni nastro contiene i suoi chip ripetuti 4 volte:
   l'animazione trasla del -25% e così il loop sembra infinito
   senza buchi.
══════════════════════════════════════════════ */

#skills {
  max-width: 1600px;
  margin: 0 auto;
}

.skills-marquees {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* ── MARQUEE — singolo nastro ──
   overflow: hidden taglia tutto quello che sborda dai bordi:
   senza questo vedresti il nastro "uscire" dal contenitore.
   border + padding: aspetto editoriale, contiene il nastro. */
.marquee {
  overflow: hidden;
  border-top: 1px solid var(--dim);
  border-bottom: 1px solid var(--dim);
  padding: 1.2rem 0;
}

/* ── TRACK — il nastro che scorre veramente ──
   white-space: nowrap impedisce ai chip di andare a capo.
   width: max-content fa sì che il track sia largo quanto serve
   per contenere TUTTI i suoi chip in riga, anche se sborda. */
.marquee-track {
  display: flex;
  align-items: center;
  white-space: nowrap;
  width: max-content;
  /* l'animazione fa scorrere il nastro all'infinito */
  animation: marqueeScroll 25s linear infinite;
}

/* ── KEYFRAMES MARQUEE ──
   trasla il nastro del -25% della sua larghezza.
   Visto che il contenuto è ripetuto 4 volte (4 copie identiche),
   quando arriva al -25% sta mostrando esattamente il punto
   da cui era partito → l'occhio non vede il salto → loop infinito. */
@keyframes marqueeScroll {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-25%);
  }
}

/* il secondo nastro va in direzione opposta:
   animation-direction: reverse inverte l'animazione */
.marquee-reverse .marquee-track {
  animation-direction: reverse;
}

/* su hover il nastro si ferma — utile per leggere bene */
.marquee:hover .marquee-track {
  animation-play-state: paused;
}

/* ── SINGOLO CHIP "skill" ──
   inline-flex per allineare il pallino col testo,
   gap piccolo tra dot e testo */
.skill {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text);
  padding: 0.5rem 1rem;
  border: 1px solid var(--dim);
  border-radius: 4px;
  flex-shrink: 0; /* impedisce ai chip di "schiacciarsi"
                     se il browser prova a comprimerli */
  /* margin-right invece di gap sul track:
     così l'ultimo chip ha lo stesso spazio del primo della copia successiva
     → il loop è matematicamente perfetto, senza buchi visibili */
  margin-right: 2rem;
}

/* il pallino accent dentro ogni chip */
.skill-dot {
  width: 6px;
  height: 6px;
  background: var(--accent);
  border-radius: 50%;
  flex-shrink: 0;
}

/* ════════════════════════════════════════════
   TABLET — max 800px
   Sovrascrive solo quello che cambia rispetto al desktop.
══════════════════════════════════════════════ */
@media (max-width: 800px) {
  /* nasconde la linea decorativa laterale */
  .deco-line {
    display: none;
  }

  /* nav: sostituisce link con hamburger */
  .nav-links {
    display: none;
  }
  .hamburger {
    display: flex;
  }
  .mobile-menu {
    display: block;
  }
  .mobile-backdrop {
    display: block;
  }

  /* hero: nome più piccolo, layout più compatto */
  .hero-first,
  .hero-last {
    font-size: clamp(2.4rem, 13vw, 5rem);
    line-height: 1;
  }

  .hero-first span {
    -webkit-text-stroke: 1px var(--accent); /* stroke più sottile */
  }

  .hero-name-block {
    flex: 0; /* non si espande verticalmente — su tablet creava troppo vuoto */
    padding: 1.2rem 0;
  }

  .hero-bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 1.2rem;
  }

  .hero-cta {
    width: 100%;
  }

  .btn {
    flex: 1;
    text-align: center;
  }

  .live-system {
    gap: 1rem;
  }

  /* skills: marquee più veloce su mobile per compensare lo schermo stretto */
  .marquee-track {
    animation-duration: 18s;
  }

  /* chip un po' più piccoli su tablet */
  .skill {
    font-size: 0.62rem;
    padding: 0.4rem 0.8rem;
    margin-right: 1.2rem;
  }
}

/* ════════════════════════════════════════════
   MOBILE — max 430px
══════════════════════════════════════════════ */
@media (max-width: 430px) {
  /* svh invece di vh: tiene conto della barra browser
     che appare/scompare su mobile, evitando salti */
  #hero {
    padding: 5rem 1.4rem 2rem;
    min-height: 100svh;
  }

  .hero-first,
  .hero-last {
    font-size: clamp(2rem, 14.5vw, 3.5rem);
  }

  /* top row in colonna, separatore via, bottoni in colonna */
  .hero-top-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
  }

  .hero-sep {
    display: none;
  }

  .hero-cta {
    flex-direction: column;
  }

  /* sezioni: padding più stretto su mobile */
  section {
    padding: 5rem 1.4rem 3rem;
  }
}
