// Common UI components for the Duyuf app

// ─── Icons ────────────────────────────────────────────────────────────
function Icon({ name, size = 22, color = 'currentColor', strokeWidth = 1.7 }) {
  const s = { width: size, height: size, fill: 'none', stroke: color, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'home': return (<svg viewBox="0 0 24 24" style={s}><path d="M3 11.5 12 4l9 7.5"/><path d="M5 10v10h14V10"/></svg>);
    case 'explore': return (<svg viewBox="0 0 24 24" style={s}><circle cx="12" cy="12" r="9"/><path d="m15 9-2 6-6 2 2-6 6-2z"/></svg>);
    case 'briefcase': return (<svg viewBox="0 0 24 24" style={s}><rect x="3" y="7" width="18" height="13" rx="2"/><path d="M8 7V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M3 13h18"/></svg>);
    case 'wallet': return (<svg viewBox="0 0 24 24" style={s}><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18"/><circle cx="17" cy="14" r="1.2" fill={color}/></svg>);
    case 'user': return (<svg viewBox="0 0 24 24" style={s}><circle cx="12" cy="8" r="4"/><path d="M4 21c1.5-4 5-6 8-6s6.5 2 8 6"/></svg>);
    case 'plane': return (<svg viewBox="0 0 24 24" style={s}><path d="M2 14l9-2 4-9 2 1-2 8 7 3-1 2-7-2-3 5-2-1 1-5z"/></svg>);
    case 'bus': return (<svg viewBox="0 0 24 24" style={s}><rect x="4" y="4" width="16" height="14" rx="2"/><path d="M4 12h16"/><circle cx="8" cy="20" r="1.2"/><circle cx="16" cy="20" r="1.2"/><path d="M9 8h6"/></svg>);
    case 'bed': return (<svg viewBox="0 0 24 24" style={s}><path d="M3 18V8"/><path d="M3 14h18v4"/><path d="M21 18v-4a3 3 0 0 0-3-3H10v3"/><circle cx="7" cy="11" r="2"/></svg>);
    case 'car': return (<svg viewBox="0 0 24 24" style={s}><path d="M5 16V11l2-5h10l2 5v5"/><path d="M3 16h18v3H3z"/><circle cx="7" cy="19" r="1.2"/><circle cx="17" cy="19" r="1.2"/></svg>);
    case 'kaaba': return (<svg viewBox="0 0 24 24" style={s}><rect x="5" y="7" width="14" height="13"/><path d="M5 11h14"/><path d="M9 7V5h6v2"/></svg>);
    case 'search': return (<svg viewBox="0 0 24 24" style={s}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>);
    case 'bell': return (<svg viewBox="0 0 24 24" style={s}><path d="M6 16V11a6 6 0 1 1 12 0v5l1 2H5l1-2z"/><path d="M10 20a2 2 0 0 0 4 0"/></svg>);
    case 'heart': return (<svg viewBox="0 0 24 24" style={s}><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/></svg>);
    case 'star': return (<svg viewBox="0 0 24 24" style={s}><path d="m12 3 2.7 5.5 6 .9-4.3 4.2 1 6L12 17l-5.4 2.6 1-6L3.3 9.4l6-.9L12 3z"/></svg>);
    case 'star-fill': return (<svg viewBox="0 0 24 24" style={{...s, fill: color, stroke: 'none'}}><path d="m12 3 2.7 5.5 6 .9-4.3 4.2 1 6L12 17l-5.4 2.6 1-6L3.3 9.4l6-.9L12 3z"/></svg>);
    case 'arrow-l': return (<svg viewBox="0 0 24 24" style={s}><path d="m14 6-6 6 6 6"/></svg>);
    case 'arrow-r': return (<svg viewBox="0 0 24 24" style={s}><path d="m10 6 6 6-6 6"/></svg>);
    case 'arrow-down': return (<svg viewBox="0 0 24 24" style={s}><path d="m6 9 6 6 6-6"/></svg>);
    case 'pin': return (<svg viewBox="0 0 24 24" style={s}><path d="M12 22s-7-7-7-12a7 7 0 1 1 14 0c0 5-7 12-7 12z"/><circle cx="12" cy="10" r="2.5"/></svg>);
    case 'calendar': return (<svg viewBox="0 0 24 24" style={s}><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg>);
    case 'plus': return (<svg viewBox="0 0 24 24" style={s}><path d="M12 5v14M5 12h14"/></svg>);
    case 'minus': return (<svg viewBox="0 0 24 24" style={s}><path d="M5 12h14"/></svg>);
    case 'check': return (<svg viewBox="0 0 24 24" style={s}><path d="m4 12 5 5L20 6"/></svg>);
    case 'close': return (<svg viewBox="0 0 24 24" style={s}><path d="M6 6l12 12M18 6 6 18"/></svg>);
    case 'filter': return (<svg viewBox="0 0 24 24" style={s}><path d="M4 5h16M7 12h10M10 19h4"/></svg>);
    case 'qr': return (<svg viewBox="0 0 24 24" style={s}><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><path d="M14 14h3v3h-3zM20 14v3M14 20h3M20 20v1"/></svg>);
    case 'gift': return (<svg viewBox="0 0 24 24" style={s}><rect x="3" y="9" width="18" height="11" rx="1"/><path d="M3 13h18M12 9v11"/><path d="M12 9c-2-3-6-2-6 0M12 9c2-3 6-2 6 0"/></svg>);
    case 'shield': return (<svg viewBox="0 0 24 24" style={s}><path d="M12 3 4 6v6c0 5 4 8 8 9 4-1 8-4 8-9V6l-8-3z"/></svg>);
    case 'wifi': return (<svg viewBox="0 0 24 24" style={s}><path d="M3 9a14 14 0 0 1 18 0"/><path d="M6 13a9 9 0 0 1 12 0"/><path d="M9 17a4 4 0 0 1 6 0"/><circle cx="12" cy="20" r="0.8" fill={color}/></svg>);
    case 'coffee': return (<svg viewBox="0 0 24 24" style={s}><path d="M4 9h13v6a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4V9z"/><path d="M17 11h2a2 2 0 0 1 0 4h-2"/><path d="M8 3v3M12 3v3"/></svg>);
    case 'settings': return (<svg viewBox="0 0 24 24" style={s}><circle cx="12" cy="12" r="3"/><path d="M19 12a7 7 0 0 0-.1-1.2l2-1.5-2-3.4-2.3.9a7 7 0 0 0-2-1.2L14 3h-4l-.6 2.6a7 7 0 0 0-2 1.2l-2.3-.9-2 3.4 2 1.5A7 7 0 0 0 5 12a7 7 0 0 0 .1 1.2l-2 1.5 2 3.4 2.3-.9a7 7 0 0 0 2 1.2L10 21h4l.6-2.6a7 7 0 0 0 2-1.2l2.3.9 2-3.4-2-1.5c.1-.4.1-.8.1-1.2z"/></svg>);
    case 'globe': return (<svg viewBox="0 0 24 24" style={s}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></svg>);
    case 'moon': return (<svg viewBox="0 0 24 24" style={s}><path d="M20 14A8 8 0 0 1 10 4a8 8 0 1 0 10 10z"/></svg>);
    case 'sun': return (<svg viewBox="0 0 24 24" style={s}><circle cx="12" cy="12" r="4"/><path d="M12 3v2M12 19v2M3 12h2M19 12h2M5.5 5.5l1.4 1.4M17.1 17.1l1.4 1.4M5.5 18.5l1.4-1.4M17.1 6.9l1.4-1.4"/></svg>);
    case 'chevron-r': return (<svg viewBox="0 0 24 24" style={s}><path d="m9 6 6 6-6 6"/></svg>);
    case 'chevron-l': return (<svg viewBox="0 0 24 24" style={s}><path d="m15 6-6 6 6 6"/></svg>);
    case 'phone': return (<svg viewBox="0 0 24 24" style={s}><path d="M5 4h4l2 5-3 2a12 12 0 0 0 5 5l2-3 5 2v4a2 2 0 0 1-2 2A17 17 0 0 1 3 6a2 2 0 0 1 2-2z"/></svg>);
    case 'percent': return (<svg viewBox="0 0 24 24" style={s}><circle cx="7" cy="7" r="2"/><circle cx="17" cy="17" r="2"/><path d="m6 18 12-12"/></svg>);
    case 'mail': return (<svg viewBox="0 0 24 24" style={s}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 7 9-7"/></svg>);
    case 'lock': return (<svg viewBox="0 0 24 24" style={s}><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>);
    case 'logout': return (<svg viewBox="0 0 24 24" style={s}><path d="M14 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4"/><path d="M10 17 5 12l5-5M5 12h11"/></svg>);
    case 'card': return (<svg viewBox="0 0 24 24" style={s}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 10h18M7 15h4"/></svg>);
    case 'compass': return (<svg viewBox="0 0 24 24" style={s}><circle cx="12" cy="12" r="9"/><path d="m15 9-1.5 4.5L9 15l1.5-4.5L15 9z"/></svg>);
    case 'dots': return (<svg viewBox="0 0 24 24" style={s}><circle cx="6" cy="12" r="1.4" fill={color}/><circle cx="12" cy="12" r="1.4" fill={color}/><circle cx="18" cy="12" r="1.4" fill={color}/></svg>);
    case 'trend-up': return (<svg viewBox="0 0 24 24" style={s}><path d="m3 17 6-6 4 4 8-9"/><path d="M14 6h7v7"/></svg>);
    case 'scan': return (<svg viewBox="0 0 24 24" style={s}><path d="M4 8V5a1 1 0 0 1 1-1h3M16 4h3a1 1 0 0 1 1 1v3M4 16v3a1 1 0 0 0 1 1h3M16 20h3a1 1 0 0 0 1-1v-3"/><path d="M4 12h16"/></svg>);
    default: return null;
  }
}

// Shared Booking-style date-range picker used by hotels and Umrah packages.
function DateRangeCalendar({ theme, lang = 'ar', start, end, onChange, presets = [], onDone }) {
  const rtl = isRTL(lang);
  const T = theme;
  const parse = (value) => value ? new Date(`${value}T12:00:00`) : null;
  const iso = (value) => {
    const y = value.getFullYear();
    const m = String(value.getMonth() + 1).padStart(2, '0');
    const d = String(value.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
  };
  const today = React.useMemo(() => { const d = new Date(); d.setHours(12,0,0,0); return d; }, []);
  const [cursor, setCursor] = React.useState(() => {
    const d = parse(start) || today;
    return new Date(d.getFullYear(), d.getMonth(), 1, 12);
  });
  const [choosingEnd, setChoosingEnd] = React.useState(Boolean(start && !end));
  React.useEffect(() => { setChoosingEnd(Boolean(start && !end)); }, [start, end]);
  const first = new Date(cursor.getFullYear(), cursor.getMonth(), 1, 12);
  const offset = (first.getDay() + 1) % 7; // Saturday-first in Arabic travel calendars.
  const days = Array.from({ length: 42 }, (_, index) => {
    const d = new Date(first); d.setDate(1 - offset + index); return d;
  });
  const startDate = parse(start), endDate = parse(end);
  const choose = (date) => {
    if (date < today) return;
    if (!startDate || (startDate && endDate) || !choosingEnd) {
      onChange?.(iso(date), '');
      setChoosingEnd(true);
      return;
    }
    if (date < startDate) onChange?.(iso(date), iso(startDate));
    else onChange?.(iso(startDate), iso(date));
    setChoosingEnd(false);
  };
  const monthTitle = new Intl.DateTimeFormat(rtl ? 'ar-SA-u-ca-gregory' : 'en-GB', { month:'long', year:'numeric' }).format(cursor);
  const weekdays = rtl ? ['س','ح','ن','ث','ر','خ','ج'] : ['Sa','Su','Mo','Tu','We','Th','Fr'];
  const same = (a,b) => a && b && iso(a) === iso(b);
  return (
    <div className="duyuf-range-calendar" role="dialog" aria-label={rtl ? 'اختيار فترة الإقامة' : 'Select stay dates'}>
      <div className="duyuf-calendar-head">
        <button type="button" aria-label={rtl?'الشهر التالي':'Previous month'} onClick={() => setCursor(d => new Date(d.getFullYear(), d.getMonth() - 1, 1, 12))}><Icon name={rtl?'chevron-r':'chevron-l'} size={18}/></button>
        <strong>{monthTitle}</strong>
        <button type="button" aria-label={rtl?'الشهر السابق':'Next month'} onClick={() => setCursor(d => new Date(d.getFullYear(), d.getMonth() + 1, 1, 12))}><Icon name={rtl?'chevron-l':'chevron-r'} size={18}/></button>
      </div>
      <div className="duyuf-calendar-weekdays">{weekdays.map((day,i)=><span key={`${day}-${i}`}>{day}</span>)}</div>
      <div className="duyuf-calendar-grid">
        {days.map((date) => {
          const outside = date.getMonth() !== cursor.getMonth();
          const disabled = date < today;
          const selected = same(date,startDate) || same(date,endDate);
          const inRange = startDate && endDate && date > startDate && date < endDate;
          return <button type="button" key={iso(date)} disabled={disabled} className={`${outside?'is-outside ':''}${selected?'is-selected ':''}${inRange?'is-range ':''}`} onClick={()=>choose(date)}>{date.getDate()}</button>;
        })}
      </div>
      {!!presets.length && <div className="duyuf-calendar-presets">{presets.map((preset)=><button type="button" key={preset.label} onClick={()=>{onChange?.(preset.start,preset.end); const d=parse(preset.start); if(d)setCursor(new Date(d.getFullYear(),d.getMonth(),1,12)); setChoosingEnd(false);}}>{preset.label}</button>)}</div>}
      <div className="duyuf-calendar-summary">
        <span>{start && end ? `${start} — ${end}` : rtl ? 'اختر تاريخ الوصول ثم المغادرة' : 'Select arrival, then departure'}</span>
        <button type="button" disabled={!start || !end} onClick={onDone}>{rtl ? 'اعتماد الفترة' : 'Select dates'}</button>
      </div>
    </div>
  );
}

// ─── Button ───────────────────────────────────────────────────────────
function Button({ children, kind = 'primary', size = 'md', icon, full, onClick, theme, style }) {
  const T = theme;
  const sizes = {
    sm: { h: 36, px: 14, fs: 13, r: 10 },
    md: { h: 48, px: 18, fs: 14.5, r: 14 },
    lg: { h: 56, px: 22, fs: 16, r: 16 },
  };
  const sz = sizes[size];
  const kinds = {
    primary: { bg: T.primary, fg: '#fff', border: 'none', shadow: '0 6px 16px rgba(193,152,114,0.35)' },
    secondary: { bg: T.surface, fg: T.text, border: `1px solid ${T.hairline}`, shadow: 'none' },
    ghost: { bg: 'transparent', fg: T.primary, border: 'none', shadow: 'none' },
    dark: { bg: T.ink, fg: T.cream, border: 'none', shadow: '0 6px 16px rgba(31,27,23,0.3)' },
    soft: { bg: T.camelSoft, fg: T.camelDeep, border: 'none', shadow: 'none' },
  };
  const k = kinds[kind];
  return (
    <button onClick={onClick} style={{
      height: sz.h, padding: `0 ${sz.px}px`, borderRadius: sz.r,
      background: k.bg, color: k.fg, border: k.border, boxShadow: k.shadow,
      fontFamily: 'Alexandria, system-ui, sans-serif', fontWeight: 600,
      fontSize: sz.fs, display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      gap: 8, width: full ? '100%' : 'auto', cursor: 'pointer', whiteSpace: 'nowrap',
      letterSpacing: '-0.005em',
      ...style,
    }}>
      {icon && <Icon name={icon} size={size === 'lg' ? 20 : 18} color={k.fg} />}
      {children}
    </button>
  );
}

// ─── Image placeholder ────────────────────────────────────────────────
function ImgSlot({ label, height = 160, radius = 16, tone = 'camel', children, theme }) {
  const T = theme;
  // Use brand tones for placeholders, with subtle pattern for hospitality feel
  const tones = {
    camel: { bg: T.camelSoft, fg: T.camelDeep, accent: T.camel },
    brown: { bg: '#D8CFC4', fg: T.pastelBrown, accent: T.pastelBrown },
    dark:  { bg: T.inkSoft, fg: T.cream, accent: T.camel },
    cream: { bg: T.creamDeep, fg: T.inkSoft, accent: T.camel },
  };
  const t = tones[tone] || tones.camel;
  return (
    <div style={{
      height, borderRadius: radius, background: t.bg,
      position: 'relative', overflow: 'hidden',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <DuyufPattern color={t.accent} opacity={0.18} size={48} />
      {label && (
        <div style={{
          position: 'relative', zIndex: 2,
          fontFamily: 'ui-monospace, "SF Mono", monospace',
          fontSize: 10, letterSpacing: '0.06em', textTransform: 'uppercase',
          color: t.fg, opacity: 0.7,
          padding: '4px 8px', borderRadius: 6,
          background: 'rgba(255,255,255,0.4)',
        }}>{label}</div>
      )}
      {children}
    </div>
  );
}

// ─── Bottom tab bar (3 tabs: Home / Bookings / Profile) ────────────────
function BottomTabs({ active = 'home', theme, lang, onSelect }) {
  const T = theme;
  const l = L[lang];
  const tabs = [
    { id: 'me', icon: 'user', label: l.profile },
    { id: 'home', icon: 'home', label: l.home },
    { id: 'trips', icon: 'briefcase', label: l.mybookings },
  ];
  return (
    <div style={{
      position: 'absolute', bottom: 0, left: 0, right: 0,
      background: T.surface, borderTop: `1px solid ${T.hairline}`,
      paddingTop: 8, paddingBottom: 34, paddingLeft: 8, paddingRight: 8,
      display: 'flex', justifyContent: 'space-around', alignItems: 'center',
      zIndex: 5,
    }}>
      {tabs.map(t => {
        const isActive = t.id === active;
        return (
          <button key={t.id} onClick={() => onSelect && onSelect(t.id)} style={{
            background: 'transparent', border: 0, cursor: 'pointer', padding: '6px 10px',
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
            minWidth: 48,
          }}>
            <Icon name={t.icon} size={22} color={isActive ? T.primary : T.textMuted} strokeWidth={isActive ? 2 : 1.7} />
            <span style={{
              fontFamily: 'Alexandria, system-ui, sans-serif',
              fontSize: 10.5, fontWeight: isActive ? 600 : 500,
              color: isActive ? T.primary : T.textMuted,
            }}>{t.label}</span>
          </button>
        );
      })}
    </div>
  );
}

// ─── Status bar (iOS-style, themed) ───────────────────────────────────
function PhoneStatusBar({ theme, time = '9:41', overlay = false, color }) {
  const T = theme;
  const c = color || (T.isDark || overlay ? '#fff' : T.ink);
  return (
    <div style={{
      position: 'absolute', top: 0, left: 0, right: 0,
      height: 54, padding: '14px 28px 0', zIndex: 10,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      fontFamily: '-apple-system, system-ui', fontSize: 17, fontWeight: 600,
      color: c, pointerEvents: 'none',
    }}>
      <span>{time}</span>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        {/* signal */}
        <svg width="18" height="11" viewBox="0 0 18 11"><g fill={c}>
          <rect x="0"  y="7" width="3" height="4" rx="0.5"/>
          <rect x="5"  y="5" width="3" height="6" rx="0.5"/>
          <rect x="10" y="3" width="3" height="8" rx="0.5"/>
          <rect x="15" y="0" width="3" height="11" rx="0.5"/>
        </g></svg>
        {/* wifi */}
        <svg width="16" height="11" viewBox="0 0 16 11"><path d="M8 11l2.5-3a3.5 3.5 0 0 0-5 0L8 11zM2 4a8.5 8.5 0 0 1 12 0l-1.2 1.5a6.5 6.5 0 0 0-9.6 0L2 4z" fill={c}/></svg>
        {/* battery */}
        <svg width="26" height="12" viewBox="0 0 26 12">
          <rect x="0.5" y="0.5" width="22" height="11" rx="3" fill="none" stroke={c} opacity="0.5"/>
          <rect x="2" y="2" width="19" height="8" rx="1.5" fill={c}/>
          <rect x="23" y="4" width="2" height="4" rx="1" fill={c} opacity="0.5"/>
        </svg>
      </div>
    </div>
  );
}

// ─── Home indicator ───────────────────────────────────────────────────
function HomeIndicator({ color = '#000' }) {
  return (
    <div style={{
      position: 'absolute', bottom: 8, left: 0, right: 0,
      display: 'flex', justifyContent: 'center', pointerEvents: 'none', zIndex: 6,
    }}>
      <div style={{ width: 134, height: 5, borderRadius: 100, background: color, opacity: 0.85 }}/>
    </div>
  );
}

// ─── Frame wrapper — replaces IOSDevice with our own to hold RTL etc. ─
function PhoneFrame({ width = 360, height = 760, theme, dir = 'ltr', children, statusOverlay = false, hideStatus = false }) {
  const T = theme;
  return (
    <div dir={dir} style={{
      width, height, borderRadius: 44, overflow: 'hidden', position: 'relative',
      background: T.bg, color: T.text,
      fontFamily: 'Alexandria, system-ui, sans-serif',
      WebkitFontSmoothing: 'antialiased',
      boxShadow: '0 30px 60px rgba(31,27,23,0.18), 0 0 0 1px rgba(31,27,23,0.10)',
    }}>
      {/* Dynamic island */}
      <div style={{
        position: 'absolute', top: 10, left: '50%', transform: 'translateX(-50%)',
        width: 110, height: 32, borderRadius: 22, background: '#000', zIndex: 50,
      }}/>
      {!hideStatus && <PhoneStatusBar theme={T} overlay={statusOverlay} />}
      <div style={{ height: '100%', position: 'relative' }}>{children}</div>
      <HomeIndicator color={T.isDark ? '#fff' : '#000'} />
    </div>
  );
}

// ─── Card ─────────────────────────────────────────────────────────────
function Card({ children, theme, padding = 16, radius = 18, style }) {
  const T = theme;
  return (
    <div style={{
      background: T.surface, borderRadius: radius, padding,
      border: `1px solid ${T.hairline}`,
      boxShadow: T.isDark ? 'none' : T.cardShadow,
      ...style,
    }}>{children}</div>
  );
}

// ─── Section header ───────────────────────────────────────────────────
function SectionHead({ title, action, theme, style }) {
  const T = theme;
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '14px 20px 8px', ...style,
    }}>
      <h3 style={{
        margin: 0, fontFamily: 'Alexandria', fontWeight: 700, fontSize: 18,
        color: T.text, letterSpacing: '-0.01em',
      }}>{title}</h3>
      {action && (
        <span style={{
          fontFamily: 'Alexandria', fontSize: 13, fontWeight: 500,
          color: T.primary,
        }}>{action}</span>
      )}
    </div>
  );
}

// ─── Star rating ──────────────────────────────────────────────────────
function Stars({ value = 4, color = '#C9882F', size = 12 }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 1 }}>
      {[1,2,3,4,5].map(i => (
        <Icon key={i} name={i <= value ? 'star-fill' : 'star'} size={size} color={color} strokeWidth={1.2}/>
      ))}
    </div>
  );
}

// ─── Chip ─────────────────────────────────────────────────────────────
function Chip({ children, active, theme, icon, style, onClick }) {
  const T = theme;
  return (
    <button onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '7px 14px', borderRadius: 999,
      border: active ? `1px solid ${T.primary}` : `1px solid ${T.hairline}`,
      background: active ? T.primary : T.surface,
      color: active ? '#fff' : T.text,
      fontFamily: 'Alexandria', fontSize: 12.5, fontWeight: 500, cursor: 'pointer',
      whiteSpace: 'nowrap',
      ...style,
    }}>
      {icon && <Icon name={icon} size={14} color={active ? '#fff' : T.text}/>}
      {children}
    </button>
  );
}

// ─── Badge ────────────────────────────────────────────────────────────
function Badge({ children, tone = 'camel', theme, style }) {
  const T = theme;
  const tones = {
    camel: { bg: T.camelSoft, fg: T.camelDeep },
    green: { bg: 'rgba(63,142,92,0.14)', fg: '#2E6A45' },
    warn:  { bg: 'rgba(201,136,47,0.16)', fg: '#8C5D14' },
    red:   { bg: 'rgba(180,81,59,0.14)', fg: '#8A3A29' },
    ink:   { bg: T.ink, fg: T.cream },
  };
  const t = tones[tone] || tones.camel;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '3px 9px', borderRadius: 999,
      background: t.bg, color: t.fg,
      fontFamily: 'Alexandria', fontSize: 11, fontWeight: 600,
      letterSpacing: '-0.005em',
      ...style,
    }}>{children}</span>
  );
}

// ─── Provider badge (marketplace — show vendor on every listing) ─────
function ProviderBadge({ theme, name, color, logoUrl, size = 'sm', verified = true, style }) {
  const T = theme;
  // Derive a brand chip from the provider name (deterministic by hash)
  const palette = ['#0E5C3F', '#7F6D5F', '#1F8A5B', '#8C5D14', '#3C342D', '#5B7A8A', '#A87F5A'];
  const hash = [...(name || 'X')].reduce((a, c) => a + c.charCodeAt(0), 0);
  const bg = color || palette[hash % palette.length];
  const initials = (name || 'P').split(' ').map(w => w[0]).slice(0, 2).join('');
  const sizes = {
    xs: { logo: 28, fs: 9, gap: 7, ts: 10 },
    sm: { logo: 36, fs: 10, gap: 8, ts: 11 },
    md: { logo: 52, fs: 12, gap: 10, ts: 12.5 },
  };
  const s = sizes[size];
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: s.gap, ...style }}>
      <div style={{
        width: s.logo, height: s.logo, borderRadius: 6,
        background: bg, color: '#fff',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: 'Alexandria', fontSize: s.fs, fontWeight: 700, letterSpacing: '0.02em',
      }}>{logoUrl?<img src={logoUrl} alt={name||''} style={{width:'100%',height:'100%',objectFit:'contain',borderRadius:6,background:'#fff'}}/>:initials}</div>
      <span style={{ fontFamily: 'Alexandria', fontSize: s.ts, color: T.textMuted, fontWeight: 500 }}>
        {name}
      </span>
      {verified && (
        <svg width={s.ts} height={s.ts} viewBox="0 0 24 24" style={{ marginInlineStart: -2 }}>
          <path d="M12 2 L14 4 L17 3.5 L18 6 L20.5 7 L20 10 L22 12 L20 14 L20.5 17 L18 18 L17 20.5 L14 20 L12 22 L10 20 L7 20.5 L6 18 L3.5 17 L4 14 L2 12 L4 10 L3.5 7 L6 6 L7 3.5 L10 4 Z" fill={T.primary}/>
          <path d="m8 12 3 3 5-6" stroke="#fff" strokeWidth="2.2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      )}
    </div>
  );
}

Object.assign(window, {
  Icon, Button, ImgSlot, BottomTabs, PhoneStatusBar, HomeIndicator,
  PhoneFrame, Card, SectionHead, Stars, Chip, Badge, ProviderBadge, DateRangeCalendar,
});
