/* lightbox.css  -  Modul: Bild-/Video-Lightbox (Apple-Glass)
   Eigenstaendiges Feature-Modul, per system/config/modules.php zuschaltbar.
   Liest die globalen :root-Variablen (--gnoise, --cvw, --edge) aus main.css,
   die davor laedt. Die Basis-Optik des .lightbox-trigger-Buttons bleibt bewusst
   in main.css: die Trigger sind Seiteninhalt und sollen auch bei abgeschaltetem
   Modul sauber aussehen. */

/* ---- Bild-Lightbox (Apple-Glass) ---- */
/* Die Verzoegerung haelt die Buehne genau so lange sichtbar, wie ihr laengster
   Uebergang dauert: der Backdrop faerbt 500ms lang aus, das Medium 450ms. Laenger
   darf sie nicht stehen, denn der Weichzeichner des Backdrops faedt nicht mit,
   er endet erst mit dem Element - sonst bliebe die Seite verwaschen, obwohl die
   Abdunklung schon weg ist. */
#lightbox { position: fixed; inset: 0; z-index: 9998; display: flex; align-items: center; justify-content: center; opacity: 1; visibility: hidden; pointer-events: none; transition: visibility 0s linear .5s; }
#lightbox.is-open { visibility: visible; pointer-events: auto; transition: visibility 0s linear 0s; }
body.lb-open { overflow: hidden; }
#lightbox .lb-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0); -webkit-backdrop-filter: blur(40px); backdrop-filter: blur(40px); transition: background-color .5s ease-in-out; }
/* Die Flaeche traegt allein, der Weichzeichner ist Zugabe: bei 40% blieben 60%
   der Helligkeit stehen, und wo die Engine den Weichzeichner verweigert (ueber
   laufendem Video), stand der Hintergrund unveraendert scharf da. Der Wert liegt
   jetzt im selben Korridor wie Kopfleiste und Menue. */
#lightbox.is-open .lb-backdrop { background: rgba(0,0,0,.47); }
/* Die Koernung liegt als eigene Ebene mit eigener Deckkraft, damit sie mit der
   Flaeche zusammen einblendet. Als Bild in der background-Zeile ginge das nicht:
   ein Bild kennt kein Dazwischen, es waere beim Oeffnen sofort voll da, waehrend
   die Farbe darunter noch hochzieht. Nur die zwei Vollbild-Flaechen brauchen das;
   auf den kleinen Chips ist der Sprung bei dieser Deckkraft nicht zu sehen. */
#lightbox .lb-backdrop::after { content: ""; position: absolute; inset: 0; background: var(--gnoise); opacity: 0; pointer-events: none; transition: opacity .5s ease-in-out; }
#lightbox.is-open .lb-backdrop::after { opacity: 1; }
#lightbox .lb-stage { position: relative; max-width: calc(90 * var(--cvw)); max-height: 90vh; display: flex; align-items: center; justify-content: center; }
/* Deckel-Weg fuer beide Medien: gilt nur, solange die echten Masse fehlen (Video vor
   den Metadaten, Bild vor dem Decode). Sobald sie da sind, uebernimmt die Fuell-Regel
   unten. Das Bild bringt den Startzustand der Einblendung mit, das Video den
   durchsichtigen Grund, damit Hochformat-Reels keine schwarzen Balken zeigen. */
#lightbox .lb-img { max-width: 100%; max-height: 90vh; object-fit: contain; box-shadow: 0 25px 50px -12px rgba(0,0,0,0.5); opacity: 0; transform: scale(.95); }
#lightbox .lb-vid { width: auto; height: auto; max-width: 100%; max-height: 90vh; object-fit: contain; background: transparent; box-shadow: 0 25px 50px -12px rgba(0,0,0,0.5); }
/* Buehne fuellen statt nur deckeln: nur die Breite wird gesetzt, die Hoehe folgt dem
   Verhaeltnis, damit nie zwei Achsen gegeneinander binden. Die drei Grenzen sind die
   Buehnenbreite, die Buehnenhoehe (in Breite umgerechnet) und die Schaerfe-Grenze aus
   --cap. Solange die Masse fehlen (Video vor den Metadaten), traegt das Medium die
   Klasse nicht und faellt auf den Deckel-Weg oben zurueck. */
#lightbox .lb-img.is-sized, #lightbox .lb-vid.is-sized {
  aspect-ratio: var(--ar);
  width: min(calc(90 * var(--cvw)), calc(90vh * var(--ar)), var(--cap));
  width: min(calc(90 * var(--cvw)), calc(90svh * var(--ar)), var(--cap));
  height: auto;
  max-width: none;
  max-height: none;
}
#lightbox .lb-ui { position: fixed; inset: 0; z-index: 10000; pointer-events: none; }
.lb-btn { pointer-events: auto; cursor: pointer; color: #fff; display: inline-flex; align-items: center; justify-content: center; width: 3rem; height: 3rem; border: 1px solid rgba(255,255,255,0.28); background: var(--gnoise), rgba(255,255,255,0.16); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); transition: background-color .3s ease, border-color .3s ease, color .3s ease, transform .3s ease; }
/* Das display oben schlaegt die Browser-Regel [hidden]{display:none}: Autoren-CSS
   sticht das UA-Stylesheet. Ohne diese Zeile bliebe ein per hidden markierter Knopf
   sichtbar UND per Tab erreichbar. */
.lb-btn[hidden] { display: none; }
#lightbox:not(.is-open) .lb-btn { background: rgba(255,255,255,0); border-color: rgba(255,255,255,0); color: rgba(255,255,255,0); }
.lb-btn svg { width: 1.4rem; height: 1.4rem; }
@media (hover: hover) and (pointer: fine) { .lb-btn:hover { background: #fff; color: #000; transform: scale(1.05); } }
.lb-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; box-shadow: 0 0 0 4px rgba(0,0,0,0.6); }
.lb-cluster { position: absolute; top: 1rem; right: calc(var(--edge) + 1rem); display: flex; gap: .5rem; align-items: center; }
/* Positions-Anzeige: reiht sich als erstes Kind in den Cluster und braucht deshalb
   kein eigenes Positionieren; die Zahl steht bei der Navigation, zu der sie gehoert.
   Oben links waere kein Platz, dort wohnt auf dem Desktop die Format-Leiste und
   mobil sitzt sie unten links. Glas wie die Knoepfe, aber bewusst ohne deren Klasse:
   die sammelt die Fokus-Falle ein, und hier gibt es nichts zu bedienen. Sichtbar nur
   bei mehr als einem Medium, sonst gibt es nichts zu zaehlen. */
.lb-count { display: inline-flex; align-items: center; height: 3rem; padding: 0 .85rem; border: 1px solid rgba(255,255,255,0.28); background: var(--gnoise), rgba(255,255,255,0.16); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); color: #fff; font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: .9rem; font-weight: 700; white-space: nowrap; transition: background-color .3s ease, border-color .3s ease, color .3s ease; }
html.rmo .lb-count { transition: background-color .15s linear, border-color .15s linear, color .15s linear; }
#lightbox:not(.lb-multi) .lb-count { display: none; }
#lightbox:not(.is-open) .lb-count { background: rgba(255,255,255,0); border-color: rgba(255,255,255,0); color: rgba(255,255,255,0); }
/* Eigene Video-Steuerung: Sichtbarkeit steuert der lb-vidctl-Container,
   die Icons folgen dem Play-/Ton-Zustand */
.lb-playpause .lb-pp-play { display: none; }
#lightbox.lb-vid-paused .lb-pp-pause { display: none; }
#lightbox.lb-vid-paused .lb-pp-play { display: block; }
.lb-arrow { position: absolute; top: 50%; transform: translateY(-50%); display: none; }
@media (hover: hover) and (pointer: fine) { .lb-arrow:hover { transform: translateY(-50%) scale(1.05); } }
.lb-prev { left: calc(var(--edge) + 1rem); } .lb-next { right: calc(var(--edge) + 1rem); }
#lightbox:not(.lb-multi) .lb-nav { display: none; }
/* Format-Umschaltung (oben links): auto = natives Format; die Hochformat-Zuschnitte
   fuellen die Buehne per cover. Hoehe = min(Viewport-Deckel, Breite x Seitenverhaeltnis);
   Browser ohne aspect-ratio fallen weich aufs native Verhaeltnis zurueck. */
.lb-fmt { position: absolute; top: 1rem; left: calc(var(--edge) + 1rem); display: flex; gap: .5rem; }
.lb-fmt-btn { width: auto; padding: 0 .85rem; font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: .9rem; font-weight: 700; }
.lb-fmt-btn[aria-pressed="true"] { background: #fff; color: #000; }
/* Video-Steuerung sitzt IM Medium (unten rechts): dadurch nie ausserhalb des
   Viewports, egal wie hoch das Video ist */
.lb-vidctl { position: absolute; right: 6px; bottom: 6px; display: none; gap: .3rem; z-index: 5; }
#lightbox.lb-vidmode .lb-vidctl { display: flex; }
/* Bewusst kompakt (Nice-to-have-Bedienung, kein Pflicht-Ziel); die ID haelt die
   Groesse auch gegen die allgemeine Desktop-Button-Regel */
#lightbox .lb-vidctl .lb-btn { width: 1.75rem; height: 1.75rem; }
.lb-vidctl svg { width: 1rem; height: 1rem; }
.lb-mute .lb-m-off { display: none; }
#lightbox.lb-muted .lb-m-on { display: none; }
#lightbox.lb-muted .lb-m-off { display: block; }
/* Zuschnitte rechnen nach derselben Formel wie der auto-Zustand oben, nur mit dem
   Verhaeltnis des Formats statt dem des Mediums: Breite gesetzt, Hoehe folgt. Damit
   binden sie an dieselbe Schaerfe-Grenze --cap, und ein Format, das dem nativen
   Verhaeltnis entspricht, veraendert bit-genau nichts. Der Fallback macht die Grenze
   unwirksam, wenn die Masse fehlen; ohne ihn waere die ganze Deklaration ungueltig
   und die Breite fiele auf auto. Die alten Hoehen-Konstanten waren nur diese Formel
   in umgerechneter Form (Buehnenkante / Verhaeltnis) und sind rechnerisch identisch. */
#lightbox.lb-f32 .lb-img, #lightbox.lb-f32 .lb-vid {
  aspect-ratio: 3 / 2; object-fit: cover; height: auto; max-width: none; max-height: none;
  width: min(calc(90 * var(--cvw)), calc(90vh * 3 / 2), var(--cap, 99999px));
  width: min(calc(90 * var(--cvw)), calc(90svh * 3 / 2), var(--cap, 99999px));
}
#lightbox.lb-f43 .lb-img, #lightbox.lb-f43 .lb-vid {
  aspect-ratio: 4 / 3; object-fit: cover; height: auto; max-width: none; max-height: none;
  width: min(calc(90 * var(--cvw)), calc(90vh * 4 / 3), var(--cap, 99999px));
  width: min(calc(90 * var(--cvw)), calc(90svh * 4 / 3), var(--cap, 99999px));
}
#lightbox.lb-f11 .lb-img, #lightbox.lb-f11 .lb-vid {
  aspect-ratio: 1 / 1; object-fit: cover; height: auto; max-width: none; max-height: none;
  width: min(calc(90 * var(--cvw)), 90vh, var(--cap, 99999px));
  width: min(calc(90 * var(--cvw)), 90svh, var(--cap, 99999px));
}
#lightbox.lb-f45 .lb-img, #lightbox.lb-f45 .lb-vid {
  aspect-ratio: 4 / 5; object-fit: cover; height: auto; max-width: none; max-height: none;
  width: min(calc(90 * var(--cvw)), calc(90vh * 4 / 5), var(--cap, 99999px));
  width: min(calc(90 * var(--cvw)), calc(90svh * 4 / 5), var(--cap, 99999px));
}
#lightbox.lb-f916 .lb-img, #lightbox.lb-f916 .lb-vid {
  aspect-ratio: 9 / 16; object-fit: cover; height: auto; max-width: none; max-height: none;
  width: min(calc(90 * var(--cvw)), calc(90vh * 9 / 16), var(--cap, 99999px));
  width: min(calc(90 * var(--cvw)), calc(90svh * 9 / 16), var(--cap, 99999px));
}
@media (min-width: 768px) {
  .lb-btn { width: 3.5rem; height: 3.5rem; }
  .lb-count { height: 3.5rem; } /* auf gleicher Hoehe wie die Knoepfe neben ihr */
  .lb-fmt-btn { width: auto; }
  .lb-cluster { top: 2.5rem; right: calc(var(--edge) + 2.5rem); }
  .lb-fmt { top: 2.5rem; left: calc(var(--edge) + 2.5rem); }
  .lb-mobile { display: none; }
  #lightbox.lb-multi .lb-arrow { display: inline-flex; }
  .lb-prev { left: calc(var(--edge) + 2.5rem); } .lb-next { right: calc(var(--edge) + 2.5rem); }
}
/* Mobil ist die Buehne randlos (Medien bis an die Viewport-Kanten; die
   Zuschnitt-Formeln rechnen gegen dieselbe 100vw-Kante). Die Format-Leiste wandert
   nach unten links: oben rechts wohnt der Cluster, so kollidiert nie etwas. */
@media (max-width: 767.98px) {
  #lightbox .lb-stage { max-width: 100vw; }
  /* Randlose Buehne: die Breiten-Grenze der Fuell-Formel folgt ihr auf die volle
     Viewport-Breite (steht bewusst nach der Basis-Regel, gleiche Spezifitaet). */
  #lightbox .lb-img.is-sized, #lightbox .lb-vid.is-sized {
    width: min(100vw, calc(90vh * var(--ar)), var(--cap));
    width: min(100vw, calc(90svh * var(--ar)), var(--cap));
  }
  /* Die Zuschnitte folgen der Buehne auf die volle Viewport-Breite. Sie stehen
     zwingend NACH der auto-Regel darueber: gleiche Spezifitaet, also entscheidet
     die Reihenfolge, wer beim gewaehlten Format das letzte Wort hat. */
  #lightbox.lb-f32 .lb-img, #lightbox.lb-f32 .lb-vid {
    width: min(100vw, calc(90vh * 3 / 2), var(--cap, 99999px));
    width: min(100vw, calc(90svh * 3 / 2), var(--cap, 99999px));
  }
  #lightbox.lb-f43 .lb-img, #lightbox.lb-f43 .lb-vid {
    width: min(100vw, calc(90vh * 4 / 3), var(--cap, 99999px));
    width: min(100vw, calc(90svh * 4 / 3), var(--cap, 99999px));
  }
  #lightbox.lb-f11 .lb-img, #lightbox.lb-f11 .lb-vid {
    width: min(100vw, 90vh, var(--cap, 99999px));
    width: min(100vw, 90svh, var(--cap, 99999px));
  }
  #lightbox.lb-f45 .lb-img, #lightbox.lb-f45 .lb-vid {
    width: min(100vw, calc(90vh * 4 / 5), var(--cap, 99999px));
    width: min(100vw, calc(90svh * 4 / 5), var(--cap, 99999px));
  }
  #lightbox.lb-f916 .lb-img, #lightbox.lb-f916 .lb-vid {
    width: min(100vw, calc(90vh * 9 / 16), var(--cap, 99999px));
    width: min(100vw, calc(90svh * 9 / 16), var(--cap, 99999px));
  }
  .lb-fmt { top: auto; left: .6rem; bottom: .8rem; gap: .35rem; }
  .lb-fmt-btn { height: 2.4rem; padding: 0 .55rem; font-size: .8rem; }
}
/* Stapel-Ebene 50: Das Badge haengt bei Kacheln ausserhalb der Foto-Baender am
   body und liegt damit im Root-Stacking-Context, wo es mit den fixierten
   Bedien-Elementen konkurriert. Es ist ein Hover-Indikator, kein Overlay, und
   bleibt deshalb unter Back-to-Top und Navigation. Ueber jeder Inhalts-Ebene
   liegt es trotzdem, die reicht nur bis 3. */
.lb-hover { position: absolute; z-index: 50; pointer-events: none; box-sizing: border-box; display: flex; justify-content: flex-end; align-items: flex-start; padding: 1rem; visibility: hidden; transition: visibility 0s linear .55s; }
.lb-hover.on { visibility: visible; transition: visibility 0s linear 0s; }
.lb-hover-badge { display: inline-flex; align-items: center; gap: .5rem; padding: .5rem 1rem; background: rgba(0,0,0,0); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); border: 1px solid rgba(255,255,255,0); color: rgba(255,255,255,0); font-size: .75rem; letter-spacing: .15em; text-transform: uppercase; font-weight: 500; box-shadow: 0 10px 40px rgba(0,0,0,0); transform: scale(.96); transition: background-color .35s ease, border-color .35s ease, box-shadow .35s ease, transform .4s ease, color .4s ease .12s; }
.lb-hover-badge svg { width: 1rem; height: 1rem; }
.lb-hover.on .lb-hover-badge { background: var(--gnoise), rgba(0,0,0,0.54); border-color: rgba(255,255,255,0.2); color: #fff; box-shadow: 0 10px 40px rgba(0,0,0,0.4); transform: scale(1); transition: background-color .3s ease, border-color .3s ease, box-shadow .3s ease, transform .3s ease, color .28s ease; }
html.rmo #lightbox .lb-backdrop { transition: background-color .15s linear; }
html.rmo .lb-btn { transition: background-color .15s linear, border-color .15s linear, color .15s linear; }
html.rmo .lb-btn:hover { transform: none; }
html.rmo .lb-arrow:hover { transform: translateY(-50%); }
html.rmo .lb-hover-badge { transition: background-color .15s linear, border-color .15s linear, color .15s linear, box-shadow .15s linear; transform: none; }
html.rmo .lb-hover.on .lb-hover-badge { transform: none; }
