/* style-gui-waves.css — GUI-Wellen 1-3 Components
 * Extrahiert aus style.css (Round 53 Phase 3, v231).
 * 
 * Diese Datei lebt komplett in @layer components, das in style.css
 * mit @layer state-pre, reset, base, components, utilities; deklariert
 * wird. Damit gewinnt diese Datei automatisch über base, wenn nötig.
 * 
 * Wichtig: Diese Datei MUSS NACH style.css geladen werden, damit die
 * Layer-Reihenfolge greift. Im HTML: zwei <link rel="stylesheet">-Tags.
 */

/* ============================================================
   GUI-WELLE 1 (Round 47, v205): State-Layers + Toast-Upgrade + Reduced-Motion
   Diese Komponenten leben bewusst in `@layer components`, damit sie `base`
   ohne Specificity-Eskalation überstimmen können.
   ============================================================ */

@layer components {
  /* ---------- State-Layers ----------
     Setzen wir auf alle gängigen interaktiven Elemente. Ein ::before-Overlay
     ergibt sich mit der state-layer-color (rgb-Triplett im :root) und Opacity-
     Variablen. Macht Hover/Active/Focus überall konsistent ohne Background-Farbe
     ändern zu müssen — funktioniert auf gefärbten Buttons (.btn-approve etc.)
     UND auf neutralen Buttons gleich. */
  /* WICHTIG: .tab ist NICHT in dieser Liste! Tabs haben eigene ::after-Active-
     Animation und nutzen ::before bereits für das data-icon-Symbol. State-Layer
     auf Tab würde das Emoji überschreiben (Round 49-Bug fix).
     Position-Setter ist im SEPARATEN niedrig-priorisierten Layer (state-pre) — siehe
     unten am Ende der Datei. Cascade-Layer-Order (`@layer state-pre, reset, base, ...`)
     macht state-pre zur niedrigsten Schicht, damit `.feedback-fab { position: fixed }`
     aus base gewinnt. Specificity hilft hier nicht weil Layer-Reihenfolge über
     Specificity geht. Round 49 Hotfix v211. */
  :is(button:not(:disabled):not(.tab), .btn, .btn-approve, .btn-reject, .admin-tab,
      .lead-actions button, .pill, .calc-pill,
      .region-pill, .recent-spot-pill, .template-tab, .role-select,
      .spot-tab, .achievement-card, a.lv2-btn-primary, a.lv2-btn-secondary)::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: rgb(var(--state-layer-color));
    opacity: 0;
    pointer-events: none;
    transition: opacity 120ms ease;
    z-index: -1;
  }
  /* Hover-States NUR auf Devices mit echtem Hover (Maus/Trackpad).
     Touch-Geräte würden sonst nach Tap einen „stuck hover" zeigen, bis User
     woanders hin tippt — wirkt buggy. (hover: hover) ist die saubere Detection. */
  @media (hover: hover) {
    :is(button:not(:disabled):not(.tab), .btn, .btn-approve, .btn-reject, .admin-tab,
        .lead-actions button, .pill, .calc-pill,
        .region-pill, .recent-spot-pill, .template-tab,
        .spot-tab, .achievement-card, a.lv2-btn-primary, a.lv2-btn-secondary):hover::before {
      opacity: var(--state-hover-opacity);
    }
    .spot-card[role="button"]:hover::before,
    .spot-card.clickable:hover::before,
    .trip-card:hover::before,
    .recent-spot-pill:hover::before {
      opacity: calc(var(--state-hover-opacity) * 0.6);
    }
  }
  /* :active und :focus-visible bleiben für alle Geräte aktiv —
     :active ist Press-Feedback (gewollt auf Touch), :focus-visible nur Keyboard. */
  :is(button:not(:disabled):not(.tab), .btn, .btn-approve, .btn-reject, .admin-tab,
      .lead-actions button, .pill, .calc-pill,
      .region-pill, .recent-spot-pill, .template-tab,
      .spot-tab, .achievement-card, a.lv2-btn-primary, a.lv2-btn-secondary):active::before {
    opacity: var(--state-active-opacity);
    transition-duration: 60ms;
  }
  :is(button:not(:disabled):not(.tab), .btn, .btn-approve, .btn-reject, .admin-tab,
      .lead-actions button, .pill, .calc-pill,
      .region-pill, .recent-spot-pill, .template-tab,
      .spot-tab, .achievement-card, a.lv2-btn-primary, a.lv2-btn-secondary):focus-visible::before {
    opacity: var(--state-focus-opacity);
  }

  /* ---------- Skeleton Reduced-Motion-Override ----------
     User mit prefers-reduced-motion (häufig bei Sehbehinderungen, Migräne, oder
     bewusst gewählt im OS) bekommen statt der Shimmer-Animation einen statischen
     Grau-Block. Verhindert dass die App buggy wirkt oder Beschwerden auslöst. */
  @media (prefers-reduced-motion: reduce) {
    .skeleton {
      animation: none !important;
      background: var(--cream-dark) !important;
    }
  }

  /* ---------- Toast-System Upgrade ----------
     Stacking-Container unten links. Mehrere Toasts werden vertikal gestapelt.
     Variants: success/error/warning/info. Auto-Dismiss-Bar zeigt Progress.
     Die alte vcToast bleibt rückwärtskompatibel — diese Klassen sind additiv. */
  .vc-toast-stack {
    position: fixed;
    bottom: 24px;
    left: 24px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    z-index: 99999;
    pointer-events: none;
    max-width: min(420px, calc(100vw - 48px));
  }
  .vc-toast {
    background: var(--text);
    color: var(--cream);
    border-radius: 10px;
    padding: 12px 16px;
    box-shadow: var(--elev-3);
    display: flex;
    align-items: center;
    gap: 12px;
    pointer-events: auto;
    transform: translateX(-110%);
    opacity: 0;
    transition: transform 240ms cubic-bezier(0.34, 1.56, 0.64, 1),
                opacity 240ms ease;
    overflow: hidden;
    position: relative;
    min-height: 48px;
  }
  .vc-toast.vc-toast-in {
    transform: translateX(0);
    opacity: 1;
  }
  .vc-toast.vc-toast-out {
    transform: translateX(-110%);
    opacity: 0;
  }
  .vc-toast-icon {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
  }
  .vc-toast-msg {
    flex: 1;
    min-width: 0;
    font-size: 0.88rem;
    line-height: 1.45;
    word-wrap: break-word;
  }
  .vc-toast-action {
    flex-shrink: 0;
    background: transparent;
    border: 1px solid rgba(255,255,255,0.3);
    color: inherit;
    padding: 5px 12px;
    border-radius: 6px;
    font-size: 0.82rem;
    cursor: pointer;
    font-weight: 600;
    transition: background 120ms;
  }
  .vc-toast-action:hover { background: rgba(255,255,255,0.12); }
  .vc-toast-close {
    flex-shrink: 0;
    background: transparent;
    border: none;
    color: inherit;
    cursor: pointer;
    font-size: 1.1rem;
    opacity: 0.6;
    padding: 0 4px;
    line-height: 1;
  }
  .vc-toast-close:hover { opacity: 1; }
  .vc-toast-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 3px;
    background: currentColor;
    opacity: 0.5;
    transform-origin: left;
    animation: vc-toast-progress var(--vc-toast-duration, 4000ms) linear forwards;
  }
  @keyframes vc-toast-progress {
    from { transform: scaleX(1); }
    to   { transform: scaleX(0); }
  }
  /* Variant-Farben */
  .vc-toast.vc-toast-success { background: #1e6b3a; color: #fff; }
  .vc-toast.vc-toast-error   { background: #b91c1c; color: #fff; }
  .vc-toast.vc-toast-warning { background: #b45309; color: #fff; }
  .vc-toast.vc-toast-info    { background: var(--forest); color: var(--cream); }

  @media (prefers-reduced-motion: reduce) {
    .vc-toast {
      transition: opacity 120ms ease;
      transform: none;
    }
    .vc-toast-progress { animation: none; opacity: 0.3; }
  }

  /* ---------- Elevation-Anwendung auf Standard-Container ----------
     Standardisiert die bisherigen Schatten auf das neue Token-System.
     Bestehende Komponenten nutzen weiterhin --shadow / --shadow-lg via base —
     diese hier ist additive Politur für neue Komponenten. Plus ein Override
     für Modals, damit alle Modal-Backdrops konsistent sind. */
  .modal {
    box-shadow: var(--elev-3);
  }
  .modal-overlay > .modal,
  .modal-overlay > div {
    box-shadow: var(--elev-3);
  }

  /* ============================================================
     GUI-WELLE 2 (Round 48, v206): Mobile-First-UX
     ============================================================ */

  /* ---------- Tab-Icons als data-icon (für Stack-Layout Mobile) ----------
     Desktop: Icon vor Text mit gap. Mobile: Icon über Text als Stack. */
  .tabs .tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
  }
  .tabs .tab[data-icon]::before {
    content: attr(data-icon);
    font-size: 1.05em;
    line-height: 1;
  }

  /* ---------- Mobile Bottom-Tab-Bar (≤ 640px) ----------
     Tabs werden zur fixierten Bottom-Bar, thumb-friendly. Icons gross,
     Labels klein. Active-Indicator wandert nach OBEN damit er sichtbar
     bleibt. Content + Map bekommen padding-bottom damit nichts verdeckt
     wird. Safe-Area-Inset für iPhone X+.
     v238: explizit width:100% + max-width + border-radius:0 + margin:0 als
     Defense-in-Depth gegen mögliche Inheritance/Override-Konflikte
     (User-Report v237: Tab-Bar erschien als zentrierter rounded Container). */
  @media (max-width: 640px) {
    .tabs {
      position: fixed !important;
      bottom: 0 !important;
      left: 0 !important;
      right: 0 !important;
      top: auto !important;
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
      background: var(--cream);
      border-top: 1px solid var(--cream-dark);
      border-bottom: none;
      border-radius: 0 !important;
      box-shadow: 0 -2px 12px rgba(0,0,0,0.06);
      z-index: 100;
      gap: 0;
      display: flex;
    }
    .tabs .tab {
      flex: 1 1 0 !important;  /* alle Tabs gleich breit; min-width:0 erlaubt shrink */
    }
    .tabs .tab {
      flex-direction: column;
      gap: 2px;
      font-size: 0.65rem;
      padding: 6px 2px;
      font-weight: 500;
      min-width: 0;
    }
    .tabs .tab[data-icon]::before {
      font-size: 1.4rem;
      margin: 0 0 1px;
    }
    .tabs .tab::after {
      top: -2px;
      bottom: auto;
      height: 3px;
      left: 18%;
      right: 18%;
    }
    .tabs .tab.active::after { transform: scaleX(1); }

    /* Bottom-Tab-Bar verdeckt sonst die letzten Pixel. Body-padding-bottom statt
     content-padding-bottom — der Legal-Footer (am Body-Ende) wird so direkt vor
     der Bar gerendert, kein Weißraum-Gap. Wert (52px) ≈ Bar-Höhe.
     Round 49 Hotfix v214, ersetzt das alte 60px-content-padding. */
    body {
      padding-bottom: calc(52px + env(safe-area-inset-bottom));
    }
    .spots-content { padding-bottom: 0; }
    #map { padding-bottom: 0; }
    /* Floating Action Button (FAB) muss über der Bottom-Bar bleiben.
       Auf Mobile braucht's mehr Abstand damit FAB nicht mit Footer/Copyright
       konkurriert. Side-Padding auch hoch damit der FAB nicht am Rand klebt. */
    .vc-fab {
      bottom: calc(80px + env(safe-area-inset-bottom)) !important;
      right: 16px !important;
      width: 52px !important;
      height: 52px !important;
    }
    .vc-fab svg { width: 22px; height: 22px; }
    /* Feedback-FAB wird auf Mobile in das User-Dropdown verschoben (siehe app.html
       #menu-feedback). Hier hidden — verhindert Visual-Clutter zur Bottom-Tab-Bar
       und Locate-FAB. Round 49 Hotfix v213. */
    .feedback-fab { display: none !important; }
    .dropdown-item-mobile-only { display: flex !important; }
  }
  /* Auf Desktop: Mobile-only-Dropdown-Item ausblenden, Feedback-FAB bleibt sichtbar */
  @media (min-width: 641px) {
    .dropdown-item-mobile-only { display: none !important; }
  }

  /* ---------- Legal-Footer (Round 49 Hotfix v215) ----------
     Sticky-Footer-Pattern: body als flex-column mit min-height:100vh, Footer
     mit margin-top:auto → klebt am Boden des Content-Bereichs. Auf Mobile
     sitzt er damit direkt über der fixed Bottom-Tab-Bar (body-padding-bottom),
     auf Desktop direkt am Viewport-Boden. KEIN Whitespace-Gap mehr.
     Kompakt: padding minimal, font-size klein. */
  body {
    display: flex;
    flex-direction: column;
  }
  .legal-footer {
    margin-top: auto;
    text-align: center;
    padding: 5px 8px;
    font-size: 0.72rem;
    color: var(--text-muted);
    border-top: 1px solid var(--cream-dark);
    background: var(--cream);
  }
  .legal-footer a {
    color: var(--text-muted);
    margin: 0 6px;
  }
  .legal-footer-version {
    opacity: 0.45;
    margin-left: 8px;
    font-variant-numeric: tabular-nums;
  }
  @media (max-width: 640px) {
    .legal-footer {
      padding: 3px 8px;
      font-size: 0.66rem;
      line-height: 1.4;
    }
    .legal-footer a { margin: 0 4px; }
    .legal-footer-version { margin-left: 6px; font-size: 0.6rem; }
  }

  /* ---------- Floating Action Button (FAB) ----------
     Bottom-right Locate-Button auf der Karte. Auf Desktop + Mobile.
     State-Layer-fähig (über bestehende ::before-Regel weiter oben).
     Pulse-Animation bei Locate-Aktion. */
  .vc-fab {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: none;
    background: var(--campfire);
    color: #fff;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: var(--elev-3);
    z-index: 500;
    transition: transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1),
                box-shadow 200ms ease;
  }
  .vc-fab svg {
    display: block;
    color: #fff;
    stroke: currentColor;
  }
  .vc-fab:hover { transform: scale(1.06); box-shadow: var(--elev-4); }
  .vc-fab:active { transform: scale(0.96); }
  .vc-fab[hidden] { display: none !important; }
  .vc-fab.loading { animation: vc-fab-pulse 1.2s ease-in-out infinite; }
  @keyframes vc-fab-pulse {
    0%, 100% { transform: scale(1); box-shadow: var(--elev-3); }
    50%      { transform: scale(1.08); box-shadow: var(--elev-4); }
  }
  @media (prefers-reduced-motion: reduce) {
    .vc-fab, .vc-fab:hover, .vc-fab:active { transform: none; }
    .vc-fab.loading { animation: none; opacity: 0.7; }
  }

  /* ---------- Bottom-Sheet-Look für Modals auf Mobile ----------
     ≤ 640px: das Spot-Detail-Modal (+ andere Vollbild-Modals) docken unten
     mit abgerundeten Top-Corners + Drag-Handle-Visualisierung. KEIN echtes
     Drag in v1 — nur Looks, damit's vertraut wirkt. Schließen via Backdrop-
     Tap (modalHardening) oder Close-Button. */
  @media (max-width: 640px) {
    .modal-overlay > .modal,
    .modal-overlay > div {
      position: fixed;
      bottom: 0;
      left: 0;
      right: 0;
      top: auto;
      width: 100% !important;
      max-width: 100% !important;
      max-height: 92vh;
      border-radius: 20px 20px 0 0 !important;
      animation: vc-bottom-sheet-in 280ms cubic-bezier(0.34, 1.56, 0.64, 1);
      padding-top: 28px !important; /* Platz für Drag-Handle */
    }
    .modal-overlay > .modal::before,
    .modal-overlay > div::before {
      content: "";
      position: absolute;
      top: 10px;
      left: 50%;
      transform: translateX(-50%);
      width: 44px;
      height: 4px;
      border-radius: 2px;
      background: var(--text-muted);
      opacity: 0.35;
      pointer-events: none;
    }
  }
  @keyframes vc-bottom-sheet-in {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .modal-overlay > .modal,
    .modal-overlay > div { animation: none; }
  }

  /* ---------- Inline-Validation in Forms ----------
     Defensive: wird nur auf Inputs angewendet die das data-validate-Attribut
     haben (opt-in). Andere Inputs bleiben unverändert. */
  input[data-validate].invalid,
  textarea[data-validate].invalid,
  select[data-validate].invalid {
    border-color: var(--danger) !important;
    background-color: rgba(192, 57, 43, 0.04);
  }
  input[data-validate].valid,
  textarea[data-validate].valid,
  select[data-validate].valid {
    border-color: var(--success) !important;
  }
  .form-hint {
    display: block;
    font-size: 0.78rem;
    color: var(--text-muted);
    margin-top: 4px;
    line-height: 1.4;
  }
  .form-hint.form-hint-error {
    color: var(--danger);
    font-weight: 500;
  }
  .form-hint.form-hint-success {
    color: var(--success);
  }

  /* ---------- Command-Palette (Cmd+K / Ctrl+K) ----------
     WICHTIG: [hidden]-Override muss explizit sein, weil .vc-cmdk-overlay
     mit `display: flex` sonst das Browser-Default `[hidden] { display: none }`
     überschreibt (höhere Specificity). Ohne das wäre das Modal beim Laden
     dauerhaft sichtbar — Round 49 Bug aus erstem Deploy. */
  .vc-cmdk-overlay[hidden] { display: none !important; }
  .vc-cmdk-overlay {
    position: fixed;
    inset: 0;
    background: rgba(45,74,62,0.45);
    z-index: 99998;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 80px 20px 20px;
    backdrop-filter: blur(6px);
    animation: vc-dialog-fade 160ms ease;
  }
  .vc-cmdk-box {
    background: var(--white);
    border: 1px solid var(--cream-dark);
    border-radius: 14px;
    width: 100%;
    max-width: 560px;
    box-shadow: var(--elev-4);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 100px);
  }
  .vc-cmdk-input {
    border: none;
    border-bottom: 1px solid var(--cream-dark);
    padding: 16px 20px;
    font-size: 1rem;
    background: transparent;
    color: var(--text);
    outline: none;
    font-family: inherit;
  }
  .vc-cmdk-input::placeholder { color: var(--text-muted); }
  .vc-cmdk-list {
    overflow-y: auto;
    padding: 6px 0;
  }
  .vc-cmdk-group-label {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 10px 20px 4px;
  }
  .vc-cmdk-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 20px;
    cursor: pointer;
    font-size: 0.92rem;
    color: var(--text);
    transition: background 80ms ease;
  }
  .vc-cmdk-item:hover,
  .vc-cmdk-item.active {
    background: rgba(232, 115, 26, 0.10);
  }
  .vc-cmdk-icon {
    font-size: 1.1rem;
    line-height: 1;
    width: 22px;
    flex-shrink: 0;
    text-align: center;
  }
  .vc-cmdk-label { flex: 1; min-width: 0; }
  .vc-cmdk-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
    flex-shrink: 0;
  }
  .vc-cmdk-empty {
    padding: 20px;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.88rem;
  }
  .vc-cmdk-footer {
    border-top: 1px solid var(--cream-dark);
    padding: 8px 16px;
    font-size: 0.72rem;
    color: var(--text-muted);
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
  }
  .vc-cmdk-kbd {
    background: var(--cream);
    border: 1px solid var(--cream-dark);
    border-radius: 4px;
    padding: 1px 5px;
    font-family: ui-monospace, monospace;
    font-size: 0.7rem;
  }

  /* ============================================================
     GUI-WELLE 3 (Round 49, v207): Tab-Transitions, Onboarding, Year-in-Review
     ============================================================ */

  /* ---------- Page-Transitions via View-Transitions-API ----------
     Browser mit Support animieren beim Tab-Wechsel cross-fade.
     Default-Dauer ist 250ms — wir tunen auf 200ms für Snappiness.
     Vollständig progressive enhancement: ohne Support einfach instant-Switch. */
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 200ms;
    animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  }
  ::view-transition-old(root) {
    animation-name: vc-fade-out;
  }
  ::view-transition-new(root) {
    animation-name: vc-fade-in;
  }
  @keyframes vc-fade-out {
    to { opacity: 0; }
  }
  @keyframes vc-fade-in {
    from { opacity: 0; }
  }

  /* ---------- Onboarding-Tour (Welle 3 #14) ----------
     3-Slide-Modal beim Erstaufruf. Slide-Indicator unten, Skip + Next.
     Dismissable, localStorage-persistiert via vc-onboarding-seen. */
  .vc-onboarding-overlay {
    position: fixed;
    inset: 0;
    background: rgba(45, 74, 62, 0.55);
    z-index: 99997;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    backdrop-filter: blur(4px);
    animation: vc-dialog-fade 200ms ease;
  }
  .vc-onboarding-box {
    background: var(--white);
    border-radius: 18px;
    max-width: 440px;
    width: 100%;
    overflow: hidden;
    box-shadow: var(--elev-4);
    display: flex;
    flex-direction: column;
  }
  .vc-onboarding-slide {
    padding: 32px 28px 22px;
    text-align: center;
  }
  .vc-onboarding-emoji {
    font-size: 3.4rem;
    line-height: 1;
    margin-bottom: 12px;
  }
  .vc-onboarding-title {
    font-family: "Fraunces", Georgia, serif;
    font-size: 1.45rem;
    font-weight: 700;
    color: var(--forest);
    margin: 0 0 10px;
    line-height: 1.25;
  }
  .vc-onboarding-text {
    color: var(--text-light);
    font-size: 0.94rem;
    line-height: 1.55;
    margin: 0;
  }
  .vc-onboarding-dots {
    display: flex;
    gap: 8px;
    justify-content: center;
    padding: 16px 0;
  }
  .vc-onboarding-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--cream-dark);
    transition: background 200ms ease, width 200ms ease;
  }
  .vc-onboarding-dot.active {
    background: var(--campfire);
    width: 24px;
    border-radius: 4px;
  }
  .vc-onboarding-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 20px 20px;
    gap: 10px;
    border-top: 1px solid var(--cream-dark);
  }
  .vc-onboarding-skip {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.86rem;
    padding: 8px 12px;
    font-weight: 500;
  }
  .vc-onboarding-skip:hover { color: var(--text); }
  .vc-onboarding-next {
    background: var(--campfire);
    color: #fff;
    border: none;
    border-radius: 8px;
    padding: 10px 24px;
    font-weight: 700;
    cursor: pointer;
    font-size: 0.95rem;
  }
  .vc-onboarding-next:hover { background: var(--ember); }

  /* ---------- Year-in-Review Modal ----------
     Aggregierte Yearly-Stats als 4-Card-Grid. Trigger via Stats-Tab.
     Headline mit Sparkle-Icon und Jahr, dann Cards mit großen Zahlen. */
  .vc-yir-overlay {
    position: fixed;
    inset: 0;
    background: rgba(45, 74, 62, 0.5);
    z-index: 99996;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    backdrop-filter: blur(6px);
    animation: vc-dialog-fade 200ms ease;
  }
  .vc-yir-box {
    background: linear-gradient(135deg, var(--forest), var(--forest-light));
    color: #fff;
    border-radius: 20px;
    max-width: 520px;
    width: 100%;
    max-height: 92vh;
    overflow: auto;
    box-shadow: var(--elev-4);
    position: relative;
  }
  .vc-yir-close {
    position: absolute;
    top: 12px;
    right: 12px;
    background: rgba(255,255,255,0.18);
    border: none;
    color: #fff;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
  }
  .vc-yir-close:hover { background: rgba(255,255,255,0.28); }
  .vc-yir-header {
    padding: 36px 24px 12px;
    text-align: center;
  }
  .vc-yir-eyebrow {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    opacity: 0.75;
    margin-bottom: 6px;
  }
  .vc-yir-title {
    font-family: "Fraunces", Georgia, serif;
    font-size: 2rem;
    font-weight: 700;
    margin: 0 0 4px;
    line-height: 1.15;
  }
  .vc-yir-subtitle {
    opacity: 0.85;
    font-size: 0.95rem;
    margin: 0;
  }
  .vc-yir-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    padding: 20px 24px;
  }
  .vc-yir-card {
    background: rgba(255,255,255,0.10);
    border: 1px solid rgba(255,255,255,0.15);
    border-radius: 14px;
    padding: 18px 16px;
    text-align: center;
  }
  .vc-yir-card-emoji {
    font-size: 2rem;
    line-height: 1;
    margin-bottom: 6px;
    opacity: 0.9;
  }
  .vc-yir-card-value {
    font-family: "Fraunces", Georgia, serif;
    font-size: 1.85rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
  }
  .vc-yir-card-label {
    font-size: 0.78rem;
    opacity: 0.78;
    margin-top: 4px;
  }
  .vc-yir-card-wide {
    grid-column: span 2;
  }
  .vc-yir-foot {
    padding: 14px 24px 26px;
    text-align: center;
    border-top: 1px solid rgba(255,255,255,0.15);
    font-size: 0.82rem;
    opacity: 0.78;
  }

  /* ---------- Stats-Tab: Year-in-Review-Trigger-Button ---------- */
  .vc-yir-trigger {
    margin: 18px auto 0;
    display: block;
    background: linear-gradient(135deg, var(--campfire), var(--ember));
    color: #fff;
    border: none;
    border-radius: 30px;
    padding: 12px 24px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--elev-2);
    font-size: 0.94rem;
  }
  .vc-yir-trigger:hover { box-shadow: var(--elev-3); }

  /* ============================================================
     PWA Mobile-Critical-Rules (Round 50, v216)
     ============================================================ */

  /* iOS-Anti-Zoom: Inputs MÜSSEN ≥ 16px font-size haben, sonst zoomt Safari beim
     Fokus rein (sehr disruptiv beim Formular-Ausfüllen). Auf Mobile alle Form-
     Controls global auf 16px hochziehen — überschreibt etwaige kleinere Defaults. */
  @media (max-width: 640px) {
    input[type="text"], input[type="email"], input[type="password"],
    input[type="number"], input[type="search"], input[type="tel"],
    input[type="url"], input[type="date"], input[type="time"],
    input[type="datetime-local"], input:not([type]),
    select, textarea {
      font-size: 16px !important;
    }
  }

  /* touch-action: manipulation — eliminiert die 300 ms Double-Tap-Zoom-Verzögerung
     auf Mobile bei interaktiven Elementen. Browser weiß damit: "single-tap, kein
     Pinch-Zoom auf diesem Element nötig". Macht Taps spürbar schneller. */
  button, a, label, summary,
  [role="button"], [role="tab"], [role="link"],
  .tab, .pill, .btn,
  .calc-pill, .region-pill, .recent-spot-pill, .template-tab,
  .spot-tab, .admin-tab, .lead-actions button,
  .vc-fab, .feedback-fab, .vc-cmdk-item,
  .theme-picker-option, .dropdown-item {
    touch-action: manipulation;
  }

  /* ============================================================
     Mobile Map-Focus (Round 51, v218)
     Ziel: Karte dominiert den Viewport. Toolbar minimal,
     Region-Pills + Recent-Spots versteckt, Tabs sauber lesbar.
     ============================================================ */

  /* v293: Mobile-Tab-Bar zeigt NUR Icons — kein Text-Label mehr unter dem
     Emoji (User-Wunsch). Original-Text via font-size:0 ausgeblendet. Das
     ::after-Pseudo-Element wird wieder zum Active-Indicator-Balken (content
     leer statt data-mobile-label-Text). */
  @media (max-width: 640px) {
    .tabs .tab {
      font-size: 0;            /* Original-Text ausblenden */
      min-width: 0;            /* erlaubt flex-shrink */
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .tabs .tab[data-icon]::before {
      font-size: 1.5rem;       /* Icon-Größe — etwas größer da es jetzt allein steht */
      margin: 0;
    }
    /* ::after wieder als Indicator-Balken (kein Text-Label) — überschreibt
       das content: attr(data-mobile-label) aus dem früheren Block. */
    .tabs .tab[data-mobile-label]::after {
      content: '';
      font-size: 0;
      margin: 0;
      display: block;
    }
  }

  /* Mobile-Toolbar minimal:
     - .mobile-hidden Elemente komplett raus (Standort-Button → FAB übernimmt)
     - .spots-filters ist default-collapsed; öffnet sich wenn Toolbar .show-filters hat
     - Filter-Toggle (🎚️) wird zur primären Filter-Action
     - Region-Pills + Recent-Spots-Strip versteckt für Map-Maximierung */
  .mobile-only-filters { display: none; }
  @media (max-width: 640px) {
    .mobile-only-filters { display: inline-flex; }
    .mobile-hidden { display: none !important; }

    /* Toolbar kompakter — kleineres Padding, kein Wrap (eine Zeile) */
    .spots-toolbar {
      padding: 6px 10px !important;
      gap: 6px !important;
      flex-wrap: nowrap;
      align-items: center;
    }

    /* Filter-Block default ausgeblendet, beim Aufklappen als Wrap-Block darunter */
    .spots-toolbar .spots-filters { display: none; }
    .spots-toolbar.show-filters {
      flex-wrap: wrap;
    }
    .spots-toolbar.show-filters .spots-filters {
      display: flex;
      flex-wrap: wrap;
      gap: 6px;
      width: 100%;
      padding: 6px 0 2px;
      border-top: 1px solid var(--cream-dark);
      margin-top: 4px;
    }
    /* Filter-Toggle visual-state wenn offen */
    .spots-toolbar.show-filters #btn-mobile-filters {
      background: var(--campfire);
      color: #fff;
      border-color: var(--campfire);
    }

    /* Region-Quickjump + Recent-Spots auf Mobile aus dem Default-Flow nehmen.
       Sie sind über die Filter-Sheet weiterhin erreichbar (bei Bedarf später
       integrierbar), aber dominieren nicht mehr den begrenzten Map-Space. */
    .region-quickjump,
    .recent-spots-strip {
      display: none !important;
    }
  }
}

/* ============================================================
   Spot-Vergleich Side-by-Side (v237)
   ============================================================ */

@layer components {
  /* Floating Compare-Bar (Bottom-Right über FAB) — sichtbar wenn ≥ 1 Spot
     im Vergleichs-Set. Auf Mobile sitzt sie ÜBER der Bottom-Tab-Bar. */
  .vc-compare-bar {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 90;
    background: var(--white);
    border: 1px solid var(--cream-dark);
    box-shadow: var(--elev-3);
    border-radius: 16px;
    padding: 8px 14px;
    max-width: calc(100vw - 24px);
  }
  .vc-compare-bar-inner {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
  }
  .vc-compare-bar-label {
    font-size: 0.85rem;
    color: var(--text);
    font-weight: 600;
    white-space: nowrap;
  }
  .vc-compare-bar-thumbs {
    display: flex;
    gap: 4px;
  }
  .vc-compare-bar-thumb {
    width: 32px; height: 32px;
    border-radius: 6px;
    background: var(--cream-dark);
    background-size: cover;
    background-position: center;
    border: 2px solid var(--cream);
    position: relative;
    cursor: pointer;
  }
  .vc-compare-bar-thumb-remove {
    position: absolute;
    top: -6px; right: -6px;
    width: 16px; height: 16px;
    border-radius: 50%;
    background: var(--text-light);
    color: #fff;
    border: none;
    font-size: 0.7rem;
    line-height: 1;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
  }
  .vc-compare-bar-thumb-remove:hover { background: #c0392b; }

  @media (max-width: 640px) {
    .vc-compare-bar {
      bottom: calc(70px + env(safe-area-inset-bottom));
      padding: 6px 10px;
      border-radius: 12px;
    }
    .vc-compare-bar-label { font-size: 0.75rem; }
    .vc-compare-bar-thumb { width: 26px; height: 26px; }
  }

  /* Modal: 2-4 Spalten-Layout, horizontale Scroll bei mehr Spalten */
  .compare-modal {
    max-width: 1100px;
    width: 95vw;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
  }
  .compare-content {
    overflow: auto;
    flex: 1;
    padding: 4px 0;
  }
  .compare-table {
    display: grid;
    gap: 1px;
    background: var(--cream-dark);
    min-width: max-content;
  }
  .compare-col-header {
    background: var(--white);
    padding: 12px 14px;
    text-align: center;
    position: relative;
    min-width: 220px;
  }
  .compare-col-cover {
    width: 100%;
    aspect-ratio: 4 / 3;
    background: var(--cream-dark);
    background-size: cover;
    background-position: center;
    border-radius: 8px;
    margin-bottom: 8px;
  }
  .compare-col-name {
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--text);
    line-height: 1.3;
    margin-bottom: 3px;
  }
  .compare-col-city {
    font-size: 0.78rem;
    color: var(--text-muted);
  }
  .compare-col-remove {
    position: absolute;
    top: 6px; right: 6px;
    width: 22px; height: 22px;
    border: none;
    border-radius: 50%;
    background: var(--cream-dark);
    color: var(--text);
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
    transition: background 120ms;
  }
  .compare-col-remove:hover { background: #c0392b; color: #fff; }
  .compare-row-label {
    background: var(--cream);
    padding: 8px 14px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.3px;
  }
  .compare-cell {
    background: var(--white);
    padding: 8px 14px;
    font-size: 0.85rem;
    color: var(--text);
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
  }
  .compare-cell.best { background: #d4edda; color: #155724; font-weight: 700; }
  .compare-cell.worst { background: #f5e5e5; }
  .compare-cell.true { color: var(--success); }
  .compare-cell.false { color: var(--text-muted); opacity: 0.6; }
  .compare-empty {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-muted);
  }
  .compare-empty-icon {
    font-size: 3rem;
    margin-bottom: 12px;
    opacity: 0.5;
  }

  @media (max-width: 640px) {
    .compare-modal { width: 100vw; max-height: 100vh; border-radius: 0; }
    .compare-col-header { min-width: 160px; padding: 10px; }
    .compare-col-name { font-size: 0.85rem; }
    .compare-cell { font-size: 0.78rem; padding: 6px 10px; }
    .compare-row-label { font-size: 0.7rem; padding: 6px 10px; }
  }
}

/* ============================================================
   Material Design 3 — Filled Cards (v247)
   ============================================================
   MD3-konforme Filled-Card-Variante für .tip-card + .trip-card.
   Charakteristika:
   - Tonal-Surface-Background statt flatter Weiß (subtile Färbung)
   - Border-Radius 16px (MD3 Standard für "Medium")
   - State-Layer-Animation auf Hover (vom bestehenden ::before-System)
   - Avatar-Pattern für Icons: rundes 40×40 Hintergrund-Token oben
   - MD3 Type-Scale: Title-Medium für Headlines, Body-Medium für Text
   - Soft Elevation-1 in Resting, Elevation-3 bei Hover
   - Keine Border-Lefts mehr (zu MD2 — durch tonal-tinting ersetzt)
   ============================================================ */

@layer components {

  /* ---------- Tip-Card MD3 ---------- */
  .tip-card {
    /* Filled-Surface: cream-dark mit 50% Opacity über white → tonal-warm */
    background: color-mix(in srgb, var(--cream-dark) 35%, var(--white));
    border-radius: 16px;
    border-left: none;                   /* MD3-Reset: kein border-stripe */
    padding: 20px 22px 22px;
    box-shadow: 0 1px 2px rgba(45, 74, 62, 0.06), 0 1px 3px rgba(45, 74, 62, 0.04);
    position: relative;
    isolation: isolate;
    transition: box-shadow 200ms ease, transform 200ms ease;
  }
  .tip-card:hover {
    box-shadow: 0 4px 12px rgba(45, 74, 62, 0.10), 0 2px 6px rgba(45, 74, 62, 0.06);
    transform: translateY(-2px);
  }
  [data-theme="dark"] .tip-card {
    background: color-mix(in srgb, #1f2820 75%, #2a3530);
    box-shadow: 0 1px 3px rgba(0,0,0,0.4);
  }
  [data-theme="dark"] .tip-card:hover {
    box-shadow: 0 4px 14px rgba(0,0,0,0.5);
  }

  /* Header-Zeile als Avatar-Layout */
  .tip-card .tip-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 12px;
  }
  /* MD3-Avatar: 40x40 rounded background um das Emoji */
  .tip-card .tip-icon {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--campfire) 18%, transparent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.35rem;
    flex: 0 0 auto;
    line-height: 1;
  }
  .tip-card:nth-child(4n+2) .tip-icon { background: color-mix(in srgb, var(--forest) 18%, transparent); }
  .tip-card:nth-child(4n+3) .tip-icon { background: color-mix(in srgb, #4a90e2 18%, transparent); }
  .tip-card:nth-child(4n) .tip-icon   { background: color-mix(in srgb, #d4a017 22%, transparent); }

  /* Travel-Type-Badge als MD3 „Assist Chip": Outlined statt Filled-Pill */
  .tip-card .tip-number {
    margin-left: auto;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-light);
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--cream-dark) 70%, var(--text-light));
    padding: 4px 10px;
    border-radius: 8px;
    letter-spacing: 0.02em;
  }
  [data-theme="dark"] .tip-card .tip-number {
    color: var(--text);
    border-color: rgba(255,255,255,0.18);
  }

  /* Title: MD3 Title-Medium (16px, weight 500, line-height 1.5) */
  .tip-card .tip-title {
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--text);
    letter-spacing: -0.005em;
    margin: 0 0 6px;
  }
  /* Body: MD3 Body-Medium (14px, weight 400, line-height 1.43) */
  .tip-card .tip-text {
    font-size: 0.92rem;
    font-weight: 400;
    line-height: 1.55;
    color: var(--text-light);
    margin: 0;
  }

  /* ---------- Trip-Card MD3 ---------- */
  .trip-card {
    background: color-mix(in srgb, var(--cream-dark) 35%, var(--white));
    border-radius: 16px;
    border-left: none;
    padding: 18px 20px;
    box-shadow: 0 1px 2px rgba(45, 74, 62, 0.06), 0 1px 3px rgba(45, 74, 62, 0.04);
    position: relative;
    isolation: isolate;
    transition: box-shadow 200ms ease, transform 200ms ease;
  }
  .trip-card:hover {
    box-shadow: 0 4px 14px rgba(45, 74, 62, 0.12), 0 2px 6px rgba(45, 74, 62, 0.06);
    transform: translateY(-2px);
  }
  [data-theme="dark"] .trip-card {
    background: color-mix(in srgb, #1f2820 75%, #2a3530);
    box-shadow: 0 1px 3px rgba(0,0,0,0.4);
  }
  [data-theme="dark"] .trip-card:hover {
    box-shadow: 0 4px 14px rgba(0,0,0,0.5);
  }

  /* MD3 Type-Scale Trip-Name: Title-Large (22px, weight 500) */
  .trip-card .trip-card-name {
    font-size: 1.15rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--text);
    letter-spacing: -0.01em;
  }
  /* Sub-Daten: Body-Small */
  .trip-card .trip-card-dates,
  .trip-card .trip-card-desc,
  .trip-card .trip-card-footer {
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-light);
  }

  /* Trip-Actions als MD3 Text-Buttons (transparent, kein Background, rounded) */
  .trip-actions .btn,
  .trip-actions .btn-sm {
    background: transparent;
    border: none;
    color: var(--campfire);
    padding: 6px 12px;
    border-radius: 20px;             /* MD3 Pill-Form für Action-Buttons */
    font-size: 0.83rem;
    font-weight: 500;
    transition: background 120ms ease;
    box-shadow: none;
  }
  .trip-actions .btn:hover,
  .trip-actions .btn-sm:hover {
    background: color-mix(in srgb, var(--campfire) 12%, transparent);
  }
  /* Löschen-Aktion in Error-Color (MD3 Pattern) */
  .trip-actions .btn-delete,
  .trip-actions .btn-reject {
    color: #c0392b;
  }
  .trip-actions .btn-delete:hover,
  .trip-actions .btn-reject:hover {
    background: color-mix(in srgb, #c0392b 12%, transparent);
  }

  /* Stat-Pill mit MD3-Surface-Color für Header-Zeilen-Items */
  .trip-card .trip-stat-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    background: color-mix(in srgb, var(--cream-dark) 60%, var(--white));
    border-radius: 12px;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-light);
  }
  [data-theme="dark"] .trip-card .trip-stat-pill {
    background: rgba(255,255,255,0.08);
  }

  /* Trip-Card-Cover als rundes Avatar-Pattern statt Square-Thumbnail */
  .trip-card.trip-card-with-cover {
    background: color-mix(in srgb, var(--cream-dark) 35%, var(--white));
  }
  .trip-card-cover {
    border-radius: 14px;
    border: 2px solid var(--white);
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
  }
  [data-theme="dark"] .trip-card-cover {
    border-color: rgba(255,255,255,0.12);
  }

  /* ---------- Reduced-Motion-Respect ---------- */
  @media (prefers-reduced-motion: reduce) {
    .tip-card, .trip-card { transition: none; }
    .tip-card:hover, .trip-card:hover { transform: none; }
  }

  /* ---------- Tip-Card Animation deaktivieren (Round 11 hatte tip-in
     Animation — kollidiert mit MD3-soft-static-Look). Bleibt opt-in via
     `prefers-reduced-motion: no-preference`-Override unten. */
  .tip-card { animation: none; }
  @media (prefers-reduced-motion: no-preference) {
    .tip-card { animation: tip-in 0.4s ease backwards; }
  }
}

/* ============================================================
   MD3 Filled Cards für Operator/Admin/Diary (v249)
   ============================================================
   Ersetzt die MD2 border-left-Stripe-Pattern durch tonal Surface +
   Soft Elevation. Targets sind .lead-card, .inq-card, .inq-response,
   .diary-entry, .mod-readonly-banner.
   Layer: components → wins über @layer base ohne !important.
   ============================================================ */

@layer components {

  /* ---------- Admin: Lead-Card ---------- */
  .lead-card {
    background: color-mix(in srgb, var(--cream-dark) 35%, var(--white));
    border-left: none;
    border-radius: 16px;
    padding: 16px 18px;
    box-shadow: 0 1px 2px rgba(45, 74, 62, 0.06), 0 1px 3px rgba(45, 74, 62, 0.04);
    transition: box-shadow 200ms ease, transform 200ms ease;
  }
  .lead-card:hover {
    box-shadow: 0 4px 14px rgba(45, 74, 62, 0.10), 0 2px 6px rgba(45, 74, 62, 0.06);
    transform: translateY(-1px);
  }
  /* Status-Tinting subtil über tonal accent statt border-stripe */
  .lead-card.status-contacted { background: color-mix(in srgb, #fff3e0 50%, var(--white)); }
  .lead-card.status-offered   { background: color-mix(in srgb, #e3f2fd 50%, var(--white)); }
  .lead-card.status-won       { background: color-mix(in srgb, #d4edda 45%, var(--white)); }
  .lead-card.status-lost      { background: color-mix(in srgb, #ececec 60%, var(--white)); opacity: 0.85; }
  [data-theme="dark"] .lead-card {
    background: color-mix(in srgb, #1f2820 75%, #2a3530);
  }

  /* ---------- Operator: Inquiry-Card ---------- */
  .inq-card {
    background: color-mix(in srgb, var(--cream-dark) 35%, var(--white));
    border-left: none;
    border-radius: 16px;
    padding: 18px 20px;
    margin-bottom: 14px;
    box-shadow: 0 1px 2px rgba(45, 74, 62, 0.06), 0 1px 3px rgba(45, 74, 62, 0.04);
    transition: box-shadow 200ms ease, transform 200ms ease;
  }
  .inq-card:hover {
    box-shadow: 0 4px 14px rgba(45, 74, 62, 0.10), 0 2px 6px rgba(45, 74, 62, 0.06);
    transform: translateY(-1px);
  }
  /* Status-Tinting für Operator-Cards */
  .inq-card.status-acknowledged { background: color-mix(in srgb, #fff3e0 55%, var(--white)); }
  .inq-card.status-accepted     { background: color-mix(in srgb, #d4edda 50%, var(--white)); }
  .inq-card.status-declined     { background: color-mix(in srgb, #ececec 65%, var(--white)); opacity: 0.7; }
  .inq-card.status-cancelled,
  .inq-card.status-expired      { background: color-mix(in srgb, #f5e5e5 55%, var(--white)); opacity: 0.55; }

  /* ---------- Operator-Antwort-Box: Surface-Container statt blau-blocked-border ---------- */
  .inq-response {
    background: color-mix(in srgb, #4a90e2 8%, var(--white));
    border-left: none;
    border-radius: 12px;
    padding: 12px 14px;
    box-shadow: inset 0 0 0 1px rgba(74, 144, 226, 0.18);
  }

  /* ---------- Trip-Diary-Entries ---------- */
  .diary-entry {
    background: color-mix(in srgb, var(--cream-dark) 35%, var(--white));
    border: none;
    border-left: none;
    border-radius: 16px;
    padding: 16px;
    box-shadow: 0 1px 2px rgba(45, 74, 62, 0.06), 0 1px 3px rgba(45, 74, 62, 0.04);
  }
  [data-theme="dark"] .diary-entry {
    background: color-mix(in srgb, #1f2820 75%, #2a3530);
    border: none;
  }

  /* ---------- Mod-Read-Only-Banner: Notification-Surface ---------- */
  .mod-readonly-banner {
    background: color-mix(in srgb, var(--campfire) 8%, var(--cream)) !important;
    border-left: none !important;
    border-radius: 12px !important;
    padding: 10px 16px !important;
    color: var(--text) !important;
  }

  /* ---------- Generischer MD3 Error-Banner (v249) ----------
     Genutzt für inquiry-modal Konflikt-Warnung + zukünftige Error-States.
     Folgt MD3 „Error Container"-Token: tonal-error background, no border. */
  .md-error-banner {
    background: color-mix(in srgb, #c0392b 12%, var(--white));
    border-radius: 12px;
    color: #5f1417;
    padding: 12px 14px;
    line-height: 1.5;
  }
  [data-theme="dark"] .md-error-banner {
    background: color-mix(in srgb, #c0392b 22%, #2a2e26);
    color: #ffb4b0;
  }
}

/* ============================================================
   Spot-Detail-Header Favorite-Heart (v250)
   ============================================================
   Heart-Icon-Button im Modal-Header (top-right, vor close).
   Selbe SVG-Komponente wie in Spot-Listen-Cards (createHeartSvg).
   Stil: 40×40 round, transparent background, heart wechselt
   Color-Token: outline (unset) ↔ campfire-filled (set).
   ============================================================ */

@layer components {
  .spot-detail-header-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
  }

  .btn-fav-detail {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    background: transparent;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background-color 120ms ease, transform 80ms ease;
    -webkit-tap-highlight-color: transparent;
  }
  .btn-fav-detail:hover {
    background: color-mix(in srgb, var(--text) 8%, transparent);
  }
  .btn-fav-detail:active {
    transform: scale(0.92);
  }

  /* Default (nicht-Favorit): Outline-Heart, transparent fill */
  .btn-fav-detail svg .heart-fill {
    fill: none;
    stroke: var(--text-light);
    stroke-width: 2;
    stroke-linejoin: round;
    transition: fill 180ms ease, stroke 120ms ease;
  }
  .btn-fav-detail:hover svg .heart-fill {
    stroke: var(--campfire);
  }

  /* Aktiver Favorit: gefüllt + campfire-color + leichter Pulse */
  .btn-fav-detail.active svg .heart-fill {
    fill: var(--campfire);
    stroke: var(--campfire);
  }
  .btn-fav-detail.active {
    animation: fav-detail-pop 0.32s ease;
  }
  @keyframes fav-detail-pop {
    0% { transform: scale(1); }
    40% { transform: scale(1.25); }
    100% { transform: scale(1); }
  }
  @media (prefers-reduced-motion: reduce) {
    .btn-fav-detail.active { animation: none; }
    .btn-fav-detail:active { transform: none; }
  }

  [data-theme="dark"] .btn-fav-detail svg .heart-fill {
    stroke: var(--text-light);
  }
  [data-theme="dark"] .btn-fav-detail:hover {
    background: rgba(255,255,255,0.08);
  }
}
