/* ==========================================================================
   TYPE — Strichpunkt Sans (SIL OFL, uso libero anche commerciale/web)
   ========================================================================== */
@font-face {
  font-family: "Strichpunkt Sans";
  src:
    url("../fonts/StrichpunktSans-Regular.woff2") format("woff2"),
    url("../fonts/StrichpunktSans-Regular.ttf") format("truetype");
  /* C'è un solo file (peso normale), ma il sito lo usa "in grassetto". Dichiarando che
     il file copre tutti i pesi, nessun browser si inventa un grassetto suo: ognuno lo
     disegnava in modo diverso (più sottile su Safari, più spesso su Vivaldi/Chrome).
     Lo spessore lo disegniamo noi, identico ovunque: vedi --sans-stroke qui sotto. */
  font-weight: 100 900;
  font-style: normal;
  /* "block": finché il carattere non è arrivato (pochi millesimi con la precarica in index.html) il testo
     resta invisibile invece di comparire in un altro carattere e poi "saltare" — era uno dei motivi per cui
     al primo ingresso la pagina sembrava rotta e dopo qualche visita (carattere già in memoria) no. */
  font-display: block;
}

/* -------------------------------------------------------------------------
   RESET & BASE
   ------------------------------------------------------------------------- */
* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

html {
  /* Il sito è solo chiaro: i browser che scuriscono le pagine da soli (o con il "modo scuro" del telefono) non devono toccare
     né i colori né i controlli (barre di scorrimento, campi di testo). Stessa cosa del meta "color-scheme" in index.html. */
  color-scheme: only light;
  /* iPhone/iPad ingrandiscono da soli il testo quando giri lo schermo: qui no */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-synthesis-weight: none;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Strichpunkt Sans", Helvetica, Arial, sans-serif;
  font-weight: 600;
  -webkit-font-smoothing: antialiased;
  /* Lo "spessore" del testo (il vecchio grassetto finto, ora disegnato da noi): 0.035 volte
     la grandezza della lettera — misurato per coincidere con quello che mostra Vivaldi/Chrome.
     Tutto ciò che sta nella pagina lo eredita; pulsanti e testo a macchina da scrivere lo
     azzerano più sotto, perché non erano in grassetto. */
  --sans-stroke: 0.035em;
}

*,
*::before,
*::after {
  -webkit-text-stroke-width: var(--sans-stroke, 0);
}

/* Non erano in grassetto prima, quindi niente spessore: pulsanti e testo a macchina da scrivere. */
button,
.mono,
.home-add-word-btn,
.home-view-all-photos-btn,
.home-word-delete-btn,
.caption-input,
.contact-line,
.resizable-label,
.photo-delete-btn,
.photo-link-btn,
.photo-add-btn,
.description-delete-btn,
.export-panel textarea,
.photo-caption-text,
.archive-word,
body.edit-mode .home-word-input::placeholder {
  --sans-stroke: 0;
  -webkit-text-stroke-width: 0;
}

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

/* Email nei contatti: stesso aspetto del testo; col mouse si attenua come i link in fondo alla home, da tastiera si sottolinea. */
.mail-link:hover {
  opacity: 0.6;
}
.mail-link:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

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

:root {
  --bg: #161616;
  --paper: #edebe0;
  --ink: #2b2b28;
  --muted: #8a877c;
  --hairline: rgba(43, 43, 40, 0.12);
  --panel-width: 740px;
  --transition-ms: 6000ms;
  /* Testo "a macchina da scrivere" (didascalie, contatti, pulsanti di modifica). Prima l'elenco
     cominciava con font di sistema che esistono solo su Safari (SF Mono): lì le didascalie
     uscivano con un altro disegno e un'altra larghezza rispetto a Vivaldi. Courier New c'è su
     ogni Mac, Windows e iPad. */
  --mono: "Courier New", Courier, monospace;
  /* Due estremi già provati e scartati: un ease-in-out marcato
     (cubic-bezier(0.65,0,0.35,1)) si sente come due fasi diverse — parte
     lenta, "accelera" verso metà corsa, poi rallenta di nuovo; lineare
     (velocità costante) invece non cambia mai ritmo, il che a 6 secondi si
     sente piatto/meccanico, non "fluido". Questa è la via di mezzo: la
     stessa curva "ease" di default del browser, molto più tenue della
     prima — un accenno di morbidezza in apertura/chiusura del movimento,
     quasi impercettibile, senza leggersi come due fasi distinte. */
  --transition-ease: cubic-bezier(0.25, 0.1, 0.25, 1);
}

.mono {
  font-family: var(--mono);
}

/* -------------------------------------------------------------------------
   PAGE PANEL — il "foglio" chiaro centrato sullo sfondo scuro
   ------------------------------------------------------------------------- */
.page {
  position: relative;
  width: min(100%, var(--panel-width));
  min-height: calc(100vh - 40px);
  margin: 20px auto;
  background: var(--paper);
  padding: 32px 40px 56px;
  display: flex;
  flex-direction: column;
}

.page.has-fixed-bars {
  padding-left: 0;
  padding-right: 0;
  padding-top: 0;
  padding-bottom: 0;
}

@media (max-width: 700px) {
  .page {
    width: 100%;
    min-height: 100dvh;
    margin: 0 auto;
    padding: 24px 20px 40px;
  }
}

/* -------------------------------------------------------------------------
   HOME — lista statica (nessuna animazione). Le dimensioni del blocco
   .home-list vengono impostate da JS leggendo LAYOUT.home in content.js
   (o dal valore che hai trascinato tu in modalità modifica, vedi in fondo).
   ------------------------------------------------------------------------- */
.home-header {
  display: flex;
  justify-content: space-between;
  font-size: 0.95rem;
  padding-bottom: 68px;
}

.home-list {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 0 0 auto;
  position: relative;
  max-width: 100%;
}

.home-list li {
  line-height: 1.5;
  font-size: 0.95rem;
}

.home-list a {
  display: inline-block;
  transition: opacity 0.2s ease;
  cursor: pointer;
}

.home-list a:hover {
  opacity: 0.55;
}

.home-spacer {
  flex: 1 1 auto;
}

/* "+ aggiungi una parola": solo in modalità modifica, come ogni altro
   controllo di modifica del sito. */
.home-add-word-btn {
  display: none;
  margin: 20px 0 4px;
  padding: 6px 14px;
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--paper);
  background: #2b7a4b;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

body.edit-mode .home-add-word-btn {
  display: inline-block;
}

body.edit-mode .home-add-word-btn:hover {
  background: #38995e;
}

.home-view-all-photos-btn {
  display: none;
  margin: 20px 0 4px;
  padding: 6px 14px;
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--paper);
  background: #2b547a;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

body.edit-mode .home-view-all-photos-btn {
  display: inline-block;
}

body.edit-mode .home-view-all-photos-btn:hover {
  background: #386f99;
}

/* Una "parola" aggiunta in home: è una riga della STESSA lista dei
   progetti (<li class="home-word-row">, dentro .home-list) — non più un
   blocco a posizione libera. Così si riordina con l'identica maniglia blu
   ⠿ usata per i nomi dei progetti (vedi "body.edit-mode .home-list li"
   più sotto per il layout flex condiviso), e trascinarla sposta
   davvero le righe vicine invece di limitarsi a sovrapporlesi: è
   esattamente il "creare spazio tra le parole" che serviva. L'<input>
   stesso è invisibile come contenitore (bordo/sfondo solo in modalità
   modifica) finché non ci scrivi dentro, e usa lo STESSO font della lista
   (Inter, non il monospace delle didascalie: qui non è una didascalia). */
.home-word-input {
  display: inline-block;
  /* Larghezza calcolata in JS (vedi syncWordInputWidth in app.js) in base
     al testo scritto: un <input>, a differenza di un link <a>, non si
     allarga mai da solo al contenuto — lasciarlo con una larghezza fissa
     o "min-width" tagliava le parole più lunghe di quel valore (es.
     "Compression" mostrava solo "Comp"). 24px di partenza finché JS non
     interviene, giusto per non essere invisibile per un istante.
     Niente padding orizzontale: il testo deve iniziare esattamente al
     bordo sinistro del rettangolo (niente spazio prima della prima
     lettera), altrimenti risulta sfalsato rispetto ai nomi dei progetti
     nella stessa lista quando provi ad allinearli. */
  width: 24px;
  padding: 2px 0;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 3px;
  outline: none;
  /* Sempre cliccabile, anche fuori dalla modalità modifica: è un link
     vero verso la pagina della parola (vedi renderWordPage in app.js),
     stesso comportamento al passaggio del mouse di un nome progetto. */
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.home-word-input:hover {
  opacity: 0.55;
}

.home-word-input::placeholder {
  color: transparent;
}

body.edit-mode .home-word-input {
  cursor: text;
  background: rgba(138, 135, 124, 0.1);
  border-color: var(--muted);
  opacity: 1;
}

body.edit-mode .home-word-input:hover {
  opacity: 1;
}

body.edit-mode .home-word-input::placeholder {
  color: var(--muted);
  font-style: italic;
  font-weight: 400;
}

body.edit-mode .home-word-input:focus {
  background: rgba(138, 59, 43, 0.08);
  border-color: #8a3b2b;
}

.home-word-delete-btn {
  display: none;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: 2px solid var(--paper);
  color: var(--paper);
  background: #8a3b2b;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  flex: 0 0 auto;
  padding: 0;
}

body.edit-mode .home-word-delete-btn {
  display: block;
}

body.edit-mode .home-word-delete-btn:hover {
  background: #b04d38;
}

.home-footer {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 32px;
  font-size: 0.95rem;
  color: var(--ink);
}

.home-footer .footer-link:hover {
  opacity: 0.6;
}

/* Stessi -2pt del resto del testo "principale" su mobile (vedi il
   commento sul @media della sezione GALLERY più sotto) — qui copre
   intestazione, nomi progetto/parole in home e footer. */
@media (max-width: 700px) {

  .home-header,
  .home-list li,
  .home-word-input,
  .home-footer {
    font-size: calc(0.95rem - 2pt);
  }
}

/* -------------------------------------------------------------------------
   GALLERY (progetti + core archive) — descrizione in alto, poi le foto.
   Tra una foto e l'altra (manuale o in automatico) lo scorrimento è
   ORIZZONTALE (le foto scorrono lateralmente, come una slide). La PAGINA
   nel suo insieme scorre invece in verticale quando testo o foto non
   entrano nello schermo, per poterli vedere per intero.
   ------------------------------------------------------------------------- */
/* Due righe: l'indice sopra, titolo+hamburger sotto (non più tutto in
   una riga sola). */
.topbar {
  display: flex;
  flex-direction: column;
  gap: 28px;
  background: var(--paper);
  padding: 28px 40px 40px;
  border-bottom: 1px solid transparent;
}

/* La "scatola" del titolo è larga quanto tutta la riga (flex: 1) e viene spostata di decine di pixel (60 su telefono, 120
   su computer): la parte vuota a destra usciva dal bordo e rendeva la pagina PIÙ LARGA DELLO SCHERMO — su ogni telefono di
   2 px (striscia scura sul bordo destro e pagina che "balla" di lato), su iPad in verticale fino a 42 px. Per chi visita il
   sito quella parte vuota si ritaglia (si vede solo il testo del titolo, che non cambia). In modalità modifica no: lì le
   maniglie di spostamento stanno fuori dai bordi del foglio e devono restare raggiungibili. */
body:not(.edit-mode) .topbar {
  overflow-x: clip;
}

.topbar-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

.topbar-index {
  font-size: 0.95rem;
  min-width: 1.5em;
  position: relative;
}

/* Il numero è un <input>, non più un semplice testo — sempre presente,
   invisibile come campo (bordo/sfondo solo in modalità modifica) finché
   non lo tocchi, stesso principio di didascalie e parole in home. */
.topbar-index-input {
  width: 3ch;
  padding: 1px 2px;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 3px;
  outline: none;
  pointer-events: none;
}

body.edit-mode .topbar-index-input {
  cursor: text;
  width: 5ch;
  background: rgba(138, 135, 124, 0.1);
  border-color: var(--muted);
  pointer-events: auto;
}

body.edit-mode .topbar-index-input:focus {
  background: rgba(138, 59, 43, 0.08);
  border-color: #8a3b2b;
}

.topbar-title {
  font-size: 0.95rem;
  flex: 1;
  position: relative;
}

/* La maniglia sta a destra del testo (non sopra): "13" o un titolo corto
   sarebbero più stretti della maniglia stessa, quindi la copriremmo se la
   mettessimo dentro come sulle foto. */
.topbar-index .move-handle,
.topbar-title .move-handle {
  position: absolute;
  top: 50%;
  right: 0;
  margin-right: -24px;
  transform: translateY(-50%);
}

/* L'hamburger è un link che torna alla home (niente menu a comparsa). */
.hamburger {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 22px;
  padding: 4px;
}

/* Sotto, non di lato: a sinistra c'è il titolo (flex: 1, quindi la sua
   "riga" arriva fin quasi al bordo dell'hamburger) e a destra il bordo
   della pagina — sotto invece c'è sempre spazio libero. */
.hamburger .move-handle {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 6px;
}

.hamburger span {
  display: block;
  height: 1.5px;
  background: var(--ink);
  width: 100%;
}

/* Su telefono il tasto "torna alla home" è un po' più grande di quello del computer e più facile da premere: le tre lineette
   passano da 14 a 16 px di larghezza (e da 1,5 a 2 px di spessore; erano 24 px, poi 20, e sembravano ancora grosse), e
   l'area sensibile al tocco resta di 50 × 44 px, oltre il disegno. Il bordo destro e il centro verticale restano dove erano
   e i margini negativi lasciano invariata l'altezza della barra (20,5 px, come su computer): tutto il resto della pagina non
   si muove. In modalità modifica resta com'era (lì c'è la maniglia di spostamento sotto il tasto). Misure: scatola = 16 px di
   lineette + 4 px di padding per lato = 24 px; altezza = 3 × 2 px + 2 × 4 px di spazio + 8 px di padding = 22 px, quindi
   margini di -0,75 px (22 - 0,75 - 0,75 = 20,5); area sensibile = 24 + 2 × 13 = 50 px e 22 + 2 × 11 = 44 px. */
@media (max-width: 700px) {
  body:not(.edit-mode) .hamburger {
    width: 24px;
    gap: 4px;
    margin-top: -0.75px;
    margin-bottom: -0.75px;
  }

  body:not(.edit-mode) .hamburger span {
    height: 2px;
  }

  body:not(.edit-mode) .hamburger::before {
    content: "";
    position: absolute;
    top: -11px;
    right: -13px;
    bottom: -11px;
    left: -13px;
  }
}

/* La larghezza/altezza di .description viene impostata da JS leggendo
   LAYOUT.gallery.descriptionWidth (o descriptionBox del singolo progetto).
   Il testo scorre verticalmente dall'alto verso il basso in loop continuo,
   come un marquee: dentro c'è un'unica striscia (.description-track) con
   il testo ripetuto due volte una sotto l'altra. Lo scorrimento è guidato
   da JS (requestAnimationFrame in app.js), non da un'animazione CSS,
   proprio per poterlo anche trascinare a mano — vedi il commento su
   "marqueePos" in app.js per il perché e per come resta un loop
   impercettibile (distanza esatta misurata sul DOM, non una percentuale
   come "50%", che con dei gap tra paragrafi produrrebbe un piccolo
   scatto visibile a ogni giro). */
.description {
  padding: 64px 40px 56px;
  font-size: 0.95rem;
  line-height: 1.65;
  max-width: 100%;
  position: relative;
  overflow: hidden;
  /* Con l'offset verticale di default (LAYOUT.gallery.descriptionOffset) il
     riquadro finisce per sovrapporsi alla galleria foto sotto — senza uno
     z-index esplicito qui, ".photo-viewport" (che viene dopo nel markup)
     ci dipinge sopra, rendendo la maniglia di resize nell'angolo
     irraggiungibile col mouse. */
  z-index: 2;
}

.description-track {
  /* Promuove il livello a un layer GPU dedicato, così ogni frame del
     marquee è una semplice ricomposizione invece di un repaint — a
     velocità così basse (pochi px/sec) è il repaint che si nota come un
     piccolo scatto, non lo spostamento in sé. */
  will-change: transform;
}

.description-track.draggable {
  cursor: grab;
  touch-action: none;
  user-select: none;
}

.description-track.draggable.is-dragging {
  cursor: grabbing;
}

.description-editable {
  outline: none;
  white-space: pre-wrap;
  min-height: 1.5em;
  transition: border 0.2s, background 0.2s;
  border: 1px solid transparent;
}

body.edit-mode .description-editable {
  border: 1px dashed rgba(100, 100, 100, 0.4);
  border-radius: 4px;
  padding: 4px;
}

.description-editable[contenteditable="true"]:focus {
  background: rgba(255, 255, 255, 0.5);
  border-color: rgba(100, 100, 100, 0.8);
}

.description p+p {
  margin-top: 1.1em;
}

/* Il "binario" orizzontale: contiene tutte le foto in fila, una accanto
   all'altra. La finestra (.photo-viewport) ne clip-pa la larghezza e
   mostra una sola foto alla volta, facendo scorrere il binario con una
   transform. L'altezza della finestra viene impostata da JS in base alla
   foto corrente, così la pagina scorre in verticale q.b. per vederla
   tutta se è più alta dello schermo. */
.photo-viewport {
  overflow: hidden;
  position: relative;
  width: 100%;
  transition: height var(--transition-ms) var(--transition-ease);
}

.photo-track {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  transition: transform var(--transition-ms) var(--transition-ease);
  will-change: transform;
}

.photo {
  flex: 0 0 100%;
  width: 100%;
  margin: 0;
  /* <figure> ha un margine di default del browser (~40px ai lati): lo azzeriamo */
  padding: 72px 40px 96px;
  text-align: center;
  /* centra .photo-frame quando è "inline-block" a larghezza automatica */
}

/* Finché non la tocchi, ogni foto ha la STESSA ALTEZZA (calcolata da JS
   in base allo spazio rimasto sotto il testo, vedi applyDefaultPhotoHeights
   in app.js) e la larghezza segue automaticamente le sue proporzioni
   naturali — per questo "inline-block": si restringe/allarga sul
   contenuto invece di riempire per forza tutta la riga. Se invece la
   ridimensioni a mano (maniglie rosse), width/height diventano entrambe
   esplicite e questo non cambia nulla. */
.photo-frame {
  display: inline-block;
  position: relative;
  max-width: 100%;
  height: fit-content;
}

.photo-frame img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  /* "contain", non "cover": la foto non va mai tagliata. Le maniglie di
     resize mantengono già le proporzioni naturali della foto (vedi
     makeResizable in app.js), quindi in pratica il riquadro combacia
     sempre con l'immagine; "contain" è qui solo come rete di sicurezza
     (es. prima che una foto finisca di caricare, o su misure salvate in
     precedenza) così non si vede mai un pezzo di foto tagliato via. */
  object-fit: contain;
  cursor: zoom-in;
}

/* Didascalia: un rettangolo SEMPRE presente nella struttura della pagina
   (mai nascosto in base al contenuto — niente più trucchi ":empty" per
   nasconderlo o mostrare un segnaposto: qui basta il placeholder nativo
   dell'<input>). Fuori dalla modalità modifica è invisibile come box
   (nessun bordo/sfondo, sembra testo normale); in modalità modifica
   diventa un vero rettangolo con bordo, per essere inequivocabile. */
.caption-box {
  position: absolute;
  /* "auto", non "100%": il codice rende la didascalia "relative" (sta nel flusso, 160px sotto la foto) e una
     percentuale come "top: 100%" Safari la applica (spostando la didascalia di un'intera altezza della foto,
     fuori dalla pagina), Chrome/Vivaldi no — per questo su Safari le didascalie sparivano. */
  top: auto;
  left: 0;
  right: 0;
  width: 240px;
  /* Non più "100%" (la larghezza della foto): con una foto stretta la didascalia veniva schiacciata alla larghezza della
     foto, andava a capo di più e nessuna maniglia poteva allargarla. Ora ha la sua larghezza (240px, o quella scelta con le
     maniglie ai lati) e al massimo lo schermo. */
  max-width: calc(100vw - 16px);
  /* Centrata sotto la foto qualunque sia la sua larghezza (anche più larga della foto, cosa che "margin: auto" non sa fare):
     metà della foto (50% è la larghezza della foto) meno metà della larghezza della didascalia (--cap-w, tenuta uguale a
     "width" da renderGallery). Con una didascalia più stretta della foto il risultato è identico a prima. */
  margin: 160px 0 0 calc(50% - var(--cap-w, 240px) / 2) !important;
}

.caption-box .move-handle {
  position: absolute;
  top: -30px;
  right: -30px;
}

/* Maniglia gemella a sinistra: la didascalia si trascina anche da lì,
   utile quando quella di destra finisce fuori mano dopo uno spostamento. */
.caption-box .move-handle-left {
  position: absolute;
  top: -30px;
  left: -30px;
}

/* Maniglie per allargare/restringere la didascalia (solo in modalità modifica, su computer e su telefono): una per lato, a
   metà altezza, fuori dal riquadro, lontane da quelle della foto. Trascinandole la didascalia si allarga da entrambi i lati
   (resta centrata sotto la foto) e il testo va a capo di conseguenza; la larghezza si salva per quella foto, separatamente
   per computer e per telefono. */
.caption-box .resize-handle-side {
  top: 50%;
  bottom: auto;
  margin-top: -11px;
  cursor: ew-resize;
}

.caption-box .resize-handle-side-right {
  right: -30px;
  left: auto;
}

.caption-box .resize-handle-side-left {
  left: -30px;
  right: auto;
}

/* al posto dell'angolino delle maniglie d'angolo, una doppia freccia orizzontale */
.caption-box .resize-handle-side::after {
  content: "↔";
  border: 0;
  width: auto;
  height: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
  color: var(--paper);
}

/* La scrittura delle didascalie delle foto: la STESSA identica per le parole del Core Archive, che sono
   didascalie di foto del sito. Un solo posto da cambiare. (Il nome del progetto accanto alla foto ingrandita
   NON è una didascalia: ha il carattere dei nomi della home, vedi ".lightbox-project-label" più sotto.) */
.caption-input,
.archive-word {
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 550;
  line-height: 1.4;
  letter-spacing: normal;
  color: var(--muted);
}

.caption-input {
  display: block;
  width: 100%;
  padding: 8px 12px;
  text-align: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 3px;
  outline: none;
  pointer-events: none;
  resize: none;
  overflow: hidden;
  /* fuori da edit mode non è cliccabile/selezionabile */
}

.caption-input::placeholder {
  color: transparent;
}

body.edit-mode .caption-input {
  cursor: text;
  color: var(--ink);
  background: rgba(138, 135, 124, 0.1);
  border-color: var(--muted);
  pointer-events: auto;
}

body.edit-mode .caption-input::placeholder {
  color: var(--muted);
  font-style: italic;
}

body.edit-mode .caption-input:focus {
  background: rgba(138, 59, 43, 0.08);
  border-color: #8a3b2b;
}

@media (max-width: 700px) {
  .topbar {
    padding: 20px 20px;
    gap: 20px;
  }

  /* Solo su mobile, il testo "principale" (titolo, numeri, descrizione) è
     2pt più piccolo che su desktop. */
  .topbar-index,
  .topbar-title,
  .description {
    font-size: calc(0.95rem - 2pt);
  }

  /* Anche le didascalie delle foto (e le parole del Core Archive, che hanno la stessa scrittura): prima su telefono restavano a
     0.8rem come su computer, quindi più grandi del testo che le accompagna (12,8px contro 12,5px, mentre su computer sono 12,8
     contro 15,2). Ora 2pt più piccole, come il resto del testo: 10,1px, quasi la stessa proporzione del computer. */
  .caption-input,
  .archive-word {
    font-size: calc(0.8rem - 2pt);
  }

  .description {
    padding: 40px 20px 28px;
  }

  .photo {
    padding: 32px 20px 48px;
  }
}

.gallerybar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--paper);
  padding: 32px 40px 36px;
  position: relative;
}

.gallerybar-center {
  display: flex;
  align-items: center;
  gap: 16px;
}

.grid-btn {
  display: none !important;
}

body.edit-mode .grid-btn {
  display: inline-flex !important;
  align-items: center;
  background: none;
  border: none;
  cursor: pointer;
  color: inherit;
}

.nav-arrow {
  font-size: 1rem;
  padding: 6px 10px;
  transition: opacity 0.2s ease;
}

.nav-arrow:hover {
  opacity: 0.5;
}

@media (max-width: 700px) {
  .gallerybar {
    padding: 24px 20px 28px;
  }
}

/* Core Archive: la barra in fondo ha solo il numero (niente frecce). Il numero parte a sinistra e la sua posizione la mette
   il codice (alignBottomNumber in app_v58.js): padding a sinistra = linea verticale del titolo e dell'elenco, padding in alto =
   distanza dall'ultima parola uguale a quella che in alto c'è tra il "0" e il titolo. Prima era centrato e spostato di -180px
   (computer) o di una misura a occhio (telefono): non cadeva sulla linea del titolo e, essendo riferito al centro, si
   spostava con la larghezza dello schermo. */
.gallerybar.archive-bar {
  justify-content: flex-start;
}

/* Core Archive in modifica, su telefono: i tre pulsanti fissi in basso a sinistra (+ Parola, + Spazio, Vecchio archivio, larghi
   196px) restano sopra il fondo della pagina e coprivano il numero della barra e la sua maniglia di spostamento. Con questo
   posto in più sotto la pagina si scorre abbastanza da vederlo e prenderlo. Per chi visita il sito e su computer non c'è. */
.edit-bottom-room {
  display: none;
}

@media (max-width: 700px) {
  body.edit-mode .edit-bottom-room {
    display: block;
    height: 140px;
  }
}

/* -------------------------------------------------------------------------
   SIMPLE PAGES (contacts / about / not found)
   ------------------------------------------------------------------------- */
.simple-page {
  padding-top: 24px;
}

.contact-line {
  font-family: var(--mono);
  font-size: 0.85rem;
  color: var(--muted);
}

/* ==========================================================================
   LIGHTBOX — zoom con tecnica FLIP (vedi makeZoomable/openTextLightbox in
   app.js): foto e testo condividono lo stesso sfondo scuro
   (".lightbox-backdrop", più sotto) e la stessa idea — un solo elemento
   "volante" per tipo, creato una volta e riusato, con posizione/scala di
   partenza e arrivo calcolate in JS in base a dove si trova davvero
   l'elemento sullo schermo in quel momento. Qui in CSS c'è solo
   l'aspetto, non le coordinate.
   ========================================================================== */
.lightbox-close {
  position: fixed;
  top: 20px;
  right: 24px;
  z-index: 301;
  font-size: 1.8rem;
  line-height: 1;
  color: var(--paper);
  opacity: 0.7;
}

.lightbox-close:hover {
  opacity: 1;
}

/* Sfondo scuro CONDIVISO da foto e testo (vedi ensureZoomElements). */
.lightbox-backdrop {
  /* Posizione, dimensione, colore e z-index reali sono impostati IN RIGA
     da JS (vedi ensureZoomElements in app.js), non qui: dopo aver
     scoperto che "inset: 0" veniva ignorato da alcuni browser (lasciando
     lo sfondo scuro senza dimensione, con la pagina beige sotto la foto
     ancora visibile), questi valori non devono più dipendere da nessuna
     regola del foglio di stile — solo lo stato is-active/pointer-events
     resta qui. Colore pieno, niente alpha: prima 0.96 di opacità
     lasciava un 4% di trasparenza che, sommato al problema di copertura,
     peggiorava il "residuo" beige.
     Nessuna transition fissa: la imposta JS di volta in volta (vedi
     makeZoomable) — deve arrivare a piena opacità MOLTO prima che la foto
     finisca di volare (altrimenti per gran parte dell'animazione si vede
     la pagina reale trasparire attraverso lo sfondo ancora a metà
     dissolvenza), e restare piena per quasi tutto il volo di ritorno in
     chiusura, sparendo solo all'ultimo. */
  opacity: 0;
  pointer-events: none;
}

.lightbox-backdrop.is-active {
  opacity: 1;
  pointer-events: auto;
}

/* Riquadro che vola (vedi makeZoomable in app.js): posizione/dimensione
   impostate in riga da JS, qui solo l'aspetto — è un <div>, non l'<img>
   direttamente, per poterci appoggiare le maniglie di resize (le <img>
   sono elementi "replaced", non possono avere figli visibili). */
.lightbox-active-frame {
  position: fixed;
  z-index: 301;
  will-change: transform;
  /* Senza "chiuso" non intercetta i click: a fine chiusura resta comunque
     nel DOM (a grandezza/posizione della miniatura), e senza questo
     bloccherebbe per sempre i click su qualunque cosa si trovi in quello
     stesso punto dello schermo. */
  pointer-events: none;
  /* Nessuna transition fissa qui: la imposta JS di volta in volta (curva
     diversa per apertura e chiusura, vedi makeZoomable). */
}

.lightbox-active-frame.is-active {
  pointer-events: auto;
}

/* Foto ingrandita su telefono, in modifica: le maniglie per regolarne la misura stanno normalmente a 30px FUORI dal bordo, cioè
   fuori dallo schermo (la foto arriva a 8px dal bordo): non si vedevano e non si potevano afferrare. Qui stanno DENTRO gli angoli. */
@media (max-width: 700px) {
  .lightbox-active-frame .resize-handle {
    right: 6px;
    bottom: 6px;
  }

  .lightbox-active-frame .resize-handle.resize-handle-top {
    top: 6px;
    bottom: auto;
  }
}

.lightbox-active-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  cursor: zoom-out;
}

/* Il nome del progetto accanto alla foto ingrandita (es. "Beach"): lo STESSO carattere dei nomi nella lista della
   home — stessa famiglia, grandezza, peso, interlinea e spessore (lo spessore arriva da body, vedi --sans-stroke) —
   e scritto come in home (maiuscola compresa). Colore: quello del "foglio" beige della pagina (--paper), l'unico
   che qui, sullo sfondo scuro, sta al posto dell'inchiostro scuro dei nomi della home.
   Posizione e distanza dalla foto: vedi makeZoomable. */
.lightbox-project-label {
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: normal;
  color: var(--paper);
}

/* Su telefono i nomi della home sono 2pt più piccoli (vedi sopra): anche questo. */
@media (max-width: 700px) {
  .lightbox-project-label {
    font-size: calc(0.95rem - 2pt);
  }
}

/* Zoom sul testo: stesso identico rettangolo beige di ".page" (stessa
   larghezza, stessa altezza minima quasi a schermo intero, stesso
   margine) — non un box che si stringe attorno al testo, ma il "foglio"
   pieno come in ogni altra pagina del sito, solo senza topbar/foto/
   gallerybar dentro. Posizione (position/top/left/right) e scroll
   (max-height/overflow-y) impostati in riga da JS (vedi
   ensureZoomTextPanel in app.js), non qui — stesso motivo dello sfondo
   scuro qui sopra. "transform" NON ha una regola fissa: la imposta JS di
   volta in volta (curva diversa per apertura e chiusura, vedi
   openTextLightbox), esattamente come ".lightbox-active-img". */
.lightbox-text {
  width: min(100%, var(--panel-width));
  min-height: calc(100vh - 40px);
  margin: 20px auto;
  background: var(--paper);
  color: var(--ink);
  padding: 120px 40px 56px;
  font-size: 0.95rem;
  line-height: 1.65;
  /* Invisibile e non-cliccabile finché non è davvero aperto: senza
     questo, a chiusura completata (contenuto svuotato ma "min-height"
     qui sopra lo terrebbe comunque alto quasi quanto lo schermo) il
     pannello resterebbe un rettangolo beige vuoto che blocca i click su
     tutto quello che gli sta sotto — stesso bug già trovato e risolto
     per ".lightbox-active-img" con "pointer-events", qui serve anche
     nascondere la vista, non solo i click. */
  visibility: hidden;
}

.lightbox-text.is-active {
  visibility: visible;
}

@media (max-width: 700px) {
  .lightbox-text {
    width: 100%;
    min-height: 100dvh;
    margin: 0 auto;
    padding: 120px 20px 28px;
    /* Stessi -2pt del resto del testo "principale" su mobile, vedi il
       commento sul primo @media (max-width: 700px) più sopra. */
    font-size: calc(0.95rem - 2pt);
  }
}

.lightbox-text p+p {
  margin-top: 1.1em;
}

/* ==========================================================================
   MODALITÀ MODIFICA — regolare dimensioni, ordine e posizione trascinando,
   non a numeri.
   ==========================================================================
   Il bottoncino "⇲" in basso a destra attiva/disattiva la modalità. Con la
   modalità attiva, ogni blocco mostra:
     - un'etichetta in alto a sinistra con le dimensioni attuali (lista
       home, testo, foto);
     - una maniglia rossa in basso a destra per ridimensionare (cursore a
       doppia freccia);
     - una maniglia blu con l'icona ⠿ per riordinarlo tra i suoi vicini
       (in alto a destra sulle foto, accanto al nome nella lista home);
     - sulle didascalie, una maniglia verde per spostarle liberamente
       (sopra, di lato, dove vuoi) — indipendente dalla foto: non riordina
       nulla, segue solo il trascinamento.
   Ogni modifica resta salvata nel browser (localStorage) e viene riproposta
   ad ogni visita. Quando sei soddisfatto, apri "Esporta modifiche" per
   avere il testo pronto da incollare in content.js e renderle permanenti
   sul sito pubblicato. In modalità modifica i link (voci della lista,
   frecce, hamburger) e il lightbox sono disattivati per non navigare/
   ingrandire per sbaglio mentre trascini.
   ------------------------------------------------------------------------- */
.edit-toggle,
.export-toggle,
.mobile-preview-toggle {
  position: fixed;
  right: 16px;
  z-index: 400;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: #2b2b28;
  color: var(--paper);
  font-size: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.6;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.edit-toggle {
  bottom: 16px;
}

.export-toggle {
  bottom: 68px;
  display: none;
}

/* A sinistra, non impilato con gli altri due: è utile anche FUORI dalla
   modalità modifica (per guardare il sito com'è normalmente su telefono),
   quindi resta sempre visibile, non solo "body.edit-mode". */
.mobile-preview-toggle {
  left: 16px;
  right: auto;
  bottom: 16px;
}

.phone-icon {
  display: block;
  width: 12px;
  height: 19px;
  border: 1.5px solid currentColor;
  border-radius: 3px;
  position: relative;
}

.phone-icon::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 2px;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  transform: translateX(-50%);
}

/* Anteprima mobile — vedi openMobilePreview in app.js: un vero <iframe>
   (non solo una colonna ristretta) caricato sullo stesso sito, largo
   quanto un telefono. Essendo un contesto di visualizzazione a parte, i
   @media (max-width: 700px) qui dentro scattano esattamente come su un
   telefono vero, editing compreso — non serve duplicare o simulare nulla. */
.mobile-preview-overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 400;
  background: rgba(10, 10, 10, 0.94);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 24px;
}

.mobile-preview-overlay.is-open {
  display: flex;
}

.mobile-preview-device {
  width: 390px;
  max-width: 100%;
  height: 844px;
  max-height: calc(100vh - 120px);
  background: #000;
  border-radius: 36px;
  padding: 10px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.mobile-preview-device iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: none;
  border-radius: 26px;
  background: var(--paper);
}

.mobile-preview-close {
  color: var(--paper);
  background: none;
  border: 1px solid rgba(237, 235, 224, 0.5);
  border-radius: 20px;
  padding: 8px 18px;
  font-size: 0.85rem;
  cursor: pointer;
  opacity: 0.85;
}

.mobile-preview-close:hover {
  opacity: 1;
}

@media (max-width: 480px) {

  /* Sullo schermo di un telefono vero l'anteprima non serve: sei già lì. */
  .mobile-preview-toggle {
    display: none;
  }
}

.edit-toggle:hover,
.export-toggle:hover {
  opacity: 1;
  transform: scale(1.05);
}

body.edit-mode .edit-toggle {
  opacity: 1;
  background: #8a3b2b;
}

body.edit-mode .export-toggle {
  display: flex;
}

body.edit-mode .home-list,
body.edit-mode .description {
  overflow: auto;
}

body.edit-mode .home-list,
body.edit-mode .description,
body.edit-mode .photo-frame {
  outline: 2px dashed #8a3b2b;
  outline-offset: 3px;
}

/* Griglia di allineamento: visibile solo in modalità modifica, per
   impaginare tutte le foto/blocchi allo stesso modo. Il passo (20px) deve
   restare uguale a GRID_SIZE in app.js, a cui si agganciano resize,
   riordino e spostamento libero della didascalia. */
body.edit-mode .page {
  background-image:
    repeating-linear-gradient(to right, rgba(43, 43, 40, 0.09) 0, rgba(43, 43, 40, 0.09) 1px, transparent 1px, transparent 20px),
    repeating-linear-gradient(to bottom, rgba(43, 43, 40, 0.09) 0, rgba(43, 43, 40, 0.09) 1px, transparent 1px, transparent 20px);
}

.resizable-label {
  position: absolute;
  top: -30px;
  left: -20px;
  font-family: var(--mono);
  font-size: 0.7rem;
  background: #8a3b2b;
  color: var(--paper);
  padding: 3px 7px;
  border-radius: 3px;
  pointer-events: none;
  z-index: 2;
  display: none;
  white-space: nowrap;
}

body.edit-mode .resizable-label,
.resizable.always-visible-label .resizable-label {
  display: block;
}

/* Maniglia di resize disegnata da noi (non quella nativa del browser,
   troppo piccola/incoerente tra browser diversi): un quadratino ben
   visibile nell'angolo in basso a destra, trascinabile col mouse o col
   dito. Sta leggermente FUORI dal bordo dell'elemento (right/bottom
   negativi) così è sempre raggiungibile anche se il contenuto arriva
   fino al bordo. */
.resize-handle {
  display: none;
  position: absolute;
  right: -30px;
  bottom: -30px;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  background: #8a3b2b;
  border: 2px solid var(--paper);
  cursor: nwse-resize;
  z-index: 3;
  touch-action: none;
}

/* Blocco vuoto trascinabile in altezza (vedi makeHeightResizable in
   app.js): a piena larghezza, quindi la sua maniglia sta centrata invece
   che nell'angolo, e il cursore è quello di un ridimensionamento solo
   verticale. */
.gallery-spacer {
  position: relative;
  width: 100%;
}

.gallery-spacer .resize-handle {
  right: auto;
  left: 50%;
  transform: translateX(-50%);
  cursor: ns-resize;
}

/* Sulle foto c'è anche una maniglia speculare a sinistra (oltre a quella
   di default a destra), così si può ridimensionare tirando da entrambi i
   lati: cursore ruotato di conseguenza (nesw invece di nwse). */
.resize-handle.resize-handle-left {
  right: auto;
  left: -30px;
  cursor: nesw-resize;
}

/* Solo sulla foto ingrandita dello zoom (vedi makeZoomResizable in
   app.js): copia in alto a destra della maniglia di resize, così una
   delle due resta sempre raggiungibile anche se il riquadro ingrandito
   supera l'altezza dello schermo. */
.resize-handle.resize-handle-top {
  bottom: auto;
  top: -30px;
  cursor: nwse-resize;
}

/* Su telefono (in modifica) le foto larghe quasi quanto lo schermo hanno le maniglie laterali a 30px fuori dal bordo, cioè fuori
   dallo schermo: se ne vedevano solo pochi pixel (o niente) e non si potevano afferrare bene. Qui stanno a 12px: ancora quasi
   tutte fuori dalla foto, ma dentro lo schermo (la pagina ha 20px di margine). Non vale per le parole del Core Archive. */
@media (max-width: 700px) {
  .photo-frame > .resize-handle {
    right: -12px;
  }

  .photo-frame > .resize-handle.resize-handle-left {
    right: auto;
    left: -12px;
  }
}

/* Eccezione: sulla foto ingrandita dello zoom la maniglia per decidere
   la dimensione è sempre visibile, non solo in modalità modifica — è
   l'unico modo per regolarla mentre la guardi davvero ingrandita. */
.resize-handle.always-visible {
  display: block;
}

/* Elimina questa foto ("×") / aggiungine una nuova qui accanto ("+"):
   stesso quadratino delle altre maniglie, centrate in alto — gli angoli
   sono già occupati dall'etichetta delle misure (sinistra) e dalla
   maniglia verde di spostamento della foto (destra). */
.photo-delete-btn,
.photo-link-btn,
.photo-add-btn {
  display: none;
  position: absolute;
  top: -30px;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  border: 2px solid var(--paper);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  z-index: 3;
  touch-action: none;
  padding: 0;
}

.photo-delete-btn {
  left: calc(50% - 36px);
  background: #8a3b2b;
}

.photo-link-btn {
  left: calc(50% - 10px);
  background: #2b5d7a;
}

.photo-add-btn {
  left: calc(50% + 16px);
  background: #2b7a4b;
}

body.edit-mode .photo-delete-btn,
body.edit-mode .photo-link-btn,
body.edit-mode .photo-add-btn {
  display: block;
}

body.edit-mode .photo-delete-btn:hover {
  background: #b04d38;
}

body.edit-mode .photo-link-btn:hover {
  background: #387c99;
}

body.edit-mode .photo-add-btn:hover {
  background: #38995e;
}

/* Elimina il blocco di testo della descrizione: stesso quadratino delle
   foto, ma da solo (niente "+" accanto: non ha senso "aggiungerne un'altra")
   quindi centrato per davvero, non spostato di mezzo per lasciare posto a
   un gemello. */
.description-delete-btn {
  display: none;
  position: absolute;
  top: -30px;
  left: 50%;
  transform: translateX(-50%);
  width: 22px;
  height: 22px;
  border-radius: 4px;
  border: 2px solid var(--paper);
  color: var(--paper);
  background: #8a3b2b;
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  z-index: 3;
  padding: 0;
}

body.edit-mode .description-delete-btn {
  display: block;
}

body.edit-mode .description-delete-btn:hover {
  background: #b04d38;
}

/* Maniglia di riordino: trascinala per cambiare la posizione di una foto
   dentro la galleria (orizzontale) o di un nome nella lista home
   (verticale). Colore diverso da quella di resize per non confonderle. */
.move-handle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  background: #2b6e8a;
  border: 2px solid var(--paper);
  color: var(--paper);
  font-size: 12px;
  line-height: 1;
  cursor: grab;
  z-index: 3;
  touch-action: none;
  flex: 0 0 auto;
}

.move-handle::before {
  content: "⠿";
}

body.edit-mode .move-handle {
  display: inline-flex;
}

/* Eccezione: nel testo ingrandito dello zoom la maniglia per riposizionarlo
   è sempre visibile, non solo in modalità modifica — è l'unico modo per
   aggiustarne la posizione mentre lo guardi davvero ingrandito. */
.move-handle.always-visible {
  display: inline-flex;
}

body.edit-mode .move-handle:hover,
.move-handle.always-visible:hover,
.move-handle.is-dragging {
  background: #3a8ab0;
  cursor: grabbing;
}

/* dentro una foto o nel blocco di testo: angolo in alto a destra (il
   resize resta in basso a destra, l'etichetta con le misure in alto a
   sinistra) */
.photo-frame .move-handle,
.description .move-handle,
.lightbox-text-content .move-handle {
  position: absolute;
  top: -30px;
  right: -30px;
}

.photo-frame .move-handle-left,
.description .move-handle-left,
.lightbox-text-content .move-handle-left {
  right: auto;
  left: -30px;
}

/* Maniglia verde: sposta liberamente un blocco (testo, foto, didascalia,
   numero/titolo in alto, hamburger), indipendentemente dai suoi vicini —
   semplice trascinamento libero in qualunque direzione, niente riordino. */
.move-handle.free-move {
  background: #2b7a4b;
  cursor: move;
}

.move-handle.free-move:hover,
.move-handle.free-move.is-dragging {
  background: #38995e;
  cursor: move;
}

/* dentro la lista home: icona inline prima del nome, solo in modalità
   modifica (il resto del tempo la lista resta un elenco normale) */
body.edit-mode .home-list li {
  display: flex;
  align-items: center;
  gap: 8px;
}

.is-dragging-item {
  opacity: 0.55;
  z-index: 20;
}

.resize-handle::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--paper);
  border-bottom: 2px solid var(--paper);
}

body.edit-mode .resize-handle,
.resize-handle.always-visible {
  display: block;
}

body.edit-mode .resize-handle:hover,
.resize-handle.always-visible:hover,
.resize-handle.is-dragging {
  background: #b04d38;
}

body.edit-mode .home-list a,
body.edit-mode .hamburger,
body.edit-mode .nav-arrow:not(.grid-btn),
body.edit-mode .footer-link,
body.edit-mode .photo-frame img {
  pointer-events: none;
}

/* La maniglia dell'hamburger deve restare cliccabile anche se il link
   che la contiene è disattivato sopra (altrimenti "pointer-events: none"
   si eredita anche su di lei, e in modalità modifica risulterebbe
   invisibile ai click pur essendo visibile a schermo). */
body.edit-mode .hamburger .move-handle {
  pointer-events: auto;
}

/* -------------------------------------------------------------------------
   GUIDE DI ALLINEAMENTO stile Photoshop — vedi setupAlignmentGuides in
   app.js. Due righelli fissi ai bordi del viewport da cui trascini fuori
   una linea guida: a differenza delle maniglie (che spostano UN elemento),
   la guida è un riferimento condiviso da TUTTA la galleria — resta
   esattamente dove l'hai messa (stessa riga per ogni foto), finché non la
   sposti o la ributti sul righello di origine per toglierla. Solo in
   modalità modifica, come ogni altro strumento di editing.
   ------------------------------------------------------------------------- */
.guide-ruler {
  display: none;
  position: fixed;
  z-index: 250;
  background: repeating-linear-gradient(45deg,
      rgba(34, 211, 238, 0.4),
      rgba(34, 211, 238, 0.4) 4px,
      rgba(34, 211, 238, 0.15) 4px,
      rgba(34, 211, 238, 0.15) 8px);
}

body.edit-mode .guide-ruler {
  display: block;
}

.guide-ruler-h {
  top: 0;
  left: 0;
  right: 0;
  height: 14px;
  cursor: ns-resize;
}

.guide-ruler-v {
  top: 0;
  left: 0;
  bottom: 0;
  width: 14px;
  cursor: ew-resize;
}

/* Non più nascosti sotto i 700px: da quando esiste l'anteprima mobile
   (vedi setupMobilePreviewToggle in app.js) modificare da lì è un caso
   d'uso vero, non solo un telefono reale con poco spazio — e lì servono
   TUTTI gli strumenti di editing, guide comprese. */

/* Vive dentro ".page" (position: relative), non nel viewport: così le
   guide scorrono col resto della pagina invece di restare incollate allo
   schermo mentre navighi tra le foto o scorri il testo. */
.guides-layer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  pointer-events: none;
  z-index: 6;
}

.guide-line {
  display: none;
  position: absolute;
  pointer-events: auto;
}

body.edit-mode .guide-line {
  display: block;
}

/* Zona cliccabile allargata (9px) attorno alla riga vera (1px): un filo
   così sottile sarebbe troppo difficile da riagganciare col mouse. */
.guide-line-h {
  left: 0;
  right: 0;
  height: 9px;
  margin-top: -4px;
  cursor: ns-resize;
}

.guide-line-v {
  top: 0;
  bottom: 0;
  width: 9px;
  margin-left: -4px;
  cursor: ew-resize;
}

.guide-line::after {
  content: "";
  position: absolute;
  background: #22d3ee;
}

.guide-line-h::after {
  left: 0;
  right: 0;
  top: 4px;
  height: 1px;
}

.guide-line-v::after {
  top: 0;
  bottom: 0;
  left: 4px;
  width: 1px;
}

.guide-line.is-dragging::after,
.guide-line:hover::after {
  background: #67e8f9;
}

/* Sopra al righello di origine mentre la trascini: il rilascio la elimina
   (stesso principio del "cestino" di Photoshop) — tinta rossa di anteprima
   coerente con lo stesso colore usato per eliminare altrove nel sito. */
.guide-line.guide-will-delete::after {
  background: #b04d38;
}

.export-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 500;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.export-panel-inner {
  background: var(--paper);
  color: var(--ink);
  max-width: 640px;
  width: 100%;
  max-height: 80vh;
  overflow: auto;
  padding: 24px;
  border-radius: 6px;
}

.export-panel h2 {
  font-size: 1rem;
  margin: 0 0 8px;
}

.export-panel p {
  font-size: 0.85rem;
  color: var(--muted);
  margin: 0 0 16px;
}

.export-panel textarea {
  width: 100%;
  height: 260px;
  font-family: var(--mono);
  font-size: 0.78rem;
  padding: 12px;
  box-sizing: border-box;
  background: #fff;
  border: 1px solid var(--hairline);
}

.export-uploads {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
}

.export-uploads-list {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
}

.export-uploads-list li+li {
  margin-top: 6px;
}

.export-uploads-list a {
  text-decoration: underline;
  cursor: pointer;
}

.export-panel-actions {
  display: flex;
  gap: 12px;
  margin-top: 14px;
}

.export-panel-actions button {
  padding: 8px 14px;
  border: 1px solid var(--ink);
  border-radius: 4px;
  font-size: 0.85rem;
}

/* -------------------------------------------------------------------------
   GALLERY INDEX (Grid view)
   ------------------------------------------------------------------------- */
.gallerybar-center {
  display: flex;
  align-items: center;
  gap: 16px;
}

.gallery-index-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: var(--paper);
  z-index: 400;
  overflow-y: auto;
  opacity: 1;
  pointer-events: none;
  transform: translateY(100%);
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
  padding: 80px 40px;
  box-sizing: border-box;
}

.gallery-index-overlay.is-active {
  transform: translateY(0);
  pointer-events: auto;
}

.gallery-index-close {
  position: fixed;
  top: 20px;
  right: 20px;
  background: var(--paper);
  border: 1px solid var(--ink);
  font-family: inherit;
  font-size: 1rem;
  padding: 8px 16px;
  border-radius: 20px;
  cursor: pointer;
  color: var(--ink);
  z-index: 401;
}

.gallery-index-close:hover {
  background: var(--ink);
  color: var(--paper);
}

.gallery-index-zoom {
  position: fixed;
  top: 20px;
  left: 20px;
  background: var(--paper);
  border: 1px solid var(--ink);
  font-family: inherit;
  font-size: 1rem;
  padding: 8px 16px;
  border-radius: 20px;
  cursor: pointer;
  color: var(--ink);
  z-index: 401;
}

.gallery-index-zoom:hover {
  background: var(--ink);
  color: var(--paper);
}

.gallery-index-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 40px;
  max-width: 1400px;
  margin: 0 auto;
}

.gallery-index-grid.zoomed-out {
  grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
  gap: 15px;
}

.gallery-index-item {
  position: relative;
  cursor: pointer;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.gallery-index-item:hover {
  opacity: 0.8;
}

.gallery-index-item.over {
  transform: scale(0.95);
  outline: 2px dashed var(--ink);
  outline-offset: 4px;
}

.grid-item-remove {
  position: absolute;
  top: -12px;
  right: -12px;
  width: 26px;
  height: 26px;
  background: #b04d38;
  color: #fff;
  border: none;
  border-radius: 50%;
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.gallery-index-item:hover .grid-item-remove {
  opacity: 1;
}

.grid-item-remove:hover {
  transform: scale(1.1);
}

.gallery-index-item img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: contain;
  max-height: 300px;
  background: transparent;
}

.gallery-index-grid.zoomed-out .gallery-index-item img {
  max-height: 120px;
}

@media (max-width: 700px) {
  .gallery-index-overlay {
    padding: 60px 20px;
  }
  .gallery-index-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 20px;
  }
}

/* Controlli per il blocco parola nel Core Archive: 
   Spostati a DESTRA della cornice per non coprire il testo
   quando le parole sono impilate verticalmente una vicina all'altra. */
.photo-wrapper:has(> .photo-frame.is-word) .move-handle,
.photo-frame.is-word .move-handle-left,
.photo-frame.is-word .photo-delete-btn,
.photo-frame.is-word .photo-link-btn,
.photo-frame.is-word .photo-add-btn,
.photo-frame.is-word .resizable-label {
  top: 50%;
  transform: translateY(-50%);
}

.photo-wrapper:has(> .photo-frame.is-word) .move-handle { right: -30px; left: auto; }
.photo-frame.is-word .move-handle-left { left: -30px; right: auto; }
.photo-frame.is-word .photo-delete-btn { left: calc(100% + 34px); }
.photo-frame.is-word .photo-link-btn { left: calc(100% + 60px); }
.photo-frame.is-word .resizable-label { left: calc(100% + 86px); }

.photo-frame.is-word .resize-handle {
  bottom: -30px;
  right: -30px;
}

/* Stili per le didascalie all'interno del Core Archive */
.photo-caption-text {
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: normal;
  color: var(--muted);
  text-align: center;
  margin-top: 8px;
  padding: 8px 12px;
  line-height: 1.4;
  outline: none;
}
body.edit-mode .photo-caption-text {
  color: var(--ink);
  background: rgba(138, 135, 124, 0.1);
  border-radius: 3px;
}
@media (max-width: 700px) {
  /* come le altre didascalie: 2pt più piccola su telefono (vedi più sopra, accanto a ".caption-input") */
  .photo-caption-text {
    font-size: calc(0.8rem - 2pt);
  }
}

.hidden-link-img {
  opacity: 0;
}
/* Horizontal Marquee for text paragraphs */
.marquee-horizontal {
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
  box-sizing: border-box;
}

.marquee-horizontal span {
  display: inline-block;
  padding-left: 100%;
  animation: marquee-horizontal-scroll 15s linear infinite;
}

@keyframes marquee-horizontal-scroll {
  0%   { transform: translate3d(0, 0, 0); }
  100% { transform: translate3d(-100%, 0, 0); }
}

/* -------------------------------------------------------------------------
   CORE ARCHIVE — elenco verticale di parole (ognuna è la didascalia di una foto del sito).
   Il bordo sinistro dell'elenco coincide con quello del titolo "core archive" (lo mette JS, vedi
   alignList in app.js); righe alla stessa distanza della lista in home; gruppi separati da una riga vuota.
   ------------------------------------------------------------------------- */
.archive-list {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
  max-width: 100%;
}

.archive-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 26px;
}

.archive-word-frame {
  position: relative;
  display: inline-block;
  max-width: 100%;
}

.archive-word {
  display: inline-block;
  white-space: nowrap;
  text-align: left;
  outline: none;
  /* niente spazio prima della prima lettera: deve cominciare esattamente dove comincia il titolo */
  padding: 0;
}

/* Una parola collegata a una foto si apre con un clic: stesso gesto e stessa reazione dei nomi nella home */
.archive-word-frame.is-linked {
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.archive-word-frame.is-linked:hover {
  opacity: 0.55;
}

body.edit-mode .archive-word-frame.is-linked {
  cursor: text;
}

body.edit-mode .archive-word-frame.is-linked:hover {
  opacity: 1;
}

body.edit-mode .archive-word {
  cursor: text;
  color: var(--ink);
  background: rgba(138, 135, 124, 0.1);
  box-shadow: 0 0 0 1px var(--muted);
  border-radius: 3px;
}

body.edit-mode .archive-word:focus {
  background: rgba(138, 59, 43, 0.08);
  box-shadow: 0 0 0 1px #8a3b2b;
}

.archive-link-btn {
  display: none;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: 2px solid var(--paper);
  background: #2b547a;
  font-size: 10px;
  line-height: 1;
  cursor: pointer;
  flex: 0 0 auto;
  padding: 0;
}

body.edit-mode .archive-link-btn {
  display: block;
}

body.edit-mode .archive-link-btn:hover {
  background: #386f99;
}

/* Riga vuota tra due gruppi: invisibile per i visitatori, in modalità modifica si vede e si può togliere o spostare */
.archive-break-label {
  display: none;
}

body.edit-mode .archive-break-label {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--muted);
  border: 1px dashed var(--muted);
  border-radius: 3px;
  padding: 0 8px;
  line-height: 1.6;
}

body.edit-mode .archive-row {
  gap: 8px;
}
