/* @jsx React.createElement */
/* ============================================================
   Yappari — shared kit: icons, motif, charts, primitives
   ============================================================ */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ---------------- ICONS (lucide-style, currentColor) ---------------- */
const ICONS = {
  overview: '<rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/>',
  sales: '<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>',
  stock: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',
  planogram: '<rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/>',
  control: '<line x1="21" x2="14" y1="4" y2="4"/><line x1="10" x2="3" y1="4" y2="4"/><line x1="21" x2="12" y1="12" y2="12"/><line x1="8" x2="3" y1="12" y2="12"/><line x1="21" x2="16" y1="20" y2="20"/><line x1="12" x2="3" y1="20" y2="20"/><line x1="14" x2="14" y1="2" y2="6"/><line x1="8" x2="8" y1="10" y2="14"/><line x1="16" x2="16" y1="18" y2="22"/>',
  products: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m7.5 4.27 9 5.15"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',
  events: '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>',
  settings: '<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>',
  refresh: '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
  chevronDown: '<path d="m6 9 6 6 6-6"/>',
  chevronUp: '<path d="m18 15-6-6-6 6"/>',
  chevronRight: '<path d="m9 18 6-6-6-6"/>',
  chevronLeft: '<path d="m15 18-6-6 6-6"/>',
  sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>',
  moon: '<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>',
  menu: '<line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="18" y2="18"/>',
  search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
  plus: '<path d="M5 12h14M12 5v14"/>',
  pencil: '<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',
  trash: '<path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/>',
  x: '<path d="M18 6 6 18M6 6l12 12"/>',
  check: '<path d="M20 6 9 17l-5-5"/>',
  alert: '<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><line x1="12" x2="12" y1="9" y2="13"/><line x1="12" x2="12.01" y1="17" y2="17"/>',
  thermometer: '<path d="M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z"/>',
  door: '<path d="M13 4h3a2 2 0 0 1 2 2v14"/><path d="M2 20h3M13 20h9"/><path d="M13 4.562v16.157a1 1 0 0 1-1.242.97L5 20V5.562a2 2 0 0 1 1.515-1.94l4-1A2 2 0 0 1 13 4.561Z"/><path d="M10 12v.01"/>',
  wifi: '<path d="M12 20h.01"/><path d="M2 8.82a15 15 0 0 1 20 0"/><path d="M5 12.859a10 10 0 0 1 14 0"/><path d="M8.5 16.429a5 5 0 0 1 7 0"/>',
  wifiOff: '<path d="M12 20h.01"/><path d="M8.5 16.429a5 5 0 0 1 7 0"/><path d="M5 12.859a10 10 0 0 1 5.17-2.69"/><path d="M19 12.859a10 10 0 0 0-2.007-1.523"/><path d="M2 8.82a15 15 0 0 1 4.177-2.643"/><path d="M22 8.82a15 15 0 0 0-11.288-3.764"/><path d="m2 2 20 20"/>',
  zap: '<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>',
  power: '<path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.77.04"/>',
  bulb: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',
  volume: '<path d="M11 4.7a.7.7 0 0 0-1.2-.5L6.4 7.6A1.4 1.4 0 0 1 5.4 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.4a1.4 1.4 0 0 1 1 .4l3.4 3.4a.7.7 0 0 0 1.2-.5z"/><path d="M16 9a5 5 0 0 1 0 6"/><path d="M19.4 18.4a9 9 0 0 0 0-12.7"/>',
  flame: '<path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/>',
  download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',
  upload: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/>',
  mapPin: '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',
  clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
  arrowUp: '<path d="m5 12 7-7 7 7"/><path d="M12 19V5"/>',
  arrowDown: '<path d="M12 5v14"/><path d="m19 12-7 7-7-7"/>',
  packagePlus: '<path d="M16 16h6M19 13v6"/><path d="M21 10V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l1-.57"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',
  packageX: '<path d="m21 10-1 1m-4 4-3 3m3-3 3 3m-3-3-3 3"/><path d="M21 10V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',
  wallet: '<path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1"/><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4"/>',
  cart: '<circle cx="8" cy="21" r="1"/><circle cx="19" cy="21" r="1"/><path d="M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12"/>',
  cube: '<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',
  snow: '<line x1="2" x2="22" y1="12" y2="12"/><line x1="12" x2="12" y1="2" y2="22"/><path d="m20 16-4-4 4-4M4 8l4 4-4 4M16 4l-4 4-4-4M8 20l4-4 4 4"/>',
  reset: '<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/>',
  play: '<polygon points="6 3 20 12 6 21 6 3"/>',
  users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
  cpu: '<rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><path d="M15 2v2M15 20v2M2 15h2M2 9h2M20 15h2M20 9h2M9 2v2M9 20v2"/>',
  check2: '<path d="M21.801 10A10 10 0 1 1 17 3.335"/><path d="m9 11 3 3L22 4"/>',
  filter: '<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>',
  calendar: '<rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/>',
  dollar: '<line x1="12" x2="12" y1="2" y2="22"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>',
  layers: '<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"/><path d="M2 12.5l8.6 3.9a2 2 0 0 0 1.7 0l8.6-3.9"/><path d="M2 17l8.6 3.9a2 2 0 0 0 1.7 0L21 17"/>',
  screen: '<rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>',
};
function Icon({ name, size = 20, sw = 1.75, style, className }) {
  return React.createElement('svg', {
    width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
    stroke: 'currentColor', strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round',
    style, className, dangerouslySetInnerHTML: { __html: ICONS[name] || '' },
  });
}

/* ---------------- PLUM BLOSSOM motif (Yappari crest) ---------------- */
function PlumBlossom({ size = 24, color = 'currentColor', style }) {
  // 5 petals around center — matches the logo crest
  const petals = [];
  for (let i = 0; i < 5; i++) {
    const a = (i * 72 - 90) * Math.PI / 180;
    const cx = 12 + Math.cos(a) * 5.6;
    const cy = 12 + Math.sin(a) * 5.6;
    petals.push(React.createElement('circle', { key: i, cx, cy, r: 4.1 }));
  }
  return React.createElement('svg', { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth: 1.4, style },
    petals,
    React.createElement('circle', { cx: 12, cy: 12, r: 2.3, fill: color, stroke: 'none' }),
  );
}

/* ---------------- PRODUCT GLYPH (drawn placeholder thumbnails) ---------------- */
function ProductGlyph({ glyph, color, size = 40, radius = 8 }) {
  const W = 100, H = 100;
  let inner;
  const c = color;
  if (glyph === 'bottle') {
    inner = React.createElement('g', null,
      React.createElement('path', { d: 'M42 14h16v8l4 8v50a8 8 0 0 1-8 8H46a8 8 0 0 1-8-8V30l4-8z', fill: c }),
      React.createElement('rect', { x: 44, y: 40, width: 12, height: 30, rx: 2, fill: 'rgba(255,255,255,.55)' }),
      React.createElement('rect', { x: 43, y: 8, width: 14, height: 8, rx: 2, fill: '#fff', opacity: .85 }),
    );
  } else if (glyph === 'can') {
    inner = React.createElement('g', null,
      React.createElement('rect', { x: 36, y: 16, width: 28, height: 68, rx: 6, fill: c }),
      React.createElement('rect', { x: 36, y: 30, width: 28, height: 18, fill: 'rgba(255,255,255,.85)' }),
      React.createElement('rect', { x: 38, y: 12, width: 24, height: 6, rx: 2, fill: '#b9b9b9' }),
    );
  } else if (glyph === 'carton') {
    inner = React.createElement('g', null,
      React.createElement('path', { d: 'M36 26h28v54a4 4 0 0 1-4 4H40a4 4 0 0 1-4-4z', fill: c }),
      React.createElement('path', { d: 'M36 26l14-12 14 12z', fill: c, opacity: .8 }),
      React.createElement('rect', { x: 42, y: 44, width: 16, height: 22, rx: 2, fill: 'rgba(255,255,255,.6)' }),
    );
  } else if (glyph === 'cupnoodle') {
    inner = React.createElement('g', null,
      React.createElement('path', { d: 'M30 30h40l-5 50a6 6 0 0 1-6 5H41a6 6 0 0 1-6-5z', fill: c }),
      React.createElement('rect', { x: 26, y: 24, width: 48, height: 9, rx: 4, fill: '#fff', opacity: .92 }),
      React.createElement('rect', { x: 40, y: 46, width: 20, height: 22, rx: 2, fill: 'rgba(255,255,255,.55)' }),
    );
  } else if (glyph === 'bar') {
    inner = React.createElement('g', null,
      React.createElement('rect', { x: 26, y: 34, width: 48, height: 32, rx: 5, fill: c, transform: 'rotate(-8 50 50)' }),
      React.createElement('rect', { x: 33, y: 44, width: 34, height: 6, rx: 3, fill: 'rgba(255,255,255,.7)', transform: 'rotate(-8 50 50)' }),
    );
  } else { // bag
    inner = React.createElement('g', null,
      React.createElement('path', { d: 'M32 20h36v60a4 4 0 0 1-4 4H36a4 4 0 0 1-4-4z', fill: c }),
      React.createElement('path', { d: 'M32 20l5-6h26l5 6z', fill: c, opacity: .75 }),
      React.createElement('circle', { cx: 50, cy: 52, r: 12, fill: 'rgba(255,255,255,.6)' }),
    );
  }
  return React.createElement('div', { style: { width: size, height: size, borderRadius: radius, background: 'var(--bg-sunken)', display: 'grid', placeItems: 'center', flexShrink: 0, overflow: 'hidden', border: '1px solid var(--border-subtle)' } },
    React.createElement('svg', { width: size * 0.86, height: size * 0.86, viewBox: '0 0 100 100' }, inner),
  );
}

/* ---------------- hooks / helpers ---------------- */
function useCountUp(target, dur = 900) {
  const [val, setVal] = useState(0);
  const ref = useRef(0);
  useEffect(() => {
    let raf, start;
    const from = ref.current;
    const step = (t) => {
      if (!start) start = t;
      const p = Math.min(1, (t - start) / dur);
      const e = 1 - Math.pow(1 - p, 3);
      const v = from + (target - from) * e;
      setVal(v);
      if (p < 1) raf = requestAnimationFrame(step);
      else ref.current = target;
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [target]);
  return val;
}
const fmtRp = (n) => 'Rp ' + Math.round(n).toLocaleString('id-ID');
const fmtNum = (n) => Math.round(n).toLocaleString('id-ID');
const fmtRpShort = (n) => {
  if (n >= 1e6) return 'Rp ' + (n / 1e6).toFixed(n >= 1e7 ? 0 : 1) + ' jt';
  if (n >= 1e3) return 'Rp ' + Math.round(n / 1e3) + 'rb';
  return 'Rp ' + n;
};
function relMins(m) {
  if (m == null) return '—';
  if (m < 1) return 'baru saja';
  if (m < 60) return m + ' menit lalu';
  const h = Math.floor(m / 60);
  if (h < 24) return h + ' jam lalu';
  return Math.floor(h / 24) + ' hari lalu';
}

/* ---------------- STATUS ---------------- */
const STATUS = {
  online:      { label: 'Online',      cls: 'badge-online' },
  offline:     { label: 'Offline',     cls: 'badge-offline' },
  error:       { label: 'Error',       cls: 'badge-error' },
  maintenance: { label: 'Maintenance', cls: 'badge-maintenance' },
};
function StatusBadge({ status }) {
  const s = STATUS[status] || STATUS.offline;
  return React.createElement('span', { className: 'badge ' + s.cls },
    React.createElement('span', { className: 'b-dot' }), s.label);
}

/* ---------------- CARD ---------------- */
function Card({ children, className = '', style, pad }) {
  return React.createElement('div', { className: 'card ' + (pad ? 'card-pad ' : '') + className, style }, children);
}
function SectionCard({ title, sub, right, children, bodyStyle, motif }) {
  return React.createElement('div', { className: 'card' },
    React.createElement('div', { className: 'card-head' },
      React.createElement('div', { className: 'row gap-2' },
        motif && React.createElement(PlumBlossom, { size: 18, color: 'var(--st-maint)' }),
        React.createElement('div', null,
          React.createElement('h3', null, title),
          sub && React.createElement('div', { className: 'ch-sub' }, sub),
        ),
      ),
      right,
    ),
    React.createElement('div', { style: bodyStyle }, children),
  );
}

/* ---------------- METRIC CARD ---------------- */
function MetricCard({ label, value, prefix, suffix, sub, subIcon, icon, bg, trend, animate = true }) {
  const n = useCountUp(animate ? value : value);
  const display = (prefix || '') + fmtNum(n) + (suffix || '');
  return React.createElement('div', { className: 'metric', style: { background: bg } },
    React.createElement('div', { className: 'm-blossom' }, React.createElement(PlumBlossom, { size: 96, color: '#fff' })),
    React.createElement('div', { className: 'm-top' },
      React.createElement('div', { className: 'm-label' }, label),
      React.createElement('div', { className: 'm-icon' }, React.createElement(Icon, { name: icon, size: 20 })),
    ),
    React.createElement('div', null,
      React.createElement('div', { className: 'm-value tnum' }, display),
      sub && React.createElement('div', { className: 'm-sub' },
        trend != null && React.createElement('span', { className: 'm-trend' },
          React.createElement(Icon, { name: trend >= 0 ? 'arrowUp' : 'arrowDown', size: 11, style: { verticalAlign: '-1px' } }),
          ' ' + Math.abs(trend) + '%'),
        subIcon && React.createElement(Icon, { name: subIcon, size: 13 }),
        sub),
    ),
  );
}

/* ---------------- PROGRESS BAR ---------------- */
function ProgressBar({ value, max = 100, color, className = '', height }) {
  const pct = Math.max(0, Math.min(100, (value / max) * 100));
  return React.createElement('div', { className: 'bar ' + className, style: height ? { height } : null },
    React.createElement('span', { style: { width: pct + '%', background: color } }));
}

/* ---------------- BAR CHART (HTML, solid bold) ---------------- */
function BarChart({ data, height = 200, color = 'var(--st-maint)', fmt = fmtRpShort, highlightLast }) {
  const max = Math.max(...data.map(d => d.value), 1);
  const [hover, setHover] = useState(null);
  return React.createElement('div', { style: { paddingTop: 26 } },
    React.createElement('div', { style: { display: 'flex', alignItems: 'flex-end', gap: 8, height, position: 'relative' } },
      data.map((d, i) => {
        const h = (d.value / max) * 100;
        const isLast = highlightLast && i === data.length - 1;
        return React.createElement('div', {
          key: i, style: { flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', height: '100%', justifyContent: 'flex-end', cursor: 'default' },
          onMouseEnter: () => setHover(i), onMouseLeave: () => setHover(null),
        },
          hover === i && React.createElement('div', { style: { position: 'absolute', top: -22, fontSize: 12, fontWeight: 700, color: 'var(--fg-1)', background: 'var(--bg-elev)', padding: '2px 8px', borderRadius: 6, boxShadow: 'var(--shadow-2)', whiteSpace: 'nowrap', zIndex: 5 } }, fmt(d.value)),
          React.createElement('div', {
            style: {
              width: '100%', maxWidth: 46, height: h + '%', minHeight: 4,
              background: isLast ? 'var(--accent)' : color,
              borderRadius: '5px 5px 0 0',
              opacity: hover === null || hover === i ? 1 : 0.45,
              transition: 'opacity var(--dur-fast), height var(--dur-slow) var(--ease-out)',
            },
          }),
          React.createElement('div', { style: { fontSize: 11, color: 'var(--fg-3)', marginTop: 7, fontWeight: 600 } }, d.label),
        );
      }),
    ),
  );
}

/* ---------------- LINE CHART (SVG area) ---------------- */
function LineChart({ data, height = 240, color = 'var(--st-maint)', fmt = fmtRpShort }) {
  const W = 760, H = height;
  const padL = 56, padR = 16, padT = 16, padB = 30;
  const max = Math.max(...data.map(d => d.value), 1) * 1.1;
  const min = 0;
  const ix = (i) => padL + (i / (data.length - 1)) * (W - padL - padR);
  const iy = (v) => padT + (1 - (v - min) / (max - min)) * (H - padT - padB);
  const pts = data.map((d, i) => [ix(i), iy(d.value)]);
  const line = pts.map((p, i) => (i ? 'L' : 'M') + p[0] + ' ' + p[1]).join(' ');
  const area = line + ` L${ix(data.length - 1)} ${H - padB} L${padL} ${H - padB} Z`;
  const gid = 'lg' + Math.round(max);
  const [hover, setHover] = useState(null);
  const ticks = 4;
  return React.createElement('div', { style: { position: 'relative' } },
    React.createElement('svg', { viewBox: `0 0 ${W} ${H}`, width: '100%', height: H, style: { display: 'block', overflow: 'visible' }, preserveAspectRatio: 'none' },
      React.createElement('defs', null,
        React.createElement('linearGradient', { id: gid, x1: 0, y1: 0, x2: 0, y2: 1 },
          React.createElement('stop', { offset: '0%', stopColor: color, stopOpacity: 0.32 }),
          React.createElement('stop', { offset: '100%', stopColor: color, stopOpacity: 0.02 }),
        )),
      // gridlines + y labels
      Array.from({ length: ticks + 1 }).map((_, t) => {
        const v = (max / ticks) * t;
        const y = iy(v);
        return React.createElement('g', { key: t },
          React.createElement('line', { x1: padL, x2: W - padR, y1: y, y2: y, stroke: 'var(--border-subtle)', strokeWidth: 1 }),
          React.createElement('text', { x: padL - 8, y: y + 4, textAnchor: 'end', fontSize: 11, fill: 'var(--fg-3)', fontFamily: 'var(--font-mono)' }, fmtRpShort(v).replace('Rp ', '')),
        );
      }),
      React.createElement('path', { d: area, fill: `url(#${gid})` }),
      React.createElement('path', { d: line, fill: 'none', stroke: color, strokeWidth: 2.5, strokeLinejoin: 'round', strokeLinecap: 'round', vectorEffect: 'non-scaling-stroke' }),
      pts.map((p, i) => React.createElement('g', { key: i },
        React.createElement('rect', { x: ix(i) - 14, y: 0, width: 28, height: H, fill: 'transparent', onMouseEnter: () => setHover(i), onMouseLeave: () => setHover(null) }),
        React.createElement('circle', { cx: p[0], cy: p[1], r: hover === i ? 5 : 3.5, fill: 'var(--bg-elev)', stroke: color, strokeWidth: 2.5 }),
      )),
      data.map((d, i) => i % Math.ceil(data.length / 7) === 0 || i === data.length - 1 ?
        React.createElement('text', { key: 'x' + i, x: ix(i), y: H - 10, textAnchor: 'middle', fontSize: 11, fill: 'var(--fg-3)', fontWeight: 600 }, d.label) : null),
    ),
    hover != null && React.createElement('div', { style: { position: 'absolute', left: `${(ix(hover) / W) * 100}%`, top: 0, transform: 'translateX(-50%)', background: 'var(--bg-inverse)', color: 'var(--bg)', padding: '4px 10px', borderRadius: 6, fontSize: 12, fontWeight: 700, whiteSpace: 'nowrap', pointerEvents: 'none', boxShadow: 'var(--shadow-2)' } }, fmt(data[hover].value)),
  );
}

/* ---------------- DONUT ---------------- */
function Donut({ segments, size = 180, thickness = 26, centerLabel, centerSub }) {
  const total = segments.reduce((a, s) => a + s.value, 0) || 1;
  const r = (size - thickness) / 2;
  const C = 2 * Math.PI * r;
  let acc = 0;
  return React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 24, flexWrap: 'wrap' } },
    React.createElement('div', { style: { position: 'relative', width: size, height: size, flexShrink: 0 } },
      React.createElement('svg', { width: size, height: size, style: { transform: 'rotate(-90deg)' } },
        React.createElement('circle', { cx: size / 2, cy: size / 2, r, fill: 'none', stroke: 'var(--bg-sunken)', strokeWidth: thickness }),
        segments.map((s, i) => {
          const frac = s.value / total;
          const dash = frac * C;
          const el = React.createElement('circle', {
            key: i, cx: size / 2, cy: size / 2, r, fill: 'none', stroke: s.color, strokeWidth: thickness,
            strokeDasharray: `${dash} ${C - dash}`, strokeDashoffset: -acc, strokeLinecap: 'butt',
            style: { transition: 'stroke-dasharray var(--dur-slow) var(--ease-out)' },
          });
          acc += dash;
          return el;
        }),
      ),
      React.createElement('div', { style: { position: 'absolute', inset: 0, display: 'grid', placeItems: 'center', textAlign: 'center' } },
        React.createElement('div', null,
          React.createElement('div', { style: { fontFamily: 'var(--font-display)', fontSize: 30, lineHeight: 1, color: 'var(--fg-1)' } }, centerLabel),
          centerSub && React.createElement('div', { style: { fontSize: 11, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '.08em', fontWeight: 700, marginTop: 4 } }, centerSub),
        )),
    ),
    React.createElement('div', { className: 'col gap-3', style: { flex: 1, minWidth: 140 } },
      segments.map((s, i) => React.createElement('div', { key: i, className: 'row gap-2', style: { justifyContent: 'space-between' } },
        React.createElement('div', { className: 'row gap-2' },
          React.createElement('span', { style: { width: 12, height: 12, borderRadius: 3, background: s.color } }),
          React.createElement('span', { style: { fontSize: 14, fontWeight: 600, color: 'var(--fg-2)' } }, s.label),
        ),
        React.createElement('div', { style: { textAlign: 'right' } },
          React.createElement('span', { style: { fontWeight: 700, color: 'var(--fg-1)' } }, Math.round((s.value / total) * 100) + '%'),
          React.createElement('span', { style: { fontSize: 12, color: 'var(--fg-3)', marginLeft: 6 } }, s.note || ''),
        ),
      )),
    ),
  );
}

/* ---------------- stock level color ---------------- */
function stockColor(cur, cap) {
  const p = cap ? cur / cap : 0;
  if (cur === 0) return 'var(--st-error)';
  if (p <= 0.34) return 'var(--st-warn)';
  return 'var(--st-online)';
}

/* ---------------- MODAL ---------------- */
function Modal({ title, eyebrow, danger, children, onClose, footer, lg }) {
  useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, []);
  return React.createElement('div', { className: 'modal-scrim', onClick: onClose },
    React.createElement('div', { className: 'modal ' + (lg ? 'modal-lg' : ''), onClick: (e) => e.stopPropagation() },
      danger && React.createElement('div', { className: 'modal-danger-strip' }),
      React.createElement('div', { className: 'modal-head' },
        React.createElement('div', { className: 'row', style: { justifyContent: 'space-between', alignItems: 'flex-start' } },
          React.createElement('div', null,
            eyebrow && React.createElement('div', { className: 'ph-eyebrow', style: { color: danger ? 'var(--st-error)' : 'var(--fg-3)' } }, eyebrow),
            React.createElement('h3', { style: { fontSize: 'var(--fs-lg)', fontWeight: 800, margin: '4px 0 0' } }, title),
          ),
          React.createElement('button', { className: 'icon-btn', onClick: onClose, style: { width: 34, height: 34 } }, React.createElement(Icon, { name: 'x', size: 18 })),
        )),
      React.createElement('div', { className: 'modal-body' }, children),
      footer && React.createElement('div', { className: 'modal-foot' }, footer),
    ),
  );
}

Object.assign(window, {
  Icon, ICONS, PlumBlossom, ProductGlyph, useCountUp, fmtRp, fmtNum, fmtRpShort,
  relMins, STATUS, StatusBadge, Card, SectionCard, MetricCard, ProgressBar,
  BarChart, LineChart, Donut, stockColor, Modal,
});
