/* Mapbox GL Map Styles */

/* touch-action: none stops the browser's own native pinch-to-zoom/pan
   from engaging on the map area. Without it, a pinch gesture is handled
   by BOTH the browser (scaling the whole page visually) and Mapbox GL
   (re-rendering the canvas + repositioning marker transforms) at the
   same time; the two fight over the gesture and markers visibly drift/
   snap relative to the map during and right after zooming or pinching. */
#map {
  width: 100%;
  height: 100vh;
  position: relative;
  touch-action: none;
}

.mapboxgl-canvas {
  display: block;
}

/* Map Container */
.map-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  touch-action: none;
}

/* Custom Marker Styles.
   No `position` here - mapbox-gl.css's own `.mapboxgl-marker` rule (loaded
   before this file) sets `position: absolute` on this exact element so
   Mapbox's translate() is measured from the map container's top-left
   corner. This file used to also declare `position: relative` here with
   the same specificity (single class) but later in source order, so it
   won the cascade and silently replaced "absolute" with "relative" -
   every marker div then took part in normal document flow (stacking
   top-to-bottom in the left column of #map) and Mapbox's translate(x,y)
   was applied on top of THAT stacked position instead of (0,0). At most
   zoom levels the resulting drift was small enough to miss, but it grew
   with zoom until the markers visibly lined up in a vertical column.
   `.decoration` (trees) never had this override, which is why they were
   never affected. */
.marker {
  --marker-color: #999999;
  --marker-scale: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(36px * var(--marker-scale));
  height: calc(36px * var(--marker-scale));
  border-radius: 50%;
  background: color-mix(in srgb, var(--marker-color) 18%, white);
  border: 3px solid var(--marker-color);
  cursor: pointer;
  transition: width var(--transition-base), height var(--transition-base), box-shadow var(--transition-base);
  box-shadow: var(--shadow-md);
}

.marker:hover {
  box-shadow: var(--shadow-lg);
  z-index: 5;
}

.marker.active {
  box-shadow: var(--shadow-lg);
  z-index: 5;
}

/* Marker Icons - sized relative to the marker so --marker-scale affects both.
   Hover/active "grow" effect lives HERE (on the inner icon), never on the
   .marker root: that root is the exact DOM node Mapbox positions via its
   own inline `transform` on every pan/zoom/frame, so any transform we
   declared on it got fought over and visibly reset mid-gesture. */
.marker-icon {
  width: 60%;
  height: 60%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform var(--transition-base);
}

.marker:hover .marker-icon,
.marker.active .marker-icon {
  transform: scale(1.2);
}

.marker-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
}

/* Marker States */
.marker.hidden {
  display: none;
}

/* Decorations (trees etc.) don't share the .marker class, so the shared
   .hidden toggle (used both for zoom-based auto-hide and the "Bäume"
   filter) needs its own rule here - without it, adding .hidden to a
   decoration element silently did nothing and trees never disappeared. */
.decoration.hidden,
.decoration-logo.hidden {
  display: none;
}

/* Stacked cluster marker (ClusterManager) - just the member count, no icon:
   at this zoomed-out distance the individual icon reads as noise, the
   number is what's actually useful. Kept as a `.marker` variant so it
   inherits the same circle/border/hover styling as a regular marker. */
.marker-cluster {
  width: calc(36px * var(--marker-scale));
  height: calc(36px * var(--marker-scale));
}

.marker-cluster-count {
  color: var(--marker-color);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
}

.marker.inactive {
  opacity: 0.4;
  pointer-events: none;
}

/* Decorations (trees etc.) - purely visual, never intercept clicks.
   No transform on these root elements: each one IS the DOM node passed
   to `new mapboxgl.Marker({element: ...})`, and Mapbox sets its own
   positioning `transform` on it directly via inline style on every pan/
   zoom. A CSS transform declared on the same element fights that inline
   style and visibly "resets"/jumps mid-gesture. Scale/rotate is applied
   to the inner .decoration-icon child instead, which Mapbox never touches. */
.decoration {
  width: 46px;
  height: 52px;
  pointer-events: none;
}

/* Wordmark/logo decoration - wide aspect ratio instead of the square-ish
   tree box, e.g. for placing "Weinturm Open Air" as a title on the map */
.decoration-logo {
  width: 240px;
  height: 52px;
  pointer-events: none;
}

.decoration-icon {
  width: 100%;
  height: 100%;
}

.decoration .decoration-icon {
  transform: scale(var(--decoration-scale, 1)) rotate(var(--decoration-rotation, 0deg));
  transform-origin: bottom center;
}

.decoration-logo .decoration-icon {
  transform: scale(var(--decoration-scale, 1)) rotate(var(--decoration-rotation, 0deg));
  transform-origin: center center;
}

.decoration-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.12));
}

/* Popup Styles */
.mapboxgl-popup {
  max-width: 400px;
}

.mapboxgl-popup-content {
  padding: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  background: var(--color-bg-primary);
}

.popup {
  overflow: hidden;
}

.popup-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: var(--spacing-md);
  border-bottom: 1px solid var(--color-border);
  gap: var(--spacing-md);
}

.popup-header h3 {
  margin: 0;
  font-size: 1.1rem;
  flex: 1;
}

.popup-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--color-text-secondary);
  transition: color var(--transition-base);
  flex-shrink: 0;
}

.popup-close:hover {
  color: var(--color-text-primary);
}

.popup-image {
  width: 100%;
  height: 150px;
  object-fit: cover;
  display: block;
}

.popup-body {
  padding: var(--spacing-md);
}

.popup-description {
  margin: 0 0 var(--spacing-md) 0;
  font-size: 0.9rem;
  line-height: 1.4;
  color: var(--color-text-secondary);
}

.popup-details {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--spacing-md);
  margin: var(--spacing-md) 0;
  font-size: 0.85rem;
}

.popup-details dt {
  font-weight: 600;
  color: var(--color-text-primary);
}

.popup-details dd {
  margin: 0;
  color: var(--color-text-secondary);
}

.popup-footer {
  display: flex;
  gap: var(--spacing-sm);
  padding: var(--spacing-md);
  border-top: 1px solid var(--color-border);
}

.popup-footer .btn {
  flex: 1;
}

/* Map Controls */
.mapboxgl-ctrl-attrib {
  font-size: 0.75rem;
}

.map-control-group {
  position: absolute;
  bottom: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 10;
}

.map-control {
  width: 40px;
  height: 40px;
  background: white;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-md);
  transition: all var(--transition-base);
}

.map-control:hover {
  box-shadow: var(--shadow-lg);
  background: var(--color-bg-secondary);
}

/* Responsive Design */
@media (max-width: 768px) {
  #map {
    height: calc(100vh - 60px);
  }

  .mapboxgl-popup {
    max-width: 280px;
  }

  .popup-details {
    grid-template-columns: 1fr;
  }

  .map-control-group {
    bottom: 70px;
    right: 10px;
    gap: 5px;
  }

  .map-control {
    width: 36px;
    height: 36px;
  }
}

@media (max-width: 480px) {
  .mapboxgl-popup-content {
    font-size: 0.9rem;
  }

  .popup-header h3 {
    font-size: 1rem;
  }

  .popup-details {
    font-size: 0.8rem;
  }
}

/* Fade-in on marker creation - opacity only. A second .marker rule used
   to exist here with `transform: scale(...)` keyframes; that's the same
   "don't set transform on the Mapbox-positioned root element" mistake
   fixed elsewhere in this file, just missed here. Whenever this ran
   (marker creation, and again every time a filter toggle un-hides a
   marker, since display:none -> block restarts CSS animations) it
   fought Mapbox's own positioning transform for 300ms, and starting to
   pan/zoom during that window made markers visibly jump. Opacity alone
   can't conflict with anything. */
.marker {
  animation: markerAppear 0.3s ease-out;
}

@keyframes markerAppear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.popup-footer .btn-primary {
  color: #fff;

}

/* Live navigation status bar (NavigationManager) */
.nav-status-bar {
  position: fixed;
  left: 50%;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  max-width: calc(100vw - 40px);
  padding: var(--spacing-sm) var(--spacing-md);
  background: #fff;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  font-size: 0.9rem;
  color: var(--color-text-primary);
}

.nav-status-bar.nav-status-arrived {
  background: #eaf6ea;
}

.nav-status-bar.nav-status-error {
  background: #fdeceb;
  color: #b3261e;
}

.nav-status-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav-status-close {
  flex-shrink: 0;
  border: none;
  background: var(--color-bg-secondary);
  color: inherit;
  border-radius: var(--radius-sm);
  padding: 4px 10px;
  font-size: 0.8rem;
  cursor: pointer;
}

@media (max-width: 480px) {
  .nav-status-bar {
    left: 12px;
    right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    transform: none;
    max-width: none;
  }
}

/* Loading State */
.map-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;
  display: none;
}

.map-loading.active {
  display: block;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
