// Akten — Mietverträge (Mieter) + Protokolle (Vorlagen), alles editierbar.
const { useState, useEffect, useRef } = React;

// ─── Rentals list ───────────────────────────────────────────
function RentalsList({ rentals, onSelect, onNew, equipment, blockedCustomers = [] }) {
  const t = useTheme();
  const [filter, setFilter] = useState('alle'); // alle | aktiv | reserviert | abgeschlossen | gesperrt
  const blockedSet = new Set((blockedCustomers || []).map(b => b.key));
  const isBlocked = (r) => blockedSet.has(normalizeCustomerKey(r.tenantName));
  const counts = {
    alle: rentals.length,
    aktiv: rentals.filter(r => r.status === 'aktiv').length,
    reserviert: rentals.filter(r => r.status === 'reserviert').length,
    abgeschlossen: rentals.filter(r => r.status === 'abgeschlossen').length,
    gesperrt: rentals.filter(isBlocked).length,
  };
  const visible = rentals.filter(r => {
    if (filter === 'alle') return true;
    if (filter === 'gesperrt') return isBlocked(r);
    return r.status === filter;
  });
  const SEGMENTS = [
    { id: 'alle',          label: 'Alle' },
    { id: 'aktiv',         label: 'Aktiv' },
    { id: 'reserviert',    label: 'Reserv.' },
    { id: 'abgeschlossen', label: 'Fertig' },
    { id: 'gesperrt',      label: 'Gesperrt', danger: true },
  ];
  return (
    <div>
      <Pressable onClick={onNew} scale={0.98} style={{ margin: '0 16px 12px' }}>
        <div style={{
          background: t.solidBg, color: t.solidFg, borderRadius: 14, padding: '14px 16px',
          display: 'flex', alignItems: 'center', gap: 10, justifyContent: 'center',
          boxShadow: '0 6px 16px rgba(0,0,0,0.28)', fontSize: 14, fontWeight: 600
        }}>
          <Icon d={icons.plus} color={t.solidFg} size={16} sw={2.6} />
          Neuer Auftrag
        </div>
      </Pressable>

      {/* iOS-style filter bar — Alle / Aktiv / Reserv. / Fertig / Gesperrt */}
      <div style={{
        margin: '0 12px 12px', padding: '6px 6px',
        borderBottom: `0.5px solid ${t.sep}`,
        display: 'flex', gap: 6, overflowX: 'auto',
        scrollbarWidth: 'none', WebkitOverflowScrolling: 'touch',
      }}>
        <style>{`.rf-filter-bar::-webkit-scrollbar{display:none}`}</style>
        {SEGMENTS.map(seg => {
          const on = filter === seg.id;
          const count = counts[seg.id];
          const showCount = on && count > 0 && seg.id !== 'alle';
          const dangerOn = on && seg.danger;
          return (
            <Pressable key={seg.id} onClick={() => setFilter(seg.id)} scale={0.95}>
              <div style={{
                height: 34, padding: '0 14px', borderRadius: 100,
                background: on ? (dangerOn ? t.redSoft : (t.dark ? '#48484A' : '#fff')) : 'transparent',
                boxShadow: on ? '0 1px 2px rgba(0,0,0,0.06), 0 0 0 0.5px rgba(0,0,0,0.06)' : 'none',
                display: 'flex', alignItems: 'center', gap: 6, whiteSpace: 'nowrap',
              }}>
                <span style={{
                  fontSize: 14, fontWeight: on ? 600 : 500,
                  color: on ? (dangerOn ? t.red : t.text) : t.textSec,
                  letterSpacing: -0.2,
                }}>{seg.label}</span>
                {showCount && (
                  <span style={{
                    fontSize: 10.5, fontWeight: 700,
                    color: dangerOn ? t.red : t.textSec,
                    fontVariantNumeric: 'tabular-nums',
                  }}>{count}</span>
                )}
              </div>
            </Pressable>
          );
        })}
      </div>      <div style={{ padding: '0 16px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {visible.map((r) => {
          const m = statusMeta(r.status);
          const eq = equipment.find((e) => e.id === r.equipmentId);
          const blocked = isBlocked(r);
          return (
            <Pressable key={r.id} onClick={() => onSelect(r)} scale={0.98}>
              <div style={{
                background: t.card, borderRadius: 16, padding: 14,
              }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10 }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 7, minWidth: 0 }}>
                      {blocked && (
                        <span style={{
                          width: 8, height: 8, borderRadius: 4, background: t.red,
                          flexShrink: 0, display: 'inline-block'
                        }} />
                      )}
                      <div style={{ fontSize: 15, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.tenantName}</div>
                    </div>
                    <div style={{ fontSize: 12, color: t.textSec, marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{rentalEquipmentLabel(r) || (eq ? eq.name : r.equipmentName)}</div>
                  </div>
                  <div style={{
                    fontSize: 9, fontWeight: 700, padding: '3px 7px', borderRadius: 100,
                    background: m.color + '22', color: m.color, flexShrink: 0,
                    letterSpacing: 0.4, whiteSpace: 'nowrap'
                  }}>● {m.label}</div>
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 10, paddingTop: 10, borderTop: `0.5px solid ${t.sep}` }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
                    <div style={{ fontSize: 11, color: t.textSec, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {fmtRange(r.start, r.end)}
                      {r.purpose && <span style={{ color: t.textTer }}> · {r.purpose}</span>}
                    </div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
                    <div style={{ fontSize: 14, fontWeight: 700, color: t.text }}>{rentalTotal(r)} €</div>
                  </div>
                </div>
              </div>
            </Pressable>);

        })}
        {visible.length === 0 &&
        <div style={{ textAlign: 'center', padding: '40px 20px', color: t.textSec, fontSize: 13 }}>
          {filter === 'gesperrt' ? 'Keine gesperrten Kunden.'
            : filter !== 'alle' ? 'Keine Aufträge in diesem Status.'
            : 'Noch keine Mieter angelegt.'}
        </div>
        }
      </div>
    </div>);

}

// ─── New rental sheet ─────────────────────────────────────
// ─── Reusable multi-item equipment editor ──────────────────────
const isPairEq = (eq) => eq && /lautsprech|aktivlautsprech|box\b|monitor/i.test((eq.name || '') + ' ' + (eq.cat || ''));
// expose for cross-screen peeks
if (typeof window !== 'undefined') window.isPairEq = isPairEq;

function RentalItemsEditor({ items, onChange, equipment, days, rentals = [], events = [], rentalStart, rentalEnd, excludeRentalId }) {
  const t = useTheme();
  const [picking, setPicking] = useState(false);

  const used = new Set(items.map((it) => it.equipmentId));
  const available = equipment.filter((e) => !used.has(e.id));

  const updateItem = (idx, patch) => onChange(items.map((it, i) => i === idx ? { ...it, ...patch } : it));
  const removeItem = (idx) => onChange(items.filter((_, i) => i !== idx));
  const addEquipment = (eq) => {
    const isPair = isPairEq(eq);
    onChange([...items, {
      equipmentId: eq.id, equipmentName: eq.name,
      dailyRate: Number(eq.price) || 0,
      quantity: isPair ? 2 : 1,
      // Mark pair items so totals know to halve per-piece (pair price ÷ 2 × pieces)
      isPair
    }]);
    setPicking(false);
  };

  // For pair items the catalog price is per Paar (2 pieces) → per piece = half.
  const itemDayCost = (it) => {
    const isPair = it.isPair || isPairEq(equipment.find((e) => e.id === it.equipmentId));
    const perPiece = isPair ? (Number(it.dailyRate) || 0) / 2 : Number(it.dailyRate) || 0;
    return perPiece * Math.max(1, Number(it.quantity) || 1);
  };
  const dayTotal = items.reduce((s, it) => s + itemDayCost(it), 0);
  const grandTotal = dayTotal * Math.max(1, days || 1);

  return (
    <div>
      {/* Existing items */}
      {items.length === 0 ?
      <div style={{ textAlign: 'center', padding: '20px 16px', background: t.cardAlt, borderRadius: 12, fontSize: 13, color: t.textSec, border: '1px dashed ' + t.sep }}>
          Noch keine Equipment ausgewählt.
        </div> :

      <div style={{ background: t.card, borderRadius: 14, overflow: 'hidden' }}>
          {items.map((it, idx) => {
          const eq = equipment.find((e) => e.id === it.equipmentId);
          const isPair = isPairEq(eq);
          // availability check for THIS specific item
          const conflicts = rentalStart && rentalEnd ? equipmentConflicts(it.equipmentId, rentalStart, rentalEnd, rentals, events, excludeRentalId) : [];
          const free = conflicts.length === 0;
          // Over-quantity check — booked qty exceeds equipment stock
          const stockQty = Math.max(1, Number(eq && eq.qty) || 1);
          const overbook = Number(it.quantity) > stockQty;
          // For pair items the catalog price is per Paar (2 pieces); per piece = half.
          const perPiece = isPair ? (Number(it.dailyRate) || 0) / 2 : Number(it.dailyRate) || 0;
          const priceLabel = isPair ? perPiece + ' €/Stück' : (Number(it.dailyRate) || 0) + ' €/Tag';

          return (
            <div key={it.equipmentId + '-' + idx} style={{
              padding: '12px 14px', borderBottom: idx < items.length - 1 ? `0.5px solid ${t.sep}` : 'none'
            }}>
                <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
                  {eq && <EqAvatar item={eq} size={40} radius={10} />}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {it.equipmentName}
                    </div>
                    <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 2, fontVariantNumeric: 'tabular-nums' }}>
                      {priceLabel}
                    </div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
                    <Pressable onClick={() => updateItem(idx, { quantity: Math.max(1, it.quantity - 1) })} scale={0.85}>
                      <div style={{ width: 30, height: 30, borderRadius: 15, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <Icon d="M5 12h14" color={t.text} size={13} sw={2.4} />
                      </div>
                    </Pressable>
                    <div style={{ minWidth: 22, textAlign: 'center', fontSize: 16, fontWeight: 700, color: t.text, fontVariantNumeric: 'tabular-nums' }}>{it.quantity}</div>
                    <Pressable onClick={() => updateItem(idx, { quantity: it.quantity + 1 })} scale={0.85}>
                      <div style={{ width: 30, height: 30, borderRadius: 15, background: t.solidBg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <Icon d="M12 5v14M5 12h14" color={t.solidFg} size={13} sw={2.4} />
                      </div>
                    </Pressable>
                    <Pressable onClick={() => removeItem(idx)} scale={0.85}>
                      <div style={{ width: 26, height: 26, borderRadius: 13, background: t.redSoft, display: 'flex', alignItems: 'center', justifyContent: 'center', marginLeft: 2 }}>
                        <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke={t.red} strokeWidth="2.4" strokeLinecap="round"><path d="M3 3l6 6M9 3l-6 6" /></svg>
                      </div>
                    </Pressable>
                  </div>
                </div>
                {(!free || overbook) &&
              <div style={{ display: 'flex', gap: 5, marginTop: 8, flexWrap: 'wrap' }}>
                    {!free &&
                <span style={{ fontSize: 10, fontWeight: 700, color: t.red, background: t.redSoft, padding: '2px 7px', borderRadius: 100 }}>⚠ belegt</span>
                }
                    {overbook &&
                <span style={{ fontSize: 10, fontWeight: 700, color: t.orange, background: t.orangeSoft, padding: '2px 7px', borderRadius: 100 }}>⚠ nur {stockQty} verfügbar</span>
                }
                  </div>
              }
              </div>);
        })}
          {days > 0 && dayTotal > 0 &&
        <div style={{ padding: '10px 14px', background: t.cardAlt, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
              <div style={{ fontSize: 11.5, color: t.textSec, fontWeight: 500 }}>{dayTotal} €/Tag · {days} Tag{days > 1 ? 'e' : ''}</div>
              <div style={{ fontSize: 14, fontWeight: 700, color: t.text }}>{grandTotal} €</div>
            </div>
        }
        </div>
      }

      {/* Add equipment */}
      {available.length > 0 &&
      <div style={{ marginTop: 10 }}>
          {picking ?
        <div style={{ background: t.card, borderRadius: 14, padding: 10 }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 4px 8px' }}>
                <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5 }}>Equipment hinzufügen</div>
                <Pressable onClick={() => setPicking(false)} scale={0.9}>
                  <div style={{ fontSize: 12, color: t.accent, fontWeight: 600 }}>Abbrechen</div>
                </Pressable>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {available.map((eq) =>
            <Pressable key={eq.id} onClick={() => addEquipment(eq)} scale={0.98}>
                    <div style={{ padding: '10px 12px', background: t.cardAlt, borderRadius: 10, display: 'flex', alignItems: 'center', gap: 10 }}>
                      <EqAvatar item={eq} size={30} radius={7} />
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 13, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                          {eq.name}{isPairEq(eq) && <span style={{ color: t.textSec, fontWeight: 500, marginLeft: 4 }}>· Paar</span>}
                        </div>
                        <div style={{ fontSize: 11, color: t.textSec, marginTop: 1 }}>{eq.cat} · {eq.price} €/Tag</div>
                      </div>
                      <Icon d="M12 5v14M5 12h14" color={t.accent} size={16} sw={2.4} />
                    </div>
                  </Pressable>
            )}
              </div>
            </div> :

        <Pressable onClick={() => setPicking(true)} scale={0.97}>
              <div style={{
            padding: '12px 14px', textAlign: 'center', borderRadius: 12,
            background: t.accentSoft, color: t.accent, fontSize: 13, fontWeight: 600,
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6
          }}>
                <Icon d="M12 5v14M5 12h14" color={t.accent} size={14} sw={2.4} />
                Equipment hinzufügen ({available.length})
              </div>
            </Pressable>
        }
        </div>
      }
    </div>);

}

function NewRentalSheet({ open, onClose, onSave, equipment, rentals = [], events = [], prefill = null, logistik = {}, company = {}, blockedCustomers = [], toast }) {
  const t = useTheme();
  const blank = {
    tenantName: '', address: '', email: '', phone: '', idCard: '',
    items: [],
    purpose: '', start: todayISO(), end: todayISO(),
    startTime: '09:00', endTime: '18:00',
    deposit: 100, discount: 0,
    note: '',
    color: '',
    delivery: { enabled: false, km: '', address: '' },
    status: 'reserviert', depositStatus: 'offen', paymentStatus: 'offen',
    photos: []
  };
  const [form, setForm] = useState(blank);
  const [showPicker, setShowPicker] = useState(false);

  useEffect(() => {if (open) {
      const base = { ...blank, ...(prefill || {}) };
      // Migrate prefilled single equipment to items[]
      if ((!base.items || !base.items.length) && base.equipmentId) {
        const eq = equipment.find((e) => e.id === base.equipmentId);
        if (eq) {
          base.items = [{
            equipmentId: eq.id, equipmentName: eq.name,
            dailyRate: Number(base.dailyRate || eq.price) || 0,
            quantity: Math.max(1, Number(base.quantity) || (isPairEq(eq) ? 2 : 1))
          }];
        }
      }
      if (!base.items) base.items = [];
      setForm(base);setShowPicker(false);
    }}, [open]);

  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const hasItems = !!(form.items && form.items.length > 0);
  const hasNote = !!(form.note && form.note.trim());
  // Equipment is optional — but only when a note is provided to explain why.
  const valid = !!form.tenantName.trim() && (hasItems || hasNote);

  // ── Perso-Scan (simulierte Datenerkennung aus Ausweisfoto) ──
  const fileRef = useRef(null);
  const [scan, setScan] = useState({ phase: 'idle', img: null }); // idle | scanning | done
  useEffect(() => {if (open) setScan({ phase: 'idle', img: null });}, [open]);

  // Plausible mock identities the "OCR" returns
  const MOCK_IDS = [
  { tenantName: 'Julia Sommer', address: 'Kapuzinerstr. 28\n80469 München', idCard: 'L01X9F4K7' },
  { tenantName: 'Markus Reiter', address: 'Wörthstr. 11\n81667 München', idCard: 'T22M8B1Z3' },
  { tenantName: 'Sabine Hofer', address: 'Schleißheimer Str. 94\n80797 München', idCard: 'C7P4D9Q21' },
  { tenantName: 'Daniel Vogt', address: 'Rosenheimer Str. 145\n81671 München', idCard: 'X5K2T8M40' }];


  const onPickFile = (e) => {
    const file = e.target.files && e.target.files[0];
    const img = file ? URL.createObjectURL(file) : null;
    runScan(img);
    e.target.value = '';
  };
  const runScan = (img) => {
    setScan({ phase: 'scanning', img });
    setTimeout(() => {
      const data = MOCK_IDS[Math.floor(Math.random() * MOCK_IDS.length)];
      setForm((f) => ({ ...f, ...data }));
      setScan({ phase: 'done', img });
    }, 1900);
  };

  // ─── ID-card photo upload (Vorderseite / Rückseite) ───
  const idPhotoRef = useRef(null);
  const [pendingIdSide, setPendingIdSide] = useState(null);
  const triggerIdPhoto = (side) => {
    setPendingIdSide(side);
    if (idPhotoRef.current) {
      idPhotoRef.current.value = '';
      idPhotoRef.current.click();
    }
  };
  const onIdPhotoFile = async (e) => {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    const side = pendingIdSide;
    setPendingIdSide(null);
    try {
      const dataUrl = await compressImage(file, 900);
      const label = side === 'front' ? 'Ausweis Vorderseite' : 'Ausweis Rückseite';
      setForm(f => {
        const others = (f.photos || []).filter(p => p.label !== label);
        return { ...f, photos: [...others, { id: 'ph-' + Date.now(), label, dataUrl, addedAt: todayDE() }] };
      });
    } catch (err) {
      toast && toast('Foto konnte nicht geladen werden');
    }
  };
  const removeIdPhoto = (side) => {
    const label = side === 'front' ? 'Ausweis Vorderseite' : 'Ausweis Rückseite';
    setForm(f => ({ ...f, photos: (f.photos || []).filter(p => p.label !== label) }));
  };

  // Availability check — block double bookings (per item)
  const allConflicts = (form.items || []).flatMap((it) => equipmentConflicts(it.equipmentId, form.start, form.end, rentals, events).map((c) => ({ ...c, equipmentName: it.equipmentName })));
  const free = allConflicts.length === 0 && (form.items || []).length > 0;
  const conflicts = allConflicts;

  const save = () => {
    if (!valid) return;
    const primary = form.items && form.items[0] || null;
    const computedStatus = autoRentalStatus(form.start, form.end);
    const out = {
      id: 'r-' + Date.now(),
      ...form,
      items: (form.items || []).map((it) => ({
        equipmentId: it.equipmentId, equipmentName: it.equipmentName,
        dailyRate: Number(it.dailyRate) || 0,
        quantity: Math.max(1, Number(it.quantity) || 1),
        isPair: !!it.isPair
      })),
      // Keep legacy fields populated from primary item for back-compat
      equipmentId: primary ? primary.equipmentId : '',
      equipmentName: primary ? primary.equipmentName : '',
      dailyRate: primary ? primary.dailyRate : 0,
      quantity: primary ? primary.quantity : 1,
      deposit: Number(form.deposit) || 0,
      discount: Number(form.discount) || 0,
      // Auto-derive status from the date range. Payment & Kaution remain
      // exactly as the user picked them — no override.
      status: computedStatus,
      depositStatus: form.depositStatus || 'offen',
      paymentStatus: form.paymentStatus || 'offen'
    };
    onSave(out);
    onClose();
  };

  const fInp = {
    width: '100%', padding: '12px 14px', borderRadius: 12,
    border: `0.5px solid ${t.inputBorder}`, background: t.card,
    fontSize: 15, color: t.text, outline: 'none', fontFamily: 'inherit', boxSizing: 'border-box'
  };

  return (
    <Sheet open={open} onClose={onClose}>
      <div style={{ padding: '4px 24px 24px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div>
            <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.5 }}>Neuer Mieter</div>
            <div style={{ fontSize: 13, color: t.textSec, marginTop: 4 }}>Mietvertrag anlegen</div>
          </div>
          <Pressable onClick={onClose}><div style={{ fontSize: 14, color: t.textSec, fontWeight: 500 }}>Abbrechen</div></Pressable>
        </div>

        {/* Perso-Scan */}
        <input ref={fileRef} type="file" accept="image/*" onChange={onPickFile} style={{ display: 'none' }} />
        <div style={{ marginTop: 16 }}>
          {scan.phase === 'idle' &&
          <Pressable onClick={() => fileRef.current && fileRef.current.click()} scale={0.98}>
              <div style={{
                borderRadius: 16, padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 14,
                background: t.chip
              }}>
                <div style={{ width: 42, height: 42, borderRadius: 12, background: t.solidBg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                  <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={t.solidFg} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M3 7h3l1.5-2h9L18 7h3v12H3z" /><circle cx="12" cy="13" r="3.5" /></svg>
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14, fontWeight: 700, color: t.text }}>Personalausweis scannen</div>
                  <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 1 }}>Foto aufnehmen – Daten werden automatisch erkannt</div>
                </div>
                <Icon d={icons.chev} color={t.textSec} size={15} sw={2.4} />
              </div>
            </Pressable>
          }

          {scan.phase === 'scanning' &&
          <div style={{
            borderRadius: 16, padding: 14, display: 'flex', alignItems: 'center', gap: 14,
            background: t.card, border: `1px solid ${t.sep}`, position: 'relative', overflow: 'hidden'
          }}>
              <div style={{ width: 56, height: 38, borderRadius: 8, background: t.chip, flexShrink: 0, position: 'relative', overflow: 'hidden' }}>
                {scan.img ?
              <img src={scan.img} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} /> :
              <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20 }}>🪪</div>}
                <div style={{ position: 'absolute', left: 0, right: 0, height: 2, background: t.accent, boxShadow: `0 0 8px ${t.accent}`, animation: 'rfscan 1.2s ease-in-out infinite' }} />
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 14, fontWeight: 700, color: t.text }}>Daten werden erkannt…</div>
                <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 1 }}>Name · Adresse · Ausweis-Nr.</div>
              </div>
              <div style={{ width: 18, height: 18, border: `2px solid ${t.accent}40`, borderTopColor: t.accent, borderRadius: 9, animation: 'rfspin 0.7s linear infinite' }} />
              <style>{`@keyframes rfscan{0%{top:2px}50%{top:32px}100%{top:2px}}@keyframes rfspin{to{transform:rotate(360deg)}}`}</style>
            </div>
          }

          {scan.phase === 'done' &&
          <div style={{
            borderRadius: 16, padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 12,
            background: t.greenSoft, border: `1px solid ${t.green}40`
          }}>
              <div style={{ width: 26, height: 26, borderRadius: 13, background: t.green, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12l5 5L20 7" /></svg>
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 700, color: t.green }}>Daten übernommen</div>
                <div style={{ fontSize: 11, color: t.textSec, marginTop: 1 }}>Bitte zur Sicherheit prüfen.</div>
              </div>
              <Pressable onClick={() => fileRef.current && fileRef.current.click()} scale={0.95}>
                <div style={{ fontSize: 12, fontWeight: 600, color: t.accent }}>Erneut</div>
              </Pressable>
            </div>
          }
        </div>

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Mieter</div>
        {(() => {
          const matched = findBlockedCustomer(form.tenantName, blockedCustomers);
          return (
            <>
              <input value={form.tenantName} onChange={(e) => set('tenantName', e.target.value)} placeholder="Vor- und Nachname *"
                style={{ ...fInp, border: matched ? `1.5px solid ${t.red}` : `0.5px solid ${t.inputBorder}` }} />
              {matched && (
                <div style={{
                  marginTop: 8, borderRadius: 14, padding: '12px 14px',
                  background: t.redSoft, border: `1px solid ${t.red}55`,
                  display: 'flex', alignItems: 'flex-start', gap: 12,
                }}>
                  <div style={{ width: 32, height: 32, borderRadius: 16, background: t.red, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M12 2L4 5v6c0 5 3.5 9 8 11 4.5-2 8-6 8-11V5l-8-3z"/>
                      <path d="M12 8v5M12 16v.5"/>
                    </svg>
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 700, color: t.red }}>Kunde ist gesperrt</div>
                    {matched.reason
                      ? <div style={{ fontSize: 12, color: t.text, marginTop: 3, lineHeight: 1.4 }}>{matched.reason}</div>
                      : <div style={{ fontSize: 12, color: t.textSec, marginTop: 3, lineHeight: 1.4 }}>Kein Grund hinterlegt.</div>
                    }
                    <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 4, fontVariantNumeric: 'tabular-nums' }}>Gesperrt seit {fmtDateDE(matched.since)}</div>
                  </div>
                </div>
              )}
            </>
          );
        })()}
        <div style={{ height: 8 }} />
        <textarea value={form.address} onChange={(e) => set('address', e.target.value)} placeholder="Adresse" rows={2} style={{ ...fInp, resize: 'none' }} />
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 8 }}>
          <input value={form.email} onChange={(e) => set('email', e.target.value)} placeholder="E-Mail" type="email" style={fInp} />
          <input value={form.phone} onChange={(e) => set('phone', e.target.value)} placeholder="Telefon" style={fInp} />
        </div>
        <div style={{ marginTop: 8 }}>
          <input value={form.idCard} onChange={(e) => set('idCard', e.target.value)} placeholder="Ausweis-Nr." style={fInp} />
        </div>

        {/* Ausweis-Fotos */}
        <input ref={idPhotoRef} type="file" accept="image/*" onChange={onIdPhotoFile} style={{ display: 'none' }} />
        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Ausweis-Fotos</div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
          {[
            { side: 'front', label: 'Vorderseite' },
            { side: 'back',  label: 'Rückseite' },
          ].map(({ side, label }) => {
            const fullLabel = side === 'front' ? 'Ausweis Vorderseite' : 'Ausweis Rückseite';
            const ph = (form.photos || []).find(p => p.label === fullLabel);
            return (
              <div key={side} style={{ position: 'relative' }}>
                <Pressable onClick={() => triggerIdPhoto(side)} scale={0.97}>
                  <div style={{
                    aspectRatio: '3 / 2', borderRadius: 12,
                    background: ph ? '#000' : t.chip,
                    border: ph ? 'none' : `1px dashed ${t.inputBorder}`,
                    overflow: 'hidden', position: 'relative',
                    display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 6,
                  }}>
                    {ph ? (
                      <>
                        <img src={ph.dataUrl} alt={fullLabel} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                        <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '14px 10px 8px',
                          background: 'linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.55) 100%)',
                          color: '#fff', fontSize: 11, fontWeight: 600, letterSpacing: 0.2,
                        }}>{label}</div>
                      </>
                    ) : (
                      <>
                        <div style={{ width: 36, height: 36, borderRadius: 18, background: t.chipStrong, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke={t.textSec} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
                            <path d="M3 7h3l1.5-2h9L18 7h3v12H3z" /><circle cx="12" cy="13" r="3.5" />
                          </svg>
                        </div>
                        <div style={{ fontSize: 12, fontWeight: 600, color: t.text }}>{label}</div>
                        <div style={{ fontSize: 10.5, color: t.textTer }}>Foto aufnehmen</div>
                      </>
                    )}
                  </div>
                </Pressable>
                {ph && (
                  <Pressable onClick={() => removeIdPhoto(side)} scale={0.88}>
                    <div style={{
                      position: 'absolute', top: 6, right: 6, width: 26, height: 26, borderRadius: 13,
                      background: 'rgba(0,0,0,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center',
                      backdropFilter: 'blur(8px)',
                    }}>
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.4" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg>
                    </div>
                  </Pressable>
                )}
              </div>
            );
          })}
        </div>

        {/* Mietdaten — Zweck first, mirrors the existing rental edit view */}
        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Mietdaten</div>
        <div>
          <input value={form.purpose} onChange={(e) => set('purpose', e.target.value)} placeholder="Zweck (z.B. Hochzeit)" style={fInp} />
        </div>

        <div style={{ marginTop: 12 }}>
          <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 6 }}>Zeitraum</div>
          <Pressable onClick={() => setShowPicker((s) => !s)} scale={0.99}>
            <div style={{
              padding: '12px 14px', borderRadius: 12,
              border: `0.5px solid ${t.inputBorder}`, background: t.card,
              display: 'flex', justifyContent: 'space-between', alignItems: 'center'
            }}>
              <div>
                <div style={{ fontSize: 14, color: t.text, fontWeight: 500 }}>{fmtRange(form.start, form.end)}</div>
                <div style={{ fontSize: 11, color: t.textSec, marginTop: 2 }}>{daysBetween(form.start, form.end)} Tag{daysBetween(form.start, form.end) > 1 ? 'e' : ''}</div>
              </div>
              <Icon d={showPicker ? 'M5 15l7-7 7 7' : 'M5 9l7 7 7-7'} color={t.textSec} size={16} sw={2} />
            </div>
          </Pressable>
          {showPicker &&
          <div style={{ marginTop: 10, padding: 16, background: t.card, borderRadius: 14, border: '0.5px solid ' + t.sep }}>
              <MiniRangePicker start={form.start} end={form.end}
            onChange={(s, e) => {set('start', s);set('end', e);}}
            anchorISO={form.start} />
            </div>
          }
        </div>

        {/* Pickup & return times */}
        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Uhrzeit</div>
        <div style={{ background: t.card, borderRadius: 14, overflow: 'hidden' }}>
          {/* Ganzer Tag — when on, suppress times so the calendar shows the full-day pill */}
          <div style={{ display: 'flex', padding: '11px 14px', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 12, color: t.text, fontWeight: 600 }}>Ganzer Tag</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>Uhrzeiten werden nicht erfasst</div>
            </div>
            {(() => {
              const allDay = !form.startTime && !form.endTime;
              const toggle = () => {
                if (allDay) {
                  setForm((f) => ({ ...f, startTime: '09:00', endTime: '18:00' }));
                } else {
                  setForm((f) => ({ ...f, startTime: '', endTime: '' }));
                }
              };
              return (
                <Pressable onClick={toggle} scale={0.9}>
                  <div style={{
                    width: 42, height: 26, borderRadius: 13, padding: 2,
                    background: allDay ? t.solidBg : t.chip, display: 'flex',
                    justifyContent: allDay ? 'flex-end' : 'flex-start', alignItems: 'center',
                    transition: 'background 0.15s'
                  }}>
                    <div style={{ width: 22, height: 22, borderRadius: 11, background: '#fff', boxShadow: '0 1px 3px rgba(0,0,0,0.2)' }} />
                  </div>
                </Pressable>);

            })()}
          </div>
          {(form.startTime || form.endTime) && <>
          <div style={{ height: 0.5, background: t.sep, marginLeft: 14 }} />
          <div style={{ display: 'flex', padding: '11px 14px', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Abholung</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>{fmtDateDE(form.start).slice(0, -5)}</div>
            </div>
            <input type="time" value={form.startTime || '09:00'} onChange={(e) => set('startTime', e.target.value)}
              style={{ padding: '7px 10px', borderRadius: 9, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 15, color: t.text, fontFamily: 'inherit', fontWeight: 600, fontFeatureSettings: '"tnum"' }} />
          </div>
          <div style={{ height: 0.5, background: t.sep, marginLeft: 14 }} />
          <div style={{ display: 'flex', padding: '11px 14px', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Rückgabe</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>{fmtDateDE(form.end).slice(0, -5)}</div>
            </div>
            <input type="time" value={form.endTime || '18:00'} onChange={(e) => set('endTime', e.target.value)}
              style={{ padding: '7px 10px', borderRadius: 9, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 15, color: t.text, fontFamily: 'inherit', fontWeight: 600, fontFeatureSettings: '"tnum"' }} />
          </div>
          </>}
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 12 }}>
          <div>
            <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 6 }}>Kaution €</div>
            <input type="number" value={form.deposit} onChange={(e) => set('deposit', e.target.value)} style={fInp} />
          </div>
          <div>
            <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 6 }}>Rabatt €</div>
            <input type="number" value={form.discount || ''} placeholder="0" onChange={(e) => set('discount', e.target.value)} style={fInp} />
          </div>
        </div>

        {/* Equipment — same position as in the existing rental edit view */}
        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Equipment & Anzahl</div>
        <RentalItemsEditor
          items={form.items || []}
          onChange={(v) => set('items', v)}
          equipment={equipment}
          days={daysBetween(form.start, form.end)}
          rentals={rentals} events={events}
          rentalStart={form.start} rentalEnd={form.end} />

        {/* Availability summary — directly under the equipment list */}
        {form.items && form.items.length > 0 &&
          <div style={{ marginTop: 12 }}>
            <div style={{
              borderRadius: 14, padding: '12px 14px',
              background: free ? t.greenSoft : t.redSoft,
              border: `1px solid ${free ? t.green : t.red}40`,
              display: 'flex', alignItems: 'flex-start', gap: 10
            }}>
              <div style={{ width: 26, height: 26, borderRadius: 13, background: free ? t.green : t.red, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                {free ?
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12l5 5L20 7" /></svg> :
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3" strokeLinecap="round"><path d="M12 7v7M12 17.5v.5" /></svg>}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                {free ?
                  <>
                    <div style={{ fontSize: 13, fontWeight: 700, color: t.green }}>Alle Positionen verfügbar</div>
                    <div style={{ fontSize: 11, color: t.textSec, marginTop: 1 }}>{form.items.length} Equipment im Zeitraum frei.</div>
                  </> :
                  <>
                    <div style={{ fontSize: 13, fontWeight: 700, color: t.red }}>Doppelbuchung – mind. eine Position belegt</div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 4, marginTop: 6 }}>
                      {conflicts.map((c) =>
                        <div key={c.kind + c.id} style={{ fontSize: 11, color: t.text, display: 'flex', alignItems: 'center', gap: 6 }}>
                          <span style={{ fontSize: 12 }}>{c.kind === 'rental' ? '👤' : '📅'}</span>
                          {c.equipmentName ? <span style={{ color: t.textSec, fontStyle: 'italic' }}>{c.equipmentName} ·</span> : null}
                          <strong style={{ fontWeight: 600 }}>{c.title}</strong>
                          <span style={{ color: t.textSec }}>· {fmtRange(c.start, c.end)}</span>
                        </div>
                      )}
                    </div>
                  </>
                }
              </div>
            </div>
          </div>
        }

        {/* Zahlungsstatus — user-controlled, always available */}
        {(() => {
          return (
            <>
              <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Zahlungsstatus</div>
              <div style={{ background: t.card, borderRadius: 16, overflow: 'hidden' }}>
                <div style={{ padding: '11px 14px' }}>
                  <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500, marginBottom: 8 }}>Mietbetrag-Status</div>
                  <div style={{ display: 'flex', gap: 6 }}>
                    {PAYMENT_STEPS.map((s) => {
                      const ppm = paymentMeta(s);
                      const sel = (form.paymentStatus || 'offen') === s;
                      return (
                        <Pressable key={s} onClick={() => set('paymentStatus', s)} scale={0.95} style={{ flex: 1 }}>
                          <div style={{
                            padding: '8px 0', textAlign: 'center', borderRadius: 10, fontSize: 11, fontWeight: 600,
                            background: sel ? ppm.color : t.chip,
                            color: sel ? '#fff' : t.textSec
                          }}>{ppm.short}</div>
                        </Pressable>);
                    })}
                  </div>
                </div>
                <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px' }}>
                  <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500, marginBottom: 8 }}>Kaution-Status</div>
                  <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 6 }}>
                    {DEPOSIT_STEPS.map((s) => {
                      const ddm = depositMeta(s);
                      const sel = (form.depositStatus || 'offen') === s;
                      return (
                        <Pressable key={s} onClick={() => set('depositStatus', s)} scale={0.95}>
                          <div style={{
                            padding: '8px 4px', textAlign: 'center', borderRadius: 10, fontSize: 11, fontWeight: 600,
                            background: sel ? ddm.color : t.chip,
                            color: sel ? '#fff' : t.textSec,
                            whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                          }}>{ddm.short}</div>
                        </Pressable>);
                    })}
                  </div>
                </div>
              </div>
            </>
          );
        })()}

        {/* Total */}
        {(() => {
          const days = daysBetween(form.start, form.end);
          const items = form.items || [];
          const sub = items.reduce((s, it) => s + days * Number(it.dailyRate || 0) * Math.max(1, Number(it.quantity) || 1), 0);
          const disc = Math.max(0, Number(form.discount) || 0);
          const tot = Math.max(0, sub - disc);
          if (items.length === 0) return null;
          return (
            <div style={{ marginTop: 14, background: t.card, borderRadius: 14, overflow: 'hidden' }}>
              <div style={{ padding: '11px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div>
                  <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Zwischensumme</div>
                  <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>{items.length} Position{items.length > 1 ? 'en' : ''} · {days} Tag{days > 1 ? 'e' : ''}</div>
                </div>
                <div style={{ fontSize: 14, fontWeight: 600, color: t.text }}>{sub} €</div>
              </div>
              {disc > 0 &&
              <div style={{ padding: '8px 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', borderTop: `0.5px solid ${t.sep}` }}>
                  <div style={{ fontSize: 12, color: t.red, fontWeight: 600 }}>− Rabatt</div>
                  <div style={{ fontSize: 13, fontWeight: 600, color: t.red }}>−{disc} €</div>
                </div>
              }
              <div style={{ height: 0.5, background: t.sep, marginLeft: 14 }} />
              <div style={{ padding: '12px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: t.accentSoft }}>
                <div style={{ fontSize: 13, fontWeight: 700, color: t.text }}>Gesamtpreis</div>
                <div style={{ fontSize: 20, fontWeight: 700, color: t.accent, letterSpacing: -0.4 }}>{tot} €</div>
              </div>
            </div>);

        })()}

        {/* Auto-status — computed from dates */}
        <div style={{ marginTop: 12 }}>
          <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 6 }}>Status · automatisch</div>
          {(() => {
            const autoS = autoRentalStatus(form.start, form.end);
            const sm = statusMeta(autoS);
            return (
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 14px', borderRadius: 12, background: sm.color + '20', border: '0.5px solid ' + sm.color + '40' }}>
                <div style={{ width: 9, height: 9, borderRadius: 5, background: sm.color }} />
                <div style={{ fontSize: 13, fontWeight: 700, color: sm.color, letterSpacing: 0.4 }}>{sm.label}</div>
                <div style={{ flex: 1 }} />
                <div style={{ fontSize: 11, color: t.textSec, fontWeight: 500 }}>aus Zeitraum</div>
              </div>);

          })()}
        </div>

        {/* Delivery toggle + address + auto price preview (mirrors Logistik calc) */}
        <div style={{ marginTop: 14 }}>
          <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>Abholung & Rückgabe</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6, padding: 3, borderRadius: 12, background: t.chipStrong }}>
            {(() => {
              // Two options: self-pickup uses the user's company logo (or building fallback);
              // delivery uses the truck icon from Equipment.
              const opts = [
              { id: 'self', label: 'Kunde holt & bringt' },
              { id: 'deliver', label: 'Wir liefern & holen ab' }];

              return opts.map(({ id, label }) => {
                const isOn = id === 'deliver' === !!(form.delivery && form.delivery.enabled);
                return (
                  <Pressable key={id} onClick={() => set('delivery', { ...(form.delivery || {}), enabled: id === 'deliver' })} scale={0.96} style={{ width: '100%' }}>
                    <div style={{
                      height: 44, padding: '0 8px', textAlign: 'center', borderRadius: 9,
                      background: isOn ? t.dark ? '#48484A' : '#fff' : 'transparent',
                      color: isOn ? t.text : t.textSec,
                      fontSize: 11.5, fontWeight: 600,
                      boxShadow: isOn ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      boxSizing: 'border-box'
                    }}>
                      <span style={{ whiteSpace: 'nowrap' }}>{label}</span>
                    </div>
                  </Pressable>);

              });
            })()}
          </div>

          {form.delivery && form.delivery.enabled && (() => {
            const km = form.delivery.km;
            const factor = form.delivery && form.delivery.tripFactor || logistik && logistik.tripFactor || 4;
            const rate = logistik && logistik.kmRate || 0.7;
            const pauschale = logistik && logistik.pauschale || 10;
            const rawCalc = window.calcDelivery ?
            window.calcDelivery(km, factor, rate, pauschale) :
            (() => {
              const k = Math.max(0, Number(String(km).replace(',', '.')) || 0);
              if (k === 0) return { totalKm: 0, kmCost: 0, total: 0 };
              const totalKm = k * factor;
              return { totalKm, kmCost: totalKm * rate, total: totalKm * rate + pauschale };
            })();
            // Round to whole euros for display + downstream calculations.
            const calc = { ...rawCalc, total: Math.round(rawCalc.total || 0) };

            // Mock geocoder — derives a stable km distance from an address string.
            // Real impl would call an API; here we hash the string + city heuristics.
            const lookupKm = (addr) => {
              const s = String(addr || '').trim().toLowerCase();
              if (!s) return null;
              const cities = {
                'münchen': 24, 'munich': 24, 'augsburg': 58, 'starnberg': 9, 'fürstenfeldbruck': 7,
                'gauting': 11, 'gilching': 8, 'pasing': 16, 'herrsching': 16, 'wessling': 13,
                'planegg': 14, 'krailling': 13, 'neuried': 17, 'gröbenzell': 5, 'olching': 6,
                'puchheim': 4, 'eichenau': 5, 'germering': 0
              };
              for (const [k, v] of Object.entries(cities)) {
                if (s.includes(k)) return v + Math.abs(s.length * 7) % 3;
              }
              // Fallback: hash → 8..45 km
              let h = 0;
              for (let i = 0; i < s.length; i++) h = h * 31 + s.charCodeAt(i) >>> 0;
              return 8 + h % 38;
            };
            const [autoKm, setAutoKm] = [{}, () => {}]; // placeholder satisfied by hook below
            const autoFill = (manual) => {
              const addr = form.delivery && form.delivery.address || form.address;
              const v = lookupKm(addr);
              if (v == null) {
                if (manual) toast && toast('Adresse eingeben');
                return;
              }
              set('delivery', { ...form.delivery, km: String(v).replace('.', ',') });
              if (manual) toast && toast(`~${v} km via Mock-Routing`);
            };

            return (
              <div style={{ marginTop: 10, padding: '12px 14px', background: t.card, borderRadius: 14 }}>
                <textarea value={form.delivery.address || form.address || ''}
                onChange={(e) => set('delivery', { ...form.delivery, address: e.target.value })}
                onBlur={() => {if (!form.delivery.km) autoFill(false);}}
                placeholder="Lieferadresse"
                rows={2}
                style={{ width: '100%', padding: '10px 12px', borderRadius: 10, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 13.5, color: t.text, outline: 'none', resize: 'none', fontFamily: 'inherit', boxSizing: 'border-box' }} />
                <Pressable onClick={() => autoFill(true)} scale={0.96}>
                  <div style={{
                    marginTop: 8, padding: '11px 14px', borderRadius: 10,
                    background: t.solidBg, color: t.solidFg,
                    textAlign: 'center', fontSize: 13, fontWeight: 700, letterSpacing: 0.1
                  }}>
                    Entfernung aus Adresse berechnen
                  </div>
                </Pressable>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 8 }}>
                  <div>
                    <div style={{ fontSize: 10, color: t.textSec, fontWeight: 600, marginBottom: 4 }}>Entfernung (einf.)</div>
                    <div style={{ position: 'relative' }}>
                      <input type="text" inputMode="decimal" value={km} onChange={(e) => set('delivery', { ...form.delivery, km: e.target.value })}
                      placeholder="0"
                      style={{ width: '100%', padding: '10px 30px 10px 12px', borderRadius: 10, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 14, fontWeight: 600, color: t.text, outline: 'none', fontFamily: 'inherit', fontVariantNumeric: 'tabular-nums', boxSizing: 'border-box' }} />
                      <span style={{ position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)', fontSize: 11, color: t.textSec, fontWeight: 600 }}>km</span>
                    </div>
                  </div>
                  <div>
                    <div style={{ fontSize: 10, color: t.textSec, fontWeight: 600, marginBottom: 4 }}>Fahrten <span style={{ color: t.textTer, fontWeight: 500 }}>· nur intern</span></div>
                    <div style={{ display: 'flex', gap: 3, padding: 2, borderRadius: 10, background: t.chipStrong }}>
                      {[
                      { v: 1, label: '1×' },
                      { v: 2, label: '2×' },
                      { v: 4, label: '4×' }].
                      map((opt) => {
                        const sel = factor === opt.v;
                        return (
                          <Pressable key={opt.v} onClick={() => set('delivery', { ...form.delivery, tripFactor: opt.v })} scale={0.95} style={{ flex: 1 }}>
                            <div style={{
                              padding: '7px 0', textAlign: 'center', borderRadius: 7, fontSize: 12, fontWeight: 700,
                              background: sel ? t.dark ? '#48484A' : '#fff' : 'transparent',
                              color: sel ? t.text : t.textSec,
                              boxShadow: sel ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
                              fontVariantNumeric: 'tabular-nums'
                            }}>{opt.label}</div>
                          </Pressable>);

                      })}
                    </div>
                  </div>
                </div>
                {calc.total > 0 &&
                <div style={{ marginTop: 10, paddingTop: 10, borderTop: `0.5px solid ${t.sep}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <div style={{ fontSize: 11, color: t.textSec, fontVariantNumeric: 'tabular-nums' }}>
                      {String(calc.totalKm).replace('.', ',')} km × {String(rate).replace('.', ',')} € + {pauschale} € Pauschale
                      <span style={{ color: t.textTer, marginLeft: 4 }}>· {factor === 4 ? 'bringen+abholen' : factor === 2 ? 'hin+zurück' : 'einfach'}</span>
                    </div>
                    <div style={{ fontSize: 17, fontWeight: 700, color: t.accent, fontVariantNumeric: 'tabular-nums' }}>+ {calc.total} €</div>
                  </div>
                }
              </div>);

          })()}
        </div>

        {/* Calendar bar color */}
        <div style={{ marginTop: 14 }}>
          <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>Farbe im Kalender</div>
          <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
            {EVENT_COLORS.map((c) => {
              const sel = (form.color || '') === c;
              return (
                <Pressable key={c} onClick={() => set('color', c)} scale={0.9}>
                  <div style={{
                    width: 32, height: 32, borderRadius: 16, background: c,
                    border: sel ? '3px solid #fff' : '0',
                    boxShadow: sel ? `0 0 0 2px ${c}, 0 2px 6px rgba(0,0,0,0.15)` : '0 1px 2px rgba(0,0,0,0.1)'
                  }} />
                </Pressable>);

            })}
            <label title="Eigene Farbe" style={{
              width: 32, height: 32, borderRadius: 16, cursor: 'pointer',
              background: `conic-gradient(from 0deg, #ff595e, #ffca3a, #8ac926, #1982c4, #6a4c93, #ff595e)`,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              border: '2px solid ' + t.appBg, boxShadow: '0 1px 2px rgba(0,0,0,0.15)',
            }}>
              <input type="color" value={form.color || '#007AFF'}
                onChange={(e) => set('color', e.target.value)}
                style={{ opacity: 0, width: 1, height: 1, pointerEvents: 'none' }} />
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v3M12 18v3M5 5l2 2M17 17l2 2M3 12h3M18 12h3M5 19l2-2M17 7l2-2" /></svg>
            </label>
            <Pressable onClick={() => set('color', '')} scale={0.9}>
              <div style={{
                width: 32, height: 32, borderRadius: 16, background: t.chip,
                border: !form.color ? '2px dashed ' + t.text : '0',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontSize: 10, fontWeight: 700, color: t.textSec
              }}>Auto</div>
            </Pressable>
          </div>
        </div>

        <div style={{ marginTop: 18 }}>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 6 }}>
            <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5 }}>
              Notiz{!hasItems && <span style={{ color: t.red, marginLeft: 4 }}>*</span>}
            </div>
            {!hasItems && (
              <div style={{ fontSize: 10.5, fontWeight: 700, color: t.red, letterSpacing: 0.3 }}>PFLICHT OHNE EQUIPMENT</div>
            )}
          </div>
          <textarea value={form.note || ''} onChange={(e) => set('note', e.target.value)}
            placeholder={hasItems
              ? 'Kleine Einzelheiten festhalten – z.B. Sonderwünsche, Treffpunkt, Telefon vor Ort, Equipment-Status …'
              : 'Beschreibe den Vorgang – z.B. nur Beratung, externes Equipment, Reservierung für später …'}
            rows={4}
            style={{
              ...fInp, padding: '12px 14px', fontSize: 14, lineHeight: 1.45,
              resize: 'vertical', minHeight: 88, fontFamily: 'inherit',
              border: !hasItems && !hasNote ? `1.5px solid ${t.red}` : `0.5px solid ${t.inputBorder}`,
            }}/>
          <div style={{ fontSize: 11, color: t.textTer, marginTop: 4, lineHeight: 1.4 }}>
            Wird im Kalender unter dem Eintrag angezeigt.
          </div>
        </div>

        <Pressable onClick={save} scale={0.97} disabled={!valid} style={{ marginTop: 22 }}>
          {(() => {
            const blockedHit = findBlockedCustomer(form.tenantName, blockedCustomers);
            let label = hasItems ? 'Mieter anlegen' : 'Ohne Equipment anlegen';
            let bg = t.solidBg;
            if (!valid) bg = t.chip;
            else if (blockedHit) { label = 'Trotz Sperre anlegen'; bg = t.red; }
            else if (hasItems && !free) { label = 'Trotz Belegung anlegen'; bg = t.orange; }
            return (
              <div style={{
                padding: '15px 0', textAlign: 'center', borderRadius: 14,
                background: bg, color: t.solidFg, fontSize: 16, fontWeight: 600
              }}>{label}</div>
            );
          })()}
        </Pressable>
      </div>
    </Sheet>);

}

// ─── Kundenstatus card — block/unblock a customer globally ──────────────
function KundenstatusCard({ tenantName, blockedCustomers = [], setBlockedCustomers, toast }) {
  const t = useTheme();
  const blockedHit = findBlockedCustomer(tenantName, blockedCustomers);
  const isBlocked = !!blockedHit;
  const persistedReason = blockedHit ? blockedHit.reason : '';
  const [reasonDraft, setReasonDraft] = useState(persistedReason);
  // Re-sync draft whenever the persisted reason or customer changes
  useEffect(() => { setReasonDraft(persistedReason); }, [tenantName, isBlocked, persistedReason]);

  const commit = () => {
    if (!setBlockedCustomers || !isBlocked) return;
    if (reasonDraft === persistedReason) return;
    setBlockedCustomers(prev => upsertBlockedCustomer(prev, tenantName, reasonDraft));
  };

  const toggle = () => {
    if (!setBlockedCustomers) return;
    if (isBlocked) {
      setBlockedCustomers(prev => removeBlockedCustomer(prev, tenantName));
      toast && toast(`„${tenantName}“ entsperrt`);
    } else {
      setBlockedCustomers(prev => upsertBlockedCustomer(prev, tenantName, reasonDraft));
      toast && toast(`„${tenantName}“ gesperrt`);
    }
  };

  const dirty = reasonDraft !== persistedReason;

  return (
    <>
      <div style={{ padding: '20px 20px 8px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Kundenstatus</div>
      <div style={{ padding: '0 16px' }}>
        <div style={{
          background: isBlocked ? t.redSoft : t.card, borderRadius: 16, overflow: 'hidden',
          border: isBlocked ? `1px solid ${t.red}55` : `0.5px solid ${t.sep}`,
        }}>
          <div style={{ padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{
              width: 38, height: 38, borderRadius: 12,
              background: isBlocked ? t.red + '22' : t.chip,
              display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
            }}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke={isBlocked ? t.red : t.textSec} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M12 2L4 5v6c0 5 3.5 9 8 11 4.5-2 8-6 8-11V5l-8-3z"/>
                <path d="M12 8v5M12 16v.5"/>
              </svg>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 14, fontWeight: 700, color: isBlocked ? t.red : t.text }}>
                {isBlocked ? 'Kunde ist gesperrt' : 'Kunde nicht gesperrt'}
              </div>
              <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 2, lineHeight: 1.35 }}>
                {isBlocked
                  ? 'Warnung erscheint bei jedem neuen Vorgang dieses Kunden.'
                  : 'Sperre aktivieren, um vor neuen Aufträgen zu warnen.'}
              </div>
            </div>
            <Pressable onClick={toggle} scale={0.9}>
              <div style={{
                width: 46, height: 28, borderRadius: 14, padding: 2,
                background: isBlocked ? t.red : t.chipStrong,
                display: 'flex', alignItems: 'center',
                justifyContent: isBlocked ? 'flex-end' : 'flex-start',
                transition: 'all 0.18s', flexShrink: 0,
              }}>
                <div style={{ width: 24, height: 24, borderRadius: 12, background: '#fff', boxShadow: '0 1px 3px rgba(0,0,0,0.2)' }} />
              </div>
            </Pressable>
          </div>
          {isBlocked && (
            <>
              <div style={{ height: 0.5, background: t.red + '30', marginLeft: 14 }} />
              <div style={{ padding: '12px 14px' }}>
                <div style={{ fontSize: 11, fontWeight: 600, color: t.textSec, marginBottom: 6, letterSpacing: 0.3 }}>Notiz / Grund</div>
                <textarea
                  value={reasonDraft}
                  onChange={(e) => setReasonDraft(e.target.value)}
                  onBlur={commit}
                  placeholder="z.B. Equipment beschädigt zurückgegeben, Zahlungsrückstand …"
                  rows={3}
                  style={{
                    width: '100%', boxSizing: 'border-box', padding: '10px 12px', borderRadius: 10,
                    border: `0.5px solid ${t.red}40`, background: t.dark ? 'rgba(255,255,255,0.04)' : '#fff',
                    fontSize: 13, color: t.text, outline: 'none', fontFamily: 'inherit', resize: 'vertical', lineHeight: 1.4,
                  }}
                />
                <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 6, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <span>Gesperrt seit {fmtDateDE(blockedHit.since)}</span>
                  {dirty && (
                    <Pressable onClick={commit} scale={0.95}>
                      <span style={{ color: t.red, fontWeight: 700 }}>Notiz speichern</span>
                    </Pressable>
                  )}
                </div>
              </div>
            </>
          )}
        </div>
      </div>
    </>
  );
}

// ─── Rental detail (with DRAFT EDIT — explicit save) ───────
function RentalDetail({ rental: persistedRental, onUpdate: persistOnUpdate, onDelete, onBack, equipment, onPreview, onGenerated, onDeleteDoc, generatedDocs, protocols, quickTexts = [], allRentals = [], onSelectRental, blockedCustomers = [], setBlockedCustomers, toast }) {
  const t = useTheme();
  const [protOpen, setProtOpen] = useState(false);
  const [createOpen, setCreateOpen] = useState(false);
  const [quickTextOpen, setQuickTextOpen] = useState(false);
  const [confirmDel, setConfirmDel] = useState(false);
  const [confirmDelDoc, setConfirmDelDoc] = useState(null);
  const [confirmDiscard, setConfirmDiscard] = useState(false);
  const [showPicker, setShowPicker] = useState(false);

  // ── Photo upload state ──
  const photoInputRef = React.useRef(null);
  const [pendingPhotoLabel, setPendingPhotoLabel] = React.useState(null);
  const [photoViewer, setPhotoViewer] = React.useState(null); // photo object being viewed
  const [photoConfirmDel, setPhotoConfirmDel] = React.useState(null);

  // ── Draft layer: edits stay local until "Änderungen speichern" is pressed ──
  const [draft, setDraft] = useState(persistedRental);
  useEffect(() => {setDraft(persistedRental);}, [persistedRental.id]);
  // When the persisted rental changes from outside (e.g. status auto-tick) and we
  // have no local edits, sync the draft so the user sees fresh data.
  useEffect(() => {
    if (JSON.stringify(draft) === JSON.stringify(persistedRental)) return;
    // only auto-sync when fields that drive auto-status changed and the user
    // hasn't touched anything yet — handled by id-effect above; nothing to do.
  }, [persistedRental]);
  const rental = draft;
  const onUpdate = setDraft;
  const dirty = JSON.stringify(draft) !== JSON.stringify(persistedRental);
  const saveChanges = () => {
    persistOnUpdate(draft);
    toast && toast('Änderungen gespeichert');
  };
  const discardChanges = () => {
    setDraft(persistedRental);
    setConfirmDiscard(false);
  };
  const handleBack = () => {
    if (dirty) {setConfirmDiscard(true);return;}
    onBack();
  };

  // ── Photo handlers (write directly to persistOnUpdate — photos are not draft) ──
  const persistedPhotos = persistedRental.photos || [];
  const triggerPhotoPick = (label) => {
    setPendingPhotoLabel(label);
    if (photoInputRef.current) {
      photoInputRef.current.value = '';
      photoInputRef.current.click();
    }
  };
  const onPhotoFile = (e) => {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (ev) => {
      const dataUrl = ev.target.result;
      const label = pendingPhotoLabel || 'Foto';
      let nextPhotos;
      // If a fixed slot (Vorderseite/Rückseite) replace by label; otherwise append.
      if (label === 'Ausweis Vorderseite' || label === 'Ausweis Rückseite') {
        const others = persistedPhotos.filter((p) => p.label !== label);
        nextPhotos = [...others, { id: 'ph-' + Date.now(), label, dataUrl, addedAt: todayDE() }];
      } else {
        nextPhotos = [...persistedPhotos, { id: 'ph-' + Date.now(), label, dataUrl, addedAt: todayDE() }];
      }
      // Apply to both persisted and local draft so the user sees it instantly
      // and the change survives outside the draft layer.
      const updated = { ...persistedRental, photos: nextPhotos };
      persistOnUpdate(updated);
      setDraft((d) => ({ ...d, photos: nextPhotos }));
      toast && toast('Foto hinzugefügt');
    };
    reader.readAsDataURL(file);
    setPendingPhotoLabel(null);
  };
  const deletePhoto = (photo) => {
    const next = persistedPhotos.filter((p) => p.id !== photo.id);
    const updated = { ...persistedRental, photos: next };
    persistOnUpdate(updated);
    setDraft((d) => ({ ...d, photos: next }));
    setPhotoConfirmDel(null);
    setPhotoViewer(null);
    toast && toast('Foto gelöscht');
  };
  const m = statusMeta(rental.status);
  const eq = equipment.find((e) => e.id === rental.equipmentId);
  const days = daysBetween(rental.start, rental.end);
  const subtotal = rentalSubtotal(rental);
  const discount = Math.max(0, Number(rental.discount) || 0);
  const computedTotal = Math.max(0, subtotal - discount);
  const hasOverride = rental.priceOverride != null && rental.priceOverride !== '';
  const total = hasOverride ? Math.max(0, Number(rental.priceOverride) || 0) : computedTotal;
  const deliveryFee = rentalDeliveryFee(rental);
  const qty = (getRentalItems(rental)[0] || {}).quantity || 1;

  // Stammkunde — other rentals of the same tenant
  const tenantHistory = allRentals.
  filter((r) => r.id !== rental.id && r.tenantName.trim().toLowerCase() === rental.tenantName.trim().toLowerCase()).
  sort((a, b) => b.start.localeCompare(a.start));
  const isRegular = tenantHistory.length > 0;

  const updateField = (key, val) => {
    let next = { ...rental, [key]: val };
    if (key === 'start' || key === 'end') {
      next.status = autoRentalStatus(next.start, next.end);
    }
    // Payment & Kaution are 100 % user-controlled. No more auto-override here.
    onUpdate(next);
  };
  const updateNum = (key, val) => onUpdate({ ...rental, [key]: Number(val) || 0 });

  const generateInvoice = () => {
    if (dirty) persistOnUpdate(draft);
    const num = 'RE-' + new Date().getFullYear() + '-' + String(Math.floor(Math.random() * 900) + 100);
    const net = Math.round(total / 1.19 * 100) / 100;
    const tax = Math.round((total - net) * 100) / 100;
    const its = getRentalItems(rental);
    const deliveryFee = rentalDeliveryFee(rental);
    const d = rental.delivery || {};
    const items = its.length ?
    its.map((it) => {
      const perPiece = it.isPair ? (Number(it.dailyRate) || 0) / 2 : Number(it.dailyRate) || 0;
      const sum = days * perPiece * Math.max(1, Number(it.quantity) || 1);
      return {
        desc: (it.quantity > 1 ? it.quantity + ' × ' : '') + 'Vermietung ' + it.equipmentName + (it.isPair ? ' (Stück)' : ''),
        sub: fmtRange(rental.start, rental.end),
        qty: (it.quantity > 1 ? it.quantity + ' St. × ' : '') + days + (days > 1 ? ' Tage' : ' Tag'),
        unit: perPiece,
        sum
      };
    }) :
    [{
      desc: 'Vermietung ' + (eq ? eq.name : rental.equipmentName),
      sub: fmtRange(rental.start, rental.end),
      qty: days + (days > 1 ? ' Tage' : ' Tag'),
      unit: rental.dailyRate, sum: subtotal - deliveryFee
    }];
    if (deliveryFee > 0) {
      items.push({
        desc: 'Anlieferung & Abholung',
        sub: (d.address || rental.address || '').replace(/\n/g, ', '),
        qty: '',
        unit: deliveryFee,
        sum: deliveryFee
      });
    }
    const doc = {
      id: 'inv-' + Date.now(), kind: 'invoice', number: num,
      title: 'Rechnung ' + num, date: todayDE(),
      tenantName: rental.tenantName, address: rental.address || '',
      rentalId: rental.id, total,
      invoice: { items, subtotal, discount, net, tax, total },
      text:
      `RECHNUNG  ${num}
Datum: ${todayDE()}

Empfänger:
${rental.tenantName}
${rental.address || ''}

────────────────────────────────────────────
Position                          Gesamt
────────────────────────────────────────────
Vermietung ${eq ? eq.name : rental.equipmentName}
${days} Tage à ${rental.dailyRate} €                  ${subtotal - deliveryFee} €${deliveryFee > 0 ? `
Anlieferung & Abholung
${(d.address || rental.address || '').replace(/\n/g, ', ')}    ${deliveryFee.toFixed(2).replace('.', ',')} €` : `
Abholung & Rückgabe durch Mieter`}${discount > 0 ? `
Rabatt                                              −${discount} €` : ''}
${fmtRange(rental.start, rental.end)}                        ${total} €
────────────────────────────────────────────
Nettobetrag                       ${net.toFixed(2).replace('.', ',')} €
zzgl. 19% MwSt.                   ${tax.toFixed(2).replace('.', ',')} €
────────────────────────────────────────────
GESAMTBETRAG                       ${total} €

Zahlungsziel: 14 Tage
IBAN: DE12 3456 7890 1234 5678 90

Vielen Dank für Ihren Auftrag!`
    };
    onGenerated(doc);
    onPreview(doc);
    toast('Rechnung erstellt');
  };

  const generateProtocol = (tpl) => {
    if (dirty) persistOnUpdate(draft);
    const text = fillTemplate(tpl.text, rental, eq ? eq.name : rental.equipmentName);
    const doc = {
      id: 't-' + tpl.id + '-' + Date.now(),
      kind: 'protocol', protocolId: tpl.id,
      title: tpl.name, text,
      rentalId: rental.id, date: todayDE(),
      icon: tpl.icon, color: tpl.color
    };
    onGenerated(doc);
    onPreview(doc);
    setProtOpen(false);
    toast(tpl.name + ' erstellt');
  };

  // ─── Schnelltexte (WhatsApp / E-Mail) — editable templates from the Akten ts ───
  const generateQuickText = (qt) => {
    if (dirty) persistOnUpdate(draft);
    const text = fillTemplate(qt.text, rental, eq ? eq.name : rental.equipmentName);
    const doc = {
      id: 'qt-' + qt.id + '-' + Date.now(),
      kind: 'schnelltext', subkind: qt.kind || 'whatsapp',
      title: qt.name, text,
      rentalId: rental.id, date: todayDE(),
      icon: qt.icon, color: t.purple || '#AF52DE',
    };
    onGenerated(doc);
    onPreview(doc);
    setQuickTextOpen(false);
    toast(qt.name + ' erstellt');
  };

  // Doc tile metadata for the Dokumente list
  const docMeta = (d) => {
    if (d.kind === 'invoice')     return { badge: 'PDF', color: t.green, soft: t.green + '22', typeLabel: 'Rechnung' };
    if (d.kind === 'schnelltext') return { badge: 'TXT', color: t.purple || '#AF52DE', soft: (t.purple || '#AF52DE') + '22', typeLabel: d.subkind === 'email' ? 'E-Mail' : 'WhatsApp' };
    /* protocol */
    return { badge: 'PDF', color: d.color || t.accent, soft: (d.color || t.accent) + '22', typeLabel: d.title || 'Protokoll' };
  };

  return (
    <div style={{ paddingBottom: 110 }}>
      <div style={{ padding: '8px 16px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <Pressable onClick={handleBack} scale={0.88}>
          <div style={{ width: 36, height: 36, borderRadius: 18, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Icon d={icons.back} color={t.text} size={20} sw={2.2} />
          </div>
        </Pressable>
        <Pressable onClick={() => setConfirmDel(true)} scale={0.88}>
          <div style={{ width: 36, height: 36, borderRadius: 18, background: t.redSoft, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke={t.red} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6" /></svg>
          </div>
        </Pressable>
      </div>

      <div style={{ padding: '12px 20px 0' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ fontSize: 12, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5 }}>Mietvertrag</div>
          {(() => {
            const sm = statusMeta(rental.status);
            return (
              <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 11px', borderRadius: 100, background: sm.color + '22' }}>
                <div style={{ width: 7, height: 7, borderRadius: 4, background: sm.color }} />
                <span style={{ fontSize: 11, fontWeight: 700, color: sm.color, letterSpacing: 0.4 }}>{sm.label}</span>
              </div>);

          })()}
        </div>
        <div style={{ fontSize: 28, fontWeight: 700, color: t.text, letterSpacing: -0.7, marginTop: 4 }}>
          {rental.tenantName}
        </div>
      </div>

      {/* Tenant — inline editable */}
      <div style={{ padding: '20px 20px 8px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Mieter</div>
      <div style={{ padding: '0 16px' }}>
        <div style={{ background: t.card, borderRadius: 16, overflow: 'hidden' }}>
          {[
          ['Name', 'tenantName', false, 'text'],
          ['Adresse', 'address', true, 'text'],
          ['E-Mail', 'email', false, 'email'],
          ['Telefon', 'phone', false, 'tel'],
          ['Ausweis', 'idCard', false, 'text']].
          map(([label, key, multi, type], i, arr) =>
          <div key={key} style={{ borderBottom: i < arr.length - 1 ? `0.5px solid ${t.sep}` : 'none' }}>
              <Field label={label} value={rental[key]}
            onChange={(v) => updateField(key, v)}
            multiline={multi} type={type} />
            </div>
          )}
        </div>
      </div>

      {/* Personalausweis — Vorderseite / Rückseite (moved up to Mieter area) */}
      <div style={{ padding: '20px 20px 6px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Personalausweis</div>
      <div style={{ padding: '0 20px 0', fontSize: 11.5, color: t.textTer, lineHeight: 1.4, marginBottom: 10 }}>Vorder- und Rückseite fotografieren oder hochladen — wird sicher beim Mietvorgang gespeichert.</div>
      <div style={{ padding: '0 16px' }}>
        <input ref={photoInputRef} type="file" accept="image/*" onChange={onPhotoFile} style={{ display: 'none' }} />
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          {[
            { label: 'Ausweis Vorderseite', short: 'Vorderseite', hint: 'Foto- & Datenseite' },
            { label: 'Ausweis Rückseite',   short: 'Rückseite',  hint: 'Anschrift & Behörde' },
          ].map(({ label, short, hint }) => {
            const ph = (rental.photos || []).find((x) => x.label === label);
            return (
              <div key={label}>
                <div style={{ fontSize: 12, fontWeight: 600, color: t.text, marginBottom: 6, marginLeft: 2 }}>{short}</div>
                <div style={{ position: 'relative' }}>
                  <Pressable onClick={() => ph ? setPhotoViewer(ph) : triggerPhotoPick(label)} scale={0.97}>
                    <div style={{
                      aspectRatio: '3 / 2', borderRadius: 14,
                      background: ph ? '#000' : t.chip,
                      border: ph ? 'none' : `1.5px dashed ${t.inputBorder}`,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      position: 'relative', overflow: 'hidden',
                    }}>
                      {ph ? (
                        <img src={ph.dataUrl} alt={label} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                      ) : (
                        <div style={{ textAlign: 'center', padding: '0 8px' }}>
                          <div style={{ width: 44, height: 44, borderRadius: 12, background: t.chipStrong, display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 10px' }}>
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke={t.textSec} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M3 7h3l1.5-2h9L18 7h3v12H3z" /><circle cx="12" cy="13" r="3.5" /></svg>
                          </div>
                          <div style={{ fontSize: 13, color: t.text, fontWeight: 700 }}>Foto hochladen</div>
                          <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 3 }}>{hint}</div>
                        </div>
                      )}
                    </div>
                  </Pressable>
                  {ph && (
                    <Pressable onClick={(e) => { e.stopPropagation && e.stopPropagation(); setPhotoConfirmDel(ph); }} scale={0.88}>
                      <div style={{
                        position: 'absolute', top: 8, right: 8, width: 28, height: 28, borderRadius: 14,
                        background: 'rgba(0,0,0,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center',
                      }}>
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.4" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg>
                      </div>
                    </Pressable>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* Kundenstatus — block/unblock customer globally */}
      <KundenstatusCard
        tenantName={rental.tenantName}
        blockedCustomers={blockedCustomers}
        setBlockedCustomers={setBlockedCustomers}
        toast={toast}
      />

      {/* Mietdaten (Equipment moved below) */}
      <div style={{ padding: '20px 20px 8px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Mietdaten</div>
      <div style={{ padding: '0 16px' }}>
        <div style={{ background: t.card, borderRadius: 16, overflow: 'hidden' }}>
          <Field label="Zweck" value={rental.purpose} onChange={(v) => updateField('purpose', v)} />
          <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px' }}>
            <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 6 }}>Notiz</div>
            <textarea
              value={rental.note || ''}
              onChange={(e) => updateField('note', e.target.value)}
              placeholder="Kleine Einzelheiten – Sonderwünsche, Treffpunkt …"
              rows={3}
              style={{
                width: '100%', padding: '8px 0', border: 'none', outline: 'none',
                background: 'transparent', color: t.text, fontSize: 14, lineHeight: 1.45,
                fontFamily: 'inherit', resize: 'vertical', minHeight: 60,
              }}/>
          </div>
          <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Zeitraum</div>
            <Pressable onClick={() => setShowPicker((s) => !s)} scale={0.99}>
              <div style={{ fontSize: 13, color: t.text, fontWeight: 500, textAlign: 'right' }}>
                {fmtRange(rental.start, rental.end)} <span style={{ color: t.textTer, fontSize: 10, marginLeft: 4 }}>✎</span>
              </div>
            </Pressable>
          </div>
          {showPicker &&
          <div style={{ padding: 14, borderTop: `0.5px solid ${t.sep}` }}>
              <MiniRangePicker start={rental.start} end={rental.end}
            onChange={(s, e) => onUpdate({ ...rental, start: s, end: e })}
            anchorISO={rental.start} />
            </div>
          }
          {/* Ganzer Tag toggle */}
          <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 12, color: t.text, fontWeight: 600 }}>Ganzer Tag</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>Ohne feste Uhrzeit</div>
            </div>
            {(() => {
              const allDay = !rental.startTime && !rental.endTime;
              const toggle = () => {
                if (allDay) onUpdate({ ...rental, startTime: '09:00', endTime: '18:00' });else
                onUpdate({ ...rental, startTime: '', endTime: '' });
              };
              return (
                <Pressable onClick={toggle} scale={0.9}>
                  <div style={{
                    width: 42, height: 26, borderRadius: 13, padding: 2,
                    background: allDay ? t.solidBg : t.chip, display: 'flex',
                    justifyContent: allDay ? 'flex-end' : 'flex-start', alignItems: 'center'
                  }}>
                    <div style={{ width: 22, height: 22, borderRadius: 11, background: '#fff', boxShadow: '0 1px 3px rgba(0,0,0,0.2)' }} />
                  </div>
                </Pressable>);

            })()}
          </div>
          {(rental.startTime || rental.endTime) && <>
          {/* Pickup time */}
          <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Abholung · Uhrzeit</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>{fmtDateDE(rental.start).slice(0, -5)}</div>
            </div>
            <input type="time" value={rental.startTime || '09:00'}
              onChange={(e) => updateField('startTime', e.target.value)}
              style={{ padding: '6px 10px', borderRadius: 8, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 14, color: t.text, fontFamily: 'inherit', fontWeight: 600, fontFeatureSettings: '"tnum"' }} />
          </div>
          {/* Return time */}
          <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div>
              <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Rückgabe · Uhrzeit</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>{fmtDateDE(rental.end).slice(0, -5)}</div>
            </div>
            <input type="time" value={rental.endTime || '18:00'}
              onChange={(e) => updateField('endTime', e.target.value)}
              style={{ padding: '6px 10px', borderRadius: 8, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 14, color: t.text, fontFamily: 'inherit', fontWeight: 600, fontFeatureSettings: '"tnum"' }} />
          </div>
          </>}
          <div style={{ borderTop: `0.5px solid ${t.sep}` }}>
            <Field label="Kaution €" value={String(rental.deposit)} onChange={(v) => updateNum('deposit', v)} type="number" />
          </div>
          <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Rabatt €</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>Wird vom Gesamtpreis abgezogen</div>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
              <span style={{ fontSize: 14, color: discount > 0 ? t.red : t.textTer, fontWeight: 600 }}>{discount > 0 ? '−' : ''}</span>
              <input type="number" min="0" value={rental.discount || ''} placeholder="0"
              onChange={(e) => updateNum('discount', e.target.value)}
              style={{ width: 78, padding: '6px 8px', borderRadius: 8, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 14, color: discount > 0 ? t.red : t.text, fontFamily: 'inherit', fontWeight: 600, textAlign: 'right', boxSizing: 'border-box' }} />
              <span style={{ fontSize: 13, color: t.textSec, fontWeight: 500 }}>€</span>
            </div>
          </div>
        </div>
      </div>

      {/* Equipment — between Mietdaten and the payment status rows */}
      <div style={{ padding: '20px 20px 8px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Equipment & Anzahl</div>
      <div style={{ padding: '0 16px' }}>
        <RentalItemsEditor
          items={getRentalItems(rental)}
          onChange={(newItems) => {
            const primary = newItems[0] || null;
            onUpdate({
              ...rental,
              items: newItems,
              equipmentId: primary ? primary.equipmentId : '',
              equipmentName: primary ? primary.equipmentName : '',
              dailyRate: primary ? primary.dailyRate : 0,
              quantity: primary ? primary.quantity : 1
            });
          }}
          equipment={equipment}
          days={days}
          rentals={allRentals} events={[]}
          rentalStart={rental.start} rentalEnd={rental.end}
          excludeRentalId={rental.id} />
      </div>

      {/* Zahlungsstatus — user-controlled, always selectable */}
      <div style={{ padding: '20px 20px 8px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Zahlungsstatus</div>
      <div style={{ padding: '0 16px' }}>
        <div style={{ background: t.card, borderRadius: 16, overflow: 'hidden' }}>
          <div style={{ padding: '11px 14px' }}>
            <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500, marginBottom: 8 }}>Mietbetrag-Status</div>
            <div style={{ display: 'flex', gap: 6 }}>
              {PAYMENT_STEPS.map((s) => {
                const pm = paymentMeta(s);
                const sel = (rental.paymentStatus || 'offen') === s;
                return (
                  <Pressable key={s} onClick={() => updateField('paymentStatus', s)} scale={0.95} style={{ flex: 1 }}>
                    <div style={{
                      padding: '8px 0', textAlign: 'center', borderRadius: 10, fontSize: 11, fontWeight: 600,
                      background: sel ? pm.color : t.chip,
                      color: sel ? '#fff' : t.textSec
                    }}>{pm.short}</div>
                  </Pressable>);
              })}
            </div>
          </div>
          <div style={{ borderTop: `0.5px solid ${t.sep}`, padding: '11px 14px' }}>
            <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500, marginBottom: 8 }}>Kaution-Status</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 6 }}>
              {DEPOSIT_STEPS.map((s) => {
                const dm = depositMeta(s);
                const sel = (rental.depositStatus || 'offen') === s;
                return (
                  <Pressable key={s} onClick={() => updateField('depositStatus', s)} scale={0.95}>
                    <div style={{
                      padding: '8px 4px', textAlign: 'center', borderRadius: 10, fontSize: 11, fontWeight: 600,
                      background: sel ? dm.color : t.chip,
                      color: sel ? '#fff' : t.textSec,
                      whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                    }}>{dm.short}</div>
                  </Pressable>);
              })}
            </div>
          </div>
        </div>
      </div>

      {/* Abholung & Rückgabe */}
      <div style={{ padding: '20px 20px 8px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Abholung & Rückgabe</div>
      <div style={{ padding: '0 16px' }}>
        <div style={{ background: t.card, borderRadius: 16, overflow: 'hidden' }}>
          {rental.delivery && rental.delivery.enabled ?
          <div style={{ padding: '11px 14px' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
              <div style={{ fontSize: 13, color: t.text, fontWeight: 700 }}>Lieferung</div>
              <Pressable onClick={() => onUpdate({ ...rental, delivery: { ...rental.delivery, enabled: false } })} scale={0.92}>
                <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600 }}>Selbstabholung</div>
              </Pressable>
            </div>
            <textarea value={rental.delivery.address || rental.address || ''}
              onChange={(e) => onUpdate({ ...rental, delivery: { ...rental.delivery, address: e.target.value } })}
              placeholder="Lieferadresse"
              rows={2}
              style={{ width: '100%', marginTop: 8, padding: '8px 10px', borderRadius: 8, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 13, color: t.text, outline: 'none', resize: 'none', fontFamily: 'inherit', boxSizing: 'border-box' }} />
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 6 }}>
              <div style={{ position: 'relative' }}>
                <input type="text" inputMode="decimal" value={rental.delivery.km || ''}
                  onChange={(e) => onUpdate({ ...rental, delivery: { ...rental.delivery, km: e.target.value } })}
                  placeholder="0"
                  style={{ width: '100%', padding: '8px 28px 8px 10px', borderRadius: 8, border: `0.5px solid ${t.inputBorder}`, background: t.inputBg, fontSize: 13, fontWeight: 600, color: t.text, outline: 'none', fontFamily: 'inherit', fontVariantNumeric: 'tabular-nums', boxSizing: 'border-box' }} />
                <span style={{ position: 'absolute', right: 10, top: '50%', transform: 'translateY(-50%)', fontSize: 11, color: t.textSec, fontWeight: 600 }}>km</span>
              </div>
              <div style={{ padding: '8px 10px', borderRadius: 8, background: t.accentSoft, color: t.accent, fontSize: 14, fontWeight: 700, textAlign: 'right', fontVariantNumeric: 'tabular-nums' }}>
                + {deliveryFee.toFixed(2).replace('.', ',')} €
              </div>
            </div>
            <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 4 }}>Lieferpreis wird automatisch aus km berechnet und in Summe enthalten.</div>
          </div>
          :
          <div style={{ padding: '12px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <div style={{ fontSize: 13, color: t.text, fontWeight: 700 }}>Lieferung</div>
              <div style={{ fontSize: 11, color: t.textSec, marginTop: 2 }}>Bei Vertragsabschluss: Selbstabholung · jetzt nachträglich hinzufügen</div>
            </div>
            <Pressable onClick={() => onUpdate({ ...rental, delivery: { ...(rental.delivery || {}), enabled: true } })} scale={0.92}>
              <div style={{ fontSize: 13, color: t.accent, fontWeight: 700, whiteSpace: 'nowrap' }}>+ Hinzufügen</div>
            </Pressable>
          </div>
          }
        </div>
      </div>

      {/* Farbe (Kalender-Anzeige) */}
      <div style={{ padding: '20px 20px 10px', fontSize: 11, fontWeight: 600, color: t.textSec, textTransform: 'uppercase', letterSpacing: 0.6 }}>Farbe (Kalender-Anzeige)</div>
      <div style={{ padding: '0 20px' }}>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
          {EVENT_COLORS.map((c) => {
            const sel = (rental.color || statusMeta(rental.status).color) === c;
            return (
              <Pressable key={c} onClick={() => updateField('color', c)} scale={0.88}>
                <div style={{
                  width: 32, height: 32, borderRadius: 16, background: c,
                  border: sel ? '3px solid #fff' : '0',
                  boxShadow: sel ? `0 0 0 2px ${c}, 0 1px 4px rgba(0,0,0,0.15)` : '0 1px 2px rgba(0,0,0,0.1)'
                }} />
              </Pressable>);
          })}
          <label title="Eigene Farbe" style={{
            width: 32, height: 32, borderRadius: 16, cursor: 'pointer',
            background: `conic-gradient(from 0deg, #ff595e, #ffca3a, #8ac926, #1982c4, #6a4c93, #ff595e)`,
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            border: '2px solid ' + t.appBg, boxShadow: '0 1px 2px rgba(0,0,0,0.15)'
          }}>
            <input type="color" value={rental.color || '#007AFF'}
              onChange={(e) => updateField('color', e.target.value)}
              style={{ opacity: 0, width: 1, height: 1, pointerEvents: 'none' }} />
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v3M12 18v3M5 5l2 2M17 17l2 2M3 12h3M18 12h3M5 19l2-2M17 7l2-2" /></svg>
          </label>
          <Pressable onClick={() => updateField('color', '')} scale={0.88}>
            <div style={{
              height: 32, padding: '0 14px', borderRadius: 16, background: t.chip,
              display: 'inline-flex', alignItems: 'center', fontSize: 12, fontWeight: 600,
              color: t.textSec,
              border: !rental.color ? '1.5px dashed ' + t.text : '0'
            }}>Auto (Status)</div>
          </Pressable>
        </div>
      </div>

      {/* Gesamtbetrag */}
      <div style={{ padding: '20px 16px 0' }}>
        <div style={{ background: t.card, borderRadius: 16, overflow: 'hidden' }}>
          <div style={{ padding: '13px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
            <div>
              <div style={{ fontSize: 12, color: t.textSec, fontWeight: 500 }}>Gesamt ({days} Tag{days > 1 ? 'e' : ''}{qty > 1 ? ' · ' + qty + ' St.' : ''})</div>
              <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 2 }}>
                {hasOverride ? `manuell · automatisch wäre ${computedTotal} €` :
                discount > 0 ? `Zwischensumme ${subtotal} € · −${discount} € Rabatt` :
                deliveryFee > 0 ? `Equipment + ${deliveryFee.toFixed(2).replace('.', ',')} € Lieferung` : 'automatisch berechnet'}
              </div>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
              <input type="number" min="0" value={hasOverride ? rental.priceOverride : ''} placeholder={String(computedTotal)}
              onChange={(e) => onUpdate({ ...rental, priceOverride: e.target.value === '' ? null : e.target.value })}
              style={{ width: 92, padding: '7px 8px', borderRadius: 8, border: `0.5px solid ${t.inputBorder}`, background: hasOverride ? t.accentSoft : t.inputBg, fontSize: 16, color: hasOverride ? t.accent : t.text, fontFamily: 'inherit', fontWeight: 700, textAlign: 'right', fontVariantNumeric: 'tabular-nums', boxSizing: 'border-box' }} />
              <span style={{ fontSize: 14, color: t.textSec, fontWeight: 600 }}>€</span>
              {hasOverride &&
              <Pressable onClick={() => onUpdate({ ...rental, priceOverride: null })} scale={0.85}>
                  <div style={{ width: 24, height: 24, borderRadius: 12, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center', marginLeft: 4 }}>
                    <svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke={t.textSec} strokeWidth="2.2" strokeLinecap="round"><path d="M3 3l6 6M9 3l-6 6" /></svg>
                  </div>
                </Pressable>
              }
            </div>
          </div>
        </div>
      </div>

      {/* Dokumente — unified list with Schnelltext + Neu erstellen */}
      <div style={{ padding: '28px 16px 0' }}>
        <div style={{ padding: '0 4px 12px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
          <div style={{ fontSize: 13, fontWeight: 800, color: t.text, textTransform: 'uppercase', letterSpacing: 0.8 }}>Dokumente</div>
          <div style={{ display: 'flex', gap: 8 }}>
            <Pressable onClick={() => setQuickTextOpen(true)} scale={0.94}>
              <div style={{
                height: 34, padding: '0 12px', borderRadius: 17, background: t.chip,
                display: 'flex', alignItems: 'center', gap: 6, fontSize: 12.5, fontWeight: 600, color: t.text,
              }}>
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke={t.text} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M4 6h16v12H4z"/><path d="M4 6l8 7 8-7"/>
                </svg>
                Schnelltext
              </div>
            </Pressable>
            <Pressable onClick={() => setCreateOpen(true)} scale={0.94}>
              <div style={{
                height: 34, padding: '0 14px', borderRadius: 17, background: t.accent,
                display: 'flex', alignItems: 'center', gap: 4, fontSize: 13, fontWeight: 700, color: '#fff',
              }}>+ Neu erstellen</div>
            </Pressable>
          </div>
        </div>
        <div style={{ background: t.card, borderRadius: 16, overflow: 'hidden', border: `0.5px solid ${t.sep}` }}>
          {generatedDocs.length === 0 ?
            <div style={{ padding: '36px 20px', textAlign: 'center', color: t.textSec, fontSize: 13 }}>
              Noch keine Dokumente. Tippe oben auf <strong style={{ color: t.text }}>+ Neu erstellen</strong>.
            </div>
            :
            generatedDocs.map((d, i) => {
              const m = docMeta(d);
              return (
                <Pressable key={d.id} onClick={() => onPreview(d)} scale={0.99}>
                  <div style={{
                    padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 14,
                    borderTop: i > 0 ? `0.5px solid ${t.sep}` : 'none',
                  }}>
                    <div style={{
                      width: 52, height: 52, borderRadius: 12,
                      background: m.soft, position: 'relative',
                      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                    }}>
                      {m.badge === 'TXT' ?
                        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={m.color} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
                          <path d="M3 6h18v12H3z"/><path d="M3 6l9 7 9-7"/>
                        </svg>
                        :
                        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={m.color} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
                          <path d="M14 3H6a2 2 0 00-2 2v14a2 2 0 002 2h12a2 2 0 002-2V9z"/><path d="M14 3v6h6"/>
                        </svg>
                      }
                      <span style={{
                        position: 'absolute', bottom: 4, fontSize: 8, fontWeight: 800,
                        color: m.color, letterSpacing: 0.6,
                      }}>{m.badge}</span>
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 14.5, fontWeight: 700, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.title}</div>
                      <div style={{ fontSize: 12, color: t.textSec, marginTop: 2 }}>{m.typeLabel} · {d.date}</div>
                    </div>
                    <Pressable onClick={(e) => { if (e && e.stopPropagation) e.stopPropagation(); setConfirmDelDoc(d); }} scale={0.85}>
                      <div style={{
                        width: 30, height: 30, borderRadius: 10, background: t.redSoft,
                        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                      }}>
                        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke={t.red} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6" /></svg>
                      </div>
                    </Pressable>
                    <Icon d={icons.chev} color={t.textTer} size={14} sw={2} />
                  </div>
                </Pressable>);
            })
          }
        </div>
      </div>

      <Confirm open={!!confirmDelDoc} title="Dokument löschen?"
        message={confirmDelDoc ? `„${confirmDelDoc.title}“ wird unwiderruflich entfernt.` : ''}
        onCancel={() => setConfirmDelDoc(null)}
        onConfirm={() => { if (confirmDelDoc) { onDeleteDoc && onDeleteDoc(confirmDelDoc); toast && toast('Dokument gelöscht'); setConfirmDelDoc(null); } }} />

      {/* Neu erstellen — chooser between Rechnung and Protokoll */}
      <Sheet open={createOpen} onClose={() => setCreateOpen(false)}>
        <div style={{ padding: '4px 24px 24px' }}>
          <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.5 }}>Neues Dokument</div>
          <div style={{ fontSize: 13, color: t.textSec, marginTop: 4 }}>Wähle die Art des Dokuments für <strong style={{ color: t.text }}>{rental.tenantName}</strong>.</div>

          <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 8 }}>
            <Pressable onClick={() => { setCreateOpen(false); generateInvoice(); }} scale={0.97}>
              <div style={{ background: t.card, border: `0.5px solid ${t.sep}`, borderRadius: 14, padding: 14, display: 'flex', alignItems: 'center', gap: 12 }}>
                <div style={{
                  width: 48, height: 48, borderRadius: 12, background: t.green + '22',
                  display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', flexShrink: 0,
                }}>
                  <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={t.green} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M14 3H6a2 2 0 00-2 2v14a2 2 0 002 2h12a2 2 0 002-2V9z"/><path d="M14 3v6h6"/></svg>
                  <span style={{ position: 'absolute', bottom: 4, fontSize: 8, fontWeight: 800, color: t.green, letterSpacing: 0.6 }}>PDF</span>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 14.5, fontWeight: 700, color: t.text }}>Rechnung</div>
                  <div style={{ fontSize: 12, color: t.textSec, marginTop: 2 }}>Automatisch aus Mietdaten generieren</div>
                </div>
                <Icon d={icons.chev} color={t.textTer} size={14} sw={2} />
              </div>
            </Pressable>
            <Pressable onClick={() => { setCreateOpen(false); setProtOpen(true); }} scale={0.97}>
              <div style={{ background: t.card, border: `0.5px solid ${t.sep}`, borderRadius: 14, padding: 14, display: 'flex', alignItems: 'center', gap: 12 }}>
                <div style={{
                  width: 48, height: 48, borderRadius: 12, background: t.accent + '22',
                  display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', flexShrink: 0,
                }}>
                  <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={t.accent} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M14 3H6a2 2 0 00-2 2v14a2 2 0 002 2h12a2 2 0 002-2V9z"/><path d="M14 3v6h6"/></svg>
                  <span style={{ position: 'absolute', bottom: 4, fontSize: 8, fontWeight: 800, color: t.accent, letterSpacing: 0.6 }}>PDF</span>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 14.5, fontWeight: 700, color: t.text }}>Protokoll</div>
                  <div style={{ fontSize: 12, color: t.textSec, marginTop: 2 }}>Mietvertrag, Übergabe, Rückgabe … ({protocols.length} Vorlagen)</div>
                </div>
                <Icon d={icons.chev} color={t.textTer} size={14} sw={2} />
              </div>
            </Pressable>
          </div>
        </div>
      </Sheet>

      {/* Schnelltext — quick WhatsApp / E-Mail messages */}
      <Sheet open={quickTextOpen} onClose={() => setQuickTextOpen(false)}>
        <div style={{ padding: '4px 24px 24px' }}>
          <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.5 }}>Schnelltext</div>
          <div style={{ fontSize: 13, color: t.textSec, marginTop: 4 }}>Fertige Nachrichten — wird mit Daten von <strong style={{ color: t.text }}>{rental.tenantName}</strong> ausgefüllt.</div>

          <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 8 }}>
            {quickTexts.map((qt) =>
              <Pressable key={qt.id} onClick={() => generateQuickText(qt)} scale={0.97}>
                <div style={{ background: t.card, border: `0.5px solid ${t.sep}`, borderRadius: 14, padding: 14, display: 'flex', alignItems: 'center', gap: 12 }}>
                  <div style={{
                    width: 48, height: 48, borderRadius: 12, background: (t.purple || '#AF52DE') + '22',
                    display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', flexShrink: 0,
                  }}>
                    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={t.purple || '#AF52DE'} strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18v12H3z"/><path d="M3 6l9 7 9-7"/></svg>
                    <span style={{ position: 'absolute', bottom: 4, fontSize: 8, fontWeight: 800, color: t.purple || '#AF52DE', letterSpacing: 0.6 }}>TXT</span>
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14.5, fontWeight: 700, color: t.text }}>{qt.name}</div>
                    <div style={{ fontSize: 12, color: t.textSec, marginTop: 2 }}>{qt.desc}</div>
                  </div>
                  <Icon d={icons.chev} color={t.textTer} size={14} sw={2} />
                </div>
              </Pressable>
            )}
            {quickTexts.length === 0 &&
              <div style={{ textAlign: 'center', padding: '24px 16px', color: t.textSec, fontSize: 13 }}>
                Noch keine Schnelltexte angelegt. Erstelle Vorlagen unter <strong style={{ color: t.text }}>Akten → Schnelltexte</strong>.
              </div>
            }
          </div>
        </div>
      </Sheet>

      {/* Protokoll wählen — opened from "Neu erstellen → Protokoll" */}
      <Sheet open={protOpen} onClose={() => setProtOpen(false)}>
        <div style={{ padding: '4px 24px 24px' }}>
          <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.5 }}>Protokoll wählen</div>
          <div style={{ fontSize: 13, color: t.textSec, marginTop: 4 }}>Wird mit Daten von <strong style={{ color: t.text }}>{rental.tenantName}</strong> ausgefüllt.</div>

          <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 8 }}>
            {protocols.map((tpl) =>
            <Pressable key={tpl.id} onClick={() => generateProtocol(tpl)} scale={0.97}>
                <div style={{ background: t.card, border: '0.5px solid ' + t.sep, borderRadius: 14, padding: 14, display: 'flex', alignItems: 'center', gap: 12 }}>
                  <div style={{ width: 40, height: 40, borderRadius: 12, background: tpl.color + '22', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22 }}>{tpl.icon}</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 14, fontWeight: 600, color: t.text }}>{tpl.name}</div>
                    <div style={{ fontSize: 12, color: t.textSec, marginTop: 1 }}>{tpl.desc}</div>
                  </div>
                  <Icon d={icons.chev} color={t.textTer} size={14} sw={2} />
                </div>
              </Pressable>
            )}
          </div>
        </div>
      </Sheet>

      {/* Fullscreen photo viewer */}
      {photoViewer &&
      <div onClick={() => setPhotoViewer(null)} style={{
        position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.92)', zIndex: 50,
        display: 'flex', flexDirection: 'column'
      }}>
          <div style={{ padding: '12px 16px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }} onClick={(e) => e.stopPropagation()}>
            <Pressable onClick={() => setPhotoViewer(null)} scale={0.9}>
              <div style={{ width: 36, height: 36, borderRadius: 18, background: 'rgba(255,255,255,0.14)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg>
              </div>
            </Pressable>
            <div style={{ color: '#fff', fontSize: 13, fontWeight: 600 }}>{photoViewer.label}</div>
            <Pressable onClick={() => setPhotoConfirmDel(photoViewer)} scale={0.9}>
              <div style={{ width: 36, height: 36, borderRadius: 18, background: 'rgba(255,80,80,0.20)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ff6b6b" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6M10 11v6M14 11v6" /></svg>
              </div>
            </Pressable>
          </div>
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}>
            <img src={photoViewer.dataUrl} alt={photoViewer.label} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain', borderRadius: 6 }} />
          </div>
          <div style={{ padding: '0 20px 20px', color: 'rgba(255,255,255,0.55)', fontSize: 11, textAlign: 'center' }}>Hinzugefügt am {photoViewer.addedAt || '—'}</div>
        </div>
      }

      <Confirm open={!!photoConfirmDel} title="Foto löschen?"
        message={photoConfirmDel ? `„${photoConfirmDel.label}" wird entfernt.` : ''}
        onCancel={() => setPhotoConfirmDel(null)}
        onConfirm={() => photoConfirmDel && deletePhoto(photoConfirmDel)} />

      <Confirm open={confirmDel} title="Mieter löschen?"
      message={`„${rental.tenantName}" und alle zugehörigen Daten werden entfernt.`}
      onCancel={() => setConfirmDel(false)}
      onConfirm={() => {setConfirmDel(false);onDelete(rental);}} />

      <Confirm open={confirmDiscard} title="Änderungen verwerfen?"
      message="Du hast nicht gespeicherte Änderungen am Mietvertrag. Beim Zurückgehen gehen sie verloren."
      onCancel={() => setConfirmDiscard(false)}
      onConfirm={() => {setConfirmDiscard(false);setDraft(persistedRental);onBack();}} />

      {/* ── Sticky save bar — appears when there are unsaved changes ── */}
      {dirty &&
      <div style={{
        position: 'sticky', bottom: 0, left: 0, right: 0,
        marginTop: 24,
        padding: '12px 16px 16px',
        background: `linear-gradient(to top, ${t.appBg} 0%, ${t.appBg} 70%, ${t.appBg}00 100%)`,
        display: 'flex', gap: 10, alignItems: 'center', zIndex: 5
      }}>
          <Pressable onClick={() => setConfirmDiscard(true)} scale={0.96}>
            <div style={{
            padding: '12px 16px', borderRadius: 12,
            background: t.dark ? '#3A3A3C' : '#E5E5EA',
            fontSize: 13.5, fontWeight: 600, color: t.text
          }}>Verwerfen</div>
          </Pressable>
          <Pressable onClick={saveChanges} scale={0.98} style={{ flex: 1 }}>
            <div style={{
            padding: '12px 16px', borderRadius: 12,
            background: t.solidBg,
            color: t.solidFg, textAlign: 'center',
            fontSize: 13.5, fontWeight: 700,
            boxShadow: '0 6px 16px rgba(0,0,0,0.28)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 7
          }}>
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke={t.solidFg} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg>
              Änderungen speichern
            </div>
          </Pressable>
        </div>
      }
    </div>);

}

// ─── Protocols list (editable templates) ───────────────────
// ─── Rechnungen list ────────────────────────────────────
function InvoicesList({ genDocs, rentals, equipment, onSelect }) {
  const t = useTheme();
  const [query, setQuery] = useState('');
  const [paidFilter, setPaidFilter] = useState('alle'); // alle | offen | bezahlt

  // Flatten all invoices across all rentals
  const allInvoices = [];
  Object.entries(genDocs || {}).forEach(([rentalId, docs]) => {
    (docs || []).forEach((d) => {
      if (d.kind !== 'invoice') return;
      const r = rentals.find((x) => x.id === rentalId);
      allInvoices.push({ doc: d, rental: r, rentalId });
    });
  });

  // Sort newest first (by number; falls back to date)
  allInvoices.sort((a, b) => (b.doc.number || '').localeCompare(a.doc.number || ''));

  // Filter
  const q = query.trim().toLowerCase();
  const visible = allInvoices.filter(({ doc, rental }) => {
    if (paidFilter === 'offen' && doc.paid) return false;
    if (paidFilter === 'bezahlt' && !doc.paid) return false;
    if (!q) return true;
    const hay = [
    doc.number, doc.date, String(doc.total),
    rental ? rental.tenantName : '',
    rental ? rentalEquipmentLabel(rental) : ''].
    filter(Boolean).join(' · ').toLowerCase();
    return hay.includes(q);
  });

  const sumOpen = allInvoices.filter((x) => !x.doc.paid).reduce((s, x) => s + (x.doc.total || 0), 0);
  const sumPaid = allInvoices.filter((x) => x.doc.paid).reduce((s, x) => s + (x.doc.total || 0), 0);

  const inp = {
    width: '100%', padding: '11px 12px 11px 36px', borderRadius: 12,
    border: `0.5px solid ${t.inputBorder}`, background: t.inputBg,
    fontSize: 14, color: t.text, outline: 'none', fontFamily: 'inherit', boxSizing: 'border-box'
  };

  return (
    <div>
      {/* KPI strip */}
      <div style={{ padding: '0 16px 12px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
        <div style={{ background: t.card, borderRadius: 14, padding: 12, boxShadow: t.shadowCard }}>
          <div style={{ fontSize: 11, color: t.textSec, fontWeight: 500 }}>Offen</div>
          <div style={{ fontSize: 22, fontWeight: 700, color: t.orange, marginTop: 2, letterSpacing: -0.3 }}>{Math.round(sumOpen)} €</div>
          <div style={{ fontSize: 11, color: t.textSec, marginTop: 1 }}>{allInvoices.filter((x) => !x.doc.paid).length} Rechnung{allInvoices.filter((x) => !x.doc.paid).length === 1 ? '' : 'en'}</div>
        </div>
        <div style={{ background: t.card, borderRadius: 14, padding: 12, boxShadow: t.shadowCard }}>
          <div style={{ fontSize: 11, color: t.textSec, fontWeight: 500 }}>Bezahlt</div>
          <div style={{ fontSize: 22, fontWeight: 700, color: t.green, marginTop: 2, letterSpacing: -0.3 }}>{Math.round(sumPaid)} €</div>
          <div style={{ fontSize: 11, color: t.textSec, marginTop: 1 }}>{allInvoices.filter((x) => x.doc.paid).length} Rechnung{allInvoices.filter((x) => x.doc.paid).length === 1 ? '' : 'en'}</div>
        </div>
      </div>

      {/* Search */}
      <div style={{ padding: '0 16px 10px', position: 'relative' }}>
        <div style={{ position: 'relative' }}>
          <input value={query} onChange={(e) => setQuery(e.target.value)}
          placeholder="Suche · Nr., Mieter, Equipment, Betrag…" style={inp} />
          <div style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none' }}>
            <Icon d="M11 19a8 8 0 100-16 8 8 0 000 16zM21 21l-4.3-4.3" color={t.textSec} size={15} sw={2} />
          </div>
          {query &&
          <Pressable onClick={() => setQuery('')} scale={0.85}
          style={{ position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)' }}>
              <div style={{ width: 22, height: 22, borderRadius: 11, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke={t.textSec} strokeWidth="2.4" strokeLinecap="round"><path d="M3 3l6 6M9 3l-6 6" /></svg>
              </div>
            </Pressable>
          }
        </div>
      </div>

      {/* Status filter */}
      <div style={{ padding: '0 16px 12px', display: 'flex', gap: 6 }}>
        {[['alle', 'Alle'], ['offen', 'Offen'], ['bezahlt', 'Bezahlt']].map(([id, label]) =>
        <Pressable key={id} onClick={() => setPaidFilter(id)} scale={0.95}>
            <div style={{
            padding: '7px 13px', borderRadius: 100, fontSize: 12.5, fontWeight: 600,
            background: paidFilter === id ? t.solidBg : t.chip,
            color: paidFilter === id ? t.solidFg : t.text
          }}>{label}</div>
          </Pressable>
        )}
      </div>

      {/* List */}
      <div style={{ padding: '0 16px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {visible.length === 0 &&
        <div style={{ textAlign: 'center', padding: '40px 20px', color: t.textSec, fontSize: 13, background: t.card, borderRadius: 16, border: '1px dashed ' + t.sep }}>
            {allInvoices.length === 0 ?
          'Noch keine Rechnungen.\nErstelle eine bei einem Mieter.' :
          'Keine Treffer in diesem Filter.'}
          </div>
        }
        {visible.map(({ doc, rental }) =>
        <Pressable key={doc.id} onClick={() => onSelect(doc)} scale={0.98}>
            <div style={{ background: t.card, borderRadius: 16, padding: 12, display: 'flex', gap: 12, alignItems: 'center', boxShadow: t.shadowCard }}>
              <div style={{
              width: 42, height: 42, borderRadius: 10, background: doc.paid ? t.greenSoft : t.orange + '1e',
              display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0
            }}>
                <Icon d="M6 2h9l5 5v13a2 2 0 01-2 2H6a2 2 0 01-2-2V4a2 2 0 012-2zM14 2v6h6M9 13h6M9 17h6"
              color={doc.paid ? t.green : t.orange} size={18} sw={1.8} />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
                  <div style={{ fontSize: 14, fontWeight: 700, color: t.text, fontVariantNumeric: 'tabular-nums' }}>{doc.number || doc.title}</div>
                  {doc.paid &&
                <span style={{ fontSize: 9, fontWeight: 700, color: t.green, background: t.greenSoft, padding: '1px 6px', borderRadius: 100 }}>BEZAHLT</span>
                }
                </div>
                <div style={{ fontSize: 11.5, color: t.textSec, marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {rental ? rental.tenantName : '—'}{rental ? ' · ' + rentalEquipmentLabel(rental) : ''}
                </div>
                <div style={{ fontSize: 10.5, color: t.textTer, marginTop: 1 }}>{doc.date}</div>
              </div>
              <div style={{ textAlign: 'right' }}>
                <div style={{ fontSize: 15, fontWeight: 700, color: t.text, fontVariantNumeric: 'tabular-nums' }}>{Math.round(doc.total)} €</div>
                <Icon d={icons.chev} color={t.textTer} size={12} sw={2} />
              </div>
            </div>
          </Pressable>
        )}
      </div>
    </div>);

}

function ProtocolRow({ tpl, t, onEdit, onDelete }) {
  const startX = React.useRef(0);
  const startY = React.useRef(0);
  const moved = React.useRef(false);
  const longTimer = React.useRef(null);
  const longFired = React.useRef(false);
  const rowRef = React.useRef(null);
  const [menu, setMenu] = React.useState(null);

  const cancelLong = () => { if (longTimer.current) { clearTimeout(longTimer.current); longTimer.current = null; } };

  const onPointerDown = (ev) => {
    if (ev.pointerType === 'mouse' && ev.button !== 0) return;
    startX.current = ev.clientX; startY.current = ev.clientY;
    moved.current = false; longFired.current = false;
    cancelLong();
    longTimer.current = setTimeout(() => {
      longFired.current = true;
      const rect = rowRef.current && rowRef.current.getBoundingClientRect();
      if (rect) setMenu({ x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 });
    }, 480);
    try { ev.currentTarget.setPointerCapture(ev.pointerId); } catch {}
  };
  const onPointerMove = (ev) => {
    if (moved.current) return;
    if (Math.abs(ev.clientX - startX.current) > 5 || Math.abs(ev.clientY - startY.current) > 5) {
      moved.current = true; cancelLong();
    }
  };
  const settle = () => {
    cancelLong();
    if (longFired.current || moved.current) return;
    onEdit();
  };

  return (
    <div style={{ position: 'relative' }}>
      <div ref={rowRef}
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={settle}
        onPointerCancel={cancelLong}
        style={{
          background: t.card, borderRadius: 16, padding: '14px 16px',
          display: 'flex', alignItems: 'center', gap: 12,
          boxShadow: '0 1px 2px rgba(0,0,0,0.04)',
          touchAction: 'pan-y', cursor: 'pointer', userSelect: 'none',
        }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 15, fontWeight: 600, color: t.text, letterSpacing: -0.2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{tpl.name}</div>
          <div style={{ fontSize: 12, color: t.textSec, marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{tpl.desc}</div>
        </div>
        <Icon d="M9 18l6-6-6-6" color={t.textTer} size={14} sw={2.2}/>
      </div>
      {menu && <DokuContextMenu pos={menu} t={t}
        onClose={() => setMenu(null)}
        onEdit={() => { setMenu(null); onEdit(); }}
        onDelete={() => { setMenu(null); onDelete(); }}/>}
    </div>
  );
}

function DokuContextMenu({ pos, t, onClose, onEdit, onDelete }) {
  const W = 220, H = 110;
  const vw = typeof window !== 'undefined' ? window.innerWidth  : 360;
  const vh = typeof window !== 'undefined' ? window.innerHeight : 720;
  const left = Math.max(12, Math.min(vw - W - 12, pos.x - W / 2));
  const top  = Math.max(12, Math.min(vh - H - 12, pos.y - H / 2));
  return (
    <React.Fragment>
      <div onClick={onClose} onPointerDown={(e) => e.stopPropagation()}
        style={{ position: 'fixed', inset: 0, zIndex: 200, background: 'rgba(0,0,0,0.25)', backdropFilter: 'blur(2px)', WebkitBackdropFilter: 'blur(2px)' }}/>
      <div style={{
        position: 'fixed', left, top, width: W, zIndex: 201,
        background: t.card, borderRadius: 14,
        boxShadow: '0 16px 40px rgba(0,0,0,0.35)',
        overflow: 'hidden',
        animation: 'doku-pop 0.16s cubic-bezier(.2,.8,.2,1.05)',
      }}>
        <Pressable onClick={onEdit} scale={1}>
          <div style={{ padding: '14px 16px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', borderBottom: `0.5px solid ${t.sep}` }}>
            <span style={{ fontSize: 15, color: t.text, fontWeight: 500 }}>Bearbeiten</span>
            <Icon d={icons.edit} color={t.text} size={16} sw={1.8}/>
          </div>
        </Pressable>
        <Pressable onClick={onDelete} scale={1}>
          <div style={{ padding: '14px 16px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <span style={{ fontSize: 15, color: t.red, fontWeight: 500 }}>Löschen</span>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={t.red} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/></svg>
          </div>
        </Pressable>
      </div>
      <style>{`@keyframes doku-pop { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: scale(1); } }`}</style>
    </React.Fragment>
  );
}

function ProtocolsList({ protocols, onEdit, onNew, onDelete }) {
  const t = useTheme();
  return (
    <div>
      <div style={{ padding: '0 20px 12px', fontSize: 12, color: t.textSec, lineHeight: 1.5 }}>
        Tippe an, um zu bearbeiten. Lange drücken für Optionen.
      </div>
      <Pressable onClick={onNew} scale={0.98} style={{ margin: '0 16px 10px' }}>
        <div style={{
          background: t.solidBg, color: t.solidFg, borderRadius: 14, padding: '14px 16px',
          display: 'flex', alignItems: 'center', gap: 10, justifyContent: 'center',
          boxShadow: '0 6px 16px rgba(0,0,0,0.28)', fontSize: 14, fontWeight: 600
        }}>
          <Icon d={icons.plus} color={t.solidFg} size={16} sw={2.6} />
          Neue Vorlage
        </div>
      </Pressable>
      <div style={{ padding: '0 16px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {protocols.map((tpl) =>
          <ProtocolRow key={tpl.id} tpl={tpl} t={t}
            onEdit={() => onEdit(tpl)}
            onDelete={() => onDelete(tpl)}/>
        )}
      </div>
    </div>);

}

// ─── Protocol editor sheet ─────────────────────────────────
const EMOJI_OPTIONS = ['📋', '📦', '↩️', '📝', '✉️', '📅', '🧾', '🔔', '⚠️', '✅', '💼', '🔧'];

function ProtocolEditor({ open, onClose, initial, onSave }) {
  const t = useTheme();
  const isEdit = !!(initial && initial.id);
  const blank = { id: '', name: '', icon: '📋', color: PROTOCOL_COLORS[0], desc: '', text: '' };
  const [form, setForm] = useState(blank);

  useEffect(() => {if (open) setForm(initial ? { ...blank, ...initial } : blank);}, [open, initial]);

  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const valid = form.name.trim() && form.text.trim();

  const save = () => {
    if (!valid) return;
    const out = { ...form, id: form.id || 'p-' + Date.now() };
    onSave(out);
    onClose();
  };

  const fInp = {
    width: '100%', padding: '12px 14px', borderRadius: 12,
    border: `0.5px solid ${t.inputBorder}`, background: t.card,
    fontSize: 15, color: t.text, outline: 'none', fontFamily: 'inherit', boxSizing: 'border-box'
  };

  return (
    <Sheet open={open} onClose={onClose}>
      <div style={{ padding: '4px 24px 24px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div>
            <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.5 }}>{isEdit ? 'Vorlage bearbeiten' : 'Neue Vorlage'}</div>
            <div style={{ fontSize: 13, color: t.textSec, marginTop: 4 }}>Text + Platzhalter anpassen</div>
          </div>
          <Pressable onClick={onClose}><div style={{ fontSize: 14, color: t.textSec, fontWeight: 500 }}>Abbrechen</div></Pressable>
        </div>

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Name</div>
        <input value={form.name} onChange={(e) => set('name', e.target.value)} placeholder="z.B. Mahnung" style={fInp} />

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>Kurzbeschreibung</div>
        <input value={form.desc} onChange={(e) => set('desc', e.target.value)} placeholder="z.B. Erinnerung an offene Zahlung" style={fInp} />

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>Icon</div>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          {EMOJI_OPTIONS.map((emo) =>
          <Pressable key={emo} onClick={() => set('icon', emo)} scale={0.9}>
              <div style={{
              width: 38, height: 38, borderRadius: 10, fontSize: 22,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: form.icon === emo ? t.accentSoft : t.chip,
              border: form.icon === emo ? `1.5px solid ${t.accent}` : '1.5px solid transparent'
            }}>{emo}</div>
            </Pressable>
          )}
        </div>

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>Farbe</div>
        <div style={{ display: 'flex', gap: 8 }}>
          {PROTOCOL_COLORS.map((c) =>
          <Pressable key={c} onClick={() => set('color', c)} scale={0.9}>
              <div style={{
              width: 30, height: 30, borderRadius: 15, background: c,
              border: form.color === c ? '2.5px solid #fff' : '0',
              boxShadow: form.color === c ? `0 0 0 2px ${c}` : '0 1px 2px rgba(0,0,0,0.1)'
            }} />
            </Pressable>
          )}
        </div>

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>
          Text (Platzhalter werden ersetzt)
        </div>
        <div style={{ fontSize: 10, color: t.textSec, marginBottom: 6, lineHeight: 1.5 }}>
          Verfügbar: <code>{'{tenant} {equipment} {period} {start} {end} {total} {deposit} {days} {rate} {address} {today}'}</code>
        </div>
        <textarea value={form.text} onChange={(e) => set('text', e.target.value)} rows={10}
        placeholder={"Hallo {tenant},\n\n…"}
        style={{
          ...fInp, padding: '12px 14px', minHeight: 200,
          fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace',
          fontSize: 12, lineHeight: 1.55, resize: 'vertical'
        }} />

        <Pressable onClick={save} scale={0.97} disabled={!valid} style={{ marginTop: 18 }}>
          <div style={{
            padding: '15px 0', textAlign: 'center', borderRadius: 14,
            background: valid ? t.solidBg : t.chip,
            color: t.solidFg, fontSize: 16, fontWeight: 600
          }}>{isEdit ? 'Änderungen speichern' : 'Vorlage anlegen'}</div>
        </Pressable>
      </div>
    </Sheet>);

}

// ─── Schnelltexte (editable WhatsApp/E-Mail templates) ───────────────────
function QuickTextsList({ quickTexts, onEdit, onNew, onDelete }) {
  const t = useTheme();
  const purple = t.purple || '#AF52DE';
  return (
    <div>
      <div style={{ padding: '0 20px 12px', fontSize: 12, color: t.textSec, lineHeight: 1.5 }}>
        Fertige WhatsApp- & E-Mail-Texte. Platzhalter wie <code>{'{tenant}'}</code> werden mit Mieterdaten ausgefüllt.
      </div>
      <Pressable onClick={onNew} scale={0.98} style={{ margin: '0 16px 10px' }}>
        <div style={{
          background: t.solidBg, color: t.solidFg, borderRadius: 14, padding: '14px 16px',
          display: 'flex', alignItems: 'center', gap: 10, justifyContent: 'center',
          boxShadow: '0 6px 16px rgba(0,0,0,0.28)', fontSize: 14, fontWeight: 600
        }}>
          <Icon d={icons.plus} color={t.solidFg} size={16} sw={2.6} />
          Neuer Schnelltext
        </div>
      </Pressable>
      <div style={{ padding: '0 16px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {quickTexts.map((qt) =>
          <LongPressRow key={qt.id}
            onTap={() => onEdit(qt)}
            onEdit={() => onEdit(qt)}
            onDelete={() => onDelete(qt)}>
          <div style={{ background: t.card, borderRadius: 16, padding: 14, display: 'flex', alignItems: 'center', gap: 14 }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 15, fontWeight: 600, color: t.text, display: 'flex', alignItems: 'flex-start', gap: 6, lineHeight: 1.25 }}>
                  {qt.icon && <span style={{ fontSize: 16, flexShrink: 0, lineHeight: 1.25 }}>{qt.icon}</span>}
                  <span style={{ minWidth: 0, wordBreak: 'break-word' }}>{qt.name}</span>
                </div>
                <div style={{ fontSize: 12, color: t.textSec, marginTop: 2 }}>{qt.desc}</div>
                {qt.kind && (
                  <div style={{ marginTop: 5, display: 'inline-flex', alignItems: 'center', padding: '2px 7px', borderRadius: 100, fontSize: 10, fontWeight: 700, color: purple, background: purple + '18', letterSpacing: 0.3 }}>
                    {qt.kind === 'email' ? 'E-MAIL' : 'WHATSAPP'}
                  </div>
                )}
              </div>
            <Icon d="M9 18l6-6-6-6" color={t.textTer} size={14} sw={2.2}/>
          </div>
          </LongPressRow>
        )}
        {quickTexts.length === 0 &&
          <div style={{ textAlign: 'center', padding: '40px 20px', color: t.textSec, fontSize: 13 }}>
            Noch keine Schnelltexte. Tippe oben auf <strong style={{ color: t.text }}>Neuer Schnelltext</strong>.
          </div>
        }
      </div>
    </div>
  );
}

function QuickTextEditor({ open, onClose, initial, onSave }) {
  const t = useTheme();
  const purple = t.purple || '#AF52DE';
  const isEdit = !!(initial && initial.id);
  const blank = { id: '', name: '', desc: '', icon: '💬', kind: 'whatsapp', text: '' };
  const [form, setForm] = useState(blank);

  useEffect(() => { if (open) setForm(initial ? { ...blank, ...initial } : blank); }, [open, initial]);

  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const valid = form.name.trim() && form.text.trim();
  const save = () => {
    if (!valid) return;
    const id = form.id || 'qt-' + Date.now();
    onSave({ ...form, id, name: form.name.trim(), desc: form.desc.trim() });
    onClose();
  };

  const fInp = {
    width: '100%', padding: '12px 14px', borderRadius: 12,
    border: `0.5px solid ${t.inputBorder}`, background: t.card,
    fontSize: 15, color: t.text, outline: 'none', fontFamily: 'inherit', boxSizing: 'border-box'
  };

  const KIND_OPTIONS = [
    { id: 'whatsapp', label: 'WhatsApp', icon: '💬' },
    { id: 'email',    label: 'E-Mail',   icon: '✉️' },
  ];
  const QT_EMOJI = ['💬', '✉️', '⏰', '📨', '📲', '🔔', '✅', '📝', '🙌', '🎉'];

  return (
    <Sheet open={open} onClose={onClose}>
      <div style={{ padding: '4px 24px 24px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div>
            <div style={{ fontSize: 22, fontWeight: 700, color: t.text, letterSpacing: -0.5 }}>{isEdit ? 'Schnelltext bearbeiten' : 'Neuer Schnelltext'}</div>
            <div style={{ fontSize: 13, color: t.textSec, marginTop: 4 }}>Text + Platzhalter anpassen</div>
          </div>
          <Pressable onClick={onClose}><div style={{ fontSize: 14, color: t.textSec, fontWeight: 500 }}>Abbrechen</div></Pressable>
        </div>

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 18, marginBottom: 6 }}>Name</div>
        <input value={form.name} onChange={(e) => set('name', e.target.value)} placeholder="z.B. Reservierungsbestätigung" style={fInp} />

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>Kurzbeschreibung</div>
        <input value={form.desc} onChange={(e) => set('desc', e.target.value)} placeholder="z.B. Kurze Bestätigung per WhatsApp" style={fInp} />

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>Versandweg</div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6, padding: 3, borderRadius: 12, background: t.chipStrong }}>
          {KIND_OPTIONS.map((opt) => {
            const on = form.kind === opt.id;
            return (
              <Pressable key={opt.id} onClick={() => set('kind', opt.id)} scale={0.97}>
                <div style={{
                  height: 38, borderRadius: 9,
                  background: on ? (t.dark ? '#48484A' : '#fff') : 'transparent',
                  boxShadow: on ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
                  display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 7,
                  fontSize: 13.5, fontWeight: 600, color: on ? t.text : t.textSec,
                }}>
                  <span style={{ fontSize: 15 }}>{opt.icon}</span>
                  {opt.label}
                </div>
              </Pressable>
            );
          })}
        </div>

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>Icon</div>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          <Pressable onClick={() => set('icon', '')} scale={0.9}>
            <div style={{
              width: 38, height: 38, borderRadius: 10,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: !form.icon ? purple + '22' : t.chip,
              border: !form.icon ? `1.5px solid ${purple}` : '1.5px solid transparent',
              color: t.textSec,
            }}>
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke={!form.icon ? purple : t.textSec} strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="9"/><path d="M5.6 5.6l12.8 12.8"/></svg>
            </div>
          </Pressable>
          {QT_EMOJI.map((emo) =>
            <Pressable key={emo} onClick={() => set('icon', emo)} scale={0.9}>
              <div style={{
                width: 38, height: 38, borderRadius: 10, fontSize: 22,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                background: form.icon === emo ? purple + '22' : t.chip,
                border: form.icon === emo ? `1.5px solid ${purple}` : '1.5px solid transparent'
              }}>{emo}</div>
            </Pressable>
          )}
        </div>

        <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, marginTop: 14, marginBottom: 6 }}>
          Text (Platzhalter werden ersetzt)
        </div>
        <div style={{ fontSize: 10, color: t.textSec, marginBottom: 6, lineHeight: 1.5 }}>
          Verfügbar: <code>{'{tenant} {equipment} {period} {start} {end} {total} {deposit} {days} {rate} {address} {today}'}</code>
        </div>
        <textarea value={form.text} onChange={(e) => set('text', e.target.value)} rows={9}
          placeholder={"Hallo {tenant},\n\n…"}
          style={{
            ...fInp, padding: '12px 14px', minHeight: 180,
            fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace',
            fontSize: 12, lineHeight: 1.55, resize: 'vertical'
          }} />

        <Pressable onClick={save} scale={0.97} disabled={!valid} style={{ marginTop: 18 }}>
          <div style={{
            padding: '15px 0', textAlign: 'center', borderRadius: 14,
            background: valid ? t.solidBg : t.chip,
            color: t.solidFg, fontSize: 16, fontWeight: 600
          }}>{isEdit ? 'Änderungen speichern' : 'Schnelltext anlegen'}</div>
        </Pressable>
      </div>
    </Sheet>
  );
}

// ─── Doc preview — editable, copy, share ────────────────────
function DocPreview({ doc, onBack, onUpdate, company, toast }) {
  const t = useTheme();
  const isInvoice = doc.kind === 'invoice';
  const [editing, setEditing] = useState(false);
  const [tmp, setTmp] = useState(doc.text);
  useEffect(() => {setTmp(doc.text);setEditing(false);}, [doc.id]);

  const save = () => {onUpdate({ ...doc, text: tmp });setEditing(false);toast('Gespeichert');};

  // Clean PDF render: invoices use structured data; protocols render their (edited) text as body.
  const isProtocol = !isInvoice;
  const wantsSign = isProtocol && /unterschrift|übergabe|protokoll|übernahme/i.test((doc.title || '') + ' ' + (tmp || ''));
  const renderDoc = isInvoice ?
  doc :
  { ...doc, bodyText: tmp, signature: wantsSign };
  const cleanHTML = buildDocHTML(company, renderDoc);
  const savePDF = () => {printDocHTML(buildDocHTML(company, renderDoc));toast('Drucken-Dialog → „Als PDF sichern“');};

  const copy = async () => {
    try {
      await navigator.clipboard.writeText(tmp);
      toast('In Zwischenablage kopiert');
    } catch {
      const ta = document.createElement('textarea');
      ta.value = tmp;document.body.appendChild(ta);ta.select();
      try {document.execCommand('copy');toast('Kopiert!');} catch {toast('Kopieren nicht möglich');} finally
      {document.body.removeChild(ta);}
    }
  };

  return (
    <div style={{ minHeight: '100dvh', display: 'flex', flexDirection: 'column' }}>
      <div style={{ padding: '8px 16px 12px', display: 'flex', alignItems: 'center', gap: 8, position: 'sticky', top: 0, zIndex: 20, background: t.bg }}>
        <Pressable onClick={onBack} scale={0.88}>
          <div style={{ width: 36, height: 36, borderRadius: 18, background: t.chip, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Icon d={icons.back} color={t.text} size={20} sw={2.2} />
          </div>
        </Pressable>
        <div style={{ flex: 1, fontSize: 15, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{doc.title}</div>
        <Pressable onClick={() => editing ? save() : setEditing(true)} scale={0.88}>
          <div style={{ padding: '8px 12px', borderRadius: 18, background: editing ? t.accent : t.chip, display: 'flex', alignItems: 'center', gap: 4 }}>
            {editing ?
            <span style={{ fontSize: 13, fontWeight: 600, color: t.onAccent }}>Fertig</span> :
            <Icon d={icons.edit} color={t.text} size={15} sw={1.8} />}
          </div>
        </Pressable>
      </div>

      <div style={{ flex: 1, padding: '4px 16px 110px' }}>
        {editing ?
        <div style={{
          background: t.card, borderRadius: 10, padding: '18px 16px',
          boxShadow: '0 1px 3px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.06)', minHeight: 200
        }}>
            <textarea autoFocus value={tmp} onChange={(e) => setTmp(e.target.value)}
          style={{
            width: '100%', minHeight: 380, padding: 0, border: 'none', outline: 'none',
            fontSize: 13.5, color: t.text, lineHeight: 1.6, resize: 'vertical',
            background: 'transparent', fontFamily: 'inherit'
          }} />
          </div> :

        <div style={{ background: '#e9e7e2', borderRadius: 10, padding: 14 }}>
            <div style={{
            background: '#fff', borderRadius: 4, padding: '26px 24px',
            boxShadow: '0 1px 3px rgba(0,0,0,0.12), 0 10px 30px rgba(0,0,0,0.12)',
            fontSize: 13, color: '#1a1a1a'
          }} dangerouslySetInnerHTML={{ __html: cleanHTML }} />
          </div>
        }

        <div style={{ marginTop: 12, padding: '12px 16px', background: t.cardAlt, borderRadius: 12, fontSize: 11, color: t.textSec, lineHeight: 1.45 }}>
          {editing ? '✎ Text wird gespeichert, sobald du „Fertig“ tippst.' :
          isInvoice ? '💡 Logo, Firmendaten & Vorlage kommen aus dem Firmenprofil (⚙️). „Als PDF“ → Drucken-Dialog → „Als PDF sichern“.' :
          '💡 Tippe ✎ zum Anpassen. „Als PDF“ erzeugt das saubere Dokument mit deinem Logo.'}
        </div>
      </div>

      <div style={{ position: 'absolute', bottom: 90, left: 16, right: 16, display: 'flex', gap: 8, zIndex: 25 }}>
        <Pressable onClick={savePDF} scale={0.97} style={{ flex: 1 }}>
          <div style={{
            background: t.accent, color: '#fff', borderRadius: 14, padding: '14px 0', textAlign: 'center',
            fontSize: 14, fontWeight: 600, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
            boxShadow: '0 6px 18px rgba(0,122,255,0.32)'
          }}>
            <Icon d="M6 9V2h12v7M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2M6 14h12v8H6z" color="#fff" size={15} sw={2} />
            Als PDF
          </div>
        </Pressable>
        <Pressable onClick={copy} scale={0.95}>
          <div style={{
            background: t.card, color: t.text, borderRadius: 14, padding: '14px 18px', textAlign: 'center',
            fontSize: 14, fontWeight: 600, border: '0.5px solid ' + t.sep, display: 'flex', alignItems: 'center', gap: 6
          }}>
            <Icon d="M8 4h9a2 2 0 012 2v12M4 8h9a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V10a2 2 0 012-2z" color={t.text} size={14} sw={2} />
            Text
          </div>
        </Pressable>
      </div>
    </div>);

}

// ─── Main Dokumente screen ─────────────────────────────────
function ScreenDokumente({ equipment, setEquipment, rentals, setRentals, protocols, setProtocols, quickTexts = [], setQuickTexts, genDocs, setGenDocs, emails, setEmails, company, setCompany, blockedCustomers = [], setBlockedCustomers, logistik, setLogistik, dark, toggleDark, events = [], focusRentalId, initialTab, openNewRental, origin, go, toast }) {
  const t = useTheme();
  const [tab, setTab] = useState(initialTab || 'index');
  const [search, setSearch] = useState('');
  const [selectedRental, setSelectedRental] = useState(null);
  const [previewDoc, setPreviewDoc] = useState(null);
  const [newRentalOpen, setNewRentalOpen] = useState(false);
  const [newRentalPrefill, setNewRentalPrefill] = useState(null);
  const [pendingEmailId, setPendingEmailId] = useState(null);
  const [protEdit, setProtEdit] = useState({ open: false, initial: null });
  const [confirmProt, setConfirmProt] = useState(null);
  const [qtEdit, setQtEdit] = useState({ open: false, initial: null });
  const [confirmQt, setConfirmQt] = useState(null);
  const [profileOpen, setProfileOpen] = useState(false);

  // Jump straight to a rental when navigated here from search / home / reminders
  useEffect(() => {
    if (focusRentalId) {
      const r = rentals.find((x) => x.id === focusRentalId);
      if (r) setSelectedRental(r);
    }
  }, [focusRentalId]);

  // Auto-open the new-rental sheet when navigated here with newRental=true
  useEffect(() => {
    if (openNewRental) {
      setNewRentalPrefill(null);
      setPendingEmailId(null);
      setNewRentalOpen(true);
      setTab('rentals');
    }
  }, [openNewRental]);

  const onGenerated = (doc) => {
    const rid = doc.rentalId;
    if (!rid) return;
    setGenDocs((prev) => ({ ...prev, [rid]: [doc, ...(prev[rid] || [])] }));
  };

  const updateRental = (r) => {
    setRentals((prev) => prev.map((p) => p.id === r.id ? r : p));
    setSelectedRental(r);
  };
  const addRental = (r) => {
    setRentals((prev) => [r, ...prev]);
    // Auto-increment uses on each equipment item attached to this rental
    if (setEquipment) {
      const its = r.items && r.items.length ? r.items : r.equipmentId ? [{ equipmentId: r.equipmentId }] : [];
      if (its.length) {
        const ids = new Set(its.map((it) => it.equipmentId));
        setEquipment((prev) => prev.map((e) => ids.has(e.id) ? { ...e, uses: (Number(e.uses) || 0) + 1 } : e));
      }
    }
    // link the originating email, if this rental came from a Posteingang request
    if (pendingEmailId && setEmails) {
      setEmails((prev) => prev.map((m) => m.id === pendingEmailId ? { ...m, linkedRentalId: r.id, unread: false } : m));
      setPendingEmailId(null);
    }
    setNewRentalPrefill(null);
    toast(`„${r.tenantName}“ angelegt`);
    setSelectedRental(r);
  };

  // Convert a Posteingang request email into a prefilled new-rental sheet
  const convertEmailToRental = (m) => {
    const p = m.parsed || {};
    const prefill = {
      tenantName: m.from,
      email: m.fromEmail,
      phone: p.phone || '',
      address: p.deliveryAddress || '',
      equipmentId: matchEquipmentId(p.equipmentHint, equipment),
      purpose: p.purpose || '',
      start: p.startISO || todayISO(),
      end: p.endISO || p.startISO || todayISO(),
      status: 'reserviert'
    };
    setNewRentalPrefill(prefill);
    setPendingEmailId(m.id);
    setNewRentalOpen(true);
  };
  const deleteRental = (r) => {
    setRentals((prev) => prev.filter((p) => p.id !== r.id));
    setGenDocs((prev) => {const c = { ...prev };delete c[r.id];return c;});
    setSelectedRental(null);
    toast(`„${r.tenantName}“ gelöscht`);
  };

  const updateDoc = (d) => {
    setGenDocs((prev) => {
      const list = prev[d.rentalId] || [];
      return { ...prev, [d.rentalId]: list.map((x) => x.id === d.id ? d : x) };
    });
    setPreviewDoc(d);
  };

  // Protocols
  const saveProtocol = (p) => {
    setProtocols((prev) => {
      const exists = prev.find((x) => x.id === p.id);
      if (exists) return prev.map((x) => x.id === p.id ? p : x);
      return [...prev, p];
    });
    toast(protEdit.initial ? 'Vorlage gespeichert' : `„${p.name}“ angelegt`);
  };
  const doDeleteProt = () => {
    setProtocols((prev) => prev.filter((p) => p.id !== confirmProt.id));
    toast(`„${confirmProt.name}“ gelöscht`);
    setConfirmProt(null);
  };

  // Quick texts (Schnelltexte)
  const saveQuickText = (q) => {
    setQuickTexts && setQuickTexts((prev) => {
      const exists = prev.find((x) => x.id === q.id);
      if (exists) return prev.map((x) => x.id === q.id ? q : x);
      return [...prev, q];
    });
    toast(qtEdit.initial ? 'Schnelltext gespeichert' : `„${q.name}“ angelegt`);
  };
  const doDeleteQt = () => {
    setQuickTexts && setQuickTexts((prev) => prev.filter((p) => p.id !== confirmQt.id));
    toast(`„${confirmQt.name}“ gelöscht`);
    setConfirmQt(null);
  };

  // Delete generated doc (Rechnung / Protokoll / Schnelltext) from a rental
  const deleteDoc = (d) => {
    setGenDocs((prev) => {
      const list = prev[d.rentalId] || [];
      return { ...prev, [d.rentalId]: list.filter((x) => x.id !== d.id) };
    });
  };

  // Layered routing
  if (previewDoc) return <DocPreview doc={previewDoc} onBack={() => setPreviewDoc(null)} onUpdate={updateDoc} company={company} toast={toast} />;
  if (selectedRental) {
    const live = rentals.find((r) => r.id === selectedRental.id) || selectedRental;
    return (
      <RentalDetail rental={live}
      onUpdate={updateRental} onDelete={deleteRental}
      onBack={() => {if (origin === 'cal' && go) {go('cal');} else {setSelectedRental(null);}}}
      equipment={equipment} protocols={protocols} quickTexts={quickTexts}
      allRentals={rentals} onSelectRental={(r) => setSelectedRental(r)}
      blockedCustomers={blockedCustomers} setBlockedCustomers={setBlockedCustomers}
      onPreview={setPreviewDoc} onGenerated={onGenerated} onDeleteDoc={deleteDoc}
      generatedDocs={genDocs[live.id] || []} toast={toast} />);

  }

  // ─── Grid landing ───
  const invoiceCount = Object.values(genDocs || {}).flat().filter((d) => d.kind === 'invoice').length;
  const unreadMail = (emails || []).filter((m) => !m.archived && m.unread).length;
  const openRentals = rentals.filter((r) => r.status !== 'abgeschlossen').length;
  const totalDocs = rentals.length + invoiceCount + protocols.length + (emails || []).filter((m) => !m.archived).length;

  const CATEGORIES = [
  { id: 'rentals', label: 'Mietaufträge', count: rentals.length,
    icon: 'M6 2h8l6 6v12a2 2 0 01-2 2H6a2 2 0 01-2-2V4a2 2 0 012-2zM14 2v6h6M9 14h6M9 18h4',
    hue: t.accent, tint: t.accentSoft },
  { id: 'protocols', label: 'Übergabe-Protokolle', count: protocols.length,
    icon: 'M6 2h8l6 6v12a2 2 0 01-2 2H6a2 2 0 01-2-2V4a2 2 0 012-2zM14 2v6h6M9 13l1.8 1.8L14 11M9 18h4',
    hue: t.green, tint: t.greenSoft },
  { id: 'quicktexts', label: 'Schnelltexte', count: quickTexts.length,
    icon: 'M3 7l9 6 9-6M3 7a2 2 0 012-2h14a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V7z',
    hue: t.purple || '#AF52DE', tint: t.dark ? 'rgba(175,82,222,0.18)' : 'rgba(175,82,222,0.12)' },
  { id: 'invoices', label: 'Rechnungen', count: invoiceCount,
    icon: 'M6 2h8l6 6v12a2 2 0 01-2 2H6a2 2 0 01-2-2V4a2 2 0 012-2zM14 2v6h6M12 11v7M9 14h6',
    hue: t.orange, tint: t.orangeSoft },
  { id: 'mail', label: 'Posteingang', count: (emails || []).filter((m) => !m.archived).length, badge: unreadMail,
    icon: 'M3 7l9 6 9-6M3 7a2 2 0 012-2h14a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V7z',
    hue: t.purple || '#AF52DE', tint: t.dark ? 'rgba(175,82,222,0.18)' : 'rgba(175,82,222,0.12)' }];


  const filteredCats = search.trim() ?
  CATEGORIES.filter((c) => c.label.toLowerCase().includes(search.trim().toLowerCase())) :
  CATEGORIES;

  // Full-text search across rentals, invoices, protocols, emails
  const searchResults = (() => {
    const q = search.trim().toLowerCase();
    if (!q) return [];
    const r = [];
    rentals.forEach((rt) => {
      const txt = [rt.tenantName, rt.email, rt.phone, rt.equipmentName, rt.purpose, rentalEquipmentLabel(rt)].filter(Boolean).join(' ').toLowerCase();
      if (txt.includes(q)) r.push({ kind: 'rental', id: rt.id, title: rt.tenantName, sub: (rentalEquipmentLabel(rt) || rt.equipmentName) + ' · ' + fmtRange(rt.start, rt.end), data: rt });
    });
    Object.values(genDocs || {}).flat().forEach((d) => {
      const txt = [d.title, d.tenantName, d.number, d.text].filter(Boolean).join(' ').toLowerCase();
      if (txt.includes(q)) r.push({ kind: 'doc', id: d.id, title: d.title, sub: (d.kind === 'invoice' ? 'Rechnung' : 'Protokoll') + ' · ' + (d.date || ''), data: d });
    });
    protocols.forEach((pr) => {
      const txt = [pr.name, pr.text].filter(Boolean).join(' ').toLowerCase();
      if (txt.includes(q)) r.push({ kind: 'protocol', id: pr.id, title: pr.name, sub: 'Vorlage', data: pr });
    });
    (emails || []).forEach((em) => {
      const txt = [em.from, em.subject, em.body, em.fromEmail].filter(Boolean).join(' ').toLowerCase();
      if (txt.includes(q)) r.push({ kind: 'email', id: em.id, title: em.subject || em.from, sub: 'E-Mail · ' + em.from, data: em });
    });
    return r.slice(0, 30);
  })();

  // ─── Landing (grid) view ───
  if (tab === 'index') {
    return (
      <div style={{ paddingBottom: 100 }}>
        <div style={{ padding: '8px 20px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div>
            <div style={{ fontSize: 13, color: t.textSec, fontWeight: 500 }}>
              {totalDocs} Dateien · {openRentals} Verträge offen
            </div>
            <div style={{ fontSize: 36, fontWeight: 700, color: t.text, letterSpacing: -0.9, marginTop: 2 }}>Dokumente
</div>
          </div>
          <CompanyGear size={38} />
        </div>

        {/* Search */}
        <div style={{ padding: '16px 16px 0' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '11px 14px', borderRadius: 12, background: t.chipStrong }}>
            <Icon d={icons.search} color={t.textSec} size={15} sw={2} />
            <input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Suchen" style={{ flex: 1, border: 'none', background: 'transparent', outline: 'none', color: t.text, fontFamily: 'inherit', fontSize: 15 }} />
          </div>
        </div>

        {/* Category grid 2×2 */}
        <div style={{ padding: '18px 16px 0', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          {filteredCats.map((cat) =>
          <Pressable key={cat.id} onClick={() => setTab(cat.id)} scale={0.97}>
              <div style={{
              background: t.card, borderRadius: 18, padding: '16px 16px 18px',
              minHeight: 144, display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
              boxShadow: t.shadowCard, position: 'relative', overflow: 'hidden'
            }}>
                {cat.badge > 0 &&
              <div style={{
                position: 'absolute', top: 12, right: 12,
                background: t.accent, color: '#fff', fontSize: 10, fontWeight: 700,
                minWidth: 18, height: 18, borderRadius: 10, padding: '0 6px',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center'
              }}>{cat.badge}</div>
              }
                <div style={{
                width: 44, height: 44, borderRadius: 12,
                background: cat.tint, display: 'flex', alignItems: 'center', justifyContent: 'center'
              }}>
                  <Icon d={cat.icon} color={cat.hue} size={22} sw={1.7} />
                </div>
                <div>
                  <div style={{ fontSize: 16, fontWeight: 700, color: t.text, letterSpacing: -0.3, lineHeight: 1.15 }}>{cat.label}</div>
                  <div style={{ fontSize: 12, color: t.textSec, marginTop: 4, fontWeight: 500 }}>{cat.count} {cat.count === 1 ? 'Datei' : 'Dateien'}</div>
                </div>
              </div>
            </Pressable>
          )}
        </div>

        {filteredCats.length === 0 &&
        <div style={{ padding: '40px 24px', textAlign: 'center', color: t.textSec, fontSize: 13 }}>
            Keine Treffer für „{search}".
          </div>
        }

        {/* Full-text search results */}
        {search.trim() && searchResults.length > 0 &&
        <>
            <div style={{ padding: '24px 20px 8px', fontSize: 11, color: t.textSec, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.6 }}>
              {searchResults.length} {searchResults.length === 1 ? 'Treffer' : 'Treffer'}
            </div>
            <div style={{ padding: '0 16px', display: 'flex', flexDirection: 'column', gap: 1 }}>
              {searchResults.map((r, i) => {
              const onTap = () => {
                if (r.kind === 'rental') {setSelectedRental(r.data);} else
                if (r.kind === 'doc') {setPreviewDoc(r.data);} else
                if (r.kind === 'protocol') {setTab('protocols');} else
                if (r.kind === 'email') {setTab('mail');}
              };
              const cat = CATEGORIES.find((c) =>
              c.id === 'rentals' && r.kind === 'rental' ||
              c.id === 'invoices' && r.kind === 'doc' && r.data.kind === 'invoice' ||
              c.id === 'protocols' && (r.kind === 'protocol' || r.kind === 'doc' && r.data.kind !== 'invoice') ||
              c.id === 'mail' && r.kind === 'email'
              ) || CATEGORIES[0];
              return (
                <Pressable key={r.kind + '-' + r.id} onClick={onTap} scale={0.99}>
                    <div style={{
                    background: t.card, padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 10,
                    borderTopLeftRadius: i === 0 ? 14 : 0, borderTopRightRadius: i === 0 ? 14 : 0,
                    borderBottomLeftRadius: i === searchResults.length - 1 ? 14 : 0, borderBottomRightRadius: i === searchResults.length - 1 ? 14 : 0,
                    borderBottom: i < searchResults.length - 1 ? `0.5px solid ${t.sep}` : 'none'
                  }}>
                      <div style={{ width: 32, height: 32, borderRadius: 9, background: cat.tint, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                        <Icon d={cat.icon} color={cat.hue} size={16} sw={1.7} />
                      </div>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 13, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.title}</div>
                        <div style={{ fontSize: 11, color: t.textSec, marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.sub}</div>
                      </div>
                      <Icon d={icons.chev} color={t.textTer} size={14} sw={2} />
                    </div>
                  </Pressable>);

            })}
            </div>
          </>
        }

        {search.trim() && searchResults.length === 0 && filteredCats.length === 0 &&
        <div style={{ padding: '12px 24px 0', textAlign: 'center', color: t.textTer, fontSize: 12 }}>
            Keine Dokumente gefunden.
          </div>
        }

        <FirmenprofilSheet open={profileOpen} onClose={() => setProfileOpen(false)}
        company={company} setCompany={setCompany} toast={toast}
        logistik={logistik} setLogistik={setLogistik}
        dark={dark} toggleDark={toggleDark} />
      </div>);

  }

  const currentCat = CATEGORIES.find((c) => c.id === tab);

  return (
    <div style={{ paddingBottom: 100 }}>
      <div style={{ padding: '8px 16px 0', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <Pressable onClick={() => setTab('index')} scale={0.88}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 4, padding: '8px 12px 8px 8px', borderRadius: 100, background: t.chip }}>
            <Icon d={icons.back} color={t.text} size={15} sw={2.2} />
            <span style={{ fontSize: 13, fontWeight: 600, color: t.text }}>Dokumente
</span>
          </div>
        </Pressable>
        <CompanyGear size={38} />
      </div>

      {/* Section header — title only (no tabs) */}
      <div style={{ padding: '14px 20px 4px', display: 'flex', alignItems: 'center', gap: 12 }}>
        {currentCat &&
        <div style={{
          width: 38, height: 38, borderRadius: 11,
          background: currentCat.tint, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0
        }}>
            <Icon d={currentCat.icon} color={currentCat.hue} size={20} sw={1.7} />
          </div>
        }
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 11, color: t.textSec, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.6 }}>{currentCat ? currentCat.count + ' Dateien' : ''}</div>
          <div style={{ fontSize: 28, fontWeight: 700, color: t.text, letterSpacing: -0.7, lineHeight: 1.1 }}>{currentCat ? currentCat.label : 'Akten'}</div>
        </div>
      </div>

      <div style={{ paddingTop: 14 }} />

      {tab === 'rentals' && <RentalsList rentals={rentals} equipment={equipment} blockedCustomers={blockedCustomers} onSelect={setSelectedRental} onNew={() => {setNewRentalPrefill(null);setPendingEmailId(null);setNewRentalOpen(true);}} />}
      {tab === 'invoices' &&
      <InvoicesList genDocs={genDocs} rentals={rentals} equipment={equipment} onSelect={setPreviewDoc} />
      }
      {tab === 'protocols' &&
      <ProtocolsList protocols={protocols}
      onNew={() => setProtEdit({ open: true, initial: null })}
      onEdit={(p) => setProtEdit({ open: true, initial: p })}
      onDelete={(p) => setConfirmProt(p)} />
      }
      {tab === 'quicktexts' &&
      <QuickTextsList quickTexts={quickTexts}
      onNew={() => setQtEdit({ open: true, initial: null })}
      onEdit={(q) => setQtEdit({ open: true, initial: q })}
      onDelete={(q) => setConfirmQt(q)} />
      }
      {tab === 'mail' &&
      <Posteingang emails={emails} setEmails={setEmails} equipment={equipment} rentals={rentals}
      onConvert={convertEmailToRental} toast={toast} />
      }

      <NewRentalSheet open={newRentalOpen} onClose={() => setNewRentalOpen(false)}
      onSave={addRental} equipment={equipment} rentals={rentals} events={events} prefill={newRentalPrefill}
      logistik={logistik} company={company} blockedCustomers={blockedCustomers} toast={toast} />
      <ProtocolEditor open={protEdit.open}
      onClose={() => setProtEdit({ open: false, initial: null })}
      initial={protEdit.initial} onSave={saveProtocol} />
      <QuickTextEditor open={qtEdit.open}
      onClose={() => setQtEdit({ open: false, initial: null })}
      initial={qtEdit.initial} onSave={saveQuickText} />
      <Confirm open={!!confirmProt} title="Vorlage löschen?"
      message={confirmProt ? `„${confirmProt.name}" wird entfernt.` : ''}
      onCancel={() => setConfirmProt(null)} onConfirm={doDeleteProt} />
      <Confirm open={!!confirmQt} title="Schnelltext löschen?"
      message={confirmQt ? `„${confirmQt.name}" wird entfernt.` : ''}
      onCancel={() => setConfirmQt(null)} onConfirm={doDeleteQt} />

      <FirmenprofilSheet open={profileOpen} onClose={() => setProfileOpen(false)}
      company={company} setCompany={setCompany} toast={toast}
      logistik={logistik} setLogistik={setLogistik}
      dark={dark} toggleDark={toggleDark} />
    </div>);

}

Object.assign(window, { ScreenDokumente });