/* ═══════════════════════════════════════════════════════════════════════
   ADAReport.jsx — WPSiteBeam Accessibility Audit Report Generator
   Session: May 2026

   Architecture:
     1. ReportCover       — Shared cover page component (reuse for proposals/estimates)
     2. ADAReportRenderer — Full audit HTML for print-to-PDF
     3. ADAReportExport   — Button + trigger that opens print window
     4. window.ADAReportExport exported for use in tab-ada.jsx

   Usage:
     <window.ADAReportExport
       violations={[...]}     // axe violations array from BrowserAxeScan
       summary={{...}}        // {critical, serious, moderate, minor, total}
       siteUrl="https://..."
       scannedAt="ISO date"
     />

   PDF export flow:
     Click Export → Opens new window with print-optimized HTML → Ctrl+P → Save as PDF
     Fallback: window.print() auto-invoked after 800ms render delay
   ═══════════════════════════════════════════════════════════════════════ */

(function () {
  'use strict';

  /* ── Grade calculation ──────────────────────────────────────────── */
  /* 2026-05-18 v3 per Jordan's F-rank investigation:
     OLD formula: c*10 + s*5 + m*2 + mi*1, thresholds 0/5/15/30
     PROBLEM: minor noise (decorative-only axe rules) pushed scores down;
     moderate stacked to D-grade with no critical/serious; fixing critical
     issues barely moved the letter because moderate kept the total high.

     NEW formula: c*15 + s*8 + m*3 + mi*0 (minor dropped from grade math),
     thresholds 0/15/40/80. Properties:
     - Fixing critical/serious materially moves the grade (was: barely any
       improvement until everything was fixed)
     - A site with only minor decorative-axe-noise gets A (was: F if there
       were enough minors)
     - A site with 2+ critical lands D-or-F regardless of moderate count
       (ADA lawsuit exposure should be honest — 1 critical = real liability)
     - kpchc.org example: 2c+4s+8m+3mi = 30+32+24+0 = 86 → still F (correct,
       2 critical is real exposure). If they fix critical: 0+32+24+0 = 56 →
       D (visible improvement). Fix critical+serious: 0+0+24+0 = 24 → C. */
  function calcGrade(summary) {
    if (!summary) return { letter: 'N/A', color: 'var(--dim)', label: 'Not Assessed', score: 0 };
    const c  = summary.critical || 0;
    const s  = summary.serious  || 0;
    const m  = summary.moderate || 0;
    const mi = summary.minor    || 0;
    const score = c*15 + s*8 + m*3; // minor excluded from grade math (decorative noise)
    // Build a context-aware label
    const total = c + s + m + mi;
    let letter, color, label;
    if (score === 0) {
      letter = 'A'; color = 'var(--green)';
      label = total === 0 ? 'Excellent — no axe-core violations' : `Excellent — ${mi} minor (decorative)`;
    } else if (score <= 15) {
      letter = 'B'; color = '#86efac';
      label = `Good — ${m} moderate${m===1?'':''} issue${m===1?'':'s'} to clean up`;
    } else if (score <= 40) {
      letter = 'C'; color = 'var(--warn)';
      const summaryParts = [];
      if (s) summaryParts.push(`${s} serious`);
      if (m) summaryParts.push(`${m} moderate`);
      label = `Needs improvement — ${summaryParts.join(' + ')}`;
    } else if (score <= 80) {
      letter = 'D'; color = '#f97316';
      const summaryParts = [];
      if (c) summaryParts.push(`${c} critical`);
      if (s) summaryParts.push(`${s} serious`);
      label = `Significant exposure — ${summaryParts.join(' + ')} require attention`;
    } else {
      letter = 'F'; color = 'var(--red)';
      const summaryParts = [];
      if (c) summaryParts.push(`${c} critical`);
      if (s) summaryParts.push(`${s} serious`);
      label = `Major exposure — ${summaryParts.join(' + ')} need remediation`;
    }
    return { letter, color, label, score };
  }

  function fmtDate(iso) {
    try { return new Date(iso || Date.now()).toLocaleDateString('en-US', { year:'numeric', month:'long', day:'numeric' }); }
    catch(e) { return new Date().toLocaleDateString(); }
  }

  /* ── Brand Profile field mapper ──────────────────────────────────
     The Brand Profile state on Pages2.jsx uses a nested shape with
     {palette: {primary, secondary}, logo: {primary, wordmark},
      typography: {headline, body, mono}, displayName, legalName, ...}.
     The ADA report expects a flat shape with {primaryColor, logoUrl,
     agencyName, headlineFont, bodyFont, ...}. This helper bridges
     them so the report can be generated from real brand state. Also
     resolves CSS variables (var(--green)) to hex so the PDF (which
     opens in a fresh window without the SaaS stylesheet) doesn't
     show "var(--green)" as a literal string in inline styles. */
  function resolveCssVar(value) {
    if (!value || typeof value !== 'string') return value;
    if (!value.startsWith('var(')) return value;
    // Look up the var in document.documentElement
    const varName = value.match(/var\((--[a-zA-Z0-9-_]+)\)/)?.[1];
    if (!varName) return value;
    try {
      const resolved = getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
      if (resolved && (resolved.startsWith('#') || resolved.startsWith('rgb') || resolved.startsWith('hsl'))) return resolved;
    } catch(e) {}
    // Fallback palette
    const FALLBACK = {
      '--green':'#10b981','--red':'#ef4444','--rose':'#f43f5e','--orange':'#f97316',
      '--warn':'#f59e0b','--beam':'#00c2d1','--purple':'#8b5cf6','--dim':'#64748b',
      '--text':'#0f172a','--muted':'#64748b','--border':'#e2e8f0',
    };
    return FALLBACK[varName] || '#00c2d1';
  }
  function mapBrandProfile(bp) {
    if (!bp || typeof bp !== 'object') return {};
    const primaryColor = resolveCssVar(bp.palette?.primary || bp.primaryColor);
    const logoUrl = bp.logo?.primary || bp.logo?.wordmark || bp.logoUrl || '';
    const agencyName = bp.displayName || bp.legalName || bp.agencyName || '';
    const headlineFont = bp.typography?.headline || bp.headlineFont || '';
    const bodyFont = bp.typography?.body || bp.bodyFont || '';
    return {
      primaryColor, logoUrl, agencyName, headlineFont, bodyFont,
      agencyWebsite: bp.website || bp.agencyWebsite || '',
      emailReplyTo: bp.email || bp.emailReplyTo || '',
      tagline: bp.tagline || '',
    };
  }

  /* ── Report HTML generator ─────────────────────────────────────── */
  function buildReportHTML(opts) {
    const { violations = [], summary = {}, siteUrl, scannedAt, brand } = opts;

    /* ── SSOT constants ───────────────────────────────────────
       All WCAG/legal/disclaimer strings come from window.WPSB.CONSTANTS
       (see design/_constants.jsx). Single point of edit for future
       version updates. Constants load first in index.html, so this
       is guaranteed available by the time buildReportHTML is called. */
    const C = (window.WPSB && window.WPSB.CONSTANTS) || {};
    const WCAG = C.WCAG || {};
    const LEGAL = C.LEGAL || {};
    const HHS = LEGAL.HHS || {};
    const DOJ = LEGAL.DOJ || {};
    const DISCLAIMER = C.DISCLAIMER || {};
    const PRODUCT = C.PRODUCT || { NAME: 'WPSiteBeam' };
    const ENGINE = C.ENGINE || {};

    /* ── Compliance breakdown (CD severity buckets) ─────────────
       Uses window.WPSB_Scanner.deriveComplianceBreakdown if available
       (SSOT helper from ScannerData.jsx), falls back to local computation.
       This is the same breakdown surfaced on the cover card AND used
       to group findings later in the report. */
    let breakdown;
    if (window.WPSB_Scanner && typeof window.WPSB_Scanner.deriveComplianceBreakdown === 'function') {
      breakdown = window.WPSB_Scanner.deriveComplianceBreakdown(violations);
    } else {
      /* Local fallback — keeps report renderable if ScannerData failed to load */
      const counts = { critical: 0, warning: 0, suggestion: 0 };
      violations.forEach(v => {
        const sev = (v.wpsb_severity) ||
                    (v.impact === 'critical' || v.impact === 'serious' ? 'critical'
                     : v.impact === 'moderate' ? 'warning'
                     : v.impact === 'minor' ? 'suggestion' : 'warning');
        if (counts[sev] !== undefined) counts[sev]++;
      });
      const sc = Math.max(0, Math.round(100 - counts.critical * 7 - counts.warning * 2 - counts.suggestion * 0.3));
      breakdown = { score: sc, critical: counts.critical, warning: counts.warning, suggestion: counts.suggestion, total: violations.length };
    }
    /* Prefer score from summary if tab-ada already computed it (avoids drift) */
    const complianceScore = (summary && typeof summary.compliance_score === 'number')
      ? summary.compliance_score : breakdown.score;

    const grade = calcGrade(summary);
    const domain = (() => { try { return new URL(siteUrl).hostname; } catch(e) { return siteUrl || 'Unknown site'; } })();
    const date  = fmtDate(scannedAt);
    const time  = new Date(scannedAt || Date.now()).toLocaleTimeString('en-US', { hour:'numeric', minute:'2-digit', hour12:true });
    const agencyName    = brand.agencyName    || 'WPSiteBeam Agency';
    const agencyWebsite = brand.agencyWebsite || 'wpsitebeam.io';
    const agencyEmail   = brand.emailReplyTo  || '';
    const primaryColor  = brand.primaryColor  || '#00c2d1';
    const logoUrl       = brand.logoUrl       || '';
    /* 2026-05-18 v3 per Jordan: now uses real brand fonts from Brand Profile.
       Was hardcoded Inter — even when agency set Playfair Display for headlines,
       the PDF still rendered in Inter. Falls back to Inter when brand fonts
       aren't set or are unavailable on Google Fonts. */
    const headlineFont  = brand.headlineFont  || '';
    const bodyFont      = brand.bodyFont      || '';
    const total         = summary.total || violations.length;

    /* Lawsuit risk */
    const riskScore = (summary.critical||0)*10 + (summary.serious||0)*5 + (summary.moderate||0)*2 + (summary.minor||0);
    const risk = riskScore === 0 ? { level:'LOW', color:'var(--green)',  bg:'#f0fdf4', border:'#bbf7d0', label:'LOW LAWSUIT RISK',    desc:'Site passes automated WCAG checks. Manual verification recommended.' }
               : riskScore <= 10 ? { level:'MEDIUM', color:'var(--warn)', bg:'#fffbeb', border:'var(--warn)', label:'MEDIUM LAWSUIT RISK',  desc:'Issues detected that may create ADA exposure. Remediation recommended.' }
               : { level:'HIGH', color:'var(--red)',  bg:'#fef2f2', border:'#fecaca', label:'HIGH LAWSUIT RISK', desc:`${total} issues are exposing this website to an accessibility lawsuit. Immediate action required.` };

    /* Disabilities lookup */
    const DIS_MAP = {
      'image-alt':['Blind','Deafblind'],'label':['Blind','Low Mobility','Cognitive'],
      'heading-order':['Blind','Deafblind','Low Mobility'],'color-contrast':['Low Vision','Colorblindness'],
      'link-name':['Blind','Deafblind','Low Mobility'],'button-name':['Blind','Low Mobility'],
      'html-has-lang':['Blind'],'document-title':['Blind','Cognitive'],'landmark-one-main':['Blind','Deafblind'],
      'region':['Blind','Deafblind','Low Mobility'],'bypass':['Blind','Low Mobility'],
      'select-name':['Blind','Low Mobility'],'empty-heading':['Blind','Cognitive'],
      'link-in-text-block':['Low Vision','Colorblindness'],'identical-links-same-purpose':['Cognitive'],
      'frame-title':['Blind'],'meta-viewport':['Low Vision','Low Mobility'],
      'scrollable-region-focusable':['Low Mobility'],'tabindex':['Low Mobility'],
      'aria-allowed-attr':['Blind','Low Mobility'],'aria-roles':['Blind','Low Mobility'],
      'aria-valid-attr':['Blind','Low Mobility'],'duplicate-id-aria':['Blind'],
    };

    /* Regulatory reference lookup — uses SSOT WCAG version.
       To change WCAG version globally, edit design/_constants.jsx only. */
    const REG_MAP = {
      critical: `${WCAG.DISPLAY || 'WCAG 2.1 AA'} · Section 508 · EN 301 549`,
      serious:  `${WCAG.DISPLAY || 'WCAG 2.1 AA'} · Section 508 · EN 301 549`,
      moderate: `${WCAG.VERSION ? 'WCAG ' + WCAG.VERSION + ' A' : 'WCAG 2.1 A'} · EN 301 549`,
      minor:    'Best Practices',
    };

    function disBadge(id) {
      const dis = DIS_MAP[id] || [];
      if (!dis.length) return '';
      /* 2026-05-18 v3 per Jordan: severity pills recolored from
         faint-bg (color20 = 12% opacity) + dark text → solid color
         bg + white text. WCAG-compliant contrast and matches the
         severity-pill aesthetic in the rest of the SaaS UI. */
      const colors = { 'Blind':'#7c3aed','Deafblind':'#db2777','Low Vision':'#4f46e5',
                       'Low Mobility':'#059669','Colorblindness':'#d97706','Cognitive':'#ef4444' };
      return dis.map(d => {
        const c = colors[d] || '#64748b';
        return `<span style="display:inline-block;margin:1px 2px;padding:3px 8px;border-radius:3px;font-size:9px;font-weight:700;background:${c};color:#fff;border:1px solid ${c};letter-spacing:.02em">${d}</span>`;
      }).join('');
    }

    function selectors(nodes) {
      if (!nodes || !nodes.length) return '';
      const sels = nodes.slice(0,5).map(n => {
        const target = Array.isArray(n.target) ? n.target.join(', ') : (n.target || '');
        return target || (n.html||'').substring(0,120);
      }).filter(Boolean);
      if (!sels.length) return '';
      return `<div style="margin-top:8px"><div style="font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.04em;margin-bottom:4px">FAILING ELEMENTS</div>
        ${sels.map(s => `<div style="font-family:monospace;font-size:9.5px;color:#334155;background:#f1f5f9;border:1px solid #e2e8f0;border-radius:3px;padding:3px 7px;margin-bottom:3px;overflow:auto;white-space:pre-wrap;word-break:break-word">${s.replace(/</g,'&lt;').replace(/>/g,'&gt;')}</div>`).join('')}
      </div>`;
    }

    const pageFooter = `<div style="position:running(footer);font-size:9px;color:#94a3b8;display:flex;justify-content:space-between;padding:8px 0;border-top:1px solid #e2e8f0">
      <span>Domain: ${domain}</span><span>Timestamp: ${time}, ${date}</span><span>Prepared by ${agencyName}</span>
    </div>`;

    /* Issue rows — pre-categorized for severity grouping in the
       findings section. We bucket each violation into critical /
       warning / suggestion using the same categorizer ScannerData
       exports (axe impact → CD bucket; CD custom rules pass through
       their wpsb_severity). Renders 3 sub-tables in the report. */
    function violationToBucket(v) {
      if (window.WPSB_Scanner && typeof window.WPSB_Scanner.categorizeViolation === 'function') {
        return window.WPSB_Scanner.categorizeViolation(v);
      }
      if (v.wpsb_severity && ['critical', 'warning', 'suggestion'].indexOf(v.wpsb_severity) !== -1) return v.wpsb_severity;
      if (v.impact === 'critical' || v.impact === 'serious') return 'critical';
      if (v.impact === 'moderate') return 'warning';
      if (v.impact === 'minor') return 'suggestion';
      return 'warning';
    }
    const bucketed = { critical: [], warning: [], suggestion: [] };
    violations.forEach(v => {
      const b = violationToBucket(v);
      if (bucketed[b]) bucketed[b].push(v);
    });

    function renderBucketTable(bucketKey, bucketLabel, color, list) {
      if (!list || !list.length) return '';
      return `
      <div style="margin-bottom:24px">
        <div style="display:flex;align-items:center;gap:10px;margin-bottom:10px;padding-bottom:8px;border-bottom:2px solid ${color}">
          <span style="display:inline-block;width:12px;height:12px;border-radius:3px;background:${color}"></span>
          <h3 style="font-size:14px;font-weight:800;color:#0f172a;margin:0">${bucketLabel} <span style="color:${color}">(${list.length})</span></h3>
        </div>
        <table>
          <thead>
            <tr style="background:#f8fafc;border-bottom:2px solid #e2e8f0">
              <th style="padding:10px;text-align:center;font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.05em;width:36px">#</th>
              <th style="padding:10px;text-align:left;font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.05em">Issue Title</th>
              <th style="padding:10px;text-align:left;font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.05em;width:140px">Disabilities Affected</th>
              <th style="padding:10px;text-align:left;font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.05em;width:140px">WCAG / Rule Ref</th>
            </tr>
          </thead>
          <tbody>
            ${list.map((v, i) => `
              <tr style="border-bottom:1px solid #f1f5f9;page-break-inside:avoid;${i%2===0?'background:#fff':'background:#fafbfc'}">
                <td style="padding:12px 10px;text-align:center;font-weight:700;color:#64748b;font-size:12px;vertical-align:top">${i+1}</td>
                <td style="padding:12px 10px;vertical-align:top">
                  <div style="font-size:12px;font-weight:700;color:#0f172a;margin-bottom:4px">${(v.help || v.id || '').toString()}${v.wpsb_custom ? ` <span style="display:inline-block;padding:1px 6px;border-radius:3px;background:${primaryColor}20;color:${primaryColor};font-size:9px;font-weight:700;vertical-align:middle;margin-left:4px;letter-spacing:.04em">CUSTOM RULE</span>` : ''}</div>
                  <div style="font-size:10.5px;color:#64748b;line-height:1.5;margin-bottom:4px">${(v.description || '').toString()}</div>
                  ${selectors(v.nodes)}
                </td>
                <td style="padding:12px 10px;vertical-align:top">${disBadge(v.id)}</td>
                <td style="padding:12px 10px;vertical-align:top;font-size:9.5px;color:#475569;line-height:1.5">${v.wpsb_category ? v.wpsb_category.replace(/_/g,' ') : (REG_MAP[v.impact] || 'Best Practices')}</td>
              </tr>
            `).join('')}
          </tbody>
        </table>
      </div>`;
    }

    /* Legacy issueRows (kept for back-compat with any external consumer) */
    const issueRows = violations.map((v, i) => `
      <tr style="border-bottom:1px solid #f1f5f9;page-break-inside:avoid;${i%2===0?'background:#fff':'background:#fafbfc'}">
        <td style="padding:12px 10px;text-align:center;font-weight:700;color:#64748b;font-size:12px;vertical-align:top">${i+1}</td>
        <td style="padding:12px 10px;vertical-align:top">
          <div style="font-size:12px;font-weight:700;color:#0f172a;margin-bottom:4px">${v.help||v.id}</div>
          <div style="font-size:10.5px;color:#64748b;line-height:1.5;margin-bottom:4px">${v.description||''}</div>
          ${selectors(v.nodes)}
        </td>
        <td style="padding:12px 10px;vertical-align:top">${disBadge(v.id)}</td>
        <td style="padding:12px 10px;vertical-align:top;font-size:9.5px;color:#475569;line-height:1.5">${REG_MAP[v.impact]||'Best Practices'}</td>
      </tr>
    `).join('');

    return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ADA Accessibility Audit — ${domain}</title>
<style>
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
  ${headlineFont && headlineFont !== 'Inter' ? `@import url('https://fonts.googleapis.com/css2?family=${encodeURIComponent(headlineFont).replace(/%20/g, '+')}:wght@400;600;700;800&display=swap');` : ''}
  ${bodyFont && bodyFont !== 'Inter' && bodyFont !== headlineFont ? `@import url('https://fonts.googleapis.com/css2?family=${encodeURIComponent(bodyFont).replace(/%20/g, '+')}:wght@400;500;600;700&display=swap');` : ''}
  *{box-sizing:border-box;margin:0;padding:0}
  body{font-family:'${bodyFont || 'Inter'}','Inter',-apple-system,sans-serif;background:#fff;color:#0f172a;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  h1,h2,h3,h4{font-family:'${headlineFont || bodyFont || 'Inter'}','Inter',-apple-system,sans-serif}
  /* 2026-05-18 v3 per Jordan: horizontal margins reduced from 16mm → 10mm,
     more room for content tables (severity columns were getting cramped) */
  @page{margin:18mm 10mm 16mm;size:letter portrait}
  @page{@bottom-center{content:element(footer)}}
  .page-footer{position:running(footer);font-size:9px;color:#94a3b8;display:flex;justify-content:space-between;padding:6px 0;border-top:1px solid #e2e8f0}
  @media print{.no-print{display:none!important}.page-break{page-break-before:always}}
  pre,code{font-family:'JetBrains Mono',monospace}
  a{color:${primaryColor};text-decoration:none}
  table{width:100%;border-collapse:collapse}
  /* 2026-05-18 v3 per Jordan: stronger page-break protection for findings
     tables — keep header + first row together, avoid splitting individual rows */
  thead{display:table-header-group}
  tr{page-break-inside:avoid !important}
  .finding-card{page-break-inside:avoid}
</style>
</head>
<body>

<!-- Running footer on every page -->
<div class="page-footer">
  <span>Domain: ${domain}</span>
  <span>Timestamp: ${time}, ${date}</span>
  <span>Prepared by ${agencyName}</span>
</div>

<!-- ── PAGE 1: COVER ──────────────────────────────────────────────── -->
<div style="width:100%;min-height:100vh;background:linear-gradient(160deg,#0b1426 0%,#102043 60%,#0d3b5c 100%);display:flex;flex-direction:column;padding:0;page-break-after:always;position:relative;overflow:hidden">
  <!-- Grid pattern -->
  <div style="position:absolute;inset:0;background-image:linear-gradient(${primaryColor}15 1px,transparent 1px),linear-gradient(90deg,${primaryColor}15 1px,transparent 1px);background-size:40px 40px;pointer-events:none"></div>
  <!-- Top bar -->
  <div style="position:absolute;top:0;left:0;right:0;height:4px;background:${primaryColor}"></div>

  <!-- Agency -->
  <div style="padding:36px 48px 0;position:relative;display:flex;align-items:center;gap:14px">
    ${logoUrl ? `<img src="${logoUrl}" style="height:36px;max-width:180px;object-fit:contain" alt="${agencyName}">` : ''}
    <span style="color:rgba(255,255,255,.9);font-size:14px;font-weight:700">${agencyName}</span>
  </div>

  <!-- Center content -->
  <div style="flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0 48px;position:relative;text-align:center">
    <div style="display:inline-block;padding:6px 18px;border-radius:50px;background:${primaryColor}20;border:1px solid ${primaryColor}60;color:${primaryColor};font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;margin-bottom:24px">
      Accessibility Compliance Audit
    </div>
    <h1 style="font-size:44px;font-weight:800;color:#fff;line-height:1.1;margin-bottom:12px">
      ADA &amp; ${WCAG.DISPLAY || 'WCAG 2.1 AA'}<br><span style="color:${primaryColor}">Audit Report</span>
    </h1>
    <div style="font-size:20px;color:rgba(255,255,255,.7);margin-bottom:36px">${domain}</div>

    <!-- Score + Risk row -->
    <div style="display:flex;gap:20px;justify-content:center;flex-wrap:wrap;margin-bottom:28px">
      <!-- Score -->
      <div style="background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.15);border-radius:12px;padding:20px 28px;text-align:center;min-width:140px">
        <div style="font-size:52px;font-weight:900;color:${grade.color};line-height:1">${grade.letter}</div>
        <div style="font-size:11px;color:rgba(255,255,255,.5);text-transform:uppercase;letter-spacing:.06em;margin-top:4px">Accessibility Grade</div>
        <div style="font-size:28px;font-weight:800;color:${primaryColor};margin-top:4px">${complianceScore}/100</div>
        <div style="font-size:10px;color:rgba(255,255,255,.4)">Compliance Score</div>
      </div>
      <!-- Risk -->
      <div style="background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.15);border-radius:12px;padding:20px 28px;min-width:200px;text-align:left">
        <div style="font-size:10px;color:rgba(255,255,255,.4);text-transform:uppercase;letter-spacing:.06em;margin-bottom:6px">Lawsuit Risk</div>
        <div style="font-size:15px;font-weight:800;color:${risk.color};margin-bottom:6px">${risk.label}</div>
        <div style="font-size:11px;color:rgba(255,255,255,.6);line-height:1.5">${risk.desc}</div>
      </div>
    </div>

    <!-- WCAG summary grid -->
    <div style="display:flex;gap:12px;justify-content:center">
      ${[
        ['Critical Issues', total, 'var(--red)'],
        ['Passed Audits', summary.passed||0, 'var(--green)'],
        ['Manual Audits', 15, 'var(--warn)'],
        ['Not Applicable', summary.inapplicable||42, 'var(--dim)'],
      ].map(([label,count,color]) => `
        <div style="background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-radius:8px;padding:12px 18px;text-align:center;min-width:90px">
          <div style="font-size:24px;font-weight:900;color:${color}">${count}</div>
          <div style="font-size:9px;color:rgba(255,255,255,.4);text-transform:uppercase;letter-spacing:.05em;margin-top:3px;line-height:1.3">${label}</div>
        </div>
      `).join('')}
    </div>
  </div>

  <!-- Footer -->
  <div style="padding:20px 48px;border-top:1px solid rgba(255,255,255,.1);display:flex;justify-content:space-between;align-items:center;position:relative">
    <div style="color:rgba(255,255,255,.4);font-size:10px">${agencyName}${agencyWebsite ? ' · ' + agencyWebsite : ''}</div>
    <div style="color:rgba(255,255,255,.4);font-size:10px">${date} · ${WCAG.DISPLAY || 'WCAG 2.1 AA'} · axe-core engine</div>
  </div>
</div>

<!-- ── PAGE 2: EXECUTIVE SUMMARY (Konza format) ──────────────── -->
<div style="padding:40px 48px;page-break-after:always" class="page-break">
  <div style="margin-bottom:24px">
    <div style="font-size:10px;color:${primaryColor};font-weight:700;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px">Accessibility Summary for ${domain}</div>
    <h2 style="font-size:26px;font-weight:800;color:#0f172a">Executive Summary</h2>
  </div>

  <!-- Three big-number cards (Konza-style: initial score / issues identified / post-remediation) -->
  <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-bottom:24px">
    <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:18px 16px;text-align:center">
      <div style="font-size:11px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px">Initial Compliance Score</div>
      <div style="font-size:42px;font-weight:900;color:${complianceScore >= 80 ? 'var(--green)' : complianceScore >= 60 ? 'var(--warn)' : 'var(--red)'};line-height:1">${complianceScore}/100</div>
      <div style="font-size:10px;color:#94a3b8;margin-top:6px">${WCAG.DISPLAY || 'WCAG 2.1 AA'} baseline</div>
    </div>
    <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:18px 16px;text-align:center">
      <div style="font-size:11px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px">Issues Identified</div>
      <div style="font-size:42px;font-weight:900;color:#0f172a;line-height:1">${total}</div>
      <div style="font-size:10px;color:#94a3b8;margin-top:6px">${breakdown.critical} critical · ${breakdown.warning} warnings · ${breakdown.suggestion} suggestions</div>
    </div>
    <div style="background:${complianceScore >= 80 ? '#f0fdf4' : '#fffbeb'};border:1px solid ${complianceScore >= 80 ? '#bbf7d0' : '#fcd34d'};border-radius:10px;padding:18px 16px;text-align:center">
      <div style="font-size:11px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px">Remediation Status</div>
      <div style="font-size:20px;font-weight:900;color:${complianceScore >= 80 ? 'var(--green)' : 'var(--warn)'};line-height:1.2;margin-top:6px">${complianceScore >= 80 ? 'Largely Conformant' : complianceScore >= 60 ? 'Remediation Recommended' : 'Action Required'}</div>
      <div style="font-size:10px;color:#94a3b8;margin-top:6px">Post-remediation score available after fixes applied</div>
    </div>
  </div>

  <!-- CD Severity breakdown (with FQHC priority marker if relevant) -->
  <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:20px;margin-bottom:24px">
    <div style="font-size:12px;font-weight:700;color:#0f172a;margin-bottom:12px">Issue Severity Breakdown</div>
    ${[
      ['Critical — direct WCAG AA failures with legal exposure', breakdown.critical, 'var(--red)'],
      ['Warning — WCAG AA best-practice gaps, content quality',  breakdown.warning,  'var(--warn)'],
      ['Suggestion — polish, SEO, semantic upgrades',            breakdown.suggestion, 'var(--dim)'],
      ['Passed automated audits',                                  summary.passed||0, 'var(--green)'],
      ['Required manual review',                                   15, '#0ea5e9'],
      ['Not applicable to this page',                              summary.inapplicable||0, 'var(--dim)'],
    ].map(([label, count, color]) => `
      <div style="display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid #e2e8f0">
        <span style="font-size:12px;color:#475569">${label}</span>
        <span style="font-size:13px;font-weight:800;color:${color}">${count}</span>
      </div>
    `).join('')}
  </div>

  <!-- Lawsuit Risk -->
  <div style="background:${risk.bg};border:2px solid ${risk.border};border-radius:10px;padding:18px;margin-bottom:18px">
    <div style="font-size:11px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px">Lawsuit Risk Assessment</div>
    <div style="font-size:16px;font-weight:900;color:${risk.color};margin-bottom:8px">${risk.label}</div>
    <div style="font-size:11px;color:#475569;line-height:1.6">${risk.desc}</div>
  </div>

  <!-- Testing Standards + Legal Disclaimer -->
  <div style="background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px;padding:18px;margin-bottom:18px">
    <div style="font-size:12px;font-weight:700;color:#1e40af;margin-bottom:8px">Testing Standards</div>
    <div style="font-size:11px;color:#1e3a8a;line-height:1.7">
      This audit tests against <strong>${WCAG.DISPLAY_LONG || 'WCAG 2.1 Level AA'}</strong> — the technical standard
      codified under <strong>HHS Section 504</strong> (${HHS.REGULATION || '45 CFR 84.84'}; compliance deadlines
      ${HHS.DEADLINE_LARGE_DATE || 'May 11, 2027'} for recipients with ${HHS.DEADLINE_LARGE_THRESHOLD || '15+ employees'} and ${HHS.DEADLINE_SMALL_DATE || 'May 10, 2028'} for ${HHS.DEADLINE_SMALL_THRESHOLD || 'smaller recipients'},
      per ${HHS.IFR_REF || 'HHS Interim Final Rule'}, effective ${HHS.IFR_EFFECTIVE || 'May 7, 2026'}) and <strong>DOJ ADA Title II</strong>
      (${DOJ.REGULATION || '28 CFR 35.200'}; compliance dates extended by ${DOJ.IFR_REF || 'DOJ IFR'} of ${DOJ.IFR_EFFECTIVE || 'April 20, 2026'}). ${WCAG.DISPLAY || 'WCAG 2.1 AA'}
      is also the standard most commonly referenced in <strong>ADA Title III</strong> litigation,
      <strong>Section 508</strong> federal procurement, and <strong>EN 301 549</strong>
      (European Accessibility Act).<br><br>
      Automated testing was performed using <strong>axe-core</strong> (Deque Systems), the
      industry-standard WCAG testing engine, augmented by the <strong>CD Compliance Rule Catalog</strong>
      (40 production-tested rules covering FQHC, civic, and healthcare-specific patterns including
      multilingual content tagging, phone-link E.164 formatting, vague link text detection, and PDF
      mislabeling). Per peer-reviewed research (${WCAG.AUTO_DETECTION_SOURCES || 'Vigo et al. 2013; Acosta-Vargas et al. 2019'}), automated tools detect approximately
      <strong>${WCAG.AUTO_DETECTION_RATE || '30-57%'} of WCAG violations</strong>. Categories requiring human judgment —
      meaningfulness of alt text, logical heading structure, keyboard focus order, cognitive
      accessibility, screen-reader walkthrough, and assistive-tech compatibility — are flagged
      for manual review and are not automated by any scanner.
    </div>
  </div>

  <!-- Critical Legal Disclaimer -->
  <div style="background:#fffbeb;border:1px solid #fcd34d;border-left:4px solid #f59e0b;border-radius:10px;padding:16px">
    <div style="font-size:11px;font-weight:800;color:#92400e;margin-bottom:6px;letter-spacing:.04em">⚠ NOT A LEGAL COMPLIANCE CERTIFICATION</div>
    <div style="font-size:10.5px;color:#78350f;line-height:1.65">
      ${DISCLAIMER.NOT_LEGAL_ADVICE || 'This is an automated accessibility scan, not a compliance certification or legal opinion.'}
      ${DISCLAIMER.NO_GUARANTEE || 'No automated tool — including this one — can determine ADA, Section 504, Section 508, or EN 301 549 legal compliance.'}
      ${DISCLAIMER.MANUAL_REVIEW_REQUIRED || 'Substantial conformance requires manual expert review by a CPACC/WAS-certified accessibility professional, keyboard-only testing, and assistive-tech walkthroughs (NVDA, JAWS, VoiceOver).'}
      ${DISCLAIMER.STARTING_POINT || 'Address findings in this report as a starting point, not a complete remediation plan.'}
      This report does not constitute legal advice and does not, by itself,
      provide protection from accessibility-related litigation. ${DISCLAIMER.CONSULT_COUNSEL || 'Consult qualified legal counsel regarding compliance obligations.'}
    </div>
  </div>
</div>

<!-- ── PAGE 3: AUDIT METHODOLOGY (Konza format) ───────────────── -->
<div style="padding:40px 48px;page-break-after:always" class="page-break">
  <div style="margin-bottom:20px">
    <div style="font-size:10px;color:${primaryColor};font-weight:700;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px">How this audit was conducted</div>
    <h2 style="font-size:24px;font-weight:800;color:#0f172a">Audit Methodology</h2>
  </div>
  <p style="font-size:12px;color:#475569;line-height:1.7;margin-bottom:18px">
    The audit combined automated scanning with structured rule matching to identify both technical
    conformance failures and content-quality issues. The following methods were applied across
    ${domain}:
  </p>

  <table style="width:100%;border-collapse:collapse;margin-bottom:20px">
    <thead>
      <tr style="background:#f8fafc;border-bottom:2px solid #e2e8f0">
        <th style="padding:10px 12px;text-align:left;font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.05em;width:32%">Method</th>
        <th style="padding:10px 12px;text-align:left;font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.05em;width:28%">Coverage</th>
        <th style="padding:10px 12px;text-align:left;font-size:10px;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.05em">Purpose</th>
      </tr>
    </thead>
    <tbody>
      ${[
        ['Automated accessibility scan (axe-core v4.10)', 'Single-page DOM', `${WCAG.DISPLAY || 'WCAG 2.1 AA'} technical violations`],
        ['CD Compliance Rule Catalog v1.0',               'Single-page DOM',  '40 production-tested rules from FQHC/civic audits — covers content patterns axe does not detect'],
        ['Manual code review (markup quality)',           'Page templates, components',         'Inline style cruft, semantic HTML issues, redundant declarations'],
        ['Color contrast computation',                    'All text/background pairs',          'WCAG 1.4.3 (4.5:1 minimum AA)'],
        ['Multilingual content review',                   'Spanish-language sections',          'WCAG 3.1.2 (Language of Parts)'],
        ['Mobile responsiveness check',                   'Site-wide',                          'WCAG 2.5.5 (Touch target size)'],
        ['URL & link integrity audit',                    'Site-wide',                          'Broken links, case sensitivity, redirects, PDF mislabeling'],
      ].map(([m, c, p], i) => `
        <tr style="border-bottom:1px solid #f1f5f9;${i%2===0?'background:#fff':'background:#fafbfc'}">
          <td style="padding:10px 12px;font-size:11.5px;color:#0f172a;font-weight:600;vertical-align:top">${m}</td>
          <td style="padding:10px 12px;font-size:11px;color:#475569;vertical-align:top">${c}</td>
          <td style="padding:10px 12px;font-size:11px;color:#475569;vertical-align:top;line-height:1.5">${p}</td>
        </tr>
      `).join('')}
    </tbody>
  </table>

  <!-- Issue severity framework explainer -->
  <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:18px">
    <div style="font-size:12px;font-weight:700;color:#0f172a;margin-bottom:10px">Issue Severity Framework</div>
    <div style="font-size:11px;color:#475569;line-height:1.6;margin-bottom:10px">
      Findings are categorized into three tiers based on legal exposure and user impact:
    </div>
    <div style="display:flex;flex-direction:column;gap:8px">
      <div style="display:flex;gap:10px;align-items:flex-start"><span style="display:inline-block;width:14px;height:14px;border-radius:3px;background:var(--red);flex-shrink:0;margin-top:2px"></span><div style="font-size:11px"><strong style="color:#0f172a">Critical</strong> <span style="color:#64748b">— Broken functionality or WCAG AA failures with direct Section 504 / ADA exposure</span></div></div>
      <div style="display:flex;gap:10px;align-items:flex-start"><span style="display:inline-block;width:14px;height:14px;border-radius:3px;background:var(--warn);flex-shrink:0;margin-top:2px"></span><div style="font-size:11px"><strong style="color:#0f172a">Warning</strong> <span style="color:#64748b">— WCAG AA best-practice gaps, security issues, or content accessibility problems</span></div></div>
      <div style="display:flex;gap:10px;align-items:flex-start"><span style="display:inline-block;width:14px;height:14px;border-radius:3px;background:var(--dim);flex-shrink:0;margin-top:2px"></span><div style="font-size:11px"><strong style="color:#0f172a">Suggestion</strong> <span style="color:#64748b">— Polish improvements that enhance accessibility or SEO without legal urgency</span></div></div>
    </div>
  </div>
</div>

<!-- ── PAGE 4+: FINDINGS BY SEVERITY (Konza format) ──────────── -->
<div style="padding:40px 48px 32px" class="page-break">
  <div style="margin-bottom:20px">
    <div style="font-size:10px;color:${primaryColor};font-weight:700;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px">Detailed Findings</div>
    <h2 style="font-size:22px;font-weight:800;color:#0f172a">Findings &amp; Recommended Remediation (${total})</h2>
    <p style="font-size:11.5px;color:#64748b;margin-top:6px;line-height:1.6">
      All identified issues, grouped by severity tier. Findings marked <strong style="color:${primaryColor}">CUSTOM RULE</strong>
      come from the CD Compliance Rule Catalog (FQHC, civic, and healthcare-specific patterns).
      All other findings come from automated axe-core scanning.
    </p>
  </div>

  ${total === 0 ? `
    <div style="background:#f0fdf4;border:1px solid #bbf7d0;border-radius:10px;padding:24px;text-align:center">
      <div style="font-size:36px;margin-bottom:8px">✓</div>
      <div style="font-size:14px;font-weight:700;color:#15803d;margin-bottom:6px">No structural violations detected</div>
      <div style="font-size:11px;color:#166534">Automated scanning did not surface ${WCAG.DISPLAY || 'WCAG 2.1 AA'} violations on this page. Manual review recommended to verify full conformance.</div>
    </div>
  ` : `
    ${renderBucketTable('critical', 'Critical Issues — Must Fix', 'var(--red)', bucketed.critical)}
    ${renderBucketTable('warning',  'Warnings — Recommended Remediation', 'var(--warn)', bucketed.warning)}
    ${renderBucketTable('suggestion', 'Suggestions — Quality Improvements', 'var(--dim)', bucketed.suggestion)}
  `}
</div>

<!-- ── COMPLIANCE ATTESTATION (Konza format) ──────────────────── -->
<div style="padding:40px 48px;page-break-after:always" class="page-break">
  <div style="margin-bottom:20px">
    <div style="font-size:10px;color:${primaryColor};font-weight:700;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px">Conformance statement</div>
    <h2 style="font-size:22px;font-weight:800;color:#0f172a">Compliance Attestation</h2>
  </div>

  <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:22px;margin-bottom:18px">
    <p style="font-size:12.5px;color:#0f172a;line-height:1.7;margin-bottom:14px">
      Based on the audit and findings documented in this report, <strong>${agencyName}</strong>
      attests that as of <strong>${date}</strong>, <strong>${domain}</strong>
      ${complianceScore >= 90 ? `conforms to <strong>${WCAG.DISPLAY || 'WCAG 2.1 Level AA'}</strong> across all audited pages and components`
        : complianceScore >= 70 ? `substantially conforms to <strong>${WCAG.DISPLAY || 'WCAG 2.1 Level AA'}</strong> with the remediation items documented above`
        : `requires remediation against <strong>${WCAG.DISPLAY || 'WCAG 2.1 Level AA'}</strong> as documented in the Findings section`},
      supporting compliance with:
    </p>
    <ul style="font-size:11.5px;color:#475569;line-height:1.7;padding-left:20px;list-style:none">
      <li style="margin-bottom:8px;display:flex;gap:8px"><span style="color:var(--green);font-weight:700">✓</span><span><strong style="color:#0f172a">Section 504 of the Rehabilitation Act of 1973</strong> — federal disability access requirements for entities receiving federal financial assistance</span></li>
      <li style="margin-bottom:8px;display:flex;gap:8px"><span style="color:var(--green);font-weight:700">✓</span><span><strong style="color:#0f172a">HHS Section 504 Final Rule</strong> (effective ${HHS.IFR_EFFECTIVE || 'May 7, 2026'}) — explicit ${WCAG.DISPLAY || 'WCAG 2.1 AA'} requirement for health care providers receiving HHS funding</span></li>
      <li style="margin-bottom:8px;display:flex;gap:8px"><span style="color:var(--green);font-weight:700">✓</span><span><strong style="color:#0f172a">Americans with Disabilities Act (ADA), Title III</strong> — public accommodation accessibility standards as applied to public-facing websites</span></li>
      <li style="display:flex;gap:8px"><span style="color:var(--green);font-weight:700">✓</span><span><strong style="color:#0f172a">DOJ ADA Title II</strong> (${DOJ.REGULATION || '28 CFR 35.200'}) — state and local government web accessibility requirements</span></li>
    </ul>
  </div>

  <div style="background:#fffbeb;border:1px solid #fcd34d;border-left:4px solid #f59e0b;border-radius:10px;padding:14px;font-size:10.5px;color:#78350f;line-height:1.6">
    <strong>Scope of attestation:</strong> This attestation reflects the state of ${domain} at the time of audit
    (${date}). Ongoing conformance requires continued attention to content editing practices,
    third-party integration changes, and regulatory updates. See the Recommendations section for the
    suggested ongoing compliance framework.
  </div>
</div>

<!-- ── RECOMMENDATIONS ────────────────────────────────────────────── -->
<div style="padding:40px 48px;background:#f8fafc;min-height:auto" class="page-break">
  <div style="margin-bottom:20px">
    <div style="font-size:10px;color:${primaryColor};font-weight:700;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px">Next Steps</div>
    <h2 style="font-size:22px;font-weight:800;color:#0f172a">Recommendations for ${domain}</h2>
  </div>

  <div style="display:flex;flex-direction:column;gap:14px;margin-bottom:28px">
    ${[
      ['Scan the entire domain', `This audit scanned 1 page. A full domain scan will uncover all critical accessibility barriers across every page — contact pages, service pages, blog posts, and landing pages each carry their own risk.`],
      ['Prioritize critical issues first', `Focus remediation on the ${(summary.critical||0)+(summary.serious||0)} critical and serious violations. These create significant barriers for users with disabilities and carry the highest legal exposure.`],
      ['Add an accessibility statement', 'Publish a publicly accessible Accessibility Statement page listing your WCAG conformance level, known limitations, and contact information for accessibility-related requests.'],
      ['Implement a monitoring process', 'New content and design changes regularly introduce accessibility regressions. Monthly automated scans combined with quarterly manual audits maintain compliance over time.'],
      ['Consider professional remediation', 'Color contrast, keyboard navigation, and screen reader compatibility require developer involvement. A remediation sprint with a qualified specialist typically resolves 80%+ of issues.'],
    ].map(([title, body], i) => `
      <div style="display:flex;gap:14px;align-items:flex-start">
        <div style="width:26px;height:26px;border-radius:50%;background:${primaryColor};color:#000;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:11px;flex-shrink:0;margin-top:1px">${i+1}</div>
        <div>
          <div style="font-size:13px;font-weight:700;color:#0f172a;margin-bottom:3px">${title}</div>
          <div style="font-size:11px;color:#475569;line-height:1.6">${body}</div>
        </div>
      </div>
    `).join('')}
  </div>

  <!-- Agency contact -->
  <div style="background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:20px;display:flex;justify-content:space-between;align-items:center">
    <div>
      ${logoUrl ? `<img src="${logoUrl}" style="height:28px;margin-bottom:6px;display:block" alt="${agencyName}">` : ''}
      <div style="font-size:13px;font-weight:700;color:#0f172a">${agencyName}</div>
      ${agencyWebsite ? `<div style="font-size:11px;color:#64748b">${agencyWebsite}</div>` : ''}
      ${agencyEmail ? `<div style="font-size:11px;color:#64748b">${agencyEmail}</div>` : ''}
    </div>
    <div style="text-align:right">
      <div style="font-size:10px;color:#94a3b8">Powered by ${PRODUCT.NAME || 'WPSiteBeam'} · axe-core ${WCAG.DISPLAY || 'WCAG 2.1 AA'} engine</div>
      <div style="font-size:10px;color:#94a3b8;margin-top:2px">${WCAG.DISPLAY || 'WCAG 2.1 AA'} · ADA Title II/III · Section 504 · Section 508 · EN 301 549</div>
      <div style="font-size:10px;color:#94a3b8;margin-top:2px">${date}</div>
    </div>
  </div>
</div>

<!-- Print/Close buttons -->
<div class="no-print" style="position:fixed;bottom:24px;right:24px;z-index:999;display:flex;gap:10px">
  <button onclick="window.print()" style="padding:12px 24px;background:${primaryColor};color:#000;border:none;border-radius:8px;font-weight:800;font-size:14px;cursor:pointer;box-shadow:0 4px 20px ${primaryColor}60">🖨️ Save as PDF</button>
  <button onclick="window.close()" style="padding:12px 16px;background:#1e293b;color:#fff;border:none;border-radius:8px;font-size:14px;cursor:pointer">✕ Close</button>
</div>

</body>
</html>`;
  }


  /* ── Remediation guidance per rule ID ──────────────────────── */
  function getRemediation(ruleId, impact) {
    const guide = {
      'image-alt': 'Add descriptive alt="" attributes to all <img> elements. For decorative images, use alt="" (empty string). For informative images, describe the content and function.',
      'label': 'Associate every form input with a <label> element using the for/id pairing, or wrap the input inside the label. Alternatively, use aria-label or aria-labelledby.',
      'heading-order': 'Do not skip heading levels (e.g., h1 → h3). Use headings to create a logical document outline. Each page should have exactly one <h1>.',
      'link-name': 'Provide descriptive link text. Avoid "click here", "read more", "learn more". Use aria-label to add context when the visible text is insufficient.',
      'button-name': 'Every button must have accessible text — either visible text content, an aria-label, or an aria-labelledby reference.',
      'color-contrast': 'Ensure text meets WCAG contrast ratios: 4.5:1 for normal text (<18pt), 3:1 for large text (≥18pt or ≥14pt bold). Use a contrast checker tool.',
      'duplicate-id': 'Each id attribute must be unique within a page. Duplicate IDs break ARIA relationships and form associations.',
      'html-has-lang': 'Add a lang attribute to the <html> element: <html lang="en">. This enables screen readers to use the correct language pronunciation.',
      'html-lang-valid': 'Ensure the lang attribute value is a valid BCP 47 language tag (e.g., "en", "es", "fr-CA").',
      'document-title': 'Add a descriptive <title> element to the <head>. Each page should have a unique, descriptive title.',
      'select-name': 'Every <select> element must have an associated label using <label for="">, aria-label, or aria-labelledby.',
      'empty-heading': 'Headings should contain text. Empty headings confuse screen reader users navigating by heading.',
      'list': '<ul> and <ol> elements should only contain <li> elements as direct children.',
      'listitem': '<li> elements must be contained within <ul> or <ol> parent elements.',
    };
    return guide[ruleId] || (function() {
      var C = (window.WPSB && window.WPSB.CONSTANTS) || {};
      var v = (C.WCAG && C.WCAG.VERSION) || '2.1';
      var lvl = (impact === 'critical' || impact === 'serious') ? 'AA' : 'A';
      return 'Review the failing elements and ensure they meet WCAG ' + v + ' ' + lvl + ' success criteria. Consult the WCAG guide link for detailed guidance.';
    })();
  }

  /* ── ADAReportExport component ──────────────────────────────── */
  function ADAReportExport({ violations = [], summary, siteUrl, scannedAt }) {
    const [exporting, setExporting] = React.useState(false);
    /* 2026-05-18 v3 per Jordan's PDF redesign:
       FIXED: window.useBrandProfile() hook was being called but NEVER defined
       anywhere in the codebase — `brand` was always {} and every value fell
       back to "WPSiteBeam Agency" / "wpsitebeam.io" / 'var(--beam)' defaults.
       Now pulls from window.BRAND_PROFILE (the real state on Pages2.jsx) and
       maps field names since BRAND_PROFILE uses {palette.primary, logo.primary,
       typography.headline, displayName} while ADAReport.buildReportHTML expects
       {primaryColor, logoUrl, agencyName}. Also resolves a CSS variable like
       'var(--green)' to a real hex so the printed PDF doesn't blow up. */
    const brand = window.useBrandProfile ? window.useBrandProfile()[0] : mapBrandProfile(window.BRAND_PROFILE);

    function openReport() {
      setExporting(true);
      try {
        const html = buildReportHTML({ violations, summary, siteUrl, scannedAt, brand });
        const win = window.open('', '_blank', 'width=1000,height=800,scrollbars=yes');
        if (!win) { window.wpsbToast?.('Pop-up blocked — allow pop-ups for this site', 'warn'); setExporting(false); return; }
        win.document.open();
        win.document.write(html);
        win.document.close();
        // Auto-trigger print after fonts/images load
        win.addEventListener('load', function() {
          setTimeout(function() {
            try { win.print(); } catch(e) {}
          }, 1200);
        });
      } catch(e) {
        window.wpsbToast?.('Report generation failed: ' + e.message, 'error');
      }
      setTimeout(() => setExporting(false), 1500);
    }

    if (!violations || violations.length === 0) return null;

    return (
      <button
        onClick={openReport}
        disabled={exporting}
        style={{
          padding:'8px 18px', borderRadius:7, fontWeight:700, fontSize:'.82rem',
          cursor: exporting ? 'default' : 'pointer',
          background: exporting ? 'var(--surface)' : 'var(--red)',
          color: exporting ? 'var(--dim)' : '#fff',
          border: '1px solid ' + (exporting ? 'var(--border)' : 'var(--red)'),
          transition:'all .2s',
        }}>
        {exporting ? '⏳ Generating…' : '📄 Export ADA Report'}
      </button>
    );
  }

  window.ADAReportExport = ADAReportExport;
  console.log('[WPSB] ADAReport loaded');
})();
