// ── API Client ──────────────────────────────────────────────────────────────── // Einheitlicher Fetch-Wrapper für alle Tools und Core-Komponenten export const api = async (path, { body, method, isFile } = {}) => { const token = localStorage.getItem('sk_token'); const headers = token ? { Authorization: `Bearer ${token}` } : {}; if (!isFile) headers['Content-Type'] = 'application/json'; const res = await fetch(`/api${path}`, { method: method || (body ? 'POST' : 'GET'), headers, body: isFile ? body : body ? JSON.stringify(body) : undefined, }); if (path.includes('/admin/backup') && res.ok) return res.blob(); const data = await res.json().catch(() => ({})); if (!res.ok) throw new Error(data.error || 'Fehler'); return data; }; // ── Design Tokens ───────────────────────────────────────────────────────────── // Einheitliche Styles für alle Tools – in jedem Tool importierbar export const S = { // Eingabefeld inp: { width: '100%', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: 6, padding: '8px 10px', color: '#fff', fontSize: 13, fontFamily: "'Space Mono',monospace", outline: 'none', boxSizing: 'border-box', }, // Button-Factory: btn('#4ecdc4') oder btn('#ff6b9d', true) für kleine Variante btn: (c = '#4ecdc4', sm = false) => ({ background: `${c}18`, border: `1px solid ${c}44`, borderRadius: 6, padding: sm ? '5px 10px' : '8px 14px', color: c, cursor: 'pointer', fontFamily: 'monospace', fontSize: sm ? 11 : 12, whiteSpace: 'nowrap', transition: 'all 0.15s', }), // Karten-Container card: { background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.07)', borderRadius: 12, padding: 20, }, // Abschnitts-Überschrift head: { color: 'rgba(255,255,255,0.6)', fontSize: 10, fontFamily: 'monospace', letterSpacing: 2, marginBottom: 14, }, };