/* =========================================================
   Photo stack / carousel — "Film" / "Music" (About me)
   Fonte: assets/pagine/{S,Tablet,L,XL}.png
   Token: tokens.css
   ========================================================= */

:root {
  --stack-duration: 420ms;
  /* Curva con un piccolo overshoot elastico — la stessa firma "liquid glass"
     dell'indicator della navbar. Prima usavo una curva senza rimbalzo: più
     sicura ma meno "Apple". Qui non c'è rischio di sforare un contenitore
     (a differenza della navbar), quindi il rimbalzo può restare. */
  --stack-ease: cubic-bezier(0.34, 1.56, 0.64, 1);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-family-base);
}

.photo-carousel-demo {
  min-height: 100vh;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  background: var(--color-grey);
  padding: var(--grid-margin);
}

/* ---------- Stack ---------- */

.photo-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.photo-stack__frames {
  position: relative;
  width: 220px;
  height: 300px;
  margin-bottom: var(--space-6); /* spazio per le rotazioni che sporgono */
}

/* Music: copertine quadrate, non rettangolari come i poster dei film. */
.photo-stack--square .photo-stack__frames {
  width: 260px;
  height: 260px;
}

.photo-stack__frame {
  position: absolute;
  inset: 0;
  background: var(--color-white);
  border-radius: 14px;
  box-shadow: var(--shadow-card);
  padding: var(--space-2);
  /* padding/border-radius: js/about-focus.js li riscrive inline
     durante l'ingrandimento (vedi applicaCompensazioneBordo), per
     tenere il "passe-partout" bianco alla stessa larghezza reale a
     qualunque scala — stessa correzione dello stroke di .about__photo,
     riusata qui perche' e' lo stesso difetto. Transition qui, non
     inline, cosi' l'apertura del focus non deve toccare la transition
     shorthand del frame (che serve anche allo shuffle dello stack). */
  transition: transform var(--stack-duration) var(--stack-ease), opacity var(--stack-duration) var(--stack-ease), z-index 0s, padding var(--stack-duration) var(--stack-ease), border-radius var(--stack-duration) var(--stack-ease);
}

.photo-stack__placeholder {
  width: 100%;
  height: 100%;
  border-radius: 10px;
  background: var(--color-grey-2);
  transition: border-radius var(--stack-duration) var(--stack-ease);
}

.photo-stack__photo {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 10px;
  object-fit: cover;
  transition: border-radius var(--stack-duration) var(--stack-ease);
  /* draggable="false" nell'HTML basta ovunque tranne Safari, che ignora
     l'attributo e avvia comunque il drag nativo dell'immagine — per
     questo serve anche qui, altrimenti il drag custom dello stack
     (about-me.js) non riceve mai il pointermove. */
  -webkit-user-drag: none;
  user-select: none;
}

/* Rotazione/offset/scala per posizione nello stack: 0 = in cima, via via più
   indietro e più piccola (dà profondità, come se le foto si allontanassero).
   Nessuna reference esatta sugli angoli — stimati dal mockup. */
.photo-stack__frame[data-slot="0"] {
  transform: rotate(-4deg) scale(1);
  z-index: 3;
}
.photo-stack__frame[data-slot="1"] {
  transform: rotate(6deg) translate(8px, 6px) scale(0.96);
  z-index: 2;
}
.photo-stack__frame[data-slot="2"] {
  transform: rotate(-10deg) translate(-10px, 10px) scale(0.92);
  z-index: 1;
}

/* Oltre le prime 3 posizioni la pila ne mostra sempre e solo 3: gli slot
   in piu' (usati quando le foto nello stack sono >3, es. i 6 poster del
   carosello Film) restano dietro, invisibili — cosi' cycle() puo' girare
   fra tutte le foto senza che il fan-out ne mostri piu' di 3 insieme. */
.photo-stack__frame[data-slot="3"],
.photo-stack__frame[data-slot="4"],
.photo-stack__frame[data-slot="5"] {
  transform: rotate(-10deg) translate(-10px, 10px) scale(0.88);
  opacity: 0;
  z-index: 0;
  pointer-events: none;
}

/* Ogni foto ha il proprio play/seek (ogni slide è un brano diverso) ma
   sono cliccabili/visibili solo su quella in primo piano. */
.photo-stack__frame:not([data-slot="0"]) .photo-stack__play,
.photo-stack__frame:not([data-slot="0"]) .photo-stack__seek {
  opacity: 0;
  pointer-events: none;
}

.photo-stack__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  background: var(--color-white);
  color: var(--color-black);
  box-shadow: var(--shadow-card);
  transition: transform 160ms var(--stack-ease), opacity var(--stack-duration) var(--stack-ease);
}

/* Le due icone si sovrappongono nello stesso posto: cambiare brano cambia
   quale sta sopra invece di sostituire il markup, cosi' il passaggio
   play/pausa e' una dissolvenza invece di uno scatto.

   Centrate con top/left/transform, NON con inset:0 — inset:0 su un <svg>
   ne stira il viewBox 20x20 fino a riempire l'intero bottone da 44px
   invece di lasciarlo alla sua dimensione, che e' il difetto "scalato
   strano" segnalato: l'icona cresceva a coprire il cerchio invece di
   restarci dentro piccola e centrata. */
.photo-stack__play-icon,
.photo-stack__pause-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transition: opacity 160ms var(--stack-ease), transform 160ms var(--stack-ease);
}

.photo-stack__play-icon {
  /* Centrata geometricamente, senza nudge ottici: su questo triangolo
     (24px, non piu' 20) uno scostamento manuale leggeva come decentrata
     invece che come correzione. */
  transform: translate(-50%, -50%);
}

.photo-stack__pause-icon {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.6);
}

.photo-stack__play.is-playing .photo-stack__play-icon {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.6);
}

.photo-stack__play.is-playing .photo-stack__pause-icon {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

@media (hover: hover) and (pointer: fine) {
  .photo-stack__play:hover {
    transform: translate(-50%, -50%) scale(1.08);
  }
}

.photo-stack__play:active {
  transform: translate(-50%, -50%) scale(0.94);
}

/* ---------- Seek ----------
   Prima era un oggetto inventato a parte (bordo bianco/nero traslucido
   sopra la foto) e si vedeva: sembrava incollata li', non parte del
   componente. Rifatta riusando lo stesso materiale di .photo-stack__nav
   e .photo-stack__label — pillola bianca piena, ombra, icone nere — cosi'
   la seek si legge come lo stesso linguaggio visivo, non come un widget a
   se'. Il bianco pieno risolve anche il contrasto (1.4.11) senza bisogno
   di bordi o sfondi scuri posticci: qualunque sia la copertina sotto, la
   pillola e' sempre bianca. Il bersaglio di 24px (2.5.8) resta, e il
   margine e' lo stesso (var(--space-4)) su tutti e tre i lati liberi —
   prima sotto era var(--space-2), la meta' dei lati, e la sfumatura di
   --shadow-card (40px di blur) arrivava a toccare il bordo della card. */
.photo-stack__seek {
  position: absolute;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  width: calc(100% - var(--space-4) * 2);
  height: 24px;
  margin: 0;
  padding: 0 var(--space-2);
  -webkit-appearance: none;
  appearance: none;
  background: var(--color-white);
  border-radius: 999px;
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: opacity var(--stack-duration) var(--stack-ease);
}

.photo-stack__seek::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    var(--color-black) var(--seek-pct, 0%),
    var(--color-grey-2) var(--seek-pct, 0%)
  );
}

.photo-stack__seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 12px;
  height: 12px;
  margin-top: -4px;
  border-radius: 50%;
  background: var(--color-black);
  transition: transform 120ms var(--stack-ease);
}

.photo-stack__seek::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    var(--color-black) var(--seek-pct, 0%),
    var(--color-grey-2) var(--seek-pct, 0%)
  );
}

.photo-stack__seek::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border: none;
  border-radius: 50%;
  background: var(--color-black);
  transition: transform 120ms var(--stack-ease);
}

@media (hover: hover) and (pointer: fine) {
  .photo-stack__seek:hover::-webkit-slider-thumb,
  .photo-stack__seek:hover::-moz-range-thumb {
    transform: scale(1.25);
  }
}

.photo-stack__seek:active::-webkit-slider-thumb,
.photo-stack__seek:active::-moz-range-thumb {
  transform: scale(1.4);
}

.photo-stack__seek:focus-visible {
  outline: 2px solid var(--color-black);
  outline-offset: 2px;
}

/* ---------- Controls ---------- */

.photo-stack__controls {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.photo-stack__nav {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-white);
  color: var(--color-black);
  box-shadow: var(--shadow-card);
  transition: transform 160ms var(--stack-ease), background var(--stack-duration) ease;
}

.photo-stack__label {
  min-width: 96px;
  text-align: center;
  padding: var(--space-2) var(--space-4);
  border-radius: 999px;
  background: var(--color-white);
  color: var(--color-black);
  font-family: var(--font-family-base);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-bold);
  box-shadow: var(--shadow-card);
}

.photo-stack__counter {
  margin-left: var(--space-1);
  font-weight: var(--font-weight-regular);
  opacity: 0.55;
}

@media (hover: hover) and (pointer: fine) {
  .photo-stack__nav:hover {
    background: var(--color-grey);
  }
}

.photo-stack__nav:active {
  transform: scale(0.9);
}

@media (prefers-reduced-motion: reduce) {
  .photo-stack__frame,
  .photo-stack__nav,
  .photo-stack__play,
  .photo-stack__play-icon,
  .photo-stack__pause-icon,
  .photo-stack__seek {
    transition-duration: 1ms;
  }
}
