// ScrollJob v2 — Design tokens + shared chrome + components
// Broad job-board redesign. Teal primary, warm humanist type, no emojis in UI.
// Loaded FIRST: every v2 screen depends on these.

// ────────────────────────────────────────────────────────────────────────
// TOKENS
// ────────────────────────────────────────────────────────────────────────
const V2 = {
  // ─── Brand: indigo→violet anchored on the logo gradient ───────────
  // The SJ mark is a purple→blue gradient. Primary should feel violet-blue,
  // not pure SaaS blue. Pure #2563eb felt too blue against the logo, so we
  // shift primary to indigo (mid-gradient) and keep blue + purple as the
  // two ends of the brand gradient.
  primary:      '#6366F1',  // indigo-500 — buttons, links, CTAs, headers
  primaryDark:  '#4F46E5',  // indigo-600 — hover
  primarySoft:  '#EEF2FF',  // indigo-50 — soft panels
  primaryRing:  '#E0E7FF',  // indigo-200 — hover/active rings
  primaryInk:   '#3730A3',  // indigo-800 — text on primarySoft

  // ─── Hero accent: purple→blue gradient from logo ──────────────────
  // Logo is a purple→blue "SJ" monogram. Hero, premium CTAs and Sponsored
  // tier echo the logo gradient. Not base chrome — accent only.
  heroFrom:     '#A855F7',  // bright violet (top of logo)
  heroTo:       '#2563EB',  // logo blue (arrow / bottom)
  brandPurple:  '#A855F7',
  brandBlue:    '#2563EB',
  brandIndigo:  '#6366F1',  // mid-gradient
  brandGradient:'linear-gradient(135deg, #A855F7 0%, #6366F1 50%, #2563EB 100%)',

  // ─── Tier badges (Section 9) ───────────────────────────────────────
  sponsoredBg:  '#A855F7',  // logo purple = "premium" energy
  sponsoredFg:  '#ffffff',
  featuredBg:   '#6366F1',  // logo indigo = "boosted"
  featuredFg:   '#ffffff',

  // ─── Surfaces: clean white (matches prod) ──────────────────────────
  bg:           '#ffffff',  // pure white page (was warm off-white)
  bgAlt:        '#f9fafb',  // raised surfaces, footer bg — slate-50
  panel:        '#ffffff',
  ink:          '#101828',
  ink2:         '#1D2939',
  text:         '#344054',
  muted:        '#667085',
  faint:        '#98A2B3',

  // Lines — softer
  line:         '#EAECF0',
  lineSoft:     '#F2F4F7',
  lineStrong:   '#D0D5DD',

  // Status
  success:      '#067647',
  successBg:    '#ECFDF3',
  successLine:  '#ABEFC6',
  warn:         '#B54708',
  warnBg:       '#FFFAEB',
  warnLine:     '#FEDF89',
  danger:       '#B42318',
  dangerBg:     '#FEF3F2',
  dangerLine:   '#FECDCA',
  info:         '#175CD3',
  infoBg:       '#EFF8FF',
  infoLine:     '#B2DDFF',

  // Type — Public Sans is a warm humanist sans, broad audience.
  // Falls back gracefully to system-ui without a Google Fonts dependency.
  font: '"Public Sans", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
  fontMono: 'ui-monospace, "SF Mono", Menlo, Consolas, monospace',

  // Radii — larger, softer
  r: 8, rMd: 12, rLg: 16, rXl: 20, r2xl: 28, rFull: 9999,

  // Shadows — soft, layered
  shadowSm:  '0 1px 2px rgba(16, 24, 40, 0.05)',
  shadow:    '0 1px 3px rgba(16, 24, 40, 0.10), 0 1px 2px rgba(16, 24, 40, 0.06)',
  shadowMd:  '0 4px 8px -2px rgba(16, 24, 40, 0.10), 0 2px 4px -2px rgba(16, 24, 40, 0.06)',
  shadowLg:  '0 12px 16px -4px rgba(16, 24, 40, 0.08), 0 4px 6px -2px rgba(16, 24, 40, 0.03)',
  shadowXl:  '0 20px 24px -4px rgba(16, 24, 40, 0.08), 0 8px 8px -4px rgba(16, 24, 40, 0.03)',

  // Category palette — used across cards, hubs, swipe stacks
  cats: {
    Retail:       { bg: '#FFF1E6', fg: '#9A3412', accent: '#EA580C' },
    Hospitality:  { bg: '#FEF3C7', fg: '#854D0E', accent: '#D97706' },
    Healthcare:   { bg: '#FCE7F3', fg: '#9D174D', accent: '#DB2777' },
    Logistics:    { bg: '#E0E7FF', fg: '#3730A3', accent: '#4F46E5' },
    Construction: { bg: '#FEF3C7', fg: '#92400E', accent: '#D97706' },
    Office:       { bg: '#F0FDFA', fg: '#115E59', accent: '#0D9488' },
    Remote:       { bg: '#DBEAFE', fg: '#1E3A8A', accent: '#2563EB' },
    'Part-time':  { bg: '#F5F3FF', fg: '#5B21B6', accent: '#7C3AED' },
    Graduate:     { bg: '#FAE8FF', fg: '#86198F', accent: '#A21CAF' },
    Tech:         { bg: '#E0F2FE', fg: '#075985', accent: '#0284C7' },
    Driving:      { bg: '#F1F5F9', fg: '#1E293B', accent: '#475569' },
    Care:         { bg: '#FCE7F3', fg: '#9D174D', accent: '#DB2777' },
    Trades:       { bg: '#FEF3C7', fg: '#92400E', accent: '#D97706' },
  },
};

// ────────────────────────────────────────────────────────────────────────
// ICON SYSTEM — minimal stroke icons, replace emojis everywhere
// ────────────────────────────────────────────────────────────────────────
function Icon({ name, size = 18, color = 'currentColor', strokeWidth = 1.75, style }) {
  const s = { width: size, height: size, display: 'inline-block', flexShrink: 0, verticalAlign: 'middle', ...style };
  const stroke = color, fill = 'none';
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill, stroke, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round', style: s };
  switch (name) {
    case 'search':       return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>;
    case 'pin':          return <svg {...props}><path d="M12 21s-7-7-7-12a7 7 0 1 1 14 0c0 5-7 12-7 12Z"/><circle cx="12" cy="9" r="2.5"/></svg>;
    case 'briefcase':    return <svg {...props}><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 'money':        return <svg {...props}><rect x="3" y="6" width="18" height="12" rx="2"/><circle cx="12" cy="12" r="2.5"/><path d="M6 9v.01M18 15v.01"/></svg>;
    case 'clock':        return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>;
    case 'bookmark':     return <svg {...props}><path d="M6 3h12v18l-6-4-6 4V3Z"/></svg>;
    case 'bookmarkFill': return <svg {...props} fill={color} stroke="none"><path d="M6 3h12v18l-6-4-6 4V3Z"/></svg>;
    case 'heart':        return <svg {...props}><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"/></svg>;
    case 'heartFill':    return <svg {...props} fill={color} stroke="none"><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"/></svg>;
    case 'share':        return <svg {...props}><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="m8 11 8-4M8 13l8 4"/></svg>;
    case 'arrow-right':  return <svg {...props}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case 'arrow-left':   return <svg {...props}><path d="M19 12H5M11 5l-7 7 7 7"/></svg>;
    case 'check':        return <svg {...props}><path d="m5 12 5 5L20 7"/></svg>;
    case 'x':            return <svg {...props}><path d="M18 6 6 18M6 6l12 12"/></svg>;
    case 'plus':         return <svg {...props}><path d="M12 5v14M5 12h14"/></svg>;
    case 'minus':        return <svg {...props}><path d="M5 12h14"/></svg>;
    case 'menu':         return <svg {...props}><path d="M4 6h16M4 12h16M4 18h16"/></svg>;
    case 'sliders':      return <svg {...props}><path d="M4 6h12M18 6h2M4 12h6M12 12h8M4 18h14M18 18h2"/><circle cx="17" cy="6" r="2"/><circle cx="11" cy="12" r="2"/><circle cx="15" cy="18" r="2"/></svg>;
    case 'bell':         return <svg {...props}><path d="M18 16V11a6 6 0 1 0-12 0v5l-2 2h16l-2-2Z"/><path d="M10 20a2 2 0 0 0 4 0"/></svg>;
    case 'user':         return <svg {...props}><circle cx="12" cy="8" r="4"/><path d="M4 20a8 8 0 0 1 16 0"/></svg>;
    case 'building':     return <svg {...props}><path d="M4 21h16M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16"/><path d="M10 8h4M10 12h4M10 16h4"/></svg>;
    case 'globe':        return <svg {...props}><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 'home':         return <svg {...props}><path d="m3 11 9-8 9 8"/><path d="M5 10v11h14V10"/><path d="M10 21v-6h4v6"/></svg>;
    case 'sparkle':      return <svg {...props}><path d="M12 4v4M12 16v4M4 12h4M16 12h4M6.3 6.3l2.8 2.8M14.9 14.9l2.8 2.8M6.3 17.7l2.8-2.8M14.9 9.1l2.8-2.8"/></svg>;
    case 'flame':        return <svg {...props}><path d="M12 21c-3.5 0-6-2.4-6-5.5 0-2 1.3-3.7 2.4-4.5 0 2 .8 3 2.1 3 0-3 1-5.5 4-9 .5 4 3.5 5 3.5 8.5 0 1-.2 2-.5 2.8C16.8 19 14.7 21 12 21Z"/></svg>;
    case 'lightning':    return <svg {...props}><path d="M13 3 4 14h7l-1 7 9-11h-7l1-7Z"/></svg>;
    case 'shield':       return <svg {...props}><path d="M12 3 4 6v6c0 5 4 8 8 9 4-1 8-4 8-9V6l-8-3Z"/><path d="m9 12 2 2 4-4"/></svg>;
    case 'eye':          return <svg {...props}><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Z"/><circle cx="12" cy="12" r="3"/></svg>;
    case 'mail':         return <svg {...props}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/></svg>;
    case 'star':         return <svg {...props}><path d="M12 3 14.5 9l6.5.5-5 4.5 1.5 6.5L12 17l-5.5 3.5L8 14 3 9.5 9.5 9 12 3Z"/></svg>;
    case 'starFill':     return <svg {...props} fill={color} stroke="none"><path d="M12 3 14.5 9l6.5.5-5 4.5 1.5 6.5L12 17l-5.5 3.5L8 14 3 9.5 9.5 9 12 3Z"/></svg>;
    case 'chevron-down': return <svg {...props}><path d="m6 9 6 6 6-6"/></svg>;
    case 'chevron-right':return <svg {...props}><path d="m9 6 6 6-6 6"/></svg>;
    case 'document':     return <svg {...props}><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9l-6-6Z"/><path d="M14 3v6h6"/></svg>;
    case 'edit':         return <svg {...props}><path d="M4 20h4l11-11-4-4L4 16v4Z"/><path d="m14 6 4 4"/></svg>;
    case 'play':         return <svg {...props}><path d="M7 4v16l13-8L7 4Z"/></svg>;
    case 'filter':       return <svg {...props}><path d="M3 5h18l-7 9v6l-4-2v-4L3 5Z"/></svg>;
    case 'spark-job':    return <svg {...props}><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="m12 11 1.5 2 2.5.4-1.8 1.8.4 2.5-2.6-1.2L9.4 18l.4-2.5L8 13.6l2.5-.4L12 11Z"/></svg>;
    case 'target':       return <svg {...props}><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1.5" fill={color}/></svg>;
    case 'trending':     return <svg {...props}><path d="m3 17 6-6 4 4 8-8"/><path d="M14 7h7v7"/></svg>;
    case 'tools':        return <svg {...props}><path d="M14 7a4 4 0 1 1-4 4l-7 7 3 3 7-7a4 4 0 0 1 1-7Z"/></svg>;
    case 'truck':        return <svg {...props}><path d="M3 17V7h11v10"/><path d="M14 10h5l2 4v3h-7"/><circle cx="7.5" cy="17.5" r="2"/><circle cx="16.5" cy="17.5" r="2"/></svg>;
    case 'cart':         return <svg {...props}><path d="M3 4h2l2.5 12h12L22 7H6"/><circle cx="9" cy="20" r="1.5"/><circle cx="18" cy="20" r="1.5"/></svg>;
    case 'cup':          return <svg {...props}><path d="M4 8h13v6a5 5 0 0 1-5 5H9a5 5 0 0 1-5-5V8Z"/><path d="M17 10h2a2 2 0 0 1 0 4h-2"/><path d="M7 3v2M11 3v2M15 3v2"/></svg>;
    case 'stethoscope':  return <svg {...props}><path d="M6 3v8a4 4 0 0 0 8 0V3"/><path d="M6 3h2M12 3h2"/><circle cx="18" cy="15" r="3"/><path d="M14 11v4"/></svg>;
    case 'graduate':     return <svg {...props}><path d="m2 9 10-5 10 5-10 5L2 9Z"/><path d="M6 11v5c0 2 3 3 6 3s6-1 6-3v-5"/></svg>;
    case 'hammer':       return <svg {...props}><path d="m13 8 7-7 3 3-7 7"/><path d="m12 9-8 8a2 2 0 1 0 3 3l8-8"/></svg>;
    default:             return <svg {...props}><circle cx="12" cy="12" r="9"/></svg>;
  }
}

// ────────────────────────────────────────────────────────────────────────
// SHARED CHROME — Header, Footer, Buttons, Badges, Cards
// ────────────────────────────────────────────────────────────────────────
function V2Logo({ size = 40 }) {
  // Wordmark PNG is cropped tight to its bbox + transparent bg, so the
  // image's geometric center == the wordmark's optical center. Flex-center
  // aligns it cleanly with the nav text in the header.
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center' }}>
      <img
        src="assets/scrolljob-wordmark.png"
        alt="ScrollJob"
        style={{ height: size, width: 'auto', display: 'block' }}
      />
    </span>
  );
}

function V2Header({ active, variant = 'public' }) {
  const links = variant === 'public'
    ? [
        ['Find jobs',  'Find jobs'],
        ['Discover',   'Discover'],
        ['Companies',  'Companies'],
        ['Career advice', 'Career advice'],
      ]
    : [
        ['Dashboard',  'Dashboard'],
        ['Saved',      'Saved'],
        ['Applications', 'Applications'],
        ['Resume',     'Resume'],
      ];
  return (
    <header style={{
      background: 'rgba(255,255,255,0.92)',
      backdropFilter: 'saturate(180%) blur(10px)',
      WebkitBackdropFilter: 'saturate(180%) blur(10px)',
      borderBottom: `1px solid ${V2.line}`,
      padding: '14px 0', position: 'sticky', top: 0, zIndex: 50,
    }}>
      <div style={{
        maxWidth: 1280, margin: '0 auto', padding: '0 32px',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 32,
      }}>
        <a style={{ textDecoration: 'none' }}><V2Logo /></a>
        <nav style={{ display: 'flex', gap: 4, flex: 1, justifyContent: 'center' }}>
          {links.map(([k, l]) => (
            <a key={k} style={{
              padding: '8px 14px', borderRadius: 8,
              color: active === k ? V2.ink : V2.text,
              background: active === k ? V2.bgAlt : 'transparent',
              fontWeight: active === k ? 600 : 500, fontSize: 15,
              textDecoration: 'none',
            }}>{l}</a>
          ))}
        </nav>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <a style={{
            padding: '8px 14px', color: V2.text, fontWeight: 500, fontSize: 15,
            textDecoration: 'none',
          }}>Sign in</a>
          <V2Button variant="ghost" size="sm">For employers</V2Button>
        </div>
      </div>
    </header>
  );
}

function V2Footer() {
  // Soft, warm footer — grounds page without slamming. bgAlt blends with hero/sections.
  return (
    <footer style={{
      background: V2.bgAlt, color: V2.text,
      borderTop: `1px solid ${V2.line}`,
      padding: '48px 0 24px', marginTop: 56,
    }}>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 32px' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr repeat(4, 1fr)', gap: 48, marginBottom: 36 }}>
          <div>
            <a style={{ display: 'inline-block', marginBottom: 14 }}>
              <img src="assets/scrolljob-wordmark.png" alt="ScrollJob" style={{ height: 36, width: 'auto', display: 'block' }} />
            </a>
            <p style={{ margin: 0, fontSize: 13.5, lineHeight: 1.55, maxWidth: 260, color: V2.muted }}>
              Find the right job faster. Search, swipe, save, apply — for every kind of work.
            </p>
          </div>
          {[
            ['Find work', ['Search jobs', 'Remote jobs', 'Part-time', 'Graduate jobs', 'By city', 'By industry']],
            ['Job seekers', ['Resume builder', 'Saved jobs', 'Job alerts', 'Career advice']],
            ['Employers',  ['Post a job', 'Pricing', 'Hiring solutions', 'Contact sales']],
            ['Company',    ['About', 'Press', 'Help centre', 'Terms', 'Privacy']],
          ].map(([title, items]) => (
            <div key={title}>
              <div style={{ fontWeight: 700, fontSize: 13, color: V2.ink, marginBottom: 12 }}>{title}</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                {items.map((i) => (
                  <a key={i} style={{ fontSize: 13.5, color: V2.text, textDecoration: 'none' }}>{i}</a>
                ))}
              </div>
            </div>
          ))}
        </div>
        <div style={{
          paddingTop: 20, borderTop: `1px solid ${V2.line}`,
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          fontSize: 12.5, color: V2.muted,
        }}>
          <span>© 2026 ScrollJob Ltd. All rights reserved.</span>
          <span style={{ display: 'inline-flex', gap: 16 }}>
            <a style={{ color: V2.muted, textDecoration: 'none' }}>English (UK)</a>
            <a style={{ color: V2.muted, textDecoration: 'none' }}>£ GBP</a>
          </span>
        </div>
      </div>
    </footer>
  );
}

// ────────────────────────────────────────────────────────────────────────
// Buttons — primary, secondary, ghost, destructive
// ────────────────────────────────────────────────────────────────────────
function V2Button({ children, variant = 'primary', size = 'md', icon, iconRight, full, onClick }) {
  const sizes = {
    sm: { padding: '8px 14px',  fontSize: 14, gap: 6, iconSize: 16, radius: 8 },
    md: { padding: '11px 18px', fontSize: 15, gap: 8, iconSize: 18, radius: 10 },
    lg: { padding: '14px 22px', fontSize: 16, gap: 10, iconSize: 20, radius: 12 },
    xl: { padding: '16px 28px', fontSize: 17, gap: 10, iconSize: 22, radius: 12 },
  }[size];
  const variants = {
    primary:    { bg: V2.primary, fg: '#fff', border: V2.primary, shadow: V2.shadowSm, hover: V2.primaryDark },
    secondary:  { bg: '#fff', fg: V2.ink, border: V2.lineStrong, shadow: V2.shadowSm },
    ghost:      { bg: 'transparent', fg: V2.text, border: 'transparent' },
    soft:       { bg: V2.primarySoft, fg: V2.primaryInk, border: 'transparent' },
    dark:       { bg: V2.ink, fg: '#fff', border: V2.ink, shadow: V2.shadowSm },
    destructive:{ bg: '#fff', fg: V2.danger, border: V2.dangerLine },
  }[variant];
  return (
    <button onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: sizes.gap,
      padding: sizes.padding, fontSize: sizes.fontSize, fontWeight: 600,
      background: variants.bg, color: variants.fg,
      border: `1px solid ${variants.border}`, borderRadius: sizes.radius,
      boxShadow: variants.shadow || 'none', cursor: 'pointer',
      fontFamily: V2.font, whiteSpace: 'nowrap',
      width: full ? '100%' : 'auto', letterSpacing: '-0.005em',
    }}>
      {icon && <Icon name={icon} size={sizes.iconSize} />}
      {children}
      {iconRight && <Icon name={iconRight} size={sizes.iconSize} />}
    </button>
  );
}

// ────────────────────────────────────────────────────────────────────────
// Badges — remote, hybrid, on-site, full-time, part-time, urgent, featured
// ────────────────────────────────────────────────────────────────────────
function V2Badge({ children, tone = 'neutral', size = 'md', icon }) {
  const tones = {
    neutral:  { bg: V2.bgAlt,       fg: V2.text,      line: V2.line },
    success:  { bg: V2.successBg,   fg: V2.success,   line: V2.successLine },
    warn:     { bg: V2.warnBg,      fg: V2.warn,      line: V2.warnLine },
    danger:   { bg: V2.dangerBg,    fg: V2.danger,    line: V2.dangerLine },
    info:     { bg: V2.infoBg,      fg: V2.info,      line: V2.infoLine },
    primary:  { bg: V2.primarySoft, fg: V2.primaryInk, line: V2.primaryRing },
    featured: { bg: '#FEF6E6',      fg: '#92400E',    line: '#FCD980' },
    urgent:   { bg: V2.dangerBg,    fg: V2.danger,    line: V2.dangerLine },
  };
  const t = tones[tone] || tones.neutral;
  const sizes = {
    sm: { padding: '2px 8px',  fontSize: 11.5, gap: 4, iconSize: 12 },
    md: { padding: '4px 10px', fontSize: 12.5, gap: 5, iconSize: 13 },
    lg: { padding: '6px 12px', fontSize: 13,   gap: 6, iconSize: 14 },
  }[size];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: sizes.gap,
      padding: sizes.padding, fontSize: sizes.fontSize, fontWeight: 600,
      background: t.bg, color: t.fg, border: `1px solid ${t.line}`,
      borderRadius: 999, lineHeight: 1.3, whiteSpace: 'nowrap',
    }}>
      {icon && <Icon name={icon} size={sizes.iconSize} />}
      {children}
    </span>
  );
}

// Category pill — derives color from V2.cats palette
function V2CatPill({ name, size = 'md' }) {
  const c = V2.cats[name] || { bg: V2.bgAlt, fg: V2.text };
  const sizes = {
    sm: { padding: '3px 9px',  fontSize: 11.5 },
    md: { padding: '5px 12px', fontSize: 12.5 },
    lg: { padding: '7px 14px', fontSize: 13.5 },
  }[size];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center',
      padding: sizes.padding, fontSize: sizes.fontSize, fontWeight: 600,
      background: c.bg, color: c.fg, borderRadius: 999, lineHeight: 1.3, whiteSpace: 'nowrap',
    }}>{name}</span>
  );
}

// ────────────────────────────────────────────────────────────────────────
// Company avatar — gradient by company name, fallback to monogram
// ────────────────────────────────────────────────────────────────────────
function V2CompanyAvatar({ name, size = 48, radius = 12, category }) {
  const c = V2.cats[category] || { bg: V2.primarySoft, fg: V2.primaryInk, accent: V2.primary };
  // Hash the name to a hue index so each company looks consistent
  const initial = (name || '?').trim()[0].toUpperCase();
  return (
    <span style={{
      width: size, height: size, borderRadius: radius,
      background: c.bg, color: c.fg,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontWeight: 800, fontSize: size * 0.42, flexShrink: 0,
      letterSpacing: '-0.02em',
      boxShadow: `inset 0 0 0 1px ${c.accent}22`,
    }}>{initial}</span>
  );
}

// ────────────────────────────────────────────────────────────────────────
// V2 Job card — THE core component
// Variants: 'full' (default, list/saved/discover), 'compact' (sidebar/similar),
// 'preview' (homepage hero preview)
// ────────────────────────────────────────────────────────────────────────
function V2JobCard({ job, variant = 'full', saved = false, featured = false, urgent = false }) {
  if (variant === 'compact') return <V2JobCardCompact job={job} saved={saved} />;
  return (
    <article style={{
      background: '#fff',
      border: `1px solid ${featured ? V2.primaryRing : V2.line}`,
      borderRadius: V2.rLg, padding: 24, position: 'relative',
      boxShadow: variant === 'preview' ? V2.shadowLg : V2.shadowSm,
      transition: 'all .15s ease',
      cursor: 'pointer',
    }}>
      {/* Tier badge — sponsored = purple gradient, featured = indigo solid, standard = none.
          Driven by either an explicit `job.tier` value or the legacy `featured` boolean. */}
      {(() => {
        const tier = job?.tier || (featured ? 'featured' : null);
        if (!tier || tier === 'standard') return null;
        if (tier === 'sponsored') {
          return (
            <div style={{
              position: 'absolute', top: -10, left: 18,
              padding: '3px 10px', background: V2.brandGradient, color: '#fff',
              border: 'none', borderRadius: 999,
              fontSize: 11, fontWeight: 800, letterSpacing: '0.06em', textTransform: 'uppercase',
              display: 'inline-flex', alignItems: 'center', gap: 5,
              boxShadow: V2.shadowSm,
            }}>
              <Icon name="sparkle" size={10} color="#FCD980" /> Sponsored
            </div>
          );
        }
        // featured
        return (
          <div style={{
            position: 'absolute', top: -10, left: 18,
            padding: '3px 10px', background: V2.primary, color: '#fff',
            border: 'none', borderRadius: 999,
            fontSize: 11, fontWeight: 800, letterSpacing: '0.06em', textTransform: 'uppercase',
            display: 'inline-flex', alignItems: 'center', gap: 5,
            boxShadow: V2.shadowSm,
          }}>
            <Icon name="starFill" size={10} /> Featured
          </div>
        );
      })()}

      <header style={{ display: 'flex', alignItems: 'flex-start', gap: 14, marginBottom: 14 }}>
        <V2CompanyAvatar name={job.company} category={job.category} size={48} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, marginBottom: 4 }}>
            <h3 style={{
              margin: 0, fontSize: 17, fontWeight: 700, color: V2.ink,
              letterSpacing: '-0.01em', lineHeight: 1.3,
            }}>{job.title}</h3>
            <button aria-label={saved ? 'Unsave' : 'Save'} style={{
              width: 36, height: 36, borderRadius: 8,
              border: `1px solid ${saved ? V2.dangerLine : V2.line}`,
              background: saved ? V2.dangerBg : '#fff',
              color: saved ? V2.danger : V2.muted,
              cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              flexShrink: 0,
            }}>
              <Icon name={saved ? 'bookmarkFill' : 'bookmark'} size={16} />
            </button>
          </div>
          <div style={{ fontSize: 14, color: V2.text, fontWeight: 500 }}>
            {job.company}
            {job.companyRating && (
              <span style={{ marginLeft: 8, color: V2.muted, fontSize: 13, display: 'inline-flex', alignItems: 'center', gap: 3 }}>
                <Icon name="starFill" size={12} color="#D97706" />
                {job.companyRating}
              </span>
            )}
          </div>
        </div>
      </header>

      {/* Meta row — salary, location, type */}
      <div style={{ display: 'flex', gap: 18, flexWrap: 'wrap', marginBottom: 14, fontSize: 14 }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: V2.ink, fontWeight: 600 }}>
          <Icon name="money" size={16} color={V2.muted} />
          {job.salary}
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: V2.text }}>
          <Icon name="pin" size={16} color={V2.muted} />
          {job.location}
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: V2.text }}>
          <Icon name="briefcase" size={16} color={V2.muted} />
          {job.type}
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: V2.muted }}>
          <Icon name="clock" size={16} color={V2.muted} />
          {job.posted}
        </span>
      </div>

      {/* Short description */}
      {job.summary && variant !== 'preview' && (
        <p style={{ margin: '0 0 14px', fontSize: 14, color: V2.text, lineHeight: 1.55, maxWidth: '60ch' }}>
          {job.summary}
        </p>
      )}

      {/* Tags row */}
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
        {job.category && <V2CatPill name={job.category} size="md" />}
        {job.workMode === 'Remote' && <V2Badge tone="success" icon="globe">Remote</V2Badge>}
        {job.workMode === 'Hybrid' && <V2Badge tone="info" icon="globe">Hybrid</V2Badge>}
        {job.workMode === 'On-site' && <V2Badge tone="neutral" icon="building">On-site</V2Badge>}
        {urgent && <V2Badge tone="urgent" icon="lightning">Urgent</V2Badge>}
        {job.benefits && job.benefits.slice(0, 2).map((b) => (
          <V2Badge key={b} tone="neutral">{b}</V2Badge>
        ))}
      </div>
    </article>
  );
}

function V2JobCardCompact({ job, saved }) {
  return (
    <a style={{
      display: 'block', background: '#fff',
      border: `1px solid ${V2.line}`, borderRadius: V2.rMd, padding: 16,
      textDecoration: 'none', color: 'inherit',
    }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
        <V2CompanyAvatar name={job.company} category={job.category} size={38} radius={10} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14.5, fontWeight: 600, color: V2.ink, lineHeight: 1.3 }}>{job.title}</div>
          <div style={{ fontSize: 13, color: V2.muted, marginTop: 2 }}>
            {job.company} · {job.location}
          </div>
          <div style={{ marginTop: 8, fontSize: 13, color: V2.ink, fontWeight: 600 }}>{job.salary}</div>
        </div>
      </div>
    </a>
  );
}

// ────────────────────────────────────────────────────────────────────────
// Search bar — used on homepage hero + job list page
// ────────────────────────────────────────────────────────────────────────
function V2SearchBar({ size = 'lg', defaultQ = '', defaultLoc = '' }) {
  const tall = size === 'lg';
  return (
    <div style={{
      background: '#fff', borderRadius: tall ? V2.rXl : V2.rMd,
      padding: tall ? 6 : 4, boxShadow: V2.shadowLg,
      display: 'flex', gap: 4, alignItems: 'center', flexWrap: 'wrap',
      border: `1px solid ${V2.line}`,
    }}>
      <div style={{ position: 'relative', flex: '2 1 280px' }}>
        <Icon name="search" size={tall ? 20 : 18} color={V2.muted}
              style={{ position: 'absolute', left: tall ? 20 : 14, top: '50%', transform: 'translateY(-50%)' }} />
        <input
          defaultValue={defaultQ}
          placeholder="Job title, keywords or company"
          style={{
            width: '100%', border: 'none', outline: 'none', background: 'transparent',
            padding: tall ? '18px 20px 18px 52px' : '12px 14px 12px 40px',
            fontSize: tall ? 16 : 14, fontFamily: V2.font, color: V2.ink, fontWeight: 500,
            boxSizing: 'border-box',
          }}
        />
      </div>
      <div style={{ width: 1, height: tall ? 32 : 24, background: V2.line }} />
      <div style={{ position: 'relative', flex: '1 1 200px' }}>
        <Icon name="pin" size={tall ? 20 : 18} color={V2.muted}
              style={{ position: 'absolute', left: tall ? 20 : 14, top: '50%', transform: 'translateY(-50%)' }} />
        <input
          defaultValue={defaultLoc}
          placeholder="City, town or postcode"
          style={{
            width: '100%', border: 'none', outline: 'none', background: 'transparent',
            padding: tall ? '18px 20px 18px 52px' : '12px 14px 12px 40px',
            fontSize: tall ? 16 : 14, fontFamily: V2.font, color: V2.ink, fontWeight: 500,
            boxSizing: 'border-box',
          }}
        />
      </div>
      <V2Button size={tall ? 'lg' : 'md'} icon="search">{tall ? 'Find jobs' : 'Search'}</V2Button>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// Stat card — for dashboards, hubs
// ────────────────────────────────────────────────────────────────────────
function V2Stat({ label, value, delta, deltaTone = 'success', sub, icon }) {
  return (
    <div style={{
      background: '#fff', border: `1px solid ${V2.line}`, borderRadius: V2.rLg,
      padding: 20,
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <span style={{ fontSize: 13, color: V2.muted, fontWeight: 500 }}>{label}</span>
        {icon && (
          <span style={{
            width: 32, height: 32, borderRadius: 8, background: V2.primarySoft,
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <Icon name={icon} size={16} color={V2.primary} />
          </span>
        )}
      </div>
      <div style={{ fontSize: 30, fontWeight: 700, color: V2.ink, letterSpacing: '-0.02em', lineHeight: 1.1, marginTop: 10 }}>
        {value}
      </div>
      {(delta || sub) && (
        <div style={{ fontSize: 13, marginTop: 8, display: 'inline-flex', alignItems: 'center', gap: 6 }}>
          {delta && (
            <span style={{
              color: deltaTone === 'success' ? V2.success : deltaTone === 'danger' ? V2.danger : V2.muted,
              fontWeight: 600,
            }}>{delta}</span>
          )}
          {sub && <span style={{ color: V2.muted }}>{sub}</span>}
        </div>
      )}
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// Sample data — used across v2 screens
// ────────────────────────────────────────────────────────────────────────
const V2_JOBS = [
  { id: 1, title: 'Warehouse Operative — Day Shift', company: 'Bridgewater Logistics', companyRating: '4.3',
    location: 'Manchester, UK', salary: '£12.40 / hour', type: 'Full-time', posted: '2 days ago',
    category: 'Logistics', workMode: 'On-site',
    benefits: ['Free shuttle', 'Weekly pay', 'Overtime'],
    summary: "Pick, pack and load orders for one of the UK's largest grocery distribution centres. Full training provided — no warehouse experience needed." },
  { id: 2, title: 'Care Assistant — Residential Home', company: 'Lavender House Care', companyRating: '4.7',
    location: 'Bristol, UK', salary: '£12.80 / hour', type: 'Part-time', posted: '5 hours ago',
    category: 'Healthcare', workMode: 'On-site',
    benefits: ['Paid training', 'Pension', 'Sponsorship available'],
    summary: 'Support residents with daily activities, meals and companionship in a friendly residential home. NVQ Level 2 desirable but full training given.' },
  { id: 3, title: 'Delivery Driver — Local Routes', company: 'Mercury Couriers', companyRating: '4.1',
    location: 'Birmingham, UK', salary: '£28,000 – £34,000', type: 'Full-time', posted: '1 day ago',
    category: 'Driving', workMode: 'On-site',
    benefits: ['Fuel card', 'Van provided', 'Bonus scheme'],
    summary: 'Same-day deliveries across the West Midlands. Clean Cat-B licence required. Tracked routes, supportive depot team and consistent earnings.' },
  { id: 4, title: 'Retail Assistant — Flagship Store', company: 'Wren & Co.', companyRating: '4.5',
    location: 'London, UK', salary: '£13.15 / hour', type: 'Part-time', posted: '3 days ago',
    category: 'Retail', workMode: 'On-site',
    benefits: ['Staff discount', 'Flexible shifts'],
    summary: "Be the face of our Oxford Street flagship — welcoming customers, styling outfits and keeping our floor looking its best." },
  { id: 5, title: 'Hotel Receptionist', company: 'The Bramley', companyRating: '4.4',
    location: 'Edinburgh, UK', salary: '£26,500', type: 'Full-time', posted: '4 days ago',
    category: 'Hospitality', workMode: 'On-site',
    benefits: ['Tips', 'Meals on shift', 'Career progression'],
    summary: 'Welcome guests, manage check-ins and keep the lobby running smoothly at our boutique Old Town hotel. Hospitality experience preferred.' },
  { id: 6, title: 'Remote Customer Support Specialist', company: 'Loop Energy', companyRating: '4.6',
    location: 'Remote, UK', salary: '£27,000 – £31,000', type: 'Full-time', posted: '12 hours ago',
    category: 'Remote', workMode: 'Remote',
    benefits: ['Work from home kit', 'Pension', '28 days holiday'],
    summary: 'Help customers manage their energy accounts via chat and email. UK-based remote role, supportive onboarding, and clear career path.' },
  { id: 7, title: 'Office Administrator', company: 'Northgate Solicitors', companyRating: '4.2',
    location: 'Leeds, UK · Hybrid', salary: '£24,000 – £28,000', type: 'Full-time', posted: '6 days ago',
    category: 'Office', workMode: 'Hybrid',
    benefits: ['Hybrid', 'Pension', 'Holiday loyalty'],
    summary: 'Keep our small legal practice running — diary management, reception cover and document filing. Hybrid working after probation.' },
  { id: 8, title: 'Graduate Trainee — Sales', company: 'Halo Health', companyRating: '4.5',
    location: 'Reading, UK · Hybrid', salary: '£28,000 + bonus', type: 'Graduate', posted: '1 day ago',
    category: 'Graduate', workMode: 'Hybrid', urgent: true,
    benefits: ['Structured training', 'Mentor', 'Fast progression'],
    summary: '12-month rotational programme across sales, marketing and operations. Open to 2024–2026 graduates from any discipline. Sponsorship considered.' },
  { id: 9, title: 'Qualified Electrician (NVQ Level 3)', company: 'Bright Spark Trades', companyRating: '4.8',
    location: 'Glasgow, UK', salary: '£38,000 – £46,000', type: 'Full-time', posted: '3 days ago',
    category: 'Trades', workMode: 'On-site',
    benefits: ['Van & tools', 'Overtime', 'CPD budget'],
    summary: 'Domestic and small commercial installs across central Glasgow. 17th/18th edition required. Long-term contracts, reliable monthly pay.' },
  { id: 10, title: 'Registered Nurse — Day Unit', company: 'St. Margaret\u2019s Trust', companyRating: '4.6',
    location: 'Leicester, UK', salary: 'Band 5 NHS', type: 'Full-time', posted: '2 days ago',
    category: 'Healthcare', workMode: 'On-site',
    benefits: ['NHS pension', 'CPD', 'Sponsorship available'],
    summary: 'Join our outpatient day unit looking after pre- and post-op patients. NMC registration required. Excellent learning culture.' },
  { id: 11, title: 'Software Engineer (Python)', company: 'Monzo Bank', companyRating: '4.7',
    location: 'London, UK', salary: '£90,000 – £120,000', type: 'Full-time', posted: '2 hours ago',
    category: 'Tech', workMode: 'Hybrid', featured: true,
    benefits: ['Equity', 'Remote-friendly', '33 days holiday'],
    summary: 'Join the Platform team building rails for a digital bank with 8m+ customers. Async-first Python services.' },
  { id: 12, title: 'Sales Representative (Field)', company: 'Wessex Drinks Co.', companyRating: '4.0',
    location: 'South West, UK', salary: '£26,000 + OTE £40k', type: 'Full-time', posted: '1 week ago',
    category: 'Retail', workMode: 'On-site',
    benefits: ['Company car', 'Uncapped bonus'],
    summary: 'Visit pubs, restaurants and independent retailers across Devon, Somerset and Dorset to grow our craft drinks portfolio.' },
];

// ────────────────────────────────────────────────────────────────────────
// V2 categories (homepage chips, hubs)
// ────────────────────────────────────────────────────────────────────────
const V2_CATEGORIES = [
  { name: 'Retail',       icon: 'cart',         count: 12480 },
  { name: 'Hospitality',  icon: 'cup',          count: 8214  },
  { name: 'Healthcare',   icon: 'stethoscope',  count: 9612  },
  { name: 'Logistics',    icon: 'truck',        count: 6480  },
  { name: 'Construction', icon: 'hammer',       count: 4218  },
  { name: 'Office',       icon: 'building',     count: 11248 },
  { name: 'Remote',       icon: 'globe',        count: 5128  },
  { name: 'Part-time',    icon: 'clock',        count: 7842  },
  { name: 'Graduate',     icon: 'graduate',     count: 2418  },
  { name: 'Tech',         icon: 'lightning',    count: 4218  },
];

// ────────────────────────────────────────────────────────────────────────
// Infinite scroll sentinels (used on listings + hubs)
// ────────────────────────────────────────────────────────────────────────
function V2InfiniteSentinel({ loaded, total }) {
  return (
    <div style={{
      height: 80, marginTop: 8, background: V2.bgAlt, borderRadius: V2.rMd,
      display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 12,
      color: V2.muted, fontSize: 13.5, fontWeight: 500,
    }}>
      <span style={{
        display: 'inline-block', width: 18, height: 18, borderRadius: '50%',
        border: `3px solid ${V2.line}`, borderTopColor: V2.primary,
        animation: 'v2spin 0.9s linear infinite',
      }} />
      Loading more jobs… {loaded != null && total != null && (
        <span style={{ color: V2.faint }}>· {loaded} of {total}</span>
      )}
      <style>{`@keyframes v2spin { to { transform: rotate(360deg); } }`}</style>
    </div>
  );
}

function V2EndOfResults({ kind = 'jobs' }) {
  return (
    <div style={{
      height: 120, marginTop: 12, padding: '0 24px',
      background: V2.bg, borderRadius: V2.rMd,
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      gap: 6, textAlign: 'center',
    }}>
      <div style={{ fontSize: 18, fontWeight: 600, color: V2.ink, letterSpacing: '-0.01em' }}>
        You've seen them all
      </div>
      <div style={{ fontSize: 13.5, color: V2.muted, marginBottom: 8 }}>
        Try broadening your filters or set up a job alert.
      </div>
      <V2Button variant="secondary" size="sm" icon="bell">Set up alert</V2Button>
    </div>
  );
}

// Export everything onto window (Babel scripts don't share scope otherwise)
Object.assign(window, {
  V2, Icon, V2Logo, V2Header, V2Footer,
  V2Button, V2Badge, V2CatPill, V2CompanyAvatar,
  V2JobCard, V2JobCardCompact, V2SearchBar, V2Stat,
  V2InfiniteSentinel, V2EndOfResults,
  V2_JOBS, V2_CATEGORIES,
});
