/* Property media dialog — tabs for images, floor plans, videos */

.media-dialog {
  max-width: 100vw;
  max-height: 100vh;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 0;
  background: var(--color-bg-dark);
  color: var(--color-text-inverse);
  overflow: hidden;
}

.media-dialog[open] {
  display: grid;
  grid-template-rows: auto 1fr auto;
}

.media-dialog::backdrop {
  background: var(--overlay-bg);
  backdrop-filter: blur(var(--overlay-blur));
}

/* --- Header: title + tabs + close --- */

.media-dialog > header {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: var(--space-1) var(--space-3);
  background: var(--color-bg-dark);
  border-bottom: 1px solid var(--glass-faint);
  max-height: 3rem;
}

.media-dialog > header > [data-closes] {
  position: absolute;
  right: var(--space-3);
}

.media-dialog [role="tablist"] {
  display: flex;
  gap: var(--space-3);
}

.media-dialog [role="tab"] {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  background: transparent;
  color: var(--color-text-inverse);
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: var(--text-sm);
  transition: background var(--transition), border-color var(--transition);
}

.media-dialog [role="tab"]:hover {
  background: var(--glass-faint);
}

.media-dialog [role="tab"][aria-selected="true"] {
  background: var(--glass-subtle);
  border-color: var(--glass-soft);
}

.media-dialog > header > [data-closes] {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 50%;
  color: var(--color-text-inverse);
  cursor: pointer;
}

.media-dialog > header > [data-closes]:hover {
  background: var(--glass-faint);
}

/* --- Tab panels --- */

.media-panel {
  display: grid;
  grid-template-rows: 1fr auto;
  overflow: hidden;
  min-height: 0;
}

.media-panel[hidden] {
  display: none;
}

/* Karten-Tab ("Lage"): die Map füllt das Panel. Das Dialog-Grid (auto 1fr auto)
   reserviert Header + Footer bereits, daher height:100% statt des 16:9-aspect-ratio
   aus map.css — das würde im breiten Panel überlaufen (unter den Footer). */
.media-map {
  display: block;
}
.media-map [data-map-config] {
  aspect-ratio: auto;
  height: 100%;
  border: 0;
  border-radius: 0;
}

/* Sticky-Header-Overlap vermeiden — wenn JS via scrollIntoView ein Slide
   in den Viewport zieht, lässt der Browser den --sticky-offset-Bereich
   oberhalb frei. --sticky-offset wird in header.js dynamisch aus
   header.offsetHeight befüllt → funktioniert tier-unabhängig (default,
   pro, basic haben unterschiedliche Header-Höhen). */
.media-panel .slide {
  scroll-margin-top: calc(var(--sticky-offset, 0px) + var(--space-3));
}

/* --- Stage (main media area) --- */

.media-stage {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  /* Fester Container mit aspect-ratio → kein Bouncing zwischen Slides mit
     unterschiedlichen Bild-Aspects. Bilder werden mit object-fit:contain
     proportional eingepasst (Letterbox bei Hochformat). max-height cappt
     die Höhe auf großen Viewports, damit der Slider nicht den ganzen
     Schirm einnimmt. */
  aspect-ratio: 4 / 3;
  max-height: calc(100vh - 15rem);
  width: 100%;
}

.media-track {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  overflow: hidden;
}

.media-item {
  margin: 0;
  max-width: 100%;
  max-height: 100%;
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;   /* Containing-Block fuer den KI-Badge */
}

/* KI-Bild-Hinweis (Transparenz): kleiner Badge oben links am Bild, wenn im Backend als KI-generiert markiert. */
.media-ki-badge {
  position: absolute;
  top: 0.5rem;
  inset-inline-start: 0.5rem;
  z-index: 2;
  padding: 0.15rem 0.55rem;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.2;
  color: #fff;
  background: rgba(0, 0, 0, 0.62);
  border-radius: var(--radius-media-overlay);
  pointer-events: none;
}

/* <picture>-Wrapper layout-transparent: das <img> bleibt Flex-Child der
   .media-item (Zoom/Pan-Transform + Bild-Regeln greifen am <img> wie zuvor). */
.media-item picture {
  display: contents;
}

.media-item[hidden] {
  display: none;
}

.media-item img,
.media-item video,
.media-item iframe {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.media-item iframe {
  width: min(90vw, 64rem);
  aspect-ratio: 16 / 9;
  height: auto;
}

.media-item video {
  width: min(90vw, 64rem);
  height: auto;
}

.media-item figcaption {
  display: inline-block;
  margin-block-start: var(--space-2);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
  text-align: center;
  color: var(--color-text-inverse);
  background: var(--scrim-heavy);
  border-radius: var(--radius-media-overlay);
}

/* --- Slider-based panels (images + floor plans) — reuses global .slider / carousel.js --- */

.media-dialog .slider {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.media-dialog .slider-track {
  height: 100%;
  gap: 0;
  align-items: center;
}

.media-dialog .slide {
  position: relative; /* positioning context for figcaption overlay */
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  overflow: hidden; /* clip zoomed image so it doesn't bleed into neighbours */
  /* touch-action: none → JS handled alle Touch-Gesten:
     - 1 Finger = Swipe (media-dialog.js: onSwipe → goto-slide) im 1×-Modus,
       Pan im gezoomten Modus
     - 2 Finger = Pinch-Zoom (allowPinch: true)
     pan-x würde Pinch-Events vom Browser abfangen → unser JS bekäme sie nicht. */
  touch-action: none;
  /* Zoom/Pan-State — vom JS (carousel.js) per inline-style überschrieben.
     Defaults hier, damit der CSS-Analyzer die Variablen kennt + transform sauber rendert. */
  --pan-x: 0px;
  --pan-y: 0px;
  --zoom: 1;
}

/* Per-image caption — Overlay ÜBER der Bedienzeile, mittig */
/* ⚠ Auf `bottom: var(--space-3)` sitzen in diesem Container DREI Dinge: diese Unterschrift, die
   Zoom-Leiste (.media-tools, mittig) und der Zähler (.slider-counter, rechts). Solange die
   Unterschrift ein kurzes Etikett war, ging das gut; ein ganzer Satz nimmt fast die volle Breite
   und legte sich über beide (gemeldet 31.08.2026). Sie rückt deshalb eine Reihe höher und
   orientiert sich mittig an der Leiste, statt neben ihr um Platz zu konkurrieren.
   Höchstens zwei Zeilen — der volle Text steht im alt-Attribut. */
.media-dialog .slide figcaption {
  position: absolute;
  /* 3rem = Hoehe der Zoom-Leiste (Button 1,73rem + 2x space-1 Innenabstand = 2,23rem) plus Luft;
     sie selbst sitzt auf space-3, ihre Oberkante liegt also bei rund 2,98rem. Wer die Leiste
     umbaut, rechnet hier nach. */
  bottom: calc(var(--space-3) + 3rem);
  left: 50%;
  transform: translateX(-50%);
  max-width: min(90%, 44rem);
  padding: var(--space-1) var(--space-3);
  background: var(--scrim-heavy);
  color: var(--color-text-inverse);
  border-radius: var(--radius-media-overlay);
  font-size: var(--text-xs);
  pointer-events: none;
  z-index: 1;
  text-align: center;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Antippbar, damit der volle Text auch ohne Hover erreichbar ist (media-dialog.js).
   ⚠ `pointer-events: auto` NUR hier: am Cover bliebe die Unterschrift bewusst durchlaessig, weil
   dort ein Klick die Galerie oeffnet. Im Dialog ist die Flaeche frei. */
.media-dialog .slide figcaption[data-caption-toggle] {
  pointer-events: auto;
  cursor: pointer;
}

.media-dialog .slide figcaption.is-open {
  -webkit-line-clamp: unset;
  line-clamp: unset;
  display: block;
  max-height: 40vh;
  overflow-y: auto;
}

.media-dialog .slide:hover {
  transform: none;
}

/* Volle Slide-Fläche statt shrink-to-fit: nur mit definiter Breite/Höhe hat das
   <img> darin einen Prozent-Bezug (sonst fällt width:100% auf auto zurück und
   das Bild bliebe wieder auf seiner nativen Größe stehen). figcaption liegt im
   Dialog absolut über dem Bild, kostet hier also keinen Fluss-Platz. */
.media-dialog .slide .media-item {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  height: 100%;
}

/* Das Bild füllt die Slide-Fläche (contain hält das Seitenverhältnis) statt bei
   seiner nativen Größe stehenzubleiben. Mit width/height:auto rendert der Browser
   ein Foto nie größer als seine Datei — bei Objektbildern von einer externen Quelle
   (kein srcset, nur -g.jpg) blieb so z.B. ein 1067x600-Bild mitten im Vollbild-
   Dialog winzig. calc(100vh - 15rem) war zudem eine Schätzung der Panel-Höhe; die
   ergibt sich bereits korrekt aus dem Dialog-Grid (auto 1fr auto) + .media-panel. */
.media-dialog .slide img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: var(--radius);
  user-select: none;
  -webkit-user-drag: none;
  transform: translate(var(--pan-x, 0px), var(--pan-y, 0px)) scale(var(--zoom, 1));
  transform-origin: center center;
  transition: transform var(--transition-med);
}

.media-dialog .slide.is-zoomed {
  /* Block native scroll-snap + pinch — JS handles pan via pointer events */
  touch-action: none;
}

.media-dialog .slide.is-zoomed img {
  cursor: grab;
}

.media-dialog .slide.is-panning img {
  cursor: grabbing;
  transition: none;
}

.media-dialog .slider-nav {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  pointer-events: none;
}

.media-dialog .slider-nav .prev,
.media-dialog .slider-nav .next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: auto;
  height: auto;
  background: var(--scrim-light);
  border: none;
  color: var(--color-text-inverse);
  padding: var(--space-3);
  border-radius: 50%;
  pointer-events: auto;
  cursor: pointer;
  transition: background var(--transition);
}

.media-dialog .slider-nav .prev:hover,
.media-dialog .slider-nav .next:hover {
  background: var(--scrim-heavy);
}

.media-dialog .slider-nav .prev { left: var(--space-3); }
.media-dialog .slider-nav .next { right: var(--space-3); }

.media-dialog .slider-counter {
  position: absolute;
  bottom: var(--space-3);
  right: var(--space-3);
  padding: var(--space-1) var(--space-3);
  background: var(--scrim);
  color: var(--color-text-inverse);
  border-radius: var(--radius);
  font-size: var(--text-xs);
  pointer-events: auto;
}

/* --- Nav buttons over the stage --- */

.media-prev,
.media-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: var(--scrim-light);
  border: none;
  color: var(--color-text-inverse);
  cursor: pointer;
  padding: var(--space-3);
  border-radius: 50%;
  transition: background var(--transition);
}

.media-prev:hover,
.media-next:hover {
  background: var(--scrim-heavy);
}

.media-prev { left: var(--space-3); }
.media-next { right: var(--space-3); }

.media-counter {
  position: absolute;
  top: var(--space-3);
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  padding: var(--space-1) var(--space-3);
  background: var(--scrim);
  border-radius: var(--radius);
  font-size: var(--text-xs);
}

/* --- Tools toolbar (zoom +/- reset, optional print) — bottom-center overlay --- */

.media-tools {
  position: absolute;
  bottom: var(--space-3);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: var(--space-1);
  background: var(--scrim);
  padding: var(--space-1);
  border-radius: var(--radius);
}

.media-tools button {
  background: transparent;
  border: none;
  color: var(--color-text-inverse);
  cursor: pointer;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  min-width: 2.5rem;
}

.media-tools button:hover {
  background: var(--glass-subtle);
}

/* --- Thumbnail strip --- */

.media-thumbs {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  overflow-x: auto;
  list-style: none;
  margin: 0;
  border-top: 1px solid var(--glass-faint);
  scrollbar-width: thin;
}

.media-thumbs li {
  flex: 0 0 auto;
}

.media-thumbs button {
  background: transparent;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  border-radius: var(--radius);
  overflow: hidden;
  opacity: 0.6;
  transition: opacity var(--transition), border-color var(--transition);
}

.media-thumbs button:hover {
  opacity: 1;
}

.media-thumbs button[aria-current="true"] {
  opacity: 1;
  border-color: var(--color-primary);
}

.media-thumbs img {
  display: block;
  width: 5rem;
  height: 3.5rem;
  object-fit: cover;
  border-radius: calc(var(--radius) - 0.125rem);
  transition: transform var(--transition-med);
}

.media-thumbs button[aria-current="true"] img {
  transform: scale(1.8);
}

/* Hover-Vergrößerung nur auf Geräten mit echtem Hover (Maus/Trackpad).
   Ohne den hover:hover-Guard triggert Mobile Safari/Chrome :hover beim
   ersten Tap (Sticky-Hover) → User sieht ungewollten Zoom-Effekt, der
   sich wie ein vom Tap ausgelöster Zoom anfühlt. */
@media (hover: hover) {
  .media-thumbs button:hover img {
    transform: scale(1.8);
  }
}

/* --- Bottom action bar --- */

.media-actions {
  display: flex;
  gap: var(--space-2);
  justify-content: center;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--glass-faint);
  background: var(--scrim-light);
}

.media-actions button {
  position: static;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--glass-faint);
  border: 1px solid var(--glass-subtle);
  color: var(--color-text-inverse);
  border-radius: var(--radius);
  cursor: pointer;
  font-size: var(--text-sm);
  line-height: inherit;
  transition: background var(--transition);
}

.media-actions button:hover {
  background: var(--glass-soft);
}

.media-actions .fav-btn.active {
  color: var(--color-primary);
}

/* Like-Counter neben den Action-Buttons. Heart-Icon via CSS-Mask
   (gleiches Pattern wie .property-card .fav-total). */
.media-actions .fav-total {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-inverse);
  opacity: 0.8;
}

.media-actions .fav-total::before {
  content: '';
  display: inline-block;
  width: 1rem;
  height: 1rem;
  background: currentColor;
  -webkit-mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78z"/></svg>') center / contain no-repeat;
          mask: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78z"/></svg>') center / contain no-repeat;
}

.media-actions .fav-total[hidden] {
  display: none;
}

/* --- Mobile: compact tabs (icon-only), actions bar becomes scrollable --- */

@media (max-width: 45rem) {
  .media-dialog [role="tab"] span {
    display: none;
  }
  .media-dialog [role="tab"] {
    padding: var(--space-2);
  }
  .media-actions {
    overflow-x: auto;
    justify-content: center;
    scrollbar-width: none;
  }
  .media-actions button span {
    display: none;
  }
  .media-actions button {
    padding: var(--space-3);
  }
  .media-thumbs img {
    width: 3.5rem;
    height: 2.5rem;
  }
}

/* --- Overview Tab — Bento/Masonry Grid --- */

.media-overview {
  /* display:block überschreibt das .media-panel-Grid (1fr auto) — sonst landet das Bento-Grid in der
     1fr-Zeile und wird darin vertikal zentriert (Bilder „schweben" mittig). Der Overview hat keinen
     Footer, nur das scrollbare Grid → normaler Fluss von oben-links. */
  display: block;
  overflow-y: auto;
  padding: var(--space-3);
}

/* Echtes Grid statt column-count: die Kacheln sind durch aspect-ratio + object-fit
   ohnehin alle gleich hoch, ein Masonry-Umbruch bringt hier also nichts — kostete
   aber zwei Dinge. Erstens balanciert Multi-Column die Spaltenhöhen: bei 9 Bildern
   auf 4 Spalten passen ceil(9/4)=3 pro Spalte, die vierte Spalte blieb leer und das
   Raster nutzte nur 3/4 der Breite (je nach Bildanzahl mal so, mal so). Zweitens
   läuft die Lesereihenfolge dort spaltenweise statt zeilenweise. */
.bento-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
}

.bento-grid button {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  border-radius: var(--radius);
  background: none;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: opacity var(--transition);
}

.bento-grid button:hover {
  opacity: 0.85;
}

.bento-grid img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius);
}

/* <picture>-Wrapper layout-transparent → das <img> bleibt das Grid-Element. */
.bento-grid picture {
  display: contents;
}

/* :not(.media-ki-badge) — der KI-Badge ist ebenfalls ein direktes <span> des Buttons, darf aber NICHT das
   Caption-Overlay (bottom-left, scrim) erben, sonst spannt er top→bottom als hohe schwarze Fläche auf. */
/* ⚠ EINE Zeile, und die Breite ist begrenzt. Dieses Overlay war für Etiketten gedacht („Wohnzimmer");
   seit die Bildbeschreibungen aus der KI kommen, sind es ganze Sätze. Ohne `right` wächst die Pille
   frei, ohne Zeilenbegrenzung wird sie mehrzeilig — auf einer 4:3-Kachel ergab das eine schwarze
   Fläche über dem halben Bild, also über genau dem Motiv, das sie beschreibt (gemeldet 31.08.2026).
   Der VOLLE Text geht nicht verloren: er steht im alt-Attribut des Bildes und in der Einzelansicht. */
.bento-grid button > span:not(.media-ki-badge) {
  position: absolute;
  bottom: var(--space-2);
  left: var(--space-2);
  right: var(--space-2);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-inverse);
  background: var(--scrim-heavy);
  border-radius: var(--radius-media-overlay);
  text-align: center;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 79.499rem) {
  .bento-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 44.999rem) {
  .bento-grid { grid-template-columns: repeat(2, 1fr); }
  /* Zwei Spalten auf dem Handy = knapp 10 rem je Kachel. Dort ist von einem Satz ohnehin nur ein
     Wortfragment lesbar, es verdeckt aber das ganze Motiv. Die Beschreibung steht in der
     Einzelansicht (Tab „Bilder") und im alt-Text — hier hilft sie niemandem. */
  .bento-grid button > span:not(.media-ki-badge) { display: none; }
}
