/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN SYSTEM .sb- — estratto fedele da albertopecchini.it
   (src/app/home.css, blocco .sb-home e html.dark .sb-home).

   Qui non si inventa niente: token, misure e primitive sono copiati dalla
   fonte di verità del sito. Cambia solo il contorno — lì è una SPA React con
   CSS colocato per pagina, qui è un sito statico e il foglio è uno solo.

   Regole che valgono ovunque nel file:
   · palette neutra (soli grigi) + UN'UNICA tinta, l'azzurro brand;
   · ogni colore/ombra/bordo si scrive con var(--sb-*), mai hex hard-coded
     (le uniche eccezioni sono i due blocchi di token qui sotto);
   · nessuna sezione ha un fondo o un bordo proprio: c'è UN solo fondale
     position:fixed per tutta la pagina e il contenuto ci scorre sopra.
   ═══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--ap-boot-bg, #fcfcfc); }
img { max-width: 100%; height: auto; }

.sb-home {
  /* ── Palette CHIARA (default) ── */
  --sb-bg: #fcfcfc;
  --sb-bg-alt: #f8f8f8;
  --sb-surface-75: #fbfbfb;
  --sb-surface-100: #f6f6f6;
  --sb-surface-200: #f0f0f0;
  --sb-overlay: rgba(0, 0, 0, 0.05);
  --sb-border: #e8e8e8;
  --sb-border-strong: #dbdbdb;
  --sb-border-stronger: #c7c7c7;
  --sb-fg: #171717;
  --sb-fg-light: #525252;
  --sb-fg-lighter: #6f6f6f;
  --sb-fg-muted: #8f8f8f;
  --sb-brand: hsl(197, 100%, 49%);
  --sb-brand-text: hsl(197, 86%, 28%);
  --sb-btn-bg: hsl(195, 67%, 67%);
  --sb-btn-bd: hsla(199, 78%, 40%, 0.75);
  --sb-btn-bg-hover: hsl(195, 63%, 60%);
  --sb-btn-fg: #101010;
  --sb-code-kw: #0550ae;
  --sb-code-num: #953800;
  --sb-code-fn: #8250df;
  --sb-shadow-card: 0 4px 20px -6px rgba(0, 0, 0, 0.1);

  /* ── Vetro ──────────────────────────────────────────────────────────────
     Le superfici delle card non sono tinte piatte: sono lastre che lasciano
     passare il fondale. Servono tre cose insieme — la trasparenza (--bg), la
     sfocatura di ciò che sta dietro (--blur, con un pizzico di saturazione in
     più perché il blur slava i colori) e il filo di luce sul bordo alto
     (--spec), che è quello che il cervello legge come "spessore". */
  --sb-glass-bg: color-mix(in srgb, var(--sb-surface-75) 58%, transparent);
  --sb-glass-blur: 20px;
  --sb-glass-sat: 150%;
  --sb-glass-spec: rgba(255, 255, 255, 0.72);
  --sb-glass-rim: rgba(255, 255, 255, 0.55);
  --sb-glass-shadow: 0 10px 34px -14px rgba(0, 0, 0, 0.2);
  --sb-glass-sheen: rgba(255, 255, 255, 0.42);
  --sb-glass-slab: rgba(0, 0, 0, 0.14);

  /* ── Smusso ─────────────────────────────────────────────────────────────
     Pillole e tabelle non sono più stondate: hanno l'angolo in alto a
     sinistra e quello in basso a destra tagliati a 45°. Due misure sole —
     una per gli elementi piccoli, una per le lastre. Vedi «Lo smusso» più
     avanti in questo file per come è disegnato. */
  --sb-cut: 10px;
  --sb-cut-lg: 18px;

  min-height: 100vh;
  background: var(--sb-bg);
  color: var(--sb-fg);
  font-family: "Titillium Web", Geneva, Tahoma, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

html.dark .sb-home {
  /* ── Palette SCURA ── */
  --sb-bg: #141414;
  --sb-bg-alt: #181818;
  --sb-surface-75: #1c1c1c;
  --sb-surface-100: #222222;
  --sb-surface-200: #282828;
  --sb-overlay: rgba(255, 255, 255, 0.07);
  --sb-border: #2a2a2a;
  --sb-border-strong: #343434;
  --sb-border-stronger: #414141;
  --sb-fg: #ededed;
  --sb-fg-light: #b4b4b4;
  --sb-fg-lighter: #969696;
  --sb-fg-muted: #707070;
  --sb-brand: hsl(197, 100%, 49%);
  --sb-brand-text: hsl(197, 100%, 55%);
  --sb-btn-bg: hsl(199, 100%, 19%);
  --sb-btn-bd: hsla(197, 100%, 49%, 0.3);
  --sb-btn-bg-hover: hsl(199, 74%, 25%);
  --sb-btn-fg: #ffffff;
  --sb-code-kw: #79c0ff;
  --sb-code-num: #ffcda1;
  --sb-code-fn: #bda4ff;
  --sb-shadow-card: 0 4px 24px -6px rgba(0, 0, 0, 0.55);

  /* Al buio il vetro è più scuro di ciò che ha dietro, non più chiaro: la
     lastra assorbe. Il filo specular scende a un decimo — un bordo bianco
     acceso come nel chiaro, qui, sembrerebbe un errore di rendering. */
  --sb-glass-bg: color-mix(in srgb, var(--sb-surface-75) 52%, transparent);
  --sb-glass-spec: rgba(255, 255, 255, 0.1);
  --sb-glass-rim: rgba(255, 255, 255, 0.08);
  --sb-glass-shadow: 0 10px 38px -14px rgba(0, 0, 0, 0.65);
  --sb-glass-sheen: rgba(255, 255, 255, 0.1);
  --sb-glass-slab: rgba(0, 0, 0, 0.5);
}

.sb-home ::selection { background: hsla(197, 100%, 49%, 0.35); }
.sb-home :focus-visible { outline: 2px solid var(--sb-brand); outline-offset: 2px; border-radius: 4px; }
.sb-home a { color: inherit; }

/* Contenitore di sezione */
.sb-container {
  width: 100%;
  max-width: 80rem;
  margin: 0 auto;
  padding-left: clamp(1.25rem, 4vw, 5rem);
  padding-right: clamp(1.25rem, 4vw, 5rem);
}
.sb-section { padding-top: clamp(4rem, 8vw, 6rem); padding-bottom: clamp(4rem, 8vw, 6rem); }

/* ── Fondale continuo ──────────────────────────────────────────────────────
   UN SOLO fondale per tutta la pagina, non uno per sezione: è position:fixed,
   quindi resta incollato alla finestra e nessun bordo di sezione può tagliarlo
   a metà scorrendo. Fra una sezione e l'altra non c'è nessun confine — sopra
   scorre solo il contenuto, che è trasparente.

   z-index: -1 e non 0: nell'ordine di pittura i figli con z-index negativo
   vanno subito dopo lo sfondo dell'elemento e PRIMA di tutto il contenuto. */
.sb-home::before,
.sb-home::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.sb-home::before {
  background: radial-gradient(58rem 32rem at 16% -8%, hsla(197, 100%, 49%, 0.14), transparent 62%);
  animation: sb-drift-a 74s ease-in-out infinite alternate;
}
/* Il secondo alone si sposta un po' di meno e dalla parte opposta: due strati
   che seguono la stessa mano ma non alla stessa velocità hanno una profondità
   che due strati solidali non hanno. 74 e 91 secondi non tornano mai in fase,
   così il fondo non ha un "battito" riconoscibile. */
.sb-home::after {
  background: radial-gradient(52rem 30rem at 88% 2%, hsla(192, 72%, 55%, 0.1), transparent 60%);
  animation: sb-drift-b 91s ease-in-out infinite alternate;
}
@keyframes sb-drift-a {
  from { transform: translate3d(-3vw, -2vh, 0) scale(1); }
  to   { transform: translate3d(4vw, 3vh, 0) scale(1.09); }
}
@keyframes sb-drift-b {
  from { transform: translate3d(3vw, 2vh, 0) scale(1.06); }
  to   { transform: translate3d(-4vw, -3vh, 0) scale(1); }
}
html.dark .sb-home::before {
  background: radial-gradient(58rem 32rem at 16% -8%, hsla(197, 100%, 49%, 0.16), transparent 62%);
}
html.dark .sb-home::after {
  background: radial-gradient(52rem 30rem at 88% 2%, hsla(192, 72%, 55%, 0.12), transparent 60%);
}
/* .sb-home non vuol dire "pagina": è la classe che porta i token, e se la
   mette addosso anche il footer si porterebbe dietro la sua coppia di aloni a
   tutto schermo, con l'opacità che si somma. Il fondale lo tiene solo il
   contenitore di pagina. */
.sb-home.sb-foot::before,
.sb-home.sb-foot::after { content: none; }

.sb-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  transform: translateZ(0);
}
/* Griglia tecnica: si dissolve verso il basso, così non finisce mai con una
   riga netta.

   --sb-par è la parallasse, e la scrive il JS a ogni scroll: la griglia sale
   di una frazione di quanto sale il contenuto. Il fondale è position:fixed,
   quindi senza questo resterebbe assolutamente immobile mentre tutto il resto
   scorre — ed è proprio quell'immobilità perfetta che lo fa leggere come una
   texture incollata allo schermo invece che come uno spazio dietro il vetro.
   Vale 0px senza JS: la griglia sta ferma, com'è sempre stata. */
.sb-bg-grid {
  position: absolute;
  inset: 0;
  opacity: 0.7;
  transform: translate3d(0, var(--sb-par, 0px), 0);
  background:
    linear-gradient(var(--sb-border) 1px, transparent 1px) 0 0 / 64px 64px,
    linear-gradient(90deg, var(--sb-border) 1px, transparent 1px) 0 0 / 64px 64px;
  -webkit-mask-image: radial-gradient(130% 96% at 50% -4%, #000 12%, transparent 68%);
  mask-image: radial-gradient(130% 96% at 50% -4%, #000 12%, transparent 68%);
}
.sb-main { position: relative; z-index: 1; }

@media print {
  .sb-bg { display: none; }
  .sb-home::before, .sb-home::after { content: none; }
}

/* Scorrere una pagina non è un evento da annunciare, e chi ha chiesto meno
   movimento non deve vedere derive di fondale.

   La regola * qui sotto azzera durate di transizione e animazione, ma NON
   basta: una trasformazione guidata da custom property (l'inclinazione delle
   card, la parallasse della griglia) non è un'animazione — è un valore che
   cambia, e senza transizione cambia solo più bruscamente. Quelle vanno
   spente una per una, e il JS non le attiva nemmeno: qui sotto c'è la rete di
   sicurezza per il caso in cui l'impostazione cambi a pagina aperta.

   Ogni regola è appesa a html:not(.rsm-motion) perché il tasto nella nav deve
   poter dire l'ultima parola: chi ha l'impostazione di sistema attiva ma
   preme "muovi" su questo sito ha espresso una scelta più recente e più
   specifica di quella del sistema operativo, e va rispettata. Senza scelta
   manuale la classe non c'è e comanda l'impostazione di sistema, com'è
   giusto. */
@media (prefers-reduced-motion: reduce) {
  html:not(.rsm-motion) .sb-home::before,
  html:not(.rsm-motion) .sb-home::after { animation: none; }
  html:not(.rsm-motion) .sb-bg-grid { transform: none !important; }
  html:not(.rsm-motion) :is(a.sb-card, a.sb-page-card) .sb-panel,
  html:not(.rsm-motion) .sb-panel--hover { transform: none !important; }
  html:not(.rsm-motion) .sb-panel-inner::after { content: none !important; }
  html:not(.rsm-motion) * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}

/* ── Movimento fermato a mano ──────────────────────────────────────────────
   L'altra metà del tasto. Qui NON si azzerano tutte le transizioni del sito:
   chi ferma il movimento vuole che la pagina stia ferma, non che i colori
   scattino. Restano fuori le dissolvenze di 150 ms sui link e sui bottoni —
   quelle nessuno le legge come movimento.

   Tilt, parallasse e pillola non hanno bisogno di una riga qui: li scrive il
   JS come proprietà inline, e quando si spegne il movimento se le riprende. */
html.rsm-still .sb-home::before,
html.rsm-still .sb-home::after { animation: none; }
html.rsm-still .sb-chip-dot { animation: none; }
html.rsm-still .sb-panel-inner::after,
html.rsm-still .sb-btn--primary::after,
html.rsm-still .sb-btn--secondary::after { content: none; }

/* ── Nav ─────────────────────────────────────────────────────────────────── */
.sb-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--sb-bg) 92%, transparent);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
  border-bottom: 1px solid transparent;
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}
/* In cima alla pagina la nav non ha bordo: nessuna riga a tagliare la hero.
   Compare solo quando c'è del contenuto che le scorre sotto. */
.sb-nav--scrolled { border-bottom-color: var(--sb-border); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06); }
html.dark .sb-nav--scrolled { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); }
.sb-nav-inner { display: flex; align-items: center; gap: 1rem; height: 64px; }
.sb-nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--sb-fg);
  flex-shrink: 0;
}
.sb-nav-brand-name { font-size: 0.98rem; font-weight: 500; white-space: nowrap; letter-spacing: -0.01em; }
.sb-nav-links { position: relative; display: none; align-items: center; gap: 0.15rem; }
@media (min-width: 1080px) { .sb-nav-links { display: flex; } }
.sb-nav-link {
  position: relative;
  padding: 0.35rem 0.7rem;
  border-radius: 6px;
  font-size: 0.875rem;
  color: var(--sb-fg-light);
  text-decoration: none;
  transition: color 0.15s, background 0.15s;
  white-space: nowrap;
}
.sb-nav-link:hover { color: var(--sb-fg); background: var(--sb-overlay); }
.sb-nav-link[aria-current="page"] { color: var(--sb-fg); }
/* Il filo azzurro che si apre da sinistra sotto la voce: dice "sei qui" senza
   aggiungere un secondo colore. */
.sb-nav-link::after {
  content: "";
  position: absolute;
  left: 0.7rem;
  right: 0.7rem;
  bottom: 0.1rem;
  height: 1px;
  background: var(--sb-brand);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.sb-nav-link:hover::after,
.sb-nav-link[aria-current="page"]::after { transform: scaleX(1); }

/* ── La pillola ──────────────────────────────────────────────────────────
   Un solo fondo che scivola da una voce all'altra invece di otto fondi che si
   accendono e si spengono. Il movimento continuo racconta che le voci sono
   una fila sola; otto accensioni indipendenti no.

   Riposa sotto la voce della pagina aperta, segue il puntatore e il focus da
   tastiera, torna a riposo quando si esce dalla fila. Posizione e larghezza
   arrivano dal JS come custom property, perché dipendono da quanto è lunga
   ogni etichetta — cose che il CSS da solo non può sapere.

   .sb-nav-links--pill la mette il JS: senza script la classe non c'è, la
   pillola resta larga zero e invisibile, e l'hover quadrato qui sotto continua
   a funzionare come prima. */
.sb-nav-pill {
  position: absolute;
  left: 0;
  top: 50%;
  height: 30px;
  width: var(--sb-pill-w, 0px);
  border-radius: 999px;
  background: var(--sb-overlay);
  transform: translate3d(var(--sb-pill-x, 0px), -50%, 0);
  opacity: 0;
  pointer-events: none;
  transition:
    transform 0.34s cubic-bezier(0.22, 1, 0.36, 1),
    width 0.34s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.2s ease;
}
.sb-nav-pill.sb-on { opacity: 1; }
/* Con la pillola in funzione il rettangolo dell'hover se ne va: sono due modi
   di dire la stessa cosa, e insieme si vedrebbero uno dentro l'altro. */
.sb-nav-links--pill .sb-nav-link:hover { background: transparent; }

.sb-nav-right { margin-left: auto; display: inline-flex; align-items: center; gap: 0.4rem; }
.sb-burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--sb-fg-light);
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.sb-burger:hover { color: var(--sb-fg); background: var(--sb-overlay); }
/* Sparisce l'hamburger, non tutti i tasti icona: sopra i 1080px le voci sono
   già in fila e il menu non serve più, ma il tema e il movimento sono scelte
   che si fanno da qualsiasi larghezza — e il movimento, anzi, esiste solo qui. */
@media (min-width: 1080px) { .sb-burger[data-menu-toggle] { display: none; } }

/* Il tasto del movimento sta nella barra di controllo (controlbar.css), ma
   esiste solo se glass.js è arrivato: è lui che aggiunge .sb-ready. Un tasto
   morto accanto a due che funzionano è peggio di un tasto che non c'è. */
.sb-motion-toggle { display: none; }
.sb-motion-toggle.sb-ready { display: inline-flex; }

/* Menu mobile: un foglio che scende sotto la nav, stessa lastra di vetro. */
.sb-menu-sheet {
  display: none;
  border-bottom: 1px solid var(--sb-border);
  background: color-mix(in srgb, var(--sb-bg) 96%, transparent);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
}
.sb-menu-sheet.sb-open { display: block; }
@media (min-width: 1080px) { .sb-menu-sheet.sb-open { display: none; } }
.sb-menu-nav { display: grid; gap: 0.1rem; padding: 0.7rem 0 1.1rem; }
.sb-menu-nav a {
  padding: 0.55rem 0.7rem;
  border-radius: 6px;
  font-size: 0.95rem;
  color: var(--sb-fg-light);
  text-decoration: none;
}
.sb-menu-nav a:hover { color: var(--sb-fg); background: var(--sb-overlay); }
.sb-menu-nav a[aria-current="page"] { color: var(--sb-fg); background: var(--sb-overlay); }

/* ── Bottoni (h 38px, radius 6, bordo 1px sempre) ────────────────────────── */
.sb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 38px;
  padding: 0 1rem;
  border-radius: 6px;
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 400;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.sb-btn--sm { height: 32px; padding: 0 0.8rem; font-size: 0.8rem; }
.sb-btn--primary {
  position: relative;
  background: var(--sb-btn-bg);
  border-color: var(--sb-btn-bd);
  color: var(--sb-btn-fg);
}
.sb-btn--primary:hover { background: var(--sb-btn-bg-hover); border-color: var(--sb-brand); }
.sb-btn--secondary {
  position: relative;
  background: var(--sb-bg-alt);
  border-color: var(--sb-border-strong);
  color: var(--sb-fg);
}
.sb-btn--secondary:hover { background: var(--sb-surface-200); border-color: var(--sb-border-stronger); }
.sb-btn--ghost { background: transparent; border-color: transparent; color: var(--sb-fg-light); }
.sb-btn--ghost:hover { color: var(--sb-fg); background: var(--sb-overlay); }

/* Riflesso sui bottoni — stessa banda di luce delle card, stesso ritardo di
   120 ms: passandoci sopra di corsa per arrivare altrove l'animazione non fa
   in tempo a partire, e la fila di bottoni non lampeggia. */
@media (hover: hover) and (pointer: fine) {
  .sb-btn--primary,
  .sb-btn--secondary { overflow: hidden; }
  .sb-btn--primary::after,
  .sb-btn--secondary::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: 0;
    transform: translateX(-130%);
    background: linear-gradient(105deg, transparent 38%, var(--sb-glass-sheen) 50%, transparent 62%);
  }
  .sb-btn--primary:hover::after,
  .sb-btn--secondary:hover::after {
    animation: sb-sheen 0.75s cubic-bezier(0.22, 1, 0.36, 1) 0.12s 1;
  }
  .sb-btn--primary > *,
  .sb-btn--secondary > * { position: relative; z-index: 1; }
}
@keyframes sb-sheen {
  from { opacity: 1; transform: translateX(-130%); }
  to   { opacity: 1; transform: translateX(130%); }
}

/* Link verdi "testo + freccia" */
.sb-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.875rem;
  color: var(--sb-brand-text);
  text-decoration: none;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
}
.sb-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.sb-link svg { transition: transform 0.15s ease; }
.sb-link:hover svg { transform: translateX(2px); }

/* ── Hero ────────────────────────────────────────────────────────────────
   Niente fondale proprio e niente overflow:hidden: il fondo della hero è il
   fondale continuo della pagina. Così scendendo non si vede nessuna riga dove
   "finisce la hero e comincia il resto". */
.sb-hero {
  position: relative;
  padding-top: clamp(3rem, 9vw, 8.5rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.sb-hero-title {
  margin: 0;
  font-size: clamp(2.1rem, 5.2vw, 3.6rem);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.03em;
}
.sb-hero-title span { display: block; }
.sb-hero-title .sb-brandline { color: var(--sb-brand-text); }
.sb-hero-copy { max-width: 40rem; margin-top: 1.4rem; }
.sb-hero-copy p { margin: 0 0 0.7rem; font-size: 1rem; line-height: 1.6; color: var(--sb-fg-lighter); }
.sb-hero-copy p:last-child { margin-bottom: 0; }
.sb-hero-copy strong { font-weight: 400; color: var(--sb-fg); }
.sb-hero-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.6rem; }

/* ── Lo smusso ─────────────────────────────────────────────────────────────
   La forma del sito non è più la stondatura: è un angolo tagliato a 45° in
   alto a sinistra e in basso a destra. Due diagonali opposte bastano a dare
   una direzione alla sagoma — tagliarne quattro la rimetterebbe in simmetria
   e tornerebbe a essere un ottagono, cioè di nuovo un tondo.

   Le sagome sono pronte, una per misura, e si richiamano così:

     .qualcosa { clip-path: var(--sb-shape-sm); }

   ATTENZIONE a non "semplificarle" in una sola con una misura variabile: le
   custom property vengono sostituite SUBITO, sull'elemento dove sono scritte,
   e il valore già risolto è quello che eredita. Una --sb-shape che contenesse
   var(--c) andrebbe a cercare --c qui su .sb-home, non lo troverebbe, e
   l'intera proprietà diventerebbe invalida (cioè vuota) prima ancora di
   arrivare a chi la usa. Con --sb-cut, che è dichiarato qui sopra, la
   sostituzione riesce — ed è anche il motivo per cui il tema scuro funziona
   da sé: le stesse dichiarazioni si ricalcolano dentro html.dark .sb-home. */
.sb-home {
  /* Pillole, badge, filtri */
  --sb-shape-sm: polygon(
    var(--sb-cut) 0,
    100% 0,
    100% calc(100% - var(--sb-cut)),
    calc(100% - var(--sb-cut)) 100%,
    0 100%,
    0 var(--sb-cut)
  );
  /* Lastre: il rim esterno… */
  --sb-shape-lg: polygon(
    var(--sb-cut-lg) 0,
    100% 0,
    100% calc(100% - var(--sb-cut-lg)),
    calc(100% - var(--sb-cut-lg)) 100%,
    0 100%,
    0 var(--sb-cut-lg)
  );
  /* …e il vetro dentro. 0.586px non è un numero magico: è quanto va stretto
     il taglio interno perché fra le due diagonali resti esattamente 1px, come
     sui lati dritti. L'inner è inset di 1px (il padding della lastra), e su
     una retta a 45° un pixel in perpendicolare vale √2 di scostamento —
     2 − √2 = 0.586. Non arrotondarlo a 1px: la diagonale verrebbe più spessa
     dei lati, e si vede. */
  --sb-shape-lg-in: polygon(
    calc(var(--sb-cut-lg) - 0.586px) 0,
    100% 0,
    100% calc(100% - var(--sb-cut-lg) + 0.586px),
    calc(100% - var(--sb-cut-lg) + 0.586px) 100%,
    0 100%,
    0 calc(var(--sb-cut-lg) - 0.586px)
  );

  /* Il filo da 1px sulle due diagonali, per gli elementi a livello singolo.
     clip-path taglia anche il border: sui lati dritti il contorno resta, sulle
     diagonali sparirebbe, e una pillola con due lati aperti sembra rotta.

     Si ridisegna con due gradienti confinati nei quadrati d'angolo. Il 50% non
     è a occhio: su un quadrato di lato S la linea di taglio dista S/√2
     dall'angolo, e l'asse di un gradiente a 135° è lungo S·√2 — la metà
     esatta. I ±0.7px attorno sono il mezzo pixel per lato che fa l'1px. */
  --sb-shape-edge:
    linear-gradient(
        135deg,
        transparent calc(50% - 0.7px),
        var(--sb-border-strong) calc(50% - 0.7px) calc(50% + 0.7px),
        transparent calc(50% + 0.7px)
      )
      top left / var(--sb-cut) var(--sb-cut) no-repeat,
    linear-gradient(
        315deg,
        transparent calc(50% - 0.7px),
        var(--sb-border-strong) calc(50% - 0.7px) calc(50% + 0.7px),
        transparent calc(50% + 0.7px)
      )
      bottom right / var(--sb-cut) var(--sb-cut) no-repeat;

  /* Variante per l'unica pillola piena, il badge brand. */
  --sb-shape-edge-btn:
    linear-gradient(
        135deg,
        transparent calc(50% - 0.7px),
        var(--sb-btn-bd) calc(50% - 0.7px) calc(50% + 0.7px),
        transparent calc(50% + 0.7px)
      )
      top left / var(--sb-cut) var(--sb-cut) no-repeat,
    linear-gradient(
        315deg,
        transparent calc(50% - 0.7px),
        var(--sb-btn-bd) calc(50% - 0.7px) calc(50% + 0.7px),
        transparent calc(50% + 0.7px)
      )
      bottom right / var(--sb-cut) var(--sb-cut) no-repeat;
}

/* clip-path porta via anche l'outline del focus. Su un elemento tagliato il
   contorno di messa a fuoco si ridisegna dentro, con un'ombra inset: quella
   non viene ritagliata perché sta già all'interno della sagoma. */
.sb-home .sb-riv-toc a:focus-visible,
.sb-home .sb-chip:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--sb-brand);
}

/* ── Pannello di vetro con rim da 1px (marchio di fabbrica delle card) ─────
   Il bordo non è una riga grigia uniforme: è un rim illuminato che si spegne
   allontanandosi dalla luce, come succede a una lastra vera. È metà
   dell'effetto — l'altra metà è il filo specular dentro .sb-panel-inner. Da
   soli sembrano entrambi uno sbaglio; insieme danno lo spessore. */
.sb-panel {
  position: relative;
  height: 100%;
  padding: 1px;
  /* La lastra è tagliata come tutto il resto. Il rim sopravvive alle diagonali
     senza trucchi, perché qui il bordo non è un border: è lo sfondo a
     gradiente di questo elemento, che il taglio ritaglia insieme a lui. */
  clip-path: var(--sb-shape-lg);
  background: linear-gradient(
    var(--rim-angle, 160deg),
    var(--sb-glass-rim),
    var(--sb-border-strong) 38%,
    color-mix(in srgb, var(--sb-border) 45%, transparent)
  );
  transition: background 0.2s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
/* Le card cliccabili del sito sono due parentele con due nomi — .sb-card
   (rassegna stampa) e .sb-page-card (griglia della home) — più chi chiede il
   trattamento a mano. Stanno insieme in ogni regola che le riguarda: se una
   delle tre restasse fuori si vedrebbe subito, perché sarebbe l'unica card
   della pagina che al passaggio del mouse non fa niente. */
:is(a.sb-card, a.sb-page-card):hover .sb-panel,
.sb-panel--hover:hover {
  background: var(--sb-border-stronger);
  /* Due pixel di stacco, non di più: insieme all'ombra bastano a dire che la
     lastra si è staccata dal fondo. Entra nella stessa transform
     dell'inclinazione (vedi più sotto), altrimenti l'ultima delle due
     dichiarazioni vince e l'altra sparisce. */
  --sb-tilt-lift: -2px;
}

/* ── L'ombra, che non può più essere un box-shadow ─────────────────────────
   clip-path ritaglia tutto quello che l'elemento dipinge, ombra esterna
   compresa: sulla lastra tagliata un box-shadow semplicemente non esce.
   filter: drop-shadow() la seguirebbe, ma un filter crea un backdrop root e
   spegnerebbe il backdrop-filter di tutto ciò che ha dentro — il vetro si
   smaterializzerebbe proprio al passaggio del mouse.

   Quindi l'ombra diventa un oggetto: una seconda lastra della stessa forma,
   sfocata e spostata in basso, appesa al contenitore <a> che NON è ritagliato.
   In cambio l'ombra segue lo smusso invece di arrotondarlo.

   Vale solo per .sb-card e .sb-page-card, che hanno un <a> attorno a cui
   appenderla. .sb-panel--hover è la lastra stessa, quindi è già ritagliata e
   non ha un fuori in cui mettere l'ombra: lì lo stacco resta affidato al rim
   che si accende e ai 2px di sollevamento. */
:is(a.sb-card, a.sb-page-card) {
  position: relative;
  isolation: isolate;
}
:is(a.sb-card, a.sb-page-card)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  clip-path: var(--sb-shape-lg);
  background: var(--sb-glass-slab);
  filter: blur(12px);
  transform: translateY(3px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
:is(a.sb-card, a.sb-page-card):hover::before { opacity: 1; }
/* La lastra vera sta sopra la sua ombra. isolation:isolate sull'<a> tiene
   entrambe dentro lo stesso contesto di impilamento, così l'ombra di una card
   non può finire sopra la card accanto. */
:is(a.sb-card, a.sb-page-card) > .sb-panel { z-index: 1; }

.sb-panel-inner {
  position: relative;
  height: 100%;
  /* 0.586px non è un numero magico: è quanto va stretto il taglio interno
     perché fra le due diagonali resti esattamente 1px, come sui lati dritti.
     L'inner è inset di 1px (il padding della lastra), e su una retta a 45°
     un pixel in perpendicolare vale √2 di scostamento — 2 − √2 = 0.586.
     Non "arrotondarlo" a 1px: la diagonale diventerebbe più spessa dei lati. */
  clip-path: var(--sb-shape-lg-in);
  background: var(--sb-glass-bg);
  -webkit-backdrop-filter: blur(var(--sb-glass-blur)) saturate(var(--sb-glass-sat));
  backdrop-filter: blur(var(--sb-glass-blur)) saturate(var(--sb-glass-sat));
  box-shadow: inset 0 1px 0 var(--sb-glass-spec);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* Dove il vetro non deve andare: backdrop-filter fa da containing block a
   tutti i position:fixed che ha dentro, e su un contenitore che scorre in
   orizzontale costa una sfocatura per frame. */
.sb-panel--solid > .sb-panel-inner,
.sb-panel-inner.sb-panel--solid {
  background: var(--sb-surface-75);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* Ripiego per chi non ha backdrop-filter: meglio opache che a metà. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .sb-panel-inner { background: var(--sb-surface-75); }
}
/* Su schermo piccolo la lastra si assottiglia: una dozzina di pannelli
   sfocati in viewport è lavoro vero per il compositore di un telefono. */
@media (max-width: 639.98px) {
  .sb-home { --sb-glass-blur: 12px; --sb-glass-sat: 130%; }
}

/* ── Il vetro che si inclina e riflette ───────────────────────────────────
   Tutto quello che segue vale SOLO per le card cliccabili (a.sb-card) e per
   chi chiede il trattamento a mano (.sb-panel--hover). Le lastre che fanno da
   contenitore — tabelle, riquadri di sintesi — restano ferme: inclinare un
   pannello che nessuno può premere è movimento senza risposta.

   La condizione (hover: hover) and (pointer: fine) esclude il touch: lì
   "hover" è il primo dito appoggiato prima del tap, e una card che si inclina
   mentre si scorre la pagina è solo un difetto.

   I due angoli arrivano dal JS come custom property. Se il JS non c'è valgono
   0deg e la trasformazione è l'identità: senza script non manca niente. */
@media (hover: hover) and (pointer: fine) {
  :is(a.sb-card, a.sb-page-card) .sb-panel,
  .sb-panel--hover {
    transform: perspective(760px)
      rotateX(var(--sb-tilt-x, 0deg))
      rotateY(var(--sb-tilt-y, 0deg))
      translate3d(0, var(--sb-tilt-lift, 0px), 0);
  }
  /* Mentre il puntatore è sopra, la lastra deve stare SOTTO il dito: 0.3s di
     easing sono giusti per il ritorno a riposo, ma inseguendo il mouse
     diventano un ritardo che si vede. Il JS mette questa classe all'ingresso
     e la toglie all'uscita — così l'inclinazione è immediata e il rientro no. */
  .sb-panel--tilting {
    transition: background 0.2s ease, box-shadow 0.2s ease, transform 0.08s linear;
  }

  /* Riflesso: la stessa banda di luce dei bottoni, con lo stesso ritardo di
     innesco di 120 ms. Attraversando una griglia di nove card per arrivare
     all'ultima, le otto di passaggio non fanno in tempo ad accendersi e la
     griglia non lampeggia. Escluse le lastre --solid: non sono vetro. */
  :is(a.sb-card, a.sb-page-card) .sb-panel-inner:not(.sb-panel--solid)::after,
  .sb-panel--hover > .sb-panel-inner:not(.sb-panel--solid)::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    opacity: 0;
    transform: translateX(-130%);
    background: linear-gradient(105deg, transparent 38%, var(--sb-glass-sheen) 50%, transparent 62%);
  }
  :is(a.sb-card, a.sb-page-card):hover .sb-panel-inner::after,
  .sb-panel--hover:hover > .sb-panel-inner::after {
    animation: sb-sheen 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.12s 1;
  }
}

/* ── Card ────────────────────────────────────────────────────────────────── */
.sb-card { display: block; text-decoration: none; color: inherit; }
.sb-card-head { padding: 1.4rem 1.4rem 0; display: flex; flex-direction: column; gap: 0.6rem; }
.sb-card-title { display: flex; align-items: center; gap: 0.55rem; color: var(--sb-fg-light); }
.sb-card-title h3 { margin: 0; font-size: 0.98rem; font-weight: 500; letter-spacing: -0.01em; }
.sb-card-desc { margin: 0; font-size: 0.875rem; line-height: 1.55; color: var(--sb-fg-lighter); }
.sb-card-desc strong { font-weight: 400; color: var(--sb-fg); }

/* Griglia delle pagine (dalla home di albertopecchini.it) */
.sb-pages { display: grid; grid-template-columns: 1fr; gap: 1rem; }
@media (min-width: 640px) { .sb-pages { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .sb-pages { grid-template-columns: repeat(3, 1fr); } }
.sb-page-card { display: block; text-decoration: none; color: inherit; }
.sb-page-inner { padding: 1.3rem; gap: 0.7rem; }
.sb-page-top { display: flex; align-items: center; justify-content: space-between; color: var(--sb-fg-light); }
.sb-page-top .go { color: var(--sb-fg-muted); opacity: 0; transform: translate(-3px, 3px); transition: opacity 0.15s, transform 0.15s, color 0.15s; }
.sb-page-card:hover .go { opacity: 1; transform: none; color: var(--sb-fg); }
.sb-page-card .sb-page-top > svg { transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), color 0.25s ease; }
.sb-page-card:hover .sb-page-top > svg { transform: scale(1.15) rotate(-8deg); color: var(--sb-brand-text); }
.sb-page-inner h4 { margin: 0; font-size: 0.95rem; font-weight: 500; color: var(--sb-fg); }
.sb-page-inner p { margin: 0; font-size: 0.84rem; line-height: 1.55; color: var(--sb-fg-lighter); }

/* ── Pillole / badge (angolo tagliato + vetro) ─────────────────────────────
   Non sono più pillole di tinta piatta: sono schegge di vetro. Tre cose
   insieme, le stesse delle lastre grandi — la trasparenza, la sfocatura di
   ciò che passa dietro e il filo di luce sul bordo alto. Il filo specular non
   è un vezzo: senza, il backdrop-filter da solo si legge come una macchia. */
.sb-chiprow { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.sb-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.42rem 0.85rem;
  clip-path: var(--sb-shape-sm);
  border: 1px solid var(--sb-border-strong);
  /* I due gradienti ridisegnano il bordo sulle diagonali che il clip taglia;
     l'ultimo livello è il vetro. Vedi «Lo smusso» per il perché del 50%. */
  background: var(--sb-shape-edge), var(--sb-glass-bg);
  -webkit-backdrop-filter: blur(var(--sb-glass-blur)) saturate(var(--sb-glass-sat));
  backdrop-filter: blur(var(--sb-glass-blur)) saturate(var(--sb-glass-sat));
  box-shadow: inset 0 1px 0 var(--sb-glass-spec);
  font-size: 0.8rem;
  color: var(--sb-fg-light);
  white-space: nowrap;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .sb-chip { background: var(--sb-shape-edge), var(--sb-surface-75); }
}
.sb-chip svg { color: var(--sb-fg-muted); }
.sb-chip-dot {
  display: inline-block;
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--sb-brand);
  animation: sb-ping 4.2s ease-out infinite;
}
@keyframes sb-ping {
  0% { box-shadow: 0 0 0 0 hsla(197, 100%, 49%, 0.55); }
  70% { box-shadow: 0 0 0 7px hsla(197, 100%, 49%, 0); }
  100% { box-shadow: 0 0 0 0 hsla(197, 100%, 49%, 0); }
}

/* ── Testata di sezione ──────────────────────────────────────────────────── */
.sb-sechead { max-width: 40rem; margin: 0 auto; text-align: center; }
.sb-sechead h2, .sb-sechead h3 {
  margin: 0 0 0.7rem;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.sb-sechead p { margin: 0; font-size: 0.95rem; line-height: 1.6; color: var(--sb-fg-lighter); }
/* Su una pagina di consultazione le testate stanno a sinistra: l'occhio
   torna sempre allo stesso margine mentre scorre una tabella dopo l'altra. */
.sb-sechead--start { margin-left: 0; text-align: left; max-width: 46rem; }

/* ── CTA ─────────────────────────────────────────────────────────────────── */
.sb-cta { text-align: center; }
.sb-cta h2 {
  margin: 0 0 0.8rem;
  font-size: clamp(1.8rem, 4vw, 2.8rem);
  font-weight: 400;
  letter-spacing: -0.025em;
  line-height: 1.1;
}
.sb-cta h2 .sb-brandline { display: block; color: var(--sb-brand-text); }
.sb-cta p { margin: 0 auto 1.8rem; max-width: 34rem; font-size: 1rem; line-height: 1.6; color: var(--sb-fg-lighter); }
.sb-cta-actions { display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap; }

/* ── Footer condiviso (.sb-foot) ──────────────────────────────────────────
   Lo stesso footer di albertopecchini.it: porta con sé la classe .sb-home per
   ereditare i token (e quindi il tema nativo chiaro/scuro), ma annulla il
   min-height da pagina.

   Non è un blocco a sé: niente bordo in cima. Il colore entra in dissolvenza
   dall'alto, così scendendo non si vede il punto in cui la pagina "finisce". */
.sb-home.sb-foot {
  min-height: 0;
  background: linear-gradient(to bottom, transparent, var(--sb-bg-alt) 14rem);
  position: relative;
  z-index: 1;
}
.sb-foot-wrap {
  position: relative;
  z-index: 1;
  padding-top: clamp(2.5rem, 5vw, 4rem);
  padding-bottom: calc(env(safe-area-inset-bottom) + 3rem);
}
/* Griglia alla Supabase: identità a sinistra (≈ colonna del logo), colonne di
   link a destra. Le due colonne sono card .sb-panel come quelle della home. */
.sb-foot-grid { display: grid; grid-template-columns: 1fr; gap: 1.1rem; align-items: stretch; }
@media (min-width: 1024px) { .sb-foot-grid { grid-template-columns: 2fr 5fr; gap: 1.25rem; } }
.sb-foot-card { min-width: 0; }
.sb-foot-card .sb-panel-inner { background: color-mix(in srgb, var(--sb-bg) 82%, transparent); overflow: visible; }
.sb-foot-card:hover .sb-panel {
  background: var(--sb-border-stronger);
  box-shadow: var(--sb-shadow-card);
}
.sb-foot-pad {
  padding: clamp(1.1rem, 2.4vw, 1.5rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0;
}
.sb-foot-name {
  display: inline-block;
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--sb-fg);
  text-decoration: none;
}
.sb-foot-name:hover { color: var(--sb-brand-text); }
.sb-foot-role { margin: 0.3rem 0 0; font-size: 0.875rem; line-height: 1.5; color: var(--sb-fg-lighter); }
.sb-foot-social { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1.3rem; max-width: 21rem; }
.sb-foot-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  color: var(--sb-fg-muted);
  border: 1px solid transparent;
  transition: color 0.18s, background 0.18s, border-color 0.18s;
}
.sb-foot-social a:hover {
  color: var(--sb-brand-text);
  background: var(--sb-overlay);
  border-color: color-mix(in srgb, var(--sb-brand) 35%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sb-brand) 12%, transparent);
}
/* Rimbalzo, non scivolata: la curva sfonda l'1 e torna indietro. */
.sb-foot-social a svg { transition: transform 0.42s cubic-bezier(0.34, 1.56, 0.64, 1); }
.sb-foot-social a:hover svg { transform: scale(1.24) rotate(-8deg); }
/* Colonne di link del footer */
.sb-foot-links-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.2rem 1rem;
}
@media (min-width: 720px) { .sb-foot-links-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.sb-foot-col h3 {
  margin: 0 0 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sb-fg-muted);
}
.sb-foot-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
.sb-foot-col a {
  font-size: 0.84rem;
  color: var(--sb-fg-lighter);
  text-decoration: none;
  transition: color 0.15s;
}
.sb-foot-col a:hover { color: var(--sb-brand-text); }
/* Filo sfumato (trasparente → bordo → trasparente), firma di Supabase. */
.sb-foot-hairline {
  height: 2px;
  margin-top: clamp(2rem, 4vw, 3rem);
  border-radius: 999px;
  background: linear-gradient(to right, transparent, var(--sb-border-stronger), transparent);
}
.sb-foot-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  flex-wrap: wrap;
  padding-top: 1.2rem;
  font-size: 0.8rem;
  color: var(--sb-fg-muted);
}
.sb-foot-bottom-links { display: inline-flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.sb-foot-sep { color: var(--sb-border-stronger); }
/* Il credito prende la sottolineatura che si apre da sinistra della nav. */
.sb-foot-by {
  position: relative;
  padding-bottom: 2px;
  color: var(--sb-fg-light);
  text-decoration: none;
}
.sb-foot-by::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--sb-brand);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.sb-foot-by:hover::after { transform: scaleX(1); }

/* Salto al contenuto: invisibile finché non lo si raggiunge da tastiera. */
.sb-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
}
.sb-skip:focus {
  left: 0.75rem;
  top: 0.75rem;
  padding: 0.5rem 0.9rem;
  border-radius: 6px;
  background: var(--sb-bg);
  border: 1px solid var(--sb-border-strong);
  color: var(--sb-fg);
  text-decoration: none;
}
