// ─────────────────────────────────────────────
// DEV_DesignWidgets.jsx
//
// Shared builder widgets extracted verbatim from the old v6/DEV_Design.jsx during
// the v6→v7 consolidation (2026-07-17). The v7 refactor split DEVDesign/Inspector/
// ListView into v7 files but left these shared widgets defined only in v6, while the
// live v7 code still depended on them. Extracted here so v6/ can be removed.
//
// Provides: GOOGLE_FONTS, FONT_SIZES, BORDER_RADII, PADDINGS,
//           KBSidebar, IconCell, IconBrowser, ColorPicker, ThemePanel
// Depends only on globals: React, apiFetch, API_BASE, window.jscolor.
// ─────────────────────────────────────────────

// ── Theme constants ──
const GOOGLE_FONTS = [
  { value:"'DM Sans', sans-serif",          label:'DM Sans (Sans)' },
  { value:"'Inter', sans-serif",            label:'Inter (Sans)' },
  { value:"'Open Sans', sans-serif",        label:'Open Sans (Sans)' },
  { value:"'Lato', sans-serif",             label:'Lato (Sans)' },
  { value:"'Poppins', sans-serif",          label:'Poppins (Sans)' },
  { value:"'Roboto', sans-serif",           label:'Roboto (Sans)' },
  { value:"'Merriweather', serif",          label:'Merriweather (Serif)' },
  { value:"'Playfair Display', serif",      label:'Playfair Display (Serif)' },
  { value:"'Lora', serif",                  label:'Lora (Serif)' },
  { value:"'Dancing Script', cursive",      label:'Dancing Script (Cursive)' },
  { value:"'Pacifico', cursive",            label:'Pacifico (Cursive)' },
  { value:"'DM Mono', monospace",           label:'DM Mono (Mono)' },
];
const FONT_SIZES    = ['10','12','13','14','15','16','18','20','24'];
const BORDER_RADII  = ['0','4','6','8','10','12','16'];
const PADDINGS      = [
  { value:'S',  label:'S — Compact' },
  { value:'M',  label:'M — Default' },
  { value:'L',  label:'L — Relaxed' },
  { value:'XL', label:'XL — Spacious' },
];

// ── KBSidebar — knowledge-base slide-out ──
function KBSidebar({ kbKey, onClose }) {
  const [loading, setLoading] = React.useState(true);
  const [title,   setTitle]   = React.useState('');
  const [content, setContent] = React.useState('');
  const [error,   setError]   = React.useState(null);

  React.useEffect(() => {
    setLoading(true); setError(null);
    apiFetch(`${API_BASE}/v6/kb/${encodeURIComponent(kbKey)}`)
      .then(r => r.json())
      .then(data => {
        if (data.status !== 'ok') throw new Error(data.message);
        setTitle(data.title);
        setContent(data.content);
      })
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }, [kbKey]);

  // Close on Escape
  React.useEffect(() => {
    function onKey(e) { if (e.key === 'Escape') onClose(); }
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  return (
    <>
      {/* Backdrop */}
      <div
        onClick={onClose}
        style={{
          position: 'fixed', inset: 0, zIndex: 1100,
          background: 'rgba(0,0,0,0.25)',
        }}
      />
      {/* Sidebar */}
      <div style={{
        position: 'fixed', top: 0, right: 0, bottom: 0,
        width: 360, zIndex: 1101,
        background: '#fff',
        borderLeft: '1px solid #e2e8f0',
        boxShadow: '-4px 0 24px rgba(0,0,0,0.12)',
        display: 'flex', flexDirection: 'column',
        fontFamily: 'DM Sans, sans-serif',
      }}>
        {/* Header */}
        <div style={{
          padding: '14px 16px', borderBottom: '1px solid #e2e8f0',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          background: '#0f1923', flexShrink: 0,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
              stroke="#93c5fd" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="12" cy="12" r="10"/>
              <line x1="12" y1="8" x2="12" y2="8" strokeWidth="2.5"/>
              <line x1="12" y1="12" x2="12" y2="16"/>
            </svg>
            <span style={{ color: '#fff', fontWeight: 700, fontSize: 14 }}>
              {loading ? 'Loading…' : title || 'Help'}
            </span>
          </div>
          <button onClick={onClose}
            style={{
              background: 'rgba(255,255,255,0.1)', border: 'none', color: '#fff',
              width: 28, height: 28, borderRadius: 5, cursor: 'pointer', fontSize: 16,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: 'inherit',
            }}>✕</button>
        </div>

        {/* Content */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '20px 20px' }}>
          {loading && (
            <div style={{ color: '#94a3b8', fontSize: 13, textAlign: 'center', marginTop: 40 }}>
              Loading…
            </div>
          )}
          {error && (
            <div style={{ color: '#dc2626', fontSize: 12, padding: '10px 12px',
              background: '#fee2e2', borderRadius: 6 }}>
              ⚠ {error}
            </div>
          )}
          {!loading && !error && (
            <div
              className="kb-content"
              dangerouslySetInnerHTML={{ __html: content }}
              style={{ fontSize: 13, color: '#374151', lineHeight: 1.7 }}
            />
          )}
        </div>

        {/* Footer */}
        <div style={{
          padding: '10px 16px', borderTop: '1px solid #f1f5f9',
          fontSize: 10, color: '#94a3b8', flexShrink: 0,
        }}>
          Press Esc to close · Key: {kbKey}
        </div>
      </div>

      {/* Inline styles for kb-content HTML */}
      <style>{`
        .kb-content h2 { font-size:15px; font-weight:700; color:#0f1923; margin:0 0 10px; }
        .kb-content h3 { font-size:13px; font-weight:700; color:#1e293b; margin:16px 0 6px; }
        .kb-content p  { margin:0 0 10px; }
        .kb-content ul, .kb-content ol { padding-left:18px; margin:0 0 10px; }
        .kb-content li { margin-bottom:4px; }
        .kb-content code { background:#f1f5f9; padding:1px 5px; border-radius:3px;
          font-family:DM Mono,monospace; font-size:11px; color:#2563eb; }
        .kb-content strong { font-weight:700; color:#0f1923; }
        .kb-content a { color:#2563eb; }
        .kb-content hr { border:none; border-top:1px solid #e2e8f0; margin:14px 0; }
        .kb-content .tip { background:#eff6ff; border-left:3px solid #2563eb;
          padding:8px 12px; border-radius:0 6px 6px 0; margin:10px 0; font-size:12px; }
        .kb-content .warn { background:#fef9ec; border-left:3px solid #f59e0b;
          padding:8px 12px; border-radius:0 6px 6px 0; margin:10px 0; font-size:12px; }
      `}</style>
    </>
  );
}

// ── IconCell / IconBrowser — icon picker ──
function IconCell({ ic, onSelect, onCopy, copied }) {
  const [hover, setHover] = React.useState(false);
  const isCopied = copied === ic.value;

  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      title={ic.name + (ic.desc ? ' — ' + ic.desc : '')}
      style={{ position:'relative' }}>
      {/* Main icon button — click to select */}
      <button
        onClick={() => onSelect && onSelect(ic.value)}
        style={{
          width:'100%', aspectRatio:'1', border: hover ? '1.5px solid #2563eb' : '1px solid #e2e8f0',
          borderRadius:7, background: hover ? '#eff6ff' : '#fff',
          fontSize:20, cursor:'pointer', display:'flex', alignItems:'center',
          justifyContent:'center', transition:'all 0.12s', padding:0,
        }}>
        {ic.value}
      </button>
      {/* Copy button — appears on hover */}
      {hover && (
        <button
          onClick={e => { e.stopPropagation(); onCopy(ic.value); }}
          title="Copy to clipboard"
          style={{
            position:'absolute', top:-4, right:-4, width:16, height:16,
            background: isCopied ? '#22c55e' : '#0f1923',
            border:'none', borderRadius:3, cursor:'pointer',
            color:'#fff', fontSize:8, display:'flex', alignItems:'center', justifyContent:'center',
            fontFamily:'DM Sans, sans-serif', zIndex:1,
          }}>
          {isCopied ? '✓' : '📋'}
        </button>
      )}
    </div>
  );
}

function IconBrowser({ onSelect, onClose }) {
  const [search,    setSearch]    = React.useState('');
  const [icons,     setIcons]     = React.useState({});  // grouped data
  const [loading,   setLoading]   = React.useState(true);
  const [error,     setError]     = React.useState(null);
  const [collapsed, setCollapsed] = React.useState({});  // cat collapse state
  const [copied,    setCopied]    = React.useState(null); // recently copied value
  const [filter,    setFilter]    = React.useState('emoji'); // active type tab

  // Load icons on mount
  React.useEffect(() => {
    async function load() {
      setLoading(true); setError(null);
      try {
        const res  = await apiFetch(`${API_BASE}/v7/dev/icons?type=${filter}${search ? '&q='+encodeURIComponent(search) : ''}`);
        const data = await res.json();
        if (data.status !== 'ok') throw new Error(data.message);
        setIcons(data.grouped || {});
      } catch(e) {
        setError(e.message);
      }
      setLoading(false);
    }
    load();
  }, [filter, search]);

  function handleCopy(value) {
    navigator.clipboard?.writeText(value).catch(() => {});
    setCopied(value);
    setTimeout(() => setCopied(null), 1500);
  }

  function toggleCat(key) {
    setCollapsed(prev => ({ ...prev, [key]: !prev[key] }));
  }

  // Flatten all icons for search results display
  const allIcons = [];
  Object.values(icons).forEach(cats =>
    Object.values(cats).forEach(subs =>
      Object.values(subs).forEach(arr =>
        arr.forEach(ic => allIcons.push(ic))
      )
    )
  );

  const isSearching = search.trim().length > 0;

  return (
    <div style={{
      position:'fixed', top:0, right:0, bottom:0,
      width:320, zIndex:1000,
      background:'#fff',
      borderLeft:'1px solid #e2e8f0',
      boxShadow:'-4px 0 24px rgba(0,0,0,0.12)',
      display:'flex', flexDirection:'column',
      fontFamily:'DM Sans, sans-serif',
    }}>

      {/* Header */}
      <div style={{ padding:'14px 16px', borderBottom:'1px solid #e2e8f0', display:'flex', alignItems:'center', justifyContent:'space-between', background:'#0f1923', flexShrink:0 }}>
        <div style={{ color:'#fff', fontWeight:700, fontSize:14, letterSpacing:'-0.01em' }}>
          😀 Icon Browser
        </div>
        <button onClick={onClose}
          style={{ background:'rgba(255,255,255,0.1)', border:'none', color:'#fff', width:28, height:28, borderRadius:5, cursor:'pointer', fontSize:16, display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'inherit' }}>
          ✕
        </button>
      </div>

      {/* Type tabs */}
      <div style={{ display:'flex', borderBottom:'1px solid #e2e8f0', flexShrink:0 }}>
        {['emoji','lucide','custom'].map(t => (
          <button key={t} onClick={() => setFilter(t)}
            style={{ flex:1, padding:'9px 6px', border:'none', background: filter===t ? '#f8fafc' : '#fff',
              borderBottom: filter===t ? '2px solid #0f1923' : '2px solid transparent',
              fontSize:12, fontWeight: filter===t ? 700 : 400,
              color: filter===t ? '#0f1923' : '#94a3b8',
              cursor:'pointer', fontFamily:'DM Sans, sans-serif', textTransform:'capitalize' }}>
            {t}
          </button>
        ))}
      </div>

      {/* Search */}
      <div style={{ padding:'10px 12px', borderBottom:'1px solid #f1f5f9', flexShrink:0 }}>
        <div style={{ position:'relative' }}>
          <span style={{ position:'absolute', left:9, top:'50%', transform:'translateY(-50%)', fontSize:13, color:'#94a3b8', pointerEvents:'none' }}>🔍</span>
          <input value={search} onChange={e => setSearch(e.target.value)}
            placeholder="Search icons..."
            style={{ width:'100%', padding:'7px 10px 7px 30px', border:'1.5px solid #e2e8f0', borderRadius:7, fontSize:13, fontFamily:'DM Sans, sans-serif', outline:'none', boxSizing:'border-box' }} />
          {search && (
            <button onClick={() => setSearch('')}
              style={{ position:'absolute', right:8, top:'50%', transform:'translateY(-50%)', background:'none', border:'none', color:'#94a3b8', cursor:'pointer', fontSize:14, padding:0 }}>✕</button>
          )}
        </div>
      </div>

      {/* Instruction */}
      <div style={{ padding:'6px 12px', background:'#f8fafc', borderBottom:'1px solid #f1f5f9', fontSize:11, color:'#94a3b8', flexShrink:0 }}>
        Click icon to select · 📋 to copy to clipboard
      </div>

      {/* Icon list */}
      <div style={{ flex:1, overflowY:'auto', padding:'8px 0' }}>

        {loading && (
          <div style={{ padding:40, textAlign:'center', color:'#94a3b8', fontSize:13 }}>Loading icons…</div>
        )}

        {error && (
          <div style={{ padding:20, color:'#dc2626', fontSize:12, textAlign:'center' }}>
            ⚠ {error}<br/>
            <span style={{ color:'#94a3b8', fontSize:11 }}>Add icons to DO.icons table to get started</span>
          </div>
        )}

        {!loading && !error && allIcons.length === 0 && (
          <div style={{ padding:32, textAlign:'center', color:'#94a3b8', fontSize:13 }}>
            {isSearching ? `No icons matching "${search}"` : 'No icons found in DO.icons'}
          </div>
        )}

        {/* Search results — flat grid */}
        {!loading && isSearching && allIcons.length > 0 && (
          <div style={{ padding:'8px 12px' }}>
            <div style={{ fontSize:10, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.07em', marginBottom:8 }}>
              {allIcons.length} result{allIcons.length !== 1 ? 's' : ''}
            </div>
            <div style={{ display:'grid', gridTemplateColumns:'repeat(6, 1fr)', gap:4 }}>
              {allIcons.map(ic => (
                <IconCell key={ic.id} ic={ic} onSelect={onSelect} onCopy={handleCopy} copied={copied} />
              ))}
            </div>
          </div>
        )}

        {/* Grouped — collapsible by cat */}
        {!loading && !isSearching && !error && Object.entries(icons).map(([type, cats]) => (
          Object.entries(cats).map(([cat, subs]) => {
            const catKey   = `${type}_${cat}`;
            const isOpen   = collapsed[catKey] !== true; // default open
            const catIcons = Object.values(subs).flat();
            return (
              <div key={catKey}>
                {/* Category header */}
                <button onClick={() => toggleCat(catKey)}
                  style={{ width:'100%', padding:'8px 14px', background:'#f8fafc', border:'none', borderBottom:'1px solid #f1f5f9', borderTop:'1px solid #f1f5f9', display:'flex', alignItems:'center', justifyContent:'space-between', cursor:'pointer', fontFamily:'DM Sans, sans-serif' }}>
                  <span style={{ fontSize:12, fontWeight:700, color:'#374151', textTransform:'capitalize' }}>
                    {cat} <span style={{ color:'#94a3b8', fontWeight:400 }}>({catIcons.length})</span>
                  </span>
                  <span style={{ fontSize:11, color:'#94a3b8', transform: isOpen ? 'rotate(90deg)' : 'none', transition:'transform 0.15s', display:'inline-block' }}>›</span>
                </button>

                {isOpen && (
                  <div style={{ padding:'8px 12px' }}>
                    {/* Sub-categories */}
                    {Object.entries(subs).map(([sub, subIcons]) => (
                      <div key={sub}>
                        {sub && (
                          <div style={{ fontSize:10, fontWeight:600, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.07em', marginBottom:5, marginTop:6 }}>{sub}</div>
                        )}
                        <div style={{ display:'grid', gridTemplateColumns:'repeat(6, 1fr)', gap:4, marginBottom:6 }}>
                          {subIcons.map(ic => (
                            <IconCell key={ic.id} ic={ic} onSelect={onSelect} onCopy={handleCopy} copied={copied} />
                          ))}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            );
          })
        ))}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────
// ColorPicker — jscolor + hex input
// ─────────────────────────────────────────────
function ColorPicker({ value, onChange, label }) {
  const inputRef = React.useRef(null);
  const [hex, setHex] = React.useState(value || '');

  // Sync when value changes externally
  React.useEffect(() => {
    setHex(value || '');
    if (inputRef.current?.jscolor) {
      try { inputRef.current.jscolor.fromString(value || 'ffffffff'); } catch(e) {}
    }
  }, [value]);

  // Init jscolor after mount
  React.useEffect(() => {
    if (!inputRef.current || !window.jscolor) return;
    const jsc = new window.jscolor(inputRef.current, {
      position:      'left',
      format:        'hex',
      alphaChannel:  false,
      previewSize:   0,
      padding:       4,
      borderRadius:  6,
      shadow:        true,
      zIndex:        9999,
      onChange:      function() {
        const h = '#' + this.toHEXString().replace('#','');
        setHex(h);
        onChange(h);
      },
    });
    if (value) { try { jsc.fromString(value); } catch(e) {} }
    return () => { try { jsc.hide(); } catch(e) {} };
  }, []);

  function handleInput(e) {
    const v = e.target.value;
    setHex(v);
    if (/^#[0-9A-Fa-f]{6}$/.test(v)) {
      onChange(v);
      if (inputRef.current?.jscolor) {
        try { inputRef.current.jscolor.fromString(v); } catch(e) {}
      }
    }
  }

  function handleBlur() {
    let v = hex.trim();
    if (!v) { onChange(''); return; }
    if (!v.startsWith('#')) v = '#' + v;
    if (/^#[0-9A-Fa-f]{3}$/.test(v))
      v = '#' + v[1]+v[1]+v[2]+v[2]+v[3]+v[3];
    setHex(v);
    if (/^#[0-9A-Fa-f]{6}$/.test(v)) {
      onChange(v);
      if (inputRef.current?.jscolor) {
        try { inputRef.current.jscolor.fromString(v); } catch(e) {}
      }
    }
  }

  const isValid = /^#[0-9A-Fa-f]{6}$/.test(hex);

  return (
    <div style={{ marginBottom:12, width:'100%', boxSizing:'border-box' }}>
      {label && <div style={{ fontSize:10, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.06em', marginBottom:5, marginTop:10 }}>{label}</div>}
      <div style={{ display:'flex', alignItems:'center', gap:8 }}>
        {/* Color swatch — jscolor attaches here */}
        <div style={{ width:32, height:32, borderRadius:6, flexShrink:0, overflow:'hidden',
          background: isValid ? hex : '#e2e8f0', border:'1.5px solid #e2e8f0', cursor:'pointer',
          position:'relative' }}>
          <input ref={inputRef}
            readOnly
            style={{ opacity:0, position:'absolute', inset:0, width:'100%', height:'100%',
              cursor:'pointer', border:'none', padding:0, background:'transparent' }} />
        </div>
        {/* Hex input */}
        <input value={hex} onChange={handleInput} onBlur={handleBlur}
          placeholder="#000000"
          style={{ flex:1, minWidth:0, padding:'6px 8px',
            border: isValid || !hex ? '1.5px solid #e2e8f0' : '1.5px solid #fca5a5',
            borderRadius:6, fontSize:12, fontFamily:'DM Mono, monospace',
            color:'#0f1923', outline:'none', boxSizing:'border-box' }} />
        {hex && (
          <button onClick={() => { setHex(''); onChange(''); }}
            style={{ background:'none', border:'none', color:'#94a3b8',
              cursor:'pointer', fontSize:14, padding:'0 2px', fontFamily:'inherit' }}>✕</button>
        )}
      </div>
    </div>
  );
}

// ── ThemePanel — app theme editor ──
function ThemePanel({ theme, onChange }) {
  if (!theme) return <div style={{ padding:40, textAlign:'center', color:'#94a3b8' }}>No theme data</div>;
  function set(key, val) { onChange({ ...theme, [key]: val }); }

  const colorRow = (label, key) => (
    <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f8fafc' }}>
      <span style={{ fontSize:12, color:'#374151', fontWeight:500 }}>{label}</span>
      <div style={{ display:'flex', alignItems:'center', gap:8 }}>
        <input type="color" value={theme[key] || '#000000'} onChange={e => set(key, e.target.value)}
          style={{ width:32, height:32, border:'1.5px solid #e2e8f0', borderRadius:6, cursor:'pointer', padding:2 }} />
        <span style={{ fontSize:10, fontFamily:'DM Mono, monospace', color:'#64748b', width:60 }}>{theme[key]}</span>
      </div>
    </div>
  );

  const selectRow = (label, key, options) => (
    <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f8fafc', gap:8 }}>
      <span style={{ fontSize:12, color:'#374151', fontWeight:500, flexShrink:0 }}>{label}</span>
      <select value={theme[key] || ''} onChange={e => set(key, e.target.value)}
        style={{ padding:'4px 8px', border:'1.5px solid #e2e8f0', borderRadius:6, fontSize:12, fontFamily:'DM Sans, sans-serif', color:'#0f1923', background:'#fff', maxWidth:180 }}>
        {(options || []).map(o => typeof o === 'string'
          ? <option key={o} value={o}>{o}</option>
          : <option key={o.value} value={o.value}>{o.label}</option>
        )}
      </select>
    </div>
  );

  const textRow = (label, key, placeholder='') => (
    <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f8fafc', gap:8 }}>
      <span style={{ fontSize:12, color:'#374151', fontWeight:500, flexShrink:0 }}>{label}</span>
      <input value={theme[key] || ''} onChange={e => set(key, e.target.value)} placeholder={placeholder}
        style={{ padding:'4px 8px', border:'1.5px solid #e2e8f0', borderRadius:6, fontSize:12, fontFamily:'DM Sans, sans-serif', color:'#0f1923', width:160, outline:'none' }} />
    </div>
  );

  return (
    <div style={{ padding:'16px 20px' }}>
      <div style={{ fontSize:13, fontWeight:700, color:'#0f1923', marginBottom:16, paddingBottom:10, borderBottom:'2px solid #f1f5f9' }}>
        🎨 Theme Settings
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:'0 40px' }}>
        <div>
          <div style={{ fontSize:10, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.07em', marginBottom:8 }}>Colors</div>
          {colorRow('Nav Background', 'nav_bg')}
          {colorRow('Nav Text',       'nav_color')}
          {colorRow('Primary Color',  'primary')}
          {colorRow('Accent Color',   'accent')}
          {colorRow('Card Background','card_bg')}
          {colorRow('Page Background','page_bg')}
        </div>
        <div>
          <div style={{ fontSize:10, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.07em', marginBottom:8 }}>Typography</div>
          {selectRow('Font Family',   'font',          GOOGLE_FONTS)}
          {selectRow('Font Size',     'font_size',     FONT_SIZES)}
          {selectRow('Border Radius', 'border_radius', BORDER_RADII)}
          {selectRow('Padding',       'density',       PADDINGS)}
          <div style={{ fontSize:10, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.07em', marginTop:16, marginBottom:8 }}>Branding</div>
          {textRow('Logo Text', 'logo_text', 'MyApp')}
          {textRow('Logo URL',  'logo_url',  'https://...')}
          <div style={{ fontSize:10, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.07em', marginTop:16, marginBottom:8 }}>Object Labels</div>
          {selectRow('Label Size', 'label_size', [
            { value:'9px',  label:'9px — Tiny'   },
            { value:'10px', label:'10px — Small (default)' },
            { value:'11px', label:'11px — Medium' },
            { value:'12px', label:'12px — Large'  },
            { value:'13px', label:'13px — X-Large'},
          ])}
          {colorRow('Label Color', 'label_color')}
        </div>
      </div>

      {/* Live preview */}
      <div style={{ marginTop:20, borderRadius:10, overflow:'hidden', border:'1px solid #e2e8f0' }}>
        <div style={{ background: theme.nav_bg||'#0f1923', padding:'10px 16px', display:'flex', alignItems:'center', gap:10 }}>
          <span style={{ color: theme.nav_color||'#fff', fontSize:13, fontWeight:700 }}>{theme.logo_text||'MyApp'}</span>
          <span style={{ color: theme.nav_color||'#fff', fontSize:12, opacity:0.6, marginLeft:'auto' }}>Nav Item</span>
        </div>
        <div style={{ background: theme.page_bg||'#f5f3ff', padding:16, display:'flex', gap:10 }}>
          <div style={{ background: theme.card_bg||'#fff', borderRadius: (theme.border_radius||8)+'px', padding:14, flex:1, border:'1px solid #e2e8f0', fontFamily: theme.font||'inherit', fontSize: (theme.font_size||14)+'px', color:'#374151' }}>
            <div style={{ fontWeight:700, marginBottom:6 }}>Sample Card</div>
            <div style={{ fontSize: theme.label_size||'10px', color: theme.label_color||'#64748b', fontWeight:700, textTransform:'uppercase', letterSpacing:'0.07em', marginBottom:3 }}>FIELD LABEL</div>
            <div style={{ height:28, background:'#f8fafc', border:'1px solid #e2e8f0', borderRadius:4, marginBottom:8 }} />
            <button style={{ marginTop:2, padding:'6px 14px', background: theme.primary||'#7c3aed', color:'#fff', border:'none', borderRadius: (theme.border_radius||8)+'px', fontSize:12, cursor:'pointer' }}>Button</button>
          </div>
          <div style={{ background: theme.card_bg||'#fff', borderRadius: (theme.border_radius||8)+'px', padding:14, flex:1, border:'1px solid #e2e8f0', fontFamily: theme.font||'inherit', fontSize: (theme.font_size||14)+'px' }}>
            <div style={{ fontWeight:700, marginBottom:6, color:'#374151' }}>Another Card</div>
            <div style={{ color: theme.accent||'#f59e0b', fontSize:12, fontWeight:600 }}>Accent text</div>
          </div>
        </div>
      </div>
    </div>
  );
}

