/* Token palette Cobalto, navbar a pillola e componenti condivisi:
       spostati in css/style.css (§01 token, §15 tema Cobalto) perché
       valgono per tutte le pagine. Qui resta solo lo stile della homepage. */

    /* Hero: tipografia cinetica (rif. upsunday.co) su sfondo pulito.
       Le immagini vivono DENTRO il flusso del titolo come chip arrotondate,
       una freccia si disegna da sola, le parole entrano in cascata.
       L'audit resta lo strumento centrale, un gradino sotto il titolo. */
    /* Griglia grigia leggera come fondo del hero: il design "sta su una
       griglia". La fluid simulation (canvas .fluid-canvas, z:-1) scorre
       SOPRA la griglia e SOTTO il contenuto. */
    .hero {
      display: grid;
      align-content: center;
      min-height: 100vh;  /* fallback */
      min-height: 100dvh;
      margin-top: calc(-1 * var(--header-h));
      padding-block: calc(var(--header-h) + clamp(2rem, 4vw, 3rem)) clamp(2.5rem, 5vw, 4.5rem);
      position: relative;
      overflow: hidden;
      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%;
    }
    .hero__grid {
      position: relative;
      z-index: 2;
      display: grid;
      min-height: calc(100dvh - clamp(7rem, 11vw, 9rem));
      align-content: center;
      justify-items: center;
      gap: clamp(1.75rem, 3.5vw, 2.75rem);
      text-align: center;
    }
    .hero__copy {
      display: grid;
      justify-items: center;
      gap: clamp(1rem, 2vw, 1.5rem);
      max-width: 62rem;
    }
    .hero__copy .hero__firma { display: none; }

    /* Eyebrow come tag/pill su verde chiaro (niente linea) */
    .hero__eyebrow {
      display: inline-flex;
      align-items: center;
      padding: 0.42rem 0.9rem;
      border-radius: 999px;
      background: color-mix(in srgb, var(--green-signal) 30%, #ffffff);
      color: #0f6d34;
      font-size: 0.78rem;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.12em;
    }

    /* ---- HERO VIDEO → CHIP (morph) ---- */
    .hero-wrap { position: relative; }
    /* Video overlay: nascosto finché JS non attiva il morph.
       Il video è leggermente sovradimensionato (view > 100%) così i bordi
       "sbordano" e non compare mai una riga bianca ai contorni. */
    .hero-video { display: none; }
    .hero-video video {
      position: absolute;
      top: -4%;
      left: -4%;
      width: 108%;
      height: 108%;
      /* IMPORTANTE: annulla il reset globale `video { max-width: 100% }` che
         altrimenti clampa la width a 100% → il video resta 3-4% più stretto
         del box e a destra (con left negativo) resta una striscia scoperta.
         Con max-width:none la sovradimensione 108% vale davvero e il video
         sborda 4% su ogni lato, coprendo il box sotto qualsiasi piega. */
      max-width: none;
      max-height: none;
      object-fit: cover;
      border-radius: inherit;
    }
    /* (Effetti WebGL sul video rimossi il 2026-07-03: causavano fantasma e
       bordo bianco durante il morph, e distorcevano le facce. Il video ora è
       pulito, solo il morph CSS. hero-webgl.js resta per un futuro effetto
       di aberrazione cromatica pulito, ma non è caricato.) */

    /* ---- INTRO: M verde → logo navbar ----
       La M verde (m-color.svg) parte al centro orizzontale, alla STESSA
       altezza del logo dell'header, e scrollando scivola a sinistra fino a
       posarsi ESATTAMENTE sull'inizio del logo (M identica al logo intero).
       Quando il video atterra, il menu compare e la M verde svanisce cedendo
       il posto al logo vero. Altezza/posizione le imposta JS §7 ogni frame;
       qui solo visibilità e transizioni. */
    .hero-logo-m { display: none; }
    .is-video .hero-logo-m {
      display: block;
      position: fixed;
      top: 0;
      left: 0;
      height: 28px;              /* = altezza logo navbar (impostata da JS) */
      width: auto;
      z-index: 260;              /* sopra header (200), sotto menu mobile (400) */
      pointer-events: none;
      opacity: 1;
      transition: opacity 260ms var(--ease-out);
    }
    /* Atterrato: la M verde svanisce (il logo vero prende il suo posto) */
    .is-video.hero-landed .hero-logo-m { opacity: 0; }

    /* Menu (navbar) nascosto durante l'intro video; compare quando il video
       atterra. Keyato su <html> perché l'header sta FUORI da .hero-wrap. */
    html.hero-morph .site-header {
      transition: opacity 420ms var(--ease-out), background-color 0.2s, border-color 0.2s;
    }
    html.hero-morph:not(.hero-menu-in) .site-header {
      opacity: 0;
      pointer-events: none;
    }

    /* BOOT (prima che JS aggiunga is-video al .hero-wrap): in modalità morph
       il contenuto normale (titolo, form) è nascosto e l'area hero mostra il
       PRIMO FRAME del video (poster), così al reload si vede subito l'immagine
       del video e non un flash scuro/blu. Appena JS aggiunge is-video subentra
       lo stato video (che ha lo stesso poster → passaggio invisibile). */
    html.hero-morph .hero-wrap:not(.is-video) .hero {
      background: var(--ink) url("img/home-hero-poster.jpg?v=20") center / cover no-repeat;
    }
    html.hero-morph .hero-wrap:not(.is-video) .hero__grid { opacity: 0; }
    /* Sfondo del box video = stesso poster: coperto dal video appena ha il
       primo frame; finché carica mostra il primo frame, non un colore. */
    .hero-video {
      background: var(--ink) url("img/home-hero-poster.jpg?v=20") center / cover no-repeat;
    }

    /* Intro sopra il video all'avvio: un hook che ispira (il "perché"), un
       bottone, e sotto le parole-servizio che si susseguono. Svanisce man
       mano che si scrolla (opacità del contenitore impostata da JS). */
    .hero-intro {
      display: none;
      position: absolute;
      inset: 0;
      z-index: 1;               /* sopra il video, sotto il titolo */
      align-items: center;
      justify-content: center;
      pointer-events: none;
      text-align: center;
      padding-inline: 1.5rem;
    }
    .is-video .hero-intro { display: flex; }
    .hero-intro__stage {
      display: grid;
      justify-items: center;
      gap: clamp(1rem, 2.6vh, 1.9rem);
    }
    /* Hook: ispira il perché, senza dichiararlo */
    .hero-intro__why {
      color: #ffffff;
      font-size: clamp(0.95rem, 0.8rem + 0.85vw, 1.7rem);
      font-stretch: 108%;
      font-weight: 600;
      letter-spacing: -0.01em;
      line-height: 1.25;
      white-space: nowrap;      /* "Come ti vedono cambia tutto." su una riga */
      text-shadow: 0 2px 26px rgba(11, 26, 44, 0.6);
      animation: intro-rise 800ms var(--ease-out) both;
    }
    .hero-intro__why .u-signal { -webkit-box-decoration-break: clone; box-decoration-break: clone; }
    /* Bottone in vetro, sopra le parole */
    .hero-intro__cta {
      pointer-events: auto;
      display: inline-flex;
      align-items: center;
      gap: 0.5rem;
      padding: 0.72rem 1.4rem;
      border-radius: 999px;
      font-size: 0.95rem;
      font-weight: 650;
      text-decoration: none;
      color: var(--ink);
      background: rgba(255, 255, 255, 0.92);
      border: 1px solid rgba(255, 255, 255, 0.7);
      box-shadow: 0 12px 34px rgba(11, 26, 44, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.9);
      backdrop-filter: blur(6px) saturate(150%);
      -webkit-backdrop-filter: blur(6px) saturate(150%);
      animation: intro-rise 800ms var(--ease-out) 120ms both;
      transition: background-color var(--dur-fast) ease, transform var(--dur-fast) var(--ease-out);
    }
    .hero-intro__cta svg { transition: transform var(--dur-fast) var(--ease-out); }
    .hero-intro__cta:active { transform: scale(0.97); }
    @media (hover: hover) and (pointer: fine) {
      .hero-intro__cta:hover { background: #ffffff; }
      .hero-intro__cta:hover svg { transform: translateX(3px); }
    }
    @keyframes intro-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
    .hero-intro__word {
      color: #ffffff;
      font-size: clamp(1.75rem, 4.4vw, 3.4rem);
      font-stretch: 125%;
      font-weight: 750;
      text-transform: uppercase;
      letter-spacing: 0.005em;
      text-shadow: 0 2px 30px rgba(11, 26, 44, 0.5);
      opacity: 0;
      transform: translateY(0.35em);
      transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out);
    }
    .hero-intro__word.is-in { opacity: 1; transform: none; }
    /* Atterrato: l'intro (e il suo bottone) sparisce e non intercetta i click
       sul form audit che prende il suo posto. */
    .is-video.hero-landed .hero-intro { visibility: hidden; pointer-events: none; }
    /* Durante l'intro il contenitore del titolo/form (.hero__grid, z-index 2)
       è invisibile ma STA SOPRA il bottone intro (z-index 1) e ne rubava i
       click: lo rendiamo trasparente ai click finché non atterra. */
    .is-video:not(.hero-landed) .hero__grid { pointer-events: none; }
    .is-video.hero-landed .hero__grid { pointer-events: auto; }
    /* Icona scroll moderna (mouse con rotella animata), verde. Solo full-video. */
    .hero-scroll { display: none; }
    .hero-scroll__mouse {
      display: block;
      width: 17px;             /* più piccola: altezza ~ quella del logo */
      height: 27px;
      border-radius: 999px;
      border: 1.5px solid var(--green-signal);   /* stroke più fine */
      background: rgba(255, 255, 255, 0.04);
      position: relative;
    }
    .hero-scroll__mouse::after {
      content: "";
      position: absolute;
      left: 50%;
      top: 5px;
      width: 3px;              /* rotella più sottile */
      height: 6px;
      border-radius: 2px;
      background: var(--green-signal);
      transform: translateX(-50%);
      animation: hero-wheel 1.7s var(--ease-in-out) infinite;
    }
    @keyframes hero-wheel {
      0%   { opacity: 0; transform: translate(-50%, 0); }
      25%  { opacity: 1; }
      70%  { opacity: 1; transform: translate(-50%, 9px); }
      100% { opacity: 0; transform: translate(-50%, 9px); }
    }

    /* STATO MORPH ATTIVO (JS aggiunge .is-video al wrap) */
    .hero-wrap.is-video {
      height: 220vh;
      margin-top: calc(-1 * var(--header-h)); /* video fino in cima, niente striscia bianca sotto il menu */
    }
    .is-video .hero {
      position: sticky;
      top: 0;
      height: 100vh;
      min-height: 100vh;
      margin-top: 0;
    }
    .is-video .hero-video {
      display: block;
      position: absolute;
      z-index: 0;               /* sopra griglia e fluido, sotto i testi */
      border-radius: 0;
      overflow: hidden;         /* ritaglia il video al box (niente sbordo/doppio) */
      /* NIENTE transform-style: preserve-3d — disabiliterebbe overflow:hidden,
         lasciando il video (106%) sbordare e creare bianco/doppio a destra.
         Il 3D del foglio è già dato da perspective() nel transform inline. */
      transform-origin: 50% 40%;
      will-change: transform, top, left, width, height;
    }
    .is-video .hero-scroll {
      display: block;
      position: absolute;
      left: 50%;
      bottom: clamp(1.5rem, 4vh, 3rem);
      transform: translateX(-50%);
      z-index: 3;
    }
    /* CONTENUTO durante il morph: NASCOSTO (niente fade statico). Il video
       scorre da solo. Quando si POSIZIONA (JS aggiunge .hero-landed) il
       contenuto fa la SUA animazione d'ingresso: eyebrow, cascata parole,
       freccia che si disegna, ingresso della card audit. */
    .is-video .hero__copy { opacity: 1; }        /* contenitore visibile; i figli entrano */
    .is-video .k-chip { visibility: hidden; }     /* lo slot: il video ci si posa sopra */

    /* Stato "in viaggio" (video non ancora posizionato): figli invisibili */
    .is-video:not(.hero-landed) .hero__eyebrow,
    .is-video:not(.hero-landed) .hero__kinetic > *:not(.k-chip),
    .is-video:not(.hero-landed) .hero__lead-in { opacity: 0; animation: none; }
    .is-video:not(.hero-landed) .k-arrow__path { animation: none; stroke-dashoffset: 260; }
    .is-video:not(.hero-landed) .k-arrow__head { opacity: 0; animation: none; }
    /* animation:none per fermare la cascata d'ingresso (k-in) del dock, così
       la nostra opacity:0 vince (i valori animati con fill batterebbero le
       dichiarazioni normali). */
    .is-video:not(.hero-landed) .hero__audit-dock { opacity: 0; animation: none !important; }

    /* LANDING: sequenza d'ingresso del contenuto */
    .is-video.hero-landed .hero__eyebrow {
      animation: word-in 500ms var(--ease-out) both;
    }
    .is-video.hero-landed .hero__kinetic > *:not(.k-chip) {
      animation: word-in 600ms var(--ease-out) both;
      animation-delay: calc(160ms + var(--k, 0) * 55ms);
    }
    .is-video.hero-landed .hero__lead-in {
      animation: word-in 600ms var(--ease-out) 620ms both;
    }
    .is-video.hero-landed .k-arrow__path {
      stroke-dasharray: 260; stroke-dashoffset: 260;
      animation: k-draw 700ms var(--ease-in-out) 560ms forwards;
    }
    .is-video.hero-landed .k-arrow__head {
      opacity: 0;
      animation: word-in 250ms var(--ease-out) 1120ms forwards;
    }
    .is-video.hero-landed .hero__audit-dock {
      animation: dock-in 700ms var(--ease-out) 720ms both;
    }
    @keyframes word-in {
      from { opacity: 0; transform: translateY(0.5em) rotate(var(--rot, 0deg)); }
      to   { opacity: 1; transform: translateY(0) rotate(var(--rot, 0deg)); }
    }
    @keyframes dock-in {
      from { opacity: 0; transform: translateY(26px) scale(0.985); }
      to   { opacity: 1; transform: none; }
    }

    /* Il titolo cinetico: parole e materia visiva nello stesso flusso */
    .hero__kinetic {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      align-items: center;
      column-gap: 0.26em;
      row-gap: 0.1em;
      max-width: 12.5em;
      font-size: clamp(2.75rem, 6.2vw, 5.5rem);
      font-stretch: 120%;
      font-weight: 750;
      line-height: 1.05;
      letter-spacing: -0.02em;
    }
    .k-chip {
      display: inline-flex;
      height: 0.82em;
      aspect-ratio: 8 / 5;
      border-radius: 0.28em;
      overflow: hidden;
      border: 2px solid rgba(255, 255, 255, 0.85);
      box-shadow: 0 0.12em 0.45em rgba(11, 26, 44, 0.18);
      transform: rotate(var(--rot, 0deg));
    }
    .k-chip img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 500ms var(--ease-out);
    }
    @media (hover: hover) and (pointer: fine) {
      .k-chip:hover img { transform: scale(1.12); }
    }
    .k-arrow {
      display: inline-flex;
      width: 1.45em;
      margin-block: -0.12em;
      color: var(--cobalt);
    }
    .k-arrow svg { width: 100%; height: auto; display: block; }

    /* Cascata d'ingresso: esiste solo sotto html.js, senza JS tutto visibile */
    .js .hero__kinetic > *,
    .js .hero__lead-in,
    .js .hero__dock-in {
      opacity: 0;
      transform: translateY(0.45em) rotate(var(--rot, 0deg));
      animation: k-in 700ms var(--ease-out) forwards;
      animation-delay: calc(120ms + var(--k, 0) * 70ms);
    }
    @keyframes k-in {
      to { opacity: 1; transform: translateY(0) rotate(var(--rot, 0deg)); }
    }
    /* La freccia si disegna da sola quando le parole sono entrate */
    .js .k-arrow__path {
      stroke-dasharray: 260;
      stroke-dashoffset: 260;
      animation: k-draw 800ms var(--ease-in-out) forwards;
      animation-delay: 750ms;
    }
    .js .k-arrow__head {
      opacity: 0;
      animation: k-in 250ms var(--ease-out) forwards;
      animation-delay: 1400ms;
    }
    @keyframes k-draw { to { stroke-dashoffset: 0; } }

    .hero__copy .lead {
      max-width: 32em;
      font-size: clamp(1.05rem, 1.4vw, 1.3rem);
      color: var(--ink-soft);
    }
    /* Card audit in vetro (glass-card): translucida, così la fluid
       simulation del hero si vede scorrere SOTTO. Niente blob decorativi.
       Le linee di luce sui bordi (::before alto, ::after sinistra). */
    .hero__audit-dock {
      position: relative;
      z-index: 4;
      width: min(100%, 47rem);
      margin-inline: auto;
      margin-top: 0;
      padding: clamp(1rem, 2.1vw, 1.45rem);
      border: 1px solid rgba(255, 255, 255, 0.35);
      border-radius: clamp(18px, 2vw, 26px);
      background: rgba(247, 251, 255, 0.42);
      box-shadow:
        0 18px 60px rgba(11, 26, 44, 0.14),
        inset 0 1px 0 rgba(255, 255, 255, 0.6),
        inset 0 -1px 0 rgba(255, 255, 255, 0.15),
        inset 0 0 40px 12px rgba(255, 255, 255, 0.28);
      backdrop-filter: blur(23px) saturate(160%);
      -webkit-backdrop-filter: blur(23px) saturate(160%);
      overflow: hidden;
      isolation: isolate;
    }
    .hero__audit-dock::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);
    }
    .hero__audit-dock::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));
    }
    .audit-dock__grid {
      display: grid;
      gap: var(--space-s);
      align-items: center;
      justify-items: center;
    }
    .audit-form { display: grid; gap: var(--space-s); width: 100%; }
    /* Il pannello parla a voce più bassa del titolo: gerarchia netta */
    .audit-panel__title {
      font-size: clamp(1.35rem, 2vw, 1.8rem);
      font-stretch: 120%;
      font-weight: 740;
      text-align: center;
      letter-spacing: -0.015em;
      text-wrap: balance;
    }
    .hero__audit-dock .text-soft {
      max-width: 40em;
      margin-inline: auto;
      font-size: clamp(0.95rem, 1vw, 1.02rem);
      line-height: 1.45;
    }

    /* BARRA UNICA (stile command-bar): sito + email + bottone in una sola
       pillola bianca. Etichette piccole in alto nella cella, valore sotto;
       sul focus la cella accende etichetta e sottolineatura cobalto.
       Le classi .field / .has-error / .field-error restano: la validazione
       di main.js §4 continua a funzionare senza modifiche. */
    .audit-bar {
      display: grid;
      background: rgba(255, 255, 255, 0.9);
      border: 1px solid rgba(255, 255, 255, 0.8);
      border-radius: 16px;
      box-shadow:
        0 10px 30px rgba(11, 26, 44, 0.08),
        inset 0 1px 0 rgba(255, 255, 255, 0.95);
      overflow: hidden;
    }
    .audit-bar .field {
      position: relative;
      gap: 2px;
      padding: 0.6rem 1.1rem 0.72rem;
    }
    .audit-bar .field + .field { border-top: 1px solid var(--line); }
    @media (min-width: 720px) {
      .audit-bar {
        grid-template-columns: 1.15fr 1fr auto;
        align-items: stretch;
      }
      .audit-bar .field + .field { border-top: 0; border-left: 1px solid var(--line); }
    }
    .audit-bar .field > label {
      font-size: 0.7rem;
      font-weight: 750;
      text-transform: uppercase;
      letter-spacing: var(--tracking-caps);
      color: var(--ink-soft);
      transition: color var(--dur-fast) ease;
    }
    .audit-bar .field:focus-within > label { color: var(--cobalt); }
    .audit-bar .input {
      min-height: 0;
      padding: 0;
      border: 0;
      border-radius: 0;
      background: transparent;
      font-size: 1.02rem;
      font-weight: 620;
    }
    .audit-bar .input:focus-visible { outline: none; } /* il focus è mostrato da etichetta + riga sotto */
    .audit-bar .input::placeholder { color: color-mix(in srgb, var(--ink-soft) 55%, transparent); font-weight: 500; }
    /* riga che si accende sotto il campo attivo */
    .audit-bar .field::after {
      content: "";
      position: absolute;
      left: 1.1rem;
      right: 1.1rem;
      bottom: 0.45rem;
      height: 2px;
      border-radius: 2px;
      background: var(--cobalt);
      transform: scaleX(0);
      transform-origin: left;
      transition: transform 240ms var(--ease-out);
    }
    .audit-bar .field:focus-within::after { transform: scaleX(1); }
    .audit-bar .field.has-error > label { color: var(--red-error); }
    .audit-bar .field.has-error::after { transform: scaleX(1); background: var(--red-error); }
    .audit-bar .btn {
      min-height: 100%;
      border-radius: 0;
      padding-inline: 1.7rem;
    }
    @media (max-width: 719.98px) {
      .audit-bar .btn { min-height: 52px; }
    }
    .hero__audit-dock .audit-form__note {
      margin-top: 0;
      font-size: 0.8rem;
      text-align: center;
    }
    /* Lo slogan storico: riga piccola sotto il lead, mai urlata */
    .hero__firma {
      font-size: 0.9375rem;
      font-weight: 620;
      color: var(--ink-soft);
    }
    /* Passi del metodo: prosa più quieta dentro la fact-list */
    .steps dd {
      font-weight: 450;
      color: var(--ink-soft);
      max-width: 52ch;
      line-height: var(--leading-body);
    }
    .on-paper .steps > div { border-bottom-color: var(--line); }
    /* Illustrazione del metodo: webp trasparente, mostrata a PIENA LARGHEZZA
       (niente crop, niente box cobalto: l'immagine ha già il suo sfondo). */
    .method-visual {
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .method-visual img {
      width: 100%;
      height: auto;
      object-fit: contain;
    }
    .method-grid {
      display: grid;
      gap: var(--space-2xl);
      align-items: center;
    }
    @media (min-width: 900px) {
      .method-grid {
        grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
      }
      .method-grid .steps {
        grid-column: 1 / -1;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: var(--space-xl);
      }
      .method-grid .steps > div {
        border-bottom: 0;
        border-top: 1px solid var(--line);
        padding-top: var(--space-m);
      }
    }
    /* Anteprima portfolio: RAIL ORIZZONTALE di card con copertina.
       Full-bleed: la prima card è allineata al container, le altre scorrono
       fino al bordo del viewport. Su desktop+mouse la sezione si BLOCCA a
       schermo e lo scroll verticale scorre i progetti in orizzontale
       (main.js §8 aggiunge .is-jacked al wrap); su touch/senza JS resta lo
       scroll orizzontale nativo con snap. */
    /* ul.work-rail (non solo .work-rail): il reset `ul[class]{padding:0}`
       ha specificità (0,1,1) e azzererebbe il padding del rail. */
    ul.work-rail {
      --rail-pad: max(var(--gutter), calc((100vw - var(--container)) / 2 + var(--gutter)));
      display: grid;
      grid-auto-flow: column;
      /* le card scalano col viewport: su schermi larghi restano grandi e il
         rail SBORDA sempre → c'è sempre corsa orizzontale da percorrere */
      grid-auto-columns: min(82vw, clamp(21rem, 34vw, 34rem));
      gap: clamp(1rem, 2.2vw, 1.5rem);
      margin-block: clamp(2rem, 4vw, 3rem) clamp(1.5rem, 3vw, 2.25rem);
      overflow-x: auto;
      overscroll-behavior-x: contain;
      scroll-snap-type: x proximity;
      scroll-padding-inline: var(--rail-pad);
      padding-inline: var(--rail-pad);
      padding-block: 0.25rem;          /* aria per il focus ring */
      scrollbar-width: none;
    }
    .work-rail::-webkit-scrollbar { display: none; }
    .work-card { scroll-snap-align: start; }
    .work-card__link {
      display: grid;
      gap: var(--space-s);
      text-decoration: none;
      color: inherit;
    }
    .work-card__link:active { transform: scale(0.985); }
    .work-card__media {
      display: block;
      aspect-ratio: 4 / 5;
      border-radius: var(--radius-m);
      overflow: hidden;
      border: 1px solid var(--line);
      background: var(--paper);
    }
    .work-card__media img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 480ms var(--ease-out);
    }
    .work-card__name {
      font-size: 1.05rem;
      font-stretch: 116%;
      font-weight: 750;
      color: var(--cobalt);
    }
    .work-card__sector {
      font-size: var(--size-caption);
      text-transform: uppercase;
      letter-spacing: var(--tracking-caps);
      color: var(--ink-soft);
    }
    .work-card__title {
      font-size: 1.25rem;
      font-stretch: 112%;
      font-weight: 720;
      letter-spacing: -0.01em;
      line-height: 1.25;
      max-width: 24ch;
      transition: color var(--dur-fast) ease;
    }
    @media (hover: hover) and (pointer: fine) {
      .work-card__link:hover .work-card__media img { transform: scale(1.045); }
      .work-card__link:hover .work-card__title { color: var(--cobalt); }
    }

    /* SCROLL-JACK (aggiunto da JS su desktop+mouse+motion): la scena resta
       sticky a piena altezza e il rail si muove in orizzontale col transform,
       guidato dallo scroll verticale. L'altezza del wrap la imposta JS
       (scena + corsa orizzontale), così lo sticky dura il giusto. */
    .work-jack.is-jacked .work-stage {
      position: sticky;
      top: 0;
      min-height: 100vh;
      min-height: 100dvh;
      /* FLEX column (non grid): il rail che sborda NON allarga le altre righe,
         così il container col titolo resta a sinistra e la scena è centrata
         verticalmente (titolo + card + link insieme). */
      display: flex;
      flex-direction: column;
      justify-content: center;
      gap: clamp(0.9rem, 2.2vh, 1.75rem);
      overflow-x: clip;          /* il rail sborda a destra: niente scrollbar */
      /* il titolo non finisce sotto la navbar sticky durante il pin */
      padding-top: var(--header-h);
      padding-bottom: var(--space-l);
    }
    .work-jack.is-jacked ul.work-rail {
      overflow-x: visible;       /* niente scroll nativo: muove il transform */
      scroll-snap-type: none;
      will-change: transform;
      margin-block: 0;
      /* card PIÙ GRANDI ma con altezza limitata al viewport: la copertina è
         un riquadro alto fino a metà schermo, così titolo + card + testo
         stanno tutti nella scena bloccata senza tagliarsi. */
      grid-auto-columns: min(86vw, clamp(24rem, 42vw, 42rem));
    }
    .work-jack.is-jacked .work-card__media {
      aspect-ratio: auto;
      height: min(38vh, 24rem);
    }
    /* nella scena bloccata il testo sotto la card resta compatto */
    .work-jack.is-jacked .work-card__link { gap: var(--space-2xs); }
    .work-jack.is-jacked .work-card__title { font-size: 1.15rem; }
    /* Il bridge scuro non si fonde col footer: hairline di separazione */
    .bridge { border-bottom: 1px solid var(--line-dark); }
