/* Clear Mint — Icon set (stroke, 18px grid, currentColor) */
const I = {};
const mk = (paths, fill=false) => ({size=18, ...p}) =>
  <svg width={size} height={size} viewBox="0 0 24 24" fill={fill?"currentColor":"none"}
       stroke={fill?"none":"currentColor"} strokeWidth="1.8" strokeLinecap="round"
       strokeLinejoin="round" {...p}>{paths}</svg>;

I.Dashboard = mk(<><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V21h14V9.5"/><path d="M9.5 21v-6h5v6"/></>);
I.Accounts  = mk(<><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 10h18"/></>);
I.Transactions = mk(<><path d="M4 7h13l-3-3"/><path d="M20 17H7l3 3"/></>);
I.Budget = mk(<><circle cx="12" cy="12" r="9"/><path d="M12 12V3a9 9 0 0 1 9 9z"/></>);
I.Bills = mk(<><path d="M6 3h12v18l-3-2-3 2-3-2-3 2z"/><path d="M9 8h6M9 12h6"/></>);
I.Subscriptions = mk(<><path d="M4 8a8 8 0 0 1 14-3"/><path d="M20 16a8 8 0 0 1-14 3"/><path d="M18 3v3h-3M6 21v-3h3"/></>);
I.Goals = mk(<><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1.4" fill="currentColor"/></>);
I.Investments = mk(<><path d="M4 18 10 12l3 3 7-7"/><path d="M16 8h4v4"/></>);
I.Liabilities = mk(<><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18M7 15h4"/></>);
I.Insurance = mk(<><path d="M12 3 5 6v5c0 4 3 7.5 7 9 4-1.5 7-5 7-9V6z"/><path d="m9 12 2 2 4-4"/></>);
I.Vault = mk(<><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="13" cy="12" r="3"/><path d="M13 9v-.5M16 12h.5"/></>);
I.Reports = mk(<><path d="M5 21V5a2 2 0 0 1 2-2h7l5 5v13z"/><path d="M14 3v5h5M8 13h7M8 17h7"/></>);
I.AI = mk(<><rect x="4" y="7" width="16" height="12" rx="3"/><path d="M12 3v4M8 13h.01M16 13h.01M9 16h6"/></>);
I.Settings = mk(<><circle cx="12" cy="12" r="3"/><path d="M19.4 13.5a7.6 7.6 0 0 0 0-3l1.6-1.2-2-3.4-1.9.8a7.6 7.6 0 0 0-2.6-1.5L13.5 2h-3l-.5 2.2a7.6 7.6 0 0 0-2.6 1.5l-1.9-.8-2 3.4 1.6 1.2a7.6 7.6 0 0 0 0 3L3 14.7l2 3.4 1.9-.8a7.6 7.6 0 0 0 2.6 1.5l.5 2.2h3l.5-2.2a7.6 7.6 0 0 0 2.6-1.5l1.9.8 2-3.4z"/></>);
I.Search = mk(<><circle cx="11" cy="11" r="7"/><path d="m20 20-3-3"/></>);
I.Bell = mk(<><path d="M6 9a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6"/><path d="M10 19a2 2 0 0 0 4 0"/></>);
I.Chevron = mk(<path d="m6 9 6 6 6-6"/>);
I.ChevR = mk(<path d="m9 6 6 6-6 6"/>);
I.ArrowUp = mk(<path d="M12 19V5M6 11l6-6 6 6"/>);
I.ArrowDown = mk(<path d="M12 5v14M6 13l6 6 6-6"/>);
I.Plus = mk(<path d="M12 5v14M5 12h14"/>);
I.Bolt = mk(<path d="M13 2 4 14h7l-1 8 9-12h-7z"/>);
I.Cal = mk(<><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 9h18M8 3v4M16 3v4"/></>);
I.Dollar = mk(<><circle cx="12" cy="12" r="9"/><path d="M12 7v10M9.5 9a2 2 0 0 1 2-1.5h1A2 2 0 0 1 14 11l-3 2a2 2 0 0 0 2 3.5h1a2 2 0 0 0 2-1.5"/></>);
I.Home = mk(<><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V21h14V9.5"/></>);
I.Car = mk(<><path d="M5 16v2M19 16v2"/><path d="M3 16v-3l2-5h14l2 5v3z"/><circle cx="7.5" cy="16" r="1.3"/><circle cx="16.5" cy="16" r="1.3"/></>);
I.Card = mk(<><rect x="3" y="6" width="18" height="12" rx="2"/><path d="M3 10h18"/></>);
I.Grow = mk(<><path d="M4 18 10 12l3 3 7-7"/><path d="M16 8h4v4"/></>);
I.Info = mk(<><circle cx="12" cy="12" r="9"/><path d="M12 11v5M12 8h.01"/></>);
I.Alert = mk(<><path d="M12 4 2.5 20h19z"/><path d="M12 10v4M12 17h.01"/></>);
I.Dots = mk(<><circle cx="5" cy="12" r="1.5" fill="currentColor"/><circle cx="12" cy="12" r="1.5" fill="currentColor"/><circle cx="19" cy="12" r="1.5" fill="currentColor"/></>);

/* extended set for app pages */
I.Dining = mk(<><path d="M6 3v8a2 2 0 0 0 4 0V3M8 11v10M16 3c-1.5 0-2.5 2-2.5 5s1 4 2.5 4v9"/></>);
I.Cart = mk(<><circle cx="9" cy="20" r="1.4"/><circle cx="17" cy="20" r="1.4"/><path d="M3 4h2l2.2 11h10l1.8-8H6"/></>);
I.Transport = mk(<><rect x="5" y="4" width="14" height="12" rx="2"/><path d="M5 11h14M8 16l-1 3M16 16l1 3M9 8h6"/></>);
I.Utilities = mk(<path d="M13 2 4 14h7l-1 8 9-12h-7z"/>);
I.Heart = mk(<path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.5A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/>);
I.Film = mk(<><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M7 4v16M17 4v16M3 9h4M3 15h4M17 9h4M17 15h4"/></>);
I.Plane = mk(<path d="M10 14 3 12l1-2 6 .5L14 4l2 .5-2 7 6 2v2l-6-1-2 5-1.5-.5z"/>);
I.Wallet = mk(<><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18M17 14h.01"/></>);
I.Transfer = mk(<><path d="M7 7h13l-3-3M17 17H4l3 3"/></>);
I.File = mk(<><path d="M6 2h8l4 4v16H6z"/><path d="M14 2v4h4M9 13h6M9 17h6"/></>);
I.Folder = mk(<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>);
I.Shield = mk(<><path d="M12 3 5 6v5c0 4 3 7.5 7 9 4-1.5 7-5 7-9V6z"/><path d="m9 12 2 2 4-4"/></>);
I.Spark = mk(<><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2 2M16 16l2 2M18 6l-2 2M8 16l-2 2"/><circle cx="12" cy="12" r="2.5"/></>);
I.User = mk(<><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-6 8-6s8 2 8 6"/></>);
I.Lock = mk(<><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></>);
I.Tag = mk(<><path d="M3 12V4h8l9 9-8 8z"/><circle cx="8" cy="8" r="1.4" fill="currentColor"/></>);
I.Calendar = mk(<><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 9h18M8 3v4M16 3v4"/></>);
I.Check = mk(<path d="M20 6 9 17l-5-5"/>);
I.Clock = mk(<><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>);
I.Repeat = mk(<><path d="M4 8a8 8 0 0 1 14-3M20 16a8 8 0 0 1-14 3"/><path d="M18 3v3h-3M6 21v-3h3"/></>);
I.Briefcase = mk(<><rect x="3" y="7" width="18" height="13" rx="2"/><path d="M8 7V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M3 13h18"/></>);
I.House = mk(<><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V21h14V9.5"/></>);
I.Bars = mk(<><path d="M5 20V10M12 20V4M19 20v-7"/></>);
I.Pie = mk(<><path d="M12 3v9h9a9 9 0 1 0-9-9z"/><path d="M21 12a9 9 0 0 1-9 9"/></>);
I.Gold = mk(<><path d="M4 16h16l-2-4H6z"/><path d="M8 12l1-3h6l1 3"/></>);
I.Art = mk(<><path d="M12 4v3M5 11a7 7 0 0 1 14 0v0H5z"/><path d="M12 11v7a2 2 0 0 0 2 2"/></>);
I.Bank = mk(<><path d="M3 9 12 4l9 5"/><path d="M5 9v9M9 9v9M15 9v9M19 9v9M3 18h18"/></>);
I.Logout = mk(<><path d="M15 4h3a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-3"/><path d="M10 17l-5-5 5-5M4 12h11"/></>);
I.Grip = mk(<><circle cx="9" cy="6" r="1.4" fill="currentColor" stroke="none"/><circle cx="9" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="9" cy="18" r="1.4" fill="currentColor" stroke="none"/><circle cx="15" cy="6" r="1.4" fill="currentColor" stroke="none"/><circle cx="15" cy="12" r="1.4" fill="currentColor" stroke="none"/><circle cx="15" cy="18" r="1.4" fill="currentColor" stroke="none"/></>);
I.Sun = mk(<><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5 19 19M19 5l-1.5 1.5M6.5 17.5 5 19"/></>);
I.Moon = mk(<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/>);
I.Chat = mk(<path d="M4 5h16v11H8l-4 4z"/>);

window.CMIcon = I;

/* ================= TrendChart (SVG area+line) ================= */
function TrendChart({ data, width=720, height=240, color="var(--green-500)",
                     yLabels=[], xLabels=[], pad=null, showDots=true, valueFormat=null }) {
  const P = pad || { l: 44, r: 16, t: 14, b: 26 };
  const w = width, h = height;
  const safe = (Array.isArray(data) && data.length) ? data.map(v=>Number(v)||0) : [0,0];
  const min = Math.min(...safe), max = Math.max(...safe);
  let lo = min - (max-min)*0.25, hi = max + (max-min)*0.1;
  if (hi - lo === 0) { lo = min - 1; hi = max + 1; }   // flat/empty data guard
  const n = safe.length;
  const X = i => P.l + (n>1 ? (i/(n-1)) : 0.5) * (w - P.l - P.r);
  const Y = v => P.t + (1-(v-lo)/(hi-lo)) * (h - P.t - P.b);
  const line = safe.map((v,i)=>`${i?'L':'M'}${X(i)},${Y(v)}`).join(' ');
  const area = `${line} L${X(n-1)},${h-P.b} L${X(0)},${h-P.b} Z`;
  const gid = "tg"+Math.round(width+height+data.length);
  const rows = yLabels.length || 6;
  // ── interactive hover: vertical guide + highlighted point + value tooltip ──
  const svgRef = React.useRef(null);
  const [hi_, setHi] = React.useState(null);
  const fmt = valueFormat || (v => Number(v).toLocaleString(undefined,{maximumFractionDigits:2}));
  const onMove = (e) => {
    const svg = svgRef.current; if(!svg || n<2) return;
    const r = svg.getBoundingClientRect(); if(!r.width) return;
    const sx = (e.clientX - r.left) * (w / r.width);            // client px → viewBox units
    let i = Math.round((sx - P.l) / ((w - P.l - P.r) / (n-1)));
    setHi(Math.max(0, Math.min(n-1, i)));
  };
  const tipX = hi_!=null ? Math.min(Math.max(X(hi_), P.l+28), w-P.r-28) : 0;
  const uid = gid, sheenId = "sh"+uid, clipId = "cl"+uid;
  // animation CSS: the line draws itself in, the area gently rises, and on hover a soft
  // sheen "wave" sweeps along the fill — so the chart visibly flows under the cursor.
  const css = `
    @keyframes cm-draw-${uid}{ to{ stroke-dashoffset:0; } }
    @keyframes cm-rise-${uid}{ from{ opacity:0; transform:translateY(10px) scaleY(.96); } to{ opacity:1; transform:none; } }
    @keyframes cm-sweep-${uid}{ from{ transform:translateX(${-w*0.45}px); } to{ transform:translateX(${w*1.15}px); } }
    @keyframes cm-pulse-${uid}{ 0%,100%{ r:4.5; } 50%{ r:7; } }
    .cm-line-${uid}{ stroke-dasharray:4000; stroke-dashoffset:4000; animation:cm-draw-${uid} 1.2s cubic-bezier(.4,0,.2,1) forwards; }
    .cm-area-${uid}{ transform-box:fill-box; transform-origin:bottom; animation:cm-rise-${uid} .8s ease-out both; }
    .cm-sheen-${uid}{ opacity:0; transition:opacity .25s; }
    .cm-wrap-${uid}:hover .cm-sheen-${uid}{ opacity:1; animation:cm-sweep-${uid} 1.7s linear infinite; }
    .cm-dot-${uid}{ animation:cm-pulse-${uid} 1.3s ease-in-out infinite; }
    @media (prefers-reduced-motion: reduce){ .cm-line-${uid},.cm-area-${uid},.cm-sheen-${uid},.cm-dot-${uid}{ animation:none !important; } .cm-line-${uid}{ stroke-dashoffset:0; } }
  `;
  return (
    <svg ref={svgRef} className={`cm-wrap-${uid}`} width="100%" viewBox={`0 0 ${w} ${h}`} style={{display:'block'}}
         onMouseMove={onMove} onMouseLeave={()=>setHi(null)}>
      <defs>
        <style>{css}</style>
        <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity=".18"/>
          <stop offset="100%" stopColor={color} stopOpacity="0"/>
        </linearGradient>
        <linearGradient id={sheenId} x1="0" y1="0" x2="1" y2="0">
          <stop offset="0%" stopColor="#fff" stopOpacity="0"/>
          <stop offset="50%" stopColor="#fff" stopOpacity=".55"/>
          <stop offset="100%" stopColor="#fff" stopOpacity="0"/>
        </linearGradient>
        <clipPath id={clipId}><path d={area}/></clipPath>
      </defs>
      {Array.from({length:rows}).map((_,i)=>{
        const y = P.t + i*((h-P.t-P.b)/(rows-1));
        return <line key={i} x1={P.l} y1={y} x2={w-P.r} y2={y} stroke="var(--line)" strokeWidth="1"/>;
      })}
      {yLabels.map((lb,i)=>{
        const y = P.t + i*((h-P.t-P.b)/(yLabels.length-1));
        return <text key={i} x={P.l-8} y={y+4} textAnchor="end" fontSize="11" fill="var(--ink-400)">{lb}</text>;
      })}
      <path className={`cm-area-${uid}`} d={area} fill={`url(#${gid})`}/>
      <path className={`cm-line-${uid}`} d={line} fill="none" stroke={color} strokeWidth="2.4" strokeLinejoin="round"/>
      {/* flowing sheen — clipped to the area shape, sweeps on hover */}
      <g clipPath={`url(#${clipId})`} style={{pointerEvents:'none'}}>
        <rect className={`cm-sheen-${uid}`} x={0} y={P.t} width={w*0.32} height={h-P.t-P.b} fill={`url(#${sheenId})`}/>
      </g>
      {showDots && safe.map((v,i)=> i%2===0 &&
        <circle key={i} cx={X(i)} cy={Y(v)} r="2.6" fill="#fff" stroke={color} strokeWidth="1.6"/>)}
      {xLabels.map((lb,i)=>{
        const x = X(xLabels.length>1 ? i*(n-1)/(xLabels.length-1) : (n-1)/2);
        return <text key={i} x={x} y={h-6} textAnchor="middle" fontSize="11" fill="var(--ink-400)">{lb}</text>;
      })}
      {hi_!=null && <g style={{pointerEvents:'none'}}>
        <line x1={X(hi_)} y1={P.t} x2={X(hi_)} y2={h-P.b} stroke={color} strokeWidth="1" strokeDasharray="3 3" opacity="0.55"/>
        <circle className={`cm-dot-${uid}`} cx={X(hi_)} cy={Y(safe[hi_])} r="4.5" fill={color} stroke="#fff" strokeWidth="2"/>
        <g transform={`translate(${tipX}, ${Math.max(Y(safe[hi_])-14, P.t+12)})`}>
          <rect x="-30" y="-16" width="60" height="20" rx="6" fill="var(--ink-900)" opacity="0.92"/>
          <text x="0" y="-2" textAnchor="middle" fontSize="11" fontWeight="700" fill="#fff">{fmt(safe[hi_])}</text>
        </g>
      </g>}
    </svg>
  );
}
window.TrendChart = TrendChart;

/* ================= DonutChart (SVG ring) ================= */
function DonutChart({ segments, size=180, thickness=22, center, gap=0.012, rounded=true }) {
  const r = (size - thickness)/2, C = 2*Math.PI*r;
  const total = segments.reduce((s,x)=>s+x.value,0) || 1;
  let acc = 0;
  return (
    <div style={{position:'relative', width:size, height:size}}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--line)" strokeWidth={thickness}/>
        <g transform={`rotate(-90 ${size/2} ${size/2})`}>
          {segments.map((s,i)=>{
            const frac = s.value/total;
            const len = Math.max(0, (frac-gap))*C;
            const dash = `${len} ${C-len}`;
            const off = -acc*C;
            acc += frac;
            return <circle key={i} cx={size/2} cy={size/2} r={r} fill="none"
              stroke={s.color} strokeWidth={thickness} strokeDasharray={dash}
              strokeDashoffset={off} strokeLinecap={rounded?"round":"butt"}/>;
          })}
        </g>
      </svg>
      {center && <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column',
        alignItems:'center', justifyContent:'center', textAlign:'center'}}>
        <div style={{fontSize:20, fontWeight:800, color:'var(--ink-900)', letterSpacing:'-.02em'}}>{center.value}</div>
        <div style={{fontSize:11, color:'var(--ink-400)', marginTop:2}}>{center.label}</div>
      </div>}
    </div>
  );
}
window.DonutChart = DonutChart;

/* ================= ProgressBar ================= */
function ProgressBar({ pct, caption, color="var(--green-500)", showPct=true }) {
  return (
    <div className="cm-progress">
      {(showPct || caption) &&
        <div className="pb-top">
          {showPct && <span className="pb-pct num">{pct}%</span>}
          {caption && <span className="pb-cap num">{caption}</span>}
        </div>}
      <div className="pb-track"><div className="pb-fill" style={{width:`${Math.min(100,pct)}%`, background:color}}/></div>
    </div>
  );
}
window.ProgressBar = ProgressBar;
