/* SHARPER 2026 — la homepage pubblica.
   Si appoggia a style.css per palette, tipografia e componenti (.dettaglio, .modulo,
   .campo, .azzera): qui c'è solo quello che esiste unicamente in prima pagina.

   Differenza di fondo rispetto alle altre pagine: là c'è una colonna di navigazione
   fissa e il body le fa spazio con un padding; qui la navigazione è una barra in
   cima e quel padding va tolto, altrimenti la pagina resterebbe spostata di 232px
   verso destra senza niente a sinistra. */

body.home { padding-left: 0; }

/* ═══════════════════════════════════════════════════════════════════ testata */

.testata {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .7rem var(--gutter);
  background: color-mix(in srgb, var(--notte) 82%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--bordo) 70%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

.testata-marchio { display: grid; gap: .05rem; text-decoration: none; color: var(--inchiostro); }
.testata-marchio b {
  font-family: var(--display); font-weight: 800;
  font-size: 1.05rem; letter-spacing: -.005em; line-height: 1.1;
}
.testata-marchio span {
  font-family: var(--dato); font-size: .66rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--inchiostro-3);
}

.testata-voci { margin-left: auto; display: flex; align-items: center; gap: .3rem; }
.testata-voci > a {
  padding: .45rem .7rem;
  border-radius: 8px;
  color: var(--inchiostro-2);
  text-decoration: none;
  font-size: .92rem;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}
.testata-voci > a:hover { background: var(--superficie-2); color: var(--inchiostro); }

/* Il tasto che apre tutto il resto del sito: è l'unico elemento della testata che
   deve farsi notare, quindi è l'unico con un bordo. */
.riservata {
  display: inline-flex; align-items: center; gap: .45rem;
  margin-left: .4rem;
  padding: .45rem .85rem;
  border: 1px solid var(--bordo);
  border-radius: 999px;
  background: var(--superficie);
  color: var(--inchiostro);
  font: inherit; font-size: .9rem;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .15s ease, background .15s ease;
}
.riservata:hover { border-color: var(--ancona); background: var(--superficie-2); }
.riservata .glifo-chiave { width: 15px; height: 15px; flex: 0 0 15px; opacity: .75; }
/* Sessione aperta: il lucchetto si accende, così si vede a colpo d'occhio da
   qualunque pagina pubblica che c'è un accesso attivo su questo browser. */
.riservata[data-stato="dentro"] { border-color: var(--ancona); }
.riservata[data-stato="dentro"] .glifo-chiave { color: var(--ancona); opacity: 1; }

/* Sotto gli 820px la testata va su due righe: il marchio e il tasto in alto, le voci
   sotto in una fila che scorre di lato. Il limite è 820 e non 640 perché a 641px la
   riga sola non ci stava: il marchio veniva schiacciato a 83px di larghezza e 135 di
   altezza. Nascondere le voci, com'era prima sul telefono, lasciava chi arriva da lì
   senza modo di raggiungere le sezioni e la pagina Tutti gli eventi se non scorrendo
   tutta la home.

   Il tasto resta dov'era, in alto a destra, ma per farlo staccare dalla fila delle
   voci (che sta nello stesso <nav>) è posizionato in assoluto rispetto alla testata:
   l'overflow del <nav> non lo taglia, perché il suo contenitore è la testata. Il
   marchio si tiene un'altezza minima uguale a quella del tasto e uno spazio a destra,
   così non si sovrappongono nemmeno quando il nome va su due righe. */
@media (max-width: 820px) {
  .testata { flex-wrap: wrap; row-gap: .1rem; }
  .testata-marchio span { display: none; }
  .testata-marchio { min-height: 2.75rem; align-content: center; padding-right: 8.6rem; }
  .riservata {
    position: absolute;
    top: max(.7rem, env(safe-area-inset-top));
    right: max(var(--gutter), env(safe-area-inset-right));
    margin-left: 0;
  }
  .testata-voci {
    flex: 1 0 100%;
    margin-left: 0;
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .testata-voci::-webkit-scrollbar { display: none; }
  /* 44px di altezza: la misura sotto la quale un dito sbaglia bersaglio (vedi style.css). */
  .testata-voci > a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 .65rem; }
}

/* ═══════════════════════════════════════════════════════════════════ vetrina */

.vetrina {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(2rem, 6vw, 4.5rem) var(--gutter) clamp(2.5rem, 7vw, 5rem);
}

/* Lo sfondo ufficiale SHARPER (la polvere colorata) sta in un div suo e non in un
   background del contenitore: così si può scurire con l'opacità senza portarsi
   dietro anche il testo, che invece deve restare pieno. */
.vetrina-fondo {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: url("../public/sfondo-1200.webp") center / cover no-repeat;
  opacity: .5;
}
@media (min-width: 760px) {
  .vetrina-fondo { background-image: url("../public/sfondo-1600.webp"); }
}

/* Due veli sopra la fotografia. Il primo la spegne dove passa il testo, il secondo
   la fa morire nel blu notte della pagina invece di tagliarla di netto: senza,
   il bordo inferiore della sezione sarebbe una riga orizzontale visibile. */
.vetrina::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, color-mix(in srgb, var(--notte) 45%, transparent) 0%,
                               color-mix(in srgb, var(--notte) 20%, transparent) 30%,
                               var(--notte) 100%),
    linear-gradient(to right, color-mix(in srgb, var(--notte) 10%, transparent) 0%,
                              color-mix(in srgb, var(--notte) 72%, transparent) 100%);
}

.vetrina-dentro {
  position: relative;
  z-index: 2;
  width: min(1180px, 100%);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(220px, 30%) 1fr;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
}

.locandina { margin: 0; }
.locandina img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r);
  /* La locandina è quasi nera ai bordi e su fondo scuro sparirebbe: un filo di
     luce attorno la stacca senza metterle una cornice addosso. */
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--inchiostro) 14%, transparent),
    0 24px 60px rgba(0, 0, 0, .55);
}

/* Il titolo della homepage è l'unico punto del sito scritto tutto maiuscolo, ed è
   una citazione precisa: sulla locandina "NOTTE EUROPEA DEI RICERCATORI", "SHARPER"
   e "ANCONA" sono maiuscole dello stesso slab, incolonnate e serrate. Ripeterlo qui
   è ciò che fa leggere la pagina come il seguito del manifesto invece che come un
   sito che parla dello stesso evento. Vale per questo titolo e basta: nelle pagine
   di lavoro i titoli restano in minuscolo, perché sono strumenti e non manifesti. */
/* Nella vetrina l'occhiello è la riga che nomina l'evento, e il titolo è la stessa
   voce che continua: fra i due ci stava lo stacco delle pagine di lavoro — fino a
   2,5rem — che qui li faceva sembrare due cose diverse. Riavvicinati, si leggono
   come un'unica intestazione, com'è sul manifesto. Vale per la sola homepage: le
   altre pagine tengono il loro respiro. */
.vetrina-testo .eyebrow { margin-bottom: clamp(.45rem, 1.2vw, .8rem); }

/* L'eyebrow adesso vive dentro .titolo-home, e da lì eredita line-height: .88 —
   la stessa strettezza pensata per le maiuscole senza discendenti del titolo
   grande, che qui schiaccerebbe il pallino e le lettere minuscole del testo di
   dato. L'eyebrow si è già impostato da solo il proprio carattere, corpo e
   maiuscolo: le resta solo questa, sola. */
.titolo-home .eyebrow { line-height: normal; }

.titolo-home {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.4rem, 5.8vw, 4.6rem);
  text-transform: uppercase;
  /* Le maiuscole non hanno discendenti: l'interlinea può stringersi sotto l'unità
     senza che una riga tocchi quella sotto, ed è la serratura del manifesto. */
  line-height: .88;
  letter-spacing: -.004em;
  margin: 0 0 1.2rem;
  text-shadow: 0 2px 24px rgba(4, 7, 20, .7);
}
.titolo-home em { font-style: normal; color: var(--ancona); }

.occhiello-home {
  max-width: 52ch;
  color: var(--inchiostro);
  font-size: clamp(1rem, 1.5vw, 1.12rem);
  margin: 0 0 1.8rem;
  text-shadow: 0 1px 16px rgba(4, 7, 20, .8);
}

/* Il marchio dell'ateneo: una firma, non un secondo titolo. Duecentoquaranta pixel
   di larghezza sono la misura in cui «Università Politecnica delle Marche» dentro il
   marchio si legge senza forzare — sotto, quel nome diventa un grigio illeggibile —
   e restano un terzo abbondante del titolo che ha sopra, che è il rapporto giusto fra
   chi organizza e cosa organizza.

   Il file è a 480px, il doppio: il testo dentro un marchio è la prima cosa che si
   sgrana sugli schermi fitti, e in bianco su trasparente sono trentaquattro KB.
   max-width in percentuale e non una seconda misura per il telefono: sotto i 400px di
   colonna il marchio si stringe da solo, e con height:auto le proporzioni le tiene il
   browser e non questo file. */
/* Lo stacco sotto è quasi il triplo di quello sopra, e non è una simmetria mancata:
   il marchio è la firma del testo che ha sopra, e sta con lui. Sotto invece
   cominciano i tre riquadri, che sono un'altra cosa — senza quel respiro il cerchio
   del glifo arriva a toccare il bordo del primo, e due elementi che si sfiorano si
   leggono come uno attaccato all'altro. */
.marchio-univpm { margin: .45rem 0 1.3rem; }
.marchio-univpm img {
  display: block;
  width: 240px;
  max-width: 62%;
  height: auto;
}

/* I tre fatti che servono davvero a chi arriva sulla pagina: quando, dove, quanto
   costa. Stanno in un <dl> perché sono coppie etichetta/valore, non un elenco. */
.fatti {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  margin: 0 0 1.4rem;
}
.fatti > div {
  flex: 1 1 10rem;
  padding: .75rem .9rem;
  border-radius: var(--r);
  border: 1px solid color-mix(in srgb, var(--bordo) 85%, transparent);
  background: color-mix(in srgb, var(--superficie) 72%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.fatti dt {
  font-family: var(--dato); font-size: .68rem; letter-spacing: .13em;
  text-transform: uppercase; color: var(--inchiostro-3);
  margin-bottom: .25rem;
}
.fatti dd { margin: 0; font-size: .92rem; color: var(--inchiostro-2); line-height: 1.35; }
.fatti dd b { color: var(--inchiostro); font-weight: 600; }

.vetrina-azioni { margin: 0; display: flex; flex-wrap: wrap; gap: .6rem; }
/* Il secondo tasto della vetrina porta a Tutti gli eventi: stesso corpo del primo,
   ma col contorno, perché il primo resta quello da premere per primo. */
.bottone-secondario {
  display: inline-block;
  padding: .7rem 1.4rem;
  border: 1px solid color-mix(in srgb, var(--ancona) 60%, var(--bordo));
  border-radius: 999px;
  color: var(--inchiostro);
  font-weight: 600;
  text-decoration: none;
  transition: background .15s ease;
}
.bottone-secondario:hover { background: color-mix(in srgb, var(--ancona) 14%, transparent); }


@media (max-width: 900px) {
  .vetrina-dentro { grid-template-columns: 1fr; justify-items: start; }
  /* Sotto i 900px la locandina non deve mangiarsi tutta la prima schermata: chi
     apre la pagina dal telefono deve vedere anche la data e il tasto. */
  .locandina { width: min(58%, 260px); justify-self: center; }
  /* E si accorcia: a 2:3 invece di 9:16 perde il 7,8% dell'altezza sopra e
     altrettanto sotto, cioè solo fondo nero e polvere. Il fumetto parte al 16% e
     ANCONA finisce all'84%: la grafica resta intera. Sul desktop niente taglio. */
  .locandina img { aspect-ratio: 2 / 3; object-fit: cover; object-position: center; }
}

/* ═══════════════════════════════════════════════════════ sezioni di contenuto */

.blocco-home {
  width: min(1180px, 100% - var(--gutter) * 2);
  margin-inline: auto;
  padding-block: clamp(2.2rem, 5vw, 3.5rem);
  border-top: 1px solid var(--bordo);
  scroll-margin-top: 4.5rem;   /* l'ancora non finisce sotto la testata appiccicata */
}
/* Sul telefono la testata è su due righe (vedi sopra) e le ancore devono scendere
   di più: 4.5rem è l'altezza di una riga sola. */
@media (max-width: 820px) { .blocco-home { scroll-margin-top: 7.2rem; } }

/* I titoli di sezione su una riga sola, da tablet in su.
   `.blocco-testa` porta da style.css un max-width di 62ch, che è la lunghezza di
   riga in cui si legge un paragrafo — la misura giusta per l'occhiello, sbagliata
   per il titolo, dove diventa soltanto il punto in cui andare a capo: «Programma
   SHARPER Stage» si spezzava dopo SHARPER, e «Storie di Ricercatrici e
   ricercatori» dopo la e. Il limite si sposta quindi dal blocco all'occhiello, e il
   titolo prende la colonna, che qui è larga fino a 1180px.
   Sotto i 760 resta tutto com'era: lì la riga è corta per forza e un titolo di
   quattro parole va a capo comunque, come deve. */
@media (min-width: 760px) {
  .blocco-home .blocco-testa { max-width: none; }
  .blocco-home .blocco-testa p { max-width: 62ch; }
}

.filtri-home {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  align-items: end;
  margin-bottom: 1.2rem;
}
.filtri-home .campo { max-width: 260px; }

/* ── il programma ─────────────────────────────────────────────────────────── */

/* ── il programma: una scaletta ────────────────────────────────────────────── */
/* Prima l'ora, poi il titolo, poi la descrizione. Fino a ieri le voci stavano dentro
   gruppi con l'ora nell'intestazione: con tredici interventi a orari tutti diversi
   erano tredici gruppi da uno, e per sapere a che ora fosse la voce che si sta
   guardando bisognava risalire con l'occhio. In una colonna sua l'ora è sempre lì. */

.voci-programma { display: grid; gap: .5rem; }

.voce-programma {
  --c: var(--area-ateneo);
  display: grid;
  /* barretta | ora | testo */
  grid-template-columns: 3px 4.4rem minmax(0, 1fr);
  gap: 0 .9rem;
  align-items: start;
  padding: .8rem 1rem .8rem 0;
  border-radius: var(--r);
  background: var(--superficie);
  border: 1px solid var(--bordo);
  overflow: hidden;
}
/* La barretta di colore dell'area è l'unico posto in cui il colore porta
   informazione: il resto della scheda resta neutro, così non diventa un arcobaleno. */
.voce-programma::before {
  content: "";
  grid-row: 1 / -1;
  background: var(--c);
}

/* L'ora prende il carattere dei dati e il ciano di Ancona: è la chiave con cui la
   sezione è ordinata, come i titoli dei luoghi nella fiera. Le cifre di Futura
   Condensed sono tutte larghe uguale, quindi la colonna resta allineata da sola. */
.voce-programma .quando {
  margin: 0;
  font-family: var(--dato);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: .01em;
  line-height: 1.3;
  color: var(--ancona);
  white-space: nowrap;
}
/* Chi l'orario non ce l'ha ancora lo dice, in piccolo e in grigio: è una voce in
   attesa, non un errore di caricamento. */
.voce-programma .quando.senza-ora {
  font-size: .72rem;
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
  white-space: normal;
}

.voce-programma .cosa { min-width: 0; }

.voce-programma h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.25;
  letter-spacing: -.002em;
  margin: 0 0 .3rem;
  text-wrap: pretty;
}
.voce-programma p { margin: 0 0 .5rem; color: var(--inchiostro-2); font-size: .93rem; }

/* Chi parla (025): sotto il titolo, in tondo e un gradino più in basso per corpo e
   colore. Il titolo resta la prima cosa che si legge; il nome è la seconda, e sul
   palco è quasi sempre il motivo per cui ci si ferma. */
.voce-programma .relatore { margin: 0 0 .4rem; font-size: .9rem; color: var(--inchiostro-2); }

/* ── la miniatura della locandina ─────────────────────────────────────────────
   Nelle storie del gazebo ogni voce porta la sua locandina, piccola, fra l'ora e il
   testo. Una colonna in più, e solo per le voci che ce l'hanno: la classe la mette
   home.js, così chi la locandina non ce l'ha non lascia una colonna vuota in mezzo
   alla lista.

   La misura è 72px, cioè quanto due righe di titolo: più grande diventerebbe una
   griglia di manifesti, che è già la pagina Tutti gli eventi, e questa invece è una
   scaletta da leggere in fila. Quadrata come tutte le altre del sito. */
.voce-programma.con-miniatura { grid-template-columns: 3px 4.4rem 72px minmax(0, 1fr); }

.voce-miniatura { margin: 0; }
.voce-miniatura img {
  display: block;
  width: 72px;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--bordo);
  background: var(--superficie-2);
}

@media (max-width: 520px) {
  /* Sotto questa larghezza una colonna da 4,4rem toglie troppo spazio al titolo:
     l'ora sale sopra, dove è comunque la prima cosa che si legge. */
  .voce-programma {
    grid-template-columns: 3px minmax(0, 1fr);
    gap: .15rem .9rem;
    align-items: start;
  }
  .voce-programma .quando,
  .voce-programma .cosa { grid-column: 2; }

  /* Con la miniatura le colonne restano tre: la barretta, la locandina e il testo.
     L'ora scavalca sopra il testo, come senza miniatura, e la locandina prende le
     due righe. Più stretta qui (60px) perché lo schermo è tutto quello che c'è. */
  .voce-programma.con-miniatura {
    grid-template-columns: 3px 60px minmax(0, 1fr);
    column-gap: .75rem;
  }
  .voce-programma.con-miniatura .voce-miniatura { grid-row: 1 / 3; grid-column: 2; }
  .voce-programma.con-miniatura .quando,
  .voce-programma.con-miniatura .cosa { grid-column: 3; }
  .voce-miniatura img { width: 60px; }
}

/* ── la striscia delle locandine ──────────────────────────────────────────── */
/* Cinque quadrati in fila prima della fiera. Da mille pixel in su ci stanno tutti e
   cinque nella riga; sotto, la striscia scorre di lato con l'aggancio, e la quinta
   che sbuca sul bordo dice da sola che ce n'è dell'altro. È il modo in cui si
   guardano le locandine sul telefono, e costa meno di una griglia che le impila una
   sotto l'altra per tre schermate.

   Niente titolo: è dentro la fiera, sopra il primo gruppo di stand, e un secondo
   titolo lì in mezzo spezzerebbe la sezione invece di aprirla. */
.striscia-stand { margin-block: clamp(.8rem, 2vw, 1.4rem); }

.striscia {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 62vw;
  gap: clamp(.6rem, 1.6vw, 1rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Il gutter della pagina diventa padding della striscia: così la prima locandina
     è allineata al testo sopra, e l'ultima non finisce incollata al bordo. */
  padding-inline: var(--gutter);
  margin-inline: calc(var(--gutter) * -1);
  /* Senza, l'aggancio porta la prima locandina a filo dello schermo e si mangia il
     margine appena messo: lo snap guarda il bordo della finestra di scorrimento,
     non il padding, a meno che non glielo si dica. */
  scroll-padding-inline: var(--gutter);
  scrollbar-width: none;
}
.striscia::-webkit-scrollbar { display: none; }

@media (min-width: 640px) { .striscia { grid-auto-columns: 34vw; } }
@media (min-width: 1000px) {
  .striscia {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    overflow-x: visible;
    padding-inline: 0;
    margin-inline: 0;
  }
}

.stand-locandina { margin: 0; scroll-snap-align: start; }
.stand-locandina img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid var(--bordo);
  background: var(--superficie);
}

/* ── la fiera: una fascia sola, alta quanto la mappa ──────────────────────── */
/* Titolo, numeri, chi porta gli stand e la piazza vista dall'alto stanno tutti
   dentro la stessa riga. Prima erano due blocchi impilati e su uno schermo largo
   diventavano due metri di pagina: il testo si fermava dopo un terzo di colonna e
   sotto restava il vuoto, con la scheda degli ospiti staccata in fondo.

   La mappa non supera i 340px di larghezza — cioè poco più di quattrocento di
   altezza — ed è lei a dire quanto è alta la fascia. Le parole le stanno accanto in
   colonna, dall'alto: titolo, quante attività, il racconto, le pastiglie, gli
   ospiti su una riga. align-items: start e non center, o il testo tornerebbe a
   galleggiare in mezzo al vuoto. */
.fiera-testata {
  display: grid;
  /* Una colonna che non si allarga oltre lo schermo: senza, una riga che non sa
     andare a capo porta con sé la colonna, e il telefono rimpicciolisce la pagina. */
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1rem, 2.4vw, 2rem);
  align-items: start;
  margin-bottom: clamp(1.2rem, 2.5vw, 1.8rem);
}
@media (min-width: 860px) {
  .fiera-testata { grid-template-columns: minmax(0, 1fr) clamp(240px, 27%, 340px); }
}

.fiera-parole { display: grid; gap: .9rem; align-content: start; }
.fiera-testata .blocco-testa { margin-bottom: 0; max-width: none; }

.racconto { margin: 0; max-width: 62ch; color: var(--inchiostro-2); font-size: .97rem; }

/* Le pastiglie con i numeri sono anche la legenda dei colori: lo stesso pallino che
   qui sta accanto a «Scienze» è la barretta che più sotto segna ogni stand. Per
   questo il colore ci va davvero, e non è decorazione. */
.aree-conta {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
}
.aree-conta li {
  --c: var(--area-ateneo);
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .32rem .7rem;
  border: 1px solid color-mix(in srgb, var(--c) 40%, var(--bordo));
  border-radius: 999px;
  background: color-mix(in srgb, var(--superficie) 80%, transparent);
}
.aree-conta .pallino {
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--c);
  flex: none;
}
.aree-conta .nome {
  font-family: var(--dato);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--inchiostro-2);
}
.aree-conta b { font-size: .92rem; color: var(--inchiostro); }

/* Gli ospiti su una riga e non in una scheda: sei nomi sono una frase, e una scheda
   intorno a una frase è una scatola per un fiammifero. L'etichetta sopra in
   maiuscoletto li tiene insieme senza doverlo spiegare. */
.ospiti-riga { margin: 0; color: var(--inchiostro-2); font-size: .92rem; line-height: 1.5; }
.ospiti-riga b {
  display: block;
  margin-bottom: .2rem;
  font-family: var(--dato);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
  font-weight: 400;
}
.ospiti-riga .ente { white-space: nowrap; }
.ospiti-riga .sep { color: var(--inchiostro-3); margin: 0 .1rem 0 .35rem; }

.mappa-piazza { margin: 0; }
/* Solo l'immagine figlia diretta: quando arrivano le zone (058) la figura si riempie
   di .mappa-zone-cornice, che ha bordo e proporzioni sue, e queste righe le
   raddoppierebbero addosso. */
.mappa-piazza > img {
  display: block;
  width: 100%;
  height: auto;
  /* Il rapporto del file, scritto qui perché il posto sia tenuto prima che
     l'immagine arrivi: senza, l'elenco degli stand salta in giù mentre lo si legge. */
  aspect-ratio: 1094 / 1360;
  border-radius: 14px;
  border: 1px solid var(--bordo);
  background: var(--superficie);
  box-shadow: 0 12px 28px rgba(4, 7, 20, .4);
}
.mappa-piazza figcaption {
  margin-top: .5rem;
  font-size: .78rem;
  line-height: 1.35;
  color: var(--inchiostro-3);
  text-wrap: pretty;
}

/* ── il palco: una locandina per intervento ───────────────────────────────── */
/* Sette voci sotto la vetrina, ognuna con il suo quadrato: sono le locandine che
   girano sui social, e dentro hanno già titolo, ora e marchi. Il testo accanto non
   le ripete per vezzo — una locandina non si può cercare, non si può leggere ad
   alta voce e a 200px il suo corpo minore non si legge affatto.

   Due forme e non una: sul telefono la locandina sta sopra, larga quanto la scheda,
   perché è la cosa che si riconosce da lontano; da 760px in su passa a sinistra e
   il testo le sta accanto, che è il modo in cui si legge una scaletta — la colonna
   degli orari resta allineata e l'occhio scende dritto. */
.palco-lista { display: grid; gap: clamp(.8rem, 1.6vw, 1.1rem); }

.palco-voce {
  --c: var(--area-ateneo);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  background: var(--superficie);
  border: 1px solid var(--bordo);
  border-radius: 16px;
  overflow: hidden;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}

@media (min-width: 760px) {
  /* La locandina non prende mai più di un quarto della riga e non scende sotto i
     200px: sopra diventa un manifesto che schiaccia il testo, sotto il titolo
     stampato dentro smette di leggersi e resta una macchia colorata. */
  .palco-voce { grid-template-columns: clamp(200px, 32%, 300px) minmax(0, 1fr); align-items: center; }
}

/* Da mille pixel in su le schede vanno a due per riga. In colonna unica una scheda
   larga mille e alta duecento è quasi tutta vuota: il testo si ferma dopo un terzo
   e il resto è fondo. Due colonne rimettono il rapporto giusto fra la locandina e
   le parole, e le sette voci si vedono quasi tutte in una schermata — che per una
   scaletta è il punto. */
@media (min-width: 1000px) {
  .palco-lista { grid-template-columns: 1fr 1fr; }
}

.palco-voce:hover {
  border-color: color-mix(in srgb, var(--ancona) 35%, var(--bordo));
  transform: translateY(-2px);
  box-shadow: 0 14px 34px rgba(4, 7, 20, .5);
}

.palco-locandina { margin: 0; background: var(--notte); }
.palco-locandina img {
  display: block;
  width: 100%;
  height: auto;
  /* Il file è quadrato e il riquadro pure: nessun ritaglio, nessuna sorpresa. Il
     rapporto scritto qui tiene il posto anche prima che l'immagine arrivi. */
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.palco-dentro {
  padding: clamp(1rem, 2.2vw, 1.5rem);
  display: grid;
  gap: .35rem;
  justify-items: start;
  align-content: center;
}

/* L'ora, come nelle storie: carattere dei dati, ciano di Ancona, cifre tutte larghe
   uguale. Qui però è più grande — è l'unica cosa che si cerca davvero in una
   scaletta, e ha una scheda intera intorno invece di una riga. */
.palco-dentro .quando {
  margin: 0;
  font-family: var(--dato);
  font-weight: 700;
  font-size: 1.35rem;
  line-height: 1.1;
  letter-spacing: .01em;
  color: var(--ancona);
}
.palco-dentro .quando.senza-ora {
  font-size: .78rem;
  font-weight: 400;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
}

.palco-dentro h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.1rem, 1.6vw, 1.35rem);
  line-height: 1.2;
  letter-spacing: -.003em;
  margin: 0;
  text-wrap: pretty;
}

.palco-dentro .relatore { margin: 0; font-size: .95rem; color: var(--inchiostro-2); }
.palco-dentro .etichette { margin-top: .25rem; }

.etichette { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.etichetta {
  font-family: var(--dato);
  font-size: .66rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
  border: 1px solid var(--bordo);
  border-radius: 999px;
  padding: .16rem .55rem;
  white-space: nowrap;
}
.etichetta.luogo { color: var(--inchiostro-2); }
/* Non var(--c) puro, per la stessa ragione dei titoli d'area qui sotto: Agraria
   sta a 2,97:1 su questo fondo, Economia a 3,30 e gli Ospiti a 4,03, e undici pixel
   di maiuscoletto a quel contrasto non si leggono. Schiarite verso l'inchiostro
   tutte e sette passano 4,5:1 — la più scura resta Agraria, a 4,86 — e restano
   riconoscibili come il colore della loro area, che è il mestiere della pastiglia.
   Il contorno resta sul colore crudo: è decorazione, non testo. */
.etichetta.area {
  color: color-mix(in srgb, var(--c) 72%, var(--inchiostro));
  border-color: color-mix(in srgb, var(--c) 45%, transparent);
}
.etichetta.prenota {
  color: var(--ancona);
  border-color: color-mix(in srgb, var(--ancona) 45%, transparent);
}

/* ── la sera del 25: cosa c'è adesso ──────────────────────────────────────── */
/* In piazza alle 19.40 la domanda non è «com'è il programma», è «cosa c'è ora e
   cosa comincia fra un attimo». Due marche rispondono senza far confrontare a mano
   sette orari con l'orologio del telefono.

   Sono testo prima che colore: «In corso» si legge anche da chi il ciano non lo
   vede, e il colore è la conferma, non l'informazione. I token sono quelli che il
   sito usa già per l'accento — ciano pieno con il fondo notte sopra, che è la coppia
   dei tasti principali e tiene 9:1, per quella in corso; lo stesso ciano di solo
   contorno per quella che sta per cominciare, come «Su prenotazione», a 8,4:1.
   Niente movimento: una marca che pulsa, in una lista che si legge in piedi con il
   telefono in mano, diventa la cosa che si guarda invece del programma. */
.marca {
  /* inline-block e non il blocco del <p>: dentro .cosa una pastiglia larga quanto
     la colonna sarebbe una fascia, non una marca. */
  display: inline-block;
  margin: 0;
  font-family: var(--dato);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  /* Il contorno c'è sempre, trasparente dove non serve: così le due marche hanno la
     stessa misura esatta e la pastiglia non cresce di due pixel quando «Fra poco»
     diventa «In corso». */
  border: 1px solid transparent;
  border-radius: 999px;
  padding: .12rem .5rem;
  white-space: nowrap;
}
/* Nel palco lo stacco lo fa il gap della griglia; nelle storie .cosa è un blocco
   normale e il respiro va scritto. */
.voce-programma .marca { margin-bottom: .35rem; }

.marca[data-marca="corso"] { background: var(--ancona); color: var(--notte); }
.marca[data-marca="poco"] {
  color: var(--ancona);
  border-color: color-mix(in srgb, var(--ancona) 45%, transparent);
}

/* Il bordo della scheda accompagna la marca: da lontano, scorrendo la lista col
   pollice, è il segno che si vede prima di leggere. */
.voce-programma[data-momento="corso"],
.palco-voce[data-momento="corso"] { border-color: var(--ancona); }
.voce-programma[data-momento="poco"],
.palco-voce[data-momento="poco"] { border-color: color-mix(in srgb, var(--ancona) 40%, var(--bordo)); }

/* Stato: programma non ancora pubblicato, oppure filtri che non trovano niente. */
.stato-vuoto {
  border: 1px dashed var(--bordo);
  border-radius: var(--r);
  padding: clamp(1.4rem, 4vw, 2.4rem);
  text-align: center;
  color: var(--inchiostro-2);
}
.stato-vuoto b { display: block; color: var(--inchiostro); font-size: 1.05rem; margin-bottom: .4rem; }

/* Anteprima per i redattori: la stessa lista, ma è chiaro che il pubblico non la
   vede. Il tratteggio è la convenzione più economica per dire "bozza". */
.nastro-bozza {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-bottom: 1.2rem;
  padding: .7rem .9rem;
  border: 1px dashed var(--ancona);
  border-radius: var(--r);
  background: color-mix(in srgb, var(--ancona) 8%, transparent);
  font-size: .9rem;
  color: var(--inchiostro-2);
}
.nastro-bozza b { color: var(--ancona); }

/* ── la fiera della scienza ───────────────────────────────────────────────── */
/* Un elenco, non una griglia di schede: gli stand sono cinquantanove, e altrettanti
   riquadri con bordo e sfondo diventerebbero un muro. Qui il colore dell'area sta
   in una riga verticale sottile a sinistra di ogni voce, e il gruppo si legge come
   un blocco unico invece che come tante cose separate.

   Due livelli di titolo, e si devono distinguere a colpo d'occhio senza contare i
   pixel: il luogo prende il ciano di Ancona, come le ore nel programma — è la chiave
   con cui la sezione è ordinata — e l'area prende il proprio colore, più piccola.
   Stesso mestiere, due gradi di importanza. */

.luogo-gruppo { margin-bottom: 2.8rem; }
.luogo-gruppo:last-child { margin-bottom: 0; }

.luogo-testa {
  display: flex;
  align-items: baseline;
  gap: .7rem;
  margin: 0 0 1.2rem;
  padding-bottom: .45rem;
  border-bottom: 2px solid color-mix(in srgb, var(--ancona) 35%, var(--bordo));
}
.luogo-testa h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.3rem, 2.2vw, 1.55rem);
  letter-spacing: -.004em;
  margin: 0;
  color: var(--ancona);
  text-wrap: balance;
}
.luogo-testa span { font-family: var(--dato); font-size: .72rem; color: var(--inchiostro-3); }

.area-gruppo {
  --c: var(--area-ateneo);
  margin-bottom: 1.8rem;
}
.area-gruppo:last-child { margin-bottom: 0; }

.area-testa {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  margin: 0 0 .7rem;
}
.area-testa h4 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -.002em;
  margin: 0;
  /* Non var(--c) puro: i colori delle aree sono tarati per le barre dei grafici,
     e due di loro — Agraria e Economia — su questo fondo scuro arrivano appena
     a 3:1. Schiariti verso l'inchiostro restano riconoscibili e si leggono. */
  color: color-mix(in srgb, var(--c) 72%, var(--inchiostro));
}
.area-testa span { font-family: var(--dato); font-size: .66rem; color: var(--inchiostro-3); }

/* Due o tre colonne secondo la larghezza: in una colonna sola l'area di Scienze,
   con ventun voci, sarebbe uno scorrimento lungo mezzo schermo per volta. */
.voci-fiera {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
  gap: .5rem 1.4rem;
}

.voce-fiera {
  padding: .5rem 0 .55rem .9rem;
  border-left: 2px solid color-mix(in srgb, var(--c) 55%, transparent);
}
.voce-fiera b {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.25;
  letter-spacing: -.002em;
  text-wrap: pretty;
}
.voce-fiera p {
  margin: .2rem 0 .35rem;
  color: var(--inchiostro-2);
  font-size: .9rem;
  line-height: 1.45;
  text-wrap: pretty;
}
/* Chi porta lo stand è un'informazione di servizio: si legge se la si cerca, non
   compete con il titolo. Niente bordo attorno, che qui farebbe rumore, e niente
   maiuscoletto: «A CURA DEL DISVA» urlerebbe: è una frase, non un'etichetta.

   E soprattutto niente `nowrap`, che .etichetta porta con sé: va bene per «SCIENZE»
   o «17.00», che sono due parole in un ovale e spezzarle sarebbe assurdo, non per
   «A cura del Servizio Ricerca e Valorizzazione delle Conoscenze» — sessanta
   caratteri che, non potendo andare a capo, escono dalla colonna e finiscono sopra
   la barretta della voce accanto. */
.voce-fiera .etichetta.dip {
  border: 0;
  padding: 0;
  text-transform: none;
  letter-spacing: .01em;
  font-size: .72rem;
  color: var(--inchiostro-3);
  white-space: normal;
}

/* ── compatta o estesa ────────────────────────────────────────────────────── */
/* L'interruttore: due segmenti attaccati, non due bottoni sparsi. Attaccati perché
   sono due stati della stessa cosa e uno dei due è sempre acceso — la forma dice
   già che è una scelta fra due, e non serve spiegarlo. Sta sopra l'elenco e non
   nella testata della sezione: riguarda la lista, e le sta accanto. */
.vista-scelta {
  display: inline-flex;
  margin: 0 0 1.4rem;
  border: 1px solid var(--bordo);
  border-radius: 999px;
  padding: 2px;
  gap: 2px;
}
.vista-scelta button {
  font-family: var(--dato);
  font-size: .7rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
  background: transparent;
  border: 0;
  border-radius: 999px;
  padding: .35rem .85rem;
  cursor: pointer;
}
.vista-scelta button:hover { color: var(--inchiostro-2); }
/* aria-pressed è già lo stato, e serve alle tecnologie assistive: tanto vale che
   sia anche la sorgente dello stile, invece di una classe che gli corre accanto e
   che un giorno resterà indietro. */
/* --notte e non --sfondo, che in questo progetto non esiste: era una variabile mai
   definita, quindi il colore non veniva applicato affatto e l'etichetta restava
   dell'inchiostro del body — bianco su ciano, 1,78:1, su undici pixel di
   maiuscoletto. Il fondo notte sopra il ciano tiene 9:1, ed è la stessa coppia dei
   tasti principali del sito. */
.vista-scelta button[aria-pressed="true"] {
  color: var(--notte);
  background: var(--ancona);
}

/* La vista compatta. Tutto quello che segue toglie: non c'è una riga che aggiunga
   un elemento o ne sposti uno, perché il DOM è lo stesso delle due viste e deve
   restare l'unica versione della lista.

   La descrizione sparisce ma resta nel documento: la ricerca del browser la trova
   lo stesso, e chi la vuole vedere passa a "Estesa" senza che la pagina ricarichi
   niente. Il "a cura di" sale sulla riga del titolo — è un'informazione di servizio,
   e su una riga sua raddoppierebbe l'altezza di ogni voce per poco. */
#fiera-elenco[data-vista="compatta"] .voce-fiera p { display: none; }

#fiera-elenco[data-vista="compatta"] .voci-fiera {
  /* Righe corte: ci stanno più colonne, e la colonna può essere più stretta. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
  gap: .15rem 1.4rem;
  /* Ogni voce alta quanto il suo testo, non quanto la più alta della riga. Serve
     alla barretta di colore, che è il bordo sinistro della voce: stirata all'altezza
     della cella diventerebbe una stanga lunga il doppio del titolo che accompagna,
     e una fila di stanghe di lunghezze diverse si legge come un errore. */
  align-items: start;
}
#fiera-elenco[data-vista="compatta"] .voce-fiera { padding: .3rem 0 .32rem .8rem; }
#fiera-elenco[data-vista="compatta"] .voce-fiera b {
  display: inline;
  font-size: .95rem;
}
#fiera-elenco[data-vista="compatta"] .voce-fiera .etichetta.dip { display: inline; }
#fiera-elenco[data-vista="compatta"] .voce-fiera .etichetta.dip::before { content: " · "; }

/* In colonna stretta il «a cura di» va a capo da solo, e il punto separatore resta
   appeso all'inizio della riga nuova — un puntino solo, sotto il titolo, che sembra
   un errore di battitura. Da telefono, dove il titolo occupa quasi sempre tutta la
   riga, l'ente torna a essere una riga sua e il separatore non serve più: a separare
   basta l'andare a capo. Sopra i 640px la riga è larga abbastanza perché stiano
   insieme, e lì il punto ci vuole. */
@media (max-width: 640px) {
  #fiera-elenco[data-vista="compatta"] .voce-fiera .etichetta.dip { display: block; }
  #fiera-elenco[data-vista="compatta"] .voce-fiera .etichetta.dip::before { content: none; }
}

/* I gruppi si stringono con le voci: lasciare l'aria di prima attorno a righe alte
   la metà farebbe una lista fatta più di spazi vuoti che di stand. */
#fiera-elenco[data-vista="compatta"] .luogo-gruppo { margin-bottom: 2rem; }
#fiera-elenco[data-vista="compatta"] .luogo-gruppo:last-child { margin-bottom: 0; }
#fiera-elenco[data-vista="compatta"] .area-gruppo { margin-bottom: 1.15rem; }
#fiera-elenco[data-vista="compatta"] .area-gruppo:last-child { margin-bottom: 0; }
#fiera-elenco[data-vista="compatta"] .area-testa { margin-bottom: .45rem; }

/* ── dove e quando ────────────────────────────────────────────────────────── */

.griglia-info {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1rem;
}
.scheda-info {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--bordo);
  border-radius: var(--r);
  background: var(--superficie);
}
.scheda-info h3 {
  font-family: var(--display); font-weight: 600; font-size: 1.1rem;
  letter-spacing: -.002em; margin: 0 0 .5rem;
}
.scheda-info p { margin: 0 0 .6rem; color: var(--inchiostro-2); font-size: .93rem; }
.scheda-info p:last-child { margin-bottom: 0; }

.collegamento { color: var(--ancona); text-decoration-color: color-mix(in srgb, var(--ancona) 45%, transparent); }

/* ═══════════════════════════════════════════════════════════════════ il piede */

.pie-home {
  border-top: 1px solid var(--bordo);
  padding-block: 2rem 3rem;
  margin-top: 1rem;
}
/* La dicitura obbligatoria è un'immagine, e questo decide tutto il resto: non si
   riflow, quindi la sua larghezza è anche la sua leggibilità. 760px è la misura in
   cui le due righe si leggono comode; sotto, l'immagine si stringe con la colonna e
   il testo rimpicciolisce insieme a lei — è il prezzo di una formula che dev'essere
   riprodotta esatta invece che riscritta. */
.pie-home .dicitura-ufficiale { margin: 0; }

/* La riga sul conteggio delle visite: sta sotto la dicitura obbligatoria e non deve
   competerci, quindi corpo piccolo e inchiostro terzo. Resta comunque sopra la soglia
   di contrasto, perché è un'informazione e non una decorazione. */
.pie-home .nota-conteggio {
  margin: 1.2rem 0 0;
  max-width: 62ch;
  font-size: .78rem;
  line-height: 1.5;
  color: var(--inchiostro-3);
}
.pie-home .dicitura-ufficiale img {
  display: block;
  width: 100%;
  max-width: 760px;
  height: auto;
}

/* ── i loghi in fondo ─────────────────────────────────────────────────────── */
/* La barra del 6x3, portata sul sito. È bianca e va da un bordo all'altro perché
   nel manifesto è così: una striscia che chiude la pagina, non un riquadro dentro
   il blu notte. Sul sito il motivo è anche pratico — questi loghi esistono solo
   nella versione a colori per fondo chiaro, e su scuro andrebbero rifatti uno per
   uno in negativo. */
.fascia-loghi {
  background: #fff;
  padding-block: 1.5rem 1.7rem;
  margin-top: 0;
}

.fascia-loghi-titolo {
  margin: 0 0 1.1rem;
  font-family: var(--dato);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  /* Un grigio scuro sul bianco, non l'inchiostro del sito: quello è tarato sul blu
     notte e qui sarebbe più nero del nero dei loghi. */
  color: #6b7280;
}

.loghi {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .9rem 1rem;
}

/* Dodici marchi su una riga sola, sul desktop: la fila si legge come una fila e non
   come due mezze file, e nessuno dei dodici sembra più importante per il solo fatto
   di essere capitato in cima.

   Per starci non basta stringere l'altezza: i marchi hanno proporzioni che vanno da
   1:1 a quasi 4:1, e con l'altezza uguale per tutti quelli allungati si prendevano
   centocinquanta pixel a testa. Qui ognuno si iscrive in un rettangolo — trentaquattro
   di alto, centouno di largo — e a decidere è il lato che tocca per primo: i quadrati
   restano alti trentaquattro, i lunghi scendono e stanno dentro i centouno.
   È il modo in cui una fila di loghi si equilibra davvero, perché l'occhio pesa
   l'area, non l'altezza. */
/* Dieci dei dodici loghi sono link verso il sito dell'ente. Il link deve essere alto
   quanto l'immagine e non un pixel di più: lasciato inline, sotto la riga di base
   resterebbe lo spazio che i browser tengono per i discendenti delle lettere, e il
   contorno ciano del fuoco da tastiera lo disegnerebbe intorno a quello spazio invece
   che intorno al logo. Colore e scostamento del contorno non si ripetono qui: li mette
   già la regola generale sui link in style.css. */
.loghi a { display: block; }

.loghi img {
  display: block;
  width: auto;
  height: auto;
  max-height: 34px;
  max-width: 101px;
  object-fit: contain;
}

/* I tre che a parità di regola restavano i più ingombranti. Non è una gerarchia fra
   enti: è che «Istat», «fosforo:» e «Ancona Città Universitaria» sono scritte grandi
   dentro un marchio corto, e alla misura degli altri gridavano più di tutti. */
.loghi .minore img {
  max-height: 25px;
  max-width: 71px;
}

@media (max-width: 1023px) {
  /* La soglia è 1023 e non 900 perché è lì che i dodici, alla misura piena, non
     ci stanno più in una riga: un filo più piccoli ce la fanno ancora fino a circa
     940px di finestra, e sotto vanno a capo — che è meglio che rimpicciolirli fino
     a renderli illeggibili pur di tenerli in fila. */
  .loghi { gap: .8rem 1.1rem; }
  .loghi img { max-height: 30px; max-width: 87px; }
  .loghi .minore img { max-height: 23px; max-width: 64px; }
}

/* ═════════════════════════════════════════════════════════ dialogo di accesso */

.dettaglio-nota { color: var(--inchiostro-2); margin: 0; font-size: .93rem; }
.dettaglio .azioni { display: flex; gap: .6rem; justify-content: flex-end; align-items: center; margin-top: 1rem; }

/* Le tre porte dell'area riservata: bersagli grandi, perché è la cosa che si fa
   subito dopo aver messo la password. */
.porte { list-style: none; margin: 1.1rem 0 0; padding: 0; display: grid; gap: .5rem; }
.porte a {
  display: grid;
  gap: .15rem;
  padding: .8rem .95rem;
  border: 1px solid var(--bordo);
  border-radius: var(--r);
  background: var(--superficie-2);
  text-decoration: none;
  transition: border-color .15s ease, background .15s ease;
}
.porte a:hover { border-color: var(--ancona); background: var(--superficie); }
.porte b { font-family: var(--display); font-weight: 600; font-size: 1rem; }
.porte span { color: var(--inchiostro-2); font-size: .87rem; }

/* ═══════════════════════════════════════════════════════════════════ movimento */
/* Poco, e solo dove qualcosa comparirebbe di colpo. Le tre regole che governano
   quello che segue:

   · si animano solo `transform` e `opacity`, che non fanno rifare al browser il
     calcolo del layout;
   · niente supera i 320ms — un'animazione di interfaccia più lunga si legge come
     lentezza, non come cura;
   · la curva è una sola, ed è un ease-out: la cosa parte veloce e si posa. Le
     easing predefinite del CSS sono troppo blande per vedersi a queste durate.

   Chi ha chiesto meno movimento al sistema operativo non vede niente di tutto
   questo: style.css azzera animazioni e transizioni sotto prefers-reduced-motion,
   e queste ci finiscono dentro senza doversi ripetere qui. */

body.home { --ease-out: cubic-bezier(.23, 1, .32, 1); }

/* Le voci arrivano da una fetch: prima la pagina è vuota, poi tredici interventi
   compaiono tutti insieme. Non è una decorazione, è il ponte su quel salto —
   entrano dal basso di sei pixel, sfalsate di quaranta millisecondi, e l'occhio
   le legge come una lista che si posa invece che come uno schermo che cambia.

   Lo sfalsamento si ferma all'ottava voce: `--i` continua a crescere, ma oltre
   quella soglia l'attesa dell'ultimo arrivato conterebbe più dell'effetto. È lo
   stesso mestiere di `@keyframes accendi` in style.css, con il ritardo tenuto
   corto perché qui le voci sono grandi e poche, non caselle in una griglia. */
@keyframes entra-voce {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.voci-programma.entra > .voce-programma,
.palco-lista.entra > .palco-voce,
#fiera-elenco.entra > .luogo-gruppo {
  animation: entra-voce .32s var(--ease-out) both;
  animation-delay: calc(min(var(--i, 0), 8) * 40ms);
}

/* Nella fiera si muovono i quattro gruppi di luogo, non le sessanta voci dentro:
   sessanta ritardi sono un'onda che attraversa lo schermo per due secondi, e a
   quel punto il movimento è la cosa che si guarda invece del programma. */

/* L'interruttore compatta/estesa: il colore che scivola invece di scattare. È un
   cambio di stato che si fa poche volte, e 150ms su un colore sono impercettibili
   quanto basta — non c'è nessun movimento, quindi nessun ritardo percepito. */
.vista-scelta button { transition: color .15s ease, background .15s ease; }

/* Il dialogo di accesso. Modale: nasce dov'è, al centro, senza inseguire il tasto
   che l'ha aperto — un modale non è ancorato a un trigger. Sale di sei pixel e
   arriva da 98% di scala: mai da scale(0), perché niente al mondo compare dal
   nulla, e la scala minima serve solo a dare la direzione.

   `allow-discrete` è quello che permette anche l'uscita: senza, `display: none`
   scatterebbe al primo fotogramma e la chiusura resterebbe secca. Dove non è
   supportato la regola `[open]` vince lo stesso e il dialogo appare istantaneo,
   come prima: si perde l'animazione, non il dialogo. */
.home .dettaglio {
  opacity: 0;
  transform: translateY(6px) scale(.98);
  transition:
    opacity .2s var(--ease-out),
    transform .2s var(--ease-out),
    overlay .2s allow-discrete,
    display .2s allow-discrete;
}
.home .dettaglio[open] { opacity: 1; transform: none; }
@starting-style {
  .home .dettaglio[open] { opacity: 0; transform: translateY(6px) scale(.98); }
}

.home .dettaglio::backdrop {
  opacity: 0;
  transition: opacity .2s var(--ease-out), overlay .2s allow-discrete, display .2s allow-discrete;
}
.home .dettaglio[open]::backdrop { opacity: 1; }
@starting-style {
  .home .dettaglio[open]::backdrop { opacity: 0; }
}

/* Le voci della testata sono ancore verso tre punti della stessa pagina: senza
   scorrimento continuo lo schermo si teletrasporta e si perde il filo di dov'era.
   Sta sotto no-preference e non dentro il blocco reduce di style.css perché
   scroll-behavior non è una transizione e quel blocco non lo spegnerebbe. */
@media (prefers-reduced-motion: no-preference) {
  html:has(body.home) { scroll-behavior: smooth; }
}

/* ═══════════════════════════════════════════════════════════════════ dettagli */

@media (prefers-reduced-motion: reduce) {
  .bottone-principale, .riservata, .porte a, .testata-voci > a { transition: none; }
  .bottone-principale:hover { transform: none; }
}

/* ── la copia scritta al build ───────────────────────────────────────────────────
   L'elenco che scripts/build-config.mjs scrive dentro i tre contenitori. Di solito
   nessuno lo vede: il JavaScript lo sostituisce con i dati freschi appena arrivano.
   Si vede in due casi, e sono i due che contano. Il primo è un motore di ricerca o
   un assistente, che non esegue JavaScript e legge solo questo. Il secondo è una
   persona con la rete che non passa, la sera del 25 in piazza: per lei questa è la
   pagina, e senza una riga di stile sarebbe un elenco puntato di sistema in Times,
   cioè il sito che si toglie la giacca proprio quando arrivano gli ospiti.

   Poche righe apposta: deve somigliare alle liste vere, non copiarle. Copiare la
   scheda vera qui vorrebbe dire mantenere due volte lo stesso disegno, e la seconda
   copia invecchierebbe in silenzio, perché quasi nessuno la guarda. */
.prerender {
  margin: 0;
}

.prerender > p {
  margin: 0 0 .9rem;
  font-family: var(--dato);
  font-size: .82rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--inchiostro-2);
}

.prerender ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 1px;
  background: var(--bordo);
  border: 1px solid var(--bordo);
  border-radius: var(--r);
  overflow: hidden;
}

.prerender li {
  margin: 0;
  padding: .7rem .9rem;
  background: var(--superficie);
  color: var(--inchiostro);
  font-size: .95rem;
  line-height: 1.35;
}

/* L'ora in testa alla riga, nello stesso carattere delle ore delle liste vere: le
   cifre del condensato bold sono tutte larghe uguale, quindi la colonna si allinea
   anche senza una griglia. */
.prerender li b {
  font-family: var(--dato);
  color: var(--ancona);
  margin-right: .5rem;
}

/* Luogo e chi porta l'attività: sono il contorno, e si leggono dopo il titolo. */
.prerender li span {
  color: var(--inchiostro-3);
}

.prerender li span::before {
  content: " · ";
  color: var(--bordo);
}

/* ── la griglia dei laboratori ───────────────────────────────────────────────────
   Righe che sono attività, colonne che sono orari, e in mezzo un pallino per ogni
   turno: è la forma di un orario ferroviario, e si legge per la stessa ragione. Il
   pallino porta il colore dell'area dell'attività, lo stesso che quella scheda ha
   nell'elenco della fiera e sulla piantina, così chi l'ha già incontrata la
   riconosce prima di leggerne il nome. */
.laboratori-griglia {
  border: 1px solid var(--bordo);
  border-radius: var(--r);
  background: var(--superficie);
  /* Su telefono la tabella scorre invece di spezzare le colonne: tre orari affiancati
     sotto i 400 px diventerebbero illeggibili, e una tabella che scorre resta una
     tabella. */
  overflow-x: auto;
}

.laboratori-griglia table {
  width: 100%;
  border-collapse: collapse;
  min-width: 26rem;
}

.laboratori-griglia th,
.laboratori-griglia td {
  padding: .8rem 1rem;
  text-align: center;
  border-bottom: 1px solid var(--bordo);
}
.laboratori-griglia tbody tr:last-child th,
.laboratori-griglia tbody tr:last-child td { border-bottom: 0; }

.laboratori-griglia thead th {
  font-family: var(--dato);
  font-size: .78rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
  font-weight: 400;
  white-space: nowrap;
}
.laboratori-griglia thead th:first-child { text-align: left; }

/* La colonna dei nomi: larga quanto serve, con la barretta d'area a sinistra.
   Il selettore porta anche il contenitore perché `.laboratori-griglia th` ha una
   classe e un elemento, quindi batteva la sola `.lab-nome`: le due righe sotto il
   titolo, l'ente e l'età, restavano centrate mentre il titolo era a sinistra. */
.laboratori-griglia .lab-nome {
  text-align: left;
  border-left: 3px solid var(--c, var(--bordo));
  width: 60%;
  font-weight: 400;
}

.lab-titolo {
  display: block;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--inchiostro);
  text-align: left;
  cursor: pointer;
  /* Sottolineatura discreta: dice che si preme senza trasformare una riga di tabella
     in un link azzurro, che qui somiglierebbe a tutto il resto e a niente. */
  text-decoration: underline;
  text-decoration-color: var(--bordo);
  text-underline-offset: 3px;
}
.lab-titolo:hover { text-decoration-color: var(--c, var(--ancona)); }

/* Chi porta il laboratorio: dipartimento o ente, sotto il titolo. In tondo e in
   grigio, perché è il secondo dato della riga e non deve competere con il nome. */
.lab-chi {
  display: block;
  margin-top: .25rem;
  font-size: .88rem;
  line-height: 1.3;
  color: var(--inchiostro-2);
}

.lab-eta {
  display: block;
  margin-top: .2rem;
  font-family: var(--dato);
  font-size: .74rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
}

.lab-cella { width: 4.5rem; }

/* Il pallino: il colore dice che c'è posto, il numero dentro dice quanto. Un pallino
   grande abbastanza da premerlo col pollice, che è come lo premerà quasi chiunque. */
/* Il pallino si vede piccolo, ma il bottone resta di 2.4rem: è l'area che il dito
   deve centrare sul telefono, e rimpicciolirla insieme al disegno la renderebbe
   difficile da premere. Il disegno è lo pseudo-elemento. */
.lab-pallino {
  display: inline-grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}
.lab-pallino::after {
  content: "";
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  border: 2px solid var(--c, var(--ancona));
  background: color-mix(in srgb, var(--c, var(--ancona)) 88%, var(--notte));
  transition: transform 150ms, filter 150ms;
}
.lab-pallino:hover:not(:disabled)::after { transform: scale(1.2); filter: brightness(1.1); }
.lab-pallino:focus-visible { outline: 2px solid var(--ancona); outline-offset: 0; }

/* Esaurito: vuoto e spento, ma ancora visibile. Sparire farebbe credere che quel
   turno non sia mai esistito, e chi cerca un posto deve poter vedere che c'era. */
.lab-pallino:disabled { cursor: not-allowed; }
.lab-pallino:disabled::after {
  background: transparent;
  border-color: var(--bordo);
}

/* ── dentro il dialogo ───────────────────────────────────────────────────────────
   La sezione sta alta nella pagina e deve dire due cose in un colpo: che i posti
   sono pochi e che si tengono adesso. Per questo i turni sono bottoni grandi, e non
   un elenco da leggere: la scelta è l'ora, e l'ora è
   la cosa che si guarda. */
/* ── la testa del dialogo di prenotazione ────────────────────────────────────
   La locandina del laboratorio e, accanto, il titolo con la nota. Chi arriva qui da
   un pallino della griglia non ha ancora visto altro che un cerchio colorato, e la
   locandina è la stessa che gira sui social: dentro ha turni, luogo e titolo.

   La × di chiusura sta in alto a destra: il titolo le lascia spazio con un padding,
   altrimenti su uno schermo stretto le finirebbe sotto.

   Sul telefono la locandina galleggia a sinistra e il testo le gira intorno: le
   prime righe del titolo le stanno accanto, il resto riprende la larghezza piena
   sotto. Due colonne rigide facevano un titolo di sei righe da due parole, e la
   locandina larga quanto il dialogo andava ritagliata per non mangiarsi la
   schermata, tagliando il titolo che ci sta stampato. Intera, e mai ritagliata. */
.prenota-testa { display: flow-root; }
.prenota-locandina { float: left; width: 104px; margin: 0 .9rem .5rem 0; }
.prenota-testa-testo { min-width: 0; }
.prenota-testa-testo h3 { margin-top: 0; padding-right: 2rem; }
/* Accanto a una colonna da 104px il titolo ha poco più di centosessanta pixel: al
   corpo pieno del dialogo una parola lunga ci starebbe in tre righe da due sillabe.
   Un gradino sotto, e la nota pure. */
@media (max-width: 559px) {
  .prenota-testa-testo h3 { font-size: 1.15rem; }
  .prenota-testa-testo .dettaglio-nota { font-size: .86rem; }
  /* Scelto il turno, la locandina ha finito il suo lavoro: si stringe, e il campo
     «nome» entra nella schermata invece di restare sotto il bordo. La classe la
     mette prenotazioni.js quando apre il modulo. */
  .prenota-dialogo.con-modulo .prenota-locandina { width: 72px; }
  .prenota-dialogo.con-modulo .prenota-testa-testo .dettaglio-nota { display: none; }
}

.prenota-locandina img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--bordo);
  background: var(--superficie-2);
}

/* Da 560px in su c'è spazio per due colonne vere: la locandina più grande a
   sinistra, il testo tutto accanto senza avvolgerla. */
@media (min-width: 560px) {
  .prenota-testa { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 1.2rem; align-items: start; }
  .prenota-locandina { float: none; width: auto; margin: 0; }
}

.prenota-turni-scelta {
  display: flex;
  flex-wrap: wrap;
  gap: .7rem;
  margin: 1.2rem 0 0;
}

.prenota-lab {
  background: var(--superficie);
  border: 1px solid var(--bordo);
  border-radius: var(--r);
  padding: 1.2rem 1.3rem 1.3rem;
}

.prenota-lab h3 {
  font-family: var(--display);
  font-size: 1.15rem;
  line-height: 1.15;
  margin: 0 0 .5rem;
}

.prenota-desc { margin: 0 0 .6rem; color: var(--inchiostro-2); font-size: .95rem; }

.prenota-chi {
  margin: 0 0 1rem;
  font-family: var(--dato);
  font-size: .76rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--inchiostro-3);
}

.prenota-turni { display: flex; flex-wrap: wrap; gap: .6rem; }

.prenota-turno {
  flex: 1 1 6.5rem;
  display: grid;
  gap: .15rem;
  padding: .7rem .5rem;
  border: 1px solid var(--ancona);
  border-radius: calc(var(--r) - 3px);
  background: transparent;
  color: var(--inchiostro);
  font: inherit;
  cursor: pointer;
  transition: background 150ms, color 150ms;
}
.prenota-turno b { font-family: var(--dato); font-size: 1.15rem; color: var(--ancona); }
.prenota-turno span { font-size: .78rem; color: var(--inchiostro-3); }
.prenota-turno:hover:not(:disabled) { background: color-mix(in srgb, var(--ancona) 14%, transparent); }

/* Esaurito: resta leggibile e smette di sembrare premibile. Non si nasconde, perché
   sapere che quel turno esiste ed è pieno è un'informazione, e perché sparire farebbe
   credere di aver letto male. */
.prenota-turno:disabled {
  border-color: var(--bordo);
  cursor: not-allowed;
  opacity: .75;
}
.prenota-turno:disabled b { color: var(--inchiostro-3); }

.prenota-modulo {
  margin-top: 1.4rem;
  background: var(--superficie-2);
  border: 1px solid var(--bordo);
  border-radius: var(--r);
  padding: 1.2rem 1.3rem;
}

.prenota-scelto-riga { margin: 0 0 1rem; color: var(--inchiostro-2); }
.prenota-scelto-riga b { color: var(--inchiostro); }

.prenota-form {
  display: grid;
  gap: .9rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  align-items: end;
}
.prenota-form .campo { display: grid; gap: .35rem; margin: 0; }
.prenota-form label {
  font-family: var(--dato);
  font-size: .76rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--inchiostro-2);
}
.prenota-form input,
.prenota-form select {
  font: inherit;
  padding: .6rem .7rem;
  border-radius: calc(var(--r) - 4px);
  border: 1px solid var(--bordo);
  background: var(--notte);
  color: var(--inchiostro);
}
.prenota-form input::placeholder { color: var(--inchiostro-3); }
.prenota-azioni { display: flex; gap: .6rem; flex-wrap: wrap; margin: 0; }

/* Il gemello sobrio di .bottone-principale, che nel progetto non c'era perché finora
   non era mai servito un secondo bottone accanto a uno primario. Stessa forma e
   stessa altezza, così i due stanno in riga senza scalini: cambia solo che questo non
   chiama, accompagna. */
.bottone-secondario {
  display: inline-block;
  padding: .7rem 1.2rem;
  border-radius: 999px;
  border: 1px solid var(--bordo);
  background: transparent;
  color: var(--inchiostro-2);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 150ms, color 150ms;
}
.bottone-secondario:hover { border-color: var(--inchiostro-3); color: var(--inchiostro); }

.prenota-privacy {
  margin: 1.1rem 0 0;
  max-width: 68ch;
  font-size: .78rem;
  line-height: 1.5;
  color: var(--inchiostro-3);
}

.prenota-esito {
  margin: 1.2rem 0 0;
  padding: .9rem 1.1rem;
  border-radius: var(--r);
  border: 1px solid var(--bordo);
  background: var(--superficie);
}
.prenota-esito[data-tipo="fatto"] { border-color: var(--ancona); }
/* Il rosso dell'area Medicina è l'unico rosso della palette, ed è già stato scelto
   per stare su questo fondo: un rosso nuovo apposta per gli errori sarebbe un colore
   in più da far tornare con gli altri sette. */
.prenota-esito[data-tipo="errore"] { border-color: var(--area-medicina); }
/* Il QR su fondo bianco, con il suo margine: su uno sfondo scuro i telefoni faticano
   a trovare gli angoli, e chi lo fotografa dallo schermo deve poterlo rileggere. */
.prenota-qr {
  display: block;
  width: min(225px, 100%);
  height: auto;
  margin: .9rem auto 0;
  border-radius: 8px;
  background: #fff;
  image-rendering: pixelated;
}

.prenota-vuoto { color: var(--inchiostro-3); margin: 0; }

/* Il luogo sulla mappa, accanto a «A cura di»: è un'etichetta che si preme, e per
   questo ha il ciano e il bordo pieno invece del grigio delle altre. */
.etichetta.dove {
  font: inherit;
  font-family: var(--dato);
  font-size: .72rem;
  letter-spacing: .04em;
  cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--ancona) 55%, transparent);
  color: var(--ancona);
  background: color-mix(in srgb, var(--ancona) 12%, transparent);
}
.etichetta.dove:hover { background: color-mix(in srgb, var(--ancona) 22%, transparent); }
