/* global React, I */
const { useState, useMemo, useEffect, useRef } = React;

// ────────────────────────────────────────────────────────────────────
// Seiten-Switcher (oben rechts, auf allen Unterseiten gleich)
// ────────────────────────────────────────────────────────────────────
const NAV_ICONS = {
  esel: <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M9 18h6"/><path d="M10 21h4"/><path d="M12 3a6 6 0 0 0-4 10.5c.7.7 1.2 1.6 1.4 2.5h5.2c.2-.9.7-1.8 1.4-2.5A6 6 0 0 0 12 3Z"/></svg>,
  chem: <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M9 3h6"/><path d="M10 3v6l-5 8a2 2 0 0 0 1.7 3h10.6a2 2 0 0 0 1.7-3l-5-8V3"/><path d="M7.5 14h9"/></svg>,
  neuro: <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M9 4a2.5 2.5 0 0 0-2.5 2.5c-1.2.2-2 1.2-2 2.4 0 .6.2 1.1.6 1.5-.5.5-.8 1.1-.8 1.9 0 1 .6 1.9 1.5 2.3A2.5 2.5 0 0 0 9 20Z"/><path d="M15 4a2.5 2.5 0 0 1 2.5 2.5c1.2.2 2 1.2 2 2.4 0 .6-.2 1.1-.6 1.5.5.5.8 1.1.8 1.9 0 1-.6 1.9-1.5 2.3A2.5 2.5 0 0 1 15 20Z"/></svg>,
};
const SiteNav = ({ current }) => {
  const items = [
    { key: "esel", href: "/eselsbruecken", label: "Eselsbrücken" },
    { key: "chem", href: "/chemie-trainer", label: "Chemie-Trainer" },
    { key: "neuro", href: "/neurodriller", label: "Neurodriller" },
  ];
  const base = { display:"inline-flex", alignItems:"center", gap:7, padding:"8px 12px", borderRadius:999, fontSize:12.5, fontWeight:600, border:"1px solid var(--line)", background:"#fff", color:"var(--ink-2)", whiteSpace:"nowrap" };
  const active = { ...base, background:"var(--gradient)", color:"#fff", border:"1px solid transparent", boxShadow:"var(--shadow-glow)" };
  return (
    <nav style={{display:"flex", gap:6, alignItems:"center", flexWrap:"wrap", justifyContent:"flex-end"}}>
      {items.map(it => it.key === current
        ? <span key={it.key} aria-current="page" style={active}>{NAV_ICONS[it.key]}<span className="site-nav-label">{it.label}</span></span>
        : <a key={it.key} href={it.href} className="site-nav-pill" style={base}>{NAV_ICONS[it.key]}<span className="site-nav-label">{it.label}</span></a>)}
    </nav>
  );
};

// ────────────────────────────────────────────────────────────────────
// Topbar
// ────────────────────────────────────────────────────────────────────
const Topbar = ({ query, setQuery, unlocked, onLockClick, onLogout, onMenuToggle, mobileNavOpen }) => (
  <header className="topbar-bar" style={topbarStyles.bar}>
    <div className="topbar-brand-wrap" style={topbarStyles.brandWrap}>
      <button
        className="topbar-menu-btn"
        onClick={onMenuToggle}
        aria-label={mobileNavOpen ? "Menü schließen" : "Menü öffnen"}
        aria-expanded={mobileNavOpen}
        data-open={mobileNavOpen ? "true" : "false"}
      >
        <span className="hamburger" aria-hidden="true">
          <span/><span/><span/>
        </span>
      </button>
      <img
        src="/logo/mascot-128.webp"
        srcSet="/logo/mascot-128.webp 1x, /logo/mascot-256.webp 2x"
        alt="MedGang"
        width="44" height="44"
        style={topbarStyles.mark}
      />
      <div style={{minWidth:0}}>
        <div style={topbarStyles.brand}>
          <span style={{fontWeight:800, fontSize:20, lineHeight:1, letterSpacing:"-0.02em"}}>
            <span style={{color:"var(--med-green)"}}>Med</span>
            <span style={{color:"var(--gang-blue)"}}>Gang</span>
          </span>
          <span style={{color:"var(--ink-3)", fontSize:13, marginLeft:10, fontWeight:500}}>Eselsbrücken</span>
        </div>
        <div className="topbar-sub" style={topbarStyles.sub}>Merksätze für Medizinstudent:innen.</div>
      </div>
    </div>

    <div className="topbar-search-wrap" style={topbarStyles.searchWrap}>
      <div style={{position:"absolute", left:16, top:"50%", transform:"translateY(-50%)", color:"var(--ink-3)", display:"flex", pointerEvents:"none"}}>
        <I.Search size={16}/>
      </div>
      <input
        className="search-input"
        value={query}
        onChange={(e)=>setQuery(e.target.value)}
        placeholder="Suche nach Spruch, Thema oder Tag…"
        style={topbarStyles.search}
      />
      <kbd className="topbar-kbd" style={topbarStyles.kbd}>⌘K</kbd>
    </div>

    <div style={{display:"flex", alignItems:"center", gap:10, flexWrap:"wrap", justifyContent:"flex-end"}}>
      <SiteNav current="esel" />
      {unlocked ? (
        <button className="btn btn-pill-active topbar-pill-active" onClick={onLogout} style={topbarStyles.pillActive} title="Bearbeitungsrechte aktiv – Klick zum Sperren">
          <I.Unlock size={15}/>
          <span className="topbar-pill-text">Bearbeiten aktiv</span>
          <span style={topbarStyles.dot}/>
        </button>
      ) : (
        <button className="btn btn-pill-cta topbar-pill" onClick={onLockClick} style={topbarStyles.pillCta} title="Kenncode eingeben">
          <I.Lock size={15}/>
          <span className="topbar-pill-text">Kenncode eingeben</span>
        </button>
      )}
    </div>
  </header>
);

const topbarStyles = {
  bar: {
    gridColumn:"1 / -1",
    display:"grid",
    gridTemplateColumns:"minmax(280px, 380px) 1fr auto",
    gap:20, alignItems:"center",
    padding:"16px 28px",
    background:"rgba(255,255,255,0.85)",
    backdropFilter:"saturate(180%) blur(12px)",
    WebkitBackdropFilter:"saturate(180%) blur(12px)",
    borderBottom:"1px solid var(--line)",
    position:"sticky", top:0, zIndex:30,
  },
  brandWrap: { display:"flex", alignItems:"center", gap:6, minWidth:0 },
  mark: {
    width:44, height:44, display:"block", flexShrink:0,
    objectFit:"contain",
    filter:"drop-shadow(0 6px 14px rgba(74,140,255,0.20))",
  },
  brand: { display:"flex", alignItems:"baseline", flexWrap:"wrap" },
  sub: { fontSize:12, color:"var(--ink-3)", marginTop:3 },
  searchWrap: { position:"relative", maxWidth:560, width:"100%", justifySelf:"center" },
  search: {
    width:"100%", border:"1px solid var(--line)", background:"var(--bg-sunken)",
    padding:"12px 56px 12px 42px", borderRadius:999, fontSize:14, color:"var(--ink)",
    outline:"none", fontWeight:500,
  },
  kbd: {
    position:"absolute", right:12, top:"50%", transform:"translateY(-50%)",
    fontFamily:"Geist Mono, ui-monospace", fontSize:11, color:"var(--ink-3)",
    border:"1px solid var(--line)", borderRadius:6, padding:"2px 6px", background:"#fff",
  },
  pillCta: {
    display:"inline-flex", alignItems:"center", gap:8,
    background:"var(--gradient)", color:"#fff",
    padding:"10px 16px", borderRadius:999, fontSize:13, fontWeight:700,
    boxShadow:"var(--shadow-glow)",
  },
  pillActive: {
    display:"inline-flex", alignItems:"center", gap:8,
    background:"rgba(31,194,138,0.10)", color:"#0E8B5F",
    border:"1px solid rgba(31,194,138,0.25)",
    padding:"9px 14px", borderRadius:999, fontSize:13, fontWeight:600,
  },
  dot: {
    width:6, height:6, borderRadius:99, background:"var(--med-green)",
    display:"inline-block", marginLeft:2,
    boxShadow:"0 0 0 3px rgba(31,194,138,0.20)",
    animation:"pulseDot 2s ease-in-out infinite",
  },
};

// ────────────────────────────────────────────────────────────────────
// Sidebar
// ────────────────────────────────────────────────────────────────────
const Sidebar = ({ sections, active, setActive, counts, total, unlocked, mobileOpen, onClose }) => {
  const selectAndClose = (next) => { setActive(next); if (onClose) onClose(); };
  // Gruppen nach `group` zusammenfassen, Reihenfolge der ersten Erscheinung beibehalten
  const groups = useMemo(()=>{
    const order = [];
    const map = {};
    sections.forEach(s => {
      const g = s.group || "Sonstiges";
      if (!map[g]) { map[g] = []; order.push(g); }
      map[g].push(s);
    });
    return order.map(g => ({ name: g, sections: map[g] }));
  }, [sections]);

  return (
    <React.Fragment>
      {mobileOpen && <div className="sidebar-backdrop" onClick={onClose} aria-hidden="true"/>}
    <aside className="sidebar" data-mobile-open={mobileOpen ? "true" : "false"} style={sidebarStyles.aside}>
      <button
        className="side-all"
        onClick={()=>selectAndClose({ section:"_all", category:null })}
        style={{...sidebarStyles.allBtn, ...(active.section==="_all" ? sidebarStyles.allBtnActive : {})}}
      >
        <span style={{display:"flex", alignItems:"center", gap:10}}>
          <span style={sidebarStyles.allIcon}>
            <I.Sparkle size={14}/>
          </span>
          <span style={{fontWeight:600}}>Alle Eselsbrücken</span>
        </span>
        <span style={sidebarStyles.count}>{total}</span>
      </button>

      {groups.map(group => (
        <div key={group.name} style={{marginTop:18}}>
          <div style={sidebarStyles.groupLabel}>{group.name}</div>
          <nav style={{display:"flex", flexDirection:"column", gap:1}}>
            {group.sections.map(sec => {
              const open = active.section === sec.id;
              return (
                <div key={sec.id}>
                  <button
                    className="side-sec"
                    data-open={open}
                    onClick={()=>selectAndClose({ section: sec.id, category: null })}
                    style={{...sidebarStyles.sec, ...(open ? sidebarStyles.secActive : {})}}
                  >
                    <span style={{display:"flex", alignItems:"center", gap:10, minWidth:0}}>
                      <span className="side-chevron" style={{
                        transform: open ? "rotate(90deg)" : "rotate(0deg)",
                        display:"inline-flex",
                        color: open ? "var(--accent-ink-2)" : "var(--ink-3)"
                      }}>
                        <I.Chevron size={12}/>
                      </span>
                      <span style={{whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{sec.title}</span>
                    </span>
                    <span style={sidebarStyles.count}>{counts.section[sec.id] || 0}</span>
                  </button>
                  {open && (
                    <div className="side-cat-list" style={sidebarStyles.catList}>
                      {sec.categories.map((cat, idx) => {
                        const isActive = active.section===sec.id && active.category===cat.id;
                        const c = (counts.category[sec.id+":"+cat.id] || 0);
                        return (
                          <button
                            key={cat.id}
                            className="side-cat"
                            style={{
                              ...sidebarStyles.cat,
                              ...(isActive ? sidebarStyles.catActive : {}),
                              animationDelay: `${idx * 30}ms`,
                            }}
                            onClick={()=>selectAndClose({ section: sec.id, category: cat.id })}
                          >
                            <span style={{whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{cat.title}</span>
                            <span style={{...sidebarStyles.count, opacity: c ? 1 : 0.45}}>{c}</span>
                          </button>
                        );
                      })}
                    </div>
                  )}
                </div>
              );
            })}
          </nav>
        </div>
      ))}

      <div style={sidebarStyles.footer}>
        <div style={sidebarStyles.legendRow}>
          <span style={{
            width:8, height:8, borderRadius:99,
            background: unlocked ? "var(--med-green)" : "var(--line-2)",
            boxShadow: unlocked ? "0 0 0 3px rgba(31,194,138,0.20)" : "none",
          }}/>
          <span style={{fontWeight:600, color:"var(--ink-2)"}}>{unlocked ? "Bearbeitungsrechte aktiv" : "Nur Lesemodus"}</span>
        </div>
        <div style={{fontSize:11, color:"var(--ink-3)", marginTop:6, lineHeight:1.5}}>
          Kein Ersatz für Lehrbücher. Gepflegt von der MedGang-Lerngruppe.
        </div>
      </div>
    </aside>
    </React.Fragment>
  );
};

const sidebarStyles = {
  aside: {
    borderRight:"1px solid var(--line)",
    padding:"22px 14px",
    background:"#fff",
    position:"sticky", top:81, alignSelf:"start",
    height:"calc(100vh - 81px)",
    overflowY:"auto",
    display:"flex", flexDirection:"column"
  },
  allBtn: {
    width:"100%", display:"flex", justifyContent:"space-between", alignItems:"center",
    padding:"11px 12px", borderRadius:12, fontSize:13.5, color:"var(--ink-2)",
    border:"1px solid transparent",
  },
  allBtnActive: {
    background:"linear-gradient(180deg, rgba(31,194,138,0.06) 0%, rgba(74,140,255,0.06) 100%)",
    color:"var(--ink)",
    borderColor:"rgba(74,140,255,0.18)",
    boxShadow:"var(--shadow-xs)",
  },
  allIcon: {
    width:24, height:24, borderRadius:8,
    background:"var(--gradient)", color:"#fff",
    display:"grid", placeItems:"center",
  },
  groupLabel: {
    fontSize:10, textTransform:"uppercase", letterSpacing:"0.18em",
    color:"var(--ink-3)", fontWeight:700,
    margin:"0 12px 8px",
  },
  sec: {
    width:"100%", display:"flex", justifyContent:"space-between", alignItems:"center",
    padding:"9px 12px", borderRadius:10, fontSize:13.5, color:"var(--ink-2)", textAlign:"left",
    fontWeight:500,
  },
  secActive: {
    color:"var(--ink)", background:"var(--bg-sunken)",
    fontWeight:600,
  },
  catList: {
    display:"flex", flexDirection:"column", paddingLeft:22, gap:1, marginTop:2, marginBottom:6,
    borderLeft:"1px dashed var(--line)",
    marginLeft:16,
  },
  cat: {
    width:"100%", display:"flex", justifyContent:"space-between", alignItems:"center",
    padding:"7px 10px 7px 10px", borderRadius:8, fontSize:12.5,
    color:"var(--ink-3)", textAlign:"left",
  },
  catActive: {
    color:"var(--accent-ink-2)",
    background:"rgba(74,140,255,0.10)",
    fontWeight:600,
    paddingLeft:14,
  },
  count: {
    fontFamily:"Geist Mono", fontSize:11, color:"var(--ink-3)",
    background:"var(--bg-sunken)", padding:"2px 7px", borderRadius:99,
  },
  footer: {
    marginTop:"auto", padding:"16px 12px 4px",
    borderTop:"1px solid var(--line)", marginInline:-2,
  },
  legendRow: { display:"flex", alignItems:"center", gap:8, fontSize:12, color:"var(--ink-2)" }
};

// ────────────────────────────────────────────────────────────────────
// Mnemonic Card
// ────────────────────────────────────────────────────────────────────
const Card = ({ item, sectionMap, onEdit, onDelete, unlocked }) => {
  const section = sectionMap.sections[item.section];
  const category = section && section.categories.find(c => c.id === item.category);
  return (
    <article className="card-hover card" style={cardStyles.card}>
      <header style={cardStyles.head}>
        <div style={cardStyles.crumbs}>
          <span style={{fontWeight:700, color:"var(--ink-2)"}}>{section ? section.title : "—"}</span>
          <I.Chevron size={10}/>
          <span>{category ? category.title : "—"}</span>
        </div>
        {unlocked && (
          <div style={{display:"flex", gap:2}}>
            <button className="btn icon-btn" onClick={()=>onEdit(item.id)} style={cardStyles.iconBtn} title="Bearbeiten"><I.Edit size={14}/></button>
            <button className="btn icon-btn icon-btn-danger" onClick={()=>onDelete(item.id)} style={{...cardStyles.iconBtn, color:"var(--danger)"}} title="Löschen"><I.Trash size={14}/></button>
          </div>
        )}
      </header>

      <h3 style={cardStyles.title}>{item.title}</h3>

      <blockquote className="card-mnemonic" style={cardStyles.mnemonic}>
        <span style={cardStyles.quoteMark}>„</span>{item.mnemonic}<span style={cardStyles.quoteMark}>"</span>
      </blockquote>

      {item.expansion && item.expansion.length > 0 && (
        <ul style={cardStyles.expansion}>
          {item.expansion.slice(0,5).map(([k,v],i)=>(
            <li key={i} className="card-expansion-row" style={cardStyles.expRow}>
              <span style={cardStyles.expKey}>{k}</span>
              <span style={cardStyles.expDot}/>
              <span style={cardStyles.expVal}>{v}</span>
            </li>
          ))}
          {item.expansion.length > 5 && (
            <li style={{...cardStyles.expRow, color:"var(--ink-3)", fontSize:12}}>
              <span/>
              <span/>
              <span>+ {item.expansion.length - 5} weitere</span>
            </li>
          )}
        </ul>
      )}

      {item.note && (
        <div style={cardStyles.note}>
          <I.Bulb size={13}/>
          <span>{item.note}</span>
        </div>
      )}

      <footer style={cardStyles.foot}>
        <div style={{display:"flex", gap:6, flexWrap:"wrap"}}>
          {(item.tags||[]).map(t => <span key={t} className="chip" style={cardStyles.tag}>{t}</span>)}
        </div>
        <div style={cardStyles.meta}>
          <span style={{fontWeight:600, color:"var(--ink-2)"}}>{item.author || "Anonym"}</span>
          <span style={cardStyles.metaDot}/>
          <span>{item.updated_at ? (window.fmtRelative ? window.fmtRelative(item.updated_at) : new Date(item.updated_at).toLocaleDateString("de-DE")) : (item.updated || "")}</span>
        </div>
      </footer>
    </article>
  );
};

const cardStyles = {
  card: {
    background:"#fff", border:"1px solid var(--line)", borderRadius:"var(--radius)",
    padding:"22px 22px 18px", boxShadow:"var(--shadow-xs)",
    display:"flex", flexDirection:"column", gap:14,
    position:"relative",
  },
  head: { display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:10 },
  crumbs: {
    display:"flex", alignItems:"center", gap:6, fontSize:11, color:"var(--ink-3)",
    textTransform:"uppercase", letterSpacing:"0.08em", fontWeight:600,
  },
  iconBtn: {
    width:30, height:30, borderRadius:8, display:"grid", placeItems:"center",
    color:"var(--ink-3)",
  },
  title: { margin:0, fontSize:18, fontWeight:700, letterSpacing:"-0.015em", color:"var(--ink)" },
  mnemonic: {
    margin:0, fontSize:17, lineHeight:1.55, color:"var(--ink)",
    fontWeight:400, letterSpacing:"-0.005em",
    padding:"6px 0 6px 16px",
    borderLeft:"3px solid",
    borderImage:"linear-gradient(180deg, #1FC28A 0%, #4A8CFF 100%) 1",
  },
  quoteMark: { color:"var(--gang-blue)", margin:"0 2px", fontWeight:500 },
  expansion: { listStyle:"none", margin:0, padding:0, display:"flex", flexDirection:"column", gap:7 },
  expRow: {
    display:"grid", gridTemplateColumns:"minmax(80px, 160px) 14px 1fr",
    alignItems:"center", gap:10, fontSize:13.5,
  },
  expKey: { color:"var(--ink)", fontWeight:600 },
  expDot: { height:1, background:"var(--line)", alignSelf:"center" },
  expVal: { color:"var(--ink-2)" },
  note: {
    display:"flex", gap:8, alignItems:"flex-start",
    fontSize:12.5, color:"var(--ink-2)", lineHeight:1.5,
    padding:"10px 12px",
    background:"linear-gradient(180deg, rgba(31,194,138,0.05), rgba(74,140,255,0.05))",
    borderRadius:10,
    border:"1px solid rgba(74,140,255,0.10)",
  },
  foot: {
    display:"flex", justifyContent:"space-between", alignItems:"center",
    paddingTop:12, borderTop:"1px dashed var(--line)", marginTop:2, gap:10, flexWrap:"wrap",
  },
  tag: {
    fontSize:11, padding:"3px 9px", borderRadius:999,
    background:"var(--bg-sunken)", color:"var(--ink-2)",
    border:"1px solid var(--line)", fontWeight:500,
  },
  meta: { display:"flex", alignItems:"center", gap:8, fontSize:11.5, color:"var(--ink-3)" },
  metaDot: { width:3, height:3, borderRadius:99, background:"var(--ink-3)" },
};

// ────────────────────────────────────────────────────────────────────
// Modal helper
// ────────────────────────────────────────────────────────────────────
const Modal = ({ open, onClose, children, maxWidth = 460 }) => {
  if (!open) return null;
  return (
    <div role="dialog" aria-modal="true" onClick={onClose} style={modalStyles.backdrop}>
      <div onClick={e=>e.stopPropagation()} style={{...modalStyles.shell, maxWidth}}>
        {children}
      </div>
    </div>
  );
};
const modalStyles = {
  backdrop: {
    position:"fixed", inset:0,
    background:"rgba(17,17,17,0.40)",
    backdropFilter:"blur(6px)", WebkitBackdropFilter:"blur(6px)",
    display:"grid", placeItems:"center", zIndex:60, padding:20,
    animation:"fadeIn .18s ease-out",
  },
  shell: {
    width:"100%", background:"#fff", borderRadius:"var(--radius-lg)",
    boxShadow:"var(--shadow-lg)", border:"1px solid var(--line)", overflow:"hidden",
    animation:"fadeIn .22s ease-out",
  }
};

// ────────────────────────────────────────────────────────────────────
// Auth Modal (Kenncode)
// ────────────────────────────────────────────────────────────────────
const AuthModal = ({ open, onClose, onSuccess, verify }) => {
  const [value, setValue] = useState("");
  const [shake, setShake] = useState(false);
  const [checking, setChecking] = useState(false);
  const ref = useRef(null);

  useEffect(()=>{
    if(open){ setValue(""); setShake(false); setChecking(false); setTimeout(()=>ref.current && ref.current.focus(), 60); }
  }, [open]);

  const submit = async (e) => {
    e && e.preventDefault();
    const code = value.trim();
    if (!code || checking) return;
    setChecking(true);
    try {
      const ok = await verify(code);
      if (ok) onSuccess(code);
      else { setShake(true); setTimeout(()=>setShake(false), 450); }
    } catch {
      setShake(true); setTimeout(()=>setShake(false), 450);
    } finally {
      setChecking(false);
    }
  };

  return (
    <Modal open={open} onClose={onClose}>
      <form onSubmit={submit} style={{padding:"30px 30px 24px", animation: shake ? "shake .4s" : "none"}}>
        <div style={{display:"flex", alignItems:"center", gap:14, marginBottom:22}}>
          <div style={{
            width:44, height:44, borderRadius:14,
            background:"var(--gradient)", color:"#fff",
            display:"grid", placeItems:"center",
            boxShadow:"0 10px 24px -8px rgba(74,140,255,0.45)",
          }}>
            <I.Lock size={20}/>
          </div>
          <div>
            <div style={{fontSize:21, lineHeight:1.1, fontWeight:800, letterSpacing:"-0.02em"}}>Bearbeitung freischalten</div>
            <div style={{fontSize:13, color:"var(--ink-3)", marginTop:4}}>Kenncode der MedGang-Lerngruppe eingeben.</div>
          </div>
        </div>

        <label style={{display:"block", fontSize:10, color:"var(--ink-3)", marginBottom:8, textTransform:"uppercase", letterSpacing:"0.16em", fontWeight:700}}>Kenncode</label>
        <input
          ref={ref}
          value={value}
          onChange={e=>setValue(e.target.value)}
          placeholder="z. B. MEDGANG-2024"
          autoComplete="off"
          className="mono input"
          style={{
            width:"100%", padding:"14px 16px", borderRadius:12,
            border:"1.5px solid var(--line)", background:"var(--bg-sunken)", fontSize:15,
            letterSpacing:"0.12em", textTransform:"uppercase", fontWeight:500,
            outline:"none",
          }}
        />

        <div style={{
          marginTop:14, padding:"10px 14px",
          background:"linear-gradient(180deg, rgba(31,194,138,0.06), rgba(74,140,255,0.06))",
          border:"1px solid rgba(74,140,255,0.15)", borderRadius:10,
          fontSize:12.5, color:"var(--ink-2)",
        }}>
          Den Kenncode kriegst du von der MedGang-Lerngruppe.
        </div>

        <div style={{display:"flex", gap:10, marginTop:22, justifyContent:"flex-end"}}>
          <button type="button" className={btnClass.secondary} onClick={onClose} style={btnStyle.secondary} disabled={checking}>Abbrechen</button>
          <button type="submit" className={btnClass.primary} style={{...btnStyle.primary, opacity: checking ? 0.7 : 1}} disabled={checking}>
            <I.Unlock size={15}/> {checking ? "Prüfe…" : "Freischalten"}
          </button>
        </div>
      </form>
    </Modal>
  );
};

const btnStyle = {
  primary: {
    display:"inline-flex", alignItems:"center", gap:8,
    padding:"11px 18px", borderRadius:999, fontSize:13.5, fontWeight:700,
    background:"var(--gradient)", color:"#fff",
    boxShadow:"var(--shadow-glow)",
    whiteSpace:"nowrap",
  },
  secondary: {
    display:"inline-flex", alignItems:"center", gap:8,
    padding:"11px 18px", borderRadius:999, fontSize:13.5, fontWeight:600,
    background:"#fff", color:"var(--ink-2)", border:"1px solid var(--line)",
  },
  ghost: {
    display:"inline-flex", alignItems:"center", gap:6,
    padding:"8px 12px", borderRadius:10, fontSize:13, color:"var(--ink-2)",
    fontWeight:600,
  }
};

const btnClass = {
  primary:   "btn btn-primary",
  secondary: "btn btn-secondary",
  ghost:     "btn btn-ghost",
};

// ────────────────────────────────────────────────────────────────────
// Edit Sheet (rechts)
// ────────────────────────────────────────────────────────────────────
const EditSheet = ({ open, onClose, value, onChange, onSave, onCancel, sections, isNew, saving }) => {
  if (!open || !value) return null;

  const setField = (k, v) => onChange({ ...value, [k]: v });
  const sec = sections.find(s => s.id === value.section);

  const updateExp = (i, idx, v) => {
    const next = value.expansion.map((row, r) => r===i ? row.map((c,ci)=>ci===idx?v:c) : row);
    setField("expansion", next);
  };
  const addExp = () => setField("expansion", [...(value.expansion||[]), ["",""]]);
  const removeExp = (i) => setField("expansion", value.expansion.filter((_,r)=>r!==i));

  return (
    <div style={sheetStyles.backdrop} onClick={onClose}>
      <aside style={sheetStyles.sheet} onClick={e=>e.stopPropagation()}>
        <header style={sheetStyles.head}>
          <div style={{minWidth:0}}>
            <div style={{fontSize:10, textTransform:"uppercase", letterSpacing:"0.16em", color:"var(--ink-3)", fontWeight:700}}>{isNew ? "Neue Eselsbrücke" : "Bearbeiten"}</div>
            <div style={{fontSize:22, marginTop:4, fontWeight:800, letterSpacing:"-0.02em", whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{value.title || "Ohne Titel"}</div>
          </div>
          <button className="btn icon-btn" onClick={onClose} style={{...cardStyles.iconBtn, color:"var(--ink-2)"}}><I.X size={18}/></button>
        </header>

        <div style={sheetStyles.body}>
          <Field label="Titel">
            <input className="input" value={value.title} onChange={e=>setField("title", e.target.value)} style={inputStyles.text}/>
          </Field>

          <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:12}}>
            <Field label="Sektion">
              <select className="input" value={value.section} onChange={e=>setField("section", e.target.value)} style={inputStyles.text}>
                {sections.map(s => <option key={s.id} value={s.id}>{s.title}</option>)}
              </select>
            </Field>
            <Field label="Kategorie">
              <select className="input" value={value.category} onChange={e=>setField("category", e.target.value)} style={inputStyles.text}>
                {sec && sec.categories.map(c => <option key={c.id} value={c.id}>{c.title}</option>)}
              </select>
            </Field>
          </div>

          <Field label="Merksatz">
            <textarea
              className="input"
              value={value.mnemonic}
              onChange={e=>setField("mnemonic", e.target.value)}
              rows={3}
              style={{...inputStyles.text, fontSize:15, lineHeight:1.55, fontWeight:400}}
            />
          </Field>

          <Field label="Aufschlüsselung">
            <div style={{display:"flex", flexDirection:"column", gap:8}}>
              {(value.expansion||[]).map((row, i)=>(
                <div key={i} style={{display:"grid", gridTemplateColumns:"160px 1fr auto", gap:8, alignItems:"center"}}>
                  <input className="input" value={row[0]} placeholder="Stichwort" onChange={e=>updateExp(i,0,e.target.value)} style={inputStyles.text}/>
                  <input className="input" value={row[1]} placeholder="Bedeutung" onChange={e=>updateExp(i,1,e.target.value)} style={inputStyles.text}/>
                  <button className="btn icon-btn icon-btn-danger" onClick={()=>removeExp(i)} style={{...cardStyles.iconBtn, color:"var(--danger)"}}><I.Trash size={14}/></button>
                </div>
              ))}
              <button className={btnClass.ghost} onClick={addExp} style={{...btnStyle.ghost, alignSelf:"flex-start", color:"var(--accent-ink-2)"}}>
                <I.Plus size={14}/> Zeile hinzufügen
              </button>
            </div>
          </Field>

          <Field label="Anmerkung">
            <textarea className="input" value={value.note||""} onChange={e=>setField("note", e.target.value)} rows={2} style={inputStyles.text}/>
          </Field>

          <Field label="Autor">
            <input
              className="input"
              value={value.author||""}
              onChange={e=>setField("author", e.target.value)}
              placeholder="Anonym"
              style={inputStyles.text}
            />
          </Field>

          <Field label="Tags">
            <TagInput
              value={value.tags||[]}
              onChange={(t)=>setField("tags", t)}
            />
          </Field>
        </div>

        <footer style={sheetStyles.foot}>
          <button className={btnClass.secondary} onClick={onCancel} style={btnStyle.secondary} disabled={saving}>Abbrechen</button>
          <button className={btnClass.primary} onClick={onSave} style={{...btnStyle.primary, opacity: saving ? 0.7 : 1}} disabled={saving}>
            <I.Check size={15}/> {saving ? "Speichere…" : "Speichern"}
          </button>
        </footer>
      </aside>
    </div>
  );
};

const Field = ({ label, children }) => (
  <label style={{display:"flex", flexDirection:"column", gap:7}}>
    <span style={{fontSize:10, textTransform:"uppercase", letterSpacing:"0.16em", color:"var(--ink-3)", fontWeight:700}}>{label}</span>
    {children}
  </label>
);

const TagInput = ({ value, onChange }) => {
  const [input, setInput] = useState("");
  const tags = value || [];
  const addTag = (raw) => {
    const t = (raw || "").trim();
    if (!t || tags.includes(t)) { setInput(""); return; }
    onChange([...tags, t]);
    setInput("");
  };
  const removeTag = (t) => onChange(tags.filter(x => x !== t));
  return (
    <div className="tag-input-wrap" style={{
      display:"flex", flexWrap:"wrap", gap:6, alignItems:"center",
      padding:"7px 8px", borderRadius:10,
      border:"1.5px solid var(--line)", background:"var(--bg-sunken)",
      minHeight:44, transition:"border-color .15s, background .15s, box-shadow .18s",
    }}>
      {tags.map(t => (
        <span key={t} style={{
          display:"inline-flex", alignItems:"center", gap:6,
          padding:"4px 4px 4px 10px", borderRadius:999,
          background:"#fff", border:"1px solid var(--line)",
          fontSize:12.5, color:"var(--ink-2)", fontWeight:500,
          animation:"fadeIn .15s ease-out",
        }}>
          {t}
          <button
            type="button"
            onClick={() => removeTag(t)}
            aria-label={`Tag ${t} entfernen`}
            style={{
              width:18, height:18, borderRadius:99, display:"grid", placeItems:"center",
              background:"var(--bg-sunken)", color:"var(--ink-3)",
              fontSize:12, lineHeight:1, cursor:"pointer",
            }}
          ><I.X size={10}/></button>
        </span>
      ))}
      <input
        value={input}
        onChange={e => setInput(e.target.value)}
        onKeyDown={e => {
          if (e.key === "Enter" || e.key === ",") {
            e.preventDefault();
            addTag(input);
          } else if (e.key === "Backspace" && !input && tags.length) {
            removeTag(tags[tags.length - 1]);
          }
        }}
        onBlur={() => input && addTag(input)}
        placeholder={tags.length ? "noch einen Tag…" : "Tag eingeben, Enter…"}
        style={{
          flex:"1 1 100px", minWidth:80,
          border:0, outline:"none", background:"transparent",
          padding:"4px 4px", fontSize:14, color:"var(--ink)",
        }}
      />
    </div>
  );
};

const inputStyles = {
  text: {
    width:"100%", padding:"11px 13px", borderRadius:10,
    border:"1.5px solid var(--line)", background:"var(--bg-sunken)",
    fontSize:14, color:"var(--ink)", outline:"none",
    fontWeight:500,
  }
};

const sheetStyles = {
  backdrop: {
    position:"fixed", inset:0,
    background:"rgba(17,17,17,0.35)",
    backdropFilter:"blur(4px)", WebkitBackdropFilter:"blur(4px)",
    zIndex:50, display:"flex", justifyContent:"flex-end",
    animation:"fadeIn .15s ease-out",
  },
  sheet: {
    width:"min(580px, 100%)", background:"#fff", height:"100%",
    display:"flex", flexDirection:"column",
    boxShadow:"var(--shadow-lg)", borderLeft:"1px solid var(--line)",
    animation:"slideIn .25s cubic-bezier(.2,.8,.2,1)",
  },
  head: {
    padding:"22px 24px 16px", borderBottom:"1px solid var(--line)",
    display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:12,
  },
  body: { padding:"22px 24px", overflowY:"auto", display:"flex", flexDirection:"column", gap:18, flex:1 },
  foot: {
    padding:"16px 24px", borderTop:"1px solid var(--line)",
    display:"flex", gap:10, justifyContent:"flex-end",
    background:"var(--bg-sunken)",
  }
};

Object.assign(window, { Topbar, Sidebar, Card, AuthModal, EditSheet, btnStyle, btnClass });
