// core.jsx — dot+ macOS shared core: theme tokens, icons, atoms.
// dot+ Base v1.1. No emoji (project rule). SF-symbol-style line icons, 24-grid, 1.5pt.

const SANS = "'Inter', -apple-system, system-ui, sans-serif";
const MONO = "'JetBrains Mono', ui-monospace, 'SF Mono', monospace";

// ── Theme token sets → applied as CSS variables on a scope wrapper ───────────
const THEMES = {
  dark: {
    s0:'#0F0F14', s1:'#18181F', s2:'#222229', s3:'#2A2A33', s4:'#33333E',
    c1:'#FFFFFF', c2:'#C8C8D4', c3:'#6B6B78', cdis:'#3A3A44',
    border:'#2E2E38', borderSub:'#222229',
    inkSurface:'#FAFAFC', inkContent:'#05050A',
    pos:'#1F9E6E', warn:'#BB7A00', neg:'#E11900', info:'#276EF1',
    popoverBg:'rgba(23,23,29,0.97)', popoverBorder:'rgba(255,255,255,0.10)',
    shadow:'0 18px 60px rgba(0,0,0,0.55), 0 2px 8px rgba(0,0,0,0.4)',
    menuBar:'rgba(16,16,22,0.78)', menuText:'rgba(255,255,255,0.92)',
    scrim:'rgba(5,5,10,0.55)', winBorder:'rgba(255,255,255,0.08)',
  },
  light: {
    s0:'#FFFFFF', s1:'#FAFAFC', s2:'#F2F2F5', s3:'#E6E6EB', s4:'#DADAE2',
    c1:'#05050A', c2:'#2E2E38', c3:'#6B6B78', cdis:'#C8C8D4',
    border:'#E6E6EB', borderSub:'#F2F2F5',
    inkSurface:'#05050A', inkContent:'#FFFFFF',
    pos:'#05944F', warn:'#BB7A00', neg:'#E11900', info:'#276EF1',
    popoverBg:'rgba(255,255,255,0.98)', popoverBorder:'rgba(0,0,0,0.08)',
    shadow:'0 18px 60px rgba(0,0,0,0.22), 0 2px 8px rgba(0,0,0,0.10)',
    menuBar:'rgba(248,248,251,0.82)', menuText:'rgba(0,0,0,0.85)',
    scrim:'rgba(5,5,10,0.30)', winBorder:'rgba(0,0,0,0.10)',
  },
};

// Build the inline CSS-variable style object for a scope.
function themeVars(theme, accent) {
  const t = THEMES[theme] || THEMES.dark;
  return {
    '--s0':t.s0, '--s1':t.s1, '--s2':t.s2, '--s3':t.s3, '--s4':t.s4,
    '--c1':t.c1, '--c2':t.c2, '--c3':t.c3, '--cdis':t.cdis,
    '--border':t.border, '--border-sub':t.borderSub,
    '--ink-s':t.inkSurface, '--ink-c':t.inkContent,
    '--pos':t.pos, '--warn':t.warn, '--neg':t.neg, '--info':t.info,
    '--accent':accent || t.info,
    '--pop-bg':t.popoverBg, '--pop-border':t.popoverBorder, '--pop-shadow':t.shadow,
    '--menu-bar':t.menuBar, '--menu-text':t.menuText, '--scrim':t.scrim,
    '--win-border':t.winBorder,
    color:'var(--c1)', fontFamily:SANS,
  };
}

// ── Icons ────────────────────────────────────────────────────────────────────
function Icon({ size = 20, stroke = 1.6, fill = 'none', color = 'currentColor', children, vb = 24, style }) {
  return (
    <svg width={size} height={size} viewBox={`0 0 ${vb} ${vb}`} fill={fill}
      stroke={fill === 'none' ? color : 'none'} strokeWidth={stroke}
      strokeLinecap="round" strokeLinejoin="round"
      style={{ display:'block', flexShrink:0, ...style }}>{children}</svg>
  );
}
const I = {
  record:   (p)=><Icon fill="currentColor" stroke="none" {...p}><circle cx="12" cy="12" r="6.5"/></Icon>,
  stop:     (p)=><Icon fill="currentColor" stroke="none" {...p}><rect x="7" y="7" width="10" height="10" rx="2.5"/></Icon>,
  play:     (p)=><Icon fill="currentColor" stroke="none" {...p}><path d="M8 5.5v13l11-6.5z"/></Icon>,
  pause:    (p)=><Icon fill="currentColor" stroke="none" {...p}><path d="M7 5h3.2v14H7zM13.8 5H17v14h-3.2z"/></Icon>,
  mic:      (p)=><Icon {...p}><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5.5 11.5a6.5 6.5 0 0013 0M12 18v3"/></Icon>,
  system:   (p)=><Icon {...p}><rect x="3" y="4.5" width="18" height="12" rx="2"/><path d="M8.5 20h7M12 16.5V20"/></Icon>,
  waves:    (p)=><Icon stroke={1.8} {...p}><path d="M4 12h1.6M8 7.5v9M11.6 4.5v15M15.2 8.5v7M18.8 11h1.6"/></Icon>,
  sparkles: (p)=><Icon fill="currentColor" stroke="none" {...p}><path d="M12 3l1.6 4.4L18 9l-4.4 1.6L12 15l-1.6-4.4L6 9l4.4-1.6zM18.5 13l.8 2.2 2.2.8-2.2.8-.8 2.2-.8-2.2-2.2-.8 2.2-.8z"/></Icon>,
  search:   (p)=><Icon {...p}><circle cx="11" cy="11" r="6.5"/><path d="M20 20l-3.8-3.8"/></Icon>,
  gear:     (p)=><Icon {...p}><circle cx="12" cy="12" r="3"/><path d="M12 2.5v2.5M12 19v2.5M21.5 12H19M5 12H2.5M18.7 5.3l-1.8 1.8M7.1 16.9l-1.8 1.8M18.7 18.7l-1.8-1.8M7.1 7.1L5.3 5.3"/></Icon>,
  plus:     (p)=><Icon {...p}><path d="M12 5v14M5 12h14"/></Icon>,
  cmd:      (p)=><Icon stroke={1.7} {...p}><path d="M9 9h6v6H9zM9 9V7.5A2.5 2.5 0 109 9zM15 9V7.5A2.5 2.5 0 1115 9zM9 15v1.5A2.5 2.5 0 109 15zM15 15v1.5A2.5 2.5 0 1115 15z"/></Icon>,
  cal:      (p)=><Icon {...p}><path d="M7 3v3M17 3v3M4 8h16M5 5h14a1 1 0 011 1v13a1 1 0 01-1 1H5a1 1 0 01-1-1V6a1 1 0 011-1z"/></Icon>,
  clock:    (p)=><Icon {...p}><circle cx="12" cy="12" r="8"/><path d="M12 8v4l2.5 2"/></Icon>,
  people:   (p)=><Icon {...p}><circle cx="9" cy="8" r="3"/><path d="M3.5 19a5.5 5.5 0 0111 0M16 6.5a3 3 0 010 6M16.5 19a5.5 5.5 0 00-1.8-4.1"/></Icon>,
  person:   (p)=><Icon {...p}><circle cx="12" cy="8" r="3.4"/><path d="M5.5 20a6.5 6.5 0 0113 0"/></Icon>,
  folder:   (p)=><Icon {...p}><path d="M3 7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></Icon>,
  tag:      (p)=><Icon {...p}><path d="M3 3h7l11 11-7 7L3 10z"/><circle cx="7.5" cy="7.5" r="1.4" fill="currentColor" stroke="none"/></Icon>,
  chev:     (p)=><Icon stroke={2} {...p}><path d="M9 6l6 6-6 6"/></Icon>,
  chevDown: (p)=><Icon stroke={2} {...p}><path d="M6 9l6 6 6-6"/></Icon>,
  check:    (p)=><Icon stroke={2.2} {...p}><path d="M5 12.5l4.5 4.5L19 6.5"/></Icon>,
  x:        (p)=><Icon {...p}><path d="M6 6l12 12M18 6L6 18"/></Icon>,
  share:    (p)=><Icon {...p}><path d="M12 15V4M8 8l4-4 4 4M5 12v6a2 2 0 002 2h10a2 2 0 002-2v-6"/></Icon>,
  copy:     (p)=><Icon {...p}><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 00-2-2H6a2 2 0 00-2 2v8a2 2 0 002 2h2"/></Icon>,
  doc:      (p)=><Icon {...p}><path d="M7 3h7l5 5v13H7a1 1 0 01-1-1V4a1 1 0 011-1z"/><path d="M14 3v5h5"/></Icon>,
  star:     (p)=><Icon fill="currentColor" stroke="none" {...p}><path d="M12 4l2.3 5.2 5.7.5-4.3 3.8 1.3 5.6L12 16.9 7 18.9l1.3-5.6L4 9.7l5.7-.5z"/></Icon>,
  circle:   (p)=><Icon {...p}><circle cx="12" cy="12" r="8"/></Icon>,
  checkfill:(p)=><Icon fill="currentColor" stroke="none" {...p}><path d="M12 2a10 10 0 100 20 10 10 0 000-20zm-1 14.5l-4-4 1.4-1.4 2.6 2.6 5-5L17.4 9z"/></Icon>,
  pin:      (p)=><Icon {...p}><path d="M12 21s7-5.5 7-11a7 7 0 10-14 0c0 5.5 7 11 7 11z"/><circle cx="12" cy="10" r="2.4"/></Icon>,
  pencil:   (p)=><Icon {...p}><path d="M15.5 5.5l3 3M4 20l1-4L16 5a1.5 1.5 0 013 0a1.5 1.5 0 010 2L8 18z"/></Icon>,
  sliders:  (p)=><Icon {...p}><path d="M4 8h8M16 8h4M4 16h4M12 16h8"/><circle cx="14" cy="8" r="2.3"/><circle cx="10" cy="16" r="2.3"/></Icon>,
  minimize: (p)=><Icon {...p}><path d="M10 4v4a2 2 0 01-2 2H4M14 4v4a2 2 0 002 2h4M10 20v-4a2 2 0 00-2-2H4M14 20v-4a2 2 0 012-2h4"/></Icon>,
  expand:   (p)=><Icon {...p}><path d="M4 9V5a1 1 0 011-1h4M20 9V5a1 1 0 00-1-1h-4M4 15v4a1 1 0 001 1h4M20 15v4a1 1 0 01-1 1h-4"/></Icon>,
  send:     (p)=><Icon {...p}><path d="M4 12l16-7-7 16-2.5-6.5z"/></Icon>,
  detach:   (p)=><Icon {...p}><path d="M14 4h6v6M20 4l-8 8M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4"/></Icon>,
  ellipsis: (p)=><Icon fill="currentColor" stroke="none" {...p}><circle cx="5.5" cy="12" r="1.7"/><circle cx="12" cy="12" r="1.7"/><circle cx="18.5" cy="12" r="1.7"/></Icon>,
  bolt:     (p)=><Icon fill="currentColor" stroke="none" {...p}><path d="M13 2L4 14h6l-1 8 9-12h-6z"/></Icon>,
  trash:    (p)=><Icon {...p}><path d="M4 7h16M9 7V5a1 1 0 011-1h4a1 1 0 011 1v2M6 7l1 13a1 1 0 001 1h8a1 1 0 001-1l1-13"/></Icon>,
  grip:     (p)=><Icon fill="currentColor" stroke="none" {...p}><circle cx="9" cy="6" r="1.5"/><circle cx="15" cy="6" r="1.5"/><circle cx="9" cy="12" r="1.5"/><circle cx="15" cy="12" r="1.5"/><circle cx="9" cy="18" r="1.5"/><circle cx="15" cy="18" r="1.5"/></Icon>,
  arrowOut: (p)=><Icon {...p}><path d="M7 17L17 7M9 7h8v8"/></Icon>,
  wifi:     (p)=><Icon {...p}><path d="M2.5 9a14 14 0 0119 0M5.5 12.5a9.5 9.5 0 0113 0M8.5 16a5 5 0 017 0"/><circle cx="12" cy="19" r="1" fill="currentColor" stroke="none"/></Icon>,
  battery:  (p)=><Icon {...p}><rect x="2.5" y="8" width="16" height="8" rx="2"/><path d="M20.5 11v2" stroke="currentColor" strokeWidth="2"/><rect x="4.5" y="10" width="10" height="4" rx="1" fill="currentColor" stroke="none"/></Icon>,
  control:  (p)=><Icon stroke={1.7} {...p}><rect x="3" y="5" width="8" height="14" rx="3"/><rect x="13" y="5" width="8" height="14" rx="3"/></Icon>,
  bell:     (p)=><Icon {...p}><path d="M6 9a6 6 0 0112 0c0 5 2 6 2 6H4s2-1 2-6M10 20a2 2 0 004 0"/></Icon>,
  list:     (p)=><Icon {...p}><path d="M8 6h12M8 12h12M8 18h12M4 6h.01M4 12h.01M4 18h.01"/></Icon>,
  apple:    (p)=><Icon fill="currentColor" stroke="none" {...p}><path d="M16 11.5c0-2 1.6-3 1.7-3-0.9-1.4-2.4-1.6-2.9-1.6-1.2-.1-2.4.7-3 .7-.6 0-1.6-.7-2.6-.7-1.3 0-2.6.8-3.2 2-1.4 2.4-.4 6 1 8 .7 1 1.4 2 2.4 2 1 0 1.3-.6 2.5-.6 1.2 0 1.5.6 2.5.6 1 0 1.7-.9 2.3-1.9.5-.7.7-1.4.8-1.5-.1 0-1.8-.7-1.8-2.7zM14 5.3c.5-.7.9-1.6.8-2.5-.8 0-1.7.5-2.3 1.2-.5.6-.9 1.5-.8 2.4.9.1 1.8-.4 2.3-1.1z"/></Icon>,
};

const fmtInitial = (n) => (n || '').trim().charAt(0).toUpperCase();
const SPK = ['#276EF1', '#1F9E6E', '#C2603A', '#8A5CD6'];

// ── Atoms ─────────────────────────────────────────────────────────────────────
function Avatar({ name, idx = 0, size = 28, ring }) {
  const named = !!name;
  return (
    <div style={{
      width:size, height:size, borderRadius:'50%', flexShrink:0,
      background: named ? SPK[idx % SPK.length] : 'transparent',
      border: named ? 'none' : '1.5px dashed var(--border)',
      boxShadow: ring ? '0 0 0 2px var(--pop-bg)' : 'none',
      display:'flex', alignItems:'center', justifyContent:'center',
      color:'#fff', fontFamily:SANS, fontWeight:600, fontSize:size*0.42, letterSpacing:'-0.01em',
    }}>
      {named ? fmtInitial(name) : <I.person size={size*0.56} color="var(--c3)"/>}
    </div>
  );
}

const TAG_TINT = { positive:'var(--pos)', warning:'var(--warn)', negative:'var(--neg)', info:'var(--accent)' };
function Tag({ children, variant = 'default', dot }) {
  const tint = TAG_TINT[variant];
  const isSemantic = !!tint;
  return (
    <span style={{
      display:'inline-flex', alignItems:'center', gap:5, height:20, padding:'0 8px',
      borderRadius:5, fontFamily:MONO, fontSize:11, lineHeight:1,
      background: isSemantic ? `color-mix(in srgb, ${tint} 16%, transparent)` : 'var(--s2)',
      color: isSemantic ? tint : 'var(--c2)', whiteSpace:'nowrap',
    }}>
      {dot && <span style={{ width:6, height:6, borderRadius:'50%', background: tint || 'var(--c3)' }}/>}
      {children}
    </span>
  );
}

// Generic button: variant primary | secondary | ghost | record | danger
function Btn({ children, variant = 'secondary', size = 'default', shape = 'default', onClick, style, title, full }) {
  const H = { mini:28, small:34, default:42, large:52 }[size];
  const PX = { mini:12, small:14, default:16, large:20 }[size];
  const FS = size === 'mini' || size === 'small' ? 13 : 15;
  const base = {
    primary:   { background:'var(--ink-s)', color:'var(--ink-c)', border:'1px solid transparent' },
    secondary: { background:'var(--s2)', color:'var(--c1)', border:'1px solid transparent' },
    ghost:     { background:'transparent', color:'var(--c1)', border:'1px solid var(--border)' },
    accent:    { background:'var(--accent)', color:'#fff', border:'1px solid transparent' },
    record:    { background:'var(--ink-s)', color:'var(--ink-c)', border:'1px solid transparent' },
    danger:    { background:'var(--neg)', color:'#fff', border:'1px solid transparent' },
  }[variant];
  const radius = shape === 'pill' ? 999 : shape === 'circle' ? '50%' : 8;
  return (
    <button onClick={onClick} title={title} style={{
      height:H, minHeight: shape === 'circle' ? H : undefined, width: shape === 'circle' ? H : (full ? '100%' : undefined),
      padding: shape === 'circle' ? 0 : `0 ${PX}px`, borderRadius:radius,
      display:'inline-flex', alignItems:'center', justifyContent:'center', gap:8,
      fontFamily:SANS, fontSize:FS, fontWeight:600, cursor:'pointer',
      transition:'filter .15s, background .15s', whiteSpace:'nowrap', ...base, ...style,
    }}>{children}</button>
  );
}

// Soft circular icon button used in headers / nav
function IconBtn({ icon, onClick, size = 30, title, active }) {
  return (
    <button onClick={onClick} title={title} style={{
      width:size, height:size, borderRadius:8, border:'none', cursor:'pointer',
      background: active ? 'var(--s3)' : 'transparent', color:'var(--c2)',
      display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0,
      transition:'background .15s, color .15s',
    }}
      onMouseEnter={(e)=>{ if(!active) e.currentTarget.style.background='var(--s2)'; }}
      onMouseLeave={(e)=>{ if(!active) e.currentTarget.style.background='transparent'; }}
    >{icon}</button>
  );
}

// Keycap glyph for hotkeys
function Key({ children }) {
  return <span style={{
    display:'inline-flex', alignItems:'center', justifyContent:'center', minWidth:18, height:18,
    padding:'0 4px', borderRadius:5, background:'var(--s2)', border:'1px solid var(--border)',
    fontFamily:MONO, fontSize:11, color:'var(--c2)', lineHeight:1,
  }}>{children}</span>;
}

// Animated live audio meter (vertical bars)
function Meter({ active, bars = 5, color = 'var(--c1)', h = 18 }) {
  const [seed, setSeed] = React.useState(0);
  React.useEffect(() => {
    if (!active) return;
    const id = setInterval(() => setSeed(s => s + 1), 110);
    return () => clearInterval(id);
  }, [active]);
  return (
    <span style={{ display:'inline-flex', alignItems:'flex-end', gap:2, height:h }}>
      {Array.from({ length: bars }).map((_, i) => {
        const v = active ? 0.25 + Math.abs(Math.sin((seed + i * 1.7) * 0.9)) * 0.75 : 0.18;
        return <span key={i} style={{ width:3, height:`${v*100}%`, borderRadius:2, background:color, transition:'height .11s ease' }}/>;
      })}
    </span>
  );
}

const mm = (s) => `${String(Math.floor(s/60)).padStart(2,'0')}:${String(Math.floor(s%60)).padStart(2,'0')}`;

const PANEL_W = { Compact:340, Standard:386, Roomy:440 };

Object.assign(window, {
  SANS, MONO, THEMES, themeVars, Icon, I, fmtInitial, SPK, PANEL_W,
  Avatar, Tag, Btn, IconBtn, Key, Meter, mm,
});
