/* ------------------------------------------------------------------
   Bacheca — piano infinito, immagini e fili, nessuna scritta
   ------------------------------------------------------------------ */

:root {
  /* il carattere di base lo decide la configurazione (default Arial, che non
     costa nulla perché è già nel sistema). La libreria sta in fonts.css. */
  --sans: Arial, Helvetica, sans-serif;
  --paper: #ffffff;
  --ink: #0b0b0c;
  /* gradi intermedi dell'inchiostro: servono perché il tema scuro li ribalta
     tutti in un punto solo. Scriverli a mano in rgba li renderebbe invisibili
     su fondo nero. Stessa cosa per il colore delle ombre. */
  --ink-body: rgba(11, 11, 12, .82);
  /* i gradi tenui restano tenui, ma sopra la soglia di lettura (WCAG AA ~4.5:1
     per il corpo piccolo): .45/.38/.3 su bianco non ci arrivavano */
  --ink-2: rgba(11, 11, 12, .58);
  --ink-3: rgba(11, 11, 12, .5);
  --ink-4: rgba(11, 11, 12, .42);
  --shadow-rgb: 11, 11, 12;
  --thread: rgba(11, 11, 12, .22);
  --thread-on: rgba(11, 11, 12, .78);
  --hair: rgba(11, 11, 12, .12);
  --rosso: #c8102e;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* sfondo scuro: si cambia dalla configurazione, per provare */
:root[data-theme="scuro"] {
  --paper: #0b0b0c;
  --ink: #f2f2f2;
  --ink-body: rgba(242, 242, 242, .82);
  --ink-2: rgba(242, 242, 242, .58);
  --ink-3: rgba(242, 242, 242, .5);
  --ink-4: rgba(242, 242, 242, .42);
  --shadow-rgb: 0, 0, 0;
  --thread: rgba(242, 242, 242, .26);
  --thread-on: rgba(242, 242, 242, .85);
  --hair: rgba(242, 242, 242, .16);
  --rosso: #ff4d5e;
}
/* il fondo scuro NON vale per i testi: un testo è inchiostro sul piano, non un
   riquadro. Senza il :not() questa regola vinceva su .node--note (specificità
   più alta) e ogni scritta finiva dentro una scatola nera. */
:root[data-theme="scuro"] .node:not(.node--note) { background: #17171a; }
:root[data-theme="scuro"] .frame-passepartout,
:root[data-theme="scuro"] .frame-polaroid { background: #17171a; }
:root[data-theme="scuro"] .lightbox__scrim { background: rgba(var(--shadow-rgb), .9); }
:root[data-theme="scuro"] .lightbox__figure { background: #17171a; }
/* La linguetta NON va ridipinta qui: il suo fondo è calcolato dal cursore
   «quanto si notano» e usa già --ink/--paper, che il tema ribalta da soli.
   Con l'override il cursore non aveva effetto su fondo nero. */
:root[data-theme="scuro"] .sheet { background: #17171a; color: var(--ink); }

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

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
  touch-action: none;
}

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

/* ---------------------------------------------------------- piano */

#stage {
  position: fixed;
  inset: 0;
  cursor: grab;
  contain: layout paint;
}
/* Il gesto lo gestiamo noi, su OGNI elemento toccabile: `touch-action` vale
   per il bersaglio del tocco, non si eredita. Senza questo il browser mobile
   avvia il proprio scorrimento e annulla il trascinamento a metà. */
#stage, #stage * {
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
#stage.is-dragging { cursor: grabbing; }
#stage.is-locked { pointer-events: none; }


#world {
  position: absolute;
  top: 0; left: 0;
  width: 0; height: 0;
  transform-origin: 0 0;
}
/* will-change solo in movimento: fluido mentre si muove, ridisegnato
   alla scala giusta (quindi nitido) quando si ferma */
#world.is-moving { will-change: transform; }

/* --------------------------------------------------------- i fili */

.threads {
  position: absolute;
  overflow: visible;
  pointer-events: none;
}
.threads path {
  fill: none;
  stroke: var(--thread);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;   /* filo sempre sottile, a ogni zoom */
  transition: stroke .3s linear, stroke-width .3s linear;
}
.threads path.is-lit {
  stroke: var(--thread-on);
  stroke-width: 1.4;
}
.threads circle {
  fill: var(--ink);
  opacity: .5;
  transition: opacity .3s linear;
}
.threads circle.is-lit { opacity: 1; }

/* ------------------------------------------------- agglomerati */

.cluster {
  position: absolute;
  top: 0; left: 0;
  width: 0; height: 0;
  transition: filter .4s var(--ease-out), opacity .4s linear;
}
/* puntandone uno, gli altri escono di fuoco */
#world.is-hot .cluster:not(.is-hot) {
  filter: blur(9px);
  opacity: .5;
}
/* mentre la camera si muove il filtro si sospende: si rasterizzerebbe
   a ogni fotogramma proprio quando serve fluidita'.
   Specificita' più alta della regola qui sopra, altrimenti non vincerebbe. */
#world.is-moving.is-hot .cluster:not(.is-hot) { filter: none; }

/* -------------------------------------------------------- immagini */

/* La posizione sta in `transform`, non in left/top: così cambiare la
   configurazione fa SCIVOLARE le immagini (transizione composita) invece di
   farle saltare, e il trascinamento resta a costo zero. */
.node {
  position: absolute;
  left: 0; top: 0;
  margin: 0;
  padding: 0;
  border: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  overflow: hidden;
  /* un fondo tenue: la lavagna si vede DISPORSI mentre le immagini arrivano.
     Prima erano riquadri bianchi su fondo bianco: sembrava non caricare. */
  background: color-mix(in srgb, var(--ink) 6%, var(--paper));
  opacity: 0;
  animation: node-in .45s linear forwards;
  animation-delay: var(--delay, 0ms);
  transform: translate3d(var(--x, 0px), var(--y, 0px), 0) rotate(var(--rot, 0deg));
  transform-origin: 50% 50%;
  transition: box-shadow .35s var(--ease-out), transform .35s var(--ease-out);
}
@keyframes node-in { to { opacity: 1; } }

/* ri-disposizione dal vivo: più lenta e morbida, e anche le misure seguono */
#world.is-flowing .node {
  transition: box-shadow .35s var(--ease-out),
              transform .62s var(--ease-out),
              width .5s var(--ease-out),
              height .5s var(--ease-out);
}
/* mentre si trascina non c'è nessuna transizione: l'elemento sta sotto il dito */
#stage.is-dragging .node { transition: none; }

.node.is-source { visibility: hidden; }
.node.is-off { display: none; }
[data-edit] .node.is-off { display: block; opacity: .22; }

.node img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .6s linear;
  pointer-events: none;
}
.node img.is-ready { opacity: 1; }

/* copertina animata del video: sta sopra il fermo immagine e compare
   solo quando la GIF è davvero caricata */
.node .motion {
  position: absolute;
  inset: 0;
  transition: opacity .45s linear;
}
.node .motion.is-ready { opacity: 1; }

.node:hover,
.node:focus-visible {
  transform: translate3d(var(--x, 0px), var(--y, 0px), 0) rotate(var(--rot, 0deg)) scale(1.03);
  box-shadow: 0 2px 14px rgba(var(--shadow-rgb), .13), 0 12px 40px rgba(var(--shadow-rgb), .09);
  z-index: 5;
}
.node:focus { outline: none; }
.node:focus-visible { outline: 1.5px solid var(--ink); outline-offset: 5px; }

/* Segno del video: un triangolo, non una parola. Vale SOLO per le gif ricavate
   da un video, che sono immagini animate: un filmato vero si muove da solo e
   non ha bisogno di essere annunciato. */
.node--video:not(.node--clip)::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 8%; aspect-ratio: 1 / 1.15;
  min-width: 10px;
  transform: translate(-50%, -50%);
  background: var(--paper);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  opacity: 0;
  transition: opacity .35s linear;
  mix-blend-mode: difference;
}
[data-detail="mid"] .node--video:not(.node--clip)::after,
[data-detail="near"] .node--video:not(.node--clip)::after { opacity: .92; }

/* ------------------------------------------------------ audio */

.node--audio {
  background: color-mix(in srgb, var(--ink) 6%, var(--paper));
  display: grid;
  place-items: center;
}
/* onda: barre di altezze diverse, ferme. Nessuna scritta. */
.node--audio .wave {
  display: flex;
  align-items: center;
  gap: 6%;
  width: 62%;
  height: 42%;
}
.node--audio .wave::before,
.node--audio .wave::after {
  content: '';
  flex: 1;
  background:
    linear-gradient(var(--ink), var(--ink)) left center / 8% 40% no-repeat,
    linear-gradient(var(--ink), var(--ink)) 22% center / 8% 78% no-repeat,
    linear-gradient(var(--ink), var(--ink)) 44% center / 8% 100% no-repeat,
    linear-gradient(var(--ink), var(--ink)) 66% center / 8% 60% no-repeat,
    linear-gradient(var(--ink), var(--ink)) right center / 8% 86% no-repeat;
  height: 100%;
  opacity: .55;
}
.node--audio .wave::after { transform: scaleX(-1); }
.node--audio:hover .wave::before, .node--audio:hover .wave::after { opacity: .85; }

/* Il triangolo del play. Senza, una tessera con un'onda ferma non diceva di
   essere qualcosa da ascoltare: si caricava un suono e nessuno lo premeva. */
.node--audio::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 13%; aspect-ratio: 1 / 1.15;
  min-width: 13px;
  transform: translate(-44%, -50%);
  /* lo stesso inchiostro dell'onda. Con «difference» su fondo scuro il
     triangolo si annullava: c'era, e non si vedeva. */
  background: var(--ink);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  opacity: .8;
  transition: opacity .25s linear, transform .25s var(--ease-out);
  pointer-events: none;
}
.node--audio:hover::after { transform: translate(-44%, -50%) scale(1.12); }
/* mentre suona: due barre al posto del triangolo, e l'onda respira */
.node--audio[data-suona="1"]::after {
  width: 12%;
  transform: translate(-50%, -50%);
  clip-path: none;
  background:
    linear-gradient(var(--ink), var(--ink)) left center / 34% 100% no-repeat,
    linear-gradient(var(--ink), var(--ink)) right center / 34% 100% no-repeat;
}
.node--audio[data-suona="1"] .wave::before { animation: onda 1.1s ease-in-out infinite alternate; opacity: .9; }
.node--audio[data-suona="1"] .wave::after { animation: onda 1.1s ease-in-out .55s infinite alternate; opacity: .9; }
@keyframes onda { from { transform: scaleY(.7); } to { transform: scaleY(1); } }
.node--audio[data-suona="1"] .wave::after { transform: scaleX(-1); }
/* il momento fra la pressione e il suono: il triangolo si smorza, non sparisce */
.node--audio[data-suona="attesa"]::after { opacity: .45; }
@media (prefers-reduced-motion: reduce) {
  .node--audio[data-suona="1"] .wave::before,
  .node--audio[data-suona="1"] .wave::after { animation: none; }
}

.audio {
  display: grid;
  place-content: center;
  gap: 18px;
  height: 100%;
  padding: clamp(20px, 5vw, 46px);
  background: color-mix(in srgb, var(--ink) 6%, var(--paper));
}
.audio__t {
  font-size: clamp(15px, 2vw, 22px);
  font-weight: 400;
  letter-spacing: -.02em;
  line-height: 1.3;
  color: var(--ink);
  text-align: center;
}
.audio audio { width: min(460px, 100%); }

/* ----------------------------------------------------- le cornici */

/* nudo: nessun segno, l'immagine sta sul bianco */
.frame-filo { box-shadow: inset 0 0 0 1px rgba(var(--shadow-rgb), .16); }
.frame-passepartout {
  padding: 4.5%;
  background: var(--paper);
  box-shadow: 0 0 0 1px rgba(var(--shadow-rgb), .1);
}
.frame-ombra { box-shadow: 0 1px 3px rgba(var(--shadow-rgb), .12), 0 10px 28px rgba(var(--shadow-rgb), .13); }
.frame-polaroid {
  padding: 4% 4% 13%;
  background: var(--paper);
  box-shadow: 0 1px 2px rgba(var(--shadow-rgb), .14), 0 8px 22px rgba(var(--shadow-rgb), .12);
}
.frame-tondo { border-radius: 999px; overflow: hidden; }
/* nastro: un pezzetto di scotch sull'angolo alto. Usa solo ::before —
   ::after sui video è già il triangolo del play. */
.frame-nastro { overflow: visible; }
.frame-nastro::before {
  content: '';
  position: absolute;
  z-index: 2;
  top: -3%;
  left: -4%;
  width: 26%;
  height: 8%;
  min-height: 10px;
  background: rgba(var(--shadow-rgb), .07);
  box-shadow: inset 0 0 0 1px rgba(var(--shadow-rgb), .05);
  transform: rotate(-24deg);
}

/* le cornici con imbottitura hanno bisogno che l'immagine stia nel riquadro */
.frame-passepartout img, .frame-polaroid img { height: 100%; }

/* --------------------------------------------------- testi sul piano */

.node--note {
  background: none !important;   /* nessun tema può metterci un riquadro dietro */
  overflow: visible;
  cursor: default;
  height: auto !important;
  display: block;
}
.node--note:hover {
  box-shadow: none;
  transform: translate3d(var(--x, 0px), var(--y, 0px), 0) rotate(var(--rot, 0deg));
}
.note__t {
  display: block;
  width: 100%;
  font-family: var(--tfont, var(--sans));
  font-size: var(--tsize, 26px);
  font-weight: var(--tweight, 340);
  text-align: var(--talign, left);
  letter-spacing: var(--ttrack, -.02em);
  line-height: var(--tlead, 1.3);
  white-space: pre-wrap;
  text-wrap: pretty;
}
/* tono e trattamento vengono dallo stile scelto, non da mille numeri */
.node--note[data-tone="ink"] .note__t { color: var(--ink); }
.node--note[data-tone="mid"] .note__t { color: color-mix(in srgb, var(--ink) 62%, transparent); }
.node--note[data-tone="light"] .note__t { color: color-mix(in srgb, var(--ink) 34%, transparent); }
.node--note[data-tone="rosso"] .note__t { color: var(--rosso); }
.node--note[data-tone="custom"] .note__t { color: var(--tcolor, var(--ink)); }
/* evidenziato: il testo su una fascia di colore, come col pennarello */
.node--note[data-mark="1"] .note__t {
  box-shadow: 0 0 0 .22em var(--tmark, rgba(var(--shadow-rgb), .08));
  background: var(--tmark, rgba(var(--shadow-rgb), .08));
}
.node--note[data-caps="1"] .note__t { text-transform: uppercase; }
.node--note[data-italic="1"] .note__t { font-style: italic; }
[data-edit] .node--note { cursor: move; outline: 1px dashed rgba(11, 107, 203, .35); outline-offset: 4px; }

/* -------------------------------------------- schede info / contatti */

/* le due schede: posizione, misura e tono si scelgono dalla configurazione */
/* Le due schede: posizione, misure e tono arrivano tutti da variabili scritte
   da app.js — il pannello le muove con dei cursori, non con tre formati fissi. */
.tabs {
  position: fixed;
  z-index: 30;
  display: flex;
  gap: var(--tabs-gap, 1px);
  right: 0; bottom: 0;
  padding: 0 var(--tabs-margin, 16px) 0 0;
}
.tabs[data-pos="bl"] { right: auto; left: 0; padding: 0 0 0 var(--tabs-margin, 16px); }
.tabs[data-pos="tr"] { bottom: auto; top: 0; padding: 0 var(--tabs-margin, 16px) 0 0; }
.tabs[data-pos="tl"] { bottom: auto; top: 0; right: auto; left: 0; padding: 0 0 0 var(--tabs-margin, 16px); }
.tabs[data-pos="tr"] .tabs__b,
.tabs[data-pos="tl"] .tabs__b {
  border-top: var(--tab-bd-w, 1px) solid var(--tab-bd);
  border-bottom: 0;
  border-radius: 0 0 var(--tab-radius, 0) var(--tab-radius, 0);
}
.tabs[data-pos="tr"] .tabs__b:hover, .tabs[data-pos="tr"] .tabs__b[aria-expanded="true"],
.tabs[data-pos="tl"] .tabs__b:hover, .tabs[data-pos="tl"] .tabs__b[aria-expanded="true"] {
  padding-bottom: var(--tab-py, 7px);
  padding-top: calc(var(--tab-py, 7px) + 4px);
}
.tabs:hover { --tab-fg: var(--tab-fg-hot); }
.tabs__b {
  appearance: none;
  border: var(--tab-bd-w, 1px) solid var(--tab-bd);
  border-bottom: 0;
  border-radius: var(--tab-radius, 0) var(--tab-radius, 0) 0 0;
  background: var(--tab-bg);
  backdrop-filter: blur(4px);
  color: var(--tab-fg);
  font: inherit;
  font-size: var(--tab-fs, 10px);
  font-weight: var(--tab-peso, 400);
  letter-spacing: var(--tab-track, .14em);
  text-transform: var(--tab-caps, uppercase);
  padding: var(--tab-py, 7px) var(--tab-px, 13px) calc(var(--tab-py, 7px) + 1px);
  cursor: pointer;
  transition: color .25s linear, background .25s linear, padding-bottom .25s var(--ease-out);
}
.tabs__b:hover, .tabs__b[aria-expanded="true"] {
  color: var(--tab-fg);
  padding-bottom: calc(var(--tab-py, 7px) + 4px);
  filter: brightness(1.04) saturate(1.05);
}

.sheet {
  position: fixed;
  right: clamp(10px, 1.6vw, 20px);
  bottom: 34px;
  --sheet-gap: 34px;
  z-index: 31;
  width: min(42ch, calc(100vw - 32px));
  max-height: min(60vh, 520px);
  overflow: auto;
  padding: 22px 24px 24px;
  background: var(--paper);
  border: 1px solid var(--hair);
  box-shadow: 0 2px 10px rgba(var(--shadow-rgb), .06), 0 24px 60px rgba(var(--shadow-rgb), .12);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .3s linear, transform .45s var(--ease-out);
}
.sheet[hidden] { display: none; }
body[data-tabs="bl"] .sheet { right: auto; left: clamp(10px, 1.6vw, 20px); }
body[data-tabs="tr"] .sheet { bottom: auto; top: var(--sheet-gap); }
body[data-tabs="tl"] .sheet { bottom: auto; top: var(--sheet-gap); right: auto; left: clamp(10px, 1.6vw, 20px); }
.sheet.is-open { opacity: 1; transform: none; }
.sheet__h {
  margin: 0 0 10px;
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.sheet__b { font-size: 14px; line-height: 1.6; color: var(--ink-body); }
.sheet__b p { margin: 0 0 .8em; }
.sheet__b p:last-child { margin-bottom: 0; }
.sheet__b a { color: var(--ink); text-underline-offset: 3px; }
.sheet__x {
  position: absolute;
  top: 8px; right: 10px;
  appearance: none; border: 0; background: none;
  font: inherit; font-size: 18px; line-height: 1;
  color: var(--ink-4);
  cursor: pointer;
  padding: 4px 6px;
}
.sheet__x:hover { color: var(--ink); }

/* ------------------------------------------------ modalità modifica */

[data-edit] #stage { cursor: default; }
[data-edit] .node { cursor: move; }
/* niente ::after: sui video è già il triangolo del play */
[data-edit] .node.is-picked {
  outline: 1.5px solid #0b6bcb;
  outline-offset: 3px;
  box-shadow: inset 0 0 0 3000px rgba(11, 107, 203, .12);
  z-index: 40;
}

/* ----------------------------------------------------------- aperto */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 40;
}
.lightbox[hidden] { display: none; }

.lightbox__scrim {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, .9);
  opacity: 0;
  transition: opacity .45s linear;
  cursor: zoom-out;
}
.lightbox.is-open .lightbox__scrim { opacity: 1; }

.lightbox__figure {
  position: fixed;
  margin: 0;
  top: 0; left: 0;
  overflow: hidden;
  background: var(--paper);
  transform-origin: 50% 50%;
  will-change: transform;
  cursor: zoom-out;
  box-shadow: 0 4px 24px rgba(var(--shadow-rgb), .10), 0 30px 90px rgba(var(--shadow-rgb), .12);
}
.lightbox__figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Targhetta: l'unico testo del sito, e solo a immagine aperta. Sta in una
   fascia riservata in basso (l'immagine si ferma sopra), quindi non può
   sovrapporsi alla foto per quanto lungo sia il titolo. */
/* La targhetta vive in una fascia riservata in basso (LB_BAND in app.js): il
   testo non deve MAI finire sopra la foto. Perciò il titolo è tagliato a due
   righe e le tre voci hanno un posto fisso nella griglia — altrimenti tre <p>
   in due colonne si dispongono da soli, e con i titoli lunghi dell'archivio
   NASA la fascia cresceva fino a coprire l'immagine. */
.info {
  position: fixed;
  left: clamp(16px, 2.4vw, 34px);
  right: clamp(16px, 2.4vw, 34px);
  bottom: clamp(14px, 2vw, 26px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: end;
  gap: 0 20px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .35s linear .18s, transform .5s var(--ease-out) .18s;
  pointer-events: none;
}
.lightbox.is-open .info { opacity: 1; transform: none; }

.info p { margin: 0; }

.info__set {
  grid-column: 1;
  grid-row: 1;
  font-size: var(--cap-small, 10px);
  font-weight: 400;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: var(--cap-align, left);
}
.info__title {
  grid-column: 1;
  grid-row: 2;
  font-size: var(--cap-size, 15px);
  font-weight: var(--cap-peso, 350);
  letter-spacing: var(--cap-track, -.015em);
  text-transform: var(--cap-caps, none);
  line-height: 1.32;
  color: var(--cap-ink, var(--ink));
  text-align: var(--cap-align, left);
  /* due righe e poi i puntini: è il tetto che tiene la fascia alla sua misura */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.info__meta {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: end;
  text-align: right;
  white-space: nowrap;
  font-size: var(--cap-small, 10px);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
/* Il collegamento messo su un'immagine: una riga della targhetta, nella stessa
   voce delle altre. Era una pastiglia bianca ferma in mezzo alla foto — l'unica
   cosa del sito che si mettesse davanti a un'immagine, e non se ne andava.
   Riga 4 e non 3: la riga 3 la occupa la didascalia quando le si chiede di
   andare sotto invece che a destra. Una riga di griglia vuota non occupa
   spazio. */
.info__link {
  grid-column: 1;
  grid-row: 4;
  /* il margine è 1 perché il resto lo dà il padding: la riga si vede dove si
     vedeva, ma il dito ha 25px di bersaglio invece di 13 */
  margin-top: 1px;
  padding: 6px 0;
  justify-self: var(--cap-just, start);
  max-width: 100%;
  font-size: var(--cap-small, 10px);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-align: var(--cap-align, left);
  color: var(--ink-3);
  text-decoration: none;
  /* la fascia non prende i click (si chiude toccando fuori): questo sì */
  pointer-events: auto;
  transition: color .2s linear;
}
.info__link[hidden] { display: none; }
.info__link::before { content: '\2197\00a0'; }
.info__link:hover,
.info__link:focus-visible { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* si possono spegnere: restano il titolo e basta */
.info[data-set="off"] .info__set,
.info[data-meta="off"] .info__meta { display: none; }
/* e si può chiedere che centro/anno/id vadano sotto invece che a destra */
.info[data-riga="sotto"] { grid-template-columns: minmax(0, 1fr); }
.info[data-riga="sotto"] .info__meta {
  grid-column: 1; grid-row: 3; text-align: var(--cap-align, left); margin-top: 5px;
}

@media (max-width: 640px) {
  .info { grid-template-columns: minmax(0, 1fr); }
  /* un filo più piccolo che a schermo largo, ma la misura la decide comunque
     la configurazione: prima un 14px fisso la scavalcava */
  .info__title { font-size: calc(var(--cap-size, 15px) * .92); }
  .info__meta { grid-column: 1; grid-row: 3; text-align: left; margin-top: 5px; }
  /* le due linguette sul telefono: alte come un dito, altrimenti si sbaglia
     mira fra «info» e «contatti». Le misure scelte nel pannello restano, ma
     sotto una certa soglia non si scende. */
  .tabs__b {
    min-height: 44px;
    padding: max(13px, var(--tab-py, 7px)) max(15px, var(--tab-px, 13px)) calc(max(13px, var(--tab-py, 7px)) + 1px);
  }
  .tabs { gap: max(6px, var(--tabs-gap, 1px)); }
  .tabs__b:hover, .tabs__b[aria-expanded="true"] { padding-bottom: calc(max(13px, var(--tab-py, 7px)) + 4px); }
}

@media (prefers-reduced-motion: reduce) {
  .node { animation-duration: .01ms; animation-delay: 0ms !important; opacity: 1; }
  *, *::before, *::after { transition-duration: .01ms !important; }
}

/* collegamento al portfolio, in fondo alla scheda info */
.sheet__pdf { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hair); }
.sheet__pdf a { text-decoration: none; font-size: 13px; letter-spacing: .02em; }
.sheet__pdf a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* in modalità agglomerato si vede quale gruppo si prende, e il cursore lo dice */
[data-edit][data-mode="cluster"] .node { cursor: grab; }
[data-edit][data-mode="cluster"] .node.in-hot {
  outline: 1.5px dashed #0b6bcb;
  outline-offset: 3px;
}
[data-edit][data-mode="cluster"] .node.is-picked { outline-style: solid; }

/* collegamenti dentro le schede info e contatti */
.sheet__link { margin: 0 0 .45em; }
.sheet__link a { text-decoration: none; border-bottom: 1px solid var(--hair); }
.sheet__link a:hover { border-color: currentColor; }

/* -------------------------------------------- apertura spenta */

/* Se il cliente spegne l'apertura a pieno campo, nulla si apre: allora le
   immagini non devono più comportarsi come bottoni. */
body[data-expand="0"] .node { cursor: default; }
/* un suono e un catalogo restano da premere anche li': il dito deve saperlo */
body[data-expand="0"] .node--audio,
body[data-expand="0"] .node--doc { cursor: pointer; }
body[data-expand="0"] .node:hover {
  transform: translate3d(var(--x, 0px), var(--y, 0px), 0) rotate(var(--rot, 0deg));
  box-shadow: none;
  z-index: auto;
}

/* --------------------------------------------- come si usa */

/* Una riga sola, al centro in basso, la prima volta e mai più. */
.hint {
  position: fixed;
  left: 50%;
  bottom: max(18px, env(safe-area-inset-bottom, 0px));
  transform: translate(-50%, 6px);
  z-index: 29;
  margin: 0;
  padding: 9px 15px 10px;
  background: color-mix(in srgb, var(--paper) 84%, transparent);
  backdrop-filter: blur(4px);
  border: 1px solid var(--hair);
  color: var(--ink-2);
  font-size: 10.5px;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-align: center;
  max-width: calc(100vw - 28px);
  pointer-events: none;
  opacity: 0;
  transition: opacity .45s linear, transform .5s var(--ease-out);
}
.hint.is-on { opacity: 1; transform: translate(-50%, 0); }

/* -------------------------------------- immagini con un collegamento */

/* Un collegamento su un'immagine deve vedersi, altrimenti il cliente lo
   configura e pensa che non funzioni: una freccia nell'angolo, che compare
   avvicinandosi o passandoci sopra. A immagine aperta il dominio si legge in
   fondo alla targhetta. */
.node--link::before {
  /* la parola accanto alla freccia e' facoltativa: senza, resta la freccia
     sola, come prima */
  content: '\2197' attr(data-parola);
  position: absolute;
  right: 6px; top: 5px;
  z-index: 2;
  font-size: 13px;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  color: var(--ink);
  opacity: 0;
  transition: opacity .25s linear;
  pointer-events: none;
}
.node--link:hover::before,
.node--link:focus-visible::before { opacity: 1; }
[data-detail="near"] .node--link::before { opacity: .75; }
a.node { text-decoration: none; }

/* in configurazione la freccia si vede sempre: serve a controllare a colpo
   d'occhio quali immagini hanno un collegamento */
[data-edit] .node--link::before { opacity: .85; }

/* ------------------------------------------- schede: vestito e pagina */

/* Le due presentazioni della stessa scheda. In «scheda» resta il riquadro in
   basso di sempre; in «pagina» diventa una pagina intera con una colonna di
   lettura — che è quello che serve a un testo lungo, e che una scheda da 42
   caratteri non può reggere. */
.sheet {
  font-family: var(--sh-font, var(--sans));
  background: var(--sh-paper, var(--paper));
  width: min(var(--sh-width, 42ch), calc(100vw - 32px));
}
.sheet__h { font-size: var(--sh-title, 10px); }
.sheet__b {
  font-size: var(--sh-size, 14px);
  font-weight: var(--sh-weight, 400);
  letter-spacing: var(--sh-track, 0);
  line-height: var(--sh-lead, 1.6);
  text-align: var(--sh-align, left);
  color: var(--sh-ink, var(--ink-body));
}

.sheet[data-modo="pagina"] {
  inset: 0;
  top: 0; right: 0; bottom: 0; left: 0;
  width: 100vw;
  max-width: none;
  max-height: none;
  height: 100dvh;
  border: 0;
  box-shadow: none;
  padding: 0;
  overflow: auto;
  transform: translateY(14px);
  z-index: 40;
  display: grid;
  grid-template-rows: auto 1fr;
  align-content: start;
}
.sheet[data-modo="pagina"].is-open { transform: none; }
.sheet[data-modo="pagina"] .sheet__h {
  width: min(var(--sh-width, 62ch), calc(100vw - 12vw));
  margin: clamp(56px, 12vh, 130px) auto clamp(18px, 4vh, 34px);
  padding: 0 6vw;
  letter-spacing: -.015em;
  text-transform: none;
  line-height: 1.1;
  color: var(--ink);
}
.sheet[data-modo="pagina"] .sheet__b {
  width: min(var(--sh-width, 62ch), calc(100vw - 12vw));
  margin: 0 auto;
  padding: 0 6vw clamp(60px, 14vh, 160px);
}
.sheet[data-modo="pagina"] .sheet__x {
  position: fixed;
  top: clamp(14px, 3vh, 26px);
  right: clamp(14px, 3vw, 30px);
  font-size: 26px;
  padding: 6px 10px;
  z-index: 41;
}
/* in pagina il piano sotto non deve distrarre */
body:has(.sheet[data-modo="pagina"].is-open) #stage { filter: blur(2px) saturate(.6); }
@media (max-width: 640px) {
  .sheet[data-modo="pagina"] .sheet__h,
  .sheet[data-modo="pagina"] .sheet__b { padding-left: 7vw; padding-right: 7vw; }
  .sheet[data-modo="pagina"] .sheet__h { margin-top: 64px; }
}

/* ------------------------------------------------ filmati veri */

/* Un filmato caricato dal cliente e' l'anteprima di se stesso: sulla lavagna
   scorre muto e in ciclo, come una gif, e al click si apre a pieno campo con
   l'audio e i comandi. Niente triangolo sopra: la tessera si muove, si vede da
   sola che e' un filmato. */
/* contain, non cover: con le misure giuste i due coincidono, ma se un vecchio
   caricamento ha salvato misure sbagliate il filmato si vede intero invece di
   perdere i bordi. */
.node video { width: 100%; height: 100%; object-fit: contain; display: block; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  /* Qui i filmati restano fermi, per scelta di chi guarda: il triangolo torna,
     perche' senza non si capirebbe che quella tessera e' un video. */
  .node--clip::after {
    content: '';
    position: absolute;
    left: 50%; top: 50%;
    width: 8%; aspect-ratio: 1 / 1.15;
    transform: translate(-40%, -50%);
    background: color-mix(in srgb, var(--paper) 88%, transparent);
    clip-path: polygon(0 0, 100% 50%, 0 100%);
    pointer-events: none;
  }
}
.lightbox__figure video { width: 100%; height: 100%; object-fit: contain; background: #000; display: block; }

/* ------------------------------------------- cataloghi da sfogliare */

/* Sulla lavagna un catalogo si riconosce dalle frecce ai lati (sfoglia.js). Il
   vecchio «taglio delle pagine» sul bordo e' andato: con le doppie pagine
   dentro una tessera della forma della copertina finiva a fianco del foglio,
   e si leggeva come un doppio bordo. */

/* LO SFOGLIATORE (sfoglia.js): un documento si sfoglia dove sta, come un
   libro. Le facce sono sfondi: niente «salva immagine», niente selezione,
   niente pressione lunga, niente trascinamento, niente stampa. */
.sf {
  position: relative;
  display: block;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.sf__vista { position: absolute; inset: 0; display: block; overflow: hidden; }
.sf__piano { position: absolute; inset: 0; display: block; transform-origin: 50% 50%; }
/* il libro: due facce affiancate e il foglio che gira sul dorso, al centro */
.sf__libro {
  position: absolute;
  inset: 0;
  display: block;
  perspective: 2800px;
  pointer-events: none;
  transform: translateX(var(--sf-sposta, 0%));
  transition: transform var(--sf-durata, 820ms) cubic-bezier(.45, .05, .3, 1);
}
.sf__meta { position: absolute; top: 0; bottom: 0; width: 50%; display: block; pointer-events: auto; }
.sf__sx { left: 0; }
.sf__dx { left: 50%; }
.sf__meta.sf--vuota { pointer-events: none; }
.sf__f {
  background-repeat: no-repeat;
  background-color: #fff;
}
/* una pagina intera sta nella faccia; una doppia pagina ne da' meta' per parte */
.sf__f[data-meta="tutta"] { background-size: contain; background-position: center; background-color: transparent; }
.sf__f[data-meta="sx"] { background-size: auto 100%; background-position: 0 0; }
.sf__f[data-meta="dx"] { background-size: auto 100%; background-position: 100% 0; }
.sf__meta.sf--vuota { background-color: transparent; }
/* il foglio che gira: davanti la faccia di destra, dietro quella di sinistra */
.sf__foglia {
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: 50%;
  display: block;
  z-index: 2;
  transform-origin: 0 50%;
  transform-style: preserve-3d;
  transition: transform var(--sf-durata, 820ms) cubic-bezier(.45, .05, .3, 1);
  pointer-events: auto;
}
.sf__foglia[hidden] { display: none; }
.sf__fronte,
.sf__retro {
  position: absolute;
  inset: 0;
  display: block;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.sf__retro { transform: rotateY(180deg); }
.sf .sf--fermo { transition: none !important; }
/* il dorso: un'ombra appena, dove le facce si piegano verso il centro */
.sf__meta::after,
.sf__fronte::after,
.sf__retro::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.sf__sx::after, .sf__retro::after { background: linear-gradient(to left, rgba(0, 0, 0, .15), rgba(0, 0, 0, 0) 8%); }
.sf__dx::after, .sf__fronte::after { background: linear-gradient(to right, rgba(0, 0, 0, .15), rgba(0, 0, 0, 0) 8%); }
.sf__f.sf--vuota::after,
.sf:not([data-aperto]) .sf__dx::after { display: none; }
/* mentre gira, il foglio passa in ombra a meta' corsa: la luce che cambia */
.sf__fronte::before,
.sf__retro::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: #000;
  opacity: 0;
  pointer-events: none;
}
.sf--gira .sf__fronte::before,
.sf--gira .sf__retro::before { animation: sf-luce var(--sf-durata, 820ms) ease-in-out; }
@keyframes sf-luce { 50% { opacity: .2; } }
@media print { .sf__f { visibility: hidden !important; } }

/* SULLA LAVAGNA la tessera e' la copertina. Aperto, il libro si stende a
   sinistra fuori dalla tessera, e passa sopra le vicine finche' resta aperto. */
.node.node--doc { overflow: visible; container-type: inline-size; }
:root[data-theme] .node.node--doc.frame-nudo,
.node.node--doc.frame-nudo { background: transparent; }
.node.node--doc.frame-nudo:hover,
.node.node--doc.frame-nudo:focus-visible { box-shadow: none; }
.node.node--doc[data-aperto] { z-index: 6; }
.node--doc .sf { width: 100%; height: 100%; }
.sf--lavagna .sf__vista { overflow: visible; }
.sf--lavagna .sf__libro { left: -100%; }
.sf__lato { position: absolute; top: 0; bottom: 0; width: 50%; display: block; pointer-events: auto; }
.sf__lato--prec { left: 0; cursor: w-resize; }
.sf__lato--succ { right: 0; cursor: e-resize; }
.sf[data-vuota-sx] .sf__lato--prec,
.sf[data-vuota-dx] .sf__lato--succ { display: none; }
/* le frecce: stessa misura sullo schermo a ogni zoom (--iz = 1/zoom, lo scrive
   la lavagna), ma mai piu' grandi di un settimo della tessera */
.node--doc .sf__freccia {
  position: absolute;
  top: 50%;
  width: min(calc(30px * var(--iz, 1)), 14cqw);
  height: min(calc(30px * var(--iz, 1)), 14cqw);
  translate: 0 -50%;
  box-sizing: border-box;
  padding: min(calc(6px * var(--iz, 1)), 2.8cqw);
  border-radius: 50%;
  background: rgba(0, 0, 0, .48);
  fill: none;
  stroke: #fff;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .72;
  transition: opacity .2s linear, background-color .2s linear;
  pointer-events: none;
}
.sf__lato--prec .sf__freccia { left: 3.2%; }
.sf__lato--succ .sf__freccia { right: 3.2%; }
.node--doc:hover .sf__freccia { opacity: 1; }
.sf__lato:hover .sf__freccia { background: rgba(0, 0, 0, .7); }
[data-detail="far"] .node--doc .sf__freccia { display: none; }
.node--doc .sf__n {
  position: absolute;
  left: 50%; bottom: 3%;
  transform: translateX(-50%);
  padding: .4em .7em;
  font: 500 min(calc(12px * var(--iz, 1)), 4.6cqw)/1 var(--sans);
  letter-spacing: .06em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: #fff;
  background: rgba(0, 0, 0, .55);
  opacity: 0;
  transition: opacity .25s linear;
  pointer-events: none;
}
.node--doc[data-aperto] .sf__n { left: 0; }
.node--doc:hover .sf__n,
.node--doc:focus-visible .sf__n,
.node--doc[data-sfogliato] .sf__n,
.node--doc[data-carica] .sf__n { opacity: 1; }
[data-detail="far"] .node--doc .sf__n { display: none; }

/* nella scheda: il libro sta nel riquadro, e ha i suoi comandi, perche' la
   scheda non si ingrandisce */
.sheet__pdf { margin-top: 18px; }
.sheet__pdfT { margin: 0 0 8px; }
.sf--scheda { display: flex; flex-direction: column; gap: 6px; outline: none; }
.sf--scheda:focus-visible { outline: 1.5px solid var(--ink); outline-offset: 4px; }
.sf--scheda .sf__vista {
  position: relative;
  inset: auto;
  width: 100%;
  aspect-ratio: var(--sf-r, 1.414);
  max-height: 72vh;
  touch-action: pan-y;          /* la scheda scorre col dito; il pizzico lo prende lo sfogliatore */
  cursor: pointer;
}
.sf--scheda[data-ingrandito="1"] .sf__vista { touch-action: none; cursor: grab; }
.sf__barra { display: flex; align-items: center; gap: 2px; font-size: 12px; }
.sf__b {
  min-width: 34px; min-height: 34px;
  margin: 0; padding: 0; border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
}
.sf__b:disabled { opacity: .28; cursor: default; }
.sf__spazio { flex: 1; }
.sf--scheda .sf__n { padding: 0 6px; letter-spacing: .04em; font-variant-numeric: tabular-nums; }

/* IN ARRIVO (in-arrivo.js, porta.js): finche' il sito non e' aperto al
   pubblico, la scritta e basta — nera e rossa dal primo disegno, senza
   aspettare il tema pubblicato, e senza il piede della privacy. La lavagna non
   parte nemmeno: non si scarica e non si disegna. */
.soon { display: none; }
/* I COLORI SCELTI, SENZA RITOCCHI DEL BROWSER. «only dark»: nessuno
   scurimento automatico (Chrome, Samsung Internet), qualunque sia il tema di
   chi guarda. forced-color-adjust: none: niente colori forzati (contrasto
   elevato di Windows e simili) su fondo e scritta. */
html.in-arrivo { color-scheme: only dark; }
html.in-arrivo,
html.in-arrivo body,
html.in-arrivo .soon,
html.in-arrivo .soon__t { forced-color-adjust: none; }
/* anche in stampa, e senza l'evidenziazione della selezione o del tocco */
html.in-arrivo {
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
  -webkit-tap-highlight-color: transparent;
}
html.in-arrivo .soon { -webkit-user-select: none; user-select: none; }
html.in-arrivo,
html.in-arrivo body {
  background: #0b0b0c;
  overflow: hidden;
  overscroll-behavior: none;
  /* niente pizzico e niente doppio tocco: la scritta non si ingrandisce */
  touch-action: none;
}
html.in-arrivo #stage,
html.in-arrivo .tabs,
html.in-arrivo .sheet,
html.in-arrivo .hint,
html.in-arrivo .vuota,
html.in-arrivo .lightbox,
html.in-arrivo .site-foot { display: none !important; }
html.in-arrivo .soon {
  position: fixed;
  inset: 0;
  z-index: 1;
  margin: 0;
  display: grid;
  place-items: center;
  background: #0b0b0c;
}
.soon__t {
  margin: 0;
  /* Arial Black dove c'e' (Windows, Mac); sui telefoni, che non ce l'hanno,
     il suo gemello libero gia' ospitato dal sito, invece di un grassetto finto */
  font-family: 'Arial Black', 'Archivo Black', Arial, sans-serif;
  font-weight: 900;
  font-synthesis: none;
  /* solo unita' dello schermo: con lo zoom dal menu del browser, che nessuna
     pagina puo' impedire, vw e vh si restringono quanto crescono i pixel, e la
     scritta resta della stessa misura. I 28vh fanno da tetto sugli schermi larghi. */
  font-size: min(19vw, 28vh);
  line-height: 1;
  letter-spacing: -.02em;
  /* rosso pieno, uguale con ogni tema: il rosso del sito in tema scuro tira
     al corallo */
  color: #ff0000;
  /* Le lettere le disegna un FONDO rosso ritagliato sulla loro forma, non il
     colore del testo. Lo scurimento automatico di Chrome e Samsung ritocca
     sempre i colori dei testi, e i fondi solo se sono chiari: il rosso pieno non
     lo e', e resta com'e'. Misurato: col testo rosso, telefono in tema chiaro
     e scurimento acceso, usciva #ff1203. */
  background: linear-gradient(#ff0000, #ff0000);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* gli stessi colori anche per chi ha il telefono in tema scuro: e' il segnale
   con cui Samsung Internet capisce che il sito ha gia' il suo scuro e non ci
   mette mano */
@media (prefers-color-scheme: dark) {
  html.in-arrivo, html.in-arrivo body, html.in-arrivo .soon { background: #0b0b0c; }
  html.in-arrivo .soon__t { color: #ff0000; background: linear-gradient(#ff0000, #ff0000); -webkit-background-clip: text; background-clip: text; }
}
/* chi gestisce vede il sito vero: che lo sappia, per non scambiarlo per quello
   che vede il pubblico */
.anteprima-segno {
  position: fixed;
  top: 10px; left: 12px;
  z-index: 300;
  margin: 0;
  padding: 4px 8px;
  font: 600 10px/1.2 var(--sans);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #fff;
  background: var(--rosso);
  pointer-events: none;
}

/* senza JavaScript: tre righe, non una pagina bianca */
.noscript {
  max-width: 30rem; margin: 12vh auto; padding: 0 24px;
  font: 14px/1.6 var(--sans, system-ui, sans-serif); color: var(--ink, #111);
}
.noscript b { display: block; font-size: 15px; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 12px; }
.noscript p { margin: 0 0 10px; }

/* lavagna senza niente sopra: meglio dirlo che lasciare il bianco */
.vuota {
  position: fixed; inset: 0; margin: 0;
  display: none; place-content: center; text-align: center;
  gap: 8px; color: var(--ink-2); font-size: 13px; letter-spacing: .04em;
  pointer-events: none;
}
.vuota span { display: block; font-size: 11px; color: var(--ink-3); margin-top: 6px; }
body[data-vuota="1"] .vuota { display: grid; }

/* ------------------------------------------- link all'informativa */
/* minuscolo e in disparte: deve esserci (obbligo informativo), non farsi
   notare. Il padding tiene il bersaglio cliccabile anche se il segno e' mini. */
.site-foot {
  position: fixed;
  left: 8px; bottom: 5px;
  z-index: 29;
  margin: 0;
  padding: 6px;
  font-size: 8px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-4);
  opacity: .7;
}
.site-foot a { color: inherit; text-decoration: none; }
.site-foot:hover { color: var(--ink); opacity: 1; }
.site-foot a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* se le linguette stanno a sinistra, la privacy passa a destra */
body[data-tabs="bl"] .site-foot,
body[data-tabs="tl"] .site-foot { left: auto; right: 8px; }
