(() => {
/* global React */
const { useState, useEffect, useRef, useMemo } = React;

/* =========================================================
   ICONS — clean 1.5px stroke, 18×18
   ========================================================= */
const Icon = ({ d, size = 18, fill = "none", stroke = "currentColor", sw = 1.6, children, ...rest }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke={stroke}
       strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" {...rest}>
    {d ? <path d={d} /> : children}
  </svg>
);

const Icons = {
  Home:     (p) => <Icon {...p}><path d="M3 11.5 12 4l9 7.5"/><path d="M5 10.5V20h14v-9.5"/><path d="M10 20v-5h4v5"/></Icon>,
  Teams:    (p) => <Icon {...p}><circle cx="9" cy="9" r="3"/><circle cx="17" cy="10" r="2.4"/><path d="M3 19c0-3 2.7-5 6-5s6 2 6 5"/><path d="M15 19c.3-2.2 2-3.5 4-3.5"/></Icon>,
  Patient:  (p) => <Icon {...p}><circle cx="12" cy="8" r="3.5"/><path d="M5 20c.5-3.6 3.4-6 7-6s6.5 2.4 7 6"/></Icon>,
  Capture:  (p) => <Icon {...p}><path d="M4 8h3l1.5-2h7L17 8h3v11H4z"/><circle cx="12" cy="13.5" r="3.5"/></Icon>,
  Records:  (p) => <Icon {...p}><rect x="4" y="4" width="16" height="16" rx="2"/><path d="M8 9h8M8 13h8M8 17h5"/></Icon>,
  Reports:  (p) => <Icon {...p}><path d="M6 3h9l4 4v14H6z"/><path d="M14 3v5h5"/><path d="M9 13h6M9 17h4"/></Icon>,
  Settings: (p) => <Icon {...p}><circle cx="12" cy="12" r="2.6"/><path d="M19 12a7 7 0 0 0-.1-1.2l2-1.5-2-3.4-2.4.8a7 7 0 0 0-2-1.2L14 3h-4l-.5 2.5a7 7 0 0 0-2 1.2L5 6l-2 3.4 2 1.5A7 7 0 0 0 5 12c0 .4 0 .8.1 1.2L3 14.7l2 3.4 2.4-.8c.6.5 1.3.9 2 1.2L10 21h4l.5-2.5c.7-.3 1.4-.7 2-1.2l2.4.8 2-3.4-2-1.5c0-.4.1-.8.1-1.2z"/></Icon>,
  Search:   (p) => <Icon {...p}><circle cx="11" cy="11" r="6.5"/><path d="m20 20-3.5-3.5"/></Icon>,
  Bell:     (p) => <Icon {...p}><path d="M6 16v-5a6 6 0 1 1 12 0v5l1.5 2H4.5z"/><path d="M10 21a2 2 0 0 0 4 0"/></Icon>,
  Plus:     (p) => <Icon {...p}><path d="M12 5v14M5 12h14"/></Icon>,
  ArrowR:   (p) => <Icon {...p}><path d="M5 12h14M13 6l6 6-6 6"/></Icon>,
  ArrowUp:  (p) => <Icon {...p}><path d="M12 19V5M6 11l6-6 6 6"/></Icon>,
  Download: (p) => <Icon {...p}><path d="M12 4v11M6 11l6 6 6-6"/><path d="M5 20h14"/></Icon>,
  Upload:   (p) => <Icon {...p}><path d="M12 20V9M6 13l6-6 6 6"/><path d="M5 4h14"/></Icon>,
  Filter:   (p) => <Icon {...p}><path d="M3 5h18l-7 8v6l-4-2v-4z"/></Icon>,
  Check:    (p) => <Icon {...p}><path d="m4 12 5 5L20 6"/></Icon>,
  X:        (p) => <Icon {...p}><path d="M6 6l12 12M18 6 6 18"/></Icon>,
  Camera:   (p) => <Icon {...p}><path d="M4 8h3l1.5-2h7L17 8h3v11H4z"/><circle cx="12" cy="13.5" r="3.5"/></Icon>,
  File:     (p) => <Icon {...p}><path d="M6 3h9l4 4v14H6z"/><path d="M14 3v5h5"/></Icon>,
  Calendar: (p) => <Icon {...p}><rect x="4" y="5" width="16" height="16" rx="2"/><path d="M4 9h16M9 3v4M15 3v4"/></Icon>,
  Image:    (p) => <Icon {...p}><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="9" cy="10" r="2"/><path d="m3 18 5-5 4 4 3-3 6 6"/></Icon>,
  Eye:      (p) => <Icon {...p}><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></Icon>,
  Dots:     (p) => <Icon {...p}><circle cx="6" cy="12" r="1.4"/><circle cx="12" cy="12" r="1.4"/><circle cx="18" cy="12" r="1.4"/></Icon>,
  Sparkle:  (p) => <Icon {...p}><path d="M12 4v6M12 14v6M4 12h6M14 12h6"/><path d="M7 7l3 3M14 14l3 3M17 7l-3 3M10 14l-3 3"/></Icon>,
  Smile:    (p) => <Icon {...p}><circle cx="12" cy="12" r="9"/><path d="M8 14c1 1.5 2.4 2.2 4 2.2s3-.7 4-2.2"/><circle cx="9" cy="10" r="0.6" fill="currentColor"/><circle cx="15" cy="10" r="0.6" fill="currentColor"/></Icon>,
  Tooth:    (p) => <Icon {...p}><path d="M7 4c-2 0-3 2-3 4 0 1.5.5 2.5.5 4S4 15 4 17c0 1 .5 3 2 3s2-2 2-3.5 1-2.5 2-2.5 2 1 2 2.5S13 20 15 20s2-2 2-3c0-2-.5-3.5-.5-5s.5-2.5.5-4c0-2-1-4-3-4-1.5 0-2 1-3.5 1S8.5 4 7 4z"/></Icon>,
  Logout:   (p) => <Icon {...p}><path d="M15 17l5-5-5-5"/><path d="M20 12H9"/><path d="M14 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8"/></Icon>,
  Mail:     (p) => <Icon {...p}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m4 7 8 6 8-6"/></Icon>,
  Phone:    (p) => <Icon {...p}><path d="M5 4h3l2 5-2.5 1.5a11 11 0 0 0 6 6L15 14l5 2v3a2 2 0 0 1-2 2A15 15 0 0 1 3 6a2 2 0 0 1 2-2z"/></Icon>,
  School:   (p) => <Icon {...p}><path d="M3 10 12 5l9 5-9 5z"/><path d="M7 12v5c0 1 2 2 5 2s5-1 5-2v-5"/><path d="M21 10v6"/></Icon>,
  Cloud:    (p) => <Icon {...p}><path d="M7 18a5 5 0 0 1 0-10 6 6 0 0 1 11.6 1A4.5 4.5 0 0 1 18 18z"/></Icon>,
  Clock:    (p) => <Icon {...p}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></Icon>,
};

window.Icons = Icons;
window.Icon = Icon;

/* =========================================================
   UTILITIES
   ========================================================= */

function useCountUp(target, duration = 900, start = true) {
  const [val, setVal] = useState(0);
  const tRef = useRef(0);
  useEffect(() => {
    if (!start) return;
    let raf, t0;
    const tick = (t) => {
      if (!t0) t0 = t;
      const p = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(Math.round(target * eased));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [target, duration, start]);
  return val;
}

window.useCountUp = useCountUp;

/* =========================================================
   TOAST SYSTEM (global)
   ========================================================= */
window._toastBus = window._toastBus || { subs: [] };
function toast(message, kind = "success") {
  const id = Math.random().toString(36).slice(2);
  window._toastBus.subs.forEach(fn => fn({ id, message, kind, t: Date.now() }));
  setTimeout(() => {
    window._toastBus.subs.forEach(fn => fn({ id, dismiss: true }));
  }, 3200);
}
window.toast = toast;

function ToastHost() {
  const [items, setItems] = useState([]);
  useEffect(() => {
    const fn = (e) => {
      if (e.dismiss) setItems(prev => prev.filter(x => x.id !== e.id));
      else setItems(prev => [...prev, e]);
    };
    window._toastBus.subs.push(fn);
    return () => { window._toastBus.subs = window._toastBus.subs.filter(s => s !== fn); };
  }, []);
  return (
    <div className="toast-wrap">
      {items.map(t => (
        <div key={t.id} className={`toast ${t.kind}`}>
          <span className="toast-dot"></span>
          <span>{t.message}</span>
        </div>
      ))}
    </div>
  );
}
window.ToastHost = ToastHost;

/* =========================================================
   SHARED UI
   ========================================================= */

function Avatar({ name = "", tone = "mint" }) {
  const initials = name.split(/\s+/).map(s => s[0]).slice(0, 2).join("").toUpperCase();
  const grad = {
    mint: "linear-gradient(140deg,#4ed6b0,#0e8a6d)",
    coral: "linear-gradient(140deg,#fbb89a,#e87a55)",
    gold: "linear-gradient(140deg,#e8d28b,#b89548)",
    lilac: "linear-gradient(140deg,#bfb2e4,#9a8fc7)",
    rose: "linear-gradient(140deg,#e6a5bd,#c46b8e)",
  }[tone];
  return (
    <div style={{
      width: 36, height: 36, borderRadius: 10,
      background: grad,
      display: "grid", placeItems: "center",
      color: "var(--ink)", fontFamily: "var(--font-display)", fontSize: 15,
    }}>{initials || "—"}</div>
  );
}
window.Avatar = Avatar;

/* Spark line — small SVG line chart */
function Spark({ data = [], color = "var(--mint)", w = 120, h = 36 }) {
  const max = Math.max(...data, 1);
  const min = Math.min(...data, 0);
  const range = max - min || 1;
  const pts = data.map((v, i) => [(i / (data.length - 1)) * w, h - ((v - min) / range) * (h - 4) - 2]);
  const d = pts.map((p, i) => `${i === 0 ? "M" : "L"} ${p[0]} ${p[1]}`).join(" ");
  const area = d + ` L ${w} ${h} L 0 ${h} Z`;
  return (
    <svg width={w} height={h} style={{ overflow: "visible" }}>
      <defs>
        <linearGradient id="spark-grad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.25" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={area} fill="url(#spark-grad)" />
      <path d={d} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
      {pts.slice(-1).map((p, i) => (
        <circle key={i} cx={p[0]} cy={p[1]} r="3" fill={color} stroke="white" strokeWidth="1.5" />
      ))}
    </svg>
  );
}
window.Spark = Spark;

/* Bar chart */
function Bars({ data = [], labels = [], h = 140, color = "var(--mint)" }) {
  const max = Math.max(...data, 1);
  return (
    <div style={{ display: "flex", alignItems: "flex-end", gap: 10, height: h, paddingTop: 6 }}>
      {data.map((v, i) => {
        const pct = (v / max) * 100;
        return (
          <div key={i} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 6, height: "100%" }}>
            <div style={{ flex: 1, display: "flex", alignItems: "flex-end", width: "100%" }}>
              <div style={{
                width: "100%",
                height: `${pct}%`,
                background: i === data.length - 1 ? color : "var(--paper-2)",
                border: i === data.length - 1 ? `1px solid ${color}` : "1px solid var(--line)",
                borderRadius: "6px 6px 2px 2px",
                transition: "height .6s cubic-bezier(.2,.8,.2,1)",
                transformOrigin: "bottom",
                animation: `bar-grow .8s cubic-bezier(.2,.8,.2,1) ${i * 0.05}s both`,
              }} />
            </div>
            <div style={{ fontSize: 10.5, color: "var(--muted-2)", fontFamily: "var(--font-mono)" }}>{labels[i]}</div>
          </div>
        );
      })}
      <style>{`@keyframes bar-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }`}</style>
    </div>
  );
}
window.Bars = Bars;

/* Ring progress */
function Ring({ value = 0.7, size = 96, stroke = 8, color = "var(--mint)", label, sublabel }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c * (1 - value);
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--line)" strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
                strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round"
                style={{ transition: "stroke-dashoffset 1.2s cubic-bezier(.2,.8,.2,1)" }} />
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", textAlign: "center" }}>
        <div>
          <div style={{ fontFamily: "var(--font-display)", fontSize: 22, lineHeight: 1 }}>{label}</div>
          {sublabel && <div style={{ fontSize: 10, color: "var(--muted-2)", marginTop: 2, letterSpacing: ".05em" }}>{sublabel}</div>}
        </div>
      </div>
    </div>
  );
}
window.Ring = Ring;

})();
