/* ════════════════════════════════════════════════════════════════════════
   Internal Counsel · Risk Confidence Assessment
   ─────────────────────────────────────────────
   Audience: Syndikusanwältin / Senior Employment Counsel (Germany).
   Architecture follows deploy/Audience Assessment Architecture.md:
     Q1–Q10   Best-practice questions (Always / Usually / Sometimes / Rarely / Never)
     Q11      Current reality  (file-maturity self-locate)
     Q12      Desired reality  (target reconstructability posture)
     Q13      Obstacles        (multi-select)
     Q14      Preferred solution
     Q15      Open text        ("Anything else?")

   Five tracks (per deploy/*_DEFENSIBILITY_CHECKLIST.md design docs):
     A · CONDUCT          (verhaltensbedingt, §1 KSchG / §626 BGB conduct frame)
     B · PERSONAL CAP.    (personenbedingt, illness / §167 SGB IX BEM)
     C · RESTRUCTURING    (betriebsbedingt, §1 Abs.3 KSchG Sozialauswahl, §17 KSchG)
     D · EXTRAORDINARY    (§626 BGB, 14-day clock, Abmahnung waiver)
     E · SENIOR EXEC.     (leitender Angestellter, §5(3) BetrVG, §31 SprAuG)

   Tone is calibrated to the persona:
     LANDS: procedural defensibility · evidentiary chain · reconstructable ·
            audit trail · contemporaneous record · §-anchored
     REPELS: drafting · summarisation · productivity · black-box scoring

   The assessment scores 0–100 "reconstructability" from the 10 best-practice
   questions only. Q11–Q15 generate insights, qualification, and next-step
   routing but do not move the score.
   ════════════════════════════════════════════════════════════════════════ */

const { useEffect, useMemo, useState } = React;

/* ── Question scale ───────────────────────────────────────────── */
const FREQ_SCALE = [
  { id: "always",    label: "Always",    de: "Immer",      points: 4 },
  { id: "usually",   label: "Usually",   de: "Meistens",   points: 3 },
  { id: "sometimes", label: "Sometimes", de: "Teilweise",  points: 2 },
  { id: "rarely",    label: "Rarely",    de: "Selten",     points: 1 },
  { id: "never",     label: "Never",     de: "Nie",        points: 0 },
];

/* ── Maturity, target, obstacles, solutions ──────────────────── */
const MATURITY = [
  { id: "low",   label: "Low maturity",      de: "Niedrige Reife",
    blurb: "Files are built case-by-case; reconstruction relies heavily on the HRBP, line manager, or counsel's own memory." },
  { id: "mid",   label: "Moderate maturity", de: "Mittlere Reife",
    blurb: "Templates and process exist, but evidence-to-conclusion traceability and §-deadlines remain inconsistent across sites or managers." },
  { id: "high",  label: "High maturity",     de: "Hohe Reife",
    blurb: "Reconstructable, dated, evidence-anchored files are the norm; the silent KPI is actively tracked." },
];

const TARGET = [
  { id: "audit_ready",     label: "Audit-ready, on demand",
    blurb: "Any file, any time, handed to Internal Audit or DPA without remediation." },
  { id: "court_ready",     label: "Court-ready handoff",
    blurb: "External counsel can defend the file on first read &mdash; no rebuild, no clarification calls." },
  { id: "consistent",      label: "Consistent across sites",
    blurb: "Similar cases handled similarly; arbitrary-treatment and AGG-indicator exposure closed." },
  { id: "regulator_ready", label: "Regulator-ready under §26 BDSG",
    blurb: "Processing legality, Art. 9 special-category basis, and Art. 35 DPIA reconstructable without scramble." },
];

const OBSTACLES = [
  { id: "time",        label: "Time / deadline pressure" },
  { id: "knowledge",   label: "Knowledge gaps in HR / line managers" },
  { id: "tools",       label: "Tooling does not support reconstruction" },
  { id: "process",     label: "No standard procedural template across cases" },
  { id: "leadership",  label: "Leadership treats process as overhead" },
  { id: "external",    label: "External counsel friction on handoff" },
  { id: "governance",  label: "AI / data-governance uncertainty (Art. 22, §26 BDSG, §203 StGB)" },
  { id: "consistency", label: "Inconsistency across sites / business units" },
];

const SOLUTIONS = [
  { id: "diy_template", label: "DIY template / playbook",
    blurb: "Counsel-built §-anchored checklist, applied case-by-case." },
  { id: "tooling",      label: "Structured tooling / workflow",
    blurb: "A system that captures evidence, dates, and approvals as part of the workflow." },
  { id: "audit",        label: "External Verfahrenscheck audit",
    blurb: "A one-time reconstruction audit on one anonymised matter, RDG-safe." },
  { id: "training",     label: "Counsel-led HR training",
    blurb: "Direct upskill of HRBPs and line managers on the procedural failure modes." },
  { id: "managed",      label: "Managed counsel-grade workflow",
    blurb: "Ongoing managed support across the procedural backbone." },
];

/* ── Risk bands ──────────────────────────────────────────────── */
const BANDS = [
  { min: 85, max: 100,
    en: "Strongly reconstructable",
    de: "Tragfähig rekonstruierbar",
    qualification: "high_fit",
    tone: "green",
    insight: "The file would likely survive reconstruction by an outsider. Remaining work is consistency at scale, not foundational gaps." },
  { min: 65, max: 84,
    en: "Mostly reconstructable, with named gaps",
    de: "Überwiegend rekonstruierbar &mdash; mit benennbaren Lücken",
    qualification: "high_fit",
    tone: "amber",
    insight: "The structural backbone is in place, but at least one §-anchored gap is visible. These are the cases where merits are strong and procedure becomes the attack surface." },
  { min: 40, max: 64,
    en: "Partially reconstructable",
    de: "Teilweise rekonstruierbar",
    qualification: "medium_fit",
    tone: "amber",
    insight: "Reconstruction depends on memory of the HRBP, line manager, or counsel. Procedural defects of the kind that void substantively correct decisions are likely present." },
  { min: 0, max: 39,
    en: "Weakly reconstructable",
    de: "Schwach rekonstruierbar",
    qualification: "low_fit_or_urgent",
    tone: "red",
    insight: "The file is unlikely to support the position under hostile review. Reconstruction failure &mdash; not merits &mdash; would be the dominant risk." },
];
const bandFor = (score) => BANDS.find((b) => score >= b.min && score <= b.max) || BANDS[BANDS.length - 1];

/* ════════════════════════════════════════════════════════════════════════
   TRACK DEFINITIONS
   Each track ships its own 10 best-practice questions, traced to the
   corresponding *_DEFENSIBILITY_CHECKLIST.md design doc:
     - gate-anchored (G0 / G1 / G2.* / G3 / G7 / G8 / G9)
     - evidence-coded (ED-* / EB-* / EC-* / E14-* / E31-*)
     - statute-cited (§ refs)
   ════════════════════════════════════════════════════════════════════════ */

const TRACKS = [
  /* ── A. CONDUCT ──────────────────────────────────────────── */
  {
    id: "A",
    key: "conduct",
    code: "ROUTE_D / verhaltensbedingt",
    name: "Conduct-Based",
    name_de: "Verhaltensbedingte Kündigung",
    blurb: "Performance / behaviour-driven termination. Abmahnung doctrine, §626(2) clock for extraordinary, ultima-ratio, §102 BetrVG hearing.",
    statutes: ["§1 Abs.2 KSchG", "§626 BGB", "§102 BetrVG", "AGG §22"],
    source: "CONDUCT_DEFENSIBILITY_CHECKLIST.md",
    questions: [
      { n: 1, anchor: "G2.D1 / ED-1",
        text: "The triggering event (the conduct itself) is captured in the file with date, time, place, named witnesses, and a contemporaneous account &mdash; not a retrospective summary." },
      { n: 2, anchor: "G2.D3 / ED-8",
        text: "Where the case relies on prior conduct, a written Abmahnung exists for the same type of conduct &mdash; or, if waived, the waiver basis (SEVERITY_EXTREME / FUTILITY_DEMONSTRATED) is justified in writing." },
      { n: 3, anchor: "G2.D2 / ED-2",
        text: "The decision-maker's <em>reliable-knowledge</em> date (Kenntnis des Kündigungsberechtigten) is documented &mdash; not first-witness or line-manager knowledge." },
      { n: 4, anchor: "G2.D2 / §626 II",
        text: "For extraordinary terminations, issuance is documented inside the 14-day §626 Abs. 2 BGB window from reliable knowledge, including delivery proof." },
      { n: 5, anchor: "G3 / ED-6 / ED-7",
        text: "A written Interessenabwägung weighs severity, tenure, prior conduct, personal circumstances, and milder means (Versetzung, Ermahnung, ordinary termination)." },
      { n: 6, anchor: "G2.WF / §623 BGB",
        text: "Written form is observed: wet-ink original, authorised signatory under §174 BGB, delivery proof (Zugang) on file." },
      { n: 7, anchor: "G1 / ED-9",
        text: "Where a Betriebsrat exists, the §102 hearing record covers identity, type, reason, route; the response window (1 week / 3 days for extraordinary) is respected; no Nachschieben of grounds." },
      { n: 8, anchor: "G7 / ED-11",
        text: "AGG §22 indicia have been screened; if any indicator is present, an employer rebuttal is documented in writing." },
      { n: 9, anchor: "Audit trail",
        text: "Every key factual assertion in the legal analysis can be linked to a contemporaneous piece of evidence in the file &mdash; not to recollection." },
      { n: 10, anchor: "External handoff",
        text: "External counsel could pick up the file today and defend the decision from the record alone &mdash; without an HR briefing call." },
    ],
    obstaclesExtra: [
      { id: "abmahnung",  label: "Abmahnung chain is incomplete or subject-matter mismatched" },
      { id: "clock",      label: "§626(2) 14-day clock is not deterministically tracked" },
    ],
    primaryFailure: {
      name: "Abmahnung keystone gap",
      cite: "BAG 2 AZR 736/13",
      concern: "Conduct cases collapse on the warning record &mdash; either none exists for the matching conduct, or the waiver basis is asserted without being justified in writing." },
  },

  /* ── B. PERSONAL CAPABILITY ──────────────────────────────── */
  {
    id: "B",
    key: "personal_capability",
    code: "ROUTE_B / personenbedingt",
    name: "Personal Capability",
    name_de: "Personenbedingte Kündigung &mdash; Krankheit / Leistung",
    blurb: "Illness / capability-driven termination. 24-month absence, BEM, negative prognosis, operational impact, Integrationsamt.",
    statutes: ["§1 Abs.2 KSchG", "§167(2) SGB IX", "§168 SGB IX", "§178 SGB IX", "§102 BetrVG"],
    source: "PERSONALCAPAB_DEFENSIBILITY_CHECKLIST.md",
    questions: [
      { n: 1, anchor: "G2.B1 / EB-1",
        text: "An absence record covering at least 24 months is on file, with dates, totals, and a pattern description &mdash; not a manager summary." },
      { n: 2, anchor: "G2.B1 / EB-2 / §167(2) SGB IX",
        text: "A BEM (betriebliches Eingliederungsmanagement) invitation has been sent and dated; the employee's response (ACCEPTED / DECLINED) is captured; if accepted, the exploration is documented." },
      { n: 3, anchor: "G2.B2 / EB-3",
        text: "A negative health prognosis is on file &mdash; with basis, date, and source &mdash; before the termination is issued." },
      { n: 4, anchor: "G2.B2 / EB-4",
        text: "Operational impact is documented with disruption description and cost data &mdash; not asserted in the legal memo only." },
      { n: 5, anchor: "G0.3 / EB-8 / §168 SGB IX",
        text: "If the employee is severely disabled, Integrationsamt approval exists and is dated <em>before</em> the termination issue date." },
      { n: 6, anchor: "SBV / §178 SGB IX",
        text: "If a Schwerbehindertenvertretung exists at the site, its consultation has been documented." },
      { n: 7, anchor: "G1 / EB-7",
        text: "Where a Betriebsrat exists, the §102 hearing is initiated before termination, route-correct, complete, and observes the response window; council response or silence is documented." },
      { n: 8, anchor: "G3 / EB-5",
        text: "Interessenabwägung weighs tenure, age, labour-market position, and the cause of illness (especially if work-related)." },
      { n: 9, anchor: "G3 / EB-6",
        text: "Alternatives &mdash; Versetzung, Teilzeit, Umschulung, workplace modification &mdash; have been evaluated and rejection reasons recorded per alternative." },
      { n: 10, anchor: "Audit / handoff",
        text: "The Personalakte plus medical-prognosis file could be handed to external counsel today and reconstructed without further interview." },
    ],
    obstaclesExtra: [
      { id: "bem_skipped",   label: "BEM invitations are skipped or not consistently dated" },
      { id: "prognosis",     label: "Prognosis basis is informal or undated" },
      { id: "art9",          label: "Art. 9 DSGVO (health data) handling is not documented" },
    ],
    primaryFailure: {
      name: "BEM omission &mdash; ultima-ratio collapse",
      cite: "§167(2) SGB IX, BAG line of authority",
      concern: "Absent or undocumented BEM shifts the ultima-ratio burden to the employer and reads, from outside, as if alternatives were never genuinely explored." },
  },

  /* ── C. RESTRUCTURING ────────────────────────────────────── */
  {
    id: "C",
    key: "restructuring",
    code: "ROUTE_C / betriebsbedingt",
    name: "Restructuring",
    name_de: "Betriebsbedingte Kündigung",
    blurb: "Operational / restructuring termination. Comparable pool, Sozialauswahl scoring, §17 KSchG mass-layoff timing, ultima-ratio Weiterbeschäftigung.",
    statutes: ["§1 Abs.2 KSchG", "§1 Abs.3 KSchG", "§17 KSchG", "§102 BetrVG", "§613a BGB"],
    source: "RESTRUCTURING_DEFENSIBILITY_CHECKLIST.md",
    questions: [
      { n: 1, anchor: "G2.C1 / EC-1",
        text: "The business decision &mdash; positions eliminated, headcount rationale &mdash; is documented and dated before the termination issue date." },
      { n: 2, anchor: "G2.C2 / EC-2",
        text: "The comparable pool is defined by the three-part test (hierarchical / interchangeable / same establishment) with inclusion-exclusion reasoning &mdash; not assumed." },
      { n: 3, anchor: "G2.C3 / EC-3",
        text: "Social data (tenure, age, dependents, disability) is complete for <em>every</em> member of the pool &mdash; not just the selected employee." },
      { n: 4, anchor: "G2.C4 / EC-4",
        text: "A weighting model exists in writing, with justification for the weights chosen &mdash; not just a generic point table." },
      { n: 5, anchor: "G2.C5 / EC-5 / EC-6",
        text: "The scoring matrix is complete <em>and</em> the selected employee is the lowest score in the pool; exemptions, if claimed, are justified per employee (G2.C6 / EC-7)." },
      { n: 6, anchor: "G2.C7 / EC-11 / §17 KSchG",
        text: "If the §17 threshold is met, the Massenentlassungsanzeige is filed <em>before</em> issuance, with agency receipt date on file (post-BAG / EuGH timing jurisprudence)." },
      { n: 7, anchor: "G1.6 / EC-10",
        text: "If a Betriebsrat exists, the §102 hearing letter includes the pool and the social-selection data &mdash; not just the conclusion." },
      { n: 8, anchor: "G3.C / EC-9",
        text: "Per-employee Weiterbeschäftigung alternatives have been evaluated; rejection reasons are case-specific, not boilerplate." },
      { n: 9, anchor: "G2.WF / G7",
        text: "Written form, authorised signatory, delivery proof, and an AGG-clean decision basis are documented for every issued letter in the wave." },
      { n: 10, anchor: "Audit / handoff",
        text: "An external counsel auditing the file today could reconstruct the pool, the scoring, the §17 timing, and the per-employee handling without a project briefing." },
    ],
    obstaclesExtra: [
      { id: "pool_drift",    label: "Pool definition drifts between hearing letter and termination letter" },
      { id: "scoring_opaque",label: "Scoring matrix exists but justification is missing" },
      { id: "mela_timing",   label: "§17 KSchG Massenentlassungsanzeige timing is uncertain" },
    ],
    primaryFailure: {
      name: "Sozialauswahl not in the §102 hearing",
      cite: "G1.6 / EC-10",
      concern: "A generic §102 hearing that omits the pool and scores voids the hearing on route-C even when the substance is otherwise perfect." },
  },

  /* ── D. EXTRAORDINARY ────────────────────────────────────── */
  {
    id: "D",
    key: "extraordinary",
    code: "ROUTE_D / außerordentlich §626",
    name: "Extraordinary",
    name_de: "Außerordentliche / fristlose Kündigung",
    blurb: "Summary termination under §626 BGB. 14-day clock, Abmahnung waiver, compressed 3-day §102 hearing window, §103 BetrVG consent if BR member.",
    statutes: ["§626 BGB", "§626 II BGB", "§102 BetrVG", "§103 BetrVG", "§623 BGB"],
    source: "EXTRAORDINARY_DEFENSIBILITY_CHECKLIST.md",
    questions: [
      { n: 1, anchor: "G2.D2 / ED-2",
        text: "The reliable-knowledge date is attributable to a kündigungsberechtigte Person (not a first witness), with who / when / how recorded." },
      { n: 2, anchor: "G2.D2 / ED-3 / §626 II",
        text: "Termination is documented as issued within 14 days of reliable knowledge &mdash; with delivery proof (Zugang) also within the window." },
      { n: 3, anchor: "G2.D2 / ED-4 (Pattern 6)",
        text: "If the clock was extended for investigation, the investigation log shows it was conducted <em>mit gebotener Eile</em> &mdash; no unjustified gaps." },
      { n: 4, anchor: "G2.D1 / ED-5",
        text: "The <em>wichtiger Grund</em> analysis &mdash; why continued employment until ordinary notice was unzumutbar &mdash; is in writing." },
      { n: 5, anchor: "G3.D1 / ED-6",
        text: "Interessenabwägung weighs severity, tenure, prior conduct, and personal circumstances; the result is reasoned, not boilerplate." },
      { n: 6, anchor: "G3.D2 / ED-7",
        text: "Milder means (ordinary termination, suspension, transfer) are explicitly evaluated and rejected on the record." },
      { n: 7, anchor: "G2.D3 / ED-8",
        text: "Either a prior Abmahnung exists, or the waiver basis (SEVERITY_EXTREME / FUTILITY_DEMONSTRATED) is justified in writing." },
      { n: 8, anchor: "G1 / ED-9 (Pattern 3)",
        text: "If a Betriebsrat exists, the hearing letter discloses core facts, states ROUTE_D, observes the compressed 3-day window, and does not withhold favorable facts." },
      { n: 9, anchor: "G1.8 / G0.3 / ED-10 / §103 BetrVG",
        text: "If the employee is a BR member, §103 BetrVG consent &mdash; or court substitution &mdash; is on file <em>before</em> issuance." },
      { n: 10, anchor: "G2.WF / G4 / G7",
        text: "Written form, comparator consistency, and AGG-clean basis are documented; no Nachschieben between hearing letter and termination letter." },
    ],
    obstaclesExtra: [
      { id: "clock_drift",    label: "Knowledge-date attribution is contested or undocumented" },
      { id: "abmahnung_waiver", label: "Abmahnung waiver basis is asserted but not justified" },
      { id: "compressed",     label: "Compressed 3-day BR window squeezes process" },
    ],
    primaryFailure: {
      name: "14-day clock collapse",
      cite: "§626 II BGB, Pattern 6 (10 BAG anchors)",
      concern: "Most §626 cases die on the clock &mdash; either knowledge is wrongly attributed to a first witness, or issuance / delivery slips past day 14." },
  },

  /* ── E. SENIOR EXECUTIVE ─────────────────────────────────── */
  {
    id: "E",
    key: "senior_executive",
    code: "ROUTE_E / leitender Angestellter",
    name: "Senior Executive",
    name_de: "Leitender Angestellter / Geschäftsführer",
    blurb: "Executive dismissal. §5(3) BetrVG status, §31 SprAuG hearing in place of §102, §14 KSchG Auflösungsantrag, Geschäftsführer service-contract regime.",
    statutes: ["§5(3) BetrVG", "§31 SprAuG", "§14 KSchG", "§626 BGB", "§621 BGB"],
    source: "SENIOR_EXECUTIVE_DEFENSIBILITY_CHECKLIST.md",
    questions: [
      { n: 1, anchor: "G8.1 / E14-a",
        text: "The §5(3) BetrVG basis &mdash; hire/fire OR Prokura OR entrepreneurial tasks &mdash; is documented, not asserted by title alone." },
      { n: 2, anchor: "G8.1 / E14-b",
        text: "Contemporaneous evidence shows the authority is <em>actually exercised</em>, not merely contractually conferred." },
      { n: 3, anchor: "G8.2 / E14-c",
        text: "For Geschäftsführer, the HRB Bestellung, Dienstvertrag, and §621 BGB notice regime are unambiguous &mdash; no mixed Dienst-/Arbeitsvertrag." },
      { n: 4, anchor: "G9.1 / E31-a",
        text: "If a Sprecherausschuss exists, the §31 SprAuG hearing letter covers core facts, the route flag, and any favorable facts &mdash; <em>before</em> issuance." },
      { n: 5, anchor: "G9.2 / E31-a / E31-b",
        text: "The statutory response window (7 days ordinary / 3 days extraordinary) is observed; committee response or silence is documented; termination is not premature." },
      { n: 6, anchor: "G9.3 / E31-a",
        text: "There is hearing-to-litigation congruence &mdash; no Nachschieben of reasons between the hearing letter and any later pleading." },
      { n: 7, anchor: "G0 (existing)",
        text: "Special protections persist for executives &mdash; §15 KSchG, §168 SGB IX, §17 MuSchG, §18 BEEG &mdash; and each applicable screen has been cleared." },
      { n: 8, anchor: "G_KENNTNIS_TIMING / §626 II",
        text: "If the route is extraordinary, the §626 Abs. 2 BGB 14-day clock from reliable knowledge is documented &mdash; executive status does not relax this." },
      { n: 9, anchor: "G3 / G_ABMAHNUNG / G_SOZIALAUSWAHL",
        text: "Where KSchG still applies, proportionality / ultima-ratio, the Abmahnung position, and any (limited) Sozialauswahl analysis are on file." },
      { n: 10, anchor: "G8.3 / §14 KSchG",
        text: "If the §14 KSchG Auflösungsantrag is contemplated, the file pre-supports it: §5(3) basis is proven, not just claimed; no fallback-to-ROUTE_A surprise." },
    ],
    obstaclesExtra: [
      { id: "status_thin",  label: "§5(3) basis is title-driven, not substantively documented" },
      { id: "no_committee", label: "§1 SprAuG threshold met but no committee in place" },
      { id: "nachschieben", label: "Hearing letter ≠ later pleading on core grounds" },
    ],
    primaryFailure: {
      name: "Status carve-out collapse",
      cite: "BAG 2 AZR 505/09 (PATTERN-22)",
      concern: "If §5(3) status is title-driven and the matter falls back to ROUTE_A, §102 BetrVG becomes mandatory &mdash; and the hearing was never run." },
  },
];

const trackById = (id) => TRACKS.find((t) => t.id === id) || TRACKS[0];

/* ── Insight generation ─────────────────────────────────────── */
function buildInsights(track, answers, score, target, obstacles) {
  const out = [];
  const failingQs = Object.entries(answers)
    .filter(([, v]) => v === "never" || v === "rarely")
    .map(([k]) => parseInt(k, 10))
    .sort((a, b) => a - b);
  const softQs = Object.entries(answers)
    .filter(([, v]) => v === "sometimes")
    .map(([k]) => parseInt(k, 10));

  if (failingQs.length) {
    const first = track.questions.find((q) => q.n === failingQs[0]);
    out.push({
      label: "Most exposed gate",
      body: `Question ${failingQs[0]} (${first.anchor}) is the closest case-killing item. Items rarely or never done at this point in the file lifecycle are the failure modes the engine would surface first.`,
    });
  } else if (softQs.length) {
    out.push({
      label: "Soft spot",
      body: `No hard gaps &mdash; but ${softQs.length} item(s) are only “sometimes” done. Consistency, not foundation, is the open question.`,
    });
  } else {
    out.push({
      label: "Foundation",
      body: "Every best-practice item is reported as usually or always done. The remaining work is documentation hygiene and cross-site consistency, not foundational gaps.",
    });
  }

  out.push({
    label: "Primary BAG-style failure mode for this track",
    body: `<strong>${track.primaryFailure.name}</strong> &mdash; ${track.primaryFailure.concern} <em>(${track.primaryFailure.cite})</em>.`,
  });

  if (target) {
    out.push({
      label: "Gap to desired posture",
      body: `Target: <strong>${target.label}</strong>. At this score, the gap is &mdash; ${score < 65 ? "structural; reconstruction would not yet meet that posture." : score < 85 ? "narrow; consistency and one or two named gates separate current from target." : "essentially closed on this matter; sustaining the posture across sites is the open question."}`,
    });
  }

  if (obstacles && obstacles.length) {
    out.push({
      label: "Self-named obstacles",
      body: `You named: ${obstacles.map((o) => `<em>${o.label}</em>`).join(", ")}. Previous attempts that worked on the foundation without these constraints will not transfer cleanly.`,
    });
  }

  return out;
}

function qualificationFor(score, target, solution) {
  const band = bandFor(score);
  if (band.qualification === "low_fit_or_urgent") {
    return {
      title: "Urgent reconstruction posture",
      body: "Reconstruction failure is the dominant risk on this matter. A one-time external Verfahrenscheck on the specific file is the next step &mdash; <em>before</em> external counsel is briefed.",
      cta: "Request a Verfahrenscheck review",
    };
  }
  if (band.qualification === "medium_fit") {
    return {
      title: "Structural gaps to close",
      body: "Foundation exists, but at least one named gate is exposed. The next step depends on whether the gap is process (training) or evidence-capture (workflow).",
      cta: solution && solution.id === "training" ? "Brief a counsel-led HR workshop" : "Discuss a Verfahrenscheck on one matter",
    };
  }
  return {
    title: "Consistency at scale",
    body: "Foundation is solid. The conversation worth having is how to sustain this posture across sites and managers without bottlenecking counsel.",
    cta: solution && solution.id === "managed" ? "Discuss a managed counsel-grade workflow" : "Request a structural review on one matter",
  };
}

/* ── Component styles (scoped) ──────────────────────────────── */
const STYLES = `
.ic-root{
  --paper:#F5F4F0;--surface:#FFFFFF;--fog:#F0EDE6;--warm:#E8E6E0;
  --ink:#111111;--ink-2:#3D4452;--muted:#6B7280;
  --rust:#E5631F;--accent-text:#B04714;
  --rule:#DDD9D3;--rule-soft:#EDEAE5;--panel:#1D1D1D;
  --green:#2E7D32;--green-bg:#E8F0E9;
  --amber:#9A5512;--amber-bg:#F4E9DA;
  --red:#B3261E;--red-bg:#F6E4E1;
  --radius:6px;
  --display:"Bebas Neue","Impact","Arial Narrow",sans-serif;
  --body:"Source Serif 4","Source Serif Pro",Georgia,"Times New Roman",serif;
  --mono:"Roboto Mono",SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
  --shadow-sm:0 2px 8px rgba(0,0,0,0.08);
  --shadow-md:0 6px 24px rgba(0,0,0,0.12);
  font-family:var(--body);color:var(--ink);background:transparent;
  padding:3rem 0 4rem;line-height:1.65;-webkit-font-smoothing:antialiased;
  max-width:1040px;margin:0 auto;
}
[data-theme="dark"] .ic-root{
  --paper:#0E1013;--surface:#16191F;--fog:#1C2027;--warm:#232830;
  --ink:#F2EFE8;--ink-2:#C7C3BA;--muted:#8A8F98;
  --rust:#E5631F;--accent-text:#F0834A;
  --rule:#2A2F38;--rule-soft:#20242B;--panel:#0A0C10;
  --green:#7FB994;--green-bg:rgba(127,185,148,0.12);
  --amber:#D9B36A;--amber-bg:rgba(217,179,106,0.12);
  --red:#E07A55;--red-bg:rgba(224,122,85,0.12);
  --shadow-sm:0 1px 2px rgba(0,0,0,0.45);
  --shadow-md:0 4px 16px rgba(0,0,0,0.5);
}
.ic-card{background:var(--surface);border:1px solid var(--rule);border-radius:var(--radius);padding:2rem;margin-bottom:1.25rem;box-shadow:var(--shadow-sm);}
.ic-card.accent{border-left:3px solid var(--rust);}
.ic-label{font-family:var(--mono);font-size:.7rem;font-weight:500;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);margin:0 0 1rem;}
.ic-label.muted{color:var(--muted);}
.ic-h1{font-family:var(--display);font-size:clamp(2rem,4vw,2.85rem);font-weight:400;line-height:1;letter-spacing:.02em;margin:0 0 .65rem;color:var(--ink);}
.ic-h2{font-family:var(--display);font-size:1.65rem;font-weight:400;letter-spacing:.02em;margin:0 0 .6rem;color:var(--ink);}
.ic-sub{font-family:var(--body);font-size:1.05rem;line-height:1.5;color:var(--ink-2);margin:0 0 .85rem;font-weight:500;}
.ic-help{font-size:.93rem;color:var(--ink-2);margin:0;line-height:1.65;}

.ic-tracks{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:.85rem;margin-top:.5rem;}
.ic-track{display:flex;flex-direction:column;align-items:flex-start;text-align:left;padding:1.1rem 1.25rem;border:1px solid var(--rule);border-radius:var(--radius);background:var(--surface);cursor:pointer;font:inherit;color:inherit;transition:border-color .15s,background .15s,box-shadow .15s,transform .15s;position:relative;}
.ic-track:hover{border-color:var(--ink);transform:translateY(-1px);box-shadow:var(--shadow-md);}
.ic-track[aria-pressed="true"]{border-color:var(--ink);background:var(--fog);box-shadow:inset 3px 0 0 var(--rust);}
.ic-track-id{font-family:var(--mono);font-size:.6rem;font-weight:600;text-transform:uppercase;letter-spacing:.14em;color:var(--accent-text);margin:0 0 .35rem;}
.ic-track-name{font-family:var(--display);font-size:1.15rem;font-weight:400;letter-spacing:.02em;color:var(--ink);margin:0 0 .2rem;line-height:1.1;}
.ic-track-de{font-family:var(--mono);font-size:.68rem;color:var(--muted);margin:0 0 .55rem;}
.ic-track-blurb{font-size:.86rem;line-height:1.45;color:var(--ink-2);margin:0 0 .55rem;}
.ic-track-stat{font-family:var(--mono);font-size:.6rem;color:var(--accent-text);background:var(--fog);border:1px solid var(--rule);padding:.14rem .4rem;border-radius:var(--radius);letter-spacing:.04em;white-space:nowrap;margin-right:.25rem;display:inline-block;margin-bottom:.2rem;}

.ic-progress{font-family:var(--mono);font-size:.72rem;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);margin:0 0 1rem;}
.ic-progress-bar{height:4px;background:var(--rule-soft);border-radius:999px;overflow:hidden;margin-top:.45rem;}
.ic-progress-bar > div{height:100%;background:var(--rust);transition:width .25s;}

.ic-q{padding:1.2rem 0;border-top:1px solid var(--rule-soft);}
.ic-q:first-of-type{border-top:none;padding-top:.25rem;}
.ic-qtext{font-size:1rem;line-height:1.6;margin:0 0 .65rem;color:var(--ink);}
.ic-qnum{font-family:var(--mono);color:var(--accent-text);font-weight:600;font-size:.82rem;margin-right:.45rem;}
.ic-qanchor{font-family:var(--mono);font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:.45rem;}

.ic-seg{display:inline-flex;border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden;flex-wrap:wrap;}
.ic-seg button{appearance:none;border:0;background:var(--surface);padding:.55rem 1rem;font-family:var(--mono);font-size:.7rem;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;color:var(--ink-2);border-right:1px solid var(--rule);transition:background .12s,color .12s;}
.ic-seg button:last-child{border-right:0;}
.ic-seg button:hover{background:var(--fog);color:var(--ink);}
.ic-seg button[aria-pressed="true"]{background:var(--ink);color:#fff;}
[data-theme="dark"] .ic-seg button[aria-pressed="true"]{background:var(--ink);color:var(--paper);}

.ic-actions{display:flex;gap:.85rem;flex-wrap:wrap;margin-top:.5rem;align-items:center;}
.ic-btn{appearance:none;border:1px solid var(--ink);background:var(--ink);color:#fff;padding:.8rem 1.6rem;border-radius:var(--radius);font-family:var(--body);font-size:.92rem;font-weight:600;cursor:pointer;transition:transform .2s cubic-bezier(.16,1,.3,1),box-shadow .2s,background .18s,border-color .18s,color .18s;box-shadow:0 4px 14px rgba(17,17,17,0.22);}
.ic-btn:hover{background:#222;transform:translateY(-2px);box-shadow:0 10px 26px rgba(17,17,17,0.32);}
.ic-btn.rust{background:var(--rust);border-color:var(--rust);box-shadow:0 4px 16px rgba(229,99,31,0.32);}
.ic-btn.rust:hover{background:var(--accent-text);border-color:var(--accent-text);box-shadow:0 12px 28px rgba(229,99,31,0.48);}
.ic-btn.ghost{background:transparent;color:var(--ink-2);border-color:var(--rule);box-shadow:none;}
.ic-btn.ghost:hover{background:rgba(17,17,17,0.035);border-color:var(--ink);color:var(--ink);box-shadow:0 6px 18px rgba(17,17,17,0.12);}
.ic-btn:disabled{opacity:0.4;cursor:not-allowed;transform:none;box-shadow:none;}
[data-theme="dark"] .ic-btn{background:var(--ink);color:var(--paper);border-color:var(--ink);box-shadow:var(--shadow-md);}
[data-theme="dark"] .ic-btn:hover{background:#fff;}
[data-theme="dark"] .ic-btn.rust{background:var(--rust);border-color:var(--rust);color:#fff;}
[data-theme="dark"] .ic-btn.ghost{background:transparent;color:var(--ink-2);border-color:var(--rule);}
[data-theme="dark"] .ic-btn.ghost:hover{color:var(--ink);border-color:var(--ink);}

.ic-validation{font-family:var(--body);font-size:.9rem;color:var(--red);background:var(--red-bg);border:1px solid var(--red);border-radius:var(--radius);padding:.7rem .85rem;margin-top:.85rem;}

.ic-options{display:flex;flex-direction:column;gap:.45rem;}
.ic-option{position:relative;display:flex;flex-direction:column;align-items:flex-start;text-align:left;padding:.85rem 1rem;border:1px solid var(--rule);border-radius:var(--radius);background:var(--surface);cursor:pointer;font:inherit;color:inherit;transition:border-color .15s,background .15s;}
.ic-option:hover{border-color:var(--ink-2);}
.ic-option[aria-pressed="true"]{border-color:var(--ink);background:var(--fog);box-shadow:inset 3px 0 0 var(--rust);}
.ic-option-label{font-family:var(--body);font-weight:600;font-size:.98rem;color:var(--ink);}
.ic-option-de{font-family:var(--mono);font-size:.7rem;color:var(--muted);margin-top:.2rem;letter-spacing:.02em;}
.ic-option-blurb{font-size:.88rem;color:var(--ink-2);margin-top:.35rem;line-height:1.5;}

.ic-chips{display:flex;flex-wrap:wrap;gap:.4rem;}
.ic-chip{appearance:none;border:1px solid var(--rule);background:var(--surface);color:var(--ink-2);padding:.45rem .85rem;border-radius:999px;font-family:var(--mono);font-size:.7rem;letter-spacing:.04em;cursor:pointer;transition:border-color .15s,background .15s,color .15s;}
.ic-chip:hover{border-color:var(--ink-2);color:var(--ink);}
.ic-chip[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff;}
[data-theme="dark"] .ic-chip[aria-pressed="true"]{color:var(--paper);}

.ic-textarea{width:100%;min-height:110px;padding:.85rem 1rem;border:1px solid var(--rule);border-radius:var(--radius);background:var(--surface);color:var(--ink);font:inherit;font-size:.95rem;resize:vertical;line-height:1.55;}
.ic-textarea:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px rgba(229,99,31,0.18);}

/* Results */
.ic-score-unit{font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);display:block;margin-bottom:.35rem;}
.ic-score{font-family:var(--display);font-size:clamp(3rem,9vw,5rem);font-weight:400;letter-spacing:.01em;line-height:.9;margin:.25rem 0 0;color:var(--ink);}
.ic-score.green{color:var(--green);}
.ic-score.amber{color:var(--amber);}
.ic-score.red{color:var(--red);}
.ic-band{font-family:var(--display);font-size:1.5rem;font-weight:400;letter-spacing:.03em;margin:.6rem 0 .1rem;color:var(--ink);}
.ic-band-de{font-family:var(--mono);font-size:.74rem;letter-spacing:.04em;color:var(--muted);}

.ic-insight{padding:1rem 0;border-top:1px solid var(--rule-soft);}
.ic-insight:first-of-type{border-top:none;padding-top:.5rem;}
.ic-insight-label{font-family:var(--mono);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0 0 .35rem;}
.ic-insight-body{font-size:.96rem;line-height:1.65;color:var(--ink);margin:0;}

.ic-summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.85rem;}
.ic-sum{border:1px solid var(--rule);border-radius:var(--radius);padding:1rem;background:var(--fog);}
.ic-sum-val{font-family:var(--mono);font-size:2rem;font-weight:700;line-height:1;margin:0;color:var(--ink);}
.ic-sum-label{font-family:var(--mono);font-size:.62rem;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);margin:.55rem 0 0;line-height:1.4;}

.ic-killer{font-family:var(--body);font-size:1.15rem;font-style:italic;font-weight:400;line-height:1.55;margin:0;color:var(--ink);border-left:2px solid var(--rust);padding-left:1rem;}

.ic-cta-title{font-family:var(--display);font-size:1.6rem;font-weight:400;letter-spacing:.02em;margin:0 0 .55rem;color:var(--ink);}
.ic-cta-title span{color:var(--rust);}
.ic-cta-body{font-size:.95rem;line-height:1.65;color:var(--ink-2);margin:0 0 1.1rem;}

.ic-disclaimer{font-family:var(--mono);font-size:.66rem;color:var(--muted);line-height:1.7;margin:0;letter-spacing:.01em;}

.ic-row{display:flex;flex-wrap:wrap;gap:.45rem;align-items:center;margin-bottom:.85rem;}
.ic-row .ic-stat{font-family:var(--mono);font-size:.62rem;color:var(--accent-text);background:var(--fog);border:1px solid var(--rule);padding:.18rem .45rem;border-radius:var(--radius);letter-spacing:.04em;white-space:nowrap;}

/* ── Email gate / GDPR ───────────────────────────────────── */
.ic-gate-form{display:flex;flex-direction:column;gap:1rem;margin-top:.5rem;}
.ic-field{display:flex;flex-direction:column;gap:.4rem;}
.ic-field-label{font-family:var(--mono);font-size:.65rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
.ic-input{appearance:none;width:100%;padding:.75rem .9rem;border:1px solid var(--rule);border-radius:var(--radius);background:var(--surface);color:var(--ink);font:inherit;font-size:1rem;line-height:1.4;transition:border-color .15s,box-shadow .15s;}
.ic-input:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px rgba(229,99,31,0.18);}
.ic-input::placeholder{color:var(--muted);opacity:1;}

.ic-gdpr{background:var(--fog);border:1px solid var(--rule);border-left:3px solid var(--rust);border-radius:var(--radius);padding:1.1rem 1.25rem;margin-top:.5rem;}
.ic-gdpr-label{font-family:var(--mono);font-size:.66rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-text);margin:0 0 .7rem;}
.ic-gdpr-list{list-style:none;padding:0;margin:0 0 1rem;display:flex;flex-direction:column;gap:.45rem;}
.ic-gdpr-list li{font-size:.86rem;line-height:1.6;color:var(--ink-2);padding-left:.95rem;position:relative;}
.ic-gdpr-list li::before{content:"·";position:absolute;left:.2rem;top:0;color:var(--rust);font-weight:700;}
.ic-gdpr-link{color:var(--accent-text);text-decoration:underline;}
.ic-gdpr-link:hover{color:var(--ink);}

.ic-check{display:flex;gap:.7rem;align-items:flex-start;padding:.65rem 0;cursor:pointer;font-size:.9rem;line-height:1.55;color:var(--ink);border-top:1px solid var(--rule-soft);}
.ic-check:first-of-type{border-top:1px solid var(--rule);margin-top:.35rem;}
.ic-check input[type="checkbox"]{flex-shrink:0;width:18px;height:18px;margin-top:.2rem;accent-color:var(--rust);cursor:pointer;}

.ic-devnotice{background:var(--amber-bg);border:1px solid var(--amber);border-radius:var(--radius);padding:.7rem .85rem;font-size:.88rem;line-height:1.55;color:var(--amber);}
.ic-devnotice code{font-family:var(--mono);font-size:.8rem;background:rgba(0,0,0,0.05);padding:.06rem .35rem;border-radius:3px;color:inherit;}
[data-theme="dark"] .ic-devnotice code{background:rgba(255,255,255,0.08);}

.ic-gdpr-foot{font-family:var(--mono);font-size:.66rem;line-height:1.7;letter-spacing:.02em;color:var(--muted);margin:.25rem 0 0;}

.ic-status-card{padding:1rem 1.25rem;margin-bottom:1rem;border-left:3px solid var(--rule);}
.ic-status-card--ok{border-left-color:var(--green);background:var(--green-bg);}
.ic-status-card--info{border-left-color:var(--amber);background:var(--amber-bg);}
.ic-status-card--warn{border-left-color:var(--red);background:var(--red-bg);}
.ic-status-text{margin:0;font-size:.95rem;line-height:1.55;color:var(--ink);}
.ic-status-card--ok .ic-status-text{color:var(--green);}
.ic-status-card--info .ic-status-text{color:var(--amber);}
.ic-status-card--warn .ic-status-text{color:var(--red);}

@media (max-width:640px){
  .ic-root{padding:2rem 14px 3rem;}
  .ic-card{padding:1.4rem;}
  .ic-seg{display:flex;width:100%;}
  .ic-seg button{flex:1;padding:.6rem .4rem;}
  .ic-gdpr{padding:.95rem 1rem;}
  .ic-gdpr-list li{font-size:.83rem;}
}
`;

/* ── GDPR / EmailJS helpers ─────────────────────────────────── */
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;

function emailjsConfigured() {
  const cfg = (typeof window !== "undefined") ? window.EMAILJS_CONFIG : null;
  if (!cfg) return false;
  if (!cfg.publicKey || cfg.publicKey.indexOf("YOUR_") === 0) return false;
  if (!cfg.serviceId || cfg.serviceId.indexOf("YOUR_") === 0) return false;
  if (!cfg.templateId || cfg.templateId.indexOf("YOUR_") === 0) return false;
  if (typeof window === "undefined" || !window.emailjs) return false;
  return true;
}

function buildEmailParams({ name, email, track, score, band, insights, target, obstacles, solution, comment, qualification, marketingOptIn }) {
  const tgt = TARGET.find((t) => t.id === target);
  const sol = SOLUTIONS.find((s) => s.id === solution);
  const insightsText = insights.map((i) => `• ${stripHtml(i.label)}: ${stripHtml(i.body)}`).join("\n\n");
  const obstaclesText = obstacles.map((o) => o.label).join("; ") || "(none)";
  const today = new Date().toISOString().slice(0, 10);
  return {
    to_name: name,
    to_email: email,
    track_name: track.name,
    track_code: track.code,
    track_de_name: stripHtml(track.name_de),
    score: String(score),
    band_en: band.en,
    band_de: stripHtml(band.de),
    band_insight: stripHtml(band.insight),
    primary_failure_name: track.primaryFailure.name,
    primary_failure_cite: track.primaryFailure.cite,
    primary_failure_concern: track.primaryFailure.concern,
    target_label: tgt ? tgt.label : "",
    obstacles_list: obstaclesText,
    preferred_solution: sol ? sol.label : "",
    comment: comment || "",
    next_step_title: qualification.title,
    next_step_body: stripHtml(qualification.body),
    next_step_cta: qualification.cta,
    assessment_date: today,
    marketing_optin: marketingOptIn ? "yes" : "no",
  };
}

function stripHtml(s) {
  if (s == null) return "";
  return String(s).replace(/<[^>]+>/g, "").replace(/&mdash;/g, "—").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&nbsp;/g, " ").replace(/&ldquo;|&rdquo;/g, "\"").replace(/&em;|&strong;/g, "");
}

/* Escape dynamic values before embedding in the email HTML.
   EmailJS does NOT HTML-escape template variables, and `name` is visitor
   input — so everything interpolated into {{report}} runs through this. */
function esc(s) {
  return String(s == null ? "" : s)
    .replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}

// Self-contained, inline-styled HTML email body. The shared EmailJS template's
// whole Content is the single {{report}} tag, so this is the entire email.
function buildReportHtml({ name, routeLabelEn, routeLabelDe, defensibility, bandEn, bandDe, grade,
                           primary /* {name, name_de, concern} | null */,
                           rows /* [{name, name_de, concern}] gap patterns OR insights */,
                           qualLabel, nextCta, nextBody }) {
  const C = { ink:"#111111", slate:"#3D4452", muted:"#6B7280", rust:"#E5631F",
              rule:"#DDD9D3", fog:"#F3F2EE", green:"#2E7D32", amber:"#E65100", red:"#C62828" };
  const bandColor = grade === "green" ? C.green : grade === "red" ? C.red : C.amber;
  const serif = "Georgia,'Times New Roman',serif";
  const rowHtml = (rows && rows.length)
    ? rows.map(p => `
        <tr>
          <td style="padding:10px 12px 10px 0;vertical-align:top;border-top:1px solid ${C.rule};width:42%;">
            <strong style="color:${C.ink};">${esc(p.name)}</strong><br>
            <span style="font-family:'Courier New',monospace;font-size:12px;color:${C.muted};">${esc(p.name_de || "")}</span>
          </td>
          <td style="padding:10px 0;vertical-align:top;border-top:1px solid ${C.rule};color:${C.slate};font-size:14px;">${esc(p.concern)}</td>
        </tr>`).join("")
    : `<tr><td style="padding:10px 0;color:${C.slate};font-size:14px;">No active gap patterns — the file scored cleanly on the questions answered.</td></tr>`;
  return `
<div style="font-family:${serif};color:${C.ink};line-height:1.6;max-width:640px;margin:0 auto;padding:8px 4px;">
  <p style="font-family:'Courier New',monospace;font-size:11px;letter-spacing:0.14em;text-transform:uppercase;color:${C.rust};margin:0 0 6px;">Strategic Confidence Assessment · Deutsches Arbeitsrecht</p>
  <p style="margin:0 0 4px;">Hello ${esc(name)},</p>
  <p style="margin:0 0 18px;color:${C.slate};">Here is your documented-defensibility report for <strong style="color:${C.ink};">${esc(routeLabelDe)}</strong> <span style="color:${C.muted};">(${esc(routeLabelEn)})</span>.</p>
  <div style="border:1px solid ${C.rule};border-top:3px solid ${C.rust};border-radius:6px;padding:18px 20px;margin:0 0 18px;">
    <div style="font-family:'Courier New',monospace;font-size:11px;letter-spacing:0.1em;text-transform:uppercase;color:${C.muted};">Documented defensibility</div>
    <div style="font-size:40px;font-weight:700;color:${bandColor};line-height:1.1;margin:2px 0;">${esc(String(defensibility))}</div>
    <div style="font-size:16px;color:${C.ink};">${esc(bandEn)}</div>
    <div style="font-family:'Courier New',monospace;font-size:12px;color:${C.muted};">${esc(bandDe)}</div>
    ${primary ? `
    <div style="margin-top:14px;padding-top:14px;border-top:1px solid ${C.rule};">
      <div style="font-family:'Courier New',monospace;font-size:11px;letter-spacing:0.1em;text-transform:uppercase;color:${C.muted};">Primary failure mode</div>
      <div style="font-size:16px;color:${C.ink};margin:2px 0 4px;">${esc(primary.name)} <span style="font-family:'Courier New',monospace;font-size:12px;color:${C.muted};">${esc(primary.name_de || "")}</span></div>
      <div style="font-size:14px;color:${C.slate};">${esc(primary.concern)}</div>
    </div>` : ""}
  </div>
  <p style="font-family:'Courier New',monospace;font-size:11px;letter-spacing:0.1em;text-transform:uppercase;color:${C.rust};margin:18px 0 6px;">Where the file could break down</p>
  <table style="border-collapse:collapse;width:100%;">${rowHtml}</table>
  ${nextCta ? `
  <div style="background:${C.fog};border-radius:6px;padding:16px 18px;margin:18px 0;">
    <div style="font-family:'Courier New',monospace;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:${C.muted};">${esc(qualLabel || "")}</div>
    <div style="font-size:16px;color:${C.ink};margin:4px 0;">${esc(nextCta)}</div>
    <div style="font-size:14px;color:${C.slate};">${esc(nextBody || "")}</div>
  </div>` : ""}
  <p style="font-family:'Courier New',monospace;font-size:11px;color:${C.muted};line-height:1.7;border-top:1px solid ${C.rule};padding-top:14px;margin-top:22px;">
    This is a non-legal, operational snapshot of how well a termination decision is documented, based on generalised patterns drawn from published BAG decisions. It supports counsel; it is not legal advice, does not predict outcomes, and does not constitute Rechtsberatung within the meaning of the RDG. The human remains the decider (no Art. 22 GDPR automated decision-making).
  </p>
</div>`.trim();
}

/* ════════════════════════════════════════════════════════════════════════
   Component
   ════════════════════════════════════════════════════════════════════════ */
function InternalCounselAssessment() {
  const [trackId, setTrackId] = useState(null);
  const [answers, setAnswers] = useState({});            // {1:'always',2:'rarely',...}
  const [maturity, setMaturity] = useState(null);        // Q11
  const [target, setTarget] = useState(null);            // Q12
  const [obstaclesSel, setObstaclesSel] = useState([]);  // Q13 (string ids)
  const [solution, setSolution] = useState(null);        // Q14
  const [openText, setOpenText] = useState("");          // Q15
  const [showResults, setShowResults] = useState(false);
  const [showValidation, setShowValidation] = useState(false);

  // Pre-report email gate (GDPR)
  const [showGate, setShowGate] = useState(false);
  const [gateName, setGateName] = useState("");
  const [gateEmail, setGateEmail] = useState("");
  const [gateConsent, setGateConsent] = useState(false);          // required (Art. 6(1)(a))
  const [gateMarketing, setGateMarketing] = useState(false);      // optional follow-up
  const [gateBusy, setGateBusy] = useState(false);
  const [gateError, setGateError] = useState("");
  const [emailStatus, setEmailStatus] = useState(null);           // null | "sent" | "skipped" | "failed"

  // Footer preselect handler
  useEffect(() => {
    function pre(ev){
      const tid = ev && ev.detail && ev.detail.trackId;
      if (tid && TRACKS.some(t => t.id === tid)) {
        setTrackId(tid);
        setAnswers({}); setMaturity(null); setTarget(null);
        setObstaclesSel([]); setSolution(null); setOpenText("");
        setShowResults(false); setShowValidation(false);
      }
    }
    window.addEventListener("ic-preselect-track", pre);
    try {
      const stored = sessionStorage.getItem("ic-preselect-track");
      if (stored) { pre({ detail: { trackId: stored } }); sessionStorage.removeItem("ic-preselect-track"); }
    } catch(e){}
    return () => window.removeEventListener("ic-preselect-track", pre);
  }, []);

  const track = trackId ? trackById(trackId) : null;

  const obstaclesAll = useMemo(() => {
    if (!track) return OBSTACLES;
    const seen = new Set(OBSTACLES.map((o) => o.id));
    const extras = (track.obstaclesExtra || []).filter((o) => !seen.has(o.id));
    return [...OBSTACLES, ...extras];
  }, [track]);

  const answeredCount = Object.keys(answers).length;
  const allAnswered =
    track &&
    answeredCount === track.questions.length &&
    maturity != null &&
    target != null &&
    solution != null;

  const score = useMemo(() => {
    if (!track) return 0;
    let raw = 0;
    let maxRaw = 0;
    for (const q of track.questions) {
      const a = answers[q.n];
      const p = a ? FREQ_SCALE.find((s) => s.id === a).points : 0;
      raw += p;
      maxRaw += 4;
    }
    return Math.round((raw / maxRaw) * 100);
  }, [answers, track]);

  const band = bandFor(score);

  const insights = useMemo(() => {
    if (!track || !allAnswered) return [];
    const tgt = TARGET.find((t) => t.id === target);
    const obs = obstaclesSel
      .map((id) => obstaclesAll.find((o) => o.id === id))
      .filter(Boolean);
    return buildInsights(track, answers, score, tgt, obs);
  }, [track, answers, score, target, obstaclesSel, obstaclesAll, allAnswered]);

  const qualification = useMemo(() => {
    if (!track || !allAnswered) return null;
    const tgt = TARGET.find((t) => t.id === target);
    const sol = SOLUTIONS.find((s) => s.id === solution);
    return qualificationFor(score, tgt, sol);
  }, [score, target, solution, track, allAnswered]);

  /* ── Handlers ──────────────────────────────────────────── */
  function pickTrack(id) {
    setTrackId(id);
    setAnswers({});
    setMaturity(null); setTarget(null);
    setObstaclesSel([]); setSolution(null); setOpenText("");
    setShowResults(false); setShowGate(false); setShowValidation(false);
    setEmailStatus(null); setGateError("");
    setTimeout(() => {
      const el = document.getElementById("ic-questions-anchor");
      if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
    }, 50);
  }
  function setAnswer(n, v) {
    setAnswers((prev) => ({ ...prev, [n]: v }));
    setShowValidation(false);
  }
  function toggleObstacle(id) {
    setObstaclesSel((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]);
  }
  // Q1–Q15 submit → opens the GDPR-gated email form (does not yet reveal the report).
  function generate() {
    if (!allAnswered) { setShowValidation(true); return; }
    setShowValidation(false);
    setShowGate(true);
    setTimeout(() => {
      const el = document.getElementById("ic-gate-anchor");
      if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
    }, 50);
  }
  // Gate submit → validate, send via EmailJS (or skip in DEV), then reveal the report.
  async function submitGate(ev) {
    if (ev && ev.preventDefault) ev.preventDefault();
    setGateError("");
    const name = gateName.trim();
    const email = gateEmail.trim();
    if (name.length < 2)          { setGateError("Please enter your full name."); return; }
    if (!EMAIL_RE.test(email))    { setGateError("Please enter a valid email address."); return; }
    if (!gateConsent)             { setGateError("Consent to processing is required to deliver the report. Without it we cannot send the email."); return; }

    setGateBusy(true);
    try {
      const tgt = TARGET.find((t) => t.id === target);
      const sol = SOLUTIONS.find((s) => s.id === solution);
      const obs = obstaclesSel.map((id) => obstaclesAll.find((o) => o.id === id)).filter(Boolean);
      const ins = buildInsights(track, answers, score, tgt, obs);
      const q   = qualificationFor(score, tgt, sol);
      const params = buildEmailParams({
        name, email, track, score, band, insights: ins,
        target, obstacles: obs, solution, comment: openText,
        qualification: q, marketingOptIn: gateMarketing,
      });

      // The shared template's whole Content is a single {{report}} tag, so build
      // the full inline-styled HTML body. Insights become the "where the file
      // breaks down" rows; primaryFailure is the headline failure mode.
      const report = buildReportHtml({
        name,
        routeLabelEn: track.name,
        routeLabelDe: stripHtml(track.name_de),
        defensibility: score,
        bandEn: band.en,
        bandDe: stripHtml(band.de),
        grade: band.tone,
        primary: track.primaryFailure ? {
          name: track.primaryFailure.name,
          name_de: track.primaryFailure.cite,
          concern: track.primaryFailure.concern,
        } : null,
        rows: ins.map((i) => ({ name: stripHtml(i.label), name_de: "", concern: stripHtml(i.body) })),
        qualLabel: q.title,
        nextCta: q.cta,
        nextBody: stripHtml(q.body),
      });

      if (emailjsConfigured()) {
        const cfg = window.EMAILJS_CONFIG;
        await window.emailjs.send(cfg.serviceId, cfg.templateId, {
          ...params,
          // Recipient aliases so the shared template's "To Email" always resolves.
          to_email: email, email: email, reply_to: email,
          to_name: name, name: name,
          report,                                          // the whole email body
        });
        setEmailStatus("sent");
      } else {
        setEmailStatus("skipped"); // dev / placeholder mode
      }
      setShowGate(false);
      setShowResults(true);
      setTimeout(() => {
        const el = document.getElementById("ic-results-anchor");
        if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
      }, 50);
    } catch (err) {
      console.error("EmailJS send failed", err);
      setEmailStatus("failed");
      setGateError("We could not send the email right now. You can still view the report below — try again later or copy this page.");
      setShowGate(false);
      setShowResults(true);
    } finally {
      setGateBusy(false);
    }
  }
  function reset() {
    setTrackId(null);
    setAnswers({}); setMaturity(null); setTarget(null);
    setObstaclesSel([]); setSolution(null); setOpenText("");
    setShowResults(false); setShowGate(false); setShowValidation(false);
    setGateName(""); setGateEmail(""); setGateConsent(false); setGateMarketing(false);
    setGateError(""); setEmailStatus(null);
  }
  function edit() { setShowResults(false); setShowGate(false); }
  function backToQuestionsFromGate() { setShowGate(false); }

  const scoreClass = band.tone;

  /* ── Render ────────────────────────────────────────────── */
  return (
    <div className="ic-root">
      <style>{STYLES}</style>

      {/* ─ TRACK PICKER ─ */}
      <section className="ic-card accent" id="ic-questions-anchor">
        <p className="ic-label">Step 1 · Select the file type</p>
        <h2 className="ic-h1">Which type of termination file are you assessing?</h2>
        <p className="ic-help">
          Five tracks, fifteen questions each. The question set, the §-anchored items, and the failure-mode commentary differ by track. The assessment is structural-completeness only and does not constitute Rechtsberatung.
        </p>
        <div className="ic-tracks" role="radiogroup" aria-label="Termination track">
          {TRACKS.map((t) => (
            <button
              key={t.id}
              type="button"
              className="ic-track"
              aria-pressed={trackId === t.id}
              onClick={() => pickTrack(t.id)}
            >
              <p className="ic-track-id">{t.id} · {t.code}</p>
              <p className="ic-track-name">{t.name}</p>
              <p className="ic-track-de" dangerouslySetInnerHTML={{ __html: t.name_de }} />
              <p className="ic-track-blurb">{t.blurb}</p>
              <div>
                {t.statutes.map((s) => <span key={s} className="ic-track-stat">{s}</span>)}
              </div>
            </button>
          ))}
        </div>
      </section>

      {/* ─ QUESTIONS ─ */}
      {track && !showResults && !showGate && (
        <>
          <section className="ic-card">
            <p className="ic-label">Step 2 · Best-practice questions (Q1–Q10)</p>
            <h2 className="ic-h2">{track.name} &mdash; <span style={{ fontFamily: "var(--mono)", fontSize: "0.7em", letterSpacing: "0.08em", color: "var(--muted)" }}>{track.code.toUpperCase()}</span></h2>
            <p className="ic-help">
              For each item, how consistently is this true on the matters you sign off on? Each item is gate-anchored to the corresponding pipeline check &mdash; the anchor tag (e.g. <em>G2.D3 / ED-8</em>) is shown for orientation.
            </p>

            <div className="ic-progress" aria-live="polite">
              {answeredCount} of {track.questions.length} answered
              <div className="ic-progress-bar" aria-hidden="true">
                <div style={{ width: `${(answeredCount / track.questions.length) * 100}%` }} />
              </div>
            </div>

            {track.questions.map((q) => (
              <div className="ic-q" key={q.n}>
                <p className="ic-qanchor">Q{q.n} · {q.anchor}</p>
                <p className="ic-qtext" dangerouslySetInnerHTML={{ __html: `<span class="ic-qnum">Q${q.n}.</span> ${q.text}` }} />
                <div className="ic-seg" role="radiogroup" aria-label={`Question ${q.n}`}>
                  {FREQ_SCALE.map((s) => (
                    <button
                      key={s.id}
                      type="button"
                      aria-pressed={answers[q.n] === s.id}
                      onClick={() => setAnswer(q.n, s.id)}
                      title={s.de}
                    >{s.label}</button>
                  ))}
                </div>
              </div>
            ))}
          </section>

          {/* Q11 — Current reality */}
          <section className="ic-card">
            <p className="ic-label">Q11 · Current reality</p>
            <h2 className="ic-h2">Which best describes the current file-maturity posture?</h2>
            <div className="ic-options" role="radiogroup" aria-label="File maturity">
              {MATURITY.map((m) => (
                <button
                  key={m.id}
                  type="button"
                  className="ic-option"
                  aria-pressed={maturity === m.id}
                  onClick={() => setMaturity(m.id)}
                >
                  <span className="ic-option-label">{m.label}</span>
                  <span className="ic-option-de">{m.de}</span>
                  <span className="ic-option-blurb">{m.blurb}</span>
                </button>
              ))}
            </div>
          </section>

          {/* Q12 — Desired reality */}
          <section className="ic-card">
            <p className="ic-label">Q12 · Desired reality</p>
            <h2 className="ic-h2">What posture are you trying to reach?</h2>
            <div className="ic-options" role="radiogroup" aria-label="Target posture">
              {TARGET.map((t) => (
                <button
                  key={t.id}
                  type="button"
                  className="ic-option"
                  aria-pressed={target === t.id}
                  onClick={() => setTarget(t.id)}
                >
                  <span className="ic-option-label">{t.label}</span>
                  <span className="ic-option-blurb" dangerouslySetInnerHTML={{ __html: t.blurb }} />
                </button>
              ))}
            </div>
          </section>

          {/* Q13 — Obstacles */}
          <section className="ic-card">
            <p className="ic-label">Q13 · Obstacles (multi-select)</p>
            <h2 className="ic-h2">What is preventing progress today?</h2>
            <p className="ic-help">Select all that apply. The track-specific extras (e.g. Abmahnung chain, BEM, §17 timing) are added to the base list.</p>
            <div className="ic-chips" role="group" aria-label="Obstacles">
              {obstaclesAll.map((o) => (
                <button
                  key={o.id}
                  type="button"
                  className="ic-chip"
                  aria-pressed={obstaclesSel.includes(o.id)}
                  onClick={() => toggleObstacle(o.id)}
                >{o.label}</button>
              ))}
            </div>
          </section>

          {/* Q14 — Preferred solution */}
          <section className="ic-card">
            <p className="ic-label">Q14 · Preferred solution</p>
            <h2 className="ic-h2">If you were to close the gap, what shape would suit?</h2>
            <div className="ic-options" role="radiogroup" aria-label="Preferred solution">
              {SOLUTIONS.map((s) => (
                <button
                  key={s.id}
                  type="button"
                  className="ic-option"
                  aria-pressed={solution === s.id}
                  onClick={() => setSolution(s.id)}
                >
                  <span className="ic-option-label">{s.label}</span>
                  <span className="ic-option-blurb">{s.blurb}</span>
                </button>
              ))}
            </div>
          </section>

          {/* Q15 — Anything else? */}
          <section className="ic-card">
            <p className="ic-label">Q15 · Anything else? (optional)</p>
            <h2 className="ic-h2">Context, urgency, internal constraints?</h2>
            <p className="ic-help">Often the most useful answer. Privilege note: do not include any matter-identifying detail &mdash; structural posture only.</p>
            <textarea
              className="ic-textarea"
              value={openText}
              onChange={(e) => setOpenText(e.target.value)}
              placeholder="e.g. Restructuring announcement pending; §17 threshold likely tripped; one BR site has open hearing items from the prior wave."
              maxLength={1200}
            />
          </section>

          <section className="ic-card">
            <div className="ic-actions">
              <button className="ic-btn rust" type="button" onClick={generate}>Generate result</button>
              <button className="ic-btn ghost" type="button" onClick={reset}>Start over</button>
            </div>
            {showValidation && (
              <div className="ic-validation">
                Please complete Q1–Q10, Q11 (current reality), Q12 (desired posture), and Q14 (preferred solution) before generating the result. Q13 and Q15 are optional.
              </div>
            )}
          </section>
        </>
      )}

      {/* ─ EMAIL GATE (GDPR) ─ */}
      {track && showGate && !showResults && (
        <>
          <div id="ic-gate-anchor"></div>
          <section className="ic-card accent">
            <p className="ic-label">Step 3 · Where should we send the report?</p>
            <h2 className="ic-h1">Your result is ready.</h2>
            <p className="ic-help">
              Enter your name and email to view the report on this page and receive a copy by email. The report is gated on consent because the email is the legal record &mdash; we will not deliver it without an explicit basis under Art. 6(1)(a) DSGVO.
            </p>

            <form onSubmit={submitGate} className="ic-gate-form" noValidate>
              <div className="ic-field">
                <label htmlFor="ic-name" className="ic-field-label">Full name</label>
                <input
                  id="ic-name"
                  className="ic-input"
                  type="text"
                  autoComplete="name"
                  required
                  value={gateName}
                  onChange={(e) => setGateName(e.target.value)}
                  placeholder="z. B. Dr. Maria Schneider"
                  maxLength={120}
                />
              </div>

              <div className="ic-field">
                <label htmlFor="ic-email" className="ic-field-label">Work email</label>
                <input
                  id="ic-email"
                  className="ic-input"
                  type="email"
                  autoComplete="email"
                  required
                  value={gateEmail}
                  onChange={(e) => setGateEmail(e.target.value)}
                  placeholder="maria.schneider@example.de"
                  maxLength={200}
                />
              </div>

              {/* ── GDPR notice ── */}
              <div className="ic-gdpr">
                <p className="ic-gdpr-label">Datenverarbeitung &middot; GDPR / DSGVO Art. 13</p>
                <ul className="ic-gdpr-list">
                  <li><strong>Controller (Verantwortlicher):</strong> {(window.EMAILJS_CONFIG && window.EMAILJS_CONFIG.controllerName) || "[Controller — see privacy notice]"}.</li>
                  <li><strong>Purpose:</strong> delivery of the assessment report to the email address you provide; correlation of your responses with the report record.</li>
                  <li><strong>Legal basis:</strong> Art. 6(1)(a) DSGVO &mdash; explicit consent. You can withdraw consent at any time with future effect.</li>
                  <li><strong>Recipients / processor:</strong> EmailJS Inc. acts as data processor under Art. 28 DSGVO (transmission of the report email). The full sub-processor chain and AVV terms are described in the <a href={(window.EMAILJS_CONFIG && window.EMAILJS_CONFIG.privacyUrl) || "/privacy"} className="ic-gdpr-link" target="_blank" rel="noopener noreferrer">Privacy Notice</a>.</li>
                  <li><strong>Retention:</strong> until you withdraw consent or request erasure. No matter-identifying detail is collected on this page.</li>
                  <li><strong>Your rights (Art. 15&ndash;22 DSGVO):</strong> access, rectification, erasure, restriction, portability, objection &mdash; plus the right to lodge a complaint with the supervisory authority (Aufsichtsbehörde).</li>
                </ul>

                <label className="ic-check">
                  <input
                    type="checkbox"
                    checked={gateConsent}
                    onChange={(e) => setGateConsent(e.target.checked)}
                  />
                  <span>
                    <strong>Required.</strong> I consent to the processing of my name and email address by the controller for the purpose of delivering this assessment report to my inbox (Art. 6(1)(a) DSGVO).
                  </span>
                </label>

                <label className="ic-check">
                  <input
                    type="checkbox"
                    checked={gateMarketing}
                    onChange={(e) => setGateMarketing(e.target.checked)}
                  />
                  <span>
                    <em>Optional.</em> I would like to receive follow-up information about the Verfahrenscheck service. (Separate consent &mdash; can be revoked without affecting the report delivery.)
                  </span>
                </label>
              </div>

              {gateError && (
                <div className="ic-validation" role="alert">{gateError}</div>
              )}

              {!emailjsConfigured() && (
                <div className="ic-devnotice" role="status">
                  <strong>Preview mode.</strong> The EmailJS SDK didn't load in this environment, so no email will be sent. The gate still validates your input and reveals the full report below.
                </div>
              )}

              <div className="ic-actions">
                <button className="ic-btn rust" type="submit" disabled={gateBusy}>
                  {gateBusy ? "Sending…" : (emailjsConfigured() ? "Email me the report & reveal it" : "Reveal the report (dev mode)")}
                </button>
                <button className="ic-btn ghost" type="button" onClick={backToQuestionsFromGate} disabled={gateBusy}>Back to questions</button>
              </div>

              <p className="ic-gdpr-foot">
                Submitting this form will not subscribe you to a newsletter. Marketing follow-up only happens if you tick the optional box above. The report content itself is generated locally in your browser from your answers; only the name, email, and report data are transmitted to the email-delivery processor.
              </p>
            </form>
          </section>
        </>
      )}

      {/* ─ RESULTS ─ */}
      {track && showResults && (
        <>
          <div id="ic-results-anchor"></div>
          {emailStatus === "sent" && (
            <section className="ic-card ic-status-card ic-status-card--ok">
              <p className="ic-status-text">
                <strong>✓ Report delivered.</strong> A copy of this report has been emailed to <em>{gateEmail}</em>.
                If it does not arrive within a few minutes, check the spam folder.
              </p>
            </section>
          )}
          {emailStatus === "skipped" && (
            <section className="ic-card ic-status-card ic-status-card--info">
              <p className="ic-status-text">
                <strong>Dev mode.</strong> Email delivery is not configured &mdash; the report below is shown locally only.
              </p>
            </section>
          )}
          {emailStatus === "failed" && (
            <section className="ic-card ic-status-card ic-status-card--warn">
              <p className="ic-status-text">
                <strong>⚠ Email delivery failed.</strong> The report below is the same content that would have been sent. You can copy this page or retry later.
              </p>
            </section>
          )}
          <section className="ic-card accent">
            <p className="ic-label">Result · {track.name} ({track.code})</p>
            <span className="ic-score-unit">Reconstructability score</span>
            <p className={`ic-score ${scoreClass}`}>{score}<span style={{ fontFamily: "var(--mono)", fontSize: "0.4em", marginLeft: ".15em", color: "var(--muted)" }}>/100</span></p>
            <p className="ic-band">{band.en}</p>
            <p className="ic-band-de" dangerouslySetInnerHTML={{ __html: band.de }} />
            <p className="ic-help" style={{ marginTop: "1rem" }} dangerouslySetInnerHTML={{ __html: band.insight }} />
          </section>

          <section className="ic-card">
            <p className="ic-label">Summary</p>
            <div className="ic-summary">
              <div className="ic-sum">
                <p className="ic-sum-val">{Object.values(answers).filter((v) => v === "never").length}</p>
                <p className="ic-sum-label">Items reported as <em>Never</em></p>
              </div>
              <div className="ic-sum">
                <p className="ic-sum-val">{Object.values(answers).filter((v) => v === "rarely" || v === "sometimes").length}</p>
                <p className="ic-sum-label">Items not <em>Usually/Always</em></p>
              </div>
              <div className="ic-sum">
                <p className="ic-sum-val">{obstaclesSel.length}</p>
                <p className="ic-sum-label">Obstacles named</p>
              </div>
              <div className="ic-sum">
                <p className="ic-sum-val" style={{ fontSize: "0.95rem", fontFamily: "var(--body)", fontWeight: 600, lineHeight: 1.35, color: "var(--ink-2)" }}>
                  Not computed in this snapshot
                </p>
                <p className="ic-sum-label">Estimated Streitwert &mdash; see Verfahrenscheck</p>
              </div>
            </div>
          </section>

          <section className="ic-card">
            <p className="ic-label">Insights</p>
            {insights.map((ins, i) => (
              <div className="ic-insight" key={i}>
                <p className="ic-insight-label">{ins.label}</p>
                <p className="ic-insight-body" dangerouslySetInnerHTML={{ __html: ins.body }} />
              </div>
            ))}
          </section>

          <section className="ic-card">
            <p className="ic-killer">
              The question is not whether the team knows what happened. The question is whether the file still proves it &mdash; eighteen months from now, when nobody remembers.
            </p>
          </section>

          {qualification && (
            <section className="ic-card accent">
              <p className="ic-label">Next step recommendation</p>
              <p className="ic-cta-title">{qualification.title}</p>
              <p className="ic-cta-body" dangerouslySetInnerHTML={{ __html: qualification.body }} />
              <div className="ic-actions">
                <button className="ic-btn rust" type="button" onClick={() => {
                  alert("Thank you. A Verfahrenscheck specialist will contact you.\n\n(Connect this CTA to your intake form / CRM.)");
                }}>{qualification.cta}</button>
                <button className="ic-btn ghost" type="button" onClick={edit}>Back to questions</button>
                <button className="ic-btn ghost" type="button" onClick={reset}>Start over</button>
              </div>
            </section>
          )}

          <section className="ic-card">
            <p className="ic-disclaimer">
              This tool provides a non-legal structural-completeness snapshot calibrated to recurring review themes in published BAG jurisprudence. It does not provide legal advice, predict litigation outcomes, or replace review by qualified German employment counsel. It does not constitute Rechtsberatung within the meaning of the RDG. Counsel-submitted matters remain under §203 StGB / §43e BRAO professional-secrecy framing; employer-submitted employee data remains under DSGVO / §26 BDSG / Art. 9 framing. The two regimes are treated distinctly.
            </p>
          </section>
        </>
      )}
    </div>
  );
}
