/* ============================================================================
   MASKAI AGENCY — DESIGN SYSTEM
   ----------------------------------------------------------------------------
   File condiviso da tutte le pagine del sito (index, servizi, portfolio,
   portfolio/*, chi-siamo, contatti, privacy, terms).

   DECISIONI (vedi DIRECTION.md + revisioni del founder, 2026-07-02):
   · Palette "Cobalto": bianchi freddi azzurrati + COBALTO #123fdd come
     UNICO accento funzionale (CTA, link, focus, label) + ink blu notte
     #0b1a2c (testo). Il verde signal #7cff9b resta SOLO come materia di
     marca (marquee, sottolineature .u-signal, accenti su fondo cobalto,
     logo). Il verde scuro è stato eliminato su richiesta del founder.
   · Font: Archivo variable (Google Fonts) — display in Expanded Bold
     (font-stretch 125%), corpo in larghezza normale.
   · Motion: easing tokens Kowalski, UI < 300ms, reveal 300–700ms,
     solo transform/opacity, prefers-reduced-motion completo.

   REGOLE D'USO RAPIDE:
   · Il verde signal (--green-signal) vive SOLO su superfici scure o come
     materia grande non testuale (blocchi, marquee, sottolineature spesse).
     MAI come testo piccolo su bianco.
   · Il cobalto (--cobalt) è l'accento funzionale su bianco:
     link, bottoni, focus, label. Niente verde scuro, mai.
   · Mai nero puro: usare --ink.
   · Il contenuto con classe .reveal è SEMPRE visibile senza JS: lo stato
     nascosto esiste solo sotto html.js (script inline nel <head>).

   INDICE:
   01 Token          02 Reset            03 Base & tipografia
   04 Layout         05 Header & nav     06 Menu mobile
   07 Bottoni        08 Form             09 Footer
   10 Marquee        11 Reveal & motion  12 Componenti di sezione
   13 Utility        14 Reduced motion   15 Tema Cobalto (nav pillola)
   16 Dettaglio (micro-interazioni)
   ========================================================================= */


/* ==========================================================================
   01 · TOKEN — custom properties
   ========================================================================= */

:root {
  /* ---- Colore (fallback hex; override OKLCH nel blocco @supports sotto) --
     Tema "Cobalto" (revisione founder): neutri freddi tintati verso il blu,
     cobalto come colore d'azione, verde signal ammorbidito. */
  --white:             #f7fbff;  /* fondo primario (bianco freddo) */
  --paper:             #edf6ff;  /* off-white azzurrato: sezioni alternate */
  --ink:               #0b1a2c;  /* blu notte: testo primario (16.5:1 su bianco) */
  --ink-soft:          #43566d;  /* testo secondario su bianco (≥ 7:1) */
  --surface-dark:      #123fdd;  /* cobalto: sezioni scure, footer, overlay menu */
  --surface-dark-2:    #0e34b7;  /* pannello rialzato su fondo cobalto */
  --line:              #d7e6f5;  /* hairline su bianco */
  --line-dark:         rgba(247, 251, 255, 0.22); /* hairline su fondo cobalto */
  --green-signal:      #7cff9b;  /* il verde riconoscibile: SOLO su scuro o come materia grande */
  --text-on-dark:      #f7fbff;  /* testo primario su cobalto (7.2:1) */
  --text-on-dark-soft: #c8d8ff;  /* testo secondario su cobalto */
  --cobalt:            #123fdd;  /* il colore nuovo: CTA, accenti, visual */
  --cobalt-deep:       #0a288f;  /* hover/active del cobalto */
  --mist:              #eaf4ff;  /* velo azzurro per superfici leggere */
  --aqua:              #d7fff0;  /* accento freddo verde-acqua (raro) */
  --red-error:         #be2323;  /* errori form (6.1:1 su bianco) */
  --overlay:           rgba(11, 26, 44, 0.55); /* unico overlay ammesso (immagini sotto testo) */

  /* ---- Tipografia ----
     Una sola famiglia (Archivo variable, asse width 62–125):
     display = Expanded (font-stretch 125%) Bold/Extrabold,
     corpo = larghezza normale. 5 taglie, ratio ≥ 1.25, clamp solo display. */
  --font-sans: 'Archivo', ui-sans-serif, 'Helvetica Neue', Helvetica, Arial, sans-serif;

  --size-caption: 0.8125rem;                             /* 13px — etichette, meta */
  --size-body:    1rem;                                  /* 16px — corpo, MAI meno */
  --size-lead:    1.25rem;                               /* 20px — sottotitoli, intro */
  --size-h3:      1.5rem;                                /* 24px — heading minori */
  --size-h2:      clamp(1.75rem, 1.35rem + 1.7vw, 2.625rem);  /* 28→42px */
  --size-display: clamp(2.5rem, 1.75rem + 3.6vw, 5.25rem);    /* 40→84px, sotto il tetto 6rem */

  --leading-display: 1.08;
  --leading-heading: 1.15;
  --leading-body:    1.6;
  --tracking-display: -0.02em;   /* mai sotto -0.04em */
  --tracking-caps:    0.08em;    /* etichette ALL-CAPS corte */

  /* ---- Spazio (scala 4pt) ---- */
  --space-2xs: 0.25rem;   /*   4px */
  --space-xs:  0.5rem;    /*   8px */
  --space-s:   0.75rem;   /*  12px */
  --space-m:   1rem;      /*  16px */
  --space-l:   1.5rem;    /*  24px */
  --space-xl:  2rem;      /*  32px */
  --space-2xl: 3rem;      /*  48px */
  --space-3xl: 4rem;      /*  64px */
  --space-4xl: 6rem;      /*  96px */
  --space-section: clamp(4rem, 5vw + 2rem, 7.5rem); /* respiro verticale tra sezioni */

  /* ---- Geometria ---- */
  --radius-s:  8px;      /* bottoni, input */
  --radius-m:  14px;     /* pannelli, media */
  --radius-l:  22px;     /* superfici grandi */
  --container: 72rem;    /* 1152px */
  --container-narrow: 46rem; /* prosa lunga */
  --header-h: 4.5rem;    /* 72px */
  --gutter: clamp(1.25rem, 4vw, 2.5rem);

  /* ---- Motion (charter Kowalski) ---- */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);   /* enter/exit, default UI */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);  /* movimento/morphing on-screen */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);   /* pannelli, menu mobile */
  --dur-press:   140ms;   /* feedback :active */
  --dur-fast:    200ms;   /* dropdown, hover strutturali */
  --dur-drawer:  420ms;   /* menu mobile, pannelli */
  --dur-reveal:  600ms;   /* reveal on-scroll, hero */

  /* ---- Z-index semantico (mai 999/9999) ---- */
  --z-dropdown: 100;
  --z-sticky:   200;   /* header */
  --z-backdrop: 300;
  --z-modal:    400;   /* menu mobile fullscreen */
  --z-toast:    500;
  --z-tooltip:  600;
}

/* Override percettivi per i browser che supportano OKLCH */
@supports (color: oklch(50% 0.1 150)) {
  :root {
    --white:             oklch(0.985 0.012 245);
    --paper:             oklch(0.955 0.025 238);
    --ink:               oklch(0.22 0.05 253);
    --ink-soft:          oklch(0.43 0.045 250);
    --surface-dark:      oklch(0.43 0.23 263);
    --surface-dark-2:    oklch(0.35 0.2 263);
    --line:              oklch(0.9 0.025 235);
    --line-dark:         oklch(0.72 0.08 250 / 0.34);
    --green-signal:      oklch(0.89 0.2 148);
    --text-on-dark:      oklch(0.985 0.012 245);
    --text-on-dark-soft: oklch(0.84 0.05 252);
    --cobalt:            oklch(0.43 0.23 263);
    --red-error:         oklch(0.52 0.19 27);
  }
}


/* ==========================================================================
   02 · RESET moderno
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* le ancore (#audit) non finiscono sotto l'header sticky */
  scroll-padding-top: calc(var(--header-h) + 1rem);
  /* Sfondo root VERDE: quando si tira la pagina oltre il bordo (overscroll
     rubber-band di macOS/iOS) si rivela questo, non più il bianco. Il body
     (bg bianco) copre comunque tutta la pagina; il verde si vede solo nel
     rimbalzo in cima. Copre la banda bianca "quando scrolli e porti giù
     il contenuto". */
  background-color: var(--green-signal);
}

body {
  min-height: 100svh;
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }

input, button, textarea, select { font: inherit; color: inherit; }

p, h1, h2, h3, h4 { overflow-wrap: break-word; }

button { background: none; border: none; padding: 0; cursor: pointer; }

ul[class], ol[class] { list-style: none; padding: 0; }

:target { scroll-margin-block: calc(var(--header-h) + 1rem); }


/* ==========================================================================
   03 · BASE & TIPOGRAFIA
   ========================================================================= */

body {
  font-family: var(--font-sans);
  font-size: var(--size-body);
  color: var(--ink);
  background: var(--white);
}

/* La fluid simulation (js/fluid.js) è confinata alla hero-section: il canvas
   è figlio del contenitore .fluid-host (il hero, o la sezione di testa di
   ogni pagina), non del body. z:-1 come strato di sfondo del host, sopra
   il fondo del host ma sotto i suoi contenuti. Mai su testi o card.
   La griglia grigia di fondo (come nel hero index) è qui, così su TUTTE le
   pagine la sezione di testa ha griglia + fluido. Su index il selettore
   .hero (inline, caricato dopo) sovrascrive con il suo sfondo. */
.fluid-host {
  position: relative;
  overflow: hidden;
  /* isolation: crea un contesto di impilamento così il canvas z:-1 dipinge
     SOPRA lo sfondo-griglia del host (e non dietro). Senza questo il fluido
     finisce sotto la griglia e non si vede. */
  isolation: isolate;
  background:
    linear-gradient(to right, rgba(11, 26, 44, 0.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(11, 26, 44, 0.055) 1px, transparent 1px),
    linear-gradient(180deg, var(--white), var(--mist));
  background-size: 54px 54px, 54px 54px, 100% 100%;
}
/* Pagine interne: la sezione di testa parte da SOTTO l'header trasparente,
   così la griglia comincia dal top (niente striscia bianca). La home (.hero)
   gestisce già il proprio pull-up. */
.fluid-host:not(.hero) {
  margin-top: calc(-1 * var(--header-h));
  padding-top: calc(var(--header-h) + var(--space-section));
}
.fluid-host > .fluid-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
}

::selection { background: var(--green-signal); color: var(--ink); }

/* Focus ring globale: mai outline:none senza sostituto */
:focus-visible {
  outline: 2px solid var(--cobalt);
  outline-offset: 2px;
  border-radius: 2px;
}
.on-dark :focus-visible,
[data-theme="dark"] :focus-visible { outline-color: var(--green-signal); }

h1, h2, h3, h4 {
  font-weight: 700;
  line-height: var(--leading-heading);
  text-wrap: balance;
}

/* Display: Archivo Expanded — la voce da manifesto. Usare su h1 e titoli di sezione chiave. */
.display,
h1 {
  font-size: var(--size-display);
  font-stretch: 125%;
  font-weight: 750;
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
}

h2, .h2 {
  font-size: var(--size-h2);
  font-stretch: 118%;
  font-weight: 720;
  letter-spacing: -0.015em;
}

h3, .h3 { font-size: var(--size-h3); font-stretch: 110%; font-weight: 680; }

.lead {
  font-size: var(--size-lead);
  line-height: 1.5;
  color: var(--ink-soft);
  text-wrap: pretty;
  max-width: 34em;
}

/* Etichetta corta ALL-CAPS — usarla con parsimonia, MAI su ogni sezione */
.label {
  font-size: var(--size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--cobalt);
}
.on-dark .label { color: var(--green-signal); }

/* Prosa lunga (privacy, terms, casi studio) */
.prose { max-width: var(--container-narrow); }
.prose p, .prose li { max-width: 65ch; text-wrap: pretty; }
.prose p + p { margin-top: var(--space-m); }
.prose h2 { margin-top: var(--space-2xl); margin-bottom: var(--space-m); }
.prose h3 { margin-top: var(--space-xl); margin-bottom: var(--space-s); }
.prose ul, .prose ol { margin: var(--space-m) 0; padding-left: 1.25em; }
.prose li + li { margin-top: var(--space-xs); }

/* Link nel testo */
a { color: inherit; }
.link,
.prose a {
  color: var(--cobalt);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--dur-fast) ease, text-decoration-color var(--dur-fast) ease;
}
.link:hover, .prose a:hover { color: var(--cobalt-deep); text-decoration-thickness: 2px; }
.on-dark .link { color: var(--green-signal); }
.on-dark .link:hover { color: var(--text-on-dark); }

/* Numeri che cambiano (se mai serviranno) */
.tabular { font-variant-numeric: tabular-nums; }


/* ==========================================================================
   04 · LAYOUT
   ========================================================================= */

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

/* Sezione standard: respiro verticale fluido */
.section { padding-block: var(--space-section); }

/* Sezione a piena altezza (portfolio, hero) — mai height:100vh secco */
.section-full {
  min-height: 100vh;   /* fallback */
  min-height: 100dvh;
  display: grid;
  align-content: center;
  padding-block: var(--space-3xl);
}

/* ————— Hero di pagina (pagine interne) —————
   Stessa ALTEZZA su tutte le pagine: mostra SOLO il titolo della pagina.
   È la prima <section> di <main>, quindi diventa il .fluid-host (griglia +
   fluido + pull-up sotto l'header glassati li fornisce già §fluid-host).
   Il titolo è ancorato in basso, con la griglia/fluido che respirano sopra. */
.page-hero {
  display: grid;
  align-content: end;
  min-height: 48vh;   /* fallback */
  min-height: 48dvh;
  padding-bottom: var(--space-2xl);
}
/* Titolo e frase CENTRATI (portfolio, servizi, chi siamo, contatti).
   Centrando si risolve anche il disallineamento ottico che si vedeva a
   bandiera: il riquadro dei due elementi combaciava, ma l'inchiostro della
   lettera grande parte più a destra (ogni glifo ha un margine interno che
   cresce con il corpo), e il titolo sembrava rientrato rispetto alla frase. */
.page-hero .container {
  display: grid;
  gap: var(--space-m);
  justify-items: center;
  text-align: center;
}
.page-hero__title {
  font-size: clamp(3rem, 1.5rem + 7vw, 6.5rem);
  line-height: 0.98;
  letter-spacing: var(--tracking-display);
}
/* 60rem (960px) sta dentro il container (1072px di contenuto): basta a tenere
   su UNA riga i lead brevi degli hero, senza sfondare la griglia del sito. */
.page-hero__lead { max-width: 60rem; margin-inline: auto; }

/* Superfici (opache: il fluido vive solo nel hero, non su queste sezioni) */
.on-dark {
  background: var(--surface-dark);
  color: var(--text-on-dark);
}
.on-dark .lead { color: var(--text-on-dark-soft); }
.on-paper { background: var(--paper); }

/* Split asimmetrici — collassano a colonna singola sotto 768px */
.split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2xl);
  align-items: center;
}
@media (min-width: 768px) {
  .split          { grid-template-columns: 1fr 1fr; gap: var(--space-3xl); }
  .split--wide    { grid-template-columns: 2fr 1fr; } /* contenuto pesante a sinistra */
  .split--reverse { grid-template-columns: 1fr 2fr; }
}

/* Hairline di separazione tra sezioni (alternativa al cambio di fondo) */
.rule { border: 0; border-top: 1px solid var(--line); }
.on-dark .rule { border-top-color: var(--line-dark); }

/* Skip link accessibile */
.skip-link {
  position: absolute;
  left: var(--space-m);
  top: calc(-1 * var(--space-3xl));
  z-index: var(--z-tooltip);
  padding: var(--space-s) var(--space-m);
  background: var(--ink);
  color: var(--text-on-dark);
  border-radius: var(--radius-s);
  text-decoration: none;
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus-visible { top: var(--space-m); }


/* ==========================================================================
   05 · HEADER & NAV STICKY
   --------------------------------------------------------------------------
   Uso: <header class="site-header"> con .site-nav dentro. JS aggiunge
   .is-scrolled dopo ~8px di scroll. Trasparente sopra il hero,
   bianco + hairline quando scrolla. Pagina corrente: aria-current="page".
   ========================================================================= */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  height: var(--header-h);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.site-header.is-scrolled {
  background: var(--white);
  border-bottom-color: var(--line);
}

.site-nav {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-l);
}

.site-nav__logo { display: inline-flex; align-items: center; }
.site-nav__logo img { height: 1.75rem; width: auto; }

.site-nav__links {
  display: none;
  align-items: center;
  gap: var(--space-xl);
}
@media (min-width: 900px) {
  .site-nav__links { display: flex; }
}

.site-nav__link {
  position: relative;
  font-size: 0.9375rem;
  font-weight: 550;
  text-decoration: none;
  color: var(--ink);
  padding-block: var(--space-xs); /* touch target */
  transition: color var(--dur-fast) ease;
}
.site-nav__link:hover { color: var(--cobalt); }
/* Pagina corrente: tratto pieno sotto la voce */
.site-nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--cobalt);
}

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

/* Hamburger — visibile solo sotto i 900px */
.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  align-items: center;
  border-radius: var(--radius-s);
}
@media (min-width: 900px) { .nav-toggle { display: none; } }

.nav-toggle__bar {
  display: block;
  width: 22px;
  height: 2px;
  background: currentColor;
  transition: transform var(--dur-fast) var(--ease-in-out), opacity var(--dur-fast) ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }


/* ==========================================================================
   06 · MENU MOBILE FULLSCREEN
   --------------------------------------------------------------------------
   Uso: <div class="nav-overlay" id="nav-overlay" hidden> subito dopo
   l'header. JS toglie/mette [hidden] via .is-open + gestisce inert.
   Fondo Abete ink, voci grandi in Expanded, stagger 50ms.
   ========================================================================= */

.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: var(--surface-dark);
  color: var(--text-on-dark);
  display: grid;
  align-content: center;
  padding: var(--gutter);
  /* entra dall'alto con la curva drawer */
  transform: translateY(-100%);
  visibility: hidden;
  transition:
    transform var(--dur-drawer) var(--ease-drawer),
    visibility 0s linear var(--dur-drawer);
}
.nav-overlay.is-open {
  transform: translateY(0);
  visibility: visible;
  transition:
    transform var(--dur-drawer) var(--ease-drawer),
    visibility 0s;
}

.nav-overlay__links { display: grid; gap: var(--space-l); }

.nav-overlay__link {
  font-size: clamp(1.75rem, 7vw, 2.5rem);
  font-stretch: 120%;
  font-weight: 720;
  letter-spacing: -0.015em;
  text-decoration: none;
  color: var(--text-on-dark);
  transition: color var(--dur-fast) ease;
}
.nav-overlay__link:hover,
.nav-overlay__link[aria-current="page"] { color: var(--green-signal); }

/* Stagger delle voci quando il menu si apre */
.nav-overlay__links > * {
  opacity: 0;
  transform: translateY(12px);
}
.nav-overlay.is-open .nav-overlay__links > * {
  opacity: 1;
  transform: none;
  transition:
    opacity 320ms var(--ease-out),
    transform 320ms var(--ease-out);
  transition-delay: calc(120ms + var(--i, 0) * 50ms);
}
.nav-overlay__links > :nth-child(1) { --i: 0; }
.nav-overlay__links > :nth-child(2) { --i: 1; }
.nav-overlay__links > :nth-child(3) { --i: 2; }
.nav-overlay__links > :nth-child(4) { --i: 3; }
.nav-overlay__links > :nth-child(5) { --i: 4; }
.nav-overlay__links > :nth-child(6) { --i: 5; }

.nav-overlay__footer {
  margin-top: var(--space-2xl);
  display: grid;
  gap: var(--space-xs);
  color: var(--text-on-dark-soft);
  font-size: 0.9375rem;
}

/* Blocca lo scroll del body quando il menu è aperto (JS su <html>) */
.menu-open { overflow: hidden; }


/* ==========================================================================
   07 · BOTTONI
   --------------------------------------------------------------------------
   .btn-primary  → verde ink pieno, testo bianco (su fondi chiari)
   .btn-signal   → verde neon pieno, testo ink (SOLO su superfici scure)
   .btn-secondary→ hairline, trasparente
   Tutti: :active scale(0.97), focus-visible, touch ≥ 44px.
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  min-height: 48px;
  padding: 0.75rem 1.5rem;
  border-radius: var(--radius-s);
  font-size: 1rem;
  font-weight: 620;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition:
    transform var(--dur-press) var(--ease-out),
    background-color var(--dur-fast) ease,
    border-color var(--dur-fast) ease,
    color var(--dur-fast) ease;
}
.btn:active { transform: scale(0.97); }

.btn-primary { background: var(--cobalt); color: var(--text-on-dark); }
.btn-primary:hover { background: var(--cobalt-deep); }

/* SOLO su .on-dark: il neon canta sull'Abete (11.8:1) */
.btn-signal { background: var(--green-signal); color: var(--ink); }
.btn-signal:hover { background: var(--text-on-dark); }

.btn-secondary {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink);
}
.btn-secondary:hover { border-color: var(--cobalt); color: var(--cobalt); }
.on-dark .btn-secondary { border-color: var(--line-dark); color: var(--text-on-dark); }
.on-dark .btn-secondary:hover { border-color: var(--green-signal); color: var(--green-signal); }

/* Variante compatta per la navbar */
.btn--nav { min-height: 40px; padding: 0.5rem 1.125rem; font-size: 0.9375rem; }

/* Freccia dentro i bottoni/link: micro-slide solo con mouse vero */
.btn svg, .arrow-link svg { flex: none; }
@media (hover: hover) and (pointer: fine) {
  .btn svg, .arrow-link svg { transition: transform var(--dur-fast) var(--ease-out); }
  .btn:hover svg, .arrow-link:hover svg { transform: translateX(3px); }
}

/* Link-freccia (rimandi a pagine interne, casi studio) */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-weight: 620;
  color: var(--cobalt);
  text-decoration: none;
  padding-block: var(--space-xs);
}
.arrow-link:hover { color: var(--cobalt-deep); }
.on-dark .arrow-link { color: var(--green-signal); }


/* ==========================================================================
   08 · FORM
   --------------------------------------------------------------------------
   Struttura: <div class="field"><label for=…>…</label>
   <input class="input"…><p class="field-error" id="…-error" hidden>…</p></div>
   JS aggiunge .has-error al .field e toglie [hidden] al messaggio.
   Stato successo: blocco .form-success (hidden di default), entra con
   @starting-style quando JS lo mostra.
   ========================================================================= */

.field { display: grid; gap: var(--space-2xs); text-align: left; }

.field > label {
  font-size: 0.9375rem;
  font-weight: 600;
}

.input {
  width: 100%;
  min-height: 48px;
  padding: 0.75rem 1rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  color: var(--ink);
  transition: border-color var(--dur-fast) ease, background-color var(--dur-fast) ease;
}
textarea.input { min-height: 8rem; resize: vertical; }

.input::placeholder { color: var(--ink-soft); } /* ≥ 4.5:1 anche il placeholder */

.input:hover { border-color: var(--ink-soft); }
.input:focus-visible {
  outline: 2px solid var(--cobalt);
  outline-offset: 0;
  border-color: var(--cobalt);
}

/* Form dentro sezioni scure (es. audit nel hero scuro) */
.on-dark .input {
  background: var(--surface-dark-2);
  border-color: var(--line-dark);
  color: var(--text-on-dark);
}
.on-dark .input::placeholder { color: var(--text-on-dark-soft); }
.on-dark .input:focus-visible { outline-color: var(--green-signal); border-color: var(--green-signal); }

/* Errore inline */
.field.has-error .input { border-color: var(--red-error); }
.field-error {
  font-size: var(--size-caption);
  font-weight: 550;
  color: var(--red-error);
}
.on-dark .field-error { color: #ff8d7a; } /* rosso leggibile su Abete */

/* Bottone in stato loading (JS: .is-loading + disabled) */
.btn.is-loading { opacity: 0.7; pointer-events: none; }
.btn.is-loading .btn__spinner { display: inline-block; }
.btn__spinner {
  display: none;
  width: 1em; height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Stato di successo — progettato, non un alert.
   Entra con @starting-style quando JS toglie [hidden]. */
.form-success {
  display: grid;
  gap: var(--space-s);
  padding: var(--space-xl);
  border: 1px solid var(--cobalt);
  border-radius: var(--radius-m);
  background: var(--white);
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
  @starting-style { opacity: 0; transform: translateY(12px); }
}
.form-success[hidden] { display: none; }
.on-dark .form-success {
  background: var(--surface-dark-2);
  border-color: var(--green-signal);
}
.form-success__title {
  font-size: var(--size-h3);
  font-stretch: 112%;
  font-weight: 700;
}

/* Riga URL+email+bottone del form audit: colonna su mobile */
.audit-form { display: grid; gap: var(--space-m); }
@media (min-width: 768px) {
  .audit-form__row {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: var(--space-m);
    align-items: start;
  }
}
.audit-form__note { font-size: var(--size-caption); color: var(--ink-soft); }
.on-dark .audit-form__note { color: var(--text-on-dark-soft); }

/* Honeypot anti-spam: nascosto a tutti tranne i bot */
.hp-field {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ==========================================================================
   09 · FOOTER
   --------------------------------------------------------------------------
   Uguale su tutte le pagine: superficie Abete, wordmark, nav, contatti,
   riga legale. Vedi TEMPLATE.html per il markup.
   ========================================================================= */

.site-footer {
  background: var(--surface-dark);
  color: var(--text-on-dark);
  padding-block: var(--space-3xl) var(--space-xl);
}

.site-footer__grid {
  display: grid;
  gap: var(--space-2xl);
  grid-template-columns: 1fr;
}
@media (min-width: 768px) {
  .site-footer__grid { grid-template-columns: 2fr 1fr 1fr; }
}

/* Marchio "M" verde in cima al footer */
.site-footer__mark {
  width: auto;
  height: 2.75rem;
  margin-bottom: var(--space-s);
}

.site-footer__claim {
  font-size: var(--size-h3);
  font-stretch: 115%;
  font-weight: 700;
  line-height: 1.25;
  max-width: 18em;
  text-wrap: balance;
}

.site-footer__heading {
  font-size: var(--size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--green-signal);
  margin-bottom: var(--space-m);
}

.site-footer__list { display: grid; gap: var(--space-xs); }
.site-footer__list a {
  color: var(--text-on-dark-soft);
  text-decoration: none;
  transition: color var(--dur-fast) ease;
  padding-block: 2px;
}
.site-footer__list a:hover { color: var(--green-signal); }

.site-footer__legal {
  margin-top: var(--space-2xl);
  padding-top: var(--space-l);
  border-top: 1px solid var(--line-dark);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  justify-content: space-between;
  font-size: var(--size-caption);
  color: var(--text-on-dark-soft);
}
.site-footer__legal a { color: inherit; text-decoration: none; }
.site-footer__legal a:hover { color: var(--green-signal); }


/* ==========================================================================
   10 · MARQUEE
   --------------------------------------------------------------------------
   Nastro cinetico: UN punto solo per pagina, moto linear costante.
   Markup: <div class="marquee" aria-hidden="true">
             <div class="marquee__track"> …contenuto… …contenuto duplicato… </div>
           </div>
   Il contenuto va duplicato una volta nel markup (loop al 50%).
   Variante .marquee--signal: nastro verde neon con testo ink (materia
   grande non testuale ammessa su chiaro).
   ========================================================================= */

.marquee {
  overflow: hidden;
  padding-block: var(--space-m);
  border-block: 1px solid var(--line);
}
.on-dark .marquee, .marquee--dark { border-color: var(--line-dark); }

.marquee--signal {
  background: var(--green-signal);
  color: var(--ink);
  border-block: none;
}

.marquee__track {
  display: flex;
  gap: var(--space-2xl);
  width: max-content;
  animation: marquee-scroll var(--marquee-speed, 36s) linear infinite;
}
.marquee__track > * { flex: none; }

@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - var(--space-2xl) / 2)); }
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xl);
  font-size: var(--size-lead);
  font-stretch: 118%;
  font-weight: 680;
  white-space: nowrap;
}


/* ==========================================================================
   11 · REVEAL & MOTION ON-SCROLL
   --------------------------------------------------------------------------
   REGOLA: senza JS tutto è visibile. Lo stato nascosto esiste solo sotto
   html.js (classe messa dallo script inline nel <head> — vedi TEMPLATE).
   JS (IntersectionObserver, once, rootMargin -80px) aggiunge .is-visible.

   Varianti — scegliere per contenuto, NON applicare la stessa ovunque:
   .reveal          → fade + translateY (testo, blocchi)
   .reveal--clip    → svelamento clip-path dal basso (immagini, media)
   .reveal--fade    → solo opacity (elementi che devono restare fermi)
   .stagger         → i figli entrano in cascata (50ms)
   Delay opzionale: style="--reveal-delay: 120ms"
   ========================================================================= */

.js .reveal {
  opacity: 0;
  transform: translateY(16px);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--dur-reveal) var(--ease-out) var(--reveal-delay, 0ms),
    transform var(--dur-reveal) var(--ease-out) var(--reveal-delay, 0ms);
}

.js .reveal--fade { transform: none; }

.js .reveal--clip {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 100% 0);
}
.js .reveal--clip.is-visible {
  clip-path: inset(0);
  transition: clip-path 700ms var(--ease-in-out) var(--reveal-delay, 0ms);
}

/* ————— VELO per i media grandi (foto e video dei casi studio) —————
   Un velo del colore della pagina copre la cornice e scorre via verso il
   basso: il media si scopre dall'alto, nel verso in cui si legge. Sotto,
   il media rientra da una scala appena maggiore, così l'entrata ha profondità.
   Solo opacity/transform: la GPU compone e resta fluido anche a piena
   larghezza, mentre `reveal--clip` ridisegna ogni fotogramma e scatta.
   Il velo sta DENTRO la cornice (overflow: hidden), quindi non invade mai
   la didascalia sotto: la cornice non si sposta di un pixel. */
.cs-frame {
  position: relative;
  border-radius: var(--radius-m);
  border: 1px solid var(--line);
  overflow: hidden;
}
.cs-frame > .cs-media { border: 0; border-radius: 0; }

.js .reveal .cs-frame::after {
  content: "";
  position: absolute;
  inset: -1px;                 /* copre anche il bordo della cornice */
  z-index: 2;
  background: var(--white);
  transform: translateY(0);
  transition: transform 900ms var(--ease-in-out) var(--reveal-delay, 0ms);
}
.js .reveal.is-visible .cs-frame::after { transform: translateY(101%); }

.js .reveal .cs-frame > .cs-media {
  transform: scale(1.06);
  transition: transform 1200ms var(--ease-out) var(--reveal-delay, 0ms);
}
.js .reveal.is-visible .cs-frame > .cs-media { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js .reveal .cs-frame::after { display: none; }
  .js .reveal .cs-frame > .cs-media { transform: none; }
}

/* Cascata: i figli diretti entrano a 50ms l'uno dall'altro (max 8) */
.js .stagger > * { opacity: 0; transform: translateY(10px); }
.js .stagger.is-visible > * {
  opacity: 1;
  transform: none;
  transition:
    opacity 400ms var(--ease-out),
    transform 400ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 50ms);
}
.js .stagger > :nth-child(1) { --i: 0; }
.js .stagger > :nth-child(2) { --i: 1; }
.js .stagger > :nth-child(3) { --i: 2; }
.js .stagger > :nth-child(4) { --i: 3; }
.js .stagger > :nth-child(5) { --i: 4; }
.js .stagger > :nth-child(6) { --i: 5; }
.js .stagger > :nth-child(7) { --i: 6; }
.js .stagger > :nth-child(8) { --i: 7; }


/* ==========================================================================
   12 · COMPONENTI DI SEZIONE
   ========================================================================= */

/* Pannello su fondo chiaro: hairline pieno, MAI side-stripe colorato */
.panel {
  padding: var(--space-xl);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--white);
}
.on-dark .panel, .panel--dark {
  background: var(--surface-dark-2);
  border-color: var(--line-dark);
}

/* Media frame: immagini di progetto con proporzione stabile (no CLS) */
.media {
  border-radius: var(--radius-m);
  overflow: hidden;
  background: var(--paper);
}
.media > img { width: 100%; height: 100%; object-fit: cover; }

/* Sottolineatura spessa in verde signal — la firma tipografica del brand.
   Materia grande non testuale: ammessa anche su bianco. */
.u-signal {
  background-image: linear-gradient(var(--green-signal), var(--green-signal));
  background-repeat: no-repeat;
  background-size: 100% 0.18em;
  background-position: 0 92%;
  padding-bottom: 0.04em;
}

/* Lista di definizione orizzontale (fatti, contatti, dettagli progetto) */
.fact-list { display: grid; gap: var(--space-m); }
.fact-list > div {
  display: grid;
  gap: var(--space-2xs);
  padding-bottom: var(--space-m);
  border-bottom: 1px solid var(--line);
}
.on-dark .fact-list > div { border-bottom-color: var(--line-dark); }
.fact-list dt {
  font-size: var(--size-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--ink-soft);
}
.on-dark .fact-list dt { color: var(--text-on-dark-soft); }
.fact-list dd { margin: 0; font-weight: 550; }

/* Voce di elenco grande con hairline (servizi, settori, casi studio):
   alternativa strutturale alla card-grid. Tutta la riga è cliccabile
   se contiene un <a> con .row-item__link (pseudo-elemento esteso). */
.row-item {
  position: relative;
  display: grid;
  gap: var(--space-s);
  padding-block: var(--space-l);
  border-top: 1px solid var(--line);
  transition: background-color var(--dur-fast) ease;
}
.row-item:last-child { border-bottom: 1px solid var(--line); }
@media (min-width: 768px) {
  .row-item { grid-template-columns: 2fr 3fr auto; align-items: baseline; gap: var(--space-xl); }
}
.on-dark .row-item { border-color: var(--line-dark); }
@media (hover: hover) and (pointer: fine) {
  .row-item:hover { background-color: var(--paper); }
  .on-dark .row-item:hover { background-color: var(--surface-dark-2); }
}
.row-item__title { font-size: var(--size-h3); font-stretch: 112%; font-weight: 700; }
.row-item__link { text-decoration: none; color: inherit; }
.row-item__link::after { content: ""; position: absolute; inset: 0; }


/* ==========================================================================
   13 · UTILITY
   ========================================================================= */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.text-soft { color: var(--ink-soft); }
.on-dark .text-soft { color: var(--text-on-dark-soft); }

.stack-s  > * + * { margin-top: var(--space-s); }
.stack-m  > * + * { margin-top: var(--space-m); }
.stack-l  > * + * { margin-top: var(--space-l); }
.stack-xl > * + * { margin-top: var(--space-xl); }

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: center;
}

[hidden] { display: none !important; }


/* ==========================================================================
   14 · PREFERS-REDUCED-MOTION
   --------------------------------------------------------------------------
   Ridotto ≠ zero: si toglie il movimento, restano i crossfade utili.
   ========================================================================= */

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

  /* Versione curata: opacity sì, translate/clip no */
  .js .reveal,
  .js .stagger > *,
  .nav-overlay__links > * { transform: none; }
  .js .reveal--clip { clip-path: none; }
  .nav-overlay { transform: none; opacity: 0; }
  .nav-overlay.is-open { opacity: 1; }

  .marquee__track { animation: none; flex-wrap: wrap; width: auto; }

  /* Rete di sicurezza */
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}


/* ==========================================================================
   15 · TEMA COBALTO — componenti condivisi (revisione founder 2026-07-02)
   --------------------------------------------------------------------------
   Nati sulla homepage, valgono per TUTTE le pagine: navbar a pillola di
   vetro, bottone cobalto, cornice per immagini generate, freccia delle
   righe di settore, composizioni tipografiche.
   Le regole qui sotto vincono sulla sezione 05 per ordine di sorgente.
   ========================================================================= */

/* --- Navbar flottante a pillola di vetro --- */
.site-header {
  top: clamp(0.5rem, 1.4vw, 1rem);
  height: auto;
  padding-block: var(--space-xs);
  background: transparent;
  border-bottom: 0;
}
.site-header:not(.is-scrolled),
.site-header.is-scrolled {
  background: transparent;
  border-bottom: 0;
  backdrop-filter: none;
}
.site-header .container { max-width: min(78rem, calc(100% - 1rem)); }
/* Vetro pulito (glass-card): base translucida + linee di luce sui bordi.
   La navbar galleggia anche su sezioni scure, quindi tiene abbastanza
   bianco perché le voci restino leggibili ovunque. */
.site-nav {
  position: relative;
  min-height: 58px;
  padding: 0.45rem 0.5rem 0.45rem 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  background: rgba(247, 251, 255, 0.55);
  box-shadow:
    0 8px 32px rgba(11, 26, 44, 0.12),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    inset 0 -1px 0 rgba(255, 255, 255, 0.15),
    inset 0 0 28px 8px rgba(255, 255, 255, 0.35);
  backdrop-filter: blur(23px) saturate(160%);
  -webkit-backdrop-filter: blur(23px) saturate(160%);
  overflow: hidden;
  isolation: isolate;
}
/* Linea di luce in alto (bordo superiore illuminato) */
.site-nav::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.85), transparent);
}
/* Filo di luce sul bordo sinistro */
.site-nav::after {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 1px; height: 100%;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,0.8), transparent, rgba(255,255,255,0.3));
}
/* Sopra sezioni scure: un filo più di bianco per non perdere le voci */
.site-header.is-scrolled .site-nav { background: rgba(247, 251, 255, 0.66); }
.site-nav__logo {
  min-width: 8.5rem;
  padding-inline: 0.15rem;
}
.site-nav__links {
  gap: clamp(1rem, 2vw, 1.7rem);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}
.site-nav__link {
  padding: 0.5rem 0;
  border-radius: 0;
  font-size: 0.875rem;
  font-weight: 650;
  color: var(--ink-soft);
}
.site-nav__link::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.2rem;
  height: 2px;
  background: var(--green-signal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-fast) var(--ease-out);
}
.site-nav__link:hover {
  color: var(--cobalt);
}
.site-nav__link:hover::before { transform: scaleX(1); }
.site-nav__link[aria-current="page"]::after { display: none; }
.site-nav__link[aria-current="page"] { color: var(--cobalt); }
.site-nav__link[aria-current="page"]::before { transform: scaleX(1); }
.site-nav__actions { gap: var(--space-xs); }
.site-nav .btn--nav {
  min-height: 42px;
  padding-inline: 1.1rem;
  border-radius: 999px;
  background: var(--cobalt);
  color: var(--text-on-dark);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.18);
}
.site-nav .btn--nav:hover { background: var(--cobalt-deep); }
.nav-toggle {
  border-radius: var(--radius-s);
  background: transparent;     /* niente cerchio azzurro: solo le barre */
  color: var(--ink);           /* barre scure, leggibili sul vetro */
}
@media (hover: hover) and (pointer: fine) {
  .nav-toggle:hover { color: var(--cobalt); }
}
@media (max-width: 899px) {
  .site-nav__logo { min-width: 0; }
  .site-nav .btn--nav { display: none; }
  .site-nav { padding-left: 0.85rem; }
  /* Header a filo col contenuto (niente doppio inset che lo faceva più
     stretto della griglia): il pill usa lo stesso gutter delle sezioni,
     anzi un filo più largo. */
  .site-header .container { max-width: none; padding-inline: var(--space-m); }
}

/* --- Bottone cobalto: l'azione primaria del tema --- */
.btn-cobalt { background: var(--cobalt); color: var(--text-on-dark); }
.btn-cobalt:hover { background: var(--cobalt-deep); }

/* --- Freccia nelle righe di settore/elenco --- */
.row-item__arrow {
  color: var(--cobalt);
  justify-self: start;
}
@media (min-width: 768px) {
  .row-item__arrow { justify-self: end; align-self: center; }
}

/* --- Cornice per immagini generate/di progetto --- */
.generated-image {
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  overflow: hidden;
  background: var(--paper);
  box-shadow: 0 18px 58px rgba(11, 26, 44, 0.08);
}
.generated-image img,
.generated-image svg {
  width: 100%;
  height: auto;
  display: block;
}

/* --- Composizioni tipografiche dentro .media (niente foto finte) --- */
.media > svg { width: 100%; height: auto; }
.sv-display {
  font-family: var(--font-sans);
  font-stretch: 125%;
  font-weight: 750;
  letter-spacing: -0.02em;
}
.sv-caption {
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: 0.02em;
}


/* ==========================================================================
   16 · DETTAGLIO — micro-interazioni e rifiniture (passata di qualità)
   --------------------------------------------------------------------------
   Ogni regola ha un motivo dichiarato (gerarchia, feedback, o continuità).
   Tutto solo transform/opacity/box-shadow; hover gate-ato su puntatori
   veri; la rete di sicurezza reduced-motion (§14) copre anche questo.
   ========================================================================= */

/* Feedback: la barra di scorrimento non sposta il layout tra pagine */
html { scrollbar-gutter: stable; }

/* Continuità: scrollbar discreta nel colore del tema (dove supportata) */
@supports (scrollbar-width: thin) {
  html {
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--cobalt) 30%, var(--line)) transparent;
  }
}

/* Feedback: i bottoni rispondono al passaggio con un sollevamento sottile
   e un'ombra tinta del proprio colore (mai ombra nera pura). */
.btn {
  transition:
    transform var(--dur-press) var(--ease-out),
    background-color var(--dur-fast) ease,
    border-color var(--dur-fast) ease,
    color var(--dur-fast) ease,
    box-shadow var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: translateY(-1px); }
  .btn:active { transform: translateY(0) scale(0.97); }
  .btn-primary:hover,
  .btn-cobalt:hover,
  .site-nav .btn--nav:hover { box-shadow: 0 12px 28px -12px rgba(18, 63, 221, 0.5); }
  .btn-signal:hover { box-shadow: 0 12px 28px -12px rgba(11, 26, 44, 0.35); }
  .btn-secondary:hover { box-shadow: 0 10px 24px -14px rgba(11, 26, 44, 0.25); }
}

/* Gerarchia: le immagini incorniciate respirano al passaggio (zoom lento,
   la cornice resta ferma). Solo con mouse vero. */
.generated-image img,
.media > img { transition: transform 900ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .generated-image:hover img,
  .media:hover > img,
  a:hover .media > img { transform: scale(1.03); }
}

/* Feedback: nelle righe-elenco il titolo si accende di cobalto e la
   freccia scivola verso la destinazione. */
.row-item__title { transition: color var(--dur-fast) ease; }
.row-item__arrow { transition: transform var(--dur-fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .row-item:hover .row-item__title { color: var(--cobalt); }
  .row-item:hover .row-item__arrow { transform: translateX(4px); }
}

/* Feedback: il nastro si ferma sotto il puntatore (si può leggere) */
@media (hover: hover) {
  .marquee:hover .marquee__track { animation-play-state: paused; }
}

/* Feedback: i link del footer scivolano di un soffio */
.site-footer__list a { display: inline-block; transition: color var(--dur-fast) ease, transform var(--dur-fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .site-footer__list a:hover { transform: translateX(3px); }
}
