/* ============================================================
   KRAUTH+WERNET — photo.css
   Nur Photo-Seite-spezifische Styles.
   Wird NACH global.css geladen.
   ============================================================ */

/* ---------- LAZY LOAD — INTRO TEXT + BUTTON ---------- */
/* Intro text: line-height compress + slide on the container */
@media (min-width: 769px) {
  .intro {
    transform: translateY(15px);
  }
}

/* Intro hidden state — works independently of is-loaded */
.intro.is-hidden {
  transform: translateY(15px);
  pointer-events: none;
}
.intro.is-hidden .line {
  opacity: 0;
}
.intro.is-hidden .btn-row {
  opacity: 0;
}
.is-loading .intro {
  animation: none;
}
@keyframes intro-block-in {
  0% {
    line-height: 50px;
    transform: translateY(15px);
  }
  100% {
    line-height: 39px;
    transform: translateY(0);
  }
}

/* Each line fades in individually, staggered top to bottom via JS */
.intro p {
  visibility: hidden;
}
.intro p.line-ready {
  visibility: visible;
}
.intro .line {
  display: inline;
  opacity: 0;
  transition: opacity .8s cubic-bezier(0.16, 1, 0.3, 1);
}
.intro .line.is-visible {
  opacity: 1;
}
/* Highlight button: simple fade in after text is done */
.intro .btn-row {
  opacity: 0;
  animation: fade-in-btn 1s cubic-bezier(0.16, 1, 0.3, 1) 2.5s forwards;
}
.is-loading .intro .btn-row {
  animation: none;
}
@keyframes fade-in-btn {
  to { opacity: 1; }
}

/* After initial load, remove keyframe animations so transitions can take over */
.is-loaded .intro,
.is-loaded .intro .btn-row {
  animation: none;
}
.is-loaded .intro:not(.is-hidden) .btn-row {
  opacity: 1;
}

/* Scroll-driven exit: mirrors the initial load animation in reverse */
.is-loaded .intro {
  transition: transform 3s cubic-bezier(0.05, 0.95, 0.15, 1);
}
.is-loaded .intro p {
  transition: line-height 3s cubic-bezier(0.05, 0.95, 0.15, 1);
}
.is-loaded .intro .line {
  transition: opacity 1.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.is-loaded .intro .btn-row {
  transition: opacity 1s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Hidden state: mirrors the "from" state of the initial load */
.is-loaded .intro.is-hidden {
  transform: translateY(15px);
  pointer-events: none;
  transition: transform 1.8s cubic-bezier(0.4, 0, 0.6, 1);
}
.is-loaded .intro.is-hidden p {
  line-height: 50px;
  transition: line-height 1.8s cubic-bezier(0.4, 0, 0.6, 1);
}
.is-loaded .intro.is-hidden .line {
  opacity: 0;
  transition: opacity .8s cubic-bezier(0.4, 0, 0.6, 1);
}
.is-loaded .intro.is-hidden .btn-row {
  opacity: 0;
  transition: opacity .5s cubic-bezier(0.4, 0, 0.6, 1);
}

/* ---------- INTRO POSITIONING + TYPOGRAPHY ---------- */
.intro {
  position: absolute;
  bottom: min(160px, 15vh);
  left: var(--margin-x);
  width: calc(
    ((100vw - 2 * var(--margin-x) - 2 * var(--gutter)) / 3)
    + var(--gutter)
    + ((100vw - 2 * var(--margin-x) - 2 * var(--gutter)) / 3) / 2
  );
  z-index: 1;
  font-family: var(--font-head);
  font-weight: 300;
  font-size: 36px;
  line-height: 39px;
  letter-spacing: -0.055em;
  color: var(--ink);
}
.intro p {
  margin: 0;
}
.intro p + p {
  margin-top: 39px;
}
.intro .btn-row {
  margin-top: 5px;
}

/* ---------- GALLERY ---------- */
/* Horizontal scrolling band between header and footer.
   Contains project sections, each with singles and pairs.
   Projects flow seamlessly — no visible separator. */
.gallery {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
  display: flex;
  align-items: stretch;
  padding-right: var(--margin-x);
  padding-left: calc(100vw - 126px);
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.gallery::-webkit-scrollbar { display: none; }

/* Project wrapper — invisible, just groups items for semantic structure.
   In Kirby: each project folder becomes one .project element. */
.project {
  display: contents;  /* No box of its own — children flow into .gallery flex */
}

/* ---------- GALLERY ITEMS (Singles) ---------- */
.gallery-block {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
}

.gallery-block img {
  display: block;
  height: 100%;
  width: auto;
  pointer-events: none;
  user-select: none;
  border-radius: 0;
}

/* Hero images: full gallery height */
.gallery-block--hero {
  height: 100%;
  align-self: center;
}

/* Normal single images: ~55-70% height, vertical position randomized via JS */
.gallery-block--normal {
  height: 62%;
  align-self: center;
}

/* ---------- GALLERY PAIRS ---------- */
/* Default: vertikal gestapelt (beide Querformat) */
.gallery-pair {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  height: 100%;
  position: relative;
  padding-left: 80px;
  padding-right: 80px;
}

/* Horizontale Paare: mindestens ein Hochformat → nebeneinander auf Desktop.
   Klasse wird per JS gesetzt basierend auf aspect-ratio Erkennung. */
.gallery-pair--horizontal {
  flex-direction: row;
  align-items: center;
  padding-left: 0;
  padding-right: 0;
  padding-top: 50px;
  padding-bottom: 50px;
}

.gallery-pair__top,
.gallery-pair__bottom {
  pointer-events: none;
  user-select: none;
  border-radius: 0;
  position: relative;
  flex: 0 0 auto;
  width: auto;
}

.gallery-pair__top img,
.gallery-pair__bottom img {
  display: block;
  height: 100%;
  width: auto;
  pointer-events: none;
  user-select: none;
  border-radius: 0;
}

/* Vertikale Paare: Höhen-basiert */
.gallery-pair__top {
  height: 44%;
}
.gallery-pair__bottom {
  height: 44%;
  margin-top: 20px;
}

.gallery-pair[data-primary="top"] .gallery-pair__top { height: 55%; }
.gallery-pair[data-primary="top"] .gallery-pair__bottom { height: 33%; }
.gallery-pair[data-primary="bottom"] .gallery-pair__top { height: 33%; }
.gallery-pair[data-primary="bottom"] .gallery-pair__bottom { height: 55%; }

/* Horizontale Paare: beide Bilder höhenbasiert, nebeneinander */
.gallery-pair--horizontal .gallery-pair__top,
.gallery-pair--horizontal .gallery-pair__bottom {
  height: 80%;
  width: auto;
  margin-top: 0;
}
.gallery-pair--horizontal .gallery-pair__bottom {
  margin-left: 20px;
}
.gallery-pair--horizontal[data-primary="top"] .gallery-pair__top { height: 90%; }
.gallery-pair--horizontal[data-primary="top"] .gallery-pair__bottom { height: 65%; }
.gallery-pair--horizontal[data-primary="bottom"] .gallery-pair__top { height: 65%; }
.gallery-pair--horizontal[data-primary="bottom"] .gallery-pair__bottom { height: 90%; }

/* ---------- PHOTO PAGE — SMALL DESKTOP ---------- */
/* Ab 2300px: Intro-Text in H1-Größe (50/50) damit er bei 2K+ nicht verloren wirkt */
@media (min-width: 2300px) {
  .intro {
    font-size: 50px;
    line-height: 50px;
    width: calc((100vw - 2 * var(--margin-x) - 2 * var(--gutter)) / 3);
  }
  /* Lade-Animation: proportional angepasste line-height (65→50 statt 50→39) */
  .intro {
    animation-name: intro-block-in-h1;
  }
  @keyframes intro-block-in-h1 {
    0% {
      line-height: 65px;
      transform: translateY(15px);
    }
    100% {
      line-height: 50px;
      transform: translateY(0);
    }
  }
  /* Scroll-Exit: aufgeblähter Zustand ebenfalls auf 65px */
  .is-loaded .intro.is-hidden p {
    line-height: 65px;
  }
}

@media (max-width: 1150px) and (min-width: 1025px) {
  .intro {
    /* Spans col 1 + gutter + full col 2 */
    width: calc(
      ((100vw - 2 * var(--margin-x) - 2 * var(--gutter)) / 3) * 2
      + var(--gutter)
    );
  }
}

/* ---------- PHOTO PAGE — TABLET (oberer Bereich) ---------- */
/* Zwischen 826 px und 1024 px: Intro bleibt absolut positioniert (wie Desktop),
   nur die Spaltenbreite wächst auf 2 Columns + Gutter. Kein Umbruch auf
   relative Positionierung — das verursachte zuvor einen Sprung der Headline
   und Gallery beim Überschreiten der 1024-px-Grenze. */
@media (max-width: 1024px) and (min-width: 826px) {
  .intro {
    /* Spans col 1 + gutter + col 2 (= start of col 3) */
    width: calc(
      ((100vw - 2 * var(--margin-x) - 2 * var(--gutter)) / 3) * 2
      + var(--gutter)
    );
  }
}

/* ---------- PHOTO PAGE — TABLET (unterer Bereich) ---------- */
/* Zwischen 769 px und 825 px: Intro läuft bis in die Mitte der dritten Spalte,
   damit bei schmalerem Tablet-Viewport die Headline nicht zu eng umbricht. */
@media (max-width: 825px) and (min-width: 769px) {
  .intro {
    /* Spans col 1 + gutter + col 2 + gutter + half of col 3 */
    width: calc(
      ((100vw - 2 * var(--margin-x) - 2 * var(--gutter)) / 3) * 2
      + var(--gutter) * 2
      + ((100vw - 2 * var(--margin-x) - 2 * var(--gutter)) / 3) / 2
    );
  }
}

/* ---------- PHOTO PAGE — MOBILE ---------- */
@media (max-width: 768px) {
  .intro {
    pointer-events: none;
    /* Optisch zentriert im Viewport: 45% von oben (etwas höher als exakte Mitte)
       translateY(-50%) zieht den Block um seine halbe Höhe nach oben */
    position: fixed;
    top: 45%;
    transform: translateY(-50%);
    bottom: auto;
    left: var(--margin-x);
    margin: 0;
    font-size: 28px;
    line-height: 31px;
    /* 2-col grid: spans col 1 + gutter + half col 2 */
    width: calc(
      ((100vw - 2 * var(--margin-x) - var(--gutter)) / 2)
      + var(--gutter)
      + ((100vw - 2 * var(--margin-x) - var(--gutter)) / 2) / 2
    );
    /* Lade-Animation mit korrektem translateY für die zentrierte Position */
  }

  .intro a,
  .intro button,
  .intro .btn--highlight {
    pointer-events: auto;
  }

  /* Fix gegen die "plötzlich am Ende erscheinenden" Ober-/Unterlängen:
     Beim per-Wort-Opacity-Fade rendert der Browser jedes Wort in einen
     Compositing-Buffer, dessen Grenzen = die Wortbox sind → Glyphen-Tinte, die
     über die Zeilenbox hinausragt (Ober-/Unterlängen), wird abgeschnitten und
     erscheint erst, wenn opacity 1 erreicht (daher glyphenabhängig: manche Wörter
     betroffen, andere nicht). Vertikales Padding auf den .line-Spans erweitert
     diese Grenzen, sodass die Tinte im Buffer liegt.
     Wichtig: bei display:inline (Standard) verändert vertikales Padding NICHTS
     am Layout — kein Zeilenversatz, nur größere Paint-/Compositing-Bounds.
     Nur mobil; Desktop unberührt. */
  .intro .line {
    /* Vertikal (0.5em): fängt Ober-/Unterlängen — bei inline layout-neutral.
       Horizontal (0.2em): fängt seitlich überstehende Tinte, z. B. den oberen
       Haken des f. Horizontales Padding ist bei inline layout-relevant, deshalb
       die kompensierende negative Margin (-0.2em) → Wortabstand bleibt identisch,
       nur die Paint-/Compositing-Bounds werden größer. */
    padding: 0.5em 0.2em;
    margin: 0 -0.2em;
  }

  @keyframes intro-block-in-mobile {
    0% {
      line-height: 50px;
      transform: translateY(calc(-50% + 15px));
    }
    100% {
      line-height: 39px;
      transform: translateY(-50%);
    }
  }
  /* Scroll-Exit: Hidden-State ebenfalls mit -50% Basis */
  .is-loaded .intro.is-hidden {
    transform: translateY(calc(-50% + 15px));
    transition: transform 1.8s cubic-bezier(0.4, 0, 0.6, 1);
  }
  .is-loaded .intro:not(.is-hidden) {
    transition: transform 3s cubic-bezier(0.05, 0.95, 0.15, 1);
  }
  .is-loaded .intro.is-hidden p {
    line-height: 31px !important;
    transition: none !important;
  }
  .is-loaded .intro p {
    transition: none !important;
  }
  .is-loaded .intro p {
    transition: none;
  }

  /* Gallery ends above the menu (which sits at bottom: 14px, is 4 lines × 21px = 84px tall).
     Same top-gap (18px) as the header gap is applied above the menu. */
  .gallery {
    position: fixed;
    top: 0;
    bottom: 0;
    /* Mobil: erstes Bild ragt initial nur ~12vw ins Bild (statt fix 126px, was
       auf schmalen Viewports 30%+ wären) — bessere Lesbarkeit des Intro-Texts.
       Peek = der zweite Wert (12vw); kleiner = weniger, größer = mehr Bild. */
    padding-left: calc(100vw - 12vw);
  }

  /* ---------- MOBILE GALLERY: width-basiert statt height-basiert ---------- */
  /* Heroes: 120% Viewport-Breite (10% Überstand links + rechts) */
  .gallery-block--hero {
    height: auto;
    width: 120vw;
    margin-left: -10vw;
    align-self: center;
  }

  /* Normal-Singles: width-basiert */
  .gallery-block--normal {
    height: auto;
    width: calc((100vw - 2 * var(--margin-x) - var(--gutter)) * 0.75);
    align-self: center;
  }

  /* Paare: gleicher Breitenbereich wie Normal-Singles */
  .gallery-pair,
  .gallery-pair--horizontal {
    height: auto;
    width: calc((100vw - 2 * var(--margin-x) - var(--gutter)) * 0.75);
    padding-left: 0;
    padding-right: 0;
    padding-top: 0;
    padding-bottom: 0;
    flex-direction: column;
    align-items: flex-start;
  }

  /* Pair-Kinder: Höhe auto, Breite 100% des Pair-Containers */
  .gallery-pair__top,
  .gallery-pair__bottom {
    height: auto;
    width: 100%;
  }

  /* Alle Bilder: width-basiert statt height-basiert */
  .gallery-block img,
  .gallery-pair__top img,
  .gallery-pair__bottom img {
    height: auto;
    width: 100%;
  }
}

@media (max-width: 635px) {
  .intro {
    /* Rechts aufs Grid setzen: gleicher Rand wie links, statt bis zum
       Bildschirmrand zu ragen (left + right + width:auto = Rand zu Rand). */
    width: auto;
    right: var(--margin-x);
  }
}

@media (max-width: 425px) {
  .intro {
    margin-top: 60px;
  }
}


/* ---------- LAZY LOAD + PARALLAX für Gallery-Bilder ---------- */
/* Bilder starten unsichtbar und gleiten von unten ein */
.gallery-block,
.gallery-pair__top,
.gallery-pair__bottom {
  opacity: 0;
  transform: translateY(40px);
  transition: opacity .8s cubic-bezier(0.22, 1, 0.36, 1),
              transform .8s cubic-bezier(0.16, 1, 0.3, 1);
}

.gallery-block.is-visible,
.gallery-pair__top.is-visible,
.gallery-pair__bottom.is-visible {
  opacity: 1;
  transform: translateX(calc(var(--pair-offset, 0px) + var(--parallax-x, 0px)));
  transition: opacity .8s cubic-bezier(0.22, 1, 0.36, 1),
              transform .8s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Heroes faden langsamer ein für mehr Dramatik */
.gallery-block--hero {
  transform: translateY(60px);
  transition: opacity 1.2s cubic-bezier(0.22, 1, 0.36, 1),
              transform 1.2s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Erstes Bild: spezielle Intro-Animation (von rechts reinsliden + fade) */
.gallery-block.intro-reveal {
  opacity: 0;
  transform: translateX(60px);
  transition: none;
  animation: intro-slide-in 1.2s cubic-bezier(0.16, 1, 0.3, 1) 2.8s forwards;
}
@keyframes intro-slide-in {
  0%   { opacity: 0; transform: translateX(60px); }
  100% { opacity: 1; transform: translateX(0); }
}


.gallery-block.placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #c8ced2;
  border-radius: 0;
  color: #6a7378;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.02em;
  user-select: none;
}
.gallery-block.placeholder::before {
  content: attr(data-label);
}

.gallery-pair .placeholder-img {
  /* display: block damit aspect-ratio die Breite aus der Höhe ableiten kann */
  display: block;
  background: #c8ced2;
  border-radius: 0;
  color: #6a7378;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.02em;
  user-select: none;
  text-align: center;
  line-height: 1;
  /* Vertikales Zentrieren des Labels via padding */
  display: flex;
  align-items: center;
  justify-content: center;
}
.gallery-pair .placeholder-img::before {
  content: attr(data-label);
}

/* Platzhalter-Seitenverhältnisse (gängige Fotoformate) */
.placeholder--3x2 { aspect-ratio: 3 / 2; }   /* Quer */
.placeholder--2x3 { aspect-ratio: 2 / 3; }   /* Hoch */
.placeholder--4x3 { aspect-ratio: 4 / 3; }   /* Quer */
.placeholder--3x4 { aspect-ratio: 3 / 4; }   /* Hoch */
.placeholder--16x9 { aspect-ratio: 16 / 9; } /* Quer, Kino */
.placeholder--4x5 { aspect-ratio: 4 / 5; }   /* Hoch (Instagram) */
.placeholder--5x4 { aspect-ratio: 5 / 4; }   /* Quer */
.placeholder--1x1 { aspect-ratio: 1 / 1; }   /* Quadrat */
