// Shared UI components for HelperMatch
const { useState, useEffect, useMemo, Fragment } = React;

// ===== Icons =====
const Icon = ({ name, size = 18, className = '' }) => {
  const paths = {
    search: <><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></>,
    heart: <path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/>,
    heartFill: <path fill="currentColor" d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/>,
    chat: <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2Z"/>,
    play: <polygon points="6 3 20 12 6 21 6 3" fill="currentColor"/>,
    lock: <><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></>,
    check: <polyline points="20 6 9 17 4 12"/>,
    x: <><path d="M18 6 6 18"/><path d="m6 6 12 12"/></>,
    filter: <><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"/></>,
    calendar: <><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" x2="16" y1="2" y2="6"/><line x1="8" x2="8" y1="2" y2="6"/><line x1="3" x2="21" y1="10" y2="10"/></>,
    location: <><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></>,
    globe: <><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 4 10 15 15 0 0 1-4 10 15 15 0 0 1-4-10 15 15 0 0 1 4-10Z"/></>,
    arrow: <><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></>,
    arrowLeft: <><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></>,
    user: <><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></>,
    star: <polygon points="12 2 15.1 8.3 22 9.3 17 14.1 18.2 21 12 17.8 5.8 21 7 14.1 2 9.3 8.9 8.3 12 2" fill="currentColor"/>,
    sparkle: <><path d="M12 3v3m0 12v3M3 12h3m12 0h3M5.6 5.6l2.1 2.1m8.6 8.6 2.1 2.1M5.6 18.4l2.1-2.1m8.6-8.6 2.1-2.1"/></>,
    verified: <><path d="m9 12 2 2 4-4"/><path d="M12 2 9.1 4.9 5 4l-.9 4.1L1 12l2.9 2.9L4 19l4.1-.9L12 22l2.9-2.9L19 19l.9-4.1L22 12l-2.9-2.9L20 5l-4.1.9L12 2Z"/></>,
    clock: <><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></>,
    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"/></>,
    briefcase: <><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></>,
    menu: <><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33h0a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51h0a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82v0a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z"/></>,
    inbox: <><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11Z"/></>,
    home: <><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"/><polyline points="9 22 9 12 15 12 15 22"/></>,
    send: <><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></>,
    shield: <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/>,
    paperclip: <path d="M21.44 11.05 12.25 20.24a6 6 0 0 1-8.49-8.49l8.49-8.49a4 4 0 1 1 5.66 5.66L9.5 17.33a2 2 0 0 1-2.83-2.83l8.49-8.49"/>,
    bell: <><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></>,
    dots: <><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></>,
    edit: <><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/></>,
    close: <><path d="M18 6 6 18"/><path d="m6 6 12 12"/></>,
    trash: <><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/></>,
    plus: <><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></>,
    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" y1="3" x2="12" y2="15"/></>,
    camera: <><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2Z"/><circle cx="12" cy="13" r="4"/></>,
    message: <><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2Z"/></>,
    book: <><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></>,
    moon: <><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></>,
    coin: <><circle cx="12" cy="12" r="9"/><path d="M9 9.5h4a2 2 0 0 1 0 4H10a2 2 0 0 0 0 4h5"/><path d="M12 7v10"/></>,
    sun: <><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></>,
  };
  return (
    <svg className={`icon ${className}`} width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      {paths[name]}
    </svg>
  );
};

// ===== Avatar (abstract, warm, non-face) =====
const Avatar = ({ person, size = 56, square = false }) => {
  const style = {
    width: size, height: size,
    background: `linear-gradient(135deg, ${person.color}, ${shadeColor(person.color, -20)})`,
    borderRadius: square ? 'var(--t-radius-sm)' : '50%',
    display: 'grid', placeItems: 'center',
    color: 'white', fontWeight: 600,
    fontSize: size * 0.38,
    letterSpacing: '-0.02em',
    flexShrink: 0,
    position: 'relative',
    overflow: 'hidden',
  };
  // If the person record carries a photoUrl, render it on top of the gradient
  // (the gradient acts as a tasteful placeholder while the image loads).
  // Otherwise fall back to initials — keeps non-candidate uses (reviewers, contacts) working.
  return (
    <div style={style}>
      {person.photoUrl ? (
        <img
          src={person.photoUrl}
          alt={person.name || ''}
          loading="lazy"
          style={{position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover'}}
        />
      ) : (
        <>
          <div style={{position:'absolute',inset:0,background:`radial-gradient(circle at 30% 25%, rgba(255,255,255,0.35), transparent 55%)`}} />
          <span style={{position:'relative'}}>{person.initials}</span>
        </>
      )}
    </div>
  );
};
function shadeColor(hex, pct) {
  const n = parseInt(hex.slice(1), 16);
  let r = (n >> 16) + pct, g = ((n >> 8) & 0xff) + pct, b = (n & 0xff) + pct;
  r = Math.min(255, Math.max(0, r)); g = Math.min(255, Math.max(0, g)); b = Math.min(255, Math.max(0, b));
  return '#' + ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0');
}

// ===== Toggle =====
// Stateless switch (caller owns checked/onChange). Used in notifications
// settings (employer + helper dashboards). aria-checked + role=switch keep
// it accessible and hookable for screen readers.
const Toggle = ({ checked, onChange, ariaLabel }) => (
  <button
    type="button"
    role="switch"
    aria-checked={checked}
    aria-label={ariaLabel}
    onClick={() => onChange(!checked)}
    style={{
      position: 'relative', display: 'inline-block',
      width: 38, height: 22,
      borderRadius: 99, border: 'none', padding: 0,
      background: checked ? 'var(--trust)' : 'var(--t-line)',
      cursor: 'pointer',
      transition: 'background 0.15s',
      verticalAlign: 'middle',
    }}
  >
    <span style={{
      position: 'absolute', top: 3, left: checked ? 19 : 3,
      width: 16, height: 16, borderRadius: 99,
      background: 'white', boxShadow: '0 1px 3px rgba(0,0,0,0.18)',
      transition: 'left 0.15s',
    }}/>
  </button>
);

// ===== Language Switcher =====
// Phase 0: reads/writes language via window.useI18n() directly — no props, no
// dependency on the now-removed window.I18N legacy dictionary. Drop-in replaces
// the styled switcher in the front-end Nav while staying visually identical.
//
// Close behaviour: the dropdown closes on click-outside (mousedown captured at
// document level) — NOT on mouse leave. Mouse-leave-close was unusable because
// the cursor naturally drifts off the small menu while moving toward an option.
const LanguageSwitcher = () => {
  const { lang, setLang, t, LANG_META } = window.useI18n();
  const [open, setOpen] = useState(false);
  const ref = React.useRef(null);
  const meta = LANG_META[lang] || LANG_META['zh-TW'];

  React.useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    // Defer one tick so the same click that opens us doesn't immediately close us.
    const id = setTimeout(() => document.addEventListener('mousedown', onDown), 0);
    document.addEventListener('keydown', onKey);
    return () => {
      clearTimeout(id);
      document.removeEventListener('mousedown', onDown);
      document.removeEventListener('keydown', onKey);
    };
  }, [open]);

  return (
    <div ref={ref} style={{position:'relative'}}>
      <button
        className="btn btn-ghost btn-sm"
        onClick={(e) => { e.stopPropagation(); setOpen(o => !o); }}
        title={t('nav.language')}
        aria-haspopup="listbox"
        aria-expanded={open}
        style={{gap:6}}
      >
        <Icon name="globe" size={15}/> <span style={{fontWeight:600, fontSize:13}}>{meta.short}</span>
      </button>
      {open && (
        <div role="listbox" style={{position:'absolute', right:0, top:'calc(100% + 6px)', background:'var(--t-paper)', border:'1px solid var(--t-line)', borderRadius:'var(--t-radius-sm)', boxShadow:'0 8px 24px rgba(0,0,0,0.08)', minWidth:180, zIndex:50, padding:6}}>
          {window.i18n.SUPPORTED.map(code => {
            const m = LANG_META[code];
            const active = code === lang;
            return (
              <button key={code} role="option" aria-selected={active} onClick={() => { setLang(code); setOpen(false); }}
                style={{width:'100%', display:'flex', alignItems:'center', gap:10, padding:'8px 10px', border:'none', background: active?'var(--t-bg)':'transparent', borderRadius:6, cursor:'pointer', fontSize:14, textAlign:'left', color:'var(--t-ink)'}}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = 'var(--t-bg)'; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = 'transparent'; }}>
                <span style={{fontSize:16}}>{m.flag}</span> <span style={{flex:1}}>{m.label}</span>
                {active && <Icon name="check" size={13} className="" />}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
};

// ===== Nav =====
const Nav = ({ route, go, subscription, toggleTweaks, role = 'employer', loggedIn: loggedInProp, logout }) => {
  const { t } = window.useI18n();
  const activeTop = route.split(':')[0];
  const [mobileOpen, setMobileOpen] = React.useState(false);
  React.useEffect(() => { setMobileOpen(false); }, [route]);
  // Scroll-lock body when mobile panel is open
  React.useEffect(() => {
    if (mobileOpen) document.body.classList.add('rwd-scroll-lock');
    else document.body.classList.remove('rwd-scroll-lock');
    return () => document.body.classList.remove('rwd-scroll-lock');
  }, [mobileOpen]);
  const goAndClose = (r) => { setMobileOpen(false); go(r); };
  // Real session: prefer explicit loggedIn prop; fall back to subscription heuristic for older callers
  const loggedIn = typeof loggedInProp === 'boolean' ? loggedInProp : (subscription !== 'free');
  // Helpers: don't surface the "Helpers" listing or "Pricing" (no paid tier for helpers)
  const publicLinks = role === 'helper' ? [
    { id: 'jobs', label: t('nav.jobs') },
    { id: 'guides', label: t('nav.guides') },
    { id: 'about', label: t('nav.about') },
  ] : [
    { id: 'candidates', label: t('nav.helpers') },
    { id: 'jobs', label: t('nav.jobs') },
    { id: 'pricing', label: t('nav.pricing') },
    { id: 'guides', label: t('nav.guides') },
    { id: 'about', label: t('nav.about') },
  ];
  const employerLinks = [
    { id: 'candidates', label: t('nav.helpers') },
    { id: 'jobs', label: t('nav.jobs') },
    { id: 'dashboard', label: t('nav.dashboard') },
    { id: 'inbox', label: t('nav.inbox'), badge: 3 },
    { id: 'guides', label: t('nav.guides') },
  ];
  const helperLinks = [
    { id: 'jobs', label: t('nav.browseJobs') },
    { id: 'dashboard', label: t('nav.myProfile') },
    { id: 'inbox', label: t('nav.messages'), badge: 2 },
    { id: 'guides', label: t('nav.resources') },
  ];
  const links = !loggedIn ? publicLinks : role === 'helper' ? helperLinks : employerLinks;
  const avatarInitials = role === 'helper' ? 'PW' : 'WC';
  const avatarGrad = role === 'helper' ? 'linear-gradient(135deg, #48B8A0, #2E8B74)' : 'linear-gradient(135deg, #E8856A, #C0634B)';
  return (
    <>
    <nav className="nav">
      <div className="container-wide nav-inner">
        <div className="brand" onClick={() => go('home')} style={{cursor:'pointer'}}>
          <div className="brand-mark">H</div>
          <span>HelperMatch</span>
        </div>
        <div className="nav-links">
          {links.map(l => (
            <button key={l.id} className={`nav-link ${activeTop === l.id ? 'active' : ''}`} onClick={() => go(l.id)} style={{position:'relative'}}>
              {l.label}
              {l.badge ? <span style={{marginLeft:6, background:'var(--coral)', color:'white', fontSize:10, fontWeight:700, padding:'1px 6px', borderRadius:99}}>{l.badge}</span> : null}
            </button>
          ))}
        </div>
        <div className="nav-right">
          <LanguageSwitcher/>
          <button className="btn btn-ghost btn-sm" onClick={toggleTweaks} title={t('nav.styleTweaks')}>
            <Icon name="sparkle" size={16}/>
          </button>
          {role !== 'helper' && (
            <div className="chip chip-outline" title={t('subscription.activeTitle')}>
              <span style={{width:6,height:6,borderRadius:99,background:subscription==='premium'?'#48B8A0':subscription==='standard'?'#E8856A':'#9A8B7F',display:'inline-block'}} />
              {subscription === 'premium' ? t('subscription.premium') : subscription === 'standard' ? t('subscription.standard') : t('subscription.none')}
            </div>
          )}
          {loggedIn ? (
            <button onClick={() => go('dashboard')} style={{width:36, height:36, borderRadius:99, background:avatarGrad, color:'white', fontWeight:600, fontSize:13, display:'grid', placeItems:'center'}} title={t('nav.profile')}>
              {avatarInitials}
            </button>
          ) : (
            <>
              <button className="btn btn-ghost btn-sm" onClick={() => go('auth:login')}>{t('nav.signIn')}</button>
              <button className="btn btn-primary btn-sm" onClick={() => go('auth:register')}>{t('nav.getStarted')}</button>
            </>
          )}
          <button className="nav-burger" onClick={() => setMobileOpen(o => !o)} aria-label={t('nav.menu')}>
            <Icon name={mobileOpen ? 'x' : 'menu'} size={22}/>
          </button>
        </div>
      </div>
    </nav>
    {/* Mobile menu panel — OUTSIDE nav because nav's backdrop-filter creates a
       containing block that would break position:fixed on descendants. */}
    {ReactDOM.createPortal(
      <div className={`nav-mobile-panel ${mobileOpen ? 'open' : ''}`}>
        {links.map(l => (
          <button key={l.id} className={`nav-link ${activeTop === l.id ? 'active' : ''}`} onClick={() => goAndClose(l.id)}>
            <span>{l.label}</span>
            {l.badge ? <span style={{background:'var(--coral)', color:'white', fontSize:11, fontWeight:700, padding:'2px 8px', borderRadius:99}}>{l.badge}</span> : null}
          </button>
        ))}
        <div className="nav-mobile-actions">
          {role !== 'helper' && (
            <div className="chip chip-outline" style={{alignSelf:'flex-start'}}>
              <span style={{width:6,height:6,borderRadius:99,background:subscription==='premium'?'#48B8A0':subscription==='standard'?'#E8856A':'#9A8B7F',display:'inline-block'}} />
              {subscription === 'premium' ? t('subscription.premium') : subscription === 'standard' ? t('subscription.standard') : t('subscription.none')}
            </div>
          )}
          {!loggedIn && (
            <>
              <button className="btn btn-outline btn-block" onClick={() => goAndClose('auth:login')}>{t('nav.signIn')}</button>
              <button className="btn btn-primary btn-block" onClick={() => goAndClose('auth:register')}>{t('nav.getStarted')}</button>
            </>
          )}
          {loggedIn && logout && (
            <button className="btn btn-outline btn-block" onClick={() => { setMobileOpen(false); logout(); }}>{t('nav.signOut')}</button>
          )}
          <button className="btn btn-ghost btn-block" onClick={() => { setMobileOpen(false); toggleTweaks(); }}>
            <Icon name="sparkle" size={16}/> {t('nav.styleTweaks')}
          </button>
        </div>
      </div>,
      document.body
    )}
    </>
  );
};

// ===== Footer =====
const FooterCol = ({ title, children, brand }) => {
  // Use <details> so screens ≤480 (via CSS) get collapsible groups.
  if (brand) return <div className="footer-col footer-col-brand">{children}</div>;
  return (
    <div className="footer-col">
      <details open>
        <summary><h5 style={{margin:0}}>{title}</h5></summary>
        <ul>{children}</ul>
      </details>
    </div>
  );
};
const Footer = ({ go }) => {
  const { t } = window.useI18n();
  return (
  <footer className="footer">
    <div className="container-wide">
      <div className="footer-grid">
        <FooterCol brand>
          <div className="brand" style={{color:'white', marginBottom:16}}>
            <div className="brand-mark">H</div>
            <span>HelperMatch</span>
          </div>
          <p style={{color:'#A89B8B', fontSize:14, maxWidth:300, lineHeight:1.6}}>
            {t('footer.tagline')}
          </p>
        </FooterCol>
        <FooterCol title={t('footer.colEmployers')}>
          <li><a onClick={() => go('candidates')}>{t('footer.findHelper')}</a></li>
          <li><a onClick={() => go('pricing')}>{t('footer.pricing')}</a></li>
          <li><a onClick={() => go('guides')}>{t('footer.hiringGuides')}</a></li>
        </FooterCol>
        <FooterCol title={t('footer.colHelpers')}>
          <li><a onClick={() => go('jobs')}>{t('footer.findJobs')}</a></li>
          <li><a onClick={() => go('auth:register')}>{t('footer.createProfile')}</a></li>
          <li><a>{t('footer.trainingProgram')}</a></li>
        </FooterCol>
        <FooterCol title={t('footer.colPlatform')}>
          <li><a onClick={() => go('about')}>{t('footer.aboutUs')}</a></li>
          <li><a onClick={() => go('agencies')}>{t('footer.partnerNetwork')}</a></li>
          <li><a onClick={() => go('assessment')}>{t('footer.assessmentCenter')}</a></li>
          <li><a onClick={() => go('trust')}>{t('footer.trustSafety')}</a></li>
          <li><a onClick={() => go('contact')}>{t('footer.contactUs')}</a></li>
        </FooterCol>
      </div>
      <div className="footer-bottom">
        <span>{t('footer.copyrightLine')}</span>
        <span style={{display:'flex', gap:20}}>
          <a>{t('footer.privacy')}</a><a>{t('footer.terms')}</a><a>{t('footer.cookies')}</a>
        </span>
      </div>
    </div>
  </footer>
  );
};

// ===== Tier Badge (hidden globally — tier system built but not surfaced) =====
const TierBadge = () => null;

// ===== Verified Badge (HelperMatch verified — replaces tier in public UI) =====
const VerifiedBadge = ({ big = false, mini = false }) => (
  <span className="verified-badge" style={{
    display:'inline-flex', alignItems:'center', gap:mini?4:6,
    padding: mini ? '2px 7px' : big ? '5px 12px' : '3px 9px',
    fontSize: mini ? 10 : big ? 12 : 11,
    fontWeight: 600, letterSpacing:'0.01em',
    background:'var(--trust-bg)', color:'var(--trust)',
    border:'1px solid var(--trust-soft)',
    borderRadius: 99, whiteSpace:'nowrap'
  }}>
    <Icon name="verified" size={mini?10:big?14:12}/>
    {mini ? 'Verified' : 'HelperMatch verified'}
  </span>
);

// ===== Video helpers =====
// Two video shapes coexist:
//   - Official-assessment candidates: c.videos = { cooking?, language?, housekeeping?, other? }
//     (recorded at the Surabaya station, 4 skill categories)
//   - Self / agency candidates: c.introVideo = { duration }
//     (a single self-recorded intro — categories don't apply)
// Use isOfficial(c) to decide which shape applies, or hasAnyVideo(c) for a presence check.
const VIDEO_CATEGORIES = [
  { id:'cooking',      label:'Cooking',      icon:'sparkle' },
  { id:'language',     label:'Language',     icon:'message' },
  { id:'housekeeping', label:'Housekeeping', icon:'home' },
  { id:'other',        label:'Other skills', icon:'briefcase' },
];
const isOfficial = (c) => c?.verification === 'official';
const getVideos = (c) => c?.videos || {};
const getVideoList = (c) => VIDEO_CATEGORIES
  .map(cat => ({ ...cat, video: getVideos(c)[cat.id] }))
  .filter(x => x.video);
const getVideoCount = (c) => getVideoList(c).length;
const getIntroVideo = (c) => c?.introVideo || null;
const hasAnyVideo = (c) => getVideoCount(c) > 0 || !!getIntroVideo(c);
// ===== Verification Badge =====
// Candidate-level verification status: 'official' / 'agency' / 'self' / null
const VERIFICATION_SPEC = {
  official: { label:'Official assessment', bg:'rgba(22,18,15,0.82)', fg:'#fff', icon:'verified' },
  agency:   { label:'Agency',              bg:'rgba(72,184,160,0.92)', fg:'#fff', icon:'shield' },
  self:     { label:'Self',                bg:'rgba(255,255,255,0.9)', fg:'#3D2B1F', icon:'check' },
};
const VerificationBadge = ({ verification, size = 'sm' }) => {
  const spec = VERIFICATION_SPEC[verification];
  if (!spec) return null;
  const h = size==='lg'?28:22;
  return (
    <span style={{display:'inline-flex',alignItems:'center',gap:5, padding:size==='lg'?'5px 11px':'3px 8px', background:spec.bg, color:spec.fg, borderRadius:99, fontSize:size==='lg'?12:11, fontWeight:600, lineHeight:1, height:h, backdropFilter:'blur(6px)', border: verification==='self' ? '1px solid rgba(0,0,0,0.08)' : 'none'}}>
      <Icon name={spec.icon} size={size==='lg'?13:11}/> {spec.label}
    </span>
  );
};

// ===== Video Thumb =====
const VideoThumb = ({ candidate, locked, onClick, height = 180 }) => (
  <div
    onClick={onClick}
    style={{
      position: 'relative', height,
      background: `linear-gradient(135deg, ${candidate.color}33, ${candidate.color}88), radial-gradient(circle at 60% 40%, ${shadeColor(candidate.color,30)}, ${shadeColor(candidate.color,-30)})`,
      borderRadius: 'var(--t-radius-sm)', cursor: 'pointer', overflow: 'hidden'
    }}
  >
    <div style={{position:'absolute', inset:0, display:'grid', placeItems:'center'}}>
      {!locked ? (
        <div style={{width:56, height:56, borderRadius:99, background:'rgba(255,255,255,0.95)', display:'grid', placeItems:'center', boxShadow:'0 4px 16px rgba(0,0,0,0.2)'}}>
          <Icon name="play" size={22}/>
        </div>
      ) : (
        <div style={{display:'flex',flexDirection:'column',alignItems:'center',gap:8,color:'white',textShadow:'0 2px 8px rgba(0,0,0,0.4)'}}>
          <div style={{width:48,height:48,borderRadius:99,background:'rgba(255,255,255,0.2)',backdropFilter:'blur(8px)',display:'grid',placeItems:'center',border:'1.5px solid rgba(255,255,255,0.3)'}}>
            <Icon name="lock" size={18}/>
          </div>
          <div style={{fontSize:12,fontWeight:600}}>Subscribe to watch</div>
        </div>
      )}
    </div>
    {locked && <div style={{position:'absolute',inset:0,backdropFilter:'blur(10px)',background:'rgba(30,20,15,0.35)'}}/>}
  </div>
);

// ===== Candidate Card =====
const CandidateCard = ({ candidate, go, onFav, isFav, subscription }) => {
  const { t } = window.useI18n();
  return (
    <div className="card" onClick={() => go(`candidate:${candidate.id}`)} style={{cursor:'pointer', display:'flex', flexDirection:'column'}}>
      {/* Preview is the cropped portrait. A small video badge sits at the
          bottom-right when the candidate has a video so the affordance is
          discoverable but doesn't dominate the photo. */}
      <div style={{position:'relative', height:200, overflow:'hidden', borderTopLeftRadius:'var(--t-radius-sm)', borderTopRightRadius:'var(--t-radius-sm)', background:`linear-gradient(135deg, ${candidate.color}33, ${candidate.color}88)`}}>
        {candidate.photoUrl ? (
          <img
            src={candidate.photoUrl}
            alt={candidate.name}
            loading="lazy"
            style={{width:'100%', height:'100%', objectFit:'cover', display:'block'}}
          />
        ) : (
          <div style={{position:'absolute', inset:0, display:'grid', placeItems:'center'}}>
            <Avatar person={candidate} size={88}/>
          </div>
        )}
        <button
          className="btn-fav"
          onClick={(e) => { e.stopPropagation(); onFav(candidate.id); }}
          style={{
            position:'absolute', top:12, right:12, width:36, height:36, borderRadius:99,
            background:'rgba(255,255,255,0.92)', display:'grid', placeItems:'center',
            border:'none', color: isFav ? '#E8856A' : '#3D2B1F', backdropFilter:'blur(6px)', zIndex:2
          }}
        >
          <Icon name={isFav ? 'heartFill' : 'heart'} size={18}/>
        </button>
        {candidate.hasVideo && (
          <span style={{
            position:'absolute', bottom:12, right:12, zIndex:2,
            display:'inline-flex', alignItems:'center', gap:5,
            padding:'4px 9px', borderRadius:99,
            background:'rgba(0,0,0,0.7)', color:'white',
            fontSize:11, fontWeight:600, letterSpacing:'0.02em',
            backdropFilter:'blur(6px)',
          }} title={t('card.video')}>
            <Icon name="play" size={11}/> {t('card.video')}
          </span>
        )}
        {/* Phase 2: re-enable the candidate-level VerificationBadge here.
            <div style={{position:'absolute', top:12, left:12, zIndex:2}}>
              <VerificationBadge verification={candidate.verification}/>
            </div> */}
      </div>
      <div style={{padding:16, display:'flex',flexDirection:'column', gap:10}}>
        <div style={{display:'flex', alignItems:'flex-start', justifyContent:'space-between', gap:10}}>
          <div style={{minWidth:0, flex:1}}>
            <div style={{display:'flex', alignItems:'center', gap:6, flexWrap:'wrap'}}>
              <div style={{fontWeight:600, fontSize:16, letterSpacing:'-0.01em'}}>{candidate.name}</div>
              {/* Phase 2: replace with VerificationBadge once the verification feature ships. */}
              {candidate.verified && <VerifiedBadge mini/>}
            </div>
            <div style={{fontSize:12.5, color:'var(--t-ink-muted)', marginTop:2}}>
              {candidate.age} · {candidate.flag} {candidate.nationality} · {candidate.jobTypes[0]}
            </div>
          </div>
        </div>

        {/* Meta chips — match the single helper page demographics chip pattern:
            outline pill (warm-cream bg + line border + 99 radius) with a small
            trust-bg icon disc on the left. "Very active" stays as a solid green
            pill for emphasis (same as the detail page badge). */}
        {(() => {
          const Pill = ({ icon, children }) => (
            <span style={{display:'inline-flex', alignItems:'center', gap:6, padding:'4px 10px 4px 4px', background:'var(--t-bg)', border:'1px solid var(--t-line)', borderRadius:99, fontSize:12, color:'var(--t-ink)', fontWeight:500, whiteSpace:'nowrap'}}>
              <span style={{display:'grid', placeItems:'center', width:20, height:20, borderRadius:99, background:'var(--trust-bg)', color:'var(--trust)', flexShrink:0}}>
                <Icon name={icon} size={11}/>
              </span>
              {children}
            </span>
          );
          const veryActive = (() => {
            if (!candidate.lastActiveAt) return false;
            const daysSince = (Date.now() - new Date(candidate.lastActiveAt).getTime()) / 86_400_000;
            return daysSince <= 5;
          })();
          return (
            <div style={{display:'flex', alignItems:'center', gap:6, flexWrap:'wrap'}}>
              {veryActive && (
                <span style={{display:'inline-flex', alignItems:'center', gap:5, padding:'4px 10px', borderRadius:99, background:'var(--t-accent)', color:'white', fontSize:11, fontWeight:700, letterSpacing:'0.02em'}}>
                  <span style={{fontSize:8}}>●</span> {t('card.veryActive')}
                </span>
              )}
              {candidate.city && <Pill icon="location">{candidate.city}</Pill>}
              {typeof candidate.yearsExperience === 'number' && (
                <Pill icon="briefcase">{candidate.yearsExperience} {candidate.yearsExperience === 1 ? t('card.yr') : t('card.yrs')}</Pill>
              )}
            </div>
          );
        })()}

        <div style={{fontSize:13, color:'var(--t-ink-muted)', lineHeight:1.5, display:'-webkit-box', WebkitLineClamp:2, WebkitBoxOrient:'vertical', overflow:'hidden'}}>
          {candidate.bio}
        </div>

        {/* Bottom row — availability + reference chip (when present), with the
            contract-status string sitting plain on the right (visual hierarchy:
            chips for the actionable bits, muted text for the contextual bit). */}
        {(() => {
          const Pill = ({ icon, children }) => (
            <span style={{display:'inline-flex', alignItems:'center', gap:6, padding:'4px 10px 4px 4px', background:'var(--t-bg)', border:'1px solid var(--t-line)', borderRadius:99, fontSize:12, color:'var(--t-ink)', fontWeight:500, whiteSpace:'nowrap'}}>
              <span style={{display:'grid', placeItems:'center', width:20, height:20, borderRadius:99, background:'var(--trust-bg)', color:'var(--trust)', flexShrink:0}}>
                <Icon name={icon} size={11}/>
              </span>
              {children}
            </span>
          );
          return (
            <div style={{display:'flex', alignItems:'center', gap:6, flexWrap:'wrap', paddingTop:10, borderTop:'1px solid var(--t-line)'}}>
              {candidate.availableIn && <Pill icon="calendar">{candidate.availableIn}</Pill>}
              {candidate.hasReference && <Pill icon="check">{t('card.reference')}</Pill>}
              {candidate.contractStatus && (
                <span style={{fontSize:11.5, color:'var(--t-ink-muted)', marginLeft:'auto'}}>
                  {candidate.contractStatus}
                </span>
              )}
            </div>
          );
        })()}
      </div>
    </div>
  );
};

// ===== Job Card =====
const JobCard = ({ job, go }) => {
  const { t } = window.useI18n();
  return (
  <div className="card" onClick={() => go(`job:${job.id}`)} style={{cursor:'pointer', padding:24}}>
    <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:16, marginBottom:12}}>
      <div style={{flex:1, minWidth:0}}>
        <div style={{display:'flex', gap:8, marginBottom:8}}>
          <span className="chip chip-coral" style={{fontSize:11}}>{job.market}</span>
          <span className="chip chip-ghost" style={{fontSize:11}}>{t('forms.enum.jobType.' + job.type) || job.type}</span>
        </div>
        <div style={{fontWeight:600, fontSize:18, lineHeight:1.3, marginBottom:6, letterSpacing:'-0.01em'}}>{window.pickLocalised(job, 'title') || job.title}</div>
        <div style={{fontSize:13, color:'var(--t-ink-muted)', display:'flex', alignItems:'center', gap:12, flexWrap:'wrap'}}>
          <span style={{display:'flex', alignItems:'center', gap:4}}><Icon name="location" size={13}/> {job.city}</span>
          <span style={{display:'flex', alignItems:'center', gap:4}}><Icon name="user" size={13}/> {job.familySize}</span>
        </div>
      </div>
      <div style={{textAlign:'right', flexShrink:0}}>
        <div style={{fontWeight:700, fontSize:18, letterSpacing:'-0.01em'}}>{job.salary}</div>
        <div style={{fontSize:12, color:'var(--t-ink-muted)', marginTop:2}}>{job.posted}</div>
      </div>
    </div>
    <div style={{fontSize:14, color:'var(--t-ink-muted)', lineHeight:1.55, display:'-webkit-box', WebkitLineClamp:2, WebkitBoxOrient:'vertical', overflow:'hidden', marginBottom:14}}>
      {window.pickLocalised(job, 'description') || job.description}
    </div>
    <div style={{display:'flex', alignItems:'center', justifyContent:'space-between'}}>
      <div style={{display:'flex', gap:6, flexWrap:'wrap'}}>
        {job.skills.slice(0, 3).map(s => <span key={s} className="chip" style={{fontSize:11}}>{s}</span>)}
      </div>
      <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{job.applicants} {t('jobs.applicants')}</div>
    </div>
  </div>
  );
};

// ===== Skill icons (taxonomy glyphs) =====
// Per-skill SVGs from IconSet.html — designed for the SkillsGroup chips and the
// Personality tiles on the candidate detail page. Drawn with the same 1.8px
// round stroke as the main Icon registry.
//
// 5 colored discs per category (used as item disc bg/fg + section header tile).
// Tints share a soft pastel palette: coral / amber / mint / ochre / plum.
const SKILL_CAT_COLORS = {
  language:    { bg: 'var(--coral-light)', fg: 'var(--coral-dark)' },
  personality: { bg: '#FBE9C5',           fg: '#8A5A12' },
  main:        { bg: 'var(--mint-light)', fg: 'var(--mint-dark)' },
  cooking:     { bg: '#FBD9C3',           fg: '#B85A2C' },
  other:       { bg: '#E5E0F0',           fg: '#5A4B86' },
};

const SKILL_ICON_PATHS = {
  // ----- Category headers -----
  'cat-language':    <><path d="M4 6.5a2.5 2.5 0 0 1 2.5-2.5h7A2.5 2.5 0 0 1 16 6.5v3A2.5 2.5 0 0 1 13.5 12H9l-3 3v-3a2 2 0 0 1-2-2.5z"/><path d="M9 14.5v.5a2.5 2.5 0 0 0 2.5 2.5H16l3 3v-3a2 2 0 0 0 2-2.5v-3a2.5 2.5 0 0 0-2.5-2.5h-.5"/></>,
  'cat-personality': <><circle cx="12" cy="12" r="5"/><path d="M9.5 11.5h.01M14.5 11.5h.01"/><path d="M9.5 14a3 3 0 0 0 5 0"/><path d="M12 3v1.5M12 19.5V21M3 12h1.5M19.5 12H21M5.6 5.6l1.1 1.1M17.3 17.3l1.1 1.1M5.6 18.4l1.1-1.1M17.3 6.7l1.1-1.1"/></>,
  'cat-main':        <><path d="M3 13v5a2 2 0 0 0 2 2h2v-9H5a2 2 0 0 0-2 2z"/><path d="M7 11h2.5l2 1c1 .5 2 1 3.5 1h3.5a1.5 1.5 0 0 1 0 3H14"/><path d="M14 16l3 3a2 2 0 0 0 2.8 0L21 18"/><path d="M11 7.5c0-1 .8-1.8 1.8-1.8.6 0 1.1.3 1.4.8.3-.5.8-.8 1.4-.8 1 0 1.8.8 1.8 1.8 0 1.4-2 2.7-3.2 3.5C13 10.2 11 8.9 11 7.5z"/></>,
  'cat-cooking':     <><path d="M5 11h14v5a3 3 0 0 1-3 3H8a3 3 0 0 1-3-3z"/><path d="M3 13h2M19 13h2"/><path d="M5 11l-.5-1M19 11l.5-1"/><path d="M9 7c0-1 1-1.5 1-2.5S9 3 9 3M13 7c0-1 1-1.5 1-2.5S13 3 13 3"/></>,
  'cat-other':       <><circle cx="7.5" cy="9" r="3.5"/><rect x="13" y="5.5" width="7" height="7" rx="1.2"/><path d="M5 16.5h14"/><circle cx="9" cy="19" r="0.5" fill="currentColor"/><circle cx="13" cy="19" r="0.5" fill="currentColor"/><circle cx="17" cy="19" r="0.5" fill="currentColor"/></>,

  // ----- Personality (10) -----
  patient:     <><path d="M7 3h10M7 21h10"/><path d="M7 3v3c0 2 5 4 5 6s-5 4-5 6v3"/><path d="M17 3v3c0 2-5 4-5 6s5 4 5 6v3"/><path d="M9 19h6"/></>,
  cheerful:    <><circle cx="12" cy="12" r="9"/><path d="M8 14a4.5 4.5 0 0 0 8 0"/><circle cx="9" cy="10" r="0.6" fill="currentColor"/><circle cx="15" cy="10" r="0.6" fill="currentColor"/></>,
  independent: <><circle cx="12" cy="5" r="2"/><path d="M12 7v8"/><path d="M12 10l4-3"/><path d="M12 10l-3 2"/><path d="M12 15l-2.5 6"/><path d="M12 15l2.5 6"/></>,
  detail:      <><circle cx="10.5" cy="10.5" r="6"/><path d="m20 20-4.3-4.3"/><path d="m8 10.5 2 2 3-3"/></>,
  warm:        <><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.5A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/><path d="M3 6l1 1M21 6l-1 1M5 13l-1.5.5M19 13l1.5.5"/></>,
  calm:        <><path d="M12 4c-4 4-6 8-6 11a6 6 0 0 0 12 0c0-3-2-7-6-11z"/><path d="M12 8v11"/></>,
  reliable:    <><path d="M12 3 5 5.5V12c0 4.5 3 7.5 7 9 4-1.5 7-4.5 7-9V5.5z"/><path d="m9 12 2 2 4-4"/></>,
  organized:   <><rect x="4" y="4" width="16" height="16" rx="2"/><path d="M8 9h8M8 13h8M8 17h5"/></>,
  gentle:      <><circle cx="12" cy="12" r="2"/><path d="M12 10c0-2 1-4 3-4s2 2 1 3-2 1-4 1z"/><path d="M14 12c2 0 4 1 4 3s-2 2-3 1-1-2-1-4z"/><path d="M12 14c0 2-1 4-3 4s-2-2-1-3 2-1 4-1z"/><path d="M10 12c-2 0-4-1-4-3s2-2 3-1 1 2 1 4z"/></>,
  energetic:   <><path d="M13 3 5 14h6l-2 7 8-11h-6l2-7z"/></>,

  // ----- Personality (extended) — added to match the full filter set -----
  // good-listener: ear with sound waves
  'good-listener': <><path d="M8 12a4 4 0 1 1 8 0c0 2-1 3-2 4s-2 1-2 3a2 2 0 0 1-4 0c0-2 1-3 0-5"/><path d="M3 11a1.5 1.5 0 0 0 1 0M3 8a3 3 0 0 0 2 0M3 14a3 3 0 0 0 2 0"/></>,
  // hardworking: hammer
  hardworking: <><path d="M14 4l6 6-3 3-6-6z"/><path d="M11 7l-7 7v3h3l7-7"/></>,
  // honest: shield with check (slight variant)
  honest: <><path d="M12 2 4 6v6c0 5 3.5 9 8 10 4.5-1 8-5 8-10V6z"/><path d="m9 12 2 2 4-4"/></>,
  // initiative: lightbulb with rays
  initiative: <><path d="M12 2a6 6 0 0 0-3.5 11c.5.5 1 1 1 2v2h5v-2c0-1 .5-1.5 1-2A6 6 0 0 0 12 2z"/><path d="M10 19h4M11 22h2"/><path d="M2 5l1 1M22 5l-1 1M2 11h1.5M20.5 11H22"/></>,
  // kids-lover: parent + child silhouette + small heart
  'kids-lover': <><circle cx="9" cy="6" r="2"/><circle cx="16" cy="9" r="1.5"/><path d="M5 21v-6a4 4 0 0 1 8 0v6"/><path d="M14 21v-4a3 3 0 0 1 6 0v4"/></>,
  // love-cooking: pan + heart on top
  'love-cooking': <><ellipse cx="11" cy="15" rx="7" ry="3"/><path d="M4 15c0 3 3 5 7 5s7-2 7-5"/><path d="M18 15h4"/><path d="M11 9c-1-1.5-3-1-3 1s2 3 3 4c1-1 3-2 3-4s-2-2.5-3-1z" fill="currentColor"/></>,
  // loyal: shield with star inside
  loyal: <><path d="M12 3 5 5.5V12c0 4.5 3 7.5 7 9 4-1.5 7-4.5 7-9V5.5z"/><path d="m12 9 1 2.5 2.5.3-2 1.7.6 2.5-2.1-1.4-2.1 1.4.6-2.5-2-1.7 2.5-.3z"/></>,
  // pet-lover: paw + small heart on side
  'pet-lover': <><ellipse cx="10" cy="16" rx="3.5" ry="3"/><ellipse cx="5" cy="11" rx="1.5" ry="2"/><ellipse cx="15" cy="11" rx="1.5" ry="2"/><ellipse cx="8" cy="7" rx="1.4" ry="1.8"/><path d="M18 5c-1-1-2.5-.5-2.5 1s1 2.5 2.5 3.5c1.5-1 2.5-2 2.5-3.5S19 4 18 5z" fill="currentColor"/></>,
  // trustworthy: handshake (two hands meeting)
  trustworthy: <><path d="M3 14l5-5 3 3M21 14l-5-5-3 3"/><path d="M11 12l1 1 1-1"/><path d="M9 16c1 2 4 3 6 0"/><path d="M7 10l-4 4M17 10l4 4"/></>,
  // strong: dumbbell
  strong: <><rect x="3" y="9" width="3" height="6" rx="1"/><rect x="18" y="9" width="3" height="6" rx="1"/><rect x="2" y="11" width="2" height="2"/><rect x="20" y="11" width="2" height="2"/><rect x="6" y="11" width="12" height="2"/></>,
  // willing-to-learn: graduation cap
  'willing-to-learn': <><path d="M22 10 12 6 2 10l10 4z"/><path d="M6 12.5V17c0 1 3 3 6 3s6-2 6-3v-4.5"/><path d="M22 10v6"/></>,
  // work-without-supervision: standing figure with check beside
  'work-without-supervision': <><circle cx="9" cy="5" r="2"/><path d="M9 7v6l-2 7M9 13l3 3v4"/><path d="m17 12 2 2 3-3"/></>,

  // ----- Main Skills (11) -----
  baby:         <><circle cx="12" cy="11" r="6.5"/><circle cx="9.5" cy="10" r="0.6" fill="currentColor"/><circle cx="14.5" cy="10" r="0.6" fill="currentColor"/><path d="M10.5 13.5c.7.6 2.3.6 3 0"/><path d="M12 17.5v3"/><circle cx="12" cy="20.5" r="1.3"/></>,
  child:        <><path d="M12 3 5 10l7 7 7-7z"/><path d="M5 10h14M12 3v14"/><path d="M12 17c-1 1.5-1 3-2.5 4.5"/><path d="M11 19l1 .5M9.5 21l1.2-.4"/></>,
  teen:         <><path d="M4 14v-2a8 8 0 0 1 16 0v2"/><rect x="3" y="13" width="4" height="7" rx="1.4"/><rect x="17" y="13" width="4" height="7" rx="1.4"/></>,
  elderly:      <><circle cx="11" cy="5" r="2"/><path d="M11 7v5l-2 4-2 4"/><path d="M11 12l3 3v6"/><path d="M16 6v15"/><path d="M14.5 6h3"/></>,
  pet:          <><ellipse cx="12" cy="16" rx="4" ry="3.5"/><ellipse cx="6" cy="11" rx="1.8" ry="2.3"/><ellipse cx="18" cy="11" rx="1.8" ry="2.3"/><ellipse cx="9" cy="6.5" rx="1.6" ry="2.2"/><ellipse cx="15" cy="6.5" rx="1.6" ry="2.2"/></>,
  tutoring:     <><path d="M4 5a2 2 0 0 1 2-2h6v15H6a2 2 0 0 0-2 2z"/><path d="M20 5a2 2 0 0 0-2-2h-6v15h6a2 2 0 0 1 2 2z"/><path d="M12 3v15"/><path d="M7 8h2.5M14.5 8H17"/></>,
  housekeeping: <><path d="m3 11 9-7 9 7v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z"/><path d="M9 21v-6h6v6"/><path d="M16 7l1-2"/></>,
  cooking:      <><ellipse cx="11" cy="14" rx="7" ry="3"/><path d="M4 14c0 3 3 5 7 5s7-2 7-5"/><path d="M18 14h4"/><path d="M9 7c0-1 1-1.5 1-2.5S9 3 9 3M13 7c0-1 1-1.5 1-2.5S13 3 13 3"/></>,
  driving:      <><path d="M5 16h14l-1.5-5a2 2 0 0 0-1.9-1.4H8.4a2 2 0 0 0-1.9 1.4z"/><rect x="3" y="14" width="18" height="5" rx="1.5"/><circle cx="8" cy="19" r="1.4"/><circle cx="16" cy="19" r="1.4"/></>,
  marketing:    <><path d="M5 8h14l-1 12a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1z"/><path d="M9 11V7a3 3 0 0 1 6 0v4"/></>,
  groceries:    <><path d="M12 7c-2-2-7-1-7 4 0 5 4 10 7 10s7-5 7-10c0-5-5-6-7-4z"/><path d="M12 7V4"/><path d="M12 4c1-1 2.5-1.5 4-1-1 2-2.5 3-4 3z"/></>,

  // ----- Other Skills (11) -----
  baking:           <><path d="M4 17c0-5 3-9 8-9s8 4 8 9z"/><path d="M8 17c0-3 2-5 4-5s4 2 4 5"/><path d="M12 8V5"/></>,
  caregiver:        <><path d="M12 21s-7-4.5-7-10a4 4 0 0 1 7-2.5A4 4 0 0 1 19 11c0 5.5-7 10-7 10z"/><path d="M12 9v6M9 12h6"/></>,
  'car-wash':       <><path d="M5 17h14"/><path d="M7 17v-3a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v3"/><circle cx="9" cy="7" r="1"/><circle cx="13" cy="5" r="1.2"/><circle cx="16" cy="8" r="0.8"/><circle cx="6" cy="10" r="0.6"/></>,
  computer:         <><rect x="4" y="5" width="16" height="11" rx="1.5"/><path d="M2 18h20"/><path d="M9 13h6"/></>,
  'driving-licence':<><rect x="3" y="6" width="18" height="13" rx="2"/><circle cx="8.5" cy="12" r="1.8"/><path d="M6.5 16c.4-1.2 1.2-2 2-2s1.6.8 2 2"/><path d="M14 10h4M14 13h3M14 16h2"/></>,
  'first-aid':      <><rect x="3" y="7" width="18" height="13" rx="2"/><path d="M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/><path d="M12 11v5M9.5 13.5h5"/></>,
  gardening:        <><path d="M12 21V11"/><path d="M12 11c0-3 2-5 5-5-.3 3-2 5-5 5z"/><path d="M12 14c0-2.5-1.5-4-4-4 .2 2.5 1.7 4 4 4z"/><path d="M5 21h14"/></>,
  handyman:         <><path d="M14.7 6.3a4 4 0 0 0 5 5L21 13l-8 8-8-8 1.7-1.7a4 4 0 0 0 5-5L13 5l1.7 1.3z"/></>,
  housework:        <><path d="m4 20 7-7"/><path d="m14 4 6 6-3 3-2-2-1.5 1.5-2-2L13 9l-2-2z"/><path d="M4 20l-1 1M7 17l-1.5 2M10 14l-1 2.5"/></>,
  sewing:           <><path d="m4 20 14-14"/><circle cx="19" cy="5" r="1.4"/><path d="M14 8c-1 1.5-3 1-3.5 2.5s2 2 2 3.5"/></>,
  swimming:         <><circle cx="9" cy="6" r="2"/><path d="m11 8 3 3-2 2-4-1.5"/><path d="M2 17c1.5-1.5 3-1.5 4.5 0s3 1.5 4.5 0 3-1.5 4.5 0 3 1.5 4.5 0"/><path d="M2 21c1.5-1.5 3-1.5 4.5 0s3 1.5 4.5 0 3-1.5 4.5 0 3 1.5 4.5 0"/></>,
};

const SkillIcon = ({ name, size = 18 }) => {
  const paths = SKILL_ICON_PATHS[name];
  if (!paths) return null;
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      {paths}
    </svg>
  );
};

Object.assign(window, { Icon, SkillIcon, SKILL_CAT_COLORS, Avatar, Toggle, Nav, Footer, TierBadge, VerifiedBadge, VerificationBadge, LanguageSwitcher, VideoThumb, CandidateCard, JobCard, shadeColor, VIDEO_CATEGORIES, getVideos, getVideoList, getVideoCount, getIntroVideo, hasAnyVideo, isOfficial });
