/* ── Aspekta — variable font, SIL OFL (assets/fonts/Aspekta-OFL.txt) ─────── */
@font-face{
  font-family:"Aspekta";
  /* format("woff2") copre anche i variable font: "woff2-variations" e sintassi
     obsoleta e in Chrome fa fallire il parsing di quel primo src. */
  src:url("../assets/fonts/AspektaVF.woff2") format("woff2");
  font-weight:100 1000;
  font-style:normal;
  font-display:swap;
}

/* ── Reset e primitive ───────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{-webkit-text-size-adjust:100%;overflow-x:clip;background:var(--bordeaux)}
body{background:var(--panna);color:var(--nero-verde);
  font-family:var(--ui);font-size:var(--text-base);line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:clip}
img,svg,video{display:block;max-width:100%;height:auto}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
ul,ol{list-style:none;padding:0}
/* Doppio anello: outline chiaro (leggibile sui fondi scuri) + box-shadow corallo
   (leggibile sui fondi chiari). Sui fondi verde-acqua nessuno dei due basta da
   solo: vedi override .ticker/.panel in blocks.css.
   box-shadow è !important perché diversi componenti (sticker, serata, mappa__btn,
   prize...) hanno una propria ombra hard-offset permanente, non condizionata da
   :hover: a parità di specificità vincerebbe quella e l'anello di focus
   sparirebbe proprio sugli elementi con più bisogno di essere visibili. */
:focus-visible{
  outline:2px solid var(--panna);
  outline-offset:2px;
  box-shadow:0 0 0 5px var(--corallo-ui) !important;
  border-radius:4px;
}

.wrap{max-width:calc(var(--measure) + var(--gutter) * 2);margin-inline:auto;padding-inline:var(--gutter)}
/* i grid/flex item hanno min-width:auto e non scendono sotto il min-content: causa di overflow */
.panel > *,.dove > *,.about > *,.loc > *,.card > *,.serata > *,.info > *{min-width:0}
section{padding-block:var(--space-lg)}
/* ritmo variabile: le sezioni non hanno tutte lo stesso respiro */
.s-sm{padding-block:var(--space-sm)}
.s-md{padding-block:var(--space-md)}
.s-lg{padding-block:var(--space-lg)}   /* mancava: era usato nel markup senza regola */
.s-xl{padding-block:var(--space-xl)}
.s-t0{padding-top:0}
.s-b0{padding-bottom:0}
/* area di tocco: il testo resta della sua dimensione, cresce solo il bersaglio */
.tap{display:inline-flex;align-items:center;min-height:44px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ── Tipografia ──────────────────────────────────────────────────────────── */
.h2{font-family:var(--display);font-size:var(--text-h2);line-height:1;
  text-transform:uppercase;color:var(--verde-nero)}
.h3{font-family:var(--display);font-size:var(--text-h3);line-height:1;text-transform:uppercase}
.lbl{font-size:var(--text-lbl);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--teal-scuro);margin-bottom:1.6rem}
.lead{font-size:var(--text-lead);line-height:1.55;max-width:48ch}

/* ── Pill CTA ────────────────────────────────────────────────────────────── */
.pill{display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  border-radius:var(--r-pill);padding:1.15rem 2.4rem;
  font-weight:700;font-size:.92rem;letter-spacing:.09em;text-transform:uppercase;
  text-decoration:none;white-space:nowrap;max-width:100%;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
/* sotto i 560px le etichette lunghe non ci stanno su una riga sola */
@media(max-width:560px){
  .pill{white-space:normal;text-align:center;padding-inline:1.6rem}
}
/* hover raffinato, misurato sul reference: l'ombra cresce da -6.6px a -8px
   fra 200 e 800ms (curva expo: parte decisa, poi frena), con uno squish
   (translate + scale, non border-radius — restiamo su transform/opacity)
   che rientra del tutto prima che l'ombra finisca di crescere. */
/* Misurato sul reference: in hover è il PULSANTE a spostarsi di +8px a destra
   e −8px in alto, e l'ombra dura cade esattamente dove il pulsante stava.
   Prima muovevamo solo l'ombra, che è l'effetto opposto. */
.pill{transition:box-shadow 800ms var(--ease-out-expo),
  transform 800ms var(--ease-out-expo)}
.pill:hover,.pill:focus-visible{transform:translate(8px,-8px);
  box-shadow:-8px 8px 0 0 var(--nero-verde);animation:pillSquish 500ms var(--ease-out-expo)}
.pill:active{box-shadow:-4px 4px 0 0 var(--nero-verde)}
.pill--scuro:hover,.pill--primary:hover{box-shadow:-8px 8px 0 0 var(--bordeaux)}
/* A metà transizione il reference non scala il pulsante: gli schiaccia il
   RAGGIO (misurato: 31.5% / 125% a 120ms) e lo lascia rientrare. Animare qui
   `transform` cancellerebbe lo spostamento dell'hover. */
@keyframes pillSquish{
  0%{border-radius:var(--r-pill)}
  40%{border-radius:31.5% / 125%}
  100%{border-radius:var(--r-pill)}
}
.pill--primary{background:var(--corallo-ui);color:var(--panna)}
.pill--acqua{background:var(--verde-acqua);color:var(--nero-verde)}
.pill--ocra{background:var(--ocra);color:var(--nero-verde)}
.pill--scuro{background:var(--verde-nero);color:var(--crema)}
.pill--ghost{border:2px solid var(--verde-nero);color:var(--verde-nero);padding-block:calc(1.15rem - 2px)}
.pill--ghost:hover,.pill--ghost:focus-visible{transform:translate(8px,-8px);
  box-shadow:-8px 8px 0 0 var(--verde-acqua)}

/* ── Sticker: parola in blocco colorato ruotato ──────────────────────────── */
.sticker{display:inline-block;font-family:var(--display);text-transform:uppercase;
  font-size:clamp(1.95rem,.2rem + 2.9vw + 4vh,6rem);line-height:.95;
  padding:.12em .3em .18em;border-radius:14px;box-shadow:var(--shadow-sticker)}
.sticker--acqua{background:var(--verde-acqua);color:var(--nero-verde)}
.sticker--ocra{background:var(--ocra);color:var(--nero-verde)}
.sticker--sabbia{background:var(--sabbia);color:var(--bordeaux)}
.sticker--terra{background:var(--terracotta);color:var(--crema)}
.sticker--scuro{background:var(--verde-nero);color:var(--crema)}

/* ── Divisore ────────────────────────────────────────────────────────────── */
.rule{display:flex;align-items:center;gap:1.25rem;color:var(--teal-medio)}
.rule::before,.rule::after{content:"";flex:1;border-top:2.5px dotted currentColor}
.rule b{width:46px;height:46px;border-radius:50%;background:var(--verde-acqua);
  display:grid;place-items:center;color:var(--terracotta);font-size:1.35rem;
  box-shadow:4px 4px 0 0 rgba(34,48,47,.18)}

/* ── Reveal on scroll ────────────────────────────────────────────────────── */
/* 150–200ms del reference (ticket 004 Q3): --dur-reveal di tokens.css è
   560ms e non lo tocchiamo (file non nostro), quindi variabile locale qui. */
:root{--dur-reveal-sober:180ms}
[data-motion="rich"].has-js .rv{opacity:0;transform:translateY(12px);
  transition:opacity var(--dur-reveal-sober) var(--ease-out-expo),transform var(--dur-reveal-sober) var(--ease-out-expo)}
[data-motion="rich"].has-js .rv.is-in{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
  /* stessa identica catena di selettori della regola che nasconde sopra:
     specificità pareggiata (0,3,0), vince perché arriva dopo nel sorgente.
     Era ".has-js .rv" (0,2,0) — più bassa della regola che nasconde, quindi
     non vinceva mai: bug preesistente, corretto qui (unico punto di fix per
     tutto il reveal, vedi nota in motion.css). */
  [data-motion="rich"].has-js .rv{opacity:1;transform:none}
  /* Stesso fix per il reveal-testo sugli sticker (ticket 004 Q1): il testo
     è leggibile da subito, non aspetta lo scroll-into-view. Qui serve
     !important: la regola che nasconde vive in motion.css, caricato DOPO
     base.css — a parità di specificità vincerebbe sempre lei, indipendente
     dalla media query (verificato con Playwright). */
  [data-motion="rich"].has-js .sticker--reveal .sticker__t{transform:none!important}

  /* Sipario: resta attivo anche con motion ridotta — decisione esplicita
     (ticket 004 Q4). Dura ~1,1s, sotto la soglia dei 5s del criterio WCAG
     2.2.2: non è una violazione da correggere. Specificità più alta di "*"
     sopra, stesso peso !important: vince lei sulla durata forzata. Il
     contenitore (.curtain, rimozione a 1300ms) è già 0s: nulla da ripristinare. */
  .curtain__a{animation-duration:500ms!important}
  .curtain__b{animation-duration:640ms!important}

  /* Marquee: si fermano — il reference non li anima affatto con motion
     ridotta (ticket 004 Q4, inverte la scelta precedente). */
  .ticker__track{animation:none!important}
}

/* L'attributo hidden vale solo quanto il foglio del browser: qualsiasi
   display esplicito nel nostro CSS lo scavalca. Questa regola glielo
   restituisce, così `hidden` nasconde davvero. */
[hidden]{display:none !important}
