/* ═══════════════════════════════════════════════════════════════════════════
   lupe-button.css – Goldene Lupe (v1.0.1)
   /css/ | MoAktor

   Zwei Bereiche:
     1. Button-Icon-Fallback (delegiert Basis an .qa-public-btn aus qa-button.css)
     2. Das schwebende Lupen-Widget (Klon im Glas, Badge, Pfeile)

   Das Widget wird von /js/modules/lupe.js zur Laufzeit in den <body>
   gehängt. Es ist fixed positioniert und folgt dem Mauszeiger bzw.
   Finger — es ist KEIN Modal und hat KEIN aura-modal.

   ── Changelog ───────────────────────────────────────────────────────
   v1.0.1 | 11.10.2026 | Selektor-Fix für body-Klasse.
          |
          |             Der Selektor `body.lupe-open #lupeBtn` (aus
          |             v1.0.0) matche nie — lupe.js v1.0.3 hatte im
          |             Rahmen der L-8-Härtung die body-Klasse auf
          |             `moaktor-lupe-open` umgestellt (Namespace-
          |             Präfix für Ökosystem-Konsistenz), das CSS war
          |             nicht mitgezogen worden.
          |
          |             Folge: Der Toggle-Button wurde bei geöffneter
          |             Lupe nicht über das Widget gehoben. Auf
          |             Viewports, in denen Button und Widget sich
          |             überlagern, lag der Button hinter dem Widget —
          |             der Nutzer konnte die Lupe nur noch über Escape
          |             oder einen Klick außerhalb des Widgets schließen.
          |
          |             Fix: Selektor auf `body.moaktor-lupe-open
          |             #lupeBtn` umgestellt.
          |
          |             Keine weiteren Änderungen gegenüber v1.0.0.
   v1.0.0 | Portierung aus dem v1.14-Prototyp. Alle Funktionen des
          | Standalone-Widgets erhalten: Klon mit CSS-Transform,
          | Auto-Kalibrierung des Glaskreises, Firefox-Flicker-Fix
          | (Clip und Transform auf getrennte Ebenen), Badge mit
          | +/− Buttons, Doppeltipp-Reset, Auto-Hide, Badge-Flip am
          | Viewport-Rand, Zwischenablage-freundliche sr-only-Region.
          |
          | Änderungen gegenüber v1.14:
          |   * Klassennamen von .lens* auf .lupe* umgestellt
          |     (Konsistenz zur deutschen Modul-Benennung im Ökosystem).
          |   * CSS-Variablen von --lens-size auf --lupe-size.
          |   * .lupe__badge nutzt visibility + transition-delay beim
          |     Ausblenden — die Badge-Buttons sind damit außerhalb
          |     des Sichtbarkeitsfensters NICHT tab-fokussierbar
          |     (A11y-Fix gegenüber v1.14).
          |   * body.lupe-open #lupeBtn hebt den Toggle-Button über
          |     das geöffnete Widget, damit Schließen immer klickbar
          |     bleibt — unabhängig von der Position des Widgets.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════
   1 · BUTTON-ICON
   ══════════════════════════════════════════════════════════════════════════ */

.lupe-btn-icon,
.lupe-btn-icon-fallback {
  width: 26px;
  height: 26px;
  object-fit: contain;
  display: block;
}
.lupe-btn-icon-fallback {
  display: none;
  color: #d4af37;
}
#lupeBtn.lupe-img-broken .lupe-btn-icon { display: none; }
#lupeBtn.lupe-img-broken .lupe-btn-icon-fallback { display: block; }

/* Toggle-Button über das geöffnete Widget heben.
   v1.0.1: Selektor auf `body.moaktor-lupe-open` korrigiert — die
   Klasse wurde in lupe.js v1.0.3 (L-8) umbenannt, das CSS war nicht
   mitgezogen. */
body.moaktor-lupe-open #lupeBtn {
  z-index: 99999;
}

/* ══════════════════════════════════════════════════════════════════════════
   2 · WIDGET
   ══════════════════════════════════════════════════════════════════════════ */

.lupe {
  position: fixed;
  top: 0;
  left: 0;
  width: var(--lupe-size, clamp(320px, 70vmin, 580px));
  height: var(--lupe-size, clamp(320px, 70vmin, 580px));

  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  z-index: 8000;
  transition: opacity .2s ease, visibility 0s linear .2s;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;

  /* Kalibrierungswerte — vom JS nach autoCalibrate() überschrieben */
  --glass-cx: 48%;
  --glass-cy: 46%;
  --glass-d:  76%;

  --gold: #f4c542;
  --gold-soft: rgba(244,197,66,.6);
  --gold-soft-hover: rgba(244,197,66,.18);
  --gold-soft-active: rgba(244,197,66,.32);
  --gold-arrow: rgba(244,197,66,.75);
  --gold-strong: rgba(244,197,66,.95);
}

.lupe.is-active {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  transition: opacity .2s ease, visibility 0s;
  will-change: transform, opacity;
}
.lupe.is-dragging { cursor: grabbing; }

/* Ebene 1 · skaliert beim Öffnen */
.lupe__viewport {
  position: absolute;
  left: 0; top: 0;
  width: 0; height: 0;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  box-shadow: inset 0 0 24px rgba(0,0,0,.28);
  transform: translateZ(0) scale(.35);
  transition: transform .34s cubic-bezier(.34,1.56,.64,1);
  will-change: transform;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.lupe.is-active .lupe__viewport { transform: translateZ(0) scale(1); }

/* Ebene 2 · statischer Clip-Wrapper (Firefox-Fix) */
.lupe__clip {
  position: absolute;
  inset: 0;
  clip-path: circle(50% at 50% 50%);
  -webkit-clip-path: circle(50% at 50% 50%);
  overflow: hidden;
  will-change: clip-path;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/* Ebene 3 · transformierter Klon */
.lupe__content {
  position: absolute;
  top: 0; left: 0;
  width: 0; height: 0;
  transform-origin: 0 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  will-change: transform;
}

/* Goldene Fassung */
.lupe__frame {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: contain; display: block;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  filter: drop-shadow(0 16px 30px rgba(0,0,0,.38));
  transform: scale(.35);
  transform-origin: center;
  transition: transform .34s cubic-bezier(.34,1.56,.64,1);
}
.lupe.is-active .lupe__frame { transform: scale(1); }

/* ── Badge ────────────────────────────────────────────────────────────
   visibility (nicht nur opacity) verhindert, dass die Badge-Buttons
   bei unsichtbarer Badge per Tab erreichbar sind. */
.lupe__badge {
  position: absolute;
  left: 0; top: 0;
  transform: translate(-50%, 6px);
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 4px;
  border-radius: 999px;
  color: #fff;
  background: linear-gradient(180deg, #2b2b2e, #131315);
  border: 1px solid var(--gold-soft);
  box-shadow: 0 6px 18px rgba(0,0,0,.4);
  white-space: nowrap;
  font: 600 12px/1.4 ui-monospace, "SF Mono", monospace;
  letter-spacing: .02em;

  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .4s ease, transform .4s cubic-bezier(.22,1,.36,1),
              border-color .2s ease, visibility 0s linear .4s;
  will-change: opacity, transform;
  -webkit-tap-highlight-color: transparent;
}
.lupe__badge.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  pointer-events: auto;
  cursor: ew-resize;
  touch-action: none;
  transition: opacity .4s ease, transform .4s cubic-bezier(.22,1,.36,1),
              border-color .2s ease, visibility 0s;
}
.lupe__badge.is-dragging {
  transform: translate(-50%, 0) scale(1.06);
  border-color: var(--gold-strong);
}
.lupe__badge.is-flipped {
  transform: translate(-50%, calc(-100% - 6px));
}
.lupe__badge.is-flipped.is-visible {
  transform: translate(-50%, -100%);
}
.lupe__badge.is-flipped.is-dragging {
  transform: translate(-50%, -100%) scale(1.06);
}

/* Pfeile */
.lupe__badge::before,
.lupe__badge::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 0; height: 0;
  pointer-events: none;
  transition: opacity .25s ease;
}
.lupe__badge::before {
  right: calc(100% + 6px);
  transform: translateY(-50%);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-right: 7px solid var(--gold-arrow);
}
.lupe__badge::after {
  left: calc(100% + 6px);
  transform: translateY(-50%);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 7px solid var(--gold-arrow);
}
.lupe__badge[data-bound="min"]::before { opacity: .15; }
.lupe__badge[data-bound="max"]::after  { opacity: .15; }

/* +/− Buttons */
.lupe__badge-btn {
  width: 24px; height: 24px;
  display: grid; place-items: center;
  padding: 0; margin: 0;
  border: 0; border-radius: 50%;
  background: transparent;
  color: #fff;
  font: 700 15px/1 ui-monospace, "SF Mono", monospace;
  cursor: pointer;
  transition: background .15s ease, transform .12s ease;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
}
.lupe__badge-btn:hover { background: var(--gold-soft-hover); }
.lupe__badge-btn:active { background: var(--gold-soft-active); transform: scale(.92); }
.lupe__badge-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

.lupe__badge-value {
  display: inline-block;
  min-width: 44px;
  padding: 0 4px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* Reset-Puls (zwei Varianten wegen Badge-Flip) */
@keyframes lupe-reset-pulse {
  0%   { transform: translate(-50%, 0) scale(1);    border-color: var(--gold-soft); }
  45%  { transform: translate(-50%, 0) scale(1.28); border-color: #fff6c2; }
  100% { transform: translate(-50%, 0) scale(1);    border-color: var(--gold-soft); }
}
@keyframes lupe-reset-pulse-flip {
  0%   { transform: translate(-50%, -100%) scale(1);    border-color: var(--gold-soft); }
  45%  { transform: translate(-50%, -100%) scale(1.28); border-color: #fff6c2; }
  100% { transform: translate(-50%, -100%) scale(1);    border-color: var(--gold-soft); }
}
.lupe__badge.is-resetting {
  animation: lupe-reset-pulse .4s cubic-bezier(.34,1.56,.64,1);
}
.lupe__badge.is-flipped.is-resetting {
  animation: lupe-reset-pulse-flip .4s cubic-bezier(.34,1.56,.64,1);
}

/* SR-only Live-Region */
.lupe__sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .lupe,
  .lupe__frame,
  .lupe__viewport,
  .lupe__badge { transition-duration: .01ms !important; }
  .lupe__badge.is-resetting,
  .lupe__badge.is-flipped.is-resetting { animation-duration: .01ms !important; }
}