// Numerology landing — section components
// Exports to window: NumHeader, NumHero, NumWhat, NumHow, NumTestimonials, NumCrossSell, NumFooter, NumDisclaimer, NumAboutXtra

const SG = '#14C560';     // Saladin green
const SN = '#1E3888';     // Saladin navy
const SG_DEEP = '#005323';
const SG_TINT = '#F6FFF2';
const HEADER_BASE_PATH = '/than-so-hoc';
const HEADER_BASE_PATH_NO_SLASH = HEADER_BASE_PATH.replace(/\/+$/, '') || '/than-so-hoc';

function parseCsvLine(line) {
  const out = [];
  let cur = '';
  let inQuotes = false;
  for (let i = 0; i < line.length; i += 1) {
    const ch = line[i];
    if (ch === '"') {
      if (inQuotes && line[i + 1] === '"') { cur += '"'; i += 1; }
      else inQuotes = !inQuotes;
    } else if (ch === ',' && !inQuotes) {
      out.push(cur); cur = '';
    } else {
      cur += ch;
    }
  }
  out.push(cur);
  return out;
}

function csvToObjects(text) {
  const lines = String(text || '')
    .split(/\r?\n/)
    .map((l) => l.trim())
    .filter(Boolean);
  if (!lines.length) return [];
  const header = parseCsvLine(lines[0]).map((h) => h.trim());
  return lines.slice(1).map((line) => {
    const cols = parseCsvLine(line);
    const row = {};
    header.forEach((h, idx) => { row[h] = (cols[idx] || '').trim(); });
    return row;
  });
}

const DEFAULT_SAMPLE_PROFILES = [
  { n: 1, name: 'Minh', dob: '11/01/1993', title: 'Người dẫn dắt · quyết đoán · chủ động', tags: ['Lãnh đạo', 'Bản lĩnh', 'Tập trung', 'Tiên phong'], yearLabel: 'Năm tăng tốc', avatar: 'assets/avatars/male-vn/male-vn-1.png' },
  { n: 2, name: 'Linh', dob: '21/02/1996', title: 'Người kết nối · tinh tế · kiên nhẫn', tags: ['Hợp tác', 'Lắng nghe', 'Hòa hợp', 'Bền bỉ'], yearLabel: 'Năm vun đắp', avatar: 'assets/avatars/female-vn/female-vn-6.png' },
  { n: 3, name: 'Quân', dob: '13/03/1995', title: 'Người truyền cảm hứng · sáng tạo · cởi mở', tags: ['Sáng tạo', 'Giao tiếp', 'Lan tỏa', 'Lạc quan'], yearLabel: 'Năm mở rộng', avatar: 'assets/avatars/male-vn/male-vn-2.png' },
  { n: 4, name: 'Huyền', dob: '04/04/1991', title: 'Người xây nền tảng · kỷ luật · thực tế', tags: ['Kỷ luật', 'Logic', 'Ổn định', 'Tỉ mỉ'], yearLabel: 'Năm củng cố', avatar: 'assets/avatars/female-vn/female-vn-7.png' },
  { n: 5, name: 'Đức', dob: '25/05/1992', title: 'Người linh hoạt · trải nghiệm · thích nghi', tags: ['Tự do', 'Nhạy bén', 'Thử thách', 'Đổi mới'], yearLabel: 'Năm chuyển động', avatar: 'assets/avatars/male-vn/male-vn-3.png' },
  { n: 6, name: 'Trang', dob: '06/06/1994', title: 'Người chăm sóc · trách nhiệm · ấm áp', tags: ['Quan tâm', 'Cam kết', 'Cân bằng', 'Tin cậy'], yearLabel: 'Năm trách nhiệm', avatar: 'assets/avatars/female-vn/female-vn-8.png' },
  { n: 7, name: 'An', dob: '12/03/1995', title: 'Người tìm tòi · phân tích · trầm tĩnh', tags: ['Trí tuệ', 'Độc lập', 'Trực giác', 'Cầu toàn'], yearLabel: 'Năm tự nhìn lại', avatar: 'assets/avatars/male-vn/male-vn-4.png' },
  { n: 8, name: 'Phúc', dob: '18/08/1989', title: 'Người thực thi · tham vọng · hiệu suất', tags: ['Kết quả', 'Quản trị', 'Tài chính', 'Kỷ cương'], yearLabel: 'Năm bứt phá', avatar: 'assets/avatars/male-vn/male-vn-5.png' },
  { n: 9, name: 'Mai', dob: '09/09/1990', title: 'Người nhân văn · thấu cảm · bao dung', tags: ['Phụng sự', 'Thấu hiểu', 'Khép vòng', 'Tử tế'], yearLabel: 'Năm hoàn tất', avatar: 'assets/avatars/female-vn/female-vn-5.png' },
];

const DEFAULT_TESTIMONIALS = [
  { name: 'Trần Hà Anh', gender: 'female', role: 'Marketing Manager · Hà Nội', quote: 'Mình thấy mô tả về con số chủ đạo 3 đúng đến bất ngờ — nhất là phần về khả năng giao tiếp. Đọc xong thấy hiểu mình hơn.', avatar: 'assets/avatars/female-vn/female-vn-1.png', initial: 'T' },
  { name: 'Lê Quốc Việt', gender: 'male', role: 'Software Engineer · TP.HCM', quote: 'Phần năm cá nhân 2026 gợi ý đây là năm để nhìn lại và đầu tư cho gia đình. Trùng với việc mình đang cân nhắc mua bảo hiểm.', avatar: 'assets/avatars/male-vn/male-vn-6.png', initial: 'V' },
  { name: 'Nguyễn Mai Linh', gender: 'female', role: 'Mẹ 1 con · Đà Nẵng', quote: 'Giao diện sạch sẽ, không màu mè kiểu bói toán. Đọc xong yên tâm — không phải thầy phán "vận hạn" gì cả.', avatar: 'assets/avatars/female-vn/female-vn-2.png', initial: 'L' },
  { name: 'Phạm Hoàng Nam', gender: 'male', role: 'Sales Lead · TP.HCM', quote: 'Kết quả ngắn gọn, dễ đọc. Mình thích nhất phần gợi ý hành động theo năm cá nhân.', avatar: 'assets/avatars/male-vn/male-vn-7.png', initial: 'N' },
  { name: 'Đỗ Quỳnh Trang', gender: 'female', role: 'Nhân sự · Hà Nội', quote: 'Bố cục sạch và có chiều sâu. Dùng để chia sẻ với team trong buổi bonding khá ổn.', avatar: 'assets/avatars/female-vn/female-vn-3.png', initial: 'T' },
  { name: 'Bùi Minh Tâm', gender: 'male', role: 'Chủ shop · Cần Thơ', quote: 'Tra cứu nhanh, phần poster nhìn chuyên nghiệp nên mình có động lực chia sẻ lên Facebook.', avatar: 'assets/avatars/male-vn/male-vn-8.png', initial: 'T' },
  { name: 'Vũ Khánh Ly', gender: 'female', role: 'Freelancer · Huế', quote: 'Phần mô tả tính cách và điểm mạnh khá trùng với bản thân mình, đọc xong thấy dễ định hướng hơn.', avatar: 'assets/avatars/female-vn/female-vn-4.png', initial: 'L' },
  { name: 'Ngô Thanh Phong', gender: 'male', role: 'Kỹ sư xây dựng · Bình Dương', quote: 'Mình đánh giá cao việc không thổi phồng tâm linh, đọc vẫn thấy có cơ sở và thực tế.', avatar: 'assets/avatars/male-vn/male-vn-4.png', initial: 'P' },
  { name: 'Lý Thu Hà', gender: 'female', role: 'Tư vấn viên · Hải Phòng', quote: 'Đoạn "Năng lượng hôm nay" thú vị và dễ dùng để mở đầu cuộc trò chuyện với khách hàng.', avatar: 'assets/avatars/female-vn/female-vn-5.png', initial: 'H' },
];

const VN_AVATAR_BY_GENDER = {
  female: ['assets/avatars/female-vn/female-vn-1.png', 'assets/avatars/female-vn/female-vn-2.png', 'assets/avatars/female-vn/female-vn-3.png', 'assets/avatars/female-vn/female-vn-4.png', 'assets/avatars/female-vn/female-vn-5.png', 'assets/avatars/female-vn/female-vn-6.png', 'assets/avatars/female-vn/female-vn-7.png', 'assets/avatars/female-vn/female-vn-8.png'],
  male: ['assets/avatars/male-vn/male-vn-1.png', 'assets/avatars/male-vn/male-vn-2.png', 'assets/avatars/male-vn/male-vn-3.png', 'assets/avatars/male-vn/male-vn-4.png', 'assets/avatars/male-vn/male-vn-5.png', 'assets/avatars/male-vn/male-vn-6.png', 'assets/avatars/male-vn/male-vn-7.png', 'assets/avatars/male-vn/male-vn-8.png'],
};

const VN_ROLE_BY_GENDER = {
  female: ['Marketing Manager · Hà Nội', 'Nhân sự · Hà Nội', 'Freelancer · Huế', 'Tư vấn viên · Hải Phòng'],
  male: ['Software Engineer · TP.HCM', 'Sales Lead · TP.HCM', 'Kỹ sư xây dựng · Bình Dương', 'Chủ shop · Cần Thơ'],
};

const VN_TESTIMONIAL_IDENTITY = {
  'Trần Hà Anh': { gender: 'female', role: 'Marketing Manager · Hà Nội', avatar: 'assets/avatars/female-vn/female-vn-1.png', initial: 'T' },
  'Lê Quốc Việt': { gender: 'male', role: 'Software Engineer · TP.HCM', avatar: 'assets/avatars/male-vn/male-vn-6.png', initial: 'V' },
  'Nguyễn Mai Linh': { gender: 'female', role: 'Mẹ 1 con · Đà Nẵng', avatar: 'assets/avatars/female-vn/female-vn-2.png', initial: 'L' },
  'Phạm Hoàng Nam': { gender: 'male', role: 'Sales Lead · TP.HCM', avatar: 'assets/avatars/male-vn/male-vn-7.png', initial: 'N' },
  'Đỗ Quỳnh Trang': { gender: 'female', role: 'Nhân sự · Hà Nội', avatar: 'assets/avatars/female-vn/female-vn-3.png', initial: 'T' },
  'Bùi Minh Tâm': { gender: 'male', role: 'Chủ shop · Cần Thơ', avatar: 'assets/avatars/male-vn/male-vn-8.png', initial: 'T' },
  'Vũ Khánh Ly': { gender: 'female', role: 'Freelancer · Huế', avatar: 'assets/avatars/female-vn/female-vn-4.png', initial: 'L' },
  'Ngô Thanh Phong': { gender: 'male', role: 'Kỹ sư xây dựng · Bình Dương', avatar: 'assets/avatars/male-vn/male-vn-4.png', initial: 'P' },
  'Lý Thu Hà': { gender: 'female', role: 'Tư vấn viên · Hải Phòng', avatar: 'assets/avatars/female-vn/female-vn-5.png', initial: 'H' },
};

const DEFAULT_SOCIAL_LINKS = [
  { ic: 'ri-facebook-fill', label: 'Facebook', href: 'https://www.facebook.com/saladinvn' },
  { ic: 'ri-chat-3-fill', label: 'Zalo', href: 'https://zalo.me/3235051264798843231' },
  { ic: 'ri-linkedin-fill', label: 'LinkedIn', href: 'https://www.linkedin.com/company/saladinvn' },
];

const DEFAULT_FOOTER_LINK_GROUPS = [
  { title: 'Về Saladin', links: [
    { label: 'Về chúng tôi', href: 'https://www.saladin.vn/about' },
    { label: 'Đánh giá về Saladin', href: 'https://www.saladin.vn/danh-gia-ve-saladin' },
    { label: 'Đóng góp cộng đồng', href: 'https://www.saladin.vn/blog/category/saladin-co-gi-moi/dong-gop-cong-dong/' },
    { label: 'Tuyển dụng', href: 'https://www.saladin.vn/blog/co-hoi-nghe-nghiep/' },
    { label: 'Dành cho doanh nghiệp', href: 'https://www.saladin.vn/bao-hiem-suc-khoe-cho-nhan-vien-van-phong' },
  ]},
  { title: 'Hỗ trợ', links: [
    { label: 'Liên hệ chúng tôi', href: 'https://www.saladin.vn/contact' },
  ]},
  { title: 'Bảo hiểm', links: [
    { label: 'Du lịch quốc tế 🔥HOT', href: 'https://www.saladin.vn/bao-hiem-du-lich' },
    { label: 'TNDS Ô tô', href: 'https://www.saladin.vn/bao-hiem-o-to' },
    { label: 'Vật chất Ô tô', href: 'https://www.saladin.vn/bao-hiem-vat-chat-toan-dien-xe-oto' },
    { label: 'Sức khỏe toàn diện 🔥HOT', href: 'https://www.saladin.vn/bao-hiem-suc-khoe-toan-dien' },
    { label: 'Tai nạn cá nhân 🔥MỚI', href: 'https://www.saladin.vn/mua-bao-hiem-tai-nan-ca-nhan' },
    { label: 'TNDS Xe máy', href: 'https://www.saladin.vn/bao-hiem-xe-may' },
    { label: 'Bảo hiểm Thai sản 🔥MỚI', href: 'https://www.saladin.vn/bao-hiem-thai-san' },
    { label: 'Sức khỏe & Ung thư', href: 'https://www.saladin.vn/bao-hiem-ung-thu-va-benh-hiem-ngheo' },
    { label: 'Sức khỏe trẻ em 🔥MỚI', href: 'https://www.saladin.vn/bao-hiem-suc-khoe-tre-em' },
    { label: 'Nhà tư nhân', href: 'https://www.saladin.vn/bao-hiem-nha-tu-nhan' },
  ]},
  { title: 'Khác', links: [
    { label: 'Từ điển bảo hiểm', href: 'https://www.saladin.vn/blog/category/tu-dien-bao-hiem/' },
    { label: 'Saladin Blog', href: 'https://www.saladin.vn/blog/' },
    { label: 'Điều khoản & điều kiện', href: 'https://www.saladin.vn/dieu-khoan-dieu-kien-chinh-sach#dieu-khoan-dieu-kien' },
    { label: 'Chính sách quyền riêng tư', href: 'https://www.saladin.vn/dieu-khoan-dieu-kien-chinh-sach#quyen-rieng-tu' },
  ]},
];

function isoToDMY(iso) {
  const s = String(iso || '').trim();
  const m = s.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (!m) return s;
  return `${m[3]}/${m[2]}/${m[1]}`;
}

function dmyToIso(dmy) {
  const s = String(dmy || '').trim();
  const m = s.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
  if (!m) return '';
  const dd = Number(m[1]);
  const mm = Number(m[2]);
  const yyyy = Number(m[3]);
  const dt = new Date(yyyy, mm - 1, dd);
  if (dt.getFullYear() !== yyyy || dt.getMonth() !== mm - 1 || dt.getDate() !== dd) return '';
  return `${String(yyyy).padStart(4, '0')}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`;
}

function normalizeDobTyping(v) {
  const digits = String(v || '').replace(/\D/g, '').slice(0, 8);
  if (!digits) return '';
  if (digits.length < 2) return digits;
  if (digits.length === 2) return `${digits}/`;
  if (digits.length < 4) return `${digits.slice(0, 2)}/${digits.slice(2)}`;
  if (digits.length === 4) return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/`;
  return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/${digits.slice(4)}`;
}

function dobCaretFromDigitIndex(digitIndex, formattedValue) {
  const i = Math.max(0, Math.min(8, Number(digitIndex) || 0));
  let pos = i;
  if (i >= 2) pos += 1;
  if (i >= 4) pos += 1;
  return Math.max(0, Math.min(String(formattedValue || '').length, pos));
}

function handleDobTextChange(e, setValue) {
  const raw = String(e.target.value || '');
  const caret = e.target.selectionStart == null ? raw.length : e.target.selectionStart;
  const digitsBeforeCaret = raw.slice(0, caret).replace(/\D/g, '').length;
  const next = normalizeDobTyping(raw);
  setValue(next);
  requestAnimationFrame(() => {
    try {
      const p = dobCaretFromDigitIndex(digitsBeforeCaret, next);
      e.target.setSelectionRange(p, p);
    } catch (_) {}
  });
}

function handleDobKeyDown(e, value, setValue) {
  if (e.key !== 'Backspace') return;
  const input = e.target;
  const start = input.selectionStart == null ? 0 : input.selectionStart;
  const end = input.selectionEnd == null ? start : input.selectionEnd;
  if (start !== end) return;
  if (start !== 3 && start !== 6) return;
  e.preventDefault();
  const digits = String(value || '').replace(/\D/g, '');
  const digitIndex = start === 3 ? 2 : 4;
  if (digitIndex <= 0 || digitIndex > digits.length) return;
  const nextDigits = `${digits.slice(0, digitIndex - 1)}${digits.slice(digitIndex)}`;
  const next = normalizeDobTyping(nextDigits);
  setValue(next);
  requestAnimationFrame(() => {
    try {
      const p = dobCaretFromDigitIndex(digitIndex - 1, next);
      input.setSelectionRange(p, p);
    } catch (_) {}
  });
}

// ─────────────────────────────────────────────────────────────
// Layout primitives
// ─────────────────────────────────────────────────────────────
function Container({ children, style }) {
  return (
    <div className="num-container" style={{ width: '100%', maxWidth: 1200, margin: '0 auto', padding: '0 clamp(16px, 3.2vw, 32px)', boxSizing: 'border-box', ...(style || {}) }}>
      {children}
    </div>
  );
}

// Eyebrow label used above section headings
function Eyebrow({ children, color }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 8,
      fontSize: 12, fontWeight: 600, textTransform: 'uppercase',
      letterSpacing: '0.12em', color: color || SG,
    }}>
      <span style={{ width: 20, height: 1, background: 'currentColor', opacity: 0.5 }} />
      {children}
    </span>
  );
}

// Numerology grid pattern (Pythagorean 3x3) — subtle background ornament
function GridPattern({ size = 320, opacity = 0.04, color = SN, style }) {
  const cells = ['1','2','3','4','5','6','7','8','9'];
  return (
    <svg viewBox="0 0 300 300" width={size} height={size} style={{ opacity, position: 'absolute', pointerEvents: 'none', ...(style || {}) }} aria-hidden="true">
      <g fill="none" stroke={color} strokeWidth="1">
        <rect x="1" y="1" width="298" height="298" rx="6"/>
        <line x1="100" y1="1" x2="100" y2="299"/>
        <line x1="200" y1="1" x2="200" y2="299"/>
        <line x1="1" y1="100" x2="299" y2="100"/>
        <line x1="1" y1="200" x2="299" y2="200"/>
      </g>
      <g fill={color} fontFamily="var(--font-display)" fontWeight="700" fontSize="56" textAnchor="middle" dominantBaseline="central">
        {cells.map((n, i) => {
          const col = i % 3, row = Math.floor(i / 3);
          return <text key={n} x={50 + col * 100} y={50 + row * 100}>{n}</text>;
        })}
      </g>
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// HEADER
// ─────────────────────────────────────────────────────────────
function NumHeader({ mobile }) {
  const withBasePath = (target) => {
    const path = String(target || '/');
    if (path === '/') return `${HEADER_BASE_PATH_NO_SLASH}/`;
    return `${HEADER_BASE_PATH_NO_SLASH}${path.startsWith('/') ? path : `/${path}`}`;
  };
  const goPath = (e, target) => {
    e.preventDefault();
    if (typeof window === 'undefined') return;
    const current = window.location.pathname + (window.location.search || '');
    const next = `${withBasePath(target || '/')}${window.location.search || ''}`;
    if (current !== next) history.pushState(null, '', next);
    window.dispatchEvent(new PopStateEvent('popstate'));
  };
  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 50,
      background: 'var(--header-bg)',
      backdropFilter: 'blur(16px) saturate(180%)',
      WebkitBackdropFilter: 'blur(16px) saturate(180%)',
      borderBottom: '1px solid var(--border-default)',
    }}>
      <Container style={{ display: 'flex', alignItems: 'center', gap: mobile ? 12 : 20, padding: mobile ? '10px 16px' : '8px 24px' }}>
        <a href={withBasePath('/')} onClick={(e) => goPath(e, '/')} style={{ display: 'flex', alignItems: 'center', gap: 10, color: 'inherit' }}>
          <img src="assets/saladin-xtra-logo.svg" style={{ height: mobile ? 42 : 50, width: 'auto' }} alt="Saladin Xtra"/>
          <span style={{ color: 'var(--text-support)', fontWeight: 500, fontSize: mobile ? 12 : 15, lineHeight: 1.1 }}>/ Thần số học</span>
        </a>
        <div style={{ flex: 1 }}/>
        {!mobile && (
          <nav style={{ display: 'flex', gap: 16, fontSize: 14, fontWeight: 500, alignItems: 'center' }}>
            <a href={withBasePath('/')} onClick={(e) => goPath(e, '/')} style={{ color: 'var(--text-default)', display: 'inline-flex', alignItems: 'center', gap: 6 }}><i className="ri-home-5-line"></i>Trang chủ</a>
            <a href={withBasePath('/form')} onClick={(e) => goPath(e, '/form')} style={{ color: 'var(--text-default)', display: 'inline-flex', alignItems: 'center', gap: 6 }}><i className="ri-search-line"></i>Tra cứu</a>
            <a href={withBasePath('/result')} onClick={(e) => goPath(e, '/result')} style={{ color: 'var(--text-default)', display: 'inline-flex', alignItems: 'center', gap: 6 }}><i className="ri-bar-chart-box-line"></i>Kết quả</a>
            <a href={withBasePath('/about-xtra')} onClick={(e) => goPath(e, '/about-xtra')} style={{ color: 'var(--text-default)', display: 'inline-flex', alignItems: 'center', gap: 6 }}><i className="ri-information-line"></i>Về Saladin Xtra</a>
            <a href={withBasePath('/result')} onClick={(e) => goPath(e, '/result')} style={{ color: 'var(--text-default)', display: 'inline-flex', alignItems: 'center', gap: 6 }}><i className="ri-share-forward-line"></i>Chia sẻ</a>
          </nav>
        )}
        <a href="https://saladin.vn" style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          fontSize: 13, fontWeight: 500, color: 'var(--text-support)',
        }}>
          {!mobile && <span>Về Saladin</span>}
          <i className="ri-external-link-line" style={{ fontSize: 14 }}></i>
        </a>
      </Container>
    </header>
  );
}

function NumAboutXtra({ mobile }) {
  return (
    <div style={{ background: 'var(--hero-bg)', minHeight: '100%', padding: mobile ? '18px 0 36px' : '34px 0 60px' }}>
      <Container>
        <div style={{
          marginBottom: 16,
          background: 'linear-gradient(135deg, rgba(20,197,96,0.10), rgba(30,56,136,0.08))',
          border: '1px solid rgba(20,197,96,0.22)',
          borderRadius: 16,
          padding: mobile ? 16 : 22,
        }}>
          <div style={{ color: 'var(--text-support)', fontSize: 13, marginBottom: 8, textTransform: 'uppercase', letterSpacing: '0.06em' }}>Saladin Xtra</div>
          <h1 style={{ margin: 0, fontFamily: 'var(--font-display)', fontSize: mobile ? 27 : 38, color: 'var(--text-default)' }}>
            Giới thiệu về Saladin Xtra
          </h1>
          <p style={{ margin: '8px 0 0', color: 'var(--text-support)', lineHeight: 1.65 }}>
            Mở rộng trải nghiệm tra cứu, khám phá và tương tác cộng đồng theo cách hiện đại, nhanh và vui hơn.
          </p>
        </div>

        <section style={{
          background: 'var(--card-bg)',
          border: '1px solid var(--border-default)',
          borderRadius: 16,
          padding: mobile ? 16 : 24,
          boxShadow: 'var(--shadow-sm)',
          color: 'var(--text-support)',
          lineHeight: 1.8,
          fontSize: mobile ? 14 : 15,
        }}>
          <h3 style={{ margin: '0 0 8px', color: 'var(--text-default)', fontSize: 18 }}>1. Saladin Xtra là gì</h3>
          <p style={{ marginTop: 0 }}>
            Saladin Xtra là một bộ công cụ khám phá, tra cứu và trải nghiệm tương tác được phát triển bởi đội ngũ Saladin dành cho khách hàng, cộng tác viên và người dùng trong hệ sinh thái Saladin.
            “Xtra” mang ý nghĩa mở rộng trải nghiệm, khám phá thêm nhiều góc nhìn mới.
          </p>
          <h3 style={{ margin: '10px 0 8px', color: 'var(--text-default)', fontSize: 18 }}>2. Ý nghĩa của “Xtra”</h3>
          <p>
            “X” trong toán học nghĩa là biến số chưa biết, là khả năng có thể xảy ra; cũng có thể hiểu là Explore và Experience. “Tra” nghĩa là tra cứu, tìm hiểu và tương tác với nội dung thú vị theo cách hiện đại, nhanh chóng và vui vẻ hơn.
          </p>
          <h3 style={{ margin: '10px 0 8px', color: 'var(--text-default)', fontSize: 18 }}>3. Phạm vi sử dụng</h3>
          <p>
            Saladin Xtra được xây dựng với mục đích tra cứu, tham khảo và tương tác cộng đồng. Các nội dung, kết quả, phân tích hoặc gợi ý hiển thị trên Saladin Xtra không phải là tư vấn chuyên môn dưới bất kỳ hình thức nào,
            bao gồm nhưng không giới hạn ở tư vấn tài chính, đầu tư, bảo hiểm, sức khỏe, pháp lý hoặc tư vấn cá nhân. Người dùng cần tự đánh giá, cân nhắc và chịu trách nhiệm đối với mọi quyết định hoặc hành động của mình.
          </p>
          <h3 style={{ margin: '10px 0 8px', color: 'var(--text-default)', fontSize: 18 }}>4. Tuyên bố trách nhiệm</h3>
          <p>
            Trong mọi trường hợp, Saladin sẽ không chịu trách nhiệm đối với bất kỳ tổn thất, thiệt hại, hậu quả trực tiếp hoặc gián tiếp nào phát sinh từ việc người dùng sử dụng, diễn giải hoặc dựa vào các thông tin và kết quả từ Saladin Xtra.
          </p>
          <h3 style={{ margin: '10px 0 8px', color: 'var(--text-default)', fontSize: 18 }}>5. Điều khoản và quyền riêng tư</h3>
          <p>
            Khi người dùng nhấn “Đồng ý”, tiếp tục sử dụng Saladin Xtra, đăng nhập hoặc chia sẻ bất kỳ thông tin nào trên nền tảng này, người dùng xác nhận đã đọc, hiểu và đồng ý với Điều khoản, điều kiện và chính sách quyền riêng tư hiện hành của Saladin;
            đồng thời đồng ý cho Saladin thu thập, xử lý và sử dụng dữ liệu theo chính sách bảo mật nhằm cải thiện trải nghiệm, tối ưu sản phẩm, cá nhân hóa nội dung và nâng cao chất lượng dịch vụ.
          </p>
          <h3 style={{ margin: '10px 0 8px', color: 'var(--text-default)', fontSize: 18 }}>6. Cập nhật dịch vụ</h3>
          <p style={{ marginBottom: 0 }}>
            Saladin có quyền cập nhật, chỉnh sửa, bổ sung, tạm ngưng hoặc chấm dứt một phần hoặc toàn bộ Saladin Xtra vào bất kỳ thời điểm nào mà không cần thông báo trước. Việc tiếp tục sử dụng sau các thay đổi đồng nghĩa với việc chấp nhận điều khoản cập nhật mới nhất.
          </p>
        </section>
      </Container>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// HERO
// ─────────────────────────────────────────────────────────────
function NumHero({ mobile, onCta, initialData, onDraftChange }) {
  const [name, setName] = React.useState(() => (initialData && initialData.name) || '');
  const [dob, setDob] = React.useState(() => isoToDMY((initialData && initialData.dob) || ''));
  const [loading, setLoading] = React.useState(false);
  const [dobFocused, setDobFocused] = React.useState(false);
  const dobPickerRef = React.useRef(null);
  const heroNum = 7;
  const count = 10428;
  const N = (typeof window !== 'undefined' && window.SaladinNumerology) || {};

  React.useEffect(() => {
    if (!onDraftChange) return;
    onDraftChange({ name, dob: dmyToIso(dob) });
  }, [name, dob, onDraftChange]);

  const today = new Date();
  const todayIso = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
  const todayLabel = `${String(today.getDate()).padStart(2, '0')}/${String(today.getMonth() + 1).padStart(2, '0')}/${today.getFullYear()}`;
  const universalDay = N.calcLifePath ? N.calcLifePath(todayIso) : 7;
  const dayHints = {
    1: 'Phù hợp khởi động việc mới, quyết đoán và dứt điểm.',
    2: 'Ưu tiên hợp tác, lắng nghe và tinh chỉnh chi tiết.',
    3: 'Thuận cho giao tiếp, sáng tạo và mở rộng kết nối.',
    4: 'Tập trung kỷ luật, hoàn thiện việc tồn đọng.',
    5: 'Nhiều biến động; linh hoạt nhưng giữ nguyên tắc.',
    6: 'Chăm sóc gia đình, trách nhiệm và cân bằng cảm xúc.',
    7: 'Đào sâu phân tích, phù hợp suy nghĩ chiến lược.',
    8: 'Thuận cho mục tiêu tài chính, hiệu suất và thực thi.',
    9: 'Dọn dẹp vòng cũ, hoàn tất và buông các việc kéo dài.',
    11: 'Trực giác mạnh, nên kết hợp dữ liệu trước quyết định.',
    22: 'Tốt cho kế hoạch dài hạn và cấu trúc bền vững.',
    33: 'Nuôi dưỡng cộng đồng, hành động bằng sự tử tế.',
  };
  const vietnameseAvatars = [
    { name: 'Ngọc Anh', src: 'assets/avatars/female-vn/female-vn-6.png' },
    { name: 'Minh Khoa', src: 'assets/avatars/male-vn/male-vn-6.png' },
    { name: 'Thu Trang', src: 'assets/avatars/female-vn/female-vn-7.png' },
    { name: 'Quốc Bảo', src: 'assets/avatars/male-vn/male-vn-8.png' },
  ];
  const openDobPicker = () => {
    const el = dobPickerRef.current;
    if (!el) return;
    try {
      if (typeof el.showPicker === 'function') {
        el.showPicker();
        return;
      }
    } catch (_) {}
    try { el.focus(); } catch (_) {}
    try { el.click(); } catch (_) {}
  };

  return (
    <section style={{
      position: 'relative', overflow: 'hidden',
      background: 'var(--hero-bg)',
      paddingTop: mobile ? 40 : 72,
      paddingBottom: mobile ? 48 : 88,
    }}>
      {!mobile && <GridPattern size={460} opacity={0.05} color="var(--grid-color)" style={{ position: 'absolute', right: -60, top: 60 }} />}

      <Container>
        <div style={{
          display: 'grid',
          gridTemplateColumns: mobile ? '1fr' : '1.05fr 0.95fr',
          gap: mobile ? 32 : 56,
          alignItems: 'center',
          position: 'relative',
        }}>
          <div>
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 8,
              padding: '6px 12px', background: 'var(--bg)', border: '1px solid var(--primary-95)',
              borderRadius: 50, fontSize: 12, fontWeight: 600, color: 'var(--badge-text)',
            }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: SG }} />
              Miễn phí · Không cần đăng ký
            </span>
            <h1 style={{
              fontFamily: 'var(--font-display)', fontWeight: 700,
              fontSize: mobile ? 32 : 60, lineHeight: 1.05, marginTop: 18, marginBottom: 18,
              letterSpacing: '-0.025em', textWrap: 'balance',
              color: 'var(--text-default)',
            }}>
              Khám phá <span style={{ color: SG }}>con số</span> của bạn trong <span style={{ whiteSpace: 'nowrap' }}>30 giây</span>
            </h1>
            <p style={{
              fontSize: mobile ? 16 : 18, lineHeight: 1.55, color: 'var(--text-support)',
              maxWidth: 520, margin: 0, marginBottom: 20,
            }}>
              Tra cứu thần số học miễn phí — phân tích con số chủ đạo, đường đời và năm cá nhân.
            </p>

            <div style={{ marginTop: 8, display: 'flex', alignItems: 'center', gap: 10 }}>
              <img
                src="assets/avatars/greeting-avatar.png"
                alt="avatar"
                style={{ width: 36, height: 36, borderRadius: '50%', border: '2px solid #fff', boxShadow: 'var(--shadow-xs)', objectFit: 'cover' }}
              />
              <span style={{ fontSize: 12, color: 'var(--text-support)' }}>
                {name ? `Xin chào ${name.split(' ').slice(-1)[0]}` : 'Kết quả sẽ cá nhân hoá theo thông tin của bạn'}
              </span>
            </div>

            <form
              onSubmit={(e) => {
                e.preventDefault();
                setLoading(true);
                setTimeout(() => {
                  setLoading(false);
                  if (onCta) onCta({ name, dob: dmyToIso(dob) });
                }, 450);
              }}
              style={{
                marginTop: 14,
                background: 'var(--bg)',
                border: '1px solid var(--border-default)',
                borderRadius: 12,
                padding: mobile ? 12 : 10,
                boxShadow: 'var(--shadow-sm)',
                display: 'grid',
                gridTemplateColumns: mobile ? '1fr' : '1fr auto',
                gap: 10,
                maxWidth: mobile ? '100%' : 560,
                overflowAnchor: 'none',
              }}
            >
              <div style={{
                height: 48,
                border: '1px solid var(--border-default)',
                borderRadius: 8,
                background: 'var(--bg)',
                padding: '0 12px',
                display: 'flex',
                alignItems: 'center',
                gap: 10,
                minWidth: 0,
              }}>
                <i className="ri-calendar-line" style={{ fontSize: 18, color: SG }}></i>
                <input
                  type="text"
                  required
                  value={dob}
                  inputMode="text"
                  placeholder="dd/mm/yyyy"
                  onChange={(e) => handleDobTextChange(e, setDob)}
                  onKeyDown={(e) => handleDobKeyDown(e, dob, setDob)}
                  onFocus={() => setDobFocused(true)}
                  onBlur={() => setDobFocused(false)}
                  style={{
                    width: '100%',
                    border: 'none',
                    outline: 'none',
                    background: 'transparent',
                    color: 'var(--text-default)',
                    fontFamily: 'inherit',
                    fontSize: 16,
                  }}
                />
                <button
                  type="button"
                  onClick={openDobPicker}
                  style={{
                    position: 'relative',
                    overflow: 'hidden',
                    border: 'none', background: 'transparent', color: 'var(--text-support)',
                    width: 28, height: 28, borderRadius: 6, cursor: 'pointer',
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  }}
                  title="Chọn ngày"
                >
                  <i className="ri-calendar-2-line" style={{ fontSize: 16 }} />
                </button>
                <input
                  ref={dobPickerRef}
                  type="date"
                  value={dmyToIso(dob)}
                  max={todayIso}
                  onChange={(e) => setDob(isoToDMY(e.target.value))}
                  style={{ opacity: 0, width: 28, height: 28, marginLeft: -28, cursor: 'pointer', border: 0, padding: 0 }}
                  tabIndex={-1}
                  aria-hidden="true"
                />
              </div>
              <button type="submit" disabled={loading} style={{
                background: SG, color: '#fff',
                height: 48,
                padding: mobile ? '14px 18px' : '12px 22px',
                borderRadius: 4, border: 'none',
                fontFamily: 'inherit', fontSize: 15, fontWeight: 600,
                cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                whiteSpace: 'nowrap', width: mobile ? '100%' : 'auto',
                opacity: loading ? 0.7 : 1,
                transition: 'opacity 150ms',
              }}>
                {loading ? <><i className="ri-loader-4-line" style={{ fontSize: 18, animation: 'spin 800ms linear infinite' }}></i> Đang chuyển</>
                         : <>Bắt đầu tra cứu <i className="ri-arrow-right-line" style={{ fontSize: 18 }}></i></>}
              </button>
            </form>

            <div style={{
              marginTop: 14,
              padding: '12px 14px',
              borderRadius: 10,
              background: 'var(--bg)',
              border: '1px solid var(--border-default)',
            }}>
              <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 700, color: 'var(--text-support)', marginBottom: 6 }}>
                Năng lượng hôm nay · {todayLabel}
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
                <span style={{
                  width: 28, height: 28, borderRadius: 8, background: 'var(--primary-95)',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  fontFamily: 'var(--font-display)', fontWeight: 700, color: '#005323',
                }}>{universalDay}</span>
                <div style={{ fontSize: 13, color: 'var(--text-default)', fontWeight: 600 }}>
                  Số ngày chung: {universalDay}
                </div>
              </div>
              <div style={{ fontSize: 12, color: 'var(--text-support)', lineHeight: 1.55 }}>
                {dayHints[universalDay] || dayHints[7]}
              </div>
            </div>

            <div style={{
              display: 'flex', alignItems: 'center', gap: 16,
              marginTop: mobile ? 28 : 36,
              paddingTop: mobile ? 24 : 28,
              borderTop: '1px solid var(--border-default)',
              flexWrap: 'wrap',
            }}>
              <div style={{ display: 'flex' }}>
                {vietnameseAvatars.map((avatar, i) => (
                  <div key={i} style={{
                    width: 36, height: 36, borderRadius: '50%',
                    marginLeft: i ? -10 : 0, border: '2px solid var(--bg)',
                    overflow: 'hidden',
                    boxShadow: 'var(--shadow-xs)',
                  }}>
                    <img
                      src={avatar.src}
                      alt={avatar.name}
                      loading="lazy"
                      style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                    />
                  </div>
                ))}
              </div>
              <div>
                <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-default)' }}>
                  Đã có {count.toLocaleString('vi-VN')}+ người Việt tra cứu
                </div>
                <div style={{ fontSize: 12, color: 'var(--text-support)', marginTop: 2 }}>
                  từ tháng 1/2026
                </div>
              </div>
            </div>
          </div>

          <div style={{ position: 'relative', minHeight: mobile ? 520 : 620 }}>
            <HeroSampleCard mobile={mobile} heroNum={heroNum} paused={dobFocused} />

            <div style={{
              position: 'absolute',
              left: mobile ? 12 : -24,
              bottom: mobile ? -18 : -22,
              background: 'var(--bg)',
              border: '1px solid var(--border-default)',
              borderRadius: 14,
              boxShadow: '0 18px 28px -18px rgba(16,24,40,0.35)',
              padding: '10px 14px',
              display: 'flex',
              alignItems: 'center',
              gap: 10,
              animation: dobFocused ? 'none' : 'floatCard 3200ms ease-in-out infinite',
            }}>
              <span style={{
                width: 32, height: 32, borderRadius: '50%', background: SG, color: '#fff',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                fontFamily: 'var(--font-display)', fontWeight: 700,
              }}>7</span>
              <div>
                <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-default)' }}>Phân tích hoàn tất</div>
                <div style={{ fontSize: 12, color: 'var(--text-support)' }}>28 giây · 3 chỉ số</div>
              </div>
            </div>
          </div>
        </div>
      </Container>
    </section>
  );
}

function HeroSampleCard({ mobile, heroNum, paused }) {
  const numberTheme = React.useMemo(() => ({
    1: { accent: '#2563eb', soft: '#eaf2ff', border: '#bfd5ff', icon: 'ri-flag-2-line', sticker: 'Tiên phong', motif: 'ri-focus-2-line' },
    2: { accent: '#0f766e', soft: '#eafaf7', border: '#bdebe3', icon: 'ri-team-line', sticker: 'Kết nối', motif: 'ri-links-line' },
    3: { accent: '#c2410c', soft: '#fff3e8', border: '#ffd7bf', icon: 'ri-sparkling-2-line', sticker: 'Sáng tạo', motif: 'ri-magic-line' },
    4: { accent: '#334155', soft: '#f2f5f8', border: '#d7dee7', icon: 'ri-building-2-line', sticker: 'Nền tảng', motif: 'ri-layout-grid-line' },
    5: { accent: '#7c3aed', soft: '#f4efff', border: '#d9c9ff', icon: 'ri-compass-3-line', sticker: 'Linh hoạt', motif: 'ri-windy-line' },
    6: { accent: '#be185d', soft: '#fff1f7', border: '#ffd0e5', icon: 'ri-heart-3-line', sticker: 'Chăm sóc', motif: 'ri-hand-heart-line' },
    7: { accent: '#1e3a8a', soft: '#edf2ff', border: '#c9d7ff', icon: 'ri-brain-line', sticker: 'Chiêm nghiệm', motif: 'ri-moon-clear-line' },
    8: { accent: '#166534', soft: '#eaf9ef', border: '#c4ead1', icon: 'ri-bar-chart-box-line', sticker: 'Thực thi', motif: 'ri-line-chart-line' },
    9: { accent: '#0f766e', soft: '#ebfaf6', border: '#c4efe3', icon: 'ri-service-line', sticker: 'Bao dung', motif: 'ri-seedling-line' },
  }), []);
  const tagMeta = React.useMemo(() => ({
    'Lãnh đạo': { icon: 'ri-flag-2-line', bg: '#eaf2ff', border: '#b9d2ff', text: '#1e3f9a' },
    'Bản lĩnh': { icon: 'ri-shield-check-line', bg: '#eaf8f0', border: '#bde8cc', text: '#0c6b37' },
    'Tập trung': { icon: 'ri-focus-2-line', bg: '#f3f4f6', border: '#d9dce2', text: '#1f2937' },
    'Tiên phong': { icon: 'ri-rocket-line', bg: '#fff4e8', border: '#ffd8b0', text: '#9a531e' },
    'Hợp tác': { icon: 'ri-team-line', bg: '#edf7ff', border: '#bfe2ff', text: '#0f5c8a' },
    'Lắng nghe': { icon: 'ri-ear-line', bg: '#f3fffa', border: '#c9f3e0', text: '#0d6a48' },
    'Hòa hợp': { icon: 'ri-heart-3-line', bg: '#fff1f5', border: '#ffd0dd', text: '#a12f57' },
    'Bền bỉ': { icon: 'ri-timer-2-line', bg: '#f8f5ff', border: '#dfd2ff', text: '#5a3f9a' },
    'Sáng tạo': { icon: 'ri-palette-line', bg: '#fff3ea', border: '#ffd8bb', text: '#9a4a17' },
    'Giao tiếp': { icon: 'ri-chat-1-line', bg: '#ecf7ff', border: '#bde2ff', text: '#155e87' },
    'Lan tỏa': { icon: 'ri-broadcast-line', bg: '#eefcff', border: '#c5eef7', text: '#0f6777' },
    'Lạc quan': { icon: 'ri-sun-line', bg: '#fffbe9', border: '#f8ebb0', text: '#8a6a06' },
    'Kỷ luật': { icon: 'ri-checkbox-circle-line', bg: '#edf5ff', border: '#c7dbff', text: '#1b4f9f' },
    'Logic': { icon: 'ri-function-line', bg: '#f3f4f6', border: '#d9dce2', text: '#1f2937' },
    'Ổn định': { icon: 'ri-home-4-line', bg: '#eefbf3', border: '#c6ebd4', text: '#0f6a3c' },
    'Tỉ mỉ': { icon: 'ri-draft-line', bg: '#f7f8fa', border: '#dce0e6', text: '#374151' },
    'Tự do': { icon: 'ri-compass-3-line', bg: '#fff3e8', border: '#ffd3b2', text: '#a34f1f' },
    'Nhạy bén': { icon: 'ri-flashlight-line', bg: '#eef6ff', border: '#c6dcff', text: '#1e4f9e' },
    'Thử thách': { icon: 'ri-fire-line', bg: '#fff1ef', border: '#ffcfc8', text: '#a33a2a' },
    'Đổi mới': { icon: 'ri-refresh-line', bg: '#edfffb', border: '#c2f3e8', text: '#0d7461' },
    'Quan tâm': { icon: 'ri-hand-heart-line', bg: '#fff2f7', border: '#ffd2e4', text: '#a53866' },
    'Cam kết': { icon: 'ri-links-line', bg: '#eef5ff', border: '#c7dbff', text: '#1f4a93' },
    'Cân bằng': { icon: 'ri-scales-2-line', bg: '#f3fff7', border: '#c9eed7', text: '#136743' },
    'Tin cậy': { icon: 'ri-verified-badge-line', bg: '#f3f4f6', border: '#dadce1', text: '#334155' },
    'Trí tuệ': { icon: 'ri-brain-line', bg: '#eef5ff', border: '#c6dbff', text: '#1f4f9c' },
    'Độc lập': { icon: 'ri-user-star-line', bg: '#f4f8ff', border: '#cfddff', text: '#254b8f' },
    'Trực giác': { icon: 'ri-eye-line', bg: '#f7f2ff', border: '#ddd0ff', text: '#5c4298' },
    'Cầu toàn': { icon: 'ri-medal-line', bg: '#f3f5f7', border: '#d9dde3', text: '#374151' },
    'Kết quả': { icon: 'ri-bar-chart-box-line', bg: '#ecfff3', border: '#c3ecd3', text: '#106a3d' },
    'Quản trị': { icon: 'ri-briefcase-4-line', bg: '#edf3ff', border: '#c7d8ff', text: '#1d4898' },
    'Tài chính': { icon: 'ri-money-dollar-circle-line', bg: '#eefdf4', border: '#c8efd6', text: '#0f6b3d' },
    'Kỷ cương': { icon: 'ri-shield-star-line', bg: '#f3f4f6', border: '#d9dde2', text: '#374151' },
    'Phụng sự': { icon: 'ri-service-line', bg: '#eefcf8', border: '#c4f0df', text: '#0f6f4b' },
    'Thấu hiểu': { icon: 'ri-empathize-line', bg: '#fff2f9', border: '#ffd2ea', text: '#9f3d72' },
    'Khép vòng': { icon: 'ri-loop-right-line', bg: '#f2f5ff', border: '#d0daff', text: '#3f4f9a' },
    'Tử tế': { icon: 'ri-hand-heart-line', bg: '#fff7ef', border: '#ffe0c4', text: '#8c5322' },
  }), []);
  const [sampleProfiles, setSampleProfiles] = React.useState(DEFAULT_SAMPLE_PROFILES);
  React.useEffect(() => {
    if (typeof window === 'undefined' || typeof fetch === 'undefined') return;
    let cancelled = false;
    fetch('data/sample_profiles.csv')
      .then((res) => res.ok ? res.text() : '')
      .then((text) => {
        if (cancelled || !text) return;
        const rows = csvToObjects(text)
          .map((r) => ({
            n: Number(r.n) || 0,
            name: r.name || '',
            dob: r.dob || '',
            title: r.title || '',
            tags: (r.tags || '').split('|').map((x) => x.trim()).filter(Boolean),
            yearLabel: r.yearLabel || '',
            avatar: r.avatar || '',
          }))
          .filter((r) => r.n > 0 && r.name && r.title);
        if (rows.length) setSampleProfiles(rows);
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, []);
  const initialIndex = React.useMemo(() => {
    const found = sampleProfiles.findIndex((p) => p.n === heroNum);
    return found >= 0 ? found : 0;
  }, [heroNum, sampleProfiles]);
  const [profileIndex, setProfileIndex] = React.useState(initialIndex);
  const [activeMonth, setActiveMonth] = React.useState(6);

  const profile = sampleProfiles[profileIndex] || sampleProfiles[0];
  const tone = numberTheme[profile.n] || numberTheme[7];

  React.useEffect(() => {
    setProfileIndex(initialIndex);
  }, [initialIndex]);

  React.useEffect(() => {
    if (paused) return undefined;
    const profileTimer = setInterval(() => {
      setProfileIndex((prev) => (prev + 1) % sampleProfiles.length);
    }, 2600);
    const timer = setInterval(() => {
      setActiveMonth((prev) => (prev + 1) % 12);
    }, 1600);
    return () => {
      clearInterval(timer);
      clearInterval(profileTimer);
    };
  }, [paused, sampleProfiles.length]);

  return (
    <div style={{
      background: 'var(--bg)',
      border: '1px solid var(--border-default)',
      borderRadius: 20,
      boxShadow: '0 24px 48px -24px rgba(16,24,40,0.22)',
      padding: mobile ? 16 : 24,
      position: 'relative',
      overflow: 'hidden',
    }}>
      <div style={{ display: 'flex', alignItems: mobile ? 'flex-start' : 'center', justifyContent: 'space-between', gap: 10, flexWrap: mobile ? 'wrap' : 'nowrap', marginBottom: 12 }}>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          height: 32, padding: '0 12px', borderRadius: 999,
          background: tone.soft, color: tone.accent, fontWeight: 700, fontSize: 14, border: `1px solid ${tone.border}`,
        }}><i className={tone.icon}></i>Kết quả mẫu</span>
        <span style={{ fontSize: mobile ? 12 : 13, color: 'var(--text-support)', display: 'inline-flex', alignItems: 'center', gap: 8, minWidth: 0, maxWidth: mobile ? '100%' : 'none', whiteSpace: mobile ? 'normal' : 'nowrap' }}>
          <img src={profile.avatar} alt={profile.name} style={{ width: 24, height: 24, borderRadius: '50%', objectFit: 'cover', border: '1px solid var(--border-default)' }} />
          <span style={{ overflowWrap: 'anywhere' }}>{profile.name} · {profile.dob}</span>
        </span>
      </div>

      <div style={{
        background: tone.soft,
        border: `1px solid ${tone.border}`,
        borderRadius: 14,
        padding: mobile ? 14 : 18,
        animation: paused ? 'none' : 'sampleSwap 420ms ease',
      }}>
        <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', color: '#5674b3', marginBottom: 10 }}>
          Con số chủ đạo
        </div>
        <div style={{
          position: 'relative',
          height: mobile ? 180 : 260,
          borderRadius: 12,
          overflow: 'hidden',
          border: '1px solid rgba(30,56,136,0.10)',
          background: 'rgba(255,255,255,0.6)',
        }}>
          <div style={{
            position: 'absolute',
            left: 10,
            top: 10,
            zIndex: 2,
            display: 'inline-flex',
            alignItems: 'center',
            gap: 6,
            padding: '5px 9px',
            borderRadius: 999,
            border: `1px solid ${tone.border}`,
            background: 'rgba(255,255,255,0.88)',
            color: tone.accent,
            fontSize: 11,
            fontWeight: 700,
            animation: paused ? 'none' : 'sampleSwap 520ms ease',
          }}>
            <i className={tone.icon} style={{ fontSize: 12 }}></i>{tone.sticker}
          </div>
          <div style={{
            position: 'absolute',
            left: 14,
            bottom: 12,
            zIndex: 2,
            width: 28,
            height: 28,
            borderRadius: 8,
            border: `1px solid ${tone.border}`,
            background: 'rgba(255,255,255,0.86)',
            color: tone.accent,
            display: 'inline-flex',
            alignItems: 'center',
            justifyContent: 'center',
            animation: paused ? 'none' : 'floatCard 4200ms ease-in-out infinite',
          }}>
            <i className={tone.motif} style={{ fontSize: 14 }}></i>
          </div>
          <div style={{
            position: 'absolute', right: 0, top: 0, bottom: 0, width: '56%',
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gridTemplateRows: 'repeat(3, 1fr)',
          }}>
            {[1,2,3,4,5,6,7,8,9].map((n) => (
              <div key={n} style={{ border: '1px solid rgba(30,56,136,0.07)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: mobile ? 24 : 42, color: n === profile.n ? tone.accent : 'rgba(30,56,136,0.12)', background: n === profile.n ? 'rgba(255,255,255,0.72)' : 'transparent' }}>
                {n}
              </div>
            ))}
          </div>
          <div style={{
            position: 'absolute', left: '12%', top: '48%', transform: 'translateY(-50%)',
            fontFamily: 'var(--font-ios), -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif',
            fontWeight: 700, fontSize: mobile ? 108 : 170,
            lineHeight: 1, color: tone.accent,
            width: mobile ? 86 : 132,
            textAlign: 'center',
            fontVariantNumeric: 'tabular-nums lining-nums',
            fontFeatureSettings: '"tnum" 1, "lnum" 1',
            letterSpacing: 0,
            willChange: 'transform, opacity',
            animation: paused ? 'none' : 'numPulse 2400ms ease-in-out infinite',
          }}>
            <span
              key={profile.n}
              style={{
                display: 'inline-block',
                width: '100%',
                animation: paused ? 'none' : 'sampleDigitIn 420ms cubic-bezier(0.22, 1, 0.36, 1)',
              }}
            >
              {profile.n}
            </span>
          </div>
        </div>
      </div>

      <div key={`title-${profile.n}`} style={{ marginTop: 16, fontWeight: 700, color: 'var(--text-default)', fontSize: mobile ? 16 : 20, lineHeight: 1.2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', animation: paused ? 'none' : 'sampleSwap 420ms ease' }}>{profile.title}</div>
      <div style={{ marginTop: 10, display: 'flex', flexWrap: 'wrap', gap: 8 }}>
        {profile.tags.map((tag) => (
          <span
            key={tag}
            style={{
              padding: '7px 11px',
              border: `1px solid ${(tagMeta[tag] && tagMeta[tag].border) || 'var(--border-default)'}`,
              borderRadius: 999,
              fontSize: 13,
              color: (tagMeta[tag] && tagMeta[tag].text) || 'var(--text-support)',
              background: (tagMeta[tag] && tagMeta[tag].bg) || 'var(--bg-soft)',
              display: 'inline-flex',
              alignItems: 'center',
              gap: 6,
              fontWeight: 600,
            }}
          >
            <i className={(tagMeta[tag] && tagMeta[tag].icon) || 'ri-price-tag-3-line'} style={{ fontSize: 14 }}></i>
            {tag}
          </span>
        ))}
      </div>

      <div style={{ marginTop: 16, borderRadius: 12, background: 'var(--bg-soft)', padding: 14 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: mobile ? 'flex-start' : 'center', gap: 8, flexWrap: mobile ? 'wrap' : 'nowrap', marginBottom: 10 }}>
          <span style={{ fontSize: 12, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--text-support)', fontWeight: 700 }}>Năm cá nhân 2026</span>
          <span style={{ fontSize: 13, color: tone.accent, fontWeight: 700 }}>{profile.yearLabel}</span>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(12, minmax(0, 1fr))', gap: 6, alignItems: 'end', height: 62 }}>
          {[24,30,28,42,46,58,62,54,46,44,48,42].map((h, idx) => (
            <div key={idx} style={{
              height: h,
              borderRadius: 4,
              background: idx === activeMonth ? SG : 'rgba(16,24,40,0.12)',
              transition: 'background 280ms ease',
            }} />
          ))}
        </div>
        <div style={{ marginTop: 8, display: 'flex', justifyContent: 'space-between', fontSize: 12, color: 'var(--text-support)' }}>
          <span>T1</span>
          <span>T7</span>
          <span>T12</span>
        </div>
      </div>
    </div>
  );
}

function NumWhat({ mobile }) {
  const cards = [
    {
      n: '1', icon: 'ri-user-star-line',
      title: 'Con số chủ đạo',
      desc: 'Tính cách cốt lõi và bản chất bạn từ ngày sinh.',
      tag: 'Trí tuệ · cảm xúc · động lực',
    },
    {
      n: '7', icon: 'ri-route-line',
      title: 'Đường đời',
      desc: 'Hành trình sự nghiệp, các giai đoạn lớn và thử thách.',
      tag: 'Định hướng · giai đoạn · thử thách',
    },
    {
      n: '3', icon: 'ri-calendar-2-line',
      title: 'Năm cá nhân',
      desc: 'Dự báo chủ đề và năng lượng 12 tháng tới của bạn.',
      tag: 'Cơ hội · thời điểm · rủi ro',
    },
  ];

  return (
    <section id="what" data-reveal style={{
      padding: mobile ? '64px 0' : '96px 0',
      background: 'var(--bg)',
    }}>
      <Container>
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', flexWrap: 'wrap', gap: 24, marginBottom: mobile ? 32 : 48 }}>
          <div style={{ maxWidth: 580 }}>
            <Eyebrow>Bạn sẽ biết gì?</Eyebrow>
            <h2 style={{
              fontFamily: 'var(--font-display)', fontWeight: 700,
              fontSize: mobile ? 28 : 40, lineHeight: 1.1,
              margin: '12px 0 0', letterSpacing: '-0.02em',
              color: 'var(--text-default)',
            }}>
              Ba chỉ số căn bản — viết lại từ ngày sinh của bạn.
            </h2>
          </div>
          <p style={{ fontSize: mobile ? 14 : 15, color: 'var(--text-support)', maxWidth: 360, margin: 0, lineHeight: 1.55 }}>
            Mỗi chỉ số được tính theo phương pháp Pythagorean và giải thích bằng ngôn ngữ thực tế — không huyền bí.
          </p>
        </div>

        <div style={{
          display: 'grid',
          gridTemplateColumns: mobile ? '1fr' : 'repeat(3, 1fr)',
          gap: mobile ? 16 : 20,
        }}>
          {cards.map((c, i) => (
            <article key={c.title} className="reveal-child" style={{
              background: 'var(--bg)',
              border: '1px solid var(--border-default)',
              borderRadius: 12,
              padding: mobile ? 20 : 28,
              display: 'flex', flexDirection: 'column', gap: 16,
              position: 'relative', overflow: 'hidden',
              transition: 'all 200ms cubic-bezier(0.4,0,0.2,1)',
              transitionDelay: `${i * 60}ms`,
            }}>
              {/* Big watermark number */}
              <div style={{
                position: 'absolute', right: -16, top: -28,
                fontFamily: 'var(--font-display)', fontWeight: 900,
                fontSize: 180, lineHeight: 1, color: 'var(--watermark)',
                letterSpacing: '-0.05em', pointerEvents: 'none',
                fontVariantNumeric: 'tabular-nums',
              }}>{c.n}</div>

              <div style={{
                width: 44, height: 44, borderRadius: 10,
                background: 'var(--primary-95)', color: SG_DEEP,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                position: 'relative',
              }}>
                <i className={c.icon} style={{ fontSize: 22 }}></i>
              </div>
              <div style={{ position: 'relative' }}>
                <h3 style={{
                  fontFamily: 'var(--font-display)', fontWeight: 700,
                  fontSize: 22, lineHeight: 1.2, margin: 0, color: 'var(--text-default)',
                }}>{c.title}</h3>
                <p style={{
                  fontSize: 14, lineHeight: 1.55, color: 'var(--text-support)',
                  margin: '8px 0 0',
                }}>{c.desc}</p>
              </div>
              <div style={{
                marginTop: 'auto', paddingTop: 14,
                borderTop: '1px dashed var(--border-default)',
                fontSize: 11, fontWeight: 600, textTransform: 'uppercase',
                letterSpacing: '0.08em', color: 'var(--text-support)',
                position: 'relative',
              }}>{c.tag}</div>
            </article>
          ))}
        </div>
      </Container>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// SECTION: CÁCH HOẠT ĐỘNG — 3 steps with connector
// ─────────────────────────────────────────────────────────────
function NumHow({ mobile }) {
  const steps = [
    { n: '01', icon: 'ri-edit-2-line', title: 'Nhập tên & ngày sinh', desc: 'Mất khoảng 10 giây. Không cần email, không cần đăng ký.' },
    { n: '02', icon: 'ri-bar-chart-2-line', title: 'Xem kết quả tức thì', desc: 'Phân tích đầy đủ 3 chỉ số căn bản, hoàn toàn miễn phí.' },
    { n: '03', icon: 'ri-mail-line', title: 'Lưu báo cáo (tuỳ chọn)', desc: 'Nhận tip hàng tháng qua email — bỏ theo dõi bất kỳ lúc nào.' },
  ];
  return (
    <section id="how" data-reveal style={{
      padding: mobile ? '64px 0' : '96px 0',
      background: 'var(--bg-soft)',
    }}>
      <Container>
        <div style={{ textAlign: 'center', marginBottom: mobile ? 36 : 56 }}>
          <Eyebrow>Cách hoạt động</Eyebrow>
          <h2 style={{
            fontFamily: 'var(--font-display)', fontWeight: 700,
            fontSize: mobile ? 28 : 40, lineHeight: 1.1,
            margin: '12px 0 0', letterSpacing: '-0.02em',
            color: 'var(--text-default)',
          }}>Ba bước. Không quá một phút.</h2>
        </div>

        <div style={{
          position: 'relative',
          display: 'grid',
          gridTemplateColumns: mobile ? '1fr' : 'repeat(3, 1fr)',
          gap: mobile ? 16 : 32,
        }}>
          {/* Connector line */}
          {!mobile && (
            <div aria-hidden="true" style={{
              position: 'absolute', top: 32, left: '16%', right: '16%',
              height: 2, background: 'transparent',
              backgroundImage: 'linear-gradient(to right, var(--border-strong) 50%, transparent 50%)',
              backgroundSize: '12px 2px', backgroundRepeat: 'repeat-x',
              zIndex: 0,
            }}/>
          )}
          {steps.map((s, i) => (
            <div key={s.n} className="reveal-child" style={{ position: 'relative', zIndex: 1, transitionDelay: `${i * 80}ms` }}>
              <div style={{
                width: 64, height: 64, borderRadius: '50%',
                background: 'var(--bg)',
                border: `2px solid ${i === 0 ? SG : 'var(--border-default)'}`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 22,
                color: i === 0 ? SG : 'var(--text-default)',
                margin: mobile ? '0' : '0 auto',
                boxShadow: 'var(--shadow-xs)',
                position: 'relative',
              }}>
                {s.n}
                <span style={{
                  position: 'absolute', bottom: -6, right: -6,
                  width: 26, height: 26, borderRadius: '50%',
                  background: i === 0 ? SG : 'var(--bg-variant)',
                  color: i === 0 ? '#fff' : 'var(--text-support)',
                  border: '2px solid var(--bg-soft)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>
                  <i className={s.icon} style={{ fontSize: 13 }}></i>
                </span>
              </div>
              <h3 style={{
                fontFamily: 'var(--font-display)', fontWeight: 700,
                fontSize: 20, lineHeight: 1.3,
                margin: mobile ? '14px 0 6px' : '24px 0 8px',
                textAlign: mobile ? 'left' : 'center',
                color: 'var(--text-default)',
              }}>{s.title}</h3>
              <p style={{
                fontSize: 14, lineHeight: 1.55, color: 'var(--text-support)',
                margin: 0, textAlign: mobile ? 'left' : 'center',
                maxWidth: mobile ? '100%' : 280,
                marginLeft: 'auto', marginRight: 'auto',
              }}>{s.desc}</p>
            </div>
          ))}
        </div>
      </Container>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// SECTION: TESTIMONIAL
// ─────────────────────────────────────────────────────────────
function NumTestimonials({ mobile }) {
  const [quotes, setQuotes] = React.useState(DEFAULT_TESTIMONIALS);
  const [slideIndex, setSlideIndex] = React.useState(0);
  React.useEffect(() => {
    if (typeof window === 'undefined' || typeof fetch === 'undefined') return;
    let cancelled = false;
    fetch('data/testimonials.csv')
      .then((res) => res.ok ? res.text() : '')
      .then((text) => {
        if (cancelled || !text) return;
        const rows = csvToObjects(text)
          .map((r) => ({
            name: r.name || '',
            gender: (r.gender || '').trim().toLowerCase(),
            role: r.role || '',
            quote: r.quote || '',
            avatar: r.avatar || '',
            initial: r.initial || '',
            stars: Number(r.stars) || 0,
          }))
          .filter((r) => r.name && r.quote);
        if (rows.length) setQuotes(rows);
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, []);
  const normalizedQuotes = React.useMemo(() => {
    const list = Array.isArray(quotes) ? quotes : [];
    const genderCount = { female: 0, male: 0 };
    return list
      .filter((q) => VN_TESTIMONIAL_IDENTITY[q.name])
      .map((q) => {
      const identity = VN_TESTIMONIAL_IDENTITY[q.name] || null;
      const g = (identity && identity.gender) || (q.gender === 'male' ? 'male' : 'female');
      const bucket = VN_AVATAR_BY_GENDER[g] || VN_AVATAR_BY_GENDER.female;
      const idx = genderCount[g] % bucket.length;
      genderCount[g] += 1;
      const safeAvatar = (identity && identity.avatar) || bucket[idx];
      const rolePool = VN_ROLE_BY_GENDER[g] || VN_ROLE_BY_GENDER.female;
      const fallbackRole = rolePool[idx % rolePool.length];
      const safeRole = (identity && identity.role) || (q.role && q.role.trim() ? q.role.trim() : fallbackRole);
      const safeInitial = (identity && identity.initial) || (q.initial && q.initial.trim()) || (q.name ? q.name.trim().charAt(0).toUpperCase() : '');
      return {
        ...q,
        name: q.name && q.name.trim() ? q.name.trim() : 'Người dùng Saladin',
        gender: g,
        role: safeRole,
        avatar: safeAvatar,
        initial: safeInitial,
        stars: q.stars >= 3 && q.stars <= 5 ? q.stars : (3 + Math.floor(Math.random() * 3)),
      };
    });
  }, [quotes]);
  const cardsPerSlide = mobile ? 1 : 3;
  const totalSlides = Math.max(1, Math.ceil(normalizedQuotes.length / cardsPerSlide));

  React.useEffect(() => {
    setSlideIndex(0);
  }, [mobile, normalizedQuotes.length]);

  React.useEffect(() => {
    if (totalSlides <= 1) return;
    const timer = setInterval(() => {
      setSlideIndex((prev) => (prev + 1) % totalSlides);
    }, 3800);
    return () => clearInterval(timer);
  }, [totalSlides]);

  const displayQuotes = React.useMemo(() => {
    if (!normalizedQuotes.length) return [];
    const start = slideIndex * cardsPerSlide;
    return normalizedQuotes.slice(start, start + cardsPerSlide);
  }, [normalizedQuotes, slideIndex, cardsPerSlide]);
  return (
    <section id="stories" data-reveal style={{
      padding: mobile ? '64px 0' : '96px 0',
      background: 'var(--bg)',
    }}>
      <Container>
        <div style={{ textAlign: 'center', marginBottom: mobile ? 36 : 56 }}>
          <Eyebrow>Cảm nhận</Eyebrow>
          <h2 style={{
            fontFamily: 'var(--font-display)', fontWeight: 700,
            fontSize: mobile ? 28 : 40, lineHeight: 1.1,
            margin: '12px 0 0', letterSpacing: '-0.02em',
            color: 'var(--text-default)',
          }}>Người Việt nói gì về Saladin Thần số học.</h2>
        </div>

        <div style={{
          display: 'grid',
          gridTemplateColumns: mobile ? '1fr' : 'repeat(3, 1fr)',
          gap: mobile ? 16 : 20,
          minHeight: mobile ? 280 : 320,
        }}>
          {displayQuotes.map((q, i) => (
            <article key={q.name} className="reveal-child" style={{
              background: 'var(--bg)',
              border: '1px solid var(--border-default)',
              borderRadius: 12,
              padding: mobile ? 20 : 24,
              display: 'flex', flexDirection: 'column', gap: 16,
              transitionDelay: `${i * 60}ms`,
              height: mobile ? 280 : 320,
              boxSizing: 'border-box',
            }}>
              <div style={{ display: 'flex', gap: 2, color: '#F5A623' }}>
                {Array.from({ length: q.stars }).map((_, s) => <i key={s} className="ri-star-fill" style={{ fontSize: 14 }}></i>)}
              </div>
              <p style={{
                fontFamily: 'var(--font-display)', fontWeight: 500,
                fontSize: 16, lineHeight: 1.55, color: 'var(--text-default)',
                margin: 0, flex: 1,
                overflow: 'hidden',
                display: '-webkit-box',
                WebkitLineClamp: mobile ? 5 : 6,
                WebkitBoxOrient: 'vertical',
              }}>"{q.quote}"</p>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12, paddingTop: 8, borderTop: '1px solid var(--border-default)' }}>
                <div style={{
                  width: 40, height: 40, borderRadius: '50%',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  flexShrink: 0, overflow: 'hidden', background: '#E9EEF5',
                }}>
                  <img
                    src={q.avatar}
                    alt={q.name}
                    loading="lazy"
                    style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                    onError={(e) => {
                      e.currentTarget.style.display = 'none';
                      const fb = e.currentTarget.nextSibling;
                      if (fb) fb.style.display = 'inline-flex';
                    }}
                  />
                  <span style={{
                    display: 'none', width: '100%', height: '100%',
                    alignItems: 'center', justifyContent: 'center',
                    fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 16, color: '#55708f',
                  }}>{q.initial}</span>
                </div>
                <div>
                  <div style={{ fontWeight: 600, fontSize: 14, color: 'var(--text-default)' }}>{q.name}</div>
                  <div style={{ fontSize: 12, color: 'var(--text-support)' }}>{q.role}</div>
                </div>
              </div>
            </article>
          ))}
        </div>
        {totalSlides > 1 && (
          <div style={{ marginTop: 18, display: 'flex', justifyContent: 'center', gap: 8 }}>
            {Array.from({ length: totalSlides }).map((_, idx) => (
              <button
                key={idx}
                onClick={() => setSlideIndex(idx)}
                aria-label={`Slide ${idx + 1}`}
                style={{
                  width: idx === slideIndex ? 18 : 8,
                  height: 8,
                  borderRadius: 999,
                  border: 'none',
                  background: idx === slideIndex ? SG : 'var(--border-default)',
                  cursor: 'pointer',
                  transition: 'all 180ms ease',
                }}
              />
            ))}
          </div>
        )}
      </Container>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// SECTION: CROSS-SELL (soft)
// ─────────────────────────────────────────────────────────────
function NumCrossSell({ mobile }) {
  return (
    <section data-reveal style={{
      padding: mobile ? '48px 0 64px' : '64px 0 96px',
      background: 'var(--bg)',
    }}>
      <Container>
        <div className="reveal-child" style={{
          background: 'var(--xsell-bg)',
          borderRadius: 16,
          padding: mobile ? '28px 24px' : '48px 56px',
          color: 'var(--xsell-fg)',
          display: 'grid',
          gridTemplateColumns: mobile ? '1fr' : '1.4fr 1fr',
          alignItems: 'center', gap: mobile ? 24 : 40,
          position: 'relative', overflow: 'hidden',
          border: '1px solid var(--xsell-border)',
        }}>
          <GridPattern size={mobile ? 220 : 360} opacity={0.06} color="#fff" style={{ position: 'absolute', right: -40, bottom: -60 }} />

          <div style={{ position: 'relative' }}>
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 8,
              padding: '5px 12px', background: 'rgba(255,255,255,0.10)',
              border: '1px solid rgba(255,255,255,0.18)',
              borderRadius: 50, fontSize: 11, fontWeight: 600, color: 'rgba(255,255,255,0.92)',
              textTransform: 'uppercase', letterSpacing: '0.08em',
            }}>
              <i className="ri-shield-check-line" style={{ fontSize: 13 }}></i> Một sản phẩm khác của Saladin
            </span>
            <h2 style={{
              fontFamily: 'var(--font-display)', fontWeight: 700,
              fontSize: mobile ? 24 : 34, lineHeight: 1.15,
              margin: '16px 0 12px', letterSpacing: '-0.015em', color: '#fff',
            }}>
              2026 là <span style={{ color: SG, fontWeight: 800 }}>Personal Year 7</span>, năm củng cố sự an tâm cùng <span style={{ color: SG, fontWeight: 800 }}>Saladin</span>.
            </h2>
            <p style={{
              fontSize: mobile ? 14 : 16, lineHeight: 1.6,
              margin: 0, marginBottom: 24,
              color: 'rgba(255,255,255,0.82)', maxWidth: 540,
            }}>
              Đây là thời điểm phù hợp để bạn rà soát lại kế hoạch bảo vệ cho bản thân và gia đình, từ <strong style={{ color: '#fff', fontWeight: 700 }}>Bảo hiểm Sức khỏe</strong>, <strong style={{ color: '#fff', fontWeight: 700 }}>Tai nạn cá nhân</strong>... đến <strong style={{ color: '#fff', fontWeight: 700 }}>TNDS Xe máy/Ô tô</strong> và <strong style={{ color: '#fff', fontWeight: 700 }}>Bảo hiểm Du lịch</strong>.
            </p>
            <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
              <a href="https://saladin.vn" style={{
                background: 'transparent', color: '#fff',
                padding: '12px 20px', borderRadius: 4,
                border: '1px solid rgba(255,255,255,0.45)',
                fontFamily: 'inherit', fontSize: 14, fontWeight: 600,
                display: 'inline-flex', alignItems: 'center', gap: 8,
              }}>
                Xem các gói bảo hiểm Saladin <i className="ri-arrow-right-line" style={{ fontSize: 16 }}></i>
              </a>
            </div>
          </div>

          {/* Side stat card */}
          {!mobile && (
            <div style={{ position: 'relative', zIndex: 1 }}>
              <div style={{
                background: 'rgba(255,255,255,0.06)',
                border: '1px solid rgba(255,255,255,0.14)',
                borderRadius: 12, padding: 20,
                backdropFilter: 'blur(8px)',
              }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                  <span style={{ fontSize: 11, color: 'rgba(255,255,255,0.6)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Bảo hiểm sức khoẻ gia đình</span>
                </div>
                <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 6 }}>
                  <span style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 28, color: '#fff' }}>Từ 65k</span>
                  <span style={{ fontSize: 12, color: 'rgba(255,255,255,0.6)' }}>/tháng</span>
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 16 }}>
                  {['Cấp hợp đồng 60 giây', 'Quyền lợi linh hoạt theo nhu cầu', 'Đối tác A+: Bảo Việt · Bảo Minh · PVI · VBI · MIC'].map(f => (
                    <div key={f} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'rgba(255,255,255,0.88)' }}>
                      <i className="ri-check-line" style={{ color: SG, fontSize: 16 }}></i> {f}
                    </div>
                  ))}
                </div>
              </div>
            </div>
          )}
        </div>
      </Container>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// FOOTER
// ─────────────────────────────────────────────────────────────
function NumFooter({ mobile }) {
  const [socialLinks, setSocialLinks] = React.useState(DEFAULT_SOCIAL_LINKS);
  const [footerGroups, setFooterGroups] = React.useState(DEFAULT_FOOTER_LINK_GROUPS);
  const goHome = (e) => {
    if (typeof window === 'undefined') return;
    e.preventDefault();
    history.replaceState(null, '', '/');
    window.dispatchEvent(new PopStateEvent('popstate'));
  };
  React.useEffect(() => {
    if (typeof window === 'undefined' || typeof fetch === 'undefined') return;
    let cancelled = false;
    fetch('data/social_links.csv')
      .then((res) => res.ok ? res.text() : '')
      .then((text) => {
        if (cancelled || !text) return;
        const rows = csvToObjects(text)
          .map((r) => ({ ic: r.ic || '', label: r.label || '', href: r.href || '' }))
          .filter((r) => r.ic && r.href);
        if (rows.length) setSocialLinks(rows);
      })
      .catch(() => {});

    fetch('data/footer_links.csv')
      .then((res) => res.ok ? res.text() : '')
      .then((text) => {
        if (cancelled || !text) return;
        const rows = csvToObjects(text)
          .map((r) => ({ group: r.group || '', label: r.label || '', href: r.href || '' }))
          .filter((r) => r.group && r.label && r.href);
        if (!rows.length) return;
        const grouped = [];
        rows.forEach((row) => {
          let g = grouped.find((x) => x.title === row.group);
          if (!g) { g = { title: row.group, links: [] }; grouped.push(g); }
          g.links.push({ label: row.label, href: row.href });
        });
        if (grouped.length) setFooterGroups(grouped);
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, []);

  const renderFooterLabel = (label) => {
    const raw = String(label || '');
    const hot = raw.includes('🔥HOT');
    const moi = raw.includes('🔥MỚI');
    const clean = raw.replace('🔥HOT', '').replace('🔥MỚI', '').trim();
    return (
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
        <span>{clean}</span>
        {hot && (
          <span style={{
            fontSize: 10, fontWeight: 700, color: '#fff',
            background: '#F79009', borderRadius: 4, padding: '1px 5px',
            lineHeight: 1.4,
          }}>HOT</span>
        )}
        {moi && (
          <span style={{
            fontSize: 10, fontWeight: 700, color: '#fff',
            background: '#F79009', borderRadius: 4, padding: '1px 5px',
            lineHeight: 1.4,
          }}>MỚI</span>
        )}
      </span>
    );
  };

  return (
    <footer style={{
      background: 'var(--footer-bg)',
      color: 'rgba(255,255,255,0.85)',
      borderTop: '1px solid rgba(255,255,255,0.18)',
      paddingTop: mobile ? 28 : 34,
      paddingBottom: mobile ? 24 : 32,
    }}>
      <Container>
        <div style={{
          marginBottom: mobile ? 24 : 32,
          paddingBottom: mobile ? 16 : 20,
          borderBottom: '1px solid rgba(255,255,255,0.12)',
        }}>
          <div style={{ fontSize: mobile ? 24 : 34, fontWeight: 700, color: '#fff', marginBottom: 8, lineHeight: 1.1 }}>Văn phòng</div>
          <div style={{ fontSize: mobile ? 14 : 15, lineHeight: 1.55, color: 'rgba(255,255,255,0.72)' }}>
            111 Lý Chính Thắng, Phường Xuân Hòa, TP. Hồ Chí Minh, Việt Nam
          </div>
        </div>

        <div style={{
          display: 'grid',
          gridTemplateColumns: mobile ? '1fr' : '1.7fr 1fr 1.2fr 1fr 1fr',
          gap: mobile ? 28 : 40,
          marginBottom: mobile ? 32 : 40,
        }}>
          {/* Brand col */}
          <div style={{ gridColumn: mobile ? '1 / -1' : 'auto' }}>
            <a href="/" onClick={goHome} style={{ display: 'inline-flex', alignItems: 'center', color: 'inherit' }}>
              <img src="https://www.saladin.vn/image/footer_logo.png" style={{ height: 32, width: 'auto' }} alt="Saladin"/>
            </a>
            <p style={{ fontSize: 13, lineHeight: 1.55, marginTop: 14, marginBottom: 0, color: 'rgba(255,255,255,0.65)', maxWidth: 320 }}>
              Công ty TNHH Tư vấn và Công nghệ 10x · Mã số doanh nghiệp 0316591461.
            </p>
            <a href="tel:1900638454" style={{ marginTop: 10, display: 'inline-flex', alignItems: 'center', gap: 8, fontSize: 14, fontWeight: 700, color: SG }}>
              <i className="ri-phone-fill" style={{ fontSize: 16 }}></i>1900 638 454
            </a>
            <div style={{ display: 'flex', gap: 8, marginTop: 18 }}>
              {socialLinks.map(s => (
                <a key={s.ic} href={s.href} target="_blank" rel="noreferrer" aria-label={s.label} style={{
                  width: 34, height: 34, borderRadius: 6,
                  background: '#fff',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  color: '#111',
                }}><i className={s.ic} style={{ fontSize: 18 }}></i></a>
              ))}
            </div>
          </div>

          {/* Link columns */}
          {mobile ? (
            <div style={{
              gridColumn: '1 / -1',
              display: 'grid',
              gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',
              gap: 18,
            }}>
              {footerGroups.map(c => (
                <div key={c.title} style={{ minWidth: 0 }}>
                  <div style={{
                    fontWeight: 600, fontSize: 12, textTransform: 'uppercase',
                    letterSpacing: '0.1em', color: '#fff', marginBottom: 12,
                    whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                  }}>
                    {c.title}
                  </div>
                  <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 9 }}>
                    {c.links.map(l => (
                      <li key={l.label} style={{ minWidth: 0 }}>
                        <a href={l.href} style={{
                          fontSize: 12, color: 'rgba(255,255,255,0.68)',
                          textDecoration: 'none', lineHeight: 1.45,
                          display: 'block', overflowWrap: 'anywhere',
                        }}>
                          {renderFooterLabel(l.label)}
                        </a>
                      </li>
                    ))}
                  </ul>
                </div>
              ))}
            </div>
          ) : (
            footerGroups.map(c => (
              <div key={c.title}>
                <div style={{ fontWeight: 600, fontSize: 12, textTransform: 'uppercase', letterSpacing: '0.1em', color: '#fff', marginBottom: 14 }}>
                  {c.title}
                </div>
                <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 10 }}>
                  {c.links.map(l => (
                    <li key={l.label}>
                      <a href={l.href} style={{ fontSize: 13, color: 'rgba(255,255,255,0.68)', textDecoration: 'none' }}>
                        {renderFooterLabel(l.label)}
                      </a>
                    </li>
                  ))}
                </ul>
              </div>
            ))
          )}
        </div>

        <div style={{
          borderTop: '1px solid rgba(255,255,255,0.08)',
          paddingTop: 16,
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          flexWrap: 'wrap',
          gap: 10,
        }}>
          <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.55)' }}>
            © 2026 Saladin Việt Nam · Thần số học
          </div>
          <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.55)' }}>
            version beta
          </div>
        </div>

      </Container>
    </footer>
  );
}

Object.assign(window, { NumHeader, NumHero, NumWhat, NumHow, NumTestimonials, NumCrossSell, NumFooter, NumAboutXtra });
