/* ===========================================================================
   Pagina Portfolio — lista di "lavori" (titolo + copertina) su due colonne, a schermo
   intero come le gallery ma con un corpo diverso: niente griglia di foto, solo la lista
   dei titoli scorre e quello centrato è sempre "attivo", con la sua copertina a destra.
   Il body ha `is-portfolio`; le classi sono prefissate `pf-` per non incrociare site.css
   né gallery.css (due file separati apposta — vedi PORTFOLIO.md).
   Il titolo (`.pf-title`) porta anche `.tsw-title`: lo scambio di lettere in "<HOME" è il
   meccanismo condiviso con le gallery, in title-swap.css/.js.
   =========================================================================== */

/* Stessa profondità di warp delle gallery (non è lo stesso valore per forza: sono pagine
   indipendenti), e stesso motivo per cui sta sul <body>: la condividono la lista/copertina
   e il monogramma, che sono rami diversi (fratelli dentro <main>). */
body.is-portfolio { --pf-persp: 1100; overflow: hidden; }

.pf {
  --pf-bg: #E7E7E7;
  --pf-ink: #111;
  --pf-pad: 3.2vw;
  --pf-top: 8vh;
  --pf-warp-z: 620; --pf-warp-in: -900; --pf-warp-dur: 900; --pf-warp-step: 26;
  position: fixed; inset: 0;
  background: var(--pf-bg); color: var(--pf-ink);
}

/* Prospettiva e punto di fuga: stessa storia di gallery.css — `.pf-list` e `#brand-mark`
   sono fratelli (non uno dentro l'altro), quindi `--pf-ox`/`--pf-oy` stanno su :root (li
   scrive `setOrigin` in portfolio.js) e non su `.pf`. */
body.is-portfolio #brand-mark {
  perspective: calc(var(--pf-persp) * 1px);
  perspective-origin: var(--pf-ox, 50%) var(--pf-oy, 50%);
}
body.is-portfolio .bm { -webkit-backface-visibility: hidden; backface-visibility: hidden; }

/* ---- Titolo (stato mobile: nel flusso, sopra il corpo) -------------------------------- */
.pf-title {
  margin: 0 0 4vh;
  font-family: "Helvetica Neue", Arial, sans-serif; font-weight: 700; line-height: 1;
  font-size: var(--fs, clamp(28px, 10vw, 46px));
  letter-spacing: 0.01em; text-transform: uppercase; color: var(--pf-ink);
}

/* ---- Corpo: due colonne ---------------------------------------------------------------
   La lista (più stretta) e la copertina, affiancate. `position: absolute; inset: 0` perché
   il titolo mobile, quando è nel flusso, deve scorrere SOPRA senza che il body gli lasci
   un buco fisso — su desktop il titolo è `position: fixed` (blocco sotto) e non conta nel
   flusso di .pf, quindi il corpo può occupare l'intero riquadro. */
.pf-body {
  position: absolute; inset: 0;
  display: grid;
  grid-template-columns: 0.85fr 1fr;
  gap: 4vw;
  padding: var(--pf-top) var(--pf-pad) 6vh;
}

/* ---- Lista dei titoli -------------------------------------------------------------------
   `scroll-snap-type` fa la centratura VERA: il JS (portfolio.js) osserva soltanto quale
   riga è più vicina al centro, non chiama mai `scrollTo` per animare — su iOS l'inerzia del
   tocco non si interrompe, e le due cose si contenderebbero lo scroll (stessa regola della
   home, vedi HOME.md). Gli spacer di testa/coda hanno l'altezza che JS misura e applica
   inline: le percentuali di padding-top/bottom si risolvono sulla LARGHEZZA del
   contenitore, non l'altezza, quindi non possono farlo da sole. */
.pf-list {
  position: relative;
  height: 100%;
  overflow-y: auto; overflow-x: hidden;
  scrollbar-width: none; -ms-overflow-style: none;
  scroll-snap-type: y mandatory;
}
.pf-list::-webkit-scrollbar { width: 0; height: 0; display: none; }

.pf-item {
  scroll-snap-align: center;
  padding: 1.4vh 0;
  display: flex; align-items: center; gap: 14px;
  font: 500 clamp(18px, 2.4vw, 34px)/1.2 "Helvetica Neue", Arial, sans-serif;
  text-transform: uppercase; letter-spacing: 0.01em;
  opacity: 0.32; filter: blur(2px);
  transition: opacity 320ms ease, filter 320ms ease;
  cursor: pointer;
}
/* Riga unica: un titolo che andasse a capo romperebbe il conto dell'altezza (uniforme) su
   cui si basano gli spacer — vedi PORTFOLIO.md. L'ellissi sta sul testo, non su `.pf-item`,
   da quando quest'ultimo è diventato un contenitore flex con la freccia accanto. */
.pf-item-t { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.pf-item.is-active { opacity: 1; filter: none; }
.pf-item-thumb { display: none; }   /* solo mobile, vedi sotto */

/* Freccia "apri l'overlay": SOLO sulla riga già attiva, SOLO al passaggio del mouse (vedi
   il gate desktop più sotto) — a riposo non c'è, quindi non promette un click che sulle
   righe non attive farebbe solo scorrere. Entra da sotto con un'unica transizione
   opacity+translateY, la stessa curva delle altre entrate a stagger del sito. */
.pf-item-open {
  flex: none;
  display: none;   /* riacceso solo su desktop, vedi sotto — niente hover su touch */
  align-items: center; justify-content: center;
  width: clamp(28px, 2.6vw, 38px); height: clamp(28px, 2.6vw, 38px);
  border-radius: 50%;
  background: #111; color: #fff;
  opacity: 0; transform: translateY(60%);
  transition: opacity 280ms cubic-bezier(0.16,1,0.3,1), transform 320ms cubic-bezier(0.16,1,0.3,1);
}
.pf-item-open svg { width: 46%; height: 46%; }

.pf-status {
  margin: 0; padding: 2vh 0;
  font: 500 11px/1.8 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.1em; opacity: 0.55;
}

/* ---- Copertina --------------------------------------------------------------------------
   Riquadro a dimensione FISSA: `object-fit: contain` adatta l'immagine dentro senza mai
   ritagliarla né deformarla, qualunque sia il suo formato nativo — le proporzioni restano
   quelle vere anche ridimensionando la finestra, perché il ricalcolo lo fa il browser a
   ogni layout, non un valore congelato in JS. Per lo stesso motivo lo schema non ha
   bisogno di w/h per queste foto (vedi ADMIN.md/site.ts): l'ingombro del riquadro non
   dipende dall'immagine, quindi non c'è un layout da riservare in anticipo. Le immagini
   sono impilate (stessa tecnica di "reach-roll" sulla home): una sola ha `.is-on` alla
   volta, le altre restano a `opacity: 0` pronte a entrare senza un nuovo `src`. */
.pf-cover { position: relative; overflow: hidden; border-radius: 2px; cursor: pointer; }
.pf-cover-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: contain;
  opacity: 0;
  transition: opacity 500ms ease;
}
.pf-cover-img.is-on { opacity: 1; }

/* ---- Mobile -----------------------------------------------------------------------------
   Niente due colonne su uno schermo stretto: la lista diventa un flusso di card (titolo +
   miniatura), senza stato "attivo" né centratura — vedi PORTFOLIO.md sul perché. */
@media (max-width: 900px) {
  .pf-body { position: static; display: block; padding: 5vh 5vw 4vh; height: 100%; overflow-y: auto; }
  .pf-list { height: auto; overflow: visible; scroll-snap-type: none; }
  .pf-pad-top, .pf-pad-bottom { display: none; }
  .pf-item {
    gap: 4vw;
    padding: 3vh 0; border-bottom: 1px solid rgba(0,0,0,.08);
    opacity: 1; filter: none;
  }
  .pf-item-t { white-space: normal; overflow: visible; text-overflow: clip; }
  .pf-item-thumb { display: block; width: 22vw; height: 22vw; object-fit: contain; flex: none; }
  .pf-cover { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .pf-item, .pf-cover-img, .pf-item-open { transition: none !important; }
}

/* ---- Corsia di sinistra (desktop) -------------------------------------------------------
   Il titolo passa FISSO in alto a sinistra, fuori dal flusso di `.pf-body` (che quindi può
   occupare l'intero riquadro anche qui, senza il vuoto che lascerebbe un titolo in flusso). */
@media (min-width: 901px) {
  .pf-title {
    position: fixed; z-index: 3;
    left: var(--pf-pad);
    top: calc(var(--pf-top) - 0.17em);   /* stessa correzione di cap band delle gallery */
    margin: 0; overflow-wrap: break-word;
    /* ESPLICITA e non "auto": `fitTitle` (title-swap.js) misura questa larghezza per
       scalare il corpo, e un `position: fixed` senza `width` si stringerebbe al contenuto
       — la misura diventerebbe circolare (il contenuto decide la larghezza che decide il
       corpo del contenuto). Stessa ragione per cui .rg-title in gallery.css usa
       `var(--rg-col)` invece di lasciarla implicita. */
    width: 30vw;
    font-size: var(--fs, clamp(17px, 1.6vw, 28px)); line-height: 1.02;
    color: var(--pf-ink);
    height: auto; clip: auto; overflow: visible; white-space: normal;
  }

  .pf-item-open { display: flex; }
}

/* Solo con un puntatore vero: su touch il tap sintetizza un mouseenter che non se ne va
   più (stessa cautela di gallery.js per il titolo, e di portfolio-overlay.js per il tilt
   delle card) — la freccia resterebbe accesa dopo il tocco invece di essere un hint
   sul passaggio del mouse. */
@media (min-width: 901px) and (hover: hover) and (pointer: fine) {
  .pf-item.is-active:hover .pf-item-open,
  .pf-item.is-active:focus-visible .pf-item-open {
    opacity: 1; transform: none;
  }
}
