// ui.jsx — shared gs.town components. Exported to window.

// ---------- Icon set (24x24, 2px stroke, rounded — gs.town outline family) ----------
const ICONS = {
  home:    '<path d="M3 10.8 12 3l9 7.8"/><path d="M5.6 9.6V20h12.8V9.6"/><path d="M10 20v-5h4v5"/>',
  map:     '<path d="M9 4 3 6.5v13.5L9 17.5l6 2.5 6-2.5V4l-6 2.5z"/><path d="M9 4v13.5M15 6.5V20"/>',
  plus:    '<path d="M12 5v14M5 12h14"/>',
  grid:    '<rect x="4" y="4" width="7" height="7" rx="1.6"/><rect x="13" y="4" width="7" height="7" rx="1.6"/><rect x="4" y="13" width="7" height="7" rx="1.6"/><rect x="13" y="13" width="7" height="7" rx="1.6"/>',
  user:    '<circle cx="12" cy="8" r="3.6"/><path d="M5 20c0-3.7 3.1-5.6 7-5.6s7 1.9 7 5.6"/>',
  bell:    '<path d="M6 9.5a6 6 0 0 1 12 0c0 4.5 1.8 5.5 1.8 5.5H4.2S6 14 6 9.5z"/><path d="M9.5 19a2.5 2.5 0 0 0 5 0"/>',
  search:  '<circle cx="11" cy="11" r="7"/><path d="m20 20-3.4-3.4"/>',
  filter:  '<path d="M3 6h18l-7 8v5l-4-2v-3z"/>',
  mic:     '<rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 11a7 7 0 0 0 14 0"/><path d="M12 18v3"/>',
  locate:  '<circle cx="12" cy="12" r="3.4"/><path d="M12 2.5v3M12 18.5v3M2.5 12h3M18.5 12h3"/>',
  camera:  '<path d="M4 8.5h3l1.5-2.2h7L17 8.5h3V19H4z"/><circle cx="12" cy="13.2" r="3.4"/>',
  x:       '<path d="M6 6l12 12M18 6 6 18"/>',
  check:   '<path d="M5 12.5 10 17l9-10.5"/>',
  arrow:   '<path d="M4 12h15M13 6l6 6-6 6"/>',
  chevR:   '<path d="m9 5 7 7-7 7"/>',
  chevL:   '<path d="m15 5-7 7 7 7"/>',
  chevU:   '<path d="m6 15 6-6 6 6"/>',
  heart:   '<path d="M12 20.3S4 15 4 9.2A3.8 3.8 0 0 1 12 7.6 3.8 3.8 0 0 1 20 9.2c0 5.8-8 11.1-8 11.1z"/>',
  phone:   '<path d="M6 3.5h3l2 4.8-2.4 1.5a11 11 0 0 0 4.9 4.9L16 12.3l4.8 2v3a2 2 0 0 1-2 2A15.6 15.6 0 0 1 4 5.5a2 2 0 0 1 2-2z"/>',
  globe:   '<circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17M12 3.5c3 3 3 14 0 17M12 3.5c-3 3-3 14 0 17"/>',
  clock:   '<circle cx="12" cy="12" r="8.5"/><path d="M12 7v5.2l3.4 2"/>',
  shield:  '<path d="M12 3 5 6v5.5c0 4.2 3 6.7 7 9 4-2.3 7-4.8 7-9V6z"/><path d="M12 8.5v3.4M12 15.2h.01"/>',
  cone:    '<path d="M10 4h4l3.2 16H6.8z"/><path d="M8.4 10h7.2M7.5 15h9"/>',
  traffic: '<rect x="8" y="3" width="8" height="18" rx="3"/><circle cx="12" cy="8" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="12" cy="16" r="1.5"/>',
  leaf:    '<path d="M5 19C5 11 11 5 19 5c0 8-6 14-14 14z"/><path d="M9 15c2-3.2 4.3-5.3 7.5-6.5"/>',
  bulb:    '<path d="M9.5 18.5h5M10.5 21h3"/><path d="M12 3a6 6 0 0 0-3.8 10.6c.8.7 1.1 1.4 1.1 2.4h5.4c0-1 .3-1.7 1.1-2.4A6 6 0 0 0 12 3z"/>',
  mega:    '<path d="M4 9.5v5H8l9 4.2V5.3L8 9.5z"/><path d="M19.5 9.2a3 3 0 0 1 0 5.6"/>',
  food:    '<path d="M7 3v18M5 3v5a2 2 0 0 0 4 0V3"/><path d="M16 3c-1.8 1-2.8 3-2.8 5.8 0 2.4 1 3.6 2.8 3.6V21"/>',
  coffee:  '<path d="M5 8h12v4.5a5 5 0 0 1-5 5h-2a5 5 0 0 1-5-5z"/><path d="M17 9.2h2a2.3 2.3 0 0 1 0 4.6h-2"/><path d="M8 3.2v1.8M11 3.2v1.8"/>',
  pill:    '<circle cx="12" cy="12" r="8.5"/><path d="M12 8v8M8 12h8"/>',
  dumbbell:'<path d="M3 9.5v5M6 7.5v9M18 7.5v9M21 9.5v5M6 12h12"/>',
  scissors:'<circle cx="6.5" cy="6.5" r="2.6"/><circle cx="6.5" cy="17.5" r="2.6"/><path d="M8.8 8.2 20 17M8.8 15.8 20 7"/>',
  school:  '<path d="M3 9 12 5l9 4-9 4z"/><path d="M7 11v4c0 1.6 2.6 3 5 3s5-1.4 5-3v-4"/><path d="M21 9v4.5"/>',
  wrench:  '<path d="M15.5 6.2a4 4 0 0 0-5.2 5.1L4 17.6 6.4 20l6.3-6.3a4 4 0 0 0 5.1-5.2l-2.6 2.6-2.3-2.3z"/>',
  pin:     '<path d="M12 21s7-6.1 7-11a7 7 0 0 0-14 0c0 4.9 7 11 7 11z"/><circle cx="12" cy="10" r="2.4"/>',
  sponsor: '<path d="M12 3.2 14.5 9l6.3.5-4.8 4.1 1.5 6.2L12 16.6 6.5 19.8 8 13.6 3.2 9.5 9.5 9z"/>',
  send:    '<path d="M5 12 20 4l-5 16-3.5-6.5z"/><path d="M20 4 11.5 13.5"/>',
};
function Icon({ name, size = 22, color = 'currentColor', sw = 2, fill = 'none', style = {} }) {
  const filled = name === 'star' || name === 'sponsor';
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={filled ? color : fill}
      stroke={filled ? 'none' : color} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"
      style={{ flexShrink: 0, display: 'block', ...style }}
      dangerouslySetInnerHTML={{ __html: name === 'star' ? '<path d="M12 3.2 14.5 9l6.3.5-4.8 4.1 1.5 6.2L12 16.6 6.5 19.8 8 13.6 3.2 9.5 9.5 9z"/>' : (ICONS[name] || '') }}
    />
  );
}

// ---------- gs.town logo (wordmark with coral pin as the dot) ----------
function Logo({ size = 22, light = false }) {
  const ink = light ? '#FFFFFF' : 'var(--text-1)';
  return (
    <span style={{ display: 'inline-flex', alignItems: 'baseline', fontFamily: 'var(--font)',
      fontWeight: 800, fontSize: size, letterSpacing: '-0.03em', lineHeight: 1, color: ink }}>
      <span>gs</span>
      <span style={{ display: 'inline-flex', alignItems: 'flex-end', alignSelf: 'flex-end',
        margin: '0 0.04em', transform: `translateY(${size * -0.02}px)` }}>
        <svg width={size * 0.5} height={size * 0.62} viewBox="0 0 20 25" style={{ display: 'block' }}>
          <path d="M10 24S1.5 15.5 1.5 9A8.5 8.5 0 0 1 18.5 9C18.5 15.5 10 24 10 24z" fill="var(--coral)"/>
          <circle cx="10" cy="9" r="3.1" fill={light ? '#1B4FD8' : 'var(--surface)'} />
        </svg>
      </span>
      <span style={{ fontWeight: 600 }}>town</span>
    </span>
  );
}

// ---------- Circular category seal (INDIE badge sensibility) ----------
function CatSeal({ cat, size = 38, ring = false }) {
  const c = CATS[cat] || CATS.lainnya;
  return (
    <span style={{ width: size, height: size, borderRadius: '50%', background: c.color,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      boxShadow: ring ? '0 0 0 3px var(--surface), 0 0 0 4px var(--border)' : 'none' }}>
      <Icon name={c.icon} size={size * 0.52} color="#fff" sw={2.2} />
    </span>
  );
}

// ---------- Status chip ----------
function StatusChip({ status, size = 'md' }) {
  const s = STATUS[status] || STATUS.open;
  const sm = size === 'sm';
  return (
    <span className="mono" style={{ display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: sm ? '2px 7px' : '3px 9px', borderRadius: 'var(--r-chip)',
      background: s.soft, color: s.color, fontSize: sm ? 9.5 : 10.5, fontWeight: 700,
      letterSpacing: '0.06em', lineHeight: 1.2 }}>
      <span style={{ width: 5, height: 5, borderRadius: '50%', background: s.color }} />
      {s.label}
    </span>
  );
}

// ---------- Upvote chip ----------
function Upvote({ count, active, onClick }) {
  return (
    <button onClick={onClick} style={{ display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '5px 10px', borderRadius: 'var(--r-chip)', cursor: 'pointer',
      border: `1px solid ${active ? 'var(--primary)' : 'var(--border)'}`,
      background: active ? 'var(--primary-soft)' : 'var(--surface)',
      color: active ? 'var(--primary)' : 'var(--text-2)', fontFamily: 'var(--font)',
      fontWeight: 700, fontSize: 12.5, transition: 'all var(--dur-fast) var(--ease)' }}>
      <Icon name="chevU" size={14} sw={2.6} />
      <span className="mono">{count}</span>
    </button>
  );
}

// ---------- Pill button ----------
function Pill({ active, onClick, children, color, style = {} }) {
  return (
    <button onClick={onClick} style={{ display: 'inline-flex', alignItems: 'center', gap: 7,
      padding: '8px 14px', borderRadius: 'var(--r-chip)', whiteSpace: 'nowrap', cursor: 'pointer',
      fontFamily: 'var(--font)', fontWeight: 600, fontSize: 13, transition: 'all var(--dur-fast) var(--ease)',
      border: `1px solid ${active ? (color || 'var(--primary)') : 'var(--border)'}`,
      background: active ? (color || 'var(--primary)') : 'var(--surface)',
      color: active ? '#fff' : 'var(--text-2)', ...style }}>
      {children}
    </button>
  );
}

Object.assign(window, { Icon, Logo, CatSeal, StatusChip, Upvote, Pill, ICONS });
