/* ==========================================================================
   BRT — makieta koncepcyjna (zorna.pl)
   demo.css
   Świat: karbon / kość / czerwień BRT. Zimny, przemysłowy, sieciowy.
   ========================================================================== */

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

html,
body {
  margin: 0;
  padding: 0;
  overflow-x: clip;
}

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

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

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

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

canvas {
  display: block;
}

/* ---------- Tokens ---------- */
:root {
  --carbon: #131110;
  --carbon-soft: #1C1815;
  --carbon-line: rgba(244, 241, 236, 0.12);
  --bone: #F4F1EC;
  --bone-dim: #E7E1D4;
  --red: #E2001A;
  --red-dark: #A5000F;
  --red-deep: #6E000A;

  /* Tekst na karbonie (#131110, L≈0.0058), oba tony liczone osobno —
     poprzedni komentarz twierdził błędnie ">8:1 nawet przy 50% krycia" dla
     OBU tonów, a w praktyce tylko --on-carbon-muted ma taki zapas:
     - muted (0.64 krycia): ~7.6:1 na dużym marginesie, bezpieczne dla
       każdego tekstu.
     - faint (0.4 krycia, jak było): tylko 3.53:1 — poniżej progu 4.5:1
       normalnego tekstu (potwierdzone pomiarem na .footer-col-title/
       .footer-meta/.hero-status-right). Podbite do 0.52 krycia: ~5.16:1. */
  --on-carbon-muted: rgba(244, 241, 236, 0.64);
  --on-carbon-faint: rgba(244, 241, 236, 0.52);

  /* Tekst na czerwieni (#E2001A, L≈0.162): biel wymaga wysokiej krycia,
     żeby zwykły tekst trzymał 4.5:1 — próg realnie leży ok. 0.95 krycia
     (przy 0.95 wychodzi ~4.53:1), nie samo ">=0.95" bez wyliczenia. Soft
     (0.96) to zamierzony margines nad progiem. --on-red-large było 0.82
     (~3.57:1: mieściło się w progu 3:1 DUŻEGO/pogrubionego tekstu, ale
     dwaj jego konsumenci — .rete-footnote i .rete-stat-label — to zwykły,
     mały tekst, więc realnie potrzebują 4.5:1, nie 3:1). Podbite do 0.96
     (~4.6:1+), tak jak soft. */
  --on-red-strong: #FFFFFF;
  --on-red-soft: rgba(255, 255, 255, 0.96);
  --on-red-large: rgba(255, 255, 255, 0.96);

  /* Tekst na kości (#F4F1EC, L≈0.882): karbon przy obniżonym kryciu.
     - muted (0.62 krycia): ~5.07:1, bezpieczny margines.
     - faint (0.42 krycia, jak było): tylko 2.72:1 — potwierdzone pomiarem
       na .intro-footnote, dużo poniżej 4.5:1 mimo komentarza "ogromny
       zapas kontrastu" który tu był po prostu błędny. Podbite do 0.6
       krycia: ~4.74:1. */
  --on-bone-muted: rgba(19, 17, 16, 0.62);
  --on-bone-faint: rgba(19, 17, 16, 0.6);

  --font-display: "Archivo", system-ui, sans-serif;
  --font-mono: "Fragment Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  --ease-snappy: cubic-bezier(0.16, 1, 0.3, 1);

  --grain-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");

  --header-h: clamp(84px, 15vw, 112px);
}

/* ---------- Base ---------- */
html {
  scroll-behavior: auto;
}

body {
  background: var(--bone);
  color: var(--carbon);
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-variation-settings: "wdth" 100;
  font-weight: 400;
  font-size: 1.05rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 400;
  margin: 0;
  line-height: 1;
}

p {
  margin: 0;
  max-width: 62ch;
}

.tabular-nums,
.font-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* Nagłówki display: wersaliki, oś szerokości rozciągnięta (wdth 125),
   waga 800-900, tracking lekko ujemny (podłoga -0.04em, nigdy ciaśniej). */
.display {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  line-height: 0.98;
}

h1, h2 {
  text-wrap: balance;
}

/* ---------- Anchors under fixed header ---------- */
[id] {
  scroll-margin-top: calc(var(--header-h) + 12px);
}

/* ---------- Accessibility ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  background: var(--red);
  color: #fff;
  padding: 0.75em 1.25em;
  font-weight: 700;
}

.skip-link:focus {
  left: 0;
}

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

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
}

.contatti a:focus-visible,
.site-header a:focus-visible,
.footer-wordmark a:focus-visible {
  outline-color: var(--bone);
}

.rete a:focus-visible {
  outline-color: #fff;
}

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

/* ==========================================================================
   Ziarno globalne
   ========================================================================== */
.grain-overlay {
  position: fixed;
  inset: 0;
  z-index: 500;
  pointer-events: none;
  background-image: var(--grain-img);
  background-repeat: repeat;
  background-size: 180px 180px;
  mix-blend-mode: overlay;
  opacity: 0.05;
}

/* ==========================================================================
   Preloader
   ========================================================================== */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 999;
  background: var(--carbon);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: preloader-failsafe 0.6s 4s forwards;
}

@keyframes preloader-failsafe {
  to {
    clip-path: inset(0 0 100% 0);
    visibility: hidden;
  }
}

.preloader-word {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  font-size: clamp(3.5rem, 16vw, 9rem);
  color: var(--bone);
}

.preloader-count {
  position: absolute;
  right: clamp(1.25rem, 4vw, 3rem);
  bottom: clamp(1.25rem, 4vw, 3rem);
  font-family: var(--font-mono);
  font-size: 0.9rem;
  letter-spacing: 0.08em;
  color: var(--red);
}

.preloader-count::after {
  content: " / 100";
  color: var(--on-carbon-muted);
}

@media (prefers-reduced-motion: reduce) {
  .preloader {
    display: none !important;
  }
}

/* ==========================================================================
   1. Top stack: ticker + nav (jeden wspólny pasek chowany razem)
   ========================================================================== */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
}

/* --- Ticker --- */
.ticker {
  background: var(--carbon);
  border-bottom: 1px solid var(--carbon-line);
  height: clamp(30px, 4.4vw, 38px);
  display: flex;
  align-items: center;
}

/* overflow:hidden vive qui, non più su .ticker: .ticker-tools (a destra,
   sempre visibile) non deve essere ritagliato insieme al marquee. */
.ticker-viewport {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
}

.ticker-track {
  display: flex;
  align-items: center;
  white-space: nowrap;
  will-change: transform;
}

/* Pasek narzędzi (1): due link mono caps a destra del ticker, come CARBON
   CALCULATOR | LIVE TRACKING PORTAL su unitedcarriers.com. Funzione
   dimostrativa dichiarata via title, non un vero calcolatore/tracking. */
.ticker-tools {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.7em;
  height: 100%;
  padding: 0 clamp(1rem, 2.6vw, 2rem);
  font-family: var(--font-mono);
  font-size: clamp(0.6rem, 1.2vw, 0.68rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-carbon-muted);
  border-left: 1px solid var(--carbon-line);
}

.ticker-tools a {
  color: inherit;
  transition: color 0.25s var(--ease-snappy);
}

@media (hover: hover) {
  .ticker-tools a:hover {
    color: var(--red);
  }
}

.ticker-tools-sep {
  opacity: 0.5;
}

@media (max-width: 640px) {
  .ticker-tools {
    display: none;
  }
}

.ticker-item {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: clamp(0.66rem, 1.4vw, 0.76rem);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--on-carbon-muted);
  padding: 0 clamp(1rem, 2.6vw, 2rem);
  flex-shrink: 0;
}

.ticker-item::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  background: var(--red);
  border-radius: 50%;
  margin-right: 0.9em;
  flex-shrink: 0;
}

/* Etichetta demo visibile, ripetuta nel loop tra ogni notizia: prima
   c'era solo nello .sr-only (invisibile a chi vede lo schermo).
   Colore: non var(--red) (#E2001A) — su sfondo --carbon (#131110) a
   10.88px dà solo ~3.81:1, sotto la soglia 4.5:1 del testo piccolo.
   #FF001D è lo stesso hue (~353°) di --red, solo più chiaro q.b.:
   ~4.72:1 su #131110 (formula WCAG relativa, verificato via
   getComputedStyle), margine sopra la soglia. */
.ticker-tag {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: clamp(0.6rem, 1.2vw, 0.68rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #FF001D;
  padding: 0 clamp(0.8rem, 2vw, 1.4rem);
  border-left: 1px solid var(--carbon-line);
  border-right: 1px solid var(--carbon-line);
  flex-shrink: 0;
}

@media (hover: hover) {
  .ticker:hover .ticker-track {
    animation-play-state: paused;
  }
}

/* --- Nav --- */
.site-nav {
  background: var(--carbon);
  border-bottom: 1px solid var(--carbon-line);
  transition: background-color 0.4s var(--ease-snappy);
}

.site-header[data-scrolled] .site-nav {
  background: rgba(19, 17, 16, 0.86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.nav-inner {
  max-width: 1680px;
  margin: 0 auto;
  padding: 0.9rem clamp(1.25rem, 4vw, 3rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.nav-logo {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  font-size: clamp(1.35rem, 3vw, 1.7rem);
  letter-spacing: -0.02em;
  color: var(--bone);
  flex-shrink: 0;
}

.nav-logo span {
  color: var(--red);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(1.4rem, 3vw, 2.4rem);
}

.nav-links a {
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--on-carbon-muted);
  transition: color 0.25s var(--ease-snappy);
  position: relative;
}

@media (hover: hover) {
  .nav-links a:hover {
    color: var(--bone);
  }
}

.nav-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  background: var(--red);
  color: #fff;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.7em 1.3em;
  flex-shrink: 0;
  transition: background-color 0.25s var(--ease-snappy);
}

.nav-cta:active {
  scale: 0.97 !important;
}

@media (hover: hover) {
  .nav-cta:hover {
    background: var(--red-dark);
  }
}

.nav-toggle {
  display: none;
}

@media (max-width: 767px) {
  .nav-links,
  .nav-cta {
    display: none;
  }

  .nav-toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    width: 40px;
    height: 40px;
    padding: 0;
    flex-shrink: 0;
    position: relative;
    z-index: 2;
  }
}

.nav-toggle-bar {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--bone);
  transition: transform 0.3s var(--ease-snappy), opacity 0.3s var(--ease-snappy);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* ==========================================================================
   Menu mobile a schermo intero (sotto i 768px)
   ========================================================================== */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--carbon);
  padding: calc(var(--header-h) + 2rem) clamp(1.25rem, 6vw, 3rem) 2rem;
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 8vw, 3rem);
  overflow-y: auto;
  transform: translateY(-100%);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: transform 0.4s var(--ease-snappy), opacity 0.3s var(--ease-snappy), visibility 0s linear 0.4s;
}

.mobile-menu[data-open] {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: transform 0.4s var(--ease-snappy), opacity 0.3s var(--ease-snappy), visibility 0s linear 0s;
}

.mobile-menu-links {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.mobile-menu-links a {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 122;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  font-size: clamp(2.2rem, 11vw, 3.2rem);
  color: var(--bone);
  padding: 0.35em 0;
  border-bottom: 1px solid var(--carbon-line);
  transition: color 0.25s var(--ease-snappy);
}

.mobile-menu-links a:active {
  color: var(--red);
}

@media (hover: hover) {
  .mobile-menu-links a:hover {
    color: var(--red);
  }
}

.mobile-menu-cta {
  align-self: flex-start;
}

@media (min-width: 768px) {
  .mobile-menu {
    display: none;
  }
}

/* ==========================================================================
   Przyciski / linki wspólne
   ========================================================================== */
.btn-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 1em 1.8em;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  transition: background-color 0.25s var(--ease-snappy), color 0.25s var(--ease-snappy), border-color 0.25s var(--ease-snappy);
}

.btn-cta:active {
  scale: 0.97 !important;
}

.btn-cta--primary {
  background: var(--red);
  color: #fff;
}

@media (hover: hover) {
  .btn-cta--primary:hover {
    background: var(--red-dark);
  }
}

.btn-cta--outline {
  border: 1px solid rgba(244, 241, 236, 0.4);
  color: var(--bone);
}

@media (hover: hover) {
  .btn-cta--outline:hover {
    border-color: var(--bone);
    background: rgba(244, 241, 236, 0.08);
  }
}

.btn-arrow {
  flex-shrink: 0;
  transition: transform 0.3s var(--ease-snappy);
}

@media (hover: hover) {
  .btn-cta:hover .btn-arrow {
    transform: translateX(4px);
  }
}

.link-underline {
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0% 100%;
  background-repeat: no-repeat;
  background-size: 0% 2px;
  padding-bottom: 3px;
  transition: background-size 0.35s var(--ease-snappy);
}

@media (hover: hover) {
  a:hover > .link-underline {
    background-size: 100% 2px;
  }
}

/* ==========================================================================
   Sistema icone dot-matrix (3, sygnatura grafiky)
   Markup: <svg class="dot-icon"><use href="#dot-icon-NOME"/></svg>, sprite
   nascosto in cima al <body>. Un solo posto per la dimensione/colore,
   quattro simboli, una sola gramatyka.
   ========================================================================== */
.dot-icon {
  width: 28px;
  height: 28px;
  fill: currentColor;
  flex-shrink: 0;
}

/* ==========================================================================
   2. Hero
   ========================================================================== */
.hero {
  position: relative;
  min-height: 100svh;
  background: var(--carbon);
  color: var(--bone);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-top: var(--header-h);
  /* Riserva per .hero-status, ancorato in absolute in fondo alla sezione
     (vedi sotto): senza questo spazio .hero-content (flex-end) e la barra
     di stato si sovrapporrebbero. A 1366x860 il contenuto reale (~460px:
     H1 tre righe + lead + CTA) stava ben dentro i margini, ma i vecchi
     padding verticali di .hero-content SOMMATI a questo spazio facevano
     crescere .hero oltre 100svh (misurato: 968px), spingendo .hero-status
     sotto la piega.
     Max alzato 5rem -> 6.25rem: a 1366px (dove il clamp resta sul tetto)
     lasciava solo ~-3px tra il fondo di .hero-ctas e l'inizio di
     .hero-status (misurato a 1366x860 e 1366x768, sovrapposizione).
     6.25rem = 100px dà >=12px di distacco reale su entrambe le altezze,
     senza far crescere .hero oltre 100svh (margine verificato ~87px a
     768px di altezza). */
  padding-bottom: clamp(4rem, 8vw, 6.25rem);
  overflow: hidden;
}

/* Warstwa wideo: pod kanwą ambient (z-index 0, ale WCZEŚNIEJ w DOM niż
   .hero-canvas-wrap, więc przy tym samym z-index canvas maluje się na
   wierzchu), nad tłem karbonowym sekcji. */
.hero-video-wrap {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--carbon);
}

.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Wspólny język z duotone La Rete/Il Porto: przygaszone, zdesaturowane,
     zimne — wideo nie może konkurować kontrastowo z H1/CTA/paskiem
     statusu narysowanymi nad nim. */
  filter: grayscale(0.3) brightness(0.52) contrast(1.06);
}

.hero-video-gradient {
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
}

.hero-video-gradient--bottom {
  bottom: 0;
  height: 78%;
  /* Stopniowane, nie liniowe: dolne ~35% (gdzie siedzi .hero-status) musi
     zostać czytelne niezależnie od tego, jak jasna jest klatka wideo w tym
     momencie (zweryfikowane próbkowaniem klatki przy t≈5s, najjaśniejszej
     w materiale). */
  background: linear-gradient(
    180deg,
    rgba(19, 17, 16, 0) 0%,
    rgba(19, 17, 16, 0.32) 30%,
    rgba(19, 17, 16, 0.68) 58%,
    rgba(19, 17, 16, 0.94) 82%,
    rgba(19, 17, 16, 0.98) 100%
  );
}

.hero-video-gradient--top {
  top: 0;
  height: 32%;
  background: linear-gradient(180deg, rgba(19, 17, 16, 0.5) 0%, rgba(19, 17, 16, 0) 100%);
}

.hero-canvas-wrap {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero-canvas-wrap canvas {
  width: 100%;
  height: 100%;
}

.hero-content {
  position: relative;
  z-index: 2;
  /* Solo padding orizzontale: quello verticale viveva qui PRIMA, sommato a
     padding-top/padding-bottom di .hero (header-h + riserva status) —
     doppio conteggio che faceva crescere la sezione oltre 100svh. */
  padding: 0 clamp(1.25rem, 4vw, 3rem);
  max-width: 1680px;
  margin: 0 auto;
  width: 100%;
}

.hero-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  letter-spacing: -0.035em;
  font-size: clamp(2.6rem, 7.4vw, 6rem);
  line-height: 0.98;
  /* Era max-width:62% (letterale "~60% szerokości" del thesis). Misurato:
     a wdth125/900/6rem, "UN SOLO CORRIERE." ha bisogno di ~1237px, ma il
     62% di .hero-content a 1366px dava solo ~778px — la riga wrappava
     internamente in "UN SOLO" + "CORRIERE.", trasformando le 3 righe
     mascherate autorali in 5 righe reali e gonfiando .hero ben oltre
     100svh (radice del bug .hero-status invisibile a 1366x860/768).
     Nessun limite qui: il box resta comunque legato al max-width:1680px +
     padding di .hero-content, che a schermi larghi (>=1776px) riproduce
     da solo una proporzione vicina al 60% originale — qui sotto quella
     soglia il titolo usa più spazio, ma resta 3 righe vere, mai 5. */
  color: var(--bone);
}

.hero-line {
  display: block;
  overflow: hidden;
}

.hero-line-inner {
  display: block;
  will-change: transform;
}

.hero-lead {
  margin-top: clamp(1.4rem, 3vw, 2rem);
  max-width: 42ch;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  color: var(--on-carbon-muted);
}

.hero-ctas {
  margin-top: clamp(1.8rem, 4vw, 2.6rem);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.hero-status {
  /* Ancorato in absolute in fondo alla sezione, fuori dal flusso flex di
     .hero-content: garantisce che la barra KM/H sia sempre nel primo
     viewport, indipendentemente da quanto cresce il contenuto sopra
     (entro i limiti della riserva padding-bottom di .hero). */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  border-top: 1px solid var(--carbon-line);
  padding: clamp(0.9rem, 2vw, 1.2rem) clamp(1.25rem, 4vw, 3rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: clamp(0.68rem, 1.3vw, 0.8rem);
  letter-spacing: 0.06em;
  color: var(--on-carbon-muted);
}

.hero-status-left {
  display: flex;
  align-items: baseline;
  gap: 0.8em;
}

.hero-speed {
  color: var(--red);
  font-size: 1.15em;
  font-weight: 400;
}

.hero-status-right {
  color: var(--on-carbon-faint);
}

@media (max-width: 899px) {
  .hero-title {
    max-width: 100%;
  }
}

@media (max-width: 480px) {
  .hero {
    /* .hero-status va su due righe qui sotto: la riserva deve crescere di
       conseguenza o la seconda riga (BOLOGNA HQ...) uscirebbe dal fondo
       della sezione. */
    padding-bottom: clamp(5.5rem, 20vw, 7rem);
  }

  .hero-status {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
  }
}

/* ==========================================================================
   Mosty świetlne (tonal bridges) tra sezioni
   Sostituiscono i vecchi tween scrubbati di background-color (demo.js,
   initTonalTransitions — rimossa): non più un colore piatto che insegue lo
   scroll, ma una rampa gradiente STATICA e alta (~130vh) all'inizio della
   sezione entrante, come l'atmosfera-globo di unitedcarriers.com. Le
   sezioni sotto hanno di nuovo sfondi statici puri (bez JS) — il ponte
   stesso porta lo sguardo dal colore della sezione precedente a quello
   della sezione che segue.
   Un solo hue di marca lungo tutta la rampa (karbon -> bordeaux -> rosso
   BRT "orizzonte" -> caldo -> kość o viceversa) — non un arcobaleno.
   Posizionato assoluto, DIETRO al contenuto testuale (z-index negativo):
   il testo di ciascuna sezione vive nel padding-top, sotto al ponte (vedi
   il padding-top di ciascuna sezione più sotto), non sopra di esso.
   ========================================================================== */
.tonal-bridge {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 130vh;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

/* karbon -> kość (hero->intro, viaggio->servizi): buio che sale verso la luce. */
.tonal-bridge--hero-intro,
.tonal-bridge--viaggio-servizi {
  background: linear-gradient(
    180deg,
    #131110 0%,
    #4a060f 28%,
    #8f0d14 40%,
    #e2001a 50%,
    #f2c9b4 64%,
    #f4f1ec 100%
  );
}

/* Il porto -> La rete: la "czerwona powódź" com'era pensata all'origine,
   ora come rampa statica invece di uno scrub — karbon -> bordeaux -> rosso
   pieno esattamente al bordo con .rete (che è già rossa di suo, nessun
   salto di colore alla fine del ponte). */
.tonal-bridge--porto-rete {
  background: linear-gradient(180deg, #131110 0%, #4a060f 45%, #a30f16 75%, #e2001a 100%);
}

/* La rete -> Dicono di noi: il rosso si spegne verso la kość (sezione
   opinioni). Monotona in luminanza — niente tappa bordeaux tra rosso e
   caldo (sarebbe un buco: bordeaux è PIÙ scuro del rosso stesso). */
.tonal-bridge--rete-dicono {
  background: linear-gradient(180deg, #e2001a 0%, #ee6f56 30%, #f2c9b4 55%, #f4f1ec 100%);
}

/* kość -> karbon: luce che si spegne nel buio. Condivisa da due giunzioni
   con lo stesso identico verso (intro->viaggio, dicono/partner->in
   movimento) — stesso hue, stessa direzione, un solo posto da mantenere. */
.tonal-bridge--intro-viaggio,
.tonal-bridge--dicono-inmovimento {
  background: linear-gradient(
    180deg,
    #f4f1ec 0%,
    #f2c9b4 36%,
    #e2001a 50%,
    #8f0d14 60%,
    #4a060f 72%,
    #131110 100%
  );
}

/* Bagliore radiale ("horizon glow", come la poświata del globo su
   unitedcarriers.com): solo sui due ponti con più powera drammatico
   (apertura del sito, arrivo alla Rete). Sfumato tramite gli stop del
   gradiente stesso (alpha che cala gradualmente), MAI filter:blur — quello
   costerebbe un intero layer di compositing in più su un elemento già
   enorme (130vh). */
.tonal-bridge-glow {
  position: absolute;
  left: 50%;
  width: 140vw;
  height: 60vh;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    ellipse at center,
    rgba(226, 0, 26, 0.18) 0%,
    rgba(226, 0, 26, 0.09) 40%,
    rgba(226, 0, 26, 0) 72%
  );
  will-change: transform;
}

/* Centrato sul punto di massima saturazione rossa di ciascuna rampa (vedi
   gli stop % sopra: 50% per hero-intro, ~90% per porto-rete — lì il rosso
   è più vicino al bordo con .rete, non al centro del ponte). */
.tonal-bridge-glow--hero-intro {
  top: 50%;
}

.tonal-bridge-glow--porto-rete {
  top: 90%;
}

/* ==========================================================================
   3. Intro
   ========================================================================== */
.intro {
  background: var(--bone);
  color: var(--carbon);
  position: relative;
  /* Senza questo la sezione non crea un proprio stacking context: il
     .tonal-bridge con z-index:-1 dentro sfuggirebbe al contesto ROOT,
     dipingendosi PRIMA (sotto) del background opaco della sezione stessa
     invece che sopra di esso — invisibile anche se il gradiente in sé è
     corretto (verificato: bug reale, non solo teorico). */
  isolation: isolate;
  padding: clamp(1.25rem, 4vw, 3rem);
  /* Riserva per il tonal-bridge (130vh, absolute, vedi sopra): il testo
     deve restare sotto di esso, mai sovrapposto. 140svh = altezza ponte +
     10svh di margine reale, verificato via rect del primo elemento di
     testo (.intro-heading). */
  padding-top: max(clamp(4.5rem, 10vw, 8rem), 140svh);
  /* (C) Ridotto da un clamp fino a 8rem: da fine testo a inizio rampa
     intro->viaggio deve restare ~20vh, non un vuoto enorme prima. */
  padding-bottom: 20vh;
}

/* (C) Ricomposizione: griglia 12 colonne. Foto/H2/lead in flusso naturale
   nella colonna sinistra (span 6, righe 1-3 implicite); .intro-side
   (prosa+footnote) esplicitamente in riga 2 — la STESSA riga di
   .intro-heading, non della foto — così il suo bordo superiore combacia
   con quello dell'headline, non con la foto sopra di esso. */
.intro-inner {
  max-width: 1680px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: clamp(1.5rem, 3vw, 2.5rem);
  row-gap: clamp(1.4rem, 3vw, 2rem);
}

.intro-photo {
  grid-column: 1 / 7;
  width: clamp(220px, 24vw, 300px);
  aspect-ratio: 3 / 2;
  overflow: hidden;
  box-shadow: 0 1rem 2.5rem rgba(19, 17, 16, 0.22);
}

.intro-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.intro-heading {
  grid-column: 1 / 7;
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 118;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(2rem, 4.4vw, 3.4rem);
  line-height: 1.06;
}

.intro-text {
  grid-column: 1 / 7;
  font-size: 1.05rem;
  color: var(--on-bone-muted);
}

.intro-side {
  grid-column: 8 / 13;
  grid-row: 2;
}

/* Prosa editoriale con numeri inline, non il template "numero enorme +
   etichetta piccola" (già usato in .rete-stats — ripeterlo qui sarebbe
   stato il grid-di-card-vuote dei numeri, lo stesso schema due volte). */
.intro-prose {
  font-family: var(--font-display);
  font-weight: 700;
  font-variation-settings: "wdth" 108;
  font-size: clamp(1.4rem, 2.8vw, 2.05rem);
  line-height: 1.34;
  color: var(--carbon);
  max-width: 26ch;
}

.intro-num {
  display: inline-block;
  font-family: var(--font-mono);
  font-weight: 400;
  color: var(--red);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
  white-space: nowrap;
}

.intro-footnote {
  margin-top: clamp(1.6rem, 3vw, 2rem);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--on-bone-faint);
}

@media (max-width: 899px) {
  /* Mobile: una sola colonna, ordine di lettura naturale (foto, H2, lead,
     prosa, footnote), nessun vuoto da allineamenti a griglia che qui non
     servono più. */
  .intro-inner {
    display: block;
  }

  .intro-photo {
    width: 100%;
    max-width: 300px;
  }

  .intro-heading,
  .intro-text {
    margin-top: clamp(1.4rem, 3vw, 2rem);
  }

  .intro-side {
    margin-top: clamp(1.4rem, 3vw, 2rem);
  }
}

/* ==========================================================================
   4. Il viaggio (pin + scrub)
   ========================================================================== */
.viaggio {
  background: var(--carbon);
  color: var(--bone);
  position: relative;
  /* Stesso motivo di .intro: senza isolation il tonal-bridge z-index:-1
     sfugge al contesto ROOT invece di dipingersi sopra questo background.
     .viaggio-pin diventa position:fixed durante il pin (GSAP) — resta
     comunque un discendente, quindi la sua stacking finisce dentro questo
     contesto isolato; ma .viaggio, come blocco intero, dipinge comunque
     al proprio posto nell'ordine DOM tra i fratelli a livello ROOT (stessa
     posizione di prima), e durante il pin nessun'altra sezione occupa lo
     stesso spazio schermo — verificato via elementFromPoint che il pin
     resta l'elemento più in alto al centro del viewport durante lo scrub. */
  isolation: isolate;
  padding-top: 140vh;
}

.viaggio-pin {
  height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.viaggio-inner {
  max-width: 1680px;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 3rem);
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.viaggio-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 118;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  color: var(--on-carbon-muted);
  margin-bottom: clamp(1.6rem, 4vw, 2.6rem);
}

.viaggio-steps {
  display: flex;
  gap: clamp(1rem, 2vw, 1.6rem);
}

.viaggio-progress-track {
  width: 2px;
  background: var(--carbon-line);
  flex-shrink: 0;
  position: relative;
}

.viaggio-progress-line {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0%;
  background: var(--red);
  transform-origin: top;
}

.viaggio-step-list {
  display: grid;
  gap: clamp(1.6rem, 3.4vw, 2.6rem);
}

.viaggio-step {
  opacity: 0.32;
}

.viaggio-step[data-active] {
  opacity: 1;
}

/* Transition CSS na opacity tylko tam, gdzie to CSS steruje przejściem
   (pin desktopowy, data-active przełączane wg progressu scrolla). Na
   mobile initViaggioSimple() (demo.js) animuje tę samą właściwość przez
   GSAP na inline stylu: CSS transition na tym samym property walczyłoby z
   każdym klatkowym zapisem GSAP (nowy transition-chase co tick), więc
   wizualnie opacity nigdy nie dojeżdżało do 1 mimo ukończonego tweenu. */
@media (min-width: 1024px) {
  .viaggio-step {
    transition: opacity 0.4s var(--ease-snappy);
  }
}

.viaggio-step-num {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--red);
}

.viaggio-step-title {
  margin-top: 0.35rem;
  font-family: var(--font-display);
  font-weight: 800;
  font-variation-settings: "wdth" 112;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: clamp(1.05rem, 2vw, 1.3rem);
}

.viaggio-step-desc {
  margin-top: 0.4rem;
  font-size: 0.92rem;
  color: var(--on-carbon-muted);
  max-width: 34ch;
}

.viaggio-canvas-wrap {
  position: relative;
  /* Era 4/3 (paesaggio): con la vera sagoma d'Italia (B, verticale, non
     un'astratta diagonale) dava un canvas troppo corto — l'80-90% della
     sua altezza restava sotto i ~450px anche su viewport larghi, la
     "gamba" dello stivale si leggeva a malapena. 1/1 (quadrato) sfrutta
     meglio l'altezza disponibile nel pin (100svh, ampio margine) restando
     comunque dentro ai limiti anche vicino al breakpoint mobile. */
  aspect-ratio: 1 / 1;
  width: 100%;
}

.viaggio-canvas-wrap canvas {
  width: 100%;
  height: 100%;
}

@media (max-width: 1023px) {
  .viaggio-pin {
    height: auto;
    padding: clamp(3.5rem, 9vw, 6rem) 0;
  }

  .viaggio-inner {
    grid-template-columns: 1fr;
  }

  .viaggio-canvas-wrap {
    order: -1;
    aspect-ratio: 16 / 11;
  }

  .viaggio-step {
    opacity: 1;
  }
}

/* ==========================================================================
   5. Servizi (lista edytorska, nie karty)
   ========================================================================== */
.servizi {
  background: var(--bone);
  color: var(--carbon);
  position: relative;
  isolation: isolate;
  padding: clamp(4.5rem, 10vw, 8rem) clamp(1.25rem, 4vw, 3rem);
  /* Vedi commento su .intro: stesso ponte, stessa riserva. */
  padding-top: max(clamp(4.5rem, 10vw, 8rem), 140svh);
}

.servizi-inner {
  max-width: 1680px;
  margin: 0 auto;
}

.servizi-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 118;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(2rem, 4.4vw, 3.4rem);
  line-height: 1.06;
  margin-bottom: clamp(2rem, 5vw, 3rem);
  max-width: 20ch;
}

.servizi-list {
  border-top: 1px solid rgba(19, 17, 16, 0.14);
}

.servizi-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: clamp(1.8rem, 4vw, 3rem) clamp(0.4rem, 2vw, 1rem);
  overflow: hidden;
}

/* Separatore disegnato (E, demo.js initServizi): sostituisce il vecchio
   border-bottom statico. Di default già "disegnato" (scaleX:1, tramite
   transform-origin:left non serve nemmeno lo scaleX esplicito qui) — se
   JS non parte (no-script, errore) la riga resta comunque intera; demo.js
   la porta a scaleX:0 all'avvio e la ridisegna in ingresso. */
.servizi-row-line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: rgba(19, 17, 16, 0.14);
  transform-origin: left center;
  z-index: 1;
}

.servizi-row-bg {
  position: absolute;
  inset: 0;
  background: var(--red);
  transform: scaleY(0);
  transform-origin: bottom;
  z-index: 0;
  pointer-events: none;
}

.servizi-row-text {
  /* Prima .servizi-row-title/-desc erano <span> inline: partivano nello
     stesso line-box, il margin-top dell'opis non aveva effetto e su
     375px "INTERNAZIONALE" più l'inizio della descrizione finivano nella
     stessa riga lunghissima, tagliata da overflow:hidden della riga.
     flex column + min-width:0 (per permettere il wrap dentro un flex
     item) risolve entrambi i problemi. */
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
  transition: transform 0.4s var(--ease-snappy), color 0.3s var(--ease-snappy);
}

.servizi-row-title {
  display: block;
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 122;
  text-transform: uppercase;
  letter-spacing: -0.025em;
  font-size: clamp(1.9rem, 5.4vw, 4rem);
  line-height: 1.08;
  overflow-wrap: break-word;
}

.servizi-row-desc {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.98rem;
  color: var(--on-bone-muted);
  max-width: 52ch;
  transition: color 0.3s var(--ease-snappy);
}

.servizi-row-arrow {
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  transition: transform 0.4s var(--ease-snappy), color 0.3s var(--ease-snappy);
  color: var(--carbon);
}

@media (hover: hover) {
  .servizi-row:hover .servizi-row-bg {
    transform: scaleY(1);
    transition: transform 0.45s var(--ease-snappy);
  }

  .servizi-row:hover .servizi-row-text {
    transform: translateX(8px);
    color: #fff;
  }

  .servizi-row:hover .servizi-row-desc {
    color: var(--on-red-soft);
  }

  .servizi-row:hover .servizi-row-arrow {
    transform: translateX(10px);
    color: #fff;
  }
}

@media (max-width: 767px) {
  .servizi-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
  }
}

/* ==========================================================================
   5a. La linea (scena pinnata: camion in corsa -> pas nero -> vista dall'alto)
   Tło kość, eredita da .servizi: nessun tween di colore su questo confine
   (vedi demo.js initTonalTransitions, boundary rimossa). Il confine verso
   Il porto è la scena stessa: la vista dall'alto finisce su nero pieno,
   .porto parte già su --carbon — nessun seam da smussare via JS.
   ========================================================================== */
.la-linea {
  background: var(--bone);
  color: var(--carbon);
  position: relative;
}

/* Toggle non scrubbato (demo.js, ScrollTrigger onEnter/onLeaveBack
   indipendente dal timeline del pin): niente ritardo da scrub:1 durante
   uno scroll veloce, vedi commento "Polish 3" in initLaLinea(). Nessuna
   transition qui apposta: il salto dev'essere immediato, non un'altra
   animazione da inseguire. */
.la-linea--blackout {
  background-color: var(--carbon);
}

.la-linea-pin {
  height: 100svh;
  position: relative;
  overflow: hidden;
}

.la-linea-road {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 24vh;
  background: var(--carbon);
  overflow: hidden;
  z-index: 1;
  will-change: height;
}

.la-linea-road-stripes {
  position: absolute;
  top: 50%;
  left: -10%;
  width: 220%;
  height: 6px;
  transform: translateY(-50%);
  background-image: repeating-linear-gradient(
    90deg,
    var(--bone) 0,
    var(--bone) 60px,
    transparent 60px,
    transparent 140px
  );
  opacity: 0.45;
  will-change: background-position;
}

/* Watermark gigante: base già in posizione di fine-fase-1 (x:40vw), GSAP
   prende il controllo da lì — nessun flash di posizione sbagliata prima
   che demo.js inizializzi. */
.la-linea-watermark {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(40vw, -50%);
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  font-size: 20vw;
  line-height: 1;
  white-space: nowrap;
  color: var(--bone-dim);
  z-index: 2;
  pointer-events: none;
  will-change: transform;
}

.la-linea-truck-wrap {
  position: absolute;
  left: 50%;
  bottom: 24vh;
  z-index: 3;
  transform: translateX(-50%);
  pointer-events: none;
  will-change: transform, opacity;
}

.la-linea-truck {
  display: block;
  width: max(480px, 55vw);
  height: auto;
}

.la-linea-pin .la-linea-content {
  position: absolute;
  top: calc(var(--header-h) + clamp(1.5rem, 4vw, 3rem));
  left: clamp(1.25rem, 4vw, 3rem);
  z-index: 5;
  max-width: 30ch;
}

.la-linea-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 118;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(2rem, 4.4vw, 3.4rem);
  line-height: 1.02;
  color: var(--carbon);
}

.la-linea-lead {
  margin-top: 0.9rem;
  font-size: clamp(0.95rem, 1.4vw, 1.1rem);
  color: var(--on-bone-muted);
  max-width: 34ch;
}

.la-linea-speed {
  position: absolute;
  top: calc(var(--header-h) + clamp(1.5rem, 4vw, 3rem));
  right: clamp(1.25rem, 4vw, 3rem);
  z-index: 5;
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-bone-muted);
}

.la-linea-speed [data-speed-value] {
  color: var(--red);
}

/* Fase 4 (vista dall'alto): sopra il pas che nel frattempo è cresciuto a
   height:100% (pieno nero) — z-index sopra camion/watermark laterali, che
   a quel punto sono comunque già fuori scena (opacity:0, fuori schermo). */
.la-linea-topdown {
  position: absolute;
  inset: 0;
  z-index: 4;
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}

.la-linea-topdown-road {
  position: absolute;
  top: 0;
  left: 50%;
  width: 34vw;
  height: 100%;
  transform: translateX(-50%);
  /* Nero pieno, un filo più scuro del --carbon (#131110) tutto intorno:
     "corsia" leggibile anche su fondo già pressoché nero. */
  background: #000;
  overflow: hidden;
}

.la-linea-topdown-stripes {
  position: absolute;
  left: 50%;
  top: -20%;
  width: 6px;
  height: 140%;
  transform: translateX(-50%);
  background-image: repeating-linear-gradient(
    180deg,
    var(--bone) 0,
    var(--bone) 40px,
    transparent 40px,
    transparent 110px
  );
  opacity: 0.3;
  will-change: transform;
}

.la-linea-truck-top {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  /* Sorgente orizzontale 1600x913: larghezza calcolata perché DOPO la
     rotazione di 90deg l'impronta visiva risulti larga ~13vw (1600/913 ≈
     1.7524, il fattore che scambia altezza <-> larghezza tra pre e post
     rotazione). */
  width: calc(13vw * 1.7524);
  height: auto;
  will-change: transform;
}

/* ---------- Mobile / reduced-motion: composizione statica, niente pin ---------- */
.la-linea-static {
  display: none;
  background: var(--bone);
  color: var(--carbon);
  padding: clamp(4.5rem, 10vw, 7rem) clamp(1.25rem, 4vw, 3rem);
}

.la-linea-static .la-linea-content {
  max-width: 34ch;
}

.la-linea-static-road {
  position: relative;
  margin-top: clamp(2rem, 6vw, 3rem);
  height: clamp(9rem, 30vw, 13rem);
  background: var(--carbon);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.la-linea-static-truck {
  width: min(78%, 420px);
  height: auto;
  margin-bottom: -1px;
}

@media (max-width: 1023px), (prefers-reduced-motion: reduce) {
  .la-linea-pin {
    display: none;
  }

  .la-linea-static {
    display: block;
  }
}

/* ==========================================================================
   5b. Il porto (sekwencja klatek, pin desktop / statyczna klatka mobile)
   Karbon celowo: Servizi jest na kości, La rete jest czerwona, więc ta
   sekcja pośrednia utrzymuje przeplot tonalny (kość -> karbon -> czerwień).
   ========================================================================== */
.porto {
  background: var(--carbon);
  color: var(--bone);
  position: relative;
}

.porto-pin {
  position: relative;
  height: 100svh;
  overflow: hidden;
}

.porto-canvas-wrap {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--carbon);
}

.porto-canvas-wrap canvas {
  width: 100%;
  height: 100%;
  display: block;
}

/* Container che "cala" nei primi 30% del pin (B, demo.js initPortoPinned):
   sopra la kanwa dei fotogrammi, sotto il gradiente/testo — pos/alpha
   interamente pilotati dal progress dello ScrollTrigger (reversibile). */
.porto-container-wrap {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.porto-container {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 32vw;
  height: auto;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 2.5vw 2.5vw rgba(0, 0, 0, 0.45));
  will-change: transform, opacity;
}

.porto-gradient {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(19, 17, 16, 0) 35%,
    rgba(19, 17, 16, 0.55) 66%,
    rgba(19, 17, 16, 0.94) 100%
  );
}

.porto-content {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 0 clamp(1.25rem, 4vw, 3rem) clamp(3.2rem, 7vw, 5rem);
  max-width: 1680px;
  margin: 0 auto;
}

.porto-label {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-carbon-muted);
  margin-bottom: 0.9rem;
}

.porto-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 122;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(2.2rem, 5.6vw, 5rem);
  line-height: 1.02;
  max-width: 18ch;
  color: var(--bone);
}

.porto-lead {
  margin-top: 1rem;
  max-width: 46ch;
  font-size: clamp(0.98rem, 1.4vw, 1.1rem);
  color: var(--on-carbon-muted);
}

.porto-progress-track {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--carbon-line);
  z-index: 3;
}

.porto-progress-line {
  height: 100%;
  width: 0%;
  background: var(--red);
}

/* "Perché noi" (4), come i blocchi why-us sopra l'oceano di
   unitedcarriers.com: 4 blocchi che appaiono in sequenza (demo.js,
   initPortoPinned/updateWhyBlocks) durante il progress 0.35-0.9 del pin,
   alternati sinistra/destra. z-index:2 = stesso layer di .porto-content
   (DOM prima di lui, quindi .porto-content vince in caso di sovrapposizione). */
.porto-why {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.porto-why-block {
  position: absolute;
  max-width: 30ch;
  padding: 1.5rem 1.75rem;
  opacity: 0;
  will-change: opacity, transform;
  /* Scrim locale (D): non un overlay globale sulla scena, un alone
     radiale dietro al SOLO blocco, che sfuma ai bordi invece di tagliare
     un rettangolo netto sopra le klatki. */
  background: radial-gradient(
    ellipse at center,
    rgba(19, 17, 16, 0.85) 0%,
    rgba(19, 17, 16, 0.85) 50%,
    rgba(19, 17, 16, 0) 100%
  );
}

.porto-why-block--left {
  left: clamp(0.5rem, 3vw, 2rem);
}

.porto-why-block--right {
  right: clamp(0.5rem, 3vw, 2rem);
  text-align: right;
}

.porto-why-block--right .porto-why-icon {
  margin-left: auto;
}

.porto-why-block--y1 {
  top: 16%;
}

.porto-why-block--y2 {
  top: 38%;
}

.porto-why-block--y3 {
  top: 58%;
}

.porto-why-block--y4 {
  top: 76%;
}

.porto-why-icon {
  display: block;
  color: var(--red);
  margin-bottom: 0.7rem;
}

.porto-why-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 118;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: clamp(1.1rem, 2vw, 1.4rem);
  color: var(--bone);
}

.porto-why-text {
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--on-carbon-muted);
}

@media (max-width: 1279px) {
  .porto-why-block {
    max-width: 24ch;
  }
}

/* Mobile <1024px e prefers-reduced-motion: figura statica, nessun pin. */
.porto-mobile {
  display: none;
  background: var(--carbon);
  color: var(--bone);
  padding: clamp(4.5rem, 10vw, 7rem) clamp(1.25rem, 4vw, 3rem);
}

.porto-mobile-media {
  margin-top: clamp(2rem, 6vw, 3rem);
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--carbon-line);
}

.porto-mobile-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* "Perché noi" mobile (4): lista semplice sotto la figura, niente scrim
   (sfondo già --carbon pieno, nessuna klatka viva da coprire). */
.porto-why-mobile {
  margin-top: clamp(2.5rem, 6vw, 3.5rem);
  display: grid;
  gap: clamp(1.6rem, 4vw, 2.2rem);
}

.porto-why-mobile-item .porto-why-icon {
  color: var(--red);
  margin-bottom: 0.6rem;
}

.porto-why-mobile-item .porto-why-title {
  font-size: 1.05rem;
}

.porto-noscript-fallback {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 1023px), (prefers-reduced-motion: reduce) {
  .porto-pin {
    display: none;
  }

  .porto-mobile {
    display: block;
  }

  .porto-noscript-fallback {
    display: none;
  }
}

/* ==========================================================================
   6. La rete (drenched red)
   ========================================================================== */
.rete {
  position: relative;
  /* .rete-media-overlay (dentro .rete-media, più sotto in questa sezione)
     ha mix-blend-mode:multiply col video dietro: quel blend è LOCALE tra
     due fratelli assoluti dentro .rete-media-inner, non tocca nulla fuori
     da .rete-media — isolation qui, su un antenato lontano, non cambia il
     backdrop immediato del blend (verificato via campionamento pixel). */
  isolation: isolate;
  background: var(--red);
  color: #fff;
  padding: clamp(4.5rem, 10vw, 8rem) clamp(1.25rem, 4vw, 3rem);
  /* Riserva per il tonal-bridge--porto-rete (130vh): la "czerwona powódź"
     ora vive qui, statica, non nel vecchio scrub. */
  padding-top: max(clamp(4.5rem, 10vw, 8rem), 140svh);
  overflow: hidden;
}

.rete-pattern {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(var(--red-deep) 1.4px, transparent 1.4px);
  background-size: 26px 26px;
  opacity: 0.4;
}

.rete-inner {
  position: relative;
  z-index: 1;
  max-width: 1680px;
  margin: 0 auto;
}

.rete-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  letter-spacing: -0.035em;
  font-size: clamp(2.4rem, 6.6vw, 5.6rem);
  line-height: 0.98;
  color: var(--on-red-strong);
  max-width: 16ch;
}

.rete-stats {
  margin-top: clamp(2.4rem, 5vw, 3.6rem);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.6rem, 4vw, 3rem);
  border-top: 1px solid rgba(255, 255, 255, 0.28);
  padding-top: clamp(1.6rem, 3vw, 2.2rem);
}

.rete-stat-number {
  font-family: var(--font-mono);
  font-size: clamp(1.8rem, 4.6vw, 3.2rem);
  color: var(--on-red-strong);
  line-height: 1;
}

.rete-stat-label {
  margin-top: 0.5rem;
  font-size: 0.86rem;
  letter-spacing: 0.03em;
  color: var(--on-red-large);
}

.rete-footnote {
  margin-top: clamp(1.4rem, 3vw, 2rem);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--on-red-large);
}

.rete-body {
  margin-top: clamp(1.4rem, 3vw, 2rem);
  font-size: 1.02rem;
  color: var(--on-red-soft);
  max-width: 48ch;
}

.rete-media {
  margin-top: clamp(3rem, 6vw, 4.5rem);
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.24);
}

.rete-media-inner {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

/* La rete ha ora un video (cabina notturna, cruscotto già rosso su nero)
   al posto della foto statica del magazzino. Il duotone precedente
   (grayscale(1) + multiply rosso PIENO) qui spegnerebbe la luce del
   cruscotto — il materiale ha già il colore giusto, va solo spostato
   verso la palette, non sostituito. Desaturazione parziale sul video +
   gradiente rosso->karbon in multiply a bassa opacità sopra. Verificato
   con campionamento pixel (fetch del file + canvas) che il risultato non
   deriva verso l'oliva come il primo tentativo sulla foto Unsplash. */
.rete-media video,
.rete-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.15) brightness(0.85);
}

.rete-media-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, var(--red), var(--carbon));
  mix-blend-mode: multiply;
  opacity: 0.35;
}

.rete-media-caption {
  position: absolute;
  left: 0;
  bottom: 0;
  padding: 0.6rem clamp(1rem, 2vw, 1.5rem);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.95);
  /* Chip opaco: prima la leggibilità dipendeva dal gradiente rimosso
     sopra. Ora il fondo è indipendente da cosa c'è nell'immagine sotto. */
  background: rgba(19, 17, 16, 0.82);
}

@media (max-width: 767px) {
  .rete-stats {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   6b. Dicono di noi + rete partner (5, 6)
   ========================================================================== */
.dicono {
  background: var(--bone);
  color: var(--carbon);
  position: relative;
  isolation: isolate;
  padding: clamp(4.5rem, 10vw, 8rem) clamp(1.25rem, 4vw, 3rem);
  padding-top: max(clamp(4.5rem, 10vw, 8rem), 140svh);
}

.dicono-inner {
  max-width: 1680px;
  margin: 0 auto;
}

.dicono-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 118;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(1.8rem, 3.6vw, 2.8rem);
  line-height: 1.06;
  margin-bottom: clamp(2rem, 5vw, 3rem);
}

.dicono-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2.5rem, 6vw, 5rem);
}

.dicono-item {
  position: relative;
}

/* Cudzysłów wyrazisty (5): niente corsivo (assente nella famiglia Archivo
   caricata) — enfasi tramite dimensione, non stile. */
.dicono-quote-mark {
  display: block;
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 100;
  font-size: clamp(3.5rem, 7vw, 5.5rem);
  line-height: 0.6;
  color: var(--red);
  margin-bottom: 0.4rem;
}

.dicono-quote {
  font-weight: 400;
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  line-height: 1.4;
  color: var(--carbon);
  max-width: 32ch;
}

.dicono-author {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.dicono-author-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-size: 0.76rem;
  letter-spacing: 0.02em;
}

.dicono-author-role {
  font-size: 0.86rem;
  color: var(--on-bone-muted);
  max-width: 28ch;
}

.dicono-footnote {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--on-bone-faint);
}

@media (max-width: 767px) {
  .dicono-list {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }
}

/* --- Pasek partnerów (6): hairline-grid di wordmarki testuali --- */
.partner-bar {
  position: relative;
  max-width: 1680px;
  margin: clamp(3.5rem, 8vw, 6rem) auto 0;
  padding-top: clamp(2rem, 5vw, 3rem);
  border-top: 1px solid rgba(19, 17, 16, 0.14);
}

.partner-bar-heading {
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-bone-faint);
  margin-bottom: clamp(1.5rem, 3vw, 2rem);
}

.partner-bar-list {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  border-top: 1px solid rgba(19, 17, 16, 0.14);
  border-left: 1px solid rgba(19, 17, 16, 0.14);
}

.partner-bar-item {
  padding: clamp(1.25rem, 3vw, 1.75rem) 1rem;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: clamp(0.95rem, 1.8vw, 1.2rem);
  color: var(--on-bone-muted);
  border-right: 1px solid rgba(19, 17, 16, 0.14);
  border-bottom: 1px solid rgba(19, 17, 16, 0.14);
  transition: color 0.25s var(--ease-snappy);
}

@media (hover: hover) {
  .partner-bar-item:hover {
    color: var(--carbon);
  }
}

.partner-bar-note {
  margin-top: clamp(1.25rem, 3vw, 1.75rem);
  padding-bottom: clamp(1.25rem, 3vw, 1.75rem);
  font-size: 0.85rem;
  color: var(--on-bone-muted);
}

@media (max-width: 640px) {
  .partner-bar-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ==========================================================================
   6c. In movimento (news) + FAQ (7, 8)
   ========================================================================== */
.in-movimento {
  background: var(--carbon);
  color: var(--bone);
  position: relative;
  isolation: isolate;
  padding: clamp(4.5rem, 10vw, 8rem) clamp(1.25rem, 4vw, 3rem);
  padding-top: max(clamp(4.5rem, 10vw, 8rem), 140svh);
}

.in-movimento-inner {
  max-width: 1680px;
  margin: 0 auto;
}

.in-movimento-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  font-size: clamp(2rem, 4.4vw, 3.4rem);
  line-height: 1.06;
  margin-bottom: clamp(2rem, 5vw, 3rem);
}

.news-list {
  border-top: 1px solid var(--carbon-line);
}

.news-row {
  border-bottom: 1px solid var(--carbon-line);
}

.news-row-link {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2rem);
  padding: clamp(1.1rem, 2.5vw, 1.6rem) 0;
}

.news-row-date {
  flex-shrink: 0;
  width: 8ch;
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  color: var(--on-carbon-faint);
}

.news-row-title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: clamp(1rem, 1.8vw, 1.2rem);
  color: var(--bone);
}

/* Chip kategoria: bone su karbon appena schiarito — verificato >=4.5:1
   (testo piccolo). Un solo stile neutro per tutte e 4 le categorie: la
   differenza è nel testo, non in un sistema di colori nuovo fuori
   gramatyki. */
.news-row-chip {
  flex-shrink: 0;
  padding: 0.3rem 0.7rem;
  font-size: 0.64rem;
  letter-spacing: 0.06em;
  color: var(--bone);
  background: rgba(244, 241, 236, 0.12);
  border: 1px solid rgba(244, 241, 236, 0.22);
}

.news-row-arrow {
  flex-shrink: 0;
  color: var(--on-carbon-muted);
  transition: transform 0.3s var(--ease-snappy), color 0.25s var(--ease-snappy);
}

@media (hover: hover) {
  .news-row-link:hover .news-row-title {
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  .news-row-link:hover .news-row-arrow {
    transform: translateX(4px);
    color: var(--bone);
  }
}

.news-footer {
  margin-top: clamp(2rem, 5vw, 3rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}

.news-all-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bone);
  transition: color 0.25s var(--ease-snappy);
}

@media (hover: hover) {
  .news-all-link:hover {
    color: var(--red);
  }

  .news-all-link:hover .btn-arrow {
    transform: translateX(4px);
  }
}

.news-footnote {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--on-carbon-faint);
}

/* --- FAQ (8): akordeon button+region, un solo aperto alla volta --- */
.faq {
  max-width: 1680px;
  margin: clamp(4rem, 9vw, 7rem) auto 0;
  padding-top: clamp(3rem, 7vw, 5rem);
  border-top: 1px solid var(--carbon-line);
}

.faq-inner {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}

.faq-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 118;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
}

.faq-cta {
  margin-top: 1rem;
  font-size: 0.95rem;
  color: var(--on-carbon-muted);
  max-width: 28ch;
}

.faq-cta a {
  color: var(--red);
  font-weight: 700;
}

.faq-list {
  border-top: 1px solid var(--carbon-line);
}

.faq-item-heading {
  margin: 0;
}

.faq-item {
  border-bottom: 1px solid var(--carbon-line);
}

.faq-question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1.1rem, 2.5vw, 1.5rem) 0;
  text-align: left;
  font-family: var(--font-display);
  font-weight: 700;
  font-variation-settings: "wdth" 108;
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  color: var(--bone);
}

.faq-icon {
  position: relative;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
}

.faq-icon::before,
.faq-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: currentColor;
  transform: translate(-50%, -50%);
}

.faq-icon::before {
  width: 14px;
  height: 1.5px;
}

.faq-icon::after {
  width: 1.5px;
  height: 14px;
  transition: transform 0.3s var(--ease-snappy), opacity 0.3s var(--ease-snappy);
}

.faq-question[aria-expanded="true"] .faq-icon::after {
  transform: translate(-50%, -50%) rotate(90deg);
  opacity: 0;
}

/* Altezza animata (grid-template-rows 0fr->1fr): la classe .is-open è
   messa da demo.js sullo stesso elemento il cui aria-expanded cambia,
   niente dipendenza da :has() (supporto browser meno universale). */
.faq-answer {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows 0.4s var(--ease-snappy);
}

.faq-answer.is-open {
  grid-template-rows: 1fr;
}

.faq-answer-text {
  min-height: 0;
  overflow: hidden;
  padding-bottom: clamp(1.1rem, 2.5vw, 1.5rem);
  font-size: 0.95rem;
  color: var(--on-carbon-muted);
  max-width: 60ch;
}

@media (max-width: 899px) {
  .faq-inner {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   7. Contatti
   ========================================================================== */
.contatti {
  background: var(--carbon);
  color: var(--bone);
  position: relative;
  /* Non più giunzione con ramp (era rete->contatti, ora rete->dicono di
     mezzo — vedi .dicono): .in-movimento la precede, karbon->karbon,
     nessun ponte necessario. isolation resta per i .contatti-circles
     (z-index negativo, stesso motivo dei tonal-bridge altrove). */
  isolation: isolate;
  padding: clamp(5rem, 12vw, 9rem) clamp(1.25rem, 4vw, 3rem);
}

/* Cerchi concentrici (9), come READY TO MOVE SMARTER di unitedcarriers.com:
   dietro al titolo, non davanti — z-index negativo, isolate su .contatti
   sopra li tiene dipinti sopra al background della sezione. */
.contatti-circles {
  position: absolute;
  top: 50%;
  left: clamp(1.25rem, 4vw, 3rem);
  z-index: -1;
  width: min(60vw, 900px);
  aspect-ratio: 1;
  transform: translateY(-50%);
  pointer-events: none;
}

.contatti-circle {
  position: absolute;
  inset: 0;
  border: 1px solid rgba(226, 0, 26, 0.12);
  border-radius: 50%;
  transform: scale(0.9);
  opacity: 0;
  animation: contatti-circle-pulse 7s var(--ease-snappy) infinite;
}

.contatti-circle:nth-child(1) {
  animation-delay: 0s;
}

.contatti-circle:nth-child(2) {
  animation-delay: 1.4s;
}

.contatti-circle:nth-child(3) {
  animation-delay: 2.8s;
}

.contatti-circle:nth-child(4) {
  animation-delay: 4.2s;
}

.contatti-circle:nth-child(5) {
  animation-delay: 5.6s;
}

@keyframes contatti-circle-pulse {
  0% {
    transform: scale(0.9);
    opacity: 0;
  }
  15% {
    opacity: 1;
  }
  70% {
    opacity: 0.3;
  }
  100% {
    transform: scale(1.15);
    opacity: 0;
  }
}

/* Reduced-motion: già coperto dalla regola globale animation-duration a
   fine file, ma qui serve ANCHE lo stato finale statico (senza quella
   regola i cerchi resterebbero fermi al frame 0%: scale(0.9) opacity 0,
   cioè invisibili). Un solo cerchio ben visibile, fermo. */
@media (prefers-reduced-motion: reduce) {
  .contatti-circle {
    animation: none;
    transform: scale(1);
    opacity: 0.6;
  }
}

.contatti-inner {
  max-width: 1680px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
}

.contatti-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  letter-spacing: -0.035em;
  /* Era clamp(3rem, 10vw, 7.5rem): il massimo (7.5rem) superava il
     tetto display di 6rem, e a 375px "SPEDIAMO?" (9 caratteri, wdth 125)
     usciva dal viewport col punto interrogativo tagliato. Nuovo clamp
     verificato: il minimo tiene le 9 lettere dentro 375px, il massimo
     rispetta il tetto. */
  font-size: clamp(2.5rem, 13vw, 6rem);
  line-height: 0.94;
}

.contatti-info {
  margin-top: clamp(2rem, 5vw, 3rem);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 1rem 2.4rem;
}

.contatti-email {
  position: relative;
  display: inline-block;
  font-family: var(--font-mono);
  font-size: clamp(1.1rem, 2.6vw, 1.5rem);
  color: var(--red);
}

/* Sottolineatura disegnata (D/E, demo.js initContatti): scaleX 0->1 dopo
   il reveal del titolo. Indipendente da .link-underline (quella è
   l'underline a comparsa in :hover, questa è l'ingresso in scroll —
   proprietà diverse, nessun conflitto). */
.contatti-email-line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1px;
  height: 1px;
  background: currentColor;
  transform-origin: left center;
  pointer-events: none;
}

.contatti-phone,
.contatti-address {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  color: var(--on-carbon-muted);
}

/* ==========================================================================
   8. Footer
   ========================================================================== */
.site-footer {
  background: var(--carbon);
  color: var(--bone);
  border-top: 1px solid var(--carbon-line);
  padding: clamp(3rem, 6vw, 4.5rem) clamp(1.25rem, 4vw, 3rem) 0;
  overflow: hidden;
}

/* Marquee settori (10a): puro CSS (nessun bisogno del coupling velocity
   che ha il ticker in testa pagina), pausa in hover, duplicato
   aria-hidden per il loop continuo. */
.footer-marquee {
  max-width: 1680px;
  margin: 0 auto clamp(2rem, 5vw, 3rem);
  overflow: hidden;
}

.footer-marquee-track {
  display: flex;
  width: max-content;
  animation: footer-marquee-scroll 34s linear infinite;
}

@media (hover: hover) {
  .footer-marquee:hover .footer-marquee-track {
    animation-play-state: paused;
  }
}

@keyframes footer-marquee-scroll {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

.footer-marquee-item {
  flex-shrink: 0;
  white-space: nowrap;
  padding: 0 clamp(1.5rem, 4vw, 3rem);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-carbon-faint);
  border-right: 1px solid var(--carbon-line);
}

.footer-top {
  max-width: 1680px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2.4rem;
  padding-bottom: clamp(2rem, 5vw, 3rem);
  border-bottom: 1px solid var(--carbon-line);
}

/* Mini mappa rete (10b): canvas statico, stessa rete di .viaggio a
   progress=1 (demo.js, drawViaggioNetwork riusata), nessuna animazione. */
.footer-map {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  flex: 1 1 260px;
  max-width: 320px;
}

.footer-map-canvas {
  width: 100%;
  height: auto;
  aspect-ratio: 320 / 220;
  background: var(--carbon-soft);
  border: 1px solid var(--carbon-line);
  display: block;
}

.footer-map-caption {
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  color: var(--on-carbon-faint);
}

.footer-links {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.footer-links a {
  font-size: 0.95rem;
  color: var(--on-carbon-muted);
  transition: color 0.25s var(--ease-snappy);
  width: fit-content;
}

@media (hover: hover) {
  .footer-links a:hover {
    color: var(--bone);
  }
}

.footer-col-title {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-carbon-faint);
  margin-bottom: 0.9rem;
}

.footer-contact p {
  font-family: var(--font-mono);
  font-size: 0.86rem;
  color: var(--on-carbon-muted);
  margin-bottom: 0.5rem;
}

.footer-contact a:hover {
  color: var(--red);
}

.footer-wordmark {
  overflow: hidden;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
  line-height: 0.78;
}

.footer-word {
  display: block;
  font-family: var(--font-display);
  font-weight: 900;
  font-variation-settings: "wdth" 125;
  text-transform: uppercase;
  letter-spacing: -0.04em;
  font-size: clamp(5rem, 22vw, 15rem);
  color: var(--carbon-soft);
  -webkit-text-stroke: 1px rgba(244, 241, 236, 0.5);
}

.footer-letter {
  display: inline-block;
}

.footer-meta {
  max-width: 1680px;
  margin: 0 auto;
  display: flex;
  gap: 1.5rem;
  padding: 1.2rem 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--on-carbon-faint);
  border-top: 1px solid var(--carbon-line);
}

.footer-disclaimer {
  max-width: 1680px;
  margin: 0 auto;
  padding: 1rem 0 1.6rem;
  border-top: 1px solid var(--carbon-line);
}

.footer-disclaimer p {
  font-size: 0.82rem;
  color: var(--on-carbon-muted);
  max-width: 70ch;
  margin-bottom: 0.35rem;
}

.footer-disclaimer a {
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ==========================================================================
   Kursor własny
   ========================================================================== */
.cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  width: 76px;
  height: 76px;
  scale: 0.1;
  border-radius: 50%;
  background: var(--red);
  pointer-events: none;
  z-index: 600;
  display: none;
  opacity: 0;
  transition: scale 0.35s var(--ease-snappy), background-color 0.35s var(--ease-snappy), opacity 0.2s var(--ease-snappy);
}

@media (hover: hover) and (pointer: fine) {
  html.cursor-active .cursor-dot {
    display: block;
  }
}

.cursor-dot[data-state="hover"] {
  scale: 1;
  background: var(--carbon);
  mix-blend-mode: normal;
}

.cursor-dot-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bone);
  opacity: 0;
  transition: opacity 0.25s var(--ease-snappy);
}

.cursor-dot[data-state="hover"] .cursor-dot-label {
  opacity: 1;
}

/* ==========================================================================
   "La dorsale": most ciągłości, linia trasy w gutterze lewej krawędzi
   Rysowana (scaleY) całą wysokością dokumentu przez demo.js; węzły/etykiety
   też wstrzyknięte tam (pozycja zależy od realnych granic sekcji). Ukryta
   <768px: pod tą szerokością gutter znika (padding sekcji spada do samego
   dołu clampów, linia zaczęłaby nachodzić na kolumnę tekstu).
   ========================================================================== */
.dorsale {
  position: absolute;
  top: 0;
  left: 14px;
  z-index: 40;
  pointer-events: none;
}

.dorsale-line {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 100%;
  background: var(--red);
  opacity: 0.65;
  /* Stesso trucco dell'alone dei nodi (.dorsale-dot): una linea rossa pura
     ha poco contrasto proprio nella zona rossa dei tonal-bridge (rosso su
     rosso). L'alone chiaro dà un bordo leggibile lì; quello scuro lo fa
     restare leggibile su karbon/kość come prima. */
  box-shadow: 0 0 0 0.5px rgba(19, 17, 16, 0.4), 0 0 1px 0.5px rgba(244, 241, 236, 0.5);
  transform: scaleY(0);
  transform-origin: top;
}

/* Node = ancoraggio a dimensione zero sulla coordinata esatta del confine
   di sezione (top assegnato via JS); punto e etichetta sono posizionati
   assoluti rispetto a quest'ancora, non un flex (un flex-item con
   transform:translate(-50%) non si centra sul punto, si sfasa dalla sua
   riga: qui serve la coordinata esatta, non un centraggio approssimato). */
.dorsale-node {
  position: absolute;
  left: 0;
  width: 0;
  height: 0;
}

.dorsale-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--red);
  opacity: 0.4;
  transform: translate(-50%, -50%) scale(0.55);
  /* Dwustronna obwódka (ciemna + jasna): most przecina karbon, kość i
     czerwień — żaden pojedynczy kolor kropki miałby kontrast na wszystkich
     trzech tłach naraz, ta halo daje widoczną krawędź niezależnie od tła. */
  box-shadow: 0 0 0 1px rgba(19, 17, 16, 0.55), 0 0 0 2.5px rgba(244, 241, 236, 0.55);
  transition: transform 0.5s var(--ease-snappy), opacity 0.5s var(--ease-snappy);
}

.dorsale-node.is-active .dorsale-dot {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.dorsale-label {
  position: absolute;
  top: 0;
  left: 10px;
  transform: translateY(-50%);
  writing-mode: vertical-rl;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bone);
  background: rgba(19, 17, 16, 0.7);
  padding: 0.3rem 0.2rem;
  opacity: 0;
  transition: opacity 0.5s var(--ease-snappy);
}

.dorsale-node.is-active .dorsale-label {
  opacity: 1;
}

@media (max-width: 767px) {
  .dorsale {
    display: none;
  }
}

/* ==========================================================================
   Reduced motion: baseline visibility guarantee
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  /* Rete di sicurezza indipendente da demo.js: anche se initViaggioStatic()
     non riuscisse a marcare data-active su ogni passaggio, nessuno step
     resta a opacity .32 (pensata per il pin con scrub, qui inesistente)
     quando il movimento è disattivato. */
  .viaggio-step {
    opacity: 1 !important;
  }

  /* Przejścia tonalne: rimosse dal JS (ora rampe statiche via CSS, vedi
     .tonal-bridge) — nessun inline background-color da neutralizzare più,
     rete di sicurezza non serve. */

  /* Dorsale (C): linea già disegnata per intero, nessuno scrub. */
  .dorsale-line {
    transform: scaleY(1) !important;
  }

  .dorsale-node .dorsale-dot {
    opacity: 1 !important;
    transform: translate(-50%, -50%) scale(1) !important;
  }

  .dorsale-node .dorsale-label {
    opacity: 1 !important;
  }
}

/* ==========================================================================
   Breakpointy ogólne
   ========================================================================== */
@media (max-width: 1280px) {
  .intro-inner,
  .viaggio-inner {
    gap: clamp(2rem, 4vw, 3rem);
  }
}

@media (max-width: 1024px) {
  .hero-title {
    letter-spacing: -0.03em;
  }
}

@media (max-width: 480px) {
  .servizi-row-title {
    /* Il vecchio override qui (clamp(1.6rem, 9vw, 2.4rem)) era PIÙ
       grande del valore base a questa larghezza (9vw di 375px = 33.75px
       contro i 30.4px della clamp base) — invece di restringere il
       titolo sui telefoni lo ingrandiva, causando il taglio di
       "INTERNAZIONALE"/"BRT-FERMOPOINT" contro overflow:hidden della
       riga. Valore corretto, verificato contro la parola più lunga. */
    font-size: clamp(1.4rem, 7.2vw, 2rem);
  }

  .rete-heading {
    max-width: 100%;
  }

  .footer-top {
    flex-direction: column;
  }
}
