// Petit Béret - marketing site
// Design: Native Premium (Direction B)
// Languages: EN / FR / RU
// Asset base: set window.__PB_ASSET_BASE before loading (default './')

const ASSET_BASE = window.__PB_ASSET_BASE || './';

// ── Design tokens ───────────────────────────────────────────────
const SITE_DARK = {
  bg: '#0B1220',
  bgGrad: 'radial-gradient(120% 60% at 50% 0%, #1A2744 0%, #0B1220 55%)',
  surface: '#17223A',
  surface2: '#1E2A44',
  surfaceMuted: '#141D32',
  hair: 'rgba(255,255,255,0.06)',
  hairStrong: 'rgba(255,255,255,0.12)',
  ink: '#F5F7FA',
  ink2: '#B6C0D1',
  ink3: '#7B87A0',
  ink4: '#5A6580',
  blue: '#0A84FF',
  blueSoft: 'rgba(10,132,255,0.18)',
  emerald: '#22C37A',
  emeraldSoft: 'rgba(34,195,122,0.14)',
  gold: '#E8A84A',
  goldSoft: 'rgba(232,168,74,0.14)',
  red: '#E55050',
  sky: '#5AC8FA',
};

// Light mode tokens matched to iOS app NPDesignSystem palette
const SITE_LIGHT = {
  bg: '#F6F5F1',
  bgGrad: 'radial-gradient(120% 60% at 50% 0%, #FFFFFF 0%, #EEECEA 80%)',
  surface: '#FFFFFF',
  surface2: '#FAF9F5',
  surfaceMuted: '#F0EEE8',
  hair: 'rgba(15,15,16,0.10)',
  hairStrong: 'rgba(15,15,16,0.18)',
  ink: '#0E0E0C',
  ink2: '#4A4A46',
  ink3: '#7A7A74',
  ink4: '#9A9A93',
  blue: '#1F3A8A',
  blueSoft: 'rgba(31,58,138,0.14)',
  emerald: '#1E9F65',
  emeraldSoft: 'rgba(30,159,101,0.14)',
  gold: '#B7771A',
  goldSoft: 'rgba(183,119,26,0.14)',
  red: '#B84A4A',
  sky: '#50A9D9',
};

// ── Font stacks ─────────────────────────────────────────────────
const SF_FONT = "'Inter','SF Pro Display',-apple-system,BlinkMacSystemFont,system-ui,sans-serif";
const SF_TEXT = "'Inter','SF Pro Text',-apple-system,BlinkMacSystemFont,system-ui,sans-serif";
const NY_SERIF = "'Fraunces','New York','Times New Roman',Georgia,serif";
const JB_MONO = "'JetBrains Mono',ui-monospace,'SF Mono',Menlo,monospace";

// ── Store data ──────────────────────────────────────────────────
const STORE_LINKS = {
  ios: 'https://apps.apple.com/ru/app/petit-b%C3%A9ret/id6751508281?l=en-GB',
  android: 'https://play.google.com/store/apps/details?id=com.ad.petitberet',
};

const BADGE_PATHS = {
  apple: {
    en: 'assets/Download_on_the_App_Store_Badge_US-UK_RGB_wht_092917.svg',
    fr: 'assets/Download_on_the_App_Store_Badge_FR_RGB_wht_100217.svg',
    ru: 'assets/Download_on_the_App_Store_Badge_RU_RGB_wht_100317.svg',
  },
  google: {
    en: 'assets/GetItOnGooglePlay_Badge_Web_color_English.svg',
    fr: 'assets/GetItOnGooglePlay_Badge_Web_color_French.svg',
    ru: 'assets/GetItOnGooglePlay_Badge_Web_color_Russian.svg',
  },
};

// ── Breakpoint hook ──────────────────────────────────────────────
function useBreakpoint() {
  const [w, setW] = React.useState(typeof window !== 'undefined' ? window.innerWidth : 1200);
  React.useEffect(() => {
    const handler = () => setW(window.innerWidth);
    window.addEventListener('resize', handler, { passive: true });
    return () => window.removeEventListener('resize', handler);
  }, []);
  return { isMobile: w < 640, isTablet: w < 1024 };
}

// ── Translations ────────────────────────────────────────────────
const TR = {
  en: {
    nav: {
      modules: 'Features', approach: 'Approach', mastery: 'Modules',
      support: 'Support', about: 'About', download: 'Download',
    },
    hero: {
      eyebrow: 'iOS · Android',
      h1: ['Serious French.', 'Reflexes, not just rules.'],
      body: 'A rigorous trainer for adults A1–C1. Conjugation, subjunctive, pronouns, accents - practiced sentence by sentence, without gamification. Measure your precision, not your score.',
      meta: ['100% offline', 'No registration', 'Privacy first'],
      iosAlt: 'Download on App Store', androidAlt: 'Get it on Google Play',
      phoneAlt: 'Petit Béret on iPhone', droidAlt: 'Petit Béret on Android',
    },
    modules: {
      eyebrow: '§ I · Curriculum',
      h2: ['Six modules.', 'The hard parts of French.'],
      body: 'Each module follows the same mechanic: short prompt, discreet translation, keyboard answer, immediate feedback. Precision % replaces the streak.',
      cta: 'View module ›',
      items: [
        { name: 'Conjugation', glyph: '✎', level: 'A1+', desc: '2,000 verbs, all tenses. No multiple-choice - just typing and real precision.', count: '2 000', unit: 'verbs', href: 'modules/french-conjugation-app/' },
        { name: 'Subjunctive', glyph: '◎', level: 'A2+', desc: 'Build intuition for the subjunctive through logical triggers.', count: '180', unit: 'triggers', href: 'modules/french-subjunctive-practice/' },
        { name: 'Pronouns', glyph: '↔', level: 'A2+', desc: 'Y, en, and pronoun order - until it becomes automatic.', count: '12', unit: 'case types', href: 'modules/learn-french-pronouns/' },
        { name: 'Prepositions', glyph: 'à', level: 'A1+', desc: 'Stop guessing. Learn à, de, chez through context.', count: '60', unit: 'patterns', href: 'modules/' },
        { name: 'Noun Gender', glyph: '⚥', level: 'A1+', desc: 'Build the instinct for masculine and feminine by patterns.', count: '900', unit: 'nouns', href: 'modules/french-grammar-cefr/' },
        { name: 'Accents', glyph: 'é', level: 'A1+', desc: 'Perfect your spelling: é, è, à, ê, ç - through dictation.', count: '300', unit: 'traps', href: 'modules/' },
      ],
    },
    approach: {
      eyebrow: '§ II · Approach',
      h2: 'Designed for serious adults revising their French.',
      body: 'Petit Béret treats users as students, not players. No confetti. No leagues. No voice shouting "well done". Just clear, measurable work that ends.',
      pillars: [
        { kicker: '01', title: 'Precision, not streaks.', body: 'No streak to lose. No hearts. One measure: precision %. It goes up. It goes down. It tells the truth.', stat: '∞', unit: 'days practiced' },
        { kicker: '02', title: 'Sentence by sentence.', body: "Everything is anchored in a short, readable sentence. You're not memorizing a conjugation table - you type the form in place - the app checks it and shows you the correction.", stat: '5 min', unit: 'typical session' },
        { kicker: '03', title: 'Offline, in silence.', body: 'No registration. No account. The app works on a plane, in the metro, in the countryside. Your data stays on your device.', stat: '0', unit: 'account required' },
      ],
    },
    mastery: {
      eyebrow: '§ III · Precision',
      h2: ['What we show.', 'What we hide.'],
      shown: 'Shown', hidden: 'Hidden',
      rows: [
        ['Precision %', 'daily, per module', 'Streak counter'],
        ['Days practiced', 'cumulative, never resets', 'Lost streaks, freezes'],
        ['XP today', 'small, activity signal', 'Leaderboards, leagues'],
        ['Precision per module', '0–100 %', 'Gems, currencies'],
        ['Mistakes Cabinet', '3 correct in a row to clear', 'Timers that penalize'],
        ['CEFR level', 'A1 → C1', 'Rank, division'],
      ],
    },
    download: {
      h2: ['Learn French,', 'sentence by sentence.'],
      body: 'Download Petit Béret. No registration, no ads, no sync requirements. Open the app - start your first session in under fifteen seconds.',
      meta: 'v 4.0 · Precision Edition · iOS 16+ · Android 10+',
    },
    footer: {
      privacy: 'Privacy Policy', terms: 'Terms of Service',
      about: 'About', contact: 'Contact',
      copy: '© Petit Béret · Made for learners',
    },
  },
  fr: {
    nav: {
      modules: 'Fonctionnalités', approach: 'Approche', mastery: 'Modules',
      support: 'Support', about: 'À propos', download: 'Télécharger',
    },
    hero: {
      eyebrow: 'iOS · Android',
      h1: ['Français sérieux.', 'Des réflexes, pas seulement des règles.'],
      body: "Un entraîneur rigoureux pour adultes A1–C1. Conjugaison, subjonctif, pronoms, accents - pratiqués phrase par phrase, sans gamification. Mesurez votre précision, pas votre score.",
      meta: ['100 % hors-ligne', 'Aucune inscription', "Vie privée d'abord"],
      iosAlt: "Télécharger sur l'App Store", androidAlt: 'Disponible sur Google Play',
      phoneAlt: 'Petit Béret sur iPhone', droidAlt: 'Petit Béret sur Android',
    },
    modules: {
      eyebrow: '§ I · Programme',
      h2: ['Six modules.', 'Les parties difficiles du français.'],
      body: 'Chaque module suit la même mécanique : consigne courte, traduction discrète, réponse au clavier, retour immédiat. La précision % remplace la série.',
      cta: 'Voir le module ›',
      items: [
        { name: 'Conjugaison', glyph: '✎', level: 'A1+', desc: "2 000 verbes, tous les temps. Pas de QCM - frappe au clavier, précision réelle.", count: '2 000', unit: 'verbes', href: 'modules/french-conjugation-app/' },
        { name: 'Subjonctif', glyph: '◎', level: 'A2+', desc: "Acquérez l'intuition du subjonctif par les déclencheurs logiques.", count: '180', unit: 'déclencheurs', href: 'modules/french-subjunctive-practice/' },
        { name: 'Pronoms', glyph: '↔', level: 'A2+', desc: "Y, en, et l'ordre des pronoms - jusqu'à l'automatisme.", count: '12', unit: 'cas types', href: 'modules/learn-french-pronouns/' },
        { name: 'Prépositions', glyph: 'à', level: 'A1+', desc: 'Cessez de deviner. Apprenez à, de, chez par le contexte.', count: '60', unit: 'régimes', href: 'modules/' },
        { name: 'Genres', glyph: '⚥', level: 'A1+', desc: "Bâtissez l'instinct du masculin et du féminin par les motifs.", count: '900', unit: 'noms', href: 'modules/french-grammar-cefr/' },
        { name: 'Accents', glyph: 'é', level: 'A1+', desc: 'Perfectionnez l\'orthographe : é, è, à, ê, ç - par la dictée.', count: '300', unit: 'pièges', href: 'modules/' },
      ],
    },
    approach: {
      eyebrow: '§ II · Approche',
      h2: 'Conçu pour les adultes sérieux qui révisent leur français.',
      body: "Petit Béret traite l'utilisateur en étudiant, pas en joueur. Pas de confettis. Aucune ligue. Aucune voix qui crie « bravo ». Juste un travail clair, mesurable, et qui se termine.",
      pillars: [
        { kicker: '01', title: 'Précision, pas de série.', body: "Pas de série à perdre. Pas de cœurs. Une mesure : la précision %. Elle monte. Elle descend. Elle dit la vérité.", stat: '∞', unit: 'jours pratiqués' },
        { kicker: '02', title: 'Phrase par phrase.', body: "Tout est ancré dans une phrase courte, lisible. Vous ne mémorisez pas un tableau de conjugaison - vous écrivez la forme à sa place - l'application vérifie et affiche la correction.", stat: '5 min', unit: 'session typique' },
        { kicker: '03', title: 'Hors-ligne, en silence.', body: "Aucune inscription. Aucun compte. L'application fonctionne dans l'avion, dans le métro, à la campagne. Vos données restent sur votre appareil.", stat: '0', unit: 'compte requis' },
      ],
    },
    mastery: {
      eyebrow: '§ III · Précision',
      h2: ['Ce que nous montrons.', 'Ce que nous cachons.'],
      shown: 'Montré', hidden: 'Caché',
      rows: [
        ['Précision %', 'quotidien, par module', 'Compteur de série'],
        ['Jours pratiqués', 'cumulatif, jamais réinitialisé', 'Séries perdues, gels'],
        ['XP du jour', "petit, signal d'activité", 'Classement, ligue'],
        ['Précision par module', '0–100 %', 'Gemmes, monnaies'],
        ['Cabinet des Erreurs', '3 bonnes réponses d\'affilée pour effacer', 'Minuteurs qui pénalisent'],
        ['Niveau CEFR', 'A1 → C1', 'Rang, division'],
      ],
    },
    download: {
      h2: ['Apprenez le français,', 'phrase par phrase.'],
      body: "Téléchargez Petit Béret. Aucune inscription, aucune publicité, aucune synchronisation. Ouvrez l'application - commencez votre première session en moins de quinze secondes.",
      meta: 'v 4.0 · Édition Précision · iOS 16+ · Android 10+',
    },
    footer: {
      privacy: 'Confidentialité', terms: 'Conditions',
      about: 'À propos', contact: 'Contact',
      copy: '© Petit Béret · Fait pour les apprenants',
    },
  },
  ru: {
    nav: {
      modules: 'Возможности', approach: 'Подход', mastery: 'Модули',
      support: 'Поддержка', about: 'О нас', download: 'Скачать',
    },
    hero: {
      eyebrow: 'iOS · Android',
      h1: ['Серьёзный французский.', 'Рефлексы, не просто правила.'],
      body: 'Строгий тренажёр для взрослых A1–C1. Спряжения, субжонктив, местоимения, ударения - тренировка фраза за фразой, без геймификации. Измеряйте точность, не счёт.',
      meta: ['100% офлайн', 'Без регистрации', 'Конфиденциальность'],
      iosAlt: 'Скачать в App Store', androidAlt: 'Доступно в Google Play',
      phoneAlt: 'Petit Béret на iPhone', droidAlt: 'Petit Béret на Android',
    },
    modules: {
      eyebrow: '§ I · Программа',
      h2: ['Шесть модулей.', 'Сложные части французского.'],
      body: 'Каждый модуль: короткий промпт, перевод, ввод с клавиатуры, мгновенная обратная связь. Точность % заменяет серии.',
      cta: 'Открыть модуль ›',
      items: [
        { name: 'Спряжения', glyph: '✎', level: 'A1+', desc: '2 000 глаголов, все времена. Без выбора вариантов - только набор и реальная точность.', count: '2 000', unit: 'глаголов', href: 'modules/french-conjugation-app/' },
        { name: 'Субжонктив', glyph: '◎', level: 'A2+', desc: 'Развивайте интуицию сюбжонктива через логические триггеры.', count: '180', unit: 'триггеров', href: 'modules/french-subjunctive-practice/' },
        { name: 'Местоимения', glyph: '↔', level: 'A2+', desc: 'Y, en и порядок местоимений - до автоматизма.', count: '12', unit: 'типов', href: 'modules/learn-french-pronouns/' },
        { name: 'Предлоги', glyph: 'à', level: 'A1+', desc: 'Прекратите гадать. Учите à, de, chez через контекст.', count: '60', unit: 'паттернов', href: 'modules/' },
        { name: 'Род слов', glyph: '⚥', level: 'A1+', desc: 'Развивайте чутьё на мужской и женский род через паттерны.', count: '900', unit: 'слов', href: 'modules/french-grammar-cefr/' },
        { name: 'Ударения', glyph: 'é', level: 'A1+', desc: 'Совершенствуйте орфографию: é, è, à, ê, ç - через диктант.', count: '300', unit: 'ловушек', href: 'modules/' },
      ],
    },
    approach: {
      eyebrow: '§ II · Подход',
      h2: 'Создан для серьёзных взрослых, изучающих французский.',
      body: 'Petit Béret относится к пользователю как к студенту, а не игроку. Без конфетти. Без лиг. Без голоса, кричащего «браво». Только чёткая, измеримая работа.',
      pillars: [
        { kicker: '01', title: 'Точность, не серии.', body: 'Нет серии, которую можно потерять. Нет сердечек. Одна мера: % точности.', stat: '∞', unit: 'дней практики' },
        { kicker: '02', title: 'Фраза за фразой.', body: "Всё основано на короткой, читаемой фразе. Вы не запоминаете таблицу спряжений - вы вводите форму на месте - приложение проверяет и показывает правильный ответ.", stat: '5 мин', unit: 'типичная сессия' },
        { kicker: '03', title: 'Офлайн, без шума.', body: 'Никакой регистрации. Никакого аккаунта. Приложение работает в самолёте, в метро. Ваши данные остаются на устройстве.', stat: '0', unit: 'без аккаунта' },
      ],
    },
    mastery: {
      eyebrow: '§ III · Точность',
      h2: ['Что мы показываем.', 'Что мы скрываем.'],
      shown: 'Показано', hidden: 'Скрыто',
      rows: [
        ['Точность %', 'ежедневно, по модулю', 'Счётчик серий'],
        ['Дней практики', 'накопительно, никогда не сбрасывается', 'Потерянные серии'],
        ['XP сегодня', 'небольшой, сигнал активности', 'Таблицы лидеров, лиги'],
        ['Точность по модулю', '0–100 %', 'Кристаллы, монеты'],
        ['Кабинет ошибок', '3 верных ответа подряд для очистки', 'Таймеры-штрафы'],
        ['Уровень CEFR', 'A1 → C1', 'Ранг, дивизион'],
      ],
    },
    download: {
      h2: ['Учите французский,', 'фраза за фразой.'],
      body: 'Скачайте Petit Béret. Без регистрации, без рекламы. Откройте приложение - начните первую сессию менее чем за пятнадцать секунд.',
      meta: 'v 4.0 · Издание Точности · iOS 16+ · Android 10+',
    },
    footer: {
      privacy: 'Конфиденциальность', terms: 'Условия',
      about: 'О нас', contact: 'Контакты',
      copy: '© Petit Béret · Для изучающих французский',
    },
  },
};

// ── Wordmark ────────────────────────────────────────────────────
function Wordmark({ size = 24, color, gold }) {
  return (
    <span style={{
      fontFamily: SF_FONT, fontSize: size, fontWeight: 600,
      color, letterSpacing: -size * 0.03, lineHeight: 1, whiteSpace: 'nowrap',
      display: 'inline-flex', alignItems: 'baseline',
    }}>
      Petit
      <span style={{
        fontFamily: NY_SERIF, fontStyle: 'italic', fontWeight: 400,
        marginLeft: size * 0.18, color: gold,
        letterSpacing: -size * 0.025,
      }}>
        Béret
      </span>
    </span>
  );
}

// ── Eyebrow ─────────────────────────────────────────────────────
function Eyebrow({ children, c, hair, center }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center',
      justifyContent: center ? 'center' : 'flex-start', gap: 12,
      fontFamily: JB_MONO, fontSize: 10.5, fontWeight: 700,
      color: c, letterSpacing: 1.6, textTransform: 'uppercase',
    }}>
      {children}
    </div>
  );
}

// ── Store badge (official SVGs) ──────────────────────────────────
function StoreBadge({ platform, lang }) {
  const store = platform === 'ios' ? 'apple' : 'google';
  const key = ['en', 'fr', 'ru'].includes(lang) ? lang : 'en';
  const src = ASSET_BASE + BADGE_PATHS[store][key];
  const s = TR[key] || TR.en;
  const alt = platform === 'ios' ? s.hero.iosAlt : s.hero.androidAlt;
  return (
    <a href={STORE_LINKS[platform]} target="_blank" rel="noopener noreferrer"
      style={{ display: 'inline-flex', lineHeight: 0 }}>
      <img src={src} alt={alt} style={{ height: 52, width: 'auto' }} loading="eager"/>
    </a>
  );
}

// ── Theme toggle ─────────────────────────────────────────────────
function ThemeToggle({ theme, setTheme, T }) {
  const isDark = theme === 'dark';
  const handleToggle = () => {
    const next = isDark ? 'light' : 'dark';
    setTheme(next);
    try { localStorage.setItem('pb_theme', next); } catch(e) {}
  };
  return (
    <button
      onClick={handleToggle}
      aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
      title={isDark ? 'Light mode' : 'Dark mode'}
      style={{
        background: T.hair,
        border: `1px solid ${T.hairStrong}`,
        cursor: 'pointer',
        width: 30, height: 30, borderRadius: 8,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: T.ink2, flexShrink: 0, padding: 0,
      }}
    >
      {isDark ? (
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <circle cx="7" cy="7" r="2.5" stroke="currentColor" strokeWidth="1.4"/>
          <line x1="7" y1="1" x2="7" y2="2.8" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          <line x1="7" y1="11.2" x2="7" y2="13" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          <line x1="1" y1="7" x2="2.8" y2="7" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          <line x1="11.2" y1="7" x2="13" y2="7" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          <line x1="2.75" y1="2.75" x2="4.02" y2="4.02" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          <line x1="9.98" y1="9.98" x2="11.25" y2="11.25" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          <line x1="9.98" y1="4.02" x2="11.25" y2="2.75" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
          <line x1="2.75" y1="11.25" x2="4.02" y2="9.98" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
        </svg>
      ) : (
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <path d="M11.5 8.8C10.4 10.6 8.3 11.8 6 11.8C3.35 11.8 1.2 9.65 1.2 7C1.2 4.7 2.4 2.6 4.2 1.5C2.7 2.3 1.8 4 1.8 6C1.8 8.65 3.95 10.8 6.6 10.8C8.6 10.8 10.3 9.6 11 7.8C11.2 8.1 11.5 8.5 11.5 8.8Z" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"/>
        </svg>
      )}
    </button>
  );
}

// ── Nav ──────────────────────────────────────────────────────────
function Nav({ T, lang, setLang, isRoot, theme, setTheme }) {
  const dark = T.bg === '#0B1220';
  const s = TR[lang] || TR.en;
  const langRoot = lang === 'en' ? '' : `/${lang}`;
  const h = (id) => `${langRoot}/#${id}`;
  const { isTablet } = useBreakpoint();
  const [menuOpen, setMenuOpen] = React.useState(false);

  React.useEffect(() => {
    if (!isTablet && menuOpen) setMenuOpen(false);
  }, [isTablet]);

  const linkStyle = {
    fontFamily: SF_TEXT, fontSize: 14, fontWeight: 500,
    color: dark ? '#E8ECF2' : T.ink, textDecoration: 'none',
    letterSpacing: -0.1,
  };

  const menuLinks = [
    { label: s.nav.modules, href: h('modules') },
    { label: s.nav.approach, href: h('approach') },
    { label: s.nav.mastery, href: `${langRoot}/modules/` },
    { label: s.nav.about, href: `${langRoot}/about/` },
    { label: s.nav.support, href: `${langRoot}/support/` },
  ];

  return (
    <nav style={{
      position: 'sticky', top: 0, zIndex: 50,
      backdropFilter: 'blur(20px) saturate(180%)',
      WebkitBackdropFilter: 'blur(20px) saturate(180%)',
      background: dark ? 'rgba(11,18,32,0.92)' : 'rgba(250,247,241,0.92)',
      borderBottom: `1px solid ${T.hair}`,
    }}>
      <div style={{
        maxWidth: 1180, margin: '0 auto',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '14px 20px',
      }}>
        <a href={`${langRoot}/`} style={{ display: 'flex', alignItems: 'center', gap: 10, textDecoration: 'none' }}>
          <span style={{
            width: 30, height: 30, borderRadius: 8,
            background: dark ? '#1E2A44' : '#F1ECE0',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            overflow: 'hidden', border: `1px solid ${T.hair}`,
            flexShrink: 0,
          }}>
            <img src={ASSET_BASE + 'assets/AppIcon128x128.png'} alt="" style={{
              width: '90%', height: '90%', objectFit: 'contain',
            }}/>
          </span>
          <Wordmark size={18} color={T.ink} gold={T.gold}/>
        </a>

        {isTablet ? (
          <button
            onClick={() => setMenuOpen(o => !o)}
            aria-label={menuOpen ? 'Close menu' : 'Open menu'}
            aria-expanded={menuOpen}
            style={{
              background: 'none', border: 'none', cursor: 'pointer',
              color: dark ? '#E8ECF2' : T.ink,
              padding: '6px 8px',
              display: 'flex', flexDirection: 'column', gap: 5,
              alignItems: 'center', justifyContent: 'center',
              transition: 'transform 0.3s ease',
            }}
          >
            <span style={{
              display: 'block', width: 22, height: 2,
              background: 'currentColor', borderRadius: 1,
              transition: 'transform 0.28s cubic-bezier(0.4,0,0.2,1)',
              transform: menuOpen ? 'rotate(45deg) translateY(7px)' : 'none',
              transformOrigin: 'center',
            }}/>
            <span style={{
              display: 'block', width: 22, height: 2,
              background: 'currentColor', borderRadius: 1,
              transition: 'opacity 0.18s ease, transform 0.28s cubic-bezier(0.4,0,0.2,1)',
              opacity: menuOpen ? 0 : 1,
              transform: menuOpen ? 'scaleX(0)' : 'scaleX(1)',
            }}/>
            <span style={{
              display: 'block', width: 22, height: 2,
              background: 'currentColor', borderRadius: 1,
              transition: 'transform 0.28s cubic-bezier(0.4,0,0.2,1)',
              transform: menuOpen ? 'rotate(-45deg) translateY(-7px)' : 'none',
              transformOrigin: 'center',
            }}/>
          </button>
        ) : (
          <div style={{ display: 'flex', alignItems: 'center', gap: 24 }}>
            <a href={h('modules')} style={linkStyle}>{s.nav.modules}</a>
            <a href={h('approach')} style={linkStyle}>{s.nav.approach}</a>
            <a href={`${langRoot}/modules/`} style={linkStyle}>{s.nav.mastery}</a>
            <a href={`${langRoot}/about/`} style={linkStyle}>{s.nav.about}</a>
            <a href={`${langRoot}/support/`} style={linkStyle}>{s.nav.support}</a>

            <div style={{ display: 'flex', gap: 4 }}>
              {['en', 'fr', 'ru'].map(l => (
                <button key={l} onClick={() => {
                  try { localStorage.setItem('pb_lang', l); } catch(e) {}
                  const p = window.location.pathname.replace(/^\/(fr|ru)(\/|$)/, '/') || '/';
                  window.location.href = l === 'en' ? p : `/${l}${p}`;
                }} style={{
                  fontFamily: JB_MONO, fontSize: 10, fontWeight: 700,
                  color: lang === l ? T.blue : T.ink3,
                  letterSpacing: 1, textTransform: 'uppercase',
                  background: lang === l ? T.blueSoft : 'transparent',
                  border: 'none', cursor: 'pointer',
                  padding: '4px 5px', borderRadius: 4,
                }}>{l.toUpperCase()}</button>
              ))}
            </div>

            <ThemeToggle theme={theme} setTheme={setTheme} T={T}/>

            <a href={h('download')} style={{
              background: T.blue, color: '#fff',
              fontFamily: SF_FONT, fontSize: 13, fontWeight: 600,
              letterSpacing: -0.1, textDecoration: 'none',
              padding: '9px 16px', borderRadius: 18,
              boxShadow: `0 8px 22px ${dark ? 'rgba(10,132,255,0.30)' : 'rgba(10,132,255,0.18)'}`,
            }}>{s.nav.download}</a>
          </div>
        )}
      </div>

      {isTablet && (
        <div style={{
          overflow: 'hidden',
          maxHeight: menuOpen ? '520px' : '0',
          opacity: menuOpen ? 1 : 0,
          transition: menuOpen
            ? 'max-height 0.35s cubic-bezier(0.4,0,0.2,1), opacity 0.22s ease'
            : 'max-height 0.28s cubic-bezier(0.4,0,0.2,1), opacity 0.15s ease',
          background: dark ? '#0C1322' : '#F5F2EA',
          borderTop: `1px solid ${dark ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.07)'}`,
        }}>
          <div style={{
            maxWidth: 1180, margin: '0 auto', padding: '8px 24px 28px',
            transform: menuOpen ? 'translateY(0)' : 'translateY(-10px)',
            transition: 'transform 0.32s cubic-bezier(0.4,0,0.2,1)',
          }}>
            {menuLinks.map(link => (
              <a key={link.label} href={link.href}
                onClick={() => setMenuOpen(false)}
                style={{
                  display: 'block',
                  fontFamily: SF_TEXT, fontSize: 20, fontWeight: 700,
                  color: dark ? '#F5F7FA' : '#141821',
                  textDecoration: 'none',
                  padding: '16px 0',
                  borderBottom: `1px solid ${dark ? 'rgba(255,255,255,0.09)' : 'rgba(0,0,0,0.08)'}`,
                  letterSpacing: -0.3,
                }}>{link.label}</a>
            ))}

            <a href={h('download')} onClick={() => setMenuOpen(false)} style={{
              display: 'block',
              background: T.blue, color: '#fff',
              fontFamily: SF_FONT, fontSize: 16, fontWeight: 600,
              letterSpacing: -0.1, textDecoration: 'none',
              padding: '14px 20px', borderRadius: 14,
              textAlign: 'center', marginTop: 20,
            }}>{s.nav.download}</a>

            <div style={{ display: 'flex', gap: 8, marginTop: 16, justifyContent: 'center', alignItems: 'center' }}>
              {['en', 'fr', 'ru'].map(l => (
                <button key={l} onClick={() => {
                  try { localStorage.setItem('pb_lang', l); } catch(e) {}
                  const p = window.location.pathname.replace(/^\/(fr|ru)(\/|$)/, '/') || '/';
                  window.location.href = l === 'en' ? p : `/${l}${p}`;
                }} style={{
                  fontFamily: JB_MONO, fontSize: 11, fontWeight: 700,
                  color: lang === l ? '#fff' : (dark ? '#7B87A0' : '#7A8294'),
                  letterSpacing: 1, textTransform: 'uppercase',
                  background: lang === l ? T.blue : 'transparent',
                  border: `1.5px solid ${lang === l ? T.blue : (dark ? 'rgba(255,255,255,0.15)' : 'rgba(0,0,0,0.12)')}`,
                  cursor: 'pointer',
                  padding: '8px 16px', borderRadius: 8,
                }}>{l.toUpperCase()}</button>
              ))}
              <ThemeToggle theme={theme} setTheme={setTheme} T={T}/>
            </div>
          </div>
        </div>
      )}
    </nav>
  );
}

// ── Hero ─────────────────────────────────────────────────────────
function Hero({ T, lang }) {
  const dark = T === SITE_DARK;
  const s = (TR[lang] || TR.en).hero;
  const { isMobile, isTablet } = useBreakpoint();

  return (
    <section style={{
      position: 'relative', overflow: 'hidden',
      background: T.bgGrad,
      paddingTop: isMobile ? 40 : 60,
      paddingBottom: isMobile ? 50 : 80,
    }}>
      <div style={{
        position: 'absolute', left: '62%', top: 180,
        width: 620, height: 620, borderRadius: '50%',
        background: dark
          ? 'radial-gradient(closest-side, rgba(232,168,74,0.10), transparent 70%)'
          : 'radial-gradient(closest-side, rgba(232,168,74,0.18), transparent 70%)',
        pointerEvents: 'none', filter: 'blur(2px)',
      }}/>
      <div style={{
        position: 'absolute', left: '-8%', top: -40,
        width: 480, height: 480, borderRadius: '50%',
        background: dark
          ? 'radial-gradient(closest-side, rgba(10,132,255,0.10), transparent 70%)'
          : 'radial-gradient(closest-side, rgba(10,132,255,0.06), transparent 70%)',
        pointerEvents: 'none',
      }}/>

      <div style={{
        position: 'relative', zIndex: 2,
        maxWidth: 1180, margin: '0 auto',
        padding: isMobile ? '0 20px' : '0 28px',
        display: 'grid',
        gridTemplateColumns: isTablet ? '1fr' : '1.1fr 0.9fr',
        gap: isTablet ? 0 : 60,
        alignItems: 'center',
      }}>
        <div style={{ textAlign: isTablet ? 'center' : 'left' }}>
          <Eyebrow c={T.ink3} hair={T.hair} center={isTablet}>
            <span>{s.eyebrow}</span>
          </Eyebrow>

          <h1 style={{
            fontFamily: SF_FONT, fontWeight: 600,
            fontSize: isMobile ? 44 : isTablet ? 60 : 72,
            lineHeight: 0.98,
            letterSpacing: isMobile ? -1.4 : -2.4,
            color: T.ink, margin: '24px 0 0',
          }}>
            {s.h1[0]}<br/>
            <span style={{
              fontFamily: NY_SERIF, fontStyle: 'italic', fontWeight: 400,
              letterSpacing: isMobile ? -1 : -1.6,
            }}>{s.h1[1]}</span>
          </h1>

          <div style={{
            width: 40, height: 2, background: T.blue,
            borderRadius: 1, margin: '28px 0',
          }}/>

          <p style={{
            fontFamily: SF_TEXT, fontSize: isMobile ? 16 : 18,
            lineHeight: 1.55, fontWeight: 400,
            color: T.ink2, letterSpacing: -0.15,
            maxWidth: 460, margin: 0,
          }}>{s.body}</p>

          <div style={{ marginTop: 36, display: 'flex', gap: 14, alignItems: 'center', flexWrap: 'wrap', justifyContent: isTablet ? 'center' : 'flex-start' }}>
            <StoreBadge platform="ios" lang={lang}/>
            <StoreBadge platform="android" lang={lang}/>
          </div>
        </div>

        {!isTablet ? (
          <div style={{
            display: 'flex', justifyContent: 'center', alignItems: 'flex-end',
            gap: 16, minHeight: 580,
          }}>
            <img
              src={ASSET_BASE + 'assets/android_site.png'}
              alt={s.droidAlt}
              style={{ width: 220, objectFit: 'contain', display: 'block' }}
              loading="eager"
            />
            <img
              src={ASSET_BASE + 'assets/iphone_site.png'}
              alt={s.phoneAlt}
              style={{ width: 260, objectFit: 'contain', display: 'block' }}
              loading="eager"
            />
          </div>
        ) : (
          <div style={{ display: 'flex', justifyContent: 'center', marginTop: 32 }}>
            <img
              src={ASSET_BASE + 'assets/iphone_site.png'}
              alt={s.phoneAlt}
              style={{ width: isMobile ? 200 : 280, objectFit: 'contain', display: 'block' }}
              loading="eager"
            />
          </div>
        )}
      </div>
    </section>
  );
}

// ── Modules ──────────────────────────────────────────────────────
function Modules({ T, lang }) {
  const dark = T === SITE_DARK;
  const s = (TR[lang] || TR.en).modules;
  const accents = [T.blue, T.gold, T.blue, T.blue, T.blue, T.emerald];
  const { isMobile, isTablet } = useBreakpoint();

  return (
    <section id="modules" style={{
      background: T.bg,
      padding: isMobile ? '60px 20px' : '110px 28px',
      borderTop: `1px solid ${T.hair}`,
    }}>
      <div style={{ maxWidth: 1180, margin: '0 auto' }}>
        <Eyebrow c={T.ink3} hair={T.hair}><span>{s.eyebrow}</span></Eyebrow>
        <div style={{
          display: 'flex',
          flexDirection: isTablet ? 'column' : 'row',
          justifyContent: isTablet ? 'flex-start' : 'space-between',
          alignItems: isTablet ? 'flex-start' : 'flex-end',
          marginTop: 14, gap: isTablet ? 16 : 40, flexWrap: 'wrap',
        }}>
          <h2 style={{
            fontFamily: SF_FONT,
            fontSize: isMobile ? 36 : isTablet ? 44 : 56,
            fontWeight: 600,
            letterSpacing: isMobile ? -1 : -1.6,
            lineHeight: 1.02,
            color: T.ink, margin: 0, maxWidth: 680,
          }}>
            {s.h2[0]}<br/>
            <span style={{ fontFamily: NY_SERIF, fontStyle: 'italic', fontWeight: 400, letterSpacing: -1 }}>
              {s.h2[1]}
            </span>
          </h2>
          <p style={{
            fontFamily: SF_TEXT, fontSize: 16, lineHeight: 1.55,
            color: T.ink2, maxWidth: isTablet ? '100%' : 360, margin: 0, letterSpacing: -0.1,
          }}>{s.body}</p>
        </div>

        <div style={{
          marginTop: 56,
          display: 'grid',
          gridTemplateColumns: isMobile ? '1fr' : isTablet ? 'repeat(2, 1fr)' : 'repeat(3, 1fr)',
          gap: 16,
        }}>
          {s.items.map((mod, i) => (
            <ModuleCard key={mod.name} mod={mod} T={T} dark={dark}
              accent={accents[i]} featured={i === 0} cta={s.cta}
              langRoot={lang === 'en' ? '' : `/${lang}`}/>
          ))}
        </div>
      </div>
    </section>
  );
}

function ModuleCard({ mod, T, dark, accent, featured, cta, langRoot = '' }) {
  return (
    <a href={`${langRoot}/${mod.href}`} style={{
      background: T.surface,
      borderRadius: 22, padding: 28,
      border: `1px solid ${T.hair}`,
      minHeight: 280,
      display: 'flex', flexDirection: 'column',
      position: 'relative', overflow: 'hidden',
      textDecoration: 'none',
      boxShadow: featured
        ? (dark ? 'inset 0 1px 0 rgba(255,255,255,0.04)' : '0 8px 24px rgba(15,15,16,0.05)')
        : 'none',
    }}>
      <div style={{
        position: 'absolute', top: 0, right: 0, width: 220, height: 220,
        background: `radial-gradient(closest-side, ${accent}18, transparent 70%)`,
        pointerEvents: 'none',
      }}/>

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', position: 'relative' }}>
        <div style={{
          width: 56, height: 56, borderRadius: 14,
          background: dark ? `${accent}22` : `${accent}14`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: SF_FONT, fontSize: 30, fontWeight: 400,
          color: accent, letterSpacing: 0,
        }}>{mod.glyph}</div>
        <div style={{
          padding: '4px 10px', borderRadius: 10,
          background: dark ? 'rgba(255,255,255,0.06)' : 'rgba(15,15,16,0.04)',
          fontFamily: JB_MONO, fontSize: 10, fontWeight: 700,
          color: T.ink2, letterSpacing: 0.6, textTransform: 'uppercase',
        }}>{mod.level}</div>
      </div>

      <h3 style={{
        fontFamily: SF_FONT, fontSize: 22, fontWeight: 600,
        letterSpacing: -0.4, color: T.ink,
        margin: '20px 0 0', position: 'relative',
      }}>{mod.name}</h3>

      <p style={{
        fontFamily: SF_TEXT, fontSize: 14, lineHeight: 1.5,
        color: T.ink2, margin: '8px 0 0', letterSpacing: -0.05,
        position: 'relative',
      }}>{mod.desc}</p>

      <div style={{
        marginTop: 'auto', paddingTop: 24,
        display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
        borderTop: `1px solid ${T.hair}`, position: 'relative',
      }}>
        <div>
          <div style={{
            fontFamily: SF_FONT, fontSize: 24, fontWeight: 700,
            color: T.ink, letterSpacing: -0.5, lineHeight: 1,
          }}>{mod.count}</div>
          <div style={{
            fontFamily: JB_MONO, fontSize: 9.5, fontWeight: 700,
            color: T.ink3, letterSpacing: 1, textTransform: 'uppercase', marginTop: 4,
          }}>{mod.unit}</div>
        </div>
        <span style={{
          fontFamily: SF_TEXT, fontSize: 13, fontWeight: 600,
          color: accent, letterSpacing: -0.1,
        }}>{cta}</span>
      </div>
    </a>
  );
}

// ── Approach ─────────────────────────────────────────────────────
function Approach({ T, lang }) {
  const s = (TR[lang] || TR.en).approach;
  const { isMobile, isTablet } = useBreakpoint();

  return (
    <section id="approach" style={{
      background: T.surfaceMuted,
      padding: isMobile ? '60px 20px' : '110px 28px',
      borderTop: `1px solid ${T.hair}`, borderBottom: `1px solid ${T.hair}`,
    }}>
      <div style={{ maxWidth: 1180, margin: '0 auto' }}>
        <Eyebrow c={T.ink3} hair={T.hair}><span>{s.eyebrow}</span></Eyebrow>
        <h2 style={{
          fontFamily: SF_FONT,
          fontSize: isMobile ? 36 : isTablet ? 44 : 56,
          fontWeight: 600,
          letterSpacing: isMobile ? -1 : -1.6, lineHeight: 1.02,
          color: T.ink, margin: '14px 0 0', maxWidth: 820,
        }}>
          <span style={{ fontFamily: NY_SERIF, fontStyle: 'italic', fontWeight: 400 }}>
            {s.h2}
          </span>
        </h2>
        <p style={{
          fontFamily: SF_TEXT, fontSize: isMobile ? 15 : 17, lineHeight: 1.55,
          color: T.ink2, margin: '20px 0 0', maxWidth: 620, letterSpacing: -0.1,
        }}>{s.body}</p>

        <div style={{
          marginTop: isTablet ? 40 : 64,
          display: 'grid',
          gridTemplateColumns: isTablet ? '1fr' : 'repeat(3, 1fr)',
          gap: 0,
          border: `1px solid ${T.hair}`, borderRadius: 22,
          background: T.surface, overflow: 'hidden',
        }}>
          {s.pillars.map((p, i) => (
            <div key={p.kicker} style={{
              padding: isMobile ? 24 : 36,
              borderRight: (!isTablet && i < 2) ? `1px solid ${T.hair}` : 'none',
              borderBottom: (isTablet && i < s.pillars.length - 1) ? `1px solid ${T.hair}` : 'none',
              display: 'flex', flexDirection: 'column',
            }}>
              <div style={{
                fontFamily: JB_MONO, fontSize: 11, fontWeight: 700,
                color: T.blue, letterSpacing: 1.4,
              }}>№ {p.kicker}</div>

              <h3 style={{
                fontFamily: SF_FONT,
                fontSize: isMobile ? 20 : 26,
                fontWeight: 600,
                letterSpacing: -0.6, lineHeight: 1.15,
                color: T.ink, margin: '14px 0 0',
              }}>{p.title}</h3>

              <p style={{
                fontFamily: SF_TEXT, fontSize: 14.5, lineHeight: 1.6,
                color: T.ink2, margin: '14px 0 0', letterSpacing: -0.05, flex: 1,
              }}>{p.body}</p>

              <div style={{
                marginTop: 28, paddingTop: 20,
                borderTop: `1px solid ${T.hair}`,
                display: 'flex', alignItems: 'baseline', gap: 12,
              }}>
                <div style={{
                  fontFamily: SF_FONT, fontSize: 36, fontWeight: 700,
                  letterSpacing: -1, color: T.ink, lineHeight: 1,
                }}>{p.stat}</div>
                <div style={{
                  fontFamily: JB_MONO, fontSize: 9.5, fontWeight: 700,
                  color: T.ink3, letterSpacing: 1, textTransform: 'uppercase',
                }}>{p.unit}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ── Mastery table ─────────────────────────────────────────────────
function MasteryTable({ T, lang }) {
  const s = (TR[lang] || TR.en).mastery;
  const { isMobile, isTablet } = useBreakpoint();

  return (
    <section id="precision" style={{
      background: T.bg,
      padding: isMobile ? '60px 20px' : '110px 28px',
    }}>
      <div style={{ maxWidth: 1180, margin: '0 auto' }}>
        <Eyebrow c={T.ink3} hair={T.hair}><span>{s.eyebrow}</span></Eyebrow>
        <h2 style={{
          fontFamily: SF_FONT,
          fontSize: isMobile ? 36 : isTablet ? 44 : 56,
          fontWeight: 600,
          letterSpacing: isMobile ? -1 : -1.6, lineHeight: 1.02,
          color: T.ink, margin: '14px 0 0', maxWidth: 800,
        }}>
          {s.h2[0]}<br/>
          <span style={{ fontFamily: NY_SERIF, fontStyle: 'italic', fontWeight: 400 }}>
            {s.h2[1]}
          </span>
        </h2>

        <div style={{
          marginTop: 56,
          display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0,
          border: `1px solid ${T.hair}`, borderRadius: 22,
          background: T.surface, overflow: 'hidden',
        }}>
          <div style={{
            padding: isMobile ? '16px 18px' : '20px 28px',
            borderBottom: `1px solid ${T.hair}`,
            borderRight: `1px solid ${T.hair}`,
            display: 'flex', alignItems: 'center', gap: 10,
            background: T === SITE_DARK ? 'rgba(34,195,122,0.06)' : 'rgba(34,195,122,0.04)',
          }}>
            <div style={{ width: 8, height: 8, borderRadius: 4, background: T.emerald, flexShrink: 0 }}/>
            <div style={{ fontFamily: JB_MONO, fontSize: isMobile ? 10 : 11, fontWeight: 700, color: T.emerald, letterSpacing: 1.4, textTransform: 'uppercase' }}>{s.shown}</div>
          </div>
          <div style={{
            padding: isMobile ? '16px 18px' : '20px 28px',
            borderBottom: `1px solid ${T.hair}`,
            display: 'flex', alignItems: 'center', gap: 10,
            background: T === SITE_DARK ? 'rgba(229,80,80,0.04)' : 'rgba(194,67,67,0.03)',
          }}>
            <div style={{ width: 8, height: 8, borderRadius: 4, background: T.red, flexShrink: 0 }}/>
            <div style={{ fontFamily: JB_MONO, fontSize: isMobile ? 10 : 11, fontWeight: 700, color: T.red, letterSpacing: 1.4, textTransform: 'uppercase' }}>{s.hidden}</div>
          </div>

          {s.rows.map(([show, showSub, hide], i) => (
            <React.Fragment key={i}>
              <div style={{
                padding: isMobile ? '16px 18px' : '22px 28px',
                borderBottom: i < s.rows.length - 1 ? `1px solid ${T.hair}` : 'none',
                borderRight: `1px solid ${T.hair}`,
              }}>
                <div style={{ fontFamily: SF_FONT, fontSize: isMobile ? 14 : 17, fontWeight: 600, color: T.ink, letterSpacing: -0.2 }}>{show}</div>
                <div style={{ fontFamily: NY_SERIF, fontStyle: 'italic', fontSize: isMobile ? 11 : 13, color: T.ink3, marginTop: 4 }}>{showSub}</div>
              </div>
              <div style={{
                padding: isMobile ? '16px 18px' : '22px 28px',
                borderBottom: i < s.rows.length - 1 ? `1px solid ${T.hair}` : 'none',
                display: 'flex', alignItems: 'center',
              }}>
                <div style={{
                  fontFamily: SF_FONT, fontSize: isMobile ? 13 : 16, fontWeight: 500,
                  color: T.ink3, letterSpacing: -0.2,
                  textDecoration: 'line-through', textDecorationColor: T.ink4,
                }}>{hide}</div>
              </div>
            </React.Fragment>
          ))}
        </div>
      </div>
    </section>
  );
}

// ── Download CTA ──────────────────────────────────────────────────
function Download({ T, lang }) {
  const dark = T === SITE_DARK;
  const s = (TR[lang] || TR.en).download;
  const { isMobile } = useBreakpoint();

  return (
    <section id="download" style={{
      background: T.bgGrad,
      padding: isMobile ? '60px 20px 80px' : '110px 28px 120px',
      borderTop: `1px solid ${T.hair}`,
      position: 'relative', overflow: 'hidden',
    }}>
      <div style={{
        position: 'absolute', left: '50%', top: '50%',
        transform: 'translate(-50%, -50%)',
        width: 720, height: 720, borderRadius: '50%',
        background: dark
          ? 'radial-gradient(closest-side, rgba(232,168,74,0.10), transparent 70%)'
          : 'radial-gradient(closest-side, rgba(232,168,74,0.18), transparent 70%)',
        pointerEvents: 'none',
      }}/>
      <div style={{
        position: 'absolute', left: '50%', top: '50%',
        transform: 'translate(-50%, -50%)',
        width: 380, height: 380, borderRadius: '50%',
        border: `1px solid ${T.hair}`,
        pointerEvents: 'none',
      }}/>

      <div style={{ position: 'relative', zIndex: 2, maxWidth: 720, margin: '0 auto', textAlign: 'center' }}>
        <img src={ASSET_BASE + 'assets/mascot.png'} alt="" style={{
          width: isMobile ? 120 : 200,
          height: isMobile ? 120 : 200,
          objectFit: 'contain', objectPosition: 'center top',
          filter: dark
            ? 'drop-shadow(0 12px 24px rgba(0,0,0,0.5))'
            : 'drop-shadow(0 12px 24px rgba(15,15,16,0.18))',
        }}/>

        <h2 style={{
          fontFamily: SF_FONT,
          fontSize: isMobile ? 40 : 64,
          fontWeight: 600,
          letterSpacing: isMobile ? -1.2 : -2, lineHeight: 1,
          color: T.ink, margin: '32px 0 0',
        }}>
          {s.h2[0]}<br/>
          <span style={{ fontFamily: NY_SERIF, fontStyle: 'italic', fontWeight: 400, letterSpacing: isMobile ? -0.8 : -1.4 }}>
            {s.h2[1]}
          </span>
        </h2>

        <div style={{ width: 40, height: 2, background: T.blue, borderRadius: 1, margin: '28px auto' }}/>

        <p style={{
          fontFamily: SF_TEXT, fontSize: isMobile ? 15 : 17, lineHeight: 1.55,
          color: T.ink2, maxWidth: 480, margin: '0 auto', letterSpacing: -0.1,
        }}>{s.body}</p>

        <div style={{ marginTop: 36, display: 'flex', gap: 14, justifyContent: 'center', flexWrap: 'wrap' }}>
          <StoreBadge platform="ios" lang={lang}/>
          <StoreBadge platform="android" lang={lang}/>
        </div>

      </div>
    </section>
  );
}

// ── Footer ────────────────────────────────────────────────────────
function Footer({ T, lang }) {
  const s = (TR[lang] || TR.en).footer;
  const langRoot = lang === 'en' ? '' : `/${lang}`;
  return (
    <footer style={{
      background: T.bg, color: T.ink2,
      padding: '40px 28px 60px',
      borderTop: `1px solid ${T.hair}`,
    }}>
      <div style={{
        maxWidth: 1180, margin: '0 auto',
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        flexWrap: 'wrap', gap: 20,
      }}>
        <a href={`${langRoot}/`} style={{ display: 'flex', alignItems: 'center', gap: 12, textDecoration: 'none' }}>
          <span style={{
            width: 28, height: 28, borderRadius: 7,
            overflow: 'hidden', border: `1px solid ${T.hair}`,
            background: T.surface,
            flexShrink: 0,
          }}>
            <img src={ASSET_BASE + 'assets/AppIcon128x128.png'} alt="" style={{ width: '100%', height: '100%', objectFit: 'contain' }}/>
          </span>
          <Wordmark size={16} color={T.ink} gold={T.gold}/>
        </a>

        <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap', fontFamily: SF_TEXT, fontSize: 13, fontWeight: 500 }}>
          <a href={`${langRoot}/privacy/`} style={{ color: T.ink3, textDecoration: 'none' }}>{s.privacy}</a>
          <a href={`${langRoot}/terms/`} style={{ color: T.ink3, textDecoration: 'none' }}>{s.terms}</a>
          <a href={`${langRoot}/about/`} style={{ color: T.ink3, textDecoration: 'none' }}>{s.about}</a>
          <a href={`mailto:support@petitberet.app`} style={{ color: T.ink3, textDecoration: 'none' }}>{s.contact}</a>
        </div>

        <div style={{
          fontFamily: JB_MONO, fontSize: 10, fontWeight: 700,
          color: T.ink3, letterSpacing: 1.4, textTransform: 'uppercase',
        }}>{s.copy}</div>
      </div>
    </footer>
  );
}

// ── Site (homepage) ───────────────────────────────────────────────
function Site() {
  const savedLang = (() => { try { return localStorage.getItem('pb_lang'); } catch(e) { return null; } })();
  const [lang, setLang] = React.useState(window.__PB_LANG || (['en','fr','ru'].includes(savedLang) ? savedLang : 'en'));
  const savedTheme = (() => { try { return localStorage.getItem('pb_theme'); } catch(e) { return null; } })();
  const [theme, setTheme] = React.useState(savedTheme === 'light' ? 'light' : 'dark');
  const T = theme === 'light' ? SITE_LIGHT : SITE_DARK;

  React.useEffect(() => {
    document.body.style.background = T.bg;
  }, [T.bg]);

  return (
    <div style={{ background: T.bg, color: T.ink, minHeight: '100vh', fontFamily: SF_FONT }}>
      <Nav T={T} lang={lang} setLang={setLang} isRoot={true} theme={theme} setTheme={setTheme}/>
      <Hero T={T} lang={lang}/>
      <Modules T={T} lang={lang}/>
      <Approach T={T} lang={lang}/>
      <MasteryTable T={T} lang={lang}/>
      <Download T={T} lang={lang}/>
      <Footer T={T} lang={lang} isRoot={true}/>
    </div>
  );
}

// ── Exports for subpages ──────────────────────────────────────────
window.Site          = Site;
window.Nav           = Nav;
window.ThemeToggle   = ThemeToggle;
window.Footer        = Footer;
window.Wordmark      = Wordmark;
window.Eyebrow       = Eyebrow;
window.StoreBadge    = StoreBadge;
window.useBreakpoint = useBreakpoint;
window.SITE_DARK     = SITE_DARK;
window.SITE_LIGHT    = SITE_LIGHT;
window.TR            = TR;
window.SF_FONT       = SF_FONT;
window.SF_TEXT       = SF_TEXT;
window.NY_SERIF      = NY_SERIF;
window.JB_MONO       = JB_MONO;
window.STORE_LINKS   = STORE_LINKS;
window.BADGE_PATHS   = BADGE_PATHS;
window.ASSET_BASE    = ASSET_BASE;
