/* ============================================================
   BAN YARO — Einstellungen / Account
   Login, Registrierung, Logout, Account-Info.
   ============================================================ */

window.Page_settings = (() => {

  let _container = null;
  let _appState  = null;
  let _mode      = 'login'; // 'login' | 'register'

  // ----------------------------------------------------------
  // HUNDEPASSPHRASE — sicheres Passwort aus Hundewelt
  // ----------------------------------------------------------
  const _PW_WOERTER = [
    // Rassen
    'Labrador','Pudel','Beagle','Husky','Dackel','Spitz','Mops','Boxer',
    'Collie','Setter','Pointer','Retriever','Shepherd','Terrier','Welpe',
    // Körper & Natur
    'Pfote','Schwanz','Schnauze','Schnurrbart','Fell','Nase','Ohr',
    // Aktivität
    'Gassi','Laufen','Bellen','Springen','Graben','Schnüffeln','Spielen',
    'Apportieren','Schwimmen','Hecheln','Wackeln','Toben',
    // Gegenstände
    'Leckerli','Leine','Halsband','Ball','Napf','Knochen','Frisbee',
    'Körbchen','Bürste','Leine','Stöckchen','Kauspielzeug',
    // Orte & Personen
    'Wiese','Wald','Park','Bach','Pfütze','Tierarzt','Züchter',
    // Eigenschaften
    'Treu','Tapfer','Mutig','Flauschig','Verspielt','Neugierig',
    'Wachsam','Flink','Sanft','Lieb',
    // Geräusche & Aktionen
    'Wuff','Jaulen','Schnuppern','Wedeln','Gähnen','Strecken',
    // Futter
    'Trockenfutter','Nassfutter','Kausnack','Futternapf',
  ];

  function _genPassphrase() {
    const pick = () => _PW_WOERTER[Math.floor(Math.random() * _PW_WOERTER.length)];
    const num  = Math.floor(Math.random() * 90) + 10; // 2-stellig
    // 3 zufällige Wörter + Zahl, mit Bindestrich
    const words = [];
    while (words.length < 3) {
      const w = pick();
      if (!words.includes(w)) words.push(w);
    }
    return words.join('-') + '-' + num;
  }

  // ----------------------------------------------------------
  // INIT / REFRESH
  // ----------------------------------------------------------
  async function init(container, appState) {
    _container = container;
    _appState  = appState;
    _render();
    // Frischen User-State laden damit Badges (is_founder, is_partner) aktuell sind
    if (_appState.user) {
      try {
        const fresh = await API.auth.me();
        Object.assign(_appState.user, fresh);
        _render();
      } catch {}
    }
  }

  async function refresh() {
    _render();
    if (_appState?.user) {
      try {
        const fresh = await API.auth.me();
        Object.assign(_appState.user, fresh);
        _render();
      } catch {}
    }
  }

  // ----------------------------------------------------------
  // RENDER
  // ----------------------------------------------------------
  function _render() {
    if (_appState.user) {
      _renderAccount();
    } else {
      _renderAuth(_mode);
    }
  }

  // ----------------------------------------------------------
  // EINGELOGGT — Account-Übersicht
  // ----------------------------------------------------------
  async function _renderAccount() {
    const u = _appState.user;

    // Avatar: Bild oder Buchstabe
    const avatarInner = u.avatar_url
      ? `<img src="${_esc(u.avatar_url)}" alt="Avatar"
              style="width:56px;height:56px;border-radius:50%;object-fit:cover;display:block">`
      : _esc(u.name.charAt(0).toUpperCase());

    // Mitglied seit
    const memberSince = (() => {
      if (!u.created_at) return '';
      const d = new Date(u.created_at);
      return d.toLocaleDateString('de-DE', { month: 'long', year: 'numeric' });
    })();

    // Erfahrungs-Labels
    const erfahrungLabel = {
      einsteiger: 'Einsteiger (erster Hund)',
      erfahren:   'Erfahrener Hundehalter',
      trainer:    'Trainer / Ausbilder',
      zuechter:   'Züchter',
    };

    _container.innerHTML = `
      <div class="page-container" style="box-sizing:border-box;overflow-x:hidden">

        <div class="card" style="padding:var(--space-5);margin-bottom:var(--space-4)">
          <div style="display:flex;align-items:center;gap:var(--space-4)">
            <div id="settings-avatar-btn"
                 style="width:56px;height:56px;border-radius:50%;
                        background:var(--c-primary);color:#fff;
                        display:flex;align-items:center;justify-content:center;
                        font-size:1.5rem;font-weight:700;flex-shrink:0;
                        cursor:pointer;overflow:hidden;position:relative">
              ${avatarInner}
              <div style="position:absolute;inset:0;background:rgba(0,0,0,0.25);
                          display:flex;align-items:center;justify-content:center;
                          opacity:0;transition:opacity .15s"
                   class="avatar-overlay">
                <svg style="width:20px;height:20px;color:#fff" fill="currentColor" viewBox="0 0 256 256">
                  <use href="/icons/phosphor.svg#camera"></use>
                </svg>
              </div>
            </div>
            <input type="file" id="settings-avatar-input" accept="image/*"
                   style="display:none">
            <div>
              <div style="font-weight:700;font-size:var(--text-lg)">${_esc(u.name)}</div>
              <div style="display:flex;align-items:center;gap:var(--space-2);color:var(--c-text-secondary);font-size:var(--text-sm)">
                ${_esc(u.email)}
                ${u.email_verified
                  ? `<svg class="ph-icon" aria-hidden="true" style="width:14px;height:14px;color:#22c55e" title="Bestätigt"><use href="/icons/phosphor.svg#check-circle"></use></svg>`
                  : `<span id="settings-verify-chip"
                          style="font-size:10px;background:#fef3c7;color:#d97706;padding:1px 7px;
                                 border-radius:999px;cursor:pointer;white-space:nowrap"
                          title="E-Mail noch nicht bestätigt">Nicht bestätigt</span>`}
              </div>
              <div style="display:flex;flex-wrap:wrap;gap:var(--space-1);margin-top:var(--space-1)">
                ${u.is_premium
                  ? `<span class="badge badge-primary">
                       <svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px"><use href="/icons/phosphor.svg#star"></use></svg> Ban Yaro Plus
                     </span>`
                  : `<span class="badge" style="color:var(--c-text-secondary)">Kostenlos</span>`}
                ${u.is_founder
                  ? `<span class="badge" style="background:#7c3aed;color:#fff;cursor:pointer" data-page="gruender">
                       <svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px"><use href="/icons/phosphor.svg#key"></use></svg>
                       ${u.founder_number ? `Gründer #${u.founder_number}` : 'Gründer'}
                     </span>`
                  : u.is_founder_pending
                  ? `<span class="badge" style="background:#f59e0b;color:#fff;cursor:pointer" data-page="dog-profile"
                          title="Hunde-Profil anlegen um Gründer-Platz zu sichern">
                       <svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px"><use href="/icons/phosphor.svg#hourglass"></use></svg>
                       Gründer-Platz reserviert
                     </span>` : ''}
                ${u.is_partner
                  ? `<span class="badge" style="background:#0ea5e9;color:#fff">
                       <svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px"><use href="/icons/phosphor.svg#handshake"></use></svg> Partner
                     </span>` : ''}
              </div>
            </div>
          </div>
        </div>

        <!-- Mein Profil -->
        <div class="card" style="margin-bottom:var(--space-4)">
          <div style="padding:var(--space-3) var(--space-4);
                      font-size:var(--text-xs);font-weight:600;
                      color:var(--c-text-secondary);text-transform:uppercase;
                      letter-spacing:0.05em;border-bottom:1px solid var(--c-border);
                      display:flex;align-items:center;justify-content:space-between">
            <span>Mein Profil</span>
            <button id="settings-profile-edit-btn"
                    class="btn btn-ghost"
                    style="font-size:var(--text-xs);padding:var(--space-1) var(--space-2)">
              Profil bearbeiten
            </button>
          </div>
          <div style="padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-3)">
            ${memberSince
              ? `<div style="font-size:var(--text-sm);color:var(--c-text-secondary)">
                   Mitglied seit ${_esc(memberSince)}
                 </div>`
              : ''}
            ${u.bio
              ? `<div style="font-size:var(--text-sm)">${_esc(u.bio)}</div>`
              : ''}
            ${u.wohnort
              ? `<div style="font-size:var(--text-sm);color:var(--c-text-secondary)">
                   📍 ${_esc(u.wohnort)}
                 </div>`
              : ''}
            ${u.erfahrung && erfahrungLabel[u.erfahrung]
              ? `<div style="font-size:var(--text-sm);color:var(--c-text-secondary)">
                   ${_esc(erfahrungLabel[u.erfahrung])}
                 </div>`
              : ''}
            ${u.social_link
              ? `<div style="font-size:var(--text-sm)">
                   <a href="${_esc(u.social_link)}" target="_blank" rel="noopener"
                      style="color:var(--c-primary)">${_esc(u.social_link)}</a>
                 </div>`
              : ''}
            ${!u.bio && !u.wohnort && !u.erfahrung && !u.social_link
              ? `<div style="font-size:var(--text-sm);color:var(--c-text-secondary)">
                   Noch kein Profil ausgefüllt.
                 </div>`
              : ''}
          </div>
        </div>

        <div class="card" id="settings-stats-card" style="margin-bottom:var(--space-4)">
          <div style="padding:var(--space-3) var(--space-4);font-size:var(--text-xs);font-weight:600;
                      color:var(--c-text-secondary);text-transform:uppercase;letter-spacing:0.05em;
                      border-bottom:1px solid var(--c-border)">Aktivität</div>
          <div id="settings-stats-body" style="padding:var(--space-4);display:flex;justify-content:space-around">
            <div style="color:var(--c-text-muted);font-size:var(--text-sm)">Lädt…</div>
          </div>
          <div id="settings-streak" style="display:flex;align-items:center;gap:8px;
               padding:0 var(--space-4) var(--space-3);flex-wrap:wrap"></div>
        </div>

        <!-- Züchter-Profil Slot -->
        <div id="breeder-card-slot"></div>

        <div class="card" style="margin-bottom:var(--space-4)">
          <div style="padding:var(--space-3) var(--space-4);font-size:var(--text-xs);font-weight:600;
                      color:var(--c-text-secondary);text-transform:uppercase;letter-spacing:0.05em;
                      border-bottom:1px solid var(--c-border)">Trophäen</div>
          <div id="settings-badges-body" style="padding:var(--space-4)">
            <div style="color:var(--c-text-muted);font-size:var(--text-sm)">Lädt…</div>
          </div>
        </div>

        <div class="card" style="margin-bottom:var(--space-4)">
          <div class="card-body" style="padding:0">
            <div class="sidebar-item" data-page="dog-profile"
                 style="padding:var(--space-4);border-radius:0;border-bottom:1px solid var(--c-border)">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#dog"></use></svg>
              <span>Hunde-Profile</span>
              <span style="margin-left:auto;color:var(--c-text-secondary)">›</span>
            </div>
            <div class="sidebar-item" id="settings-push-btn"
                 style="padding:var(--space-4);border-radius:0;border-bottom:1px solid var(--c-border)">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#bell"></use></svg>
              <span>Push-Benachrichtigungen</span>
              <span style="margin-left:auto;color:var(--c-text-secondary)">›</span>
            </div>
            <div class="sidebar-item" id="settings-calendar-btn"
                 style="padding:var(--space-4);border-radius:0;border-bottom:1px solid var(--c-border)">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#calendar-dots"></use></svg>
              <span>Kalender abonnieren</span>
              <span style="margin-left:auto;color:var(--c-text-secondary)">›</span>
            </div>
            <div class="sidebar-item" id="settings-worlds-btn"
                 style="padding:var(--space-4);border-radius:0;border-bottom:1px solid var(--c-border);cursor:pointer">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#squares-four"></use></svg>
              <span>Welten einrichten</span>
              <span style="margin-left:auto;color:var(--c-text-secondary)">›</span>
            </div>
            <div class="sidebar-item" id="settings-logout-btn"
                 style="padding:var(--space-4);border-radius:0;cursor:pointer;
                        color:var(--c-danger)">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#sign-out"></use></svg>
              <span>Abmelden</span>
            </div>
          </div>
        </div>

        <div class="card" style="margin-bottom:var(--space-4)">
          <div style="padding:var(--space-3) var(--space-4);
                      font-size:var(--text-xs);font-weight:600;
                      color:var(--c-text-secondary);text-transform:uppercase;
                      letter-spacing:0.05em;border-bottom:1px solid var(--c-border)">
            App-Einstellungen
          </div>
          <div class="card-body" style="padding:0">

            <!-- Dark-Mode-Auswahl -->
            <div style="display:flex;align-items:center;gap:var(--space-3);
                        padding:var(--space-4);border-bottom:1px solid var(--c-border)">
              <svg class="ph-icon" aria-hidden="true" style="width:1.25rem;height:1.25rem"><use href="/icons/phosphor.svg#moon"></use></svg>
              <div style="flex:1">
                <div style="font-weight:500">Dark Mode</div>
                <div style="font-size:var(--text-xs);color:var(--c-text-secondary);margin-top:2px">
                  Erscheinungsbild der App
                </div>
              </div>
              <select id="select-theme"
                      style="padding:var(--space-1) var(--space-2);
                             border:1.5px solid var(--c-border);
                             border-radius:var(--radius-md);
                             background:var(--c-surface);
                             color:var(--c-text);
                             font-size:var(--text-sm);
                             font-family:inherit;
                             cursor:pointer">
                <option value="system" ${(localStorage.getItem('by_theme')||'system') === 'system' ? 'selected' : ''}>System</option>
                <option value="light"  ${localStorage.getItem('by_theme') === 'light'  ? 'selected' : ''}>Hell</option>
                <option value="dark"   ${localStorage.getItem('by_theme') === 'dark'   ? 'selected' : ''}>Dunkel</option>
              </select>
            </div>

            <!-- KI-Notiz-Assistent -->
            <div style="display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4)">
              <svg class="ph-icon" aria-hidden="true" style="width:1.25rem;height:1.25rem"><use href="/icons/phosphor.svg#brain"></use></svg>
              <div style="flex:1">
                <div style="font-weight:500">KI-Notiz-Assistent</div>
                <div style="font-size:var(--text-xs);color:var(--c-text-secondary);margin-top:2px">
                  Erkennt Muster in deinen Notizen und macht Vorschläge
                </div>
              </div>
              <label style="position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0">
                <input type="checkbox" id="toggle-notes-ki"
                       style="opacity:0;width:0;height:0;position:absolute"
                       ${u.notes_ki_enabled ? 'checked' : ''}>
                <span style="position:absolute;cursor:pointer;inset:0;border-radius:12px;
                             background:var(--c-border);transition:.2s"
                      id="toggle-notes-ki-track"></span>
                <span id="toggle-notes-ki-thumb"
                      style="position:absolute;top:2px;left:${u.notes_ki_enabled ? '22px' : '2px'};
                             width:20px;height:20px;border-radius:50%;
                             background:#fff;transition:.2s;
                             box-shadow:0 1px 3px rgba(0,0,0,.3)"></span>
              </label>
            </div>

          </div>
        </div>

        <!-- App empfehlen -->
        <div class="card" style="margin-bottom:var(--space-5)" id="referral-card">
          <div style="padding:var(--space-4);border-bottom:1px solid var(--c-border)">
            <div style="font-weight:600;margin-bottom:2px">${UI.icon('arrow-square-out')} Freunde werben — dauerhafter Rabatt</div>
            <div style="font-size:var(--text-xs);color:var(--c-text-secondary)">
              10 Freunde → 20% · 20 Freunde → 30% · 50 Freunde → 50% — lebenslang, sobald Bezahlfunktionen aktiv sind.
            </div>
          </div>
          <div id="referral-body" style="padding:var(--space-4)">Lade…</div>
        </div>

        <!-- App installieren -->
        <div class="card" style="margin-bottom:var(--space-4)">
          <div style="padding:var(--space-3) var(--space-4);
                      font-size:var(--text-xs);font-weight:600;
                      color:var(--c-text-secondary);text-transform:uppercase;
                      letter-spacing:0.05em;border-bottom:1px solid var(--c-border)">
            App installieren
          </div>
          <div class="card-body" style="padding:0">
            <div class="sidebar-item" id="settings-install-btn"
                 style="padding:var(--space-4);border-radius:0;cursor:pointer">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
              <span>Installations-Anleitung</span>
              <span style="margin-left:auto;color:var(--c-text-secondary)">›</span>
            </div>
          </div>
        </div>

        <!-- App-Version & Update -->
        <div style="text-align:center;color:var(--c-text-secondary);font-size:var(--text-xs)">
          Ban Yaro · banyaro.app<br>
          Deine Daten liegen auf einem eigenen Server in Deutschland.
          <div style="margin-top:var(--space-3);display:flex;align-items:center;
                      justify-content:center;gap:var(--space-2);flex-wrap:wrap">
            <span style="background:var(--c-surface-2);border:1px solid var(--c-border);
                         border-radius:100px;padding:2px 10px;font-family:monospace;
                         font-size:10px;color:var(--c-text-muted)">
              v${typeof APP_VERSION !== 'undefined' ? APP_VERSION : '1.0.0'} <span style="opacity:0.5;font-size:10px">(${typeof APP_VER !== 'undefined' ? APP_VER : '—'})</span>
            </span>
            <button id="settings-check-update" style="background:none;border:none;cursor:pointer;
                    font-size:var(--text-xs);color:var(--c-primary);padding:2px 6px;
                    border-radius:var(--radius-sm)">
              ${UI.icon('arrows-clockwise')} Auf Update prüfen
            </button>
          </div>
        </div>

      </div>
    `;

    // Achievements laden (Streak + Stats + Badges)
    API.get('/achievements/me').then(a => {
      const statsEl  = document.getElementById('settings-stats-body');
      const badgesEl = document.getElementById('settings-badges-body');
      if (!statsEl) return;

      const s = a.stats || {}, streak = a.streak || {};
      const stat = (val, label) => `
        <div style="text-align:center">
          <div style="font-size:1.3rem;font-weight:700;color:var(--c-text)">${val}</div>
          <div style="font-size:10px;color:var(--c-text-secondary);text-transform:uppercase;letter-spacing:.05em;margin-top:2px">${label}</div>
        </div>`;
      statsEl.innerHTML =
        stat((s.total_km ?? 0) + ' km', 'gelaufen') +
        stat(s.routen ?? 0, 'Routen') +
        stat(s.pois ?? 0, 'POIs') +
        stat('#' + (a.rang ?? '–'), 'Rang');

      const streakEl = document.getElementById('settings-streak');
      if (streakEl) {
        const cur = streak.current || 0, mx = streak.max || 0;
        streakEl.innerHTML = cur > 0
          ? `<span style="font-size:1.3rem">🔥</span>
             <span style="font-weight:700;font-size:1.05rem">${cur} Tage Streak</span>
             ${mx > cur ? `<span style="color:var(--c-text-muted);font-size:11px;margin-left:auto">Best: ${mx}</span>` : ''}`
          : `<span style="color:var(--c-text-muted);font-size:var(--text-sm)">🔥 Noch kein Streak — heute aktiv werden!</span>`;
      }

      if (badgesEl && a.categories) {
        // SVG-Schild für jede Kategorie
        const shield = (color, dark, emoji, opacity = 1) => `
          <svg viewBox="0 0 60 72" xmlns="http://www.w3.org/2000/svg"
               style="width:56px;height:56px;filter:drop-shadow(0 2px 6px ${color}66)">
            <defs>
              <linearGradient id="g_${color.replace('#','')}" x1="0" y1="0" x2="1" y2="1">
                <stop offset="0%" stop-color="${color}"/>
                <stop offset="100%" stop-color="${dark}"/>
              </linearGradient>
            </defs>
            <path d="M30 3 L57 15 L57 38 Q57 60 30 70 Q3 60 3 38 L3 15 Z"
                  fill="url(#g_${color.replace('#','')})" opacity="${opacity}"/>
            <path d="M30 3 L57 15 L57 38 Q57 60 30 70 Q3 60 3 38 L3 15 Z"
                  fill="none" stroke="rgba(255,255,255,.25)" stroke-width="1.5"/>
            <text x="30" y="43" text-anchor="middle" dominant-baseline="middle"
                  font-size="22" style="user-select:none">${emoji}</text>
          </svg>`;

        badgesEl.innerHTML = (a.categories || []).map(cat => {
          const cur = cat.current_tier;
          const nxt = cat.next_tier;
          const val = cat.current_value;

          // Alle Stufen als kleine Punkte
          const dots = (cat.alle_stufen || []).map(s =>
            `<div title="${_esc(s.name)}" style="width:8px;height:8px;border-radius:50%;
             background:${s.earned ? s.color : 'var(--c-border)'}"></div>`
          ).join('');

          // Aktuelles Schild
          const shieldSvg = cur
            ? shield(cur.color, cur.dark, cat.emoji)
            : shield('#9ca3af', '#6b7280', cat.emoji, 0.5);

          // Fortschrittsbalken
          const progressBar = nxt ? `
            <div style="font-size:10px;color:var(--c-text-muted);margin-top:4px">
              ${val}${cat.einheit} / ${nxt.schwelle}${cat.einheit} → ${_esc(nxt.name)}
            </div>
            <div style="height:4px;background:var(--c-border);border-radius:2px;margin-top:4px;overflow:hidden">
              <div style="height:100%;width:${cat.progress}%;background:${nxt.color};border-radius:2px;transition:width .4s"></div>
            </div>` : `
            <div style="font-size:10px;color:var(--c-primary);font-weight:600;margin-top:4px">
              Höchste Stufe erreicht! 🎉
            </div>`;

          return `
            <div style="display:flex;gap:14px;align-items:flex-start;padding:12px 0;
                        border-bottom:1px solid var(--c-border)">
              ${shieldSvg}
              <div style="flex:1;min-width:0">
                <div style="display:flex;align-items:center;gap:6px;margin-bottom:2px">
                  <span style="font-weight:700;font-size:var(--text-sm)">${_esc(cat.name)}</span>
                  ${cur ? `<span style="font-size:10px;font-weight:600;padding:1px 6px;border-radius:999px;
                            background:${cur.color};color:${cur.text}">${_esc(cur.name)}</span>` : ''}
                </div>
                <div style="display:flex;gap:4px;margin-bottom:6px">${dots}</div>
                ${progressBar}
              </div>
            </div>`;
        }).join('');
      }

      // Neue Badges als Toast
      if (a.new_badges?.length) {
        a.new_badges.forEach(b => {
          UI.toast.success(`${b.emoji} ${b.name} — ${b.tier} freigeschaltet!`);
        });
      }
    }).catch(() => {
      const el = document.getElementById('settings-stats-body');
      if (el) el.innerHTML = '<div style="color:var(--c-text-muted);font-size:var(--text-sm)">–</div>';
    });

    // Avatar-Hover-Overlay
    // E-Mail-Verifikation: Chip → erneut senden
    document.getElementById('settings-verify-chip')?.addEventListener('click', async () => {
      await API.post('/auth/resend-verification', {});
      UI.toast.success('Bestätigungs-Mail gesendet — bitte prüfe dein Postfach.');
    });

    const avatarBtn = document.getElementById('settings-avatar-btn');
    const avatarOverlay = avatarBtn?.querySelector('.avatar-overlay');
    if (avatarBtn && avatarOverlay) {
      avatarBtn.addEventListener('mouseenter', () => { avatarOverlay.style.opacity = '1'; });
      avatarBtn.addEventListener('mouseleave', () => { avatarOverlay.style.opacity = '0'; });
    }

    // Avatar-Upload
    avatarBtn?.addEventListener('click', () => {
      document.getElementById('settings-avatar-input')?.click();
    });
    document.getElementById('settings-avatar-input')?.addEventListener('change', async e => {
      const file = e.target.files?.[0];
      if (!file) return;
      try {
        const fd = new FormData();
        fd.append('file', file);
        const res = await API.post('/profile/avatar', fd);
        _appState.user.avatar_url = res.avatar_url;
        UI.toast.success('Avatar aktualisiert.');
        _render();
      } catch {
        UI.toast.error('Avatar-Upload fehlgeschlagen.');
      }
    });

    // Profil bearbeiten
    document.getElementById('settings-profile-edit-btn')?.addEventListener('click', () => {
      const u = _appState.user;
      const inputStyle = `width:100%;box-sizing:border-box;padding:var(--space-2) var(--space-3);
        border:1.5px solid var(--c-border);border-radius:var(--radius-md);
        font-size:var(--text-sm);font-family:inherit;
        background:var(--c-surface);color:var(--c-text)`;

      const erfahrungOpts = [
        ['', 'Bitte wählen...'],
        ['einsteiger', 'Einsteiger (erster Hund)'],
        ['erfahren', 'Erfahrener Hundehalter'],
        ['trainer', 'Trainer / Ausbilder'],
        ['zuechter', 'Züchter'],
      ].map(([val, label]) =>
        `<option value="${_esc(val)}" ${u.erfahrung === val ? 'selected' : ''}>${_esc(label)}</option>`
      ).join('');

      const sichtbarkeitOpts = [
        ['public', 'Öffentlich'],
        ['friends', 'Nur Freunde'],
        ['private', 'Privat'],
      ].map(([val, label]) =>
        `<option value="${_esc(val)}" ${(u.profil_sichtbarkeit || 'public') === val ? 'selected' : ''}>${_esc(label)}</option>`
      ).join('');

      UI.modal.open({
        title: 'Profil bearbeiten',
        body: `
          <form id="profile-form" style="display:flex;flex-direction:column;gap:var(--space-4)">
            <div>
              <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Echter Name (privat)</label>
              <input name="real_name" type="text" maxlength="80"
                     placeholder="z. B. Maria Müller"
                     value="${_esc(u.real_name || '')}"
                     style="${inputStyle}">
            </div>
            <div>
              <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Bio</label>
              <textarea name="bio" maxlength="300" rows="4"
                        placeholder="Kurze Vorstellung (max. 300 Zeichen)"
                        style="${inputStyle};resize:vertical">${_esc(u.bio || '')}</textarea>
            </div>
            <div>
              <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Wohnort</label>
              <input name="wohnort" type="text" maxlength="60"
                     placeholder="z.B. München"
                     value="${_esc(u.wohnort || '')}"
                     style="${inputStyle}">
            </div>
            <div>
              <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Erfahrung</label>
              <select name="erfahrung" style="${inputStyle}">${erfahrungOpts}</select>
            </div>
            <div>
              <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Social-Link</label>
              <input name="social_link" type="url" maxlength="120"
                     placeholder="https://instagram.com/dein-hundeaccount"
                     value="${_esc(u.social_link || '')}"
                     style="${inputStyle}">
            </div>
            <div>
              <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Profil-Sichtbarkeit</label>
              <select name="profil_sichtbarkeit" style="${inputStyle}">${sichtbarkeitOpts}</select>
            </div>
          </form>
        `,
        footer: `
          <div style="display:flex;flex-direction:column;gap:var(--space-2);width:100%">
            <button type="submit" form="profile-form" class="btn btn-primary" style="width:100%">Speichern</button>
            <button type="button" class="btn btn-secondary" data-modal-close>Abbrechen</button>
          </div>
        `,
      });

      document.getElementById('profile-form')?.addEventListener('submit', async e => {
        e.preventDefault();
        const btn = document.querySelector('[form="profile-form"]');
        const fd  = UI.formData(e.target);
        await UI.asyncButton(btn, async () => {
          const updated = await API.patch('/profile', {
            real_name:            fd.real_name            || '',
            bio:                  fd.bio                  || '',
            wohnort:              fd.wohnort              || '',
            erfahrung:            fd.erfahrung            || '',
            social_link:          fd.social_link          || '',
            profil_sichtbarkeit:  fd.profil_sichtbarkeit  || 'public',
          });
          Object.assign(_appState.user, updated);
          UI.modal.close?.();
          UI.toast.success('Profil gespeichert.');
          _render();
        });
      });
    });

    document.getElementById('settings-check-update')?.addEventListener('click', async () => {
      const btn = document.getElementById('settings-check-update');
      if (!('serviceWorker' in navigator)) {
        UI.toast.info('Service Worker nicht verfügbar.');
        return;
      }
      if (btn) btn.textContent = 'Prüfe…';
      try {
        // Aktuelle Version vom Server holen (no-cache)
        const serverResp = await fetch('/js/app.js', { cache: 'no-store' });
        const serverText = await serverResp.text();
        const match = serverText.match(/APP_VERSION\s*=\s*'([^']+)'/);
        const serverVersion = match?.[1] || null;
        const localVersion  = typeof APP_VERSION !== 'undefined' ? APP_VERSION : '0';

        // SW update anstoßen
        const reg = await navigator.serviceWorker.getRegistration();
        await reg?.update();

        if (serverVersion && serverVersion !== localVersion) {
          // Neuere Version verfügbar — Seite neu laden
          if (reg?.waiting) reg.waiting.postMessage({ type: 'SKIP_WAITING' });
          UI.toast.info(`Update auf v${serverVersion} verfügbar — Seite wird neu geladen…`);
          setTimeout(() => location.reload(), 1500);
        } else if (reg?.waiting) {
          reg.waiting.postMessage({ type: 'SKIP_WAITING' });
          UI.toast.success('Update wird installiert…');
        } else {
          UI.toast.success(`Ban Yaro ist aktuell — v${localVersion}`);
        }
      } catch {
        UI.toast.error('Update-Prüfung fehlgeschlagen.');
      } finally {
        if (btn) btn.innerHTML = UI.icon('arrows-clockwise') + ' Auf Update prüfen';
      }
    });

    document.getElementById('settings-worlds-btn')?.addEventListener('click', () => {
      if (window.Worlds?._openConfigModal) window.Worlds._openConfigModal();
      else if (window.Worlds) window.Worlds.openConfig?.();
    });

    document.getElementById('settings-logout-btn')?.addEventListener('click', async () => {
      const ok = await UI.modal.confirm({
        title  : 'Abmelden?',
        message: 'Du wirst aus deinem Konto abgemeldet.',
        confirmText: 'Abmelden',
      });
      if (!ok) return;
      try {
        await API.auth.logout();
      } catch { /* cookie wird trotzdem gelöscht */ }
      _appState.user      = null;
      _appState.dogs      = [];
      _appState.activeDog = null;
      UI.toast.info('Du wurdest abgemeldet.');
      _render();
    });

    document.getElementById('settings-install-btn')?.addEventListener('click', () => {
      App.navigate('welcome', true, { install: true });
    });

    document.getElementById('settings-push-btn')?.addEventListener('click', async () => {
      try {
        await API.subscribeToPush();
        UI.toast.success('Push-Benachrichtigungen aktiviert.');
      } catch {
        UI.toast.warning('Push-Benachrichtigungen konnten nicht aktiviert werden.');
      }
    });

    document.getElementById('settings-calendar-btn')?.addEventListener('click', async () => {
      try {
        const { token } = await API.webcal.getToken();
        const url = `webcal://${location.host}/api/webcal/${token}.ics`;
        const httpsUrl = `https://${location.host}/api/webcal/${token}.ics`;
        UI.modal.open({
          title: `${UI.icon('calendar-dots')} Kalender abonnieren`,
          body: `
            <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-4)">
              Abonniere deinen persönlichen Ban-Yaro-Kalender. Er enthält Impf-Erinnerungen,
              Läufigkeits-Termine, Events und Gassi-Treffen — immer aktuell.
            </p>
            <div style="background:var(--c-bg);border-radius:var(--radius-md);
                        padding:var(--space-3) var(--space-4);
                        font-size:var(--text-xs);color:var(--c-text-secondary);
                        word-break:break-all;margin-bottom:var(--space-4)">
              ${httpsUrl}
            </div>
            <div style="display:flex;flex-direction:column;gap:var(--space-2)">
              <a href="${url}"
                 class="btn btn-primary"
                 style="text-align:center">
                ${UI.icon('calendar-dots')} In Kalender-App öffnen
              </a>
              <button class="btn btn-secondary" id="cal-copy-btn">
                ${UI.icon('clipboard-text')} URL kopieren
              </button>
            </div>
            <p style="font-size:var(--text-xs);color:var(--c-text-muted);margin-top:var(--space-4)">
              Tipp: iOS → Einstellungen › Kalender › Accounts › Account hinzufügen › Andere › Kalenderabo
            </p>
          `,
        });
        document.getElementById('cal-copy-btn')?.addEventListener('click', async () => {
          try {
            await navigator.clipboard.writeText(httpsUrl);
            UI.toast.success('URL kopiert.');
          } catch {
            UI.toast.warning('Kopieren nicht möglich — URL oben manuell kopieren.');
          }
        });
      } catch(err) {
        console.error('Kalender-Fehler:', err);
        UI.toast.error('Kalender-Token konnte nicht geladen werden: ' + (err?.message || err));
      }
    });

    document.getElementById('select-theme')?.addEventListener('change', e => {
      const val = e.target.value;
      localStorage.setItem('by_theme', val);
      const html = document.documentElement;
      if (val === 'dark') {
        html.setAttribute('data-theme', 'dark');
      } else if (val === 'light') {
        html.setAttribute('data-theme', 'light');
      } else {
        html.removeAttribute('data-theme');
      }
      UI.toast.info(
        val === 'dark'   ? 'Dark Mode aktiviert.' :
        val === 'light'  ? 'Hell-Modus aktiviert.' :
                           'Theme folgt der Systemeinstellung.'
      );
    });

    document.getElementById('toggle-pocket-mode')?.addEventListener('change', e => {
      localStorage.setItem('by_pocket_mode', String(e.target.checked));
      UI.toast.info(e.target.checked
        ? 'Pocket-Modus aktiviert — Bildschirm bleibt bei Aufzeichnung an.'
        : 'Pocket-Modus deaktiviert.');
    });

    document.getElementById('toggle-notes-ki')?.addEventListener('change', async e => {
      const enabled = e.target.checked;
      const track = document.getElementById('toggle-notes-ki-track');
      const thumb = document.getElementById('toggle-notes-ki-thumb');
      if (track) track.style.background = enabled ? 'var(--c-primary)' : 'var(--c-border)';
      if (thumb) thumb.style.left = enabled ? '22px' : '2px';
      try {
        await API.patch('/profile', { notes_ki_enabled: enabled ? 1 : 0 });
        _appState.user.notes_ki_enabled = enabled ? 1 : 0;
        UI.toast.success(enabled ? 'KI-Notiz-Assistent aktiviert.' : 'KI-Notiz-Assistent deaktiviert.');
      } catch (err) {
        UI.toast.error(err?.message || 'Einstellung konnte nicht gespeichert werden.');
        // Revert UI
        e.target.checked = !enabled;
        if (track) track.style.background = !enabled ? 'var(--c-primary)' : 'var(--c-border)';
        if (thumb) thumb.style.left = !enabled ? '22px' : '2px';
      }
    });

    _loadReferral();
    _loadBreederCard();
  }

  // ----------------------------------------------------------
  // KI-Toggle-Zeile (Hilfsfunktion für Züchter-Card)
  // ----------------------------------------------------------
  function _kiToggleRow(key, label, user) {
    const active = user[key] !== 0;
    return `
      <div style="display:flex;justify-content:space-between;align-items:center;
                  padding:var(--space-2) 0;font-size:var(--text-sm)">
        <span>${_esc(label)}</span>
        <button class="by-toggle ki-toggle-btn" data-key="${_esc(key)}"
                data-active="${active ? '1' : '0'}"
                style="position:relative;display:inline-block;width:44px;height:24px;
                       border:none;border-radius:12px;cursor:pointer;flex-shrink:0;
                       background:${active ? 'var(--c-primary)' : 'var(--c-border)'};
                       transition:background .2s">
          <span class="by-toggle-thumb"
                style="position:absolute;top:2px;left:${active ? '22px' : '2px'};
                       width:20px;height:20px;border-radius:50%;
                       background:#fff;transition:left .2s;
                       box-shadow:0 1px 3px rgba(0,0,0,.3)"></span>
        </button>
      </div>`;
  }

  // ----------------------------------------------------------
  // ZÜCHTER-CARD — asynchron laden und in Slot rendern
  // ----------------------------------------------------------
  async function _loadBreederCard() {
    const slot = document.getElementById('breeder-card-slot');
    if (!slot) return;

    let status = null;
    try {
      status = await API.breeder.status();
    } catch {
      // API nicht verfügbar — Card weglassen
      return;
    }

    const { rolle, breeder_status, profile } = status;

    const inputStyle = `width:100%;box-sizing:border-box;padding:var(--space-2) var(--space-3);
      border:1.5px solid var(--c-border);border-radius:var(--radius-md);
      font-size:var(--text-sm);font-family:inherit;
      background:var(--c-surface);color:var(--c-text)`;

    let statusBadge = '';
    let actionBlock = '';

    if (rolle === 'breeder' || rolle === 'admin') {
      statusBadge = `<span class="badge badge-primary" style="background:var(--c-success);color:#fff">
        ${UI.icon('check-circle')} ${rolle === 'admin' ? 'Admin — alle Züchter-Features verfügbar' : 'Verifizierter Züchter'}
      </span>`;
      actionBlock = `
        <div style="margin-top:var(--space-3);font-size:var(--text-sm);display:flex;flex-direction:column;gap:var(--space-1)">
          ${profile?.zwingername ? `<div style="color:var(--c-text-secondary)">Zwinger: <strong>${_esc(profile.zwingername)}</strong></div>` : ''}
          ${profile?.rasse_text  ? `<div style="color:var(--c-text-secondary)">Rasse: <strong>${_esc(profile.rasse_text)}</strong></div>`  : ''}
        </div>
        ${rolle === 'breeder' && profile ? `
        <button class="btn btn-secondary btn-sm" id="breeder-edit-profile-btn" style="margin-top:var(--space-3)">
          ${UI.icon('pencil-simple')} Profil bearbeiten
        </button>` : ''}
        ${rolle === 'admin' && !profile ? `
        <button class="btn btn-primary btn-sm" id="breeder-admin-create-btn" style="margin-top:var(--space-3)">
          ${UI.icon('plus')} Admin-Züchterprofil anlegen
        </button>` : ''}
        ${rolle === 'admin' && profile ? `
        <button class="btn btn-secondary btn-sm" id="breeder-edit-profile-btn" style="margin-top:var(--space-3)">
          ${UI.icon('pencil-simple')} Profil bearbeiten
        </button>` : ''}
        ${profile ? `
        <div style="margin-top:var(--space-4);padding-top:var(--space-3);border-top:1px solid var(--c-border)">
          <div style="font-size:var(--text-xs);font-weight:600;color:var(--c-text-secondary);
                      text-transform:uppercase;letter-spacing:0.05em;margin-bottom:var(--space-3)">
            KI-Züchter-Assistenz
          </div>
          ${_kiToggleRow('ki_zucht_wurfankuendigung', 'Wurfankündigungen schreiben', _appState.user || {})}
          ${_kiToggleRow('ki_zucht_genetik', 'Genetik-Erklärung für Käufer', _appState.user || {})}
          ${_kiToggleRow('ki_zucht_paarung', 'Paarungsanalyse', _appState.user || {})}
          ${_kiToggleRow('ki_zucht_beschreibung', 'Hunde-Beschreibungen', _appState.user || {})}
          ${_kiToggleRow('ki_zucht_jahresbericht', 'Jahresauswertung', _appState.user || {})}
          <div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-top:var(--space-2)">
            ${UI.icon('info')} Der Tierschutz-Check läuft immer automatisch und ist nicht abschaltbar.
          </div>
        </div>` : ''}`;
    } else if (breeder_status === 'pending') {
      statusBadge = `<span class="badge" style="background:#f59e0b;color:#fff">
        ${UI.icon('hourglass')} Antrag wird geprüft
      </span>`;
    } else if (breeder_status === 'rejected') {
      statusBadge = `<span class="badge" style="background:var(--c-danger);color:#fff">
        ${UI.icon('x-circle')} Abgelehnt
      </span>`;
      actionBlock = `
        <div style="margin-top:var(--space-3)">
          <button class="btn btn-secondary btn-sm" id="breeder-reapply-btn">
            ${UI.icon('arrow-counter-clockwise')} Neu beantragen
          </button>
        </div>`;
    } else {
      actionBlock = `
        <div style="margin-top:var(--space-3)">
          <button class="btn btn-primary btn-sm" id="breeder-apply-btn">
            ${UI.icon('certificate')} Züchter werden
          </button>
        </div>`;
    }

    slot.innerHTML = `
      <div class="card" style="margin-bottom:var(--space-4)">
        <div style="padding:var(--space-3) var(--space-4);
                    font-size:var(--text-xs);font-weight:600;
                    color:var(--c-text-secondary);text-transform:uppercase;
                    letter-spacing:0.05em;border-bottom:1px solid var(--c-border)">
          Züchter-Profil
        </div>
        <div style="padding:var(--space-4)">
          ${statusBadge}
          ${actionBlock}
        </div>
      </div>`;

    // Button-Handler binden
    const applyBtn   = slot.querySelector('#breeder-apply-btn');
    const reapplyBtn = slot.querySelector('#breeder-reapply-btn');
    if (applyBtn || reapplyBtn) {
      (applyBtn || reapplyBtn).addEventListener('click', () => _openBreederApplyModal());
    }

    slot.querySelector('#breeder-edit-profile-btn')?.addEventListener('click', () =>
      _openBreederEditModal(profile)
    );

    slot.querySelector('#breeder-admin-create-btn')?.addEventListener('click', async (e) => {
      const btn = e.currentTarget;
      btn.disabled = true;
      btn.textContent = 'Wird angelegt…';
      try {
        await API.breeder.adminCreateProfile();
        UI.toast.success('Admin-Züchterprofil angelegt. Bitte Seite neu laden.');
        _loadBreederCard();
      } catch (err) {
        UI.toast.error(err.message || 'Fehler beim Anlegen.');
        btn.disabled = false;
        btn.innerHTML = `${UI.icon('plus')} Admin-Züchterprofil anlegen`;
      }
    });

    // KI-Toggle-Handler
    slot.querySelectorAll('.ki-toggle-btn').forEach(btn => {
      btn.addEventListener('click', async () => {
        const key    = btn.dataset.key;
        const active = btn.dataset.active === '1';
        const newVal = active ? 0 : 1;

        // Optimistisches UI-Update
        btn.dataset.active = newVal ? '1' : '0';
        btn.style.background = newVal ? 'var(--c-primary)' : 'var(--c-border)';
        const thumb = btn.querySelector('.by-toggle-thumb');
        if (thumb) thumb.style.left = newVal ? '22px' : '2px';

        try {
          const updated = await API.patch('/profile', { [key]: newVal });
          if (_appState?.user) _appState.user[key] = newVal;
          UI.toast.success(newVal ? 'KI-Feature aktiviert.' : 'KI-Feature deaktiviert.');
        } catch (err) {
          // Revert
          btn.dataset.active = active ? '1' : '0';
          btn.style.background = active ? 'var(--c-primary)' : 'var(--c-border)';
          if (thumb) thumb.style.left = active ? '22px' : '2px';
          UI.toast.error(err?.message || 'Einstellung konnte nicht gespeichert werden.');
        }
      });
    });
  }

  // ----------------------------------------------------------
  // ZÜCHTER-PROFIL BEARBEITEN MODAL
  // ----------------------------------------------------------
  function _openBreederEditModal(profile) {
    const inputStyle = `width:100%;box-sizing:border-box;padding:var(--space-2) var(--space-3);
      border:1.5px solid var(--c-border);border-radius:var(--radius-md);
      font-size:var(--text-sm);font-family:inherit;
      background:var(--c-surface);color:var(--c-text)`;

    UI.modal.open({
      title: `${UI.icon('pencil-simple')} Züchter-Profil bearbeiten`,
      body: `
        <form id="breeder-edit-form" style="display:flex;flex-direction:column;gap:var(--space-4)">
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Zwingername</label>
            <input name="zwingername" type="text" maxlength="100" style="${inputStyle}"
                   value="${_esc(profile?.zwingername || '')}">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Rasse</label>
            <input name="rasse_text" type="text" maxlength="100" style="${inputStyle}"
                   value="${_esc(profile?.rasse_text || '')}">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Zuchtverein</label>
            <input name="verein" type="text" maxlength="100" style="${inputStyle}"
                   value="${_esc(profile?.verein || '')}">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Stadt</label>
            <input name="stadt" type="text" maxlength="80" style="${inputStyle}"
                   value="${_esc(profile?.stadt || '')}">
          </div>
          <div style="display:flex;align-items:center;gap:var(--space-3)">
            <input name="vdh_mitglied" type="checkbox" id="edit-breeder-vdh"
                   style="width:18px;height:18px;cursor:pointer;flex-shrink:0"
                   ${profile?.vdh_mitglied ? 'checked' : ''}>
            <label for="edit-breeder-vdh" style="font-size:var(--text-sm);cursor:pointer">VDH-Mitglied</label>
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Website (optional)</label>
            <input name="website" type="url" maxlength="200" style="${inputStyle}"
                   value="${_esc(profile?.website || '')}" placeholder="https://mein-zwinger.de">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">Beschreibung (optional)</label>
            <textarea name="beschreibung" maxlength="500" rows="3"
                      style="${inputStyle};resize:vertical">${_esc(profile?.beschreibung || '')}</textarea>
          </div>
        </form>`,
      footer: `
        <div style="display:flex;gap:var(--space-2);width:100%">
          <button type="submit" form="breeder-edit-form" class="btn btn-primary flex-1" id="breeder-edit-submit">Speichern</button>
          <button type="button" class="btn btn-secondary" data-modal-close>Abbrechen</button>
        </div>`,
    });

    document.getElementById('breeder-edit-form')?.addEventListener('submit', async e => {
      e.preventDefault();
      const btn = document.getElementById('breeder-edit-submit');
      await UI.asyncButton(btn, async () => {
        const form = e.target;
        const data = {
          zwingername:  form.zwingername.value.trim()  || undefined,
          rasse_text:   form.rasse_text.value.trim()   || undefined,
          verein:       form.verein.value.trim()        || undefined,
          stadt:        form.stadt.value.trim()         || undefined,
          vdh_mitglied: form.vdh_mitglied.checked ? 1 : 0,
          website:      form.website.value.trim()       || undefined,
          beschreibung: form.beschreibung.value.trim()  || undefined,
        };
        await API.breeder.updateProfile(data);
        UI.modal.close?.();
        UI.toast.success('Profil aktualisiert.');
        _loadBreederCard();
      });
    });
  }

  // ----------------------------------------------------------
  // ZÜCHTER-ANTRAG MODAL
  // ----------------------------------------------------------
  function _openBreederApplyModal() {
    const inputStyle = `width:100%;box-sizing:border-box;padding:var(--space-2) var(--space-3);
      border:1.5px solid var(--c-border);border-radius:var(--radius-md);
      font-size:var(--text-sm);font-family:inherit;
      background:var(--c-surface);color:var(--c-text)`;

    UI.modal.open({
      title: `${UI.icon('certificate')} Züchter-Antrag stellen`,
      body: `
        <form id="breeder-apply-form" style="display:flex;flex-direction:column;gap:var(--space-4)">
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">
              Zwingername <span style="color:var(--c-danger)">*</span>
            </label>
            <input name="zwingername" type="text" maxlength="100" required
                   placeholder="z. B. vom Sonnenfeld"
                   style="${inputStyle}">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">
              Rasse <span style="color:var(--c-danger)">*</span>
            </label>
            <input name="rasse_text" type="text" maxlength="100" required
                   placeholder="z. B. Labrador Retriever"
                   style="${inputStyle}">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">
              Zuchtverein <span style="color:var(--c-danger)">*</span>
            </label>
            <input name="verein" type="text" maxlength="100" required
                   placeholder="z. B. DLRG, VDH, BCD"
                   style="${inputStyle}">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">
              Stadt <span style="color:var(--c-danger)">*</span>
            </label>
            <input name="stadt" type="text" maxlength="80" required
                   placeholder="z. B. München"
                   style="${inputStyle}">
          </div>
          <div style="display:flex;align-items:center;gap:var(--space-3)">
            <input name="vdh_mitglied" type="checkbox" id="breeder-vdh"
                   style="width:18px;height:18px;cursor:pointer;flex-shrink:0">
            <label for="breeder-vdh" style="font-size:var(--text-sm);cursor:pointer">
              VDH-Mitglied
            </label>
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">
              Website (optional)
            </label>
            <input name="website" type="url" maxlength="200"
                   placeholder="https://mein-zwinger.de"
                   style="${inputStyle}">
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">
              Beschreibung (optional)
            </label>
            <textarea name="beschreibung" maxlength="500" rows="3"
                      placeholder="Kurze Beschreibung deines Zwingers"
                      style="${inputStyle};resize:vertical"></textarea>
          </div>
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:600;margin-bottom:var(--space-1)">
              Dokument hochladen <span style="color:var(--c-danger)">*</span>
            </label>
            <input name="dokument" type="file" id="breeder-doc-input" required
                   accept=".pdf,.jpg,.jpeg,.png,.webp"
                   style="font-size:var(--text-sm);width:100%;box-sizing:border-box">
            <div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-top:var(--space-1)">
              Zuchtbuch-Eintrag, Vereinsmitgliedschaft o.ä. (PDF, JPG, PNG, WebP)
            </div>
          </div>
        </form>
      `,
      footer: `
        <div style="display:flex;flex-direction:column;gap:var(--space-2);width:100%">
          <button type="submit" form="breeder-apply-form" class="btn btn-primary" id="breeder-apply-submit"
                  style="width:100%">Antrag einreichen</button>
          <button type="button" class="btn btn-secondary" data-modal-close>Abbrechen</button>
        </div>
      `,
    });

    document.getElementById('breeder-apply-form')?.addEventListener('submit', async e => {
      e.preventDefault();
      const btn = document.getElementById('breeder-apply-submit');
      await UI.asyncButton(btn, async () => {
        const form = e.target;
        const fd = new FormData(form);
        // Checkbox-Wert normalisieren
        fd.set('vdh_mitglied', form.querySelector('[name="vdh_mitglied"]').checked ? '1' : '0');
        await API.breeder.apply(fd);
        UI.modal.close?.();
        UI.toast.success('Antrag eingereicht. Du wirst benachrichtigt sobald er geprüft wurde.');
        // Card neu laden
        _loadBreederCard();
      });
    });
  }

  // ----------------------------------------------------------
  // REFERRAL — Einladungslink laden und rendern
  // ----------------------------------------------------------
  async function _loadReferral() {
    const el = document.getElementById('referral-body');
    if (!el) return;
    try {
      const r = await API.auth.referral();

      const TIERS = [{t:10,d:20},{t:20,d:30},{t:50,d:50}];
      const currentTier = r.discount_pct;
      const next        = r.next_tier;

      // Fortschrittsbalken-Berechnung
      let barPct = 0, barLabel = '';
      if (!next) {
        barPct = 100;
        barLabel = 'Maximaler Rabatt erreicht!';
      } else {
        const prevT = TIERS.find(t => t.d === currentTier)?.t || 0;
        barPct  = Math.round(((r.count - prevT) / (next.count - prevT)) * 100);
        barLabel = `Noch ${next.count - r.count} ${next.count - r.count === 1 ? 'Person' : 'Personen'} bis ${next.discount}% Rabatt`;
      }

      el.innerHTML = `
        <!-- Tier-Übersicht -->
        <div style="display:flex;gap:var(--space-2);margin-bottom:var(--space-4)">
          ${TIERS.map(({t, d}) => {
            const reached = r.count >= t;
            return `<div style="flex:1;padding:var(--space-2) var(--space-1);border-radius:var(--radius-md);
                                text-align:center;border:2px solid ${reached ? '#7c3aed' : 'var(--c-border)'};
                                background:${reached ? 'rgba(124,58,237,.08)' : 'var(--c-surface-2)'}">
              <div style="font-size:var(--text-lg);font-weight:800;color:${reached ? '#7c3aed' : 'var(--c-text-muted)'}">
                ${d}%
              </div>
              <div style="font-size:10px;color:var(--c-text-muted)">ab ${t} Freunden</div>
              ${reached ? `<div style="font-size:10px;font-weight:700;color:#7c3aed">✓ Erreicht</div>` : ''}
            </div>`;
          }).join('')}
        </div>

        <!-- Zähler + Fortschritt -->
        <div style="margin-bottom:var(--space-4)">
          <div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:var(--space-1)">
            <span style="font-size:var(--text-sm);font-weight:600">
              ${UI.icon('users')} <strong>${r.count}</strong> ${r.count === 1 ? 'Freund geworben' : 'Freunde geworben'}
            </span>
            ${currentTier > 0 ? `<span style="font-size:var(--text-xs);font-weight:700;color:#7c3aed">${currentTier}% Rabatt aktiv</span>` : ''}
          </div>
          <div style="background:var(--c-surface-2);border-radius:var(--radius-full);height:10px;overflow:hidden">
            <div style="background:linear-gradient(90deg,#7c3aed,#a855f7);width:${barPct}%;height:100%;
                        border-radius:var(--radius-full);transition:width .5s ease"></div>
          </div>
          <div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-top:var(--space-1)">${barLabel}</div>
        </div>

        <!-- Link + QR -->
        <div style="display:flex;align-items:center;gap:var(--space-3);margin-bottom:var(--space-3)">
          <div style="flex:1;min-width:0;background:var(--c-surface-2);border-radius:var(--radius-md);
                      padding:var(--space-2) var(--space-3);font-family:monospace;font-size:var(--text-sm);
                      overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${r.link}</div>
          <button class="btn btn-primary btn-sm" id="ref-share-btn">${UI.icon('arrow-square-out')} Teilen</button>
        </div>
        <div style="display:flex;justify-content:center;margin-bottom:var(--space-1)">
          <div style="position:relative;width:140px;height:140px">
            <div id="ref-qr" style="width:140px;height:140px;border-radius:var(--radius-md);overflow:hidden"></div>
            <img src="/icons/icon-180.png" alt=""
                 style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
                        width:32px;height:32px;border-radius:7px;border:2px solid #fff">
          </div>
        </div>
        <p style="font-size:var(--text-xs);color:var(--c-text-muted);text-align:center;margin:0">
          Der Rabatt gilt für dich — sobald Bezahlfunktionen aktiv sind, dauerhaft und automatisch.
        </p>
      `;

      document.getElementById('ref-share-btn')?.addEventListener('click', async () => {
        const msg = `Ich bin bei Ban Yaro — der coolsten Hunde-App! Registrier dich mit meinem Link und wir wachsen zusammen 🐾`;
        if (navigator.share) {
          navigator.share({ title: 'Ban Yaro', text: msg, url: r.link }).catch(() => {});
        } else {
          await navigator.clipboard.writeText(r.link);
          UI.toast.success('Link kopiert!');
        }
      });

      await App.loadScript('/js/qrcode.min.js');
      new QRCode(document.getElementById('ref-qr'), {
        text: r.link, width: 140, height: 140,
        colorDark: '#000000', colorLight: '#ffffff',
        correctLevel: QRCode.CorrectLevel.H,
      });
    } catch { el.innerHTML = ''; }
  }

  // ----------------------------------------------------------
  // NICHT EINGELOGGT — Login / Registrierung
  // ----------------------------------------------------------
  function _renderVerifyPending(email) {
    _container.innerHTML = `
      <div style="max-width:380px;margin:0 auto;padding:var(--space-6) 0;text-align:center">
        <div style="margin-bottom:var(--space-5)">
          <img src="/icons/icon-180.png" alt="Ban Yaro"
               style="width:72px;height:72px;border-radius:var(--radius-lg);margin-bottom:var(--space-3)">
          <h1 style="font-size:var(--text-2xl);font-weight:700;margin:0">E-Mail bestätigen</h1>
        </div>
        <div style="background:var(--c-surface-2);border-radius:var(--radius-lg);
                    padding:var(--space-5);margin-bottom:var(--space-4);text-align:left">
          <p style="margin:0 0 var(--space-2)">
            Wir haben einen Bestätigungslink an<br>
            <strong>${email}</strong><br>
            gesendet.
          </p>
          <p style="margin:0;color:var(--c-text-secondary);font-size:var(--text-sm)">
            Bitte prüfe dein Postfach und klicke auf den Link, um dein Konto zu aktivieren.
            Danach kannst du dich hier anmelden.
          </p>
        </div>
        <button id="verify-resend-btn2" class="btn btn-ghost w-full"
                style="margin-bottom:var(--space-3)">
          Link erneut senden
        </button>
        <button id="verify-back-btn" class="btn btn-ghost w-full"
                style="color:var(--c-text-muted);font-size:var(--text-sm)">
          Anderes Konto / Anmelden
        </button>
      </div>
    `;
    document.getElementById('verify-resend-btn2')?.addEventListener('click', async function() {
      this.disabled = true;
      this.textContent = 'Gesendet …';
      try {
        await API.post('/auth/resend-verification', { email });
        UI.toast.success('Bestätigungs-Mail erneut gesendet.');
      } catch {
        UI.toast.error('Fehler beim Senden — bitte versuche es später erneut.');
      }
    });
    document.getElementById('verify-back-btn')?.addEventListener('click', () => _renderAuth('login'));
  }

  function _renderAuth(mode) {
    // Passwort-Reset über Link aus E-Mail
    const resetToken = sessionStorage.getItem('by_reset_token');
    if (resetToken) {
      sessionStorage.removeItem('by_reset_token');
      _renderResetPassword(resetToken);
      return;
    }

    _mode = mode;
    _container.innerHTML = `
      <div style="max-width:380px;margin:0 auto;padding:var(--space-6) 0">

        <!-- Logo -->
        <div style="text-align:center;margin-bottom:var(--space-6)">
          <img src="/icons/icon-180.png" alt="Ban Yaro"
               style="width:72px;height:72px;border-radius:var(--radius-lg);
                      margin-bottom:var(--space-3)">
          <h1 style="font-size:var(--text-2xl);font-weight:700;margin:0">Ban Yaro</h1>
          <p style="color:var(--c-text-secondary);margin:var(--space-1) 0 0">
            Alles rund um deinen Hund
          </p>
        </div>

        <!-- Tab-Toggle -->
        <div style="display:flex;background:var(--c-surface-2);
                    border-radius:var(--radius-md);padding:3px;
                    margin-bottom:var(--space-5)">
          <button id="tab-login"
                  class="btn flex-1 ${mode === 'login' ? 'btn-primary' : 'btn-ghost'}"
                  style="border-radius:calc(var(--radius-md) - 2px)">
            Anmelden
          </button>
          <button id="tab-register"
                  class="btn flex-1 ${mode === 'register' ? 'btn-primary' : 'btn-ghost'}"
                  style="border-radius:calc(var(--radius-md) - 2px)">
            Registrieren
          </button>
        </div>

        ${mode === 'login' ? _loginFormHTML() : _registerFormHTML()}

      </div>
    `;

    document.getElementById('tab-login')
      ?.addEventListener('click', () => _renderAuth('login'));
    document.getElementById('tab-register')
      ?.addEventListener('click', () => _renderAuth('register'));

    if (mode === 'login') {
      _bindLoginForm();
    } else {
      _bindRegisterForm();
    }
  }

  function _loginFormHTML() {
    return `
      <form id="auth-form" autocomplete="on" novalidate>
        <div class="form-group">
          <label class="form-label">E-Mail</label>
          <input class="form-control" type="email" name="email"
                 placeholder="deine@email.de" autocomplete="email" required>
        </div>
        <div class="form-group">
          <label class="form-label">Passwort</label>
          <div style="position:relative">
            <input class="form-control" type="password" name="password" id="login-pw"
                   placeholder="Passwort" autocomplete="current-password" required
                   style="padding-right:var(--space-10)">
            <button type="button" id="login-pw-toggle"
                    class="btn btn-ghost btn-icon"
                    aria-label="Passwort anzeigen"
                    style="position:absolute;right:var(--space-1);top:50%;transform:translateY(-50%);
                           color:var(--c-text-muted);padding:var(--space-2)">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#eye"></use></svg>
            </button>
          </div>
        </div>
        <button type="submit" class="btn btn-primary w-full" style="margin-top:var(--space-2)">
          Anmelden
        </button>
        <p style="text-align:center;margin-top:var(--space-3);font-size:var(--text-xs)">
          <button type="button" id="forgot-pw-link"
                  class="btn btn-ghost"
                  style="font-size:var(--text-xs);color:var(--c-text-muted);padding:0">
            Passwort vergessen?
          </button>
        </p>
      </form>
    `;
  }

  function _registerFormHTML() {
    return `
      <form id="auth-form" autocomplete="on" novalidate>
        <div class="form-group">
          <label class="form-label">Benutzername</label>
          <input class="form-control" type="text" name="name"
                 placeholder="z. B. bellas_mama" autocomplete="username" required
                 pattern="^\\S+$" title="Kein Leerzeichen erlaubt">
          <p style="margin:var(--space-1) 0 0;font-size:var(--text-xs);color:var(--c-text-secondary)">
            Dieser Name ist öffentlich sichtbar und wird bei deinen Beiträgen, Pins und Kommentaren angezeigt.
          </p>
        </div>
        <div class="form-group">
          <label class="form-label">E-Mail</label>
          <input class="form-control" type="email" name="email"
                 placeholder="deine@email.de" autocomplete="email" required>
        </div>
        <div class="form-group">
          <label class="form-label">Passwort</label>
          <div style="position:relative">
            <input class="form-control" type="password" name="password" id="register-pw"
                   placeholder="Mindestens 8 Zeichen" autocomplete="new-password"
                   minlength="8" required style="padding-right:var(--space-10)">
            <button type="button" id="register-pw-toggle"
                    class="btn btn-ghost btn-icon"
                    aria-label="Passwort anzeigen"
                    style="position:absolute;right:var(--space-1);top:50%;transform:translateY(-50%);
                           color:var(--c-text-muted);padding:var(--space-2)">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#eye"></use></svg>
            </button>
          </div>
          <!-- Hundepassphrase-Generator -->
          <div id="pw-gen-box" style="margin-top:var(--space-2);padding:var(--space-3);
                                      background:var(--c-surface-2);border-radius:var(--radius-md);
                                      border-left:3px solid var(--c-primary)">
            <div style="display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-2)">
              <span style="font-size:var(--text-xs);font-weight:700;color:var(--c-text-secondary);
                            text-transform:uppercase;letter-spacing:.05em">🐾 Passwort-Vorschlag</span>
              <button type="button" id="pw-gen-new"
                      style="margin-left:auto;font-size:var(--text-xs);color:var(--c-primary);
                             background:none;border:none;cursor:pointer;padding:0;font-weight:600">
                ↺ neu
              </button>
            </div>
            <div style="display:flex;align-items:center;gap:var(--space-2)">
              <code id="pw-gen-phrase"
                    style="flex:1;font-size:var(--text-sm);font-weight:700;
                           color:var(--c-text);letter-spacing:.02em;word-break:break-all"></code>
              <button type="button" id="pw-gen-use"
                      style="flex-shrink:0;font-size:var(--text-xs);font-weight:600;
                             padding:4px 10px;border-radius:var(--radius-md);
                             background:var(--c-primary);color:#fff;border:none;cursor:pointer">
                Übernehmen
              </button>
            </div>
            <div style="font-size:10px;color:var(--c-text-muted);margin-top:var(--space-1)">
              Sichere Passphrase aus der Hundewelt — leicht zu merken, schwer zu knacken.
            </div>
          </div>
        </div>
        <div class="form-group" style="margin-top:var(--space-2)">
          <label class="form-label" style="font-size:var(--text-xs)">
            Einladungscode <span style="color:var(--c-text-muted);font-weight:400">(optional)</span>
          </label>
          <input class="form-control" type="text" name="partner_code" id="reg-partner-code"
                 placeholder="z. B. HUNDEBLOG" autocomplete="off"
                 style="text-transform:uppercase;font-family:monospace;letter-spacing:.08em">
          <div id="reg-partner-hint" style="display:none;margin-top:var(--space-1);font-size:var(--text-xs);
               padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm)"></div>
        </div>
        <button type="submit" class="btn btn-primary w-full" style="margin-top:var(--space-2)">
          Konto erstellen
        </button>
        <p style="text-align:center;font-size:var(--text-xs);
                  color:var(--c-text-secondary);margin-top:var(--space-3)">
          Mit der Registrierung stimmst du unseren Datenschutzhinweisen zu.<br>
          Deine Daten werden ausschließlich auf unserem Server gespeichert.
        </p>
      </form>
    `;
  }

  function _bindPwToggle(inputId, btnId) {
    const input = document.getElementById(inputId);
    const btn   = document.getElementById(btnId);
    if (!input || !btn) return;
    btn.addEventListener('click', () => {
      const visible = input.type === 'text';
      input.type = visible ? 'password' : 'text';
      btn.setAttribute('aria-label', visible ? 'Passwort anzeigen' : 'Passwort verbergen');
      btn.querySelector('use').setAttribute('href',
        visible ? '/icons/phosphor.svg#eye' : '/icons/phosphor.svg#eye-slash');
    });
  }

  function _bindLoginForm() {
    _bindPwToggle('login-pw', 'login-pw-toggle');

    document.getElementById('forgot-pw-link')?.addEventListener('click', () => {
      const id = 'forgot-pw-modal';
      UI.modal.open({
        title: 'Passwort zurücksetzen',
        body: `
          <form id="${id}" style="display:flex;flex-direction:column;gap:var(--space-3)">
            <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin:0">
              Gib deine E-Mail-Adresse ein. Du erhältst einen Link zum Zurücksetzen deines Passworts.
            </p>
            <div>
              <label class="form-label">E-Mail</label>
              <input class="form-control" id="forgot-pw-email" type="email"
                     placeholder="deine@email.de" autocomplete="email" required>
            </div>
          </form>`,
        footer: `
          <button class="btn btn-secondary" onclick="UI.modal.close()">Abbrechen</button>
          <button class="btn btn-primary" form="${id}" type="submit">Link senden</button>`,
      });
      document.getElementById(id)?.addEventListener('submit', async e => {
        e.preventDefault();
        const btn   = document.querySelector(`[form="${id}"]`);
        const email = document.getElementById('forgot-pw-email').value.trim();
        await UI.asyncButton(btn, async () => {
          await API.post('/auth/forgot-password', { email });
          UI.modal.close();
          UI.toast.success('Falls ein Account existiert, haben wir dir einen Link geschickt.');
        });
      });
    });

    document.getElementById('auth-form')?.addEventListener('submit', async e => {
      e.preventDefault();
      const btn = e.target.querySelector('[type="submit"]');
      const fd  = UI.formData(e.target);

      await UI.asyncButton(btn, async () => {
        let result;
        try {
          result = await API.auth.login(fd.email, fd.password);
        } catch (err) {
          if (err.message === 'EMAIL_NOT_VERIFIED') {
            _renderVerifyPending(fd.email);
            return;
          }
          throw err;
        }
        localStorage.setItem('by_token', result.token);

        // User-Daten laden
        _appState.user = await API.auth.me();
        document.getElementById('sidebar-username').textContent = _appState.user.name;

        // Hunde laden
        try {
          _appState.dogs = await API.dogs.list();
          _appState.activeDog = _appState.dogs[0] || null;
        } catch { /* keine Hunde = okay */ }

        document.getElementById('header-login-btn')?.remove();
        UI.toast.success(`Willkommen zurück, ${_appState.user.name}!`);

        // Push-Benachrichtigungen anbieten wenn noch nicht entschieden
        if (typeof Notification !== 'undefined' && Notification.permission === 'default') {
          _offerPushNotifications();
        }

        // Nach Login: Direkt in HUND-Welt oder Profil anlegen
        if (_appState.activeDog) {
          window.Worlds?.show(1);
        } else {
          App.navigate('dog-profile');
        }
      });
    });
  }

  function _bindRegisterForm() {
    _bindPwToggle('register-pw', 'register-pw-toggle');

    // Hundepassphrase-Generator initialisieren
    const phraseEl = document.getElementById('pw-gen-phrase');
    const pwInput  = document.getElementById('register-pw');
    if (phraseEl) {
      const _refresh = () => { phraseEl.textContent = _genPassphrase(); };
      _refresh();
      document.getElementById('pw-gen-new')?.addEventListener('click', _refresh);
      document.getElementById('pw-gen-use')?.addEventListener('click', () => {
        const phrase = phraseEl.textContent;
        pwInput.value = phrase;
        pwInput.type  = 'text'; // sichtbar machen
        document.getElementById('register-pw-toggle')
          ?.querySelector('use')
          ?.setAttribute('href', '/icons/phosphor.svg#eye-slash');
        // kurzes visuelles Feedback
        const btn = document.getElementById('pw-gen-use');
        btn.textContent = '✓ Übernommen';
        btn.style.background = 'var(--c-success)';
        setTimeout(() => {
          btn.textContent = 'Übernehmen';
          btn.style.background = 'var(--c-primary)';
        }, 1500);
      });
    }

    // Partner-Code live validieren
    const partnerInput = document.getElementById('reg-partner-code');
    const partnerHint  = document.getElementById('reg-partner-hint');
    let _partnerValid  = false;
    if (partnerInput) {
      // Vorausfüllen falls via sessionStorage gesetzt
      const stored = sessionStorage.getItem('by_ref_code') || '';
      if (stored) partnerInput.value = stored;

      let _debounce = null;
      partnerInput.addEventListener('input', () => {
        const code = partnerInput.value.trim().toUpperCase();
        partnerInput.value = code;
        clearTimeout(_debounce);
        partnerHint.style.display = 'none';
        _partnerValid = false;
        if (code.length < 3) return;
        _debounce = setTimeout(async () => {
          try {
            const info = await API.get(`/partner/codes/${encodeURIComponent(code)}/info`);
            if (info.redeemable) {
              partnerHint.textContent = info.grants_founder
                ? `✓ Gültiger Code von "${info.label}" — du erhältst eine lebenslange Gründer-Lizenz!`
                : `✓ Gültiger Einladungscode von "${info.label}"`;
              partnerHint.style.cssText = 'display:block;background:var(--c-success-bg,#f0fdf4);color:var(--c-success,#16a34a);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-xs)';
              _partnerValid = true;
            } else {
              partnerHint.textContent = 'Dieser Code ist bereits vollständig eingelöst.';
              partnerHint.style.cssText = 'display:block;background:#fef2f2;color:#dc2626;padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-xs)';
            }
          } catch {
            partnerHint.textContent = 'Code nicht gefunden.';
            partnerHint.style.cssText = 'display:block;color:var(--c-text-muted);font-size:var(--text-xs)';
          }
        }, 500);
      });
    }

    document.getElementById('auth-form')?.addEventListener('submit', async e => {
      e.preventDefault();
      const btn = e.target.querySelector('[type="submit"]');
      const fd  = UI.formData(e.target);

      if (!fd.name?.trim()) {
        UI.toast.warning('Bitte einen Namen eingeben.');
        return;
      }
      if ((fd.password || '').length < 8) {
        UI.toast.warning('Passwort muss mindestens 8 Zeichen lang sein.');
        return;
      }

      await UI.asyncButton(btn, async () => {
        const partnerCode = (fd.partner_code || '').trim().toUpperCase() || undefined;
        const refCode     = sessionStorage.getItem('by_ref_code') || '';
        const finalCode   = partnerCode || refCode || undefined;
        const result = await API.auth.register(fd.email, fd.password, fd.name.trim(), finalCode);
        if (refCode) sessionStorage.removeItem('by_ref_code');

        if (result.pending_verification) {
          _renderVerifyPending(fd.email);
          return;
        }
      });
    });
  }

  // ----------------------------------------------------------
  // PUSH-BENACHRICHTIGUNGEN ANBIETEN (nach Login)
  // ----------------------------------------------------------
  function _offerPushNotifications() {
    // Kleiner Toast-Banner mit Ja-Button — nicht-invasiv
    const toastEl = document.createElement('div');
    toastEl.id = 'push-offer-banner';
    toastEl.style.cssText = [
      'position:fixed',
      'bottom:calc(var(--nav-h, 64px) + var(--space-3))',
      'left:50%',
      'transform:translateX(-50%)',
      'background:var(--c-surface)',
      'border:1.5px solid var(--c-border)',
      'border-radius:var(--radius-lg)',
      'box-shadow:var(--shadow-lg)',
      'padding:var(--space-3) var(--space-4)',
      'display:flex',
      'align-items:center',
      'gap:var(--space-3)',
      'font-size:var(--text-sm)',
      'z-index:1100',
      'max-width:340px',
      'width:calc(100% - var(--space-8))',
    ].join(';');
    toastEl.innerHTML = `
      <svg class="ph-icon" aria-hidden="true" style="flex-shrink:0;color:var(--c-primary)">
        <use href="/icons/phosphor.svg#bell-ringing"></use>
      </svg>
      <span style="flex:1;line-height:1.4">Push-Benachrichtigungen aktivieren?</span>
      <button id="push-offer-yes" class="btn btn-primary" style="font-size:var(--text-xs);padding:var(--space-1) var(--space-3);flex-shrink:0">Ja</button>
      <button id="push-offer-no" class="btn btn-ghost btn-icon" aria-label="Schließen" style="flex-shrink:0">
        <svg class="ph-icon" style="width:16px;height:16px" aria-hidden="true"><use href="/icons/phosphor.svg#x"></use></svg>
      </button>
    `;
    document.body.appendChild(toastEl);

    const remove = () => toastEl.remove();

    document.getElementById('push-offer-yes')?.addEventListener('click', async () => {
      remove();
      try {
        await API.subscribeToPush();
        UI.toast.success('Push-Benachrichtigungen aktiviert.');
      } catch {
        UI.toast.warning('Push-Benachrichtigungen konnten nicht aktiviert werden.');
      }
    });
    document.getElementById('push-offer-no')?.addEventListener('click', remove);

    // Automatisch ausblenden nach 12 Sekunden
    setTimeout(remove, 12000);
  }

  // ----------------------------------------------------------
  // PASSWORT ZURÜCKSETZEN
  // ----------------------------------------------------------
  function _renderResetPassword(token) {
    _container.innerHTML = `
      <div style="max-width:380px;margin:0 auto;padding:var(--space-6) 0">
        <div style="text-align:center;margin-bottom:var(--space-6)">
          <img src="/icons/icon-180.png" alt="Ban Yaro"
               style="width:72px;height:72px;border-radius:var(--radius-lg);margin-bottom:var(--space-3)">
          <h1 style="font-size:var(--text-2xl);font-weight:700;margin:0">Neues Passwort</h1>
          <p style="color:var(--c-text-secondary);margin:var(--space-1) 0 0">
            Wähle ein sicheres Passwort für deinen Account.
          </p>
        </div>

        <form id="reset-pw-form" style="display:flex;flex-direction:column;gap:var(--space-4)">
          <div>
            <label class="form-label">Neues Passwort</label>
            <div style="position:relative">
              <input class="form-control" type="password" id="reset-pw-input"
                     placeholder="Mindestens 8 Zeichen" autocomplete="new-password"
                     minlength="8" required style="padding-right:var(--space-10)">
              <button type="button" id="reset-pw-toggle"
                      class="btn btn-ghost btn-icon"
                      style="position:absolute;right:var(--space-1);top:50%;transform:translateY(-50%);
                             color:var(--c-text-muted);padding:var(--space-2)">
                <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#eye"></use></svg>
              </button>
            </div>
            <!-- Hundepassphrase-Generator -->
            <div style="margin-top:var(--space-2);padding:var(--space-3);
                        background:var(--c-surface-2);border-radius:var(--radius-md);
                        border-left:3px solid var(--c-primary)">
              <div style="display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-2)">
                <span style="font-size:var(--text-xs);font-weight:700;color:var(--c-text-secondary);
                              text-transform:uppercase;letter-spacing:.05em">🐾 Passwort-Vorschlag</span>
                <button type="button" id="reset-gen-new"
                        style="margin-left:auto;font-size:var(--text-xs);color:var(--c-primary);
                               background:none;border:none;cursor:pointer;padding:0;font-weight:600">
                  ↺ neu
                </button>
              </div>
              <div style="display:flex;align-items:center;gap:var(--space-2)">
                <code id="reset-gen-phrase"
                      style="flex:1;font-size:var(--text-sm);font-weight:700;
                             color:var(--c-text);letter-spacing:.02em;word-break:break-all"></code>
                <button type="button" id="reset-gen-use"
                        class="btn btn-sm btn-secondary" style="flex-shrink:0">
                  Übernehmen
                </button>
              </div>
            </div>
          </div>

          <button type="submit" class="btn btn-primary w-full">
            Passwort speichern
          </button>
        </form>
      </div>
    `;

    _bindPwToggle('reset-pw-input', 'reset-pw-toggle');

    const phraseEl = document.getElementById('reset-gen-phrase');
    const pwInput  = document.getElementById('reset-pw-input');
    const _refresh = () => { phraseEl.textContent = _genPassphrase(); };
    _refresh();
    document.getElementById('reset-gen-new')?.addEventListener('click', _refresh);
    document.getElementById('reset-gen-use')?.addEventListener('click', () => {
      pwInput.value = phraseEl.textContent;
      pwInput.type  = 'text';
    });

    document.getElementById('reset-pw-form')?.addEventListener('submit', async e => {
      e.preventDefault();
      const btn      = e.target.querySelector('[type="submit"]');
      const password = document.getElementById('reset-pw-input').value;
      await UI.asyncButton(btn, async () => {
        const res = await API.post('/auth/reset-password', { token, password });
        if (res?.ok) {
          UI.toast.success('Passwort geändert! Du kannst dich jetzt anmelden.');
          _renderAuth('login');
        }
      });
    });
  }

  // ----------------------------------------------------------
  // HELPER
  // ----------------------------------------------------------
  function _esc(str) {
    if (!str) return '';
    return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
              .replace(/"/g, '&quot;');
  }

  // ----------------------------------------------------------
  // PUBLIC
  // ----------------------------------------------------------
  return { init, refresh };

})();
