/* Clear Mint — Financial Health themed kit (light + dark).
   Shared chrome + charts for the four FH pages. Theme flows through
   window.FHTheme (React context); every component reads its palette
   from context so a single toggle re-skins all four pages.
   Depends on: React, window.CMIcon, window.CMChart (ECharts), window.echarts. */
(function () {
  const I = window.CMIcon;
  const round = n => Math.round(n);

  /* ---------------- palettes ---------------- */
  const DARK = {
    name: 'dark',
    bg: '#0E1A14', panel: '#13241C', panel2: '#16291F', sunk: '#0F1E17',
    line: 'rgba(255,255,255,.08)', line2: 'rgba(255,255,255,.14)',
    ink: '#EAF1EC', sub: 'rgba(232,239,233,.6)', mut: 'rgba(232,239,233,.4)',
    emerald: '#3ECF8E', emDeep: '#16A34A', gold: '#E6C878', red: '#F0876B',
    blue: '#5B9BD5', amber: '#E0A458', purple: '#A78BDA', plum: '#8A6E9E', teal: '#4FC4B0',
    track: 'rgba(255,255,255,.09)', chip: 'rgba(255,255,255,.05)', tab: 'rgba(255,255,255,.05)',
    grid: 'rgba(255,255,255,.07)', good: '#3ECF8E', shadow: '0 18px 40px -22px rgba(0,0,0,.6)'
  };
  const LIGHT = {
    name: 'light',
    bg: '#F4F0E6', panel: '#FFFFFF', panel2: '#FBF9F3', sunk: '#F6F2E8',
    line: '#ECE6D8', line2: '#E0D8C7',
    ink: '#16241D', sub: '#6B7A70', mut: '#98A39B',
    emerald: '#10915F', emDeep: '#0F6B4F', gold: '#B8942A', red: '#C35B5B',
    blue: '#3E7CC4', amber: '#C8742E', purple: '#7848C0', plum: '#8A6E9E', teal: '#0E9F8E',
    track: 'rgba(20,40,30,.08)', chip: '#F4F0E6', tab: '#F1ECE0',
    grid: 'rgba(20,40,30,.07)', good: '#10915F', shadow: '0 16px 34px -24px rgba(20,40,30,.28)'
  };
  const FHTheme = window.FHTheme || React.createContext(LIGHT);
  window.FHTheme = FHTheme;
  const useC = () => React.useContext(FHTheme);
  function hexA(hex, a) { const h = hex.replace('#', ''); if (h.length < 6) return hex; const r = parseInt(h.slice(0, 2), 16), g = parseInt(h.slice(2, 4), 16), b = parseInt(h.slice(4, 6), 16); return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; }

  const ICMAP = { Grow:'Grow', Goals:'Goals', Card:'Card', Shield:'Shield', Pie:'Pie', Insurance:'Insurance', Investments:'Investments', Vault:'Vault', Refresh:'Repeat', Reports:'Reports', House:'House', Bars:'Bars', Spark:'Spark', Info:'Info', Wallet:'Wallet' };
  function Icon({ name, size = 18 }) { const C = ICMAP[name] || 'Grow'; const Cmp = I[C] || I.Grow; return React.createElement(Cmp, { size }); }
  window.FHIcon = Icon;

  /* ---------------- chrome ---------------- */
  function Card({ title, info, right, children, style, pad = 20, className }) {
    const C = useC();
    return React.createElement('div', { className, style: Object.assign({ background: C.panel, border: '1px solid ' + C.line, borderRadius: 18, padding: pad, boxShadow: C.shadow }, style || {}) },
      (title || right) ? React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 14 } },
        React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 7, minWidth: 0 } },
          React.createElement('span', { style: { fontWeight: 800, fontSize: 15, color: C.ink, fontFamily: 'var(--font-serif)' } }, title),
          info ? React.createElement(I.Info, { size: 14, style: { color: C.mut, flexShrink: 0 } }) : null),
        right || null) : null,
      children);
  }
  window.FHCard = Card;

  function Pill({ children, color, soft, style }) {
    const C = useC();
    const c = color || C.emerald;
    return React.createElement('span', { style: Object.assign({ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 11.5, fontWeight: 800, color: c, background: hexA(c, C.name === 'dark' ? 0.16 : 0.12), padding: '3px 9px', borderRadius: 999, whiteSpace: 'nowrap' }, style || {}) }, children);
  }
  window.FHPill = Pill;

  function ChipIcon({ name, color, size = 38, radius = 11 }) {
    const C = useC();
    const c = color || C.emerald;
    return React.createElement('span', { style: { width: size, height: size, flex: '0 0 ' + size + 'px', borderRadius: radius, background: hexA(c, C.name === 'dark' ? 0.18 : 0.13), color: c, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' } }, React.createElement(Icon, { name, size: Math.round(size * 0.46) }));
  }
  window.FHChip = ChipIcon;

  function Segmented({ options, value, onChange, size = 'md' }) {
    const C = useC();
    const pad = size === 'sm' ? '5px 10px' : '7px 14px';
    return React.createElement('div', { style: { display: 'inline-flex', gap: 2, background: C.tab, border: '1px solid ' + C.line, borderRadius: 10, padding: 3 } },
      options.map(o => { const v = typeof o === 'string' ? o : o.v; const l = typeof o === 'string' ? o : o.l;
        const on = v === value;
        return React.createElement('button', { key: v, onClick: () => onChange && onChange(v),
          style: { border: 0, background: on ? hexA(C.emerald, C.name === 'dark' ? 0.18 : 0.14) : 'transparent', color: on ? C.emerald : C.sub, fontWeight: 700, fontSize: size === 'sm' ? 11.5 : 12.5, padding: pad, borderRadius: 8, cursor: 'pointer', fontFamily: 'inherit', whiteSpace: 'nowrap', transition: '.15s' } }, l); }));
  }
  window.FHSegmented = Segmented;

  function Select({ options, value, onChange, icon }) {
    const C = useC();
    const [open, setOpen] = React.useState(false);
    const ref = React.useRef(null);
    React.useEffect(() => { const h = e => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }; document.addEventListener('mousedown', h); return () => document.removeEventListener('mousedown', h); }, []);
    return React.createElement('div', { ref, style: { position: 'relative' } },
      React.createElement('button', { onClick: () => setOpen(o => !o), style: { display: 'inline-flex', alignItems: 'center', gap: 7, background: C.panel, border: '1px solid ' + C.line2, color: C.ink, borderRadius: 10, padding: '8px 12px', fontSize: 12.5, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit' } },
        icon ? React.createElement(I.Calendar, { size: 14, style: { color: C.sub } }) : null, value, React.createElement(I.Chevron, { size: 13, style: { color: C.sub } })),
      open ? React.createElement('div', { style: { position: 'absolute', top: '100%', right: 0, marginTop: 6, background: C.panel, border: '1px solid ' + C.line2, borderRadius: 12, padding: 5, minWidth: 180, zIndex: 40, boxShadow: '0 18px 40px -16px rgba(0,0,0,.4)' } },
        options.map(o => React.createElement('button', { key: o, onClick: () => { onChange && onChange(o); setOpen(false); }, style: { display: 'block', width: '100%', textAlign: 'left', border: 0, background: o === value ? hexA(C.emerald, 0.12) : 'transparent', color: o === value ? C.emerald : C.ink, padding: '8px 11px', borderRadius: 8, fontSize: 12.5, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' } }, o))) : null);
  }
  window.FHSelect = Select;

  function Bar({ pct, color, height = 7, track }) {
    const C = useC();
    return React.createElement('div', { style: { height, borderRadius: 999, background: track || C.track, overflow: 'hidden', flex: 1 } },
      React.createElement('div', { style: { height: '100%', width: Math.max(0, Math.min(100, pct)) + '%', borderRadius: 999, background: color || C.emerald, transition: 'width .5s cubic-bezier(.4,0,.2,1)' } }));
  }
  window.FHBar = Bar;

  function ThemeToggle({ value, onChange }) {
    const C = useC();
    const sun = React.createElement('svg', { width: 13, height: 13, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2 }, React.createElement('circle', { cx: 12, cy: 12, r: 4 }), React.createElement('path', { d: 'M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5L19 19M19 5l-1.5 1.5M6.5 17.5L5 19', strokeLinecap: 'round' }));
    const moon = React.createElement('svg', { width: 13, height: 13, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2 }, React.createElement('path', { d: 'M21 12.8A9 9 0 1111.2 3 7 7 0 0021 12.8z' }));
    return React.createElement('div', { style: { display: 'inline-flex', background: C.tab, border: '1px solid ' + C.line, borderRadius: 999, padding: 3 } },
      [['light', 'Light', sun], ['dark', 'Dark', moon]].map(o => React.createElement('button', { key: o[0], onClick: () => onChange(o[0]),
        style: { border: 0, background: value === o[0] ? (C.name === 'dark' ? hexA(C.emerald, 0.2) : '#0F3D2C') : 'transparent', color: value === o[0] ? (C.name === 'dark' ? C.emerald : '#fff') : C.sub, fontWeight: 700, fontSize: 12, padding: '6px 14px', borderRadius: 999, cursor: 'pointer', fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 6 } }, o[2], o[1])));
  }
  window.FHThemeToggle = ThemeToggle;

  /* ---------------- charts ---------------- */
  function axisLabel(C) { return { color: C.sub, fontSize: 11 }; }
  function tip(C) { return { trigger: 'axis', backgroundColor: C.name === 'dark' ? 'rgba(8,20,14,.96)' : 'rgba(15,40,30,.95)', borderWidth: 0, padding: [9, 13], textStyle: { color: '#EAF1EC', fontSize: 12 }, extraCssText: 'border-radius:10px;box-shadow:0 12px 30px -12px rgba(8,20,13,.5);' }; }

  // Multi-series area / line
  function Line({ series, x, height = 230, money = false, yFmt, area = true, smooth = true, dotsLast }) {
    const C = useC(); const e = window.echarts; const E = window.CMChart || {};
    const ser = (series || []).map(s => ({
      name: s.name, type: 'line', data: s.data, smooth: smooth, showSymbol: !!s.dots, symbol: 'circle', symbolSize: 6,
      lineStyle: { width: s.width || 2.6, color: s.color, type: s.dashed ? 'dashed' : 'solid', shadowColor: hexA(s.color, .3), shadowBlur: s.dashed ? 0 : 10, shadowOffsetY: 5 },
      itemStyle: { color: s.color, borderColor: C.panel, borderWidth: 2 },
      areaStyle: (area && s.fill !== false && !s.dashed) ? { color: e ? new e.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: hexA(s.color, C.name === 'dark' ? .34 : .26) }, { offset: 1, color: hexA(s.color, 0) }]) : hexA(s.color, .2) } : undefined,
      z: s.z || 1
    }));
    const option = e ? {
      animationDuration: 700, color: ser.map(s => s.lineStyle.color),
      legend: { show: (series || []).length > 1, top: 0, right: 0, icon: 'roundRect', itemWidth: 9, itemHeight: 9, textStyle: { color: C.sub, fontSize: 11.5, fontWeight: 600 } },
      grid: { left: 6, right: 14, top: (series || []).length > 1 ? 26 : 12, bottom: 4, containLabel: true },
      tooltip: Object.assign(tip(C), { valueFormatter: v => yFmt ? yFmt(v) : (money ? E.fmtCompact(v) : v) }),
      xAxis: { type: 'category', data: x, boundaryGap: false, axisLine: { lineStyle: { color: C.grid } }, axisTick: { show: false }, axisLabel: axisLabel(C) },
      yAxis: { type: 'value', splitLine: { lineStyle: { color: C.grid } }, axisLine: { show: false }, axisTick: { show: false }, axisLabel: Object.assign({}, axisLabel(C), { formatter: v => yFmt ? yFmt(v) : (money ? E.fmtCompact(v) : v) }) },
      series: ser
    } : {};
    return React.createElement(E.EChart, { option, height, dark: C.name === 'dark', empty: !(series && series.length) });
  }
  window.FHLine = Line;

  // Grouped/stacked bars (+ optional overlay line)
  function Bars({ series, x, height = 230, money = true, stack = false, line }) {
    const C = useC(); const e = window.echarts; const E = window.CMChart || {};
    const ser = (series || []).map(s => ({ name: s.name, type: 'bar', stack: stack ? 't' : undefined, data: s.data, barMaxWidth: 22, itemStyle: { borderRadius: stack ? 0 : [5, 5, 0, 0], color: s.color }, emphasis: { itemStyle: { color: hexA(s.color, .85) } } }));
    if (line) ser.push({ name: line.name, type: 'line', data: line.data, smooth: true, symbol: 'circle', symbolSize: 6, lineStyle: { color: line.color, width: 2.4 }, itemStyle: { color: line.color }, z: 5 });
    const option = e ? {
      animationDuration: 700,
      legend: { show: true, top: 0, right: 0, icon: 'roundRect', itemWidth: 9, itemHeight: 9, textStyle: { color: C.sub, fontSize: 11.5, fontWeight: 600 } },
      grid: { left: 6, right: 12, top: 28, bottom: 4, containLabel: true },
      tooltip: Object.assign(tip(C), { axisPointer: { type: 'shadow' }, valueFormatter: v => money ? E.fmtCompact(v) : v }),
      xAxis: { type: 'category', data: x, axisLine: { lineStyle: { color: C.grid } }, axisTick: { show: false }, axisLabel: axisLabel(C) },
      yAxis: { type: 'value', splitLine: { lineStyle: { color: C.grid } }, axisLine: { show: false }, axisTick: { show: false }, axisLabel: Object.assign({}, axisLabel(C), { formatter: v => money ? E.fmtCompact(v) : v }) },
      series: ser
    } : {};
    return React.createElement(E.EChart, { option, height, dark: C.name === 'dark', empty: !(series && series.length) });
  }
  window.FHBars = Bars;

  // Radar
  function Radar({ axes, datasets, height = 320 }) {
    const C = useC(); const e = window.echarts; const E = window.CMChart || {};
    const option = e ? {
      animationDuration: 700,
      tooltip: Object.assign(tip(C), { trigger: 'item' }),
      legend: { show: datasets.length > 1, bottom: 0, icon: 'roundRect', itemWidth: 9, itemHeight: 9, textStyle: { color: C.sub, fontSize: 12, fontWeight: 600 } },
      radar: {
        indicator: axes.map(a => ({ name: a.label, max: 100 })), splitNumber: 4, center: ['50%', '48%'], radius: '66%',
        axisName: { color: C.sub, fontSize: 11, fontWeight: 600 },
        splitLine: { lineStyle: { color: C.grid } }, axisLine: { lineStyle: { color: C.grid } },
        splitArea: { areaStyle: { color: [hexA(C.emerald, .03), hexA(C.emerald, .06)] } }
      },
      series: [{ type: 'radar', data: datasets.map(d => ({ value: d.values, name: d.name,
        symbol: d.dashed ? 'none' : 'circle', symbolSize: 4,
        lineStyle: { color: d.color, width: d.dashed ? 1.6 : 2.4, type: d.dashed ? 'dashed' : 'solid' },
        itemStyle: { color: d.color }, areaStyle: d.fill === false ? undefined : { color: hexA(d.color, C.name === 'dark' ? .22 : .16) } })) }]
    } : {};
    return React.createElement(E.EChart, { option, height, dark: C.name === 'dark', empty: !axes });
  }
  window.FHRadar = Radar;

  // Semicircle gauge
  function Gauge({ value, size = 180, label, thickness }) {
    const C = useC();
    const W = size, H = Math.round(size * 0.62), t = thickness || Math.round(size * 0.11), cx = W / 2, cy = H - 8, r = (W - t) / 2 - 2;
    const arc = (a, b) => { const x1 = cx + r * Math.cos(a), y1 = cy + r * Math.sin(a), x2 = cx + r * Math.cos(b), y2 = cy + r * Math.sin(b); return 'M ' + x1 + ' ' + y1 + ' A ' + r + ' ' + r + ' 0 ' + (b - a > Math.PI ? 1 : 0) + ' 1 ' + x2 + ' ' + y2; };
    const f = Math.max(0, Math.min(1, value / 100)), end = Math.PI + f * Math.PI;
    const gid = 'fhg' + size + round(value);
    return React.createElement('div', { style: { position: 'relative', width: W, height: H } },
      React.createElement('svg', { width: W, height: H + 4, viewBox: '0 0 ' + W + ' ' + (H + 4) },
        React.createElement('defs', null, React.createElement('linearGradient', { id: gid, x1: 0, y1: 0, x2: 1, y2: 0 }, React.createElement('stop', { offset: '0%', stopColor: '#C35B5B' }), React.createElement('stop', { offset: '50%', stopColor: C.gold }), React.createElement('stop', { offset: '100%', stopColor: C.emerald }))),
        React.createElement('path', { d: arc(Math.PI, 2 * Math.PI), fill: 'none', stroke: C.track, strokeWidth: t, strokeLinecap: 'round' }),
        React.createElement('path', { d: arc(Math.PI, end), fill: 'none', stroke: 'url(#' + gid + ')', strokeWidth: t, strokeLinecap: 'round' }),
        React.createElement('circle', { cx: cx + r * Math.cos(end), cy: cy + r * Math.sin(end), r: t * 0.4, fill: '#fff', stroke: C.emDeep, strokeWidth: 2 })),
      React.createElement('div', { style: { position: 'absolute', inset: 0, top: H * 0.22, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' } },
        React.createElement('div', { style: { fontFamily: 'var(--font-serif)', fontWeight: 800, fontSize: size * 0.27, color: C.ink, lineHeight: 1 } }, round(value)),
        label ? React.createElement('div', { style: { fontSize: size * 0.075, color: C.sub, fontWeight: 700, marginTop: 2 } }, label) : null));
  }
  window.FHGauge = Gauge;

  // Weight donut (single value ring with center label)
  function Donut({ value, size = 120, label, sub, color }) {
    const C = useC(); const c = color || C.emerald;
    const r = (size - 14) / 2, circ = 2 * Math.PI * r, off = circ * (1 - value / 100);
    return React.createElement('div', { style: { position: 'relative', width: size, height: size } },
      React.createElement('svg', { width: size, height: size, viewBox: '0 0 ' + size + ' ' + size },
        React.createElement('circle', { cx: size / 2, cy: size / 2, r, fill: 'none', stroke: C.track, strokeWidth: 11 }),
        React.createElement('circle', { cx: size / 2, cy: size / 2, r, fill: 'none', stroke: c, strokeWidth: 11, strokeLinecap: 'round', strokeDasharray: circ, strokeDashoffset: off, transform: 'rotate(-90 ' + size / 2 + ' ' + size / 2 + ')', style: { transition: 'stroke-dashoffset .6s' } })),
      React.createElement('div', { style: { position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' } },
        React.createElement('div', { style: { fontFamily: 'var(--font-serif)', fontWeight: 800, fontSize: size * 0.26, color: C.ink } }, label),
        sub ? React.createElement('div', { style: { fontSize: 10.5, color: C.sub, fontWeight: 700, marginTop: 1 } }, sub) : null));
  }
  window.FHDonut = Donut;

  // Bell-curve distribution with "you / median / average" markers
  function BellCurve({ youPct = 0.6, height = 150, color, ticks, youLabel = 'You', youTop }) {
    const C = useC(); const c = color || C.emerald;
    const W = 320, H = height, pad = 8, baseY = H - 22;
    const mu = W / 2, sigma = W / 7;
    const gy = x => { const z = (x - mu) / sigma; return baseY - Math.exp(-0.5 * z * z) * (baseY - pad); };
    let d = 'M ' + pad + ' ' + baseY; for (let x = pad; x <= W - pad; x += 4) d += ' L ' + x.toFixed(1) + ' ' + gy(x).toFixed(1); d += ' L ' + (W - pad) + ' ' + baseY + ' Z';
    const youX = pad + youPct * (W - 2 * pad);
    let fillD = 'M ' + pad + ' ' + baseY; for (let x = pad; x <= youX; x += 4) fillD += ' L ' + x.toFixed(1) + ' ' + gy(x).toFixed(1); fillD += ' L ' + youX.toFixed(1) + ' ' + baseY + ' Z';
    const gid = 'bc' + round(youPct * 100) + C.name;
    return React.createElement('div', { style: { width: '100%' } },
      React.createElement('svg', { viewBox: '0 0 ' + W + ' ' + (H + 14), width: '100%', style: { display: 'block' } },
        React.createElement('defs', null, React.createElement('linearGradient', { id: gid, x1: 0, y1: 0, x2: 0, y2: 1 }, React.createElement('stop', { offset: '0%', stopColor: hexA(c, .4) }), React.createElement('stop', { offset: '100%', stopColor: hexA(c, 0) }))),
        React.createElement('path', { d, fill: hexA(C.ink, C.name === 'dark' ? .06 : .05), stroke: C.line2, strokeWidth: 1 }),
        React.createElement('path', { d: fillD, fill: 'url(#' + gid + ')' }),
        React.createElement('line', { x1: youX, y1: gy(youX), x2: youX, y2: baseY, stroke: c, strokeWidth: 2 }),
        React.createElement('circle', { cx: youX, cy: gy(youX), r: 4.5, fill: c, stroke: C.panel, strokeWidth: 2 }),
        React.createElement('line', { x1: pad, y1: baseY, x2: W - pad, y2: baseY, stroke: C.line2, strokeWidth: 1 }),
        ticks ? ticks.map((t, i) => React.createElement('text', { key: i, x: pad + (i / (ticks.length - 1)) * (W - 2 * pad), y: baseY + 13, fill: C.mut, fontSize: 9.5, textAnchor: 'middle' }, t)) : null,
        React.createElement('g', null,
          React.createElement('rect', { x: Math.max(2, Math.min(W - 64, youX - 28)), y: gy(youX) - 30, width: 56, height: 20, rx: 6, fill: c }),
          React.createElement('text', { x: Math.max(30, Math.min(W - 36, youX)), y: gy(youX) - 16, fill: '#fff', fontSize: 10, fontWeight: 800, textAnchor: 'middle' }, youTop || youLabel))));
  }
  window.FHBellCurve = BellCurve;

  // Spending heatmap grid
  function Heatmap({ weeks, color, days = ['M', 'T', 'W', 'T', 'F', 'S', 'S'] }) {
    const C = useC(); const c = color || C.emerald;
    return React.createElement('div', { style: { display: 'flex', gap: 5 } },
      React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 4, justifyContent: 'space-between', paddingTop: 1 } },
        days.map((d, i) => React.createElement('div', { key: i, style: { fontSize: 9, color: C.mut, fontWeight: 700, height: 12, display: 'flex', alignItems: 'center' } }, d))),
      React.createElement('div', { style: { display: 'flex', gap: 4, flex: 1, overflow: 'hidden' } },
        (weeks || []).map((wk, wi) => React.createElement('div', { key: wi, style: { display: 'flex', flexDirection: 'column', gap: 4, flex: 1 } },
          wk.map((v, di) => React.createElement('div', { key: di, style: { aspectRatio: '1', borderRadius: 3, background: v < 0.05 ? C.track : hexA(c, 0.15 + v * 0.85), minHeight: 8 } }))))));
  }
  window.FHHeatmap = Heatmap;

  // Impact matrix (effort vs impact quadrants)
  function ImpactMatrix({ points, height = 300 }) {
    const C = useC();
    const W = 460, H = height, pad = 34;
    const px = e => pad + (e / 100) * (W - 2 * pad);
    const py = im => (H - pad) - (im / 100) * (H - 2 * pad);
    const quad = [
      { x: pad, y: pad, w: (W - 2 * pad) / 2, h: (H - 2 * pad) / 2, label: 'High Impact · Low Effort', good: true },
      { x: W / 2, y: pad, w: (W - 2 * pad) / 2, h: (H - 2 * pad) / 2, label: 'High Impact · High Effort' },
      { x: pad, y: H / 2, w: (W - 2 * pad) / 2, h: (H - 2 * pad) / 2, label: 'Low Impact · Low Effort' },
      { x: W / 2, y: H / 2, w: (W - 2 * pad) / 2, h: (H - 2 * pad) / 2, label: 'Low Impact · High Effort' }
    ];
    return React.createElement('svg', { viewBox: '0 0 ' + W + ' ' + H, width: '100%', style: { display: 'block' } },
      quad.map((q, i) => React.createElement('rect', { key: i, x: q.x, y: q.y, width: q.w, height: q.h, fill: q.good ? hexA(C.emerald, C.name === 'dark' ? .1 : .07) : 'transparent', stroke: C.grid, strokeWidth: 1 })),
      quad.map((q, i) => React.createElement('text', { key: 'l' + i, x: q.x + 8, y: q.y + 16, fill: q.good ? C.emerald : C.mut, fontSize: 9.5, fontWeight: 700 }, q.label)),
      React.createElement('text', { x: W / 2, y: H - 6, fill: C.sub, fontSize: 10.5, fontWeight: 700, textAnchor: 'middle' }, 'Effort →'),
      React.createElement('text', { x: 12, y: H / 2, fill: C.sub, fontSize: 10.5, fontWeight: 700, textAnchor: 'middle', transform: 'rotate(-90 12 ' + H / 2 + ')' }, 'Impact →'),
      (points || []).map((p, i) => React.createElement('g', { key: i },
        React.createElement('circle', { cx: px(p.effort), cy: py(p.impact), r: Math.max(9, p.size || 12), fill: hexA(p.color || C.emerald, .9), stroke: C.panel, strokeWidth: 2 }),
        React.createElement('text', { cx: px(p.effort), x: px(p.effort), y: py(p.impact) + 3.5, fill: '#fff', fontSize: 10, fontWeight: 800, textAnchor: 'middle' }, p.n))));
  }
  window.FHImpactMatrix = ImpactMatrix;

  // tiny sparkline
  function Spark({ data, color, w = 120, h = 36, fill = true }) {
    const C = useC(); const c = color || C.emerald;
    if (!data || !data.length) return null;
    const min = Math.min.apply(null, data), max = Math.max.apply(null, data), rng = (max - min) || 1;
    const X = i => (i / (data.length - 1)) * w, Y = v => h - 3 - ((v - min) / rng) * (h - 6);
    const line = data.map((v, i) => (i ? 'L' : 'M') + X(i).toFixed(1) + ',' + Y(v).toFixed(1)).join(' ');
    const gid = 'sp' + round(w + h + data[0]) + c.replace('#', '');
    return React.createElement('svg', { width: '100%', height: h, viewBox: '0 0 ' + w + ' ' + h, preserveAspectRatio: 'none', style: { display: 'block' } },
      fill ? React.createElement('defs', null, React.createElement('linearGradient', { id: gid, x1: 0, y1: 0, x2: 0, y2: 1 }, React.createElement('stop', { offset: '0%', stopColor: hexA(c, .28) }), React.createElement('stop', { offset: '100%', stopColor: hexA(c, 0) }))) : null,
      fill ? React.createElement('path', { d: line + ' L' + w + ',' + h + ' L0,' + h + ' Z', fill: 'url(#' + gid + ')' }) : null,
      React.createElement('path', { d: line, fill: 'none', stroke: c, strokeWidth: 2, strokeLinejoin: 'round', strokeLinecap: 'round' }));
  }
  window.FHSpark = Spark;

  window.FH_PALETTES = { DARK, DARK_: DARK, LIGHT, dark: DARK, light: LIGHT };
  window.FHhexA = hexA;
})();
