/* ═══════════════════════════════════════════════════════════════════════════
   LEOBI v2 — foglio di stile unico

   Riferimento dichiarato: sileent.com (S-18). Tradotto nel brand:
     · il video è lo sfondo; l'interfaccia sta agli angoli e tace
     · nei reel il lavoro è in bicromia Night Blue → Paper; il colore arriva
       quando si entra nel progetto ("quiet so the work carries the colour")
     · le pagine di testo sono bianche: il 70% di bianco della brand guide
     · Dreamfield ha la sua palette (F-02) e non ne esce mai

   Indice
     1. Font                 6. Menu
     2. Token                7. Reel e Indice
     3. Base                 8. Lab
     4. Superfici            9. Pagina lavoro
     5. Barra e angoli      10. Pagine di testo
                            11. Movimento ridotto, stampa
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 1. Font — gli stessi di v1 (F-03) ──────────────────────────────────── */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("../fonts/archivo-latin-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("../fonts/archivo-latin-ext-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Space Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/space-mono-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Space Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/space-mono-latin-700-normal.woff2") format("woff2");
}

/* ─── 2. Token ───────────────────────────────────────────────────────────── */

:root {
  /* Brand (F-01) */
  --blue: #004e8e;
  --night: #00243f;
  --white: #ffffff;
  --paper: #f2f6fa;
  --slate: #5b7286;
  --line: #d6e1ea;

  /* Dreamfield (F-02) — usata SOLO sotto [data-palette="dream"] */
  --df-night: #060a12;
  --df-indigo: #1b1f45;
  --df-cobalt: #12356b;
  --df-petrol: #123a45;
  --df-haze: #9fb6ce;
  --df-tungsten: #b9762c;
  --df-amber: #e9a64d;

  --font: "Archivo", "Helvetica Neue", Arial, system-ui, sans-serif;
  --mono: "Space Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --gutter: clamp(16px, 2.1vw, 34px);
  --safe-t: max(var(--gutter), env(safe-area-inset-top));
  --safe-b: max(var(--gutter), env(safe-area-inset-bottom));
  --safe-l: max(var(--gutter), env(safe-area-inset-left));
  --safe-r: max(var(--gutter), env(safe-area-inset-right));
  /* Il rigo dell'interfaccia in basso (S-35). Il testo di "Play" sta 18 px
     sopra il fondo del suo riquadro, che appoggia sul margine; menu e
     didascalia hanno la linea di base 7 px sopra il loro fondo. Alzandoli di
     11 px tutte le etichette in basso stanno sulla stessa linea di base. */
  --lift: 11px;

  /* Tempi lunghi (S-13): la pazienza è metà del registro. */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 0.32s;
  --t-mid: 0.7s;
  --t-slow: 1.3s;

  --ui: clamp(17px, 1.25vw, 21px);
  --caption: clamp(30px, 3.3vw, 58px);
  --display: clamp(46px, 8.2vw, 148px);

  /* Tema scuro di default: la maggior parte delle pagine è un video. */
  --bg: var(--night);
  --fg: var(--white);
  --fg-dim: rgba(255, 255, 255, 0.62);
  --rule: rgba(255, 255, 255, 0.24);
  --accent: var(--white);
  --scrim: rgba(0, 36, 63, 0.42);
  --scrim-strong: rgba(0, 36, 63, 0.78);
}

/* Al tocco il bordo basso è la zona dei gesti di sistema: su Android lo
   scorrimento verso l'alto per tornare alla home parte da lì e si prendeva i
   tocchi su Play (segnalato dall'utente); su iPhone c'è la linea della home.
   Tutto il rigo in basso sale insieme, perché parte da --safe-b: su Android da
   16 a 32 px, su iPhone da 34 a 46 (S-37). */
@media (pointer: coarse) {
  :root {
    --safe-b: max(calc(var(--gutter) + 16px), calc(env(safe-area-inset-bottom) + 12px));
  }
}

[data-theme="light"] {
  --bg: var(--white);
  --fg: var(--night);
  --fg-dim: var(--slate);
  --rule: var(--line);
  --accent: var(--blue);
  --scrim: rgba(255, 255, 255, 0);
  --scrim-strong: rgba(255, 255, 255, 0);
}

/* Dreamfield: freddo che domina, caldo solo in piccole quantità — l'ambra è
   il segno del progresso e del link attivo, nient'altro. */
[data-palette="dream"] {
  --bg: var(--df-night);
  --fg: var(--df-haze);
  /* 0,6 dava 3,98:1 sul Night: sotto il minimo AA (4,5:1) per il testo piccolo.
     0,76 dà ~5,6:1. */
  --fg-dim: rgba(159, 182, 206, 0.76);
  --rule: rgba(159, 182, 206, 0.24);
  --accent: var(--df-amber);
  --scrim: rgba(6, 10, 18, 0.45);
  --scrim-strong: rgba(6, 10, 18, 0.82);
}

/* ─── 3. Base ────────────────────────────────────────────────────────────── */

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

html {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-weight: 400;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  background: transparent;
  line-height: 1.6;
  overflow-x: hidden;
}

/* Le pagine a tutto schermo non scorrono: ogni gesto è una navigazione.
   Dreamfield non è più un reel ma la scheda della serie, che scorre. */
html[data-page="home"],
html[data-page="work"],
html[data-page="project"] {
  overflow: hidden;
  overscroll-behavior: none;
}
html[data-page="home"] body,
html[data-page="work"] body,
html[data-page="project"] body {
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

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

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

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

p {
  margin: 0;
}

::selection {
  background: var(--blue);
  color: var(--white);
}

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}
#main:focus {
  outline: none;
}

.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: fixed;
  z-index: 100;
  top: var(--safe-t);
  left: 50%;
  translate: -50% -200%;
  padding: 10px 16px;
  background: var(--white);
  color: var(--night);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  transition: translate var(--t-fast) var(--ease);
}
.skip:focus {
  translate: -50% 0;
}

/* Space Mono, maiuscolo, 11 px, 0,24em (F-03): menu, etichette, metadati.
   Alcune etichette sono titoli veri (h2/h3) per chi naviga per titoli: stesso
   aspetto, nessun margine del browser. */
h2.label,
h3.label {
  margin: 0;
}
.label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-dim);
}

/* ─── 4. Superfici persistenti: il canvas e la cornice ─────────────────────
   Stanno fuori da #swap: sopravvivono ai cambi di pagina, ed è per questo
   che il video può restare fermo mentre tutto il resto cambia. */

.stage {
  position: fixed;
  z-index: 0;
  inset: 0 0 auto 0;
  width: 100%;
  height: 100vh;
  height: 100lvh; /* fisso anche quando la barra di Safari si ritrae */
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.has-stage .stage {
  opacity: 1;
}

/* Ripiego senza WebGL: gli stessi video, in CSS. */
.stage-dom {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--bg);
}
.stage-dom__layer {
  position: absolute;
  inset: 0;
  transition: opacity 1.1s var(--ease);
  background: var(--night);
}
.stage-dom__layer video,
.stage-dom__layer img {
  position: absolute;
  object-fit: cover;
  width: 100%;
  height: 100%;
  inset: 0;
  transition: filter 1s var(--ease);
}
.stage-dom__layer.is-duo video,
.stage-dom__layer.is-duo img {
  filter: grayscale(1) contrast(1.08);
  mix-blend-mode: screen;
}

/* Gli angoli della cornice: quando il formato del lavoro non combacia con lo
   schermo (verticale su desktop, orizzontale su telefono) il video sta in un
   riquadro e questi quattro angoli lo inseguono da una forma all'altra. */
.marks {
  position: fixed;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t-mid) var(--ease);
}
.marks.is-on {
  opacity: 0.9;
}
/* Il contenitore sta fermo a tutto schermo; ogni angolo va al suo posto con
   transform (marks.set in main.js). Una transizione su left/top/width/height
   sarebbe uno spostamento di layout a ogni fotogramma: Lighthouse lo contava
   come CLS (0,215 sulla home, 2026-09-27). Si parte dagli angoli dello
   schermo, come prima. */
.marks i {
  position: absolute;
  left: 0;
  top: 0;
  width: 14px;
  height: 14px;
  border: 0 solid var(--fg);
  transition: transform var(--t-slow) var(--ease-io);
}
.marks i:nth-child(1) { transform: translate(-12px, -12px); border-width: 1px 0 0 1px; }
.marks i:nth-child(2) { transform: translate(calc(100vw - 2px), -12px); border-width: 1px 1px 0 0; }
.marks i:nth-child(3) { transform: translate(calc(100vw - 2px), calc(100vh - 2px)); border-width: 0 1px 1px 0; }
.marks i:nth-child(4) { transform: translate(-12px, calc(100vh - 2px)); border-width: 0 0 1px 1px; }

#swap {
  position: relative;
  z-index: 2;
}

/* ─── 5. Barra superiore e angoli ────────────────────────────────────────── */

.bar {
  position: fixed;
  z-index: 20;
  top: 0;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: 16px;
  padding: var(--safe-t) var(--safe-r) 0 var(--safe-l);
  pointer-events: none;
  font-size: var(--ui);
  line-height: 1;
}
.bar > * {
  pointer-events: auto;
}

/* Logotipo: l'SVG fornito (assets/leobi-logo-mono.svg) usato come maschera. Il
   colore arriva da CSS, quindi resta dentro le versioni approvate (F-07):
   bianco su scuro, blu su chiaro.
   Larghezza ≥ 90 px (F-08); il margine della barra rispetta il clear space. */
.logo {
  justify-self: start;
  display: block;
  width: clamp(92px, 7.6vw, 124px);
  aspect-ratio: 1472 / 490;
  color: var(--white);
}
[data-theme="light"] .logo {
  color: var(--blue);
}
.logo__mark {
  display: block;
  width: 100%;
  height: 100%;
  background: currentColor;
  -webkit-mask: url("../media/brand/logo.svg") center / contain no-repeat;
  mask-image: url("../media/brand/logo.svg");
  mask-position: center;
  mask-size: contain;
  mask-repeat: no-repeat;
  transition: background-color var(--t-mid) var(--ease);
}

.bar__center {
  justify-self: center;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  text-align: center;
}
.bar__right {
  justify-self: end;
  display: flex;
  align-items: flex-start;
  gap: clamp(18px, 2vw, 34px);
}
.bar__label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-dim);
  line-height: 1.6;
}
.bar__back,
.toggle,
.lang {
  position: relative;
  display: inline-flex;
  justify-content: center;
  min-height: 24px;
  min-width: 24px;
}

/* Pausa (WCAG 2.2.2): due barre, o un triangolo quando è tutto fermo. */
.motion {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  color: var(--fg-dim);
  transition: color var(--t-fast) var(--ease);
}
.motion:hover,
.motion[aria-pressed="true"] {
  color: var(--fg);
}
.motion i {
  display: block;
  width: 9px;
  height: 10px;
  border-left: 3px solid currentColor;
  border-right: 3px solid currentColor;
}
.motion[aria-pressed="true"] i {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 5px 0 5px 9px;
  border-color: transparent transparent transparent currentColor;
}
.no-js .motion {
  display: none;
}
.lang {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  line-height: 1.9;
  color: var(--fg-dim);
  transition: color var(--t-fast) var(--ease);
}
.lang:hover {
  color: var(--fg);
}

/* Sottolineatura che si disegna da sinistra: l'unico segno di stato. */
.u,
.toggle,
.bar__back,
.menu__list a,
.caption__title a,
.links a,
.foot a,
.prose a,
.policy__body a {
  background: linear-gradient(currentColor, currentColor) 0 100% / 0% 1px no-repeat;
  transition: background-size var(--t-mid) var(--ease-expo);
  padding-bottom: 3px;
}
.toggle:hover,
.bar__back:hover,
.menu__list a:hover,
.menu__list a[aria-current="page"],
.caption__title a:hover,
.toggle[aria-pressed="true"],
.toggle[aria-expanded="true"] {
  background-size: 100% 1px;
}
/* Link di contenuto (S-43): dentro un testo, nei contatti, nel piè di pagina
   e nell'informativa un link è sempre sottolineato, perché si riconosca come
   link anche senza passarci sopra; al passaggio la linea si ispessisce.
   L'interfaccia (menu, barra, didascalie, comandi) si sottolinea solo al
   passaggio: lì è la posizione a dire che si può toccare. */
.links a,
.foot a,
.prose a,
.policy__body a {
  background-size: 100% 1px;
}
.links a:hover,
.foot a:hover,
.prose a:hover,
.policy__body a:hover {
  background-size: 100% 2px;
}

.toggle__b {
  display: none;
}
.toggle[aria-pressed="true"] .toggle__a,
.toggle[aria-expanded="true"] .toggle__a {
  display: none;
}
.toggle[aria-pressed="true"] .toggle__b,
.toggle[aria-expanded="true"] .toggle__b {
  display: inline;
}

/* Il contatore: cifre grandi e leggere, il totale in mono, e sotto un filo
   che si riempie mentre il lavoro resta in scena. */
.counter {
  display: inline-grid;
  justify-items: center;
  gap: 6px;
  font-weight: 300;
  font-size: clamp(20px, 1.6vw, 26px);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.counter__now {
  display: block;
  overflow: hidden;
  height: 1em;
  line-height: 1;
}
.counter__now span {
  display: block;
}
.counter__total {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
}
.counter__bar {
  display: block;
  width: 44px;
  height: 1px;
  background: var(--rule);
  overflow: hidden;
}
.counter__bar i {
  display: block;
  height: 100%;
  background: var(--accent);
  transform-origin: 0 50%;
  transform: scaleX(0);
}
.counter__bar.is-running i {
  animation: fill var(--dwell, 9s) linear forwards;
}
@keyframes fill {
  to {
    transform: scaleX(1);
  }
}

/* ─── 6. Menu ────────────────────────────────────────────────────────────────
   Desktop: una frase in basso a sinistra — "Work, Lab, Dreamfield, About,
   Contact." — con i conteggi in apice. Sui reel, dopo il primo gesto, si
   ritira in "Menu" e si riapre al passaggio.
   Telefono: "Menu" apre un pannello a tutto schermo, a portata di pollice. */

.menu {
  position: fixed;
  z-index: 30;
  left: var(--safe-l);
  bottom: calc(var(--safe-b) + var(--lift));
  font-size: var(--ui);
  line-height: 1.1;
}

.menu__toggle {
  display: none;
  min-height: 44px;
  align-items: flex-end;
  padding-bottom: 3px;
}
.menu__close {
  display: none;
}

.menu__list {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  margin: 0;
  padding: 0;
  list-style: none;
}
.menu__list li {
  display: inline-flex;
  align-items: flex-end;
}
.menu__list li > i {
  font-style: normal;
  margin-right: 0.28em;
}
.menu__list a {
  position: relative;
  display: inline-flex;
  align-items: flex-start;
  padding-top: 3px;
  transition: opacity var(--t-fast) var(--ease), background-size var(--t-mid) var(--ease-expo);
}
.menu__list sup {
  position: absolute;
  top: -1.05em;
  left: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--fg-dim);
}
.menu__list:hover a:not(:hover) {
  opacity: 0.55;
}
.menu__extra {
  display: none;
}

/* Ritirato (solo desktop, solo sui reel). */
@media (min-width: 761px) and (hover: hover) {
  .menu.is-collapsed .menu__toggle {
    display: inline-flex;
    position: absolute;
    left: 0;
    bottom: 0;
    transition: opacity var(--t-fast) var(--ease);
  }
  .menu.is-collapsed .menu__list {
    opacity: 0;
    transform: translateY(8px);
    pointer-events: none;
    transition: opacity var(--t-fast) var(--ease), transform var(--t-mid) var(--ease-expo);
  }
  .menu.is-collapsed:hover .menu__list,
  .menu.is-collapsed:focus-within .menu__list {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .menu.is-collapsed:hover .menu__toggle,
  .menu.is-collapsed:focus-within .menu__toggle {
    opacity: 0;
  }
  .menu .menu__list {
    transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease-expo);
  }
}

/* ─── 7. Reel e Indice ───────────────────────────────────────────────────── */

/* touch-action: manipulation lascia lo zoom con due dita (WCAG 1.4.4) e toglie
   solo il doppio tocco. La pagina non scorre, quindi lo swipe non trascina
   niente: lo leggono touchstart/touchend. */
.view--reel {
  position: fixed;
  inset: 0;
  touch-action: manipulation;
  cursor: pointer;
}

/* Velature sulle pagine video: il bianco sta su un'area scurita del
   fotogramma (brand guide, p.12), mai su una zona chiara e affollata. */
.view--reel::before,
.view--reel::after,
.view--project::before,
.view--project::after,
.view--404::before,
.view--404::after {
  content: "";
  position: fixed;
  z-index: 0;
  left: 0;
  right: 0;
  pointer-events: none;
}
.view--reel::before,
.view--project::before,
.view--404::before {
  top: 0;
  height: 22vh;
  background: linear-gradient(to bottom, var(--scrim), transparent);
}
.view--reel::after,
.view--project::after,
.view--404::after {
  bottom: 0;
  height: 38vh;
  background: linear-gradient(to top, var(--scrim-strong), var(--scrim) 38%, transparent);
}
.no-js .view--reel::before,
.no-js .view--reel::after {
  display: none;
}

/* Senza JavaScript il reel è un indice: miniature e titoli su Night Blue. */
.no-js .view--reel {
  position: static;
  min-height: 100vh;
  padding: calc(var(--safe-t) + 90px) var(--safe-r) 140px var(--safe-l);
  touch-action: auto;
  cursor: auto;
  background: var(--night);
}
html.no-js,
html.no-js body {
  overflow: auto !important;
  height: auto !important;
}
.reel__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: 40px 24px;
}
.reel__link {
  display: grid;
  gap: 6px;
}
.reel__thumb { order: -3; }
.reel__num { order: -2; }
.reel__meta { order: -1; }
.reel__thumb {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.06);
}
.reel__num,
.reel__meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-dim);
}
.reel__title {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.no-js .caption,
.no-js .hint,
.no-js .strip,
.no-js .home-intro,
.no-js .dream-intro,
.no-js .bar__center,
.no-js .toggle {
  display: none !important;
}
/* Con JavaScript la lista resta nel DOM per screen reader e tastiera. */
.js .reel__list {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* La didascalia: in basso a destra su desktop, sopra il menu su telefono. */
.caption {
  position: fixed;
  z-index: 10;
  right: var(--safe-r);
  /* Il titolo sulla linea di base del menu, a ogni corpo (S-35): in Archivo
     con interlinea 1 la linea di base sta a 0,17 × corpo sopra il fondo del
     riquadro, quella del menu a 7,7 px. */
  bottom: calc(var(--safe-b) + var(--lift) + 7.7px - 0.17 * var(--caption));
  max-width: min(64vw, 900px);
  text-align: right;
  pointer-events: none;
}
.caption__meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: 10px;
  min-height: 1.4em;
}
.caption__title {
  margin: 0;
  font-size: var(--caption);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  text-wrap: balance;
}
.caption__title a {
  pointer-events: auto;
  padding-bottom: 0.06em;
  background-size: 0% 2px;
}
.caption__title a:hover {
  background-size: 100% 2px;
}
/* Il Play dello Show Reel in home (feedback 1, punto 4): lo stesso pulsante
   delle pagine lavoro, sopra la didascalia, allineato come lei. C'è solo
   mentre in scena c'è lo Show Reel (la classe la mette il JavaScript). */
.caption__play {
  position: absolute;
  right: 0;
  bottom: calc(100% + 16px);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 12px 18px;
  border: 1px solid var(--fg);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease-expo), visibility 0s linear var(--t-mid),
    background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.caption__play.is-on {
  pointer-events: auto;
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
.caption__play:hover {
  background: var(--fg);
  color: var(--bg);
}
html.is-chrome-hidden .caption__play {
  pointer-events: none;
}
/* Il fuoco da tastiera sulla lista nascosta dei lavori si vede qui: la voce
   a fuoco è invisibile, il titolo in scena no (WCAG 2.4.7). */
.caption.is-kbd .caption__title a {
  outline: 2px solid currentColor;
  outline-offset: 8px;
}
/* Riga che entra da sotto dentro la propria maschera. */
.line-mask {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}
.line-mask > span {
  display: block;
}

.hint {
  position: fixed;
  z-index: 10;
  left: 50%;
  bottom: var(--safe-b);
  translate: -50% 0;
  display: grid;
  justify-items: center;
  gap: 10px;
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-dim);
  transition: opacity var(--t-mid) var(--ease);
}
.hint i {
  display: block;
  width: 1px;
  height: 34px;
  background: var(--rule);
  position: relative;
  overflow: hidden;
}
.hint i::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--fg);
  transform: translateY(-100%);
  animation: drip 2.4s var(--ease-io) infinite;
}
@keyframes drip {
  60%,
  100% {
    transform: translateY(100%);
  }
}
.hint__m {
  display: none;
}
.has-interacted .hint {
  opacity: 0;
}

/* Gli incipit: quello della home (logotipo e motto) e quello di Dreamfield. */
.home-intro,
.dream-intro {
  position: fixed;
  z-index: 9;
  left: var(--safe-l);
  right: var(--safe-r);
  top: 50%;
  translate: 0 -50%;
  pointer-events: none;
  transition: opacity 1.2s var(--ease), translate 1.6s var(--ease-expo);
}
/* L'apertura della home: una composizione centrata — logotipo, motto, cosa fa
   Leobi — che rispetta il clear space della brand guide (F-08).

   Misurato sul PNG (1472×490): la "o" è alta 339 px, cioè 0,2303 della larghezza
   del file, e le lettere occupano x 33–1435, y 56–441. Oltre il riquadro del
   file vanno quindi lasciati liberi 0,19 W sopra, 0,20 W sotto e 0,21 W ai lati.

   Da qui la larghezza: al massimo il 62% dello schermo (ai lati ne servirebbe
   almeno il 29%) e mai più di quanto l'altezza permetta, testo compreso. Con
   min() su entrambe le misure il logotipo non può né uscire dallo schermo né
   finire sopra il testo, su nessun formato.
   Il cliente lo vuole "un po' più piccolo" (feedback 1, punto 1): sul
   computer entrambi i limiti scendono di un quinto — 50% invece di 62%. */
.home-intro {
  --logo-w: min(50vw, calc((100svh - 200px) / 0.95 * 0.8));
  inset: 0;
  padding: 0 var(--safe-r) 0 var(--safe-l);
  translate: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  opacity: 0;
}
/* Il bianco sta su un'area scurita del fotogramma (brand guide, p. 12). */
.home-intro::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse 70% 60% at 50% 48%, rgba(0, 36, 63, 0.62), rgba(0, 36, 63, 0.2) 70%, transparent);
}
.is-opening .home-intro {
  opacity: 1;
}
.home-intro__logo {
  flex: none;
  width: var(--logo-w);
  aspect-ratio: 1472 / 490;
  background: var(--white);
  -webkit-mask: url("../media/brand/logo.svg") center / contain no-repeat;
  mask-image: url("../media/brand/logo.svg");
  mask-position: center;
  mask-size: contain;
  mask-repeat: no-repeat;
  clip-path: inset(100% 0 0 0);
  transition: clip-path 1.6s var(--ease-expo);
}
.is-logo-in .home-intro__logo {
  clip-path: inset(0 0 0 0);
}
/* Sotto il logotipo due righe nel mono delle etichette: la frase del cliente
   e, per ultimo, il motto (feedback 1, punto 1). Un po' più grandi delle
   etichette, che a 11 px sotto un logotipo così sparirebbero. */
.home-intro__line {
  font-family: var(--mono);
  font-size: clamp(11px, 0.8vw, 15px);
  letter-spacing: 0.24em;
  line-height: 1.4;
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--fg);
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 1s var(--ease) 0.5s, transform 1.4s var(--ease-expo) 0.5s;
}
/* Il clear space sotto il logotipo: 0,20 della sua larghezza. */
.home-intro__logo + .home-intro__line {
  margin-top: calc(var(--logo-w) * 0.2);
}
.home-intro__line + .home-intro__line {
  margin-top: 1.1em;
  transition-delay: 0.75s;
}
.is-logo-in .home-intro__line {
  opacity: 1;
  transform: none;
}
.is-intro-done .dream-intro {
  opacity: 0;
  translate: 0 calc(-50% - 24px);
}
.is-intro-done .home-intro {
  opacity: 0;
  translate: 0 -24px;
}

.dream-intro {
  text-align: center;
  display: grid;
  justify-items: center;
  gap: 18px;
}
.dream-intro .label {
  color: var(--df-amber);
}
.dream-intro__title {
  font-size: var(--display);
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 0.9;
}
.dream-intro__line {
  font-size: clamp(18px, 1.7vw, 28px);
  font-weight: 300;
  max-width: 28ch;
  line-height: 1.35;
}

/* L'interfaccia entra dopo l'apertura, un pezzo alla volta. */
html.is-chrome-hidden .bar,
html.is-chrome-hidden .menu,
html.is-chrome-hidden .caption,
html.is-chrome-hidden .hint,
html.is-chrome-hidden .legal {
  opacity: 0;
  pointer-events: none;
}
.bar,
.menu,
.caption,
.hint,
.legal {
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease-expo);
}
/* Sulle pagine che scorrono barra e menu si ritirano scendendo e tornano
   risalendo: non restano sopra il testo che si sta leggendo. */
html.is-scrolling-down .bar {
  transform: translateY(-120%);
  opacity: 0;
}
html.is-scrolling-down .menu,
html.is-foot-under .menu {
  transform: translateY(120%);
  opacity: 0;
}
/* Mentre il testo del piè di pagina passa sotto il menu, il menu si ritira
   (autoHideChrome): le due righe piccole si mescolavano. */
html.is-foot-under .menu {
  pointer-events: none;
}
html.is-foot-under .menu:focus-within,
html.is-foot-under.is-menu .menu {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}
/* Da ritirati non si cliccano: prima restavano attivi e invisibili (il
   browser mostrava l'indirizzo del link sotto il mouse, sullo schermo niente). */
html.is-scrolling-down .bar > *,
html.is-scrolling-down .menu {
  pointer-events: none;
}
/* Ma chi arriva con la tastiera li ritrova: col fuoco dentro tornano. */
html.is-scrolling-down .bar:focus-within,
html.is-scrolling-down .menu:focus-within,
html.is-scrolling-down.is-menu .menu {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}
html.is-scrolling-down .bar:focus-within > * {
  pointer-events: auto;
}
.caption {
  transition-delay: 0.15s;
}
.menu {
  transition-delay: 0.3s;
}

/* L'Indice: le miniature su una superficie curva, come uno schermo che ci
   avvolge. La curvatura è calcolata dal JavaScript a ogni scorrimento. */
.strip {
  position: fixed;
  z-index: 6;
  inset: 0;
  display: grid;
  align-items: center;
  opacity: 0;
  transition: opacity var(--t-mid) var(--ease);
  cursor: grab;
}
.strip.is-open {
  opacity: 1;
}
.strip[hidden] {
  display: none;
}
.strip__track {
  display: flex;
  align-items: center;
  gap: clamp(8px, 1vw, 16px);
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0 50vw;
  height: 70vh;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  touch-action: pan-x pinch-zoom;
}
.strip__track::-webkit-scrollbar {
  display: none;
}
.card {
  position: relative;
  flex: none;
  height: min(44vh, calc(46vw / var(--ar, 1.7778)));
  aspect-ratio: var(--ar, 1.7778);
  scroll-snap-align: center;
  background: var(--night);
  will-change: transform;
}
.card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
  mix-blend-mode: screen;
  opacity: 0.92;
  transition: filter 0.8s var(--ease), opacity 0.8s var(--ease);
  -webkit-user-drag: none;
  user-select: none;
}
.card.is-current img,
.card:hover img {
  filter: none;
  mix-blend-mode: normal;
  opacity: 1;
}
.card__num {
  position: absolute;
  left: 0;
  top: -22px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
}
.is-strip .caption__title a {
  pointer-events: auto;
}
.is-strip .hint,
.is-strip .home-intro,
.is-strip .dream-intro {
  opacity: 0;
}

/* ─── 8. Lab — la scacchiera ─────────────────────────────────────────────────
   Una casella piena e una vuota. Nella vuota accanto a ogni video sta il suo
   titolo: su telefono la griglia diventa uno zig-zag video/testo. */

.view--lab {
  padding-top: calc(var(--safe-t) + clamp(90px, 18vh, 200px));
}
/* Due velature ferme, in alto e in basso: logo e menu restano leggibili
   quando sotto passano le caselle chiare. */
.view--lab::before,
.view--lab::after {
  content: "";
  position: fixed;
  z-index: 5;
  left: 0;
  right: 0;
  pointer-events: none;
}
.view--lab::before {
  top: 0;
  height: calc(var(--safe-t) + 70px);
  background: linear-gradient(to bottom, rgba(0, 36, 63, 0.92), rgba(0, 36, 63, 0));
}
.view--lab::after {
  bottom: 0;
  height: calc(var(--safe-b) + 90px);
  background: linear-gradient(to top, rgba(0, 36, 63, 0.92), rgba(0, 36, 63, 0));
}
.lab__head {
  display: grid;
  gap: clamp(18px, 3vh, 34px);
  padding: 0 var(--safe-r) clamp(70px, 14vh, 160px) var(--safe-l);
}
.lab__title {
  margin: 0;
  font-size: clamp(88px, 19vw, 320px);
  font-weight: 600;
  letter-spacing: -0.06em;
  line-height: 0.8;
}
/* Il numero dei lavori: dal CSS, fuori dal testo dell'h1 (S-51). */
.lab__title::after {
  content: attr(data-count);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  font-weight: 400;
  vertical-align: top;
  margin-left: 0.4em;
  color: var(--fg-dim);
}
.lab__intro {
  max-width: 34ch;
  font-size: clamp(19px, 1.7vw, 27px);
  font-weight: 300;
  line-height: 1.35;
  color: var(--fg-dim);
}

.checker {
  --cols: 2;
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  margin: 0;
  padding: 0;
  list-style: none;
  transform-origin: 50% 0;
  will-change: transform;
}
.tile {
  position: relative;
  aspect-ratio: 1;
}
/* Telefono: una per riga, alternando lato. La riga va data esplicitamente:
   con due sole colonne il posizionamento automatico metterebbe la seconda
   casella accanto alla prima. Su 4 e 6 colonne il motivo va a capo da solo. */
.tile { grid-row: calc(var(--i) + 1); }
.tile:nth-child(2n + 1) { grid-column: 1; }
.tile:nth-child(2n + 2) { grid-column: 2; }

.tile__link {
  position: absolute;
  inset: 0;
  display: block;
}
.tile__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--night);
}
.tile__media img,
.tile__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Bicromia in CSS: grigio in "screen" sul Night Blue = Night → bianco. */
.tile__media img {
  filter: grayscale(1) contrast(1.06);
  mix-blend-mode: screen;
  transition: transform 1.2s var(--ease-expo), opacity 0.6s var(--ease);
}
.tile__media video {
  opacity: 0;
  transition: opacity 0.7s var(--ease);
}
.tile.is-playing .tile__media video {
  opacity: 1;
}
.tile.is-playing .tile__media img {
  opacity: 0;
}
.tile:hover .tile__media img {
  transform: scale(1.04);
}
/* Al passaggio la casella è subito a colori (feedback 1, punto 6): prima
   diventava a colori solo quando il suo video partiva, online anche dopo uno
   o due secondi. Il fotogramma fermo lascia la bicromia all'istante; il video
   arriva sopra, già a colori. */
@media (hover: hover) {
  .tile .tile__media img {
    transition: transform 1.2s var(--ease-expo), opacity 0.6s var(--ease), filter 0.45s var(--ease);
  }
  .tile:hover .tile__media img,
  .tile:focus-within .tile__media img {
    filter: none;
    mix-blend-mode: normal;
  }
}

.tile__num,
.tile__title,
.tile__meta {
  position: absolute;
  z-index: 1;
}
.tile__num {
  top: 12px;
  left: 12px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--white);
  mix-blend-mode: difference;
}
/* Titolo e metadati nella casella vuota accanto. */
.tile__title,
.tile__meta {
  left: calc(100% + 16px);
  right: calc(-100% + 16px);
  transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease-expo);
}
.tile__title {
  bottom: 38px;
  font-size: clamp(20px, 1.6vw, 28px);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.05;
}
.tile__meta {
  bottom: 16px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-dim);
}
.tile:nth-child(2n + 2) .tile__title,
.tile:nth-child(2n + 2) .tile__meta {
  left: calc(-100% + 16px);
  right: calc(100% + 16px);
  text-align: right;
}

@media (min-width: 700px) {
  .checker {
    --cols: 4;
  }
  .tile {
    grid-row: auto;
  }
  .tile:nth-child(4n + 1) { grid-column: 1; }
  .tile:nth-child(4n + 2) { grid-column: 3; }
  .tile:nth-child(4n + 3) { grid-column: 2; }
  .tile:nth-child(4n + 4) { grid-column: 4; }
  .tile:nth-child(4n + 1) .tile__title, .tile:nth-child(4n + 1) .tile__meta,
  .tile:nth-child(4n + 2) .tile__title, .tile:nth-child(4n + 2) .tile__meta,
  .tile:nth-child(4n + 3) .tile__title, .tile:nth-child(4n + 3) .tile__meta {
    left: calc(100% + 16px);
    right: calc(-100% + 16px);
    text-align: left;
  }
  .tile:nth-child(4n + 4) .tile__title,
  .tile:nth-child(4n + 4) .tile__meta {
    left: calc(-100% + 16px);
    right: calc(100% + 16px);
    text-align: right;
  }
}

@media (min-width: 1100px) {
  .checker {
    --cols: 6;
  }
  .tile:nth-child(6n + 1) { grid-column: 1; }
  .tile:nth-child(6n + 2) { grid-column: 3; }
  .tile:nth-child(6n + 3) { grid-column: 5; }
  .tile:nth-child(6n + 4) { grid-column: 2; }
  .tile:nth-child(6n + 5) { grid-column: 4; }
  .tile:nth-child(6n + 6) { grid-column: 6; }
  .tile:nth-child(n) .tile__title,
  .tile:nth-child(n) .tile__meta {
    left: calc(100% + 16px);
    right: calc(-100% + 16px);
    text-align: left;
  }
  .tile:nth-child(6n + 6) .tile__title,
  .tile:nth-child(6n + 6) .tile__meta {
    left: calc(-100% + 16px);
    right: calc(100% + 16px);
    text-align: right;
  }
}

/* Con il puntatore i titoli compaiono al passaggio; su touch restano. */
@media (hover: hover) and (min-width: 700px) {
  .tile .tile__title,
  .tile .tile__meta {
    opacity: 0;
    transform: translateY(8px);
  }
  .tile:hover .tile__title,
  .tile:hover .tile__meta,
  .tile:focus-within .tile__title,
  .tile:focus-within .tile__meta {
    opacity: 1;
    transform: none;
  }
}

/* ─── 8b. Dreamfield — la scheda della serie (feedback 1, punto 7) ─────────
   A sinistra titolo, introduzione ed episodi; a destra l'anteprima, cioè il
   canvas con la cornice nella colonna di destra (frameAt in main.js). Il testo
   sta sulla luce sfocata del video: una velatura da sinistra lo tiene
   leggibile. L'ambra segna solo ciò che è attivo: l'occhiello, l'episodio in
   anteprima (S-25). */

.view--series {
  --col: min(600px, 48vw);
  position: relative;
  z-index: 0;
  padding: calc(var(--safe-t) + clamp(84px, 12vh, 150px)) var(--safe-r) 0 var(--safe-l);
}
.view--series::before {
  content: "";
  position: fixed;
  z-index: -1;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(6, 10, 18, 0.9) 0%, rgba(6, 10, 18, 0.72) 38%, rgba(6, 10, 18, 0) 62%),
    linear-gradient(to top, rgba(6, 10, 18, 0.85), rgba(6, 10, 18, 0) calc(var(--safe-b) + 110px));
}
/* Due velature ferme, in alto e in basso, sopra il testo che scorre: barra e
   menu restano leggibili, come nel Lab. */
.view--series::after {
  content: "";
  position: fixed;
  z-index: 5;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(6, 10, 18, 0.92), rgba(6, 10, 18, 0) calc(var(--safe-t) + 70px)),
    linear-gradient(to top, rgba(6, 10, 18, 0.94), rgba(6, 10, 18, 0) calc(var(--safe-b) + 96px));
}
.series__head,
.series__episodes,
.series__about {
  max-width: var(--col);
}
.series__kicker {
  color: var(--df-amber);
}
.series__title {
  margin: 20px 0 0;
  font-size: clamp(64px, 8vw, 150px);
  font-weight: 600;
  letter-spacing: -0.05em;
  line-height: 0.86;
}
.series__line {
  margin-top: 22px;
  max-width: 24ch;
  font-size: clamp(21px, 1.9vw, 32px);
  font-weight: 300;
  line-height: 1.25;
  letter-spacing: -0.015em;
}
.series__intro {
  margin-top: 22px;
  max-width: 44ch;
  font-size: clamp(16px, 1.1vw, 19px);
  font-weight: 300;
  line-height: 1.6;
  color: var(--fg-dim);
}
.series__play {
  display: inline-flex;
  align-items: baseline;
  gap: 14px;
  margin-top: 30px;
  padding: 13px 20px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--df-night);
  background: var(--fg);
  transition: background-color var(--t-fast) var(--ease);
}
.series__play span {
  opacity: 0.62;
}
.series__play:hover,
.series__play:focus-visible {
  background: var(--df-amber);
}

/* Sul computer la fila degli episodi si affaccia già nella prima schermata:
   invita a scorrere. */
.series__episodes {
  margin-top: clamp(48px, 7vh, 96px);
}
.series__episodes h2 sup,
.series__episodes .label sup {
  margin-left: 0.6em;
  font-size: 1em;
  vertical-align: baseline;
}
.series__lead {
  margin-top: 14px;
  max-width: 46ch;
  font-size: clamp(16px, 1.1vw, 19px);
  font-weight: 300;
  line-height: 1.55;
}
.episodes {
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(10px, 1.2vw, 18px);
  max-width: 500px;
}
.episode__link {
  display: grid;
  gap: 8px;
}
.episode__media {
  position: relative;
  display: block;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: var(--df-night);
  outline: 1px solid var(--rule);
  outline-offset: 0;
  transition: outline-color var(--t-fast) var(--ease);
}
.episode__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.55;
  filter: saturate(0.6);
  transition: opacity var(--t-mid) var(--ease), filter var(--t-mid) var(--ease), transform 1.2s var(--ease-expo);
}
.episode.is-current .episode__media {
  outline: 1px solid var(--df-amber);
}
.episode.is-current .episode__media img,
.episode__link:hover .episode__media img,
.episode__link:focus-visible .episode__media img {
  opacity: 1;
  filter: none;
}
.episode__link:hover .episode__media img {
  transform: scale(1.03);
}
.episode__num {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
}
.episode.is-current .episode__num {
  color: var(--df-amber);
}
.episode__title {
  font-size: clamp(15px, 1.05vw, 18px);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.15;
}
.episode__meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
}

.series__about {
  margin-top: clamp(64px, 11vh, 130px);
  padding-bottom: clamp(90px, 16vh, 200px);
}
.series__about p:not(.label) {
  margin-top: 14px;
  max-width: 46ch;
  font-size: clamp(16px, 1.1vw, 19px);
  font-weight: 300;
  line-height: 1.6;
  color: var(--fg-dim);
}

/* La didascalia sotto l'anteprima: numero, titolo, durata. La posizione la
   mette il JavaScript, sotto la cornice. */
.series__now {
  position: fixed;
  z-index: 0;
  display: flex;
  gap: 14px;
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-dim);
  opacity: 0;
  transition: opacity var(--t-mid) var(--ease);
}
.series__now.is-on {
  opacity: 1;
}
.series__now-num {
  color: var(--df-amber);
}
/* Il piè di pagina passa sopra l'anteprima, che resta ferma mentre si scorre. */
.view--series ~ .foot {
  position: relative;
  z-index: 1;
  background: var(--bg);
}

/* Telefono e finestre strette: il film verticale riempie lo schermo e fa da
   sfondo; il testo gli scorre sopra, su una velatura uniforme. */
@media (max-width: 899px), (max-height: 500px), (orientation: portrait) {
  .view--series {
    --col: 100%;
    padding-top: calc(var(--safe-t) + 34vh);
  }
  .view--series::before {
    background: linear-gradient(to bottom, rgba(6, 10, 18, 0) 0%, rgba(6, 10, 18, 0.55) 30vh, rgba(6, 10, 18, 0.82) 60vh);
  }
  .series__now {
    display: none;
  }
  .episodes {
    gap: 10px;
  }
  .episode__title {
    font-size: 14px;
  }
}

/* ─── 8c. Film (feedback 1, punto 9) ────────────────────────────────────────
   Una specie di slideshow: in cima il testo del cliente, poi una locandina per
   schermata e sotto le informazioni classiche. La pagina scorre e si ferma a
   ogni schermata (scroll-snap "proximity": aiuta senza imprigionare). Le
   locandine sono a colori, nella cornice del sito, con attorno la loro luce
   sfocata — come i video nei reel — e si scoprono per caselle. */

html[data-page="film"] {
  scroll-snap-type: y proximity;
}
/* Due velature ferme, in alto e in basso, sopra il testo che scorre: barra e
   menu restano leggibili, come nel Lab. */
.view--film {
  position: relative;
  z-index: 0;
}
.view--film::after {
  content: "";
  position: fixed;
  z-index: 5;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(0, 36, 63, 0.92), rgba(0, 36, 63, 0) calc(var(--safe-t) + 70px)),
    linear-gradient(to top, rgba(0, 36, 63, 0.94), rgba(0, 36, 63, 0) calc(var(--safe-b) + 96px));
}
.film__intro,
.film {
  min-height: 100svh;
  scroll-snap-align: start;
  padding: calc(var(--safe-t) + 72px) var(--safe-r) calc(var(--safe-b) + 90px) var(--safe-l);
}
.film__intro {
  display: grid;
  align-content: center;
  gap: 24px;
}
.film__title {
  margin: 0;
  max-width: 15ch;
  font-size: clamp(40px, 6.4vw, 116px);
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 0.95;
  text-wrap: balance;
}
.film__lead {
  max-width: 54ch;
  font-size: clamp(17px, 1.3vw, 22px);
  font-weight: 300;
  line-height: 1.55;
  color: var(--fg-dim);
}
.films {
  margin: 0;
  padding: 0;
  list-style: none;
}
.film {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: clamp(24px, 4vh, 40px);
  text-align: center;
}
.film__poster {
  position: relative;
  margin: 0;
  height: min(56svh, 760px);
  aspect-ratio: var(--ar);
  max-width: 100%;
}
/* La luce sfocata della locandina, come attorno ai video nei reel. */
.film__poster::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -16%;
  background: var(--img, none) center / cover no-repeat;
  filter: blur(64px) saturate(1.1);
  opacity: 0.38;
  pointer-events: none;
}
.film__poster img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.film__cells {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(8, 1fr);
  pointer-events: none;
}
.film__cells i {
  background: var(--bg);
  transition: transform 0.9s var(--ease-expo);
  transition-delay: calc(var(--d, 0) * 22ms + 120ms);
}
.film__poster.is-in .film__cells i {
  transform: scale(0);
}
.no-js .film__cells {
  display: none;
}
.film__marks i {
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid var(--fg);
}
.film__marks i:nth-child(1) { left: -12px; top: -12px; border-width: 1px 0 0 1px; }
.film__marks i:nth-child(2) { right: -12px; top: -12px; border-width: 1px 1px 0 0; }
.film__marks i:nth-child(3) { right: -12px; bottom: -12px; border-width: 0 1px 1px 0; }
.film__marks i:nth-child(4) { left: -12px; bottom: -12px; border-width: 0 0 1px 1px; }
/* Locandina in arrivo: un cartello col titolo, nella stessa cornice. */
.film__slate {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 18px;
  padding: 12%;
  border: 1px solid var(--rule);
  background: rgba(255, 255, 255, 0.03);
}
.film__slate-title {
  font-size: clamp(26px, 2.6vw, 44px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  text-wrap: balance;
}
.film__info {
  display: grid;
  justify-items: center;
  gap: 16px;
  max-width: 62ch;
}
.film__name {
  margin: 0;
  font-size: var(--caption);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
}
.film__facts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 36px;
  margin: 4px 0 0;
}
.film__facts div {
  display: grid;
  gap: 4px;
}
.film__facts dt,
.film__plot .label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-dim);
}
.film__facts dd {
  margin: 0;
  font-size: clamp(16px, 1.1vw, 18px);
}
.film__plot {
  display: grid;
  gap: 6px;
}
.film__plot p:not(.label) {
  font-size: clamp(16px, 1.1vw, 18px);
  font-weight: 300;
  line-height: 1.55;
}
.film__tbc {
  color: var(--fg-dim);
  font-style: italic;
  font-weight: 300;
}
@media (max-width: 760px) {
  .film__poster {
    height: min(50svh, 560px);
  }
  .film__facts {
    gap: 10px 24px;
  }
}

/* ─── 9. Pagina lavoro ───────────────────────────────────────────────────── */

.view--project {
  position: fixed;
  inset: 0;
  touch-action: manipulation;
}
.no-js .view--project,
.no-stage .view--project {
  background: var(--poster) center / cover no-repeat var(--night);
}
.view--project .caption {
  pointer-events: none;
}

.project__bar {
  position: fixed;
  z-index: 10;
  left: 50%;
  bottom: var(--safe-b);
  translate: -50% 0;
  display: flex;
  align-items: baseline;
  gap: clamp(20px, 3vw, 48px);
  font-size: 14px;
  white-space: nowrap;
}
.project__nav {
  display: grid;
  gap: 4px;
  color: var(--fg-dim);
  transition: color var(--t-fast) var(--ease);
}
.project__nav:hover {
  color: var(--fg);
}
.project__nav--next {
  text-align: right;
}
.project__nav .label {
  font-size: 11px;
}
/* Le frecce sono solo per il telefono (S-34). */
.project__arrow {
  display: none;
}
.project__badge {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-dim);
  padding: 8px 12px;
  border: 1px solid var(--rule);
}
.project__play {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 12px 18px;
  border: 1px solid var(--fg);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.project__play:hover {
  background: var(--fg);
  color: var(--bg);
}

/* Il pannello Info: bianco (Paper), come le pagine di testo. Su telefono sale
   dal basso. In Dreamfield prende la palette del progetto. */
.drawer {
  position: fixed;
  z-index: 15;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(560px, 44vw);
  background: var(--paper);
  color: var(--night);
  transform: translateX(101%);
  /* Chiuso è anche invisibile: la visibilità si spegne a scorrimento finito
     e si riaccende subito all'apertura. Senza, allargando o stringendo la
     finestra oltre i 760 px il pannello chiuso passava da "fuori a destra" a
     "fuori in basso" attraversando lo schermo; e restava leggibile agli
     screen reader pur essendo fuori vista. */
  visibility: hidden;
  transition: transform 0.9s var(--ease-expo), visibility 0s linear 0.9s;
  overflow-y: auto;
  overscroll-behavior: contain;
}
[data-palette="dream"] .drawer {
  background: var(--df-indigo);
  color: var(--df-haze);
}
.is-info .drawer {
  transform: none;
  visibility: visible;
  transition: transform 0.9s var(--ease-expo), visibility 0s;
}
.drawer__inner {
  display: grid;
  gap: 28px;
  padding: calc(var(--safe-t) + 80px) var(--safe-r) calc(var(--safe-b) + 40px) clamp(24px, 3vw, 48px);
}
.drawer .label {
  color: var(--slate);
}
[data-palette="dream"] .drawer .label {
  color: var(--df-amber);
}
.drawer__title {
  margin: 0;
  font-size: clamp(34px, 3.4vw, 56px);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 0.98;
}
.facts {
  margin: 0;
  display: grid;
  border-top: 1px solid var(--line);
}
[data-palette="dream"] .facts {
  border-color: rgba(159, 182, 206, 0.25);
}
.facts div {
  display: grid;
  grid-template-columns: 9em 1fr;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
[data-palette="dream"] .facts div {
  border-color: rgba(159, 182, 206, 0.25);
}
.facts dt {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--slate);
  padding-top: 3px;
}
[data-palette="dream"] .facts dt {
  color: rgba(159, 182, 206, 0.86);
}
.facts dd {
  margin: 0;
  font-size: 16px;
}
.drawer__note {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--slate);
}
[data-palette="dream"] .drawer__note {
  color: rgba(159, 182, 206, 0.86);
}
.drawer:focus {
  outline: none;
}
.drawer__text {
  display: grid;
  gap: 1em;
  font-weight: 300;
  font-size: 17px;
  max-width: 620px;
}
.project__bar,
.view--project .caption {
  transition: opacity var(--t-mid) var(--ease);
}
.is-info .project__bar,
.is-info .view--project .caption {
  opacity: 0;
  pointer-events: none;
}

/* Con Film nel menu (S-47) la frase del menu è più lunga: fra 761 e 839 px,
   prima del primo gesto, arrivava a toccare "Scroll" al centro (misurato: 8 px
   di sovrapposizione a 761, 6 px di spazio a 790). Lì l'invito a scorrere si
   toglie: contatore e reel dicono già che si scorre. Il telefono girato ha le
   sue regole e resta com'è. */
@media (min-width: 761px) and (max-width: 839px) and (min-height: 501px) {
  .view--reel .hint {
    display: none;
  }
}

/* Finestre medie, 761–1199 px (S-34). Menu a sinistra, barra al centro e
   didascalia a destra non ci stanno su una riga: misurato su tutte le 64
   pagine lavoro, EN e IT, lo scontro è fra la barra e il titolo grande della
   didascalia. Si prende la disposizione del telefono: didascalia a sinistra
   sopra "Menu", barra a destra; con un mouse il menu si raccoglie in "Menu" e
   si riapre al passaggio, come nei reel. La lista di query è esattamente
   "fra 761 e 1199 px, tranne il telefono girato" (vedi mqMobile in main.js),
   che ha già le sue regole. */
@media (min-width: 761px) and (max-width: 1199px) and (min-height: 501px),
  (min-width: 1101px) and (max-width: 1199px),
  (min-width: 761px) and (max-width: 1199px) and (orientation: portrait) {
  .view--project .caption {
    left: var(--safe-l);
    right: auto;
    bottom: calc(var(--safe-b) + var(--lift) + 58px);
    text-align: left;
  }
  .project__bar {
    left: auto;
    right: var(--safe-r);
    translate: none;
  }
}
@media (min-width: 761px) and (max-width: 1199px) and (min-height: 501px) and (hover: hover),
  (min-width: 1101px) and (max-width: 1199px) and (hover: hover),
  (min-width: 761px) and (max-width: 1199px) and (orientation: portrait) and (hover: hover) {
  .view--project ~ .menu .menu__toggle {
    display: inline-flex;
    position: absolute;
    left: 0;
    bottom: 0;
    transition: opacity var(--t-fast) var(--ease);
  }
  .view--project ~ .menu .menu__list {
    opacity: 0;
    transform: translateY(8px);
    pointer-events: none;
  }
  .view--project ~ .menu:hover .menu__list,
  .view--project ~ .menu:focus-within .menu__list {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .view--project ~ .menu:hover .menu__toggle,
  .view--project ~ .menu:focus-within .menu__toggle {
    opacity: 0;
  }
}
/* La barra resta leggibile sopra il pannello chiaro. */
.is-info .bar__right {
  color: var(--night);
}
[data-palette="dream"] .is-info .bar__right {
  color: var(--df-haze);
}

/* Il lettore del film intero (S-33). Il video occupa la finestra e ci sta
   dentro intero: un verticale su desktop ha le bande ai lati, un orizzontale
   su telefono sopra e sotto. È posizionato, non affidato a una griglia: lì
   height: 100% non si risolveva e un verticale diventava alto 2297 px su 720,
   coi controlli fuori dallo schermo. Una velatura in alto tiene leggibili
   titolo e Close sui fotogrammi chiari. */
.player {
  position: fixed;
  z-index: 50;
  inset: 0;
  background: #000;
}
.player[hidden] {
  display: none;
}
.player__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.player::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0 0 auto;
  height: calc(var(--safe-t) + 64px);
  background: linear-gradient(rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0));
  pointer-events: none;
}
.player__close {
  position: absolute;
  z-index: 2;
  top: var(--safe-t);
  right: var(--safe-r);
  font-size: var(--ui);
  color: var(--white);
}
.player__title {
  position: absolute;
  z-index: 2;
  top: var(--safe-t);
  left: var(--safe-l);
  margin: 0;
  color: rgba(255, 255, 255, 0.7);
  line-height: 24px;
}

/* Il Play al centro, quando il browser non avvia il film da solo: un link
   diretto (…/#film) aperto da fuori, senza un gesto sulla pagina (S-40). */
.player__start {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 14px 22px;
  color: var(--white);
  background: rgba(0, 36, 63, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.7);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.player__start:hover {
  background: var(--white);
  color: var(--night);
}
.player__start[hidden] {
  display: none;
}

/* Fine del film: "A seguire" (S-39), come su Netflix e YouTube. Sull'ultimo
   fotogramma, velato di Night Blue: il titolo del lavoro successivo, la sua
   miniatura dentro gli angoli della cornice (gli stessi che il sito mette
   attorno ai video), la cifra leggera che scorre come nel contatore e il filo
   che si riempie in 5 s. Poi si va alla pagina del lavoro successivo, col suo
   loop. La velatura lascia passare i tocchi: i controlli del video restano
   usabili, e spostare la testina ferma il conto. */
.player__end {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 18px;
  padding: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
  /* L'ultimo fotogramma si allontana: sfocato e velato, così le scritte
     restano nette anche su un finale chiaro (un logo bianco, un cartello). */
  background: rgba(0, 36, 63, 0.74);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  text-align: center;
  pointer-events: none;
  animation: end-in 0.7s var(--ease) both;
}
.player__end[hidden] {
  display: none;
}
.player__end a,
.player__end button {
  pointer-events: auto;
}
.player__up {
  margin: 0;
  color: rgba(255, 255, 255, 0.72);
}
.player__next-title {
  margin: -8px 0 6px;
  font-size: clamp(22px, 2.6vw, 34px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--white);
}
/* La miniatura prende il formato del lavoro successivo, dentro un quadrato di
   lato --s: nessun formato è dato per scontato. --fw e --fh sono le frazioni
   del lato (1 per il lato lungo), calcolate dal JavaScript dal formato. */
.player__count {
  --s: min(200px, 44vw, 30vh);
  --fw: 1;
  --fh: 0.5625;
  display: grid;
  justify-items: center;
  gap: 18px;
}
.player__next {
  display: block;
}
.player__frame {
  position: relative;
  display: grid;
  place-items: center;
  width: calc(var(--s) * var(--fw));
  height: calc(var(--s) * var(--fh));
}
.player__thumb {
  position: absolute;
  inset: 0;
  background: center / cover no-repeat;
  filter: brightness(0.55);
  transition: filter var(--t-fast) var(--ease);
}
.player__next:hover .player__thumb,
.player__next:focus-visible .player__thumb {
  filter: brightness(0.8);
}
.player__frame i {
  position: absolute;
  z-index: 1;
  width: 14px;
  height: 14px;
  border: 0 solid var(--white);
  animation: corner-in 1s var(--ease-expo) both;
}
.player__frame i:nth-of-type(1) { left: -12px; top: -12px; border-width: 1px 0 0 1px; --dx: -24px; --dy: -24px; }
.player__frame i:nth-of-type(2) { right: -12px; top: -12px; border-width: 1px 1px 0 0; --dx: 24px; --dy: -24px; }
.player__frame i:nth-of-type(3) { right: -12px; bottom: -12px; border-width: 0 1px 1px 0; --dx: 24px; --dy: 24px; }
.player__frame i:nth-of-type(4) { left: -12px; bottom: -12px; border-width: 0 0 1px 1px; --dx: -24px; --dy: 24px; }
.player__num {
  position: relative;
  z-index: 1;
  display: block;
  overflow: hidden;
  height: 1em;
  font-size: clamp(48px, 6vw, 80px);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--white);
}
.player__num span {
  display: block;
}
.player__bar {
  --dwell: 5s;
  width: calc(var(--s) * var(--fw));
  background: rgba(255, 255, 255, 0.24);
}
.player__bar i {
  background: var(--white);
}
/* I due comandi sulla stessa linea di base (S-35). */
.player__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 12px 28px;
  margin-top: 6px;
}
.player__replay {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 12px 18px;
  color: var(--white);
  border: 1px solid rgba(255, 255, 255, 0.5);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.player__replay:hover {
  background: var(--white);
  color: var(--night);
}
.player__back {
  padding: 12px 4px;
  color: rgba(255, 255, 255, 0.78);
  transition: color var(--t-fast) var(--ease);
}
.player__back:hover {
  color: var(--white);
}
/* Conto trattenuto (il mouse su un comando, un tocco, uno scorrimento): la
   cifra si attenua e il filo si ferma. */
.player__num span {
  transition: opacity var(--t-fast) var(--ease);
}
.player__end.is-held .player__num span {
  opacity: 0.4;
}
/* Col movimento in pausa niente conto alla rovescia: la miniatura resta, e
   porta al successivo solo se la si tocca. */
.player__end.is-still .player__num,
.player__end.is-still .player__bar {
  display: none;
}
@keyframes end-in {
  from {
    opacity: 0;
  }
}
@keyframes corner-in {
  from {
    opacity: 0;
    transform: translate(var(--dx), var(--dy));
  }
}

/* ─── 9b. Il 404: "Cut." (S-44) ──────────────────────────────────────────────
   Una scena tagliata al montaggio: il titolo enorme a sinistra, su una
   velatura che scende da sinistra; sotto, il ciak e i due comandi. Il film a
   caso sta sul canvas; "Now showing" in basso a destra, come nei reel. */
.view--404 {
  position: fixed;
  inset: 0;
  touch-action: manipulation;
  cursor: pointer;
}
.no-js .view--404,
.no-stage .view--404 {
  background: var(--poster) center / cover no-repeat var(--night);
}
.nf {
  position: absolute;
  z-index: 2;
  left: var(--safe-l);
  top: 50%;
  translate: 0 -54%;
  display: grid;
  justify-items: start;
  gap: 14px;
  max-width: min(92vw, 900px);
  padding-right: var(--safe-r);
  cursor: auto;
}
/* Una velatura da sinistra: il bianco sta sempre su una zona scura. */
.view--404 .nf::before {
  content: "";
  position: fixed;
  z-index: -1;
  inset: 0 auto 0 0;
  width: min(100vw, 980px);
  background: linear-gradient(to right, var(--scrim-strong), var(--scrim) 55%, transparent);
  pointer-events: none;
}
.nf__label {
  margin: 0;
  color: rgba(255, 255, 255, 0.72);
}
.nf__title {
  margin: 0 0 0 -0.04em;
  font-size: clamp(96px, 17vw, 280px);
  font-weight: 600;
  letter-spacing: -0.055em;
  line-height: 0.82;
  color: var(--white);
}
.nf__body {
  margin: 4px 0 6px;
  max-width: 34ch;
  text-wrap: balance;
  font-size: clamp(18px, 1.7vw, 28px);
  font-weight: 300;
  line-height: 1.3;
  color: var(--white);
}
.nf__slate {
  margin: 0;
  color: rgba(255, 255, 255, 0.72);
  font-variant-numeric: tabular-nums;
}
/* Il numero del ciak scorre come le cifre del contatore. */
.nf__take {
  display: inline-block;
  overflow: hidden;
  height: 1.4em;
  vertical-align: bottom;
}
.nf__take span {
  display: block;
}
.nf__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px 28px;
  margin-top: 14px;
}
.nf__back {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 12px 18px;
  color: var(--white);
  border: 1px solid var(--white);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.nf__back:hover {
  background: var(--white);
  color: var(--night);
}
.nf__again {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 12px 4px;
  color: rgba(255, 255, 255, 0.78);
  transition: color var(--t-fast) var(--ease);
}
.nf__again:hover {
  color: var(--white);
}
/* Il timecode al posto del contatore, con il punto di registrazione che
   lampeggia (quadrato, come tutto il resto). Fermo col movimento in pausa. */
.timecode {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
.timecode i {
  width: 6px;
  height: 6px;
  background: var(--white);
  animation: rec 1.2s steps(1) infinite;
}
.is-still .timecode i {
  animation: none;
}
@keyframes rec {
  50% {
    opacity: 0;
  }
}

/* ─── 10. Pagine di testo: About, Contact, 404 ──────────────────────────── */

.view--text {
  padding-top: calc(var(--safe-t) + clamp(110px, 20vh, 220px));
}
/* Una velatura bianca ferma in alto, sopra il testo che scorre: quando la
   barra ricompare a metà pagina, logo e lingua non si posano sulle righe
   (come nel Lab, e come il menu col piè di pagina). */
.view--text::before {
  content: "";
  position: fixed;
  z-index: 5;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--safe-t) + 76px);
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.96) 45%, rgba(255, 255, 255, 0));
}
.block {
  padding: 0 var(--safe-r) clamp(90px, 16vh, 200px) var(--safe-l);
  display: grid;
  gap: 28px;
}
.display {
  margin: 0;
  font-size: var(--display);
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 0.93;
  max-width: 13ch;
  text-wrap: balance;
}
.display span {
  display: block;
  font-weight: 300;
  color: var(--fg-dim);
}
.display--motto {
  max-width: 12ch;
}

.block--about {
  grid-template-columns: 1fr;
  gap: clamp(40px, 7vw, 120px);
}
.portrait {
  position: relative;
  margin: 0;
  width: min(100%, 520px);
}
.portrait img {
  width: 100%;
  height: auto;
  aspect-ratio: 1200 / 1490;
  object-fit: cover;
  background: var(--paper);
}
.portrait figcaption {
  margin-top: 12px;
}
/* La foto si scopre per caselle: la stessa griglia delle transizioni. */
.portrait__cells {
  position: absolute;
  inset: 0 0 auto 0;
  aspect-ratio: 1200 / 1490;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(8, 1fr);
  pointer-events: none;
}
.portrait__cells i {
  background: var(--white);
  transition: transform 0.9s var(--ease-expo);
  transition-delay: calc(var(--d, 0) * 22ms + 120ms);
}
.portrait.is-in .portrait__cells i {
  transform: scale(0);
}
.no-js .portrait__cells {
  display: none;
}

.prose {
  display: grid;
  gap: 1.1em;
  max-width: 620px;
  font-size: clamp(17px, 1.25vw, 20px);
  font-weight: 300;
  line-height: 1.6;
}
/* Un link dentro un testo si distingue anche senza colore (WCAG 1.4.1):
   sempre sottolineato, vedi "Link di contenuto" (S-43). */

/* L'informativa privacy (S-41): titoletti a sinistra, testo a destra, come un
   documento; su telefono uno sotto l'altro. */
.block--policy {
  gap: 0;
}
.policy {
  display: grid;
  gap: 14px 48px;
  padding: 28px 0;
  border-top: 1px solid var(--line);
}
.policy__h {
  margin: 0;
  font-size: clamp(19px, 1.5vw, 24px);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}
.policy__body {
  display: grid;
  gap: 1em;
  max-width: 68ch;
  font-size: 17px;
  font-weight: 300;
  line-height: 1.6;
}
.policy__body p {
  margin: 0;
}
@media (min-width: 900px) {
  .policy {
    grid-template-columns: minmax(200px, 1fr) 2fr;
  }
}

/* La partita IVA in home e il link all'informativa (S-41, S-45): una riga di
   corpo minimo nel margine in basso, allineata al menu, come la riga legale di
   un piè di pagina. Sta sotto il rigo delle etichette (S-35) senza spostarlo:
   misurata, la sua linea di base è 37 px sotto quella del menu sugli schermi
   larghi, 25–30 px nelle finestre strette, dove si ferma a 8 px dal fondo.
   Corpo 9 px, sotto gli 11 delle etichette: è la stampa piccola (richiesta
   dell'utente). */
.legal {
  position: fixed;
  z-index: 10;
  left: var(--safe-l);
  bottom: max(8px, calc(var(--safe-b) - 20px));
  display: flex;
  gap: 20px;
  margin: 0;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--fg-dim);
}
.legal a {
  color: inherit;
  transition: color var(--t-fast) var(--ease);
}
.legal a:hover,
.legal a:focus-visible {
  color: var(--fg);
}
.prose__lead {
  font-size: clamp(21px, 1.8vw, 28px);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: -0.01em;
}

.direction {
  display: grid;
  gap: 48px;
}
.direction__item {
  display: grid;
  gap: 16px;
  max-width: 820px;
}
.direction__item p:not(.label) {
  font-weight: 300;
  font-size: clamp(17px, 1.25vw, 20px);
  max-width: 620px;
}
.quote {
  margin: 0;
  font-size: clamp(30px, 3.6vw, 62px);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 1.08;
}

.offer {
  display: grid;
  gap: 40px;
  border-top: 1px solid var(--rule);
}
.offer__item {
  display: grid;
  gap: 14px;
  padding-top: 28px;
  max-width: 560px;
}
.offer__item p:not(.label):not(.offer__num) {
  font-weight: 300;
}
.offer__num {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--accent);
}
.offer__title {
  margin: 0;
  font-size: clamp(28px, 2.6vw, 44px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.02;
}

.facts-row {
  display: grid;
  gap: 28px;
  border-top: 1px solid var(--rule);
  padding-top: 28px;
  margin-bottom: 36px;
}
.fact {
  display: grid;
  gap: 8px;
}
.fact__value {
  font-size: clamp(64px, 10vw, 180px);
  font-weight: 600;
  letter-spacing: -0.06em;
  line-height: 0.85;
  color: var(--blue);
}
.fact__label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-dim);
}
.broadcast {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  border-top: 1px solid var(--rule);
}
.broadcast li {
  flex: 1 0 auto;
  padding: 16px 22px 16px 0;
  font-size: clamp(22px, 2.4vw, 40px);
  font-weight: 300;
  letter-spacing: -0.02em;
  border-bottom: 1px solid var(--rule);
}

/* Contact: l'indirizzo è l'eroe della pagina. Sopra, la frase che invita a
   scrivere (feedback 1, punto 15): la prima parte attenuata, "Let's talk."
   piena. */
.invite {
  max-width: 30ch;
  margin: 0 0 clamp(18px, 2.4vw, 40px);
  font-size: clamp(21px, 1.9vw, 34px);
  font-weight: 300;
  letter-spacing: -0.015em;
  line-height: 1.3;
  color: var(--fg-dim);
  text-wrap: balance;
}
.invite span {
  font-weight: 600;
  color: var(--fg);
}
.mail {
  margin: 0;
  font-size: clamp(30px, 8.6vw, 150px);
  font-weight: 600;
  letter-spacing: -0.05em;
  line-height: 0.95;
}
.mail a {
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 2px no-repeat;
  padding-bottom: 0.04em;
  transition: color var(--t-fast) var(--ease);
}
.mail a:hover {
  color: var(--blue);
}
.links {
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
  font-size: clamp(24px, 3.1vw, 52px);
  letter-spacing: -0.025em;
  line-height: 1.2;
}
.links__k {
  color: var(--fg-dim);
  font-weight: 300;
}
.links a {
  overflow-wrap: anywhere;
}
.links a:hover {
  color: var(--blue);
}

/* Contatti in fondo a ogni pagina che scorre (F-06). Sulle pagine a tutto
   schermo il contatto è l'ultima voce del menu, in basso. */
.foot {
  display: grid;
  gap: 40px;
  padding: clamp(70px, 14vh, 160px) var(--safe-r) calc(var(--safe-b) + 90px) var(--safe-l);
  border-top: 1px solid var(--rule);
}
.foot__motto {
  font-size: clamp(34px, 4.6vw, 80px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 0.95;
}
.foot__contact {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 6px;
  font-size: clamp(18px, 1.6vw, 26px);
}
/* Le etichette in colonna, larghe quanto "Instagram." (feedback 1, punto 12). */
.foot__contact .label {
  display: inline-block;
  width: 9.6em;
}
.foot__small {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-dim);
}

/* Entrata allo scorrimento. Senza JavaScript tutto resta visibile. */
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 1s var(--ease), transform 1.3s var(--ease-expo);
  transition-delay: calc(var(--i, 0) * 45ms);
}
.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

@media (min-width: 900px) {
  .block--about {
    grid-template-columns: 5fr 1fr 6fr;
    align-items: start;
  }
  .block--about .prose {
    grid-column: 3;
    padding-top: 6vh;
  }
  .direction {
    grid-template-columns: 1fr 1fr;
    gap: 6vw;
  }
  .offer {
    grid-template-columns: 1fr 1fr;
    gap: 6vw;
  }
  .facts-row {
    grid-template-columns: 1fr 1fr;
    gap: 6vw;
  }
  .foot {
    grid-template-columns: 1.4fr 1fr;
    align-items: end;
  }
  .foot__small {
    grid-column: 1 / -1;
  }
  .block--contact .links {
    grid-auto-flow: column;
    justify-content: start;
    gap: 6vw;
  }
}

/* ─── Schermi grandi (feedback 1, punto 13) ─────────────────────────────────
   Le pagine di testo si fermavano alle misure pensate per 1440 px — testo a
   20 px, foto a 520, colonne a 620 — mentre la griglia continuava ad
   allargarsi: a 2560 px fra la foto e il testo restavano 840 px vuoti. Oltre i
   1600 px ora crescono in proporzione, come se fossero disegnate per quello
   schermo. --u è il pixel "di progetto": 1 px fino a 1600, poi cresce con la
   finestra fino a 1,6 px a 2560, dove si ferma; oltre, la pagina resta larga
   2560 e centrata. Ogni misura è il suo valore a 1600 px per --u, quindi a
   1600 non cambia niente e non c'è salto. Le etichette dell'interfaccia fissa
   (barra, menu) restano come sono: sono comandi, non contenuto. */
@media (min-width: 1600px) {
  :root {
    --u: clamp(1px, 100vw / 1600, 1.6px);
  }
  .view--text .label,
  .foot .label,
  .foot__small,
  .offer__num,
  .fact__label {
    font-size: calc(11 * var(--u));
  }
  .view--text .display {
    font-size: calc(131.2 * var(--u));
  }
  .block--about {
    gap: calc(112 * var(--u));
  }
  .view--text .block {
    row-gap: calc(28 * var(--u));
  }
  .portrait {
    width: min(100%, calc(520 * var(--u)));
  }
  .prose,
  .direction__item p:not(.label) {
    font-size: calc(20 * var(--u));
    max-width: calc(620 * var(--u));
  }
  .prose__lead {
    font-size: calc(28 * var(--u));
  }
  .direction__item {
    max-width: calc(820 * var(--u));
  }
  .quote {
    font-size: calc(57.6 * var(--u));
  }
  .offer__item {
    max-width: calc(560 * var(--u));
  }
  .offer__item p:not(.label):not(.offer__num) {
    font-size: calc(16 * var(--u));
  }
  .offer__title {
    font-size: calc(41.6 * var(--u));
  }
  .fact__value {
    font-size: calc(160 * var(--u));
  }
  .broadcast li {
    font-size: calc(38.4 * var(--u));
  }
  .invite {
    font-size: calc(30.4 * var(--u));
  }
  .mail {
    font-size: calc(137.6 * var(--u));
  }
  .links {
    font-size: calc(49.6 * var(--u));
  }
  .policy__h {
    font-size: calc(24 * var(--u));
  }
  .policy__body {
    font-size: calc(17 * var(--u));
  }
  .foot__motto {
    font-size: calc(73.6 * var(--u));
  }
  .foot__contact {
    font-size: calc(25.6 * var(--u));
  }
}
@media (min-width: 2561px) {
  .view--text > .block,
  .foot {
    max-width: 2560px;
    margin-inline: auto;
  }
}

/* ─── Telefono ───────────────────────────────────────────────────────────── */

/* Telefono — e telefono girato: un 844×390 è più largo di 760 px ma alto
   quanto un'unghia, e il layout desktop non ci sta. */
@media (max-width: 760px), (max-height: 500px) and (orientation: landscape) and (max-width: 1100px) {
  :root {
    --caption: clamp(30px, 9.4vw, 44px);
  }

  .bar {
    grid-template-columns: auto 1fr auto;
  }
  .bar__center {
    justify-self: end;
  }
  .bar .lang {
    display: none;
  }

  .counter {
    grid-auto-flow: column;
    align-items: baseline;
    gap: 6px;
    font-size: 18px;
  }
  .counter__bar {
    display: none;
  }

  /* In basso, a portata di pollice: titolo sopra, poi Menu e Indice. */
  .caption {
    left: var(--safe-l);
    right: var(--safe-r);
    bottom: calc(var(--safe-b) + var(--lift) + 58px);
    max-width: none;
    text-align: left;
  }
  .caption__meta {
    margin-bottom: 8px;
  }
  .caption__play {
    left: 0;
    right: auto;
  }

  .view--reel ~ .menu .menu__toggle,
  .menu__toggle {
    display: inline-flex;
  }
  .menu {
    left: var(--safe-l);
    right: var(--safe-r);
    bottom: calc(var(--safe-b) + var(--lift));
    /* La scatola è larga quanto lo schermo e sta sopra la barra del lavoro:
       si prendeva i tocchi su Play e sulle frecce, che rispondevano solo in
       una striscia in basso (segnalato dall'utente). Contano solo "Menu" e il
       pannello aperto. */
    pointer-events: none;
  }
  .menu__toggle,
  .menu__panel {
    pointer-events: auto;
  }
  .menu__toggle {
    position: relative;
    z-index: 2;
  }
  .menu__panel {
    position: fixed;
    z-index: 1;
    inset: 0;
    display: grid;
    align-content: end;
    gap: 44px;
    padding: calc(var(--safe-t) + 90px) var(--safe-r) calc(var(--safe-b) + 70px) var(--safe-l);
    background: var(--night);
    visibility: hidden;
    clip-path: inset(100% 0 0 0);
    transition:
      clip-path 0.8s var(--ease-expo),
      visibility 0s linear 0.8s;
  }
  [data-palette="dream"] .menu__panel {
    background: var(--df-night);
  }
  .is-menu .menu__panel {
    visibility: visible;
    clip-path: inset(0 0 0 0);
    transition:
      clip-path 0.8s var(--ease-expo),
      visibility 0s;
  }
  .is-menu .menu__open {
    display: none;
  }
  .is-menu .menu__close {
    display: inline;
  }
  .menu__list {
    display: grid;
    gap: 0;
  }
  .menu__list li {
    display: block;
    overflow: hidden;
    border-bottom: 1px solid var(--rule);
  }
  .menu__list li > i {
    display: none;
  }
  .menu__list a {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 0 12px;
    font-size: clamp(40px, 12.5vw, 64px);
    font-weight: 600;
    letter-spacing: -0.045em;
    line-height: 1;
    background: none;
    transform: translateY(105%);
    transition: transform 0.9s var(--ease-expo);
    transition-delay: calc(var(--i) * 55ms + 120ms);
  }
  .menu__list a[aria-current="page"] {
    color: var(--accent);
  }
  .menu__list sup {
    position: static;
    padding-top: 6px;
    order: 2;
  }
  .is-menu .menu__list a {
    transform: none;
  }
  .menu__list:hover a:not(:hover) {
    opacity: 1;
  }
  [data-theme="light"] .menu__panel {
    background: var(--white);
  }
  .menu__extra {
    display: grid;
    gap: 10px;
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: 0.14em;
    color: var(--fg-dim);
    opacity: 0;
    transition: opacity 0.6s var(--ease) 0.4s;
  }
  .is-menu .menu__extra {
    opacity: 1;
  }
  .menu__lang {
    margin-top: 10px;
    color: var(--fg);
    text-transform: uppercase;
    letter-spacing: 0.24em;
    font-size: 11px;
  }

  .hint {
    left: auto;
    right: var(--safe-r);
    translate: 0 0;
    /* "Swipe" sulla linea di base di "Menu": il suo testo sta 5,6 px sopra
       il fondo, quello di "Menu" 7,7. */
    bottom: calc(var(--safe-b) + var(--lift) + 2px);
    justify-items: end;
    grid-auto-flow: column;
    align-items: end;
  }
  .hint i {
    height: 22px;
  }
  .hint__d {
    display: none;
  }
  .hint__m {
    display: inline;
  }
  /* La riga legale sta nella zona dei gesti di sistema (S-37): lì solo testo.
     L'informativa si apre dal pannello del menu. */
  .legal a {
    display: none;
  }

  .dream-intro {
    top: auto;
    bottom: calc(var(--safe-b) + 170px);
    translate: none;
  }
  /* Telefono: il clear space ai lati permetterebbe fino al 70% della
     larghezza; si usa il 66%. */
  .home-intro {
    --logo-w: min(66vw, calc((100svh - 190px) / 0.95));
  }
  .is-intro-done .home-intro,
  .is-intro-done .dream-intro {
    translate: 0 -24px;
  }
  .dream-intro {
    text-align: left;
    justify-items: start;
  }

  .strip__track {
    height: 64vh;
    padding: 0 18vw;
  }
  .card {
    height: min(52vh, calc(66vw / var(--ar, 1.7778)));
  }

  .project__bar {
    left: auto;
    right: var(--safe-r);
    translate: none;
    bottom: var(--safe-b);
    gap: 16px;
  }
  .project__nav {
    padding: 8px 0;
  }
  /* Sul telefono le parole non ci stanno: in italiano "Precedente · Guarda ·
     Successivo" arrivava a coprire "Menu". Restano le frecce; le parole
     passano agli screen reader (S-34). */
  .project__nav .label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .project__arrow {
    display: block;
    font-size: 20px;
    line-height: 1;
    color: var(--fg);
  }
  .project__badge {
    display: none;
  }

  .drawer {
    top: auto;
    width: 100%;
    max-height: 84vh;
    transform: translateY(101%);
  }
  .drawer__inner {
    padding-top: 36px;
  }
  .view--project .caption {
    bottom: calc(var(--safe-b) + var(--lift) + 58px);
  }
}

/* ─── Telefono girato ───────────────────────────────────────────────────────
   Valgono le regole del telefono, più queste: l'altezza è la misura scarsa,
   quindi testi e pannello del menu si dimensionano su quella. */
@media (max-height: 500px) and (orientation: landscape) and (max-width: 1100px) {
  :root {
    --caption: clamp(24px, 8.5vh, 38px);
  }
  .hint {
    display: none;
  }
  /* Il menu in due colonne: le voci a sinistra, contatti e lingua a destra. */
  .menu__panel {
    grid-template-columns: 1fr auto;
    align-content: end;
    align-items: end;
    gap: 16px 48px;
    padding-top: calc(var(--safe-t) + 56px);
    padding-bottom: calc(var(--safe-b) + 56px);
    overflow-y: auto;
  }
  .menu__list a {
    font-size: clamp(24px, 10vh, 44px);
    padding: 5px 0 7px;
  }
  .dream-intro {
    top: 50%;
    bottom: auto;
    translate: 0 -50%;
    text-align: center;
    justify-items: center;
  }
  .is-intro-done .dream-intro {
    translate: 0 calc(-50% - 24px);
  }
  .dream-intro__title {
    font-size: clamp(40px, 16vh, 96px);
  }
  .drawer {
    max-height: 92vh;
  }
}

/* ─── Il puntatore ───────────────────────────────────────────────────────────
   Un punto quadrato esatto e quattro angoli che lo inseguono (main.js, 8b).
   Prende il colore del testo della pagina: bianco sul video, Night Blue sul
   bianco, Haze in Dreamfield. Il cursore di sistema sparisce solo quando
   questo è attivo — cioè con un mouse vero e senza colori forzati. */
.cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1000;
  pointer-events: none;
  color: var(--fg);
  opacity: 0;
  transition: opacity 0.35s var(--ease), color 0.4s var(--ease);
}
.cursor.is-visible {
  opacity: 1;
}
.cursor.is-light {
  color: var(--night);
}
.cursor__dot,
.cursor__frame,
.cursor__label {
  position: absolute;
  left: 0;
  top: 0;
  will-change: transform;
}
.cursor__dot {
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  background: currentColor;
  transition: opacity 0.25s var(--ease), scale 0.35s var(--ease-expo);
}
.cursor[data-mode="lock"] .cursor__dot {
  opacity: 0;
  scale: 0;
}
.cursor__frame i {
  position: absolute;
  width: 8px;
  height: 8px;
  border: 0 solid currentColor;
}
.cursor__frame i:nth-child(1) { left: 0; top: 0; border-width: 1.5px 0 0 1.5px; }
.cursor__frame i:nth-child(2) { right: 0; top: 0; border-width: 1.5px 1.5px 0 0; }
.cursor__frame i:nth-child(3) { right: 0; bottom: 0; border-width: 0 1.5px 1.5px 0; }
.cursor__frame i:nth-child(4) { left: 0; bottom: 0; border-width: 0 0 1.5px 1.5px; }
.cursor__label {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
.cursor.has-label .cursor__label {
  opacity: 1;
}
html.has-cursor,
html.has-cursor * {
  cursor: none !important;
}
@media (forced-colors: active) {
  .cursor {
    display: none;
  }
  html.has-cursor,
  html.has-cursor * {
    cursor: auto !important;
  }
}

/* ─── Bersagli touch ─────────────────────────────────────────────────────────
   Col dito servono almeno 44×44 px (WCAG 2.5.5). Invece di ingrandire i
   comandi — cambierebbe il disegno — si allarga l'area che risponde, con un
   elemento invisibile centrato sul comando. */
@media (pointer: coarse) {
  .logo,
  .lang,
  .bar__back,
  .toggle,
  .motion,
  .menu__toggle,
  .project__nav,
  .legal a,
  .caption__title a,
  .foot a,
  .links a,
  .mail a,
  .menu__extra a {
    position: relative;
  }
  .logo::after,
  .lang::after,
  .bar__back::after,
  .toggle::after,
  .motion::after,
  .menu__toggle::after,
  .project__nav::after,
  .legal a::after,
  .caption__play::after,
  .caption__title a::after,
  .foot a::after,
  .links a::after,
  .mail a::after,
  .menu__extra a::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
  }
  .menu__extra a {
    padding: 4px 0;
  }
}

/* ─── 11. Movimento ridotto, stampa ──────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
  .js .reveal {
    opacity: 1;
    transform: none;
  }
  .portrait__cells {
    display: none;
  }
}

@media print {
  .stage,
  .marks,
  .bar,
  .menu,
  .hint,
  .strip {
    display: none !important;
  }
  html,
  body {
    background: #fff !important;
    color: #000 !important;
    overflow: visible !important;
    height: auto !important;
  }
}
