/* ------------------------------------------------------------------
   Foto-Portfolio — One Pager
   Viel Weißraum, Bilder in unterschiedlichen Größen, Parallax-Versatz.
   Layout pro Bild über Custom Properties im HTML:
     --col   Startspalte im 12er-Raster (1–12)
     --span  Breite in Spalten
     --ar    Seitenverhältnis (z. B. 2/3, 3/2, 1/1, 16/9, 4/5)
     --mt    Abstand nach oben (vh) = Weißraum
     --speed Parallax-Faktor (negativ = läuft langsamer/zurück)
   ------------------------------------------------------------------ */

:root {
  --bg: #000;
  --gutter: clamp(1.5rem, 4vw, 5rem);
  --page-max: 1600px;
  /* Versatz als Anteil der Viewport-Höhe — so bleibt das Verhältnis von
     Weißraum (in vh) zu Bewegung auf jedem Bildschirm gleich. */
  --parallax-amp: 0.40;
  --zoom-ease: cubic-bezier(.19,.87,.36,1);
}

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

html {
  background: var(--bg);
  /* Kein scroll-behavior:smooth — würde mit der Parallax-Interpolation kämpfen */
}

body {
  margin: 0;
  background: var(--bg);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* --- Logo --------------------------------------------------------- */

.logo {
  position: fixed;
  top: clamp(1.25rem, 3vw, 2.5rem);
  left: clamp(1.25rem, 3vw, 2.5rem);
  z-index: 20;
  display: block;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: clamp(0.8rem, 1.6vw, 1.05rem);
  line-height: 1.35;
  letter-spacing: 0.05em;
  text-decoration: none;
  text-transform: uppercase;
  /* Invertiert sich gegen den Untergrund: dunkel auf hellem Weißraum,
     hell sobald ein Foto darunter liegt. */
  color: #fff;
  mix-blend-mode: difference;
  opacity: .9;
  transition: opacity .4s ease;
}

.logo:hover { opacity: 1; }

/* Direkt unter dem zweizeiligen Logo, gleiche linke Kante, senkrecht
   gestapelt. mix-blend-mode sitzt bewusst auf .sections selbst (dem
   position:fixed-Element), nicht auf den einzelnen <a> darunter — in
   Chrome hat der Blend-Modus auf einem normal positionierten Kind
   sonst keine Wirkung und der Text bleibt praktisch unsichtbar. */
.sections {
  position: fixed;
  top: clamp(4.5rem, 9vw, 6.25rem);
  left: clamp(1.25rem, 3vw, 2.5rem);
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.35em;
  color: #fff;
  mix-blend-mode: difference;
}

.sections a {
  display: block;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: clamp(0.75rem, 1.3vw, 0.9rem);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
  opacity: .7;
  transition: opacity .3s ease;
}

/* Höhere Spezifität als .sections a nötig (Klasse+Element schlägt
   sonst die browsereigene [hidden]{display:none}-Regel) — sonst bleibt
   ein ausgeblendeter Link trotz hidden-Attribut sichtbar. */
.sections a[hidden] { display: none; }

.sections a:hover { opacity: 1; }

.imprint {
  position: fixed;
  bottom: clamp(1.25rem, 3vw, 2.5rem);
  left: clamp(1.25rem, 3vw, 2.5rem);
  z-index: 20;
  display: block;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: clamp(0.7rem, 1.1vw, 0.8rem);
  letter-spacing: 0.05em;
  text-decoration: none;
  text-transform: uppercase;
  /* Gleicher Invert-Trick wie beim Logo, nur unauffälliger platziert */
  color: #fff;
  mix-blend-mode: difference;
  opacity: .55;
  transition: opacity .4s ease;
}

.imprint:hover { opacity: .9; }

/* --- Raster ------------------------------------------------------- */

.gallery {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  align-items: start;          /* Figuren nicht auf Zeilenhöhe strecken */
  column-gap: var(--gutter);
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 18vh var(--gutter) 26vh;
}

.shot {
  grid-column: var(--col) / span var(--span);
  margin: 0;
  margin-top: var(--mt);
  /* Reihen dürfen sich nicht gegenseitig blockieren: jedes Bild bekommt
     eine eigene implizite Zeile, der Versatz entsteht über --mt. */
  will-change: transform;
  transform: translate3d(0, var(--y, 0px), 0);
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--ar);
  object-fit: cover;
  background: #141414;

  /* Sanftes Einblenden beim Eintreten in den Viewport */
  opacity: 0;
  transform: scale(1.015);
  transition: opacity 1.1s cubic-bezier(.22,.61,.36,1),
              transform 1.4s cubic-bezier(.22,.61,.36,1);
}

.shot.is-visible img {
  opacity: 1;
  transform: scale(1);
}

.shot img { cursor: zoom-in; }

/* Das Original bleibt beim Zoom als Lücke stehen */
.shot.is-zoomed img { visibility: hidden; }

/* --- Zoom ---------------------------------------------------------
   Kein Overlay-Kasten, keine Bedienleiste: das Bild wächst aus seiner
   Position heraus auf, der Rest der Seite tritt in den Hintergrund.
   ------------------------------------------------------------------ */

.zoom-veil {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--bg);
  opacity: 0;
  cursor: zoom-out;
  touch-action: none;      /* Wischen soll nicht die Seite bewegen */
  transition: opacity .5s ease;
}

.zoom-veil.is-open { opacity: .97; }

.zoom-clone {
  position: fixed;
  z-index: 41;
  margin: 0;
  object-fit: cover;      /* öffnet den Beschnitt beim Aufziehen */
  cursor: grab;           /* ziehen zum Blättern, klicken zum Schließen */
  touch-action: none;
  user-select: none;
  -webkit-user-drag: none;
  will-change: top, left, width, height, transform;
  transition: top .62s var(--zoom-ease),
              left .62s var(--zoom-ease),
              width .62s var(--zoom-ease),
              height .62s var(--zoom-ease),
              transform .45s var(--zoom-ease),
              opacity .45s ease;
}

/* Startzustand beim Blättern: erst setzen, dann animieren */
.zoom-clone.is-entering { transition: none; }

/* Am Finger/Cursor hängend — folgt ohne Verzögerung */
.zoom-clone.is-dragging { transition: none; cursor: grabbing; }

/* Beim Zurückfahren nichts mehr abfangen — die Seite ist sofort wieder klickbar */
.zoom-veil.is-closing, .zoom-clone.is-closing { pointer-events: none; }

/* Während des Zooms tritt das Logo zurück */
body.is-zooming .logo,
body.is-zooming .imprint,
body.is-zooming .sections { opacity: 0; pointer-events: none; }

/* --- Tablet ------------------------------------------------------- */

@media (min-width: 641px) and (max-width: 1024px) {
  :root { --parallax-amp: 0.12; }

  .gallery { padding-top: 12vh; padding-bottom: 18vh; }

  /* Bilder werden breiter, die Asymmetrie bleibt über einen festen
     Rhythmus erhalten (Grid-Linien dürfen kein calc() sein). */
  .shot                 { grid-column: 2 / span 8;  margin-top: calc(var(--mt) * 1.6); }
  .shot:nth-child(3n)   { grid-column: 4 / span 9; }
  .shot:nth-child(4n+1) { grid-column: 1 / span 7; }
  .shot:nth-child(5n)   { grid-column: 5 / span 8; }
}

/* --- Mobil -------------------------------------------------------- */

@media (max-width: 640px) {
  /* Kein Parallax-Versatz und kein asymmetrisches Raster auf Mobil:
     eine Spalte, gleicher Abstand, immer volle Breite. Ruhiger beim
     Scrollen mit dem Daumen, und jedes Bild bekommt genug Platz für
     sein eigenes Format statt beschnitten zu werden. */
  .gallery {
    /* minmax(0, 1fr) statt 1fr: ein 1fr-Track schrumpft sonst nicht unter
       die "bevorzugte" Breite seines Inhalts — ein Bild mit
       aspect-ratio:auto bringt seine volle natürliche Pixelbreite als
       Wunschgröße mit und würde die Spalte (und die Seite) aufsprengen. */
    grid-template-columns: minmax(0, 1fr);
    row-gap: 7vh;
    padding: 8vh 1.25rem 12vh;
  }

  .shot {
    grid-column: 1;
    min-width: 0;                /* dieselbe Falle auch auf Item-Ebene */
    margin-top: 0;              /* Abstand kommt einheitlich vom row-gap */
    transform: none !important; /* JS setzt --y weiter, hier ohne Wirkung */
  }

  .shot img {
    aspect-ratio: auto;   /* zeigt das ganze Bild im Originalformat … */
    object-fit: contain;  /* … statt es auf --ar zurechtzuschneiden    */
  }
}

/* --- Barrierefreiheit --------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .shot { transform: none !important; }
  .zoom-clone, .zoom-veil { transition: none !important; }
  .shot img {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
