/* ==========================================================================
   COME MODIFICARE QUESTO FILE (guida rapida per chi non programma)
   --------------------------------------------------------------------------
   - I COLORI si cambiano tutti in un unico posto: il blocco ":root" qui
     sotto. Cambia il valore esadecimale e si aggiorna ovunque nel sito.
   - Le SCRITTE (testi) NON sono in questo file: sono in "index.html".
     Questo file si occupa solo di come le cose appaiono (colori, spazi,
     dimensioni, font, animazioni).
   - Il sito usa un linguaggio visivo ricorrente ("blueprint"): pannelli blu
     notte, diagrammi a nodi che mostrano lo stack reale dei progetti,
     etichette in monospace in stile disegno tecnico. Cercalo commentato
     dove compare, per capire come riusarlo in caso di modifiche.
   ========================================================================== */

:root {
  /* --- Colori di brand (non cambiare: sono il vincolo di partenza) --- */
  --color-primary: #1d70b7; /* blu principale: bottoni, link, "inchiostro" delle linee */
  --color-secondary: #35a8e0; /* azzurro: stati attivi, accenti "dati" */

  /* --- Neutri, tutti derivati dai due blu di brand (mai grigio puro) --- */
  --color-dark: #0b1e33; /* blu-notte "blueprint": pannelli scuri, non un nero neutro */
  --color-bg: #f5f8fc; /* carta: sfondo di base, bianco a base fredda, non crema */
  --color-white: #ffffff; /* superfici in rilievo (card, header) */
  --color-text: #3d5064; /* testo corrente, slate scuro */
  --color-slate: #6b8098; /* testo secondario/didascalie, slate medio */
  --color-border: #dce6ef; /* bordi sottili */

  /* --- Accento "segnale": usato con parsimonia (indicatori, dettagli hover) --- */
  --color-signal: #33ce14;

  --gradient-brand: linear-gradient(135deg, var(--color-primary), var(--color-secondary));

  /* --- Font: Plus Jakarta Sans per i testi, JetBrains Mono per dati ed
     etichette tecniche (stack dei progetti, coordinate, stato) --- */
  --font-main: 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* --- Scala di spaziatura, multipli di 8px --- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 16px;
  --space-4: 24px;
  --space-5: 32px;
  --space-6: 48px;
  --space-7: 64px;
  --space-8: 96px;
  --space-9: 140px;

  /* --- Durate delle animazioni collegate allo scroll ---
     @media (prefers-reduced-motion: reduce) più in fondo le azzera tutte. */
  --motion-fast: 0.4s;
  --motion-slow: 0.7s;
  --motion-ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* Altezza reale dell'header (.site-header), misurata in js/main.js: la
     usano lo scroll-margin delle sezioni e il pin di "Chi sono". Il valore
     qui è solo il fallback prima che lo script giri la prima volta. */
  --header-height: 84px;

  /* --- Larghezza massima dei contenuti --- */
  --container-width: 1160px;
}

/* Reset di base, minimo indispensabile */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-main);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Le card progetto a tutto schermo usano 100vw: senza questo, la
     larghezza della scrollbar verticale genera qualche pixel di
     overflow orizzontale sull'intera pagina. */
  overflow-x: hidden;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

.container {
  width: 100%;
  max-width: var(--container-width);
  margin-inline: auto;
  padding-inline: 24px;
}

/* Focus da tastiera: sempre visibile, sempre coerente col brand — nessun
   "outline: none" nel sito, solo questo trattamento intenzionale. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--color-secondary);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Evita che il contenuto delle sezioni finisca nascosto sotto l'header
   sticky quando ci si arriva con un link di ancora (es. "Vediamo i
   progetti", o il logo che riporta a #home). */
.hero,
.section {
  scroll-margin-top: var(--header-height);
}

/* ==========================================================================
   BOTTONI (CTA)
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 28px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.95rem;
  white-space: nowrap;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  border: 2px solid transparent;
}

.btn--primary {
  background: var(--color-primary);
  color: var(--color-white);
  box-shadow: 0 8px 20px -6px rgba(29, 112, 183, 0.55);
}

.btn--primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 24px -6px rgba(29, 112, 183, 0.6);
}

.btn--secondary {
  background: transparent;
  color: var(--color-primary);
  border-color: var(--color-border);
}

.btn--secondary:hover {
  border-color: var(--color-primary);
  background: rgba(29, 112, 183, 0.06);
}

.btn--nav {
  padding: 10px 22px;
  font-size: 0.9rem;
}

/* ==========================================================================
   INDICATORE DI AVANZAMENTO SCROLL
   ========================================================================== */

.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  z-index: 100;
  background: transparent;
}

.scroll-progress__bar {
  height: 100%;
  width: 0%;
  background: var(--gradient-brand);
  transition: width 0.1s linear;
}

/* ==========================================================================
   HEADER / NAV
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-block: 14px;
}

.site-header__logo img {
  height: 50px;
  width: auto;
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* Hamburger accanto a "Lavoriamo insieme", visibile a ogni larghezza:
   apre/chiude .mobile-nav. Le due barre sono pseudo-elementi, quella
   centrale è lo <span> stesso: diventano una "X" con .is-open. */
.site-header__menu-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 0px solid var(--color-border);
  background: none;
}

.site-header__menu-toggle:hover {
  border-color: var(--color-primary);
}

.site-header__menu-icon,
.site-header__menu-icon::before,
.site-header__menu-icon::after {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--color-dark);
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.site-header__menu-icon::before,
.site-header__menu-icon::after {
  content: '';
  position: relative;
}

.site-header__menu-icon::before {
  top: -5px;
}

.site-header__menu-icon::after {
  top: -7px;
}

.site-header__menu-toggle.is-open .site-header__menu-icon {
  background: transparent;
}

.site-header__menu-toggle.is-open .site-header__menu-icon::before {
  top: 0;
  transform: rotate(45deg);
}

.site-header__menu-toggle.is-open .site-header__menu-icon::after {
  top: -2px;
  transform: rotate(-45deg);
}

/* Pannello a tendina, visibile a ogni larghezza: chiuso di default
   (max-height: 0, overflow hidden), .mobile-nav.is-open lo apre con una
   transizione morbida. display:flex sempre (niente display:none) così
   la transizione di apertura/chiusura può animare. */
.mobile-nav {
  display: flex;
  flex-direction: column;
  max-height: 0;
  overflow: hidden;
  background: var(--color-white);
  border-top: 1px solid transparent;
  transition: max-height 0.25s ease, border-color 0.25s ease;
}

.mobile-nav.is-open {
  max-height: 320px;
  border-top-color: var(--color-border);
}

.mobile-nav__link {
  padding: 14px 24px;
  font-weight: 600;
  color: var(--color-text);
  border-bottom: 1px solid var(--color-border);
}

.mobile-nav__link:hover {
  color: var(--color-primary);
}

/* ==========================================================================
   SUPERFICIE "BLUEPRINT" (pannelli scuri ricorrenti)
   Sfondo blu-notte con una griglia leggerissima, come la carta di un
   disegno tecnico: la usano il pannello Hero, i divisori tra sezioni, la
   rotaia di "Chi sono", i frame degli screenshot progetto e i loro
   diagrammi stack, e la sezione Contatti — è il filo conduttore visivo
   del sito (vedi anche .stack-diagram più sotto).
   ========================================================================== */

.blueprint-surface {
  background-color: var(--color-dark);
  background-image: linear-gradient(rgba(53, 168, 224, 0.12) 1px, transparent 1px),
    linear-gradient(90deg, rgba(53, 168, 224, 0.12) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* Divisore sottile tra sezioni: una fascia scura con una coordinata in
   mono, come i numeri di foglio di un fascicolo di disegni tecnici (qui il
   numero ha un significato reale: indica dove sei nella pagina). */
.blueprint-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 56px;
  color: rgba(255, 255, 255, 0.55);
}

.blueprint-divider__label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* ==========================================================================
   DIAGRAMMA A NODI (stack tecnico)
   Componente condiviso tra Hero (versione grande, su sfondo scuro) e le
   card progetto (".stack-diagram--sm", chip scuri orizzontali): mostra lo
   stack REALE di ogni progetto, al posto di tag a pillola generici.
   ========================================================================== */

.stack-diagram {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.stack-diagram__node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 22px 24px;
  border: 1px solid rgba(53, 168, 224, 0.35);
  border-radius: 10px;
  background: rgba(53, 168, 224, 0.08);
}

.stack-diagram__label {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--color-white);
  letter-spacing: 0.02em;
}

.stack-diagram__tag {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  color: var(--color-secondary);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.stack-diagram__connector {
  align-self: center;
  width: 1px;
  height: 40px;
  background: rgba(53, 168, 224, 0.45);
}

/* Variante piccola: chip orizzontali scuri dentro le card progetto (sfondo
   chiaro), al posto della vecchia fila di badge a pillola */
.stack-diagram--sm {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: auto;
  padding-top: 8px;
}

.stack-diagram--sm .stack-diagram__node {
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--color-dark);
  border-color: transparent;
}

.stack-diagram--sm .stack-diagram__label {
  font-size: 0.72rem;
}

.stack-diagram--sm .stack-diagram__connector {
  width: 16px;
  height: 1px;
  background: var(--color-border);
}

/* ==========================================================================
   HERO
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-5) var(--space-5);
  background: var(--color-bg);
}

.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: var(--space-8);
  align-items: start;
}

.hero__intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
}

.hero__status {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-slate);
}

.hero__status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-signal);
  box-shadow: 0 0 0 3px rgba(34, 126, 6, 0.25);
}

.hero__title {
  font-size: clamp(2.4rem, 5vw, 4.4rem);
  font-weight: 800;
  line-height: 1.08;
  color: var(--color-dark);
  letter-spacing: -0.02em;
}

.hero__title span {
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__subtitle {
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  color: var(--color-text);
  max-width: 58ch;
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 8px;
}

/* Pannello "blueprint" della Hero: il diagramma a nodi reale di come
   Luigi costruisce i prodotti (UI → Auth/Dati → Prodotto pubblicato). */
.hero__blueprint {
  border-radius: 20px;
  padding: var(--space-6) var(--space-5);
  /* Allinea il bordo superiore del pannello alla prima riga del titolo
     ("Sviluppatore"), non al blocco .hero__intro nel suo insieme: quella
     riga inizia dopo lo status pill (~28px) più il gap tra i due
     (var(--space-4)). Un valore fisso qui è la scelta più semplice per un
     dettaglio di allineamento fine come questo. */
  margin-top: 52px;
}

.hero__blueprint-caption {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  margin-bottom: var(--space-4);
}

/* ==========================================================================
   HERO — ingresso animato (una tantum) e parallax leggero
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  html.js .hero__status,
  html.js .hero__title,
  html.js .hero__subtitle,
  html.js .hero__cta,
  html.js .hero__blueprint {
    opacity: 0;
    translate: 0 18px;
    animation: hero-enter var(--motion-slow) var(--motion-ease) forwards;
  }

  html.js .hero__status {
    animation-delay: 0.05s;
  }
  html.js .hero__title {
    animation-delay: 0.15s;
  }
  html.js .hero__subtitle {
    animation-delay: 0.3s;
  }
  html.js .hero__cta {
    animation-delay: 0.42s;
  }
  html.js .hero__blueprint {
    animation-delay: 0.3s;
  }

  @keyframes hero-enter {
    to {
      opacity: 1;
      translate: 0 0;
    }
  }

  .hero__status-dot {
    animation: status-pulse 2.4s ease-in-out infinite;
  }

  @keyframes status-pulse {
    50% {
      box-shadow: 0 0 0 6px rgba(232, 162, 61, 0.12);
    }
  }

}

/* ==========================================================================
   BLOCCHI COMUNI ALLE SEZIONI
   ========================================================================== */

.section {
  padding-block: var(--space-9);
}

.section--muted {
  background: var(--color-bg);
}

.section__eyebrow {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-primary);
  margin-bottom: var(--space-3);
}

.section__title {
  font-size: clamp(2.2rem, 5.5vw, 3.4rem);
  font-weight: 800;
  line-height: 1.12;
  color: var(--color-dark);
  letter-spacing: -0.02em;
  max-width: 680px;
}

/* ==========================================================================
   CHI SONO
   ========================================================================== */

.about__head {
  margin-bottom: var(--space-6);
}

.about__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}

/* Rotaia laterale: foto + "spina" con le etichette delle 4 battute. Fa
   parte del sistema blueprint (sfondo scuro, vedi .blueprint-surface). */
.about__rail {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-4);
  border-radius: 18px;
  padding: var(--space-4);
}

.about__portrait {
  width: 88px;
  height: 88px;
  flex-shrink: 0;
  border-radius: 12px;
  object-fit: cover;
  object-position: center 15%;
  border: 1px solid rgba(255, 255, 255, 0.18);
}

.about__spine {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.about__tick {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.65);
  white-space: nowrap;
}

.about__heading {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-primary);
  margin-bottom: var(--space-3);
}

.about__block p {
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  line-height: 1.55;
  max-width: 62ch;
}

/* Reveal-on-scroll delle battute quando scorrono normalmente (mobile, o
   "riduci movimento" attivo, o comunque prima che lo script attivi il
   layout pinnato più sotto): nascoste solo con JS attivo. */
html.js .about__beat {
  opacity: 0;
  translate: 0 24px;
  transition: opacity var(--motion-slow) var(--motion-ease), translate var(--motion-slow) var(--motion-ease);
}

html.js .about__beat.is-visible {
  opacity: 1;
  translate: 0 0;
}

.about__beats {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

@media (min-width: 769px) and (prefers-reduced-motion: no-preference) {
  .about__layout {
    grid-template-columns: 240px 1fr;
    align-items: start;
  }

  .about__rail {
    position: sticky;
    top: calc(var(--header-height) + var(--space-4));
    flex-direction: column;
    align-items: flex-start;
  }

  .about__portrait {
    width: 100%;
    height: auto;
    aspect-ratio: 1;
  }

  .about__spine {
    flex-direction: column;
    gap: var(--space-3);
  }

  .about__tick.is-active {
    color: var(--color-secondary);
  }

  /* L'altezza del pin-wrapper (4 "schermi") è lo spazio di scroll che dà
     il tempo alle 4 battute di succedersi mentre la sezione resta ferma. */
  .about__pin-wrapper {
    height: 400vh;
  }

  .about__pin-inner {
    position: sticky;
    top: var(--header-height, 84px);
    height: calc(100vh - var(--header-height, 84px));
    display: flex;
    align-items: center;
    overflow: hidden;
  }

  .about__beats {
    display: grid;
    gap: 0;
    width: 100%;
  }

  html.js .about__beat {
    grid-area: 1 / 1;
    opacity: 0;
    translate: 0;
    visibility: hidden;
    transition: opacity var(--motion-slow) var(--motion-ease);
  }

  html.js .about__beat.is-active {
    opacity: 1;
    visibility: visible;
  }

  @supports (animation-timeline: view()) {
    /* .about__tick vive in .about__rail, FUORI da .about__pin-wrapper (che
       definisce il timeline): senza "timeline-scope" sull'antenato comune,
       il timeline non sarebbe visibile lì e le etichette non si
       aggiornerebbero mai (restano quella iniziale scritta in HTML). */
    .about__layout {
      timeline-scope: --about-progress;
    }

    .about__pin-wrapper {
      view-timeline-name: --about-progress;
      view-timeline-axis: block;
    }

    html.js .about__beat {
      animation-name: beat-step;
      animation-timeline: --about-progress;
      animation-fill-mode: both;
      transition: none;
    }

    /* Le battute (e le rispettive etichette poco più sotto) sono sincronizzate
       sulla progress bar dell'INTERO .about__pin-wrapper (0%–100% = da quando
       il suo bordo superiore tocca il fondo dello schermo a quando il bordo
       inferiore ne esce da sopra). Ma il contenuto resta effettivamente
       "agganciato" e leggibile solo per la fetta centrale di quel range —
       circa 20%–80% — perché prima e dopo il wrapper sta ancora scorrendo
       in/out di vista (non è ancora, o non è più, in posizione sticky).
       Distribuire le 4 battute sull'intero 0%–100% (come prima) faceva sì
       che la prima terminasse la sua dissolvenza già a ridosso del 20%, cioè
       proprio mentre l'utente iniziava a vedere la sezione agganciata:
       appariva sparire "subito". Le 4 fasce qui sotto restano dentro il
       20%–80% effettivamente visibile, mantenendo la stessa dissolvenza. */
    .about__beat[data-beat='0'] {
      animation-range: cover 20% cover 33%;
    }
    .about__beat[data-beat='1'] {
      animation-range: cover 32% cover 48%;
    }
    .about__beat[data-beat='2'] {
      animation-range: cover 47% cover 63%;
    }
    .about__beat[data-beat='3'] {
      animation-range: cover 62% cover 80%;
    }

    @keyframes beat-step {
      0%,
      100% {
        opacity: 0;
        visibility: hidden;
      }
      35%,
      65% {
        opacity: 1;
        visibility: visible;
      }
    }

    .about__tick {
      animation-name: tick-step;
      animation-timeline: --about-progress;
      animation-fill-mode: both;
    }

    .about__tick[data-tick='0'] {
      animation-range: cover 20% cover 33%;
    }
    .about__tick[data-tick='1'] {
      animation-range: cover 32% cover 48%;
    }
    .about__tick[data-tick='2'] {
      animation-range: cover 47% cover 63%;
    }
    .about__tick[data-tick='3'] {
      animation-range: cover 62% cover 80%;
    }

    @keyframes tick-step {
      0%,
      100% {
        color: rgba(255, 255, 255, 0.65);
      }
      35%,
      65% {
        color: var(--color-secondary);
      }
    }
  }
}

/* ==========================================================================
   PROGETTI
   ========================================================================== */

.projects__head {
  margin-bottom: var(--space-4);
}

/* Corsia orizzontale delle card: sotto i 769px (o "riduci movimento"
   attivo) resta uno scroll normale trascinabile a mano, con snap per
   fermarsi allineata a ciascuna — il pin qui sotto la sostituisce sugli
   schermi larghi. */
.projects__scroll {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--color-primary) transparent;
}

.projects__scroll::-webkit-scrollbar {
  height: 8px;
}

.projects__scroll::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: 999px;
}

.projects__scroll::-webkit-scrollbar-thumb:hover {
  background: var(--color-primary);
}

.projects__track {
  display: flex;
  width: max-content;
}

.project-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--color-white);
  transition: box-shadow 0.15s ease;
}

.project-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1;
}

/* Una card = una schermata intera: larga quanto la finestra (100vw),
   contenuto (screenshot a sinistra, testo a destra) centrato alla
   stessa larghezza del resto del sito grazie al padding-inline. */
.project-card--featured {
  flex: 0 0 100vw;
  width: 100vw;
  scroll-snap-align: start;
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: var(--space-5);
  align-items: center;
  padding-inline: max(24px, calc((100vw - var(--container-width)) / 2 + 24px));
  padding-block: var(--space-6);
}

/* Frame che incornicia gli screenshot reali: bordo blueprint, etichetta
   in mono al posto delle solite "pallline" da finta barra del browser. */
.device-frame {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  background: var(--color-dark);
  box-shadow: 0 24px 48px -28px rgba(11, 30, 51, 0.45);
}

.device-frame img {
  display: block;
  width: 100%;
  height: auto;
  transition: transform var(--motion-slow) var(--motion-ease);
}

.project-card:hover .device-frame img {
  transform: scale(1.03);
}

.project-card__eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-primary);
}

.project-card__eyebrow--wip {
  color: var(--color-signal);
}

.project-card__title {
  font-size: 1.3rem;
  font-weight: 800;
  color: var(--color-dark);
}

.project-card--featured .project-card__title {
  font-size: clamp(1.6rem, 3vw, 2.1rem);
}

.project-card--featured .project-card__body {
  gap: var(--space-3);
}

.project-card__desc {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--color-text);
}

.project-card__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--color-primary);
  text-decoration: none;
  width: fit-content;
}

.project-card__link:hover {
  text-decoration: underline;
}

/* Reveal-on-scroll delle card, stesso pattern del resto del sito */
html.js .project-card {
  opacity: 0;
  translate: 0 28px;
  transition: opacity var(--motion-slow) var(--motion-ease),
    translate var(--motion-slow) var(--motion-ease), transform 0.15s ease, box-shadow 0.15s ease;
}

html.js .project-card.is-visible {
  opacity: 1;
  translate: 0 0;
}

/* ==========================================================================
   PROGETTI — sequenza pinnata (stesso meccanismo di "Chi sono", vedi i
   commenti più dettagliati in quella sezione): qui, invece di dissolvenza
   tra 4 battute impilate, la sezione resta ferma mentre le card
   scorrono in orizzontale una alla volta. L'altezza del pin-wrapper è lo
   spazio di scroll che serve a "consumare" la sequenza — è questo, non
   un intercettore della rotellina, a garantire che anche uno scroll
   molto veloce non possa saltarla: per attraversare il wrapper la pagina
   deve comunque scorrere quella distanza, quale che sia il dispositivo
   di input.
   ========================================================================== */

@media (min-width: 769px) and (prefers-reduced-motion: no-preference) {
  /* 100vh circa per card (5 card = 500vh): se cambia il numero di card,
     aggiorna proporzionalmente sia questa altezza sia i keyframe
     projects-slide più sotto. */
  .projects__pin-wrapper {
    height: 500vh;
  }

  .projects__pin-inner {
    position: sticky;
    top: var(--header-height, 84px);
    height: calc(100vh - var(--header-height, 84px));
    display: flex;
    align-items: center;
    overflow: hidden;
  }

  .projects__scroll {
    overflow: hidden;
  }

  /* In modalità pinnata le card sono già tutte visibili una accanto
     all'altra nella corsia: a cambiare è solo quale porzione della
     corsia rientra nella finestra visibile (il resto è tagliato da
     .projects__scroll { overflow: hidden }), non serve più il
     reveal-on-scroll verticale del fallback semplice. */
  html.js .project-card {
    opacity: 1;
    translate: 0;
  }

  /* Transizione dell'assestamento tra una card e l'altra nel ripiego JS
     (initProjectsPin in js/main.js), che aggiorna translate a scatti a
     ogni frame di scroll: senza, il passaggio da una card alla successiva
     sarebbe un taglio secco invece di uno scorrimento. Nel ramo nativo
     qui sotto (animation-timeline) la transizione è già incorporata
     nei keyframe stessi, e un'animazione CSS ha comunque la precedenza
     su questa transition sulla stessa proprietà, quindi non confliggono. */
  .projects__track {
    transition: translate 0.4s var(--motion-ease);
  }

  @supports (animation-timeline: view()) {
    .projects__pin-wrapper {
      view-timeline-name: --projects-progress;
      view-timeline-axis: block;
    }

    .projects__track {
      animation-name: projects-slide;
      animation-timeline: --projects-progress;
      animation-fill-mode: both;
      /* Stessa idea delle battute di "Chi sono": il range 15%–85% (invece
         di 0%–100%) tiene la traslazione dentro la fetta in cui il
         wrapper è effettivamente agganciato in posizione sticky. */
      animation-range: cover 15% cover 85%;
    }

    /* Cinque soste nette (una per card) invece di uno scorrimento
       continuo: fermandosi a metà scroll si vede sempre una card intera,
       mai due a metà — come le battute di "Chi sono", che restano ferme
       sul 0%/100% di opacità e non a un valore intermedio. -100vw/-200vw/
       -300vw/-400vw = -(indice card) * 100vw: aggiungendo/togliendo una
       card, aggiorna sia questi valori (e le percentuali delle soste,
       spaziate qui a intervalli regolari sull'intero 0%–100%) sia
       window.innerWidth * indice nel fallback JS (initProjectsPin in
       js/main.js — quello si adatta già da solo al numero di card
       presenti nel markup, non serve toccarlo). */
    @keyframes projects-slide {
      0%,
      14% {
        translate: 0 0;
      }
      21%,
      35% {
        translate: -100vw 0;
      }
      43%,
      57% {
        translate: -200vw 0;
      }
      64%,
      78% {
        translate: -300vw 0;
      }
      86%,
      100% {
        translate: -400vw 0;
      }
    }
  }
}

/* ==========================================================================
   CONTATTI — "cartiglio" di chiusura (sfondo blueprint scuro)
   ========================================================================== */

.contact__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}

.contact__inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.section__eyebrow--light {
  color: var(--color-secondary);
}

.section__title--light {
  color: var(--color-white);
}

.contact__lead {
  margin-top: 8px;
  max-width: 560px;
  color: rgba(255, 255, 255, 0.75);
  font-size: clamp(1rem, 1.6vw, 1.1rem);
}

.contact__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: var(--space-5);
}

.contact .btn--secondary {
  color: var(--color-white);
  border-color: rgba(255, 255, 255, 0.3);
}

.contact .btn--secondary:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: var(--color-white);
}

/* Riga di metadati in stile "cartiglio" tecnico, sostituisce la semplice
   nota di copyright con qualcosa coerente col resto del sito */
.contact__meta {
  margin-top: var(--space-7);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  width: 100%;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
}

html.js .contact__inner {
  opacity: 0;
  translate: 0 24px;
  transition: opacity var(--motion-slow) var(--motion-ease), translate var(--motion-slow) var(--motion-ease);
}

html.js .contact__inner.is-visible {
  opacity: 1;
  translate: 0 0;
}

/* ==========================================================================
   MODULO PROGETTO (dentro Contatti)
   Pannello "vetro" sul fondo scuro, coerente col resto del sistema
   blueprint: etichette in mono, campi con bordo sottile e focus in blu
   secondario. Vedi js/main.js (initContactForm) per l'invio via mailto.
   ========================================================================== */

.contact__form {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 18px;
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.contact__form-caption {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}

.contact__form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.contact__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.contact__field label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
}

.contact__field input,
.contact__field select,
.contact__field textarea {
  font-family: var(--font-main);
  font-size: 0.95rem;
  color: var(--color-white);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 8px;
  padding: 10px 14px;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.contact__field input::placeholder,
.contact__field textarea::placeholder {
  color: rgba(255, 255, 255, 0.35);
}

.contact__field input:hover,
.contact__field select:hover,
.contact__field textarea:hover {
  border-color: rgba(255, 255, 255, 0.35);
}

.contact__field input:focus,
.contact__field select:focus,
.contact__field textarea:focus {
  outline: none;
  border-color: var(--color-secondary);
  background: rgba(255, 255, 255, 0.09);
}

.contact__field textarea {
  resize: vertical;
  min-height: 96px;
}

.contact__field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%2335A8E0' stroke-width='2'%3E%3Cpath d='M5 7.5l5 5 5-5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 18px;
  padding-right: 36px;
}

.contact__field select option {
  background: var(--color-dark);
  color: var(--color-white);
}

.contact__form-submit {
  align-self: flex-start;
  margin-top: 4px;
}

.contact__form-note {
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.65);
  min-height: 1.2em;
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 900px) {
  .hero__grid {
    grid-template-columns: 1fr;
  }

  .hero__blueprint {
    order: -1;
    max-width: 420px;
    margin-top: 0;
  }

  .project-card--featured {
    grid-template-columns: 1fr;
    padding-block: var(--space-4);
  }

  .contact__form-row {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 901px) {
  .contact__layout {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 640px) {
  .site-header__logo img {
    height: 32px;
  }

  .hero {
    padding-block: 64px 80px;
  }

  .hero__cta {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  .hero__cta .btn {
    width: 100%;
  }

  .section {
    padding-block: 64px;
  }

  .about__rail {
    flex-direction: row;
  }

  .about__spine {
    flex-direction: column;
    gap: var(--space-2);
  }

  .contact__actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  .contact__actions .btn {
    width: 100%;
  }

  .contact__meta {
    flex-direction: column;
    gap: var(--space-1);
  }
}

/* ==========================================================================
   PREFERENZA "RIDUCI MOVIMENTO"
   Le animazioni più elaborate (ingresso hero, parallax, sequenza pinnata)
   sono già escluse del tutto per chi ha questa preferenza attiva, vedi i
   rispettivi @media (prefers-reduced-motion: no-preference) più sopra.
   Qui si occupano dei reveal-on-scroll più semplici (card progetti, "Chi
   sono" a scorrimento normale, contatti): restano, ma praticamente
   istantanei invece che animati.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  * {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
  }
}
