// EU AI Act Compliance Checker — interactive bilingual (HE/EN) questionnaire.
// Logic faithful to the Future of Life Institute flowchart "How will the EU AI Act
// affect my AI system?" (v1.0, 28 July 2025). Lawyerit-branded tool, FLI credited.
// Not affiliated with the EU. Indicative only, not legal advice.

// ────────────────────────────────────────────────────────────────────────────
// Reveal-on-scroll (shared pattern with other pages)
function useAiactReveal() {
  React.useEffect(() => {
    const timer = setTimeout(() => {
      const obs = new IntersectionObserver((entries) => {
        entries.forEach(e => {
          if (e.isIntersecting) { e.target.classList.add('revealed'); obs.unobserve(e.target); }
        });
      }, { threshold: 0.12 });
      document.querySelectorAll('[data-reveal]').forEach(el => obs.observe(el));
      return () => obs.disconnect();
    }, 80);
    return () => clearTimeout(timer);
  }, []);
}

// ────────────────────────────────────────────────────────────────────────────
// Obligations / outcomes catalog  (tone: red | orange | purple | blue | green | gray)
const AIACT_OBL = {
  AILiteracy:        { tone: 'blue',   art: 'Article 4',            he: ['אוריינות AI', 'כספק או מפעיל, עליכם להבטיח רמת אוריינות AI מספקת בקרב הצוות שלכם והעוסקים בהפעלת המערכת מטעמכם.'], en: ['AI Literacy', 'As a provider or deployer, you must ensure a sufficient level of AI literacy among your staff and those operating the system on your behalf.'] },
  Handover:          { tone: 'blue',   art: 'Article 25',          he: ['מסירה (Handover)', 'שינוי שביצע גורם במורד השרשרת הופך אותו ל"ספק". אתם, כספק המקורי, חדלים להיחשב ספק של המערכת המשונה, אך חלה עליכם חובה לספק לספק החדש מידע, חומרים וגישה.'], en: ['Handover', 'A downstream modification makes that party a "provider". You, as the original provider, are no longer the provider of the modified system, but you must supply the new provider with information, materials and access.'] },
  BecomeProvider:    { tone: 'orange', art: 'Article 25',          he: ['הפכתם ל"ספק"', 'לצורך החוק אתם נחשבים כעת "ספק", ותקבלו את חובות הספק בהתאם, לכל השאלות מכאן ואילך.'], en: ['You became a "Provider"', 'For the purposes of the Act you are now considered a "provider", and receive provider obligations accordingly, for all questions from here on.'] },
  HighRisk:          { tone: 'orange', art: 'Article 6',           he: ['מערכת בסיכון גבוה', 'לפי סעיף 6, מערכת ה-AI שלכם נחשבת "בסיכון גבוה". החובות שיחולו תלויות בסוג הישות שלכם.'], en: ['High-risk system', 'Under Article 6 your AI system is considered "high-risk". The obligations depend on your entity type.'] },
  ProviderObl:       { tone: 'orange', art: 'Article 16',          he: ['חובות ספק (סיכון גבוה)', 'כספק של מערכת בסיכון גבוה, עליכם לעמוד בחובות סעיף 16: ניהול סיכונים, איכות נתונים, תיעוד, שקיפות, פיקוח אנושי ודיוק.'], en: ['Provider obligations (high-risk)', 'As provider of a high-risk system, you must comply with Article 16: risk management, data quality, documentation, transparency, human oversight and accuracy.'] },
  DeployerObl:       { tone: 'orange', art: 'Article 26',          he: ['חובות מפעיל (סיכון גבוה)', 'כמפעיל של מערכת בסיכון גבוה, עליכם לעמוד בחובות סעיף 26.'], en: ['Deployer obligations (high-risk)', 'As deployer of a high-risk system, you must comply with Article 26.'] },
  DistributorObl:    { tone: 'orange', art: 'Article 24',          he: ['חובות מפיץ (סיכון גבוה)', 'כמפיץ של מערכת בסיכון גבוה, עליכם לעמוד בחובות סעיף 24.'], en: ['Distributor obligations (high-risk)', 'As distributor of a high-risk system, you must comply with Article 24.'] },
  ImporterObl:       { tone: 'orange', art: 'Article 23',          he: ['חובות יבואן (סיכון גבוה)', 'כיבואן של מערכת בסיכון גבוה, עליכם לעמוד בחובות סעיף 23.'], en: ['Importer obligations (high-risk)', 'As importer of a high-risk system, you must comply with Article 23.'] },
  ProductManufacturer:{ tone: 'blue',  art: 'Recitals 47, 166',    he: ['יצרן מוצר', 'כיצרן המשווק או מפעיל מערכת AI תחת שמכם או סימנכם המסחרי, חלות עליכם חובות לפי מבוא 47 ו-166. אם המערכת בסיכון גבוה, תיחשבו גם ל"ספק".'], en: ['Product Manufacturer', 'As a manufacturer placing/putting into service an AI system under your name or trademark, you have obligations under Recitals 47 and 166. If the system is high-risk you are also a "provider".'] },
  AuthRep:           { tone: 'blue',   art: 'Articles 22 / 54',    he: ['נציג מורשה', 'כנציג מורשה שמונה בכתב על ידי ספק של מערכת בסיכון גבוה או מודל GPAI, עליכם לעמוד בחובות סעיף 22 ו/או סעיף 54.'], en: ['Authorised Representative', 'As an authorised representative appointed in writing by a provider of a high-risk system or a GPAI model, you must comply with Article 22 and/or Article 54.'] },
  GPAI:              { tone: 'purple', art: 'Article 53',          he: ['מודל AI למטרות כלליות (GPAI)', 'עליכם לעמוד בחובות ספקי מודלי GPAI לפי סעיף 53. ייתכן שיחולו גם חובות מערכות בסיכון גבוה, במישרין או בעקיפין (מבוא 85).'], en: ['General-Purpose AI model (GPAI)', 'You must follow the obligations for providers of GPAI models under Article 53. High-risk obligations may also apply, directly or indirectly (Recital 85).'] },
  GPAISystemic:      { tone: 'purple', art: 'Article 55',          he: ['GPAI בעל סיכון מערכתי', 'עליכם לעמוד בחובות ספקי מודלי GPAI בעלי סיכון מערכתי לפי סעיף 55.'], en: ['GPAI with systemic risk', 'You must follow the obligations for providers of GPAI models with systemic risk under Article 55.'] },
  NotifyNCA:         { tone: 'blue',   art: 'Articles 6(4), 49',   he: ['רישום ותיעוד מול הרשות (NCA)', 'אם אתם סבורים שהמערכת אינה מציבה סיכון משמעותי, עליכם לרשום אותה במאגר האירופי לפני השקתה, לתעד את ההערכה ולהעבירה לרשות המוסמכת (NCA) לפי דרישה. סיווג שגוי עלול לחשוף לחובות סיכון-גבוה ולקנסות.'], en: ['Register & document with the NCA', 'If you consider the system not to pose a significant risk, you must register it in the EU database before it goes live, document your assessment and provide it to the National Competent Authority on request. Misclassification can expose you to high-risk obligations and fines.'] },
  TransparencyNatural:  { tone: 'blue', art: 'Article 50(1)',      he: ['שקיפות: יידוע אנשים', 'מערכת המקיימת אינטראקציה ישירה עם אנשים חייבת בחובות שקיפות לפי סעיף 50(1): ליידע את המשתמש שהוא מתקשר עם מערכת AI.'], en: ['Transparency: informing people', 'A system interacting directly with people must meet transparency obligations under Article 50(1): informing the user they are dealing with an AI system.'] },
  TransparencySynthetic:{ tone: 'blue', art: 'Article 50(2)',      he: ['שקיפות: תוכן סינתטי', 'מערכת המייצרת תוכן סינתטי (אודיו, תמונה, וידאו, טקסט) חייבת בסימון התוכן כמיוצר-מכונה לפי סעיף 50(2).'], en: ['Transparency: synthetic content', 'A system generating synthetic audio, image, video or text content must mark it as machine-generated under Article 50(2).'] },
  TransparencyEmotion:  { tone: 'blue', art: 'Article 50(3)',      he: ['שקיפות: זיהוי רגשות / ביומטריה', 'מערכת לזיהוי רגשות או סיווג ביומטרי חייבת ליידע את האנשים החשופים אליה, לפי סעיף 50(3).'], en: ['Transparency: emotion / biometric', 'An emotion-recognition or biometric-categorisation system must inform the people exposed to it, under Article 50(3).'] },
  TransparencyContent:  { tone: 'blue', art: 'Article 50(4)',      he: ['שקיפות: דיפ-פייק / תוכן ציבורי', 'תוכן דמוי-אמת (deep fake) או טקסט שפורסם ליידוע הציבור חייבים בגילוי שהתוכן נוצר או שונה באופן מלאכותי, לפי סעיף 50(4).'], en: ['Transparency: deep fakes / public text', 'Deep-fake content, or text published to inform the public, must be disclosed as artificially generated or manipulated, under Article 50(4).'] },
  FRIA:              { tone: 'orange', art: 'Article 27',          he: ['הערכת השפעה על זכויות יסוד (FRIA)', 'לפני הפעלת מערכת בסיכון גבוה עליכם לבצע הערכת השפעה על זכויות יסוד (למעט מערכות המיועדות לתשתיות קריטיות), לפי סעיף 27.'], en: ['Fundamental Rights Impact Assessment (FRIA)', 'Before deploying a high-risk system you must perform a fundamental rights impact assessment (except systems for critical infrastructure), under Article 27.'] },
  Prohibited:        { tone: 'red',    art: 'Article 5',           he: ['פרקטיקה אסורה', 'המערכת עשויה להיות אסורה לחלוטין תחת ה-AI Act. פרקטיקות אלו מהוות סיכון בלתי-מתקבל על הדעת ואסורות לפי סעיף 5. יש להיוועץ בדחיפות.'], en: ['Prohibited practice', 'The system may be outright prohibited under the AI Act. These practices are an unacceptable risk and are banned under Article 5. Seek advice urgently.'] },
  HighRiskException: { tone: 'green',  art: 'Article 112',         he: ['חריג סיכון-גבוה', 'המערכת ככל הנראה נכנסת לחריג של סעיף 2. משמעות הדבר שרק סעיף 112 חל עליכם, בעיקר מעקב אחר עדכוני החוק ושמירה על ציות מתמשך.'], en: ['High-risk exception', 'Your system likely falls under an Article 2 exception, meaning only Article 112 applies, mainly monitoring updates to the Act and maintaining ongoing compliance.'] },
  OutOfScope:        { tone: 'green',  art: 'Article 2',           he: ['מחוץ לתחולת החוק', 'המערכת ככל הנראה מחוץ לתחולת ה-AI Act. שווה לוודא, התחולה חוצת-גבולות והגדרותיה רחבות.'], en: ['Out of scope', 'Your system is likely outside the scope of the AI Act. Worth confirming, the scope is extraterritorial and its definitions are broad.'] },
  Excluded:          { tone: 'green',  art: 'Article 2',           he: ['מוחרג מהחוק', 'המערכת ככל הנראה מוחרגת מה-AI Act ואינה כפופה לחובות. ראו סעיף 2.'], en: ['Excluded', 'Your system is likely excluded from the AI Act and faces no obligations. See Article 2.'] },
  ExclusionResearch: { tone: 'green',  art: 'Article 2(6),(8)',    he: ['החרגה: מחקר ופיתוח', 'פעילות מחקר ופיתוח מוחרגת בדרך כלל עד להשקת המערכת בשוק או להפעלתה. מערכות שמטרתן הבלעדית מחקר מדעי מוחרגות לחלוטין.'], en: ['Exclusion: research & development', 'R&D activity is generally excluded until the system is placed on the market or put into service. Systems whose sole purpose is scientific research are fully excluded.'] },
  ExclusionOpenSource:{ tone: 'green', art: 'Article 2(12)',       he: ['החרגה: קוד פתוח', 'כל עוד המערכת בקוד פתוח לא הושקה כחלק ממערכת בסיכון גבוה, אסורה, GPAI או חייבת-שקיפות, היא מוחרגת בדרך כלל.'], en: ['Exclusion: open source', 'Until placed on the market as part of a system that is high-risk, prohibited, GPAI or subject to transparency, your open-source system is generally excluded.'] },
  ExclusionPersonal: { tone: 'green',  art: 'Article 2(10)',       he: ['החרגה: שימוש אישי', 'חובות המפעיל אינן חלות על אדם פרטי המשתמש במערכת לפעילות אישית לא-מקצועית בלבד.'], en: ['Exclusion: personal use', 'Deployer obligations do not apply to a natural person using a system purely for personal, non-professional activity.'] },
  NotAI:             { tone: 'gray',   art: 'Article 3(1)',        he: ['אינה "מערכת AI"', 'לפי ההגדרה שסימנתם, המערכת אינה עונה על הגדרת "מערכת בינה מלאכותית" ולכן אינה בתחולת החוק. אם יש ספק, כדאי לבדוק, ההגדרה רחבה.'], en: ['Not an "AI system"', 'Based on your answer, this does not meet the definition of an "AI system" and is out of scope. If in doubt, check, the definition is broad.'] },
  Minimal:           { tone: 'green',  art: '—',                   he: ['סיכון מינימלי', 'לא זוהו חובות מהותיות מעבר לאלה שכבר צוינו. עדיין מומלץ לתעד את ההערכה ולעקוב אחר שינויי רגולציה.'], en: ['Minimal risk', 'No material obligations were identified beyond those already listed. It is still advisable to document your assessment and monitor regulatory change.'] },
};

const TONE_STYLE = {
  red:    { bg: '#FEF2F2', border: '#FCA5A5', fg: '#B91C1C', dot: '#DC2626' },
  orange: { bg: '#FFF7ED', border: '#FED7AA', fg: '#9A3412', dot: '#EA580C' },
  purple: { bg: '#F5F3FF', border: '#DDD6FE', fg: '#6D28D9', dot: '#7C3AED' },
  blue:   { bg: 'var(--turquoise-50)', border: '#CDEDED', fg: 'var(--turquoise-700)', dot: 'var(--turquoise)' },
  green:  { bg: '#ECFDF5', border: '#A7F3D0', fg: '#047857', dot: '#059669' },
  gray:   { bg: '#F7F7F5', border: 'var(--border)', fg: 'var(--ink-2)', dot: 'var(--muted)' },
};

// ────────────────────────────────────────────────────────────────────────────
// State helpers
const initCtx = () => ({
  roles: { provider: false, deployer: false, distributor: false, importer: false, manufacturer: false, authRep: false },
  flags: { highRisk: false, gpai: false, gpaiSystemic: false, prohibited: false, annex1A: false, annex1B: false },
  obligations: [],
});
const addObl = (ctx, ...keys) => ({ ...ctx, obligations: Array.from(new Set([...ctx.obligations, ...keys])) });
const setRole = (ctx, role) => ({ ...ctx, roles: { ...ctx.roles, [role]: true } });
const setFlag = (ctx, flag) => ({ ...ctx, flags: { ...ctx.flags, [flag]: true } });
const markHighRisk = (ctx) => {
  let c = addObl(setFlag(ctx, 'highRisk'), 'HighRisk');
  if (!c.roles.provider) c = addObl(setRole(c, 'provider'), 'BecomeProvider');
  return c;
};
const has = (sel, ...keys) => keys.some(k => sel.includes(k));
const onlyNone = (sel) => sel.length === 0 || (sel.length === 1 && sel[0] === 'none');

// ────────────────────────────────────────────────────────────────────────────
// Nodes.  type: 'single' | 'multi'.  group: entity | risk | scope | rules
// resolve(sel, ctx) → { ctx, next }   (next = node id or 'RESULT')
const AIACT_NODES = {
  AI: {
    group: 'entity', type: 'single',
    tag: ['הגדרה', 'Definition'],
    q: ['האם המערכת שלכם היא "מערכת AI" לפי החוק?',
        'Is your system an "AI system" under the EU AI Act?'],
    hint: ['מערכת AI מוגדרת כמערכת מבוססת-מכונה הפועלת ברמת אוטונומיה כלשהי, שעשויה להסתגל לאחר הפריסה, ומסיקה מהקלט שלה כיצד לייצר פלטים (תחזיות, תוכן, המלצות או החלטות) המשפיעים על סביבות פיזיות או וירטואליות.',
           'An AI system is a machine-based system that operates with some autonomy, may be adaptive after deployment, and infers from its input how to generate outputs (predictions, content, recommendations or decisions) that influence physical or virtual environments.'],
    opts: [
      { k: 'yes', label: ['כן, זו מערכת AI', 'Yes, it is an AI system'] },
      { k: 'no',  label: ['לא / זו אינה מערכת AI', 'No / it is not an AI system'] },
    ],
    resolve: (sel, ctx) => sel.includes('no')
      ? { ctx: addObl(ctx, 'NotAI'), next: 'RESULT' }
      : { ctx, next: 'E1' },
  },

  E1: {
    group: 'entity', type: 'single',
    tag: ['הישות', 'Your entity'],
    q: ['איזה סוג ישות אתם ביחס למערכת?', 'Which kind of entity is your organisation?'],
    hint: ['ניתן להיות כמה סוגים בו-זמנית. במקרה כזה יש למלא את השאלון פעם אחת לכל תפקיד (מבוא 83).',
           'You can be several types at once. If so, complete the questionnaire once for each role (Recital 83).'],
    opts: [
      { k: 'provider',     label: ['ספק: מפתח/מזמין מערכת ומשווק אותה בשמו', 'Provider: develops a system and places it on the market under its own name'] },
      { k: 'deployer',     label: ['מפעיל: משתמש במערכת תחת סמכותו', 'Deployer: uses a system under its own authority'] },
      { k: 'distributor',  label: ['מפיץ: מעמיד מערכת לרשות השוק האירופי', 'Distributor: makes a system available on the EU market'] },
      { k: 'importer',     label: ['יבואן: מייבא לאיחוד מערכת של גורם מחוץ לאיחוד', 'Importer: places a non-EU party’s system on the EU market'] },
      { k: 'manufacturer', label: ['יצרן מוצר: משלב מערכת AI במוצר תחת שמו', 'Product manufacturer: integrates AI into a product under its name'] },
      { k: 'authRep',      label: ['נציג מורשה: מונה בכתב על ידי ספק', 'Authorised representative: appointed in writing by a provider'] },
    ],
    resolve: (sel, ctx) => {
      const k = sel[0];
      if (k === 'provider')     return { ctx: addObl(setRole(ctx, 'provider'), 'AILiteracy'), next: 'E2' };
      if (k === 'deployer')     return { ctx: addObl(setRole(ctx, 'deployer'), 'AILiteracy'), next: 'E2' };
      if (k === 'distributor')  return { ctx: setRole(ctx, 'distributor'), next: 'E2' };
      if (k === 'importer')     return { ctx: setRole(ctx, 'importer'), next: 'E2' };
      if (k === 'manufacturer') return { ctx: setRole(ctx, 'manufacturer'), next: 'E3' };
      return { ctx: addObl(setRole(ctx, 'authRep'), 'AuthRep'), next: 'RESULT' };
    },
  },

  E2: {
    group: 'entity', type: 'multi',
    tag: ['שינויים', 'Modifications'],
    q: ['האם אתם (או גורם במורד השרשרת) מבצעים אחד מהשינויים הבאים במערכת?',
        'Do you (or a downstream party) make any of the following modifications to the system?'],
    opts: [
      { k: 'rename',      label: ['הצמדת שם/סימן מסחרי אחר למערכת', 'Putting a different name / trademark on the system'] },
      { k: 'purpose',     label: ['שינוי המטרה המיועדת של מערכת פעילה', 'Modifying the intended purpose of a system already in operation'] },
      { k: 'substantial', label: ['ביצוע שינוי מהותי במערכת (סעיף 3(23))', 'Performing a substantial modification (Article 3(23))'] },
      { k: 'none',        label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => {
      if (has(sel, 'rename', 'purpose', 'substantial')) {
        let c = ctx.roles.provider ? addObl(ctx, 'Handover')
                                   : addObl(setFlag(setRole(ctx, 'provider'), 'becameProvider'), 'BecomeProvider');
        return { ctx: c, next: 'HR1' };
      }
      return { ctx, next: 'HR1' };
    },
  },

  E3: {
    group: 'entity', type: 'multi',
    tag: ['מוצר', 'Product'],
    q: ['האם המוצר שלכם משלב מערכת AI ומקיים אחד מהתנאים הבאים?',
        'Does your product integrate an AI system AND meet either of the following?'],
    hint: ['רלוונטי רק אם המוצר משווק/מופעל בתוך האיחוד, גם אם אינכם מבוססים באיחוד.',
           'Applies only if the product is placed/put into service within the EU, regardless of where you are established.'],
    opts: [
      { k: 'withProduct',  label: ['ה-AI שווק יחד עם המוצר תחת שמי המסחרי', 'The AI was placed on the market together with my product, under my name'] },
      { k: 'afterProduct', label: ['ה-AI הופעל תחת שמי לאחר שהמוצר כבר שווק', 'The AI was put into service under my name after the product was placed'] },
      { k: 'none',         label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => has(sel, 'withProduct', 'afterProduct')
      ? { ctx, next: 'HR6' }
      : { ctx: addObl(ctx, 'OutOfScope'), next: 'RESULT' },
  },

  HR1: {
    group: 'risk', type: 'multi',
    tag: ['נספח I-B', 'Annex I-B'],
    q: ['האם המערכת נכנסת לאחת מקטגוריות המוצרים המוסדרים הבאות? (נספח I, חלק B)',
        'Does your system fall within any of these regulated product categories? (Annex I, Section B)'],
    opts: [
      { k: 'aviationSec', label: ['אבטחת תעופה אזרחית', 'Civil aviation security'] },
      { k: 'twoWheel',    label: ['רכב דו/תלת-גלגלי ומרכבות', 'Two/three-wheel vehicles & quadricycles'] },
      { k: 'agri',        label: ['רכבים חקלאיים ויעריים', 'Agricultural & forestry vehicles'] },
      { k: 'marine',      label: ['ציוד ימי', 'Marine equipment'] },
      { k: 'rail',        label: ['יכולת-פעולה הדדית של מערכות רכבת', 'Interoperability of rail systems'] },
      { k: 'motor',       label: ['כלי רכב מנועיים וגרוריהם', 'Motor vehicles and their trailers'] },
      { k: 'aviation',    label: ['תעופה אזרחית', 'Civil aviation'] },
      { k: 'none',        label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => onlyNone(sel)
      ? { ctx, next: 'HR2' }
      : { ctx: setFlag(ctx, 'annex1B'), next: 'HR3' },
  },

  HR2: {
    group: 'risk', type: 'multi',
    tag: ['נספח I-A', 'Annex I-A'],
    q: ['האם המערכת נכנסת לאחת מקטגוריות המוצרים המוסדרים הבאות? (נספח I, חלק A)',
        'Does your system fall within any of these regulated product categories? (Annex I, Section A)'],
    opts: [
      { k: 'machinery', label: ['מכונות', 'Machinery'] },
      { k: 'toys',      label: ['צעצועים', 'Toys'] },
      { k: 'craft',     label: ['כלי שיט לפנאי', 'Recreational craft & personal watercraft'] },
      { k: 'lifts',     label: ['מעליות ורכיבי בטיחות שלהן', 'Lifts and their safety components'] },
      { k: 'atex',      label: ['ציוד לסביבות נפיצות', 'Equipment for potentially explosive atmospheres'] },
      { k: 'radio',     label: ['ציוד רדיו', 'Radio equipment'] },
      { k: 'pressure',  label: ['ציוד לחץ', 'Pressure equipment'] },
      { k: 'cableway',  label: ['מתקני כבלים', 'Cableway installations'] },
      { k: 'ppe',       label: ['ציוד מגן אישי', 'Personal protective equipment'] },
      { k: 'gas',       label: ['מכשירים הבוערים בגז', 'Appliances burning gaseous fuels'] },
      { k: 'medical',   label: ['מכשור רפואי', 'Medical devices'] },
      { k: 'ivd',       label: ['מכשור רפואי לאבחון (IVD)', 'In-vitro diagnostic medical devices'] },
      { k: 'none',      label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => onlyNone(sel)
      ? { ctx, next: 'HR4' }
      : { ctx: setFlag(ctx, 'annex1A'), next: 'HR3' },
  },

  HR3: {
    group: 'risk', type: 'single',
    tag: ['הערכת תאימות', 'Conformity'],
    q: ['האם המוצר (או המוצר שהמערכת שלכם היא "רכיב בטיחות" בו) נדרש לעבור הערכת תאימות של צד שלישי לפי דין אירופי קיים?',
        'Is the product (or the product for which your system is a "safety component") required to undergo a third-party conformity assessment under existing EU law?'],
    hint: ['כל קטגוריה בנספח I חלק A מקושרת לדין אירופי קיים. חלק מהמוצרים חייבים בהערכת צד-שלישי לפי אותו דין. אם המוצר שלכם חייב, סמנו "כן". אם קיימת אפשרות לוותר ואתם עומדים בתנאי סעיף 43(3), ניתן לסמן "לא". בספק? כדאי להיוועץ בעו"ד.',
           'Each Annex I-A category maps to an existing EU law; some products require a third-party assessment under it. If yours does, choose "Yes". If you can opt out and meet Article 43(3), you may choose "No". Unsure? Consult a lawyer.'],
    opts: [
      { k: 'yes', label: ['כן', 'Yes'] },
      { k: 'no',  label: ['לא', 'No'] },
    ],
    resolve: (sel, ctx) => sel[0] === 'yes'
      ? { ctx: markHighRisk(ctx), next: 'S1' }
      : { ctx, next: 'HR4' },
  },

  HR4: {
    group: 'risk', type: 'multi',
    tag: ['נספח III', 'Annex III'],
    q: ['האם המערכת נכנסת לאחת מקטגוריות הסיכון-הגבוה הבאות? (נספח III)',
        'Does your system fall within any of these high-risk categories? (Annex III)'],
    opts: [
      { k: 'biometrics',  label: ['ביומטריה', 'Biometrics'] },
      { k: 'critical',    label: ['תשתיות קריטיות', 'Critical infrastructure'] },
      { k: 'education',   label: ['חינוך והכשרה מקצועית', 'Education & vocational training'] },
      { k: 'employment',  label: ['תעסוקה, ניהול עובדים וגישה לתעסוקה עצמאית', 'Employment, worker management & self-employment access'] },
      { k: 'essential',   label: ['גישה לשירותים פרטיים וציבוריים חיוניים והטבות', 'Access to essential private & public services and benefits'] },
      { k: 'lawEnf',      label: ['אכיפת חוק', 'Law enforcement'] },
      { k: 'migration',   label: ['הגירה, מקלט ובקרת גבולות', 'Migration, asylum & border control'] },
      { k: 'justice',     label: ['מערכת המשפט ותהליכים דמוקרטיים', 'Administration of justice & democratic processes'] },
      { k: 'none',        label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => onlyNone(sel)
      ? { ctx, next: 'S1' }
      : { ctx, next: 'HR5' },
  },

  HR5: {
    group: 'risk', type: 'single',
    tag: ['משמעות הסיכון', 'Significance'],
    q: ['האם המערכת מציבה סיכון משמעותי לפגיעה בבריאות, בטיחות או זכויות יסוד של אדם?',
        'Does your system pose a significant risk of harm to the health, safety or fundamental rights of any person?'],
    hint: ['אין סיכון משמעותי אם המערכת: מבצעת משימה פרוצדורלית צרה; משפרת תוצאה של פעילות אנושית שהושלמה; מזהה דפוסי-החלטה או סטיות מבלי להחליף/להשפיע על הערכה אנושית ללא בקרה; או מבצעת משימת הכנה בלבד. אם מתקיים אחד מאלה, סמנו "לא". פרופיילינג של בני-אדם נחשב תמיד לסיכון גבוה, סמנו "כן".',
           'No significant risk if the system: performs a narrow procedural task; improves the result of a completed human activity; detects decision patterns/deviations without replacing human review; or performs a preparatory task. If any applies, choose "No". Profiling of natural persons is always high-risk, choose "Yes".'],
    opts: [
      { k: 'yes', label: ['כן', 'Yes'] },
      { k: 'no',  label: ['לא', 'No'] },
    ],
    resolve: (sel, ctx) => sel[0] === 'yes'
      ? { ctx: markHighRisk(ctx), next: 'S1' }
      : { ctx: ctx.roles.provider ? addObl(ctx, 'NotifyNCA') : ctx, next: 'S1' },
  },

  HR6: {
    group: 'risk', type: 'multi',
    tag: ['רכיב בטיחות', 'Safety component'],
    q: ['האם המוצר כולל מערכת AI כ"רכיב בטיחות" ונכנס לאחת מהקטגוריות הבאות?',
        'Does your product include an AI system as a "safety component" AND fall within any of these categories?'],
    hint: ['רכיב בטיחות: רכיב הממלא פונקציית בטיחות, שכשלו מסכן בריאות ובטיחות של אנשים או רכוש (סעיף 3(14)).',
           'Safety component: a component fulfilling a safety function whose failure endangers the health/safety of persons or property (Article 3(14)).'],
    opts: [
      { k: 'machinery', label: ['מכונות', 'Machinery'] },
      { k: 'toys',      label: ['צעצועים', 'Toys'] },
      { k: 'craft',     label: ['כלי שיט לפנאי', 'Recreational craft & personal watercraft'] },
      { k: 'lifts',     label: ['מעליות ורכיבי בטיחות שלהן', 'Lifts and their safety components'] },
      { k: 'atex',      label: ['ציוד לסביבות נפיצות', 'Equipment for potentially explosive atmospheres'] },
      { k: 'radio',     label: ['ציוד רדיו', 'Radio equipment'] },
      { k: 'pressure',  label: ['ציוד לחץ', 'Pressure equipment'] },
      { k: 'cableway',  label: ['מתקני כבלים', 'Cableway installations'] },
      { k: 'ppe',       label: ['ציוד מגן אישי', 'Personal protective equipment'] },
      { k: 'gas',       label: ['מכשירים הבוערים בגז', 'Appliances burning gaseous fuels'] },
      { k: 'medical',   label: ['מכשור רפואי', 'Medical devices'] },
      { k: 'ivd',       label: ['מכשור רפואי לאבחון (IVD)', 'In-vitro diagnostic medical devices'] },
      { k: 'none',      label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => onlyNone(sel)
      ? { ctx: addObl(ctx, 'ProductManufacturer'), next: 'S1' }
      : { ctx: setFlag(markHighRisk(ctx), 'annex1A'), next: 'S1' },
  },

  S1: {
    group: 'scope', type: 'multi',
    tag: ['תחולה', 'Scope'],
    q: ['האם מתקיים לגביכם אחד מהתנאים הבאים?', 'Do you meet any of the following criteria?'],
    hint: ['התחולה חוצת-גבולות: גם גורם מחוץ לאיחוד עשוי להיכנס אם הפלט של המערכת נעשה בו שימוש באיחוד.',
           'The scope is extraterritorial: a non-EU party can be caught if the system’s output is used in the EU.'],
    opts: [
      { k: 'placeAI',       label: ['אני משווק/מפעיל מערכות AI באיחוד', 'I place / put into service AI systems in the EU'] },
      { k: 'placeGPAI',     label: ['אני משווק מודלי AI למטרות כלליות (GPAI) באיחוד', 'I place General-Purpose AI models on the market in the EU'] },
      { k: 'establishedEU', label: ['אני מבוסס או ממוקם בתוך האיחוד', 'I am established or located within the EU'] },
      { k: 'importerEU',    label: ['אני באיחוד ומשווק מערכת הנושאת שם של גורם מחוץ לאיחוד', 'I am in the EU and place a system bearing a non-EU party’s name'] },
      { k: 'outputEU',      label: ['הפלט של המערכת שלי נעשה בו שימוש באיחוד', 'My system’s output is used in the EU'] },
      { k: 'none',          label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => {
      if (onlyNone(sel)) return { ctx: addObl(ctx, 'OutOfScope'), next: 'RESULT' };
      let c = ctx;
      if (sel.includes('placeAI'))       c = setRole(c, 'provider');
      if (sel.includes('placeGPAI'))     c = addObl(setFlag(setRole(c, 'provider'), 'gpai'), 'GPAI');
      if (sel.includes('establishedEU')) c = setRole(c, 'deployer');
      if (sel.includes('importerEU'))    c = setRole(c, 'importer');
      return { ctx: c, next: c.flags.gpai ? 'R1' : 'R2' };
    },
  },

  R1: {
    group: 'rules', type: 'multi',
    tag: ['GPAI', 'GPAI'],
    q: ['האם מודל ה-GPAI שלכם מקיים אחד מהתנאים הבאים?',
        'Does your GPAI model meet any of the following criteria?'],
    hint: ['יכולת השפעה גבוהה: מודל נחשב כבעל יכולת-השפעה גבוהה אם סך חישוב האימון עולה על 10^25 פעולות נקודה-צפה (סעיף 51(2)).',
           'High-impact capabilities: a model qualifies if the cumulative training compute exceeds 10^25 floating-point operations (Article 51(2)).'],
    opts: [
      { k: 'highImpact', label: ['יש לו יכולות בעלות השפעה גבוהה', 'It has high-impact capabilities'] },
      { k: 'commission', label: ['הנציבות קבעה שיש לו יכולות/השפעה גבוהות (נספח XIII)', 'The Commission decided it has high capabilities/impact (Annex XIII)'] },
      { k: 'none',       label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => has(sel, 'highImpact', 'commission')
      ? { ctx: addObl(setFlag(ctx, 'gpaiSystemic'), 'GPAISystemic'), next: 'R2' }
      : { ctx, next: 'R2' },
  },

  R2: {
    group: 'rules', type: 'multi',
    tag: ['החרגות', 'Exclusions'],
    q: ['האם המערכת או השימוש בה נכנסים לאחת מהקטגוריות הבאות?',
        'Does your system or use case fall within any of the following?'],
    opts: [
      { k: 'military',     label: ['מערכות המפותחות ומשמשות למטרות צבאיות בלבד', 'Systems developed & used exclusively for military purposes'] },
      { k: 'thirdCountry', label: ['רשויות/ארגונים במדינות שלישיות לאכיפת חוק ושת"פ שיפוטי', 'Third-country authorities/organisations for law enforcement & judicial cooperation'] },
      { k: 'research',     label: ['פעילות מחקר ופיתוח של AI', 'AI research & development activity'] },
      { k: 'openSource',   label: ['רכיבי AI המסופקים ברישיון קוד-פתוח חופשי', 'AI components provided under free & open-source licences'] },
      { k: 'personal',     label: ['שימוש אישי לא-מקצועי בלבד', 'Purely personal, non-professional use'] },
      { k: 'none',         label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => {
      if (has(sel, 'military', 'thirdCountry')) return { ctx: addObl(ctx, 'Excluded'), next: 'RESULT' };
      let c = ctx;
      if (sel.includes('research'))   c = addObl(c, 'ExclusionResearch');
      if (sel.includes('openSource')) c = addObl(c, 'ExclusionOpenSource');
      if (sel.includes('personal'))   c = addObl(c, 'ExclusionPersonal');
      return { ctx: c, next: 'R3' };
    },
  },

  R3: {
    group: 'rules', type: 'multi',
    tag: ['אסור', 'Prohibited'],
    q: ['האם המערכת מבצעת אחת מהפונקציות הבאות?',
        'Does your system perform any of these functions?'],
    hint: ['פונקציות אלו מהוות סיכון בלתי-מתקבל על הדעת ואסורות לפי סעיף 5.',
           'These functions are an unacceptable risk and are prohibited under Article 5.'],
    opts: [
      { k: 'subliminal',  label: ['טכניקות סמויות, מניפולציה והטעיה', 'Subliminal techniques, manipulation & deception'] },
      { k: 'exploit',     label: ['ניצול פגיעוּיות', 'Exploiting vulnerabilities'] },
      { k: 'bioCateg',    label: ['סיווג ביומטרי', 'Biometric categorisation'] },
      { k: 'social',      label: ['ניקוד חברתי', 'Social scoring'] },
      { k: 'predictive',  label: ['שיטור מנבא', 'Predictive policing'] },
      { k: 'facialDB',    label: ['הרחבת מאגרי זיהוי פנים', 'Expanding facial-recognition databases'] },
      { k: 'emotionWork', label: ['זיהוי רגשות במקום עבודה/חינוך (למעט רפואי/בטיחותי)', 'Emotion recognition at work/education (except medical/safety)'] },
      { k: 'realBio',     label: ['זיהוי ביומטרי מרחוק בזמן אמת', 'Real-time remote biometrics'] },
      { k: 'none',        label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => {
      if (onlyNone(sel)) return { ctx, next: 'R4' };
      const c = addObl(setFlag(ctx, 'prohibited'), 'Prohibited');
      return { ctx: c, next: (c.roles.provider || c.roles.deployer) ? 'R4' : 'RESULT' };
    },
  },

  R4: {
    group: 'rules', type: 'multi',
    tag: ['שקיפות', 'Transparency'],
    q: ['האם המערכת מבצעת אחת מהפונקציות הבאות?',
        'Does your system perform any of these functions?'],
    opts: [
      { k: 'deepfake',    label: ['יצירה/שינוי של תמונה, אודיו או וידאו כדיפ-פייק', 'Generating/manipulating image, audio or video as a deep fake'] },
      { k: 'publicText',  label: ['יצירת טקסט המתפרסם ליידוע הציבור בעניינים ציבוריים', 'Generating text published to inform the public on matters of public interest'] },
      { k: 'emotionBio',  label: ['זיהוי רגשות או סיווג ביומטרי', 'Emotion recognition or biometric categorisation'] },
      { k: 'interacting', label: ['אינטראקציה ישירה עם בני אדם', 'Interacting directly with people'] },
      { k: 'synthetic',   label: ['יצירת תוכן סינתטי (אודיו, תמונה, וידאו, טקסט)', 'Generating synthetic audio, image, video or text'] },
      { k: 'none',        label: ['אף אחד מהאמור', 'None of the above'] },
    ],
    resolve: (sel, ctx) => {
      let c = ctx;
      if (sel.includes('interacting')) c = addObl(c, 'TransparencyNatural');
      if (sel.includes('synthetic'))   c = addObl(c, 'TransparencySynthetic');
      if (sel.includes('emotionBio'))  c = addObl(c, 'TransparencyEmotion');
      if (has(sel, 'deepfake', 'publicText')) c = addObl(c, 'TransparencyContent');
      const next = (c.roles.deployer && c.flags.highRisk) ? 'R5' : 'RESULT';
      return { ctx: c, next };
    },
  },

  R5: {
    group: 'rules', type: 'single',
    tag: ['זכויות יסוד', 'Fundamental rights'],
    q: ['האם אתם גוף מהמשפט הציבורי, או גוף פרטי המספק שירותים ציבוריים?',
        'Are you a body governed by public law, or a private entity providing public services?'],
    hint: ['רלוונטי למפעיל של מערכת בסיכון גבוה (מבוא 96).', 'Relevant to a deployer of a high-risk system (Recital 96).'],
    opts: [
      { k: 'yes', label: ['כן', 'Yes'] },
      { k: 'no',  label: ['לא', 'No'] },
    ],
    resolve: (sel, ctx) => sel[0] === 'yes'
      ? { ctx: addObl(ctx, 'FRIA'), next: 'RESULT' }
      : { ctx, next: 'RESULT' },
  },
};

const GROUP_LABEL = {
  entity: ['התפקיד שלכם', 'Your role'],
  risk:   ['רמת הסיכון', 'Risk level'],
  scope:  ['תחולה', 'Scope'],
  rules:  ['כללים מיוחדים', 'Specific rules'],
};
const GROUP_ORDER = ['entity', 'risk', 'scope', 'rules'];

// Add role-based obligations at the end, based on accumulated roles + high-risk.
function finalizeObligations(ctx) {
  let keys = [...ctx.obligations];
  if (ctx.flags.highRisk) {
    if (ctx.roles.provider)    keys.push('ProviderObl');
    if (ctx.roles.deployer)    keys.push('DeployerObl');
    if (ctx.roles.distributor) keys.push('DistributorObl');
    if (ctx.roles.importer)    keys.push('ImporterObl');
  }
  if (ctx.roles.manufacturer && !keys.includes('ProductManufacturer')) keys.push('ProductManufacturer');
  keys = Array.from(new Set(keys));
  const meaningful = keys.filter(k => !['NotAI', 'OutOfScope', 'Excluded'].includes(k));
  if (meaningful.length === 0 && !keys.some(k => ['NotAI', 'OutOfScope', 'Excluded'].includes(k))) keys.push('Minimal');
  // Order: red → orange → purple → blue → green → gray
  const rank = { red: 0, orange: 1, purple: 2, blue: 3, green: 4, gray: 5 };
  return keys.sort((a, b) => rank[AIACT_OBL[a].tone] - rank[AIACT_OBL[b].tone]);
}

function headlineFor(keys) {
  if (keys.includes('Prohibited'))    return { tone: 'red',    he: ['פרקטיקה אסורה', 'המערכת עשויה להיות אסורה תחת ה-AI Act. יש לפעול בדחיפות.'], en: ['Prohibited practice', 'Your system may be banned under the AI Act. Act urgently.'] };
  if (keys.includes('HighRisk'))      return { tone: 'orange', he: ['סיכון גבוה', 'המערכת מסווגת כסיכון גבוה, עם חבילת חובות משמעותית.'], en: ['High-risk', 'Your system is classified high-risk, with a substantial set of obligations.'] };
  if (keys.includes('GPAISystemic'))  return { tone: 'purple', he: ['GPAI בעל סיכון מערכתי', 'מודל למטרות כלליות בעל סיכון מערכתי, עם החובות המחמירות ביותר על מודלים.'], en: ['GPAI with systemic risk', 'A general-purpose model with systemic risk, the strictest model-level obligations.'] };
  if (keys.includes('GPAI'))          return { tone: 'purple', he: ['מודל GPAI', 'מודל AI למטרות כלליות, עם חובות ספק ייעודיות.'], en: ['GPAI model', 'A general-purpose AI model, with dedicated provider obligations.'] };
  if (keys.some(k => k.startsWith('Transparency'))) return { tone: 'blue', he: ['סיכון מוגבל: חובות שקיפות', 'המערכת חייבת בעיקר בחובות שקיפות כלפי המשתמשים.'], en: ['Limited risk: transparency', 'Your system mainly carries transparency duties toward users.'] };
  if (keys.includes('NotAI') || keys.includes('OutOfScope') || keys.includes('Excluded'))
    return { tone: 'green', he: ['ככל הנראה מחוץ לתחולה', 'לא זוהו חובות מהותיות. עם זאת, כדאי לתעד ולוודא.'], en: ['Likely out of scope', 'No material obligations identified. Still, document and confirm.'] };
  return { tone: 'green', he: ['סיכון מינימלי', 'לא זוהו חובות מהותיות מעבר למפורט למטה.'], en: ['Minimal risk', 'No material obligations beyond what is listed below.'] };
}

// ────────────────────────────────────────────────────────────────────────────
// Components
function AIActBreadcrumb() {
  const lang = useLang();
  return (
    <div className="container" style={{ paddingTop: 20, paddingBottom: 12, fontSize: 13, color: 'var(--muted)' }}>
      <a href="Lawyerit Homepage.html" style={{ color: 'var(--muted)' }}>{t(lang, 'דף הבית', 'Home')}</a>
      <span style={{ margin: '0 8px', color: 'var(--border)' }}>/</span>
      <a href="Lawyerit Homepage.html#services" style={{ color: 'var(--muted)' }}>{t(lang, 'שירותים', 'Services')}</a>
      <span style={{ margin: '0 8px', color: 'var(--border)' }}>/</span>
      <span style={{ color: 'var(--ink-2)' }}>{t(lang, 'בדיקת AI Act', 'AI Act check')}</span>
    </div>
  );
}

function AIActHero() {
  useAiactReveal();
  const lang = useLang();
  return (
    <section style={{ paddingTop: 40, paddingBottom: 40 }}>
      <div className="container" style={{ maxWidth: 780 }}>
        <div className="eyebrow fade-up">{t(lang, 'כלי חינמי · EU AI Act', 'Free tool · EU AI Act')}</div>
        <h1 className="fade-up fade-up-d1" style={{ fontSize: 'clamp(34px, 4.6vw, 54px)', fontWeight: 700, lineHeight: 1.1, letterSpacing: '-0.035em', marginBottom: 20 }}>
          {t(lang, 'איך ה-', 'How will the ')}
          <span style={{ color: 'var(--turquoise-700)' }}>EU AI Act</span>
          {t(lang, ' משפיע על מערכת ה-AI שלכם?', ' affect your AI system?')}
        </h1>
        <p className="fade-up fade-up-d2" style={{ fontSize: 18.5, lineHeight: 1.6, color: 'var(--muted)', maxWidth: 640 }}>
          {t(lang,
            'ענו על מספר שאלות קצרות לגבי מערכת ה-AI שלכם, וקבלו מיפוי ראשוני של הסיווג והחובות שעשויים לחול עליכם תחת חוק ה-AI האירופי. ללא עלות, בעברית ובאנגלית.',
            'Answer a few short questions about your AI system and get an initial map of the classification and obligations that may apply to you under the EU AI Act. Free, in Hebrew and English.')}
        </p>
      </div>
    </section>
  );
}

function AIActOption({ node, opt, selected, onToggle, lang }) {
  const isMulti = node.type === 'multi';
  return (
    <button
      onClick={onToggle}
      style={{
        width: '100%', textAlign: 'start', display: 'flex', alignItems: 'center', gap: 14,
        background: selected ? 'var(--turquoise-50)' : 'white',
        border: '1px solid ' + (selected ? 'var(--turquoise)' : 'var(--border)'),
        borderRadius: 12, padding: '15px 18px', cursor: 'pointer', fontFamily: 'inherit',
        transition: 'all 0.15s', marginBottom: 10,
      }}
      onMouseEnter={e => { if (!selected) e.currentTarget.style.borderColor = 'var(--turquoise-700)'; }}
      onMouseLeave={e => { if (!selected) e.currentTarget.style.borderColor = 'var(--border)'; }}
    >
      <span style={{
        width: 22, height: 22, flexShrink: 0,
        borderRadius: isMulti ? 6 : '50%',
        border: '2px solid ' + (selected ? 'var(--turquoise)' : 'var(--border)'),
        background: selected ? 'var(--turquoise)' : 'white',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        {selected && <svg width="12" height="12" viewBox="0 0 10 10"><path d="M2 5.5 L4 7.5 L8 3" stroke="white" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" fill="none" /></svg>}
      </span>
      <span style={{ fontSize: 15.5, color: 'var(--ink-2)', lineHeight: 1.4 }}>{t(lang, opt.label[0], opt.label[1])}</span>
    </button>
  );
}

function AIActChecker() {
  const lang = useLang();
  const [nodeId, setNodeId] = React.useState('AI');
  const [sel, setSel] = React.useState([]);
  const [ctx, setCtx] = React.useState(initCtx());
  const [history, setHistory] = React.useState([]); // [{nodeId, sel, ctx}]
  const [done, setDone] = React.useState(false);
  const topRef = React.useRef(null);

  const node = AIACT_NODES[nodeId];
  const stepNo = history.length + 1;

  const scrollTop = () => { if (topRef.current) topRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }); };

  const toggle = (k) => {
    if (node.type === 'single') { setSel([k]); return; }
    // multi: "none" is exclusive
    if (k === 'none') { setSel(['none']); return; }
    setSel(prev => {
      const next = prev.filter(x => x !== 'none');
      return next.includes(k) ? next.filter(x => x !== k) : [...next, k];
    });
  };

  const canContinue = sel.length > 0;

  const onContinue = () => {
    if (!canContinue) return;
    const { ctx: nextCtx, next } = node.resolve(sel, ctx);
    setHistory(h => [...h, { nodeId, sel, ctx }]);
    setCtx(nextCtx);
    if (next === 'RESULT') { setDone(true); }
    else { setNodeId(next); setSel([]); }
    setTimeout(scrollTop, 30);
  };

  const onBack = () => {
    if (history.length === 0) return;
    const prev = history[history.length - 1];
    setHistory(h => h.slice(0, -1));
    setNodeId(prev.nodeId);
    setSel(prev.sel);
    setCtx(prev.ctx);
    setDone(false);
    setTimeout(scrollTop, 30);
  };

  const onRestart = () => {
    setNodeId('AI'); setSel([]); setCtx(initCtx()); setHistory([]); setDone(false);
    setTimeout(scrollTop, 30);
  };

  if (done) return <AIActResult ctx={ctx} onBack={onBack} onRestart={onRestart} topRef={topRef} />;

  const groupIdx = GROUP_ORDER.indexOf(node.group);

  return (
    <section className="section" style={{ paddingTop: 12 }}>
      <div className="container" style={{ maxWidth: 720 }}>
        <div ref={topRef} />
        {/* Stage indicator */}
        <div data-reveal style={{ display: 'flex', gap: 8, marginBottom: 22, flexWrap: 'wrap' }}>
          {GROUP_ORDER.map((g, i) => (
            <div key={g} style={{
              flex: 1, minWidth: 120, padding: '9px 12px', borderRadius: 9, textAlign: 'center',
              fontSize: 12, fontWeight: 600, letterSpacing: '-0.01em',
              background: i === groupIdx ? 'var(--turquoise)' : (i < groupIdx ? 'var(--turquoise-50)' : 'var(--bg-2)'),
              color: i === groupIdx ? 'white' : (i < groupIdx ? 'var(--turquoise-700)' : 'var(--muted)'),
              border: '1px solid ' + (i <= groupIdx ? 'transparent' : 'var(--border)'),
              transition: 'all 0.2s',
            }}>
              {t(lang, GROUP_LABEL[g][0], GROUP_LABEL[g][1])}
            </div>
          ))}
        </div>

        <div style={{ background: 'white', border: '1px solid var(--border)', borderRadius: 18, padding: 'clamp(22px, 4vw, 36px)', boxShadow: 'var(--shadow-md)' }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16, gap: 12 }}>
            <span className="en" style={{
              fontSize: 10.5, fontWeight: 700, letterSpacing: '0.06em', textTransform: 'uppercase',
              color: 'var(--turquoise-700)', background: 'var(--turquoise-50)', padding: '3px 9px', borderRadius: 5,
            }}>{t(lang, node.tag[0], node.tag[1])}</span>
            <span style={{ fontSize: 13, color: 'var(--muted)', fontWeight: 500 }}>{t(lang, 'שאלה ', 'Step ')}{stepNo}</span>
          </div>

          <h2 style={{ fontSize: 'clamp(20px, 2.6vw, 26px)', fontWeight: 700, letterSpacing: '-0.02em', lineHeight: 1.3, marginBottom: node.hint ? 12 : 22 }}>
            {t(lang, node.q[0], node.q[1])}
          </h2>

          {node.hint && (
            <p style={{ fontSize: 13.5, lineHeight: 1.6, color: 'var(--muted)', marginBottom: 22, paddingInlineStart: 14, borderInlineStart: '3px solid var(--turquoise-50)' }}>
              {t(lang, node.hint[0], node.hint[1])}
            </p>
          )}

          {node.type === 'multi' && (
            <p style={{ fontSize: 12.5, color: 'var(--muted-2, var(--muted))', marginBottom: 12, fontWeight: 500 }}>
              {t(lang, 'ניתן לסמן יותר מאפשרות אחת', 'You can select more than one')}
            </p>
          )}

          <div>
            {node.opts.map(opt => (
              <AIActOption key={opt.k} node={node} opt={opt} selected={sel.includes(opt.k)} onToggle={() => toggle(opt.k)} lang={lang} />
            ))}
          </div>

          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 24, gap: 12 }}>
            <button onClick={onBack} disabled={history.length === 0} style={{
              background: 'transparent', border: 'none', cursor: history.length === 0 ? 'default' : 'pointer',
              color: history.length === 0 ? 'var(--border)' : 'var(--muted)', fontSize: 14, fontFamily: 'inherit',
              display: 'flex', alignItems: 'center', gap: 6, padding: '8px 4px',
            }}>
              <svg width="14" height="14" viewBox="0 0 16 16" style={{ transform: lang === 'en' ? 'none' : 'scaleX(-1)' }}><path d="M10 4L6 8l4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" fill="none" /></svg>
              {t(lang, 'חזרה', 'Back')}
            </button>
            <button onClick={onContinue} disabled={!canContinue} className="btn btn-brand btn-lg" style={{
              opacity: canContinue ? 1 : 0.45, cursor: canContinue ? 'pointer' : 'default',
              paddingInline: 30, position: 'relative',
            }}>
              {t(lang, 'המשך', 'Continue')}
              <svg width="15" height="15" viewBox="0 0 16 16" style={{ transform: lang === 'en' ? 'scaleX(-1)' : 'none' }}><path d="M10 4L6 8l4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" fill="none" /></svg>
            </button>
          </div>
        </div>

        <p style={{ textAlign: 'center', fontSize: 12.5, color: 'var(--muted)', marginTop: 18 }}>
          {t(lang, 'הכלי אינדיקטיבי בלבד ואינו מהווה ייעוץ משפטי.', 'This tool is indicative only and is not legal advice.')}
        </p>
      </div>
    </section>
  );
}

function AIActResult({ ctx, onBack, onRestart, topRef }) {
  const lang = useLang();
  const keys = finalizeObligations(ctx);
  const head = headlineFor(keys);
  const hs = TONE_STYLE[head.tone];

  return (
    <section className="section" style={{ paddingTop: 12 }}>
      <div className="container" style={{ maxWidth: 760 }}>
        <div ref={topRef} />

        {/* Headline classification */}
        <div data-reveal style={{ background: hs.bg, border: '1px solid ' + hs.border, borderRadius: 18, padding: 'clamp(24px, 4vw, 36px)', marginBottom: 22 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
            <span style={{ width: 11, height: 11, borderRadius: '50%', background: hs.dot }} />
            <span style={{ fontSize: 12.5, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: hs.fg }}>
              {t(lang, 'הסיווג הראשוני שלכם', 'Your initial classification')}
            </span>
          </div>
          <h2 style={{ fontSize: 'clamp(28px, 4vw, 40px)', fontWeight: 700, letterSpacing: '-0.03em', marginBottom: 10, color: hs.fg }}>
            {t(lang, head.he[0], head.en[0])}
          </h2>
          <p style={{ fontSize: 16.5, lineHeight: 1.6, color: 'var(--ink-2)' }}>{t(lang, head.he[1], head.en[1])}</p>
        </div>

        {/* Obligations list */}
        <div data-reveal data-delay="1" style={{ marginBottom: 8 }}>
          <h3 style={{ fontSize: 20, fontWeight: 700, letterSpacing: '-0.02em', marginBottom: 6 }}>
            {t(lang, 'מה זה אומר מבחינתכם', 'What this means for you')}
          </h3>
          <p style={{ fontSize: 14.5, color: 'var(--muted)', marginBottom: 20 }}>
            {t(lang, keys.length + ' נקודות שזוהו על סמך התשובות שלכם:', keys.length + ' points identified from your answers:')}
          </p>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 32 }}>
          {keys.map((k, i) => {
            const o = AIACT_OBL[k]; const s = TONE_STYLE[o.tone];
            return (
              <div key={k} data-reveal data-delay={String(Math.min(i + 1, 3))} style={{
                background: 'white', border: '1px solid var(--border)', borderRadius: 14,
                padding: '18px 20px', display: 'flex', gap: 15, alignItems: 'flex-start',
                borderInlineStart: '4px solid ' + s.dot,
              }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', marginBottom: 6 }}>
                    <h4 style={{ fontSize: 16.5, fontWeight: 700, letterSpacing: '-0.01em' }}>{t(lang, o.he[0], o.en[0])}</h4>
                    {o.art !== '—' && (
                      <span className="en" style={{ fontSize: 10.5, fontWeight: 600, color: s.fg, background: s.bg, border: '1px solid ' + s.border, padding: '2px 8px', borderRadius: 20, direction: 'ltr' }}>{o.art}</span>
                    )}
                  </div>
                  <p style={{ fontSize: 14.5, lineHeight: 1.6, color: 'var(--muted)' }}>{t(lang, o.he[1], o.en[1])}</p>
                </div>
              </div>
            );
          })}
        </div>

        {/* CTA */}
        <div data-reveal style={{
          background: 'linear-gradient(135deg, #2FB5B5 0%, #47CBCB 100%)', color: '#fff',
          borderRadius: 20, padding: 'clamp(28px, 4vw, 40px)', textAlign: 'center', marginBottom: 24,
        }}>
          <h3 style={{ fontSize: 'clamp(22px, 3vw, 30px)', fontWeight: 700, letterSpacing: '-0.02em', marginBottom: 12, lineHeight: 1.2 }}>
            {t(lang, 'רוצים לתרגם את זה לתוכנית עבודה?', 'Want to turn this into an action plan?')}
          </h3>
          <p style={{ fontSize: 16.5, lineHeight: 1.55, color: 'rgba(255,255,255,0.9)', maxWidth: 520, marginInline: 'auto', marginBottom: 26 }}>
            {t(lang,
              'הסיווג הוא ההתחלה. אנחנו מלווים חברות SaaS, ביטוח וטכנולוגיה ביישום בפועל של חובות ה-AI Act, ה-GDPR וחוק הגנת הפרטיות, בשיחת היכרות של 30 דקות, ללא עלות.',
              'Classification is the start. We help SaaS, insurance and tech companies actually implement AI Act, GDPR and privacy-law obligations, in a free 30-minute intro call.')}
          </p>
          <a href="https://www.cal.eu/lawyer-it/30min" target="_blank" rel="noopener noreferrer" className="btn btn-lg" style={{
            background: '#0F1115', color: '#fff', padding: '15px 30px', paddingInlineEnd: 48, fontSize: 16, borderRadius: 12, position: 'relative',
          }}>
            {t(lang, 'קבעו שיחה', 'Book a call')}
            <svg width="16" height="16" viewBox="0 0 16 16" style={{ transform: lang === 'en' ? 'scaleX(-1)' : 'none' }}><path d="M10 4L6 8l4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" fill="none" /></svg>
            <span style={{ position: 'absolute', top: -6, insetInlineEnd: -6, width: 14, height: 14, borderRadius: '50%', background: 'var(--orange)', boxShadow: '0 0 0 3px rgba(237,137,54,0.25)' }} />
          </a>
        </div>

        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 20 }}>
          <button onClick={onBack} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: 'var(--muted)', fontSize: 14, fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 6 }}>
            <svg width="14" height="14" viewBox="0 0 16 16" style={{ transform: lang === 'en' ? 'none' : 'scaleX(-1)' }}><path d="M10 4L6 8l4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" fill="none" /></svg>
            {t(lang, 'לשאלה הקודמת', 'Previous question')}
          </button>
          <button onClick={onRestart} style={{ background: 'transparent', border: '1px solid var(--border)', borderRadius: 9, cursor: 'pointer', color: 'var(--ink-2)', fontSize: 14, fontFamily: 'inherit', padding: '8px 16px' }}>
            {t(lang, 'להתחיל מחדש', 'Start over')}
          </button>
        </div>
      </div>
    </section>
  );
}

function AIActAttribution() {
  const lang = useLang();
  return (
    <section style={{ background: 'var(--bg-2)', padding: '48px 0' }}>
      <div className="container" style={{ maxWidth: 760 }}>
        <div style={{ background: 'white', border: '1px solid var(--border)', borderRadius: 16, padding: '26px 28px' }}>
          <h3 style={{ fontSize: 15, fontWeight: 700, marginBottom: 12, letterSpacing: '-0.01em' }}>
            {t(lang, 'קרדיט, מקור והבהרה משפטית', 'Credit, source & legal disclaimer')}
          </h3>
          <p style={{ fontSize: 13.5, lineHeight: 1.7, color: 'var(--muted)', marginBottom: 10 }}>
            {t(lang,
              'לוגיקת השאלון מבוססת על תרשים הזרימה "How will the EU AI Act affect my AI system?" (גרסה 1.0, יולי 2025) של ',
              'The questionnaire logic is based on the flowchart "How will the EU AI Act affect my AI system?" (v1.0, July 2025) by the ')}
            <a href="https://futureoflife.org" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--turquoise-700)', fontWeight: 600 }}>Future of Life Institute</a>
            {t(lang, ', המשותף לשימוש חופשי לא-מסחרי. כלי זה מוצע על ידי Lawyerit ללא עלות. Lawyerit ו-Future of Life Institute אינם מזוהים עם האיחוד האירופי.',
                    ', shared for free non-commercial use. Lawyerit offers this tool free of charge. Neither Lawyerit nor the Future of Life Institute is affiliated with the European Union.')}
          </p>
          <p style={{ fontSize: 13.5, lineHeight: 1.7, color: 'var(--muted)' }}>
            {t(lang,
              'התוצאה היא הערכה ראשונית ואינדיקטיבית בלבד, אינה ממצה כל חריג, ואינה מהווה ייעוץ משפטי או יחסי עו"ד–לקוח. לפני קבלת החלטות יש להיוועץ בעורך/ת דין. הנוסח המחייב הוא ה-AI Act עצמו.',
              'The result is an initial, indicative estimate only, does not capture every exception, and is not legal advice or an attorney–client relationship. Consult a lawyer before making decisions. The binding text is the AI Act itself.')}
          </p>
        </div>
      </div>
    </section>
  );
}

// ────────────────────────────────────────────────────────────────────────────
// FAQ — visible Q&A that mirrors the FAQPage JSON-LD in the HTML head (SEO/GEO).
const AIACT_FAQ = [
  { he: ['האם ה-EU AI Act חל על חברה ישראלית?',
         'כן, ייתכן. החוק חוצה-גבולות: הוא חל גם על חברות מחוץ לאיחוד האירופי אם הן משווקות מערכת AI באיחוד, או אם הפלט של המערכת נעשה בו שימוש באיחוד. חברות SaaS ישראליות רבות עם לקוחות באירופה נכנסות לתחולה.'],
    en: ['Does the EU AI Act apply to an Israeli company?',
         'Possibly, yes. The Act is extraterritorial: it applies to non-EU companies that place an AI system on the EU market, or whose system output is used in the EU. Many Israeli SaaS companies with EU customers are in scope.'] },
  { he: ['מהי מערכת AI בסיכון גבוה?',
         'מערכות בסיכון גבוה הן בעיקר כאלה המשמשות בתחומים רגישים לפי נספח III, כמו ביומטריה, תעסוקה וגיוס, חינוך, שירותים חיוניים, אכיפת חוק והגירה, וכן AI המהווה רכיב בטיחות במוצרים מוסדרים. עליהן חלה חבילת החובות המחמירה ביותר.'],
    en: ['What is a high-risk AI system?',
         'High-risk systems are mainly those used in sensitive areas under Annex III, such as biometrics, employment and recruitment, education, essential services, law enforcement and migration, plus AI that is a safety component of a regulated product. They carry the strictest obligations.'] },
  { he: ['מה ההבדל בין מודל GPAI (כמו ChatGPT) למערכת AI רגילה?',
         'מודל AI למטרות כלליות (GPAI), כמו מודל שפה גדול, כפוף לחובות ספק ייעודיות (סעיף 53), ואם יש לו יכולות בעלות השפעה גבוהה, גם לחובות סיכון מערכתי (סעיף 55). מי שרק משתמש במודל כזה במוצר שלו עשוי להיות כפוף לחובות שקיפות, ולא לחובות המודל עצמו.'],
    en: ['How is a GPAI model (like ChatGPT) different from a regular AI system?',
         'A general-purpose AI (GPAI) model, such as a large language model, is subject to dedicated provider obligations (Article 53), and if it has high-impact capabilities, also systemic-risk obligations (Article 55). Companies that merely use such a model in their product may face transparency duties rather than the model-level obligations.'] },
  { he: ['צ׳אטבוט או כלי AI גנרטיבי, חייבים בשקיפות?',
         'בדרך כלל כן. מערכת המקיימת אינטראקציה ישירה עם אנשים חייבת ליידע שמדובר ב-AI, ותוכן סינתטי או דיפ-פייק חייב בסימון, לפי סעיף 50. אלו חובות "סיכון מוגבל" וקלות יחסית ליישום.'],
    en: ['Do chatbots and generative-AI tools have transparency duties?',
         'Usually yes. A system interacting directly with people must disclose it is an AI, and synthetic or deep-fake content must be labelled, under Article 50. These are "limited-risk" transparency duties and relatively light to implement.'] },
  { he: ['מה באמת חל עליכם היום, אחרי הדחייה?',
         'לוח הזמנים שונה ביוני 2026. מה שכבר חל: איסורי הפרקטיקות האסורות, חובות ספקי מודלי GPAI (מאוגוסט 2025), וחובות השקיפות לפי סעיף 50 (מ-2 באוגוסט 2026), שרלוונטיות לכל צ׳אטבוט, דיפ-פייק ותוכן מיוצר. מה שנדחה במסגרת ה-Digital Omnibus: חובות הסיכון הגבוה. מערכות עצמאיות לפי נספח III נדחו ל-2 בדצמבר 2027, ומערכות המשולבות במוצרים מוסדרים לפי נספח I לאוגוסט 2028. חשוב: דחייה אינה פטור. הסיווג שלכם לא השתנה, רק המועד, וזה הזמן להיערך בו.'],
    en: ['What actually applies to you today, after the postponement?',
         'The timetable changed in June 2026. Already in force: the bans on prohibited practices, GPAI provider obligations (from August 2025), and the Article 50 transparency duties (from 2 August 2026), which reach any chatbot, deep fake or generated content. Postponed by the Digital Omnibus: the high-risk obligations. Standalone Annex III systems moved to 2 December 2027, and AI embedded in regulated products under Annex I to August 2028. Note: a postponement is not an exemption. Your classification did not change, only the date, and this is the window to get ready in.'] },
];

function AIActFAQ() {
  const lang = useLang();
  const [open, setOpen] = React.useState(0);
  return (
    <section className="section" style={{ paddingTop: 8 }}>
      <div className="container" style={{ maxWidth: 760 }}>
        <div data-reveal style={{ marginBottom: 28 }}>
          <div className="eyebrow">{t(lang, 'שאלות נפוצות', 'FAQ')}</div>
          <h2 style={{ fontSize: 'clamp(26px, 3vw, 36px)', letterSpacing: '-0.03em' }}>
            {t(lang, 'ה-EU AI Act, בשפה של בעלי עסקים', 'The EU AI Act, in founder language')}
          </h2>
        </div>
        <div data-reveal data-delay="1" style={{ background: 'white', border: '1px solid var(--border)', borderRadius: 16, overflow: 'hidden' }}>
          {AIACT_FAQ.map((it, i) => {
            const [q, a] = t(lang, it.he, it.en);
            return (
              <div key={i} style={{ borderTop: i ? '1px solid var(--border-2)' : 'none' }}>
                <button onClick={() => setOpen(open === i ? -1 : i)} style={{
                  width: '100%', padding: '20px 24px', display: 'flex', justifyContent: 'space-between',
                  alignItems: 'center', gap: 16, background: 'transparent', border: 'none', cursor: 'pointer',
                  fontFamily: 'inherit', textAlign: 'start',
                }}>
                  <span style={{ fontSize: 16.5, fontWeight: 600, color: 'var(--ink)', letterSpacing: '-0.005em' }}>{q}</span>
                  <span style={{
                    width: 28, height: 28, borderRadius: '50%', flexShrink: 0,
                    background: open === i ? 'var(--turquoise)' : 'var(--bg-2)',
                    color: open === i ? 'white' : 'var(--ink-2)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.2s',
                  }}>
                    <svg width="12" height="12" viewBox="0 0 12 12" style={{ transform: open === i ? 'rotate(45deg)' : 'none', transition: 'transform 0.2s' }}>
                      <path d="M6 2v8M2 6h8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
                    </svg>
                  </span>
                </button>
                {open === i && (
                  <div style={{ padding: '0 24px 22px' }}>
                    <p style={{ fontSize: 15.5, color: 'var(--muted)', lineHeight: 1.7 }}>{a}</p>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {
  AIActBreadcrumb, AIActHero, AIActChecker, AIActResult, AIActFAQ, AIActAttribution,
});
