// Stocks page — Sector clouds with ticker chips + index summary
// StocksPage & WatchlistPage both live here

// ── Watchlist storage ─────────────────────────────────────────────────────────
const WL_KEY = 'jastocks-watchlist';
function loadWatchlist() {
  try { return JSON.parse(localStorage.getItem(WL_KEY) || '[]'); } catch { return []; }
}
function saveWatchlist(list) { localStorage.setItem(WL_KEY, JSON.stringify(list)); }

// ── Portfolio storage (re-use existing key) ───────────────────────────────────
const PF_KEY = 'jastocks-manual-portfolio';
function loadPortfolio() {
  try { return JSON.parse(localStorage.getItem(PF_KEY) || '[]'); } catch { return []; }
}
function savePortfolio(list) { localStorage.setItem(PF_KEY, JSON.stringify(list)); }

// ── Sector colour map (matches api.js SECTOR_COLORS) ─────────────────────────
const SECTOR_PALETTE = {
  'Financials':    { bg: 'oklch(0.72 0.14 240 / 0.13)', border: 'oklch(0.72 0.14 240 / 0.35)', text: 'oklch(0.82 0.14 240)', header: 'oklch(0.72 0.14 240)' },
  'Consumer':      { bg: 'oklch(0.75 0.14 145 / 0.13)', border: 'oklch(0.75 0.14 145 / 0.35)', text: 'oklch(0.85 0.14 145)', header: 'oklch(0.75 0.14 145)' },
  'Conglomerate':  { bg: 'oklch(0.75 0.16 290 / 0.13)', border: 'oklch(0.75 0.16 290 / 0.35)', text: 'oklch(0.85 0.16 290)', header: 'oklch(0.75 0.16 290)' },
  'Insurance':     { bg: 'oklch(0.78 0.14 200 / 0.13)', border: 'oklch(0.78 0.14 200 / 0.35)', text: 'oklch(0.88 0.14 200)', header: 'oklch(0.78 0.14 200)' },
  'Real Estate':   { bg: 'oklch(0.75 0.15 75  / 0.13)', border: 'oklch(0.75 0.15 75  / 0.35)', text: 'oklch(0.85 0.15 75)',  header: 'oklch(0.75 0.15 75)'  },
  'Utilities':     { bg: 'oklch(0.75 0.14 30  / 0.13)', border: 'oklch(0.75 0.14 30  / 0.35)', text: 'oklch(0.85 0.14 30)',  header: 'oklch(0.75 0.14 30)'  },
  'Industrial':    { bg: 'oklch(0.75 0.12 60  / 0.13)', border: 'oklch(0.75 0.12 60  / 0.35)', text: 'oklch(0.85 0.12 60)',  header: 'oklch(0.75 0.12 60)'  },
  'Logistics':     { bg: 'oklch(0.78 0.14 320 / 0.13)', border: 'oklch(0.78 0.14 320 / 0.35)', text: 'oklch(0.88 0.14 320)', header: 'oklch(0.78 0.14 320)' },
  'Retail':        { bg: 'oklch(0.75 0.14 170 / 0.13)', border: 'oklch(0.75 0.14 170 / 0.35)', text: 'oklch(0.85 0.14 170)', header: 'oklch(0.75 0.14 170)' },
  'Technology':    { bg: 'oklch(0.75 0.16 260 / 0.13)', border: 'oklch(0.75 0.16 260 / 0.35)', text: 'oklch(0.85 0.16 260)', header: 'oklch(0.75 0.16 260)' },
  'Media':         { bg: 'oklch(0.78 0.13 350 / 0.13)', border: 'oklch(0.78 0.13 350 / 0.35)', text: 'oklch(0.88 0.13 350)', header: 'oklch(0.78 0.13 350)' },
  'Healthcare':    { bg: 'oklch(0.75 0.14 155 / 0.13)', border: 'oklch(0.75 0.14 155 / 0.35)', text: 'oklch(0.85 0.14 155)', header: 'oklch(0.75 0.14 155)' },
  'Education':     { bg: 'oklch(0.78 0.13 45  / 0.13)', border: 'oklch(0.78 0.13 45  / 0.35)', text: 'oklch(0.88 0.13 45)',  header: 'oklch(0.78 0.13 45)'  },
  'Gaming':        { bg: 'oklch(0.75 0.16 310 / 0.13)', border: 'oklch(0.75 0.16 310 / 0.35)', text: 'oklch(0.85 0.16 310)', header: 'oklch(0.75 0.16 310)' },
  'Entertainment': { bg: 'oklch(0.75 0.14 280 / 0.13)', border: 'oklch(0.75 0.14 280 / 0.35)', text: 'oklch(0.85 0.14 280)', header: 'oklch(0.75 0.14 280)' },
  'Infrastructure':{ bg: 'oklch(0.78 0.12 90  / 0.13)', border: 'oklch(0.78 0.12 90  / 0.35)', text: 'oklch(0.88 0.12 90)',  header: 'oklch(0.78 0.12 90)'  },
  'Other':         { bg: 'oklch(0.6  0.04 240 / 0.10)', border: 'oklch(0.6  0.04 240 / 0.25)', text: 'oklch(0.75 0.04 240)', header: 'oklch(0.6 0.04 240)'  },
};
function sectorPalette(s) { return SECTOR_PALETTE[s] || SECTOR_PALETTE['Other']; }

// ── Index bar — computed from live stock data ─────────────────────────────────
const IndexBar = ({ stocks }) => {
  const main   = stocks.filter(s => s.market === 'Main');
  const junior = stocks.filter(s => s.market === 'Junior');

  function mktStats(arr) {
    const advancers = arr.filter(s => s.change > 0).length;
    const decliners = arr.filter(s => s.change < 0).length;
    const unchanged = arr.filter(s => s.change === 0).length;
    // Weighted average % change by price (proxy for index move)
    const totalPrice = arr.reduce((s, x) => s + x.price, 0);
    const wavg = totalPrice > 0
      ? arr.reduce((s, x) => s + x.changePct * (x.price / totalPrice), 0)
      : 0;
    return { advancers, decliners, unchanged, wavg, total: arr.length };
  }

  const ms = mktStats(main);
  const js = mktStats(junior);

  const Stat = ({ label, stat }) => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '12px 20px', borderRight: '1px solid var(--border)' }}>
      <div>
        <div style={{ fontSize: 11, color: 'var(--text-3)', fontWeight: 500, marginBottom: 3, letterSpacing: '0.04em', textTransform: 'uppercase' }}>{label}</div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{
            fontSize: 18, fontWeight: 700, fontFamily: 'Geist Mono, monospace',
            color: stat.wavg > 0 ? 'var(--up)' : stat.wavg < 0 ? 'var(--down)' : 'var(--text-2)',
          }}>
            {stat.wavg >= 0 ? '+' : ''}{stat.wavg.toFixed(2)}%
          </span>
          <span style={{ fontSize: 11, color: 'var(--text-3)' }}>avg move · {stat.total} stocks</span>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 10, fontSize: 11, fontFamily: 'Geist Mono, monospace' }}>
        <span style={{ color: 'var(--up)' }}>▲ {stat.advancers}</span>
        <span style={{ color: 'var(--down)' }}>▼ {stat.decliners}</span>
        <span style={{ color: 'var(--text-3)' }}>— {stat.unchanged}</span>
      </div>
    </div>
  );

  return (
    <div className="card mb-4" style={{ display: 'flex', flexWrap: 'wrap', padding: 0, overflow: 'hidden' }}>
      <Stat label="JSE Main Market" stat={ms} />
      <Stat label="JSE Junior Market" stat={js} />
      <div style={{ padding: '12px 20px', display: 'flex', alignItems: 'center' }}>
        <div style={{ fontSize: 11, color: 'var(--text-3)' }}>
          Index moves are weighted-average price change across all listed stocks.<br/>
          <span style={{ opacity: 0.7 }}>Data from Stacks JSE API · refreshes every 90s</span>
        </div>
      </div>
    </div>
  );
};

// ── Ticker chip ───────────────────────────────────────────────────────────────
const TickerChip = ({ stock, palette, inPortfolio, inWatchlist, onAdd, onWatch, goTo }) => {
  const [hover, setHover] = React.useState(false);
  const up   = stock.changePct > 0;
  const down = stock.changePct < 0;

  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        position: 'relative',
        display: 'inline-flex', alignItems: 'center', gap: 0,
        borderRadius: 8,
        border: `1px solid ${hover ? palette.border : 'var(--border)'}`,
        background: hover ? palette.bg : 'var(--bg-2)',
        transition: 'all 0.15s',
        overflow: 'hidden',
        cursor: 'default',
      }}
    >
      {/* Ticker button */}
      <button
        onClick={() => goTo && goTo('stock', stock.sym)}
        style={{
          display: 'flex', flexDirection: 'column', alignItems: 'flex-start',
          padding: '7px 10px', background: 'none', border: 'none', cursor: 'pointer',
          minWidth: 64,
        }}
      >
        <span style={{
          fontSize: 12, fontWeight: 700, fontFamily: 'Geist Mono, monospace',
          color: hover ? palette.text : 'var(--text)',
          letterSpacing: '0.03em',
        }}>
          {stock.sym}
        </span>
        <span style={{
          fontSize: 10, fontFamily: 'Geist Mono, monospace', marginTop: 2,
          color: up ? 'var(--up)' : down ? 'var(--down)' : 'var(--text-3)',
        }}>
          {up ? '+' : ''}{stock.changePct.toFixed(2)}%
        </span>
      </button>

      {/* + Add to portfolio button */}
      <button
        title={inPortfolio ? 'In portfolio' : 'Add to portfolio'}
        onClick={(e) => { e.stopPropagation(); onAdd(stock); }}
        style={{
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          width: 26, height: '100%', minHeight: 40,
          background: inPortfolio ? 'var(--accent-dim)' : 'none',
          border: 'none', borderLeft: '1px solid var(--border)',
          cursor: 'pointer',
          color: inPortfolio ? 'var(--accent)' : 'var(--text-3)',
          fontSize: 14, fontWeight: 700,
          transition: 'all 0.12s',
          padding: 0,
        }}
        onMouseEnter={e => { if (!inPortfolio) e.currentTarget.style.color = 'var(--accent)'; }}
        onMouseLeave={e => { if (!inPortfolio) e.currentTarget.style.color = 'var(--text-3)'; }}
      >
        {inPortfolio ? '✓' : '+'}
      </button>
    </div>
  );
};

// ── Sector cloud card ─────────────────────────────────────────────────────────
const SectorCloud = ({ sector, stocks, portfolio, watchlist, onAdd, goTo }) => {
  const pal = sectorPalette(sector);
  const sorted = [...stocks].sort((a, b) => Math.abs(b.changePct) - Math.abs(a.changePct));
  const advancers = stocks.filter(s => s.changePct > 0).length;
  const decliners = stocks.filter(s => s.changePct < 0).length;
  const avgChange = stocks.length > 0
    ? stocks.reduce((s, x) => s + x.changePct, 0) / stocks.length
    : 0;

  return (
    <div style={{
      background: pal.bg,
      border: `1px solid ${pal.border}`,
      borderRadius: 14,
      padding: '14px 16px',
      display: 'flex', flexDirection: 'column', gap: 10,
    }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{
            width: 8, height: 8, borderRadius: '50%',
            background: pal.header, flexShrink: 0,
          }}/>
          <span style={{ fontSize: 12, fontWeight: 700, color: pal.text, letterSpacing: '0.01em' }}>
            {sector}
          </span>
          <span style={{ fontSize: 11, color: 'var(--text-3)' }}>{stocks.length} stocks</span>
        </div>
        <span style={{
          fontSize: 11, fontFamily: 'Geist Mono, monospace', fontWeight: 600,
          color: avgChange > 0 ? 'var(--up)' : avgChange < 0 ? 'var(--down)' : 'var(--text-3)',
        }}>
          {avgChange >= 0 ? '+' : ''}{avgChange.toFixed(2)}%
        </span>
      </div>

      {/* Ticker chips cloud */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
        {sorted.map(stock => (
          <TickerChip
            key={stock.sym}
            stock={stock}
            palette={pal}
            inPortfolio={portfolio.some(h => h.sym === stock.sym)}
            inWatchlist={watchlist.includes(stock.sym)}
            onAdd={onAdd}
            goTo={goTo}
          />
        ))}
      </div>

      {/* Footer breadth */}
      <div style={{ display: 'flex', gap: 10, fontSize: 10.5, fontFamily: 'Geist Mono, monospace', paddingTop: 4, borderTop: '1px solid var(--border)' }}>
        <span style={{ color: 'var(--up)' }}>▲ {advancers} up</span>
        <span style={{ color: 'var(--down)' }}>▼ {decliners} down</span>
        <span style={{ color: 'var(--text-3)' }}>— {stocks.length - advancers - decliners} flat</span>
      </div>
    </div>
  );
};

// ── Add-to-portfolio toast ────────────────────────────────────────────────────
const AddToast = ({ stock, onClose, onConfirm }) => {
  const [shares, setShares] = React.useState('');
  const [cost, setCost] = React.useState(stock.price > 0 ? stock.price.toFixed(2) : '');

  return (
    <div style={{
      position: 'fixed', bottom: 24, right: 24, zIndex: 200,
      background: 'var(--bg-elev)', border: '1px solid var(--border-strong)',
      borderRadius: 14, boxShadow: '0 8px 40px rgba(0,0,0,0.4)',
      padding: '18px 20px', minWidth: 280,
      animation: 'slideUp 0.2s ease',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
        <SymBadge sym={stock.sym} size={30}/>
        <div>
          <div style={{ fontWeight: 700, fontSize: 14 }}>{stock.sym}</div>
          <div style={{ fontSize: 11, color: 'var(--text-3)' }}>{stock.name}</div>
        </div>
        <button onClick={onClose} style={{ marginLeft: 'auto', background: 'none', border: 'none', color: 'var(--text-3)', cursor: 'pointer', fontSize: 16 }}>✕</button>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 12 }}>
        <input
          type="number" min="1" placeholder="Shares"
          value={shares} onChange={e => setShares(e.target.value)}
          autoFocus
          style={{ padding: '8px 10px', background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 7, color: 'var(--text)', fontSize: 13, fontFamily: 'Geist Mono, monospace' }}
        />
        <input
          type="number" min="0" step="0.01" placeholder={`Avg cost (J$${stock.price > 0 ? stock.price.toFixed(2) : '0.00'})`}
          value={cost} onChange={e => setCost(e.target.value)}
          style={{ padding: '8px 10px', background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 7, color: 'var(--text)', fontSize: 13, fontFamily: 'Geist Mono, monospace' }}
        />
      </div>
      <div style={{ display: 'flex', gap: 8 }}>
        <button className="btn primary" style={{ flex: 1 }}
          onClick={() => {
            const sh = parseFloat(shares);
            if (!sh || sh <= 0) return;
            onConfirm(stock, sh, parseFloat(cost) || stock.price || 0);
            onClose();
          }}>
          + Add to portfolio
        </button>
        <button className="btn ghost" onClick={onClose}>Cancel</button>
      </div>
    </div>
  );
};

// ── Main StocksPage ───────────────────────────────────────────────────────────
window.StocksPage = ({ currency, goTo, setPage, setSelectedStock }) => {
  const { stocks, bySym } = window.JASTOCKS_DATA;

  const [portfolio, setPortfolio] = React.useState(() => loadPortfolio());
  const [watchlist, setWatchlist] = React.useState(() => loadWatchlist());
  const [addingStock, setAddingStock] = React.useState(null);
  const [filterMarket, setFilterMarket] = React.useState('all'); // 'all' | 'Main' | 'Junior'
  const [search, setSearch] = React.useState('');
  const [toast, setToast] = React.useState(null); // { message }

  // Filter stocks
  const filtered = React.useMemo(() => {
    let s = stocks;
    if (filterMarket !== 'all') s = s.filter(x => x.market === filterMarket);
    if (search.trim()) {
      const q = search.trim().toUpperCase();
      s = s.filter(x => x.sym.includes(q) || x.name.toUpperCase().includes(q));
    }
    return s;
  }, [stocks, filterMarket, search]);

  // Group by sector
  const sectors = React.useMemo(() => {
    const map = {};
    filtered.forEach(s => {
      if (!map[s.sector]) map[s.sector] = [];
      map[s.sector].push(s);
    });
    // Sort sectors: by total stocks descending, with 'Other' always last
    return Object.entries(map)
      .sort(([a, as], [b, bs]) => {
        if (a === 'Other') return 1;
        if (b === 'Other') return -1;
        return bs.length - as.length;
      });
  }, [filtered]);

  const handleAdd = (stock) => {
    // If already in portfolio, just show a quick toast
    if (portfolio.some(h => h.sym === stock.sym)) {
      setToast(`${stock.sym} is already in your portfolio`);
      setTimeout(() => setToast(null), 2500);
      return;
    }
    setAddingStock(stock);
  };

  const confirmAdd = (stock, shares, avgCost) => {
    const existing = portfolio.find(h => h.sym === stock.sym);
    let next;
    if (existing) {
      next = portfolio.map(h => h.sym === stock.sym ? { ...h, shares: h.shares + shares } : h);
    } else {
      const id = Date.now().toString(36) + Math.random().toString(36).slice(2, 5);
      next = [...portfolio, { id, sym: stock.sym, shares, avgCost, addedAt: new Date().toISOString() }];
    }
    savePortfolio(next);
    setPortfolio(next);
    setToast(`Added ${shares} × ${stock.sym} to portfolio`);
    setTimeout(() => setToast(null), 2500);
  };

  return (
    <div className="page">
      {/* Header */}
      <div className="page-header">
        <div>
          <h1 className="page-title">Markets</h1>
          <div className="page-subtitle">JSE stocks by sector — click any ticker to view, + to add to portfolio</div>
        </div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
          {/* Search */}
          <div className="search" style={{ minWidth: 200 }}>
            <Icons.Search/>
            <input
              placeholder="Search ticker or name…"
              value={search}
              onChange={e => setSearch(e.target.value)}
            />
          </div>
          {/* Market filter */}
          <div className="seg">
            {['all', 'Main', 'Junior'].map(m => (
              <button key={m} className={filterMarket === m ? 'active' : ''}
                onClick={() => setFilterMarket(m)}>
                {m === 'all' ? 'All' : m}
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Index bar */}
      <IndexBar stocks={stocks} />

      {/* Sector legend */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 20 }}>
        {sectors.map(([sector]) => {
          const pal = sectorPalette(sector);
          return (
            <div key={sector} style={{
              display: 'inline-flex', alignItems: 'center', gap: 5,
              padding: '3px 10px', borderRadius: 999,
              background: pal.bg, border: `1px solid ${pal.border}`,
              fontSize: 11, fontWeight: 600, color: pal.text,
            }}>
              <div style={{ width: 6, height: 6, borderRadius: '50%', background: pal.header }}/>
              {sector}
            </div>
          );
        })}
      </div>

      {/* Sector clouds grid */}
      {sectors.length === 0 ? (
        <div className="card" style={{ textAlign: 'center', padding: '48px 24px' }}>
          <div style={{ fontWeight: 700, fontSize: 16, marginBottom: 8 }}>No stocks found</div>
          <div className="text-3">Try a different search or market filter.</div>
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(340px, 1fr))', gap: 14 }}>
          {sectors.map(([sector, sStocks]) => (
            <SectorCloud
              key={sector}
              sector={sector}
              stocks={sStocks}
              portfolio={portfolio}
              watchlist={watchlist}
              onAdd={handleAdd}
              goTo={goTo}
            />
          ))}
        </div>
      )}

      {/* Add-to-portfolio modal */}
      {addingStock && (
        <AddToast
          stock={addingStock}
          onClose={() => setAddingStock(null)}
          onConfirm={confirmAdd}
        />
      )}

      {/* Toast notification */}
      {toast && (
        <div style={{
          position: 'fixed', bottom: 24, left: '50%', transform: 'translateX(-50%)',
          background: 'var(--bg-elev)', border: '1px solid var(--border-strong)',
          borderRadius: 8, padding: '10px 18px', fontSize: 13, fontWeight: 500,
          boxShadow: '0 4px 20px rgba(0,0,0,0.3)', zIndex: 300,
          color: 'var(--text)',
        }}>
          {toast}
        </div>
      )}

      <style>{`
        @keyframes slideUp {
          from { opacity: 0; transform: translateY(16px); }
          to   { opacity: 1; transform: translateY(0); }
        }
      `}</style>
    </div>
  );
};

// ── WatchlistPage ─────────────────────────────────────────────────────────────
window.WatchlistPage = ({ currency, goTo, setPage, setSelectedStock }) => {
  const { stocks, bySym } = window.JASTOCKS_DATA;
  const [watchlist, setWatchlist] = React.useState(() => loadWatchlist());

  const watched = watchlist.map(sym => bySym[sym]).filter(Boolean);

  const remove = (sym) => {
    const next = watchlist.filter(s => s !== sym);
    saveWatchlist(next);
    setWatchlist(next);
  };

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <h1 className="page-title">Watchlist</h1>
          <div className="page-subtitle">Stocks you're keeping an eye on</div>
        </div>
      </div>

      {watched.length === 0 ? (
        <div className="card" style={{ textAlign: 'center', padding: '48px 24px' }}>
          <div style={{ width: 48, height: 48, borderRadius: 12, background: 'var(--bg-2)', border: '1px solid var(--border)', display: 'grid', placeItems: 'center', margin: '0 auto 16px', fontSize: 22 }}>👁</div>
          <div style={{ fontWeight: 700, fontSize: 16, marginBottom: 8 }}>Your watchlist is empty</div>
          <div className="text-3" style={{ maxWidth: 300, margin: '0 auto' }}>
            Browse the <b>Markets</b> page and add stocks to track them here.
          </div>
          <button className="btn primary" style={{ marginTop: 16 }} onClick={() => { setPage && setPage('stocks'); }}>
            Browse Markets
          </button>
        </div>
      ) : (
        <div className="card">
          <table className="data">
            <thead>
              <tr>
                <th>Stock</th>
                <th style={{ textAlign: 'right' }}>Price</th>
                <th style={{ textAlign: 'right' }}>Change</th>
                <th style={{ textAlign: 'right' }}>% Change</th>
                <th style={{ textAlign: 'right' }}>Yield</th>
                <th style={{ textAlign: 'right' }}>Market</th>
                <th style={{ width: 40 }}></th>
              </tr>
            </thead>
            <tbody>
              {watched.map(s => (
                <tr key={s.sym} style={{ cursor: 'pointer' }} onClick={() => goTo && goTo('stock', s.sym)}>
                  <td>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      <SymBadge sym={s.sym} size={28}/>
                      <div>
                        <div style={{ fontWeight: 600, fontSize: 13 }}>{s.sym}</div>
                        <div style={{ fontSize: 11, color: 'var(--text-3)' }}>{s.name}</div>
                      </div>
                    </div>
                  </td>
                  <td className="mono" style={{ textAlign: 'right' }}>{fmtPrice(s.price, currency)}</td>
                  <td className="mono" style={{ textAlign: 'right', color: s.change >= 0 ? 'var(--up)' : 'var(--down)' }}>
                    {s.change >= 0 ? '+' : ''}{s.change.toFixed(2)}
                  </td>
                  <td className="mono" style={{ textAlign: 'right', color: s.changePct >= 0 ? 'var(--up)' : 'var(--down)' }}>
                    {s.changePct >= 0 ? '+' : ''}{s.changePct.toFixed(2)}%
                  </td>
                  <td className="mono" style={{ textAlign: 'right', color: 'var(--accent)' }}>
                    {s.yield > 0 ? `${s.yield.toFixed(2)}%` : '—'}
                  </td>
                  <td style={{ textAlign: 'right' }}>
                    <span className={`tag ${s.market === 'Junior' ? 'junior' : 'main'}`}>{s.market}</span>
                  </td>
                  <td>
                    <button
                      onClick={e => { e.stopPropagation(); remove(s.sym); }}
                      style={{ background: 'none', border: 'none', color: 'var(--text-3)', cursor: 'pointer', fontSize: 14, padding: '4px 6px' }}
                      title="Remove from watchlist"
                    >✕</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
};
