/* global React, ReactDOM, RETAILERS, DEALS, SM_Components,
   useTweaks, TweaksPanel, TweakSection, TweakRadio, TweakToggle, TweakColor */

const { useState, useEffect, useMemo, useRef } = window.React;
const { IconSearch, IconChevron, IconBookmark, IconShare, IconBarcode, IconBell, IconArrow, IconLightning, SparkStar, Star, StarLogo, Thumb, Sparkline, LivePulse, Sidebar } = SM_Components;

// ─── Retailer tab strip ─────────────────────────────────────────────────────
const RetailerTabs = ({ active, onChange }) => (
  <div className="sm-retailer-tabs" style={{
    display: 'flex', gap: 4, alignItems: 'center', padding: '12px 24px 0',
    borderBottom: '1px solid var(--border)', overflowX: 'auto',
  }}>
    {RETAILERS.map(r => {
      const isActive = r.id === active;
      return (
        <button
          key={r.id}
          onClick={r.soon ? undefined : () => onChange(r.id)}
          disabled={r.soon}
          aria-disabled={r.soon ? 'true' : undefined}
          title={r.soon ? `${r.name} integration is coming soon` : undefined}
          className={`sm-tab ${isActive ? 'sm-tab-active' : ''}`}
          style={r.soon ? { opacity: 0.62, cursor: 'not-allowed' } : undefined}>
          <span style={{
            width: 6, height: 6, borderRadius: 2, background: r.color, opacity: isActive ? 1 : 0.55,
            boxShadow: isActive ? `0 0 0 2px ${r.color}33` : 'none',
          }}/>
          {r.name}
          {r.soon ? (
            <span style={{
              marginLeft: 6, padding: '2px 5px', borderRadius: 4,
              background: 'rgba(194,167,83,0.12)', border: '1px solid rgba(194,167,83,0.35)',
              color: 'var(--gold)', fontFamily: 'var(--mono)', fontSize: 9, fontWeight: 600,
              letterSpacing: '0.10em', textTransform: 'uppercase', lineHeight: 1,
            }}>Soon</span>
          ) : (
            <span style={{
              fontFamily: 'var(--mono)', fontSize: 10, color: isActive ? 'var(--gold)' : 'var(--muted)',
              marginLeft: 4,
            }}>{(r.count/1000).toFixed(0)}k</span>
          )}
        </button>
      );
    })}
    <div style={{ flex: 1 }}/>
    <div className="sm-tertiary-links" style={{ display: 'flex', alignItems: 'center', gap: 16, paddingLeft: 16, marginLeft: 8, borderLeft: '1px solid var(--border)', height: 24 }}>
      <a className="sm-link" href="#">App guide</a>
      <a className="sm-link" href="#">API <span style={{ opacity: 0.6 }}>↗</span></a>
      <a className="sm-link" href="#">FAQ</a>
    </div>
  </div>
);

// ─── Search bar + sort row ──────────────────────────────────────────────────
const SearchBar = ({ retailer, query, onQuery, sort, onSort, onOpenFilters }) => {
  const r = RETAILERS.find(x => x.id === retailer);
  return (
    <div className="sm-search-row" style={{ display: 'flex', gap: 12, padding: '18px 24px 12px', alignItems: 'center' }}>
      <button
        className="sm-btn sm-btn-ghost sm-filter-btn"
        onClick={onOpenFilters}
        style={{ display: 'none', width: 'auto', padding: '0 12px', flexShrink: 0 }}
        aria-label="Open filters">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
          <path d="M3 5h18M6 12h12M10 19h4"/>
        </svg>
      </button>
      <div className="sm-search" style={{ flex: 1, minWidth: 0 }}>
        <IconSearch/>
        <input placeholder={`Search ${r?.name || ''} deals — SKU, brand, keyword…`}
               value={query} onChange={(e) => onQuery(e.target.value)}/>
        <span className="sm-kbd">⌘K</span>
      </div>
      <button className="sm-btn sm-btn-ghost sm-sort-btn" style={{ width: 'auto', padding: '0 14px' }}>
        Sort: <span style={{ color: 'var(--gold)' }}>{sort}</span> <IconChevron/>
      </button>
      <button className="sm-btn sm-btn-ghost sm-refresh-btn" style={{ width: 'auto', padding: '0 14px' }}>
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/>
          <path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/>
        </svg> Refresh
      </button>
    </div>
  );
};

// ─── Page header (title + summary line) ─────────────────────────────────────
const PageHeader = ({ retailer, shown, total }) => {
  const r = RETAILERS.find(x => x.id === retailer);
  return (
    <div className="sm-page-header" style={{ padding: '0 24px 14px', display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 24 }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        <h1 style={{ fontSize: 22, fontWeight: 600, letterSpacing: '-0.015em', margin: 0 }}>
          {r?.name} Clearance Deals
        </h1>
        <div style={{ fontSize: 12.5, color: 'var(--muted)', fontFamily: 'var(--mono)' }}>
          Showing <span style={{ color: 'var(--fg)' }}>{shown}</span> of <span style={{ color: 'var(--fg)' }}>{total.toLocaleString()}</span> active deals · refreshed 4s ago
        </div>
      </div>
      <div className="sm-disclaimer" style={{ fontSize: 11, color: 'var(--muted)', maxWidth: 360, textAlign: 'right', lineHeight: 1.5 }}>
        Star Monitors may earn a referral fee on purchases.&nbsp;
        <a style={{ color: 'var(--gold)' }}>How it works</a>
      </div>
    </div>
  );
};

// ─── Deal row ───────────────────────────────────────────────────────────────
const DealRow = ({ deal, index, t, saved, onSave, onBarcode, onShare, copied }) => {
  const r = useRef(null);
  const dStr = t.density;
  const thumbSize = dStr === 'compact' ? 56 : dStr === 'comfy' ? 84 : 72;
  const padY = dStr === 'compact' ? 10 : dStr === 'comfy' ? 18 : 14;

  return (
    <div ref={r} className="sm-row sm-deal-row" style={{
      display: 'grid',
      gridTemplateColumns: `${thumbSize + 24}px 1fr 110px 140px 100px 100px 120px`,
      alignItems: 'center', gap: 12, padding: `${padY}px 24px`,
      borderBottom: '1px solid var(--border)',
    }}>
      {/* Image */}
      <div className="sm-deal-thumb" style={{ position: 'relative' }}>
        <Thumb cat={deal.cat} sku={deal.sku} size={thumbSize} img={deal.img}/>
        {deal.hot && t.showHotBadges && (
          <span style={{
            position: 'absolute', top: -6, left: -6, padding: '3px 6px 3px 5px',
            background: '#c2a753', color: '#0d0c0c', fontSize: 9, fontWeight: 700,
            letterSpacing: '0.08em', borderRadius: 4, display: 'inline-flex', alignItems: 'center', gap: 3,
            fontFamily: 'var(--mono)', textTransform: 'uppercase',
          }}>
            <IconLightning size={9}/> HOT
          </span>
        )}
      </div>

      {/* Product name & meta */}
      <div className="sm-deal-body" style={{ display: 'flex', flexDirection: 'column', gap: 4, minWidth: 0 }}>
        <div style={{ fontSize: 13, lineHeight: 1.4, fontWeight: 500, color: 'var(--fg)', textWrap: 'pretty' }}>
          {deal.name}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 10.5, color: 'var(--muted)', fontFamily: 'var(--mono)', flexWrap: 'wrap' }}>
          <span style={{ color: 'var(--gold)' }}>{deal.cat}</span>
          <span>·</span>
          <span>SKU {deal.sku}</span>
          <span>·</span>
          <span>UPC {deal.upc}</span>
        </div>
      </div>

      {/* Price */}
      <div className="sm-deal-price" style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
        <span style={{ fontFamily: t.monoNumerics ? 'var(--mono)' : 'inherit', fontSize: 16, fontWeight: 600, color: 'var(--fg)' }}>
          {deal.now}
        </span>
        <span style={{ fontFamily: t.monoNumerics ? 'var(--mono)' : 'inherit', fontSize: 11, color: 'var(--muted)', textDecoration: 'line-through' }}>
          {deal.was}
        </span>
      </div>

      {/* Discount + sparkline */}
      <div className="sm-deal-disc" style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <span style={{
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          minWidth: 46, padding: '4px 10px', borderRadius: 999,
          background: deal.discount >= 60 ? 'rgba(194,167,83,0.22)' : 'rgba(194,167,83,0.10)',
          border: `1px solid ${deal.discount >= 60 ? 'rgba(194,167,83,0.55)' : 'rgba(194,167,83,0.30)'}`,
          color: 'var(--gold)', fontSize: 11.5, fontWeight: 600, fontFamily: 'var(--mono)',
        }}>−{deal.discount}%</span>
        {t.showSparklines && <Sparkline data={deal.sparkline} color="var(--gold-spark)"/>}
      </div>

      {/* Added */}
      <div className="sm-deal-added" style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
        <span style={{ fontSize: 12.5, color: 'var(--fg)', fontFamily: 'var(--mono)' }}>{deal.added}</span>
        <span style={{ fontSize: 10, color: 'var(--muted)', fontFamily: 'var(--mono)' }}>first seen</span>
      </div>

      {/* Locations */}
      <div className="sm-deal-stores" style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
        <span style={{ fontSize: 13, color: 'var(--fg)', fontFamily: 'var(--mono)' }}>
          {deal.stores} <span style={{ color: 'var(--muted)' }}>{deal.stores === 1 ? 'store' : 'stores'}</span>
        </span>
        <a style={{ fontSize: 10.5, color: 'var(--blue)', fontFamily: 'var(--mono)', cursor: 'default' }}>
          View map ↗
        </a>
      </div>

      {/* Actions */}
      <div className="sm-deal-actions" style={{ display: 'flex', flexDirection: 'row', gap: 6 }}>
        <button className="sm-btn sm-btn-line" onClick={() => onShare(deal.sku)} title="Share link">
          {copied === deal.sku ? <>✓</> : <IconShare size={12}/>}
        </button>
        <button className="sm-btn sm-btn-line" onClick={() => onBarcode(deal)} title="Reveal barcode">
          <IconBarcode size={12}/>
        </button>
        <button className="sm-btn sm-btn-line" onClick={() => {}} title="Save deal" style={{ color: saved ? 'var(--gold)' : 'inherit', borderColor: saved ? 'rgba(194,167,83,0.45)' : 'var(--border-strong)' }}>
          <IconBookmark size={12} filled={saved}/>
        </button>
      </div>
    </div>
  );
};

// ─── Column headers ─────────────────────────────────────────────────────────
const ColumnHeaders = ({ t }) => {
  const dStr = t.density;
  const thumbSize = dStr === 'compact' ? 56 : dStr === 'comfy' ? 84 : 72;
  const Cell = ({ children, sortable, active }) => (
    <span style={{
      display: 'flex', alignItems: 'center', gap: 4, fontSize: 9.5, color: active ? 'var(--gold)' : 'var(--muted)',
      letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'var(--mono)', fontWeight: 600,
    }}>
      {children}
      {sortable && <span style={{ opacity: active ? 1 : 0.5 }}>{active ? '▼' : '↕'}</span>}
    </span>
  );
  return (
    <div className="sm-col-headers" style={{
      display: 'grid',
      gridTemplateColumns: `${thumbSize + 24}px 1fr 110px 140px 100px 100px 120px`,
      gap: 12, padding: '10px 24px', borderBottom: '1px solid var(--border)',
      background: 'var(--panel-elev)',
    }}>
      <Cell>Image</Cell>
      <Cell>Product</Cell>
      <Cell sortable>Price</Cell>
      <Cell sortable>Discount · Trend</Cell>
      <Cell sortable active>Added</Cell>
      <Cell sortable>Locations</Cell>
      <Cell>Action</Cell>
    </div>
  );
};

// ─── Barcode modal ──────────────────────────────────────────────────────────
const BarcodeModal = ({ deal, onClose }) => {
  if (!deal) return null;
  // Generate a deterministic bar pattern from the SKU
  const seed = parseInt(deal.sku, 10) || 0;
  const bars = useMemo(() => {
    const arr = []; let s = seed;
    for (let i = 0; i < 70; i++) { s = (s * 1103515245 + 12345) & 0x7fffffff; arr.push((s % 4) + 1); }
    return arr;
  }, [seed]);
  return (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.7)', backdropFilter: 'blur(6px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 100,
      animation: 'sm-fade-in 0.18s ease-out',
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: 460, maxWidth: 'calc(100vw - 32px)',
        background: 'var(--panel-elev)', border: '1px solid var(--border)',
        borderRadius: 14, padding: '24px 24px 20px', display: 'flex', flexDirection: 'column', gap: 16,
        boxShadow: '0 24px 80px rgba(0,0,0,0.6)',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <SparkStar size={11} color="#c2a753"/>
            <span style={{ fontSize: 11, color: 'var(--gold)', letterSpacing: '0.14em', textTransform: 'uppercase', fontFamily: 'var(--mono)' }}>
              In-store barcode
            </span>
          </div>
          <button onClick={onClose} className="sm-btn sm-btn-ghost" style={{ width: 24, height: 24, padding: 0 }}>×</button>
        </div>
        <div style={{ fontSize: 13, lineHeight: 1.4, color: 'var(--fg)' }}>{deal.name}</div>
        <div style={{
          padding: '22px 18px 14px', background: '#f4f0e6', borderRadius: 8,
          display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
        }}>
          <svg width="100%" height="60" viewBox="0 0 420 60" preserveAspectRatio="none">
            {(() => {
              let x = 0; const els = [];
              bars.forEach((w, i) => {
                if (i % 2 === 0) els.push(<rect key={i} x={x} y="0" width={w*1.5} height="60" fill="#0d0c0c"/>);
                x += w * 1.5 + 1;
              });
              return els;
            })()}
          </svg>
          <div style={{ fontFamily: 'var(--mono)', fontSize: 12, letterSpacing: '0.18em', color: '#0d0c0c' }}>
            {deal.sku.padStart(12, '0').match(/.{1,4}/g).join('  ')}
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="sm-btn sm-btn-primary" style={{ flex: 1 }}><IconShare size={11}/> Share to Discord</button>
          <button className="sm-btn sm-btn-ghost" style={{ flex: 1 }}><IconBookmark size={11}/> Save deal</button>
        </div>
        <div style={{ fontSize: 10.5, color: 'var(--muted)', fontFamily: 'var(--mono)', textAlign: 'center' }}>
          Show at register · location-specific pricing may vary
        </div>
      </div>
    </div>
  );
};

// ─── Coming-soon placeholder for retailers not yet wired up ────────────────
const ComingSoonPanel = ({ retailer }) => {
  const r = RETAILERS.find(x => x.id === retailer);
  if (!r) return null;
  return (
    <div className="sm-coming-soon" style={{
      flex: 1, minHeight: 0,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: '40px 24px',
    }}>
      <div style={{
        maxWidth: 460, width: '100%', display: 'flex', flexDirection: 'column',
        alignItems: 'center', textAlign: 'center', gap: 14,
        padding: '36px 28px',
        background: 'var(--panel-elev)', border: '1px solid var(--border)',
        borderRadius: 14,
        boxShadow: '0 1px 0 rgba(255,255,255,0.02) inset, 0 12px 40px rgba(0,0,0,0.25)',
      }}>
        {/* Retailer dot ring */}
        <div style={{
          width: 56, height: 56, borderRadius: '50%', position: 'relative',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          background: 'rgba(255,255,255,0.02)',
          border: `1px solid ${r.color}55`,
        }}>
          <span style={{ width: 14, height: 14, borderRadius: 4, background: r.color, display: 'block' }}/>
          <span style={{
            position: 'absolute', inset: -6, borderRadius: '50%',
            border: `1px dashed ${r.color}44`,
          }}/>
        </div>

        <div style={{
          display: 'inline-flex', alignItems: 'center', gap: 8,
          padding: '4px 10px', borderRadius: 999,
          background: 'rgba(194,167,83,0.10)', border: '1px solid rgba(194,167,83,0.35)',
        }}>
          <SparkStar size={10} color="var(--gold)"/>
          <span style={{
            fontFamily: 'var(--mono)', fontSize: 10, fontWeight: 600,
            letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--gold)',
          }}>Coming soon</span>
        </div>

        <h2 style={{
          margin: 0, fontSize: 22, fontWeight: 600, letterSpacing: '-0.01em', color: 'var(--fg)',
        }}>{r.name} integration is on the way</h2>

        <p style={{
          margin: 0, fontSize: 13.5, lineHeight: 1.55, color: 'var(--muted)',
        }}>
          We're wiring up {r.name}'s in-store inventory and clearance feeds. Home Depot and Lowe's
          are live now — flip to either tab to start sourcing while we finish this one.
        </p>

        <div style={{ display: 'flex', gap: 8, marginTop: 6, width: '100%', maxWidth: 360 }}>
          <button className="sm-btn sm-btn-primary" style={{ flex: 1 }}>
            <IconBell size={11}/> Notify me when live
          </button>
          <a href="https://discord.gg/NGc2eaUPBp" className="sm-btn sm-btn-ghost" style={{
            flex: 1, textDecoration: 'none',
          }}>Join Discord</a>
        </div>

        <div style={{
          marginTop: 8, fontFamily: 'var(--mono)', fontSize: 10.5, color: 'var(--muted-2)',
          letterSpacing: '0.06em',
        }}>
          Tracker eta · rolling out over the next few weeks
        </div>
      </div>
    </div>
  );
};

// ─── Ticker (live drops) ────────────────────────────────────────────────────
const Ticker = ({ className }) => {
  const items = [
    'WMT · NIKE Pegasus 40 → $42 (−58%)',
    'HD · DEWALT DCD777 → $89 (−47%)',
    'LOW · Kobalt 80V Trimmer → $129 (−40%)',
    'TGT · Instant Pot Duo 6Q → $39.98 (−56%)',
    'WGN · Olay Regenerist → $14.99 (−40%)',
    'CST · Kirkland Cashews 2.5lb → $14.49 (−37%)',
    'HD · Milwaukee M18 Combo → $199 (−54%)',
  ];
  return (
    <div className={`sm-ticker ${className || ''}`} style={{
      display: 'flex', alignItems: 'center', gap: 12, padding: '8px 24px',
      borderTop: '1px solid var(--border)', background: 'var(--panel)',
      fontSize: 11, color: 'var(--muted)', fontFamily: 'var(--mono)',
      overflow: 'hidden', whiteSpace: 'nowrap', height: 32,
    }}>
      <span style={{ color: 'var(--gold)', letterSpacing: '0.14em', textTransform: 'uppercase', flexShrink: 0 }}>
        <SparkStar size={9}/> Latest drops
      </span>
      <div style={{ flex: 1, overflow: 'hidden', position: 'relative' }}>
        <div style={{ display: 'inline-flex', gap: 28, animation: 'sm-ticker 60s linear infinite' }}>
          {[...items, ...items].map((s, i) => (
            <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
              <span style={{ color: 'var(--blue-light)' }}>●</span>
              <span>{s}</span>
            </span>
          ))}
        </div>
      </div>
    </div>
  );
};

// ─── Main App ───────────────────────────────────────────────────────────────
const App = () => {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [retailer, setRetailer] = useState('homedepot');
  const [query, setQuery] = useState('');
  const [sort, setSort] = useState('Added ▼');
  const [saved, setSaved] = useState(new Set());
  const [barcodeDeal, setBarcodeDeal] = useState(null);
  const [copied, setCopied] = useState(null);
  const [filters, setFilters] = useState({
    inStock: true, clearance: true, priceDrop: false, restock: false, multi: false,
  });
  const [drawerOpen, setDrawerOpen] = useState(false);

  // Lock body scroll while the mobile drawer is open
  useEffect(() => {
    if (drawerOpen) {
      const prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => { document.body.style.overflow = prev; };
    }
  }, [drawerOpen]);

  // Apply accent token
  useEffect(() => {
    document.documentElement.style.setProperty('--gold', t.accent);
    document.documentElement.style.setProperty('--gold-spark', t.accent);
  }, [t.accent]);

  const filtered = useMemo(() => {
    return DEALS.filter(d => {
      if (filters.multi && d.stores < 3) return false;
      if (query && !d.name.toLowerCase().includes(query.toLowerCase()) && !d.cat.toLowerCase().includes(query.toLowerCase())) return false;
      return true;
    });
  }, [query, filters]);

  const toggleSave = (sku) => {
    const next = new Set(saved);
    if (next.has(sku)) next.delete(sku); else next.add(sku);
    setSaved(next);
  };
  const handleShare = (sku) => {
    setCopied(sku);
    setTimeout(() => setCopied(null), 1400);
  };

  const r = RETAILERS.find(x => x.id === retailer);

  return (
    <div className="sm-app" style={{ display: 'flex', height: '100vh', minHeight: 0, overflowX: 'auto', overflowY: 'hidden', background: 'var(--bg)' }}>
      <Sidebar t={t} retailer={retailer} filters={filters} setFilters={setFilters} savedCount={saved.size}
               drawerOpen={drawerOpen} onCloseDrawer={() => setDrawerOpen(false)}/>

      <main className="sm-main" style={{ flex: 1, minWidth: 1080, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
        <RetailerTabs active={retailer} onChange={setRetailer}/>
        <SearchBar retailer={retailer} query={query} onQuery={setQuery} sort={sort} onSort={setSort}
                   onOpenFilters={() => setDrawerOpen(true)}/>
        {r?.soon ? (
          <ComingSoonPanel retailer={retailer}/>
        ) : (
          <React.Fragment>
            <PageHeader retailer={retailer} shown={filtered.length} total={r?.count || 0}/>
            <ColumnHeaders t={t}/>
            <div style={{ flex: 1, overflowY: 'auto', overflowX: 'hidden' }}>
              {filtered.map((d, i) => (
                <DealRow key={d.sku} deal={d} index={i} t={t} saved={saved.has(d.sku)} onSave={toggleSave}
                         onBarcode={setBarcodeDeal} onShare={handleShare} copied={copied}/>
              ))}
              {filtered.length === 0 && (
                <div style={{ padding: 60, textAlign: 'center', color: 'var(--muted)', fontSize: 13 }}>
                  No deals match. Loosen the filters or clear the search.
                </div>
              )}
            </div>
          </React.Fragment>
        )}
        <Ticker/>
      </main>

      <BarcodeModal deal={barcodeDeal} onClose={() => setBarcodeDeal(null)}/>

      <TweaksPanel>
        <TweakSection label="Theme"/>
        <TweakColor label="Accent" value={t.accent}
          options={['#c2a753', '#e0b956', '#5fb87c', '#7aa8d4', '#c97a5f']}
          onChange={(v) => setTweak('accent', v)}/>
        <TweakSection label="Layout"/>
        <TweakRadio label="Density" value={t.density}
          options={['compact', 'regular', 'comfy']}
          onChange={(v) => setTweak('density', v)}/>
        <TweakSection label="Display"/>
        <TweakToggle label="Sparklines" value={t.showSparklines}
          onChange={(v) => setTweak('showSparklines', v)}/>
        <TweakToggle label="Hot badges" value={t.showHotBadges}
          onChange={(v) => setTweak('showHotBadges', v)}/>
        <TweakToggle label="Monospaced numerics" value={t.monoNumerics}
          onChange={(v) => setTweak('monoNumerics', v)}/>
      </TweaksPanel>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
