/* ────────────────── EVE Monitor — Pages (Intel · Market · Kills · Settings) ────────────────── */
const { useState: useState2, useEffect: useEffect2, useMemo: useMemo2, useRef: useRef2, useCallback: useCallback2 } = React;

/* ─── helpers ─── */
async function apiFetch2(url, opts) {
  try {
    const r = await fetch(url, { credentials: 'include', ...opts });
    if (!r.ok) return null;
    return await r.json();
  } catch { return null; }
}

const KIND_TAG2 = {
  hostile: 'HOSTILE', hostile_seen: 'HOSTILE', cyno: 'CYNO', bubble: 'BUBBLE',
  gate_camp: 'GATECAMP', neutral: 'NEUTRAL', all_clear: 'CLEAR', kill: 'KILL',
  wormhole_signature: 'WARN', blob: 'GANG', note: 'INTEL', spike: 'SPIKE',
};
const SEV_MAP2 = { 1: 'low', 2: 'low', 3: 'med', 4: 'high', 5: 'high' };
const sevColor2 = (sev) => sev === 'high' ? 'red' : sev === 'med' ? 'amber' : 'green';

function fmtTime(iso) {
  if (!iso) return '—';
  return new Date(iso).toTimeString().slice(0, 8);
}
function fmtIsk(v) {
  if (!v && v !== 0) return '—';
  if (v >= 1e12) return (v / 1e12).toFixed(2) + 'T';
  if (v >= 1e9)  return (v / 1e9).toFixed(2) + 'B';
  if (v >= 1e6)  return (v / 1e6).toFixed(2) + 'M';
  if (v >= 1e3)  return (v / 1e3).toFixed(1) + 'K';
  return v.toFixed(2);
}

/* ─── Sparkline ─── */
function Sparkline({ data, color = '#38bdf8', width = 60, height = 18, fill = true }) {
  if (!data || data.length < 2) return null;
  const max = Math.max(...data), min = Math.min(...data);
  const range = max - min || 1;
  const pts = data.map((v, i) =>
    `${(i / (data.length - 1)) * width},${height - ((v - min) / range) * (height - 2) - 1}`
  ).join(' ');
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={{ display: 'block' }}>
      {fill && (
        <polyline points={`0,${height} ${pts} ${width},${height}`}
          fill={color} opacity="0.12" stroke="none"/>
      )}
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.2"/>
    </svg>
  );
}

/* ─── useRandomWalk ─── */
function useRandomWalk(seed, len = 24, vol = 0.06) {
  const ref = useRef2(null);
  if (!ref.current) {
    const out = [seed];
    for (let i = 1; i < len; i++) out.push(out[i-1] * (1 + (Math.random() - 0.5) * vol));
    ref.current = out;
  }
  const [series, setSeries] = useState2(ref.current);
  useEffect2(() => {
    const id = setInterval(() => {
      setSeries(s => {
        const last = s[s.length - 1];
        return [...s.slice(1), last * (1 + (Math.random() - 0.5) * vol)];
      });
    }, 1400);
    return () => clearInterval(id);
  }, []);
  return series;
}

/* ─── TickValue ─── */
function TickValue({ value, color = '#38bdf8', upColor = '#5be584', downColor = '#ff5577', format = (v)=>v, style }) {
  const [prev, setPrev] = useState2(value);
  const [flash, setFlash] = useState2(null);
  useEffect2(() => {
    if (value !== prev) {
      setFlash(value > prev ? 'up' : 'down');
      const t = setTimeout(() => setFlash(null), 600);
      setPrev(value);
      return () => clearTimeout(t);
    }
  }, [value]);
  const c = flash === 'up' ? upColor : flash === 'down' ? downColor : color;
  return (
    <span style={{
      color: c,
      transition: 'color 0.6s ease, background 0.6s ease',
      background: flash ? `${c}1a` : 'transparent',
      padding: '0 4px', borderRadius: 1, ...style,
    }}>{format(value)}</span>
  );
}

/* ──────────────────────────────── INTEL PAGE ──────────────────────────────── */
function IntelPage() {
  const [rows, setRows]         = useState2([]);
  const [stats, setStats]       = useState2(null);
  const [loading, setLoading]   = useState2(true);
  const [filter, setFilter]     = useState2('ALL');
  const [region, setRegion]     = useState2('ALL');
  const [pulse, setPulse]       = useState2(null);
  const prevLenRef              = useRef2(0);

  const regionBySystem = useMemo2(() => {
    const m = new Map();
    const systems = window.RadarData?.allSystems ?? [];
    for (const s of systems) if (s.region_name) m.set(s.id, s.region_name);
    return m;
  }, []);

  const parseRow = (r) => {
    const reporter = r.reporters?.[0] || '—';
    const tag = KIND_TAG2[r.kind] ?? 'INTEL';
    const sev = SEV_MAP2[r.severity] ?? 'med';
    const rg  = regionBySystem.get(r.system_name) ?? r.region_name ?? '—';
    const trust = Math.min(100, 55 + (r.report_count || 1) * 9);
    const hostile = r.hostile_tags?.[0] || null;
    return {
      id:       r.id,
      ts:       r.observed_at ? new Date(r.observed_at).getTime() : 0,
      time:     fmtTime(r.observed_at),
      region:   rg,
      sys:      r.system_name || '—',
      tag, sev,
      count:    r.report_count ?? 1,
      reporter,
      hostile,
      trust,
      text:     r.message || (r.hostile_tags?.join(', ')) || r.kind || '—',
    };
  };

  useEffect2(() => {
    let alive = true;
    async function load() {
      const [evData, stData] = await Promise.all([
        apiFetch2('/api/radar-00/events?limit=200'),
        apiFetch2('/api/radar-00/stats'),
      ]);
      if (!alive) return;
      setLoading(false);
      if (evData?.ok && evData.rows?.length) {
        const parsed = evData.rows.map(parseRow).sort((a,b) => b.ts - a.ts);
        if (parsed.length > prevLenRef.current && prevLenRef.current > 0) {
          setPulse(parsed[0].region);
          setTimeout(() => setPulse(null), 900);
        }
        prevLenRef.current = parsed.length;
        setRows(parsed);
      }
      if (stData?.ok) setStats(stData.stats);
    }
    load();
    const id = setInterval(load, 30_000);
    return () => { alive = false; clearInterval(id); };
  }, []);

  const regions = useMemo2(() =>
    ['ALL', ...new Set(rows.map(r => r.region).filter(x => x !== '—'))], [rows]);
  const tags = ['ALL','HOSTILE','GANG','GATECAMP','CYNO','BUBBLE','CLEAR','KILL','INTEL','WARN'];

  const filtered = useMemo2(() => rows.filter(r =>
    (filter === 'ALL' || r.tag === filter) &&
    (region === 'ALL' || r.region === region)
  ), [rows, filter, region]);

  const regionCounts = useMemo2(() =>
    regions.slice(1).map(rg => ({
      region: rg,
      high: rows.filter(r => r.region === rg && r.sev === 'high').length,
      med:  rows.filter(r => r.region === rg && r.sev === 'med').length,
      low:  rows.filter(r => r.region === rg && r.sev === 'low').length,
    })), [rows, regions]);

  const topReporters = useMemo2(() => {
    if (stats?.top_pilots?.length) {
      return stats.top_pilots.slice(0, 6).map(p => ({
        name: p.name, count: p.mentions, charId: p.character_id ?? null,
      }));
    }
    const m = new Map();
    for (const r of rows) {
      if (r.reporter === '—') continue;
      m.set(r.reporter, (m.get(r.reporter) || 0) + 1);
    }
    return [...m.entries()].sort((a,b)=>b[1]-a[1]).slice(0,6).map(([name,count])=>({name,count,charId:null}));
  }, [rows, stats]);

  const eventRate = useRandomWalk(rows.length > 0 ? rows.length / 10 : 5, 30, 0.18);

  return (
    <div data-screen-label="02 Intel" style={{
      display: 'grid', gridTemplateColumns: '220px 1fr 240px',
      gap: 5, padding: 5, height: 'calc(100vh - 30px)', boxSizing: 'border-box',
      minHeight: 0, overflow: 'hidden',
    }}>
      {/* LEFT — regions */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>▸ REGIONS</PanelHeader>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {regions.map(rg => {
            const rc = regionCounts.find(x => x.region === rg);
            const active = region === rg;
            const isPulse = pulse === rg;
            return (
              <button key={rg} onClick={() => setRegion(rg)} style={{
                width: '100%', textAlign: 'left',
                background: active ? 'rgba(56,189,248,0.12)' : isPulse ? 'rgba(255,85,119,0.10)' : 'transparent',
                transition: 'background 0.6s ease', border: 'none',
                borderLeft: active ? '2px solid #38bdf8' : '2px solid transparent',
                borderBottom: '1px solid rgba(56,189,248,0.06)',
                padding: '5px 8px', cursor: 'pointer',
                display: 'grid', gridTemplateColumns: '1fr auto auto auto',
                gap: 4, alignItems: 'center', position: 'relative',
              }}>
                {isPulse && <div style={{
                  position: 'absolute', right: 4, top: '50%', transform: 'translateY(-50%)',
                  width: 4, height: 4, borderRadius: '50%', background: '#ff5577',
                  boxShadow: '0 0 6px #ff5577', animation: 'pulse 1.6s ease infinite',
                }}/>}
                <Mono style={{ fontSize: 9, color: active ? '#38bdf8' : '#cbd5df',
                               letterSpacing: '0.12em', fontWeight: 600 }}>{rg}</Mono>
                {rc && <>
                  <Mono style={{ fontSize: 8, color: '#ff5577', minWidth: 12, textAlign: 'right' }}>{rc.high}</Mono>
                  <Mono style={{ fontSize: 8, color: '#f5b042', minWidth: 12, textAlign: 'right' }}>{rc.med}</Mono>
                  <Mono style={{ fontSize: 8, color: '#5be584', minWidth: 12, textAlign: 'right' }}>{rc.low}</Mono>
                </>}
              </button>
            );
          })}
        </div>
        <div style={{ padding: '6px 8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 7.5, color: '#5b6577', letterSpacing: '0.25em' }}>
            <span style={{ color: '#ff5577' }}>HIGH</span>{' · '}
            <span style={{ color: '#f5b042' }}>MED</span>{' · '}
            <span style={{ color: '#5be584' }}>LOW</span>
          </Mono>
        </div>
      </Panel>

      {/* CENTER — feed */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>
          {'▸ INTEL FEED · ' + filtered.length + ' report'}
          <span style={{ flex: 1 }}/>
          <div style={{ display: 'flex', gap: 2 }}>
            {tags.slice(0, 8).map(t => (
              <button key={t} onClick={() => setFilter(t)} style={{
                background: filter === t ? '#38bdf8' : 'transparent',
                color: filter === t ? '#0a0e14' : '#8a96a8',
                border: '1px solid rgba(56,189,248,0.3)',
                padding: '1px 5px', borderRadius: 1,
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 8, letterSpacing: '0.15em', cursor: 'pointer',
              }}>{t}</button>
            ))}
          </div>
        </PanelHeader>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '60px 60px 70px 70px 1fr 80px 52px 10px',
          gap: 6, padding: '3px 8px',
          background: 'rgba(56,189,248,0.04)',
          borderBottom: '1px solid rgba(56,189,248,0.1)',
        }}>
          {['TIME','TAG','REGION','SYSTEM','REPORT','REPORTER','TRUST',''].map((h,i) =>
            <Mono key={i} style={{ fontSize: 7.5, color: '#5b6577', letterSpacing: '0.25em' }}>{h}</Mono>
          )}
        </div>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {loading && (
            <div style={{ padding: 16, textAlign: 'center' }}>
              <Mono style={{ fontSize: 9, color: '#5b6577', letterSpacing: '0.3em' }}>CARICAMENTO…</Mono>
            </div>
          )}
          {!loading && filtered.length === 0 && (
            <div style={{ padding: 16, textAlign: 'center' }}>
              <Mono style={{ fontSize: 9, color: '#5b6577', letterSpacing: '0.3em' }}>NESSUN EVENTO</Mono>
            </div>
          )}
          {filtered.map((r) => (
            <a key={r.id}
               href={zkillUrl({ pilot: r.hostile || (r.reporter !== '—' ? r.reporter : null) })}
               target="_blank" rel="noopener noreferrer"
               style={{
                 display: 'grid',
                 gridTemplateColumns: '60px 60px 70px 70px 1fr 80px 52px 10px',
                 gap: 6, padding: '3px 8px',
                 borderBottom: '1px solid rgba(56,189,248,0.06)',
                 alignItems: 'center', textDecoration: 'none',
                 transition: 'background 0.12s',
               }}
               onMouseEnter={(e) => e.currentTarget.style.background = 'rgba(56,189,248,0.06)'}
               onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
              <Mono style={{ fontSize: 8.5, color: '#5b6577' }}>{r.time}</Mono>
              <Pill color={sevColor2(r.sev)}>{r.tag}</Pill>
              <Mono style={{ fontSize: 8.5, color: '#cbd5df', letterSpacing: '0.04em',
                              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{r.region}</Mono>
              <Mono style={{ fontSize: 9, color: '#38bdf8', fontWeight: 600, letterSpacing: '0.05em' }}>{r.sys}</Mono>
              <Mono style={{ fontSize: 9, color: '#e8ecf2', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {r.count > 1 && <span style={{ color: '#f5b042', marginRight: 6 }}>{'×' + r.count}</span>}
                {r.text}
              </Mono>
              <Mono style={{ fontSize: 8.5, color: '#cbd5df', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {r.reporter}
              </Mono>
              <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                <div style={{ flex: 1, height: 3, background: 'rgba(56,189,248,0.15)', position: 'relative' }}>
                  <div style={{
                    position: 'absolute', top: 0, left: 0, height: '100%',
                    width: r.trust + '%',
                    background: r.trust >= 90 ? '#5be584' : r.trust >= 70 ? '#38bdf8' : '#f5b042',
                  }}/>
                </div>
                <Mono style={{ fontSize: 7.5, color: '#5b6577', minWidth: 16, textAlign: 'right' }}>{r.trust}</Mono>
              </div>
              <Mono style={{ fontSize: 8, color: '#5b6577', textAlign: 'right' }}>↗</Mono>
            </a>
          ))}
        </div>
      </Panel>

      {/* RIGHT — cluster */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>▸ CLUSTER · 1h</PanelHeader>
        <div style={{ padding: '8px' }}>
          {[
            { l: 'HIGH', c: 'red',   col: '#ff5577', v: rows.filter(r => r.sev === 'high').length },
            { l: 'MED',  c: 'amber', col: '#f5b042', v: rows.filter(r => r.sev === 'med').length },
            { l: 'LOW',  c: 'green', col: '#5be584', v: rows.filter(r => r.sev === 'low').length },
          ].map((row) => (
            <div key={row.l} style={{ marginBottom: 8 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 2 }}>
                <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.25em' }}>{row.l}</Mono>
                <Mono style={{ fontSize: 11, fontWeight: 700, color: row.col }}>{row.v}</Mono>
              </div>
              <div style={{ height: 3, background: 'rgba(56,189,248,0.10)' }}>
                <div style={{
                  width: rows.length ? (row.v / rows.length * 100) + '%' : '0%',
                  height: '100%', background: row.col, transition: 'width 0.6s ease',
                }}/>
              </div>
            </div>
          ))}
        </div>
        <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>EVENT RATE · 30m</Mono>
          <div style={{ marginTop: 6 }}>
            <Sparkline data={eventRate} width={220} height={48} color="#38bdf8"/>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4 }}>
            <Mono style={{ fontSize: 8, color: '#5b6577' }}>
              tot <TickValue value={rows.length} format={(v) => v.toString()}
                style={{ fontWeight: 700, fontSize: 9 }}/> eventi
            </Mono>
            {stats && <Mono style={{ fontSize: 8, color: '#5b6577' }}>{'sys ' + (stats.unique_systems ?? '—')}</Mono>}
          </div>
        </div>
        <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)', flex: 1 }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>TOP REPORTERS</Mono>
          <div style={{ marginTop: 6 }}>
            {topReporters.length === 0 && (
              <Mono style={{ fontSize: 8.5, color: '#5b6577' }}>nessun dato</Mono>
            )}
            {topReporters.map((p, i) => (
              <a key={p.name}
                 href={zkillUrl({ pilot: p.name, charId: p.charId })}
                 target="_blank" rel="noopener noreferrer"
                 style={{ textDecoration: 'none' }}>
                <div style={{
                  display: 'grid', gridTemplateColumns: '14px 1fr 30px auto',
                  gap: 6, alignItems: 'center', padding: '2px 0',
                  borderBottom: '1px solid rgba(56,189,248,0.06)',
                }}>
                  <Mono style={{ fontSize: 8.5, color: '#5b6577' }}>{String(i+1).padStart(2,'0')}</Mono>
                  <Mono style={{ fontSize: 9, color: '#e8ecf2' }}>{p.name}</Mono>
                  <Mono style={{ fontSize: 9, color: '#38bdf8', fontWeight: 600, textAlign: 'right' }}>{p.count}</Mono>
                  <Mono style={{ fontSize: 8, color: '#5b6577' }}>↗</Mono>
                </div>
              </a>
            ))}
          </div>
        </div>
      </Panel>
    </div>
  );
}

/* ────────────────────────────── MARKET PAGE ──────────────────────────────── */

const TRADE_HUBS = [
  { name: 'Jita IV-4',     hub: true,  orders: 2480000 },
  { name: 'Amarr VIII-4',  hub: true,  orders: 820000  },
  { name: 'Dodixie IX-20', hub: true,  orders: 480000  },
  { name: 'Rens VI-8',     hub: false, orders: 280000  },
  { name: 'Hek VIII-12',   hub: false, orders: 180000  },
];

const MARKET_DEFS = [
  { typeId: 34,    name: 'Tritanium',      cat: 'Mineral',  vol: '8.2B',  d: 2.3  },
  { typeId: 35,    name: 'Pyerite',        cat: 'Mineral',  vol: '3.1B',  d: -1.2 },
  { typeId: 36,    name: 'Mexallon',       cat: 'Mineral',  vol: '1.4B',  d: 0.8  },
  { typeId: 37,    name: 'Isogen',         cat: 'Mineral',  vol: '420M',  d: 3.1  },
  { typeId: 38,    name: 'Nocxium',        cat: 'Mineral',  vol: '180M',  d: -0.5 },
  { typeId: 39,    name: 'Zydrine',        cat: 'Mineral',  vol: '94M',   d: 1.8  },
  { typeId: 40,    name: 'Megacyte',       cat: 'Mineral',  vol: '48M',   d: -2.1 },
  { typeId: 11399, name: 'Morphite',       cat: 'Mineral',  vol: '12M',   d: 0.4  },
  { typeId: 29668, name: 'PLEX',           cat: 'Currency', vol: '24K',   d: 1.5  },
  { typeId: 44992, name: 'Skill Injector', cat: 'Skills',   vol: '8K',    d: -0.8 },
];

function MarketPage() {
  const [hub, setHub]         = useState2('Jita IV-4');
  const [prices, setPrices]   = useState2({});
  const [walks, setWalks]     = useState2(() => MARKET_DEFS.map(() => 1));
  const [sel, setSel]         = useState2(MARKET_DEFS[8]);
  const [esiLoaded, setEsiLoaded] = useState2(false);

  useEffect2(() => {
    let alive = true;
    fetch('https://esi.evetech.net/latest/markets/prices/?datasource=tranquility')
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (!alive || !Array.isArray(data)) return;
        const m = {};
        for (const item of data) {
          const p = item.average_price || item.adjusted_price;
          if (p && p > 0) m[item.type_id] = p;
        }
        setPrices(m);
        setEsiLoaded(true);
      })
      .catch(() => {});
    return () => { alive = false; };
  }, []);

  useEffect2(() => {
    const id = setInterval(() => {
      setWalks(w => w.map(v => v * (1 + (Math.random() - 0.5) * 0.010)));
    }, 1200);
    return () => clearInterval(id);
  }, []);

  const sparks = useMemo2(() =>
    MARKET_DEFS.map((_, i) => {
      const arr = [];
      let v = 1;
      for (let j = 0; j < 18; j++) {
        v *= 1 + (Math.sin(i + j * 0.5) * 0.04) + ((Math.random() - 0.5) * 0.03);
        arr.push(v);
      }
      return arr;
    }), []);

  const marketIndex = useRandomWalk(1248, 28, 0.04);

  const getPrice = (item, wi) => {
    const base = prices[item.typeId] || 0;
    return base > 0 ? base * walks[wi] : null;
  };

  return (
    <div data-screen-label="03 Market" style={{
      display: 'grid',
      gridTemplateColumns: '200px 1fr 300px',
      gridTemplateRows: '28px 1fr',
      gap: 5, padding: 5, height: 'calc(100vh - 30px)', boxSizing: 'border-box',
      minHeight: 0, overflow: 'hidden',
    }}>
      {/* TICKER TAPE */}
      <div style={{
        gridColumn: '1 / -1',
        background: 'rgba(15,20,28,0.55)',
        border: '1px solid rgba(56,189,248,0.18)',
        overflow: 'hidden', display: 'flex', alignItems: 'center',
      }}>
        <Mono style={{
          padding: '0 10px', fontSize: 9, color: '#0a0e14',
          background: '#38bdf8', fontWeight: 700, letterSpacing: '0.3em',
          height: '100%', display: 'flex', alignItems: 'center', flexShrink: 0,
        }}>▸ LIVE TICKER</Mono>
        <div style={{
          display: 'flex', gap: 22,
          animation: 'tickerScroll 60s linear infinite',
          paddingLeft: 12, whiteSpace: 'nowrap',
        }}>
          {[...MARKET_DEFS, ...MARKET_DEFS].map((it, i) => {
            const p = getPrice(it, i % MARKET_DEFS.length);
            const pos = it.d >= 0;
            return (
              <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                <Mono style={{ fontSize: 9, color: '#cbd5df', fontWeight: 600, letterSpacing: '0.08em' }}>
                  {it.name.toUpperCase()}
                </Mono>
                <Mono style={{ fontSize: 9, color: '#38bdf8', fontVariantNumeric: 'tabular-nums' }}>
                  {p ? fmtIsk(p) : '—'}
                </Mono>
                <Mono style={{ fontSize: 8.5, color: pos ? '#5be584' : '#ff5577' }}>
                  {pos ? '▲' : '▼'}{Math.abs(it.d).toFixed(1) + '%'}
                </Mono>
              </span>
            );
          })}
        </div>
      </div>

      {/* LEFT — hubs */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>▸ TRADE HUBS</PanelHeader>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {TRADE_HUBS.map(rg => {
            const active = hub === rg.name;
            return (
              <button key={rg.name} onClick={() => setHub(rg.name)} style={{
                width: '100%', textAlign: 'left',
                background: active ? 'rgba(56,189,248,0.12)' : 'transparent',
                border: 'none',
                borderLeft: active ? '2px solid #38bdf8' : '2px solid transparent',
                borderBottom: '1px solid rgba(56,189,248,0.06)',
                padding: '5px 8px', cursor: 'pointer',
              }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <Mono style={{ fontSize: 9.5, color: active ? '#38bdf8' : '#e8ecf2',
                                 letterSpacing: '0.08em', fontWeight: 600 }}>{rg.name}</Mono>
                  {rg.hub && <Pill color="amber">HUB</Pill>}
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 2 }}>
                  <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.18em' }}>
                    {rg.orders.toLocaleString() + ' orders'}
                  </Mono>
                  <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#5be584', boxShadow: '0 0 4px #5be584' }}/>
                </div>
              </button>
            );
          })}
        </div>
        <div style={{ padding: '6px 8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.25em' }}>QUICK FILTER</Mono>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 3, marginTop: 4 }}>
            {['Ships','T2','Faction','Mins','Mods','PI','Caps'].map(t => (
              <button key={t} style={{
                background: 'transparent', color: '#cbd5df',
                border: '1px solid rgba(56,189,248,0.3)',
                padding: '1px 5px', borderRadius: 1,
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 8, letterSpacing: '0.1em', cursor: 'pointer',
              }}>{t}</button>
            ))}
          </div>
        </div>
        <div style={{ padding: '6px 8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>MARKET INDEX</Mono>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 4, marginTop: 4 }}>
            <TickValue value={Math.round(marketIndex[marketIndex.length-1])}
              format={(v) => v.toLocaleString()}
              style={{ fontSize: 18, fontWeight: 700, fontFamily: "'JetBrains Mono', monospace" }}/>
            <Mono style={{ fontSize: 8, color: '#5b6577', letterSpacing: '0.2em' }}>EMI</Mono>
          </div>
          <Sparkline data={marketIndex} width={170} height={24} color="#38bdf8"/>
        </div>
      </Panel>

      {/* CENTER — items */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>
          {'▸ TOP MOVERS · ' + hub}
          <span style={{ flex: 1 }}/>
          {!esiLoaded && <Pill color="amber">ESI…</Pill>}
          {esiLoaded && <Pill color="green">● ESI LIVE</Pill>}
        </PanelHeader>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1.3fr 0.8fr 0.9fr 60px 60px 0.7fr',
          gap: 6, padding: '3px 8px',
          background: 'rgba(56,189,248,0.04)',
          borderBottom: '1px solid rgba(56,189,248,0.1)',
        }}>
          {['NAME','CATEGORIA','PREZZO ISK','Δ 24h','30D','VOLUME'].map(h =>
            <Mono key={h} style={{ fontSize: 7.5, color: '#5b6577', letterSpacing: '0.25em' }}>{h}</Mono>
          )}
        </div>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {MARKET_DEFS.map((it, i) => {
            const isSel = sel.typeId === it.typeId;
            const pos = it.d >= 0;
            const sparkColor = pos ? '#5be584' : '#ff5577';
            const tickedPrice = getPrice(it, i);
            return (
              <button key={it.typeId} onClick={() => setSel(it)} style={{
                display: 'grid', gridTemplateColumns: '1.3fr 0.8fr 0.9fr 60px 60px 0.7fr',
                gap: 6, padding: '4px 8px', width: '100%', textAlign: 'left',
                background: isSel ? 'rgba(56,189,248,0.10)' : 'transparent',
                borderTop: 'none', borderRight: 'none',
                borderBottom: '1px solid rgba(56,189,248,0.06)',
                borderLeft: isSel ? '2px solid #38bdf8' : '2px solid transparent',
                outline: 'none', cursor: 'pointer', alignItems: 'center',
              }}>
                <Mono style={{ fontSize: 9.5, color: '#e8ecf2', fontWeight: 600, letterSpacing: '0.05em' }}>{it.name}</Mono>
                <Mono style={{ fontSize: 8.5, color: '#8a96a8', letterSpacing: '0.1em' }}>{it.cat}</Mono>
                <span>
                  {tickedPrice
                    ? <TickValue value={tickedPrice} format={(v) => fmtIsk(v)} color="#38bdf8"
                        style={{ fontSize: 10, fontWeight: 600, fontFamily: "'JetBrains Mono', monospace",
                                 fontVariantNumeric: 'tabular-nums' }}/>
                    : <Mono style={{ fontSize: 9, color: '#5b6577' }}>—</Mono>
                  }
                </span>
                <Mono style={{ fontSize: 9, color: pos ? '#5be584' : '#ff5577', fontWeight: 600 }}>
                  {(pos ? '▲' : '▼') + ' ' + Math.abs(it.d).toFixed(1) + '%'}
                </Mono>
                <Sparkline data={sparks[i]} width={50} height={14} color={sparkColor}/>
                <Mono style={{ fontSize: 9, color: '#cbd5df', letterSpacing: '0.05em' }}>{it.vol}</Mono>
              </button>
            );
          })}
        </div>
      </Panel>

      {/* RIGHT — detail */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>{'▸ ' + sel.name.toUpperCase()}</PanelHeader>
        <div style={{ padding: '8px' }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>{sel.cat.toUpperCase()}</Mono>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginTop: 4 }}>
            {(() => {
              const p = getPrice(sel, MARKET_DEFS.indexOf(sel));
              return p
                ? <Mono style={{ fontSize: 22, color: '#38bdf8', fontWeight: 700, letterSpacing: '-0.02em', fontVariantNumeric: 'tabular-nums' }}>{fmtIsk(p)}</Mono>
                : <Mono style={{ fontSize: 22, color: '#5b6577', fontWeight: 700 }}>—</Mono>;
            })()}
            <Mono style={{ fontSize: 9, color: '#5b6577', letterSpacing: '0.2em' }}>ISK</Mono>
          </div>
          <div style={{ display: 'flex', gap: 4, marginTop: 4 }}>
            <Pill color={sel.d >= 0 ? 'green' : 'red'}>
              {(sel.d >= 0 ? '▲' : '▼') + ' ' + Math.abs(sel.d).toFixed(1) + '% · 24h'}
            </Pill>
            <Pill color="dim">{'vol ' + sel.vol}</Pill>
          </div>
        </div>
        <div style={{ padding: '0 8px 8px' }}>
          <svg width="100%" height="80" viewBox="0 0 280 80">
            {[0,1,2,3,4].map(i => <line key={i} x1="0" y1={i*16+4} x2="280" y2={i*16+4} stroke="rgba(56,189,248,0.06)"/>)}
            <polyline points="0,60 20,58 40,55 60,50 80,52 100,46 120,48 140,40 160,42 180,32 200,36 220,22 240,18 260,12 280,16"
              fill="none" stroke="#38bdf8" strokeWidth="1.5"/>
            <polyline points="0,80 0,60 20,58 40,55 60,50 80,52 100,46 120,48 140,40 160,42 180,32 200,36 220,22 240,18 260,12 280,16 280,80"
              fill="rgba(56,189,248,0.10)" stroke="none"/>
            <circle cx="280" cy="16" r="2.5" fill="#38bdf8">
              <animate attributeName="r" values="2.5;4;2.5" dur="1.6s" repeatCount="indefinite"/>
            </circle>
          </svg>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4 }}>
            <Mono style={{ fontSize: 7.5, color: '#5b6577' }}>30d ago</Mono>
            <Mono style={{ fontSize: 7.5, color: '#5b6577' }}>● NOW</Mono>
          </div>
        </div>
        <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>ORDER DEPTH</Mono>
          <svg width="100%" height="40" viewBox="0 0 280 40" style={{ marginTop: 4 }}>
            {[80,72,64,56,48,40,32].map((h,i) => (
              <rect key={'b'+i} x={5+i*19} y={40-h*0.45} width="16" height={h*0.45} fill="#ff5577" opacity="0.55"/>
            ))}
            {[30,42,54,64,72,80,72].map((h,i) => (
              <rect key={'s'+i} x={147+i*19} y={40-h*0.45} width="16" height={h*0.45} fill="#5be584" opacity="0.55"/>
            ))}
            <line x1="140" y1="0" x2="140" y2="40" stroke="#38bdf8" strokeWidth="1" strokeDasharray="2 2"/>
          </svg>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 2 }}>
            <Mono style={{ fontSize: 7.5, color: '#ff5577' }}>BUY</Mono>
            <Mono style={{ fontSize: 7.5, color: '#38bdf8' }}>MID</Mono>
            <Mono style={{ fontSize: 7.5, color: '#5be584' }}>SELL</Mono>
          </div>
        </div>
        <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)', flex: 1 }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>ESI TYPE ID</Mono>
          <div style={{ marginTop: 6 }}>
            <a href={'https://market.fuzzwork.co.uk/type/' + sel.typeId + '/'} target="_blank" rel="noopener noreferrer">
              <Mono style={{ fontSize: 12, color: '#38bdf8', fontWeight: 700 }}>{sel.typeId}</Mono>
            </a>
            <Mono style={{ fontSize: 8, color: '#5b6577', display: 'block', marginTop: 6 }}>
              prezzi ESI tranquility · aggiornamento ogni 20min
            </Mono>
          </div>
        </div>
      </Panel>
    </div>
  );
}

/* ──────────────────────────────── KILLS PAGE ──────────────────────────────── */
function KillsPage() {
  const [allRows, setAllRows] = useState2([]);
  const [stats, setStats]     = useState2(null);
  const [tab, setTab]         = useState2('ALL');
  const [flashId, setFlashId] = useState2(null);
  const [loading, setLoading] = useState2(true);
  const prevLenRef            = useRef2(0);

  const parseKill = (r) => {
    const tags = r.hostile_tags || [];
    const reps = r.reporters || [];
    const victim = tags[0] || '—';
    const attackers = reps.join(', ') || tags.slice(1).join(', ') || '—';
    return {
      id:        r.id,
      ts:        r.observed_at ? new Date(r.observed_at).getTime() : 0,
      time:      new Date(r.observed_at || Date.now()).toTimeString().slice(0,5),
      sys:       r.system_name || '—',
      victim,
      attackers,
      value:     '—',
      loss:      false,
    };
  };

  useEffect2(() => {
    let alive = true;
    async function load() {
      const [evData, stData] = await Promise.all([
        apiFetch2('/api/radar-00/events?limit=100'),
        apiFetch2('/api/radar-00/stats'),
      ]);
      if (!alive) return;
      setLoading(false);
      if (evData?.ok && evData.rows?.length) {
        const kills = evData.rows
          .filter(r => r.kind === 'kill')
          .sort((a,b) => new Date(b.observed_at) - new Date(a.observed_at))
          .map(parseKill);
        if (kills.length > prevLenRef.current && prevLenRef.current > 0) {
          const fresh = kills[0];
          setFlashId(fresh.id);
          setTimeout(() => setFlashId(null), 1500);
        }
        prevLenRef.current = kills.length;
        setAllRows(kills);
      }
      if (stData?.ok) setStats(stData.stats);
    }
    load();
    const id = setInterval(load, 30_000);
    return () => { alive = false; clearInterval(id); };
  }, []);

  const filtered = tab === 'ALL' ? allRows
                 : tab === 'KILLS' ? allRows.filter(r => !r.loss)
                 : allRows.filter(r => r.loss);

  const activityWalk = useRandomWalk(12, 24, 0.25);
  const actData = activityWalk;
  const iskWalk = useRandomWalk(180, 24, 0.10);

  const shipSparks = useMemo2(() => Array.from({length:5}).map(() =>
    Array.from({length:14}).map((_,j) => 5 + Math.random()*18 + Math.sin(j)*4)
  ), []);

  const hotZones = useMemo2(() => {
    if (stats?.hot_systems?.length) {
      return stats.hot_systems.slice(0,5).map(s => ({
        sys: s.system_name || '—',
        n:   s.events,
        c:   s.hostile_events > s.events * 0.5 ? '#ff5577'
             : s.hostile_events > s.events * 0.25 ? '#f5b042' : '#38bdf8',
      }));
    }
    return [];
  }, [stats]);
  const maxZone = hotZones.reduce((m,z) => Math.max(m, z.n), 1);

  const totalEvents   = stats?.total_events ?? allRows.length;
  const hostileEvents = stats?.hostile_events ?? 0;
  const uniqueSystems = stats?.unique_systems ?? '—';
  const topPilot      = stats?.top_pilots?.[0]?.name ?? '—';
  const totalReporters = stats?.unique_reporters ?? '—';

  return (
    <div data-screen-label="04 Killboard" style={{
      display: 'grid',
      gridTemplateRows: 'auto 1fr',
      gridTemplateColumns: '1fr 280px',
      gap: 5, padding: 5, height: 'calc(100vh - 30px)', boxSizing: 'border-box',
      minHeight: 0, overflow: 'hidden',
    }}>
      {/* STAT STRIP */}
      <div style={{ gridColumn: '1 / -1', display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 5 }}>
        {[
          { l: 'KILL EVENTS · 24h', v: allRows.length,    c: '#5be584' },
          { l: 'HOSTILE EVENTS',    v: hostileEvents,      c: '#ff5577' },
          { l: 'SISTEMI UNICI',     v: uniqueSystems,      c: '#38bdf8' },
          { l: 'EVENTI TOTALI',     v: totalEvents,        c: '#5be584' },
          { l: 'REPORTERS',         v: totalReporters,     c: '#f5b042' },
          { l: 'TOP THREAT',        v: topPilot,           c: '#38bdf8' },
        ].map((s,i) => (
          <Panel key={i} style={{ padding: '6px 10px', position: 'relative', overflow: 'hidden' }}>
            <Mono style={{ fontSize: 7.5, color: '#5b6577', letterSpacing: '0.3em' }}>{s.l}</Mono>
            <div style={{ marginTop: 2 }}>
              <Mono style={{ fontSize: typeof s.v === 'number' ? 18 : 11, color: s.c,
                              fontWeight: 700, display: 'block',
                              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                              fontVariantNumeric: 'tabular-nums' }}>
                {typeof s.v === 'number' ? s.v.toLocaleString() : s.v}
              </Mono>
            </div>
            <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0,
                          height: 2, background: 'rgba(56,189,248,0.08)' }}>
              <div style={{ height: '100%', width: '45%', background: s.c, opacity: 0.4 }}/>
            </div>
          </Panel>
        ))}
      </div>

      {/* KILL TABLE */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>
          ▸ KILL EVENTS
          <span style={{
            width: 6, height: 6, borderRadius: '50%', background: '#5be584',
            boxShadow: '0 0 6px #5be584', marginLeft: 8,
            animation: 'pulse 1.6s ease infinite',
          }}/>
          <Mono style={{ fontSize: 8, color: '#5be584', marginLeft: 4, letterSpacing: '0.2em' }}>LIVE</Mono>
          <span style={{ flex: 1 }}/>
          <div style={{ display: 'flex', gap: 2 }}>
            {['ALL','KILLS','LOSSES'].map(t => (
              <button key={t} onClick={() => setTab(t)} style={{
                background: tab === t ? '#38bdf8' : 'transparent',
                color: tab === t ? '#0a0e14' : '#8a96a8',
                border: '1px solid rgba(56,189,248,0.3)',
                padding: '1px 6px', borderRadius: 1,
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 8.5, letterSpacing: '0.18em', cursor: 'pointer',
              }}>{t}</button>
            ))}
          </div>
        </PanelHeader>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '50px 64px 1.2fr 1.4fr 60px 40px 10px',
          gap: 6, padding: '3px 8px',
          background: 'rgba(56,189,248,0.04)',
          borderBottom: '1px solid rgba(56,189,248,0.1)',
        }}>
          {['TIME','SYSTEM','VITTIMA','AGGRESSORI','VAL','K/L',''].map((h,i) =>
            <Mono key={i} style={{ fontSize: 7.5, color: '#5b6577', letterSpacing: '0.25em' }}>{h}</Mono>
          )}
        </div>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {loading && (
            <div style={{ padding: 16, textAlign: 'center' }}>
              <Mono style={{ fontSize: 9, color: '#5b6577', letterSpacing: '0.3em' }}>CARICAMENTO…</Mono>
            </div>
          )}
          {!loading && filtered.length === 0 && (
            <div style={{ padding: 16, textAlign: 'center' }}>
              <Mono style={{ fontSize: 9, color: '#5b6577', letterSpacing: '0.3em' }}>NESSUN KILL EVENT</Mono>
            </div>
          )}
          {filtered.map(r => {
            const isFlash = flashId === r.id;
            const borderCol = r.loss ? '#ff5577' : '#5be584';
            return (
              <a key={r.id}
                 href={zkillUrl({ pilot: r.victim !== '—' ? r.victim : null })}
                 target="_blank" rel="noopener noreferrer"
                 style={{
                   display: 'grid',
                   gridTemplateColumns: '50px 64px 1.2fr 1.4fr 60px 40px 10px',
                   gap: 6, padding: '4px 8px',
                   borderBottom: '1px solid rgba(56,189,248,0.06)',
                   alignItems: 'center',
                   borderLeft: '2px solid ' + borderCol,
                   textDecoration: 'none',
                   background: isFlash ? 'rgba(91,229,132,0.16)' : 'transparent',
                   transition: 'background 1.4s ease',
                 }}
                 onMouseEnter={(e) => { if(!isFlash) e.currentTarget.style.background='rgba(56,189,248,0.06)'; }}
                 onMouseLeave={(e) => { if(!isFlash) e.currentTarget.style.background='transparent'; }}>
                <Mono style={{ fontSize: 8.5, color: '#5b6577' }}>{r.time}</Mono>
                <Mono style={{ fontSize: 9, color: '#38bdf8', fontWeight: 600, letterSpacing: '0.05em' }}>{r.sys}</Mono>
                <Mono style={{ fontSize: 9.5, color: '#e8ecf2', fontWeight: 600,
                                overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {r.victim}
                </Mono>
                <Mono style={{ fontSize: 9, color: '#cbd5df',
                                overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {r.attackers}
                </Mono>
                <Mono style={{ fontSize: 9.5, color: r.loss ? '#ff5577' : '#5be584',
                                fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>
                  {r.value}
                </Mono>
                <Pill color={r.loss ? 'red' : 'green'}>{r.loss ? 'L' : 'K'}</Pill>
                <Mono style={{ fontSize: 8, color: '#5b6577', textAlign: 'right' }}>↗</Mono>
              </a>
            );
          })}
        </div>
      </Panel>

      {/* RIGHT */}
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>▸ ACTIVITY · 24h</PanelHeader>
        <div style={{ padding: '8px' }}>
          <svg width="100%" height="64" viewBox="0 0 260 64" preserveAspectRatio="none">
            {[0,1,2,3].map(i => <line key={i} x1="0" y1={i*15+5} x2="260" y2={i*15+5}
                                       stroke="rgba(56,189,248,0.06)"/>)}
            {actData.map((h,i) => {
              const hp = Math.max(2, (h / (Math.max(...actData) || 1)) * 56);
              return (
                <rect key={i} x={i*10+2} y={62-hp} width="8" height={hp}
                      fill={i === actData.length-1 ? '#38bdf8' : '#5be584'}
                      opacity={i === actData.length-1 ? 1 : 0.7}/>
              );
            })}
          </svg>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>
            <Mono style={{ fontSize: 8, color: '#5b6577' }}>00:00</Mono>
            <Mono style={{ fontSize: 8, color: '#38bdf8' }}>NOW</Mono>
          </div>
        </div>

        <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>ISK DESTROYED · 24h</Mono>
          <Sparkline data={iskWalk} width={244} height={32} color="#5be584"/>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>
            <TickValue value={Math.round(iskWalk[iskWalk.length-1]*10)/10}
              format={(v) => v.toFixed(1)+'B'} color="#5be584"
              style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9, fontWeight: 600 }}/>
            <Mono style={{ fontSize: 8, color: '#5be584' }}>▲ stima</Mono>
          </div>
        </div>

        {hotZones.length > 0 && (
          <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
            <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>HOT ZONES</Mono>
            <div style={{ marginTop: 6 }}>
              {hotZones.map(s => (
                <div key={s.sys} style={{ marginBottom: 5 }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 2 }}>
                    <Mono style={{ fontSize: 9, color: '#38bdf8', fontWeight: 600 }}>{s.sys}</Mono>
                    <Mono style={{ fontSize: 9, color: '#cbd5df' }}>{s.n}</Mono>
                  </div>
                  <div style={{ height: 3, background: 'rgba(56,189,248,0.1)' }}>
                    <div style={{ width: (s.n/maxZone*100) + '%', height: '100%', background: s.c }}/>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)', flex: 1 }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>TOP SHIPS LOST</Mono>
          <div style={{ marginTop: 6 }}>
            {[
              { ship: 'Rorqual',  c: 12, isk: '18.4B' },
              { ship: 'Vargur',   c: 8,  isk: '12.2B' },
              { ship: 'Loki',     c: 24, isk: '8.6B'  },
              { ship: 'Cerberus', c: 18, isk: '5.2B'  },
              { ship: 'Sabre',    c: 42, isk: '2.4B'  },
            ].map((s,i) => (
              <div key={s.ship} style={{
                display: 'grid', gridTemplateColumns: '1fr 30px 36px auto',
                gap: 5, alignItems: 'center', padding: '3px 0',
                borderBottom: '1px solid rgba(56,189,248,0.06)',
              }}>
                <Mono style={{ fontSize: 9, color: '#e8ecf2', fontWeight: 600 }}>{s.ship}</Mono>
                <Mono style={{ fontSize: 9, color: '#cbd5df' }}>{'x'+s.c}</Mono>
                <Sparkline data={shipSparks[i]} width={36} height={12} color="#ff5577" fill={false}/>
                <Mono style={{ fontSize: 9, color: '#ff5577', fontWeight: 600, textAlign: 'right',
                                fontVariantNumeric: 'tabular-nums' }}>{s.isk}</Mono>
              </div>
            ))}
          </div>
        </div>
      </Panel>
    </div>
  );
}

/* ────────────────────────────── SETTINGS PAGE ──────────────────────────────── */
const SETTINGS_GROUPS = [
  { name: 'RADAR', items: [
    { k: 'radar_hops',    label: 'Jump range',         type: 'number', v: 2 },
    { k: 'radar_refresh', label: 'Refresh interval',   type: 'select', v: '30s' },
    { k: 'radar_alerts',  label: 'Audio alerts',       type: 'toggle', v: true },
    { k: 'radar_focus',   label: 'Auto-focus on login',type: 'toggle', v: true },
    { k: 'radar_filter',  label: 'Default filter',     type: 'select', v: 'ALL' },
  ]},
  { name: 'INTEL', items: [
    { k: 'intel_minSev',  label: 'Min severity shown', type: 'select', v: 'low' },
    { k: 'intel_sound',   label: 'Sound on HOSTILE',   type: 'toggle', v: true },
    { k: 'intel_flash',   label: 'Flash on new intel', type: 'toggle', v: true },
    { k: 'intel_limit',   label: 'Max rows',           type: 'number', v: 200 },
  ]},
  { name: 'MARKET', items: [
    { k: 'mkt_hub',       label: 'Default hub',        type: 'select', v: 'Jita IV-4' },
    { k: 'mkt_tick',      label: 'Price tick speed',   type: 'select', v: '1.2s' },
    { k: 'mkt_currency',  label: 'Currency display',   type: 'select', v: 'ISK (M)' },
  ]},
  { name: 'DISPLAY', items: [
    { k: 'ui_theme',      label: 'Theme',              type: 'select', v: 'Dark HUD' },
    { k: 'ui_font',       label: 'Font',               type: 'select', v: 'JetBrains Mono' },
    { k: 'ui_compact',    label: 'Compact rows',       type: 'toggle', v: false },
    { k: 'ui_animations', label: 'Animations',         type: 'toggle', v: true },
  ]},
  { name: 'ACCOUNT', items: [
    { k: 'acc_esi',       label: 'ESI connection',     type: 'select', v: 'Connected' },
    { k: 'acc_sync',      label: 'Auto-sync on login', type: 'toggle', v: true },
  ]},
];

function SettingsPage() {
  const [state, setState] = useState2(() => {
    const o = {};
    SETTINGS_GROUPS.forEach(g => g.items.forEach(it => o[it.k] = it.v));
    return o;
  });
  const [saving, setSaving] = useState2(false);
  const saveTimer = useRef2(null);
  const [sessionSec, setSessionSec] = useState2(45720);

  useEffect2(() => {
    const id = setInterval(() => setSessionSec(s => s + 1), 1000);
    return () => clearInterval(id);
  }, []);

  const fmtSession = (s) => {
    const h = Math.floor(s/3600), m = Math.floor((s%3600)/60), sec = s%60;
    return h + 'h ' + String(m).padStart(2,'0') + 'm ' + String(sec).padStart(2,'0') + 's';
  };

  const set = (k, v) => {
    setState(s => ({ ...s, [k]: v }));
    setSaving(true);
    clearTimeout(saveTimer.current);
    saveTimer.current = setTimeout(() => setSaving(false), 900);
  };

  return (
    <div data-screen-label="05 Settings" style={{
      display: 'grid', gridTemplateColumns: '220px 1fr 260px',
      gap: 5, padding: 5, height: 'calc(100vh - 30px)', boxSizing: 'border-box',
      minHeight: 0, overflow: 'hidden',
    }}>
      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>▸ SECTIONS</PanelHeader>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {SETTINGS_GROUPS.map(g => (
            <a key={g.name} href={'#s-' + g.name} style={{
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              padding: '6px 8px', textDecoration: 'none',
              borderLeft: '2px solid transparent',
              borderBottom: '1px solid rgba(56,189,248,0.06)',
            }}>
              <Mono style={{ fontSize: 9, color: '#cbd5df', letterSpacing: '0.12em', fontWeight: 600 }}>{g.name}</Mono>
              <Mono style={{ fontSize: 8.5, color: '#5b6577' }}>{g.items.length}</Mono>
            </a>
          ))}
        </div>
        <div style={{ padding: '8px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>KEYBINDS</Mono>
          <div style={{ marginTop: 6 }}>
            {[['Quick search','Cmd K'],['Toggle audio','Cmd /'],['Refresh sensor','Cmd R'],['Settings','Cmd ,']].map(([l,k]) => (
              <div key={k} style={{ display: 'flex', justifyContent: 'space-between', padding: '2px 0' }}>
                <Mono style={{ fontSize: 8.5, color: '#5b6577' }}>{l}</Mono>
                <Mono style={{ fontSize: 8.5, color: '#38bdf8', fontWeight: 600 }}>{k}</Mono>
              </div>
            ))}
          </div>
        </div>
      </Panel>

      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>
          {'▸ PREFERENCES · ' + Object.keys(state).length + ' keys'}
          <span style={{ flex: 1 }}/>
          {saving ? <Pill color="amber">SAVING…</Pill> : <Pill color="green">● SAVED</Pill>}
        </PanelHeader>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {SETTINGS_GROUPS.map(g => (
            <div key={g.name} id={'s-' + g.name}>
              <div style={{
                padding: '6px 10px', background: 'rgba(56,189,248,0.04)',
                borderTop: '1px solid rgba(56,189,248,0.1)', borderBottom: '1px solid rgba(56,189,248,0.1)',
                display: 'flex', alignItems: 'center', gap: 8,
              }}>
                <Mono style={{ fontSize: 9, color: '#38bdf8', letterSpacing: '0.3em', fontWeight: 600 }}>{g.name}</Mono>
                <div style={{ flex: 1, height: 1, background: 'rgba(56,189,248,0.1)' }}/>
                <Mono style={{ fontSize: 8, color: '#5b6577' }}>{g.items.length + ' keys'}</Mono>
              </div>
              {g.items.map(it => {
                const v = state[it.k];
                return (
                  <div key={it.k} style={{
                    display: 'grid', gridTemplateColumns: '200px 1fr',
                    gap: 10, padding: '5px 10px',
                    borderBottom: '1px solid rgba(56,189,248,0.06)',
                    alignItems: 'center',
                  }}>
                    <Mono style={{ fontSize: 9.5, color: '#cbd5df', letterSpacing: '0.05em' }}>{it.label}</Mono>
                    <div>
                      {it.type === 'toggle' && (
                        <button onClick={() => set(it.k, !v)} style={{
                          width: 32, height: 14, padding: 0,
                          background: v ? '#38bdf8' : 'rgba(56,189,248,0.12)',
                          border: 'none', borderRadius: 7, position: 'relative', cursor: 'pointer',
                        }}>
                          <div style={{
                            position: 'absolute', top: 2, left: v ? 20 : 2,
                            width: 10, height: 10, borderRadius: '50%',
                            background: v ? '#0a0e14' : '#8a96a8',
                            transition: 'left 0.2s',
                          }}/>
                        </button>
                      )}
                      {it.type !== 'toggle' && (
                        <div style={{
                          display: 'inline-block', padding: '2px 8px',
                          background: 'rgba(56,189,248,0.06)',
                          border: '1px solid rgba(56,189,248,0.25)',
                          borderRadius: 1, fontFamily: "'JetBrains Mono', monospace",
                          fontSize: 9, color: '#38bdf8',
                        }}>{v}{it.type === 'select' ? ' ▾' : ''}</div>
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          ))}
        </div>
      </Panel>

      <Panel style={{ padding: 0, display: 'flex', flexDirection: 'column' }}>
        <PanelHeader>▸ ACCOUNT</PanelHeader>
        <div style={{ padding: '10px', textAlign: 'center' }}>
          <div style={{
            width: 60, height: 60, borderRadius: 2,
            background: 'linear-gradient(135deg, #38bdf8 0%, #2a6fdb 100%)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            margin: '0 auto 10px', boxShadow: '0 0 20px rgba(56,189,248,0.25)',
          }}>
            <Mono style={{ fontSize: 20, color: '#0a0e14', fontWeight: 700 }}>*</Mono>
          </div>
          <Mono style={{ fontSize: 11, color: '#e8ecf2', fontWeight: 600, display: 'block', letterSpacing: '0.1em' }}>
            EVE Monitor
          </Mono>
          <div style={{ display: 'flex', justifyContent: 'center', gap: 4, marginTop: 6 }}>
            <Pill color="green">● ONLINE</Pill>
            <Pill color="cyan">CAPSULEER</Pill>
          </div>
        </div>
        <div style={{ padding: '8px 10px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          {[
            { l: 'ESI',     v: 'CONNECTED', c: '#5be584' },
            { l: 'API',     v: 'Public read' },
            { l: 'SESSION', v: fmtSession(sessionSec), mono: true },
          ].map(r => (
            <div key={r.l} style={{
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              padding: '3px 0', borderBottom: '1px solid rgba(56,189,248,0.06)',
            }}>
              <Mono style={{ fontSize: 8, color: '#5b6577', letterSpacing: '0.25em' }}>{r.l}</Mono>
              <Mono style={{ fontSize: 9, color: r.c || '#cbd5df',
                              fontVariantNumeric: r.mono ? 'tabular-nums' : 'normal' }}>{r.v}</Mono>
            </div>
          ))}
        </div>
        <div style={{ padding: '10px', borderTop: '1px solid rgba(56,189,248,0.15)', flex: 1 }}>
          <Mono style={{ fontSize: 8.5, color: '#5b6577', letterSpacing: '0.28em' }}>SYSTEM HEALTH</Mono>
          <div style={{ marginTop: 6 }}>
            {[
              { l: 'Sensor',   v: 98, c: '#5be584' },
              { l: 'ESI',      v: 94, c: '#5be584' },
              { l: 'zKill WS', v: 88, c: '#5be584' },
              { l: 'Market',   v: 72, c: '#f5b042' },
            ].map(s => (
              <div key={s.l} style={{ marginBottom: 5 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 2 }}>
                  <Mono style={{ fontSize: 8.5, color: '#cbd5df' }}>{s.l}</Mono>
                  <Mono style={{ fontSize: 9, color: s.c, fontWeight: 600 }}>{s.v + '%'}</Mono>
                </div>
                <div style={{ height: 3, background: 'rgba(56,189,248,0.1)' }}>
                  <div style={{ width: s.v + '%', height: '100%', background: s.c }}/>
                </div>
              </div>
            ))}
          </div>
        </div>
        <div style={{ padding: '8px 10px', borderTop: '1px solid rgba(56,189,248,0.15)' }}>
          <Mono style={{ fontSize: 11, color: '#e8ecf2', fontWeight: 600, display: 'block' }}>v0.7.4 · build 2603</Mono>
          <Mono style={{ fontSize: 8, color: '#5b6577', display: 'block', marginTop: 4, lineHeight: 1.6 }}>
            EVE Monitor · third-party · not affiliated CCP · EULA compliant
          </Mono>
        </div>
      </Panel>
    </div>
  );
}

Object.assign(window, { IntelPage, MarketPage, KillsPage, SettingsPage, Sparkline, TickValue });
