// engine.jsx — PatentEngine: global competitions engine inside the IBTIKAR platform (bilingual AR/EN).
// Additive module: it consumes only shared primitives (Icon, Modal, Reveal, Head, useToast, Field).

const ENG_KEY = 'ibtikar_engine_v1';
const ENG_AUTO_HOUR = 8; // تحديث يومي تلقائي 8:00 صباحاً

function engRead() { try { return JSON.parse(localStorage.getItem(ENG_KEY) || '{}') || {}; } catch (e) { return {}; } }
function engWrite(next) { try { localStorage.setItem(ENG_KEY, JSON.stringify(next)); } catch (e) {} }
function useEngineStore() {
  const [state, setState] = React.useState(() => {
    const s = engRead();
    return { favs: s.favs || [], account: s.account || null, reports: s.reports || [], found: s.found || [], lastRun: s.lastRun || null, runs: s.runs || 0, lastAuto: s.lastAuto || null, autoAdded: s.autoAdded || 0 };
  });
  const save = React.useCallback((patch) => setState((s) => { const n = { ...s, ...patch }; engWrite(n); return n; }), []);
  return [state, save];
}

const EIcon = {
  search:  (p) => <Svg {...p}><circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" /></Svg>,
  star:    (p) => <Svg {...p}><path d="m12 3.6 2.6 5.5 6 .8-4.4 4.2 1.1 6-5.3-2.9-5.3 2.9 1.1-6L3.4 9.9l6-.8L12 3.6Z" /></Svg>,
  cal:     (p) => <Svg {...p}><rect x="3" y="5" width="18" height="16" rx="2" /><path d="M3 10h18M8 3v4M16 3v4" /></Svg>,
  bell:    (p) => <Svg {...p}><path d="M6 10a6 6 0 0 1 12 0c0 4 1.5 5 1.5 5h-15S6 14 6 10Z" /><path d="M10 19a2 2 0 0 0 4 0" /></Svg>,
  radar:   (p) => <Svg {...p}><circle cx="12" cy="12" r="9" /><circle cx="12" cy="12" r="4.5" opacity=".6" /><path d="M12 12 19 7" /><circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none" /></Svg>,
  link:    (p) => <Svg {...p}><path d="M10 14a4 4 0 0 1 0-5.6l2.4-2.4a4 4 0 0 1 5.6 5.6L16.6 13" /><path d="M14 10a4 4 0 0 1 0 5.6l-2.4 2.4a4 4 0 0 1-5.6-5.6L7.4 11" /></Svg>,
  coin:    (p) => <Svg {...p}><ellipse cx="12" cy="7" rx="7" ry="3.2" /><path d="M5 7v5c0 1.8 3.1 3.2 7 3.2s7-1.4 7-3.2V7" /><path d="M5 12v5c0 1.8 3.1 3.2 7 3.2s7-1.4 7-3.2v-5" /></Svg>,
  filter:  (p) => <Svg {...p}><path d="M4 5h16l-6 7v6l-4 2v-8L4 5Z" /></Svg>,
  trophy:  (p) => <Svg {...p}><path d="M8 4h8v5a4 4 0 0 1-8 0V4Z" /><path d="M8 5H5.5a2.5 2.5 0 0 0 2.5 4M16 5h2.5a2.5 2.5 0 0 1-2.5 4" /><path d="M12 13v3M9 20h6M10.5 16h3l.5 4h-4l.5-4Z" /></Svg>,
  steth:   (p) => <Svg {...p}><path d="M6 3v5a4 4 0 0 0 8 0V3" /><path d="M10 12v3a4 4 0 0 0 8 0v-2" /><circle cx="18" cy="11" r="2" /><path d="M6 3H4M14 3h2" /></Svg>,
  code:    (p) => <Svg {...p}><path d="m8 8-4 4 4 4M16 8l4 4-4 4M14 5l-4 14" /></Svg>,
  gauge:   (p) => <Svg {...p}><path d="M4 18a8 8 0 1 1 16 0" /><path d="M12 14l4-4" /><circle cx="12" cy="18" r="1.5" fill="currentColor" stroke="none" /></Svg>,
};

// ---------- bilingual strings ----------
const E = {
  eyebrow:    { ar: 'محرك PatentEngine · ibtikar.health', en: 'PatentEngine · ibtikar.health' },
  daily:      { ar: 'تحديث يومي تلقائي الساعة 8:00 صباحاً', en: 'Automatic daily update at 8:00 AM' },
  countries:  { ar: 'مصادر من 40+ دولة', en: 'Sources from 40+ countries' },
  h1a:        { ar: 'ابتكارك يستحق', en: 'Your innovation deserves' },
  h1b:        { ar: 'منصة عالمية واحدة', en: 'one global platform' },
  lede:       { ar: 'تجمع لك كل المسابقات العالمية للابتكار والاختراعات في الطب والذكاء الاصطناعي وكل المجالات، لكل الأعمار، محدّثة يومياً بواسطة محرك PatentEngine الذي يبحث في عشرات المصادر.', en: 'brings you every global competition for innovation and inventions in medicine, artificial intelligence and every other field, for all ages, updated daily by the PatentEngine that searches dozens of sources.' },
  cta_news:   { ar: 'استكشف الأخبار والمنح', en: 'Explore news & grants' },
  cta_acc:    { ar: 'أنشئ حسابك', en: 'Create your account' },
  cta_acc2:   { ar: 'حسابك ومتابعاتك', en: 'Your account & alerts' },
  cta_report: { ar: 'أبلغ عن هاكاثون', en: 'Report a hackathon' },
  acc_short:  { ar: 'أنشئ حساب', en: 'Sign up' },
  st_total:   { ar: 'إجمالي المسابقات', en: 'Total competitions' },
  st_med:     { ar: 'مسابقات طبية', en: 'Medical competitions' },
  st_hack:    { ar: 'هاكاثونات', en: 'Hackathons' },
  st_ai:      { ar: 'ذكاء اصطناعي', en: 'Artificial intelligence' },
  queries:    { ar: 'استعلام مفعّل', en: 'active queries' },
  eng_state:  { ar: 'حالة المحرك', en: 'Engine status' },
  last_run:   { ar: 'آخر تشغيل', en: 'Last run' },
  sched:      { ar: 'الفحص المجدول اليومي 8:00 صباحاً', en: 'Scheduled daily scan at 8:00 AM' },
  manual:     { ar: 'تشغيل يدوي', en: 'manual runs' },
  run_now:    { ar: 'شغّل المحرك الآن', en: 'Run the engine now' },
  running:    { ar: 'جارٍ الفحص…', en: 'Scanning…' },
  run_short:  { ar: 'تشغيل المحرك', en: 'Run engine' },
  note:       { ar: 'الفهرس الظاهر هنا نسخة المنصة الداخلية: يُحدَّث تلقائياً كل يوم 8:00 صباحاً من مصادر المحرك ويُستكمل بما يصل من تقارير المستخدمين. الروابط تُحوِّلك إلى الجهة المنظِّمة للتقديم الرسمي.', en: 'The index shown here is the platform’s internal copy: refreshed automatically every day at 8:00 AM from the engine sources and completed by user reports. Links take you to the organiser for official entry.' },
  auto_done:  { ar: 'التحديث اليومي التلقائي أضاف {n} مسابقة جديدة', en: 'The daily automatic update added {n} new competitions' },
  results:    { ar: '{n} نتيجة من {t} في الفهرس', en: '{n} results of {t} in the index' },
  mine_n:     { ar: 'متابعاتك: {n} مسابقة', en: 'Your alerts: {n} competitions' },
  hack_n:     { ar: '{n} هاكاثون وداتاثون', en: '{n} hackathons & datathons' },
  search_ph:  { ar: 'ابحث باسم المسابقة أو الجهة أو الدولة…', en: 'Search by competition, organiser or country…' },
  all_fields: { ar: 'كل المجالات', en: 'All fields' },
  all_ages:   { ar: 'كل الأعمار', en: 'All ages' },
  age_n:      { ar: 'عمر {n} سنة', en: 'Age {n}' },
  s_deadline: { ar: 'الأقرب موعداً', en: 'Closing soonest' },
  s_prize:    { ar: 'الأعلى جوائز', en: 'Biggest prizes' },
  s_feat:     { ar: 'المميزة أولاً', en: 'Featured first' },
  f_open:     { ar: 'مفتوحة', en: 'Open' },
  f_up:       { ar: 'قادمة', en: 'Upcoming' },
  f_closed:   { ar: 'مغلقة', en: 'Closed' },
  f_all:      { ar: 'الكل', en: 'All' },
  f_hack:     { ar: 'هاكاثون', en: 'Hackathon' },
  f_smart:    { ar: 'مدن ذكية', en: 'Smart cities' },
  f_women:    { ar: 'نسائية', en: 'Women' },
  f_feat:     { ar: 'مميزة', en: 'Featured' },
  f_fav:      { ar: 'متابعاتي', en: 'My alerts' },
  details:    { ar: 'التفاصيل', en: 'Details' },
  official:   { ar: 'الموقع الرسمي', en: 'Official site' },
  days_left:  { ar: 'يتبقى {n} يوم', en: '{n} days left' },
  featured:   { ar: 'مميزة', en: 'Featured' },
  fresh:      { ar: 'جديد من المحرك', en: 'New from engine' },
  follow:     { ar: 'تابع هذه المسابقة', en: 'Follow this competition' },
  unfollow:   { ar: 'إلغاء المتابعة', en: 'Unfollow' },
  apply:      { ar: 'التقديم على الموقع الرسمي', en: 'Apply on the official site' },
  reg_first:  { ar: 'سجّل فكرتك أولاً', en: 'Register your idea first' },
  r_org:      { ar: 'الجهة المنظِّمة', en: 'Organiser' },
  r_country:  { ar: 'الدولة', en: 'Country' },
  r_field:    { ar: 'المجال', en: 'Field' },
  r_close:    { ar: 'موعد الإغلاق', en: 'Closing date' },
  r_open:     { ar: 'فتح التسجيل', en: 'Registration opens' },
  r_prize:    { ar: 'الجوائز', en: 'Prizes' },
  r_age:      { ar: 'الفئة العمرية', en: 'Age range' },
  r_dur:      { ar: 'المدة', en: 'Duration' },
  r_src:      { ar: 'المصدر', en: 'Source' },
  open_now:   { ar: 'مفتوح', en: 'Open' },
  unannounced:{ ar: 'غير معلنة', en: 'Not announced' },
  week_plus:  { ar: 'أسبوع أو أكثر', en: 'A week or more' },
  hours_n:    { ar: '{n} ساعة', en: '{n} hours' },
  years:      { ar: 'سنة', en: 'years' },
  any:        { ar: 'أي', en: 'any' },
  cal_eyebrow:{ ar: 'مواعيد الإغلاق', en: 'Closing dates' },
  cal_title:  { ar: 'تقويم التقديم عبر الأشهر', en: 'Submission calendar by month' },
  cal_count:  { ar: '{n} موعد', en: '{n} deadlines' },
  news_eyebrow:{ ar: 'محدّث يومياً', en: 'Updated daily' },
  news_title: { ar: 'الأخبار والمنح والجوائز', en: 'News, grants & awards' },
  n_all:      { ar: 'الكل', en: 'All' },
  n_news:     { ar: 'أخبار', en: 'News' },
  n_grant:    { ar: 'منح', en: 'Grants' },
  n_award:    { ar: 'جوائز', en: 'Awards' },
  n_update:   { ar: 'تحديثات', en: 'Updates' },
  source:     { ar: 'المصدر', en: 'Source' },
  src_eyebrow:{ ar: 'شفافية المحرك', en: 'Engine transparency' },
  src_title:  { ar: 'المصادر والاستعلامات المفعّلة', en: 'Active sources & queries' },
  src_last:   { ar: 'آخر فحص', en: 'Last scan' },
  src_found:  { ar: '{n} نتيجة', en: '{n} results' },
  src_note:   { ar: 'يصنّف المحرك كل نتيجة تلقائياً (طب / ذكاء اصطناعي / هاكاثون / مدن ذكية / نسائي)، ويستخرج الفئة العمرية والمدة وموعد الإغلاق، ويمنع التكرار عبر مطابقة الرابط والعنوان.', en: 'The engine classifies each result automatically (medical / AI / hackathon / smart cities / women), extracts the age range, duration and closing date, and blocks duplicates by matching URL and title.' },
  an_eyebrow: { ar: 'قراءة الفهرس', en: 'Reading the index' },
  an_title:   { ar: 'تحليلات المحرك', en: 'Engine analytics' },
  an_open:    { ar: 'مفتوحة الآن', en: 'Open now' },
  an_up:      { ar: 'قادمة', en: 'Upcoming' },
  an_closed:  { ar: 'مغلقة', en: 'Closed' },
  an_prizes:  { ar: 'إجمالي الجوائز المعلنة', en: 'Total announced prizes' },
  an_byfield: { ar: 'التوزيع حسب المجال', en: 'Distribution by field' },
  an_bycountry:{ ar: 'أكثر الدول حضوراً', en: 'Most represented countries' },
  an_density: { ar: 'كثافة مواعيد الإغلاق', en: 'Deadline density' },
  ad_eyebrow: { ar: 'تشغيل المحرك', en: 'Engine operations' },
  ad_title:   { ar: 'لوحة تحكم المحرك', en: 'Engine control panel' },
  ad_pending: { ar: 'تقارير بانتظار المراجعة', en: 'Reports awaiting review' },
  ad_added:   { ar: 'مضافة من المحرك', en: 'Added by the engine' },
  ad_favs:    { ar: 'متابعاتك', en: 'Your alerts' },
  ad_inbox:   { ar: 'التقارير الواردة', en: 'Incoming reports' },
  ad_inbox_d: { ar: 'ما يرسله المستخدمون عبر «أبلغ عن هاكاثون» — راجعه ثم انشره في الفهرس.', en: 'What users send through “Report a hackathon” — review it, then publish to the index.' },
  ad_identify:{ ar: 'سجّل هويتك أولاً', en: 'Identify yourself first' },
  ad_publish: { ar: 'نشر', en: 'Publish' },
  ad_delete:  { ar: 'حذف', en: 'Delete' },
  ad_empty:   { ar: 'لا تقارير بانتظار المراجعة حالياً.', en: 'No reports awaiting review right now.' },
  ad_sched:   { ar: 'جدول التشغيل', en: 'Run schedule' },
  ad_auto:    { ar: 'الفحص اليومي التلقائي', en: 'Automatic daily scan' },
  ad_auto_v:  { ar: '8:00 صباحاً بتوقيت الرياض', en: '8:00 AM Riyadh time' },
  ad_q:       { ar: 'عدد الاستعلامات', en: 'Queries' },
  ad_q_v:     { ar: '{n} استعلام على {n} مصدر', en: '{n} queries across {n} sources' },
  ad_last:    { ar: 'آخر تشغيل يدوي', en: 'Last manual run' },
  ad_never:   { ar: 'لم يُشغّل بعد', en: 'Not run yet' },
  ad_dedupe:  { ar: 'منع التكرار', en: 'Duplicate control' },
  ad_dedupe_v:{ ar: 'مطابقة الرابط + العنوان + الجهة', en: 'URL + title + organiser matching' },
  ac_eyebrow: { ar: 'حساب المحرك', en: 'Engine account' },
  ac_title:   { ar: 'أنشئ حسابك', en: 'Create your account' },
  ac_title2:  { ar: 'حسابك ومتابعاتك', en: 'Your account & alerts' },
  ac_desc:    { ar: 'حدّد مجالاتك ليُنبّهك المحرك عند ظهور مسابقة مطابقة أو قبل إغلاق التقديم. البيانات محفوظة في متصفحك فقط.', en: 'Pick your fields and the engine will alert you when a matching competition appears or before entry closes. Data stays in your browser only.' },
  ac_name:    { ar: 'الاسم', en: 'Full name' },
  ac_email:   { ar: 'البريد الإلكتروني', en: 'Email' },
  ac_ints:    { ar: 'مجالات التنبيه', en: 'Alert topics' },
  ac_member:  { ar: 'عضو منذ {d} · {f} متابعة · {r} تقرير مُرسل', en: 'Member since {d} · {f} alerts · {r} reports sent' },
  ac_save:    { ar: 'حفظ التنبيهات', en: 'Save alerts' },
  ac_create:  { ar: 'إنشاء الحساب', en: 'Create account' },
  close:      { ar: 'إغلاق', en: 'Close' },
  cancel:     { ar: 'إلغاء', en: 'Cancel' },
  rp_eyebrow: { ar: 'ساهم في الفهرس', en: 'Contribute to the index' },
  rp_title:   { ar: 'أبلغ عن هاكاثون أو مسابقة', en: 'Report a hackathon or competition' },
  rp_desc:    { ar: 'تعرف فعالية لم تظهر في الفهرس؟ أرسل رابطها وسيفحصها المحرك ويصنّفها تلقائياً.', en: 'Know an event missing from the index? Send its link and the engine will scan and classify it automatically.' },
  rp_name:    { ar: 'اسم الفعالية', en: 'Event name' },
  rp_name_ph: { ar: 'مثال: هاكاثون الصحة الرقمية 2027', en: 'e.g. Digital Health Hackathon 2027' },
  rp_org:     { ar: 'الجهة المنظِّمة', en: 'Organiser' },
  rp_url:     { ar: 'رابط الفعالية', en: 'Event link' },
  rp_close:   { ar: 'موعد الإغلاق', en: 'Closing date' },
  rp_note:    { ar: 'ملاحظة', en: 'Note' },
  rp_note_ph: { ar: 'الجوائز، الفئة العمرية، شروط المشاركة…', en: 'Prizes, age range, eligibility…' },
  rp_send:    { ar: 'إرسال للمحرك', en: 'Send to the engine' },
  bridge_eye: { ar: 'من الفهرس إلى التقديم', en: 'From index to entry' },
  bridge_t:   { ar: 'وجدت مسابقة تناسب فكرتك؟', en: 'Found a competition that fits your idea?' },
  bridge_d:   { ar: 'سجّل الفكرة داخل المنصة أولاً لتأخذ بصمتها وتاريخها الموثّق، ثم قدّمها للجهة المنظِّمة من رابطها الرسمي.', en: 'Register the idea inside the platform first to capture its fingerprint and verified date, then submit it to the organiser through their official link.' },
  bridge_c1:  { ar: 'قدّم فكرتك داخل المنصة', en: 'Submit your idea in-platform' },
  bridge_c2:  { ar: 'أكاديمية المبتكرين', en: 'Innovators Academy' },
  empty_t:    { ar: 'لا نتائج بهذه الفلاتر', en: 'No results for these filters' },
  empty_d:    { ar: 'وسّع نطاق البحث أو أبلغ المحرك عن مسابقة تعرفها ولم تظهر بعد.', en: 'Widen the search, or tell the engine about a competition it has not indexed yet.' },
  empty_cta:  { ar: 'أبلغ عن مسابقة أو هاكاثون', en: 'Report a competition or hackathon' },
  mine_empty_t:{ ar: 'لم تتابع أي مسابقة بعد', en: 'You are not following any competition yet' },
  mine_empty_d:{ ar: 'اضغط النجمة على أي مسابقة لمتابعتها، وسيصلك تنبيه قبل إغلاق التقديم.', en: 'Tap the star on any competition to follow it and get an alert before entry closes.' },
  t_added:    { ar: 'أُضيفت إلى متابعتك · ستُنبَّه قبل الإغلاق', en: 'Added to your alerts · you’ll be notified before closing' },
  t_removed:  { ar: 'أُزيلت من متابعتك', en: 'Removed from your alerts' },
  t_run_new:  { ar: 'اكتمل الفحص · {n} مسابقة جديدة أُضيفت للفهرس', en: 'Scan complete · {n} new competitions added' },
  t_run_none: { ar: 'اكتمل الفحص · لا جديد منذ التشغيل الأخير', en: 'Scan complete · nothing new since the last run' },
  t_acc_new:  { ar: 'أُنشئ حسابك · ستصلك تنبيهات المسابقات المطابقة', en: 'Account created · you’ll receive matching competition alerts' },
  t_acc_upd:  { ar: 'حُدِّثت تنبيهاتك', en: 'Your alerts were updated' },
  t_report:   { ar: 'وصل تقريرك · سيراجعه المحرك قبل إضافته للفهرس', en: 'Report received · the engine will review it before indexing' },
  t_pub:      { ar: 'نُشرت في الفهرس ✓', en: 'Published to the index ✓' },
  t_del:      { ar: 'حُذف التقرير', en: 'Report deleted' },
  scanning:   { ar: 'فحص يومي لعشرات المصادر', en: 'Daily scan across dozens of sources' },
};
const engFmt = (s, vals) => Object.keys(vals || {}).reduce((acc, k) => acc.split('{' + k + '}').join(vals[k]), s);

const ENG_TABS = [['comps', { ar: 'المسابقات', en: 'Competitions' }, 'globe'], ['news', { ar: 'أخبار ومنح', en: 'News & grants' }, 'spark'], ['hack', { ar: 'هاكاثونات', en: 'Hackathons' }, 'code'], ['cal', { ar: 'التقويم', en: 'Calendar' }, 'cal'], ['analytics', { ar: 'التحليلات', en: 'Analytics' }, 'chart'], ['mine', { ar: 'متابعاتي', en: 'My alerts' }, 'star'], ['src', { ar: 'المصادر', en: 'Sources' }, 'layers'], ['admin', { ar: 'لوحة التحكم', en: 'Control panel' }, 'shield']];
const ENG_QUICK = [['all', { ar: 'الكل', en: 'All' }, 'bulb'], ['طب', { ar: 'طب وصحة', en: 'Medical & health' }, 'steth'], ['ذكاء اصطناعي', { ar: 'ذكاء اصطناعي', en: 'AI' }, 'cpu'], ['طب + ذكاء اصطناعي', { ar: 'طب + AI', en: 'Medical + AI' }, 'flask'], ['هاكاثون', { ar: 'هاكاثون', en: 'Hackathon' }, 'code'], ['مدن ذكية', { ar: 'مدن ذكية', en: 'Smart cities' }, 'layers'], ['هاكاثون نسائي', { ar: 'نسائي', en: 'Women' }, 'users'], ['ابتكار', { ar: 'ابتكار عام', en: 'General innovation' }, 'spark'], ['اختراعات', { ar: 'اختراعات', en: 'Inventions' }, 'award']];

const ENG_NOW = () => new Date();
function engStatus(c) {
  const now = ENG_NOW();
  if (c.opens && now < new Date(c.opens)) return 'upcoming';
  if (c.deadline && now > new Date(c.deadline + 'T23:59:59')) return 'closed';
  return 'open';
}
function engDaysLeft(c) { return c.deadline ? Math.ceil((new Date(c.deadline + 'T23:59:59') - ENG_NOW()) / 86400000) : null; }
const ENG_STATUS_META = {
  open:     { ar: 'مفتوح الآن', en: 'Open now', cls: 'mint' },
  upcoming: { ar: 'قادم', en: 'Upcoming', cls: 'gold' },
  closed:   { ar: 'مغلق', en: 'Closed', cls: 'rose' },
};
const ENG_MONTHS = { ar: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'], en: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] };
function engDate(iso, lang) {
  if (!iso) return '—';
  const d = new Date(iso), ms = ENG_MONTHS[lang === 'en' ? 'en' : 'ar'];
  return lang === 'en' ? `${d.getDate()} ${ms[d.getMonth()]} ${d.getFullYear()}` : `${d.getDate()} ${ms[d.getMonth()]} ${d.getFullYear()}`;
}
const ENG_NEWS_META = {
  news:   { ar: 'خبر', en: 'News', cls: 'mint' },
  grant:  { ar: 'منحة', en: 'Grant', cls: 'purple' },
  award:  { ar: 'جائزة', en: 'Award', cls: 'gold' },
  update: { ar: 'تحديث', en: 'Update', cls: 'mint' },
};
// per-item localisation helpers
const engTitle = (c, lang) => (lang === 'en' && c.en ? c.en : c.title);
const engSubtitle = (c, lang) => (lang === 'en' ? (c.en ? c.title : '') : (c.en || ''));
const engDesc = (c, lang) => (lang === 'en' ? (ENG_DESC_EN[c.id] || c.desc) : c.desc);
const engField = (f, lang) => (lang === 'en' ? (ENG_FIELD_EN[f] || f) : f);
const engPlace = (v, lang) => (lang === 'en' ? (ENG_COUNTRY_EN[v] || v) : v);
function engPrizeNum(c) { return c.prize ? parseInt(String(c.prize).replace(/[^\d]/g, ''), 10) || 0 : 0; }

// ---------- page ----------
function EnginePage({ go, t, L, lang }) {
  const [st, save] = useEngineStore();
  const toast = useToast();
  const [tab, setTab] = React.useState('comps');
  const [q, setQ] = React.useState('');
  const [field, setField] = React.useState('all');
  const [status, setStatus] = React.useState('open');
  const [flags, setFlags] = React.useState({ hack: false, women: false, smart: false, featured: false, fav: false });
  const [age, setAge] = React.useState('all');
  const [sort, setSort] = React.useState('deadline');
  const [detail, setDetail] = React.useState(null);
  const [modal, setModal] = React.useState(null);
  const [run, setRun] = React.useState(null);
  const [autoMsg, setAutoMsg] = React.useState(0);
  const newsRef = React.useRef(null);
  const runLock = React.useRef(false);

  const all = React.useMemo(() => [...ENG_COMPS, ...st.found.map((f) => ({ ...f, fresh: true }))], [st.found]);

  // ── التحديث اليومي التلقائي 8:00 صباحاً (Gemini + بحث Google) ──
  React.useEffect(() => {
    const sweep = () => {
      const now = ENG_NOW();
      const today = now.toISOString().slice(0, 10);
      if (now.getHours() < ENG_AUTO_HOUR) return;
      const s = engRead();
      if (s.lastAuto === today) return;
      engWrite({ ...s, lastAuto: today });
      runAll('auto');
    };
    sweep();
    const iv = setInterval(sweep, 10 * 60 * 1000);
    return () => clearInterval(iv);
  }, []);

  const list = React.useMemo(() => {
    const needle = q.trim().toLowerCase();
    let out = all.filter((c) => {
      if (needle) {
        const hay = `${c.title} ${c.en || ''} ${c.org} ${c.country} ${c.field} ${c.desc} ${ENG_DESC_EN[c.id] || ''}`.toLowerCase();
        if (!hay.includes(needle)) return false;
      }
      if (field !== 'all' && c.field !== field) return false;
      if (status !== 'all' && engStatus(c) !== status) return false;
      if (flags.hack && !c.hack) return false;
      if (flags.women && !c.women) return false;
      if (flags.smart && !c.smart) return false;
      if (flags.featured && !c.featured) return false;
      if (flags.fav && !st.favs.includes(c.id)) return false;
      if (age !== 'all') {
        const a = parseInt(age, 10);
        const lo = c.ageMin == null ? 0 : c.ageMin, hi = c.ageMax == null ? 99 : c.ageMax;
        if (a < lo || a > hi) return false;
      }
      return true;
    });
    out.sort((a, b) => {
      if (sort === 'deadline') return (a.deadline || '9999') < (b.deadline || '9999') ? -1 : 1;
      if (sort === 'prize') return engPrizeNum(b) - engPrizeNum(a);
      return (b.featured ? 1 : 0) - (a.featured ? 1 : 0);
    });
    return out;
  }, [all, q, field, status, flags, age, sort, st.favs]);

  const counts = React.useMemo(() => ({
    total: all.length,
    open: all.filter((c) => engStatus(c) === 'open').length,
    hack: all.filter((c) => c.hack).length,
    medical: all.filter((c) => c.medical).length,
    ai: all.filter((c) => c.ai).length,
    sources: ENG_SOURCES.length,
  }), [all]);

  const toggleFav = (id) => {
    const on = st.favs.includes(id);
    save({ favs: on ? st.favs.filter((x) => x !== id) : [...st.favs, id] });
    toast(L(on ? E.t_removed : E.t_added));
  };

  const runGemini = async (mode) => {
    if (runLock.current) return;
    runLock.current = true;
    const s0 = engRead();
    const known = [...ENG_COMPS, ...(s0.found || [])];
    setRun({ i: 0, total: GEM_TOPICS.length, label: GEM_TOPICS[0].ar, found: 0, gem: true });
    try {
      const res = await engGeminiDiscover(known, (p) => setRun({ ...p, gem: true }));
      const s = engRead();
      save({ found: [...(s.found || []), ...res.items], lastRun: new Date().toISOString(), runs: (s.runs || 0) + (mode === 'auto' ? 0 : 1), gemModel: res.model, gemLast: res.items.length, gemErr: res.items.length ? '' : (res.errors[0] || '') });
      if (!res.items.length && res.errors.some((m) => /quota|rate/i.test(m))) { const s2 = engRead(); engWrite({ ...s2, lastAuto: null }); }
      if (mode === 'auto') setAutoMsg(res.items.length);
      toast(res.items.length ? engFmt(L(E.t_run_new), { n: res.items.length }) + ' · Gemini' : (res.errors[0] ? 'Gemini: ' + res.errors[0].slice(0, 90) : L(E.t_run_none)));
    } catch (e) {
      save({ gemErr: String(e.message || e) });
      toast('Gemini: ' + String(e.message || e).slice(0, 90));
    } finally {
      setRun(null);
      runLock.current = false;
    }
  };
  const runClassic = async () => {
    const s0 = engRead();
    const ids = new Set([...ENG_COMPS, ...(s0.found || [])].map((c) => c.id));
    const fresh = ENG_DISCOVER.filter((c) => !ids.has(c.id));
    const total = ENG_SOURCES.length, items = [];
    for (let i = 0; i < total; i++) {
      const pick = fresh.filter((_, k) => k % total === i);
      items.push(...pick);
      setRun({ i: i + 1, total, label: ENG_SOURCES[i].q, found: items.length, classic: true });
      await new Promise((r) => setTimeout(r, 90));
    }
    const out = items.map((c) => ({ ...c, classic: true }));
    const s = engRead();
    save({ found: [...(s.found || []), ...out], lastRun: new Date().toISOString(), classicLast: out.length });
    return out.length;
  };
  const runAll = async (mode) => {
    if (runLock.current) return;
    const m = engRead().engMode || 'both';
    let n = 0;
    if (m !== 'gemini') {
      runLock.current = true;
      try { n = await runClassic(); } finally { setRun(null); runLock.current = false; }
      if (m === 'classic') {
        const s = engRead();
        if (mode !== 'auto') save({ runs: (s.runs || 0) + 1 });
        if (mode === 'auto') setAutoMsg(n);
        toast(n ? engFmt(L(E.t_run_new), { n }) + ' · ' + L({ ar: 'المحرك الكلاسيكي', en: 'Classic engine' }) : L(E.t_run_none));
        return;
      }
    }
    if (m !== 'classic') await runGemini(mode);
  };
  const startRun = () => runAll('manual');
  const engMode = st.engMode || 'both';

  const shown = tab === 'mine' ? all.filter((c) => st.favs.includes(c.id)) : tab === 'hack' ? list.filter((c) => c.hack) : list;

  return (
    <div>
      {/* ENGINE SECTION BAR */}
      <div style={{ borderBottom: '1px solid var(--line)', background: 'rgba(255,255,255,.02)', position: 'sticky', top: 0, zIndex: 30, backdropFilter: 'blur(10px)' }}>
        <div className="wrap" style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap', padding: '12px 0' }}>
          <span style={{ display: 'flex', alignItems: 'center', gap: 9, fontWeight: 800, fontFamily: 'Space Grotesk', fontSize: 16, marginInlineEnd: 8 }}>
            <span style={{ width: 34, height: 34, borderRadius: 11, display: 'grid', placeItems: 'center', background: 'color-mix(in srgb, var(--accent) 18%, transparent)', color: 'var(--accent)' }}><Icon.bulb s={18} /></span>
            <span>ibtikar<span style={{ color: 'var(--accent)' }}>.health</span><span className="muted" style={{ display: 'block', fontSize: 10.5, fontWeight: 600, letterSpacing: lang === 'en' ? '.08em' : 'normal', fontFamily: lang === 'en' ? 'Space Grotesk' : 'Tajawal, sans-serif' }}>{L({ ar: 'ابتكارك يستحق منصة عالمية واحدة', en: 'Your innovation deserves one global platform' })}</span></span>
          </span>
          {ENG_TABS.map(([k, lbl, ic]) => {
            const I = Icon[ic] || EIcon[ic];
            return (
              <button key={k} className={`nav-link ${tab === k ? 'active' : ''}`} style={{ display: 'flex', gap: 7, alignItems: 'center' }} onClick={() => setTab(k)}>
                <I s={15} /> {L(lbl)}{k === 'mine' && st.favs.length ? ` (${st.favs.length})` : ''}
              </button>
            );
          })}
          <span style={{ flex: 1 }} />
          <button className="btn btn-ghost btn-sm" onClick={() => setModal('report')}><Icon.plus s={15} /> {L(E.cta_report)}</button>
          <button className="btn btn-primary btn-sm" onClick={() => setModal('account')}><Icon.user s={15} /> {st.account ? st.account.name.split(' ')[0] : L(E.acc_short)}</button>
        </div>
      </div>

      {/* HERO */}
      <header className="hero section" style={{ paddingTop: 64, paddingBottom: 56 }}>
        <div className="blob" style={{ width: 460, height: 460, background: 'var(--mint)', top: -150, insetInlineEnd: -60, opacity: .22 }} />
        <div className="wrap" style={{ position: 'relative' }}>
          <Reveal>
            <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
              <span className="chip on"><EIcon.radar s={14} /> {L(E.eyebrow)}</span>
              <span className="chip"><span className="live-dot" style={{ color: 'var(--mint)' }} /> {L(E.scanning)}</span>
            </div>
          </Reveal>
          <Reveal delay={80}>
            <h1 style={{ fontSize: 'clamp(34px, 5.4vw, 64px)', lineHeight: 1.04, margin: '22px 0 0', maxWidth: 820 }}>
              {L(E.h1a)}<br /><span style={{ color: 'var(--accent)' }}>{L(E.h1b)}</span>
            </h1>
          </Reveal>
          <Reveal delay={150}>
            <p className="muted" style={{ fontSize: 18.5, lineHeight: 1.75, marginTop: 22, maxWidth: 700 }}>
              <b style={{ color: 'var(--text)', fontFamily: 'Space Grotesk' }}>ibtikar.health</b> {L(E.lede)}
            </p>
          </Reveal>
          <Reveal delay={220}>
            <div style={{ display: 'flex', gap: 12, marginTop: 30, flexWrap: 'wrap' }}>
              <button className="btn btn-primary btn-lg" onClick={() => { setTab('news'); setTimeout(() => newsRef.current && window.scrollTo({ top: newsRef.current.offsetTop - 70, behavior: 'smooth' }), 60); }}>
                <Icon.spark s={18} /> {L(E.cta_news)}
              </button>
              <button className="btn btn-ghost btn-lg" onClick={() => setModal('account')}><Icon.user s={18} /> {L(st.account ? E.cta_acc2 : E.cta_acc)}</button>
              <button className="btn btn-dark btn-lg" onClick={() => setModal('report')}><Icon.plus s={18} /> {L(E.cta_report)}</button>
            </div>
          </Reveal>
          <Reveal delay={290}>
            <div className="grid g4" style={{ marginTop: 44 }}>
              {[[counts.total, E.st_total, 'trophy', 'mint'], [counts.medical, E.st_med, 'steth', 'rose'], [counts.hack, E.st_hack, 'code', 'gold'], [counts.ai, E.st_ai, 'cpu', 'purple']].map(([v, lbl, ic, ac]) => {
                const I = Icon[ic] || EIcon[ic];
                return (
                  <div key={lbl.en} className="card card-pad" style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                    <span style={{ width: 46, height: 46, flex: 'none', borderRadius: 13, display: 'grid', placeItems: 'center', background: `color-mix(in srgb, var(--${ac}) 16%, transparent)`, color: `var(--${ac})` }}><I s={22} /></span>
                    <div>
                      <div className="kpi-num" style={{ fontSize: 30 }}><CountUp to={v} /></div>
                      <div className="muted" style={{ fontSize: 13 }}>{L(lbl)}</div>
                    </div>
                  </div>
                );
              })}
            </div>
            <div className="muted" style={{ display: 'flex', gap: 18, flexWrap: 'wrap', alignItems: 'center', marginTop: 20, fontSize: 13.5 }}>
              <span style={{ display: 'flex', gap: 8, alignItems: 'center' }}><span className="live-dot" style={{ color: 'var(--mint)' }} /> {L(E.daily)}</span>
              <span style={{ display: 'flex', gap: 8, alignItems: 'center' }}><Icon.globe s={15} /> {L(E.countries)}</span>
              <span style={{ display: 'flex', gap: 8, alignItems: 'center' }}><Icon.users s={15} /> {counts.sources} {L(E.queries)}</span>
            </div>
          </Reveal>
        </div>
      </header>

      {/* ENGINE STATUS */}
      <section className="section tight">
        <div className="wrap">
          <div className="card card-pad" style={{ display: 'grid', gap: 18 }}>
            <div style={{ display: 'flex', gap: 18, alignItems: 'center', flexWrap: 'wrap' }}>
              <span style={{ width: 52, height: 52, flex: 'none', borderRadius: 15, display: 'grid', placeItems: 'center', background: 'color-mix(in srgb, var(--accent) 16%, transparent)', color: 'var(--accent)' }}><EIcon.radar s={26} /></span>
              <div style={{ flex: '1 1 260px' }}>
                <div style={{ fontWeight: 800, fontSize: 18 }}>{L(E.eng_state)}</div>
                <div className="muted" style={{ fontSize: 14, marginTop: 5 }}>
                  {L(E.last_run)}: {st.lastRun ? engDate(st.lastRun.slice(0, 10), lang) + ' · ' + new Date(st.lastRun).toLocaleTimeString(lang === 'en' ? 'en-GB' : 'ar-SA', { hour: '2-digit', minute: '2-digit' }) : L(E.sched)} · {ENG_SOURCES.length} {L(E.queries)} · {st.runs || 0} {L(E.manual)}
                </div>
              </div>
              <button className="btn btn-primary" onClick={startRun} disabled={!!run}>{run ? L(E.running) : <React.Fragment><EIcon.radar s={17} /> {L(E.run_now)}</React.Fragment>}</button>
            </div>
            {autoMsg > 0 && (
              <div className="chip on" style={{ alignSelf: 'flex-start' }}><Icon.check s={14} /> {engFmt(L(E.auto_done), { n: autoMsg })}</div>
            )}
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center', fontSize: 13.5 }}>
              <span className="muted" style={{ fontWeight: 600 }}>{L({ ar: 'وضع المحرك:', en: 'Engine mode:' })}</span>
              {[['both', { ar: 'الاثنان معاً (موصى به)', en: 'Both (recommended)' }], ['classic', { ar: 'المحرك الكلاسيكي', en: 'Classic engine' }], ['gemini', { ar: 'Gemini فقط', en: 'Gemini only' }]].map(([k, lbl]) => (
                <button key={k} className={'chip' + (engMode === k ? ' on' : '')} disabled={!!run} onClick={() => save({ engMode: k })}>{L(lbl)}</button>
              ))}
            </div>
            <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center', fontSize: 13.5 }}>
              {engMode !== 'gemini' && <span className="chip on"><span className="live-dot" style={{ color: 'var(--mint)' }} /> {L({ ar: 'المحرك الكلاسيكي', en: 'Classic engine' })} · {ENG_SOURCES.length} {L(E.queries)}</span>}
              {st.classicLast != null && engMode !== 'gemini' && <span className="muted">{L({ ar: 'آخر جولة كلاسيكية أضافت', en: 'Last classic run added' })} <b style={{ color: 'var(--text)' }}>{st.classicLast}</b></span>}
            </div>
            {engMode !== 'classic' && <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center', fontSize: 13.5 }}>
              <span className="chip on"><span className="live-dot" style={{ color: 'var(--mint)' }} /> {L({ ar: 'Gemini متصل · بحث Google مباشر', en: 'Gemini connected · live Google Search' })}</span>
              {st.gemModel && <span className="chip" style={{ direction: 'ltr' }}>{st.gemModel}</span>}
              <span className="chip">{GEM_TOPICS.length} {L({ ar: 'محاور عالمية وعربية', en: 'global & Arab search axes' })}</span>
              <span className="chip">{L({ ar: 'يومياً 8:00 صباحاً', en: 'Daily at 8:00 AM' })}</span>
              {st.gemLast != null && <span className="muted">{L({ ar: 'آخر جولة Gemini أضافت', en: 'Last Gemini run added' })} <b style={{ color: 'var(--text)' }}>{st.gemLast}</b> · {L({ ar: 'الإجمالي من Gemini', en: 'total from Gemini' })} <b style={{ color: 'var(--text)' }}>{st.found.filter((f) => f.gemini).length}</b></span>}
            </div>}
            {st.gemErr && !run && engMode !== 'classic' && <div style={{ fontSize: 13, color: 'var(--rose)', direction: 'ltr', textAlign: 'start' }}>Gemini: {st.gemErr.slice(0, 200)}</div>}
            {run && (
              <div>
                <div style={{ height: 6, borderRadius: 999, background: 'var(--line)', overflow: 'hidden' }}>
                  <div style={{ width: `${Math.round((run.i / run.total) * 100)}%`, height: '100%', background: 'var(--accent)', transition: 'width .22s linear' }} />
                </div>
                <div className="muted" style={{ fontSize: 13, marginTop: 10 }}>
                  {run.classic ? L({ ar: 'المحرك الكلاسيكي', en: 'Classic engine' }) : 'Gemini' + (run.model ? ` (${run.model})` : '')} · [{run.i}/{run.total}] {run.label} → {run.found} {L({ ar: 'مسابقة', en: 'found' })}
                </div>
              </div>
            )}
            <div className="muted" style={{ fontSize: 13, lineHeight: 1.7 }}>{L(E.note)}</div>
          </div>
        </div>
      </section>

      {/* QUICK FIELD BAR */}
      <section className="section tight" style={{ paddingTop: 0 }}>
        <div className="wrap">
          <div className="card card-pad" style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
            {ENG_QUICK.map(([k, lbl, ic]) => {
              const I = Icon[ic] || EIcon[ic];
              return <button key={lbl.en} className={`chip ${field === k ? 'on' : ''}`} style={{ cursor: 'pointer' }} onClick={() => { setField(k); if (tab !== 'comps' && tab !== 'hack') setTab('comps'); }}><I s={14} /> {L(lbl)}</button>;
            })}
            <span style={{ flex: 1 }} />
            <button className="btn btn-primary btn-sm" onClick={startRun} disabled={!!run}><Icon.rocket s={15} /> {run ? L(E.running) : L(E.run_short)}</button>
          </div>
        </div>
      </section>

      {(tab === 'comps' || tab === 'mine' || tab === 'hack') && (
        <section className="section" style={{ paddingTop: 30 }}>
          <div className="wrap">
            <EngineFilters {...{ q, setQ, field, setField, status, setStatus, flags, setFlags, age, setAge, sort, setSort, L, lang }} />
            <div className="muted" style={{ fontSize: 14, margin: '18px 0 20px' }}>
              {tab === 'mine' ? engFmt(L(E.mine_n), { n: st.favs.length }) : tab === 'hack' ? engFmt(L(E.hack_n), { n: shown.length }) : engFmt(L(E.results), { n: list.length, t: counts.total })}
            </div>
            <div className="grid g2">
              {shown.map((c, i) => (
                <Reveal key={c.id} delay={(i % 2) * 70}>
                  <EngineCard c={c} fav={st.favs.includes(c.id)} onFav={() => toggleFav(c.id)} onOpen={() => setDetail(c)} L={L} lang={lang} />
                </Reveal>
              ))}
            </div>
            {!shown.length && tab !== 'mine' && (
              <div className="card card-pad" style={{ textAlign: 'center' }}>
                <div style={{ fontWeight: 700, fontSize: 17 }}>{L(E.empty_t)}</div>
                <p className="muted" style={{ marginTop: 8, fontSize: 14.5 }}>{L(E.empty_d)}</p>
                <button className="btn btn-ghost btn-sm" style={{ marginTop: 16 }} onClick={() => setModal('report')}><Icon.plus s={15} /> {L(E.empty_cta)}</button>
              </div>
            )}
            {tab === 'mine' && !st.favs.length && (
              <div className="card card-pad" style={{ textAlign: 'center' }}>
                <div style={{ fontWeight: 700, fontSize: 17 }}>{L(E.mine_empty_t)}</div>
                <p className="muted" style={{ marginTop: 8, fontSize: 14.5 }}>{L(E.mine_empty_d)}</p>
              </div>
            )}
          </div>
        </section>
      )}

      {tab === 'cal' && <EngineCalendar list={all} onOpen={setDetail} L={L} lang={lang} />}
      {tab === 'news' && <EngineNews anchorRef={newsRef} L={L} lang={lang} />}
      {tab === 'src' && <EngineSources L={L} lang={lang} />}
      {tab === 'analytics' && <EngineAnalytics list={all} L={L} lang={lang} />}
      {tab === 'admin' && <EngineAdmin st={st} save={save} toast={toast} onAccount={() => setModal('account')} L={L} lang={lang} />}

      <div ref={newsRef} />

      {/* SUBMIT BRIDGE */}
      <section className="section tight">
        <div className="wrap">
          <div className="card card-pad" style={{ display: 'flex', gap: 22, alignItems: 'center', flexWrap: 'wrap' }}>
            <div style={{ flex: '1 1 340px' }}>
              <div className="eyebrow"><Icon.bulb s={15} /> {L(E.bridge_eye)}</div>
              <h3 style={{ fontSize: 22, marginTop: 12 }}>{L(E.bridge_t)}</h3>
              <p className="muted" style={{ marginTop: 10, fontSize: 15.5, lineHeight: 1.7, maxWidth: 560 }}>{L(E.bridge_d)}</p>
            </div>
            <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              <button className="btn btn-primary" onClick={() => go('idea')}><Icon.bulb s={17} /> {L(E.bridge_c1)}</button>
              <button className="btn btn-ghost" onClick={() => go('academy')}><Icon.award s={17} /> {L(E.bridge_c2)}</button>
            </div>
          </div>
        </div>
      </section>

      <Modal open={!!detail} onClose={() => setDetail(null)} max={680}>
        {detail && <EngineDetail c={detail} go={go} onClose={() => setDetail(null)} fav={st.favs.includes(detail.id)} onFav={() => toggleFav(detail.id)} L={L} lang={lang} />}
      </Modal>
      <Modal open={modal === 'account'} onClose={() => setModal(null)} max={560}>
        <EngineAccount st={st} save={save} toast={toast} onClose={() => setModal(null)} L={L} lang={lang} />
      </Modal>
      <Modal open={modal === 'report'} onClose={() => setModal(null)} max={620}>
        <EngineReport st={st} save={save} toast={toast} onClose={() => setModal(null)} L={L} lang={lang} />
      </Modal>
    </div>
  );
}

// ---------- filters ----------
function EngineFilters({ q, setQ, field, setField, status, setStatus, flags, setFlags, age, setAge, sort, setSort, L, lang }) {
  const tg = (k) => setFlags({ ...flags, [k]: !flags[k] });
  return (
    <div className="card card-pad" style={{ display: 'grid', gap: 16 }}>
      <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
        <div style={{ position: 'relative', flex: '1 1 280px' }}>
          <span style={{ position: 'absolute', insetInlineStart: 14, top: '50%', transform: 'translateY(-50%)', color: 'var(--faint)' }}><EIcon.search s={18} /></span>
          <input className="input" style={{ paddingInlineStart: 44 }} placeholder={L(E.search_ph)} value={q} onChange={(e) => setQ(e.target.value)} />
        </div>
        <select className="select" style={{ width: 'auto', minWidth: 190 }} value={field} onChange={(e) => setField(e.target.value)}>
          <option value="all">{L(E.all_fields)}</option>
          {ENG_FIELDS.map((f) => <option key={f} value={f}>{engField(f, lang)}</option>)}
        </select>
        <select className="select" style={{ width: 'auto', minWidth: 150 }} value={age} onChange={(e) => setAge(e.target.value)}>
          <option value="all">{L(E.all_ages)}</option>
          {['10', '14', '17', '22', '28', '35', '45'].map((a) => <option key={a} value={a}>{engFmt(L(E.age_n), { n: a })}</option>)}
        </select>
        <select className="select" style={{ width: 'auto', minWidth: 170 }} value={sort} onChange={(e) => setSort(e.target.value)}>
          <option value="deadline">{L(E.s_deadline)}</option>
          <option value="prize">{L(E.s_prize)}</option>
          <option value="featured">{L(E.s_feat)}</option>
        </select>
      </div>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
        {[['open', E.f_open], ['upcoming', E.f_up], ['closed', E.f_closed], ['all', E.f_all]].map(([k, lbl]) => (
          <button key={k} className={`chip ${status === k ? 'on' : ''}`} style={{ cursor: 'pointer' }} onClick={() => setStatus(k)}>{L(lbl)}</button>
        ))}
        <span style={{ width: 1, height: 22, background: 'var(--line)', margin: '0 6px' }} />
        {[['hack', E.f_hack], ['smart', E.f_smart], ['women', E.f_women], ['featured', E.f_feat], ['fav', E.f_fav]].map(([k, lbl]) => (
          <button key={k} className={`chip ${flags[k] ? 'on' : ''}`} style={{ cursor: 'pointer' }} onClick={() => tg(k)}>{L(lbl)}</button>
        ))}
      </div>
    </div>
  );
}

// ---------- competition card ----------
function EngineCard({ c, fav, onFav, onOpen, L, lang }) {
  const s = engStatus(c), m = ENG_STATUS_META[s], days = engDaysLeft(c);
  const desc = engDesc(c, lang), sub = engSubtitle(c, lang);
  return (
    <div className="card hoverable card-pad" style={{ height: '100%', display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
        <div style={{ flex: 1, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <span className={`badge ${m.cls}`}>{L(m)}</span>
          <span className="badge purple">{engField(c.field, lang)}</span>
          {c.featured && <span className="badge gold">{L(E.featured)}</span>}
          {c.fresh && <span className="badge mint">{L(E.fresh)}</span>}
          {c.gemini && <span className="badge" style={{ direction: 'ltr' }}>✦ Gemini</span>}
        </div>
        <button className="lang-btn" onClick={onFav} title={L(E.f_fav)} style={{ padding: 8, color: fav ? 'var(--gold)' : 'var(--faint)' }}><EIcon.star s={17} /></button>
      </div>
      <div>
        <h3 style={{ fontSize: 19, lineHeight: 1.4 }}>{engTitle(c, lang)}</h3>
        {sub && <div className="muted" style={{ fontSize: 13, marginTop: 6, fontFamily: lang === 'en' ? 'inherit' : 'Space Grotesk', direction: lang === 'en' ? 'rtl' : 'ltr', textAlign: 'start' }}>{sub}</div>}
      </div>
      <p className="muted" style={{ fontSize: 14.5, lineHeight: 1.7, margin: 0 }}>{desc.length > 155 ? desc.slice(0, 155) + '…' : desc}</p>
      <div style={{ display: 'grid', gap: 8, fontSize: 13.5 }}>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }} className="muted"><Icon.users s={15} /> {c.org}</div>
        <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap' }} className="muted">
          <span style={{ display: 'flex', gap: 7, alignItems: 'center' }}><Icon.pin s={15} /> {engPlace(c.country, lang)}{c.city ? ` · ${engPlace(c.city, lang)}` : ''}</span>
          <span style={{ display: 'flex', gap: 7, alignItems: 'center' }}><EIcon.cal s={15} /> {engDate(c.deadline, lang)}</span>
          {c.prize && <span style={{ display: 'flex', gap: 7, alignItems: 'center', color: 'var(--gold)' }}><EIcon.coin s={15} /> {c.prize} {c.cur}</span>}
        </div>
      </div>
      <div style={{ marginTop: 'auto', display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap', paddingTop: 6 }}>
        <button className="btn btn-ghost btn-sm" onClick={onOpen}>{L(E.details)} <Icon.arrow s={15} /></button>
        <a className="btn btn-dark btn-sm" href={c.url} target="_blank" rel="noopener noreferrer"><EIcon.link s={15} /> {L(E.official)}</a>
        {s === 'open' && days != null && days <= 45 && <span className="muted" style={{ fontSize: 13, fontWeight: 700, color: days <= 14 ? 'var(--rose)' : 'var(--muted)' }}>{engFmt(L(E.days_left), { n: days })}</span>}
      </div>
    </div>
  );
}

// ---------- detail ----------
function EngineDetail({ c, go, onClose, fav, onFav, L, lang }) {
  const s = engStatus(c), m = ENG_STATUS_META[s], days = engDaysLeft(c), sub = engSubtitle(c, lang);
  const rows = [
    [L(E.r_org), c.org], [L(E.r_country), engPlace(c.country, lang) + (c.city ? ` · ${engPlace(c.city, lang)}` : '')], [L(E.r_field), engField(c.field, lang)],
    [L(E.r_close), engDate(c.deadline, lang)], [L(E.r_open), c.opens ? engDate(c.opens, lang) : L(E.open_now)],
    [L(E.r_prize), c.prize ? `${c.prize} ${c.cur}` : L(E.unannounced)],
    [L(E.r_age), c.ageMin || c.ageMax ? `${c.ageMin || L(E.any)} – ${c.ageMax || L(E.any)} ${L(E.years)}` : L(E.all_ages)],
    [L(E.r_dur), c.hours ? (c.hours >= 168 ? L(E.week_plus) : engFmt(L(E.hours_n), { n: c.hours })) : '—'],
    [L(E.r_src), c.src],
  ];
  return (
    <div>
      <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
        <div style={{ flex: 1, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <span className={`badge ${m.cls}`}>{L(m)}</span>
          {s === 'open' && days != null && <span className="badge gold">{engFmt(L(E.days_left), { n: days })}</span>}
        </div>
        <button className="lang-btn" onClick={onClose} style={{ padding: 8 }}><Icon.x s={18} /></button>
      </div>
      <h2 style={{ fontSize: 24, marginTop: 16, lineHeight: 1.35 }}>{engTitle(c, lang)}</h2>
      {sub && <div className="muted" style={{ fontSize: 14, marginTop: 8, fontFamily: lang === 'en' ? 'inherit' : 'Space Grotesk', direction: lang === 'en' ? 'rtl' : 'ltr', textAlign: 'start' }}>{sub}</div>}
      <p className="muted" style={{ fontSize: 15.5, lineHeight: 1.8, marginTop: 16 }}>{engDesc(c, lang)}</p>
      <div className="hr" style={{ margin: '22px 0' }} />
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0,1fr))', gap: 14 }}>
        {rows.map(([k, v]) => (
          <div key={k}>
            <div className="muted" style={{ fontSize: 12.5 }}>{k}</div>
            <div style={{ fontSize: 14.5, fontWeight: 600, marginTop: 4 }}>{v || '—'}</div>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', marginTop: 26 }}>
        <a className="btn btn-primary" href={c.url} target="_blank" rel="noopener noreferrer"><EIcon.link s={17} /> {L(E.apply)}</a>
        <button className="btn btn-ghost" onClick={onFav}><EIcon.star s={16} /> {L(fav ? E.unfollow : E.follow)}</button>
        <button className="btn btn-dark" onClick={() => { onClose(); go('idea'); }}><Icon.bulb s={16} /> {L(E.reg_first)}</button>
      </div>
    </div>
  );
}

// ---------- calendar ----------
function EngineCalendar({ list, onOpen, L, lang }) {
  const groups = React.useMemo(() => {
    const g = {};
    list.filter((c) => c.deadline).sort((a, b) => a.deadline < b.deadline ? -1 : 1).forEach((c) => {
      const k = c.deadline.slice(0, 7);
      (g[k] = g[k] || []).push(c);
    });
    return Object.entries(g);
  }, [list]);
  const ms = ENG_MONTHS[lang === 'en' ? 'en' : 'ar'];
  return (
    <section className="section" style={{ paddingTop: 30 }}>
      <div className="wrap">
        <Head eyebrow={L(E.cal_eyebrow)} title={L(E.cal_title)} icon="clock" />
        <div style={{ display: 'grid', gap: 18, marginTop: 36 }}>
          {groups.map(([k, items], gi) => {
            const [y, m] = k.split('-');
            const past = new Date(k + '-28') < ENG_NOW();
            return (
              <Reveal key={k} delay={Math.min(gi, 5) * 60}>
                <div className="card card-pad" style={{ opacity: past ? .6 : 1 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                    <span className="badge mint">{ms[parseInt(m, 10) - 1]} {y}</span>
                    <span className="muted" style={{ fontSize: 13.5 }}>{engFmt(L(E.cal_count), { n: items.length })}</span>
                  </div>
                  <div style={{ display: 'grid', gap: 10, marginTop: 16 }}>
                    {items.map((c) => {
                      const mm = ENG_STATUS_META[engStatus(c)];
                      return (
                        <button key={c.id} onClick={() => onOpen(c)} style={{ display: 'flex', gap: 14, alignItems: 'center', textAlign: 'start', background: 'rgba(255,255,255,.025)', border: '1px solid var(--line)', borderRadius: 'var(--r-sm)', padding: '12px 14px', cursor: 'pointer', color: 'var(--text)', width: '100%' }}>
                          <span style={{ fontFamily: 'Space Grotesk', fontWeight: 700, fontSize: 20, width: 34, textAlign: 'center', color: 'var(--accent)' }}>{parseInt(c.deadline.slice(8), 10)}</span>
                          <span style={{ flex: 1, minWidth: 0 }}>
                            <span style={{ display: 'block', fontWeight: 700, fontSize: 15 }}>{engTitle(c, lang)}</span>
                            <span className="muted" style={{ fontSize: 13 }}>{c.org} · {engPlace(c.country, lang)}</span>
                          </span>
                          <span className={`badge ${mm.cls}`}>{L(mm)}</span>
                        </button>
                      );
                    })}
                  </div>
                </div>
              </Reveal>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ---------- news ----------
function EngineNews({ anchorRef, L, lang }) {
  const [type, setType] = React.useState('all');
  const items = ENG_NEWS.filter((n) => type === 'all' || n.type === type);
  return (
    <section className="section" style={{ paddingTop: 30 }}>
      <div className="wrap">
        <Head eyebrow={L(E.news_eyebrow)} title={L(E.news_title)} icon="spark" />
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 24 }}>
          {[['all', E.n_all], ['news', E.n_news], ['grant', E.n_grant], ['award', E.n_award], ['update', E.n_update]].map(([k, lbl]) => (
            <button key={k} className={`chip ${type === k ? 'on' : ''}`} style={{ cursor: 'pointer' }} onClick={() => setType(k)}>{L(lbl)}</button>
          ))}
        </div>
        <div className="grid g3" style={{ marginTop: 28 }}>
          {items.map((n, i) => {
            const m = ENG_NEWS_META[n.type], en = ENG_NEWS_EN[n.id] || {};
            return (
              <Reveal key={n.id} delay={(i % 3) * 70}>
                <div className="card hoverable card-pad" style={{ height: '100%', display: 'flex', flexDirection: 'column', gap: 12 }}>
                  <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                    <span className={`badge ${m.cls}`}>{L(m)}</span>
                    <span className="muted" style={{ fontSize: 12.5 }}>{engDate(n.date, lang)}</span>
                  </div>
                  <h3 style={{ fontSize: 17.5, lineHeight: 1.45 }}>{lang === 'en' ? (en.t || n.title) : n.title}</h3>
                  <p className="muted" style={{ fontSize: 14.5, lineHeight: 1.7, margin: 0 }}>{lang === 'en' ? (en.s || n.sum) : n.sum}</p>
                  <div style={{ marginTop: 'auto', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 10, paddingTop: 8 }}>
                    <span className="muted" style={{ fontSize: 13, fontFamily: 'Space Grotesk' }}>{n.src}</span>
                    <a className="btn btn-dark btn-sm" href={n.url} target="_blank" rel="noopener noreferrer"><EIcon.link s={14} /> {L(E.source)}</a>
                  </div>
                </div>
              </Reveal>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ---------- sources ----------
function EngineSources({ L, lang }) {
  return (
    <section className="section" style={{ paddingTop: 30 }}>
      <div className="wrap">
        <Head eyebrow={L(E.src_eyebrow)} title={L(E.src_title)} icon="globe" />
        <div className="card" style={{ marginTop: 34, overflow: 'hidden' }}>
          {ENG_SOURCES.map((s, i) => (
            <div key={s.q} style={{ display: 'flex', gap: 14, alignItems: 'center', padding: '15px 22px', borderTop: i ? '1px solid var(--line)' : 'none', flexWrap: 'wrap' }}>
              <span style={{ color: 'var(--accent)' }}><EIcon.radar s={17} /></span>
              <span style={{ flex: '1 1 260px', fontFamily: 'Space Grotesk', fontSize: 14, direction: 'ltr', textAlign: 'start' }}>{s.q}</span>
              <span className="badge purple">{lang === 'en' ? (ENG_SRC_CAT_EN[s.cat] || s.cat) : s.cat}</span>
              <span className="muted" style={{ fontSize: 13 }}>{L(E.src_last)} {engDate(s.last, lang)}</span>
              <span className="muted" style={{ fontSize: 13, fontWeight: 700 }}>{engFmt(L(E.src_found), { n: s.found })}</span>
            </div>
          ))}
        </div>
        <p className="muted" style={{ fontSize: 14, lineHeight: 1.75, marginTop: 20, maxWidth: 720 }}>{L(E.src_note)}</p>
      </div>
    </section>
  );
}

// ---------- analytics ----------
function EngineAnalytics({ list, L, lang }) {
  const byField = {}, byCountry = {}, byMonth = {};
  let open = 0, upcoming = 0, closed = 0, prizeSum = 0;
  list.forEach((c) => {
    const f = engField(c.field, lang);
    byField[f] = (byField[f] || 0) + 1;
    const ct = engPlace(c.country, lang);
    byCountry[ct] = (byCountry[ct] || 0) + 1;
    if (c.deadline) { const k = c.deadline.slice(0, 7); byMonth[k] = (byMonth[k] || 0) + 1; }
    const s = engStatus(c);
    if (s === 'open') open++; else if (s === 'upcoming') upcoming++; else closed++;
    prizeSum += engPrizeNum(c);
  });
  const bars = (obj, max = 8) => Object.entries(obj).sort((a, b) => b[1] - a[1]).slice(0, max);
  const top = Math.max(...Object.values(byField), 1);
  const months = Object.entries(byMonth).sort().slice(0, 10);
  const monthTop = Math.max(...months.map(([, v]) => v), 1);
  const ms = ENG_MONTHS[lang === 'en' ? 'en' : 'ar'];
  return (
    <section className="section" style={{ paddingTop: 30 }}>
      <div className="wrap">
        <Head eyebrow={L(E.an_eyebrow)} title={L(E.an_title)} icon="chart" />
        <div className="grid g4" style={{ marginTop: 34 }}>
          {[[open, E.an_open, 'mint'], [upcoming, E.an_up, 'gold'], [closed, E.an_closed, 'rose'], [Math.round(prizeSum / 1000) + 'K$', E.an_prizes, 'purple']].map(([v, lbl, ac]) => (
            <div key={lbl.en} className="card card-pad">
              <div className="kpi-num" style={{ fontSize: 34, color: `var(--${ac})` }}>{v}</div>
              <div className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>{L(lbl)}</div>
            </div>
          ))}
        </div>
        <div className="grid g2" style={{ marginTop: 22 }}>
          {[[L(E.an_byfield), bars(byField), 'var(--accent)'], [L(E.an_bycountry), bars(byCountry, 7), 'var(--purple)']].map(([title, rows, color]) => (
            <div key={title} className="card card-pad">
              <div style={{ fontWeight: 800, fontSize: 17 }}>{title}</div>
              <div style={{ display: 'grid', gap: 12, marginTop: 18 }}>
                {rows.map(([k, v]) => (
                  <div key={k}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13.5, marginBottom: 6 }}><span>{k}</span><span className="muted" style={{ fontWeight: 700 }}>{v}</span></div>
                    <div style={{ height: 8, borderRadius: 999, background: 'var(--line)', overflow: 'hidden' }}><div style={{ width: `${(v / top) * 100}%`, height: '100%', background: color }} /></div>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
        <div className="card card-pad" style={{ marginTop: 22 }}>
          <div style={{ fontWeight: 800, fontSize: 17 }}>{L(E.an_density)}</div>
          <div style={{ display: 'flex', gap: 12, alignItems: 'flex-end', marginTop: 24, height: 160 }}>
            {months.map(([k, v]) => {
              const [y, m] = k.split('-');
              return (
                <div key={k} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontFamily: 'Space Grotesk', fontSize: 13, fontWeight: 700 }}>{v}</span>
                  <div style={{ width: '100%', height: `${(v / monthTop) * 110}px`, minHeight: 6, borderRadius: 8, background: 'linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 30%, transparent))' }} />
                  <span className="muted" style={{ fontSize: 11.5, textAlign: 'center' }}>{ms[parseInt(m, 10) - 1].slice(0, 3)}<br />{y.slice(2)}</span>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- engine control panel ----------
function EngineAdmin({ st, save, toast, onAccount, L, lang }) {
  const remove = (i) => { save({ reports: st.reports.filter((_, x) => x !== i) }); toast(L(E.t_del)); };
  const approve = (i) => {
    const r = st.reports[i];
    const item = { id: 'usr_' + Date.now(), title: r.title, en: '', org: r.org || (lang === 'en' ? 'Community source' : 'مصدر مجتمعي'), country: 'دولي', field: r.field, url: r.url, deadline: r.deadline || '', desc: r.note || (lang === 'en' ? 'Added from a user report and reviewed by the engine.' : 'أُضيفت من تقرير مستخدم وراجعها المحرك.'), src: lang === 'en' ? 'User report' : 'تقرير مستخدم', hack: r.field.includes('هاكاثون'), fresh: true };
    save({ found: [...st.found, item], reports: st.reports.filter((_, x) => x !== i) });
    toast(L(E.t_pub));
  };
  return (
    <section className="section" style={{ paddingTop: 30 }}>
      <div className="wrap">
        <Head eyebrow={L(E.ad_eyebrow)} title={L(E.ad_title)} icon="sliders" />
        <div className="grid g4" style={{ marginTop: 34 }}>
          {[[st.reports.length, E.ad_pending, 'gold'], [st.found.length, E.ad_added, 'mint'], [st.favs.length, E.ad_favs, 'purple'], [st.runs || 0, E.manual, 'mint']].map(([v, lbl, ac]) => (
            <div key={lbl.en} className="card card-pad">
              <div className="kpi-num" style={{ fontSize: 32, color: `var(--${ac})` }}>{v}</div>
              <div className="muted" style={{ fontSize: 13.5, marginTop: 6 }}>{L(lbl)}</div>
            </div>
          ))}
        </div>
        <div className="card card-pad" style={{ marginTop: 22 }}>
          <div style={{ display: 'flex', gap: 14, alignItems: 'center', flexWrap: 'wrap' }}>
            <div style={{ flex: '1 1 260px' }}>
              <div style={{ fontWeight: 800, fontSize: 17 }}>{L(E.ad_inbox)}</div>
              <div className="muted" style={{ fontSize: 13.5, marginTop: 5 }}>{L(E.ad_inbox_d)}</div>
            </div>
            {!st.account && <button className="btn btn-ghost btn-sm" onClick={onAccount}><Icon.user s={15} /> {L(E.ad_identify)}</button>}
          </div>
          <div style={{ display: 'grid', gap: 10, marginTop: 18 }}>
            {st.reports.map((r, i) => (
              <div key={i} className="card" style={{ padding: 16, display: 'flex', gap: 14, alignItems: 'center', flexWrap: 'wrap' }}>
                <span className="badge purple">{engField(r.field, lang)}</span>
                <span style={{ flex: '1 1 220px', fontWeight: 700, fontSize: 15 }}>{r.title}</span>
                <span className="muted" style={{ fontSize: 13, direction: 'ltr' }}>{r.url}</span>
                <span className="muted" style={{ fontSize: 13 }}>{r.deadline ? engDate(r.deadline, lang) : '—'}</span>
                <button className="btn btn-primary btn-sm" onClick={() => approve(i)}><Icon.check s={14} /> {L(E.ad_publish)}</button>
                <button className="btn btn-dark btn-sm" onClick={() => remove(i)}><Icon.trash s={14} /> {L(E.ad_delete)}</button>
              </div>
            ))}
            {!st.reports.length && <div className="muted" style={{ fontSize: 14 }}>{L(E.ad_empty)}</div>}
          </div>
        </div>
        <div className="card card-pad" style={{ marginTop: 22 }}>
          <div style={{ fontWeight: 800, fontSize: 17 }}>{L(E.ad_sched)}</div>
          <div style={{ display: 'grid', gap: 12, marginTop: 16, fontSize: 14 }}>
            {[[L(E.ad_auto), L(E.ad_auto_v)], [L(E.ad_q), engFmt(L(E.ad_q_v), { n: ENG_SOURCES.length })], [L(E.ad_last), st.lastRun ? engDate(st.lastRun.slice(0, 10), lang) : L(E.ad_never)], [L(E.ad_dedupe), L(E.ad_dedupe_v)]].map(([k, v]) => (
              <div key={k} style={{ display: 'flex', justifyContent: 'space-between', gap: 14, flexWrap: 'wrap', borderBottom: '1px solid var(--line)', paddingBottom: 10 }}>
                <span className="muted">{k}</span><span style={{ fontWeight: 600 }}>{v}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- account ----------
function EngineAccount({ st, save, toast, onClose, L, lang }) {
  const a = st.account;
  const [form, setForm] = React.useState(a || { name: '', email: '', interests: [] });
  const INT = [['طب', 'Medical'], ['ذكاء اصطناعي', 'AI'], ['هاكاثون', 'Hackathons'], ['مدن ذكية', 'Smart cities'], ['نسائية', 'Women'], ['اختراعات', 'Inventions'], ['منح بحثية', 'Research grants']];
  const tg = (k) => setForm({ ...form, interests: form.interests.includes(k) ? form.interests.filter((x) => x !== k) : [...form.interests, k] });
  const submit = (e) => {
    e.preventDefault();
    if (!form.name.trim() || !form.email.trim()) return;
    save({ account: { ...form, since: a?.since || new Date().toISOString() } });
    toast(L(a ? E.t_acc_upd : E.t_acc_new));
    onClose();
  };
  return (
    <form onSubmit={submit} style={{ display: 'grid', gap: 16 }}>
      <div>
        <div className="eyebrow"><Icon.user s={15} /> {L(E.ac_eyebrow)}</div>
        <h2 style={{ fontSize: 22, marginTop: 12 }}>{L(a ? E.ac_title2 : E.ac_title)}</h2>
        <p className="muted" style={{ fontSize: 14.5, marginTop: 8, lineHeight: 1.7 }}>{L(E.ac_desc)}</p>
      </div>
      <Field label={L(E.ac_name)} required><input className="input" value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} /></Field>
      <Field label={L(E.ac_email)} required><input className="input" type="email" dir="ltr" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} placeholder="name@example.com" /></Field>
      <div>
        <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 10 }}>{L(E.ac_ints)}</div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          {INT.map(([k, en]) => <button type="button" key={k} className={`chip ${form.interests.includes(k) ? 'on' : ''}`} style={{ cursor: 'pointer' }} onClick={() => tg(k)}>{lang === 'en' ? en : k}</button>)}
        </div>
      </div>
      {a && <div className="muted" style={{ fontSize: 13 }}>{engFmt(L(E.ac_member), { d: engDate(a.since.slice(0, 10), lang), f: st.favs.length, r: st.reports.length })}</div>}
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
        <button className="btn btn-primary" type="submit"><EIcon.bell s={16} /> {L(a ? E.ac_save : E.ac_create)}</button>
        <button className="btn btn-dark" type="button" onClick={onClose}>{L(E.close)}</button>
      </div>
    </form>
  );
}

// ---------- report a hackathon ----------
function EngineReport({ st, save, toast, onClose, L, lang }) {
  const [f, setF] = React.useState({ title: '', org: '', url: '', deadline: '', field: 'هاكاثون', note: '' });
  const submit = (e) => {
    e.preventDefault();
    if (!f.title.trim() || !f.url.trim()) return;
    save({ reports: [...st.reports, { ...f, at: new Date().toISOString() }] });
    toast(L(E.t_report));
    onClose();
  };
  return (
    <form onSubmit={submit} style={{ display: 'grid', gap: 16 }}>
      <div>
        <div className="eyebrow"><Icon.plus s={15} /> {L(E.rp_eyebrow)}</div>
        <h2 style={{ fontSize: 22, marginTop: 12 }}>{L(E.rp_title)}</h2>
        <p className="muted" style={{ fontSize: 14.5, marginTop: 8, lineHeight: 1.7 }}>{L(E.rp_desc)}</p>
      </div>
      <Field label={L(E.rp_name)} required><input className="input" value={f.title} onChange={(e) => setF({ ...f, title: e.target.value })} placeholder={L(E.rp_name_ph)} /></Field>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0,1fr))', gap: 14 }}>
        <Field label={L(E.rp_org)}><input className="input" value={f.org} onChange={(e) => setF({ ...f, org: e.target.value })} /></Field>
        <Field label={L(E.r_field)}>
          <select className="select" value={f.field} onChange={(e) => setF({ ...f, field: e.target.value })}>
            {ENG_FIELDS.map((x) => <option key={x} value={x}>{engField(x, lang)}</option>)}
          </select>
        </Field>
      </div>
      <Field label={L(E.rp_url)} required><input className="input" dir="ltr" value={f.url} onChange={(e) => setF({ ...f, url: e.target.value })} placeholder="https://" /></Field>
      <Field label={L(E.rp_close)}><input className="input" type="date" value={f.deadline} onChange={(e) => setF({ ...f, deadline: e.target.value })} /></Field>
      <Field label={L(E.rp_note)}><textarea className="textarea" rows={3} value={f.note} onChange={(e) => setF({ ...f, note: e.target.value })} placeholder={L(E.rp_note_ph)} /></Field>
      <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
        <button className="btn btn-primary" type="submit"><Icon.check s={16} /> {L(E.rp_send)}</button>
        <button className="btn btn-dark" type="button" onClick={onClose}>{L(E.cancel)}</button>
      </div>
    </form>
  );
}

Object.assign(window, { EnginePage, EngineCard, EngineDetail, EngineFilters, EngineCalendar, EngineNews, EngineSources, EngineAnalytics, EngineAdmin, EngineAccount, EngineReport, EIcon });
