/* =========================================================================
   Plenty-of Studio — one-page site
   Le misure di riferimento vengono dal mockup Figma a 1440px (desktop) e
   402px (mobile): margini 25px, colonne 328.5px, gap 26px, nav 44px di
   altezza. Qui sono espresse in vw/clamp per scalare oltre quelle larghezze.
   ========================================================================= */

/* Archivo variabile, servito dalla cartella assets: nessuna richiesta a
   Google Fonts, quindi nessuna dipendenza esterna e nessun tracciamento. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('../assets/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('../assets/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Il rombo ◊ delle caption non sta in nessuno dei due sottoinsiemi latini:
   senza questo file cadrebbe su un font di sistema, con peso e dimensione
   diversi da caption a caption a seconda del sistema operativo. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('../assets/fonts/archivo-lozenge.woff2') format('woff2');
  unicode-range: U+25CA;
}

/* ---------- token ------------------------------------------------------ */

:root {
  /* Palette: bianco caldo e nero morbido, nessun accento (brief §9). */
  --paper: #faf9f6;
  --ink: #1a1a18;
  /* Grigio per il testo secondario. L'opacità è tarata sul contrasto: a
     0.55 sulla carta si scendeva a 3.7:1, sotto la soglia AA per il testo
     normale; a 0.68 si sta sopra 5:1 restando visibilmente più tenue. */
  --ink-soft: rgba(26, 26, 24, 0.68);
  --pill-bg: #e8e7e3;

  /* 25px a 1440px di viewport. */
  --gutter: clamp(20px, 1.74vw, 34px);
  /* 26px a 1440px: il gap fra le colonne del mosaico. */
  --grid-gap: clamp(14px, 1.81vw, 36px);

  --fs-word: clamp(14px, 1.67vw, 30px);   /* ART / STUDIO — 24px a 1440 */
  --fs-body: clamp(19px, 1.39vw, 26px);   /* bio, commissions — 20px a 1440 */
  --fs-caption: clamp(13px, 0.97vw, 17px);/* caption opere — 14px a 1440 */
  --fs-nav: clamp(14px, 1.32vw, 21px);    /* voci nav — 19px a 1440 */
  --fs-foot: clamp(15px, 1.25vw, 22px);   /* footer — 18px a 1440 */

  /* Geometria della nav flottante, in variabili perché anche il footer ci
     si allinea (vedi il padding di body). */
  --pill-offset: clamp(18px, 2.2vw, 40px);  /* distanza dal fondo pagina */
  --pill-height: clamp(44px, 3.05vw, 60px); /* 44px a 1440 */

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  color-scheme: light;
}

/* ---------- reset ------------------------------------------------------ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* La nav flottante sta in basso: lo scroll ad ancora si ferma un po'
     prima, così il titolo della sezione non finisce sotto il bordo. */
  scroll-padding-top: clamp(24px, 4vw, 64px);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Archivo', -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Spazio in fondo alla pagina. Su desktop è calcolato perché, arrivati in
     fondo allo scroll, l'ultima riga del footer risulti sulla stessa linea
     della nav flottante: centro della pillola (offset + metà altezza) meno
     la mezza altezza della riga di testo (~0.6em del corpo del footer).
     La nav è centrata orizzontalmente e i due testi stanno ai lati, quindi
     non si sovrappongono. Su mobile la pillola è larga quanto la pagina e
     serve invece parecchia aria: vedi la media query. */
  padding-bottom: calc(
    var(--pill-offset) + var(--pill-height) / 2 - 0.6 * var(--fs-foot)
  );
}

img { display: block; max-width: 100%; height: auto; }

p { margin: 0; }
h1, h2 { margin: 0; font-size: inherit; font-weight: inherit; }
ul { margin: 0; padding: 0; list-style: none; }

a { color: inherit; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -120%);
  z-index: 100;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 0 0 10px 10px;
  font-size: 15px;
  text-decoration: none;
}
.skip-link:focus-visible { transform: translate(-50%, 0); }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- header ----------------------------------------------------- */

.masthead {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: var(--gutter);
  padding: clamp(20px, 2.19vw, 42px) var(--gutter) 0;
}

.masthead__word {
  font-size: var(--fs-word);
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}
.masthead__word--right { text-align: right; }

.masthead__logo { line-height: 0; }
.masthead__logo img {
  width: auto;
  /* 147px di altezza a 1440px di viewport. */
  height: clamp(96px, 10.2vw, 210px);
}

/* ---------- ritmo verticale delle sezioni ------------------------------ */

.section { padding-inline: var(--gutter); }

/* logo (fine ~186px) -> testo bio (245px) nel mockup */
.bio { padding-top: clamp(38px, 4.1vw, 80px); }

/* bio (fine ~379px) -> prima caption del catalogue (509px) */
.catalogue { padding-top: clamp(64px, 9vw, 170px); }

.commissions { padding-top: clamp(90px, 11vw, 210px); }

/* ---------- bio -------------------------------------------------------- */

.bio__text {
  /* ~505px a 1440px, ma legato alla dimensione del testo così la misura
     di riga resta comoda a qualsiasi scala. */
  max-width: 26em;
  text-wrap: pretty;
}

/* ---------- catalogue -------------------------------------------------- */

.catalogue__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--grid-gap);
  align-items: start;
}

.catalogue__col {
  display: flex;
  flex-direction: column;
}

/* Sfalsamento verticale delle colonne (effetto mosaico del mockup). Le
   percentuali di padding e margin si risolvono sulla larghezza della
   colonna, quindi tutta la spaziatura del mosaico resta proporzionata a
   ogni viewport senza altre media query. (Un `gap` in % non funzionerebbe:
   in un flex verticale ad altezza automatica varrebbe zero.) */
.catalogue__col:nth-child(2) { padding-top: 37%; }
.catalogue__col:nth-child(4) { padding-top: 100%; }

.work { margin: 0; }
.catalogue__col > .work + .work { margin-top: 34%; }

/* Variazione sul secondo elemento di ogni colonna, per evitare che le opere
   si allineino su righe leggibili come griglia. */
.catalogue__col > .work:nth-child(2) { margin-top: 48%; }

.work__caption {
  font-size: var(--fs-caption);
  font-weight: 500; /* Medium */
  line-height: 1.2;
  /* 19.4px fra caption e immagine a 1440px. */
  margin-bottom: clamp(10px, 1.35vw, 26px);
}

.work__frame {
  aspect-ratio: 1081 / 1351;
  overflow: hidden;
  background: rgba(26, 26, 24, 0.04);
}

.work__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Comparsa morbida: parte solo se il JS è attivo, altrimenti le immagini
   restano semplicemente visibili. */
.js .work {
  opacity: 0;
  transform: translateY(14px);
}
.js .work.is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

/* ---------- commissions ------------------------------------------------ */

.commissions__text {
  max-width: 26em;
  text-wrap: pretty;
}

.commissions__cta {
  margin-top: clamp(24px, 2.6vw, 50px);
  font-size: clamp(26px, 3.05vw, 58px);
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.commissions__cta a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  transition: background-size 0.4s var(--ease);
}
.commissions__cta a:hover { background-size: 0 1px; }

.commissions__alt {
  margin-top: clamp(18px, 1.8vw, 34px);
  color: var(--ink-soft);
}
.commissions__alt a {
  color: var(--ink);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

/* ---------- nav a pillola ---------------------------------------------- */

.pillnav {
  position: fixed;
  left: 50%;
  bottom: var(--pill-offset);
  z-index: 20;
  transform: translateX(-50%);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.pillnav__pill {
  position: relative;
  display: flex;
  border-radius: 10px;
  background: var(--pill-bg);
  box-shadow: 0 2px 24px rgba(26, 26, 24, 0.12);
}

/* Su schermi che lo supportano la pillola resta leggibile anche sopra le
   opere, senza aggiungere un bordo. */
@supports (backdrop-filter: blur(12px)) {
  .pillnav__pill {
    background: rgba(232, 231, 227, 0.86);
    backdrop-filter: blur(14px) saturate(1.4);
  }
}

.pillnav__marker {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 0;
  border-radius: 10px;
  background: var(--ink);
  transition: transform 0.42s var(--ease), width 0.42s var(--ease);
  will-change: transform, width;
}

.pillnav__list { display: flex; }

/* Copia delle etichette in colore carta, sovrapposta e ritagliata esattamente
   sulla pillola scura: così l'etichetta attiva diventa chiara nello stesso
   istante in cui la pillola la copre, invece di sbiadire per conto suo e
   restare illeggibile per mezzo secondo durante lo scorrimento.
   Il layer è costruito dal JS clonando la lista (vedi js/main.js). */
.pillnav__labels {
  position: absolute;
  inset: 0;
  z-index: 2;
  color: var(--paper);
  pointer-events: none;
  clip-path: inset(0 100% 0 0 round 10px);
  transition: clip-path 0.42s var(--ease);
}
.pillnav__labels .pillnav__link { color: inherit; }

.pillnav__link {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--pill-height);
  padding-inline: clamp(20px, 2.8vw, 56px);
  border-radius: 10px;
  font-size: var(--fs-nav);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  color: var(--ink);
}

/* Finché il JS non ha misurato la pillola, evidenziamo la voce attiva con
   uno sfondo pieno: senza JS la nav resta comunque leggibile e usabile. */
.pillnav__pill:not(.is-measured) .pillnav__link[aria-current='true'] {
  background: var(--ink);
  color: var(--paper);
}

/* ---------- footer ----------------------------------------------------- */

.colophon {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: var(--gutter);
  padding: clamp(120px, 14vw, 280px) var(--gutter) 0;
  font-size: var(--fs-foot);
}

.colophon__social { line-height: 1.2; }
.colophon__label { display: block; color: var(--ink-soft); }
.colophon__social a {
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
.colophon__copy { grid-column: 2; text-align: right; }

/* ---------- pagina 404 -------------------------------------------------- */

/* Qui non c'è la nav flottante, quindi non serve lo spazio in fondo. */
.page-404 { padding-bottom: 0; }

.notfound {
  padding: clamp(50px, 8vw, 130px) var(--gutter) clamp(90px, 16vw, 220px);
}

.notfound__code {
  font-size: clamp(52px, 7vw, 120px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.03em;
}

.notfound__text {
  max-width: 26em;
  margin-top: clamp(18px, 2vw, 36px);
  text-wrap: pretty;
}

.notfound__back { margin-top: clamp(24px, 2.6vw, 46px); }
.notfound__back a {
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

/* ---------- mobile ----------------------------------------------------- */

@media (max-width: 899px) {

  :root {
    --gutter: clamp(20px, 8.1vw, 34px); /* 32.7px a 402px */
    --fs-word: clamp(12px, 3vw, 15px);
    --fs-body: clamp(17px, 4.98vw, 21px); /* 20px a 402px */
    --fs-caption: clamp(13px, 3.48vw, 15px);
    --fs-foot: clamp(15px, 4vw, 18px);
    --pill-height: 46px; /* bersaglio comodo al tocco */
  }

  /* Qui la pillola è larga quanto la pagina: il footer non le si può
     affiancare, deve restarci sopra con un margine buono. */
  body { padding-bottom: clamp(96px, 26vw, 140px); }

  .masthead {
    grid-template-columns: auto auto;
    justify-content: center;
    column-gap: clamp(36px, 14vw, 60px);
    row-gap: clamp(4px, 1vw, 10px);
    padding-top: clamp(18px, 5vw, 28px);
  }
  .masthead__word--left  { grid-column: 1; grid-row: 1; text-align: center; }
  .masthead__word--right { grid-column: 2; grid-row: 1; text-align: center; }
  .masthead__logo {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: center;
  }
  .masthead__logo img { height: clamp(110px, 36.6vw, 190px); }

  .bio { padding-top: clamp(40px, 11vw, 70px); }
  .catalogue { padding-top: clamp(70px, 24vw, 140px); }
  .commissions { padding-top: clamp(70px, 22vw, 130px); }

  /* Le colonne spariscono come contenitori: le opere tornano in un'unica
     sequenza, riordinata in modo da rispettare l'ordine del catalogo. */
  .catalogue__grid {
    display: flex;
    flex-direction: column;
    gap: clamp(60px, 23vw, 110px);
    /* Obbligatorio: l'`align-items: start` della griglia desktop agisce
       sull'asse verticale, ma in un flex in colonna agisce su quello
       orizzontale e lascerebbe le opere larghe quanto la loro caption. */
    align-items: stretch;
  }
  .catalogue__col { display: contents; }
  .catalogue__col > .work:nth-child(1) { order: var(--col); }
  .catalogue__col > .work:nth-child(2) { order: calc(var(--col) + 4); }
  .catalogue__col > .work:nth-child(3) { order: calc(var(--col) + 8); }
  .catalogue__col > .work,
  .catalogue__col > .work + .work { margin-top: 0; }

  .work__caption { margin-bottom: clamp(12px, 4.8vw, 22px); }

  .commissions__cta { font-size: clamp(24px, 7.2vw, 40px); }

  /* Pillola quasi a tutta larghezza, come nel mockup mobile. */
  .pillnav {
    left: var(--gutter);
    right: var(--gutter);
    transform: none;
  }
  .pillnav__pill { display: block; }
  .pillnav__list { justify-content: space-between; }
  .pillnav__list li { flex: 1 1 0; }
  .pillnav__link {
    padding-inline: 4px;
    font-size: clamp(13px, 3.5vw, 15px);
  }

  .colophon {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    row-gap: clamp(28px, 9vw, 44px);
    padding-top: clamp(90px, 28vw, 160px);
  }
  .colophon__copy { grid-column: 1; text-align: center; }
}

/* ---------- preferenze di movimento ------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  .js .work { opacity: 1; transform: none; }
}

/* ---------- stampa ------------------------------------------------------ */

@media print {
  .pillnav, .skip-link { display: none; }
  .js .work { opacity: 1; transform: none; }
  body { padding-bottom: 0; }
}
