// ─── UI primitives + icon set for Gunzaru ───

// Lucide-style stroke icons (handcrafted, no library)
const Icon = ({ name, size = 22, color = 'currentColor', strokeWidth = 1.75, style = {} }) => {
  const s = { width: size, height: size, ...style };
  const p = { fill: 'none', stroke: color, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const paths = {
    home: <><path d="M3 11l9-7 9 7" {...p}/><path d="M5 10v10h14V10" {...p}/></>,
    compass: <><circle cx="12" cy="12" r="9" {...p}/><path d="M15.5 8.5l-2 5-5 2 2-5 5-2z" {...p}/></>,
    plus: <><path d="M12 5v14M5 12h14" {...p}/></>,
    chat: <><path d="M21 12a8 8 0 11-3.5-6.6L21 4l-1 4.2A8 8 0 0121 12z" {...p}/></>,
    user: <><circle cx="12" cy="8" r="4" {...p}/><path d="M4 21c0-4 3.5-7 8-7s8 3 8 7" {...p}/></>,
    pin: <><path d="M12 22s7-6.5 7-12a7 7 0 10-14 0c0 5.5 7 12 7 12z" {...p}/><circle cx="12" cy="10" r="2.5" {...p}/></>,
    clock: <><circle cx="12" cy="12" r="9" {...p}/><path d="M12 7v5l3 2" {...p}/></>,
    calendar: <><rect x="3" y="5" width="18" height="16" rx="2" {...p}/><path d="M3 9h18M8 3v4M16 3v4" {...p}/></>,
    users: <><circle cx="9" cy="8" r="3.5" {...p}/><path d="M3 20c0-3 2.5-5.5 6-5.5s6 2.5 6 5.5" {...p}/><circle cx="17" cy="8" r="3" {...p}/><path d="M15 14.5c3.5.5 6 2.8 6 5.5" {...p}/></>,
    check: <><path d="M5 12l5 5L20 7" {...p}/></>,
    x: <><path d="M6 6l12 12M18 6L6 18" {...p}/></>,
    qm: <><circle cx="12" cy="12" r="9" {...p}/><path d="M9.5 9a2.5 2.5 0 015 0c0 1.5-2.5 2-2.5 3.5M12 17h.01" {...p}/></>,
    search: <><circle cx="11" cy="11" r="7" {...p}/><path d="M21 21l-4.5-4.5" {...p}/></>,
    filter: <><path d="M3 5h18M6 12h12M10 19h4" {...p}/></>,
    bell: <><path d="M6 9a6 6 0 1112 0c0 5 2 6 2 7H4c0-1 2-2 2-7z" {...p}/><path d="M10 21a2 2 0 004 0" {...p}/></>,
    lock: <><rect x="5" y="11" width="14" height="10" rx="2" {...p}/><path d="M8 11V8a4 4 0 018 0v3" {...p}/></>,
    eye: <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z" {...p}/><circle cx="12" cy="12" r="3" {...p}/></>,
    eyeOff: <><path d="M3 3l18 18M10.6 6.1A10 10 0 0112 6c6 0 10 6 10 6a17 17 0 01-3.4 4M6.4 6.4A17 17 0 002 12s4 6 10 6c1.5 0 2.9-.3 4.1-.9" {...p}/></>,
    card: <><rect x="2" y="6" width="20" height="13" rx="2" {...p}/><path d="M2 10h20" {...p}/></>,
    camera: <><rect x="3" y="7" width="18" height="13" rx="2" {...p}/><path d="M8 7l2-3h4l2 3" {...p}/><circle cx="12" cy="13" r="3.5" {...p}/></>,
    chevron: <><path d="M9 6l6 6-6 6" {...p}/></>,
    chevronL: <><path d="M15 6l-6 6 6 6" {...p}/></>,
    chevronD: <><path d="M6 9l6 6 6-6" {...p}/></>,
    star: <><path d="M12 3l2.7 5.7 6.3.9-4.6 4.5 1.1 6.3L12 17.6 6.5 20.4 7.6 14 3 9.6l6.3-.9L12 3z" {...p}/></>,
    sparkle: <><path d="M12 3v6m0 6v6M3 12h6m6 0h6" {...p}/><path d="M5.6 5.6l3 3m6.8 6.8l3 3M5.6 18.4l3-3m6.8-6.8l3-3" {...p}/></>,
    qr: <><rect x="3" y="3" width="7" height="7" rx="1" {...p}/><rect x="14" y="3" width="7" height="7" rx="1" {...p}/><rect x="3" y="14" width="7" height="7" rx="1" {...p}/><path d="M14 14h3v3h-3zM21 14v3M14 21h3M21 21v-3" {...p}/></>,
    settings: <><circle cx="12" cy="12" r="3" {...p}/><path d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1" {...p}/></>,
    send: <><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z" {...p}/></>,
    share: <><circle cx="6" cy="12" r="3" {...p}/><circle cx="18" cy="6" r="3" {...p}/><circle cx="18" cy="18" r="3" {...p}/><path d="M8.6 10.5l6.8-3M8.6 13.5l6.8 3" {...p}/></>,
    heart: <><path d="M12 21s-7-4.5-7-11a4 4 0 017-2.7A4 4 0 0119 10c0 6.5-7 11-7 11z" {...p}/></>,
    flame: <><path d="M12 22c4 0 7-3 7-7 0-3-2-5-3-7-1-2-1-4 0-6-3 1-7 4-7 9 0 0-3-1-3-4-2 2-4 4-4 8 0 4 3 7 7 7z" {...p}/></>,
    bolt: <><path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z" {...p}/></>,
    ticket: <><path d="M3 8a2 2 0 012-2h14a2 2 0 012 2v2a2 2 0 000 4v2a2 2 0 01-2 2H5a2 2 0 01-2-2v-2a2 2 0 000-4V8z" {...p}/><path d="M14 6v2M14 11v2M14 16v2" {...p}/></>,
    arrowR: <><path d="M5 12h14M13 6l6 6-6 6" {...p}/></>,
    map: <><path d="M9 4v16l-6-2V2l6 2zM15 6l6-2v16l-6 2M9 4l6 2M9 20l6-2" {...p}/></>,
    waves: <><path d="M2 8c2 0 2-2 4-2s2 2 4 2 2-2 4-2 2 2 4 2 2-2 4-2M2 14c2 0 2-2 4-2s2 2 4 2 2-2 4-2 2 2 4 2 2-2 4-2M2 20c2 0 2-2 4-2s2 2 4 2 2-2 4-2 2 2 4 2 2-2 4-2" {...p}/></>,
  };
  return <svg viewBox="0 0 24 24" style={s} aria-hidden="true">{paths[name]}</svg>;
};

// Button
const Button = ({ children, variant = 'primary', size = 'md', icon, onClick, full, style = {} }) => {
  const sizes = {
    sm: { padding: '8px 14px', fontSize: 13, height: 34, gap: 6 },
    md: { padding: '12px 20px', fontSize: 15, height: 46, gap: 8 },
    lg: { padding: '16px 24px', fontSize: 16, height: 54, gap: 10 },
  };
  const variants = {
    primary: { background: 'var(--primary)', color: 'var(--primary-ink)', border: '1px solid var(--primary)' },
    accent: { background: 'var(--accent)', color: '#fff', border: '1px solid var(--accent)' },
    secondary: { background: 'var(--surface)', color: 'var(--ink)', border: '1px solid var(--line)' },
    ghost: { background: 'transparent', color: 'var(--ink)', border: '1px solid transparent' },
    dark: { background: 'var(--ink)', color: 'var(--bg)', border: '1px solid var(--ink)' },
  };
  return (
    <button onClick={onClick} style={{
      ...sizes[size], ...variants[variant],
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      borderRadius: 999, fontFamily: 'Geist, system-ui', fontWeight: 600,
      letterSpacing: '-0.01em', cursor: 'pointer',
      width: full ? '100%' : 'auto',
      transition: 'transform .12s ease, opacity .12s', ...style,
    }}>
      {icon && <Icon name={icon} size={16} style={{ marginRight: 6 }} />}
      {children}
    </button>
  );
};

// Avatar — deterministic gradient from name
const Avatar = ({ name = 'A', size = 36, src }) => {
  // hash for color
  let h = 0;
  for (let i = 0; i < name.length; i++) h = name.charCodeAt(i) + ((h << 5) - h);
  const hue = Math.abs(h) % 360;
  const initials = name.split(' ').map(s => s[0]).slice(0, 2).join('').toUpperCase();
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: src ? `url(${src}) center/cover` : `linear-gradient(135deg, oklch(70% 0.13 ${hue}), oklch(50% 0.13 ${(hue+40)%360}))`,
      color: '#fff', display: 'grid', placeItems: 'center',
      fontFamily: 'Geist', fontWeight: 600, fontSize: size * 0.36,
      flexShrink: 0,
      boxShadow: 'inset 0 -1px 0 rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.05)',
    }}>{!src && initials}</div>
  );
};

// AvatarStack
const AvatarStack = ({ names = [], size = 26, max = 4 }) => (
  <div style={{ display: 'flex' }}>
    {names.slice(0, max).map((n, i) => (
      <div key={i} style={{ marginLeft: i === 0 ? 0 : -size * 0.35, border: '2px solid var(--surface)', borderRadius: '50%' }}>
        <Avatar name={n} size={size} />
      </div>
    ))}
  </div>
);

// Chip / Tag
const Chip = ({ children, tone = 'neutral', icon, style = {} }) => {
  const tones = {
    neutral: { background: 'var(--bg-2)', color: 'var(--ink-2)' },
    primary: { background: 'var(--primary-soft)', color: 'var(--primary)' },
    accent: { background: 'var(--accent-soft)', color: 'var(--accent)' },
    ok: { background: 'var(--ok-soft)', color: 'var(--ok)' },
    warn: { background: 'var(--warn-soft)', color: 'var(--warn)' },
    ink: { background: 'var(--ink)', color: 'var(--bg)' },
  };
  return (
    <span style={{
      ...tones[tone],
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '5px 10px', borderRadius: 999,
      fontFamily: 'Geist', fontSize: 12, fontWeight: 500,
      letterSpacing: '-0.005em',
      ...style,
    }}>
      {icon && <Icon name={icon} size={12} />}
      {children}
    </span>
  );
};

// Image placeholder — striped, gives a hint
const Placeholder = ({ label = 'photo', h = 160, hue = 215, style = {} }) => (
  <div style={{
    height: h, borderRadius: 14,
    background: `repeating-linear-gradient(135deg, oklch(78% 0.06 ${hue}) 0 18px, oklch(72% 0.07 ${hue}) 18px 36px)`,
    position: 'relative', overflow: 'hidden',
    ...style,
  }}>
    <div style={{
      position: 'absolute', bottom: 8, right: 10,
      fontFamily: 'Geist Mono', fontSize: 9, color: 'rgba(255,255,255,0.85)',
      letterSpacing: '0.08em', textTransform: 'uppercase',
      background: 'rgba(0,0,0,0.2)', padding: '3px 7px', borderRadius: 4,
      backdropFilter: 'blur(4px)',
    }}>{label}</div>
  </div>
);

// Card
const Card = ({ children, onClick, style = {}, padding = 16 }) => (
  <div onClick={onClick} style={{
    background: 'var(--surface)',
    borderRadius: 'var(--radius-card)',
    padding,
    boxShadow: 'var(--shadow-sm)',
    border: '1px solid var(--line-2)',
    cursor: onClick ? 'pointer' : 'default',
    ...style,
  }}>{children}</div>
);

// Section header
const SectionTitle = ({ title, action, style = {} }) => (
  <div style={{
    display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
    padding: '0 20px', margin: '4px 0 12px', ...style,
  }}>
    <h3 style={{
      margin: 0, fontFamily: 'Bricolage Grotesque', fontWeight: 600,
      fontSize: 19, letterSpacing: '-0.02em', color: 'var(--ink)',
    }}>{title}</h3>
    {action && <button style={{
      background: 'none', border: 'none', padding: 0, cursor: 'pointer',
      fontFamily: 'Geist', fontSize: 13, color: 'var(--ink-3)', fontWeight: 500,
    }}>{action}</button>}
  </div>
);

// Currency formatter
const mvr = (n) => `MVR ${n}`;

// Sample event data
const EVENTS = [
  {
    id: 'fri-football', title: 'Friday Pickup Football',
    org: 'Ahmed Rasheed', orgVerified: true,
    where: 'Galolhu Stadium', city: 'Malé',
    date: 'Fri, 22 May', time: '5:30 PM', endTime: '7:00 PM',
    cap: 22, going: 18, maybe: 4,
    going_list: ['Hassan', 'Ibrahim', 'Mariyam', 'Aisha', 'Mohamed', 'Yusuf'],
    img: { label: 'futsal court · golden hour', hue: 35 },
    tags: ['Sports', 'Free'], category: 'Sports',
    about: 'Casual 5-a-side. Bring water. Two teams rotate every 12 mins. Cleats optional.',
    distance: '0.8 km', price: 0,
  },
  {
    id: 'hulhumale-run', title: 'Hulhumalé Sunset Run · 5K',
    org: 'Rashfa F.', orgVerified: false,
    where: 'Central Park, Hulhumalé', city: 'Hulhumalé',
    date: 'Sat, 23 May', time: '5:45 PM',
    cap: null, going: 34, maybe: 11,
    going_list: ['Sana', 'Hassan', 'Layla', 'Adam', 'Naseema'],
    img: { label: 'coastal boulevard · dusk', hue: 22 },
    tags: ['Fitness', 'Free'], category: 'Fitness',
    about: 'Easy 5K along the eastern boulevard. Walkers welcome at the back.',
    distance: '4.2 km', price: 0,
  },
  {
    id: 'maafushi-fish', title: 'Maafushi Fishing Trip',
    org: 'Blue Reef Charters', orgVerified: true,
    where: 'Jetty 4 · T-Jetty', city: 'Malé',
    date: 'Sun, 24 May', time: '6:00 AM',
    cap: 12, going: 9, maybe: 2,
    going_list: ['Yoosuf', 'Imran', 'Saud', 'Hawwa'],
    img: { label: 'dhoni · open water', hue: 215 },
    tags: ['Outdoors', 'Paid'], category: 'Outdoors',
    about: 'Half-day handline trip. Rods, bait, lunch included. Bring a hat.',
    distance: '1.5 km', price: 650,
  },
  {
    id: 'code-cucina', title: 'Coffee & Code',
    org: 'Maldives Devs', orgVerified: true,
    where: 'La Cucina · Boduthakurufaanu Magu', city: 'Malé',
    date: 'Tue, 26 May', time: '7:30 PM',
    cap: 20, going: 14, maybe: 5,
    going_list: ['Nashid', 'Faiz', 'Lina', 'Adam'],
    img: { label: 'cafe interior · warm', hue: 45 },
    tags: ['Tech', 'Casual'], category: 'Community',
    about: 'Open coworking + show-and-tell. Bring your laptop or your questions.',
    distance: '0.4 km', price: 0,
  },
  {
    id: 'addu-study', title: 'Final Year Study Jam',
    org: 'Addu Study Co.', orgVerified: false,
    where: 'Library Block C', city: 'Addu City',
    date: 'Wed, 27 May', time: '4:00 PM',
    cap: 30, going: 21, maybe: 8,
    going_list: ['Eman', 'Nahid', 'Sajila', 'Anan'],
    img: { label: 'study tables · soft light', hue: 250 },
    tags: ['Study', 'Free'], category: 'Study',
    about: 'Quiet co-study session. Pomodoro intervals announced at the front.',
    distance: 'Addu', price: 0,
  },
];

const PACKAGES = [
  {
    id: 'free', name: 'Free', price: 0, tagline: 'Try the platform',
    features: [
      { ok: true, t: 'View public events' },
      { ok: true, t: 'Join 1 event at a time' },
      { ok: true, t: 'Reminders' },
      { ok: false, t: 'Create events' },
      { ok: false, t: 'Event chat' },
    ],
  },
  {
    id: 'basic', name: 'Basic', price: 49, tagline: 'For active joiners',
    features: [
      { ok: true, t: 'Join unlimited events' },
      { ok: true, t: 'Reminders & updates' },
      { ok: true, t: 'Attendance numbers' },
      { ok: false, t: 'Create events' },
      { ok: false, t: 'Event chat' },
    ],
  },
  {
    id: 'gold', name: 'Gold', price: 89, tagline: 'For organisers', recommended: true,
    features: [
      { ok: true, t: 'Create events' },
      { ok: true, t: 'Event chat' },
      { ok: true, t: 'Manage attendance' },
      { ok: true, t: 'Join unlimited events' },
      { ok: false, t: 'Promote events' },
    ],
  },
  {
    id: 'premium', name: 'Premium', price: 149, tagline: 'For businesses',
    features: [
      { ok: true, t: 'Unlimited event creation' },
      { ok: true, t: 'Event promotion' },
      { ok: true, t: 'Detailed analytics' },
      { ok: true, t: 'Large group tools' },
      { ok: true, t: 'Priority support' },
    ],
  },
];

Object.assign(window, {
  Icon, Button, Avatar, AvatarStack, Chip, Placeholder, Card, SectionTitle,
  mvr, EVENTS, PACKAGES,
});
